fix: asset new URL(,import.meta.url) match (#18194)

This commit is contained in:
翠 / green 2024-10-31 00:55:25 +09:00 committed by GitHub
parent 85bd0e9b0d
commit 5286a90a3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 77 additions and 13 deletions

View File

@ -0,0 +1,65 @@
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)"`,
)
})
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)"`)
})
})

View File

@ -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
@ -168,19 +168,18 @@ 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) {
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
}