From 5060abbe326727fdba28d480392be4dd8e0693ef Mon Sep 17 00:00:00 2001 From: poyoho <907415276@qq.com> Date: Sat, 12 Feb 2022 14:18:44 +0800 Subject: [PATCH 1/4] feat: explicit the word boundary --- packages/playground/assets/index.html | 12 ++++++++++++ packages/vite/src/node/plugins/html.ts | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index f3b9a0b372a608..aefc7a5d55e7ed 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -149,9 +149,21 @@

new URL(`./${dynamic}`, 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 e7ca5e63961253..c0ea065620f908 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -12,8 +12,10 @@ import { generateCodeFrame, isDataUrl, isExternalUrl, + multilineCommentsRE, normalizePath, processSrcSet, + singlelineCommentsRE, slash } from '../utils' import type { ResolvedConfig } from '../config' @@ -43,7 +45,8 @@ interface ScriptAssetsUrl { const htmlProxyRE = /\?html-proxy[&inline\-css]*&index=(\d+)\.(js|css)$/ const inlineCSSRE = /__VITE_INLINE_CSS__([^_]+_\d+)__/g -const inlineImportRE = /\bimport\s*\(("[^"]*"|'[^']*')\)/g +// Do not allow preceding '.', but do allow preceding '...' for spread operations +const inlineImportRE = /(? htmlProxyRE.test(id) // HTML Proxy Caches are stored by config -> filePath -> index @@ -298,6 +301,9 @@ 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)) + let match: RegExpExecArray | null while ((match = inlineImportRE.exec(code))) { const { 0: full, 1: url, index } = match From 6f78ce545653a0cc51812d89218a28caeef22644 Mon Sep 17 00:00:00 2001 From: poyoho <907415276@qq.com> Date: Sat, 12 Feb 2022 14:38:57 +0800 Subject: [PATCH 2/4] feat: ignore import in the string --- packages/playground/assets/index.html | 3 +++ packages/vite/src/node/plugins/html.ts | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index aefc7a5d55e7ed..bbb9130c16b461 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -150,12 +150,14 @@

new URL(`./${dynamic}`, 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 c0ea065620f908..f0292bad9d1fa7 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -303,14 +303,22 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { const code = scriptNode.content .replace(multilineCommentsRE, (m) => ' '.repeat(m.length)) .replace(singlelineCommentsRE, (m) => ' '.repeat(m.length)) + .replace( + /"[^"]*"|'[^']*'|`[^`]*`/g, + (m) => `'${' '.repeat(m.length - 2)}'` + ) 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 + const start = index + 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(index + startUrl + 1, end) + }) } } } From f2dd1cb9caa83de8f70b9d31677cda6103b149eb Mon Sep 17 00:00:00 2001 From: yoho Date: Tue, 12 Apr 2022 14:57:06 +0800 Subject: [PATCH 3/4] chore: use empty string --- .../assets/__tests__/assets.spec.ts | 7 +++++++ packages/playground/assets/index.html | 8 ++++++-- packages/vite/src/node/plugins/html.ts | 19 +++++++------------ 3 files changed, 20 insertions(+), 14 deletions(-) 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) }) } } From 4f12402f67e4730003c04e385e4f8062b1919e9b Mon Sep 17 00:00:00 2001 From: yoho Date: Tue, 12 Apr 2022 14:57:27 +0800 Subject: [PATCH 4/4] chore: remove usless re --- packages/vite/src/node/plugins/html.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 42e63418bba973..5c86b6c0ac6073 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -13,10 +13,8 @@ import { generateCodeFrame, isDataUrl, isExternalUrl, - multilineCommentsRE, normalizePath, processSrcSet, - singlelineCommentsRE, slash } from '../utils' import type { ResolvedConfig } from '../config'