Skip to content

Commit d8fd2ba

Browse files
committed
[Fix] [Generic Import Callback] Make callback for all import once in rules
Fixes #1230.
1 parent 957092a commit d8fd2ba

9 files changed

+124
-94
lines changed

src/rules/extensions.js

+3-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import path from 'path'
22

33
import resolve from 'eslint-module-utils/resolve'
44
import { isBuiltIn, isExternalModule, isScoped, isScopedModule } from '../core/importType'
5+
import moduleVisitor from 'eslint-module-utils/moduleVisitor'
56
import docsUrl from '../docsUrl'
67

78
const enumValues = { enum: [ 'always', 'ignorePackages', 'never' ] }
@@ -134,12 +135,7 @@ module.exports = {
134135
return false
135136
}
136137

137-
function checkFileExtension(node) {
138-
const { source } = node
139-
140-
// bail if the declaration doesn't have a source, e.g. "export { foo };"
141-
if (!source) return
142-
138+
function checkFileExtension(source) {
143139
const importPathWithQueryString = source.value
144140

145141
// don't enforce anything on builtins
@@ -181,9 +177,6 @@ module.exports = {
181177
}
182178
}
183179

184-
return {
185-
ImportDeclaration: checkFileExtension,
186-
ExportNamedDeclaration: checkFileExtension,
187-
}
180+
return moduleVisitor(checkFileExtension, { commonjs: true })
188181
},
189182
}

src/rules/max-dependencies.js

+6-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import isStaticRequire from '../core/staticRequire'
1+
import moduleVisitor from 'eslint-module-utils/moduleVisitor'
22
import docsUrl from '../docsUrl'
33

44
const DEFAULT_MAX = 10
@@ -36,23 +36,13 @@ module.exports = {
3636
const dependencies = new Set() // keep track of dependencies
3737
let lastNode // keep track of the last node to report on
3838

39-
return {
40-
ImportDeclaration(node) {
41-
dependencies.add(node.source.value)
42-
lastNode = node.source
43-
},
44-
45-
CallExpression(node) {
46-
if (isStaticRequire(node)) {
47-
const [ requirePath ] = node.arguments
48-
dependencies.add(requirePath.value)
49-
lastNode = node
50-
}
51-
},
52-
39+
return Object.assign({
5340
'Program:exit': function () {
5441
countDependencies(dependencies, lastNode, context)
5542
},
56-
}
43+
}, moduleVisitor((source) => {
44+
dependencies.add(source.value)
45+
lastNode = source
46+
}, { commonjs: true }))
5747
},
5848
}

src/rules/no-extraneous-dependencies.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ module.exports = {
200200
allowBundledDeps: testConfig(options.bundledDependencies, filename) !== false,
201201
}
202202

203-
return moduleVisitor(node => {
204-
reportIfMissing(context, deps, depsOptions, node, node.value)
203+
return moduleVisitor((source, node) => {
204+
reportIfMissing(context, deps, depsOptions, node, source.value)
205205
}, {commonjs: true})
206206
},
207207
}

src/rules/no-internal-modules.js

+4-20
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import minimatch from 'minimatch'
22

33
import resolve from 'eslint-module-utils/resolve'
44
import importType from '../core/importType'
5-
import isStaticRequire from '../core/staticRequire'
5+
import moduleVisitor from 'eslint-module-utils/moduleVisitor'
66
import docsUrl from '../docsUrl'
77

88
module.exports = {
@@ -87,24 +87,8 @@ module.exports = {
8787
}
8888
}
8989

90-
return {
91-
ImportDeclaration(node) {
92-
checkImportForReaching(node.source.value, node.source)
93-
},
94-
ExportAllDeclaration(node) {
95-
checkImportForReaching(node.source.value, node.source)
96-
},
97-
ExportNamedDeclaration(node) {
98-
if (node.source) {
99-
checkImportForReaching(node.source.value, node.source)
100-
}
101-
},
102-
CallExpression(node) {
103-
if (isStaticRequire(node)) {
104-
const [ firstArgument ] = node.arguments
105-
checkImportForReaching(firstArgument.value, firstArgument)
106-
}
107-
},
108-
}
90+
return moduleVisitor((source) => {
91+
checkImportForReaching(source.value, source)
92+
}, { commonjs: true })
10993
},
11094
}

src/rules/no-nodejs-modules.js

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import importType from '../core/importType'
2-
import isStaticRequire from '../core/staticRequire'
2+
import moduleVisitor from 'eslint-module-utils/moduleVisitor'
33
import docsUrl from '../docsUrl'
44

55
function reportIfMissing(context, node, allowed, name) {
@@ -35,15 +35,8 @@ module.exports = {
3535
const options = context.options[0] || {}
3636
const allowed = options.allow || []
3737

38-
return {
39-
ImportDeclaration: function handleImports(node) {
40-
reportIfMissing(context, node, allowed, node.source.value)
41-
},
42-
CallExpression: function handleRequires(node) {
43-
if (isStaticRequire(node)) {
44-
reportIfMissing(context, node, allowed, node.arguments[0].value)
45-
}
46-
},
47-
}
38+
return moduleVisitor((source, node) => {
39+
reportIfMissing(context, node, allowed, source.value)
40+
}, { commonjs: true })
4841
},
4942
}

src/rules/no-restricted-paths.js

+4-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import containsPath from 'contains-path'
22
import path from 'path'
33

44
import resolve from 'eslint-module-utils/resolve'
5-
import isStaticRequire from '../core/staticRequire'
5+
import moduleVisitor from 'eslint-module-utils/moduleVisitor'
66
import docsUrl from '../docsUrl'
77
import importType from '../core/importType'
88

