11import fs from "node:fs" ;
2+ import os from "node:os" ;
23import path from "node:path" ;
34
45import { buildSync } from "esbuild" ;
56import { OpenNextConfig } from "types/open-next.js" ;
67
78import logger from "../logger.js" ;
9+ import { validateConfig } from "./validateConfig.js" ;
810
9- export function compileOpenNextConfigNode (
10- outputDir : string ,
11+ /**
12+ * Compiles the OpenNext configuration.
13+ *
14+ * The configuration is always compiled for Node.js and for the edge only if needed.
15+ *
16+ * @param baseDir Directory where to look for the configuration.
17+ * @param openNextConfigPath Override the default configuration when provided. Relative to baseDir.
18+ * @param nodeExternals Externals for the Node.js compilation.
19+ * @return The configuration and the build directory.
20+ */
21+ export async function compileOpenNextConfig (
22+ baseDir : string ,
1123 openNextConfigPath ?: string ,
1224 nodeExternals ?: string ,
1325) {
1426 const sourcePath = path . join (
15- process . cwd ( ) ,
27+ baseDir ,
1628 openNextConfigPath ?? "open-next.config.ts" ,
1729 ) ;
30+
31+ const buildDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "open-next-tmp" ) ) ;
32+ let configPath = compileOpenNextConfigNode (
33+ sourcePath ,
34+ buildDir ,
35+ nodeExternals ? nodeExternals . split ( "," ) : [ ] ,
36+ ) ;
37+
38+ // On Windows, we need to use file:// protocol to load the config file using import()
39+ if ( process . platform === "win32" ) configPath = `file://${ configPath } ` ;
40+ const config = ( await import ( configPath ) ) . default as OpenNextConfig ;
41+ if ( ! config || ! config . default ) {
42+ logger . error (
43+ `config.default cannot be empty, it should be at least {}, see more info here: https://open-next.js.org/config#configuration-file` ,
44+ ) ;
45+ process . exit ( 1 ) ;
46+ }
47+
48+ validateConfig ( config ) ;
49+
50+ // We need to check if the config uses the edge runtime at any point
51+ // If it does, we need to compile it with the edge runtime
52+ const usesEdgeRuntime =
53+ config . middleware ?. external ||
54+ Object . values ( config . functions || { } ) . some ( ( fn ) => fn . runtime === "edge" ) ;
55+ if ( ! usesEdgeRuntime ) {
56+ logger . debug (
57+ "No edge runtime found in the open-next.config.ts. Using default config." ,
58+ ) ;
59+ //Nothing to do here
60+ } else {
61+ compileOpenNextConfigEdge ( sourcePath , buildDir , config . edgeExternals ?? [ ] ) ;
62+ }
63+
64+ return { config, buildDir } ;
65+ }
66+
67+ export function compileOpenNextConfigNode (
68+ sourcePath : string ,
69+ outputDir : string ,
70+ externals : string [ ] ,
71+ ) {
1872 const outputPath = path . join ( outputDir , "open-next.config.mjs" ) ;
1973
2074 //Check if open-next.config.ts exists
@@ -29,7 +83,7 @@ export function compileOpenNextConfigNode(
2983 bundle : true ,
3084 format : "esm" ,
3185 target : [ "node18" ] ,
32- external : nodeExternals ? nodeExternals . split ( "," ) : [ ] ,
86+ external : externals ,
3387 platform : "node" ,
3488 banner : {
3589 js : [
@@ -46,38 +100,22 @@ export function compileOpenNextConfigNode(
46100}
47101
48102export function compileOpenNextConfigEdge (
49- tempDir : string ,
50- config : OpenNextConfig ,
51- openNextConfigPath ? : string ,
103+ sourcePath : string ,
104+ outputDir : string ,
105+ externals : string [ ] ,
52106) {
53- const sourcePath = path . join (
54- process . cwd ( ) ,
55- openNextConfigPath ?? "open-next.config.ts" ,
56- ) ;
57- const outputPath = path . join ( tempDir , "open-next.config.edge.mjs" ) ;
107+ const outputPath = path . join ( outputDir , "open-next.config.edge.mjs" ) ;
58108
59- // We need to check if the config uses the edge runtime at any point
60- // If it does, we need to compile it with the edge runtime
61- const usesEdgeRuntime =
62- config . middleware ?. external ||
63- Object . values ( config . functions || { } ) . some ( ( fn ) => fn . runtime === "edge" ) ;
64- if ( ! usesEdgeRuntime ) {
65- logger . debug (
66- "No edge runtime found in the open-next.config.ts. Using default config." ,
67- ) ;
68- //Nothing to do here
69- } else {
70- logger . info ( "Compiling open-next.config.ts for edge runtime." , outputPath ) ;
71- buildSync ( {
72- entryPoints : [ sourcePath ] ,
73- outfile : outputPath ,
74- bundle : true ,
75- format : "esm" ,
76- target : [ "es2020" ] ,
77- conditions : [ "worker" , "browser" ] ,
78- platform : "browser" ,
79- external : config . edgeExternals ?? [ ] ,
80- } ) ;
81- logger . info ( "Compiled open-next.config.ts for edge runtime." ) ;
82- }
109+ logger . info ( "Compiling open-next.config.ts for edge runtime." , outputPath ) ;
110+ buildSync ( {
111+ entryPoints : [ sourcePath ] ,
112+ outfile : outputPath ,
113+ bundle : true ,
114+ format : "esm" ,
115+ target : [ "es2020" ] ,
116+ conditions : [ "worker" , "browser" ] ,
117+ platform : "browser" ,
118+ external : externals ,
119+ } ) ;
120+ logger . info ( "Compiled open-next.config.ts for edge runtime." ) ;
83121}
0 commit comments