diff --git a/packages/playground/assets/__tests__/assets.spec.ts b/packages/playground/assets/__tests__/assets.spec.ts index e08de24265e24a..75c0e57952db24 100644 --- a/packages/playground/assets/__tests__/assets.spec.ts +++ b/packages/playground/assets/__tests__/assets.spec.ts @@ -307,3 +307,10 @@ if (!isBuild) { await untilUpdated(() => getColor('.import-css'), 'rgb(0, 255, 136)') }) } + +test('html import word boundary', async () => { + expect(await page.textContent('.obj-import-express')).toMatch( + 'ignore object import prop' + ) + expect(await page.textContent('.string-import-express')).toMatch('no load') +}) diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index b0ec76f5483b6f..6678a2da7c2106 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -176,9 +176,28 @@

new URL(`non-existent`, import.meta.url)

simple script tag import-expression

+ +

url in style tag

url

diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 25ad91582140c3..5c86b6c0ac6073 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -35,6 +35,7 @@ import type { TextNode } from '@vue/compiler-dom' import { NodeTypes } from '@vue/compiler-dom' +import { emptyString } from '../cleanString' interface ScriptAssetsUrl { start: number @@ -44,8 +45,9 @@ interface ScriptAssetsUrl { const htmlProxyRE = /\?html-proxy=?[&inline\-css]*&index=(\d+)\.(js|css)$/ const inlineCSSRE = /__VITE_INLINE_CSS__([^_]+_\d+)__/g +// Do not allow preceding '.', but do allow preceding '...' for spread operations +const inlineImportRE = /(? htmlProxyRE.test(id) @@ -303,14 +305,19 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { } } else if (node.children.length) { const scriptNode = node.children.pop()! as TextNode - const code = scriptNode.content + const cleanCode = emptyString(scriptNode.content) + let match: RegExpExecArray | null - while ((match = inlineImportRE.exec(code))) { - const { 0: full, 1: url, index } = match - const startUrl = full.indexOf(url) - const start = scriptNode.loc.start.offset + index + startUrl + 1 + while ((match = inlineImportRE.exec(cleanCode))) { + const { 1: url, index } = match + const startUrl = cleanCode.indexOf(url, index) + const start = startUrl + 1 const end = start + url.length - 2 - scriptUrls.push({ start, end, url: url.slice(1, -1) }) + scriptUrls.push({ + start: start + scriptNode.loc.start.offset, + end: end + scriptNode.loc.start.offset, + url: scriptNode.content.slice(start, end) + }) } } }