From 778ee0392ca25cbfea044ed6f3cf2db62dacfdc1 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Tue, 31 Aug 2021 11:54:39 +0200 Subject: [PATCH] Fix wrong offset with comments in dynamic imports --- .changeset/proud-shoes-explode.md | 5 +++++ packages/wmr/src/lib/transform-imports.js | 7 +++++++ .../dynamic-import-comment.expected.js | 2 ++ .../dynamic-import-comment.js | 2 ++ packages/wmr/test/transform-imports.test.js | 13 +++++++++++++ 5 files changed, 29 insertions(+) create mode 100644 .changeset/proud-shoes-explode.md create mode 100644 packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.expected.js create mode 100644 packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.js diff --git a/.changeset/proud-shoes-explode.md b/.changeset/proud-shoes-explode.md new file mode 100644 index 000000000..eefda99f0 --- /dev/null +++ b/.changeset/proud-shoes-explode.md @@ -0,0 +1,5 @@ +--- +'wmr': patch +--- + +Fix incorrectly transformed dynamic import statements when there was a comment in front of the specifier (`import(/* foo */ 'my-module')`) diff --git a/packages/wmr/src/lib/transform-imports.js b/packages/wmr/src/lib/transform-imports.js index d2672ccdb..89e015e64 100644 --- a/packages/wmr/src/lib/transform-imports.js +++ b/packages/wmr/src/lib/transform-imports.js @@ -80,11 +80,18 @@ export async function transformImports(code, id, { resolveImportMeta, resolveId, // `slice(item.d, item.s)` gives us "import(" to implement this. // Strip comments - these are usually Webpack magic comments. + let originalSpec = spec; spec = spec .replace(/\/\*[\s\S]*\*\//g, '') .replace(/^\s*\/\/.*$/gm, '') .trim(); + // Update start position if we stripped leading characters + if (originalSpec.length !== spec.length) { + // @ts-ignore + item.s += originalSpec.indexOf(spec); + } + // For dynamic imports, spec is a JavaScript expression. // We need to try to convert it to a specifier, or bail if it's not static. quote = (spec.match(/^\s*(['"`])/) || [])[1]; diff --git a/packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.expected.js b/packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.expected.js new file mode 100644 index 000000000..682b02763 --- /dev/null +++ b/packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.expected.js @@ -0,0 +1,2 @@ +// @ts-ignore +const About = lazy(() => import(/* webpackChunkName: foo */ 'it_works')); diff --git a/packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.js b/packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.js new file mode 100644 index 000000000..a4cf95cbc --- /dev/null +++ b/packages/wmr/test/fixtures/_unit-transform-imports/dynamic-import-comment.js @@ -0,0 +1,2 @@ +// @ts-ignore +const About = lazy(() => import(/* webpackChunkName: foo */ 'foo')); diff --git a/packages/wmr/test/transform-imports.test.js b/packages/wmr/test/transform-imports.test.js index 905070a85..42f892083 100644 --- a/packages/wmr/test/transform-imports.test.js +++ b/packages/wmr/test/transform-imports.test.js @@ -92,6 +92,19 @@ describe('transformImports', () => { }); expect(result.code).toEqual(expected); }); + + it('should transform imports with comments', async () => { + const code = await readFile('dynamic-import-comment.js'); + const expected = await readFile('dynamic-import-comment.expected.js'); + const result = await transformImports(code, 'my-test', { + resolveDynamicImport(id) { + if (id === 'foo') { + return 'it_works'; + } + } + }); + expect(result.code).toEqual(expected); + }); }); describe('import.meta', () => {