Turbopack: enable export mangling by default in production builds (#97676)
Stacked on #97672 — enable export mangling by default on canary
releases.
### What?
Two defaults change:
- **Next.js builds.** `experimental.turbopackMangleExportNames` is
pinned to `false` for stable
releases and left *unset* on canary, where Turbopack then defaults it
from the build mode: on for
production builds, off in development. Explicitly setting the option
wins in either direction, so
setting it to `true` in development is honoured.
- **Turbopack's own execution test suite.**
`TestOptions::mangle_export_names` defaults to `true`,
so all 279 fixtures exercise mangling instead of only the handful that
opt in.
### Why?
The feature is verified by turbopack's own fixtures, targeted e2e
suites, and a couple of
bundle-size measurements — a narrow slice of what Next.js's test suites
actually cover. Defaulting
it on for canary puts every production-mode e2e and integration test
through the mangled code path
for real users of the canary channel, without committing stable users to
it yet. Turning it on for
stable is a separate, later decision that can stack on top of this once
canary has soaked it.
Broad exposure has already earned its keep several times over. Turning
mangling on in CI and in the
fixture suite surfaced bugs that no hand-picked suite had found,
including a module-fragments helper
handing out another module's exports value (#97672's
`EcmascriptExports::borrowed()`), a
client-reference proxy memoized per wrapper instance rather than per
content, and a
code-elimination bug for export-less modules (fixed in the follow-up
PR).
### How?
`defaultConfig` cannot see the build mode, so it only expresses the
stable/canary split
(`isStableBuild() ? false : undefined`) and
`NextConfig::turbopack_mangle_export_names(mode)`
supplies the mode-dependent default on the Turbopack side. This is
deliberately *not* the shape of
the neighbouring `turbopackSharedRuntime: !isStableBuild()`: mangling
should not apply in
development, and hard-forcing `false` there in Rust — as an earlier
revision of this PR did — would
silently ignore a user who asked for it explicitly.
Mangling does **not** depend on minification. An earlier version of this
PR gated it on
`minify(mode)`, which was wrong and has been removed; `--no-mangling` is
a minifier flag and does
not affect export mangling.
Verified with a real `next build` A/B on a small app: the option left
unset mangles (959,174 B total
emitted JS, 293,407 B gzipped) while explicitly setting it to `false`
does not (966,519 B / 294,963
B gzipped), confirming both the default and the override. All 279
execution fixtures pass with the
suite default flipped, with no fixture needing an opt-out.
Note this layer does not change the `turbopack-emit-collect` snapshots
on its own: making a module
without re-exports split additionally requires the split trigger added
in the follow-up PR, so those
snapshots move there.
This is the layer to revert if canary turns up problems specific to
running with the option on by
default; #97672 remains useful as an opt-in feature either way.
<!-- NEXT_JS_LLM -->
Co-authored-by: Luke Sandberg
<210140+lukesandberg@users.noreply.github.com>
<!-- fleet ecdfa248-cd54-41ac-b4a2-c9d49e2a67ee -->
---------
Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Co-authored-by: Luke Sandberg <210140+lukesandberg@users.noreply.github.com>