From b76f9a69ce42588e44d2b7ced66e697215d0a33d Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Wed, 7 Nov 2018 09:50:37 -0800 Subject: [PATCH 1/2] Fix: no-restricted-imports to check re-export (fixes #9678) --- docs/rules/no-restricted-imports.md | 16 ++++++- lib/rules/no-restricted-imports.js | 60 +++++++++++++++--------- tests/lib/rules/no-restricted-imports.js | 12 +++++ 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/docs/rules/no-restricted-imports.md b/docs/rules/no-restricted-imports.md index 66b8095a02b..62747ebcecb 100644 --- a/docs/rules/no-restricted-imports.md +++ b/docs/rules/no-restricted-imports.md @@ -1,6 +1,6 @@ # Disallow specific imports (no-restricted-imports) -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`. +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? @@ -87,6 +87,18 @@ Examples of **incorrect** code for this rule: import fs from 'fs'; ``` +```js +/*eslint no-restricted-imports: ["error", "fs"]*/ + +export { fs } from 'fs'; +``` + +```js +/*eslint no-restricted-imports: ["error", "fs"]*/ + +export * from 'fs'; +``` + ```js /*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/ @@ -135,6 +147,7 @@ Examples of **correct** code for this rule: /*eslint no-restricted-imports: ["error", "fs"]*/ import crypto from 'crypto'; +export { foo } from "bar"; ``` ```js @@ -142,6 +155,7 @@ import crypto from 'crypto'; import crypto from 'crypto'; import eslint from 'eslint'; +export * from "path"; ``` ```js diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js index e4563172e0b..fe2fd148d38 100644 --- a/lib/rules/no-restricted-imports.js +++ b/lib/rules/no-restricted-imports.js @@ -236,31 +236,47 @@ module.exports = { return restrictedPatterns.length > 0 && restrictedPatternsMatcher.ignores(importSource); } - return { - ImportDeclaration(node) { - const importSource = node.source.value.trim(); - const importNames = node.specifiers.reduce((set, specifier) => { - if (specifier.type === "ImportDefaultSpecifier") { - set.add("default"); - } else if (specifier.type === "ImportNamespaceSpecifier") { - set.add("*"); - } else { - set.add(specifier.imported.name); - } - return set; - }, new Set()); - - if (isRestrictedForEverythingImported(importSource, importNames)) { - reportPathForEverythingImported(importSource, node); + /** + * Checks a node to see if any problems should be reported. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkNode(node) { + const importSource = node.source.value.trim(); + const importNames = node.specifiers ? node.specifiers.reduce((set, specifier) => { + if (specifier.type === "ImportDefaultSpecifier") { + set.add("default"); + } else if (specifier.type === "ImportNamespaceSpecifier") { + set.add("*"); + } else if (specifier.imported) { + set.add(specifier.imported.name); + } else if (specifier.exported) { + set.add(specifier.exported.name); } + return set; + }, new Set()) : new Set(); - if (isRestrictedPath(importSource, importNames)) { - reportPath(node); - } - if (isRestrictedPattern(importSource)) { - reportPathForPatterns(node); - } + if (isRestrictedForEverythingImported(importSource, importNames)) { + reportPathForEverythingImported(importSource, node); + } + + if (isRestrictedPath(importSource, importNames)) { + reportPath(node); + } + if (isRestrictedPattern(importSource)) { + reportPathForPatterns(node); } + } + + return { + ImportDeclaration: checkNode, + ExportNamedDeclaration(node) { + if (node.source) { + checkNode(node); + } + }, + ExportAllDeclaration: checkNode }; } }; diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js index 5d279d5a31b..1daf8556778 100644 --- a/tests/lib/rules/no-restricted-imports.js +++ b/tests/lib/rules/no-restricted-imports.js @@ -193,6 +193,18 @@ ruleTester.run("no-restricted-imports", rule, { code: "import withGitignores from \"foo/bar\";", options: [{ patterns: ["foo/*", "!foo/baz"] }], errors: [{ message: "'foo/bar' import is restricted from being used by a pattern.", type: "ImportDeclaration" }] + }, { + code: "export * from \"fs\";", + options: ["fs"], + errors: [{ message: "'fs' import is restricted from being used.", type: "ExportAllDeclaration" }] + }, { + code: "export a from \"fs\";", + options: ["fs"], + errors: [{ message: "'fs' import is restricted from being used.", type: "ExportAllDeclaration" }] + }, { + code: "export {a} from \"fs\";", + options: ["fs"], + errors: [{ message: "'fs' import is restricted from being used.", type: "ExportNamedDeclaration" }] }, { code: "import withGitignores from \"foo\";", options: [{ From ada46a201a8a341d6faedb255db35c97b8be48e8 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Thu, 8 Nov 2018 14:04:58 -0800 Subject: [PATCH 2/2] Add export as use case --- lib/rules/no-restricted-imports.js | 4 ++-- tests/lib/rules/no-restricted-imports.js | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js index fe2fd148d38..b8fcca1aaf8 100644 --- a/lib/rules/no-restricted-imports.js +++ b/lib/rules/no-restricted-imports.js @@ -251,8 +251,8 @@ module.exports = { set.add("*"); } else if (specifier.imported) { set.add(specifier.imported.name); - } else if (specifier.exported) { - set.add(specifier.exported.name); + } else if (specifier.local) { + set.add(specifier.local.name); } return set; }, new Set()) : new Set(); diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js index 1daf8556778..c4f2abb602b 100644 --- a/tests/lib/rules/no-restricted-imports.js +++ b/tests/lib/rules/no-restricted-imports.js @@ -197,14 +197,20 @@ ruleTester.run("no-restricted-imports", rule, { code: "export * from \"fs\";", options: ["fs"], errors: [{ message: "'fs' import is restricted from being used.", type: "ExportAllDeclaration" }] - }, { - code: "export a from \"fs\";", - options: ["fs"], - errors: [{ message: "'fs' import is restricted from being used.", type: "ExportAllDeclaration" }] }, { code: "export {a} from \"fs\";", options: ["fs"], errors: [{ message: "'fs' import is restricted from being used.", type: "ExportNamedDeclaration" }] + }, { + code: "export {foo as b} from \"fs\";", + options: [{ + paths: [{ + name: "fs", + importNames: ["foo"], + message: "Don't import 'foo'." + }] + }], + errors: [{ message: "'fs' import is restricted from being used. Don't import 'foo'.", type: "ExportNamedDeclaration" }] }, { code: "import withGitignores from \"foo\";", options: [{