I'm using TypeScript, with my source files in src/
and outputting to dist/
. I have modules in src/modules/
and some other stuff in src/scripts/
. The directory structure is maintained when TypeScript transpiles to JavaScript in dist/
. However, the import...
statements are transpiled to require()
statements with the (non-relative) paths unchanged.
In TypeScript, I can refer to my modules without having to use messy relative paths by setting baseUrl
in tsconfig.json
. If I set it to ./src
, I can then import my modules with something like:
import * as myModule from "modules/myModule";
However when that is transpiled to the Node.js equivalent:
const my_module_1 = require("modules/myModule");
... Node.js doesn't find the module because the file pulling in the module is in src/scripts
. Wouldn't it be nice if you could just add module search paths to the beginning of Node's paths list by just having a moduleSearchPaths
property in package.json
(@refack suggested using .npmrc
instead)? Then the first place Node would search would be those paths and I could just say:
...
"moduleSearchPaths": [
"./dist"
]
...
... making Node first search for dist/modules/myModule.js
- and it would work.
By the way, I know you can set the NODE_PATH
env variable to do this but I think that's a nasty solution because I always try to avoid using env variables. They don't translate well between different environments.
I think this is unlikely to gain traction because I see this as a similar request brought up during the ES modules implementation discussion(s), which was voted down by the TSC. I think this just unnecessarily complicates the lookup algorithm even further, when the lookup algorithm is already fairly complicated.
So there's literally no way to get away from relative paths? This seems like a really basic issue to me.
There is a way that I've used a few times. You can create a src/node_modules
directory and put your files in it.
Yeah that does work. Feels like a hack though. People will think it should be for NPM modules.
It's not really a hack though - node_modules
is a _node_ thing. npm just happens to install to it so that things work out of the box.
But is it really a good idea to dictate that you have a src/node_modules
directory structure rather than have what you want and point to it?
Yes, IMO. It means there is One And Only One Way to do it.
Right now the rule is 'look in node_modules' and every developer knows that.
Except that it isn't because it looks in a bunch of different places including the NODE_PATH
variable.
@jez9999 NODE_PATH
is deprecated and does not work w/ ESM loader. If someone is relying on it you should feel encouraged to tell them to move off of it.
And switch to having a second ugly node_modules
directory in their source tree. Not exactly something I can recommend either.
I have to agree with @jez9999. I can see some of the philosophical/implementation issues with a package.json configurable paths
option, but it seems like a common issue that many devs have with Node, no? And it likely _is_ solvable by smarter minds than mine? In any case, would be a fantastic feature for a common usecase!
My understanding is that NODE_PATH=./path/to/somewhere node file.js
is the only practical means of specifying a path.
I do this because
const myModule = require('static-path-to/my-module')
````
is much cleaner than
```javascript
const myModule = require('../../../../../omg/../relative-path-to/my-module')
which is brittle because it may break when the containing file moves or when copied to another file; and it just looks terrible.
If NODE_PATH
is going away, we need an equivalent. A --node_path="./path/to/somewhere"
flag or a "paths": "./path/to/somewhere"
package.json
key/value would work just fine in my case. Either would also work for Windows unlike my current solution. See https://github.com/nodejs/node-v0.x-archive/issues/4609 by @ForbesLindesay.
Put into https://github.com/nodejs/node/projects/13 backlog
At the top of your script, use the following to add a new search path for modules search.
module.paths.push('[MEW_PATH');
For example:
module.paths.push('../../../../../omg/../relative-path-to');
const myModule = require('my-module')
@RoyeA I presume, it'll work for scripts, but not for programs. module
is not a global but a local-per-module.
On the other hand, if it was truely global (like NODE_PATH
), it'll lead to broken code in other modules just because they're may be unaware of that certain path modification.
Most helpful comment
My understanding is that
NODE_PATH=./path/to/somewhere node file.js
is the only practical means of specifying a path.I do this because
which is brittle because it may break when the containing file moves or when copied to another file; and it just looks terrible.
If
NODE_PATH
is going away, we need an equivalent. A--node_path="./path/to/somewhere"
flag or a"paths": "./path/to/somewhere"
package.json
key/value would work just fine in my case. Either would also work for Windows unlike my current solution. See https://github.com/nodejs/node-v0.x-archive/issues/4609 by @ForbesLindesay.