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 472e51f4d404ee..6678a2da7c2106 100644
--- a/packages/playground/assets/index.html
+++ b/packages/playground/assets/index.html
@@ -184,7 +184,7 @@
simple script tag import-expression
text('.obj-import-express', t)
}
}
- const stringImport = "import('package')"
+ const stringImport = "const t = import('package')"
function text(el, text) {
document.querySelector(el).textContent = text
}
@@ -193,7 +193,11 @@ simple script tag import-expression
// import('./static/raw.js')
/* import('./static/raw.js') */
obj.import('ignore object import prop')
- text('.string-import-express', t)
+ try {
+ text('.string-import-express', t)
+ } catch {
+ text('.string-import-express', 'no load')
+ }
url in style tag
url
diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts
index 57ed5c1c37e60c..42e63418bba973 100644
--- a/packages/vite/src/node/plugins/html.ts
+++ b/packages/vite/src/node/plugins/html.ts
@@ -37,6 +37,7 @@ import type {
TextNode
} from '@vue/compiler-dom'
import { NodeTypes } from '@vue/compiler-dom'
+import { emptyString } from '../cleanString'
interface ScriptAssetsUrl {
start: number
@@ -306,24 +307,18 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
}
} else if (node.children.length) {
const scriptNode = node.children.pop()! as TextNode
- const code = scriptNode.content
- .replace(multilineCommentsRE, (m) => ' '.repeat(m.length))
- .replace(singlelineCommentsRE, (m) => ' '.repeat(m.length))
- .replace(
- /"[^"]*"|'[^']*'|`[^`]*`/g,
- (m) => `'${' '.repeat(m.length - 2)}'`
- )
+ 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 = 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: start + scriptNode.loc.start.offset,
end: end + scriptNode.loc.start.offset,
- url: scriptNode.content.slice(index + startUrl + 1, end)
+ url: scriptNode.content.slice(start, end)
})
}
}