Core is moving to an ESM only monorepo (MetaMask/core#9536), so this package
should arrive already converted rather than landing as the sole hybrid one.
BREAKING: the CommonJS build is gone. require('@metamask/utils') now fails
with ERR_REQUIRE_ESM. `main` and `module` are removed, and both `.` and
`./node` resolve through `exports` to a single ./dist/*.js with ./dist/*.d.ts
types. Consumers already using `import` are unaffected.
package.json adds "type": "module", collapses the dual exports map
build ts-bridge -> tsc, since ts-bridge exists to emit both formats
@ts-bridge/cli removed, rimraf added for build:only-clean
tsconfig.build drops emitDeclarationOnly, tsc now emits the JS too
102 relative import specifiers across 45 files gained explicit .js
extensions, which ESM requires. Directories resolve to /index.js. Core's
sources already look like this and enforce it with n/file-extension-in-import,
so the same three import rules are adopted here verbatim.
Two things only surfaced by running the built output rather than the tests:
lodash `import { memoize } from 'lodash'` throws at runtime under ESM,
because Node's lexer cannot see named exports through lodash's CJS.
Switched to `lodash/memoize.js`, a default import of the single
method. Core solved the same problem by moving to lodash-es plus a
jest moduleNameMapper; this needs neither.
scure-bip39 the deep wordlist import needed an explicit .js.
Every other CJS dependency survives named imports untouched: semver,
superstruct, @scure/base, @noble/hashes and pony-cause all have lexer
friendly CJS. Verified by importing all 27 built modules individually.
jest.config.js and .prettierrc.js are renamed to .cjs, since "type": "module"
makes bare .js ESM. Tests still compile to CommonJS through a ts-jest
transform override, matching core, with a moduleNameMapper stripping the .js
specifiers back off. constraints.pro is rewritten for the single entrypoint
shape.
Top of stack #315, on #322.
Core is moving to an ESM only monorepo (MetaMask/core#9536), so this package should arrive already converted rather than landing as the only hybrid one in it.
Breaking
require('@metamask/utils')now fails withERR_REQUIRE_ESM.mainandmoduleare gone, and both.and./noderesolve throughexportsto a single./dist/*.jswith./dist/*.d.tstypes. Consumers already usingimportare unaffected.ts-bridgetsc.cjs+.mjs+.d.cts+.d.mts.js+.d.ts@ts-bridge/clirimrafadded for cleaning)ts-bridgeexists to emit both formats, so it goes with the CJS half.Import specifiers
102 relative specifiers across 45 files gained explicit
.jsextensions, which ESM requires; directories resolve to/index.js. Core's sources already look like this and enforce it withn/file-extension-in-import, so the same three import rules are adopted here verbatim.Two things only the built output revealed
Neither would have been caught by the test suite, because tests run against
src/:lodash—import { memoize } from 'lodash'throws at runtime under ESM: Node's lexer cannot see named exports through lodash's CJS. Switched tolodash/memoize.js, a default import of the single method. Core hit the same wall and solved it withlodash-esplus a jestmoduleNameMapper; this approach needs neither.@metamask/scure-bip39— the deep wordlist import needed an explicit.js.Every other CJS dependency survives named imports untouched.
semver,@metamask/superstruct,@scure/base,@noble/hashesandpony-causeall have lexer friendly CJS. Verified by importing all 27 built modules individually, plus the exports map by bare specifier.Tooling
jest.config.jsand.prettierrc.jsare renamed to.cjs, since"type": "module"makes bare.jsfiles ESM. Tests still compile to CommonJS via a ts-jesttransformoverride (matching core) with amoduleNameMapperstripping the.jsspecifiers back off.constraints.prois rewritten for the single entrypoint shape.Note
High Risk
Breaking module format and entrypoint resolution affects every consumer still on CommonJS
require; lodash and deep-import path changes can break at runtime if missed in downstream bundles.Overview
Breaking: The published package is now ESM-only. CommonJS output and
main/moduleare removed;require('@metamask/utils')fails withERR_REQUIRE_ESM. Entry points.and./noderesolve throughexportsto a single./dist/*.jswith matching./dist/*.d.ts. Consumers already usingimportare unaffected.The build pipeline switches from ts-bridge (dual CJS/ESM) to
tsc, withrimraffor dist cleanup andconstraints.pro/ CHANGELOG updated for the new package shape.Relative imports across src gain explicit
.jsspecifiers (plus ESLintn/file-extension-in-import). Jest keeps running tests as CommonJS via ts-jest overrides and amoduleNameMapperthat strips.jsback to.tssources.Runtime fixes for ESM output:
hex.tsuseslodash/memoize.js(default import) instead of a namedlodashimport, and the BIP-39 wordlist deep import adds.js.Reviewed by Cursor Bugbot for commit a2d5883. Bugbot is set up for automated code reviews on this repo. Configure here.