Reputation: 26075
I find that I need to type ../
a lot to require()
files. My directory structure includes these:
js/
components/
...
actions/
...
From the components folder, I need to do import foo from '../actions/fooAction'
. Is it possible to make the root directory the root of the project? I.e. I want to do import foo from '/actions/fooAction'
instead. I tried setting Webpack's resolve.root
option, but it didn't seem to do anything.
Upvotes: 35
Views: 56894
Reputation: 1140
With Webpack 5 you have to add the following lines into your webpack.config.js file:
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules']
}
Upvotes: 1
Reputation: 1140
now you should use
resolve: {
roots: [
path.resolve(__dirname, 'src', 'components'),
],
},
see more https://webpack.js.org/configuration/resolve/#resolveroots
Upvotes: 2
Reputation: 91
Other solution is using resolve.alias
to import js like a module (I'm not saying that it's a module, just the syntax is similar).
resolve: {
alias: {
js: path.resolve(__dirname, './js'),
},
}
And you can import fooAction
this way:
import foo from 'js/actions/fooAction';
Upvotes: 5
Reputation: 1890
I am going to answer this slightly differently without using resolve.root. Everything @dresyecat said is correct. However, I just went through the same exercise of moving from relative paths everywhere to module paths. Here is the doc that explains the three different types of paths you can use in the import statement.
You are asking to use a module path, which I believe is the preferred way to go.
The problem is that by default, module paths only work with things imported via npm because the new modules variable on resolve defaults to ["node_modules"]. This lets you import 3rd party code from npm really easily. But it means importing your code with a module path needs a config change. BTW, the modules used to be called moduleDirectories in previous versions. Here are the docs for the resolve variable configuration.
Ok assuming you have a directory structure like this:
project/
webpack.config.json
js/
components
actions
You can set the modules directory to be:
resolve: {
extensions: [ '.ts', '.js', '*' ],
modules: [ path.resolve(__dirname, "js"), "node_modules"]
}
A couple important points:
Be sure to import the path component in your configuration so that path is defined
var path = require('path');
Then you can use the following (as was pointed out - without the leading /) to import your components using the module path form:
import "actions/fooAction";
Upvotes: 16
Reputation: 10376
The resolving process is basically simple and distinguishes between three variants:
absolute path: require("/home/me/file")
relative path: require("../src/file") or require("./file")
module path: require("module/lib/file")
Absolute to your filesystem indeed
Relative to the current file (if that file is in src/foo/bar
or webpack/config/subconfig
, then indeed that's it...)
In contrast to import
(which handles 1+2 pretty much the same way, but would send you looking in node_modules
right away) path 'module' indeed means your project root for paths without a need to resolve, like output.path
in your webpack config... and: (on resolving) Only 3 is subject to resolve.root
and resolve.moduleDirectories
resolving, see webpack docs here
Upvotes: 4
Reputation: 13798
The resolve.root
option does not modifiy how file modules are resolved.
A required module prefixed with '/' is an absolute path to the file. For example, require('/home/marco/foo.js') will load the file at /home/marco/foo.js.
The /
resolves to the root of your file system.
Maybe what you want is to resolve your js
folder as a modules directory.
webpack.config.js
resolve: {
root: path.resolve('./js')
}
With this configuration added to your config file will tell webpack to resolve any import
or require
relative to your js
folder. Then, instead of using
import foo from '../actions/fooAction'
you will be able to:
import foo from 'actions/fooAction`
Mind the lack of /
at the beginning.
Upvotes: 52