diff options
-rw-r--r-- | .changeset/tasty-tigers-flow.md | 5 | ||||
-rw-r--r-- | packages/astro/package.json | 2 | ||||
-rw-r--r-- | packages/astro/src/runtime/client/hmr.ts | 46 | ||||
-rw-r--r-- | packages/astro/src/vite-plugin-astro-server/index.ts | 1 | ||||
-rw-r--r-- | packages/astro/src/vite-plugin-astro/hmr.ts | 12 | ||||
-rw-r--r-- | packages/astro/src/vite-plugin-astro/index.ts | 2 | ||||
-rw-r--r-- | yarn.lock | 5 |
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); }, }; } @@ -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" |