diff --git a/packages/astro/src/content/index.ts b/packages/astro/src/content/index.ts index a2eae67ed532..ff88bcc166c3 100644 --- a/packages/astro/src/content/index.ts +++ b/packages/astro/src/content/index.ts @@ -2,7 +2,6 @@ export { createContentTypesGenerator } from './types-generator.js'; export { contentObservable, getContentPaths, getDotAstroTypeReference } from './utils.js'; export { astroContentAssetPropagationPlugin, - astroContentProdBundlePlugin, } from './vite-plugin-content-assets.js'; export { astroContentServerPlugin } from './vite-plugin-content-server.js'; export { astroContentVirtualModPlugin } from './vite-plugin-content-virtual-mod.js'; diff --git a/packages/astro/src/content/vite-plugin-content-assets.ts b/packages/astro/src/content/vite-plugin-content-assets.ts index 01c2572351da..bfaa02150a76 100644 --- a/packages/astro/src/content/vite-plugin-content-assets.ts +++ b/packages/astro/src/content/vite-plugin-content-assets.ts @@ -1,4 +1,5 @@ import { pathToFileURL } from 'url'; +import npath from 'node:path'; import type { Plugin } from 'vite'; import { moduleIsTopLevelPage, walkParentInfos } from '../core/build/graph.js'; import { BuildInternals, getPageDataByViteID } from '../core/build/internal.js'; @@ -14,6 +15,8 @@ import { SCRIPTS_PLACEHOLDER, STYLES_PLACEHOLDER, } from './consts.js'; +import type { RollupOutput, OutputChunk, StaticBuildOptions } from '../core/build/types'; +import { prependForwardSlash } from '../core/path.js'; function isPropagatedAsset(viteId: string): boolean { const url = new URL(viteId, 'file://'); @@ -73,67 +76,95 @@ export function astroContentAssetPropagationPlugin({ mode }: { mode: string }): }; } -export function astroContentProdBundlePlugin({ internals }: { internals: BuildInternals }): Plugin { +export function astroConfigBuildPlugin(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin { + let ssrPluginContext: any = undefined; return { - name: 'astro:content-prod-bundle', - async generateBundle(_options, bundle) { - for (const [_, chunk] of Object.entries(bundle)) { - if ( - chunk.type === 'chunk' && - (chunk.code.includes(LINKS_PLACEHOLDER) || chunk.code.includes(SCRIPTS_PLACEHOLDER)) - ) { - for (const id of Object.keys(chunk.modules)) { - for (const [pageInfo, depth, order] of walkParentInfos(id, this)) { - if (moduleIsTopLevelPage(pageInfo)) { - const pageViteID = pageInfo.id; - const pageData = getPageDataByViteID(internals, pageViteID); - if (!pageData) continue; -<<<<<<< HEAD + build: 'ssr', + hooks: { + 'build:before': ({ build }) => { + return { + vitePlugin: { + name: 'astro:content-build-plugin', + generateBundle() { + if(build === 'ssr') { + ssrPluginContext = this; + } + } + }, + }; + }, + 'build:post': ({ ssrOutputs, clientOutputs, mutate }) => { + const outputs = ssrOutputs.flatMap(o => o.output); + for (const chunk of outputs) { + if ( + chunk.type === 'chunk' && + (chunk.code.includes(LINKS_PLACEHOLDER) || chunk.code.includes(SCRIPTS_PLACEHOLDER)) + ) { + let entryCSS = new Set(); + let entryScripts = new Set(); -======= - console.log({ pageData }); ->>>>>>> bdc0a6498 (updated) - const entryCss = pageData.contentCollectionCss?.get(id); - const entryScripts = pageData.propagatedScripts?.get(id); - if (entryCss) { - chunk.code = chunk.code.replace( - JSON.stringify(LINKS_PLACEHOLDER), - JSON.stringify([...entryCss]) - ); + for (const id of Object.keys(chunk.modules)) { + for (const [pageInfo] of walkParentInfos(id, ssrPluginContext)) { + if (moduleIsTopLevelPage(pageInfo)) { + const pageViteID = pageInfo.id; + const pageData = getPageDataByViteID(internals, pageViteID); + if (!pageData) continue; + + const _entryCss = pageData.contentCollectionCss?.get(id); + const _entryScripts = pageData.propagatedScripts?.get(id); + if(_entryCss) { + for(const value of _entryCss) { + entryCSS.add(value); + } + } + if(_entryScripts) { + for(const value of _entryScripts) { + entryScripts.add(value); + } + } } - if (entryScripts) { -<<<<<<< HEAD -======= - console.log({ entryScripts }); ->>>>>>> bdc0a6498 (updated) - chunk.code = chunk.code.replace( - JSON.stringify(SCRIPTS_PLACEHOLDER), - JSON.stringify( - [...entryScripts].map((src) => ({ - props: { src, type: 'module' }, - children: '', - })) - ) - ); + } + } + + let newCode = chunk.code; + if (entryCSS.size) { + newCode = newCode.replace( + JSON.stringify(LINKS_PLACEHOLDER), + JSON.stringify([...entryCSS]) + ); + } + if (entryScripts.size) { + const entryFileNames = new Set(); + for(const output of clientOutputs) { + for(const clientChunk of output.output) { + if(clientChunk.type !== 'chunk') continue; + for(const [id] of Object.entries(clientChunk.modules)) { + if(entryScripts.has(id)) { + entryFileNames.add(clientChunk.fileName); + } + } } } + newCode = newCode.replace( + JSON.stringify(SCRIPTS_PLACEHOLDER), + JSON.stringify( + [...entryFileNames].map((src) => ({ + props: { + src: prependForwardSlash(npath.posix.join( + options.settings.config.base, + src + )), + type: 'module' + }, + children: '', + })) + ) + ); } + mutate(chunk, 'server', newCode); } } } }, }; } - -export function astroConfigBuildPlugin(internals: BuildInternals): AstroBuildPlugin { - return { - build: 'ssr', - hooks: { - 'build:before': () => { - return { - vitePlugin: astroContentProdBundlePlugin({ internals }), - }; - }, - }, - }; -} diff --git a/packages/astro/src/core/build/plugins/index.ts b/packages/astro/src/core/build/plugins/index.ts index 29591185da7b..cf0f9bf7c66d 100644 --- a/packages/astro/src/core/build/plugins/index.ts +++ b/packages/astro/src/core/build/plugins/index.ts @@ -16,7 +16,7 @@ export function registerAllPlugins({ internals, options, register }: AstroBuildP register(pluginPages(options, internals)); register(pluginCSS(options, internals)); register(pluginPrerender(options, internals)); - register(astroConfigBuildPlugin(internals)); + register(astroConfigBuildPlugin(options, internals)); register(pluginHoistedScripts(options, internals)); register(pluginSSR(options, internals)); } diff --git a/packages/astro/src/core/build/plugins/plugin-analyzer.ts b/packages/astro/src/core/build/plugins/plugin-analyzer.ts index 3dd7835fb57a..6bf7ffe29bc9 100644 --- a/packages/astro/src/core/build/plugins/plugin-analyzer.ts +++ b/packages/astro/src/core/build/plugins/plugin-analyzer.ts @@ -179,7 +179,7 @@ export function pluginAnalyzer(internals: BuildInternals): AstroBuildPlugin { return { vitePlugin: vitePluginAnalyzer(internals), }; - }, + } }, }; } diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 4e3238978003..0dcfa6a51782 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -245,9 +245,12 @@ async function runPostBuildHooks( clientReturn: Awaited> ) { const mutations = await container.runPostHook(ssrReturn, clientReturn); + const config = container.options.settings.config; const buildConfig = container.options.settings.config.build; for (const [fileName, mutation] of mutations) { - const root = mutation.build === 'server' ? buildConfig.server : buildConfig.client; + const root = config.output === 'server' ? + mutation.build === 'server' ? buildConfig.server : buildConfig.client : + config.outDir; const fileURL = new URL(fileName, root); await fs.promises.mkdir(new URL('./', fileURL), { recursive: true }); await fs.promises.writeFile(fileURL, mutation.code, 'utf-8'); diff --git a/packages/astro/test/content-collections-render.test.js b/packages/astro/test/content-collections-render.test.js index 5915fada8da7..ad45e58a4c61 100644 --- a/packages/astro/test/content-collections-render.test.js +++ b/packages/astro/test/content-collections-render.test.js @@ -46,7 +46,7 @@ describe('Content Collections - render()', () => { // Includes hoisted script expect( [...allScripts].find((script) => - $(script).text().includes('document.querySelector("#update-me")') + $(script).attr('src')?.includes('WithScripts') ), '`WithScripts.astro` hoisted script missing from head.' ).to.not.be.undefined;