Include astro components for HMR invalidation (#4240)
* Include astro components for HMR invalidation * Changeset * remove extra vite server passing
This commit is contained in:
parent
d186c406b9
commit
561a34d912
9 changed files with 86 additions and 2 deletions
5
.changeset/nasty-gifts-push.md
Normal file
5
.changeset/nasty-gifts-push.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Properly invalidate Astro modules when a child script updates in HMR
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "@e2e/invalidate-script-deps",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1></h1>
|
||||
<script>
|
||||
import '../scripts/heading.js';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
document.querySelector('h1').textContent = 'before';
|
31
packages/astro/e2e/invalidate-script-deps.test.js
Normal file
31
packages/astro/e2e/invalidate-script-deps.test.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = testFactory({
|
||||
root: './fixtures/invalidate-script-deps/',
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeEach(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('Scripts with dependencies', () => {
|
||||
test('refresh with HMR', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const h = page.locator('h1');
|
||||
await expect(h, 'original text set').toHaveText('before');
|
||||
|
||||
await astro.editFile('./src/scripts/heading.js', (original) =>
|
||||
original.replace('before', 'after')
|
||||
);
|
||||
|
||||
await expect(h, 'text changed').toHaveText('after');
|
||||
});
|
||||
});
|
|
@ -6,6 +6,7 @@ import type { LogOptions } from '../core/logger/core.js';
|
|||
import { info } from '../core/logger/core.js';
|
||||
import * as msg from '../core/messages.js';
|
||||
import { cachedCompilation, invalidateCompilation, isCached } from './compile.js';
|
||||
import { isAstroScript } from './query.js';
|
||||
|
||||
interface TrackCSSDependenciesOptions {
|
||||
viteDevServer: ViteDevServer | null;
|
||||
|
@ -141,12 +142,23 @@ export async function handleHotUpdate(
|
|||
// 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')) {
|
||||
if (imp.id && isAstroScript(imp.id)) {
|
||||
mods.push(imp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a module that is imported from a <script>, invalidate the Astro
|
||||
// component so that it is cached by the time the script gets transformed.
|
||||
for(const mod of filtered) {
|
||||
if(mod.id && isAstroScript(mod.id) && mod.file) {
|
||||
const astroMod = ctx.server.moduleGraph.getModuleById(mod.file);
|
||||
if(astroMod) {
|
||||
mods.unshift(astroMod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Svelte files should be marked as `isSelfAccepting` but they don't appear to be
|
||||
const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte'));
|
||||
if (isSelfAccepting) {
|
||||
|
|
|
@ -359,7 +359,11 @@ ${source}
|
|||
pluginContext: this,
|
||||
};
|
||||
const compile = () => cachedCompilation(compileProps);
|
||||
return handleHotUpdate.call(this, context, { config, logging, compile });
|
||||
return handleHotUpdate.call(this, context, {
|
||||
config,
|
||||
logging,
|
||||
compile
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,3 +35,8 @@ export function parseAstroRequest(id: string): ParsedRequestResult {
|
|||
query,
|
||||
};
|
||||
}
|
||||
|
||||
export function isAstroScript(id: string): boolean {
|
||||
const parsed = parseAstroRequest(id);
|
||||
return parsed.query.type === 'script';
|
||||
}
|
||||
|
|
|
@ -659,6 +659,12 @@ importers:
|
|||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
|
||||
packages/astro/e2e/fixtures/invalidate-script-deps:
|
||||
specifiers:
|
||||
astro: workspace:*
|
||||
devDependencies:
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/e2e/fixtures/lit-component:
|
||||
specifiers:
|
||||
'@astrojs/lit': workspace:*
|
||||
|
|
Loading…
Reference in a new issue