package: CommonJS projects get their own declarations (dist/types-cjs; node16 / nodenext refused an ESM-only .d.ts from a CJS file, TS1541); the package-types test covers ES module and CommonJS projects under bundler / node16 / nodenext / node10 and loads the package with import() and require() under Node; pitfall 69

This commit is contained in:
CRTkafa 2026-10-15 06:01:33 +08:00
parent d717ceb4cd
commit 04647c079e
6 changed files with 42 additions and 14 deletions

View file

@ -5,7 +5,7 @@
// bun tools/build-node.ts write dist/storebound.mjs (npm pack / publish run it: prepack)
// bun tools/build-node.ts --out <f> write elsewhere (tests)
// The bundle is checked for this machine's home and checkout paths (like the sidecar): nothing private may ship.
import { chmodSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
import { chmodSync, cpSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { dirname, join, relative, resolve } from 'node:path';
import { privateStrings, ROOT } from './build-sidecars';
@ -45,6 +45,12 @@ export function buildEntry(dir = join(ROOT, 'dist')): void {
if (tsc.exitCode !== 0) throw new Error(`tsc (declarations) failed\n${tsc.stdout.toString()}${tsc.stderr.toString()}`);
if (!statSync(join(types, 'lib', 'config.d.ts'), { throwIfNoEntry: false })) throw new Error('no dist/types/lib/config.d.ts');
pruneDeclarations(types, 'lib/config.d.ts');
// the same declarations for CommonJS projects (no "type": "module"): node16 / nodenext read a .d.ts as ESM or CJS
// from the nearest package.json, and a CJS file may not type-import an ESM-only declaration (TS1541)
const cjs = join(dir, 'types-cjs');
rmSync(cjs, { recursive: true, force: true });
cpSync(types, cjs, { recursive: true });
writeFileSync(join(cjs, 'package.json'), '{ "type": "commonjs" }\n');
const js = Bun.spawnSync(['bun', 'build', 'cli/lib/config.ts', '--target=node', '--format=esm', ...NODE_EXTERNALS.flatMap(e => ['--external', e]), '--outfile', join(dir, 'config.js')], { cwd: ROOT, stdout: 'pipe', stderr: 'pipe' });
if (js.exitCode !== 0) throw new Error(`bun build (config entry) failed\n${js.stderr.toString()}`);
const leaked = privateStrings().filter(s => readFileSync(join(dir, 'config.js'), 'utf8').includes(s));