Bring in the node_modules from an absolute path instead of a relative one

I am facing an issue while trying to import a custom framework that I published on npmjs.org. I have created a .js file and a .d.ts file for this framework.

Initially, there are no errors during the import process until I compile the code. All the map links seem to work correctly and lead to the source when clicked with ctrl, and the types file is being detected.

The problem arises during compilation where any file importing these modules attempts to import them relative to its own path. Despite going through several questions on Stack Overflow and trying various suggestions, including using paths in the tsconfig file, the issue persists.

Error:

ERROR in ./src/scripts/game/mGameModel.ts 17:16-34

Module not found: Error: Can't resolve 'Scratch' in '/Users/derek/Projects/ghg/cash-mania/src/scripts/game'

The actual library files can be found at;

node_modules/@myorg/game-framework/dist/Scratch.js
node_modules/@myorg/game-framework/dist/Scratch.d.ts
node_modules/@myorg/game-framework/dist/Scratch.js.map

Could there be an issue with how I'm building the types file or what mistake might I be making?

Here is my tsconfig setup:

{
  "compilerOptions": {
    "target": "ES5",
    "module": "commonjs",
    "strict": true,
    "noImplicitAny": false,
    "esModuleInterop": true,
    "allowUnreachableCode": false,
    "experimentalDecorators": true,
    "sourceMap": true,
    "strictPropertyInitialization": false,
    "typeRoots": [
      "./node_modules/phaser/types",
      "./node_modules/@myorg/game-framework/dist/"
    ],
    "baseUrl": "./",
    "types": [
      "node",
      "phaser"
    ],
   ...

I've tried adding paths in different ways and also included the folder in the 'include' section while ensuring the baseUrl is set correctly to ./. However, the module always gets imported relative to the importing file's directory.

This is my webpack configuration:

...

Answer №1

Although it may not align exactly with what you had in mind, here is my approach to using path imports with '@'

1 - Start by installing these babel dependencies to help compile the paths:

npm install -D @babel/cli @babel/node @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/preset-env @babel/preset-typescript babel-plugin-module-resolver babel-plugin-transform-typescript-metadata

2 - Create a file named babel.config.js and define custom paths within it...

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: '14.19.13'  // SPECIFY NODE VERSION HERE
        }
      }
    ],
    '@babel/preset-typescript'
  ],
  plugins: [
    ['module-resolver', {
      alias: {
        '@domain': './src/domain',  // CUSTOM ALIAS DECLARATION
      }
    }],
    'babel-plugin-transform-typescript-metadata',
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties', { loose: true }]
  ],
  ignore: [
    '**/*.spec.ts',
    '**/*.test.ts',
    'test/**/*.spec.ts'
  ]
}

3 - Modify your ts.config.json file to include paths for importing...

"paths":{
    "@main/*": ["main/*"],
}

4 - Create a build script in your package.json like this...

  "scripts": {
    "build": "babel src --extensions \".js,.ts\" --out-dir dist --copy-files --no-copy-ignored"
}

If you'd like some inspiration, feel free to check out one of my projects: https://github.com/Christiangsn/Nodejs-API-IntegrationWithFacebook/blob/Master/package.json

As a bonus tip: consider using an alternative to nodemon such as: https://www.npmjs.com/package/tsconfig-paths

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Make a POST request including a JSON object that contains a file

My JSON object is structured as follows: const people = { admin: { name: 'john', avatar: { img: File } }, moderator: { name: 'jake', avatar: { img: File } } }; The img property is a File obj ...

Displaying JSON array data across three different pages using AngularJS and Ionic framework

I have an array of categories with multiple products. I want to display these categories on a category page. When a category is clicked, it should redirect to the product page and show the relevant products. Similarly, when a product is clicked, it shou ...

Execute the script only if the designated object is present on the page

A few years ago, I wrote some JavaScript code that is now causing errors to pop up in the console on pages where the object it relies on is not present. The error messages look like this... Cannot read property 'top' of undefined TypeError: Ca ...

The switchMap function is sending back a single item

I'm having an issue with switching the observable using the switchMap operator: return this.db.list(`UserPlaces/${this.authData.auth.auth.currentUser.uid}`, { query: { orderByChild: 'deleted', equalTo: false } }) .ma ...

