fix(build): apply default server externals#2257
Conversation
|
/bigbonk review for issues |
commit: |
|
There was a problem hiding this comment.
Review: fix(build): apply default server externals
I verified this against the authoritative Next.js source and the package list matches exactly. Solid PR. A few notes below — none are blocking, one is worth a second look.
Verified correct against Next.js
-
Package list parity. The 79-entry
DEFAULT_SERVER_EXTERNAL_PACKAGESinserver-external-packages.tsis byte-for-byte identical tonext/dist/lib/server-external-packages.jsoncin the installed Next.js (16.2.7). I diffed both sets programmatically — zero entries differ. (Minor: the header comment says "Next.js 16.2.6" while the repo ships 16.2.7; the lists are identical, but you may want to bump the comment to avoid confusion.) -
Conflict semantics match Next.js.
next/dist/build/webpack-config.js:667-678throwsThe packages specified in the 'transpilePackages' conflict with the 'serverExternalPackages': ...only for the intersection of user-explicitserverExternalPackagesandtranspilePackages.mergeServerExternalPackagesreproduces this exactly (userPackages.filter(name => transpiled.has(name))), including the error message string. -
Merge/override semantics match Next.js.
webpack-config.js:681computesEXTERNAL_PACKAGES.concat(serverExternalPackages).filter(pkg => !transpilePackages.includes(pkg)). The PR filters transpiled only out of the defaults, relying on the conflict check to guarantee no user package overlaps transpiled — functionally equivalent, andtypescriptstaying external is the intended fix for the twoslash 500s.
Worth a second look
- Client dep-optimizer exclude now spans all 79 packages (
index.ts:2434-2438). Previously thisoptimizeDeps.excludeonly received the (usually empty) userserverExternalPackages; it now receives the full default set. The comment there only motivates server-only conditional-export packages (file-type-style). The default list includes packages that can legitimately be imported from client components in some apps (e.g.shiki,autoprefixer,postcss). Excluding them from the client optimizer means they get resolved lazily rather than prebundled, which at worst causes a late re-optimization + full reload on first client use rather than a hard failure. This matches Next.js'soptOutBundlingPackagestreatment, so it's defensible — but it's a wider behavioral change than the PR description implies, and the inline comment no longer fully explains why the entire default set is excluded. Consider a one-line comment update noting these are the Next.js default server externals.
Minor / non-blocking
index.ts:2043now mergesconfig.ssr.externalinto the top-levelviteConfig.ssr.externalarray alongsidenextServerExternal. This is a genuine improvement (userssr.externalwas previously dropped on the Pages-Router/single-build path), and duplicates with the default list are harmless since Vite dedupes external matching. Just calling it out as an in-scope behavioral change not mentioned in the summary.
Testing
- Ran
tests/server-external-packages.test.ts+tests/next-config.test.ts(205 passed) and a scopedtsc --noEmiton the package (clean). - The new
app-router-production-build.test.tscase is a strong end-to-end check — it builds, assertstypescriptis invinext-externals.json, and exercises the TS language service through a real production route handler for both default and ESNext lib configs. Good port of Next.js'stest/e2e/twoslash.
Overall: behavior matches Next.js, tests are well-targeted, and the fix is sound. The only thing I'd action is tightening the comments around the widened client-optimizer exclusion and the 16.2.6/16.2.7 version note.
|
Review posted to PR #2257. SummaryI reviewed the PR by verifying it against the authoritative Next.js source ( Verified correct:
Flagged for a second look (non-blocking):
No correctness issues found. The fix is sound and well-tested, including a strong end-to-end production-build test that exercises the TypeScript language service through a real route handler. |
Performance benchmarksCompared 1 improved · 0 regressed · 5 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
…fault-server-externals # Conflicts: # tests/build-optimization.test.ts
Summary
transpilePackagesand reject conflicting explicit external/transpile configurationNext.js parity
Targets both
twoslashHTTP 500 failures in the latest deploy-suite report. Bundling TypeScript detached it from itslib.*.d.tsfiles; externalizing the Next.js default package set restores twoslash hover evaluation.This independently reproduced implementation overlaps open PR #2115.
Validation
vp checkFull suites are deferred to CI.