no-restricted-imports
Запрещает указанные модули при их загрузке с помощью import
Импорты — это стандарт ES6/ES2015, позволяющий использовать функциональность других модулей в текущем модуле. В CommonJS это реализовано с помощью вызова require(), поэтому это правило ESLint примерно эквивалентно его аналогу для CommonJS — no-restricted-modules.
Зачем ограничивать импорты?
-
Некоторые импорты могут быть неуместны в определённой среде. Например, модуль
fsв Node.js не имеет смысла в среде, где нет файловой системы. -
Некоторые модули предоставляют похожую или идентичную функциональность — например,
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.
Если указать строку "default" в массиве importNames, импорт экспорта по умолчанию будет запрещён.
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"importNames": ["Bar"],
"message": "Please use Bar from /import-bar/baz/ instead."
}]
}]
Примеры неправильного кода, когда importNames в paths содержит "default":
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["default"],
message: "Please use the default import from '/bar/baz/' instead."
}]}]*/
import from "foo";
Примеры неправильного кода для importNames в 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";
Примеры правильного кода для importNames в paths:
Если локальное имя, присвоенное экспорту по умолчанию, совпадает со строкой в 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
Этот параметр представляет собой массив. allowImportNames — противоположность importNames: он разрешает импорты, указанные в этом массиве. Таким образом, он ограничивает все импорты из модуля, кроме указанных разрешённых.
Примечание: allowImportNames нельзя использовать вместе с importNames.
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"allowImportNames": ["Bar"],
"message": "Please use only Bar from import-foo."
}]
}]
Примеры неправильного кода для allowImportNames в paths:
Запрещены все имена импортов, кроме «AllowedObject».
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
allowImportNames: ["AllowedObject"],
message: "Please use only 'AllowedObject' from 'foo'."
}]}]*/
import { } from "foo";
Примеры правильного кода для allowImportNames в paths:
Запрещены все имена импортов, кроме «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.
Примеры неправильного кода для allowTypeImports в paths:
/*eslint no-restricted-imports: ["error", { paths: [{
name: "import-foo",
allowTypeImports: true,
message: "Please use only type-only imports from 'import-foo'."
}]}]*/
Примеры правильного кода для allowTypeImports в paths:
/*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*"],
}]
}]
Эта конфигурация ограничивает импорт не только из import-foo с помощью path, но также из import-foo/bar и import-foo/baz с помощью patterns.
Чтобы снова разрешить импорт модуля при использовании шаблонов в стиле 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
Этот логический параметр задаёт чувствительность к регистру для шаблонов, указанных в свойствах group или regex, при использовании true. Значение по умолчанию — 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
Также можно указать importNames внутри объектов в массиве patterns. В этом случае указанные имена применяются только к соответствующему свойству group или regex.
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"importNames": ["isEmpty"],
"message": "Use 'isEmpty' from lodash instead."
}]
}]
Примеры неправильного кода для importNames в patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { } from 'utils/collection-utils';
Примеры правильного кода для importNames в patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { hasValues } from 'utils/collection-utils';
allowImportNames
Также можно указать allowImportNames внутри объектов в массиве patterns. В этом случае указанные имена применяются только к соответствующему свойству group или regex.
Примечание: allowImportNames нельзя использовать вместе с importNames, importNamePattern или allowImportNamePattern.
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"allowImportNames": ["isEmpty"],
"message": "Please use only 'isEmpty' from utils."
}]
}]
Примеры неправильного кода для allowImportNames в patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNames: ['isEmpty'],
message: "Please use only 'isEmpty' from utils."
}]}]*/
import { } from 'utils/collection-utils';
Примеры правильного кода для allowImportNames в 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
Этот параметр позволяет использовать шаблоны регулярных выражений для ограничения имён импортов:
"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,
}]
}]
Примеры неправильного кода для allowTypeImports в patterns:
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["import/private/*"],
allowTypeImports: true,
message: "Please use only type-only imports from 'import/private/*'."
}]}]*/
Примеры правильного кода для allowTypeImports в patterns:
/*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.
Ресурсы
© OpenJS Foundation and other contributors
Licensed under the MIT License.
https://eslint.org/docs/latest/rules/no-restricted-imports