no-restricted-imports

import 加载时禁止指定模块

Imports 是 ES6/ES2015 标准,用于使当前模块中的其他模块的功能可用。在 CommonJS 中,这是通过 require() 调用实现的,这使得这个 ESLint 规则大致相当于其 CommonJS 对应的 no-restricted-modules

¥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?

  • 某些导入在特定环境中可能没有意义。例如,Node.js 的 fs 模块在没有文件系统的环境中没有意义。

    ¥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.

  • 一些模块提供相似或相同的功能,想想 lodashunderscore。你的项目可能已经标准化了一个模块。你要确保不使用其他替代方案,因为这会不必要地使项目膨胀,并在一个足够的情况下提供两个依赖的更高维护成本。

    ¥Some modules provide similar or identical functionality, think lodash and underscore. 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"]*/

import fs from 'fs';

字符串选项还限制模块的导出,如下例所示:

¥String options also restrict the module from being exported, as in this example:

在线运行
/*eslint no-restricted-imports: ["error", "fs"]*/

export { fs } from 'fs';
在线运行
/*eslint no-restricted-imports: ["error", "fs"]*/

export * from 'fs';

字符串选项的正确代码示例:

¥Examples of correct code for string option:

在线运行
/*eslint no-restricted-imports: ["error", "fs"]*/

import crypto from 'crypto';
export { foo } from "bar";

你还可以使用对象内的 namemessage 属性为特定模块指定自定义消息,其中 name 的值是模块的名称,message 属性包含自定义消息。(自定义消息附加到规则中的默认错误消息中。)

¥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"
}]*/

import foo from 'disallowed-import';

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"] }]

paths 的错误代码示例:

¥Examples of incorrect code for paths:

在线运行
/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/

import cluster from 'cluster';

还可以使用具有 namemessage 的对象在 paths 数组中指定特定模块的自定义消息。

¥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

paths 中的此选项是一个数组,可用于指定从模块导出的某些绑定的名称。paths 数组中指定的导入名称会影响相应对象的 name 属性中指定的模块,因此在使用 importNamesmessage 选项时需要先指定 name 属性。

¥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.

importNames 数组内指定 "default" 字符串将限制导入默认导出。

¥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."
  }]
}]

paths 中的 importNames"default" 时的错误代码示例:

¥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 DisallowedObject from "foo";

pathsimportNames 的错误代码示例:

¥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 { 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";

pathsimportNames 的正确代码示例:

¥Examples of correct code for importNames in paths:

如果分配给默认导出的局部名称与 importNames 中的字符串相同,则不会导致错误。

¥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

该选项是一个数组。与 importNames 相反,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.

注意:allowImportNames 不能与 importNames 组合使用。

¥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."
  }]
}]

pathsallowImportNames 的错误代码示例:

¥Examples of incorrect code for allowImportNames in paths:

禁止除 ‘AllowedObject’ 之外的所有导入名称。

¥Disallowing all import names except ‘AllowedObject’.

在线运行
/*eslint no-restricted-imports: ["error", { paths: [{
    name: "foo",
    allowImportNames: ["AllowedObject"],
    message: "Please use only 'AllowedObject' from 'foo'."
}]}]*/

import { DisallowedObject } from "foo";

pathsallowImportNames 的正确代码示例:

¥Examples of correct code for allowImportNames in paths:

禁止除 ‘AllowedObject’ 之外的所有导入名称。

¥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

这也是一个对象选项,其值为数组。此选项允许你指定多个模块以使用 gitignore 样式模式或正则表达式进行限制。

¥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 or regular expressions.

paths 选项采用精确的导入路径时,patterns 选项可用于更灵活地指定导入路径,从而允许限制同一目录中的多个模块。例如:

¥Where paths option takes exact import paths, patterns option can be used to specify the import paths with more flexibility, allowing for the restriction of multiple modules within the same directory. For example:

"no-restricted-imports": ["error", {
  "paths": [{
    "name": "import-foo",
  }]
}]

此配置限制 import-foo 模块的导入,但不会限制 import-foo/barimport-foo/baz 的导入。你可以使用 patterns 来限制两者:

¥This configuration restricts import of the import-foo module but wouldn’t restrict the import of import-foo/bar or import-foo/baz. You can use patterns to restrict both:

"no-restricted-imports": ["error", {
    "paths": [{
      "name": "import-foo",
    }],
    "patterns": [{
      "group": ["import-foo/ba*"],
    }]
}]

此配置不仅限制使用 pathimport-foo 导入,还限制使用 patternsimport-foo/barimport-foo/baz 导入。

¥This configuration restricts imports not just from import-foo using path, but also import-foo/bar and import-foo/baz using patterns.

要在使用 gitignore- 样式模式时重新包含模块,请在模式前添加否定(!)标记。(确保这些否定模式放在数组的最后,因为顺序很重要)

¥To re-include a module when using gitignore-style patterns, add a negation (!) mark before the pattern. (Make sure these negated patterns are placed last in the array, as order matters)

"no-restricted-imports": ["error", {
    "patterns": ["import1/private/*", "import2/*", "!import2/good"]
}]

你还可以使用正则表达式来限制模块(请参阅 regex 选项)。

¥You can also use regular expressions to restrict modules (see the regex option).

patterns 选项的错误代码示例:

¥Examples of incorrect code for patterns option:

在线运行
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*"] }]*/

import pick from 'lodash/pick';
在线运行
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*", "!lodash/pick"] }]*/

