summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/tasty-tigers-flow.md5
-rw-r--r--packages/astro/package.json2
-rw-r--r--packages/astro/src/runtime/client/hmr.ts46
-rw-r--r--packages/astro/src/vite-plugin-astro-server/index.ts1
-rw-r--r--packages/astro/src/vite-plugin-astro/hmr.ts12
-rw-r--r--packages/astro/src/vite-plugin-astro/index.ts2
-rw-r--r--yarn.lock5
7 files changed, 37 insertions, 36 deletions
diff --git a/.changeset/tasty-tigers-flow.md b/.changeset/tasty-tigers-flow.md
new file mode 100644
index 000000000..e7a67c8d0
--- /dev/null
+++ b/.changeset/tasty-tigers-flow.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Add fine-grained HMR support for Astro files
diff --git a/packages/astro/package.json b/packages/astro/package.json
index a1f114ba8..2a09498ac 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -85,8 +85,8 @@
"htmlparser2": "^7.1.2",
"kleur": "^4.1.4",
"magic-string": "^0.25.7",
+ "micromorph": "^0.0.2",
"mime": "^3.0.0",
- "morphdom": "^2.6.1",
"parse5": "^6.0.1",
"path-to-regexp": "^6.2.0",
"postcss": "^8.3.8",
diff --git a/packages/astro/src/runtime/client/hmr.ts b/packages/astro/src/runtime/client/hmr.ts
index ca98ceeff..8bd8d3937 100644
--- a/packages/astro/src/runtime/client/hmr.ts
+++ b/packages/astro/src/runtime/client/hmr.ts
@@ -1,38 +1,20 @@
if (import.meta.hot) {
const parser = new DOMParser();
- import.meta.hot.on('astro:reload', async ({ html }: { html: string }) => {
- const { default: morphdom } = await import('morphdom');
+ import.meta.hot.on('astro:update', async ({ file }) => {
+ const { default: diff } = await import('micromorph');
+ // eslint-disable-next-line no-console
+ console.log(`[vite] hot updated: ${file}`);
+ const html = await fetch(`${window.location}`).then(res => res.text());
const doc = parser.parseFromString(html, 'text/html');
- morphdom(document.head, doc.head, {
- onBeforeElUpdated(fromEl, toEl) {
- // Do not update identical tags
- if (fromEl.isEqualNode(toEl)) {
- return false;
- }
-
- // Do not update <link> or <script> tags
- // to avoid re-fetching their contents
- if (fromEl.tagName === toEl.tagName && (toEl.tagName === 'LINK' || toEl.tagName === 'SCRIPT')) {
- return false;
- }
-
- return true;
- },
- });
-
- morphdom(document.body, doc.body, {
- onBeforeElUpdated(fromEl, toEl) {
- if (fromEl.localName === 'astro-root') {
- return fromEl.getAttribute('uid') !== toEl.getAttribute('uid');
- }
-
- if (fromEl.isEqualNode(toEl)) {
- return false;
- }
-
- return true;
- },
- });
+ // Match incoming islands to current state
+ for (const root of doc.querySelectorAll('astro-root')) {
+ const uid = root.getAttribute('uid');
+ const current = document.querySelector(`astro-root[uid="${uid}"]`);
+ if (current) {
+ root.innerHTML = current?.innerHTML;
+ }
+ }
+ diff(document, doc);
});
}
diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts
index bf1ae7f11..929040679 100644
--- a/packages/astro/src/vite-plugin-astro-server/index.ts
+++ b/packages/astro/src/vite-plugin-astro-server/index.ts
@@ -112,7 +112,6 @@ async function handleRequest(
routeCache: routeCache,
viteServer: viteServer,
});
- info(logging, 'astro', msg.req({ url: pathname, statusCode, reqTime: performance.now() - reqStart }));
writeHtmlResponse(res, statusCode, html);
} catch (_err: any) {
info(logging, 'astro', msg.req({ url: pathname, statusCode: 500 }));
diff --git a/packages/astro/src/vite-plugin-astro/hmr.ts b/packages/astro/src/vite-plugin-astro/hmr.ts
index 9c753da3e..f69d48cbb 100644
--- a/packages/astro/src/vite-plugin-astro/hmr.ts
+++ b/packages/astro/src/vite-plugin-astro/hmr.ts
@@ -1,7 +1,10 @@
import type { AstroConfig } from '../@types/astro';
+import type { LogOptions } from '../core/logger.js';
import type { ViteDevServer, ModuleNode, HmrContext } from 'vite';
import type { PluginContext as RollupPluginContext, ResolvedId } from 'rollup';
import { invalidateCompilation, isCached } from './compile.js';
+import { logger } from '../core/logger.js'
+import { green } from 'kleur/colors';
interface TrackCSSDependenciesOptions {
viteDevServer: ViteDevServer | null;
@@ -43,7 +46,7 @@ export async function trackCSSDependencies(this: RollupPluginContext, opts: Trac
}
}
-export function handleHotUpdate(ctx: HmrContext, config: AstroConfig) {
+export function handleHotUpdate(ctx: HmrContext, config: AstroConfig, logging: LogOptions) {
// Invalidate the compilation cache so it recompiles
invalidateCompilation(config, ctx.file);
@@ -70,5 +73,12 @@ export function handleHotUpdate(ctx: HmrContext, config: AstroConfig) {
invalidateCompilation(config, file);
}
+ if (ctx.file.endsWith('.astro')) {
+ const file = ctx.file.replace(config.projectRoot.pathname, '/');
+ logger.info('astro', green('hmr'), `${file}`)
+ ctx.server.ws.send({ type: "custom", event: "astro:update", data: { file } })
+ return []
+ }
+
return Array.from(filtered);
}
diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts
index 77381eb9c..1249b0605 100644
--- a/packages/astro/src/vite-plugin-astro/index.ts
+++ b/packages/astro/src/vite-plugin-astro/index.ts
@@ -199,7 +199,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
}
},
async handleHotUpdate(context) {
- return handleHotUpdate(context, config);
+ return handleHotUpdate(context, config, logging);
},
};
}
diff --git a/yarn.lock b/yarn.lock
index 0bd521f0e..169bb4009 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5867,6 +5867,11 @@ micromatch@^4.0.2, micromatch@^4.0.4:
braces "^3.0.1"
picomatch "^2.2.3"
+micromorph@^0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/micromorph/-/micromorph-0.0.2.tgz#5cfbaea66ae5fb8629c8041897e88d9e827afc2f"
+ integrity sha512-hfy/OA8rtwI/vPRm4L6a3/u6uDvqsPmTok7pPmtfv2a7YfaTVfxd9HX2Kdn/SZ8rGMKkKVJ9A0WcBnzs0bjLXw==
+
mime@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"