You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Imported CJS function-constructor loses its own .name (decimal.js clone() shape): constructor.name is empty, Node says "Decimal" #10702
Found while validating the removal of the native decimal.js binding (#10684) — with the binding
gone, import Decimal from "decimal.js" now compiles the real npm package from source (via #10699).
Every value checked matches Node 26.5.1 exactly (1/3, 10/4, the large multiplication that used to
abort the process, instanceof, sqrt, pow, toFixed, toPrecision, cmp, chained arithmetic) — except constructor.name, which is empty instead of "Decimal".
importDecimalfrom"decimal.js";constd=newDecimal(5);console.log(dinstanceofDecimal);// true on both (fixed by #10477)console.log(d.constructor.name);// Node: "Decimal" Perry: ""console.log((Decimalasany).name);// Node: "Decimal" Perry: ""
Root cause (as far as I traced it)
decimal.js's real source has no class Decimal; it is an ES5-style function constructor built by a clone() factory and exported CommonJS-style (module.exports = Decimal;, decimal.js:4935) — the
same shape #10477 already tracked for instanceof (now fixed).
Isolated repros:
A function constructor built by a same-file factory (function clone() { function Decimal(v) {...} return Decimal; }) — .name and .constructor.name are both correct.
The same shape with the prototype wholesale-replaced (Decimal.prototype = { constructor: Decimal, ... }, matching decimal.js exactly) in the same file — still correct.
The same shape moved to a separate module and exported via module.exports = Decimal (CJS),
then imported with import Decimal from "./lib.js" — Decimal.name itself is already empty
before .constructor even enters the picture.
So the loss happens specifically in the CJS-import interop path for a plain (non-class) function
value: whatever rebinds the CJS export at the import site is not preserving the underlying function
object's own .name. instanceof (#10477) and ordinary calls/construction work fine through the same
path; only the .name property is lost.
Impact
Any npm package (CJS or UMD, decimal.js/bignumber.js among them) that exports an ES5-style function
constructor and whose callers inspect .name / .constructor.name (error reporting, assert-style
type tags, some validation/serialization libraries) will see an empty string where Node reports the
real name.
Not fixed by, and not caused by, #10684's binding removal — decimal.js's own arithmetic, instanceof,
and everything else checked in that PR's acceptance test match Node exactly.
Activity