@@ -109,17 +109,8 @@ module.exports = {
109109
})
110110
}
111111

112-
return {
113-
ImportDeclaration(node) {
114-
checkForRestrictedImportPath(node.source.value, node.source)
115-
},
116-
CallExpression(node) {
117-
if (isStaticRequire(node)) {
118-
const [ firstArgument ] = node.arguments
119-
120-
checkForRestrictedImportPath(firstArgument.value, firstArgument)
121-
}
122-
},
123-
}
112+
return moduleVisitor((source) => {
113+
checkForRestrictedImportPath(source.value, source)
114+
}, { commonjs: true })
124115
},
125116
}

src/rules/no-self-import.js

+4-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import resolve from 'eslint-module-utils/resolve'
7-
import isStaticRequire from '../core/staticRequire'
7+
import moduleVisitor from 'eslint-module-utils/moduleVisitor'
88
import docsUrl from '../docsUrl'
99

1010
function isImportingSelf(context, node, requireName) {
@@ -31,15 +31,8 @@ module.exports = {
3131
schema: [],
3232
},
3333
create: function (context) {
34-
return {
35-
ImportDeclaration(node) {
36-
isImportingSelf(context, node, node.source.value)
37-
},
38-
CallExpression(node) {
39-
if (isStaticRequire(node)) {
40-
isImportingSelf(context, node, node.arguments[0].value)
41-
}
42-
},
43-
}
34+
return moduleVisitor((source, node) => {
35+
isImportingSelf(context, node, source.value)
36+
}, { commonjs: true })
4437
},
4538
}

src/rules/no-webpack-loader-syntax.js

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import isStaticRequire from '../core/staticRequire'
1+
import moduleVisitor from 'eslint-module-utils/moduleVisitor'
22
import docsUrl from '../docsUrl'
33

44
function reportIfNonStandard(context, node, name) {
@@ -19,15 +19,8 @@ module.exports = {
1919
},
2020

2121
create: function (context) {
22-
return {
23-
ImportDeclaration: function handleImports(node) {
24-
reportIfNonStandard(context, node, node.source.value)
25-
},
26-
CallExpression: function handleRequires(node) {
27-
if (isStaticRequire(node)) {
28-
reportIfNonStandard(context, node, node.arguments[0].value)
29-
}
30-
},
31-
}
22+
return moduleVisitor((source, node) => {
23+
reportIfNonStandard(context, node, source.value)
24+
}, { commonjs: true })
3225
},
3326
}

tests/src/rules/extensions.js

+93
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,22 @@ ruleTester.run('extensions', rule, {
391391
options: [ 'never', {ignorePackages: true} ],
392392
}),
393393

394+
test({
395+
code: `
396+
import foo from './foo.js'
397+
import bar from './bar.json'
398+
import Component from './Component.jsx'
399+
`,
400+
errors: [
401+
{
402+
message: 'Unexpected use of file extension "jsx" for "./Component.jsx"',
403+
line: 4,
404+
column: 31,
405+
},
406+
],
407+
options: [ 'always', {pattern: {jsx: 'never'}} ],
408+
}),
409+
394410
// export (#964)
395411
test({
396412
code: [
@@ -444,6 +460,48 @@ ruleTester.run('extensions', rule, {
444460
},
445461
],
446462
}),
463+
// require (#1230)
464+
test({
465+
code: [
466+
'const { foo } = require("./foo")',
467+
'export { foo }',
468+
].join('\n'),
469+
options: [ 'always' ],
470+
errors: [
471+
{
472+
message: 'Missing file extension for "./foo"',
473+
line: 1,
474+
column: 25,
475+
},
476+
],
477+
}),
478+
test({
479+
code: [
480+
'const { foo } = require("./foo.js")',
481+
'export { foo }',
482+
].join('\n'),
483+
options: [ 'never' ],
484+
errors: [
485+
{
486+
message: 'Unexpected use of file extension "js" for "./foo.js"',
487+
line: 1,
488+
column: 25,
489+
},
490+
],
491+
}),
492+
493+
// export { } from
494+
test({
495+
code: 'export { foo } from "./foo"',
496+
options: [ 'always' ],
497+
errors: [
498+
{
499+
message: 'Missing file extension for "./foo"',
500+
line: 1,
501+
column: 21,
502+
},
503+
],
504+
}),
447505
test({
448506
code: 'import foo from "@/ImNotAScopedModule"',
449507
options: ['always'],
@@ -454,5 +512,40 @@ ruleTester.run('extensions', rule, {
454512
},
455513
],
456514
}),
515+
test({
516+
code: 'export { foo } from "./foo.js"',
517+
options: [ 'never' ],
518+
errors: [
519+
{
520+
message: 'Unexpected use of file extension "js" for "./foo.js"',
521+
line: 1,
522+
column: 21,
523+
},
524+
],
525+
}),
526+
527+
// export * from
528+
test({
529+
code: 'export * from "./foo"',
530+
options: [ 'always' ],
531+
errors: [
532+
{
533+
message: 'Missing file extension for "./foo"',
534+
line: 1,
535+
column: 15,
536+
},
537+
],
538+
}),
539+
test({
540+
code: 'export * from "./foo.js"',
541+
options: [ 'never' ],
542+
errors: [
543+
{
544+
message: 'Unexpected use of file extension "js" for "./foo.js"',
545+
line: 1,
546+
column: 15,
547+
},
548+
],
549+
}),
457550
],
458551
})

0 commit comments

Comments
 (0)