Skip to content

Commit ee15fa4

Browse files
authored
Merge pull request #880 from futpib/no-commonjs-allow-require
Add `allow-require` option to `no-commonjs` rule
2 parents 48d0a8a + c438d3e commit ee15fa4

File tree

3 files changed

+66
-6
lines changed

3 files changed

+66
-6
lines changed

docs/rules/no-commonjs.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,29 @@ module.exports = { a: "b" }
2121
exports.c = "d"
2222
```
2323

24-
If `allow-primitive-modules` is provided as an option, the following is valid:
24+
### Allow require
25+
26+
If `allowRequire` option is set to `true`, `require` calls are valid:
27+
28+
```js
29+
/*eslint no-commonjs: [2, { allowRequire: true }]*/
30+
31+
if (typeof window !== "undefined") {
32+
require('that-ugly-thing');
33+
}
34+
```
35+
36+
but `module.exports` is reported as usual.
37+
38+
This is useful for conditional requires.
39+
If you don't rely on synchronous module loading, check out [dynamic import](https://github.com/airbnb/babel-plugin-dynamic-import-node).
40+
41+
### Allow primitive modules
42+
43+
If `allowPrimitiveModules` option is set to `true`, the following is valid:
2544

2645
```js
27-
/*eslint no-commonjs: [2, "allow-primitive-modules"]*/
46+
/*eslint no-commonjs: [2, { allowPrimitiveModules: true }]*/
2847

2948
module.exports = "foo"
3049
module.exports = function rule(context) { return { /* ... */ } }
@@ -33,7 +52,7 @@ module.exports = function rule(context) { return { /* ... */ } }
3352
but this is still reported:
3453

3554
```js
36-
/*eslint no-commonjs: [2, "allow-primitive-modules"]*/
55+
/*eslint no-commonjs: [2, { allowPrimitiveModules: true }]*/
3756

3857
module.exports = { x: "y" }
3958
exports.z = function boop() { /* ... */ }

src/rules/no-commonjs.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,69 @@ import docsUrl from '../docsUrl'
88
const EXPORT_MESSAGE = 'Expected "export" or "export default"'
99
, IMPORT_MESSAGE = 'Expected "import" instead of "require()"'
1010

11-
function allowPrimitive(node, context) {
12-
if (context.options.indexOf('allow-primitive-modules') < 0) return false
11+
function normalizeLegacyOptions(options) {
12+
if (options.indexOf('allow-primitive-modules') >= 0) {
13+
return { allowPrimitiveModules: true }
14+
}
15+
return options[0] || {}
16+
}
17+
18+
function allowPrimitive(node, options) {
19+
if (!options.allowPrimitiveModules) return false
1320
if (node.parent.type !== 'AssignmentExpression') return false
1421
return (node.parent.right.type !== 'ObjectExpression')
1522
}
1623

24+
function allowRequire(node, options) {
25+
return options.allowRequire
26+
}
27+
1728
//------------------------------------------------------------------------------
1829
// Rule Definition
1930
//------------------------------------------------------------------------------
2031

32+
const schemaString = { enum: ['allow-primitive-modules'] }
33+
const schemaObject = {
34+
type: 'object',
35+
properties: {
36+
allowPrimitiveModules: { 'type': 'boolean' },
37+
allowRequire: { 'type': 'boolean' },
38+
},
39+
additionalProperties: false,
40+
}
2141

2242
module.exports = {
2343
meta: {
2444
docs: {
2545
url: docsUrl('no-commonjs'),
2646
},
47+
48+
schema: {
49+
anyOf: [
50+
{
51+
type: 'array',
52+
items: [schemaString],
53+
additionalItems: false,
54+
},
55+
{
56+
type: 'array',
57+
items: [schemaObject],
58+
additionalItems: false,
59+
},
60+
],
61+
},
2762
},
2863

2964
create: function (context) {
65+
const options = normalizeLegacyOptions(context.options)
3066

3167
return {
3268

3369
'MemberExpression': function (node) {
3470

3571
// module.exports
3672
if (node.object.name === 'module' && node.property.name === 'exports') {
37-
if (allowPrimitive(node, context)) return
73+
if (allowPrimitive(node, options)) return
3874
context.report({ node, message: EXPORT_MESSAGE })
3975
}
4076

@@ -65,6 +101,8 @@ module.exports = {
65101
if (module.type !== 'Literal') return
66102
if (typeof module.value !== 'string') return
67103

104+
if (allowRequire(call, options)) return
105+
68106
// keeping it simple: all 1-string-arg `require` calls are reported
69107
context.report({
70108
node: call.callee,

tests/src/rules/no-commonjs.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ ruleTester.run('no-commonjs', require('rules/no-commonjs'), {
3737
{ code: "var bar = proxyquire('./bar');" },
3838
{ code: "var bar = require('./ba' + 'r');" },
3939
{ code: 'var zero = require(0);' },
40+
{ code: 'require("x")', options: [{ allowRequire: true }] },
4041

4142
{ code: 'module.exports = function () {}', options: ['allow-primitive-modules'] },
43+
{ code: 'module.exports = function () {}', options: [{ allowPrimitiveModules: true }] },
4244
{ code: 'module.exports = "foo"', options: ['allow-primitive-modules'] },
45+
{ code: 'module.exports = "foo"', options: [{ allowPrimitiveModules: true }] },
4346
],
4447

4548
invalid: [

0 commit comments

Comments
 (0)