@@ -4,11 +4,10 @@ import path from "node:path";
44import { fileURLToPath } from "node:url" ;
55
66import { Lang , parse } from "@ast-grep/napi" ;
7- import type { BuildOptions } from "@opennextjs/aws/build/helper.js" ;
7+ import { type BuildOptions , getPackagePath } from "@opennextjs/aws/build/helper.js" ;
88import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js" ;
99import { build , Plugin } from "esbuild" ;
1010
11- import { Config } from "../config.js" ;
1211import { patchOptionalDependencies } from "./patches/ast/optional-deps.js" ;
1312import * as patches from "./patches/index.js" ;
1413import { normalizePath , patchCodeWithValidations } from "./utils/index.js" ;
@@ -19,22 +18,25 @@ const packageDistDir = path.join(path.dirname(fileURLToPath(import.meta.url)), "
1918/**
2019 * Bundle the Open Next server.
2120 */
22- export async function bundleServer ( config : Config , openNextOptions : BuildOptions ) : Promise < void > {
23- patches . copyPackageCliFiles ( packageDistDir , config , openNextOptions ) ;
24-
25- const nextConfigStr =
26- fs
27- . readFileSync ( path . join ( config . paths . output . standaloneApp , "server.js" ) , "utf8" )
28- ?. match ( / c o n s t n e x t C o n f i g = ( { .+ ?} ) \n / ) ?. [ 1 ] ?? { } ;
21+ export async function bundleServer ( buildOpts : BuildOptions ) : Promise < void > {
22+ patches . copyPackageCliFiles ( packageDistDir , buildOpts ) ;
23+
24+ const { appPath, outputDir, monorepoRoot } = buildOpts ;
25+ const serverFiles = path . join (
26+ outputDir ,
27+ "server-functions/default" ,
28+ getPackagePath ( buildOpts ) ,
29+ ".next/required-server-files.json"
30+ ) ;
31+ const nextConfig = JSON . parse ( fs . readFileSync ( serverFiles , "utf-8" ) ) . config ;
2932
3033 console . log ( `\x1b[35m⚙️ Bundling the OpenNext server...\n\x1b[0m` ) ;
3134
32- patches . patchWranglerDeps ( config ) ;
33- patches . updateWebpackChunksFile ( config ) ;
35+ patches . patchWranglerDeps ( buildOpts ) ;
36+ patches . updateWebpackChunksFile ( buildOpts ) ;
3437
35- const { appBuildOutputPath, appPath, outputDir, monorepoRoot } = openNextOptions ;
3638 const outputPath = path . join ( outputDir , "server-functions" , "default" ) ;
37- const packagePath = path . relative ( monorepoRoot , appBuildOutputPath ) ;
39+ const packagePath = getPackagePath ( buildOpts ) ;
3840 const openNextServer = path . join ( outputPath , packagePath , `index.mjs` ) ;
3941 const openNextServerBundle = path . join ( outputPath , packagePath , `handler.mjs` ) ;
4042
@@ -45,25 +47,28 @@ export async function bundleServer(config: Config, openNextOptions: BuildOptions
4547 format : "esm" ,
4648 target : "esnext" ,
4749 minify : false ,
48- plugins : [ createFixRequiresESBuildPlugin ( config ) ] ,
50+ plugins : [ createFixRequiresESBuildPlugin ( buildOpts ) ] ,
4951 external : [ "./middleware/handler.mjs" , "caniuse-lite" ] ,
5052 alias : {
5153 // Note: we apply an empty shim to next/dist/compiled/ws because it generates two `eval`s:
5254 // eval("require")("bufferutil");
5355 // eval("require")("utf-8-validate");
54- "next/dist/compiled/ws" : path . join ( config . paths . internal . templates , "shims" , " empty.js") ,
56+ "next/dist/compiled/ws" : path . join ( buildOpts . outputDir , "cloudflare-templates/ shims/ empty.js" ) ,
5557 // Note: we apply an empty shim to next/dist/compiled/edge-runtime since (amongst others) it generated the following `eval`:
5658 // eval(getModuleCode)(module, module.exports, throwingRequire, params.context, ...Object.values(params.scopedContext));
5759 // which comes from https://github.com/vercel/edge-runtime/blob/6e96b55f/packages/primitives/src/primitives/load.js#L57-L63
5860 // QUESTION: Why did I encountered this but mhart didn't?
59- "next/dist/compiled/edge-runtime" : path . join ( config . paths . internal . templates , "shims" , "empty.js" ) ,
61+ "next/dist/compiled/edge-runtime" : path . join (
62+ buildOpts . outputDir ,
63+ "cloudflare-templates/shims/empty.js"
64+ ) ,
6065 // `@next/env` is a library Next.js uses for loading dotenv files, for obvious reasons we need to stub it here
6166 // source: https://github.com/vercel/next.js/tree/0ac10d79720/packages/next-env
62- "@next/env" : path . join ( config . paths . internal . templates , "shims" , " env.js") ,
67+ "@next/env" : path . join ( buildOpts . outputDir , "cloudflare-templates/ shims/ env.js" ) ,
6368 } ,
6469 define : {
6570 // config file used by Next.js, see: https://github.com/vercel/next.js/blob/68a7128/packages/next/src/build/utils.ts#L2137-L2139
66- "process.env.__NEXT_PRIVATE_STANDALONE_CONFIG" : JSON . stringify ( nextConfigStr ) ,
71+ "process.env.__NEXT_PRIVATE_STANDALONE_CONFIG" : ` ${ JSON . stringify ( nextConfig ) } ` ,
6772 // Next.js tried to access __dirname so we need to define it
6873 __dirname : '""' ,
6974 // Note: we need the __non_webpack_require__ variable declared as it is used by next-server:
@@ -117,7 +122,7 @@ globalThis.__BUILD_TIMESTAMP_MS__ = ${Date.now()};
117122 } ,
118123 } ) ;
119124
120- await updateWorkerBundledCode ( openNextServerBundle , config , openNextOptions ) ;
125+ await updateWorkerBundledCode ( openNextServerBundle , buildOpts ) ;
121126
122127 const isMonorepo = monorepoRoot !== appPath ;
123128 if ( isMonorepo ) {
@@ -127,35 +132,26 @@ globalThis.__BUILD_TIMESTAMP_MS__ = ${Date.now()};
127132 ) ;
128133 }
129134
130- console . log ( `\x1b[35mWorker saved in \`${ getOutputWorkerPath ( openNextOptions ) } \` 🚀\n\x1b[0m` ) ;
135+ console . log ( `\x1b[35mWorker saved in \`${ getOutputWorkerPath ( buildOpts ) } \` 🚀\n\x1b[0m` ) ;
131136}
132137
133138/**
134- * This function applies string replacements on the bundled worker code necessary to get it to run in workerd
135- *
136- * Needless to say all the logic in this function is something we should avoid as much as possible!
137- *
138- * @param workerOutputFile
139- * @param config
139+ * This function applies patches required for the code to run on workers.
140140 */
141- async function updateWorkerBundledCode (
142- workerOutputFile : string ,
143- config : Config ,
144- openNextOptions : BuildOptions
145- ) : Promise < void > {
141+ async function updateWorkerBundledCode ( workerOutputFile : string , buildOpts : BuildOptions ) : Promise < void > {
146142 const code = await readFile ( workerOutputFile , "utf8" ) ;
147143
148144 const patchedCode = await patchCodeWithValidations ( code , [
149145 [ "require" , patches . patchRequire ] ,
150- [ "`buildId` function" , ( code ) => patches . patchBuildId ( code , config ) ] ,
151- [ "`loadManifest` function" , ( code ) => patches . patchLoadManifest ( code , config ) ] ,
152- [ "next's require" , ( code ) => patches . inlineNextRequire ( code , config ) ] ,
153- [ "`findDir` function" , ( code ) => patches . patchFindDir ( code , config ) ] ,
154- [ "`evalManifest` function" , ( code ) => patches . inlineEvalManifest ( code , config ) ] ,
155- [ "cacheHandler" , ( code ) => patches . patchCache ( code , openNextOptions ) ] ,
146+ [ "`buildId` function" , ( code ) => patches . patchBuildId ( code , buildOpts ) ] ,
147+ [ "`loadManifest` function" , ( code ) => patches . patchLoadManifest ( code , buildOpts ) ] ,
148+ [ "next's require" , ( code ) => patches . inlineNextRequire ( code , buildOpts ) ] ,
149+ [ "`findDir` function" , ( code ) => patches . patchFindDir ( code , buildOpts ) ] ,
150+ [ "`evalManifest` function" , ( code ) => patches . inlineEvalManifest ( code , buildOpts ) ] ,
151+ [ "cacheHandler" , ( code ) => patches . patchCache ( code , buildOpts ) ] ,
156152 [
157153 "'require(this.middlewareManifestPath)'" ,
158- ( code ) => patches . inlineMiddlewareManifestRequire ( code , config ) ,
154+ ( code ) => patches . inlineMiddlewareManifestRequire ( code , buildOpts ) ,
159155 ] ,
160156 [ "exception bubbling" , patches . patchExceptionBubbling ] ,
161157 [ "`loadInstrumentationModule` function" , patches . patchLoadInstrumentationModule ] ,
@@ -185,15 +181,15 @@ async function updateWorkerBundledCode(
185181 await writeFile ( workerOutputFile , bundle . commitEdits ( edits ) ) ;
186182}
187183
188- function createFixRequiresESBuildPlugin ( config : Config ) : Plugin {
184+ function createFixRequiresESBuildPlugin ( options : BuildOptions ) : Plugin {
189185 return {
190186 name : "replaceRelative" ,
191187 setup ( build ) {
192188 // Note: we (empty) shim require-hook modules as they generate problematic code that uses requires
193189 build . onResolve (
194190 { filter : getCrossPlatformPathRegex ( String . raw `^\./require-hook$` , { escape : false } ) } ,
195191 ( ) => ( {
196- path : path . join ( config . paths . internal . templates , "shims" , " empty.js") ,
192+ path : path . join ( options . outputDir , "cloudflare-templates/ shims/ empty.js" ) ,
197193 } )
198194 ) ;
199195 } ,
@@ -203,9 +199,9 @@ function createFixRequiresESBuildPlugin(config: Config): Plugin {
203199/**
204200 * Gets the path of the worker.js file generated by the build process
205201 *
206- * @param openNextOptions the open-next build options
202+ * @param buildOpts the open-next build options
207203 * @returns the path of the worker.js file that the build process generates
208204 */
209- export function getOutputWorkerPath ( openNextOptions : BuildOptions ) : string {
210- return path . join ( openNextOptions . outputDir , "worker.js" ) ;
205+ export function getOutputWorkerPath ( buildOpts : BuildOptions ) : string {
206+ return path . join ( buildOpts . outputDir , "worker.js" ) ;
211207}
0 commit comments