From b386fba49ee66a3dce362f2887176dd2a0738771 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Mon, 22 Aug 2022 01:26:13 +0800 Subject: [PATCH] fix(html): move importmap before module scripts (#9392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 翠 / green --- packages/vite/src/node/plugins/html.ts | 52 +++++++++++++++++++ .../src/node/server/middlewares/indexHtml.ts | 24 ++++++--- .../external/__tests__/external.spec.ts | 8 ++- playground/html/__tests__/html.spec.ts | 16 +++++- playground/html/vite.config.js | 19 +++++++ 5 files changed, 111 insertions(+), 8 deletions(-) diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index b8cd3713e..4c46d9888 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -7,6 +7,7 @@ import type { SourceMapInput } from 'rollup' import MagicString from 'magic-string' +import colors from 'picocolors' import type { AttributeNode, CompilerError, @@ -54,6 +55,10 @@ const inlineImportRE = /(?]*type\s*=\s*["']?importmap["']?[^>]*>.*?<\/script>/is +const moduleScriptRE = /[ \t]*]*type\s*=\s*["']?module["']?[^>]*>/is + export const isHTMLProxy = (id: string): boolean => htmlProxyRE.test(id) export const isHTMLRequest = (request: string): boolean => @@ -225,6 +230,8 @@ function handleParseError( */ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { const [preHooks, postHooks] = resolveHtmlTransforms(config.plugins) + preHooks.unshift(preImportMapHook(config)) + postHooks.push(postImportMapHook()) const processedHtml = new Map() const isExcludedUrl = (url: string) => url.startsWith('#') || @@ -796,6 +803,51 @@ export type IndexHtmlTransform = transform: IndexHtmlTransformHook } +export function preImportMapHook( + config: ResolvedConfig +): IndexHtmlTransformHook { + return (html, ctx) => { + const importMapIndex = html.match(importMapRE)?.index + if (importMapIndex === undefined) return + + const moduleScriptIndex = html.match(moduleScriptRE)?.index + if (moduleScriptIndex === undefined) return + + if (moduleScriptIndex < importMapIndex) { + const relativeHtml = normalizePath( + path.relative(config.root, ctx.filename) + ) + config.logger.warnOnce( + colors.yellow( + colors.bold( + `(!)