webpack: resolve.alias not works

Do you want to request a feature or report a bug? Bug

What is the current behavior? Resolve.alias not works as mentioned in https://webpack.js.org/configuration/resolve/#resolve-alias

/* ./webpack/base.js */
  ...
  resolve: {
    extensions: [ '.js', '.json', '.css' ],
    modules: [
      config.compile.entry,
      'node_modules'
    ],
    alias: {
      Actions: config.compile.entry + '/actions/'
    }
  }
  ...

If the current behavior is a bug, please provide the steps to reproduce.

1- git clone https://github.com/raminious/react-universal-boilerplate
2- cd react-universal-boilerplate
3- git checkout webpack-alias
4- yarn (or npm install)
5- npm run dev

What is the expected behavior? import { types } from 'Actions/app' should work but getting this error: Error: Cannot find module 'Actions/app'

Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System.

Node version: v6.6.0 Webpack version: 2.2.1 OS: OSX El Capitan

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 117
  • Comments: 100 (4 by maintainers)

Commits related to this issue

Most upvoted comments

I am having the same issue. resolve.alias seems to be doing absolutely nothing

Not a single solution worked from this discussion for @React

Aliases are absolute nonsense for resolving imports. If you don’t want to type ../ consider using something like path.resolve(__dirname, '../src') so you can do

import Stuff from 'client/components/stuff'; // relative to root of project

instead of:

import Stuff from 'COMPONENTS/stuff'; // this is dumb

or:

import Stuff from './../stuff; // once upon a time highly paid web devs didn't complain about relative paths now they do

I resolved the issue by using path.join, instead of path.resolve

alias: {
    Ui: path.join(__dirname, '/resources/assets/js/ui/'),
}

and usage

import RadioButton from 'Ui/RadioButton.js'

Same here! I was kicking tires with a simple sample using 2.2.1 and I’m facing the same issue.

same

This happens to me with Webpack 3

Same issue here. Node version: v6.10.1 Webpack version: 2.2.1 OS: OSX El Capitan

resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
    '@': resolve('src')
  }
},
import App from '@/App.vue'

ERROR in ./src/js/dashboard.js Module not found: Error: Can’t resolve ‘@/App.vue’

I’ve given up on this for now and just started using babel-plugin-module-resolver because I’m already using babel anyway. That allows me to create the same type of aliases through a babel transform.

This happens for me:

  1. set up the alias: OurComponents: path.resolve(__dirname, '../app/components/index.js'),
  2. use it in one file like import {App} from 'OurComponents';
  3. start webpack (dev server)

Works fine 🥇

  1. Add it to another file, like import {Hamburger} from 'OurComponents';
  2. Refresh the page

Works fine

  1. Restart webpack (not making any change to the code)

I get Error: Cannot find module 'OurComponents'

So for me at least it seems to be something when it’s used in more than one file and when webpack is first starting causing this error, that isn’t happening when webpack is re-compiling or when it’s only used in one file.

The full thing:

Error: Cannot find module 'OurComponents'
    at Function.Module._resolveFilename (module.js:472:15)
    at Function.Module._load (module.js:420:25)
    at Module.require (module.js:500:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:/web/davidg-site/app/components/App/App.jsx:12:1)
    at Module._compile (module.js:573:32)
    at loader (C:\web\davidg-site\node_modules\babel-register\lib\node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .jsx] (C:\web\davidg-site\node_modules\babel-register\lib\node.js:154:7)
    at Module.load (module.js:490:32)
    at tryModuleLoad (module.js:449:12)

I set resolve.alias = path.resolve(__dirname, './src/styles/') and when I use import "styles/common.css" it failed, getiing error : Cannot find module 'styles/common.css'

but when i use require('styles/common.css') it just worked what happened?

my issue turned up, that I was wrongly using path.resolve(__dirname, "app/some/path")

correct is path.resolve(__dirname, "app", "some", "path") and that works…

quite a lot comments on this issue xD

I’m still getting this issue in version 4.29.6.

I am doing this successfully in a new project, and it seems to be working well. What I am doing is:

base-ui/client/package.json

"devDependencies": {
    ...
    "webpack": "^2.2.0"
}

webpack.dev.config.js

resolve: {
            modules: [path.resolve('./node_modules')],
            alias: {
                Common: path.resolve(__dirname, '../../../../base-ui/client')
            },
            extensions: ['.js', '.jsx', '.json', '.scss']
        },

We have different applications that use the components inside “base-ui” and these applications live in the same parent directory as base-ui.

base-ui/client/components/index.js

