Skip to content

Release Notes ​

What changed in the notable releases of @remotex-labs/xbuild.

v3.0.3 ​

  • Added: excludeTypeChack in tsconfig.json - the globs naming files the type check leaves out. Each entry is tested against the file's path relative to the working directory, and a leading ! keeps a file an earlier pattern caught. An excluded file stays in the program, so the types it exports are still read wherever it is imported and only its own diagnostics go unreported. Leaving the key out, or naming an empty list, checks every file.
  • Fixed: A rebuild that no watch event asked for now re-reads the files that changed on disk. Only a watch event swept the cached file contents, so a build started by the b or r key recompiled the text of the first read, and an edit the watcher missed never reached the output. The sweep moved into the rebuild itself, which puts a build a key asks for on the same footing as one a changed file asks for. It asks the filesystem rather than the watcher and re-reads only the files whose time moved, so it costs a stat per tracked path.

v3.0.2 ​

  • Fixed: A banner or a footer written as a string now reaches esbuild as the code it is, rather than as a JSON string. banner: { js: '#!/usr/bin/env node' } emitted "#!/usr/bin/env node" at the top of the output, a string expression standing where the shebang belonged. A define is unchanged, since it holds an expression rather than code, so a string there still arrives quoted as "1.0.0".
  • Fixed: A build esbuild turns away over an invalid option now announces its end and fails the run. esbuild validates the options only once every plugin is set up, so the start of such a build was announced while its end was left to a stage that never ran. The terminal held at building, and the run finished without an exit code to say it had failed. The end event follows the rejection instead. An option the dependency scan reads as well is reported with it, while one only the build itself reads fails the run on its own. The lifecycle hooks stay out of that path, since no stage of the build ran.

v3.0.1 ​

  • Fixed: Declarations are emitted through the project's own TypeScript program rather than through oxc's isolated-declarations pass, which carries no type checker. A property whose type had to be inferred was dropped from the emitted type literal rather than degraded. const Num = { UInt8: Uint8Array } as const came out as declare const Num: {}, and every keyof typeof Num downstream then resolved against an empty object. Macros stay on oxc, so only the declaration half of the 3.0.0 move went back to the compiler.
  • Removed: oxc-transform as a dependency, and the platform binaries of its pass with it. oxc-parser stays, since the emitted declaration text is still parsed with it.

v3.0.0 ​

A rewrite of the compiler-facing half of xBuild. Macros and the declaration pipeline moved from TypeScript's own AST to oxc, reporting became a level rather than a boolean, and lifecycle hooks gained a named, reusable form.

ts
export const config: xBuildConfig = {
    logLevel: 'info',
    common: {
        plugins: [ timing ],
        logOverride: { 'direct-eval': 'silent' }
    },
    variants: {
        main: { esbuild: { outdir: 'dist', entryPoints: [ 'src/**/*.ts' ] } }
    },
    watch: { debounce: 50 }
};
  • Added: plugins - lifecycle hooks as a named set, several of which can stand on one build. Adds onSetup, the one place a plugin changes the options a build receives, run before every build of the variant rather than once.
  • Added: logOverride - the level a single esbuild message is reported at, keyed by its id or by an anchored pattern claiming a family of them. silent drops a message rather than filing it.
  • Added: watch as a configuration block - filter, recursive, debounce, dot, and followSymlinks. A filter a file names joins the defaults rather than replacing them, and each output directory is excluded automatically.
  • Added: --clean removes dist before building.
  • Added: An interactive terminal for watching and serving runs - a status bar on the last row, and single-key build, reload, verbose, clear, open, and quit. See Getting Started.
  • Added: Glob patterns in esbuild.entryPoints, matched from the working directory and keyed by path with the extension dropped.
  • Added: context.stage.reachableFiles and context.stage.dropped on the lifecycle context, and info and verbose buckets on both context.logs and buildResult.
  • Changed: Lifecycle hooks take one object with the shared context as a field on it, rather than the context itself - onLoad({ args, contents, loader, context }). contents arrives as a string rather than as bytes.
  • Changed: Macros are span edits over an oxc AST. A conditional binding whose flag does not hold is now dropped across the whole build: the declaration goes, the imports naming it are pruned, and its reads become undefined.
  • Changed: A define flag is decided by the text it substitutes, so only false, null, undefined, and an absent key leave it unset. 0 and the empty string now set it.
  • Changed: $$inline serializes objects and arrays as JSON instead of rendering them as undefined, and a bigint as its exact digits.
  • Changed: logLevel replaces the top-level verbose boolean, with verbose, info, warning, error, and silent.
  • Changed: Declarations follow esbuild.bundle - a bundled build gets one rolled-up .d.ts per entry point, an unbundled one gets a .d.ts per input.
  • Changed: $argv carries the whole parsed command line, the project's own userArgv options included, rather than only the pre-config parse. See The $argv global.
  • Changed: The observable and symlink internals moved out to xObservable and @remotex-labs/xinject, and both ServerModule and WatchService now report as streams rather than writing to the console.
  • Removed: BuildService, overwriteConfig, and patchConfig from the public exports. See Programmatic API.
  • Removed: The context global inside an $$inline sandbox, and MacroContextInterface with it. Reach the same values through a define function or a lifecycle hook.
  • Removed: declaration.bundle, which esbuild.bundle now decides.
  • Removed: Function references in $$inline - $$inline(getPort) no longer resolves, since the argument is built on its own.
  • Migration: Rename verbose: true to logLevel: 'verbose'; destructure context out of every hook argument; drop .toString() on onLoad contents; drop declaration.bundle; replace 0 with false in any define that meant off; and move $$inline callbacks that read context onto define functions.
  • Migration: Node.js 22 or newer is required.

Earlier releases ​

  • v2.5.x - the last of the TypeScript-AST line (archived docs).
  • v2.0.0 / v2.1.x - the variant/directive rewrite and the $argv global (archived docs).
  • v1.x - the original hooks-based toolchain (archived docs).

See also ​

Released under the Mozilla Public License 2.0