From e7fec9c738b9af9dc92f19447dad0d75363307ed Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:17:10 +0900 Subject: [PATCH 1/3] fix: asset `new URL(,import.meta.url` match --- .../plugins/assetImportMetaUrl.spec.ts | 59 +++++++++++++++++++ .../src/node/plugins/assetImportMetaUrl.ts | 24 ++++---- 2 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts diff --git a/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts b/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts new file mode 100644 index 00000000000000..16a16a58d3f9e8 --- /dev/null +++ b/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts @@ -0,0 +1,59 @@ +import { describe, expect, test } from 'vitest' +import { parseAst } from 'rollup/parseAst' +import { assetImportMetaUrlPlugin } from '../../plugins/assetImportMetaUrl' +import { resolveConfig } from '../../config' +import { PartialEnvironment } from '../../baseEnvironment' + +async function createAssetImportMetaurlPluginTransform() { + const config = await resolveConfig({ configFile: false }, 'serve') + const instance = assetImportMetaUrlPlugin(config) + const environment = new PartialEnvironment('client', config) + + return async (code: string) => { + // @ts-expect-error transform should exist + const result = await instance.transform.call( + { environment, parse: parseAst }, + code, + 'foo.ts', + ) + return result?.code || result + } +} + +describe('assetImportMetaUrlPlugin', async () => { + const transform = await createAssetImportMetaurlPluginTransform() + + test('variable between /', async () => { + expect( + await transform('new URL(`./foo/${dir}/index.js`, import.meta.url)'), + ).toMatchInlineSnapshot( + `"new URL((import.meta.glob("./foo/**/index.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}/index.js\`], import.meta.url)"`, + ) + }) + + test('variable before non-/', async () => { + expect( + await transform('new URL(`./foo/${dir}.js`, import.meta.url)'), + ).toMatchInlineSnapshot( + `"new URL((import.meta.glob("./foo/**/*.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}.js\`], import.meta.url)"`, + ) + }) + + test('two variables', async () => { + expect( + await transform('new URL(`./foo/${dir}${file}.js`, import.meta.url)'), + ).toMatchInlineSnapshot( + `"new URL((import.meta.glob("./foo/**/*.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}\${file}.js\`], import.meta.url)"`, + ) + }) + + test('two variables between /', async () => { + expect( + await transform( + 'new URL(`./foo/${dir}${dir2}/index.js`, import.meta.url)', + ), + ).toMatchInlineSnapshot( + `"new URL((import.meta.glob("./foo/**/index.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}\${dir2}/index.js\`], import.meta.url)"`, + ) + }) +}) diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index 1b2473137c5431..445649d1b364bd 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -160,19 +160,21 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { function buildGlobPattern(ast: any) { let pattern = '' - let lastElementIndex = -1 - for (const exp of ast.expressions) { - for (let i = lastElementIndex + 1; i < ast.quasis.length; i++) { - const el = ast.quasis[i] - if (el.end < exp.start) { - pattern += el.value.raw - lastElementIndex = i + let lastIsGlob = false + for (let i = 0; i < ast.quasis.length; i++) { + const str = ast.quasis[i].value.raw + if (str) { + if (lastIsGlob && str[0] !== '/') { + pattern += '/*' } + pattern += str + lastIsGlob = false + } + + if (ast.expressions[i] && !lastIsGlob) { + pattern += '**' + lastIsGlob = true } - pattern += '**' - } - for (let i = lastElementIndex + 1; i < ast.quasis.length; i++) { - pattern += ast.quasis[i].value.raw } return pattern } From 33b1fcb5eab0187ddcfa3e221b3cd0160f69eac0 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:22:16 +0900 Subject: [PATCH 2/3] fix: don't use ** --- .../src/node/__tests__/plugins/assetImportMetaUrl.spec.ts | 8 ++++---- packages/vite/src/node/plugins/assetImportMetaUrl.ts | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts b/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts index 16a16a58d3f9e8..67aac4bacfbd3f 100644 --- a/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts @@ -27,7 +27,7 @@ describe('assetImportMetaUrlPlugin', async () => { expect( await transform('new URL(`./foo/${dir}/index.js`, import.meta.url)'), ).toMatchInlineSnapshot( - `"new URL((import.meta.glob("./foo/**/index.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}/index.js\`], import.meta.url)"`, + `"new URL((import.meta.glob("./foo/*/index.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}/index.js\`], import.meta.url)"`, ) }) @@ -35,7 +35,7 @@ describe('assetImportMetaUrlPlugin', async () => { expect( await transform('new URL(`./foo/${dir}.js`, import.meta.url)'), ).toMatchInlineSnapshot( - `"new URL((import.meta.glob("./foo/**/*.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}.js\`], import.meta.url)"`, + `"new URL((import.meta.glob("./foo/*.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}.js\`], import.meta.url)"`, ) }) @@ -43,7 +43,7 @@ describe('assetImportMetaUrlPlugin', async () => { expect( await transform('new URL(`./foo/${dir}${file}.js`, import.meta.url)'), ).toMatchInlineSnapshot( - `"new URL((import.meta.glob("./foo/**/*.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}\${file}.js\`], import.meta.url)"`, + `"new URL((import.meta.glob("./foo/*.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}\${file}.js\`], import.meta.url)"`, ) }) @@ -53,7 +53,7 @@ describe('assetImportMetaUrlPlugin', async () => { 'new URL(`./foo/${dir}${dir2}/index.js`, import.meta.url)', ), ).toMatchInlineSnapshot( - `"new URL((import.meta.glob("./foo/**/index.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}\${dir2}/index.js\`], import.meta.url)"`, + `"new URL((import.meta.glob("./foo/*/index.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}\${dir2}/index.js\`], import.meta.url)"`, ) }) }) diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index 445649d1b364bd..1baebc5aa8b072 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -164,15 +164,12 @@ function buildGlobPattern(ast: any) { for (let i = 0; i < ast.quasis.length; i++) { const str = ast.quasis[i].value.raw if (str) { - if (lastIsGlob && str[0] !== '/') { - pattern += '/*' - } pattern += str lastIsGlob = false } if (ast.expressions[i] && !lastIsGlob) { - pattern += '**' + pattern += '*' lastIsGlob = true } } From 16550433039e167cc081946ed8d686ae9e5ac4b4 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 30 Oct 2024 18:27:34 +0900 Subject: [PATCH 3/3] fix: ignore "glob all files" case correctly --- .../src/node/__tests__/plugins/assetImportMetaUrl.spec.ts | 6 ++++++ packages/vite/src/node/plugins/assetImportMetaUrl.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts b/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts index 67aac4bacfbd3f..37dc870372da0f 100644 --- a/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/assetImportMetaUrl.spec.ts @@ -56,4 +56,10 @@ describe('assetImportMetaUrlPlugin', async () => { `"new URL((import.meta.glob("./foo/*/index.js", {"eager":true,"import":"default","query":"?url"}))[\`./foo/\${dir}\${dir2}/index.js\`], import.meta.url)"`, ) }) + + test('ignore starting with a variable', async () => { + expect( + await transform('new URL(`${file}.js`, import.meta.url)'), + ).toMatchInlineSnapshot(`"new URL(\`\${file}.js\`, import.meta.url)"`) + }) }) diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index 99a8ef1d7d6057..ba3e434d44d2a0 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -81,7 +81,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { const templateLiteral = (ast as any).body[0].expression if (templateLiteral.expressions.length) { const pattern = buildGlobPattern(templateLiteral) - if (pattern.startsWith('**')) { + if (pattern.startsWith('*')) { // don't transform for patterns like this // because users won't intend to do that in most cases continue