export { default as Button } from './button/Button';
export { default as SingleInput } from './singleInput/SingleInput';

base-ui/client/components/button/Button.jsx

...
export default Button

In these applications we can do things like:

account-ui/client/page/ForgotPassword.jsx

import { Button, SingleInput } from 'Common/components';

This method seems to be working across the board. It has it’s challenges when it comes to Jest testing and using things like wallabyjs which I am still figuring out, but as for webpack and resolve.alias it is working great.

I hope this helps.

+1 same error

Aliases are absolute nonsense for resolving imports. If you don’t want to type ../ consider using something like path.resolve(__dirname, '../src') so you can do

import Stuff from 'client/components/stuff'; // relative to root of project

instead of:

import Stuff from 'COMPONENTS/stuff'; // this is dumb

or:

import Stuff from './../stuff; // once upon a time highly paid web devs didn't complain about relative paths now they do

This is not dumb at all. It is exceedingly common to use aliases. It’s not about being lazy, it’s about writing portable code.

Saying that web devs used to be fine with relative imports is like saying that human beings used to be fine living without refrigerators. Sure we did. But was it better than it is now? No. No, it wasn’t.

Adding @ in front of the alias name solve the issue

Why? Where is this documented?

don’t use eslint-loader and everything will be ok

I recently stumbled onto a solution that works for me. If you’re using Typescript 2.0+ (which you should be) and awesome-typescript-loader (which you should be) you can obviate the need for resolve.alias by using the tsconfig parameters baseUrl and paths inside of the top-level compilerOptions parameter. It’s great because it works regardless of how you manage your modules and if you’re using a linter (which you should be) will automatically be understood. Here’s an example from my code:

"compilerOptions": {
  ...
  "baseUrl": ".",
  "paths": {
    "@Client/*": ["client/*"],
    "@Components/*": ["client/src/components/*"],
    "@Containers/*": ["client/src/containers/*"],
    "@Repository/*": ["server/src/repository/*"],
    "@Server/*": ["server/*"],
    "@Shared/*": ["shared/*"]
  }
  ...
}

To allow webpack to access these aliases, add the following require and also add the following plugins configuration to your webpack config’s resolve:

const { TsConfigPathsPlugin } = require('awesome-typescript-loader');
resolve: {
  ...
  plugins: [
    new TsConfigPathsPlugin(/* { tsconfig, compiler } */)
  ],
  ...
},

Now, when you want to import something from the {projectDir}/shared directory you can reference it like this: import { MyType, MyInterface } from "@Shared/types";

🎉

Had an alias issue with tsx files, turns out that path.resolve was indeed the fix on my end

what used to be

'#': './src/'

is now

'#': path.resolve('src/')

In my case, I don’t get any errors, but the exact same import in two different files produces different values:

// file 1:
import { StatusBar } from 'Components' // works great!

// file 2:
import { StatusBar } from 'Components' // undefined :(

Also, just as a friendly reminder, if you’re using Babel, make sure you deactivate modules,

{
  "presets": [["env", {"modules": false}], "react"],
}

Given the following folder structure: ~/src/components/Button.js

Storybook Webpack config ~/.storybook/webpack.config.js

module.exports = {
  resolve: {
    alias: {
      '@components': path.resolve('src/components/')
    }
  }
};

Your component ~/src/components/Button.js

import React from 'react'

export default ({ children, ...rest }) => (
  <button {...rest}>{children}!!!</button>
)

Storybook stories ~/stories/index.stories.js

import React from 'react';

import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';

import Button from '@components/Button'

storiesOf('Button', module)
  .add('with text', () => <Button onClick={action('clicked')}>Hello Button</Button>)
  .add('with some emoji', () => (
    <Button onClick={action('clicked')}>
      <span role="img" aria-label="so cool">
        😀 😎 👍 💯
      </span>
    </Button>
  ));

It should work. 😎

Things to notice Exports/Imports import { Button } from '@components/Button' != import Button from '@components/Button'

@jarecsni By googling lots and lots of webpack errors without a useful error messages, I discovered the great flag “–display-error-details” which actually helps a lot. It displays a boatload of error details that actually help quite often. HTH.

A new decade has arrived - this still does not work. Latest Webpack4.

@imam According to node.js documentation;

Simply how resolve works;

path.resolve('/foo', '/bar') outputs /bar

If you want multiple directory segments, you should use it like;

path.resolve('/foo', './bar', './baz')

This will always result in absolute url, simply passing __dirname as first argument doesn’t matter in this case. Calling path.resolve() without any argument will give you __dirname.

