feat(cli): add npmextra-based compile target configuration for deno builds

This commit is contained in:
2026-03-15 15:28:17 +00:00
parent 0c86e0b43e
commit 3f483ccd9c
9 changed files with 153 additions and 58 deletions

View File

@@ -1,9 +1,12 @@
import * as plugins from './plugins.js';
import type { ITsdenoConfig, ICompileTarget } from './tsdeno.interfaces.js';
const shell = new plugins.smartshell.Smartshell({
executor: 'bash',
});
const smartfs = new plugins.SmartFs(new plugins.SmartFsProviderNode());
export class TsDeno {
public cwd: string;
@@ -20,13 +23,7 @@ export class TsDeno {
const packageJsonPath = plugins.path.join(this.cwd, 'package.json');
const backupPath = plugins.path.join(this.cwd, 'package.json.bak');
let hasPackageJson = false;
try {
await plugins.fs.access(packageJsonPath);
hasPackageJson = true;
} catch {
hasPackageJson = false;
}
const hasPackageJson = await smartfs.file(packageJsonPath).exists();
// Ensure --node-modules-dir=none is present
if (!args.some((arg) => arg.startsWith('--node-modules-dir'))) {
@@ -36,7 +33,7 @@ export class TsDeno {
// Temporarily hide package.json from Deno
if (hasPackageJson) {
console.log('tsdeno: temporarily hiding package.json to exclude devDependencies from bundle');
await plugins.fs.rename(packageJsonPath, backupPath);
await smartfs.file(packageJsonPath).move(backupPath);
}
try {
@@ -51,9 +48,81 @@ export class TsDeno {
} finally {
// Always restore package.json
if (hasPackageJson) {
await plugins.fs.rename(backupPath, packageJsonPath);
await smartfs.file(backupPath).move(packageJsonPath);
console.log('tsdeno: restored package.json');
}
}
}
/**
* Reads compile targets from npmextra.json and compiles each one.
* The package.json hide/restore wraps the entire loop.
*/
public async compileFromConfig(): Promise<void> {
const npmextraInstance = new plugins.npmextra.Npmextra(this.cwd);
const config = npmextraInstance.dataFor<ITsdenoConfig>('@git.zone/tsdeno', {
compileTargets: [],
});
if (config.compileTargets.length === 0) {
console.error('tsdeno: no compileTargets found in npmextra.json under "@git.zone/tsdeno"');
console.error('tsdeno: either pass args directly or add config to npmextra.json');
process.exit(1);
}
console.log(`tsdeno: found ${config.compileTargets.length} compile target(s) in npmextra.json`);
const packageJsonPath = plugins.path.join(this.cwd, 'package.json');
const backupPath = plugins.path.join(this.cwd, 'package.json.bak');
const hasPackageJson = await smartfs.file(packageJsonPath).exists();
// Hide package.json once for all targets
if (hasPackageJson) {
console.log('tsdeno: temporarily hiding package.json to exclude devDependencies from bundle');
await smartfs.file(packageJsonPath).move(backupPath);
}
try {
for (const target of config.compileTargets) {
console.log(`\ntsdeno: compiling target "${target.name}"...`);
const args = this.buildArgsFromTarget(target);
const shellCommand = `cd ${this.cwd} && deno compile ${args.join(' ')}`;
console.log(`tsdeno: running deno compile ${args.join(' ')}`);
const result = await shell.execPassthrough(shellCommand);
if (result.exitCode !== 0) {
console.error(`tsdeno: deno compile exited with code ${result.exitCode} for target "${target.name}"`);
process.exit(result.exitCode);
}
}
} finally {
if (hasPackageJson) {
await smartfs.file(backupPath).move(packageJsonPath);
console.log('\ntsdeno: restored package.json');
}
}
console.log(`\ntsdeno: all ${config.compileTargets.length} target(s) compiled successfully`);
}
private buildArgsFromTarget(target: ICompileTarget): string[] {
const args: string[] = ['--node-modules-dir=none'];
if (target.noCheck) {
args.push('--no-check');
}
if (target.permissions) {
args.push(...target.permissions);
}
const outputPath = plugins.path.join(target.outDir, target.name);
args.push('--output', outputPath);
args.push('--target', target.target);
args.push(target.entryPoint);
return args;
}
}