@@ -3,20 +3,15 @@ import { build, Plugin } from "esbuild";
3
3
import { readdirSync , readFileSync , writeFileSync } from "node:fs" ;
4
4
import { cp , readFile , writeFile } from "node:fs/promises" ;
5
5
6
- import { resolve } from "node:path" ;
7
-
8
6
import { patchRequire } from "./patches/investigated/patchRequire" ;
9
7
import { patchUrl } from "./patches/investigated/patchUrl" ;
8
+ import { copyTemplates } from "./patches/investigated/copyTemplates" ;
10
9
11
10
import { patchReadFile } from "./patches/to-investigate/patchReadFile" ;
12
11
import { patchFindDir } from "./patches/to-investigate/patchFindDir" ;
13
12
import { inlineNextRequire } from "./patches/to-investigate/inlineNextRequire" ;
14
13
import { inlineEvalManifest } from "./patches/to-investigate/inlineEvalManifest" ;
15
14
16
- import * as url from "url" ;
17
-
18
- const __dirname = url . fileURLToPath ( new URL ( "." , import . meta. url ) ) ;
19
-
20
15
/**
21
16
* Using the Next.js build output in the `.next` directory builds a workerd compatible output
22
17
*
@@ -25,11 +20,12 @@ const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
25
20
*/
26
21
export async function buildWorker (
27
22
outputDir : string ,
28
- nextjsAppPaths : NextjsAppPaths
23
+ nextjsAppPaths : NextjsAppPaths ,
24
+ templateSrcDir : string
29
25
) : Promise < void > {
30
- const repoRoot = resolve ( ` ${ __dirname } /../..` ) ;
26
+ const templateDir = copyTemplates ( templateSrcDir , nextjsAppPaths ) ;
31
27
32
- const workerEntrypoint = `${ __dirname } /templates /worker.ts` ;
28
+ const workerEntrypoint = `${ templateDir } /worker.ts` ;
33
29
const workerOutputFile = `${ outputDir } /index.mjs` ;
34
30
const nextConfigStr =
35
31
readFileSync ( nextjsAppPaths . standaloneAppDir + "/server.js" , "utf8" ) ?. match (
@@ -44,27 +40,27 @@ export async function buildWorker(
44
40
format : "esm" ,
45
41
target : "esnext" ,
46
42
minify : false ,
47
- plugins : [ fixRequiresESBuildPlugin ] ,
43
+ plugins : [ createFixRequiresESBuildPlugin ( templateDir ) ] ,
48
44
alias : {
49
45
// Note: we apply an empty shim to next/dist/compiled/ws because it generates two `eval`s:
50
46
// eval("require")("bufferutil");
51
47
// eval("require")("utf-8-validate");
52
- "next/dist/compiled/ws" : `${ __dirname } /templates /shims/empty.ts` ,
48
+ "next/dist/compiled/ws" : `${ templateDir } /shims/empty.ts` ,
53
49
// Note: we apply an empty shim to next/dist/compiled/edge-runtime since (amongst others) it generated the following `eval`:
54
50
// eval(getModuleCode)(module, module.exports, throwingRequire, params.context, ...Object.values(params.scopedContext));
55
51
// which comes from https://github.com/vercel/edge-runtime/blob/6e96b55f/packages/primitives/src/primitives/load.js#L57-L63
56
52
// QUESTION: Why did I encountered this but mhart didn't?
57
- "next/dist/compiled/edge-runtime" : `${ __dirname } /templates /shims/empty.ts` ,
53
+ "next/dist/compiled/edge-runtime" : `${ templateDir } /shims/empty.ts` ,
58
54
// Note: we need to stub out `@opentelemetry/api` as that is problematic and doesn't get properly bundled...
59
- critters : `${ __dirname } /templates /shims/empty.ts` ,
55
+ critters : `${ templateDir } /shims/empty.ts` ,
60
56
// Note: we need to stub out `@opentelemetry/api` as it is problematic
61
57
// IMPORTANT: we shim @opentelemetry /api to the throwing shim so that it will throw right away, this is so that we throw inside the
62
58
// try block here: https://github.com/vercel/next.js/blob/9e8266a7/packages/next/src/server/lib/trace/tracer.ts#L27-L31
63
59
// causing the code to require the 'next/dist/compiled/@opentelemetry/api' module instead (which properly works)
64
- "@opentelemetry/api" : `${ __dirname } /templates /shims/throw.ts` ,
60
+ "@opentelemetry/api" : `${ templateDir } /shims/throw.ts` ,
65
61
// `@next/env` is a library Next.js uses for loading dotenv files, for obvious reasons we need to stub it here
66
62
// source: https://github.com/vercel/next.js/tree/0ac10d79720/packages/next-env
67
- "@next/env" : `${ __dirname } /templates /shims/env.ts` ,
63
+ "@next/env" : `${ templateDir } /shims/env.ts` ,
68
64
} ,
69
65
define : {
70
66
// config file used by Next.js, see: https://github.com/vercel/next.js/blob/68a7128/packages/next/src/build/utils.ts#L2137-L2139
@@ -147,13 +143,19 @@ async function updateWorkerBundledCode(
147
143
* so this shows that not everything that's needed to deploy the application is in the output directory...
148
144
*/
149
145
async function updateWebpackChunksFile ( nextjsAppPaths : NextjsAppPaths ) {
146
+ console . log ( "# updateWebpackChunksFile" ) ;
150
147
const webpackRuntimeFile = `${ nextjsAppPaths . standaloneAppServerDir } /webpack-runtime.js` ;
151
148
149
+ console . log ( { webpackRuntimeFile } ) ;
150
+
152
151
const fileContent = readFileSync ( webpackRuntimeFile , "utf-8" ) ;
153
152
154
153
const chunks = readdirSync ( `${ nextjsAppPaths . standaloneAppServerDir } /chunks` )
155
154
. filter ( ( chunk ) => / ^ \d + \. j s $ / . test ( chunk ) )
156
- . map ( ( chunk ) => chunk . replace ( / \. j s $ / , "" ) ) ;
155
+ . map ( ( chunk ) => {
156
+ console . log ( ` - chunk ${ chunk } ` ) ;
157
+ return chunk . replace ( / \. j s $ / , "" ) ;
158
+ } ) ;
157
159
158
160
const updatedFileContent = fileContent . replace (
159
161
"__webpack_require__.f.require = (chunkId, promises) => {" ,
@@ -175,12 +177,14 @@ async function updateWebpackChunksFile(nextjsAppPaths: NextjsAppPaths) {
175
177
writeFileSync ( webpackRuntimeFile , updatedFileContent ) ;
176
178
}
177
179
178
- const fixRequiresESBuildPlugin : Plugin = {
179
- name : "replaceRelative" ,
180
- setup ( build ) {
181
- // Note: we (empty) shim require-hook modules as they generate problematic code that uses requires
182
- build . onResolve ( { filter : / ^ \. \/ r e q u i r e - h o o k $ / } , ( args ) => ( {
183
- path : `${ __dirname } /templates/shims/empty.ts` ,
184
- } ) ) ;
185
- } ,
180
+ function createFixRequiresESBuildPlugin ( templateDir : string ) : Plugin {
181
+ return {
182
+ name : "replaceRelative" ,
183
+ setup ( build ) {
184
+ // Note: we (empty) shim require-hook modules as they generate problematic code that uses requires
185
+ build . onResolve ( { filter : / ^ \. \/ r e q u i r e - h o o k $ / } , ( args ) => ( {
186
+ path : `${ templateDir } /shims/empty.ts` ,
187
+ } ) ) ;
188
+ } ,
189
+ } ;
186
190
} ;
0 commit comments