Skip to content

build(packages): emit ESM type marker for publish#8

Merged
yyyyaaa merged 1 commit into
mainfrom
build/esm-type-marker
May 14, 2026
Merged

build(packages): emit ESM type marker for publish#8
yyyyaaa merged 1 commit into
mainfrom
build/esm-type-marker

Conversation

@yyyyaaa
Copy link
Copy Markdown
Contributor

@yyyyaaa yyyyaaa commented May 14, 2026

Summary

  • Add scripts/write-esm-package-json.js as a shared postbuild step that writes dist/esm/package.json with {"type":"module"}. Without this marker, bundlers (webpack, esbuild, vite, rollup) and older Node versions parse dist/esm/*.js as CommonJS and error on the export syntax emitted by tsc.
  • Drop "source": "./src/index.ts" from each package's exports map — src/ is not shipped in the published tarball, so this condition pointed at a path that doesn't exist for consumers.

Why this is the minimum needed to publish

The published shape is dual-CJS+ESM (index.js + esm/index.js). Node and bundlers determine how to parse .js files via the closest package.json's "type" field. Without a marker inside dist/esm/, the ESM build inherits the package root's default ("commonjs") and fails wherever syntax detection isn't available.

Verification

Decisive pack-and-import matrix run against @agentic-kit/anthropic (leaf package, no workspace deps):

Scenario Marker Detection Result
1 ✅ Node 22+ default ✅ OK (detection masks the bug)
2 ❌ (--no-experimental-detect-module) FAILERR_REQUIRE_CYCLE_MODULE
3 ✅ OK
4 ✅ OK — marker IS the fix
5 (CJS require) ✅ OK

Test 2 vs Test 4 isolates the marker as the cause: same Node, same tarball shape minus one file, opposite outcomes.

Test plan

  • pnpm clean && pnpm build — all 6 packages emit dist/esm/package.json with {"type":"module"}
  • pnpm test — 99 tests pass across 6 packages
  • Pack + import ESM from a fresh Node process (with and without --experimental-detect-module)
  • Pack + require() from a CJS consumer
  • After merge: lerna publish dry-run sanity check before the first real publish

Out of scope

  • Lint fix for the pre-existing jest.environment.js eslint-disable directive (lives in a separate branch). CI doesn't gate on lint, so this PR is independently mergeable.
  • engines.node floor — keeping the marker means we don't need to commit to a Node version yet.

🤖 Generated with Claude Code

- Add scripts/write-esm-package-json.js to write dist/esm/package.json
  with {"type":"module"} as a postbuild step. Required so bundlers
  (webpack, esbuild, vite, rollup) and older Node parse the ESM build
  as modules rather than CJS.
- Drop "source": "./src/index.ts" from each package's exports map.
  Source files are not shipped in dist/, so this condition pointed at
  nothing in the published tarball.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@yyyyaaa yyyyaaa merged commit 86c30ea into main May 14, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant