-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
104 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
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,24 @@ | ||
# Forbid `require()` calls with expressions | ||
|
||
The `require` method from CommonJS is used to import modules from different files. Unlike the ES6 `import` syntax, it can be given expressions that will be resolved at runtime. While this is sometimes necessary and useful, in most cases it isn't. Using expressions (for instance, concatenating a path and variable) as the argument makes it harder for tools to do static code analysis, or to find where in the codebase a module is used. | ||
|
||
This rule checks every call to `require()` that uses expressions for the module name argument. | ||
|
||
## Rule Details | ||
|
||
### Fail | ||
|
||
```js | ||
require(name); | ||
require('../' + name); | ||
require(`../${name}`); | ||
require(name()); | ||
``` | ||
|
||
### Pass | ||
|
||
```js | ||
require('../name'); | ||
require('../name' + name); | ||
require(`../name`); | ||
``` |
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,25 @@ | ||
function isRequire(node) { | ||
return node && | ||
node.callee && | ||
node.callee.type === 'Identifier' && | ||
node.callee.name === 'require' && | ||
node.arguments.length >= 1 | ||
} | ||
|
||
function isStaticValue(arg) { | ||
return arg.type === 'Literal' || | ||
(arg.type === 'TemplateLiteral' && arg.expressions.length === 0) | ||
} | ||
|
||
module.exports = function (context) { | ||
return { | ||
CallExpression(node) { | ||
if (isRequire(node) && !isStaticValue(node.arguments[0])) { | ||
context.report({ | ||
node, | ||
message: 'Calls to require() should use string literals', | ||
}) | ||
} | ||
}, | ||
} | ||
} |
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,49 @@ | ||
import { test } from '../utils' | ||
|
||
import { RuleTester } from 'eslint' | ||
|
||
const ruleTester = new RuleTester() | ||
, rule = require('rules/no-dynamic-require') | ||
|
||
const error = { | ||
ruleId: 'no-dynamic-require', | ||
message: 'Calls to require() should use string literals', | ||
} | ||
|
||
ruleTester.run('no-dynamic-require', rule, { | ||
valid: [ | ||
test({ code: 'import _ from "lodash"'}), | ||
test({ code: 'require("foo")'}), | ||
test({ code: 'require(`foo`)'}), | ||
test({ code: 'require("./foo")'}), | ||
test({ code: 'require("@scope/foo")'}), | ||
test({ code: 'require()'}), | ||
test({ code: 'require("./foo", "bar" + "okay")'}), | ||
test({ code: 'var foo = require("foo")'}), | ||
test({ code: 'var foo = require(`foo`)'}), | ||
test({ code: 'var foo = require("./foo")'}), | ||
test({ code: 'var foo = require("@scope/foo")'}), | ||
], | ||
invalid: [ | ||
test({ | ||
code: 'require("../" + name)', | ||
errors: [error], | ||
}), | ||
test({ | ||
code: 'require(`../${name}`)', | ||
errors: [error], | ||
}), | ||
test({ | ||
code: 'require(name)', | ||
errors: [error], | ||
}), | ||
test({ | ||
code: 'require(name())', | ||
errors: [error], | ||
}), | ||
test({ | ||
code: 'require(name + "foo", "bar")', | ||
errors: [error], | ||
}), | ||
], | ||
}) |