From 56c45161f3746f259d918d1654386626006ebe78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=AF=E7=84=B6?= Date: Wed, 12 May 2021 07:23:24 +0800 Subject: [PATCH] fix: no-unresolved check import() (fixes #2024) --- CHANGELOG.md | 2 ++ tests/src/rules/no-unresolved.js | 22 ++++++++++++++++++++-- tests/src/utils.js | 4 ++++ utils/moduleVisitor.js | 14 +++++++++++--- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 438efefc98..39dbaf52de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`no-extraneous-dependencies`]: Exclude flow `typeof` imports ([#1534], thanks [@devongovett]) - [`newline-after-import`]: respect decorator annotations ([#1985], thanks [@lilling]) - [`no-restricted-paths`]: enhance performance for zones with `except` paths ([#2022], thanks [@malykhinvi]) +- [`no-unresolved`]: Check dynamic imports when using the built-in Eslint parser ([#2026], thanks [@aladdin-add]) ### Changed - [Generic Import Callback] Make callback for all imports once in rules ([#1237], thanks [@ljqx]) @@ -1355,3 +1356,4 @@ for info on changes for earlier releases. [@s-h-a-d-o-w]: https://github.com/s-h-a-d-o-w [@grit96]: https://github.com/grit96 [@lilling]: https://github.com/lilling +[@aladdin-add]: https://github.com/aladdin-add diff --git a/tests/src/rules/no-unresolved.js b/tests/src/rules/no-unresolved.js index da7d4dc5ae..e4dba2f2e6 100644 --- a/tests/src/rules/no-unresolved.js +++ b/tests/src/rules/no-unresolved.js @@ -1,6 +1,6 @@ import * as path from 'path'; -import { test, SYNTAX_CASES } from '../utils'; +import { test, SYNTAX_CASES, satisfiesEslint } from '../utils'; import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve'; @@ -93,7 +93,6 @@ function runResolverTests(resolver) { '\'./reallyfake/module\'.' }], }), - rest({ code: "import bar from './baz';", errors: [{ message: "Unable to resolve path to module './baz'.", @@ -382,3 +381,22 @@ ruleTester.run('no-unresolved syntax verification', rule, { valid: SYNTAX_CASES, invalid:[], }); + +// https://github.com/benmosher/eslint-plugin-import/issues/2024 +satisfiesEslint('>=7') && ruleTester.run('import() with eslint v7 built-in parser', rule, { + valid: [ + { + code: "import('fs');", + parser: require.resolve('espree'), + parserOptions: { ecmaVersion: 2021 }, + }, + ], + invalid: [ + { + code: 'import("./does-not-exist").then(() => {})', + parser: require.resolve('espree'), + parserOptions: { ecmaVersion: 2021 }, + errors: ["Unable to resolve path to module './does-not-exist'."], + }, + ], +}); diff --git a/tests/src/utils.js b/tests/src/utils.js index a76826de51..566b0eac25 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -31,6 +31,10 @@ export function testVersion(specifier, t) { return semver.satisfies(eslintPkg.version, specifier) && test(t()); } +export function satisfiesEslint(specifier) { + return semver.satisfies(eslintPkg.version, specifier); +} + export function test(t) { return Object.assign({ filename: FILENAME, diff --git a/utils/moduleVisitor.js b/utils/moduleVisitor.js index d801515bce..69269985bd 100644 --- a/utils/moduleVisitor.js +++ b/utils/moduleVisitor.js @@ -36,10 +36,17 @@ exports.default = function visitModules(visitor, options) { // for esmodule dynamic `import()` calls function checkImportCall(node) { - if (node.callee.type !== 'Import') return; - if (node.arguments.length !== 1) return; + let modulePath; + // refs https://github.com/estree/estree/blob/master/es2020.md#importexpression + if (node.type === 'ImportExpression') { + modulePath = node.source; + } else if (node.type === 'CallExpression') { + if (node.callee.type !== 'Import') return; + if (node.arguments.length !== 1) return; + + modulePath = node.arguments[0]; + } - const modulePath = node.arguments[0]; if (modulePath.type !== 'Literal') return; if (typeof modulePath.value !== 'string') return; @@ -87,6 +94,7 @@ exports.default = function visitModules(visitor, options) { 'ExportNamedDeclaration': checkSource, 'ExportAllDeclaration': checkSource, 'CallExpression': checkImportCall, + 'ImportExpression': checkImportCall, }); }