Skip to content

Commit 8ff322d

Browse files
committed
Extend no-extraneous-dependencies to support globs and arrays.
1 parent 1be4720 commit 8ff322d

File tree

4 files changed

+73
-12
lines changed

4 files changed

+73
-12
lines changed

docs/rules/no-extraneous-dependencies.md

+15-3
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ You can set the options like this:
1919
"import/no-extraneous-dependencies": ["error", {"devDependencies": false, "optionalDependencies": false, "peerDependencies": false}]
2020
```
2121

22-
You can also use regular expressions instead of literal booleans:
22+
You can also use globs instead of literal booleans:
2323

2424
```js
25-
"import/no-extraneous-dependencies": ["error", {"devDependencies": "test|spec"}]
25+
"import/no-extraneous-dependencies": ["error", {"devDependencies": "*.test.js"}]
26+
```
27+
28+
You can also use regular expressions instead of literal booleans or globs (note: the string must begin and end with `/`):
29+
30+
```js
31+
"import/no-extraneous-dependencies": ["error", {"devDependencies": "/test|spec/"}]
2632
```
2733

2834
If you are using JavaScript configuration (e.g., `.eslintrc.js`), then you can use a RegExp literal instead of a string:
@@ -31,7 +37,13 @@ If you are using JavaScript configuration (e.g., `.eslintrc.js`), then you can u
3137
"import/no-extraneous-dependencies": ["error", {"devDependencies": /test|spec/}]
3238
```
3339

34-
When using a regular expression, the setting will be activated if the name of the file being linted matches the given regular expression. For example, the above configurations will allow the import of `devDependencies` in files whose names include `test` or `spec`.
40+
When using a glob or regular expression, the setting will be activated if the name of the file being linted matches the given glob or regular expression. In addition, you can use an array to specify multiple globs or regular expressions:
41+
42+
```js
43+
"import/no-extraneous-dependencies": ["error", {"devDependencies": [/test/, '/spec/', '*.test.js', '*.spec.js']}]
44+
```
45+
46+
When using an array of globs or regular expressions, the setting will be activated if the name of the file being linted matches a single glob or regular expression in the array.
3547

3648
## Rule Details
3749

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"lodash.endswith": "^4.0.1",
8282
"lodash.find": "^4.3.0",
8383
"lodash.findindex": "^4.3.0",
84+
"minimatch": "^3.0.3",
8485
"object-assign": "^4.0.1",
8586
"pkg-dir": "^1.0.0",
8687
"pkg-up": "^1.0.0"

src/rules/no-extraneous-dependencies.js

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from 'fs'
22
import pkgUp from 'pkg-up'
3+
import minimatch from 'minimatch'
34
import importType from '../core/importType'
45
import isStaticRequire from '../core/staticRequire'
56

@@ -72,11 +73,25 @@ function reportIfMissing(context, deps, depsOptions, node, name) {
7273
}
7374

7475
function testConfig(config, filename) {
76+
// Simplest configuration first
7577
if (typeof config === 'boolean' || typeof config === 'undefined') {
7678
return config
7779
}
78-
const pattern = new RegExp(config) // `config` is either a string or RegExp
79-
return pattern.test(filename)
80+
// Account for the possibility of an array for multiple configuration
81+
return [].concat(config).some(c => {
82+
if (typeof c === 'object') {
83+
// `c` is a literal RegExp
84+
return c.test(filename)
85+
}
86+
// By this point `c` must be a string.
87+
if (/^\/.+\/$/.test(c)) {
88+
// `c` is a string representation of a RegExp.
89+
const pattern = new RegExp(c.substring(1, c.length - 1))
90+
return pattern.test(filename)
91+
}
92+
// `c` must be a string representing a glob
93+
return minimatch(filename, c)
94+
})
8095
}
8196

8297
module.exports = function (context) {
@@ -111,9 +126,9 @@ module.exports.schema = [
111126
{
112127
'type': 'object',
113128
'properties': {
114-
'devDependencies': { 'type': ['boolean', 'string', 'object'] },
115-
'optionalDependencies': { 'type': ['boolean', 'string', 'object'] },
116-
'peerDependencies': { 'type': ['boolean', 'string', 'object'] },
129+
'devDependencies': { 'type': ['boolean', 'string', 'object', 'array'] },
130+
'optionalDependencies': { 'type': ['boolean', 'string', 'object', 'array'] },
131+
'peerDependencies': { 'type': ['boolean', 'string', 'object', 'array'] },
117132
},
118133
'additionalProperties': false,
119134
},

tests/src/rules/no-extraneous-dependencies.js

+37-4
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,27 @@ ruleTester.run('no-extraneous-dependencies', rule, {
3838
test({
3939
code: 'import chai from "chai"',
4040
options: [{devDependencies: /test|spec/}],
41-
filename: 'glob.test.js',
41+
filename: 'foo.test.js',
4242
}),
4343
test({
4444
code: 'import chai from "chai"',
45-
options: [{devDependencies: 'test|spec'}],
46-
filename: 'glob.spec.js',
45+
options: [{devDependencies: '/test|spec/'}],
46+
filename: 'foo.spec.js',
47+
}),
48+
test({
49+
code: 'import chai from "chai"',
50+
options: [{devDependencies: '*.spec.js'}],
51+
filename: 'foo.spec.js',
52+
}),
53+
test({
54+
code: 'import chai from "chai"',
55+
options: [{devDependencies: ['*.test.js', '*.spec.js']}],
56+
filename: 'foo.spec.js',
57+
}),
58+
test({
59+
code: 'import chai from "chai"',
60+
options: [{devDependencies: [/\.test\.js$/, /\.spec\.js$/]}],
61+
filename: 'foo.spec.js',
4762
}),
4863
],
4964
invalid: [
@@ -110,7 +125,25 @@ ruleTester.run('no-extraneous-dependencies', rule, {
110125
}),
111126
test({
112127
code: 'import chai from "chai"',
113-
options: [{devDependencies: 'test|spec'}],
128+
options: [{devDependencies: '/test|spec/'}],
129+
filename: 'foo.tes.js',
130+
errors: [{
131+
ruleId: 'no-extraneous-dependencies',
132+
message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.',
133+
}],
134+
}),
135+
test({
136+
code: 'import chai from "chai"',
137+
options: [{devDependencies: '*.test.js'}],
138+
filename: 'foo.tes.js',
139+
errors: [{
140+
ruleId: 'no-extraneous-dependencies',
141+
message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.',
142+
}],
143+
}),
144+
test({
145+
code: 'import chai from "chai"',
146+
options: [{devDependencies: ['*.test.js', /test\.js$/, '/test/']}],
114147
filename: 'foo.tes.js',
115148
errors: [{
116149
ruleId: 'no-extraneous-dependencies',

0 commit comments

Comments
 (0)