Spec-Zone.ru › ESLint

no-restricted-imports

Запрещает указанные модули при их загрузке с помощью import

Импорты — это стандарт ES6/ES2015, позволяющий использовать функциональность других модулей в текущем модуле. В CommonJS это реализовано с помощью вызова require(), поэтому это правило ESLint примерно эквивалентно его аналогу для CommonJS — no-restricted-modules.

Зачем ограничивать импорты?

  • Некоторые импорты могут быть неуместны в определённой среде. Например, модуль fs в Node.js не имеет смысла в среде, где нет файловой системы.

  • Некоторые модули предоставляют похожую или идентичную функциональность — например, lodash и underscore. В вашем проекте мог быть выбран один из этих модулей в качестве стандартного. Чтобы избежать ненужного увеличения размера проекта и дополнительных затрат на поддержку двух зависимостей, когда достаточно одной, следует убедиться, что другие варианты не используются.

Описание правила

Это правило позволяет указать импорты, использование которых в приложении нежелательно.

Оно применяется только к статическим импортам, но не к динамическим.

Параметры

Это правило поддерживает параметры в виде строк и объектов для указания модулей, импорт которых нужно ограничить.

При использовании строкового параметра можно указать имя модуля, импорт которого нужно запретить, в массиве параметров правила:

"no-restricted-imports": ["error", "import1", "import2"]

Примеры неправильного кода со строковым параметром:

Открыть в Playground
/*eslint no-restricted-imports: ["error", "fs"]*/

import fs from 'fs';

Строковые параметры также запрещают экспорт модуля, как в этом примере:

Открыть в Playground
/*eslint no-restricted-imports: ["error", "fs"]*/

export { fs } from 'fs';
Открыть в Playground
/*eslint no-restricted-imports: ["error", "fs"]*/

export * from 'fs';

Примеры правильного кода со строковым параметром:

Открыть в Playground
/*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."
}]

Примеры неправильного кода со строковым параметром:

Открыть в Playground
/*eslint no-restricted-imports: ["error", {
    "name": "disallowed-import",
    "message": "Please use 'allowed-import' instead"
}]*/

import foo from 'disallowed-import';

paths

Это параметр-объект, значением которого является массив с именами модулей, импорт которых нужно ограничить.

"no-restricted-imports": ["error", { "paths": ["import1", "import2"] }]

Примеры неправильного кода для paths:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/

import cluster from '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":

Открыть в Playground
/*eslint no-restricted-imports: ["error", { paths: [{
    name: "foo",
    importNames: ["default"],
    message: "Please use the default import from '/bar/baz/' instead."
}]}]*/

import DisallowedObject from "foo";

Примеры неправильного кода для importNames в paths:

Открыть в Playground
/*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";
Открыть в Playground
/*eslint no-restricted-imports: ["error", { paths: [{
    name: "foo",
    importNames: ["DisallowedObject"],
    message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/

import * as Foo from "foo";

Примеры правильного кода для importNames в paths:

Если локальное имя, присвоенное экспорту по умолчанию, совпадает со строкой в importNames, ошибки не возникнет.

Открыть в Playground
/*eslint no-restricted-imports: ["error", { paths: [{ name: "foo", importNames: ["DisallowedObject"] }] }]*/

import DisallowedObject from "foo"
Открыть в Playground
/*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».

Открыть в Playground
/*eslint no-restricted-imports: ["error", { paths: [{
    name: "foo",
    allowImportNames: ["AllowedObject"],
    message: "Please use only 'AllowedObject' from 'foo'."
}]}]*/

import { DisallowedObject } from "foo";

Примеры правильного кода для allowImportNames в paths:

Запрещены все имена импортов, кроме «AllowedObject».

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { paths: [{
    name: "import-foo",
    allowTypeImports: true,
    message: "Please use only type-only imports from 'import-foo'."
}]}]*/

import foo from 'import-foo';
export { Foo } from 'import-foo';

Примеры правильного кода для allowTypeImports в paths:

Открыть в Playground
/*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");
Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*"] }]*/

import pick from 'lodash/pick';
Открыть в Playground
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*", "!lodash/pick"] }]*/

import pick from 'lodash/map';
Открыть в Playground
/*eslint no-restricted-imports: ["error", { "patterns": ["import1/*", "!import1/private/*"] }]*/

import pick from 'import1/private/someModule';

В этом примере "!import1/private/*" не разрешает повторный импорт модулей из private, потому что знак отрицания (!) не возвращает файлы в выборку, если их родительский каталог исключён шаблоном. В данном случае каталог import1/private уже исключён шаблоном import1/*. (Исключённый каталог можно снова включить с помощью "!import1/private".)

Примеры правильного кода с параметром patterns:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { "patterns": ["crypto/*"] }]*/

import crypto from 'crypto';
Открыть в Playground
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*", "!lodash/pick"] }]*/

import pick from 'lodash/pick';
Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["lodash/*"],
    message: "Please use the default import from 'lodash' instead."
}]}]*/

import pick from 'lodash/pick';

Примеры правильного кода для этого параметра group:

Открыть в Playground
/*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:

Открыть в Playground
/*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:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["foo[A-Z]*"],
    caseSensitive: true
}]}]*/

import pick from 'fooBar';

Примеры правильного кода с параметром caseSensitive: true:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    importNames: ['isEmpty'],
    message: "Use 'isEmpty' from lodash instead."
}]}]*/

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

Примеры правильного кода для importNames в patterns:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    allowImportNames: ['isEmpty'],
    message: "Please use only 'isEmpty' from utils."
}]}]*/

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

Примеры правильного кода для allowImportNames в patterns:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    importNamePattern: '^is',
    message: "Use 'is*' functions from lodash instead."
}]}]*/

import { isEmpty } from 'utils/collection-utils';
Открыть в Playground
/*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';
Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["foo/*"],
    importNames: ["bar"],
    importNamePattern: '^baz',
}]}]*/

import { bar, bazQux } from 'foo/quux';

Примеры правильного кода с параметром importNamePattern:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    importNamePattern: "^"
}]}]*/

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

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

Примеры правильного кода с параметром importNamePattern:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["utils/*"],
    allowImportNamePattern: '^has'
}]}]*/

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

Примеры правильного кода с параметром allowImportNamePattern:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", { patterns: [{
    group: ["import/private/*"],
    allowTypeImports: true,
    message: "Please use only type-only imports from 'import/private/*'."
}]}]*/

import { foo } from 'import/private/bar';
export { foo } from 'import/private/bar';

Примеры правильного кода для allowTypeImports в patterns:

Открыть в Playground
/*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");
Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-restricted-imports: ["error", "disallowed-import"]*/

import foo = require("disallowed-import");
Открыть в Playground
/*eslint no-restricted-imports: ["error", { 
  "paths": [{ "name": "disallowed-import" }] 
}]*/

import foo = require("disallowed-import");

Примечание: Ограничения на имена импортов не применяются к объявлениям TypeScript import equals. Следующая конфигурация не будет ограничивать объявление import equals:

Открыть в Playground
/*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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API