Five packaging defects, all pre-existing:
1. dist/esm/index.js held ESM syntax while the package is not
"type": "module", so Node classified it as CommonJS. It failed
outright on Node 18 ("Unexpected token 'export'") and only worked on
Node >= 22 because Node re-parses after guessing the module type,
paying that cost on every import. Bundles now carry explicit
extensions: .mjs for ES output, .cjs/.js for CommonJS. The browser
build gained a real CommonJS output too — the exports map previously
pointed the browser "require" condition at an ES module.
The exports map now also leads with "types" and ends with a "default"
fallback for resolvers matching neither "node" nor "browser".
2. files: ["native"] published the local build directory: a 94.6 kB
Linux-x64 .node binary, a 148 kB object file and generated Makefiles.
node-gyp-build checks build/Release before prebuilds, so every
consumer on every platform would have found this machine's binary,
skipped compiling, and failed to load it. It fails safe (native/
index.js catches and returns null), but the addon could never work
for anyone else. Narrowed to the four source files.
3. binding.gyp resolves node-addon-api at build time, but nothing
declared it: it was a devDependency of the root, absent from
native/package.json. The build only succeeded here because a dev
install populates the root node_modules. Declared as a dependency of
the native package, where it is actually needed.
4. No clean step, so stale output shipped — the tarball carried both
dist/types/core/** and a dist/types/src/** tree left over from before
rootDir was set. build now runs clean first.
5. test:browser ran `karma start` with no karma.conf.js anywhere in the
repo, and tests/browser is an empty directory. Removed the script and
the karma devDependency rather than leave a script that cannot run.
Verified: CommonJS require and ESM import both resolve on Node 18.19.1
and 24.18.0; TypeScript resolves types under both bundler and node16;
npm pack now produces 35 files / 103.8 kB with no build artefacts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
1.4 KiB
JavaScript
53 lines
1.4 KiB
JavaScript
import typescript from '@rollup/plugin-typescript';
|
|
import resolve from '@rollup/plugin-node-resolve';
|
|
import commonjs from '@rollup/plugin-commonjs';
|
|
|
|
const target = process.env.TARGET || 'node';
|
|
|
|
const config = {
|
|
input: target === 'browser' ? 'src/browser.ts' : 'src/node.ts',
|
|
plugins: [
|
|
resolve(),
|
|
commonjs(),
|
|
typescript({
|
|
tsconfig: './tsconfig.json',
|
|
declaration: false,
|
|
declarationDir: undefined
|
|
})
|
|
]
|
|
};
|
|
|
|
// Extensions are explicit rather than bare `.js`: the package is not
|
|
// "type": "module", so Node treats a .js file as CommonJS. An ES-format bundle
|
|
// named .js therefore fails to import on Node < 22, and only works above that
|
|
// because Node re-parses it after guessing — at a cost on every import.
|
|
if (target === 'node') {
|
|
config.output = [
|
|
{
|
|
file: 'dist/node/index.js',
|
|
format: 'cjs',
|
|
exports: 'named'
|
|
},
|
|
{
|
|
file: 'dist/esm/index.mjs',
|
|
format: 'es'
|
|
}
|
|
];
|
|
config.external = ['crypto', 'https', 'fs', 'path'];
|
|
} else if (target === 'browser') {
|
|
config.output = [
|
|
{
|
|
file: 'dist/browser/index.mjs',
|
|
format: 'es',
|
|
name: 'Nomyo'
|
|
},
|
|
{
|
|
file: 'dist/browser/index.cjs',
|
|
format: 'cjs',
|
|
exports: 'named',
|
|
name: 'Nomyo'
|
|
}
|
|
];
|
|
}
|
|
|
|
export default config;
|