no-restricted-imports
禁止在 `import` 语句中加载指定的模块
导入是 ES6/ES2015 标准中使其他模块的功能在当前模块中可用的方式。在 CommonJS 中,这通过 `require()` 调用实现,这使得此 ESLint 规则大致等同于其 CommonJS 对应规则 `no-restricted-modules`。
为什么要限制导入?
-
某些导入可能在特定环境中没有意义。例如,Node.js 的 `fs` 模块在没有文件系统的环境中没有意义。
-
某些模块提供相似或相同的功能,例如 `lodash` 和 `underscore`。您的项目可能已经标准化为一个模块。您希望确保不使用其他替代方案,因为这会不必要地使项目膨胀,并增加维护两个依赖项的成本,而一个就足够了。
规则详情
此规则允许您指定不希望在应用程序中使用的导入。
它仅适用于静态导入,不适用于动态导入。
选项
此规则具有字符串和对象选项,用于指定要限制的导入模块。
使用字符串选项,您可以指定要限制导入的模块的名称作为规则选项数组中的值
"no-restricted-imports": ["error", "import1", "import2"]
字符串选项的错误代码示例
/*eslint no-restricted-imports: ["error", "fs"]*/
字符串选项也会限制模块的导出,如本例所示
/*eslint no-restricted-imports: ["error", "fs"]*/
/*eslint no-restricted-imports: ["error", "fs"]*/
字符串选项的正确代码示例
/*eslint no-restricted-imports: ["error", "fs"]*/
import crypto from 'crypto';
export { foo } from "bar";
您还可以使用对象内的 `name` 和 `message` 属性为特定模块指定自定义消息,其中 `name` 的值为模块名称,`message` 属性包含自定义消息。(自定义消息将附加到规则的默认错误消息。)
"no-restricted-imports": ["error", {
"name": "import-foo",
"message": "Please use import-bar instead."
}, {
"name": "import-baz",
"message": "Please use import-quux instead."
}]
字符串选项的错误代码示例
/*eslint no-restricted-imports: ["error", {
"name": "disallowed-import",
"message": "Please use 'allowed-import' instead"
}]*/
paths
这是一个对象选项,其值为一个包含要限制的模块名称的数组。
"no-restricted-imports": ["error", { "paths": ["import1", "import2"] }]
paths 的错误代码示例
/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/
也可以在 `paths` 数组中使用带有 `name` 和 `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
`paths` 中的此选项是一个数组,可用于指定从模块导出的某些绑定的名称。在 `paths` 数组中指定的导入名称会影响相应对象中 `name` 属性指定的模块,因此在使用 `importNames` 或 `message` 选项时,需要先指定 `name` 属性。
在 `importNames` 数组中指定字符串 `"default"` 将限制默认导出被导入。
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"importNames": ["Bar"],
"message": "Please use Bar from /import-bar/baz/ instead."
}]
}]
当 `paths` 中的 `importNames` 包含 `"default"` 时的错误代码示例
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["default"],
message: "Please use the default import from '/bar/baz/' instead."
}]}]*/
import from "foo";
`paths` 中 `importNames` 的错误代码示例
/*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";
`paths` 中 `importNames` 的正确代码示例
如果分配给默认导出的本地名称与 `importNames` 中的字符串相同,则不会导致错误。
/*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
此选项是一个数组。与 `importNames` 相反,`allowImportNames` 允许在此数组中指定的导入。因此,它限制了模块的所有导入,除了指定的允许导入。
注意:`allowImportNames` 不能与 `importNames` 结合使用。
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"allowImportNames": ["Bar"],
"message": "Please use only Bar from import-foo."
}]
}]
`paths` 中 `allowImportNames` 的错误代码示例
禁止所有导入名称,除了 ‘AllowedObject’。
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
allowImportNames: ["AllowedObject"],
message: "Please use only 'AllowedObject' from 'foo'."
}]}]*/
import { } from "foo";
`paths` 中 `allowImportNames` 的正确代码示例
禁止所有导入名称,除了 ‘AllowedObject’。
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
allowImportNames: ["AllowedObject"],
message: "Only use 'AllowedObject' from 'foo'."
}]}]*/
import { AllowedObject } from "foo";
allowTypeImports (仅 TypeScript)
是否允许针对路径使用 仅类型导入。这包括仅类型的 `export` 语句,因为它们等同于重新导出 `import`。默认值:`false`。
`paths` 中 `allowTypeImports` 的错误代码示例
/*eslint no-restricted-imports: ["error", { paths: [{
name: "import-foo",
allowTypeImports: true,
message: "Please use only type-only imports from 'import-foo'."
}]}]*/
`paths` 中 `allowTypeImports` 的正确代码示例
/*eslint no-restricted-imports: ["error", { paths: [{
name: "import-foo",
allowTypeImports: true,
message: "Please use only type-only imports from 'import-foo'."
}]}]*/
import type foo from 'import-foo';
export type { Foo } from 'import-foo';
import type foo = require("import-foo");
/*eslint no-restricted-imports: ["error", { paths: [{
name: "import-foo",
importNames: ["Baz"],
allowTypeImports: true,
message: "Please use 'Baz' from 'import-foo' as a type only."
}]}]*/
import { Bar, type Baz } from "import-foo";
patterns
这也是一个对象选项,其值为一个数组。此选项允许您使用 `gitignore` 样式的模式或正则表达式来指定多个要限制的模块。
其中 `paths` 选项采用精确的导入路径,而 `patterns` 选项可用于使用更灵活的方式指定导入路径,从而允许限制同一目录中的多个模块。例如
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
}]
}]
此配置限制了 `import-foo` 模块的导入,但不会限制 `import-foo/bar` 或 `import-foo/baz` 的导入。您可以使用 `patterns` 来限制两者
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
}],
"patterns": [{
"group": ["import-foo/ba*"],
}]
}]
此配置不仅使用 `path` 限制了 `import-foo` 的导入,还使用 `patterns` 限制了 `import-foo/bar` 和 `import-foo/baz`。
在使用 `gitignore` 样式模式时,要在重新包含模块,请在模式前添加否定标记 (!)。(确保这些否定模式放在数组的最后,因为顺序很重要)
"no-restricted-imports": ["error", {
"patterns": ["import1/private/*", "import2/*", "!import2/good"]
}]
您还可以使用正则表达式来限制模块(请参阅 regex 选项)。
`patterns` 选项的错误代码示例
/*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/*"] }]*/
在本例中,`"!import1/private/*"` 没有重新包含 `private` 内部的模块,因为否定标记 (!) 如果其父目录被模式排除,则不会重新包含文件。在本例中,`import1/private` 目录已经被 `import1/*` 模式排除。(可以使用 `"!import1/private"` 重新包含排除的目录。)
`patterns` 选项的正确代码示例
/*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
`patterns` 数组也可以包含对象。`group` 属性用于指定用于限制模块的 `gitignore` 样式模式,`message` 属性用于指定自定义消息。
使用 `patterns` 选项时,`group` 或 `regex` 属性中的一个是必需的。
"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."
}]
}]
`group` 选项的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
此 `group` 选项的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
import lodash from 'lodash';
regex
`regex` 属性用于指定用于限制模块的正则表达式模式。
注意:`regex` 不能与 `group` 结合使用。
"no-restricted-imports": ["error", {
"patterns": [{
"regex": "import1/private/",
"message": "usage of import1 private modules not allowed."
}, {
"regex": "import2/(?!good)",
"message": "import2 is deprecated, except the modules in import2/good."
}]
}]
`regex` 选项的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
regex: "@app/(?!(api/enums$)).*",
}]}]*/
`regex` 选项的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
regex: "@app/(?!(api/enums$)).*",
}]}]*/
import Foo from '@app/api/enums';
caseSensitive
这是一个布尔选项,当设置为 `true` 时,将使 `group` 或 `regex` 属性中指定的模式区分大小写。默认值为 `false`。
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import1/private/prefix[A-Z]*"],
"caseSensitive": true
}]
}]
`caseSensitive: true` 选项的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
`caseSensitive: true` 选项的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
import pick from 'food';
importNames
您还可以在 `patterns` 数组内的对象中指定 `importNames`。在这种情况下,指定的名称仅适用于关联的 `group` 或 `regex` 属性。
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"importNames": ["isEmpty"],
"message": "Use 'isEmpty' from lodash instead."
}]
}]
`patterns` 中 `importNames` 的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { } from 'utils/collection-utils';
`patterns` 中 `importNames` 的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { hasValues } from 'utils/collection-utils';
allowImportNames
您还可以在 `patterns` 数组内的对象中指定 `allowImportNames`。在这种情况下,指定的名称仅适用于关联的 `group` 或 `regex` 属性。
注意:`allowImportNames` 不能与 `importNames`、`importNamePattern` 或 `allowImportNamePattern` 结合使用。
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"allowImportNames": ["isEmpty"],
"message": "Please use only 'isEmpty' from utils."
}]
}]
`patterns` 中 `allowImportNames` 的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNames: ['isEmpty'],
message: "Please use only 'isEmpty' from utils."
}]}]*/
import { } from 'utils/collection-utils';
`patterns` 中 `allowImportNames` 的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNames: ['isEmpty'],
message: "Please use only 'isEmpty' from utils."
}]}]*/
import { isEmpty } from 'utils/collection-utils';
importNamePattern
此选项允许您使用正则表达式模式来限制导入名称
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import-foo/*"],
"importNamePattern": "^foo",
}]
}]
`importNamePattern` 选项的错误代码示例
/*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';
`importNamePattern` 选项的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: '^is',
message: "Use 'is*' functions from lodash instead."
}]}]*/
import isEmpty, { hasValue } from 'utils/collection-utils';
您还可以通过将其设置为匹配任何名称的模式(例如 `^`)来仅允许副作用导入。
`importNamePattern` 选项的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: "^"
}]}]*/
import , { } from 'utils/collection-utils';
import from 'utils/file-utils';
`importNamePattern` 选项的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: "^"
}]}]*/
import 'utils/init-utils';
allowImportNamePattern
这是一个字符串选项。与 `importNamePattern` 相反,此选项允许匹配指定的正则表达式模式的导入。因此,它限制了模块的所有导入,除了指定的允许模式。
注意:`allowImportNamePattern` 不能与 `importNames`、`importNamePattern` 或 `allowImportNames` 结合使用。
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import-foo/*"],
"allowImportNamePattern": "^foo",
}]
}]
`allowImportNamePattern` 选项的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNamePattern: '^has'
}]}]*/
import { } from 'utils/collection-utils';
`allowImportNamePattern` 选项的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNamePattern: '^is'
}]}]*/
import { isEmpty } from 'utils/collection-utils';
allowTypeImports (仅 TypeScript)
是否允许针对路径使用 仅类型导入。这包括仅类型的 `export` 语句,因为它们等同于重新导出 `import`。默认值:`false`。
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import/private/*"],
"allowTypeImports": true,
}]
}]
`patterns` 中 `allowTypeImports` 的错误代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["import/private/*"],
allowTypeImports: true,
message: "Please use only type-only imports from 'import/private/*'."
}]}]*/
`patterns` 中 `allowTypeImports` 的正确代码示例
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["import/private/*"],
allowTypeImports: true,
message: "Please use only type-only imports from 'import/private/*'."
}]}]*/
import type { foo } from 'import/private/bar';
export type { foo } from 'import/private/bar';
import type foo = require("import/private/bar");
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["import/private/*"],
importNames: ["Baz"],
allowTypeImports: true,
message: "Please use 'Baz' from 'import/private/*' as a type only."
}]}]*/
import { Bar, type Baz } from "import/private/bar";
已知限制
TypeScript import = require() 语法 有效,该规则可以识别和检查此类实例,但存在某些限制。
您只能完全限制这些导入,不能根据特定的导入名称(例如 `importNames`、`allowImportNames`、`importNamePattern` 或 `allowImportNamePattern` 选项)来限制它们。
TypeScript import equals 声明的错误代码示例
/*eslint no-restricted-imports: ["error", "disallowed-import"]*/
/*eslint no-restricted-imports: ["error", {
"paths": [{ "name": "disallowed-import" }]
}]*/
注意: 导入名称限制不适用于 TypeScript import equals 声明。以下配置将不会限制 import equals 声明
/*eslint no-restricted-imports: ["error", {
"paths": [{
"name": "foo",
"importNames": ["foo"]
}]
}]*/
// This import equals declaration will NOT be restricted
// even though it imports the entire module
import foo = require("foo");
何时不使用它
如果您希望能够在不出现 ESLint 错误或警告的情况下在项目中导入模块,请不要使用此规则或不要将模块包含在此规则的列表中。
版本
此规则是在 ESLint v2.0.0-alpha-1 中引入的。