diff --git a/.changeset/ten-emus-raise.md b/.changeset/ten-emus-raise.md new file mode 100644 index 000000000..c0bc48195 --- /dev/null +++ b/.changeset/ten-emus-raise.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix linked Astro library style HMR diff --git a/packages/astro/e2e/astro-component.test.js b/packages/astro/e2e/astro-component.test.js index 8ebbcd3a6..ac5531fbe 100644 --- a/packages/astro/e2e/astro-component.test.js +++ b/packages/astro/e2e/astro-component.test.js @@ -1,6 +1,5 @@ import { expect } from '@playwright/test'; -import os from 'os'; -import { testFactory } from './test-utils.js'; +import { getColor, testFactory } from './test-utils.js'; const test = testFactory({ root: './fixtures/astro-component/' }); @@ -79,4 +78,32 @@ test.describe('Astro component HMR', () => { await updatedLog; }); + + test('update linked dep Astro html', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + let h1 = page.locator('#astro-linked-lib'); + expect(await h1.textContent()).toBe('astro-linked-lib'); + await Promise.all([ + page.waitForLoadState('networkidle'), + await astro.editFile('../_deps/astro-linked-lib/Component.astro', (content) => + content.replace('>astro-linked-lib<', '>astro-linked-lib-update<') + ), + ]); + h1 = page.locator('#astro-linked-lib'); + expect(await h1.textContent()).toBe('astro-linked-lib-update'); + }); + + test('update linked dep Astro style', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + let h1 = page.locator('#astro-linked-lib'); + expect(await getColor(h1)).toBe('rgb(255, 0, 0)'); + await Promise.all([ + page.waitForLoadState('networkidle'), + await astro.editFile('../_deps/astro-linked-lib/Component.astro', (content) => + content.replace('color: red', 'color: green') + ), + ]); + h1 = page.locator('#astro-linked-lib'); + expect(await getColor(h1)).toBe('rgb(0, 128, 0)'); + }); }); diff --git a/packages/astro/e2e/fixtures/_deps/astro-linked-lib/Component.astro b/packages/astro/e2e/fixtures/_deps/astro-linked-lib/Component.astro new file mode 100644 index 000000000..074ccbc9b --- /dev/null +++ b/packages/astro/e2e/fixtures/_deps/astro-linked-lib/Component.astro @@ -0,0 +1,9 @@ + + +

astro-linked-lib

+ + \ No newline at end of file diff --git a/packages/astro/e2e/fixtures/_deps/astro-linked-lib/package.json b/packages/astro/e2e/fixtures/_deps/astro-linked-lib/package.json new file mode 100644 index 000000000..55578c8ae --- /dev/null +++ b/packages/astro/e2e/fixtures/_deps/astro-linked-lib/package.json @@ -0,0 +1,13 @@ +{ + "name": "@e2e/astro-linked-lib", + "version": "0.0.0", + "private": true, + "exports": { + ".": { + "astro": "./Component.astro" + } + }, + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/e2e/fixtures/astro-component/package.json b/packages/astro/e2e/fixtures/astro-component/package.json index a994d4936..a821672ab 100644 --- a/packages/astro/e2e/fixtures/astro-component/package.json +++ b/packages/astro/e2e/fixtures/astro-component/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@astrojs/preact": "^1.1.0", + "@e2e/astro-linked-lib": "link:../_deps/astro-linked-lib", "astro": "workspace:*", "preact": "^10.11.0" } diff --git a/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro b/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro index c7522dc54..527f33a74 100644 --- a/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro @@ -1,5 +1,6 @@ --- import Hero from '../components/Hero.astro'; +import LinkedLib from '@e2e/astro-linked-lib' --- @@ -11,6 +12,7 @@ import Hero from '../components/Hero.astro'; Lorem ipsum, dolor sit amet consectetur adipisicing elit. + diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts index fd9b1805d..f81266846 100644 --- a/packages/astro/src/vite-plugin-astro/index.ts +++ b/packages/astro/src/vite-plugin-astro/index.ts @@ -9,7 +9,12 @@ import esbuild from 'esbuild'; import slash from 'slash'; import { fileURLToPath } from 'url'; import { cachedCompilation, CompileProps, getCachedSource } from '../core/compile/index.js'; -import { isRelativePath, prependForwardSlash, startsWithForwardSlash } from '../core/path.js'; +import { + isRelativePath, + prependForwardSlash, + removeLeadingForwardSlashWindows, + startsWithForwardSlash, +} from '../core/path.js'; import { viteID } from '../core/util.js'; import { getFileInfo } from '../vite-plugin-utils/index.js'; import { handleHotUpdate } from './hmr.js'; @@ -80,12 +85,20 @@ export default function astro({ settings, logging }: AstroPluginOptions): vite.P // serve sub-part requests (*?astro) as virtual modules const { query } = parseAstroRequest(id); if (query.astro) { + // TODO: Try to remove these custom resolve so HMR is more predictable. // Convert /src/pages/index.astro?astro&type=style to /Users/name/ // Because this needs to be the id for the Vite CSS plugin to property resolve // relative @imports. if (query.type === 'style' && isBrowserPath(id)) { return relativeToRoot(id); } + // Strip `/@fs` from linked dependencies outside of root so we can normalize + // it in the condition below. This ensures that the style module shared the same is + // part of the same "file" as the main Astro module in the module graph. + // "file" refers to `moduleGraph.fileToModulesMap`. + if (query.type === 'style' && id.startsWith('/@fs')) { + id = removeLeadingForwardSlashWindows(id.slice(4)); + } // Convert file paths to ViteID, meaning on Windows it omits the leading slash if (isFullFilePath(id)) { return viteID(new URL('file://' + id)); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index faf1e2c06..d8724f8dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -606,13 +606,21 @@ importers: chai-as-promised: 7.1.1_chai@4.3.7 mocha: 9.2.2 + packages/astro/e2e/fixtures/_deps/astro-linked-lib: + specifiers: + astro: workspace:* + dependencies: + astro: link:../../../.. + packages/astro/e2e/fixtures/astro-component: specifiers: '@astrojs/preact': ^1.1.0 + '@e2e/astro-linked-lib': link:../_deps/astro-linked-lib astro: workspace:* preact: ^10.11.0 dependencies: '@astrojs/preact': link:../../../../integrations/preact + '@e2e/astro-linked-lib': link:../_deps/astro-linked-lib astro: link:../../.. preact: 10.11.3