diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 64a8fdce9b2826..0e5a1ce6879f1c 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -835,7 +835,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { isSelfAccepting, staticImportedUrls, ) - if (hasHMR && prunedImports) { + if (prunedImports) { handlePrunedModules(prunedImports, environment) } } diff --git a/playground/hmr/__tests__/hmr.spec.ts b/playground/hmr/__tests__/hmr.spec.ts index 499aae1b4e2cf6..139355368e53b1 100644 --- a/playground/hmr/__tests__/hmr.spec.ts +++ b/playground/hmr/__tests__/hmr.spec.ts @@ -997,6 +997,17 @@ if (!isBuild) { .toMatch('parent:child') }) + test('deleting import from non-self-accepting module can trigger prune event', async () => { + await page.goto(viteTestUrl) + await expect.poll(() => page.textContent('.prune')).toMatch('prune-init') + editFile('prune/dep1.js', (code) => + code.replace(`import './dep2.js'`, `// import './dep2.js'`), + ) + await expect + .poll(() => page.textContent('.prune')) + .toMatch('prune-init|dep2-disposed|dep2-pruned') + }) + test('import.meta.hot?.accept', async () => { await page.goto(viteTestUrl) diff --git a/playground/hmr/hmr.ts b/playground/hmr/hmr.ts index 57eb5df0ab30ea..859809801f29cd 100644 --- a/playground/hmr/hmr.ts +++ b/playground/hmr/hmr.ts @@ -7,6 +7,7 @@ import './file-delete-restore' import './optional-chaining/parent' import './intermediate-file-delete' import './circular' +import './prune' import logo from './logo.svg' import logoNoInline from './logo-no-inline.svg' import { msg as softInvalidationMsg } from './soft-invalidation' diff --git a/playground/hmr/index.html b/playground/hmr/index.html index 8bd295beb73c95..e4ea468b98d67d 100644 --- a/playground/hmr/index.html +++ b/playground/hmr/index.html @@ -45,3 +45,4 @@
+
prune-init
diff --git a/playground/hmr/prune/dep1.js b/playground/hmr/prune/dep1.js new file mode 100644 index 00000000000000..6621b014013ab3 --- /dev/null +++ b/playground/hmr/prune/dep1.js @@ -0,0 +1,8 @@ +import './dep2.js' + +// TODO: https://github.com/vitejs/vite/issues/20781 +// currently we need one more `import` in this module +// to trigger prune for depending module `dep2.js` since +// the prune event logic is skipped when `es-module-lexer` +// detects `imports.length === 0` +import './dep2-other.js' diff --git a/playground/hmr/prune/dep2-other.js b/playground/hmr/prune/dep2-other.js new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/playground/hmr/prune/dep2.js b/playground/hmr/prune/dep2.js new file mode 100644 index 00000000000000..95db869caa5e07 --- /dev/null +++ b/playground/hmr/prune/dep2.js @@ -0,0 +1,8 @@ +if (import.meta.hot) { + import.meta.hot.dispose(() => { + document.querySelector('.prune').textContent += '|dep2-disposed' + }) + import.meta.hot.prune(() => { + document.querySelector('.prune').textContent += '|dep2-pruned' + }) +} diff --git a/playground/hmr/prune/index.js b/playground/hmr/prune/index.js new file mode 100644 index 00000000000000..f79e0d2d015aef --- /dev/null +++ b/playground/hmr/prune/index.js @@ -0,0 +1,5 @@ +import './dep1.js' + +if (import.meta.hot) { + import.meta.hot.accept(() => {}) +}