From 11c58a9c5a33a44756435e2acede68cb274fb05b Mon Sep 17 00:00:00 2001 From: Martin Trapp <94928215+martrapp@users.noreply.github.com> Date: Mon, 6 May 2024 15:55:37 +0200 Subject: [PATCH 1/6] Adds missing readonly (#10956) --- packages/astro/src/transitions/events.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro/src/transitions/events.ts b/packages/astro/src/transitions/events.ts index 969a12139943..a35fd72cb6f3 100644 --- a/packages/astro/src/transitions/events.ts +++ b/packages/astro/src/transitions/events.ts @@ -25,7 +25,7 @@ class BeforeEvent extends Event { readonly sourceElement: Element | undefined; readonly info: any; newDocument: Document; - signal: AbortSignal; + readonly signal: AbortSignal; constructor( type: string, From 082abb82d574a200f9168ee5ae92c65c71e29eda Mon Sep 17 00:00:00 2001 From: Florian Lefebvre Date: Mon, 6 May 2024 16:02:06 +0200 Subject: [PATCH 2/6] feat(vue): add support for devtools (#10929) Co-authored-by: Sarah Rainsberger --- .changeset/thin-rabbits-wait.md | 18 ++ packages/integrations/vue/package.json | 3 +- packages/integrations/vue/src/index.ts | 35 ++-- pnpm-lock.yaml | 243 ++++++++++++++++++++++++- 4 files changed, 279 insertions(+), 20 deletions(-) create mode 100644 .changeset/thin-rabbits-wait.md diff --git a/.changeset/thin-rabbits-wait.md b/.changeset/thin-rabbits-wait.md new file mode 100644 index 000000000000..1556e0147fc9 --- /dev/null +++ b/.changeset/thin-rabbits-wait.md @@ -0,0 +1,18 @@ +--- +"@astrojs/vue": minor +--- + +Adds a `devtools` option + +You can enable the [official Vue DevTools](https://devtools-next.vuejs.org/) while working in development mode by setting `devtools:true` in your `vue()` integration config: + +```js +import { defineConfig } from "astro/config" +import vue from "@astrojs/vue" + +export default defineConfig({ + integrations: [ + vue({ devtools: true }) + ] +}) +``` \ No newline at end of file diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json index 102d102ba5db..5fcf280a49b4 100644 --- a/packages/integrations/vue/package.json +++ b/packages/integrations/vue/package.json @@ -42,7 +42,8 @@ "dependencies": { "@vitejs/plugin-vue": "^5.0.4", "@vitejs/plugin-vue-jsx": "^3.1.0", - "@vue/compiler-sfc": "^3.4.26" + "@vue/compiler-sfc": "^3.4.26", + "vite-plugin-vue-devtools": "^7.1.3" }, "devDependencies": { "astro": "workspace:*", diff --git a/packages/integrations/vue/src/index.ts b/packages/integrations/vue/src/index.ts index 803095c19c4b..f61b35a09d6b 100644 --- a/packages/integrations/vue/src/index.ts +++ b/packages/integrations/vue/src/index.ts @@ -3,12 +3,16 @@ import type { Options as VueOptions } from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue'; import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx'; import { MagicString } from '@vue/compiler-sfc'; -import type { AstroIntegration, AstroRenderer } from 'astro'; +import type { AstroIntegration, AstroRenderer, HookParameters } from 'astro'; import type { Plugin, UserConfig } from 'vite'; +const VIRTUAL_MODULE_ID = 'virtual:@astrojs/vue/app'; +const RESOLVED_VIRTUAL_MODULE_ID = `\0${VIRTUAL_MODULE_ID}`; + interface Options extends VueOptions { jsx?: boolean | VueJsxOptions; appEntrypoint?: string; + devtools?: boolean; } function getRenderer(): AstroRenderer { @@ -28,9 +32,6 @@ function getJsxRenderer(): AstroRenderer { } function virtualAppEntrypoint(options?: Options): Plugin { - const virtualModuleId = 'virtual:@astrojs/vue/app'; - const resolvedVirtualModuleId = '\0' + virtualModuleId; - let isBuild: boolean; let root: string; let appEntrypoint: string | undefined; @@ -49,12 +50,12 @@ function virtualAppEntrypoint(options?: Options): Plugin { } }, resolveId(id: string) { - if (id == virtualModuleId) { - return resolvedVirtualModuleId; + if (id == VIRTUAL_MODULE_ID) { + return RESOLVED_VIRTUAL_MODULE_ID; } }, load(id: string) { - if (id === resolvedVirtualModuleId) { + if (id === RESOLVED_VIRTUAL_MODULE_ID) { if (appEntrypoint) { return `\ import * as mod from ${JSON.stringify(appEntrypoint)}; @@ -93,7 +94,10 @@ export const setup = async (app) => { }; } -async function getViteConfiguration(options?: Options): Promise { +async function getViteConfiguration( + command: HookParameters<'astro:config:setup'>['command'], + options?: Options +): Promise { let vueOptions = { ...options, template: { @@ -105,7 +109,7 @@ async function getViteConfiguration(options?: Options): Promise { const config: UserConfig = { optimizeDeps: { include: ['@astrojs/vue/client.js', 'vue'], - exclude: ['@astrojs/vue/server.js', 'virtual:@astrojs/vue/app'], + exclude: ['@astrojs/vue/server.js', VIRTUAL_MODULE_ID], }, plugins: [vue(vueOptions), virtualAppEntrypoint(vueOptions)], ssr: { @@ -119,6 +123,15 @@ async function getViteConfiguration(options?: Options): Promise { config.plugins?.push(vueJsx(jsxOptions)); } + if (command === 'dev' && options?.devtools) { + const vueDevTools = (await import('vite-plugin-vue-devtools')).default; + config.plugins?.push( + vueDevTools({ + appendTo: VIRTUAL_MODULE_ID, + }) + ); + } + return config; } @@ -126,12 +139,12 @@ export default function (options?: Options): AstroIntegration { return { name: '@astrojs/vue', hooks: { - 'astro:config:setup': async ({ addRenderer, updateConfig }) => { + 'astro:config:setup': async ({ addRenderer, updateConfig, command }) => { addRenderer(getRenderer()); if (options?.jsx) { addRenderer(getJsxRenderer()); } - updateConfig({ vite: await getViteConfiguration(options) }); + updateConfig({ vite: await getViteConfiguration(command, options) }); }, }, }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e7fd73d2047..0649f9fa1f17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5235,6 +5235,9 @@ importers: '@vue/compiler-sfc': specifier: ^3.4.26 version: 3.4.26 + vite-plugin-vue-devtools: + specifier: ^7.1.3 + version: 7.1.3(vite@5.2.10)(vue@3.4.26) devDependencies: astro: specifier: workspace:* @@ -5584,6 +5587,10 @@ packages: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 + /@antfu/utils@0.7.7: + resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==} + dev: false + /@asamuzakjp/dom-selector@2.0.2: resolution: {integrity: sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==} dependencies: @@ -5787,7 +5794,7 @@ packages: '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-split-export-declaration': 7.24.5 semver: 6.3.1 dev: false @@ -5897,13 +5904,6 @@ packages: '@babel/types': 7.24.5 dev: false - /@babel/helper-split-export-declaration@7.22.6: - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.5 - dev: false - /@babel/helper-split-export-declaration@7.24.5: resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} engines: {node: '>=6.9.0'} @@ -5955,6 +5955,59 @@ packages: dependencies: '@babel/types': 7.24.5 + /@babel/plugin-proposal-decorators@7.24.1(@babel/core@7.24.5): + resolution: {integrity: sha512-zPEvzFijn+hRvJuX2Vu3KbEBN39LN3f7tW3MQO2LsIs57B26KU+kUc82BdAktS1VCM6libzh45eKGI65lg0cpA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.5) + '@babel/helper-plugin-utils': 7.24.0 + '@babel/plugin-syntax-decorators': 7.24.1(@babel/core@7.24.5) + dev: false + + /@babel/plugin-syntax-decorators@7.24.1(@babel/core@7.24.5): + resolution: {integrity: sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.0 + dev: false + + /@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.5): + resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.0 + dev: false + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.5): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.0 + dev: false + /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5): resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} engines: {node: '>=6.9.0'} @@ -7780,6 +7833,10 @@ packages: playwright: 1.43.1 dev: true + /@polka/url@1.0.0-next.25: + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + dev: false + /@preact/preset-vite@2.8.2(preact@10.20.2): resolution: {integrity: sha512-m3tl+M8IO8jgiHnk+7LSTFl8axdPXloewi7iGVLdmCwf34XOzEUur0bZVewW4DUbUipFjTS2CXu27+5f/oexBA==} peerDependencies: @@ -7873,6 +7930,20 @@ packages: picomatch: 2.3.1 dev: false + /@rollup/pluginutils@5.1.0: + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: false + /@rollup/rollup-android-arm-eabi@4.17.1: resolution: {integrity: sha512-P6Wg856Ou/DLpR+O0ZLneNmrv7QpqBg+hK4wE05ijbC/t349BRfMfx+UFj5Ha3fCFopIa6iSZlpdaB4agkWp2Q==} cpu: [arm] @@ -8982,6 +9053,39 @@ packages: '@vue/compiler-dom': 3.4.26 '@vue/shared': 3.4.26 + /@vue/devtools-core@7.1.3(vite@5.2.10)(vue@3.4.26): + resolution: {integrity: sha512-pVbWi8pf2Z/fZPioYOIgu+cv9pQG55k4D8bL31ec+Wfe+pQR0ImFDu0OhHfch1Ra8uvLLrAZTF4IKeGAkmzD4A==} + dependencies: + '@vue/devtools-kit': 7.1.3(vue@3.4.26) + '@vue/devtools-shared': 7.1.3 + mitt: 3.0.1 + nanoid: 3.3.7 + pathe: 1.1.2 + vite-hot-client: 0.2.3(vite@5.2.10) + transitivePeerDependencies: + - vite + - vue + dev: false + + /@vue/devtools-kit@7.1.3(vue@3.4.26): + resolution: {integrity: sha512-NFskFSJMVCBXTkByuk2llzI3KD3Blcm7WqiRorWjD6nClHPgkH5BobDH08rfulqq5ocRt5xV+3qOT1Q9FXJrwQ==} + peerDependencies: + vue: ^3.0.0 + dependencies: + '@vue/devtools-shared': 7.1.3 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + vue: 3.4.26(typescript@5.4.5) + dev: false + + /@vue/devtools-shared@7.1.3: + resolution: {integrity: sha512-KJ3AfgjTn3tJz/XKF+BlVShNPecim3G21oHRue+YQOsooW+0s+qXvm09U09aO7yBza5SivL1QgxSrzAbiKWjhQ==} + dependencies: + rfdc: 1.3.1 + dev: false + /@vue/reactivity@3.1.5: resolution: {integrity: sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==} dependencies: @@ -10594,6 +10698,10 @@ packages: is-arrayish: 0.2.1 dev: true + /error-stack-parser-es@0.1.1: + resolution: {integrity: sha512-g/9rfnvnagiNf+DRMHEVGuGuIBlCIMDFoTA616HaP2l9PlCjGjVhD98PNbVSJvmK4TttqT5mV5tInMhoFgi+aA==} + dev: false + /es-abstract@1.23.3: resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} @@ -11711,6 +11819,10 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + /hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + dev: false + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true @@ -13351,6 +13463,10 @@ packages: rimraf: 5.0.5 dev: false + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: false + /mixme@0.5.10: resolution: {integrity: sha512-5H76ANWinB1H3twpJ6JY8uvAtpmFvHNArpilJAjXRKXSDDLPIMoZArw5SH0q9z+lLs8IrMw7Q2VWpWimFKFT1Q==} engines: {node: '>= 8.0.0'} @@ -13945,6 +14061,10 @@ packages: engines: {node: '>= 14.16'} dev: true + /perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + dev: false + /periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} dependencies: @@ -14995,6 +15115,10 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + /rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + dev: false + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true @@ -15363,6 +15487,15 @@ packages: is-arrayish: 0.3.2 dev: false + /sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + dev: false + /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} dev: false @@ -15496,6 +15629,11 @@ packages: resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} dev: true + /speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + dev: false + /speech-rule-engine@4.0.7: resolution: {integrity: sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==} hasBin: true @@ -15965,6 +16103,11 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + /totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + dev: false + /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} @@ -16510,6 +16653,17 @@ packages: unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 + /vite-hot-client@0.2.3(vite@5.2.10): + resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 5.2.10(@types/node@18.19.31)(sass@1.75.0) + dev: false + /vite-node@1.5.0(@types/node@18.19.31): resolution: {integrity: sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -16531,6 +16685,33 @@ packages: - terser dev: false + /vite-plugin-inspect@0.8.4(vite@5.2.10): + resolution: {integrity: sha512-G0N3rjfw+AiiwnGw50KlObIHYWfulVwaCBUBLh2xTW9G1eM9ocE5olXkEYUbwyTmX+azM8duubi+9w5awdCz+g==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + vite: + optional: true + dependencies: + '@antfu/utils': 0.7.7 + '@rollup/pluginutils': 5.1.0 + debug: 4.3.4(supports-color@8.1.1) + error-stack-parser-es: 0.1.1 + fs-extra: 11.2.0 + open: 10.1.0 + perfect-debounce: 1.0.0 + picocolors: 1.0.0 + sirv: 2.0.4 + vite: 5.2.10(@types/node@18.19.31)(sass@1.75.0) + transitivePeerDependencies: + - rollup + - supports-color + dev: false + /vite-plugin-solid@2.10.2(solid-js@1.8.17): resolution: {integrity: sha512-AOEtwMe2baBSXMXdo+BUwECC8IFHcKS6WQV/1NEd+Q7vHPap5fmIhLcAzr+DUJ04/KHx/1UBU0l1/GWP+rMAPQ==} peerDependencies: @@ -16554,6 +16735,52 @@ packages: - supports-color dev: false + /vite-plugin-vue-devtools@7.1.3(vite@5.2.10)(vue@3.4.26): + resolution: {integrity: sha512-qv8Z4yok9RYo6TEs89WnIAlmTHby/+XTim8tlSnMs3lAPcQqqcl/wGRY8gAeYrGCANngOqO+VuabW3Jb1HZtyw==} + engines: {node: '>=v14.21.3'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + '@vue/devtools-core': 7.1.3(vite@5.2.10)(vue@3.4.26) + '@vue/devtools-kit': 7.1.3(vue@3.4.26) + '@vue/devtools-shared': 7.1.3 + execa: 8.0.1 + sirv: 2.0.4 + vite: 5.2.10(@types/node@18.19.31)(sass@1.75.0) + vite-plugin-inspect: 0.8.4(vite@5.2.10) + vite-plugin-vue-inspector: 5.0.1(vite@5.2.10) + transitivePeerDependencies: + - '@nuxt/kit' + - rollup + - supports-color + - vue + dev: false + + /vite-plugin-vue-inspector@5.0.1(vite@5.2.10): + resolution: {integrity: sha512-R93P8iFa6BPODhc/aOtO04A8FFMMyFIfm8ZVSmN+8vU1TgwsHya734APGpX4fVHSPX2aVwYyiezXBUYQ0Opsqw==} + peerDependencies: + vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + '@babel/core': 7.24.5 + '@babel/plugin-proposal-decorators': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-syntax-import-attributes': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.5) + '@babel/plugin-transform-typescript': 7.24.4(@babel/core@7.24.5) + '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.24.5) + '@vue/compiler-dom': 3.4.26 + kolorist: 1.8.0 + magic-string: 0.30.10 + vite: 5.2.10(@types/node@18.19.31)(sass@1.75.0) + transitivePeerDependencies: + - supports-color + dev: false + /vite-svg-loader@4.0.0: resolution: {integrity: sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==} peerDependencies: From 4d905ccef663f728fc981181f5bb9f1d157184ff Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 6 May 2024 11:27:07 -0400 Subject: [PATCH 3/6] Preserve content modules properly in cache (#10889) * Wait until after build to preserve content modules * Properly build hoisted scripts * Add changeset * Fix tests hitting each other * Global state, the shame * Move the file copying over to earlier in the process --- .changeset/spicy-keys-own.md | 5 + packages/astro/content-module.template.mjs | 2 + packages/astro/src/assets/build/generate.ts | 2 +- .../astro/src/assets/vite-plugin-assets.ts | 2 +- packages/astro/src/content/runtime.ts | 3 +- .../content/vite-plugin-content-imports.ts | 2 +- .../vite-plugin-content-virtual-mod.ts | 3 +- packages/astro/src/core/build/generate.ts | 4 +- packages/astro/src/core/build/index.ts | 3 +- packages/astro/src/core/build/internal.ts | 3 + packages/astro/src/core/build/pipeline.ts | 3 +- .../src/core/build/plugins/plugin-analyzer.ts | 91 +++++--- .../src/core/build/plugins/plugin-content.ts | 51 +++-- .../build/plugins/plugin-hoisted-scripts.ts | 53 +++-- .../src/core/build/plugins/plugin-ssr.ts | 2 +- packages/astro/src/core/build/static-build.ts | 9 +- packages/astro/src/core/build/types.ts | 4 +- packages/astro/src/core/config/config.ts | 5 - packages/astro/src/core/util.ts | 12 +- packages/astro/src/integrations/hooks.ts | 2 +- packages/astro/src/prerender/utils.ts | 5 +- .../src/vite-plugin-astro-server/pipeline.ts | 3 +- .../astro/src/vite-plugin-scanner/index.ts | 4 +- ...collections-css-inline-stylesheets.test.js | 61 +---- ...imental-content-collections-render.test.js | 208 ++---------------- .../css-inline-stylesheets-2/package.json | 8 + .../src/components/Button.astro | 86 ++++++++ .../src/content/en/endeavour.md | 15 ++ .../css-inline-stylesheets-2/src/imported.css | 15 ++ .../src/layouts/Layout.astro | 35 +++ .../src/pages/index.astro | 17 ++ packages/astro/test/test-utils.js | 6 +- pnpm-lock.yaml | 6 + 33 files changed, 385 insertions(+), 345 deletions(-) create mode 100644 .changeset/spicy-keys-own.md create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets-2/package.json create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets-2/src/components/Button.astro create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets-2/src/imported.css create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets-2/src/layouts/Layout.astro create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro diff --git a/.changeset/spicy-keys-own.md b/.changeset/spicy-keys-own.md new file mode 100644 index 000000000000..066d764a740c --- /dev/null +++ b/.changeset/spicy-keys-own.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Preserve content modules properly in cache diff --git a/packages/astro/content-module.template.mjs b/packages/astro/content-module.template.mjs index 35c6a55c9b2a..f246678a25ec 100644 --- a/packages/astro/content-module.template.mjs +++ b/packages/astro/content-module.template.mjs @@ -48,10 +48,12 @@ const collectionToRenderEntryMap = createCollectionToGlobResultMap({ contentDir, }); +const cacheEntriesByCollection = new Map(); export const getCollection = createGetCollection({ contentCollectionToEntryMap, dataCollectionToEntryMap, getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap), + cacheEntriesByCollection, }); export const getEntryBySlug = createGetEntryBySlug({ diff --git a/packages/astro/src/assets/build/generate.ts b/packages/astro/src/assets/build/generate.ts index f209345387a7..c363a6349786 100644 --- a/packages/astro/src/assets/build/generate.ts +++ b/packages/astro/src/assets/build/generate.ts @@ -10,7 +10,7 @@ import { AstroError } from '../../core/errors/errors.js'; import { AstroErrorData } from '../../core/errors/index.js'; import type { Logger } from '../../core/logger/core.js'; import { isRemotePath, removeLeadingForwardSlash } from '../../core/path.js'; -import { isServerLikeOutput } from '../../prerender/utils.js'; +import { isServerLikeOutput } from '../../core/util.js'; import type { MapValue } from '../../type-utils.js'; import { getConfiguredImageService } from '../internal.js'; import type { LocalImageService } from '../services/service.js'; diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts index 6114e7bf9bdc..eda4b6cfbc2a 100644 --- a/packages/astro/src/assets/vite-plugin-assets.ts +++ b/packages/astro/src/assets/vite-plugin-assets.ts @@ -12,7 +12,7 @@ import { removeBase, removeQueryString, } from '../core/path.js'; -import { isServerLikeOutput } from '../prerender/utils.js'; +import { isServerLikeOutput } from '../core/util.js'; import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from './consts.js'; import { emitESMImage } from './utils/emitAsset.js'; import { getAssetsPrefix } from './utils/getAssetsPrefix.js'; diff --git a/packages/astro/src/content/runtime.ts b/packages/astro/src/content/runtime.ts index c4fc8573910b..21af34e1d280 100644 --- a/packages/astro/src/content/runtime.ts +++ b/packages/astro/src/content/runtime.ts @@ -44,15 +44,16 @@ export function createCollectionToGlobResultMap({ return collectionToGlobResultMap; } -const cacheEntriesByCollection = new Map(); export function createGetCollection({ contentCollectionToEntryMap, dataCollectionToEntryMap, getRenderEntryImport, + cacheEntriesByCollection, }: { contentCollectionToEntryMap: CollectionToEntryMap; dataCollectionToEntryMap: CollectionToEntryMap; getRenderEntryImport: GetEntryImport; + cacheEntriesByCollection: Map; }) { return async function getCollection(collection: string, filter?: (entry: any) => unknown) { let type: 'content' | 'data'; diff --git a/packages/astro/src/content/vite-plugin-content-imports.ts b/packages/astro/src/content/vite-plugin-content-imports.ts index 6540d483ae5b..2589a9629444 100644 --- a/packages/astro/src/content/vite-plugin-content-imports.ts +++ b/packages/astro/src/content/vite-plugin-content-imports.ts @@ -15,7 +15,7 @@ import type { import { getProxyCode } from '../assets/utils/proxy.js'; import { AstroError } from '../core/errors/errors.js'; import { AstroErrorData } from '../core/errors/index.js'; -import { isServerLikeOutput } from '../prerender/utils.js'; +import { isServerLikeOutput } from '../core/util.js'; import { CONTENT_FLAG, DATA_FLAG } from './consts.js'; import { type ContentConfig, diff --git a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts index 474e96235d6d..bd3362343daf 100644 --- a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts +++ b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts @@ -8,8 +8,7 @@ import type { AstroSettings } from '../@types/astro.js'; import { encodeName } from '../core/build/util.js'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { appendForwardSlash, removeFileExtension } from '../core/path.js'; -import { rootRelativePath } from '../core/util.js'; -import { isServerLikeOutput } from '../prerender/utils.js'; +import { rootRelativePath, isServerLikeOutput } from '../core/util.js'; import type { AstroPluginMetadata } from '../vite-plugin-astro/index.js'; import { CONTENT_FLAG, diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 5c6c302db773..ffe799f6e7e4 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -31,7 +31,7 @@ import { } from '../../core/path.js'; import { toRoutingStrategy } from '../../i18n/utils.js'; import { runHookBuildGenerated } from '../../integrations/hooks.js'; -import { getOutputDirectory, isServerLikeOutput } from '../../prerender/utils.js'; +import { getOutputDirectory } from '../../prerender/utils.js'; import type { SSRManifestI18n } from '../app/types.js'; import { NoPrerenderedRoutesWithDomains } from '../errors/errors-data.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; @@ -45,7 +45,7 @@ import { RenderContext } from '../render-context.js'; import { callGetStaticPaths } from '../render/route-cache.js'; import { createRequest } from '../request.js'; import { matchRoute } from '../routing/match.js'; -import { getOutputFilename } from '../util.js'; +import { getOutputFilename, isServerLikeOutput } from '../util.js'; import { getOutDirWithinCwd, getOutFile, getOutFolder } from './common.js'; import { cssOrder, diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index ea1b715bbd57..2dbf8967287c 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -19,7 +19,6 @@ import { runHookConfigDone, runHookConfigSetup, } from '../../integrations/hooks.js'; -import { isServerLikeOutput } from '../../prerender/utils.js'; import { resolveConfig } from '../config/config.js'; import { createNodeLogger } from '../config/logging.js'; import { createSettings } from '../config/settings.js'; @@ -28,7 +27,7 @@ import type { Logger } from '../logger/core.js'; import { levels, timerMessage } from '../logger/core.js'; import { apply as applyPolyfill } from '../polyfill.js'; import { createRouteManifest } from '../routing/index.js'; -import { ensureProcessNodeEnv } from '../util.js'; +import { ensureProcessNodeEnv, isServerLikeOutput } from '../util.js'; import { collectPagesData } from './page-data.js'; import { staticBuild, viteBuild } from './static-build.js'; import type { StaticBuildOptions } from './types.js'; diff --git a/packages/astro/src/core/build/internal.ts b/packages/astro/src/core/build/internal.ts index a5e456627155..a7ff537dc8a4 100644 --- a/packages/astro/src/core/build/internal.ts +++ b/packages/astro/src/core/build/internal.ts @@ -25,6 +25,8 @@ export interface BuildInternals { hoistedScriptIdToHoistedMap: Map>; // A mapping of hoisted script ids back to the pages which reference it hoistedScriptIdToPagesMap: Map>; + // A mapping of hoisted script ids back to the content which reference it + hoistedScriptIdToContentMap: Map>; /** * Used by the `directRenderScript` option. If script is inlined, its id and @@ -123,6 +125,7 @@ export function createBuildInternals(): BuildInternals { cssModuleToChunkIdMap: new Map(), hoistedScriptIdToHoistedMap, hoistedScriptIdToPagesMap, + hoistedScriptIdToContentMap: new Map(), inlinedScripts: new Map(), entrySpecifierToBundleMap: new Map(), pageToBundleMap: new Map(), diff --git a/packages/astro/src/core/build/pipeline.ts b/packages/astro/src/core/build/pipeline.ts index a733d4c6fe16..5df7cb1e3061 100644 --- a/packages/astro/src/core/build/pipeline.ts +++ b/packages/astro/src/core/build/pipeline.ts @@ -1,5 +1,5 @@ import type { RouteData, SSRLoadedRenderer, SSRResult } from '../../@types/astro.js'; -import { getOutputDirectory, isServerLikeOutput } from '../../prerender/utils.js'; +import { getOutputDirectory } from '../../prerender/utils.js'; import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js'; import type { SSRManifest } from '../app/types.js'; import { routeIsFallback, routeIsRedirect } from '../redirects/helpers.js'; @@ -21,6 +21,7 @@ import { getVirtualModulePageNameFromPath } from './plugins/util.js'; import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js'; import type { PageBuildData, StaticBuildOptions } from './types.js'; import { i18nHasFallback } from './util.js'; +import { isServerLikeOutput } from '../util.js'; /** * The build pipeline is responsible to gather the files emitted by the SSR build and generate the pages by executing these files. diff --git a/packages/astro/src/core/build/plugins/plugin-analyzer.ts b/packages/astro/src/core/build/plugins/plugin-analyzer.ts index cb1f4078b44f..c72026e0f1fd 100644 --- a/packages/astro/src/core/build/plugins/plugin-analyzer.ts +++ b/packages/astro/src/core/build/plugins/plugin-analyzer.ts @@ -6,6 +6,7 @@ import type { AstroBuildPlugin } from '../plugin.js'; import { PROPAGATED_ASSET_FLAG } from '../../../content/consts.js'; import { prependForwardSlash } from '../../../core/path.js'; +import { isContentCollectionsCacheEnabled } from '../../../core/util.js'; import { getParentModuleInfos, getTopLevelPageModuleInfos, @@ -31,6 +32,7 @@ export function vitePluginAnalyzer( const pageScripts = new Map< string, { + type: 'page' | 'content'; hoistedSet: Set; propagatedMapByImporter: Map>; } @@ -51,20 +53,38 @@ export function vitePluginAnalyzer( if (hoistedScripts.size) { for (const parentInfo of getParentModuleInfos(from, this, isPropagatedAsset)) { if (isPropagatedAsset(parentInfo.id)) { - for (const nestedParentInfo of getParentModuleInfos(from, this)) { - if (moduleIsTopLevelPage(nestedParentInfo)) { - for (const hid of hoistedScripts) { - if (!pageScripts.has(nestedParentInfo.id)) { - pageScripts.set(nestedParentInfo.id, { - hoistedSet: new Set(), - propagatedMapByImporter: new Map(), - }); - } - const entry = pageScripts.get(nestedParentInfo.id)!; - if (!entry.propagatedMapByImporter.has(parentInfo.id)) { - entry.propagatedMapByImporter.set(parentInfo.id, new Set()); + if(isContentCollectionsCacheEnabled(options.settings.config)) { + if (!pageScripts.has(parentInfo.id)) { + pageScripts.set(parentInfo.id, { + type: 'content', + hoistedSet: new Set(), + propagatedMapByImporter: new Map(), + }); + } + const propagaters = pageScripts.get(parentInfo.id)!.propagatedMapByImporter; + for(const hid of hoistedScripts) { + if(!propagaters.has(parentInfo.id)) { + propagaters.set(parentInfo.id, new Set()); + } + propagaters.get(parentInfo.id)!.add(hid); + } + } else { + for (const nestedParentInfo of getParentModuleInfos(from, this)) { + if (moduleIsTopLevelPage(nestedParentInfo)) { + for (const hid of hoistedScripts) { + if (!pageScripts.has(nestedParentInfo.id)) { + pageScripts.set(nestedParentInfo.id, { + type: 'page', + hoistedSet: new Set(), + propagatedMapByImporter: new Map(), + }); + } + const entry = pageScripts.get(nestedParentInfo.id)!; + if (!entry.propagatedMapByImporter.has(parentInfo.id)) { + entry.propagatedMapByImporter.set(parentInfo.id, new Set()); + } + entry.propagatedMapByImporter.get(parentInfo.id)!.add(hid); } - entry.propagatedMapByImporter.get(parentInfo.id)!.add(hid); } } } @@ -72,6 +92,7 @@ export function vitePluginAnalyzer( for (const hid of hoistedScripts) { if (!pageScripts.has(parentInfo.id)) { pageScripts.set(parentInfo.id, { + type: 'page', hoistedSet: new Set(), propagatedMapByImporter: new Map(), }); @@ -84,12 +105,21 @@ export function vitePluginAnalyzer( }, finalize() { - for (const [pageId, { hoistedSet, propagatedMapByImporter }] of pageScripts) { - const pageData = getPageDataByViteID(internals, pageId); - if (!pageData) continue; + for (const [pageId, { hoistedSet, propagatedMapByImporter, type }] of pageScripts) { + let astroModuleId: string; + if(type === 'page') { + const pageData = getPageDataByViteID(internals, pageId); + if (!pageData) { + continue; + }; + const { component } = pageData; + astroModuleId = prependForwardSlash(component); - const { component } = pageData; - const astroModuleId = prependForwardSlash(component); + // Keep track of the importers + pageData.propagatedScripts = propagatedMapByImporter; + } else { + astroModuleId = pageId; + } const uniqueHoistedId = JSON.stringify(Array.from(hoistedSet).sort()); let moduleId: string; @@ -104,8 +134,6 @@ export function vitePluginAnalyzer( } internals.discoveredScripts.add(moduleId); - pageData.propagatedScripts = propagatedMapByImporter; - // Add propagated scripts to client build, // but DON'T add to pages -> hoisted script map. for (const propagatedScripts of propagatedMapByImporter.values()) { @@ -114,13 +142,24 @@ export function vitePluginAnalyzer( } } - // Make sure to track that this page uses this set of hoisted scripts - if (internals.hoistedScriptIdToPagesMap.has(moduleId)) { - const pages = internals.hoistedScriptIdToPagesMap.get(moduleId); - pages!.add(astroModuleId); + if(type === 'page') { + // Make sure to track that this page uses this set of hoisted scripts + if (internals.hoistedScriptIdToPagesMap.has(moduleId)) { + const pages = internals.hoistedScriptIdToPagesMap.get(moduleId); + pages!.add(astroModuleId); + } else { + internals.hoistedScriptIdToPagesMap.set(moduleId, new Set([astroModuleId])); + internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedSet); + } } else { - internals.hoistedScriptIdToPagesMap.set(moduleId, new Set([astroModuleId])); - internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedSet); + // For content collections save to hoistedScriptIdToContentMap instead + if (internals.hoistedScriptIdToContentMap.has(moduleId)) { + const contentModules = internals.hoistedScriptIdToContentMap.get(moduleId); + contentModules!.add(astroModuleId); + } else { + internals.hoistedScriptIdToContentMap.set(moduleId, new Set([astroModuleId])); + internals.hoistedScriptIdToHoistedMap.set(moduleId, hoistedSet); + } } } }, diff --git a/packages/astro/src/core/build/plugins/plugin-content.ts b/packages/astro/src/core/build/plugins/plugin-content.ts index 24512f8ebc8e..c94f01f3fc98 100644 --- a/packages/astro/src/core/build/plugins/plugin-content.ts +++ b/packages/astro/src/core/build/plugins/plugin-content.ts @@ -9,7 +9,6 @@ import { generateContentEntryFile, generateLookupMap, } from '../../../content/vite-plugin-content-virtual-mod.js'; -import { isServerLikeOutput } from '../../../prerender/utils.js'; import { configPaths } from '../../config/index.js'; import { emptyDir } from '../../fs/index.js'; import { @@ -26,6 +25,8 @@ import { copyFiles } from '../static-build.js'; import type { StaticBuildOptions } from '../types.js'; import { encodeName } from '../util.js'; import { extendManualChunks } from './util.js'; +import { isContentCollectionsCacheEnabled } from '../../util.js'; +import type { AstroConfig } from '../../../@types/astro.js'; const CONTENT_CACHE_DIR = './content/'; const CONTENT_MANIFEST_FILE = './manifest.json'; @@ -69,6 +70,10 @@ function createContentManifest(): ContentManifest { }; } +const getContentRoot = (config: AstroConfig) => new URL('./content/', config.outDir); +const getContentCacheDir = (config: AstroConfig) => new URL(CONTENT_CACHE_DIR, config.cacheDir); +const getCacheTmp = (contentCacheDir: URL) => new URL('./.tmp/', contentCacheDir); + function vitePluginContent( opts: StaticBuildOptions, lookupMap: ContentLookupMap, @@ -76,12 +81,9 @@ function vitePluginContent( cachedBuildOutput: Array<{ cached: URL; dist: URL }> ): VitePlugin { const { config } = opts.settings; - const { cacheDir } = config; - const distRoot = config.outDir; - const distContentRoot = new URL('./content/', distRoot); - const contentCacheDir = new URL(CONTENT_CACHE_DIR, cacheDir); + const distContentRoot = getContentRoot(config); + const contentCacheDir = getContentCacheDir(config); const contentManifestFile = new URL(CONTENT_MANIFEST_FILE, contentCacheDir); - const cacheTmp = new URL('./.tmp/', contentCacheDir); let oldManifest = createContentManifest(); let newManifest = createContentManifest(); let entries: ContentEntries; @@ -151,6 +153,11 @@ function vitePluginContent( await copyFiles(cached, dist, true); } } + // Copy over the content cache now so that new files override it + const cacheExists = fsMod.existsSync(contentCacheDir); + if (cacheExists) { + await copyFiles(contentCacheDir, distContentRoot, false); + } } // If nothing needs to be rebuilt, we inject a fake entrypoint to appease Rollup @@ -242,7 +249,6 @@ function vitePluginContent( ...oldManifest.clientEntries, ...internals.discoveredHydratedComponents.keys(), ...internals.discoveredClientOnlyComponents.keys(), - ...internals.discoveredScripts, ]); // Likewise, these are server modules that might not be referenced // once the cached items are excluded from the build process @@ -263,13 +269,6 @@ function vitePluginContent( await fsMod.promises.writeFile(contentManifestFile, JSON.stringify(newManifest), { encoding: 'utf8', }); - await fsMod.promises.mkdir(cacheTmp, { recursive: true }); - await copyFiles(distContentRoot, cacheTmp, true); - if (cacheExists && currentManifestState === 'valid') { - await copyFiles(contentCacheDir, distContentRoot, false); - } - await copyFiles(cacheTmp, contentCacheDir); - await fsMod.promises.rm(cacheTmp, { recursive: true, force: true }); }, }; } @@ -319,6 +318,7 @@ function getEntriesFromManifests( entries.buildFromSource.push(entry); } } + return entries; } @@ -438,6 +438,19 @@ function collectionTypeToFlag(type: 'content' | 'data') { return `astro${name}CollectionEntry`; } +export async function copyContentToCache(opts: StaticBuildOptions) { + const { config } = opts.settings; + const distContentRoot = getContentRoot(config); + const contentCacheDir = getContentCacheDir(config); + const cacheTmp = getCacheTmp(contentCacheDir); + + await fsMod.promises.mkdir(cacheTmp, { recursive: true }); + await copyFiles(distContentRoot, cacheTmp, true); + + await copyFiles(cacheTmp, contentCacheDir); + await fsMod.promises.rm(cacheTmp, { recursive: true, force: true }); +} + export function pluginContent( opts: StaticBuildOptions, internals: BuildInternals @@ -456,10 +469,7 @@ export function pluginContent( targets: ['server'], hooks: { async 'build:before'() { - if (!opts.settings.config.experimental.contentCollectionCache) { - return { vitePlugin: undefined }; - } - if (isServerLikeOutput(opts.settings.config)) { + if (!isContentCollectionsCacheEnabled(opts.settings.config)) { return { vitePlugin: undefined }; } const lookupMap = await generateLookupMap({ settings: opts.settings, fs: fsMod }); @@ -469,10 +479,7 @@ export function pluginContent( }, async 'build:post'() { - if (!opts.settings.config.experimental.contentCollectionCache) { - return; - } - if (isServerLikeOutput(opts.settings.config)) { + if(!isContentCollectionsCacheEnabled(opts.settings.config)) { return; } // Cache build output of chunks and assets diff --git a/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts b/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts index 2ed3c7fa746d..641665b84c1a 100644 --- a/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts +++ b/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts @@ -1,6 +1,6 @@ import type { BuildOptions, Plugin as VitePlugin } from 'vite'; import type { AstroSettings } from '../../../@types/astro.js'; -import { viteID } from '../../util.js'; +import { isContentCollectionsCacheEnabled, viteID } from '../../util.js'; import type { BuildInternals } from '../internal.js'; import { getPageDataByViteID } from '../internal.js'; import type { AstroBuildPlugin } from '../plugin.js'; @@ -11,6 +11,7 @@ function virtualHoistedEntry(id: string) { return id.startsWith('/astro/hoisted.js?q='); } + export function vitePluginHoistedScripts( settings: AstroSettings, internals: BuildInternals @@ -72,23 +73,41 @@ export function vitePluginHoistedScripts( output.dynamicImports.length === 0 && shouldInlineAsset(output.code, output.fileName, assetsInlineLimit); let removeFromBundle = false; + const facadeId = output.facadeModuleId!; - const pages = internals.hoistedScriptIdToPagesMap.get(facadeId)!; - for (const pathname of pages) { - const vid = viteID(new URL('.' + pathname, settings.config.root)); - const pageInfo = getPageDataByViteID(internals, vid); - if (pageInfo) { - if (canBeInlined) { - pageInfo.hoistedScript = { - type: 'inline', - value: output.code, - }; - removeFromBundle = true; - } else { - pageInfo.hoistedScript = { - type: 'external', - value: id, - }; + + // Pages + if(internals.hoistedScriptIdToPagesMap.has(facadeId)) { + const pages = internals.hoistedScriptIdToPagesMap.get(facadeId)!; + for (const pathname of pages) { + const vid = viteID(new URL('.' + pathname, settings.config.root)); + + const pageInfo = getPageDataByViteID(internals, vid); + if (pageInfo) { + if (canBeInlined) { + pageInfo.hoistedScript = { + type: 'inline', + value: output.code, + }; + removeFromBundle = true; + } else { + pageInfo.hoistedScript = { + type: 'external', + value: id, + }; + } + } + } + } + // Content collection entries + else { + const contentModules = internals.hoistedScriptIdToContentMap.get(facadeId)!; + for(const contentId of contentModules) { + if(isContentCollectionsCacheEnabled(settings.config)) { + const scripts = internals.propagatedScriptsMap.get(contentId) ?? + internals.propagatedScriptsMap.set(contentId, new Set()).get(contentId)!; + + scripts.add(facadeId); } } } diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts index 5ccb8746364f..1d8ea677f4b2 100644 --- a/packages/astro/src/core/build/plugins/plugin-ssr.ts +++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts @@ -2,8 +2,8 @@ import { join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import type { Plugin as VitePlugin } from 'vite'; import type { AstroAdapter } from '../../../@types/astro.js'; +import { isServerLikeOutput } from '../../util.js'; import { isFunctionPerRouteEnabled } from '../../../integrations/hooks.js'; -import { isServerLikeOutput } from '../../../prerender/utils.js'; import { routeIsRedirect } from '../../redirects/index.js'; import { addRollupInput } from '../add-rollup-input.js'; import type { BuildInternals } from '../internal.js'; diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 6aa1eca901ba..91d17e37431c 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -16,9 +16,9 @@ import { } from '../../core/build/internal.js'; import { emptyDir, removeEmptyDirs } from '../../core/fs/index.js'; import { appendForwardSlash, prependForwardSlash, removeFileExtension } from '../../core/path.js'; -import { isModeServerWithNoAdapter } from '../../core/util.js'; +import { isModeServerWithNoAdapter, isServerLikeOutput } from '../../core/util.js'; import { runHookBuildSetup } from '../../integrations/hooks.js'; -import { getOutputDirectory, isServerLikeOutput } from '../../prerender/utils.js'; +import { getOutputDirectory } from '../../prerender/utils.js'; import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; import { routeIsRedirect } from '../redirects/index.js'; @@ -35,6 +35,7 @@ import { RESOLVED_SPLIT_MODULE_ID, RESOLVED_SSR_VIRTUAL_MODULE_ID } from './plug import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js'; import type { StaticBuildOptions } from './types.js'; import { encodeName, getTimeStat, viteBuildReturnToRollupOutputs } from './util.js'; +import { copyContentToCache } from './plugins/plugin-content.js'; export async function viteBuild(opts: StaticBuildOptions) { const { allPages, settings } = opts; @@ -107,7 +108,9 @@ export async function viteBuild(opts: StaticBuildOptions) { const ssrOutputs = viteBuildReturnToRollupOutputs(ssrOutput); const clientOutputs = viteBuildReturnToRollupOutputs(clientOutput ?? []); await runPostBuildHooks(container, ssrOutputs, clientOutputs); - + if(opts.settings.config.experimental.contentCollectionCache) { + await copyContentToCache(opts); + } settings.timer.end('Client build'); // Free up memory diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts index 9608ba04c524..9b418f7bc56d 100644 --- a/packages/astro/src/core/build/types.ts +++ b/packages/astro/src/core/build/types.ts @@ -20,13 +20,15 @@ export type StylesheetAsset = | { type: 'inline'; content: string } | { type: 'external'; src: string }; +export type HoistedScriptAsset = { type: 'inline' | 'external'; value: string }; + export interface PageBuildData { component: ComponentPath; route: RouteData; moduleSpecifier: string; propagatedStyles: Map>; propagatedScripts: Map>; - hoistedScript: { type: 'inline' | 'external'; value: string } | undefined; + hoistedScript: HoistedScriptAsset | undefined; styles: Array<{ depth: number; order: number; sheet: StylesheetAsset }>; hasSharedModules: boolean; } diff --git a/packages/astro/src/core/config/config.ts b/packages/astro/src/core/config/config.ts index 5bb2eda77287..d0cfd0e49702 100644 --- a/packages/astro/src/core/config/config.ts +++ b/packages/astro/src/core/config/config.ts @@ -45,11 +45,6 @@ export async function validateConfig( throw e; } - // TODO: fix inlineStylesheets behavior with content collection cache - if (result.build.inlineStylesheets !== 'auto' && result.experimental.contentCollectionCache) { - result.experimental.contentCollectionCache = false; - } - // If successful, return the result as a verified AstroConfig object. return result; } diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index 4db3549a2a6d..405479030a2f 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -3,7 +3,6 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { normalizePath } from 'vite'; import type { AstroConfig, AstroSettings, RouteType } from '../@types/astro.js'; -import { isServerLikeOutput } from '../prerender/utils.js'; import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './constants.js'; import type { ModuleLoader } from './module-loader/index.js'; import { prependForwardSlash, removeTrailingForwardSlash, slash } from './path.js'; @@ -148,10 +147,21 @@ export function isEndpoint(file: URL, settings: AstroSettings): boolean { return !endsWithPageExt(file, settings); } +export function isServerLikeOutput(config: AstroConfig) { + return config.output === 'server' || config.output === 'hybrid'; +} + export function isModeServerWithNoAdapter(settings: AstroSettings): boolean { return isServerLikeOutput(settings.config) && !settings.adapter; } + +export function isContentCollectionsCacheEnabled(config: AstroConfig): boolean { + return config.experimental.contentCollectionCache && + // contentCollectionsCache is an SSG only feature + !isServerLikeOutput(config); +} + export function relativeToSrcDir(config: AstroConfig, idOrUrl: URL | string) { let id: string; if (typeof idOrUrl !== 'string') { diff --git a/packages/astro/src/integrations/hooks.ts b/packages/astro/src/integrations/hooks.ts index 51f600ae85f6..ae97802eebb0 100644 --- a/packages/astro/src/integrations/hooks.ts +++ b/packages/astro/src/integrations/hooks.ts @@ -19,7 +19,7 @@ import type { PageBuildData } from '../core/build/types.js'; import { buildClientDirectiveEntrypoint } from '../core/client-directive/index.js'; import { mergeConfig } from '../core/config/index.js'; import type { AstroIntegrationLogger, Logger } from '../core/logger/core.js'; -import { isServerLikeOutput } from '../prerender/utils.js'; +import { isServerLikeOutput } from '../core/util.js'; import { validateSupportedFeatures } from './features-validation.js'; async function withTakingALongTimeMsg({ diff --git a/packages/astro/src/prerender/utils.ts b/packages/astro/src/prerender/utils.ts index c671a68e06af..4097b66b1f6d 100644 --- a/packages/astro/src/prerender/utils.ts +++ b/packages/astro/src/prerender/utils.ts @@ -1,9 +1,6 @@ import type { AstroConfig } from '../@types/astro.js'; import { getOutDirWithinCwd } from '../core/build/common.js'; - -export function isServerLikeOutput(config: AstroConfig) { - return config.output === 'server' || config.output === 'hybrid'; -} +import { isServerLikeOutput } from '../core/util.js'; export function getPrerenderDefault(config: AstroConfig) { return config.output !== 'server'; diff --git a/packages/astro/src/vite-plugin-astro-server/pipeline.ts b/packages/astro/src/vite-plugin-astro-server/pipeline.ts index 09366d885cc7..2dfaaac55f07 100644 --- a/packages/astro/src/vite-plugin-astro-server/pipeline.ts +++ b/packages/astro/src/vite-plugin-astro-server/pipeline.ts @@ -16,8 +16,7 @@ import { AggregateError, CSSError, MarkdownError } from '../core/errors/index.js import type { Logger } from '../core/logger/core.js'; import type { ModuleLoader } from '../core/module-loader/index.js'; import { Pipeline, loadRenderer } from '../core/render/index.js'; -import { isPage, resolveIdToUrl, viteID } from '../core/util.js'; -import { isServerLikeOutput } from '../prerender/utils.js'; +import { isPage, resolveIdToUrl, viteID, isServerLikeOutput } from '../core/util.js'; import { PAGE_SCRIPT_ID } from '../vite-plugin-scripts/index.js'; import { getStylesForURL } from './css.js'; import { getComponentMetadata } from './metadata.js'; diff --git a/packages/astro/src/vite-plugin-scanner/index.ts b/packages/astro/src/vite-plugin-scanner/index.ts index fb1ce4f7b5ff..b0065f1ab67a 100644 --- a/packages/astro/src/vite-plugin-scanner/index.ts +++ b/packages/astro/src/vite-plugin-scanner/index.ts @@ -4,8 +4,8 @@ import type { Plugin as VitePlugin } from 'vite'; import { normalizePath } from 'vite'; import type { AstroSettings } from '../@types/astro.js'; import { type Logger } from '../core/logger/core.js'; -import { isEndpoint, isPage, rootRelativePath } from '../core/util.js'; -import { getPrerenderDefault, isServerLikeOutput } from '../prerender/utils.js'; +import { isEndpoint, isPage, rootRelativePath, isServerLikeOutput } from '../core/util.js'; +import { getPrerenderDefault } from '../prerender/utils.js'; import { scan } from './scan.js'; export interface AstroPluginScannerOptions { diff --git a/packages/astro/test/experimental-content-collections-css-inline-stylesheets.test.js b/packages/astro/test/experimental-content-collections-css-inline-stylesheets.test.js index a3e4cf113276..a4aede4966a5 100644 --- a/packages/astro/test/experimental-content-collections-css-inline-stylesheets.test.js +++ b/packages/astro/test/experimental-content-collections-css-inline-stylesheets.test.js @@ -13,7 +13,7 @@ describe('Experimental Content Collections cache inlineStylesheets', () => { // to bust cache and prevent modules and their state // from being reused site: 'https://test.dev/', - root: './fixtures/css-inline-stylesheets/', + root: './fixtures/css-inline-stylesheets-2/', output: 'static', build: { inlineStylesheets: 'never', @@ -145,65 +145,6 @@ describe('Experimental Content Collections cache - inlineStylesheets to auto in }); }); -describe('Setting inlineStylesheets to auto in server output', () => { - let app; - let fixture; - - before(async () => { - fixture = await loadFixture({ - // inconsequential config that differs between tests - // to bust cache and prevent modules and their state - // from being reused - site: 'https://test.info/', - root: './fixtures/css-inline-stylesheets/', - output: 'server', - adapter: testAdapter(), - build: { - inlineStylesheets: 'auto', - }, - vite: { - build: { - assetsInlineLimit: 512, - }, - }, - experimental: { - contentCollectionCache: true, - }, - }); - await fixture.build(); - app = await fixture.loadTestAdapterApp(); - }); - - after(async () => await fixture.clean()); - - it( - 'Renders some \ No newline at end of file diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md new file mode 100644 index 000000000000..240eeeae3993 --- /dev/null +++ b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md @@ -0,0 +1,15 @@ +--- +title: Endeavour +description: 'Learn about the Endeavour NASA space shuttle.' +publishedDate: 'Sun Jul 11 2021 00:00:00 GMT-0400 (Eastern Daylight Time)' +layout: '../../layouts/Layout.astro' +tags: [space, 90s] +--- + +**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Endeavour) + +Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbiter from NASA's Space Shuttle program and the fifth and final operational Shuttle built. It embarked on its first mission, STS-49, in May 1992 and its 25th and final mission, STS-134, in May 2011. STS-134 was expected to be the final mission of the Space Shuttle program, but with the authorization of STS-135, Atlantis became the last shuttle to fly. + +The United States Congress approved the construction of Endeavour in 1987 to replace the Space Shuttle Challenger, which was destroyed in 1986. + +NASA chose, on cost grounds, to build much of Endeavour from spare parts rather than refitting the Space Shuttle Enterprise, and used structural spares built during the construction of Discovery and Atlantis in its assembly. \ No newline at end of file diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/imported.css b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/imported.css new file mode 100644 index 000000000000..3959523ff16e --- /dev/null +++ b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/imported.css @@ -0,0 +1,15 @@ +.bg-skyblue { + background: skyblue; +} + +.bg-lightcoral { + background: lightcoral; +} + +.red { + color: darkred; +} + +.blue { + color: royalblue; +} diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/layouts/Layout.astro b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/layouts/Layout.astro new file mode 100644 index 000000000000..0a26655189f5 --- /dev/null +++ b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/layouts/Layout.astro @@ -0,0 +1,35 @@ +--- +import Button from '../components/Button.astro'; +import '../imported.css'; + +interface Props { + title: string; +} + +const { title } = Astro.props; +--- + + + + + + + + + {title} + + + + + + + diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro new file mode 100644 index 000000000000..2aecfb0f2eb7 --- /dev/null +++ b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro @@ -0,0 +1,17 @@ +--- +import { getEntryBySlug } from 'astro:content'; +import Button from '../components/Button.astro'; + +const entry = await getEntryBySlug('en', 'endeavour'); +const { Content } = await entry.render(); +--- + +
+

Welcome to Astro

+ + +
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index d72680c2fd8d..e0eb8c2b71d2 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -204,9 +204,9 @@ export async function loadFixture(inlineConfig) { recursive: true, force: true, }); - const contentCache = new URL('./node_modules/.astro/content', config.root); - if (fs.existsSync(contentCache)) { - await fs.promises.rm(contentCache, { + const astroCache = new URL('./node_modules/.astro', config.root); + if (fs.existsSync(astroCache)) { + await fs.promises.rm(astroCache, { maxRetries: 10, recursive: true, force: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0649f9fa1f17..be362ddc2641 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2606,6 +2606,12 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/css-inline-stylesheets-2: + dependencies: + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/test/fixtures/css-no-code-split: dependencies: astro: From 4efe519456de50ae9636ac7dce684af1830afccc Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 6 May 2024 15:28:05 +0000 Subject: [PATCH 4/6] [ci] format --- .../src/content/vite-plugin-content-virtual-mod.ts | 2 +- packages/astro/src/core/build/pipeline.ts | 2 +- .../astro/src/core/build/plugins/plugin-analyzer.ts | 12 ++++++------ .../astro/src/core/build/plugins/plugin-content.ts | 6 +++--- .../src/core/build/plugins/plugin-hoisted-scripts.ts | 12 ++++++------ packages/astro/src/core/build/plugins/plugin-ssr.ts | 2 +- packages/astro/src/core/build/static-build.ts | 4 ++-- packages/astro/src/core/util.ts | 7 ++++--- .../astro/src/vite-plugin-astro-server/pipeline.ts | 2 +- packages/astro/src/vite-plugin-scanner/index.ts | 2 +- .../experimental-content-collections-render.test.js | 4 ++-- 11 files changed, 28 insertions(+), 27 deletions(-) diff --git a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts index bd3362343daf..de50edeaaad5 100644 --- a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts +++ b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts @@ -8,7 +8,7 @@ import type { AstroSettings } from '../@types/astro.js'; import { encodeName } from '../core/build/util.js'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { appendForwardSlash, removeFileExtension } from '../core/path.js'; -import { rootRelativePath, isServerLikeOutput } from '../core/util.js'; +import { isServerLikeOutput, rootRelativePath } from '../core/util.js'; import type { AstroPluginMetadata } from '../vite-plugin-astro/index.js'; import { CONTENT_FLAG, diff --git a/packages/astro/src/core/build/pipeline.ts b/packages/astro/src/core/build/pipeline.ts index 5df7cb1e3061..a78c8eaf893c 100644 --- a/packages/astro/src/core/build/pipeline.ts +++ b/packages/astro/src/core/build/pipeline.ts @@ -9,6 +9,7 @@ import { createModuleScriptsSet, createStylesheetElementSet, } from '../render/ssr-element.js'; +import { isServerLikeOutput } from '../util.js'; import { type BuildInternals, cssOrder, @@ -21,7 +22,6 @@ import { getVirtualModulePageNameFromPath } from './plugins/util.js'; import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js'; import type { PageBuildData, StaticBuildOptions } from './types.js'; import { i18nHasFallback } from './util.js'; -import { isServerLikeOutput } from '../util.js'; /** * The build pipeline is responsible to gather the files emitted by the SSR build and generate the pages by executing these files. diff --git a/packages/astro/src/core/build/plugins/plugin-analyzer.ts b/packages/astro/src/core/build/plugins/plugin-analyzer.ts index c72026e0f1fd..5bc0c53e04ea 100644 --- a/packages/astro/src/core/build/plugins/plugin-analyzer.ts +++ b/packages/astro/src/core/build/plugins/plugin-analyzer.ts @@ -53,7 +53,7 @@ export function vitePluginAnalyzer( if (hoistedScripts.size) { for (const parentInfo of getParentModuleInfos(from, this, isPropagatedAsset)) { if (isPropagatedAsset(parentInfo.id)) { - if(isContentCollectionsCacheEnabled(options.settings.config)) { + if (isContentCollectionsCacheEnabled(options.settings.config)) { if (!pageScripts.has(parentInfo.id)) { pageScripts.set(parentInfo.id, { type: 'content', @@ -62,8 +62,8 @@ export function vitePluginAnalyzer( }); } const propagaters = pageScripts.get(parentInfo.id)!.propagatedMapByImporter; - for(const hid of hoistedScripts) { - if(!propagaters.has(parentInfo.id)) { + for (const hid of hoistedScripts) { + if (!propagaters.has(parentInfo.id)) { propagaters.set(parentInfo.id, new Set()); } propagaters.get(parentInfo.id)!.add(hid); @@ -107,11 +107,11 @@ export function vitePluginAnalyzer( finalize() { for (const [pageId, { hoistedSet, propagatedMapByImporter, type }] of pageScripts) { let astroModuleId: string; - if(type === 'page') { + if (type === 'page') { const pageData = getPageDataByViteID(internals, pageId); if (!pageData) { continue; - }; + } const { component } = pageData; astroModuleId = prependForwardSlash(component); @@ -142,7 +142,7 @@ export function vitePluginAnalyzer( } } - if(type === 'page') { + if (type === 'page') { // Make sure to track that this page uses this set of hoisted scripts if (internals.hoistedScriptIdToPagesMap.has(moduleId)) { const pages = internals.hoistedScriptIdToPagesMap.get(moduleId); diff --git a/packages/astro/src/core/build/plugins/plugin-content.ts b/packages/astro/src/core/build/plugins/plugin-content.ts index c94f01f3fc98..7210dd4f184b 100644 --- a/packages/astro/src/core/build/plugins/plugin-content.ts +++ b/packages/astro/src/core/build/plugins/plugin-content.ts @@ -3,6 +3,7 @@ import fsMod from 'node:fs'; import { fileURLToPath } from 'node:url'; import pLimit from 'p-limit'; import { type Plugin as VitePlugin, normalizePath } from 'vite'; +import type { AstroConfig } from '../../../@types/astro.js'; import { CONTENT_RENDER_FLAG, PROPAGATED_ASSET_FLAG } from '../../../content/consts.js'; import { type ContentLookupMap, hasContentFlag } from '../../../content/utils.js'; import { @@ -17,6 +18,7 @@ import { removeFileExtension, removeLeadingForwardSlash, } from '../../path.js'; +import { isContentCollectionsCacheEnabled } from '../../util.js'; import { addRollupInput } from '../add-rollup-input.js'; import { CHUNKS_PATH } from '../consts.js'; import { type BuildInternals } from '../internal.js'; @@ -25,8 +27,6 @@ import { copyFiles } from '../static-build.js'; import type { StaticBuildOptions } from '../types.js'; import { encodeName } from '../util.js'; import { extendManualChunks } from './util.js'; -import { isContentCollectionsCacheEnabled } from '../../util.js'; -import type { AstroConfig } from '../../../@types/astro.js'; const CONTENT_CACHE_DIR = './content/'; const CONTENT_MANIFEST_FILE = './manifest.json'; @@ -479,7 +479,7 @@ export function pluginContent( }, async 'build:post'() { - if(!isContentCollectionsCacheEnabled(opts.settings.config)) { + if (!isContentCollectionsCacheEnabled(opts.settings.config)) { return; } // Cache build output of chunks and assets diff --git a/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts b/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts index 641665b84c1a..80bfa6a6e964 100644 --- a/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts +++ b/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts @@ -11,7 +11,6 @@ function virtualHoistedEntry(id: string) { return id.startsWith('/astro/hoisted.js?q='); } - export function vitePluginHoistedScripts( settings: AstroSettings, internals: BuildInternals @@ -77,7 +76,7 @@ export function vitePluginHoistedScripts( const facadeId = output.facadeModuleId!; // Pages - if(internals.hoistedScriptIdToPagesMap.has(facadeId)) { + if (internals.hoistedScriptIdToPagesMap.has(facadeId)) { const pages = internals.hoistedScriptIdToPagesMap.get(facadeId)!; for (const pathname of pages) { const vid = viteID(new URL('.' + pathname, settings.config.root)); @@ -102,11 +101,12 @@ export function vitePluginHoistedScripts( // Content collection entries else { const contentModules = internals.hoistedScriptIdToContentMap.get(facadeId)!; - for(const contentId of contentModules) { - if(isContentCollectionsCacheEnabled(settings.config)) { - const scripts = internals.propagatedScriptsMap.get(contentId) ?? + for (const contentId of contentModules) { + if (isContentCollectionsCacheEnabled(settings.config)) { + const scripts = + internals.propagatedScriptsMap.get(contentId) ?? internals.propagatedScriptsMap.set(contentId, new Set()).get(contentId)!; - + scripts.add(facadeId); } } diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts index 1d8ea677f4b2..07cba1d57cd2 100644 --- a/packages/astro/src/core/build/plugins/plugin-ssr.ts +++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts @@ -2,9 +2,9 @@ import { join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import type { Plugin as VitePlugin } from 'vite'; import type { AstroAdapter } from '../../../@types/astro.js'; -import { isServerLikeOutput } from '../../util.js'; import { isFunctionPerRouteEnabled } from '../../../integrations/hooks.js'; import { routeIsRedirect } from '../../redirects/index.js'; +import { isServerLikeOutput } from '../../util.js'; import { addRollupInput } from '../add-rollup-input.js'; import type { BuildInternals } from '../internal.js'; import { eachPageFromAllPages } from '../internal.js'; diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 91d17e37431c..e2acc4ea56ca 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -28,6 +28,7 @@ import { generatePages } from './generate.js'; import { trackPageData } from './internal.js'; import { type AstroBuildPluginContainer, createPluginContainer } from './plugin.js'; import { registerAllPlugins } from './plugins/index.js'; +import { copyContentToCache } from './plugins/plugin-content.js'; import { RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID } from './plugins/plugin-manifest.js'; import { ASTRO_PAGE_RESOLVED_MODULE_ID } from './plugins/plugin-pages.js'; import { RESOLVED_RENDERERS_MODULE_ID } from './plugins/plugin-renderers.js'; @@ -35,7 +36,6 @@ import { RESOLVED_SPLIT_MODULE_ID, RESOLVED_SSR_VIRTUAL_MODULE_ID } from './plug import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js'; import type { StaticBuildOptions } from './types.js'; import { encodeName, getTimeStat, viteBuildReturnToRollupOutputs } from './util.js'; -import { copyContentToCache } from './plugins/plugin-content.js'; export async function viteBuild(opts: StaticBuildOptions) { const { allPages, settings } = opts; @@ -108,7 +108,7 @@ export async function viteBuild(opts: StaticBuildOptions) { const ssrOutputs = viteBuildReturnToRollupOutputs(ssrOutput); const clientOutputs = viteBuildReturnToRollupOutputs(clientOutput ?? []); await runPostBuildHooks(container, ssrOutputs, clientOutputs); - if(opts.settings.config.experimental.contentCollectionCache) { + if (opts.settings.config.experimental.contentCollectionCache) { await copyContentToCache(opts); } settings.timer.end('Client build'); diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index 405479030a2f..a48a85d16b35 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -155,11 +155,12 @@ export function isModeServerWithNoAdapter(settings: AstroSettings): boolean { return isServerLikeOutput(settings.config) && !settings.adapter; } - export function isContentCollectionsCacheEnabled(config: AstroConfig): boolean { - return config.experimental.contentCollectionCache && + return ( + config.experimental.contentCollectionCache && // contentCollectionsCache is an SSG only feature - !isServerLikeOutput(config); + !isServerLikeOutput(config) + ); } export function relativeToSrcDir(config: AstroConfig, idOrUrl: URL | string) { diff --git a/packages/astro/src/vite-plugin-astro-server/pipeline.ts b/packages/astro/src/vite-plugin-astro-server/pipeline.ts index 2dfaaac55f07..7ccc63638284 100644 --- a/packages/astro/src/vite-plugin-astro-server/pipeline.ts +++ b/packages/astro/src/vite-plugin-astro-server/pipeline.ts @@ -16,7 +16,7 @@ import { AggregateError, CSSError, MarkdownError } from '../core/errors/index.js import type { Logger } from '../core/logger/core.js'; import type { ModuleLoader } from '../core/module-loader/index.js'; import { Pipeline, loadRenderer } from '../core/render/index.js'; -import { isPage, resolveIdToUrl, viteID, isServerLikeOutput } from '../core/util.js'; +import { isPage, isServerLikeOutput, resolveIdToUrl, viteID } from '../core/util.js'; import { PAGE_SCRIPT_ID } from '../vite-plugin-scripts/index.js'; import { getStylesForURL } from './css.js'; import { getComponentMetadata } from './metadata.js'; diff --git a/packages/astro/src/vite-plugin-scanner/index.ts b/packages/astro/src/vite-plugin-scanner/index.ts index b0065f1ab67a..78069b937a3a 100644 --- a/packages/astro/src/vite-plugin-scanner/index.ts +++ b/packages/astro/src/vite-plugin-scanner/index.ts @@ -4,7 +4,7 @@ import type { Plugin as VitePlugin } from 'vite'; import { normalizePath } from 'vite'; import type { AstroSettings } from '../@types/astro.js'; import { type Logger } from '../core/logger/core.js'; -import { isEndpoint, isPage, rootRelativePath, isServerLikeOutput } from '../core/util.js'; +import { isEndpoint, isPage, isServerLikeOutput, rootRelativePath } from '../core/util.js'; import { getPrerenderDefault } from '../prerender/utils.js'; import { scan } from './scan.js'; diff --git a/packages/astro/test/experimental-content-collections-render.test.js b/packages/astro/test/experimental-content-collections-render.test.js index cf7a22bad172..19349dc39764 100644 --- a/packages/astro/test/experimental-content-collections-render.test.js +++ b/packages/astro/test/experimental-content-collections-render.test.js @@ -114,10 +114,10 @@ if (!isWindows) { it('Includes CSS for rendered entry', async () => { const html = await fixture.readFile('/launch-week/index.html'); const $ = cheerio.load(html); - + // Renders content assert.equal($('ul li').length, 3); - + // Includes styles assert.equal($('link[rel=stylesheet]').length, 1); }); From 2978287f92dbd135f5c3efc6a037ea1756064d35 Mon Sep 17 00:00:00 2001 From: Florian Lefebvre Date: Mon, 6 May 2024 17:35:17 +0200 Subject: [PATCH 5/6] fix(astro): handle AstroUserError during sync and exports types (#10955) Co-authored-by: Luiz Ferraz --- .changeset/strong-peaches-learn.md | 5 +++++ packages/astro/src/core/sync/index.ts | 4 +++- packages/astro/types/content.d.ts | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 .changeset/strong-peaches-learn.md diff --git a/.changeset/strong-peaches-learn.md b/.changeset/strong-peaches-learn.md new file mode 100644 index 000000000000..263746d6be38 --- /dev/null +++ b/.changeset/strong-peaches-learn.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Handles `AstroUserError`s thrown while syncing content collections and exports `BaseSchema` and `CollectionConfig` types diff --git a/packages/astro/src/core/sync/index.ts b/packages/astro/src/core/sync/index.ts index a5763b68f370..b5cfc945b772 100644 --- a/packages/astro/src/core/sync/index.ts +++ b/packages/astro/src/core/sync/index.ts @@ -17,7 +17,7 @@ import { createNodeLogger } from '../config/logging.js'; import { createSettings } from '../config/settings.js'; import { createVite } from '../create-vite.js'; import { collectErrorMetadata } from '../errors/dev/utils.js'; -import { AstroError, AstroErrorData, createSafeError, isAstroError } from '../errors/index.js'; +import { AstroError, AstroErrorData, AstroUserError, createSafeError, isAstroError } from '../errors/index.js'; import type { Logger } from '../logger/core.js'; import { formatErrorMessage } from '../messages.js'; import { ensureProcessNodeEnv } from '../util.js'; @@ -159,9 +159,11 @@ export async function syncContentCollections( if (isAstroError(e)) { throw e; } + const hint = AstroUserError.is(e) ? e.hint : AstroErrorData.GenerateContentTypesError.hint; throw new AstroError( { ...AstroErrorData.GenerateContentTypesError, + hint, message: AstroErrorData.GenerateContentTypesError.message(safeError.message), }, { cause: e } diff --git a/packages/astro/types/content.d.ts b/packages/astro/types/content.d.ts index 45f0d4af79b2..e09bda61844b 100644 --- a/packages/astro/types/content.d.ts +++ b/packages/astro/types/content.d.ts @@ -26,7 +26,7 @@ declare module 'astro:content' { | import('astro/zod').ZodDiscriminatedUnion | import('astro/zod').ZodIntersection; - type BaseSchema = + export type BaseSchema = | BaseSchemaWithoutEffects | import('astro/zod').ZodEffects; @@ -42,7 +42,7 @@ declare module 'astro:content' { schema?: S | ((context: SchemaContext) => S); }; - type CollectionConfig = + export type CollectionConfig = | ContentCollectionConfig | DataCollectionConfig; From 23fb790f40fa642392092489c79da4fc372c1182 Mon Sep 17 00:00:00 2001 From: Florian Lefebvre Date: Mon, 6 May 2024 15:36:13 +0000 Subject: [PATCH 6/6] [ci] format --- packages/astro/src/core/sync/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/core/sync/index.ts b/packages/astro/src/core/sync/index.ts index b5cfc945b772..0b4bd1af46d1 100644 --- a/packages/astro/src/core/sync/index.ts +++ b/packages/astro/src/core/sync/index.ts @@ -17,7 +17,13 @@ import { createNodeLogger } from '../config/logging.js'; import { createSettings } from '../config/settings.js'; import { createVite } from '../create-vite.js'; import { collectErrorMetadata } from '../errors/dev/utils.js'; -import { AstroError, AstroErrorData, AstroUserError, createSafeError, isAstroError } from '../errors/index.js'; +import { + AstroError, + AstroErrorData, + AstroUserError, + createSafeError, + isAstroError, +} from '../errors/index.js'; import type { Logger } from '../logger/core.js'; import { formatErrorMessage } from '../messages.js'; import { ensureProcessNodeEnv } from '../util.js';