PranavPinarayi
PranavPinarayi

Reputation: 3207

eslint error showing with webpack alias

In my webpack config. I defined aliases

alias: {
            components: 'src/components/',
            config: 'src/config/'
}

When I import a module from this path an eslint error occurred.

import ShadowWrapper from 'components/ShadowWrapper'

error 'components' should be listed in the project's dependencies. Run 'npm i -S components' to add it import/no-extraneous-dependencies

Upvotes: 17

Views: 24946

Answers (5)

KarljoY973
KarljoY973

Reputation: 11

Personally I had to use multiple ways to tell my project I needed my aliases, I had to use the package.json way with __moduleAliases, like so

"_moduleAliases": {
"@root": ".",
"@sApi": "./Server/api",
"@sApp": "./Server/app",
"@sCtrl": "./Server/controller",
"@sData": "./Server/data",
"@sDoc": "./Server/doc",
"@sError": "./Server/error",
"@sLog": "./Server/log",
"@sLog-w":"./Server/log/winston",
"@sMid-dto": "./Server/middleware/dto",
"@sMid-jSche": "./Server/middleware/schema",
"@sMid-utils": "./Server/middleware/utils"

}

I had to use createAliasSettings with path like so :

...createAliasSetting({
  '@sApi': path.resolve(__dirname, './Server/api'),
  '@sApp': path.resolve(__dirname, './Server/app'),
  '@sCtrl': path.resolve(__dirname, './Server/controller'),
  '@sData': path.resolve(__dirname, './Server/data'),
  '@sDoc': path.resolve(__dirname, './Server/doc'),
  '@sError': path.resolve(__dirname, './Server/error'),
  '@sLog': path.resolve(__dirname, './Server/log'),
  '@sLog-w': path.resolve(__dirname, './Server/log/winston'),
  '@sMid-dto': path.resolve(__dirname, './Server/middleware/dto'),
  '@sMid-jSche': path.resolve(__dirname, './Server/middleware/schema'),
  '@sMid-utils': path.resolve(__dirname, './Server/middleware/utils'),
}),

and the eslint-import-resolver-alias like so :

'import/resolver': {
  alias: {
    map: [
      ['@sApi', './Server/api'],
      ['@sApp', './Server/app'],
      ['@sCtrl', './Server/controller'],
      ['@sData', './Server/data'],
      ['@sDoc', './Server/doc'],
      ['@sError', './Server/error'],
      ['@sLog', './Server/log'],
      ['@sLog-w', './Server/log/winston'],
      ['@sMid-dto', './Server/middleware/dto'],
      ['@sMid-jSche', './Server/middleware/schema'],
      ['@sMid-utils', './Server/middleware/utils'],
    ],
    extentions: ['.js', '.json'],
  },
},

if I omit one of the 3 ways it does not work I dont know why but it works like this. I'm using es5 syntax and it works fine, the only thing that does not work is, lets say i'm in /a.js and I do const b = require('@b/index') it won't bring me to the index file in the folder that is linked to the b-alias but I guess it is ok, if you think I could do better with my config, let me know :)

Upvotes: 0

Belyash
Belyash

Reputation: 792

Another way, without mapping aliases between webpack.config.js and .eslintrc.

You can use eslint-import-resolver-webpack and setup you .eslintrc file like this:

{
  "extends": [
    "plugin:import/recommended"
  ],
  "settings": {
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"],
        "moduleDirectory": [
          "node_modules",
          "src"
        ]
      }
    }
  }
}

Upvotes: 0

Abhisek Pandey
Abhisek Pandey

Reputation: 174

Here is what worked for me:

  1. I installed eslint-import-resolver-alias as dev dependency:

    npm install eslint-plugin-import eslint-import-resolver-alias --save-dev

  2. In the Webpack config (in my case, it was Vue config, which is merged with Webpack config by Vue-cli), I added a few aliases:

     resolve: {
         extensions: ['.js', '.vue', '.json', '.less'],
         alias: {
             Site: path.resolve(__dirname, 'src/site'),
             Admin: path.resolve(__dirname, 'src/admin'),
             Common: path.resolve(__dirname, 'src/common'),
             Assets: path.resolve(__dirname, 'src/common/assets'),
             Configs: path.resolve(__dirname, 'src/common/configs'),
             Style: path.resolve(__dirname, 'src/common/style')
         }
     }
    
  3. In the .eslintsrc (or .eslintsrc.js, if you use that), I added the plugin and maps for these aliases, as follows:

    "extends": ["plugin:import/recommended"],
    "settings": {
         "import/resolver": {
             "alias": {
                 "map": [
                     ["Site", "./src/site"],
                     ["Admin", "./src/admin"],
                     ["Common", "./src/common"],
                     ["Assets", "./src/common/assets"],
                     ["Configs", "./src/common/configs"],
                     ["Style", "./src/common/style"]
                 ]
             },
             "extensions": [".js", ".less", ".json", ".vue"]
         }
    }
    

I have added extensions for clarity and some good measures, which you can choose to not use for yourself.

Optional:

If you use VS Code and want these aliases working with the path intellisense, add a file jsconfig.json at the root, and specify your alias paths:

{
    "compilerOptions": {
        "target": "esnext",
        "allowSyntheticDefaultImports": false,
        "baseUrl": "./",
        "paths": {
            "~/*": ["src/*"],
            "Root/*": ["src/*"],
            "Site/*": ["src/site/*"],
            "Admin/*": ["src/admin/*"],
            "Common/*": ["src/common/*"],
            "Assets/*": ["src/common/assets/*"],
            "Configs/*": ["src/common/configs/*"],
            "Style/*": ["src/common/style/*"]
        }
    },
    "exclude": ["node_modules", "dist"]
}

There are additional settings for React and Typescript. Check the documentation at official site.

Upvotes: 12

Przemek Nowicki
Przemek Nowicki

Reputation: 635

Thanks, Pranav for the solution to this issue!
I add some code to this post to make it more practical for others.
First of all, in webpack config file I had defined this alias:

alias:{
  components: path.resolve(__dirname, "src", "components")
}

That allow me to import components in my app in that way:

import NewsFeed from 'components/NewsFeed'

I have installed eslint-import-resolver-webpack plugin and put below code into .eslintrc.js or .eslintrc file :

settings: {
    'import/resolver': {
      alias: {
        map: [
          ['components', './src/components']
        ]
      }
    }

That's it after running linter I got rid of Unable to resolve path to module 'components/NewsFeed' error message
Hope it will be helpful for some of you!

Upvotes: 18

PranavPinarayi
PranavPinarayi

Reputation: 3207

This issue can be resolved by using the eslint-import-resolver-webpack

Upvotes: 6

Related Questions