diff --git a/.changeset/orange-windows-battle.md b/.changeset/orange-windows-battle.md deleted file mode 100644 index 37fcb28fa..000000000 --- a/.changeset/orange-windows-battle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/cloudflare': minor ---- - -Change build target from `es2020` to `es2022`, for better support diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7161a0d0f..feecf12a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,6 +22,9 @@ jobs: name: Changelog PR or Release if: ${{ github.repository_owner == 'withastro' }} runs-on: ubuntu-latest + permissions: + contents: write + id-token: write steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/snapshot-release.yml b/.github/workflows/snapshot-release.yml index 29f8c7f11..3025c60f0 100644 --- a/.github/workflows/snapshot-release.yml +++ b/.github/workflows/snapshot-release.yml @@ -81,6 +81,8 @@ jobs: id: publish run: | pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1 + echo "Release complete" + cat publish.output.txt echo ::set-output name=result::`cat publish.output.txt` env: # Needs access to publish to npm diff --git a/examples/basics/package.json b/examples/basics/package.json index b9c2f8405..912e95290 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.2.0" + "astro": "^3.2.3" } } diff --git a/examples/blog/package.json b/examples/blog/package.json index f1d800c36..55e083973 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^1.1.0", + "@astrojs/mdx": "^1.1.1", "@astrojs/rss": "^3.0.0", - "@astrojs/sitemap": "^3.0.0", - "astro": "^3.2.0" + "@astrojs/sitemap": "^3.0.1", + "astro": "^3.2.3" } } diff --git a/examples/component/package.json b/examples/component/package.json index 6476be5ac..701f1d180 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -15,7 +15,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^3.2.0" + "astro": "^3.2.3" }, "peerDependencies": { "astro": "^2.0.0-beta.0" diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index b3f1cd709..732152d0b 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/alpinejs": "^0.3.0", + "@astrojs/alpinejs": "^0.3.1", "@types/alpinejs": "^3.7.2", "alpinejs": "^3.12.3", - "astro": "^3.2.0" + "astro": "^3.2.3" } } diff --git a/examples/framework-lit/package.json b/examples/framework-lit/package.json index 9b50c39cc..407227d7f 100644 --- a/examples/framework-lit/package.json +++ b/examples/framework-lit/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/lit": "^3.0.0", + "@astrojs/lit": "^3.0.1", "@webcomponents/template-shadowroot": "^0.2.1", - "astro": "^3.2.0", + "astro": "^3.2.3", "lit": "^2.8.0" } } diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index 508e93a79..48cdd3aa5 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -11,12 +11,12 @@ "astro": "astro" }, "dependencies": { - "@astrojs/preact": "^3.0.0", - "@astrojs/react": "^3.0.2", - "@astrojs/solid-js": "^3.0.1", - "@astrojs/svelte": "^4.0.2", - "@astrojs/vue": "^3.0.0", - "astro": "^3.2.0", + "@astrojs/preact": "^3.0.1", + "@astrojs/react": "^3.0.3", + "@astrojs/solid-js": "^3.0.2", + "@astrojs/svelte": "^4.0.3", + "@astrojs/vue": "^3.0.1", + "astro": "^3.2.3", "preact": "^10.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index f1e16f0da..f57093b82 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/preact": "^3.0.0", + "@astrojs/preact": "^3.0.1", "@preact/signals": "^1.2.1", - "astro": "^3.2.0", + "astro": "^3.2.3", "preact": "^10.17.1" } } diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index fdd46e936..fc5c09440 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -11,10 +11,10 @@ "astro": "astro" }, "dependencies": { - "@astrojs/react": "^3.0.2", + "@astrojs/react": "^3.0.3", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", - "astro": "^3.2.0", + "astro": "^3.2.3", "react": "^18.2.0", "react-dom": "^18.2.0" } diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index e5596fd97..652e66209 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -11,8 +11,8 @@ "astro": "astro" }, "dependencies": { - "@astrojs/solid-js": "^3.0.1", - "astro": "^3.2.0", + "@astrojs/solid-js": "^3.0.2", + "astro": "^3.2.3", "solid-js": "^1.7.11" } } diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index 13c3b0048..cd6fcc4b4 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -11,8 +11,8 @@ "astro": "astro" }, "dependencies": { - "@astrojs/svelte": "^4.0.2", - "astro": "^3.2.0", + "@astrojs/svelte": "^4.0.3", + "astro": "^3.2.3", "svelte": "^4.2.0" } } diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index 31b4a243e..c2a6900d0 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -11,8 +11,8 @@ "astro": "astro" }, "dependencies": { - "@astrojs/vue": "^3.0.0", - "astro": "^3.2.0", + "@astrojs/vue": "^3.0.1", + "astro": "^3.2.3", "vue": "^3.3.4" } } diff --git a/examples/hackernews/package.json b/examples/hackernews/package.json index 662bdfab4..01e390b65 100644 --- a/examples/hackernews/package.json +++ b/examples/hackernews/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/node": "^6.0.1", - "astro": "^3.2.0" + "@astrojs/node": "^6.0.3", + "astro": "^3.2.3" } } diff --git a/examples/integration/package.json b/examples/integration/package.json index 438218492..01b9cba09 100644 --- a/examples/integration/package.json +++ b/examples/integration/package.json @@ -15,7 +15,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^3.2.0" + "astro": "^3.2.3" }, "peerDependencies": { "astro": "^2.0.0-beta.0" diff --git a/examples/middleware/package.json b/examples/middleware/package.json index d15f99ca5..e2c640532 100644 --- a/examples/middleware/package.json +++ b/examples/middleware/package.json @@ -12,8 +12,8 @@ "server": "node dist/server/entry.mjs" }, "dependencies": { - "@astrojs/node": "^6.0.1", - "astro": "^3.2.0", + "@astrojs/node": "^6.0.3", + "astro": "^3.2.3", "html-minifier": "^4.0.0" } } diff --git a/examples/minimal/package.json b/examples/minimal/package.json index 448adabe5..eb852999f 100644 --- a/examples/minimal/package.json +++ b/examples/minimal/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.2.0" + "astro": "^3.2.3" } } diff --git a/examples/non-html-pages/package.json b/examples/non-html-pages/package.json index 0a99088be..7655413b5 100644 --- a/examples/non-html-pages/package.json +++ b/examples/non-html-pages/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.2.0" + "astro": "^3.2.3" } } diff --git a/examples/portfolio/package.json b/examples/portfolio/package.json index d3440479a..058b8a1fc 100644 --- a/examples/portfolio/package.json +++ b/examples/portfolio/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.2.0" + "astro": "^3.2.3" } } diff --git a/examples/ssr/package.json b/examples/ssr/package.json index ac2732434..3873a6098 100644 --- a/examples/ssr/package.json +++ b/examples/ssr/package.json @@ -12,9 +12,9 @@ "server": "node dist/server/entry.mjs" }, "dependencies": { - "@astrojs/node": "^6.0.1", - "@astrojs/svelte": "^4.0.2", - "astro": "^3.2.0", + "@astrojs/node": "^6.0.3", + "@astrojs/svelte": "^4.0.3", + "astro": "^3.2.3", "svelte": "^4.2.0" } } diff --git a/examples/view-transitions/package.json b/examples/view-transitions/package.json index ee1ff91e5..63afa93a2 100644 --- a/examples/view-transitions/package.json +++ b/examples/view-transitions/package.json @@ -10,8 +10,8 @@ "astro": "astro" }, "devDependencies": { - "@astrojs/tailwind": "^5.0.0", - "@astrojs/node": "^6.0.1", - "astro": "^3.2.0" + "@astrojs/tailwind": "^5.0.1", + "@astrojs/node": "^6.0.3", + "astro": "^3.2.3" } } diff --git a/examples/with-markdoc/package.json b/examples/with-markdoc/package.json index 3a05e55ef..47abbe3d7 100644 --- a/examples/with-markdoc/package.json +++ b/examples/with-markdoc/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/markdoc": "^0.5.0", - "astro": "^3.2.0" + "@astrojs/markdoc": "^0.5.2", + "astro": "^3.2.3" } } diff --git a/examples/with-markdown-plugins/package.json b/examples/with-markdown-plugins/package.json index c347f223f..fdf825dcb 100644 --- a/examples/with-markdown-plugins/package.json +++ b/examples/with-markdown-plugins/package.json @@ -11,8 +11,8 @@ "astro": "astro" }, "dependencies": { - "@astrojs/markdown-remark": "^3.2.0", - "astro": "^3.2.0", + "@astrojs/markdown-remark": "^3.2.1", + "astro": "^3.2.3", "hast-util-select": "^5.0.5", "rehype-autolink-headings": "^6.1.1", "rehype-slug": "^5.1.0", diff --git a/examples/with-markdown-shiki/package.json b/examples/with-markdown-shiki/package.json index 17615e975..0da01ebdd 100644 --- a/examples/with-markdown-shiki/package.json +++ b/examples/with-markdown-shiki/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.2.0" + "astro": "^3.2.3" } } diff --git a/examples/with-mdx/package.json b/examples/with-mdx/package.json index 4d65d87bb..a6d84a347 100644 --- a/examples/with-mdx/package.json +++ b/examples/with-mdx/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^1.1.0", - "@astrojs/preact": "^3.0.0", - "astro": "^3.2.0", + "@astrojs/mdx": "^1.1.1", + "@astrojs/preact": "^3.0.1", + "astro": "^3.2.3", "preact": "^10.17.1" } } diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index f2d45cb96..9939e0779 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/preact": "^3.0.0", + "@astrojs/preact": "^3.0.1", "@nanostores/preact": "^0.5.0", - "astro": "^3.2.0", + "astro": "^3.2.3", "nanostores": "^0.9.3", "preact": "^10.17.1" } diff --git a/examples/with-tailwindcss/package.json b/examples/with-tailwindcss/package.json index 560674866..f6b4f9d25 100644 --- a/examples/with-tailwindcss/package.json +++ b/examples/with-tailwindcss/package.json @@ -11,10 +11,10 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^1.1.0", - "@astrojs/tailwind": "^5.0.0", + "@astrojs/mdx": "^1.1.1", + "@astrojs/tailwind": "^5.0.1", "@types/canvas-confetti": "^1.6.0", - "astro": "^3.2.0", + "astro": "^3.2.3", "autoprefixer": "^10.4.15", "canvas-confetti": "^1.6.0", "postcss": "^8.4.28", diff --git a/examples/with-vite-plugin-pwa/package.json b/examples/with-vite-plugin-pwa/package.json index 07dbc1a7c..aafacac3a 100644 --- a/examples/with-vite-plugin-pwa/package.json +++ b/examples/with-vite-plugin-pwa/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.2.0", + "astro": "^3.2.3", "vite-plugin-pwa": "0.16.4", "workbox-window": "^7.0.0" } diff --git a/examples/with-vitest/package.json b/examples/with-vitest/package.json index 421190d78..bcd760017 100644 --- a/examples/with-vitest/package.json +++ b/examples/with-vitest/package.json @@ -12,7 +12,7 @@ "test": "vitest" }, "dependencies": { - "astro": "^3.2.0", + "astro": "^3.2.3", "vitest": "^0.34.2" } } diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index 53c4c2097..0d48bc340 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,46 @@ # astro +## 3.2.3 + +### Patch Changes + +- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI + +- [#8747](https://github.com/withastro/astro/pull/8747) [`d78806dfe`](https://github.com/withastro/astro/commit/d78806dfe0301ea7ffe6c7c1f783bd415ac7cda9) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve error message when user attempts to render a dynamic component reference + +- [#8736](https://github.com/withastro/astro/pull/8736) [`d1c75fe15`](https://github.com/withastro/astro/commit/d1c75fe158839699c59728cf3a83888e8c72a459) Thanks [@bluwy](https://github.com/bluwy)! - Fix `tsconfig.json` update causing the server to crash + +- [#8743](https://github.com/withastro/astro/pull/8743) [`aa265d730`](https://github.com/withastro/astro/commit/aa265d73024422967c1b1c68ad268c419c6c798f) Thanks [@bluwy](https://github.com/bluwy)! - Remove unused CSS output files when inlined + +- [#8700](https://github.com/withastro/astro/pull/8700) [`78adbc443`](https://github.com/withastro/astro/commit/78adbc4433208458291e36713909762e148e1e5d) Thanks [@jacobthesheep](https://github.com/jacobthesheep)! - Update link for Netlify SSR + +- [#8729](https://github.com/withastro/astro/pull/8729) [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436) Thanks [@lilnasy](https://github.com/lilnasy)! - Node-based adapters now create less server-side javascript + +- [#8730](https://github.com/withastro/astro/pull/8730) [`357270f2a`](https://github.com/withastro/astro/commit/357270f2a3d0bf2aa634ba7e52e9d17618eff4a7) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve `astro info` copy to clipboard compatability + +- Updated dependencies [[`21f482657`](https://github.com/withastro/astro/commit/21f4826576c2c812a1604e18717799da3470decd), [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c), [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436)]: + - @astrojs/markdown-remark@3.2.1 + - @astrojs/internal-helpers@0.2.1 + - @astrojs/telemetry@3.0.3 + +## 3.2.2 + +### Patch Changes + +- [#8724](https://github.com/withastro/astro/pull/8724) [`455af3235`](https://github.com/withastro/astro/commit/455af3235b3268852e6988accecc796f03f6d16e) Thanks [@bluwy](https://github.com/bluwy)! - Fix CSS styles on Windows + +- [#8710](https://github.com/withastro/astro/pull/8710) [`4c2bec681`](https://github.com/withastro/astro/commit/4c2bec681b0752e7215b8a32bd2d44bf477adac1) Thanks [@matthewp](https://github.com/matthewp)! - Fixes View transition styles being missing when component used multiple times + +## 3.2.1 + +### Patch Changes + +- [#8680](https://github.com/withastro/astro/pull/8680) [`31c59ad8b`](https://github.com/withastro/astro/commit/31c59ad8b6a72f95c98a306ecf92d198c03110b4) Thanks [@bluwy](https://github.com/bluwy)! - Fix hydration on slow connection + +- [#8698](https://github.com/withastro/astro/pull/8698) [`47ea310f0`](https://github.com/withastro/astro/commit/47ea310f01d06ed1562c790bec348718a2fa8277) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Use a Node-specific image endpoint to resolve images in dev and Node SSR. This should fix many issues related to getting 404 from the \_image endpoint under certain configurations + +- [#8706](https://github.com/withastro/astro/pull/8706) [`345808170`](https://github.com/withastro/astro/commit/345808170fce783ddd3c9a4035a91fa64dcc5f46) Thanks [@bluwy](https://github.com/bluwy)! - Fix duplicated Astro and Vite injected styles + ## 3.2.0 ### Minor Changes diff --git a/packages/astro/astro.js b/packages/astro/astro.js index ef5349854..f227ae9e9 100755 --- a/packages/astro/astro.js +++ b/packages/astro/astro.js @@ -3,7 +3,6 @@ // ISOMORPHIC FILE: NO TOP-LEVEL IMPORT/REQUIRE() ALLOWED // This file has to run as both ESM and CJS on older Node.js versions -// Needed for Stackblitz: https://github.com/stackblitz/webcontainer-core/issues/281 const CI_INSTRUCTIONS = { NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript', @@ -16,15 +15,11 @@ const CI_INSTRUCTIONS = { const engines = '>=18.14.1'; const skipSemverCheckIfAbove = 19; -// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported -// TODO: Remove when Node 18 is supported on Stackblitz -const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null; - /** `astro *` */ async function main() { const version = process.versions.node; // Fast-path for higher Node.js versions - if (!isStackblitz && (parseInt(version) || 0) <= skipSemverCheckIfAbove) { + if ((parseInt(version) || 0) <= skipSemverCheckIfAbove) { try { const semver = await import('semver'); if (!semver.satisfies(version, engines)) { diff --git a/packages/astro/e2e/css-sourcemaps.test.js b/packages/astro/e2e/css-sourcemaps.test.js deleted file mode 100644 index 4ea3fc0e2..000000000 --- a/packages/astro/e2e/css-sourcemaps.test.js +++ /dev/null @@ -1,36 +0,0 @@ -import { expect } from '@playwright/test'; -import { testFactory } from './test-utils.js'; - -const test = testFactory({ - root: './fixtures/css/', -}); - -let devServer; - -test.beforeAll(async ({ astro }) => { - devServer = await astro.startDevServer(); -}); - -test.afterAll(async () => { - await devServer.stop(); -}); - -test.describe('CSS Sourcemap HMR', () => { - test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => { - const html = await astro.fetch('/').then((res) => res.text()); - - // style[data-astro-dev-id] should exist in initial SSR'd markup - expect(html).toMatch('data-astro-dev-id'); - - await page.goto(astro.resolveUrl('/')); - - // Ensure JS has initialized - await page.waitForTimeout(500); - - // style[data-astro-dev-id] should NOT exist once JS runs - expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0); - - // style[data-vite-dev-id] should exist now - expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0); - }); -}); diff --git a/packages/astro/e2e/css.test.js b/packages/astro/e2e/css.test.js index b302d9d90..3e0486d0f 100644 --- a/packages/astro/e2e/css.test.js +++ b/packages/astro/e2e/css.test.js @@ -29,21 +29,9 @@ test.describe('CSS HMR', () => { await expect(h).toHaveCSS('color', 'rgb(0, 128, 0)'); }); - test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => { + test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ astro }) => { const html = await astro.fetch('/').then((res) => res.text()); - - // style[data-astro-dev-id] should exist in initial SSR'd markup - expect(html).toMatch('data-astro-dev-id'); - - await page.goto(astro.resolveUrl('/')); - - // Ensure JS has initialized - await page.waitForTimeout(500); - - // style[data-astro-dev-id] should NOT exist once JS runs - expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0); - - // style[data-vite-dev-id] should exist now - expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0); + // style[data-vite-dev-id] should exist in initial SSR'd markup + expect(html).toMatch('data-vite-dev-id'); }); }); diff --git a/packages/astro/e2e/fixtures/css-sourcemaps/astro.config.mjs b/packages/astro/e2e/fixtures/css-sourcemaps/astro.config.mjs deleted file mode 100644 index 7e8fac1e7..000000000 --- a/packages/astro/e2e/fixtures/css-sourcemaps/astro.config.mjs +++ /dev/null @@ -1,7 +0,0 @@ -export default { - vite: { - css: { - devSourcemap: true, - } - } -}; diff --git a/packages/astro/e2e/fixtures/css-sourcemaps/package.json b/packages/astro/e2e/fixtures/css-sourcemaps/package.json deleted file mode 100644 index 1fa4c2c79..000000000 --- a/packages/astro/e2e/fixtures/css-sourcemaps/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@e2e/css-sourcemaps", - "version": "0.0.0", - "private": true, - "dependencies": { - "astro": "workspace:*" - } -} diff --git a/packages/astro/e2e/fixtures/css-sourcemaps/src/env.d.ts b/packages/astro/e2e/fixtures/css-sourcemaps/src/env.d.ts deleted file mode 100644 index 8c34fb45e..000000000 --- a/packages/astro/e2e/fixtures/css-sourcemaps/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// \ No newline at end of file diff --git a/packages/astro/e2e/fixtures/css-sourcemaps/src/pages/index.astro b/packages/astro/e2e/fixtures/css-sourcemaps/src/pages/index.astro deleted file mode 100644 index 7275177f9..000000000 --- a/packages/astro/e2e/fixtures/css-sourcemaps/src/pages/index.astro +++ /dev/null @@ -1,9 +0,0 @@ -

hello world

- - diff --git a/packages/astro/e2e/fixtures/css-sourcemaps/src/styles/main.css b/packages/astro/e2e/fixtures/css-sourcemaps/src/styles/main.css deleted file mode 100644 index c80a6cde1..000000000 --- a/packages/astro/e2e/fixtures/css-sourcemaps/src/styles/main.css +++ /dev/null @@ -1,3 +0,0 @@ -:root { - --h1-color: red; -} diff --git a/packages/astro/e2e/fixtures/view-transitions/public/one.css b/packages/astro/e2e/fixtures/view-transitions/public/one.css new file mode 100644 index 000000000..4a1589c4d --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/public/one.css @@ -0,0 +1,3 @@ +#one { + background-color: whitesmoke; +} diff --git a/packages/astro/e2e/fixtures/view-transitions/public/styles.css b/packages/astro/e2e/fixtures/view-transitions/public/styles.css new file mode 100644 index 000000000..37fc7c196 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/public/styles.css @@ -0,0 +1,3 @@ +h1 { + color: blue +} diff --git a/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro b/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro index 1dc1a1c24..ddafb98a9 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro @@ -18,6 +18,7 @@ const { link } = Astro.props as Props; margin: auto; } + diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/one.astro index cc57e76d8..d05973036 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/one.astro @@ -1,7 +1,7 @@ --- import Layout from '../components/Layout.astro'; --- - +

Page 1

test go to 2 diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index 05a8f8ad0..31e3128f5 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -20,6 +20,20 @@ function scrollToBottom(page) { }); } +function collectPreloads(page) { + return page.evaluate(() => { + window.preloads = []; + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => + mutation.addedNodes.forEach((node) => { + if (node.nodeName === 'LINK' && node.rel === 'preload') preloads.push(node.href); + }) + ); + }); + observer.observe(document.head, { childList: true }); + }); +} + test.describe('View Transitions', () => { test('Moving from page 1 to page 2', async ({ page, astro }) => { const loads = []; @@ -170,11 +184,15 @@ test.describe('View Transitions', () => { let p = page.locator('#one'); await expect(p, 'should have content').toHaveText('Page 1'); + await collectPreloads(page); + // Go to page 2 await page.click('#click-two'); p = page.locator('#two'); await expect(p, 'should have content').toHaveText('Page 2'); await expect(p, 'imported CSS updated').toHaveCSS('font-size', '24px'); + const preloads = await page.evaluate(() => window.preloads); + expect(preloads.length === 1 && preloads[0].endsWith('/two.css')).toBeTruthy(); }); test('astro:page-load event fires when navigating to new page', async ({ page, astro }) => { @@ -631,7 +649,7 @@ test.describe('View Transitions', () => { }); test('client:only styles are retained on transition', async ({ page, astro }) => { - const totalExpectedStyles = 8; + const totalExpectedStyles = 7; // Go to page 1 await page.goto(astro.resolveUrl('/client-only-one')); diff --git a/packages/astro/package.json b/packages/astro/package.json index afa6a47d7..33bf6eb4f 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "astro", - "version": "3.2.0", + "version": "3.2.3", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "type": "module", "author": "withastro", @@ -56,7 +56,7 @@ "./components/*": "./components/*", "./assets": "./dist/assets/index.js", "./assets/utils": "./dist/assets/utils/index.js", - "./assets/image-endpoint": "./dist/assets/image-endpoint.js", + "./assets/endpoint/*": "./dist/assets/endpoint/*.js", "./assets/services/sharp": "./dist/assets/services/sharp.js", "./assets/services/squoosh": "./dist/assets/services/squoosh.js", "./assets/services/noop": "./dist/assets/services/noop.js", @@ -168,7 +168,6 @@ "string-width": "^6.1.0", "strip-ansi": "^7.1.0", "tsconfig-resolver": "^3.0.1", - "undici": "^5.23.0", "unist-util-visit": "^4.1.2", "vfile": "^5.3.7", "vite": "^4.4.9", @@ -226,5 +225,8 @@ "engines": { "node": ">=18.14.1", "npm": ">=6.14.0" + }, + "publishConfig": { + "provenance": true } } diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 29123235f..2bacd5d53 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -636,7 +636,7 @@ export interface AstroUserConfig { * @see output * @description * - * Deploy to your favorite server, serverless, or edge host with build adapters. Import one of our first-party adapters for [Netlify](https://docs.astro.build/en/guides/deploy/netlify/#adapter-for-ssredge), [Vercel](https://docs.astro.build/en/guides/deploy/vercel/#adapter-for-ssr), and more to engage Astro SSR. + * Deploy to your favorite server, serverless, or edge host with build adapters. Import one of our first-party adapters for [Netlify](https://docs.astro.build/en/guides/deploy/netlify/#adapter-for-ssr), [Vercel](https://docs.astro.build/en/guides/deploy/vercel/#adapter-for-ssr), and more to engage Astro SSR. * * [See our Server-side Rendering guide](https://docs.astro.build/en/guides/server-side-rendering/) for more on SSR, and [our deployment guides](https://docs.astro.build/en/guides/deploy/) for a complete list of hosts. * @@ -1172,10 +1172,10 @@ export interface AstroUserConfig { * Pass [rehype plugins](https://github.com/remarkjs/remark-rehype) to customize how your Markdown's output HTML is processed. You can import and apply the plugin function (recommended), or pass the plugin name as a string. * * ```js - * import rehypeMinifyHtml from 'rehype-minify'; + * import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis'; * { * markdown: { - * rehypePlugins: [rehypeMinifyHtml] + * rehypePlugins: [rehypeAccessibleEmojis] * } * } * ``` @@ -2213,7 +2213,7 @@ export interface SSRMetadata { hasRenderedHead: boolean; headInTree: boolean; extraHead: string[]; - propagators: Map; + propagators: Set; } /* Preview server stuff */ diff --git a/packages/astro/src/assets/image-endpoint.ts b/packages/astro/src/assets/endpoint/generic.ts similarity index 89% rename from packages/astro/src/assets/image-endpoint.ts rename to packages/astro/src/assets/endpoint/generic.ts index b7f027536..140189fe0 100644 --- a/packages/astro/src/assets/image-endpoint.ts +++ b/packages/astro/src/assets/endpoint/generic.ts @@ -1,8 +1,8 @@ import { isRemotePath } from '@astrojs/internal-helpers/path'; import mime from 'mime/lite.js'; -import type { APIRoute } from '../@types/astro.js'; -import { getConfiguredImageService, isRemoteAllowed } from './internal.js'; -import { etag } from './utils/etag.js'; +import type { APIRoute } from '../../@types/astro.js'; +import { getConfiguredImageService, isRemoteAllowed } from '../internal.js'; +import { etag } from '../utils/etag.js'; // @ts-expect-error import { imageConfig } from 'astro:assets'; @@ -40,7 +40,6 @@ export const GET: APIRoute = async ({ request }) => { let inputBuffer: Buffer | undefined = undefined; - // TODO: handle config subpaths? const sourceUrl = isRemotePath(transform.src) ? new URL(transform.src) : new URL(transform.src, url.origin); diff --git a/packages/astro/src/assets/endpoint/node.ts b/packages/astro/src/assets/endpoint/node.ts new file mode 100644 index 000000000..1e9616264 --- /dev/null +++ b/packages/astro/src/assets/endpoint/node.ts @@ -0,0 +1,88 @@ +import { isRemotePath, removeQueryString } from '@astrojs/internal-helpers/path'; +import { readFile } from 'fs/promises'; +import mime from 'mime/lite.js'; +import type { APIRoute } from '../../@types/astro.js'; +import { getConfiguredImageService, isRemoteAllowed } from '../internal.js'; +import { etag } from '../utils/etag.js'; +// @ts-expect-error +import { assetsDir, imageConfig } from 'astro:assets'; + +async function loadLocalImage(src: string, url: URL) { + const filePath = import.meta.env.DEV + ? removeQueryString(src.slice('/@fs'.length)) + : new URL('.' + src, assetsDir); + let buffer: Buffer | undefined = undefined; + + try { + buffer = await readFile(filePath); + } catch (e) { + const sourceUrl = new URL(src, url.origin); + buffer = await loadRemoteImage(sourceUrl); + } + + return buffer; +} + +async function loadRemoteImage(src: URL) { + try { + const res = await fetch(src); + + if (!res.ok) { + return undefined; + } + + return Buffer.from(await res.arrayBuffer()); + } catch (err: unknown) { + return undefined; + } +} + +/** + * Endpoint used in dev and SSR to serve optimized images by the base image services + */ +export const GET: APIRoute = async ({ request }) => { + try { + const imageService = await getConfiguredImageService(); + + if (!('transform' in imageService)) { + throw new Error('Configured image service is not a local service'); + } + + const url = new URL(request.url); + const transform = await imageService.parseURL(url, imageConfig); + + if (!transform?.src) { + throw new Error('Incorrect transform returned by `parseURL`'); + } + + let inputBuffer: Buffer | undefined = undefined; + + if (isRemotePath(transform.src)) { + if (isRemoteAllowed(transform.src, imageConfig) === false) { + return new Response('Forbidden', { status: 403 }); + } + + inputBuffer = await loadRemoteImage(new URL(transform.src)); + } else { + inputBuffer = await loadLocalImage(transform.src, url); + } + + if (!inputBuffer) { + return new Response('Not Found', { status: 404 }); + } + + const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig); + + return new Response(data, { + status: 200, + headers: { + 'Content-Type': mime.getType(format) ?? `image/${format}`, + 'Cache-Control': 'public, max-age=31536000', + ETag: etag(data.toString()), + Date: new Date().toUTCString(), + }, + }); + } catch (err: unknown) { + return new Response(`Server Error: ${err}`, { status: 500 }); + } +}; diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts index f6c3b0b52..9cb48f588 100644 --- a/packages/astro/src/assets/internal.ts +++ b/packages/astro/src/assets/internal.ts @@ -10,10 +10,11 @@ import type { } from './types.js'; import { matchHostname, matchPattern } from './utils/remotePattern.js'; -export function injectImageEndpoint(settings: AstroSettings) { - const endpointEntrypoint = settings.config.image.endpoint ?? 'astro/assets/image-endpoint'; +export function injectImageEndpoint(settings: AstroSettings, mode: 'dev' | 'build') { + const endpointEntrypoint = + settings.config.image.endpoint ?? + (mode === 'dev' ? 'astro/assets/endpoint/node' : 'astro/assets/endpoint/generic'); - // TODO: Add a setting to disable the image endpoint settings.injectedRoutes.push({ pattern: '/_image', entryPoint: endpointEntrypoint, diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts index 9c95b6dc4..fd3ca2c32 100644 --- a/packages/astro/src/assets/vite-plugin-assets.ts +++ b/packages/astro/src/assets/vite-plugin-assets.ts @@ -10,6 +10,7 @@ import { prependForwardSlash, removeQueryString, } from '../core/path.js'; +import { isServerLikeOutput } from '../prerender/utils.js'; import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from './consts.js'; import { emitESMImage } from './utils/emitAsset.js'; import { hashTransform, propsToFilename } from './utils/transformToPath.js'; @@ -58,6 +59,13 @@ export default function assets({ export { default as Image } from "astro/components/Image.astro"; export const imageConfig = ${JSON.stringify(settings.config.image)}; + export const assetsDir = new URL(${JSON.stringify( + new URL( + isServerLikeOutput(settings.config) + ? settings.config.build.client + : settings.config.outDir + ) + )}); export const getImage = async (options) => await getImageInternal(options, imageConfig); `; } diff --git a/packages/astro/src/cli/info/index.ts b/packages/astro/src/cli/info/index.ts index 2ee9ffd0d..cfa9aca8f 100644 --- a/packages/astro/src/cli/info/index.ts +++ b/packages/astro/src/cli/info/index.ts @@ -41,10 +41,22 @@ export async function printInfo({ flags }: InfoOptions) { await copyToClipboard(output.trim()); } -const SUPPORTED_SYSTEM = new Set(['darwin', 'win32']); async function copyToClipboard(text: string) { const system = platform(); - if (!SUPPORTED_SYSTEM.has(system)) return; + let command = ''; + if (system === 'darwin') { + command = 'pbcopy'; + } else if (system === 'win32') { + command = 'clip'; + } else { + // Unix: check if `xclip` is installed + const output = execSync('which xclip', { encoding: 'utf8' }); + if (output[0] !== '/') { + // Did not find a path for xclip, bail out! + return; + } + command = 'xclip -sel clipboard -l 1'; + } console.log(); const { shouldCopy } = await prompts({ @@ -54,11 +66,11 @@ async function copyToClipboard(text: string) { initial: true, }); if (!shouldCopy) return; - const command = system === 'darwin' ? 'pbcopy' : 'clip'; + try { - execSync(`echo ${JSON.stringify(text.trim())} | ${command}`, { + execSync(command, { + input: text.trim(), encoding: 'utf8', - stdio: 'ignore', }); } catch (e) { console.error( diff --git a/packages/astro/src/content/vite-plugin-content-assets.ts b/packages/astro/src/content/vite-plugin-content-assets.ts index 5d82a684f..133fc9edd 100644 --- a/packages/astro/src/content/vite-plugin-content-assets.ts +++ b/packages/astro/src/content/vite-plugin-content-assets.ts @@ -64,7 +64,7 @@ export function astroContentAssetPropagationPlugin({ if (!devModuleLoader.getModuleById(basePath)?.ssrModule) { await devModuleLoader.import(basePath); } - const { stylesMap, urls } = await getStylesForURL( + const { styles, urls } = await getStylesForURL( pathToFileURL(basePath), devModuleLoader, 'development' @@ -77,7 +77,7 @@ export function astroContentAssetPropagationPlugin({ ); stringifiedLinks = JSON.stringify([...urls]); - stringifiedStyles = JSON.stringify([...stylesMap.values()]); + stringifiedStyles = JSON.stringify(styles.map((s) => s.content)); stringifiedScripts = JSON.stringify([...hoistedScripts]); } else { // Otherwise, use placeholders to inject styles and scripts diff --git a/packages/astro/src/content/vite-plugin-content-imports.ts b/packages/astro/src/content/vite-plugin-content-imports.ts index 4643e0922..15ca6d956 100644 --- a/packages/astro/src/content/vite-plugin-content-imports.ts +++ b/packages/astro/src/content/vite-plugin-content-imports.ts @@ -148,9 +148,15 @@ export const _internal = { hasContentFlag(modUrl, DATA_FLAG) || Boolean(getContentRendererByViteId(modUrl, settings)) ) { - const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl); - if (mod) { - viteServer.moduleGraph.invalidateModule(mod); + try { + const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl); + if (mod) { + viteServer.moduleGraph.invalidateModule(mod); + } + } catch (e: any) { + // The server may be closed due to a restart caused by this file change + if (e.code === 'ERR_CLOSED_SERVER') break; + throw e; } } } diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index aefea5080..5f5ae69a1 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -111,7 +111,7 @@ class AstroBuilder { }); if (isServerLikeOutput(this.settings.config)) { - this.settings = injectImageEndpoint(this.settings); + this.settings = injectImageEndpoint(this.settings, 'build'); } this.manifest = createRouteManifest({ settings: this.settings }, this.logger); diff --git a/packages/astro/src/core/build/plugins/plugin-css.ts b/packages/astro/src/core/build/plugins/plugin-css.ts index d85dc8e56..85652e13b 100644 --- a/packages/astro/src/core/build/plugins/plugin-css.ts +++ b/packages/astro/src/core/build/plugins/plugin-css.ts @@ -200,7 +200,7 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] { const inlineConfig = settings.config.build.inlineStylesheets; const { assetsInlineLimit = 4096 } = settings.config.vite?.build ?? {}; - Object.entries(bundle).forEach(([_, stylesheet]) => { + Object.entries(bundle).forEach(([id, stylesheet]) => { if ( stylesheet.type !== 'asset' || stylesheet.name?.endsWith('.css') !== true || @@ -224,10 +224,15 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] { : { type: 'external', src: stylesheet.fileName }; const pages = Array.from(eachPageData(internals)); + let sheetAddedToPage = false; pages.forEach((pageData) => { const orderingInfo = pagesToCss[pageData.moduleSpecifier]?.[stylesheet.fileName]; - if (orderingInfo !== undefined) return pageData.styles.push({ ...orderingInfo, sheet }); + if (orderingInfo !== undefined) { + pageData.styles.push({ ...orderingInfo, sheet }); + sheetAddedToPage = true; + return; + } const propagatedPaths = pagesToPropagatedCss[pageData.moduleSpecifier]; if (propagatedPaths === undefined) return; @@ -243,8 +248,21 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] { pageData.propagatedStyles.set(pageInfoId, new Set()).get(pageInfoId)!; propagatedStyles.add(sheet); + sheetAddedToPage = true; }); }); + + if (toBeInlined && sheetAddedToPage) { + // CSS is already added to all used pages, we can delete it from the bundle + // and make sure no chunks reference it via `importedCss` (for Vite preloading) + // to avoid duplicate CSS. + delete bundle[id]; + for (const chunk of Object.values(bundle)) { + if (chunk.type === 'chunk') { + chunk.viteMetadata?.importedCss?.delete(id); + } + } + } }); }, }; diff --git a/packages/astro/src/core/dev/container.ts b/packages/astro/src/core/dev/container.ts index 52dd4c1a4..6cc5713f2 100644 --- a/packages/astro/src/core/dev/container.ts +++ b/packages/astro/src/core/dev/container.ts @@ -50,7 +50,7 @@ export async function createContainer({ isRestart, }); - settings = injectImageEndpoint(settings); + settings = injectImageEndpoint(settings, 'dev'); const { base, diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index 380e9e345..b62ba8bed 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -39,7 +39,6 @@ export function createAPIContext({ props, adapterName, }: CreateAPIContext): APIContext { - initResponseWithEncoding(); const context = { cookies: new AstroCookies(request), request, @@ -92,44 +91,28 @@ export function createAPIContext({ type ResponseParameters = ConstructorParameters; -export let ResponseWithEncoding: ReturnType; -// TODO Remove this after StackBlitz supports Node 18. -let initResponseWithEncoding = () => { - class LocalResponseWithEncoding extends Response { - constructor( - body: ResponseParameters[0], - init: ResponseParameters[1], - encoding?: BufferEncoding - ) { - // If a body string is given, try to encode it to preserve the behaviour as simple objects. - // We don't do the full handling as simple objects so users can control how headers are set instead. - if (typeof body === 'string') { - // In NodeJS, we can use Buffer.from which supports all BufferEncoding - if (typeof Buffer !== 'undefined' && Buffer.from) { - body = Buffer.from(body, encoding); - } - // In non-NodeJS, use the web-standard TextEncoder for utf-8 strings - else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') { - body = encoder.encode(body); - } +export class ResponseWithEncoding extends Response { + constructor(body: ResponseParameters[0], init: ResponseParameters[1], encoding?: BufferEncoding) { + // If a body string is given, try to encode it to preserve the behaviour as simple objects. + // We don't do the full handling as simple objects so users can control how headers are set instead. + if (typeof body === 'string') { + // In NodeJS, we can use Buffer.from which supports all BufferEncoding + if (typeof Buffer !== 'undefined' && Buffer.from) { + body = Buffer.from(body, encoding); } - - super(body, init); - - if (encoding) { - this.headers.set('X-Astro-Encoding', encoding); + // In non-NodeJS, use the web-standard TextEncoder for utf-8 strings + else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') { + body = encoder.encode(body); } } + + super(body, init); + + if (encoding) { + this.headers.set('X-Astro-Encoding', encoding); + } } - - // Set the module scoped variable. - ResponseWithEncoding = LocalResponseWithEncoding; - - // Turn this into a noop. - initResponseWithEncoding = (() => {}) as any; - - return LocalResponseWithEncoding; -}; +} export async function callEndpoint( mod: EndpointHandler, diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 5f825126f..d805bb6ff 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -1158,7 +1158,7 @@ export const ContentSchemaContainsSlugError = { /** * @docs * @message A collection queried via `getCollection()` does not exist. - * @deprecated Collections that do not exist no longer result in an error. A warning is omitted instead. + * @deprecated Collections that do not exist no longer result in an error. A warning is given instead. * @description * When querying a collection, ensure a collection directory with the requested name exists under `src/content/`. */ diff --git a/packages/astro/src/core/module-loader/vite.ts b/packages/astro/src/core/module-loader/vite.ts index f58b2e720..48ec230f0 100644 --- a/packages/astro/src/core/module-loader/vite.ts +++ b/packages/astro/src/core/module-loader/vite.ts @@ -1,19 +1,52 @@ import { EventEmitter } from 'node:events'; +import path from 'node:path'; import type * as vite from 'vite'; import type { ModuleLoader, ModuleLoaderEventEmitter } from './loader.js'; export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader { const events = new EventEmitter() as ModuleLoaderEventEmitter; - viteServer.watcher.on('add', (...args) => events.emit('file-add', args)); - viteServer.watcher.on('unlink', (...args) => events.emit('file-unlink', args)); - viteServer.watcher.on('change', (...args) => events.emit('file-change', args)); + let isTsconfigUpdated = false; + function isTsconfigUpdate(filePath: string) { + const result = path.basename(filePath) === 'tsconfig.json'; + if (result) isTsconfigUpdated = true; + return result; + } - wrapMethod(viteServer.ws, 'send', (msg) => { + // Skip event emit on tsconfig change as Vite restarts the server, and we don't + // want to trigger unnecessary work that will be invalidated shortly. + viteServer.watcher.on('add', (...args) => { + if (!isTsconfigUpdate(args[0])) { + events.emit('file-add', args); + } + }); + viteServer.watcher.on('unlink', (...args) => { + if (!isTsconfigUpdate(args[0])) { + events.emit('file-unlink', args); + } + }); + viteServer.watcher.on('change', (...args) => { + if (!isTsconfigUpdate(args[0])) { + events.emit('file-change', args); + } + }); + + const _wsSend = viteServer.ws.send; + viteServer.ws.send = function (...args: any) { + // If the tsconfig changed, Vite will trigger a reload as it invalidates the module. + // However in Astro, the whole server is restarted when the tsconfig changes. If we + // do a restart and reload at the same time, the browser will refetch and the server + // is not ready yet, causing a blank page. Here we block that reload from happening. + if (isTsconfigUpdated) { + isTsconfigUpdated = false; + return; + } + const msg = args[0] as vite.HMRPayload; if (msg?.type === 'error') { events.emit('hmr-error', msg); } - }); + _wsSend.apply(this, args); + }; return { import(src) { @@ -56,11 +89,3 @@ export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader { events, }; } - -function wrapMethod(object: any, method: string, newFn: (...args: any[]) => void) { - const orig = object[method]; - object[method] = function (...args: any[]) { - newFn.apply(this, args); - return orig.apply(this, args); - }; -} diff --git a/packages/astro/src/core/polyfill.ts b/packages/astro/src/core/polyfill.ts index ea7916eb3..c183d23f6 100644 --- a/packages/astro/src/core/polyfill.ts +++ b/packages/astro/src/core/polyfill.ts @@ -1,63 +1,7 @@ +import buffer from 'node:buffer'; import crypto from 'node:crypto'; -import { - ByteLengthQueuingStrategy, - CountQueuingStrategy, - ReadableByteStreamController, - ReadableStream, - ReadableStreamBYOBReader, - ReadableStreamBYOBRequest, - ReadableStreamDefaultController, - ReadableStreamDefaultReader, - TransformStream, - WritableStream, - WritableStreamDefaultController, - WritableStreamDefaultWriter, -} from 'node:stream/web'; -import { File, FormData, Headers, Request, Response, fetch } from 'undici'; - -// NOTE: This file does not intend to polyfill everything that exists, its main goal is to make life easier -// for users deploying to runtime that do support these features. In the future, we hope for this file to disappear. - -// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported -// TODO: Remove when Node 18 is supported on Stackblitz. File should get imported from `node:buffer` instead of `undici` once this is removed -const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null; export function apply() { - if (isStackblitz) { - const neededPolyfills = { - ByteLengthQueuingStrategy, - CountQueuingStrategy, - ReadableByteStreamController, - ReadableStream, - ReadableStreamBYOBReader, - ReadableStreamBYOBRequest, - ReadableStreamDefaultController, - ReadableStreamDefaultReader, - TransformStream, - WritableStream, - WritableStreamDefaultController, - WritableStreamDefaultWriter, - File, - FormData, - Headers, - Request, - Response, - fetch, - }; - - for (let polyfillName of Object.keys(neededPolyfills)) { - if (Object.hasOwnProperty.call(globalThis, polyfillName)) continue; - - // Add polyfill to globalThis - Object.defineProperty(globalThis, polyfillName, { - configurable: true, - enumerable: true, - writable: true, - value: neededPolyfills[polyfillName as keyof typeof neededPolyfills], - }); - } - } - // Remove when Node 18 is dropped for Node 20 if (!globalThis.crypto) { Object.defineProperty(globalThis, 'crypto', { @@ -68,7 +12,7 @@ export function apply() { // Remove when Node 18 is dropped for Node 20 if (!globalThis.File) { Object.defineProperty(globalThis, 'File', { - value: File, + value: buffer.File, }); } } diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index abfcb5e3e..6f8ca9303 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -224,7 +224,7 @@ export function createResult(args: CreateResultArgs): SSRResult { hasDirectives: new Set(), headInTree: false, extraHead: [], - propagators: new Map(), + propagators: new Set(), }, }; diff --git a/packages/astro/src/runtime/client/hmr.ts b/packages/astro/src/runtime/client/hmr.ts index 989ddc6b9..5b6eddc23 100644 --- a/packages/astro/src/runtime/client/hmr.ts +++ b/packages/astro/src/runtime/client/hmr.ts @@ -1,46 +1,7 @@ /// if (import.meta.hot) { - // Vite injects `