Giter VIP home page Giter VIP logo

eslint-import-resolver-alias's Introduction

eslint-import-resolver-alias

Version npm Version node Build Status Download Dependencies peerDependencies Coverage Status Known Vulnerabilities License

This is a simple Node.js module import resolution plugin for eslint-plugin-import, which supports native Node.js module resolution, module alias/mapping and custom file extensions.

Installation

Prerequisites: Node.js >=4.x and corresponding version of npm.

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

Usage

Pass this resolver and its parameters to eslint-plugin-import using your eslint config file, .eslintrc or .eslintrc.js.

// .eslintrc.js
module.exports = {
  settings: {
    'import/resolver': {
      alias: {
        map: [
          ['babel-polyfill', 'babel-polyfill/dist/polyfill.min.js'],
          ['helper', './utils/helper'],
          ['material-ui/DatePicker', '../custom/DatePicker'],
          ['material-ui', 'material-ui-ie10']
        ],
        extensions: ['.ts', '.js', '.jsx', '.json']
      }
    }
  }
};

Note:

  • The alias config object contains two properties, map and extensions, both of which are array types
  • The item of map array is also array type which contains 2 string
    • The first string represents the alias of module name or path
    • The second string represents the actual module name or path
  • The map item ['helper', './utils/helper'] means that the modules which match helper or helper/* will be resolved to ./utils/helper or ./utils/helper/* which are located relative to the process current working directory (almost the project root directory). If you just want to resolve helper to ./utils/helper, use ['^helper$', './utils/helper'] instead. See issue #3
  • The order of 'material-ui/DatePicker' and 'material-ui' cannot be reversed, otherwise the alias rule 'material-ui/DatePicker' does not work
  • The default value of extensions property is ['.js', '.json', '.node'] if it is assigned to an empty array or not specified

If the extensions property is not specified, the config object can be simplified to the map array.

// .eslintrc.js
module.exports = {
  settings: {
    'import/resolver': {
      alias: [
        ['babel-polyfill', 'babel-polyfill/dist/polyfill.min.js'],
        ['helper', './utils/helper'],
        ['material-ui/DatePicker', '../custom/DatePicker'],
        ['material-ui', 'material-ui-ie10']
      ]
    }
  }
};

When the config is not a valid object (such as true), the resolver falls back to native Node.js module resolution.

// .eslintrc.js
module.exports = {
  settings: {
    'import/resolver': {
      alias: true
    }
  }
};

CHANGELOG

CHANGELOG

References

  • eslint-plugin-import/no-extraneous-dependencies
  • eslint-plugin-import/no-unresolved
  • eslint-module-utils/resolve
  • resolve
  • eslint-import-resolver-node

eslint-import-resolver-alias's People

Contributors

johvin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

eslint-import-resolver-alias's Issues

resolve root path problem

recently, I myself find a bug about inner function resolveLookupPaths that the resolved lookup paths array includes '//node_modules' which should be '/node_modules'

Support for reading mapping from tsconfig.json

Greetings,

I have a setup of ESLint + Node + TS and VS Code for a server-side project. In order to get my path aliases working in ESLint plugin of VS Code, I decided to use this package. I spent 4 hours today and finally got it to work after debugging this code!

The problem was that my project was in a subfolder of the WorkingDirectory, so the process.cwd() in https://github.com/johvin/eslint-import-resolver-alias/blob/master/index.js#L70-L71 was returning / and couldn't resolve the path to the referred module. I found that I needed to use changeProcessDirectory in the ESLint settings of VS Code in settings.json for my subfolder WorkingDirectroy. (As shown in microsoft/vscode-eslint#196 (comment))

With this history, the biggest problem I have right now is every time I want to define a new module path-mapping (alias), I need to change 3 different places individually! that is:

  1. tsconfig.json,
  2. .eslintrc.js (for this alias resolver),
  3. and finally a manual module-alias because tsc doesn't resolve the mapping when it emits the JS codes. (Filed at microsoft/TypeScript#26722 (comment))

Suggestion

In order to reduce the number of places I need to change upon adding a new mapping, I was thinking that maybe this resolver can take a parameter to read the mapping from tsconfig.json.

To start, it can take a pathToTSConfig and pathPrefix (e.g. @ or ~ to make it easier to identify the custom paths) and extract the mapping from there. That way, the source of truth will live in one less place.

I don't know if you guys think it's a good addition to this NPM package. If so, I can start working on a PR. Otherwise, I think the best I should do is to fork this resolver and create a new one, simply to support reading from tsconfig.json.

Please advise.

Thanks!

Next.js resolve alias with root/wildcard path?

I'm using Next.js and trying to setup aliases in my eslint.

My folder structure is:

/components/Cart.js
/pages/Home.js
/utils/addToCart.js
etc.

and I import them like:
import addToCart from '@/utils/addToCart'

Currently I have my eslint import resolver setup like this:

"settings": {
  "import/resolver": {
    "alias": [
        ["@/components", "./components"],
        ["@/utils", "./utils"],
        ["@/pages", "./pages"]
    ]
  }
}

This works great, but I'd like to not have to create each alias individually. Instead, I'd prefer to set up a sort of root alias or wildcard alias like this:

["@/*", "./*"]
or ["@/$", "./$"]
or ["@/", "./"]
etc.

But everything I've tried has broken the imports and given me the "Unable to resolve path to module" error. Is there a correct way to handle this?

Custom file extensions

I'm using eslint-import-resolver-alias along with eslint-import-resolver-typescript.

I have the following alias:
["@dpStores", path.resolve(__dirname, './src/stores')]

But have the following eslint error when I try to import a types.tsx file without specifying the extension:
image

If I specify the extension it works just fine.
Importing files without an extension works fine when not using an alias.

This is my resolver settings in .eslintrc:
"settings": { "import/resolver": { "node": true, "eslint-import-resolver-typescript": true, "alias": [ ["@dpStores", path.resolve(__dirname, './src/stores')] ] } }

Support for link-module-alias

I installed the link-module-alias and used eslint-import-resolver-alias to resolve the linting conflict but I encountered the import/no-extraneous-dependencies error when I ran the lint. This error occurred despite the plugin.

This is my .eslintrc.js file

settings: {
		'import/resolver': {
			alias: [  [ '@components', 'src/components' ], [ '@navigation', 'src/navigation' ] ]
		}
	}

This is what I have added in package.json

	"scripts": {
		"postinstall": "link-module-alias",
		"preinstall": "command -v link-module-alias && link-module-alias clean || true"
	},
	"_moduleAliases": {
		"@components": "src/components",
		"@navigation": "src/navigation"
	}

Check alias in array of paths

Is ist possible to have alias check for array of paths?

Example:

export default {
	// ...
	alias: {
		map: ['foo', ['./first-path-to-check', './second-path-to-check']]
	}
};

Alias Not Working with Serverless Framework Project

I am attempting to get a serverless framework project setup with es6 import/export support. I am able to get it to work with the serverless-webpack however there is an eslint-plugin-node rule that I can't seem to fix with this plugin.

error  "~/utils/logging" is not found  node/no-missing-import

This is my eslint configuration:

{
  "parser": "@babel/eslint-parser",
  "parserOptions": {
    "sourceType": "module"
  },
  "extends": [
    "eslint:recommended",
    "plugin:node/recommended",
    "plugin:jest/recommended",
    "prettier"
  ],
  "plugins": ["prettier"],
  "settings": {
    "import/resolver": {
      "alias": {
        "map": [["~", "./src"]],
        "extensions": [".js", ".json"]
      }
    }
  },
  "rules": {
    "prettier/prettier": "error",
    "node/no-unsupported-features/es-syntax": [
      "error",
      {
        "version": ">=12.10.0",
        "ignores": ["modules"]
      }
    ]
  }
}

For now, I will disable the rule but I wonder if this is expected to work when working with Node.js files.

Hi

冒昧打扰,我是阿里前端工程师,方便交换联系方式吗?手机:13162473297

Feature: Allow failing of linting if an alias isn't used

Setting up aliases are great, but they can just be ignored and use the normal relative path. For consistency it would be nice to have the ability to throw a eslint warning/error if an alias isnt used, or a path where one exists.

Example, with config

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

would throw a warning/error as you didnt do

import Button from 'components/Button

Next.js app with absolute path - getting eslint "Unable to resolve path to module" error

Hello,
I'm wondering what I've done wrong because in a really simple use case i'm still getting the "Unable to resolve path to module" error. Here is my configuration:
"eslint-plugin-import": "^2.23.3",
"eslint-import-resolver-alias": "^1.1.2",

My folders:
project/src/components
project/src/styles
project/src/utils

project/jsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": [
        "src/components/*"
      ],
      "@utils/*": [
        "src/utils/*"
      ],
      "@styles/*": [
        "src/styles/*"
      ]
    }
  }
}

project/.eslintrc.js

settings: {
  'import/resolver': {
    alias: [
      ['@components', './src/components'],
      ['@styles', './src/styles'],
      ['@utils', './src/utils'],
    ],
  },
},

I'm using the import like this import Layout from '@components/Layout';
The Next.js compilation is working great but eslint doesn't seems to use import/resolver settings. Any ideas?
Thanks.

peerDependency of eslint

It doesn't appear to be mentioned anywhere which version of eslint this is compatible with. This should be added as a peer dependency to ensure users have the correct version installed.

I'd recommend making this a bit flexible e.g.

"eslint": ">=3.x.x"

Characters in aliases interpreted as regex

Thank you for the project!

We're using module-alias in our project to prevent import hell. According to this issue they are recommending a $ prefix to aliases in order to avoid the @ that is being used as a namespace among npm packages.

It looks like your plugin will interpret $ as regex, which means if I had an alias for $src defined, I would need to write in my eslint alias settings:

'\\$src', './src'

I'm not sure the ideal solution from a project perspective, but it would be great to be able to use $ (or other regex characters) in my aliases.

Note: in our case we are addressing this by changing $src to %src but ideally we wouldn't have to.

Throw errors when resolving packages whose "main" is set to a folder (i.e enzyme)

When using eslint-import-resolver-alias with enzyme, it throws an error.

// item.test.tsx
import { shallow } from 'enzyme';
// .eslint.json
"settings": {
  "import/resolver": {
    "alias": {
      "map": [["src", "./src"]],
      "extensions": [".ts", ".tsx"]
    }
  }
}
1:1  error  Resolve error: Cannot find module '/Users/zeroliu/Developer/Advanced-React/sick-fits/frontend/node_modules/enzyme/build'. Please verify that the package.json has a valid "main" entry
    at tryPackage (internal/modules/cjs/loader.js:323:19)
    at Function.Module._findPath (internal/modules/cjs/loader.js:680:18)
    at findModulePath (/Users/zeroliu/Developer/Advanced-React/sick-fits/frontend/node_modules/eslint-import-resolver-alias/index.js:100:27)

It works for other packages. The error goes away if I stop importing enzyme or remove eslint-import-resolver-alias from my pipeline. Looking at enzyme package.json, its "main" property is set to "build" folder, which is different from most NPM packages that use a js file as entry. According to the call stack, I believe the problem is caused by calling the private __findPath method directly.

const filename = Module._findPath(request, paths);

I'm not quite familiar with the internal implementation of node module. Please help.

For now, there are these workarounds:

  1. map enzyme to a random path.
"map": [["src", "./src"], ["enzyme", "foo"]]
  1. update enzyme package.json main to "build/index.js"

Option 1 is probably better since we don't want to touch third party packages.

Can not resolve `index.js` under aliased folders?

Eslint complains about index.js under aliased folders import/no-unresolved.

For exp, I have folder utils under the path @, it contains a lot of files and index.js to export everything.

import { foo, bar } from '@/utils'; // eslint: `import/no-unresolved`
import { foo, bar } from '@/utils/index'; // adding `index` would work

Anything else like

import store from './store';

which is a folder and contains index.js works fine.

Also my webpack works fine with same settings:

// webpack settings
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': path.resolve(__dirname, './packs'),
    },
  },

My .eslintrc.js

const path = require('path');

module.exports = {
  root: true,
  parserOptions: {
    parser: 'babel-eslint'
  },
  env: {
    browser: true,
  },
  extends: ['plugin:vue/essential', 'airbnb-base', 'plugin:lodash/recommended'],
  plugins: [
    'vue',
    'lodash',
    'lodash-fp',
  ],
  settings: {
    'import/resolver': {
      alias: {
        extensions: ['.js', '.vue', '.json'],
        map: [
          ['@', path.resolve(__dirname, './packs')],
        ],
      },
    },
  },
  rules: {
    'import/extensions': ['error', 'always', {
      js: 'never',
      vue: 'never'
    }],
    'no-param-reassign': ['error', {
      props: true,
      ignorePropertyModificationsFor: [
        'state', // for vuex state
        'acc', // for reduce accumulators
        'e' // for e.returnvalue
      ]
    }],
    'import/no-extraneous-dependencies': ['error', {
      optionalDependencies: ['test/unit/index.js']
    }],
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  }
}

Dependencies in package.json about eslint

    "babel-eslint": "^8.2.3",
    "eslint": "^4.19.1",
    "eslint-config-airbnb-base": "^12.1.0",
    "eslint-friendly-formatter": "^4.0.1",
    "eslint-import-resolver-alias": "^1.1.0",
    "eslint-loader": "^2.0.0",
    "eslint-plugin-import": "^2.11.0",
    "eslint-plugin-lodash": "^2.7.0",
    "eslint-plugin-lodash-fp": "^2.1.3",
    "eslint-plugin-vue": "^4.5.0",

yarn list --depth 0 | grep eslint

Is it posible to automatically resolve modules from aliased directory?

Suppose I have module alias in package.json:

"_moduleAliases": {
    "@modules": "modules"
  }

why should I have not only alias for modules directory in this plugin's settings, but for each of its children modules (js files)?

"settings": {
    "import/resolver": {
      "alias": {
        "map": [
          ["modules", "./modules"],
          // aliases, I wish to get rid of
          ["@modules/balance-manager", "./modules/balance-manager"],
          ["@modules/coin-finances", "./modules/coin-finances"],
          ["@modules/config", "./modules/config"],
          ["@modules/rub-finances", "./modules/rub-finances"]
        ],
        "extensions": [".ts", ".js", ".jsx", ".json"]
      }
    }
  }

Question

Hi, thanks for the plugin!

I wanted to know if the plugin accepts something like this?

module.exports = {
  "settings": {
    "import/resolver": {
      "alias": [
        ["apis/*", "./app/apis/*"],
        ["constants/*", "./app/constants/*"],
        ["state/*", "./app/state/*"],
        ["utilities/*", "./app/utilities/*"],
      ]
    }
  }
}

If yes, do you know why I'm having trouble with that configuration? If no, think this could be an enhancement?

Thanks again!

Question about subfolders

Hi,
I have a folder structure like:

src/helpers/
src/abcd/helpers/

If i have an alias "helpers" for src/helpers then the resolver tries to resolve src/abcs/helpers to that alias too and then eslint throws import/no-unresolved.

Wanted to know if i am doing something wrong or if this is not supported.

Thanks

Seems broken be working with [email protected]

eslint-import-resolver-alias works fine with eslint-plugin-import 2.18.2, after update to the latest 2.20.1, all of the aliases won't find anymore.

The eslintrc is - https://github.com/Tencent/Hippy/blob/master/.eslintrc.js#L82

Hippy on  chore/update-dependencies [$!] via ⬢ v12.16.1 took 2s 
➜ npm ls eslint-plugin-import eslint-import-resolver-alias
hippy@ /Users/xqkuang/Projects/github/Hippy
├── [email protected] 
└── [email protected] 


Hippy on  chore/update-dependencies [$!] via ⬢ v12.16.1 took 2s 
➜ npm run lint

> hippy@ lint /Users/xqkuang/Projects/github/Hippy
> eslint "packages/**/*.@(js|ts|tsx)" "examples/hippy-react-demo/**/*.@(js|jsx)"


