@@ -35,8 +35,6 @@ import { OpenNextConfig } from "./types/open-next.js";
3535
3636const require = topLevelCreateRequire ( import . meta. url ) ;
3737const __dirname = url . fileURLToPath ( new URL ( "." , import . meta. url ) ) ;
38- let options : BuildOptions ;
39- let config : OpenNextConfig ;
4038
4139export type PublicFiles = {
4240 files : string [ ] ;
@@ -57,7 +55,7 @@ export async function build(
5755 ) ;
5856 // On Windows, we need to use file:// protocol to load the config file using import()
5957 if ( process . platform === "win32" ) configPath = `file://${ configPath } ` ;
60- config = ( await import ( configPath ) ) . default as OpenNextConfig ;
58+ const config = ( await import ( configPath ) ) . default as OpenNextConfig ;
6159 if ( ! config || ! config . default ) {
6260 logger . error (
6361 `config.default cannot be empty, it should be at least {}, see more info here: https://open-next.js.org/config#configuration-file` ,
@@ -68,42 +66,38 @@ export async function build(
6866
6967 compileOpenNextConfigEdge ( tempDir , config , openNextConfigPath ) ;
7068
71- const { root : monorepoRoot , packager } = findMonorepoRoot (
72- path . join ( process . cwd ( ) , config . appPath || "." ) ,
73- ) ;
74-
7569 // Initialize options
76- options = normalizeOptions ( config , monorepoRoot ) ;
70+ const options = normalizeOptions ( config ) ;
7771 logger . setLevel ( options . debug ? "debug" : "info" ) ;
7872
7973 // Pre-build validation
80- checkRunningInsideNextjsApp ( ) ;
81- printNextjsVersion ( ) ;
82- printOpenNextVersion ( ) ;
74+ checkRunningInsideNextjsApp ( options ) ;
75+ printNextjsVersion ( options ) ;
76+ printOpenNextVersion ( options ) ;
8377
8478 // Build Next.js app
8579 printHeader ( "Building Next.js app" ) ;
86- setStandaloneBuildMode ( monorepoRoot ) ;
87- buildNextjsApp ( packager ) ;
80+ setStandaloneBuildMode ( options ) ;
81+ buildNextjsApp ( options ) ;
8882
8983 // Generate deployable bundle
9084 printHeader ( "Generating bundle" ) ;
91- initOutputDir ( tempDir ) ;
85+ initOutputDir ( tempDir , options ) ;
9286
9387 // Compile cache.ts
94- compileCache ( ) ;
88+ compileCache ( options ) ;
9589
9690 // Compile middleware
97- await createMiddleware ( ) ;
91+ await createMiddleware ( options ) ;
9892
99- createStaticAssets ( ) ;
100- await createCacheAssets ( monorepoRoot ) ;
93+ createStaticAssets ( options ) ;
94+ await createCacheAssets ( options ) ;
10195
102- await createServerBundle ( config , options ) ;
103- await createRevalidationBundle ( config ) ;
104- await createImageOptimizationBundle ( config ) ;
105- await createWarmerBundle ( config ) ;
106- await generateOutput ( options . appBuildOutputPath , config ) ;
96+ await createServerBundle ( options ) ;
97+ await createRevalidationBundle ( options ) ;
98+ await createImageOptimizationBundle ( options ) ;
99+ await createWarmerBundle ( options ) ;
100+ await generateOutput ( options ) ;
107101 logger . info ( "OpenNext build complete." ) ;
108102}
109103
@@ -127,7 +121,7 @@ function initTempDir() {
127121 return tempDir ;
128122}
129123
130- function checkRunningInsideNextjsApp ( ) {
124+ function checkRunningInsideNextjsApp ( options : BuildOptions ) {
131125 const { appPath } = options ;
132126 const extension = [ "js" , "cjs" , "mjs" , "ts" ] . find ( ( ext ) =>
133127 fs . existsSync ( path . join ( appPath , `next.config.${ ext } ` ) ) ,
@@ -140,48 +134,23 @@ function checkRunningInsideNextjsApp() {
140134 }
141135}
142136
143- function findMonorepoRoot ( appPath : string ) {
144- let currentPath = appPath ;
145- while ( currentPath !== "/" ) {
146- const found = [
147- { file : "package-lock.json" , packager : "npm" as const } ,
148- { file : "yarn.lock" , packager : "yarn" as const } ,
149- { file : "pnpm-lock.yaml" , packager : "pnpm" as const } ,
150- { file : "bun.lockb" , packager : "bun" as const } ,
151- ] . find ( ( f ) => fs . existsSync ( path . join ( currentPath , f . file ) ) ) ;
152-
153- if ( found ) {
154- if ( currentPath !== appPath ) {
155- logger . info ( "Monorepo detected at" , currentPath ) ;
156- }
157- return { root : currentPath , packager : found . packager } ;
158- }
159- currentPath = path . dirname ( currentPath ) ;
160- }
161-
162- // note: a lock file (package-lock.json, yarn.lock, or pnpm-lock.yaml) is
163- // not found in the app's directory or any of its parent directories.
164- // We are going to assume that the app is not part of a monorepo.
165- return { root : appPath , packager : "npm" as const } ;
166- }
167-
168- function setStandaloneBuildMode ( monorepoRoot : string ) {
169- // Equivalent to setting `target: "standalone"` in next.config.js
137+ function setStandaloneBuildMode ( options : BuildOptions ) {
138+ // Equivalent to setting `output: "standalone"` in next.config.js
170139 process . env . NEXT_PRIVATE_STANDALONE = "true" ;
171140 // Equivalent to setting `experimental.outputFileTracingRoot` in next.config.js
172- process . env . NEXT_PRIVATE_OUTPUT_TRACE_ROOT = monorepoRoot ;
141+ process . env . NEXT_PRIVATE_OUTPUT_TRACE_ROOT = options . monorepoRoot ;
173142}
174143
175- function buildNextjsApp ( packager : "npm" | "yarn" | "pnpm" | "bun" ) {
176- const { appPackageJsonPath } = options ;
144+ function buildNextjsApp ( options : BuildOptions ) {
145+ const { config , packager } = options ;
177146 const command =
178147 config . buildCommand ??
179148 ( [ "bun" , "npm" ] . includes ( packager )
180149 ? `${ packager } run build`
181150 : `${ packager } build` ) ;
182151 cp . execSync ( command , {
183152 stdio : "inherit" ,
184- cwd : path . dirname ( appPackageJsonPath ) ,
153+ cwd : path . dirname ( options . appPackageJsonPath ) ,
185154 } ) ;
186155}
187156
@@ -198,47 +167,48 @@ function printHeader(header: string) {
198167 ) ;
199168}
200169
201- function printNextjsVersion ( ) {
202- const { nextVersion } = options ;
203- logger . info ( `Next.js version : ${ nextVersion } ` ) ;
170+ function printNextjsVersion ( options : BuildOptions ) {
171+ logger . info ( `Next.js version : ${ options . nextVersion } ` ) ;
204172}
205173
206- function printOpenNextVersion ( ) {
207- const { openNextVersion } = options ;
208- logger . info ( `OpenNext v${ openNextVersion } ` ) ;
174+ function printOpenNextVersion ( options : BuildOptions ) {
175+ logger . info ( `OpenNext v${ options . openNextVersion } ` ) ;
209176}
210177
211- function initOutputDir ( tempDir : string ) {
178+ function initOutputDir ( srcTempDir : string , options : BuildOptions ) {
212179 // We need to get the build relative to the cwd to find the compiled config
213180 // This is needed for the case where the app is a single-version monorepo and the package.json is in the root of the monorepo
214181 // where the build is in the app directory, but the compiled config is in the root of the monorepo.
215- const { outputDir, tempDir : lTempDir } = options ;
216182 const openNextConfig = readFileSync (
217- path . join ( tempDir , "open-next.config.mjs" ) ,
183+ path . join ( srcTempDir , "open-next.config.mjs" ) ,
218184 "utf8" ,
219185 ) ;
220186 let openNextConfigEdge : string | null = null ;
221- if ( fs . existsSync ( path . join ( tempDir , "open-next.config.edge.mjs" ) ) ) {
187+ if ( fs . existsSync ( path . join ( srcTempDir , "open-next.config.edge.mjs" ) ) ) {
222188 openNextConfigEdge = readFileSync (
223- path . join ( tempDir , "open-next.config.edge.mjs" ) ,
189+ path . join ( srcTempDir , "open-next.config.edge.mjs" ) ,
224190 "utf8" ,
225191 ) ;
226192 }
227- fs . rmSync ( outputDir , { recursive : true , force : true } ) ;
228- fs . mkdirSync ( lTempDir , { recursive : true } ) ;
229- fs . writeFileSync ( path . join ( lTempDir , "open-next.config.mjs" ) , openNextConfig ) ;
193+ fs . rmSync ( options . outputDir , { recursive : true , force : true } ) ;
194+ const destTempDir = options . tempDir ;
195+ fs . mkdirSync ( destTempDir , { recursive : true } ) ;
196+ fs . writeFileSync (
197+ path . join ( destTempDir , "open-next.config.mjs" ) ,
198+ openNextConfig ,
199+ ) ;
230200 if ( openNextConfigEdge ) {
231201 fs . writeFileSync (
232- path . join ( lTempDir , "open-next.config.edge.mjs" ) ,
202+ path . join ( destTempDir , "open-next.config.edge.mjs" ) ,
233203 openNextConfigEdge ,
234204 ) ;
235205 }
236206}
237207
238- async function createWarmerBundle ( config : OpenNextConfig ) {
208+ async function createWarmerBundle ( options : BuildOptions ) {
239209 logger . info ( `Bundling warmer function...` ) ;
240210
241- const { outputDir } = options ;
211+ const { config , outputDir } = options ;
242212
243213 // Create output folder
244214 const outputPath = path . join ( outputDir , "warmer-function" ) ;
@@ -278,10 +248,10 @@ async function createWarmerBundle(config: OpenNextConfig) {
278248 ) ;
279249}
280250
281- async function createRevalidationBundle ( config : OpenNextConfig ) {
251+ async function createRevalidationBundle ( options : BuildOptions ) {
282252 logger . info ( `Bundling revalidation function...` ) ;
283253
284- const { appBuildOutputPath, outputDir } = options ;
254+ const { appBuildOutputPath, config , outputDir } = options ;
285255
286256 // Create output folder
287257 const outputPath = path . join ( outputDir , "revalidation-function" ) ;
@@ -317,10 +287,10 @@ async function createRevalidationBundle(config: OpenNextConfig) {
317287 ) ;
318288}
319289
320- async function createImageOptimizationBundle ( config : OpenNextConfig ) {
290+ async function createImageOptimizationBundle ( options : BuildOptions ) {
321291 logger . info ( `Bundling image optimization function...` ) ;
322292
323- const { appPath, appBuildOutputPath, outputDir } = options ;
293+ const { appPath, appBuildOutputPath, config , outputDir } = options ;
324294
325295 // Create output folder
326296 const outputPath = path . join ( outputDir , "image-optimization-function" ) ;
@@ -436,7 +406,7 @@ async function createImageOptimizationBundle(config: OpenNextConfig) {
436406 }
437407}
438408
439- function createStaticAssets ( ) {
409+ function createStaticAssets ( options : BuildOptions ) {
440410 logger . info ( `Bundling static assets...` ) ;
441411
442412 const { appBuildOutputPath, appPublicPath, outputDir, appPath } = options ;
@@ -475,13 +445,14 @@ function createStaticAssets() {
475445 }
476446}
477447
478- async function createCacheAssets ( monorepoRoot : string ) {
448+ async function createCacheAssets ( options : BuildOptions ) {
449+ const { config } = options ;
479450 if ( config . dangerous ?. disableIncrementalCache ) return ;
480451
481452 logger . info ( `Bundling cache assets...` ) ;
482453
483454 const { appBuildOutputPath, outputDir } = options ;
484- const packagePath = path . relative ( monorepoRoot , appBuildOutputPath ) ;
455+ const packagePath = path . relative ( options . monorepoRoot , appBuildOutputPath ) ;
485456 const buildId = getBuildId ( appBuildOutputPath ) ;
486457
487458 // Copy pages to cache folder
@@ -683,7 +654,11 @@ async function createCacheAssets(monorepoRoot: string) {
683654/* Server Helper Functions */
684655/***************************/
685656
686- export function compileCache ( format : "cjs" | "esm" = "cjs" ) {
657+ export function compileCache (
658+ options : BuildOptions ,
659+ format : "cjs" | "esm" = "cjs" ,
660+ ) {
661+ const { config } = options ;
687662 const ext = format === "cjs" ? "cjs" : "mjs" ;
688663 const outfile = path . join ( options . outputDir , ".build" , `cache.${ ext } ` ) ;
689664
@@ -713,10 +688,10 @@ export function compileCache(format: "cjs" | "esm" = "cjs") {
713688 return outfile ;
714689}
715690
716- async function createMiddleware ( ) {
691+ async function createMiddleware ( options : BuildOptions ) {
717692 console . info ( `Bundling middleware function...` ) ;
718693
719- const { appBuildOutputPath, outputDir } = options ;
694+ const { appBuildOutputPath, config , outputDir } = options ;
720695
721696 // Get middleware manifest
722697 const middlewareManifest = JSON . parse (
0 commit comments