From 8ab04b70ada119fbca2fc5a53c36f233423febbe Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 18 Nov 2024 21:01:09 +0900 Subject: [PATCH] fix(html): fix inline proxy modules invalidation (#18696) --- .../src/node/server/middlewares/indexHtml.ts | 21 +++++++++++++------ playground/html/__tests__/html.spec.ts | 9 ++++++++ playground/html/transform-inline-js.html | 5 +++++ playground/html/vite.config.js | 14 +++++++++++++ 4 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 playground/html/transform-inline-js.html diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index c752febbdfaa6c..ae432900d46756 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -218,6 +218,7 @@ const devHtmlHook: IndexHtmlTransformHook = async ( ) const styleUrl: AssetNode[] = [] const inlineStyles: InlineStyleAttribute[] = [] + const inlineModulePaths: string[] = [] const addInlineModule = ( node: DefaultTreeAdapterMap['element'], @@ -246,13 +247,8 @@ const devHtmlHook: IndexHtmlTransformHook = async ( // inline js module. convert to src="proxy" (dev only, base is never relative) const modulePath = `${proxyModuleUrl}?html-proxy&index=${inlineModuleIndex}.${ext}` + inlineModulePaths.push(modulePath) - // invalidate the module so the newly cached contents will be served - const clientModuleGraph = server?.environments.client.moduleGraph - const module = clientModuleGraph?.getModuleById(modulePath) - if (module) { - clientModuleGraph!.invalidateModule(module) - } s.update( node.sourceCodeLocation!.startOffset, node.sourceCodeLocation!.endOffset, @@ -350,6 +346,19 @@ const devHtmlHook: IndexHtmlTransformHook = async ( } }) + // invalidate the module so the newly cached contents will be served + const clientModuelGraph = server?.environments.client.moduleGraph + if (clientModuelGraph) { + await Promise.all( + inlineModulePaths.map(async (url) => { + const module = await clientModuelGraph.getModuleByUrl(url) + if (module) { + clientModuelGraph.invalidateModule(module) + } + }), + ) + } + await Promise.all([ ...styleUrl.map(async ({ start, end, code }, index) => { const url = `${proxyModulePath}?html-proxy&direct&index=${index}.css` diff --git a/playground/html/__tests__/html.spec.ts b/playground/html/__tests__/html.spec.ts index 14ada2ccc5b36a..55b587f928fe30 100644 --- a/playground/html/__tests__/html.spec.ts +++ b/playground/html/__tests__/html.spec.ts @@ -510,3 +510,12 @@ test('escape html attribute', async () => { const el = await page.$('.unescape-div') expect(el).toBeNull() }) + +test('invalidate inline proxy module on reload', async () => { + await page.goto(`${viteTestUrl}/transform-inline-js`) + expect(await page.textContent('.test')).toContain('ok') + await page.reload() + expect(await page.textContent('.test')).toContain('ok') + await page.reload() + expect(await page.textContent('.test')).toContain('ok') +}) diff --git a/playground/html/transform-inline-js.html b/playground/html/transform-inline-js.html new file mode 100644 index 00000000000000..bfe65686e6970d --- /dev/null +++ b/playground/html/transform-inline-js.html @@ -0,0 +1,5 @@ +
id: {{ id }}
+
test: ???
+ diff --git a/playground/html/vite.config.js b/playground/html/vite.config.js index ba9cc59efefbdb..ff59f5db10a2c5 100644 --- a/playground/html/vite.config.js +++ b/playground/html/vite.config.js @@ -35,6 +35,7 @@ export default defineConfig({ serveBothFile: resolve(__dirname, 'serve/both.html'), serveBothFolder: resolve(__dirname, 'serve/both/index.html'), write: resolve(__dirname, 'write.html'), + 'transform-inline-js': resolve(__dirname, 'transform-inline-js.html'), relativeInput: relative( process.cwd(), resolve(__dirname, 'relative-input.html'), @@ -249,6 +250,19 @@ ${ }, }, }, + { + name: 'transform-inline-js', + transformIndexHtml: { + order: 'pre', + handler(html, ctx) { + if (!ctx.filename.endsWith('html/transform-inline-js.html')) return + return html.replaceAll( + '{{ id }}', + Math.random().toString(36).slice(2), + ) + }, + }, + }, serveExternalPathPlugin(), ], })