/Users/xqkuang/Projects/github/Hippy/packages/hippy-vue/src/elements/index.js
  1:1  error  'shared' should be listed in the project's dependencies. Run 'npm i -S shared' to add it  import/no-extraneous-dependencies

/Users/xqkuang/Projects/github/Hippy/packages/hippy-vue/src/renderer/native/event/emitter.js
  5:1  error  'shared' should be listed in the project's dependencies. Run 'npm i -S shared' to add it  import/no-extraneous-dependencies

/Users/xqkuang/Projects/github/Hippy/packages/hippy-vue/src/runtime/index.js
   5:1  error  'core' should be listed in the project's dependencies. Run 'npm i -S core' to add it      import/no-extraneous-dependencies
   6:1  error  'core' should be listed in the project's dependencies. Run 'npm i -S core' to add it      import/no-extraneous-dependencies
   7:1  error  'shared' should be listed in the project's dependencies. Run 'npm i -S shared' to add it  import/no-extraneous-dependencies
   8:1  error  'core' should be listed in the project's dependencies. Run 'npm i -S core' to add it      import/no-extraneous-dependencies
   9:1  error  'web' should be listed in the project's dependencies. Run 'npm i -S web' to add it        import/no-extraneous-dependencies
  10:1  error  'core' should be listed in the project's dependencies. Run 'npm i -S core' to add it      import/no-extraneous-dependencies
  16:1  error  'shared' should be listed in the project's dependencies. Run 'npm i -S shared' to add it  import/no-extraneous-dependencies
....

Setting root path?

Is there a way in the configuration to set a root path? ie. id love to be able to supply alias relative to the root path rather than the file path

Unexpected use of file extensions

I'm working with a project written entirely in TS. This project imports code from node_modules, which for the most part is in plain JS. Despite everything in node_modules being in JS, the plugin works as expected when defining the extensions array as [.ts, .tsx].

However -- There is one package I'm importing which contains another "sub-package": it has a folder with a package.json with a main field. To be clear, this "sub-package" is not in the package's node_modules, it is just in a regular directory in the package,

# contents of package inside root node_modules
node_modules/ # the package's own packages
package.json
index.js
some-folder/
  package.json # with "main": "lib"
  lib/
    index.js

Under these circumstances, if the extensions array does not contain .js, importing from package/some-folder with throw an error. Is this a bug? Was under the impression that the extensions array should not have an effect when the fully resolved path lives inside node_modules.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.