Skip to content

Commit b023519

Browse files
committed
modern dual
1 parent 734e8bf commit b023519

File tree

1 file changed

+89
-12
lines changed

1 file changed

+89
-12
lines changed

src/commands/build.ts

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const filesToExcludeFromDist = [
4343

4444
const moduleMappings = {
4545
esm: 'es2022',
46-
cjs: 'commonjs',
46+
cjs: 'nodenext',
4747
} as const;
4848

4949
function typeScriptCompilerOptions(target: 'esm' | 'cjs'): Record<string, unknown> {
@@ -89,17 +89,22 @@ async function buildTypeScript(
8989
reporter,
9090
);
9191

92-
assertTypeScriptBuildResult(
93-
await execa('npx', [
94-
'tsc',
95-
...(tsconfig ? ['--project', tsconfig] : []),
96-
...compilerOptionsToArgs(typeScriptCompilerOptions('cjs')),
97-
...(options.incremental ? ['--incremental'] : []),
98-
'--outDir',
99-
join(buildPath, 'cjs'),
100-
]),
101-
reporter,
102-
);
92+
const revertPackageJsonsType = await setPackageJsonsType(options.cwd, 'commonjs');
93+
try {
94+
assertTypeScriptBuildResult(
95+
await execa('npx', [
96+
'tsc',
97+
...(tsconfig ? ['--project', tsconfig] : []),
98+
...compilerOptionsToArgs(typeScriptCompilerOptions('cjs')),
99+
...(options.incremental ? ['--incremental'] : []),
100+
'--outDir',
101+
join(buildPath, 'cjs'),
102+
]),
103+
reporter,
104+
);
105+
} finally {
106+
await revertPackageJsonsType();
107+
}
103108
}
104109

105110
export const buildCommand = createCommand<
@@ -479,6 +484,78 @@ export function validatePackageJson(
479484
}
480485
}
481486

487+
type PackageJsonType = 'module' | 'commonjs';
488+
489+
/**
490+
* Sets the {@link filePath package.json} `"type"` field to the defined {@link type}
491+
* returning a "revert" function which puts the original `"type"` back.
492+
*
493+
* @returns A revert function that reverts the original value of the `"type"` field.
494+
*/
495+
async function setPackageJsonsType(
496+
cwd: string,
497+
type: PackageJsonType,
498+
): Promise<() => Promise<void>> {
499+
const rootPkgJsonPath = join(cwd, 'package.json');
500+
const rootContents = await fse.readFile(rootPkgJsonPath, 'utf8');
501+
const rootPkg = JSON.parse(rootContents);
502+
503+
const reverts: (() => Promise<void>)[] = [];
504+
505+
if ('workspaces' in rootPkg) {
506+
for (const pkgJsonPath of [
507+
// we also want to modify the root package.json
508+
// TODO: do we?
509+
rootPkgJsonPath,
510+
// get all package.jsons from the defined workspaces
511+
...(await globby(
512+
rootPkg.workspaces.map((w: string) => w + '/package.json'),
513+
{ cwd, absolute: true },
514+
)),
515+
]) {
516+
const contents =
517+
pkgJsonPath === rootPkgJsonPath
518+
? // no need to re-read the root package.json
519+
rootContents
520+
: await fse.readFile(pkgJsonPath, 'utf8');
521+
const endsWithNewline = contents.endsWith('\n');
522+
523+
const pkg = JSON.parse(contents);
524+
if (pkg.type != null && pkg.type !== 'commonjs' && pkg.type !== 'module') {
525+
throw new Error(`Invalid "type" property value "${pkg.type}" in ${pkgJsonPath}`);
526+
}
527+
528+
const originalType: PackageJsonType | undefined = pkg.type;
529+
const differentType =
530+
(pkg.type ||
531+
// default when the type is not defined
532+
'commonjs') !== type;
533+
534+
// change only if the provided type is different
535+
if (differentType) {
536+
pkg.type = type;
537+
await fse.writeFile(
538+
pkgJsonPath,
539+
JSON.stringify(pkg, null, ' ') + (endsWithNewline ? '\n' : ''),
540+
);
541+
542+
// revert change, of course only if we changed something
543+
reverts.push(async () => {
544+
pkg.type = originalType;
545+
await fse.writeFile(
546+
pkgJsonPath,
547+
JSON.stringify(pkg, null, ' ') + (endsWithNewline ? '\n' : ''),
548+
);
549+
});
550+
}
551+
}
552+
}
553+
554+
return async function revert() {
555+
await Promise.all(reverts.map(r => r()));
556+
};
557+
}
558+
482559
async function executeCopy(sourcePath: string, destPath: string) {
483560
await fse.mkdirp(dirname(destPath));
484561
await fse.copyFile(sourcePath, destPath);

0 commit comments

Comments
 (0)