@@ -29,35 +29,27 @@ import { OpenNextConfig } from "./types/open-next.js";
29
29
30
30
const __dirname = url . fileURLToPath ( new URL ( "." , import . meta. url ) ) ;
31
31
let options : BuildOptions ;
32
+ let config : OpenNextConfig ;
32
33
33
34
export type PublicFiles = {
34
35
files : string [ ] ;
35
36
} ;
36
37
37
38
export async function build ( openNextConfigPath ?: string ) {
38
- const outputTmpPath = path . join ( process . cwd ( ) , ".open-next" , ".build" ) ;
39
+ showWindowsWarning ( ) ;
39
40
40
- if ( os . platform ( ) === "win32" ) {
41
- logger . error (
42
- "OpenNext is not properly supported on Windows. On windows you should use WSL. It might works or it might fail in unpredictable way at runtime" ,
43
- ) ;
44
- // Wait 10s here so that the user see this message
45
- await new Promise ( ( resolve ) => setTimeout ( resolve , 10000 ) ) ;
46
- }
47
-
48
- // Compile open-next.config.ts
49
- createOpenNextConfigBundle ( outputTmpPath , openNextConfigPath ) ;
50
-
51
- const config = await import ( outputTmpPath + "/open-next.config.mjs" ) ;
52
- const opts = config . default as OpenNextConfig ;
53
- validateConfig ( opts ) ;
41
+ // Load open-next.config.ts
42
+ const tempDir = initTempDir ( ) ;
43
+ const configPath = compileOpenNextConfig ( tempDir , openNextConfigPath ) ;
44
+ config = ( await import ( configPath ) ) . default as OpenNextConfig ;
45
+ validateConfig ( config ) ;
54
46
55
47
const { root : monorepoRoot , packager } = findMonorepoRoot (
56
- path . join ( process . cwd ( ) , opts . appPath || "." ) ,
48
+ path . join ( process . cwd ( ) , config . appPath || "." ) ,
57
49
) ;
58
50
59
51
// Initialize options
60
- options = normalizeOptions ( opts , monorepoRoot ) ;
52
+ options = normalizeOptions ( config , monorepoRoot ) ;
61
53
logger . setLevel ( options . debug ? "debug" : "info" ) ;
62
54
63
55
// Pre-build validation
@@ -75,57 +67,70 @@ export async function build(openNextConfigPath?: string) {
75
67
initOutputDir ( ) ;
76
68
77
69
// Compile cache.ts
78
- compileCache ( options ) ;
70
+ compileCache ( ) ;
79
71
80
72
// Compile middleware
81
- await createMiddleware ( opts ) ;
73
+ await createMiddleware ( ) ;
82
74
83
75
createStaticAssets ( ) ;
84
- if ( ! options . dangerous ?. disableIncrementalCache ) {
85
- await createCacheAssets ( monorepoRoot , options . dangerous ?. disableTagCache ) ;
86
- }
87
- await createServerBundle ( opts , options ) ;
76
+ await createCacheAssets ( monorepoRoot ) ;
77
+ await createServerBundle ( config , options ) ;
88
78
await createRevalidationBundle ( ) ;
89
79
createImageOptimizationBundle ( ) ;
90
80
await createWarmerBundle ( ) ;
91
- await generateOutput ( options . appBuildOutputPath , opts ) ;
81
+ await generateOutput ( options . appBuildOutputPath , config ) ;
92
82
}
93
83
94
- function createOpenNextConfigBundle (
95
- tempDir : string ,
96
- openNextConfigPath ?: string ,
97
- ) {
98
- //Check if open-next.config.ts exists
99
- const pathToOpenNextConfig = path . join (
84
+ function showWindowsWarning ( ) {
85
+ if ( os . platform ( ) !== "win32" ) return ;
86
+
87
+ logger . warn ( "OpenNext is not fully compatible with Windows." ) ;
88
+ logger . warn (
89
+ "For optimal performance, it is recommended to use Windows Subsystem for Linux (WSL)." ,
90
+ ) ;
91
+ logger . warn (
92
+ "While OpenNext may function on Windows, it could encounter unpredictable failures during runtime." ,
93
+ ) ;
94
+ }
95
+
96
+ function initTempDir ( ) {
97
+ const dir = path . join ( process . cwd ( ) , ".open-next" ) ;
98
+ const tempDir = path . join ( dir , ".build" ) ;
99
+ fs . rmSync ( dir , { recursive : true , force : true } ) ;
100
+ fs . mkdirSync ( tempDir , { recursive : true } ) ;
101
+ return tempDir ;
102
+ }
103
+
104
+ function compileOpenNextConfig ( tempDir : string , openNextConfigPath ?: string ) {
105
+ const sourcePath = path . join (
100
106
process . cwd ( ) ,
101
107
openNextConfigPath ?? "open-next.config.ts" ,
102
108
) ;
103
- if ( ! fs . existsSync ( pathToOpenNextConfig ) ) {
109
+ const outputPath = path . join ( tempDir , "open-next.config.mjs" ) ;
110
+
111
+ //Check if open-next.config.ts exists
112
+ if ( ! fs . existsSync ( sourcePath ) ) {
104
113
//Create a simple open-next.config.mjs file
105
- logger . warn (
106
- "You don't have an open-next.config.ts file. Using default configuration." ,
107
- ) ;
114
+ logger . debug ( "Cannot find open-next.config.ts. Using default config." ) ;
108
115
fs . writeFileSync (
109
- path . join ( tempDir , "open-next.config.mjs" ) ,
110
- `var config = {
111
- default: {
112
- },
113
- };
114
- var open_next_config_default = config;
115
- export {
116
- open_next_config_default as default
117
- };
118
- ` ,
116
+ outputPath ,
117
+ [
118
+ "var config = { default: { } };" ,
119
+ "var open_next_config_default = config;" ,
120
+ "export { open_next_config_default as default };" ,
121
+ ] . join ( "\n" ) ,
119
122
) ;
120
123
} else {
121
124
buildSync ( {
122
- entryPoints : [ pathToOpenNextConfig ] ,
123
- outfile : path . join ( tempDir , "open-next.config.mjs" ) ,
125
+ entryPoints : [ sourcePath ] ,
126
+ outfile : outputPath ,
124
127
bundle : true ,
125
128
format : "esm" ,
126
129
target : [ "node18" ] ,
127
130
} ) ;
128
131
}
132
+
133
+ return outputPath ;
129
134
}
130
135
131
136
function checkRunningInsideNextjsApp ( ) {
@@ -176,7 +181,7 @@ function setStandaloneBuildMode(monorepoRoot: string) {
176
181
function buildNextjsApp ( packager : "npm" | "yarn" | "pnpm" | "bun" ) {
177
182
const { nextPackageJsonPath } = options ;
178
183
const command =
179
- options . buildCommand ??
184
+ config . buildCommand ??
180
185
( [ "bun" , "npm" ] . includes ( packager )
181
186
? `${ packager } run build`
182
187
: `${ packager } build` ) ;
@@ -430,10 +435,9 @@ function createStaticAssets() {
430
435
}
431
436
}
432
437
433
- async function createCacheAssets (
434
- monorepoRoot : string ,
435
- disableDynamoDBCache = false ,
436
- ) {
438
+ async function createCacheAssets ( monorepoRoot : string ) {
439
+ if ( config . dangerous ?. disableIncrementalCache ) return ;
440
+
437
441
logger . info ( `Bundling cache assets...` ) ;
438
442
439
443
const { appBuildOutputPath, outputDir } = options ;
@@ -527,7 +531,7 @@ async function createCacheAssets(
527
531
fs . writeFileSync ( cacheFilePath , JSON . stringify ( cacheFileContent ) ) ;
528
532
} ) ;
529
533
530
- if ( ! disableDynamoDBCache ) {
534
+ if ( ! config . dangerous ?. disableTagCache ) {
531
535
// Generate dynamodb data
532
536
// We need to traverse the cache to find every .meta file
533
537
const metaFiles : {
@@ -635,9 +639,8 @@ async function createCacheAssets(
635
639
/* Server Helper Functions */
636
640
/***************************/
637
641
638
- function compileCache ( options : BuildOptions ) {
642
+ function compileCache ( ) {
639
643
const outfile = path . join ( options . outputDir , ".build" , "cache.cjs" ) ;
640
- const dangerousOptions = options . dangerous ;
641
644
esbuildSync (
642
645
{
643
646
external : [ "next" , "styled-jsx" , "react" , "@aws-sdk/*" ] ,
@@ -648,10 +651,10 @@ function compileCache(options: BuildOptions) {
648
651
banner : {
649
652
js : [
650
653
`globalThis.disableIncrementalCache = ${
651
- dangerousOptions ?. disableIncrementalCache ?? false
654
+ config . dangerous ?. disableIncrementalCache ?? false
652
655
} ;`,
653
656
`globalThis.disableDynamoDBCache = ${
654
- dangerousOptions ?. disableTagCache ?? false
657
+ config . dangerous ?. disableTagCache ?? false
655
658
} ;`,
656
659
] . join ( "" ) ,
657
660
} ,
@@ -661,10 +664,10 @@ function compileCache(options: BuildOptions) {
661
664
return outfile ;
662
665
}
663
666
664
- async function createMiddleware ( config : OpenNextConfig ) {
667
+ async function createMiddleware ( ) {
665
668
console . info ( `Bundling middleware function...` ) ;
666
669
667
- const { appBuildOutputPath, outputDir, externalMiddleware } = options ;
670
+ const { appBuildOutputPath, outputDir } = options ;
668
671
669
672
// Get middleware manifest
670
673
const middlewareManifest = JSON . parse (
@@ -688,7 +691,7 @@ async function createMiddleware(config: OpenNextConfig) {
688
691
appBuildOutputPath,
689
692
} ;
690
693
691
- if ( externalMiddleware ) {
694
+ if ( config . middleware ?. external ) {
692
695
outputPath = path . join ( outputDir , "middleware" ) ;
693
696
fs . mkdirSync ( outputPath , { recursive : true } ) ;
694
697
0 commit comments