no-restricted-imports
Disallow specified modules when loaded by import
Imports are an ES6/ES2015 standard for making the functionality of other modules available in your current module. In CommonJS this is implemented through the require() call which makes this ESLint rule roughly equivalent to its CommonJS counterpart no-restricted-modules.
Why would you want to restrict imports?
-
Some imports might not make sense in a particular environment. For example, Node.js’
fsmodule would not make sense in an environment that didn’t have a file system. -
Some modules provide similar or identical functionality, think
lodashandunderscore. Your project may have standardized on a module. You want to make sure that the other alternatives are not being used as this would unnecessarily bloat the project and provide a higher maintenance cost of two dependencies when one would suffice.
Rule Details
This rule allows you to specify imports that you don’t want to use in your application.
It applies to static imports only, not dynamic ones.
Options
This rule has both string and object options to specify the imported modules to restrict.
Using string option, you can specify the name of a module that you want to restrict from being imported as a value in the rule options array:
"no-restricted-imports": ["error", "import1", "import2"]
Examples of incorrect code for string option:
/*eslint no-restricted-imports: ["error", "fs"]*/
String options also restrict the module from being exported, as in this example:
/*eslint no-restricted-imports: ["error", "fs"]*/
/*eslint no-restricted-imports: ["error", "fs"]*/
Examples of correct code for string option:
/*eslint no-restricted-imports: ["error", "fs"]*/
import crypto from 'crypto';
export { foo } from "bar";
You may also specify a custom message for a particular module using the name and message properties inside an object, where the value of the name is the name of the module and message property contains the custom message. (The custom message is appended to the default error message from the rule.)
"no-restricted-imports": ["error", {
"name": "import-foo",
"message": "Please use import-bar instead."
}, {
"name": "import-baz",
"message": "Please use import-quux instead."
}]
Examples of incorrect code for string option:
/*eslint no-restricted-imports: ["error", {
"name": "disallowed-import",
"message": "Please use 'allowed-import' instead"
}]*/
paths
This is an object option whose value is an array containing the names of the modules you want to restrict.
"no-restricted-imports": ["error", { "paths": ["import1", "import2"] }]
Examples of incorrect code for paths:
/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/
Custom messages for a particular module can also be specified in paths array using objects with name and message.
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"message": "Please use import-bar instead."
}, {
"name": "import-baz",
"message": "Please use import-quux instead."
}]
}]
importNames
This option in paths is an array and can be used to specify the names of certain bindings exported from a module. Import names specified inside paths array affect the module specified in the name property of corresponding object, so it is required to specify the name property first when you are using importNames or message option.
Specifying "default" string inside the importNames array will restrict the default export from being imported.
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"importNames": ["Bar"],
"message": "Please use Bar from /import-bar/baz/ instead."
}]
}]
Examples of incorrect code when importNames in paths has "default":
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["default"],
message: "Please use the default import from '/bar/baz/' instead."
}]}]*/
import from "foo";
Examples of incorrect code for importNames in paths:
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import { } from "foo";
import { } from "foo";
import { } from "foo";
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import from "foo";
Examples of correct code for importNames in paths:
If the local name assigned to a default export is the same as a string in importNames, this will not cause an error.
/*eslint no-restricted-imports: ["error", { paths: [{ name: "foo", importNames: ["DisallowedObject"] }] }]*/
import DisallowedObject from "foo"
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import { AllowedObject as DisallowedObject } from "foo";
allowImportNames
This option is an array. Inverse of importNames, allowImportNames allows the imports that are specified inside this array. So it restricts all imports from a module, except specified allowed ones.
Note: allowImportNames cannot be used in combination with importNames.
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"allowImportNames": ["Bar"],
"message": "Please use only Bar from import-foo."
}]
}]
Examples of incorrect code for allowImportNames in paths:
Disallowing all import names except ‘AllowedObject’.
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
allowImportNames: ["AllowedObject"],
message: "Please use only 'AllowedObject' from 'foo'."
}]}]*/
import { } from "foo";
Examples of correct code for allowImportNames in paths:
Disallowing all import names except ‘AllowedObject’.
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
allowImportNames: ["AllowedObject"],
message: "Only use 'AllowedObject' from 'foo'."
}]}]*/
import { AllowedObject } from "foo";
patterns
This is also an object option whose value is an array. This option allows you to specify multiple modules to restrict using gitignore-style patterns.
Because the patterns follow the gitignore-style, if you want to reinclude any particular module this can be done by prefixing a negation (!) mark in front of the pattern. (Negated patterns should come last in the array because order is important.)
"no-restricted-imports": ["error", {
"patterns": ["import1/private/*", "import2/*", "!import2/good"]
}]
Examples of incorrect code for pattern option:
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*"] }]*/
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*", "!lodash/pick"] }]*/
/*eslint no-restricted-imports: ["error", { "patterns": ["import1/*", "!import1/private/*"] }]*/
In this example, "!import1/private/*" is not reincluding the modules inside private because the negation mark (!) does not reinclude the files if it’s parent directory is excluded by a pattern. In this case, import1/private directory is already excluded by the import1/* pattern. (The excluded directory can be reincluded using "!import1/private".)
Examples of correct code for pattern option:
/*eslint no-restricted-imports: ["error", { "patterns": ["crypto/*"] }]*/
import crypto from 'crypto';
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*", "!lodash/pick"] }]*/
import pick from 'lodash/pick';
/*eslint no-restricted-imports: ["error", { "patterns": ["import1/*", "!import1/private"] }]*/
import pick from 'import1/private/someModule';
group
The patterns array can also include objects. The group property is used to specify the gitignore-style patterns for restricting modules and the message property is used to specify a custom message.
The group property is required property when using objects inside the patterns array.
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import1/private/*"],
"message": "usage of import1 private modules not allowed."
}, {
"group": ["import2/*", "!import2/good"],
"message": "import2 is deprecated, except the modules in import2/good."
}]
}]
Examples of incorrect code for group option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
Examples of correct code for this group option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
import lodash from 'lodash';
caseSensitive
This is a boolean option and sets the patterns specified in the group array to be case-sensitive when true. Default is false.
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import1/private/prefix[A-Z]*"],
"caseSensitive": true
}]
}]
Examples of incorrect code for caseSensitive: true option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
Examples of correct code for caseSensitive: true option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
import pick from 'food';
importNames
You can also specify importNames on objects inside of patterns. In this case, the specified names are applied only to the specified group.
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"importNames": ["isEmpty"],
"message": "Use 'isEmpty' from lodash instead."
}]
}]
Examples of incorrect code for importNames in patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { } from 'utils/collection-utils';
Examples of correct code for importNames in patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { hasValues } from 'utils/collection-utils';
allowImportNames
You can also specify allowImportNames on objects inside of patterns. In this case, the specified names are applied only to the specified group.
Note: allowImportNames cannot be used in combination with importNames, importNamePattern or allowImportNamePattern.
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"allowImportNames": ["isEmpty"],
"message": "Please use only 'isEmpty' from utils."
}]
}]
Examples of incorrect code for allowImportNames in patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNames: ['isEmpty'],
message: "Please use only 'isEmpty' from utils."
}]}]*/
import { } from 'utils/collection-utils';
Examples of correct code for allowImportNames in patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNames: ['isEmpty'],
message: "Please use only 'isEmpty' from utils."
}]}]*/
import { isEmpty } from 'utils/collection-utils';
importNamePattern
This option allows you to use regex patterns to restrict import names:
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import-foo/*"],
"importNamePattern": "^foo",
}]
}]
Examples of incorrect code for importNamePattern option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: '^is',
message: "Use 'is*' functions from lodash instead."
}]}]*/
import { } from 'utils/collection-utils';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo/*"],
importNamePattern: '^(is|has)',
message: "Use 'is*' and 'has*' functions from baz/bar instead"
}]}]*/
import { , } from 'foo/bar';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo/*"],
importNames: ["bar"],
importNamePattern: '^baz',
}]}]*/
import { , } from 'foo/quux';
Examples of correct code for importNamePattern option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: '^is',
message: "Use 'is*' functions from lodash instead."
}]}]*/
import isEmpty, { hasValue } from 'utils/collection-utils';
allowImportNamePattern
This is a string option. Inverse of importNamePattern, this option allows imports that matches the specified regex pattern. So it restricts all imports from a module, except specified allowed patterns.
Note: allowImportNamePattern cannot be used in combination with importNames, importNamePattern or allowImportNames.
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import-foo/*"],
"allowImportNamePattern": "^foo",
}]
}]
Examples of incorrect code for allowImportNamePattern option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNamePattern: '^has'
}]}]*/
import { } from 'utils/collection-utils';
Examples of correct code for allowImportNamePattern option:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNamePattern: '^is'
}]}]*/
import { isEmpty } from 'utils/collection-utils';
When Not To Use It
Don’t use this rule or don’t include a module in the list for this rule if you want to be able to import a module in your project without an ESLint error or warning.
Version
This rule was introduced in ESLint v2.0.0-alpha-1.