Repository: vercel/next.js
Pull request: Turbopack build: Switch to using workerthreads for process

## What?

Switches the worker booted to run Turbopack build (for fast memory cleanup when this step is done) to using worker threads instead of child process.

Closes PACK-5672

Changed files:
filename: packages/next/src/build/turbopack-build/impl.ts
patch: @@ -210,7 +210,9 @@ export async function turbopackBuild(): Promise<{
 let shutdownPromise: Promise<void> | undefined
 export async function workerMain(workerData: {
   buildContext: typeof NextBuildContext
-}): Promise<Awaited<ReturnType<typeof turbopackBuild>>> {
+}): Promise<
+  Omit<Awaited<ReturnType<typeof turbopackBuild>>, 'shutdownPromise'>
+> {
   // setup new build context from the serialized data passed from the parent
   Object.assign(NextBuildContext, workerData.buildContext)
 
@@ -234,9 +236,16 @@ export async function workerMain(workerData: {
   })
   setGlobal('telemetry', telemetry)
 
-  const result = await turbopackBuild()
-  shutdownPromise = result.shutdownPromise
-  return result
+  const {
+    shutdownPromise: resultShutdownPromise,
+    buildTraceContext,
+    duration,
+  } = await turbopackBuild()
+  shutdownPromise = resultShutdownPromise
+  return {
+    buildTraceContext,
+    duration,
+  }
 }
 
 export async function waitForShutdown(): Promise<void> {

filename: packages/next/src/build/turbopack-build/index.ts
patch: @@ -3,10 +3,13 @@ import path from 'path'
 import { Worker } from '../../lib/worker'
 import { NextBuildContext } from '../build-context'
 
-async function turbopackBuildWithWorker() {
+async function turbopackBuildWithWorker(): ReturnType<
+  typeof import('./impl').turbopackBuild
+> {
   try {
     const worker = new Worker(path.join(__dirname, 'impl.js'), {
       exposedMethods: ['workerMain', 'waitForShutdown'],
+      enableWorkerThreads: true,
       debuggerPortOffset: -1,
       isolatedMemory: false,
       numWorkers: 1,
@@ -17,18 +20,25 @@ async function turbopackBuildWithWorker() {
         },
       },
     }) as Worker & typeof import('./impl')
-    const { nextBuildSpan, ...prunedBuildContext } = NextBuildContext
-    const result = await worker.workerMain({
+    const {
+      nextBuildSpan,
+      // Config is not serializable and is loaded in the worker.
+      config: _config,
+      ...prunedBuildContext
+    } = NextBuildContext
+    const { buildTraceContext, duration } = await worker.workerMain({
       buildContext: prunedBuildContext,
     })
 
-    // destroy worker when Turbopack has shutdown so it's not sticking around using memory
-    // We need to wait for shutdown to make sure filesystem cache is flushed
-    result.shutdownPromise = worker.waitForShutdown().then(() => {
-      worker.end()
-    })
-
-    return result
+    return {
+      // destroy worker when Turbopack has shutdown so it's not sticking around using memory
+      // We need to wait for shutdown to make sure filesystem cache is flushed
+      shutdownPromise: worker.waitForShutdown().then(() => {
+        worker.end()
+      }),
+      buildTraceContext,
+      duration,
+    }
   } catch (err: any) {
     // When the error is a serialized `Error` object we need to recreate the `Error` instance
     // in order to keep the consistent error reporting behavior.