Skip to content

Build a multi-file project ​

Point the compiler at the entry file; it follows the imports and compiles the whole program into one binary. Module resolution is tsc's, so write specifiers the way TypeScript accepts them: ./stats, ./stats.js and ./stats.ts all work.

The files ​

ts
// Entry file: `bin/chad build main.ts -o stats` follows the imports.
import { mean, median } from "./stats";
import formatRow from "./format";

const samples: number[] = [12, 7, 3, 21, 9, 14];
console.log(formatRow("mean", mean(samples)));
console.log(formatRow("median", median(samples)));
ts
export function mean(xs: number[]): number {
  let sum = 0;
  for (const x of xs) sum += x;
  return xs.length === 0 ? 0 : sum / xs.length;
}

export function median(xs: number[]): number {
  const sorted = [...xs].sort((a: number, b: number): number => a - b);
  const mid = Math.floor(sorted.length / 2);
  const hi = sorted[mid] ?? 0;
  if (sorted.length % 2 === 1) return hi;
  const lo = sorted[mid - 1] ?? 0;
  return (lo + hi) / 2;
}
ts
export default function formatRow(label: string, value: number): string {
  const rounded = Math.round(value * 100) / 100;
  return `${label.padEnd(8)}${rounded}`;
}

Build and run ​

sh
bin/chad build main.ts -o stats
./stats
text
mean    11
median  10.5

Node runs the same entry unchanged (node --import tsx main.ts) and prints the same bytes.

Things to know ​

  • Named, default, namespace and type-only imports all work, and so do re-exports; see Modules and imports for the full list and a larger example.
  • A package under node_modules is compiled like your own code if it ships TypeScript source. A package that ships only JavaScript is rejected with CS1226.
  • Top-level code in each module runs once, in dependency order, as in Node.

Next: parse a JSON config file.