Skip to content

Commit

Permalink
fix(export): make static export work with worker_threads (#47784)
Browse files Browse the repository at this point in the history
Fixes #46993.

The issue is introduced in #46705 by @ijjk 

Next.js uses `jest-worker` for multiprocessing. `jest-worker` supports both `child_process` and `worker_threads` modes. Next.js use `child_process` mode by default, but can also switch to using `worker_threads` mode with an experimental flag `config.experimental.workerThreads`.

In #46705, @ijjk applies a fix that works for the `child_process` mode, which breaks the `worker_threads` mode (`jest-worker`'s `NodeThreadWorker` interface doesn't have the private property `_child`), causing static HTML export to fail with the following error (#46993):

```
> Build error occurred
TypeError: Cannot read properties of undefined (reading 'on')
    at createWorker (/Users/[redacted]/node_modules/next/dist/lib/worker.js:32:31)
    at new Worker (/Users/[redacted]/node_modules/next/dist/lib/worker.js:42:9)
    at /Users/[redacted]/node_modules/next/dist/build/index.js:629:35
    at async Span.traceAsyncFn (/Users/[redacted]/node_modules/next/dist/trace/trace.js:79:20)
    at async Object.build [as default] (/Users/[redacted]/node_modules/next/dist/build/index.js:74:29)
```

The PR fixes that.
  • Loading branch information
SukkaW committed Apr 1, 2023
1 parent 2abc824 commit b132efc
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions packages/next/src/lib/worker.ts
Expand Up @@ -14,6 +14,7 @@ export class Worker {
timeout?: number
onRestart?: (method: string, args: any[], attempts: number) => void
exposedMethods: ReadonlyArray<string>
enableWorkerThreads?: boolean
}
) {
let { timeout, onRestart, ...farmOptions } = options
Expand Down Expand Up @@ -44,18 +45,29 @@ export class Worker {
(resolve) => (resolveRestartPromise = resolve)
)

for (const worker of ((this._worker as any)._workerPool?._workers ||
[]) as {
_child: ChildProcess
}[]) {
worker._child.on('exit', (code, signal) => {
// log unexpected exit if .end() wasn't called
if ((code || signal) && this._worker) {
console.error(
`Static worker unexpectedly exited with code: ${code} and signal: ${signal}`
)
}
})
/**
* Jest Worker has two worker types, ChildProcessWorker (uses child_process) and NodeThreadWorker (uses worker_threads)
* Next.js uses ChildProcessWorker by default, but it can be switched to NodeThreadWorker with an experimental flag
*
* We only want to handle ChildProcessWorker's orphan process issue, so we access the private property "_child":
* https://github.com/facebook/jest/blob/b38d7d345a81d97d1dc3b68b8458b1837fbf19be/packages/jest-worker/src/workers/ChildProcessWorker.ts
*
* But this property is not available in NodeThreadWorker, so we need to check if we are using ChildProcessWorker
*/
if (!farmOptions.enableWorkerThreads) {
for (const worker of ((this._worker as any)._workerPool?._workers ||
[]) as {
_child?: ChildProcess
}[]) {
worker._child?.on('exit', (code, signal) => {
// log unexpected exit if .end() wasn't called
if ((code || signal) && this._worker) {
console.error(
`Static worker unexpectedly exited with code: ${code} and signal: ${signal}`
)
}
})
}
}

this._worker.getStdout().pipe(process.stdout)
Expand Down

0 comments on commit b132efc

Please sign in to comment.