javascriptnode.jswebstormrequirecommonjs

How to import JavaScript files in NodeJS using file paths from project root? (instead of relative file paths)


Question:

How to import JavaScript files in NodeJS using file paths from project root? (instead of relative file paths)

In other words, my team is trying to transition from Syntax Style A to Syntax Style B (shown below):

Syntax Style A

const source = require('../../../../../../source.js');

Syntax Style B

const source = require('src/source.js'); // "src" is a direct subfolder of the project root

I have reviewed a lot of posts on this topic, and none of them can satisfy my project's requirements...


Project Requirements:


Setup:

Below is my setup. Package.json was generated by WebStorm, and I haven't changed it.

Screenshot_of_Project_Structure

Project_Root
├─-─ src
│    └── a1
│       └── a2
│           └── a3
│               └── Worker.js
├──- subFolder1
│    └── SubWorker.js
├─ main.js
└─ package.json

main.js

const Worker = require('./src/a1/a2/a3/Worker.js');
Worker.doWork();

Worker.js

// If I replace the following with Project Root path, such as:
//    const SubWorker = require('src/subFolder1/SubWorker.js');
// The script will fail with "Error: Cannot find module './src/subFolder1/SubWorker.js'."

const SubWorker = require('../../../subFolder1/SubWorker.js');

module.exports =
class Worker { 

        static doWork() {
                console.log("doing work");
                SubWorker.doMoreWork();
        }
}

SubWorker.js

module.exports =
class SubWorker {

        static doMoreWork() {
                console.log("doing more work");
        }

};

Attempt #1: path.resolve

I tried the "path.resolve" solution, as suggested by this post:


Attempt #2: app-module-path


Attempt #3: dynamic import()

Worker.js

const rootPath = 'src/subFolder1';
const SubWorker = require(`${rootPath}/SubWorker.js`);


Attempt #4: subpath imports


Expected Outcome:

Since NodeJs is one of the most important backend languages, I was expecting excellent IDE support for imports... Referencing a source file from Project Root should be a simple operation that is handled by the IDE (I shouldn't need to use Babel.js or Webpack). Am I doing something wrong here?

I don't know what I am doing wrong, since I have already followed standard practices:

Thanks!


Related Posts:

The Stack Overflow posts below are relevant, but do not address the specific issue in this post. (Please kindly search by the title on Stack Overflow, since the spam filter limited the number of links in this post, thanks!)



Solution

  • Using the "Imports" property

    As of March 2023, a good way to eliminate the NodeJS relative paths is to use the imports property in package.json. (In the codes below, #root is the project root.)


    For CommonJS-style JavaScripts:

    // package.json
    {
      "imports": {
        "#root/*.js": "./*.js"
      }
    }
    
    // main.js:
    const Source = require('#root/path/to/Source.js');
    
    // Source.js:
    module.exports = class Source {
      // ...
    }
    
    

    For ECMAScript-style JavaScripts:

    // package.json:
    {
      "type" : "module",
      "imports": {
        "#root/*.js": "./*.js"
      }
    }
    
    // main.js
    import { Source } from '#root/path/to/Source.js';
    
    // Source.js:
    export class Source {
      // ...
    }
    
    

    Advantages:

    Updates in April 2023: