In Node.js, is there any way to require file from the same package without using relative paths? For example, here's a snippet of code from ESLint.
const rule = require("../../../lib/rules/accessor-pairs"),
{ RuleTester } = require("../../../lib/rule-tester");
The fact that we have to walk all the way up the tree ../../../
to get to the root is not only annoying. It's also brittle, because I can't move the code without updating all of dependency references.
Yet somehow Node.js developers seem to have lived with it the past 10 years. I can't find anything in the docs or Stack Overflow that solves this problem other than a third-party dependency called require-self. Nor have I been able to find a definitive statement that using relative paths is the only non-hacky way for a file to require another file in the same module.
If there's a way to specify a path relative to the package root in ECMAScript Modules (ESM) but not CommonJS (CJS), or vice versa, I would like to know that as well.
To be clear, I don't think there is a solution to the problem. If there is great. Otherwise, I'm looking for confirmation with an authoritative reference.
Not necessarily the same package - if you are writing libraries this won't be useful, but if you are writing the "final application" - the thing that actually gets run:
One option:
If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they are not found elsewhere.
So you can do any of:
1.
export NODE_PATH=.
node app.js
NODE_PATH=. node app.js
// app.js (or whatever your entry point is) before *any* require() calls
process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();
Or, another way:
The Module object representing the entry script loaded when the Node.js process launched.
https://nodejs.org/api/modules.html#modules_require_main
So you can just do:
const rule = require.main.require("./lib/rules/accessor-pairs")
anytime you want it to be relative to the root (assuming that is how you have your project structured).
You can use the package name itself as a "symlink" to the package root.
Example - foo
package imports bar
script relative to the foo
package root.
package.json
{
"dependencies": {
"foo": "file:./foo"
}
}
index.js
const foo = require('foo');
console.log(foo.bar); // prints "hello"
foo/index.js
const bar = require('foo/bar'); // import relative to the package root
module.exports = {
bar: bar
}
foo/bar.js
module.exports = 'hello';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With