Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* New: Add no-restricted-exports rule (fixes #10428) * Remove `fixable` from meta * Change configuration
- Loading branch information
1 parent
1aff21b
commit 985dac3
Showing
5 changed files
with
651 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# Disallow specified names in exports (no-restricted-exports) | ||
|
||
In a project, certain names may be disallowed from being used as exported names for various reasons. | ||
|
||
## Rule Details | ||
|
||
This rule disallows specified names from being used as exported names. | ||
|
||
## Options | ||
|
||
By default, this rule doesn't disallow any names. Only the names you specify in the configuration will be disallowed. | ||
|
||
This rule has an object option: | ||
|
||
* `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted. | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
/*eslint no-restricted-exports: ["error", { | ||
"restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d"] | ||
}]*/ | ||
|
||
export const foo = 1; | ||
|
||
export function bar() {} | ||
|
||
export class Baz {} | ||
|
||
const a = {}; | ||
export { a }; | ||
|
||
function someFunction() {} | ||
export { someFunction as b }; | ||
|
||
export { c } from 'some_module'; | ||
|
||
export { something as d } from 'some_module'; | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
/*eslint no-restricted-exports: ["error", { | ||
"restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d"] | ||
}]*/ | ||
|
||
export const quux = 1; | ||
|
||
export function myFunction() {} | ||
|
||
export class MyClass {} | ||
|
||
const a = {}; | ||
export { a as myObject }; | ||
|
||
function someFunction() {} | ||
export { someFunction }; | ||
|
||
export { c as someName } from 'some_module'; | ||
|
||
export { something } from 'some_module'; | ||
``` | ||
|
||
### Default exports | ||
|
||
By design, this rule doesn't disallow `export default` declarations. If you configure `"default"` as a restricted name, that restriction will apply only to named export declarations. | ||
|
||
Examples of additional **incorrect** code for this rule: | ||
|
||
```js | ||
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/ | ||
|
||
function foo() {} | ||
|
||
export { foo as default }; | ||
``` | ||
|
||
```js | ||
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/ | ||
|
||
export { default } from 'some_module'; | ||
``` | ||
|
||
Examples of additional **correct** code for this rule: | ||
|
||
```js | ||
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default", "foo"] }]*/ | ||
|
||
export default function foo() {} | ||
``` | ||
|
||
## Known Limitations | ||
|
||
This rule doesn't inspect the content of source modules in re-export declarations. In particular, if you are re-exporting everything from another module's export, that export may include a restricted name. This rule cannot detect such cases. | ||
|
||
```js | ||
|
||
//----- some_module.js ----- | ||
export function foo() {} | ||
|
||
//----- my_module.js ----- | ||
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["foo"] }]*/ | ||
|
||
export * from 'some_module'; // allowed, although this declaration exports "foo" from my_module | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/** | ||
* @fileoverview Rule to disallow specified names in exports | ||
* @author Milos Djermanovic | ||
*/ | ||
|
||
"use strict"; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: { | ||
type: "suggestion", | ||
|
||
docs: { | ||
description: "disallow specified names in exports", | ||
category: "ECMAScript 6", | ||
recommended: false, | ||
url: "https://eslint.org/docs/rules/no-restricted-exports" | ||
}, | ||
|
||
schema: [{ | ||
type: "object", | ||
properties: { | ||
restrictedNamedExports: { | ||
type: "array", | ||
items: { | ||
type: "string" | ||
}, | ||
uniqueItems: true | ||
} | ||
}, | ||
additionalProperties: false | ||
}], | ||
|
||
messages: { | ||
restrictedNamed: "'{{name}}' is restricted from being used as an exported name." | ||
} | ||
}, | ||
|
||
create(context) { | ||
|
||
const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports); | ||
|
||
/** | ||
* Checks and reports given exported identifier. | ||
* @param {ASTNode} node exported `Identifer` node to check. | ||
* @returns {void} | ||
*/ | ||
function checkExportedName(node) { | ||
const name = node.name; | ||
|
||
if (restrictedNames.has(name)) { | ||
context.report({ | ||
node, | ||
messageId: "restrictedNamed", | ||
data: { name } | ||
}); | ||
} | ||
} | ||
|
||
return { | ||
ExportNamedDeclaration(node) { | ||
const declaration = node.declaration; | ||
|
||
if (declaration) { | ||
if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") { | ||
checkExportedName(declaration.id); | ||
} else if (declaration.type === "VariableDeclaration") { | ||
context.getDeclaredVariables(declaration) | ||
.map(v => v.defs.find(d => d.parent === declaration)) | ||
.map(d => d.name) // Identifier nodes | ||
.forEach(checkExportedName); | ||
} | ||
} else { | ||
node.specifiers | ||
.map(s => s.exported) | ||
.forEach(checkExportedName); | ||
} | ||
} | ||
}; | ||
} | ||
}; |
Oops, something went wrong.