From d6dd30aa4146da28f8ca5b376756811de69ca246 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Tue, 27 Dec 2022 00:52:22 +0800 Subject: [PATCH 1/3] fix: importmap should insert before module preload link --- packages/vite/src/node/plugins/html.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 2deeebfc9a42ab..81f6ede47edbdd 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -50,6 +50,8 @@ const importMapRE = /[ \t]*]*type\s*=\s*(?:"importmap"|'importmap'|importmap)[^>]*>.*?<\/script>/is const moduleScriptRE = /[ \t]*]*type\s*=\s*(?:"module"|'module'|module)[^>]*>/i +const modulePreloadLinkRE = + /[ \t]*]*rel\s*=\s*(?:"modulepreload"|'modulepreload'|modulepreload).*?\/>/is export const isHTMLProxy = (id: string): boolean => htmlProxyRE.test(id) @@ -910,7 +912,7 @@ export function preImportMapHook( } /** - * Move importmap before the first module script + * Move importmap before the first module script and modulepreload link */ export function postImportMapHook(): IndexHtmlTransformHook { return (html) => { @@ -921,9 +923,20 @@ export function postImportMapHook(): IndexHtmlTransformHook { importMap = match return '' }) - if (importMap) { - html = html.replace(moduleScriptRE, (match) => `${importMap}\n${match}`) - } + + if (!importMap) return html + + const firstModuleScriptIndex = html.match(moduleScriptRE)?.index + const firstModulePreloadIndex = html.match(modulePreloadLinkRE)?.index + const ImportMapInsertionIndex = Math.min( + firstModuleScriptIndex ?? Infinity, + firstModulePreloadIndex ?? Infinity, + ) + if (ImportMapInsertionIndex === Infinity) return html + + html = `${html.slice(0, ImportMapInsertionIndex)}${importMap}\n${html.slice( + ImportMapInsertionIndex, + )}` return html } From 52bfae4bc8a5d6b721bc66fe07c679a30a7b7aec Mon Sep 17 00:00:00 2001 From: fi3ework Date: Wed, 28 Dec 2022 15:24:56 +0800 Subject: [PATCH 2/3] fix: merge module script and module preload link regex --- packages/vite/src/node/plugins/html.ts | 35 ++++++++++++-------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 81f6ede47edbdd..9521f8b89bf2e1 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -51,7 +51,12 @@ const importMapRE = const moduleScriptRE = /[ \t]*]*type\s*=\s*(?:"module"|'module'|module)[^>]*>/i const modulePreloadLinkRE = - /[ \t]*]*rel\s*=\s*(?:"modulepreload"|'modulepreload'|modulepreload).*?\/>/is + /[ \t]*]*rel\s*=\s*(?:"modulepreload"|'modulepreload'|modulepreload)[\s\S]*?\/>/i + +const importMapDependenciesRE = new RegExp( + [moduleScriptRE, modulePreloadLinkRE].map((r) => r.source).join('|'), + 'i', +) export const isHTMLProxy = (id: string): boolean => htmlProxyRE.test(id) @@ -893,17 +898,17 @@ export function preImportMapHook( const importMapIndex = html.match(importMapRE)?.index if (importMapIndex === undefined) return - const moduleScriptIndex = html.match(moduleScriptRE)?.index - if (moduleScriptIndex === undefined) return + const importMapDepIndex = html.match(importMapDependenciesRE)?.index + if (importMapDepIndex === undefined) return - if (moduleScriptIndex < importMapIndex) { + if (importMapDepIndex < importMapIndex) { const relativeHtml = normalizePath( path.relative(config.root, ctx.filename), ) config.logger.warnOnce( colors.yellow( colors.bold( - `(!) + + + + diff --git a/playground/html/vite.config.js b/playground/html/vite.config.js index 4d029b1e835d26..f7eb421975ee00 100644 --- a/playground/html/vite.config.js +++ b/playground/html/vite.config.js @@ -28,6 +28,7 @@ module.exports = { ), linkProps: resolve(__dirname, 'link-props/index.html'), valid: resolve(__dirname, 'valid.html'), + importmapOrder: resolve(__dirname, 'importmapOrder.html'), }, }, }, @@ -168,7 +169,9 @@ ${ }, { name: 'head-prepend-importmap', - transformIndexHtml() { + transformIndexHtml(_, ctx) { + if (ctx.path.includes('importmapOrder')) return + return [ { tag: 'script',