Fix ssr, probably

This commit is contained in:
unknown 2022-06-17 12:01:08 -04:00
parent e19994a08d
commit 599447c905
3 changed files with 44 additions and 14 deletions

View file

@ -1,4 +1,4 @@
import type { RenderedChunk } from 'rollup'; import type { OutputChunk, RenderedChunk } from 'rollup';
import type { PageBuildData, ViteID } from './types'; import type { PageBuildData, ViteID } from './types';
import { prependForwardSlash } from '../path.js'; import { prependForwardSlash } from '../path.js';
@ -47,6 +47,11 @@ export interface BuildInternals {
* These will be used as the top-level entrypoints for the client build. * These will be used as the top-level entrypoints for the client build.
*/ */
discoveredScripts: Set<string>; discoveredScripts: Set<string>;
// A list of all static files created during the build. Used for SSR.
staticFiles: Set<string>;
// The SSR entry chunk. Kept in internals to share between ssr/client build steps
ssrEntryChunk?: OutputChunk;
} }
/** /**
@ -84,6 +89,7 @@ export function createBuildInternals(): BuildInternals {
discoveredHydratedComponents: new Set(), discoveredHydratedComponents: new Set(),
discoveredClientOnlyComponents: new Set(), discoveredClientOnlyComponents: new Set(),
discoveredScripts: new Set(), discoveredScripts: new Set(),
staticFiles: new Set(),
}; };
} }

View file

@ -7,7 +7,6 @@ import * as vite from 'vite';
import { import {
BuildInternals, BuildInternals,
createBuildInternals, createBuildInternals,
trackClientOnlyPageDatas,
} from '../../core/build/internal.js'; } from '../../core/build/internal.js';
import { prependForwardSlash } from '../../core/path.js'; import { prependForwardSlash } from '../../core/path.js';
import { emptyDir, removeDir } from '../../core/util.js'; import { emptyDir, removeDir } from '../../core/util.js';
@ -23,7 +22,7 @@ import { getTimeStat } from './util.js';
import { vitePluginHoistedScripts } from './vite-plugin-hoisted-scripts.js'; import { vitePluginHoistedScripts } from './vite-plugin-hoisted-scripts.js';
import { vitePluginInternals } from './vite-plugin-internals.js'; import { vitePluginInternals } from './vite-plugin-internals.js';
import { vitePluginPages } from './vite-plugin-pages.js'; import { vitePluginPages } from './vite-plugin-pages.js';
import { vitePluginSSR } from './vite-plugin-ssr.js'; import { vitePluginSSR, vitePluginSSRInject } from './vite-plugin-ssr.js';
import { vitePluginAnalyzer } from './vite-plugin-analyzer.js'; import { vitePluginAnalyzer } from './vite-plugin-analyzer.js';
export async function staticBuild(opts: StaticBuildOptions) { export async function staticBuild(opts: StaticBuildOptions) {
@ -220,6 +219,8 @@ async function clientBuild(
target: 'client', target: 'client',
}), }),
...(viteConfig.plugins || []), ...(viteConfig.plugins || []),
// SSR needs to be last
isBuildingToSSR(opts.astroConfig) && vitePluginSSRInject(opts, internals),
], ],
publicDir: viteConfig.publicDir, publicDir: viteConfig.publicDir,
root: viteConfig.root, root: viteConfig.root,

View file

@ -12,6 +12,7 @@ import { pagesVirtualModuleId } from '../app/index.js';
import { serializeRouteData } from '../routing/index.js'; import { serializeRouteData } from '../routing/index.js';
import { addRollupInput } from './add-rollup-input.js'; import { addRollupInput } from './add-rollup-input.js';
import { eachPageData } from './internal.js'; import { eachPageData } from './internal.js';
import * as fs from 'fs';
export const virtualModuleId = '@astrojs-ssr-virtual-entry'; export const virtualModuleId = '@astrojs-ssr-virtual-entry';
const resolvedVirtualModuleId = '\0' + virtualModuleId; const resolvedVirtualModuleId = '\0' + virtualModuleId;
@ -69,7 +70,7 @@ if(_start in adapter) {
return void 0; return void 0;
}, },
async generateBundle(_opts, bundle) { async generateBundle(_opts, bundle) {
const staticFiles = new Set( internals.staticFiles = new Set(
await glob('**/*', { await glob('**/*', {
cwd: fileURLToPath(buildOpts.buildConfig.client), cwd: fileURLToPath(buildOpts.buildConfig.client),
}) })
@ -78,28 +79,50 @@ if(_start in adapter) {
// Add assets from this SSR chunk as well. // Add assets from this SSR chunk as well.
for (const [_chunkName, chunk] of Object.entries(bundle)) { for (const [_chunkName, chunk] of Object.entries(bundle)) {
if (chunk.type === 'asset') { if (chunk.type === 'asset') {
staticFiles.add(chunk.fileName); internals.staticFiles.add(chunk.fileName);
} }
} }
const manifest = buildManifest(buildOpts, internals, Array.from(staticFiles)); for (const [chunkName, chunk] of Object.entries(bundle)) {
await runHookBuildSsr({ config: buildOpts.astroConfig, manifest });
for (const [_chunkName, chunk] of Object.entries(bundle)) {
if (chunk.type === 'asset') { if (chunk.type === 'asset') {
continue; continue;
} }
if (chunk.modules[resolvedVirtualModuleId]) { if (chunk.modules[resolvedVirtualModuleId]) {
const code = chunk.code; internals.ssrEntryChunk = chunk;
chunk.code = code.replace(replaceExp, () => { delete bundle[chunkName];
return JSON.stringify(manifest);
});
} }
} }
}, },
}; };
} }
export function vitePluginSSRInject(
buildOpts: StaticBuildOptions,
internals: BuildInternals,
): VitePlugin {
return {
name: '@astrojs/vite-plugin-astro-ssr-inject',
async writeBundle(opts, bundle) {
if(!internals.ssrEntryChunk) {
throw new Error(`Did not generate an entry chunk for SSR`);
}
const staticFiles = internals.staticFiles;
const manifest = buildManifest(buildOpts, internals, Array.from(staticFiles));
await runHookBuildSsr({ config: buildOpts.astroConfig, manifest });
const chunk = internals.ssrEntryChunk;
const code = chunk.code;
chunk.code = code.replace(replaceExp, () => {
return JSON.stringify(manifest);
});
const serverEntryURL = new URL(buildOpts.buildConfig.serverEntry, buildOpts.buildConfig.server);
await fs.promises.mkdir(new URL('./', serverEntryURL), { recursive: true });
await fs.promises.writeFile(serverEntryURL, chunk.code, 'utf-8');
},
}
}
function buildManifest( function buildManifest(
opts: StaticBuildOptions, opts: StaticBuildOptions,
internals: BuildInternals, internals: BuildInternals,