According to my example, if i want to use path.resolve i need to use it like path.resolve('resources/assets/js/ui/'). It outputs __dirname/resources/assets/js/ui

How join works is simple, it brings all given arguments together and and gives you to path string;

path.join(__dirname, '/foo') outputs __dirname/foo

I had a similar issue with aliases not working. I fixed it by removing node_modules folder and installing packages again (running yarn).

I have not found a solution yet, but this occurs in all new Vue-CLI projects - works in my older ones…

This is (at least for me) down to the addition of using @types in my node modules, I guess Vue uses this now… but i’m in the middle of trying to solve this without pulling my hair out. It is interesting to know that @babel does not trip up the use of @ aliases within paths…

Thought it was one/two of my VS-Code extensions for intellisense paths, but that turned out to be a red herring.

Hello everyone

I had a problem with resolving files outside my project directory. It worked for some files and didn’t work for others like @aryzing mentioned above…

I just managed to solve this problem with a simple edit: putting a @ character in front of the alias…

Before it was config.resolve.alias['global'] = path.join(__dirname, '../_global')

Now it is config.resolve.alias['@global'] = path.join(__dirname, '../_global')

And it works…

One more note (for Vue.js users): If you are trying to use this alias from a template, then put a ~ character in front of the alias. For example

<img src="@global/static/icons/Footer_Mail.svg" class="contact-icon"/>

above doesn’t work whereas…

<img src="~@global/static/icons/Footer_Mail.svg" class="contact-icon"/>

…works fine

Hope this will help others

Thanks to @MartanLV I managed to fix my issue. In my case a stupid typo compounded the issue. To be honest, webpack could be better at emitting useful error messages. Saying that an alias cant be found is as useful as saying ‘something’s wrong’

Hello everybody,

Adding @ in front of the alias name solve the issue of resolving files outside my project directory for me as well.

'common': resolve('../common') was not working

'@common': resolve('../common') is working

Good luck!

After reading and trying most of the options here this worked from me: @tugayilik got it…

  Containers: path.resolve('src/containers/'),
  Components: path.resolve('src/components/'),

What worked here.

I fixed it by removing node_modules and run npm install

I am sorry @evilebottnawi just realized it was a problem on my side, please disregard.

I still have this problem when I have nested alias, for example:

 '@graphql-schema/order': path.resolve('src/graphql-schemas/order/'), // doesn't work
 '@graphql-schema': path.resolve('src/graphql-schemas/'), // works

I thought that the second line would be enough to resolve imports like import orderResolvers from '@graphql-schemas/order/resolvers'; but I get Module not found: Error: Can't resolve '@graphql-schemas/order/resolvers' in '/my-app/src/graphql'

😦

Also for me the issue was the “./”. After removing it from the path Webpack finally resolves the alias!! 🎉 (Actually I am using Encore but in the end it should be similar also for pure Webpack config)

let config = Encore.getWebpackConfig();
config.resolve.alias["~"] = path.resolve(__dirname, 'assets/js');
module.exports = config;

And then just like this:

import Header from '~/components/Header.vue'

More Info here: https://webpack.js.org/configuration/resolve/

Your problem might be that you have your webpack config in some nested folder, f.e.: project-name/configs/webpack/dev.js Then you would need something like this:

const srcDir = path.resolve(__dirname, '../../src'); // resolve project src directory

module.exports = {
	resolve: {
		alias: {
			'@components': path.join(srcDir, 'components'),
			'@modules': path.join(srcDir, 'modules'),
			'@store': path.join(srcDir, 'store')
		}
	}
       //...
}

This worked for me.

I can confirm that the problem is connected with using custom context in my case too

For me this issue was triggered when changing the Webpack context. By setting the Webpack context to the src dir, aliases DO NOT work:

// webpack.config.js:
module.exports = {
  context: path.resolve(__dirname, './src'),
  entry: {
    app: ['./index.js']
  }
  // ...
}

When using the root of the project as the Webpack context, aliases DO work:

// webpack.config.js:
module.exports = {
  context: path.resolve(__dirname, '.'),
  entry: {
    app: ['./src/index.js'],
  }
  // ...
}

@kemhwd Ok, seems this makes things more clear

If you want to add a directory to search in that takes precedences over node_modules/: modules: [path.resolve(__dirname, “src”), “node_modules”]

Having same issue. I ended up using resolve.modules config instead for the time being.

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

So instead of referencing import file by relative path, you can reference it from the project directory.

@sokra Any good news ?