25

Let's say i have following codes:

var mod1 = require('../../../../ok/mod1');
var mod2 = require('../../../info/mod2');

It's not pretty coding like above, i am wondering if there is a way to configure the root resolver just like webpack-resolve-root in nodejs?

So far as i know, the NODE_PATH can be used to replace the root of node_modules, but that's not what i want. I'd like to have the resolver to resolve multiple folders in order.

Howard
  • 4,474
  • 6
  • 29
  • 42

3 Answers3

38

Updated answer for 2021.

nodejs subpath imports have been added in: v14.6.0, v12.19.0

This allows for you to add the following to package.json

"imports": {
  "#ok/*": "./some-path/ok/*"
  "#info/*": "./some-other-path/info/*"
},

and in your .js

import mod1 from '#ok/mod1';
import mod2 from '#info/mod2';
Davey
  • 2,355
  • 1
  • 17
  • 18
  • could this work with const mod = require('')? – radiorz Aug 20 '21 at 08:55
  • oh, that's a good question. Especially as it's what OP asked about. I don't know, but I doubt it. – Davey Aug 20 '21 at 11:03
  • It actually works with const mod = require('') as well. – Expenzor Oct 11 '21 at 09:47
  • 1
    Is there a way to make this work for an external folder that sits beyond the node root? E.g: a server and shared folder, with server being a package that has the subpath import defined to the shared folder. Was hoping for this to work: `"#shared/*": "../shared/src/*"` – Oli414 Oct 15 '21 at 20:28
  • 3
    This works with typescript but you do need to use "#" instead of "@". tsconfig.json: `"paths": { "#pkg2/*": ["./pkg2/*"] },` package.json: `"imports": { "#pkg2/*": "./pkg2/*" }` – Corey Alix Oct 28 '21 at 15:33
  • does nodejs version 16 have this? only v14.6.0, v12.19.0? – May'Habit Mar 31 '22 at 05:00
  • 1
    @May'Habit yes 16 has this. – Davey Apr 11 '22 at 14:43
  • Couldn't get this to work. I remember the "@" was working with me with some previous project.. – busaud Feb 13 '23 at 16:11
  • OK. I found it in the tsconfig.json file. – busaud Feb 13 '23 at 16:30
  • Are any changes required for a node.js typescript project working with webpack? – Remy Apr 13 '23 at 14:57
14

There is an npm package called module-alias that may do what you are looking for.

Prusprus
  • 7,987
  • 9
  • 42
  • 57
  • 1
    Is it possible to retain path intellisense with this package? (https://stackoverflow.com/questions/53693686) – Florian Ludewig Apr 22 '19 at 07:10
  • 2
    Beware that package has some issues. It wipes your entire repository. Apparently it happens for few users. There is no solution for the data loss. Make sure you commit all your changes before you use this module – Ashwin R Jul 29 '20 at 12:13
  • package.json "imports" is the way to go. See newer answers. – Corey Alix Oct 28 '21 at 15:39
-6

The best way to approach this would be to use a global (config) container. In most cases you will have a config file in your application. In this config you can add a property which will be an object containing all absolute paths to files/folders. Because config files are used at the start of you application, you just do the following:

var config = require("./config.js");
//config = {... , path: {"someModule": "/absolute/path/to", "someModule2": "/absolute/path/to"...}}
global.CONFIG_CONTAINER = config

Later on in your application you can just use

var myModule = require(CONFIG_CONTAINER.path.someModule)
// + concat if you are looking for a file

In case you have some complex paths and you need a more dynamic system, you can always implement a function inside the config that will build paths for you. ( config.makePath = function(){...} ) That should take care of it in a nutshell.

OrahKokos
  • 180
  • 1
  • 8
  • I cannot using this way. I am front-end developer, and i am using `webpack` as devtool to compile the source code written in commonjs. Once i'd like to write unit-test, i found the module cannot be loaded correctly, since the paths i am using in `require` are resolved by the [webpack-resolve-root](http://webpack.github.io/docs/configuration.html#resolve-root) – Howard Oct 19 '15 at 13:43