From e66cf69cc27b8a8900f14af746ed6925c8af8fdc Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Sat, 23 Jul 2022 15:09:45 +0800 Subject: [PATCH] fix: support multiline dynamic imports (#9314) --- packages/vite/src/node/plugins/dynamicImportVars.ts | 13 ++++++++----- packages/vite/src/node/utils.ts | 4 ++++ .../dynamic-import/__tests__/dynamic-import.spec.ts | 8 ++++++++ playground/dynamic-import/nested/index.js | 9 +++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/plugins/dynamicImportVars.ts b/packages/vite/src/node/plugins/dynamicImportVars.ts index 97f605c1758d53..b7d5ed5a5f8792 100644 --- a/packages/vite/src/node/plugins/dynamicImportVars.ts +++ b/packages/vite/src/node/plugins/dynamicImportVars.ts @@ -10,6 +10,7 @@ import { createFilter, normalizePath, parseRequest, + removeComments, requestQuerySplitRE, transformStableResult } from '../utils' @@ -176,11 +177,13 @@ export function dynamicImportVarsPlugin(config: ResolvedConfig): Plugin { s ||= new MagicString(source) let result try { - result = await transformDynamicImport( - source.slice(start, end), - importer, - resolve - ) + // When import string is using backticks, es-module-lexer `end` captures + // until the closing parenthesis, instead of the closing backtick. + // There may be inline comments between the backtick and the closing + // parenthesis, so we manually remove them for now. + // See https://github.com/guybedford/es-module-lexer/issues/118 + const importSource = removeComments(source.slice(start, end)).trim() + result = await transformDynamicImport(importSource, importer, resolve) } catch (error) { if (warnOnError) { this.warn(error) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 4398ec70f56121..85f85adf3cf550 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -984,6 +984,10 @@ export function emptyCssComments(raw: string): string { return raw.replace(multilineCommentsRE, (s) => ' '.repeat(s.length)) } +export function removeComments(raw: string): string { + return raw.replace(multilineCommentsRE, '').replace(singlelineCommentsRE, '') +} + function mergeConfigRecursively( defaults: Record, overrides: Record, diff --git a/playground/dynamic-import/__tests__/dynamic-import.spec.ts b/playground/dynamic-import/__tests__/dynamic-import.spec.ts index 86c42a4d79a7e5..c8a90a32aeaf75 100644 --- a/playground/dynamic-import/__tests__/dynamic-import.spec.ts +++ b/playground/dynamic-import/__tests__/dynamic-import.spec.ts @@ -68,6 +68,14 @@ test('should load dynamic import with vars', async () => { ) }) +test('should load dynamic import with vars multiline', async () => { + await untilUpdated( + () => page.textContent('.dynamic-import-with-vars'), + 'hello', + true + ) +}) + test('should load dynamic import with vars alias', async () => { await untilUpdated( () => page.textContent('.dynamic-import-with-vars-alias'), diff --git a/playground/dynamic-import/nested/index.js b/playground/dynamic-import/nested/index.js index 0b229055b32b7c..75d6c0fdd9b224 100644 --- a/playground/dynamic-import/nested/index.js +++ b/playground/dynamic-import/nested/index.js @@ -84,6 +84,15 @@ import(`../alias/${base}.js`).then((mod) => { text('.dynamic-import-with-vars', mod.hello()) }) +// prettier-ignore +import( + /* this messes with */ + `../alias/${base}.js` + /* es-module-lexer */ +).then((mod) => { + text('.dynamic-import-with-vars-multiline', mod.hello()) +}) + import(`../alias/${base}.js?raw`).then((mod) => { text('.dynamic-import-with-vars-raw', JSON.stringify(mod)) })