Reproduction link or steps
Minimal repo: https://github.com/ksmth/rolldown-cjs-class-field-repro
git clone https://github.com/ksmth/rolldown-cjs-class-field-repro
cd rolldown-cjs-class-field-repro
npm install
npm run build
npm run preview # then open http://localhost:4173
In the browser console:
Uncaught (in promise) TypeError: _defineProperty is not a function
at new EraParser (assets/index-XXXXXXXX.js:…)
The full repro recipe, three "make it stop" knobs, and a grep snippet to confirm-vs-adjacent-bugs are all in the repo's README.md.
What is expected?
Class fields declared in a CJS-classified source module should still work after Rolldown downlevels them to _defineProperty(this, …). The hoisted _defineProperty binding inside the __commonJSMin wrapper should refer to the helper function, not its module namespace.
What is actually happening?
For every CJS-classified module that uses class fields, Rolldown emits this binding at the top of the __commonJSMin wrapper:
var require_EraParser = /* @__PURE__ */ __commonJSMin(((exports) => {
var _defineProperty = (init_defineProperty(), __toCommonJS(defineProperty_exports));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var EraParser = class extends _Parser.Parser {
constructor(..._args) {
super(..._args);
_defineProperty(this, "priority", 140); // 💥 TypeError
__toCommonJS(defineProperty_exports) returns the namespace object { __esModule: true, default: <fn> }, not the function — so _defineProperty(this, "priority", 140) throws TypeError: _defineProperty is not a function at module-init time, before any user code runs.
The helper itself is correctly emitted as a top-level function elsewhere in the bundle:
//#region \0@[email protected]/helpers/defineProperty.js
var defineProperty_exports = /* @__PURE__ */ __exportAll({ default: () => _defineProperty });
function _defineProperty(e, r, t) { … }
…and ESM-classified modules call that function directly with no __toCommonJS indirection. The bug is specifically that the local shadow inside __commonJSMin wrappers binds to the namespace instead of to the helper.
In the linked repro this expression shows up 32 times in the unminified dist/assets/index-*.js. You can confirm with:
grep -c '(init_defineProperty(), __toCommonJS(defineProperty_exports))' dist/assets/*.js
Workarounds (any of these makes the bug vanish)
build.target: 'es2022' — class fields are emitted natively, the broken binding is never generated.
- A small
resolveId plugin that rewrites date-fns/**/*.cjs → *.js — keeps the old target, keeps the _defineProperty(this, …) lowering, but no longer goes through CJS classification, so _defineProperty is hoisted as a plain top-level function (no __toCommonJS wrapper) and called directly.
- Downgrade to
vite@7 (Rollup-based build path).
The repro repo includes config files for each of the first two and verifies all three with grep counts in the README.
Notes / non-duplicates
System Info
System:
OS: macOS 26.3.1
CPU: (12) arm64 Apple M3 Pro
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.12.0
npm: 10.9.0
Browsers:
Chrome: 147.0.7727.102
Firefox: 149.0
Safari: 26.3.1
npmPackages:
vite: 8.0.10
rolldown: 1.0.0-rc.17 (transitive, pinned by [email protected])
date-fns: 4.1.0
@oxc-project/runtime: 0.127.0 (transitive)
Any additional comments?
Hit while bundling a real app whose dep graph reaches date-fns/parse via the require exports condition; the minimal repro pins resolve.conditions: ["require", "node", "default"] to make that condition selection deterministic. The bug is about CJS classification, not specifically about date-fns — any .cjs source with class fields and a sub-ES2022 target should reproduce it.
Reproduction link or steps
Minimal repo: https://github.com/ksmth/rolldown-cjs-class-field-repro
In the browser console:
The full repro recipe, three "make it stop" knobs, and a grep snippet to confirm-vs-adjacent-bugs are all in the repo's
README.md.What is expected?
Class fields declared in a CJS-classified source module should still work after Rolldown downlevels them to
_defineProperty(this, …). The hoisted_definePropertybinding inside the__commonJSMinwrapper should refer to the helper function, not its module namespace.What is actually happening?
For every CJS-classified module that uses class fields, Rolldown emits this binding at the top of the
__commonJSMinwrapper:__toCommonJS(defineProperty_exports)returns the namespace object{ __esModule: true, default: <fn> }, not the function — so_defineProperty(this, "priority", 140)throwsTypeError: _defineProperty is not a functionat module-init time, before any user code runs.The helper itself is correctly emitted as a top-level function elsewhere in the bundle:
…and ESM-classified modules call that function directly with no
__toCommonJSindirection. The bug is specifically that the local shadow inside__commonJSMinwrappers binds to the namespace instead of to the helper.In the linked repro this expression shows up 32 times in the unminified
dist/assets/index-*.js. You can confirm with:Workarounds (any of these makes the bug vanish)
build.target: 'es2022'— class fields are emitted natively, the broken binding is never generated.resolveIdplugin that rewritesdate-fns/**/*.cjs→*.js— keeps the old target, keeps the_defineProperty(this, …)lowering, but no longer goes through CJS classification, so_definePropertyis hoisted as a plain top-level function (no__toCommonJSwrapper) and called directly.vite@7(Rollup-based build path).The repro repo includes config files for each of the first two and verifies all three with
grepcounts in the README.Notes / non-duplicates
build.minify: false, so this is not the eval-mangler shadow bug from [Bug]: Private class field helper variable shadowing causes 'n is not a function' error #7843 (which only showed up under minification and was fixed in1.0.0-rc.13).__commonJSMin is not a function, called-before-defined) either.@oxc-project/[email protected]'shelpers/defineProperty.js.System Info
System: OS: macOS 26.3.1 CPU: (12) arm64 Apple M3 Pro Shell: 5.9 - /bin/zsh Binaries: Node: 22.12.0 npm: 10.9.0 Browsers: Chrome: 147.0.7727.102 Firefox: 149.0 Safari: 26.3.1 npmPackages: vite: 8.0.10 rolldown: 1.0.0-rc.17 (transitive, pinned by [email protected]) date-fns: 4.1.0 @oxc-project/runtime: 0.127.0 (transitive)Any additional comments?
Hit while bundling a real app whose dep graph reaches
date-fns/parsevia therequireexports condition; the minimal repro pinsresolve.conditions: ["require", "node", "default"]to make that condition selection deterministic. The bug is about CJS classification, not specifically about date-fns — any.cjssource with class fields and a sub-ES2022 target should reproduce it.