Skip to content

Commit

Permalink
[New] no-dynamic-require: support dynamic import with espree
Browse files Browse the repository at this point in the history
  • Loading branch information
sosukesuzuki committed Jan 25, 2022
1 parent 0ded887 commit 9ea1536
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 75 deletions.
13 changes: 12 additions & 1 deletion src/rules/no-dynamic-require.js
Expand Up @@ -19,6 +19,8 @@ function isStaticValue(arg) {
(arg.type === 'TemplateLiteral' && arg.expressions.length === 0);
}

const dynamicImportErrorMessage = 'Calls to import() should use string literals';

module.exports = {
meta: {
type: 'suggestion',
Expand Down Expand Up @@ -55,10 +57,19 @@ module.exports = {
if (options.esmodule && isDynamicImport(node)) {
return context.report({
node,
message: 'Calls to import() should use string literals',
message: dynamicImportErrorMessage,
});
}
},
ImportExpression(node) {
if (!options.esmodule || isStaticValue(node.source)) {
return;
}
return context.report({
node,
message: dynamicImportErrorMessage,
});
},
};
},
};
208 changes: 134 additions & 74 deletions tests/src/rules/no-dynamic-require.js
@@ -1,10 +1,13 @@
import { parsers, test } from '../utils';
import { parsers, test, testVersion } from '../utils';

import { RuleTester } from 'eslint';
import flatMap from 'array.prototype.flatmap';

const ruleTester = new RuleTester();
const rule = require('rules/no-dynamic-require');

const espree = require.resolve('espree');

const error = {
message: 'Calls to require() should use string literals',
};
Expand All @@ -28,56 +31,93 @@ ruleTester.run('no-dynamic-require', rule, {
test({ code: 'var foo = require("@scope/foo")' }),

//dynamic import
test({
code: 'import("foo")',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'import(`foo`)',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'import("./foo")',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'import("@scope/foo")',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'var foo = import("foo")',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'var foo = import(`foo`)',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'var foo = import("./foo")',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'var foo = import("@scope/foo")',
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'import("../" + name)',
errors: [dynamicImportError],
parser: parsers.BABEL_OLD,
options: [{ esmodule: false }],
}),
test({
code: 'import(`../${name}`)',
errors: [dynamicImportError],
parser: parsers.BABEL_OLD,
...flatMap([espree, parsers.BABEL_OLD], (parser) => {
const _test =
parser === espree
? (testObj) => testVersion('>= 6.2.0', () => testObj)
: (testObj) => test(testObj);
return [
_test({
code: 'import("foo")',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import(`foo`)',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import("./foo")',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import("@scope/foo")',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'var foo = import("foo")',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'var foo = import(`foo`)',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'var foo = import("./foo")',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'var foo = import("@scope/foo")',
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import("../" + name)',
errors: [dynamicImportError],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import(`../${name}`)',
errors: [dynamicImportError],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
];
}),
],
invalid: [
Expand All @@ -104,29 +144,49 @@ ruleTester.run('no-dynamic-require', rule, {
}),

// dynamic import
test({
code: 'import("../" + name)',
errors: [dynamicImportError],
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'import(`../${name}`)',
errors: [dynamicImportError],
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'import(name)',
errors: [dynamicImportError],
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
}),
test({
code: 'import(name())',
errors: [dynamicImportError],
parser: parsers.BABEL_OLD,
options: [{ esmodule: true }],
...flatMap([espree, parsers.BABEL_OLD], (parser) => {
const _test =
parser === espree
? (testObj) => testVersion('>= 6.2.0', () => testObj)
: (testObj) => test(testObj);
return [
_test({
code: 'import("../" + name)',
errors: [dynamicImportError],
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import(`../${name}`)',
errors: [dynamicImportError],
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import(name)',
errors: [dynamicImportError],
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
_test({
code: 'import(name())',
errors: [dynamicImportError],
options: [{ esmodule: true }],
parser,
parserOptions: {
ecmaVersion: 2020,
},
}),
];
}),
test({
code: 'require(`foo${x}`)',
Expand Down

0 comments on commit 9ea1536

Please sign in to comment.