Fix: Windows client-side script reloads on dev server (#4645)

* fix: append forward slash to script paths for "C:/" prob

* chore: remove dead regex

* chore: changeset

* test: add client script test back to windows!

* test: add inline script test for sanity

* The actual fix

Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
Ben Holmes 2022-09-09 10:53:34 -04:00 committed by GitHub
parent d136864bff
commit f27ca6ab3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 17 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix client-side scripts reloads on dev server in windows

View file

@ -36,10 +36,7 @@ test.describe('Astro component HMR', () => {
); );
}); });
// TODO: Re-enable this test on windows when #3424 is fixed test('hoisted scripts', async ({ page, astro }) => {
// https://github.com/withastro/astro/issues/3424
const it = os.platform() === 'win32' ? test.skip : test;
it('hoisted scripts', async ({ page, astro }) => {
const initialLog = page.waitForEvent( const initialLog = page.waitForEvent(
'console', 'console',
(message) => message.text() === 'Hello, Astro!' (message) => message.text() === 'Hello, Astro!'
@ -60,4 +57,26 @@ test.describe('Astro component HMR', () => {
await updatedLog; await updatedLog;
}); });
test('inline scripts', async ({ page, astro }) => {
const initialLog = page.waitForEvent(
'console',
(message) => message.text() === 'Hello, inline Astro!'
);
await page.goto(astro.resolveUrl('/'));
await initialLog;
const updatedLog = page.waitForEvent(
'console',
(message) => message.text() === 'Hello, updated inline Astro!'
);
// Edit the inline script on the page
await astro.editFile('./src/pages/index.astro', (content) =>
content.replace('Hello, inline Astro!', 'Hello, updated inline Astro!')
);
await updatedLog;
});
}); });

View file

@ -18,3 +18,7 @@ import Hero from '../components/Hero.astro';
<script> <script>
console.log('Hello, Astro!'); console.log('Hello, Astro!');
</script> </script>
<script is:inline>
console.log('Hello, inline Astro!');
</script>

View file

@ -126,7 +126,7 @@ export function resolveDependency(dep: string, projectRoot: URL) {
* Windows: C:/Users/astro/code/my-project/src/pages/index.astro * Windows: C:/Users/astro/code/my-project/src/pages/index.astro
*/ */
export function viteID(filePath: URL): string { export function viteID(filePath: URL): string {
return slash(fileURLToPath(filePath)); return slash(fileURLToPath(filePath) + filePath.search);
} }
export const VALID_ID_PREFIX = `/@id/`; export const VALID_ID_PREFIX = `/@id/`;

View file

@ -9,8 +9,9 @@ import ancestor from 'common-ancestor-path';
import esbuild from 'esbuild'; import esbuild from 'esbuild';
import slash from 'slash'; import slash from 'slash';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { isRelativePath, prependForwardSlash, startsWithForwardSlash } from '../core/path.js';
import { viteID } from '../core/util.js';
import { cachedCompilation, CompileProps, getCachedSource } from '../core/compile/index.js'; import { cachedCompilation, CompileProps, getCachedSource } from '../core/compile/index.js';
import { isRelativePath, startsWithForwardSlash } from '../core/path.js';
import { getFileInfo } from '../vite-plugin-utils/index.js'; import { getFileInfo } from '../vite-plugin-utils/index.js';
import { import {
createTransformStyles, createTransformStyles,
@ -48,6 +49,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
// Variables for determining if an id starts with /src... // Variables for determining if an id starts with /src...
const srcRootWeb = config.srcDir.pathname.slice(config.root.pathname.length - 1); const srcRootWeb = config.srcDir.pathname.slice(config.root.pathname.length - 1);
const isBrowserPath = (path: string) => path.startsWith(srcRootWeb); const isBrowserPath = (path: string) => path.startsWith(srcRootWeb);
const isFullFilePath = (path: string) => path.startsWith(prependForwardSlash(slash(fileURLToPath(config.root))));
function resolveRelativeFromAstroParent(id: string, parsedFrom: ParsedRequestResult): string { function resolveRelativeFromAstroParent(id: string, parsedFrom: ParsedRequestResult): string {
const filename = normalizeFilename(parsedFrom.filename); const filename = normalizeFilename(parsedFrom.filename);
@ -94,7 +96,10 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
if (query.type === 'style' && isBrowserPath(id)) { if (query.type === 'style' && isBrowserPath(id)) {
return relativeToRoot(id); return relativeToRoot(id);
} }
// Convert file paths to ViteID, meaning on Windows it omits the leading slash
if(isFullFilePath(id)) {
return viteID(new URL('file://' + id));
}
return id; return id;
} }
}, },
@ -245,18 +250,8 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
)};export { $$file as file, $$url as url };\n`; )};export { $$file as file, $$url as url };\n`;
// Add HMR handling in dev mode. // Add HMR handling in dev mode.
if (!resolvedConfig.isProduction) { if (!resolvedConfig.isProduction) {
// HACK: extract dependencies from metadata until compiler static extraction handles them
const metadata = transformResult.code.split('$$createMetadata(')[1].split('});\n')[0];
const pattern = /specifier:\s*'([^']*)'/g;
const deps = new Set();
let match;
while ((match = pattern.exec(metadata)?.[1])) {
deps.add(match);
}
let i = 0; let i = 0;
while (i < transformResult.scripts.length) { while (i < transformResult.scripts.length) {
deps.add(`${id}?astro&type=script&index=${i}&lang.ts`);
SUFFIX += `import "${id}?astro&type=script&index=${i}&lang.ts";`; SUFFIX += `import "${id}?astro&type=script&index=${i}&lang.ts";`;
i++; i++;
} }