31

I am trying to have a namespace for my app to work as a module, and import my components using this namespace and limit the use of relative path.

Although, even though I followed the webpack documentation for alias here: http://webpack.github.io/docs/configuration.html#resolve-alias I can't make it to work.

This is how my resolve object looks like:

resolve: {
  root: path.resolve(__dirname),
  alias: {
    myApp: './src',
  },
  extensions: ['', '.js', '.json', '.jsx']
}

path.resolve(__dirname) resolves /Users/Alex/Workspace/MyAppName/ui/

I import my file that way in the file /Users/Alex/Workspace/MyAppName/ui/src/components/Header/index.jsx:

import { myMethod } from 'myApp/utils/myUtils';

I get the following error during the build:

ERROR in ./src/components/Header/index.jsx
Module not found: Error: Cannot resolve module 'myApp/utils/myUtils' in /Users/Alex/Workspace/MyAppName/ui/src/components/Header
 @ ./src/components/Header/index.jsx 33:19-56

I also tried with modulesDirectories but it doesn't work either.

Do you have any idea what is wrong?

alexmngn
  • 9,107
  • 19
  • 70
  • 130

6 Answers6

26

Resolving the alias to the absolute path should do the trick:

resolve: {
  alias: {
    myApp: path.resolve(__dirname, 'src'),
  },
  extensions: ['', '.js', '.jsx']
}

Check this webpack resolve alias gist with a simple example.

Another solution to limit the number of relative paths is to add your ./src folder as root instead of aliasing it:

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

Then you will be able to require all folders inside ./src as if they where modules. For example, assuming you have the following directory structure:

.
├── node_modules
├── src
│   ├── components
│   └── utils

you would be able to import from components and utils like this:

import Header from 'components/Header';
import { myMethod } from 'utils/myUtils';

Something like having an alias for each folder inside ./src.

dreyescat
  • 13,558
  • 5
  • 50
  • 38
7

Most of the time it depends on your project folder structure. If your webpack file is inside a folder then make sure you handle it accordingly

.
├── node_modules
├── src
│   ├── components
│   └── config/webpack.config.js
modules.exports = {
 resolve: {
    extensions: ['.js', '.jsx'],
    alias: {
      Components: path.resolve(__dirname, '../src/components/'),
    }
  },
  ...
  resolve: {
    ...
  }
}

Also it often happens that we name our folder as "source" but use "src" in path.

Darn! that copy paste has taken alot of my debug time

Hope this helps someone who is facing such issues due to the above reasons.

Vinayak humberi
  • 191
  • 3
  • 8
  • 1
    this is a clear explanation! the alias config depends on where the webpack config is located in the folder structure. thanks for the `.../` – Nwawel A Iroume Feb 27 '22 at 06:35
6

This might be obvious to many but if you, like me, have spent too much time trying to figure out why it suddenly does not work when moving from Windows or Mac to Linux then check casing in the paths...

Me and everyone else on the project are using Windows or Mac but at home I dual boot ubuntu which I enjoy using. On cloning our code and running webpack i got a whole lot of Cannot resolve module... errors. I spent more time than I'd like to admit searching for some obscure error in node, npm, webpack or anything until I noticed the paths of the failing modules were something like @app/Shared/settings.js and the require was require('@app/shared/settings'). Windows doesn't care so everything was fine all until I started working on linux. As it turned out problem was not with webpack, node or anything else so that's probably why I didn't find anyone suggesting that this could be the problem.

Hope this saves some time for someone. Or maybe I'm just dumb, I don't know.

niknoe
  • 323
  • 5
  • 14
  • 4
    In short: some OSes/filesystems are case-sensitive so this issue is not due to `resolve.alias` but rather how files are looked up on the filesystem. – fregante Dec 09 '19 at 06:41
2

I got the same error. Finnaly I found the problem was that I wrote resolve twice. And the second resolve override the previous one. My code is like this:

modules.exports = {
 resolve: {
    extensions: ['.js', '.jsx'],
    alias: {
      Components: path.resolve(__dirname, 'src/components/'),
    }
  },
  ...
  resolve: {
    ...
  }
}

More help can be found in Webpack Doc

waltermitty
  • 453
  • 3
  • 12
0

I use without next syntax :

resolve: {
        alias: {
            Data:  __dirname + '/src/data'
        },
        extensions: ['.js', '.jsx', '.json']

    }

import points from 'Data/points.json';
zloctb
  • 10,592
  • 8
  • 70
  • 89
0

In my case, I wanted to alias mobx, so that any import of mobx would always return the same instance, regardless of whether the import call was from my main app, or from within one of the libraries it used.

At first I had this:

webpackConfig.resolve.alias = {
    mobx: path.resolve(root, "node_modules", "mobx"),
};

However, this only forced imports of mobx from my app's own code to use the alias.

To have it work for the library's import calls as well, I had to do:

webpackConfig.resolve.alias = {
    mobx: path.resolve(root, "node_modules", "mobx"),
    "LIBRARY_X/node_modules/mobx": path.resolve(root, "node_modules", "mobx"),
};

It's odd, because I'm pretty sure just having the mobx alias used to work for both contexts before, but now it apparently doesn't (Webpack v4.41.2).

Anyway, the above is how I solved it. (In my case, I needed it to prevent two mobx instances from being used as that breaks things, and LIBRARY_X was symlinked using npm-link, so I couldn't delete/unify the secondary mobx folder itself)

Venryx
  • 15,624
  • 10
  • 70
  • 96