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’
fs
module would not make sense in an environment that didn’t have a file system. -
Some modules provide similar or identical functionality, think
lodash
andunderscore
. 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
The syntax to specify restricted imports looks like this:
"no-restricted-imports": ["error", "import1", "import2"]
or like this:
"no-restricted-imports": ["error", { "paths": ["import1", "import2"] }]
When using the object form, you can also specify an array of gitignore-style patterns:
"no-restricted-imports": ["error", {
"paths": ["import1", "import2"],
"patterns": ["import1/private/*", "import2/*", "!import2/good"]
}]
You may also specify a custom message for any paths you want to restrict as follows:
"no-restricted-imports": ["error", {
"name": "import-foo",
"message": "Please use import-bar instead."
}, {
"name": "import-baz",
"message": "Please use import-quux instead."
}]
or like this:
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"message": "Please use import-bar instead."
}, {
"name": "import-baz",
"message": "Please use import-quux instead."
}]
}]
or like this if you need to restrict only certain imports from a module:
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"importNames": ["Bar"],
"message": "Please use Bar from /import-bar/baz/ instead."
}]
}]
or like this if you want to apply a custom message to pattern matches:
"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."
}]
}]
The custom message will be appended to the default error message.
Pattern matches can also be configured to be case-sensitive:
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import1/private/prefix[A-Z]*"],
"caseSensitive": true
}]
}]
Pattern matches can restrict specific import names only, similar to the paths
option:
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"importNames": ["isEmpty"],
"message": "Use 'isEmpty' from lodash instead."
}]
}]
Regex patterns can also be used to restrict specific import Name:
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import-foo/*"],
"importNamePattern": "^foo",
}]
}]
To restrict the use of all Node.js core imports (via https://github.com/nodejs/node/tree/master/lib):
"no-restricted-imports": ["error",
"assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","freelist","fs","http","https","module","net","os","path","punycode","querystring","readline","repl","smalloc","stream","string_decoder","sys","timers","tls","tracing","tty","url","util","vm","zlib"
],
Examples
Examples of incorrect code for this rule:
/*eslint no-restricted-imports: ["error", "fs"]*/
import fs from 'fs';
/*eslint no-restricted-imports: ["error", "fs"]*/
export { fs } from 'fs';
/*eslint no-restricted-imports: ["error", "fs"]*/
export * from 'fs';
/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/
import cluster from 'cluster';
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*"] }]*/
import pick from 'lodash/pick';
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["default"],
message: "Please use the default import from '/bar/baz/' instead."
}]}]*/
import DisallowedObject from "foo";
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import { DisallowedObject } from "foo";
import { DisallowedObject as AllowedObject } from "foo";
import { "DisallowedObject" as SomeObject } from "foo";
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import * as Foo from "foo";
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
import pick from 'lodash/pick';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
import pick from 'fooBar';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { isEmpty } from 'utils/collection-utils';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: '^is',
message: "Use 'is*' functions from lodash instead."
}]}]*/
import { isEmpty } 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 { isSomething, hasSomething } from 'foo/bar';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo/*"],
importNames: ["bar"],
importNamePattern: '^baz',
}]}]*/
import { bar, bazQux } from 'foo/quux';
Examples of correct code for this rule:
/*eslint no-restricted-imports: ["error", "fs"]*/
import crypto from 'crypto';
export { foo } from "bar";
/*eslint no-restricted-imports: ["error", { "paths": ["fs"], "patterns": ["eslint/*"] }]*/
import crypto from 'crypto';
import eslint from 'eslint';
export * from "path";
/*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";
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
import lodash from 'lodash';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
import pick from 'food';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { hasValues } from 'utils/collection-utils';
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: '^is',
message: "Use 'is*' functions from lodash instead."
}]}]*/
import isEmpty, { hasValue } 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.