Node.js tip: track down and address ignored errors in your code

Is there a method in node.js to track and log all exceptions? I find process.on('uncaughtException') insufficient for my needs, as I want to log all handled and unhandled exceptions, even if they were caught and disregarded using a catch block s ...

Utilize Jquery to insert the text into the input or textarea field

<div class="ctrlHolder"> <label for="" id="name.label">Name</label> <input name="name" id="name" type="text" class="textInput small" /> <p class="formHint">Please enter the name of the item you are submitting</p> </di ...

The Correct Way to Implement Google ReCaptcha

I've developed a PHP contact form that performs validation using AJAX/JSON on the server side. The errors are then passed to Javascript for display and adjustments to the HTML/CSS. My challenge now is to integrate Google ReCaptcha with AJAX validatio ...

Import all constants that have been exported in ES6 TypeScript and store them as an array

I am faced with the challenge of exporting multiple constants that I will later need to import and iterate through as an array. Due to my use of generics (OptionInterface) and the necessity to maintain type validations, I cannot simply place all constants ...

Tips on how to toggle/close a dropdown menu that is displayed on a different page using Vue

Below is a screenshot of my cart dropdown: https://i.sstatic.net/IdOZK.png The issue I am facing is that the cart stays open even when I navigate to another page. I need it to close when I move to a different page. Below is my component code: <template ...

Creating a modal pop-up using Vue.js

Just delved into learning Vue.js and I'm struggling with creating a modal window. Any ideas on what could be causing my issue? How can I connect a button element in the Header.vue component to a modal window in Modal.vue? Check out this sandbox for r ...

Showing post response (XMLHttpRequest) on Chrome extension interface instead of Python console

I am currently developing a Chrome extension that sends a post request with information about the specific URL being browsed by the user to Flask (local host). A web scraping process is then carried out on this URL to determine a category based on the obta ...

Exploring the possibilities of manipulating the query string with Vue router in vue.js

I've been working on a Vue.js app that includes a tagging feature. I'm looking to implement URL parameters like where users can add tag_ids by interacting with the UI. Although I've successfully managed to update the tag_ids within the app ...

What methods can be used to center a Google map on a specific location?

I am facing an issue with three map canvases on different divs. Despite setting the center to the same position in all three of them using JavaScript, the second and third maps do not seem to reflect that center. Does anyone have any insights on what cou ...

NodeJS does not support the Array.Push method

I'm having trouble getting this code to work. I want to generate 5 random items from my database and store them in an array called 'dato'. However, when I print the array, it appears to be empty. /* GET users listing. */ router.get('/& ...

Is there a way to have a button click automatically triggered after a 5-second delay using React?

Is it possible to have an 'Accept' button that gets automatically clicked after 5 seconds? I am working with React in Next.js environment. Here is the code for the button: <button name="accept" className="alertButtonPrimary" ...

Running multiple Karma and Jasmine projects within a single solution efficiently (and the necessity for Jenkins integration)

In our extensive solution, we are managing various projects with Karma & Jasmine Tests. Utilizing Jenkins for continuous integration, our goal is to streamline the process by running the Karma execute command just once. This means eliminating the need to m ...

Can you explain the concept of the "Regular Expression Denial of Service vulnerability"?

After recently setting up nodejs on a server, I ran a basic npm install command and received multiple messages like the following: $ npm install npm WARN deprecated <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="55383c3b3c3834 ...

The functionality of a basic each/while loop in jQuery using CoffeeScript is not producing the desired results

I've been experimenting with different methods to tackle this issue. Essentially, I need to update the content of multiple dropdowns in the same way. I wanted to use an each or a while loop to keep the code DRY, but my experience in coffeeScript is li ...

Getting the card height in Bootstrap Vue: Tips and tricks

Utilizing the card component in bootstrap-vue is my current project. One challenge I'm facing is determining the height of the card post-rendering, as the height varies depending on the amount of text within. Can you provide a possible solution? ...

What is the best way to conditionally return an optional generic type from a function?

In this code snippet, we have a simple example of a function that accepts an optional generic type and an optional second parameter. If the second parameter is provided, it will return the generic type. const helper = async <T = void>( config: { bo ...