11import { mkdir , readFile , rename , rm , writeFile } from "node:fs/promises" ;
22import path from "node:path" ;
33import { build as esbuild } from "esbuild" ;
4- import type { Rollup } from "vite" ;
5- import { build as viteBuild } from "vite" ;
4+ import { createBuilder } from "vite" ;
65import { ZuploEnv } from "../app/env.js" ;
76import { getZudokuRootDir } from "../cli/common/package-json.js" ;
87import {
@@ -19,21 +18,6 @@ import { prerender } from "./prerender/prerender.js";
1918
2019const DIST_DIR = "dist" ;
2120
22- const extractAssets = ( result : Rollup . RollupOutput ) => {
23- const jsEntry = result . output . find (
24- ( o ) => "isEntry" in o && o . isEntry ,
25- ) ?. fileName ;
26- const cssEntries = result . output
27- . filter ( ( o ) => o . fileName . endsWith ( ".css" ) )
28- . map ( ( o ) => o . fileName ) ;
29-
30- if ( ! jsEntry || cssEntries . length === 0 ) {
31- throw new Error ( "Build failed. No js or css assets found" ) ;
32- }
33-
34- return { jsEntry, cssEntries } ;
35- } ;
36-
3721export type BuildOptions = {
3822 dir : string ;
3923 ssr ?: boolean ;
@@ -43,49 +27,56 @@ export type BuildOptions = {
4327export async function runBuild ( options : BuildOptions ) {
4428 const { dir, ssr, adapter = "node" } = options ;
4529
46- // Build client and server bundles
47- const viteClientConfig = await getViteConfig ( dir , {
48- mode : "production" ,
49- command : "build" ,
50- } ) ;
51- const viteServerConfig = await getViteConfig ( dir , {
30+ const viteConfig = await getViteConfig ( dir , {
5231 mode : "production" ,
5332 command : "build" ,
54- isSsrBuild : true ,
5533 } ) ;
5634
57- const clientResult = await viteBuild ( viteClientConfig ) ;
58- const serverResult = await viteBuild ( {
59- ...viteServerConfig ,
60- logLevel : "silent" ,
61- } ) ;
35+ const builder = await createBuilder ( viteConfig ) ;
6236
63- if ( Array . isArray ( clientResult ) || ! ( "output" in clientResult ) ) {
64- throw new Error ( "Client build failed" ) ;
65- }
66- if ( Array . isArray ( serverResult ) || ! ( "output" in serverResult ) ) {
67- throw new Error ( "Server build failed" ) ;
68- }
37+ invariant ( builder . environments . client , "Client environment is missing" ) ;
38+ invariant ( builder . environments . ssr , "SSR environment is missing" ) ;
39+
40+ const [ clientResult , serverResult ] = await Promise . all ( [
41+ builder . build ( builder . environments . client ) ,
42+ builder . build ( builder . environments . ssr ) ,
43+ ] ) ;
44+
45+ invariant (
46+ clientResult && ! Array . isArray ( clientResult ) && "output" in clientResult ,
47+ "Client build failed to produce valid output" ,
48+ ) ;
49+ invariant ( serverResult , "SSR build failed to produce valid output" ) ;
6950
7051 const { config } = await loadZudokuConfig (
7152 { mode : "production" , command : "build" } ,
7253 dir ,
7354 ) ;
7455
75- const { jsEntry, cssEntries } = extractAssets ( clientResult ) ;
56+ const base = viteConfig . base ?? "/" ;
57+ const clientOutDir = viteConfig . environments ?. client ?. build ?. outDir ;
58+ const serverOutDir = viteConfig . environments ?. ssr ?. build ?. outDir ;
59+
60+ invariant ( clientOutDir , "Client build outDir is missing" ) ;
61+ invariant ( serverOutDir , "Server build outDir is missing" ) ;
62+
63+ const jsEntry = clientResult . output . find (
64+ ( o ) => "isEntry" in o && o . isEntry ,
65+ ) ?. fileName ;
66+ const cssEntries = clientResult . output
67+ . filter ( ( o ) => o . fileName . endsWith ( ".css" ) )
68+ . map ( ( o ) => o . fileName ) ;
69+
70+ if ( ! jsEntry || cssEntries . length === 0 ) {
71+ throw new Error ( "Build failed. No js or css assets found" ) ;
72+ }
7673
7774 const html = getBuildHtml ( {
78- jsEntry : joinUrl ( viteClientConfig . base , jsEntry ) ,
79- cssEntries : cssEntries . map ( ( css ) => joinUrl ( viteClientConfig . base , css ) ) ,
75+ jsEntry : joinUrl ( base , jsEntry ) ,
76+ cssEntries : cssEntries . map ( ( css ) => joinUrl ( base , css ) ) ,
8077 dir : config . site ?. dir ,
8178 } ) ;
8279
83- invariant ( viteClientConfig . build ?. outDir , "Client build outDir is missing" ) ;
84- invariant ( viteServerConfig . build ?. outDir , "Server build outDir is missing" ) ;
85-
86- const clientOutDir = viteClientConfig . build . outDir ;
87- const serverOutDir = viteServerConfig . build . outDir ;
88-
8980 if ( ssr ) {
9081 // SSR: bundle entry.js and remove index.html
9182 await bundleSSREntry ( {
@@ -115,7 +106,7 @@ type PrerenderOptions = {
115106 html : string ;
116107 clientOutDir : string ;
117108 serverOutDir : string ;
118- serverResult : Rollup . RollupOutput ;
109+ serverResult : Awaited < ReturnType < typeof import ( "vite" ) . build > > ;
119110} ;
120111
121112const runPrerender = async ( options : PrerenderOptions ) => {
0 commit comments