Summary
require('oakscriptjs') in a CJS consumer returns an empty, frozen, null-prototype object. None of the 81 declared exports are reachable. ESM consumers (import 'oakscriptjs') are unaffected.
Reproduction
In any Node project that has oakscriptjs@0.2.7 installed:
node -e "const oak = require('oakscriptjs'); console.log(Object.keys(oak).length, typeof oak.getSourceSeries);"
# 0 undefined
Compare to ESM, which works:
node -e "import('oakscriptjs').then(m => console.log(Object.keys(m).length, typeof m.getSourceSeries));"
# 81 function
Root cause
package.json declares "type": "module" while pointing the CJS entry at a .js file:
{
"type": "module",
"main": "dist/index.js",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
}
}
With "type": "module", Node treats every .js file in the package as ESM, regardless of its contents. But dist/index.js is built by esbuild with --format=cjs and ends with:
module.exports = __toCommonJS(src_exports);
When require() resolves to dist/index.js, Node parses it as ESM. The module.exports = ... line is a no-op in ESM scope, so the returned namespace is empty. The compiled CJS exports never reach the consumer.
Downstream impact
lightweight-charts-indicators (which depends on oakscriptjs) crashes when imported via CJS:
TypeError: (0, import_oakscriptjs10.getSourceSeries) is not a function
at calculate10 (.../lightweight-charts-indicators/dist/index.cjs:1321)
The crash surfaces in lightweight-charts-indicators, but the namespace it received from oakscriptjs was already empty.
Suggested fix
Rename the CJS bundle to .cjs and update both main and the require export:
{
"type": "module",
"main": "dist/index.cjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./runtime": {
"types": "./dist/runtime/index.d.ts",
"import": "./dist/runtime/index.mjs",
"require": "./dist/runtime/index.cjs"
}
}
}
And update the build scripts to emit .cjs:
- "build:cjs": "esbuild src/index.ts --bundle --format=cjs --outfile=dist/index.js ...",
+ "build:cjs": "esbuild src/index.ts --bundle --format=cjs --outfile=dist/index.cjs ...",
- "build:runtime:cjs": "esbuild src/runtime/index.ts --bundle --format=cjs --outfile=dist/runtime/index.js ...",
+ "build:runtime:cjs": "esbuild src/runtime/index.ts --bundle --format=cjs --outfile=dist/runtime/index.cjs ...",
Alternative: drop "type": "module" and keep the .js CJS naming, renaming only the ESM output to .mjs. Either option is correct; the key point is that the file extension and the package's module type must agree.
Environment
- Node v24.11.0
- pnpm-managed install
- oakscriptjs 0.2.7
Summary
require('oakscriptjs')in a CJS consumer returns an empty, frozen, null-prototype object. None of the 81 declared exports are reachable. ESM consumers (import 'oakscriptjs') are unaffected.Reproduction
In any Node project that has
oakscriptjs@0.2.7installed:Compare to ESM, which works:
Root cause
package.jsondeclares"type": "module"while pointing the CJS entry at a.jsfile:{ "type": "module", "main": "dist/index.js", "exports": { ".": { "import": "./dist/index.mjs", "require": "./dist/index.js" } } }With
"type": "module", Node treats every.jsfile in the package as ESM, regardless of its contents. Butdist/index.jsis built by esbuild with--format=cjsand ends with:When
require()resolves todist/index.js, Node parses it as ESM. Themodule.exports = ...line is a no-op in ESM scope, so the returned namespace is empty. The compiled CJS exports never reach the consumer.Downstream impact
lightweight-charts-indicators(which depends on oakscriptjs) crashes when imported via CJS:The crash surfaces in
lightweight-charts-indicators, but the namespace it received fromoakscriptjswas already empty.Suggested fix
Rename the CJS bundle to
.cjsand update bothmainand therequireexport:{ "type": "module", "main": "dist/index.cjs", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs" }, "./runtime": { "types": "./dist/runtime/index.d.ts", "import": "./dist/runtime/index.mjs", "require": "./dist/runtime/index.cjs" } } }And update the build scripts to emit
.cjs:Alternative: drop
"type": "module"and keep the.jsCJS naming, renaming only the ESM output to.mjs. Either option is correct; the key point is that the file extension and the package's module type must agree.Environment