Resolving Require Paths with Webpack

Resolving require paths with webpack

Webpack >2.0

See wtk's answer.

Webpack 1.0

A more straightforward way to do this would be to use resolve.root.

http://webpack.github.io/docs/configuration.html#resolve-root

resolve.root

The directory (absolute path) that contains your modules. May also be an array of directories. This setting should be used to add individual directories to the search path.

In your case:

webpack config

var path = require('path');

// ...

resolve: {
root: path.resolve('./mydir'),
extensions: ['', '.js']
}

consuming module

require('myfile')

or

require('myfile.js')

see also: http://webpack.github.io/docs/configuration.html#resolve-modulesdirectories

Why webpack config has to use path.resolve & path.join

This has nothing to do with webpack, only with the way Node.js handles paths. Paths are not resolved relative to the file path, but relative to the working directory by default. Say we have the following directory structure:

project
├── a
| └── 1.js
└── b
└── 2.txt

with 1.js containing the following:

const filePath = '../b/2.txt';
const content = require('fs').readFileSync(filePath);
console.log(content.toString());

then, if we run

cd a
node 1.js

everything works fine.

But if, instead we execute from the toplevel directory, the following:

node a/1.js

we get an error:

Error: ENOENT: no such file or directory, open 'C:\Users\baryl\Desktop\b\2.txt'

because the path is now resolved relative to project instead of project/a. path.resolve solves that.

const path = require('path');
const filePath = path.resolve(__dirname, '../b/2.txt');
const content = require('fs').readFileSync(filePath);
console.log(content.toString());

now we can safely execute node a/1.js from the project directory, and it will work as expected.

Webpack can't resolve relative path import express static

You're using an absolute path

import getGraphAccessToken from "/javascripts/ssoAuthES6.js";
// ^ this will look in your topmost directory on your OS

The relative path, from commands.js, would be:

import getGraphAccessToken from "../../javascripts/ssoAuthES6.js";

Alternatively, you can set Webpack to look for modules from your root directory by adding the following to your webpack configuration:

{
// ...
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
},
// ...
}

Then you can import from your project's root directory from anywhere, like so:

import getGraphAccessToken from "javascripts/ssoAuthES6.js";

Some other points:

  • Since you're setting the extensions: [".ts", ".tsx", ".html", ".js"], you don't need to provide file extensions for those imports
  • You specify .ts and .tsx in your webpack config, but you are using .js files. Consider removing the Typescript extensions
  • If you are using Typescript, you will need to update import paths in your tsconfig.json
  • You can consider import path aliases in both Webpack and Typescript to be more explicit that your imports are coming from your project root. Instructions here

Make absolute paths relative to the project root in Webpack

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.



Related Topics



Leave a reply



Submit