Skip to content

Commit

Permalink
Fix: no-restricted-imports to check re-export (fixes #9678)
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Nov 7, 2018
1 parent 7ad86de commit b76f9a6
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 23 deletions.
16 changes: 15 additions & 1 deletion 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?

Expand Down Expand Up @@ -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"] }]*/

Expand Down Expand Up @@ -135,13 +147,15 @@ Examples of **correct** code for this rule:
/*eslint no-restricted-imports: ["error", "fs"]*/

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

```js
/*eslint no-restricted-imports: ["error", { "paths": ["fs"], "patterns": ["eslint/*"] }]*/

import crypto from 'crypto';
import eslint from 'eslint';
export * from "path";
```

```js
Expand Down
60 changes: 38 additions & 22 deletions lib/rules/no-restricted-imports.js
Expand Up @@ -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
};
}
};
12 changes: 12 additions & 0 deletions tests/lib/rules/no-restricted-imports.js
Expand Up @@ -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: [{
Expand Down

0 comments on commit b76f9a6

Please sign in to comment.