feat!: ship dual ESM/CJS builds and require Node 20.9+ - #273
Closed
Walkeezy wants to merge 1 commit into
Closed
Conversation
Walkeezy
force-pushed
the
feat/dual-esm-cjs-exports
branch
from
August 5, 2026 09:21
babe285 to
301ab6f
Compare
Ship dual ESM and CommonJS builds for every public entry point (`.`, `/http`, `/datocms`, `/next`), verified against a packed tarball and by real Next builds on both bundlers. The `/next` subpath keeps bare `next/*` specifiers. The fully-specified `next/headers.js` form resolves under Node and webpack but makes Turbopack miss its react-server aliases, so `next build` fails with MODULE_UNPARSABLE on app-router-context. BREAKING CHANGE: engines.node is now >=20.9.0 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Walkeezy
force-pushed
the
feat/dual-esm-cjs-exports
branch
from
August 5, 2026 09:35
301ab6f to
816cbc0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ships dual ESM/CJS builds for every public entry point (
.,/http,/datocms,/next) and raises the Node floor.BREAKING:
engines.nodeis now>=20.9.0. Node 18 has been EOL since April 2025, and 20.9 matches Next 16's own floor — which also removes the need to test against two differentnextmajors per Node version.The
/nextsubpath keeps barenext/*specifiersAn earlier revision of this branch rewrote
next/headers→next/headers.js, somoduleResolution: nodenextcould resolve them without apathshack. That breaksnext buildunder Turbopack, the default bundler in Next 16:Turbopack does not apply its
react-serveraliases to fully-specifiednext/*.jsrequests, so server-layer code pulls the clientnavigationmodule. webpack does alias the.jsform (create-compiler-aliases.js), which is why this looked fine locally.'next/headers.js''next/headers'Neither form is universally correct, but
/nextis bundler-only by nature —cookies()/draftMode()only work inside a Next request context — so bare specifiers win. Thepathstype-check mapping is restored intsconfig.jsonwith a comment explaining why not to "fix" it again.Verification
scripts/verify-packed-package.mjs— packs the tarball, then asserts ESM / CJS /createRequireresolution and type-checks consumers undernodenext,nodenext+CJS, andnode10. New--layout-onlyflag runs the offline subset.scripts/verify-next-build.mjs(new) — builds a real Next app (Server Component + three route handlers, coveringnext/headers,next/navigation,next/serverin the server-only layer) against the packed tarball on both bundlers, type-checked undermoduleResolution: bundlerlike real apps use. Verified it actually fails when the.jsform is reintroduced.CI gains
package-smoke(Node 20.9.0, 22) andnext-build(next 15 + 16, each on Turbopack and webpack), plus a stableCIgate job — the matrix job names embed matrix values, so requiring them directly would break branch protection on every version bump.release.ymlnow runsverify:release, which omits the registry-dependent smokes so a registry blip cannot fail a publish. It still builds and asserts the published layout offline.Before merging
Require the
CIstatus check onmain. It currently requires none, andverify:releaseis justified by PR CI having gated the same commit:Expect a 2.0.0 release from the
BREAKING CHANGEfooter.