summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/happy-wasps-check.md5
-rw-r--r--examples/minimal/src/pages/index.astro2
-rw-r--r--packages/astro/src/vite-plugin-astro/hmr.ts10
-rw-r--r--packages/astro/src/vite-plugin-astro/index.ts31
-rw-r--r--packages/astro/test/astro-markdown-css.test.js3
5 files changed, 42 insertions, 9 deletions
diff --git a/.changeset/happy-wasps-check.md b/.changeset/happy-wasps-check.md
new file mode 100644
index 000000000..6fb90627b
--- /dev/null
+++ b/.changeset/happy-wasps-check.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes HMR of hoisted script tags
diff --git a/examples/minimal/src/pages/index.astro b/examples/minimal/src/pages/index.astro
index 25f796bf1..346e155c4 100644
--- a/examples/minimal/src/pages/index.astro
+++ b/examples/minimal/src/pages/index.astro
@@ -10,4 +10,4 @@
<body>
<h1>Astro</h1>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/packages/astro/src/vite-plugin-astro/hmr.ts b/packages/astro/src/vite-plugin-astro/hmr.ts
index 4e194993e..2b11585ca 100644
--- a/packages/astro/src/vite-plugin-astro/hmr.ts
+++ b/packages/astro/src/vite-plugin-astro/hmr.ts
@@ -68,6 +68,7 @@ export async function handleHotUpdate(ctx: HmrContext, config: AstroConfig, logg
filtered.add(mod);
files.add(mod.file);
}
+
for (const imp of mod.importers) {
if (imp.file && isCached(config, imp.file)) {
filtered.add(imp);
@@ -85,6 +86,15 @@ export async function handleHotUpdate(ctx: HmrContext, config: AstroConfig, logg
// Bugfix: sometimes style URLs get normalized and end with `lang.css=`
// These will cause full reloads, so filter them out here
const mods = ctx.modules.filter((m) => !m.url.endsWith('='));
+
+ // Add hoisted scripts so these get invalidated
+ for(const mod of mods) {
+ for(const imp of mod.importedModules) {
+ if(imp.id?.includes('?astro&type=script')) {
+ mods.push(imp);
+ }
+ }
+ }
const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte'));
const file = ctx.file.replace(config.root.pathname, '/');
diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts
index ea6f17dcd..47ecfee1e 100644
--- a/packages/astro/src/vite-plugin-astro/index.ts
+++ b/packages/astro/src/vite-plugin-astro/index.ts
@@ -126,6 +126,12 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
if (typeof query.index === 'undefined') {
throw new Error(`Requests for hoisted scripts must include an index`);
}
+ // HMR hoisted script only exists to make them appear in the module graph.
+ if(opts?.ssr) {
+ return {
+ code: `/* client hoisted script, empty in SSR: ${id} */`
+ };
+ }
const transformResult = await cachedCompilation(config, filename, source, viteTransform, {
ssr: Boolean(opts?.ssr),
@@ -182,17 +188,28 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
while ((match = pattern.exec(metadata)?.[1])) {
deps.add(match);
}
- // // import.meta.hot.accept(["${id}", "${Array.from(deps).join('","')}"], (...mods) => mods);
- // We need to be self-accepting, AND
- // we need an explicity array of deps to track changes for SSR-only components
- SUFFIX += `\nif (import.meta.hot) {
- import.meta.hot.accept(mod => mod);
- }`;
+
+ let i = 0;
+ while(i < transformResult.scripts.length) {
+ deps.add(`${id}?astro&type=script&index=${i}`);
+ SUFFIX += `import "${id}?astro&type=script&index=${i}";`;
+ i++;
+ }
+
+ // We only need to define deps if there are any
+ if(deps.size > 1) {
+ SUFFIX += `\nif(import.meta.hot) import.meta.hot.accept(["${id}", "${Array.from(deps).join('","')}"], (...mods) => mods);`
+ } else {
+ SUFFIX += `\nif (import.meta.hot) {
+ import.meta.hot.accept(mod => mod);
+ }`;
+ }
}
// Add handling to inject scripts into each page JS bundle, if needed.
if (isPage) {
SUFFIX += `\nimport "${PAGE_SSR_SCRIPT_ID}";`;
}
+
return {
code: `${code}${SUFFIX}`,
map,
@@ -260,7 +277,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
},
async handleHotUpdate(context) {
if (context.server.config.isProduction) return;
- return handleHotUpdate(context, config, logging);
+ return handleHotUpdate.call(this, context, config, logging);
},
};
}
diff --git a/packages/astro/test/astro-markdown-css.test.js b/packages/astro/test/astro-markdown-css.test.js
index 40710ce85..fcb1408f0 100644
--- a/packages/astro/test/astro-markdown-css.test.js
+++ b/packages/astro/test/astro-markdown-css.test.js
@@ -34,11 +34,12 @@ describe('Imported markdown CSS', function () {
});
describe('dev', () => {
let devServer;
+ let html;
let $;
before(async () => {
devServer = await fixture.startDevServer();
- const html = await fixture.fetch('/').then((res) => res.text());
+ html = await fixture.fetch('/').then((res) => res.text());
$ = cheerio.load(html);
});