Files
Sebastian "Sebbie" Silbermann 55e7e1903a [test] Cover the prerender worker-thread backend with an addon we control (#97543)
`experimental.workerThreads` decides whether static generation runs in
real worker threads or forked child processes, and a native addon
declared with `NODE_MODULE` can only be loaded once per process. That is
why the flag defaults to false (#9199) and why the static export worker
was fixed to respect it rather than hardcoding threads on (#25063).
Nothing tested it: the only suite that tried, `firebase-grpc`, had its
assertion skipped since 2019, and modern `firebase` ships no native
module at all, so its remaining test asserted only that a build
succeeds.

This adds a `single-context-addon` fixture, deliberately declared with
`NODE_MODULE`, and a production suite asserting both directions: the
build succeeds by default and fails with "Module did not self-register"
once worker threads are enabled. The fixture loads the addon from
`next.config.js` as well as from the page, because that failure only
happens on a second `dlopen` within one process, so an addon loaded only
inside the worker would register there and the build would pass.

A third case documents a bug rather than intended behaviour. `next
build` runs Turbopack in a worker thread and that worker re-evaluates
`next.config.js`, so requiring a non-context-aware addon from the config
breaks the build even with `experimental.workerThreads` off. Webpack and
rspack are unaffected, since their build workers are forked child
processes. Isolated with an unguarded `require` and default flags,
Turbopack exits 1 with "Module did not self-register" where webpack
exits 0. It is the same class of failure #9199 and #25063 fixed, in a
worker those PRs did not touch. The assertion is branched on the bundler
and carries a note to drop the branch once Turbopack stops evaluating
the config on a worker thread. The `isMainThread` guard in the fixture's
config keeps the first two cases pointed at the static generation worker
instead.

A development suite covers the other direction, asserting that
evaluating a route does not put such an addon on one of the threads
`next dev` uses regardless of the flag, so it would catch a change that
moved route evaluation onto the dev validation pool. The expectation is
the same with and without Cache Components; both were checked by logging
the thread id from the page's module scope, and the route is evaluated
on the main thread either way.

`firebase-grpc` is removed, since it covered the same flag with a
skipped assertion and a vacuous one.
2026-08-20 11:57:04 +02:00

7 lines
117 B
JSON

{
"dependencies": {
"single-context-addon": "file:single-context-addon",
"bindings": "file:bindings"
}
}