Release Notes
What changed in the notable releases of @remotex-labs/xbuild.
v3.0.3
- Added:
excludeTypeChackintsconfig.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
borrkey 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 astatper tracked path.
v3.0.2
- Fixed: A
banneror afooterwritten 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. Adefineis 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 constcame out asdeclare const Num: {}, and everykeyof typeof Numdownstream 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-transformas a dependency, and the platform binaries of its pass with it.oxc-parserstays, 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. AddsonSetup, 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.silentdrops a message rather than filing it. - Added:
watchas a configuration block -filter,recursive,debounce,dot, andfollowSymlinks. Afiltera file names joins the defaults rather than replacing them, and each output directory is excluded automatically. - Added:
--cleanremovesdistbefore 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.reachableFilesandcontext.stage.droppedon the lifecycle context, andinfoandverbosebuckets on bothcontext.logsandbuildResult. - 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 }).contentsarrives 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
defineflag is decided by the text it substitutes, so onlyfalse,null,undefined, and an absent key leave it unset.0and the empty string now set it. - Changed:
$$inlineserializes objects and arrays as JSON instead of rendering them asundefined, and abigintas its exact digits. - Changed:
logLevelreplaces the top-levelverboseboolean, withverbose,info,warning,error, andsilent. - Changed: Declarations follow
esbuild.bundle- a bundled build gets one rolled-up.d.tsper entry point, an unbundled one gets a.d.tsper input. - Changed:
$argvcarries the whole parsed command line, the project's ownuserArgvoptions included, rather than only the pre-config parse. See The$argvglobal. - Changed: The observable and symlink internals moved out to xObservable and
@remotex-labs/xinject, and bothServerModuleandWatchServicenow report as streams rather than writing to the console. - Removed:
BuildService,overwriteConfig, andpatchConfigfrom the public exports. See Programmatic API. - Removed: The
contextglobal inside an$$inlinesandbox, andMacroContextInterfacewith it. Reach the same values through adefinefunction or a lifecycle hook. - Removed:
declaration.bundle, whichesbuild.bundlenow decides. - Removed: Function references in
$$inline-$$inline(getPort)no longer resolves, since the argument is built on its own. - Migration: Rename
verbose: truetologLevel: 'verbose'; destructurecontextout of every hook argument; drop.toString()ononLoadcontents; dropdeclaration.bundle; replace0withfalsein anydefinethat meant off; and move$$inlinecallbacks that readcontextontodefinefunctions. - 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
$argvglobal (archived docs). - v1.x - the original hooks-based toolchain (archived docs).