import pick from 'lodash/map';
在线运行
/*eslint no-restricted-imports: ["error", { "patterns": ["import1/*", "!import1/private/*"] }]*/

import pick from 'import1/private/someModule';

在此示例中,"!import1/private/*" 不会重新包含 private 内的模块,因为如果其父目录被模式排除,则否定标记 (!) 不会重新包含文件。在这种情况下,import1/private 目录已被 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".)

patterns 选项的正确代码示例:

¥Examples of correct code for patterns 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

patterns 数组还可以包含对象。group 属性用于指定限制模块的 gitignore 样式模式,message 属性用于指定自定义消息。

¥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.

使用 patterns 选项时,需要 groupregex 属性。

¥Either of the group or regex properties is required when using the patterns option.

"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 选项的错误代码示例:

¥Examples of incorrect code for group option:

在线运行
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["lodash/*"],
    message: "Please use the default import from 'lodash' instead."
}]}]*/

import pick from 'lodash/pick';

group 选项的正确代码示例:

¥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';

regex

regex 属性用于指定限制模块的正则表达式模式。

¥The regex property is used to specify the regex patterns for restricting modules.

注意:regex 不能与 group 组合使用。

¥Note: regex cannot be used in combination with 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 选项的错误代码示例:

¥Examples of incorrect code for regex option:

在线运行
/*eslint no-restricted-imports: ["error", { patterns: [{
    regex: "@app/(?!(api/enums$)).*",
}]}]*/

import Foo from '@app/api';
import Bar from '@app/api/bar';
import Baz from '@app/api/baz';
import Bux from '@app/api/enums/foo';

regex 选项的正确代码示例:

¥Examples of correct code for regex option:

在线运行
/*eslint no-restricted-imports: ["error", { patterns: [{
    regex: "@app/(?!(api/enums$)).*",
}]}]*/

import Foo from '@app/api/enums';

caseSensitive

这是一个布尔选项,将 groupregex 属性中指定的模式设置为 true 时区分大小写。默认为 false

¥This is a boolean option and sets the patterns specified in the group or regex properties to be case-sensitive when true. Default is false.

"no-restricted-imports": ["error", {
    "patterns": [{
      "group": ["import1/private/prefix[A-Z]*"],
      "caseSensitive": true
    }]
}]

caseSensitive: true 选项的错误代码示例:

¥Examples of incorrect code for caseSensitive: true option:

在线运行
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["foo[A-Z]*"],
    caseSensitive: true
}]}]*/

import pick from 'fooBar';

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

你还可以在 patterns 数组内的对象中指定 importNames。在这种情况下,指定的名称仅适用于关联的 groupregex 属性。

¥You can also specify importNames within objects inside the patterns array. In this case, the specified names apply only to the associated group or regex property.

"no-restricted-imports": ["error", {
    "patterns": [{
      "group": ["utils/*"],
      "importNames": ["isEmpty"],
      "message": "Use 'isEmpty' from lodash instead."
    }]
}]

patternsimportNames 的错误代码示例:

¥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 { isEmpty } from 'utils/collection-utils';

patternsimportNames 的正确代码示例:

¥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

你还可以在 patterns 数组内的对象中指定 allowImportNames。在这种情况下,指定的名称仅适用于关联的 groupregex 属性。

¥You can also specify allowImportNames within objects inside the patterns array. In this case, the specified names apply only to the associated group or regex property.

注意:allowImportNames 不能与 importNamesimportNamePatternallowImportNamePattern 组合使用。

¥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."
    }]
}]

patternsallowImportNames 的错误代码示例:

¥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 { hasValues } from 'utils/collection-utils';

patternsallowImportNames 的正确代码示例:

¥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",
    }]
}]

importNamePattern 选项的错误代码示例:

¥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 { 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';

importNamePattern 选项的正确代码示例:

¥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';

你还可以使用此选项仅允许副作用导入,方法是将其设置为与任何名称匹配的模式,例如 ^

¥You can also use this option to allow only side-effect imports by setting it to a pattern that matches any name, such as ^.

importNamePattern 选项的错误代码示例:

¥Examples of incorrect code for importNamePattern option:

在线运行
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    importNamePattern: "^"
}]}]*/

import isEmpty, { hasValue } from 'utils/collection-utils';

import * as file from 'utils/file-utils';

importNamePattern 选项的正确代码示例:

¥Examples of correct code for importNamePattern option:

在线运行
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    importNamePattern: "^"
}]}]*/

import 'utils/init-utils';

allowImportNamePattern

这是一个字符串选项。与 importNamePattern 相反,此选项允许导入与指定的正则表达式模式匹配的导入。因此,它限制来自模块的所有导入,除了指定的允许模式。

¥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.

注意:allowImportNamePattern 不能与 importNamesimportNamePatternallowImportNames 组合使用。

¥Note: allowImportNamePattern cannot be used in combination with importNames, importNamePattern or allowImportNames.

"no-restricted-imports": ["error", {
    "patterns": [{
      "group": ["import-foo/*"],
      "allowImportNamePattern": "^foo",
    }]
}]

allowImportNamePattern 选项的错误代码示例:

¥Examples of incorrect code for allowImportNamePattern option:

在线运行
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    allowImportNamePattern: '^has'
}]}]*/

import { isEmpty } from 'utils/collection-utils';

allowImportNamePattern 选项的正确代码示例:

¥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

如果你希望能够在项目中导入模块而不会出现 ESLint 错误或警告,请不要使用此规则或不在此规则的列表中包含模块。

¥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.

版本

此规则是在 ESLint v2.0.0-alpha-1 中引入。

资源