diff --git a/changelog.md b/changelog.md index 5193da2..6a69eec 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2025-11-02 - 2.7.1 - fix(readme) +Update documentation: expand README with usage, CLI and API examples; add readme.hints.md project memory + +- Add readme.hints.md: new project memory / quick reference with public API and CLI summaries +- Expand and restructure readme.md: more comprehensive Quick Start, CLI Commands, API Reference, configuration, examples and troubleshooting +- Clarify protected compiler options, default compiler options, path transformation behavior and error-handling patterns +- Docs-only change — no source code or behavioral changes + ## 2025-11-02 - 2.7.0 - feat(tsbuild) Add tsconfig.json support and safer compiler option merging; protect critical options; apply path and enum transforms; bump dependencies. diff --git a/readme.hints.md b/readme.hints.md index e69de29..cf2b172 100644 --- a/readme.hints.md +++ b/readme.hints.md @@ -0,0 +1,175 @@ +# @git.zone/tsbuild - Project Memory + +## Quick Reference + +### Public API (8 functions + 1 class) +1. **compileFileArray()** - Basic compilation, throws on error +2. **compileFileArrayWithErrorTracking()** - RECOMMENDED, returns IErrorSummary +3. **compileGlobStringObject()** - Most powerful, multiple patterns +4. **TsBuild Class** - Object-oriented API with compile, checkTypes, checkEmit methods +5. **mergeCompilerOptions()** - Utility for option merging +6. **compiler()** - Legacy function +7. **emitCheck()** - Validate emit capability +8. **checkTypes()** - Type checking only + +### CLI Commands (5) +1. **tsbuild** (default) - Compiles ./ts/**/*.ts → ./dist_ts/ +2. **tsbuild custom ** - Custom directory compilation +3. **tsbuild tsfolders** - Auto-discover ts_* folders, compile in order +4. **tsbuild emitcheck ** - Validate emit without output +5. **tsbuild check [pattern]** - Type check only + +### CLI Flags +- `--skiplibcheck` - Skip .d.ts type checking (shows warning) +- `--confirmskiplibcheck` - Extended warning with 5s pause +- `--disallowimplicitany` - Stricter type checking +- `--commonjs` - Use CommonJS instead of ESNext +- `--quiet` - Suppress non-error output +- `--json` - JSON output format + +## Key Architecture Decisions + +### Configuration Priority (5 levels) +1. Default options (hardcoded) +2. tsconfig.json (if exists) +3. Protected defaults (ensure integrity) +4. Programmatic options (function params) +5. CLI flags (highest priority) + +### Protected Options +Cannot be overridden by tsconfig.json alone: +- `outDir: 'dist_ts/'` - Path transformation logic +- `noEmitOnError: true` - Build integrity +- `declaration: true` - Library support +- `emitDecoratorMetadata: true` - DI frameworks +- `inlineSourceMap: true` - Debugging + +### Path Transformation +- Automatic: `./ts_interfaces` → `./dist_ts_interfaces` +- In tsconfig paths: `./ts_*` → `./dist_ts_*` (first array element only) + +## Default Compiler Options +- Module: NodeNext (ESM with CommonJS fallback) +- Target: ESNext (latest JavaScript) +- Decorators: ENABLED (experimentalDecorators + emitDecoratorMetadata) +- Source Maps: Inline (no separate .map files) +- Declaration Files: ALWAYS generated (protected) +- Output: dist_ts/ +- Implicit any: ALLOWED by default +- esModuleInterop: true + +## Error Handling + +### Error Summary Structure +```typescript +interface IErrorSummary { + errorsByFile: Record + generalErrors: Diagnostic[] + totalErrors: number + totalFiles: number +} +``` + +### Three Error Patterns +1. **Throw Pattern** - compileFileArray: throws on error +2. **Tracking Pattern** - compileFileArrayWithErrorTracking: returns IErrorSummary, NO throw +3. **Boolean Pattern** - checkTypes/emitCheck: returns boolean + +RECOMMENDATION: Use compileFileArrayWithErrorTracking for production code + +## JSON Output Format +```json +{ + "success": boolean, + "totals": { + "errors": number, + "filesWithErrors": number, + "tasks": number + }, + "errorsByFile": { + "fileName": [ + { "code": number, "message": string } + ] + } +} +``` + +## Special Behaviors + +### tsfolders Command Ordering +1. Always: ts_interfaces first +2. Always: ts_shared second +3. Then: Other folders by `order` property in their tspublish.json +4. Finally: Folders without order property (Infinity) + +### check Command Default (No Arguments) +Two-phase check: +1. Phase 1: Type check ts/**/* (strict, include .d.ts) +2. Phase 2: Type check test/**/* (relaxed, skipLibCheck: true) + +### Glob Pattern Support +- `*` single level +- `**` recursive +- `?` single char +- `{a,b}` alternation +- Duplicates: Files matching multiple patterns compile multiple times + +### Task Information Display +When compiling multiple files with taskInfo param: +Shows: `[1/3] Compiling 45 files from ./src/**/*.ts` +Plus: File counts, duration, and file type breakdown + +## File Structure +- **index.ts** - Main entry, re-exports all +- **tsbuild.exports.ts** - Core API functions +- **tsbuild.classes.tsbuild.ts** - TsBuild class + utility functions +- **tsbuild.cli.ts** - CLI command definitions +- **plugins.ts** - Dependency imports (smartfile, smartpath, smartcli, etc.) +- **paths.ts** - Path utilities (cwd, packageDir) + +## Dependencies Used +- @git.zone/tspublish@^1.10.3 - Module ordering +- @push.rocks/* - smartcli, smartfile, smartpath, smartpromise, smartdelay +- typescript@5.9.3 - TypeScript compiler + +## Edge Cases + +1. **Empty file list** - Returns [], no error +2. **Glob duplicates** - Files compile multiple times, possible duplicate errors +3. **Non-existent files** - Handled by TypeScript "file not found" errors +4. **skipLibCheck warning** - 1-line default, 5-second pause with --confirmskiplibcheck +5. **Missing tsconfig.json** - Graceful fallback, no error +6. **Module resolution** - --commonjs switches to NodeJs (not NodeNext) +7. **Source maps** - Inline only (not separate .map files) +8. **File filtering** - Only .ts and .tsx; .d.ts and .js ignored + +## Build Safety Features +- `noEmitOnError: true` - Prevents broken builds +- Error aggregation before final output +- Protected options ensure integrity +- Pre-emit checks before emit phase +- CLI exit code handling (0=success, 1=error) + +## Recent Changes (from git log) +- 2.6.8 - Current version +- 2.6.7 - Previous version +- Added confirmskiplibcheck flag +- Improved CLI exit handling +- JSON/quiet modes enhanced +- Test script updates + +## Configuration Example (tsconfig.json) +Paths get automatically transformed: +```json +{ + "compilerOptions": { + "paths": { + "@utils/*": ["./ts_utils/*"] // → ["./dist_ts_utils/*"] + } + } +} +``` + +## No ts_* folders found in project root +The project itself doesn't have ts_interfaces, ts_shared, etc. directories. +The tsfolders command is designed for OTHER projects using tsbuild. diff --git a/readme.md b/readme.md index b8cddc0..2f18579 100644 --- a/readme.md +++ b/readme.md @@ -1,272 +1,882 @@ # @git.zone/tsbuild -A flexible TypeScript compiler that leverages the latest TypeScript features to streamline your build process. +> 🚀 **A powerful, modern TypeScript build tool with smart defaults and full tsconfig.json support** + +A production-ready TypeScript compiler that combines flexibility with safety. Built for modern JavaScript development with ESNext, NodeNext modules, and automatic decorator support. + +## Why tsbuild? + +- ✅ **Smart tsconfig.json Integration** - Respects all your compiler options with intelligent merging +- ✅ **Protected Defaults** - Critical build settings are safeguarded while staying flexible +- ✅ **Zero Config** - Works perfectly without tsconfig.json +- ✅ **Glob Pattern Support** - Compile multiple directories with a single command +- ✅ **Dependency-Aware** - Automatically orders compilation based on module dependencies +- ✅ **Type Checking** - Validate code without emitting files +- ✅ **CI/CD Ready** - JSON output mode and proper exit codes +- ✅ **Library Safe** - Never calls `process.exit()` in library code +- ✅ **Modern Defaults** - ESNext, NodeNext modules, decorators out of the box ## Install -Add `@git.zone/tsbuild` to your project using npm or yarn: +```bash +npm install @git.zone/tsbuild --save-dev +``` + +or with pnpm: ```bash -npm install @git.zone/tsbuild +pnpm install @git.zone/tsbuild --save-dev ``` -or +## Quick Start -```bash -yarn add @git.zone/tsbuild -``` - -## Key Features - -- Utilize the latest TypeScript features -- Flexible API for customized compilation processes -- Intuitive CLI for common build tasks -- Support for glob patterns to easily target files -- Ordered compilation to respect module dependencies - -## API Reference - -### Core Compilation Functions - -#### `compileFileArray(fileStringArrayArg: string[], compilerOptionsArg?: CompilerOptions, argvArg?: any): Promise` - -Compiles an array of TypeScript files with customizable compiler options. - -```typescript -import { compileFileArray } from '@git.zone/tsbuild'; - -const files = [ - './src/file1.ts', - './src/file2.ts', -]; -const options = { - target: "ES2020", - module: "CommonJS" -}; - -compileFileArray(files, options) - .then(compiledFiles => { - console.log('Compiled Files:', compiledFiles); - }) - .catch(error => { - console.error('Compilation Error:', error); - }); -``` - -#### `compileGlobStringObject(globStringObjectArg: Record, tsOptionsArg?: CompilerOptions, cwdArg?: string, argvArg?: any): Promise` - -Compiles files matching glob patterns to specified output directories. - -```typescript -import { compileGlobStringObject } from '@git.zone/tsbuild'; - -const globPattern = { - './src/**/*.ts': './dist', -}; -const compilerOptions = { - target: "ESNext", - module: "ESNext", -}; - -compileGlobStringObject(globPattern, compilerOptions) - .then(compiledFiles => { - console.log('Compilation complete:', compiledFiles); - }) - .catch(error => { - console.error('Error during compilation:', error); - }); -``` - -## Command Line Interface - -The CLI provides convenient commands for common compilation tasks. - -### Standard Command - -Compiles all TypeScript files in the `ts/` directory to the `dist_ts` directory: +### CLI Usage +**Compile your TypeScript project:** ```bash npx tsbuild ``` +Compiles `./ts/**/*.ts` → `./dist_ts/` -### Custom Command - -Compile specific directories to corresponding `dist_` directories: - +**Custom directories:** ```bash -npx tsbuild custom ... +npx tsbuild custom src utils ``` +Compiles: +- `./src/**/*.ts` → `./dist_src/` +- `./utils/**/*.ts` → `./dist_utils/` -Example: `npx tsbuild custom src utils` compiles: -- `./src/**/*.ts` → `./dist_src` -- `./utils/**/*.ts` → `./dist_utils` - -### TSFolders Command - -Compiles TypeScript folders in a specific order based on dependencies: - +**Auto-discover and compile in dependency order:** ```bash npx tsbuild tsfolders ``` +Finds all `ts_*` folders and compiles them respecting dependencies. -This command: -1. Identifies all folders starting with `ts` in the current directory -2. Prioritizes `ts_interfaces` and `ts_shared` to be compiled first -3. Orders other folders based on the `order` property in their `tspublish.json` files (if available) -4. Compiles each folder to its corresponding `dist_` folder +### Programmatic Usage -Example compilation order output: +**Basic compilation:** +```typescript +import { compileFileArray } from '@git.zone/tsbuild'; + +await compileFileArray([ + './src/index.ts', + './src/utils.ts' +]); +``` + +**Production-ready with error tracking (recommended):** +```typescript +import { compileFileArrayWithErrorTracking } from '@git.zone/tsbuild'; + +const result = await compileFileArrayWithErrorTracking([ + './src/**/*.ts' +], { + target: 'ES2022', + module: 'NodeNext' +}); + +if (result.hasErrors) { + console.error('Compilation failed!'); + console.error('Files with errors:', result.fileCount); + process.exit(1); +} + +console.log('✅ Compilation successful!'); +``` + +**Advanced glob compilation:** +```typescript +import { compileGlobStringObject } from '@git.zone/tsbuild'; + +await compileGlobStringObject({ + './ts/**/*.ts': './dist_ts', + './ts_web/**/*.ts': './dist_web' +}, { + target: 'ES2022', + module: 'ESNext' +}); +``` + +## CLI Commands + +### 1. Default Build + +```bash +npx tsbuild [options] +``` + +Compiles all TypeScript files from `./ts/` to `./dist_ts/` + +**Options:** +- `--web` - Include web-specific compilation +- `--skiplibcheck` - Skip type checking of declaration files (shows 5-second warning) +- `--confirmskiplibcheck` - Skip lib check without warning +- `--disallowimplicitany` - Disallow implicit `any` types +- `--commonjs` - Use CommonJS instead of ESNext modules +- `--json` - Output results as JSON (for CI/CD) +- `--quiet` - Suppress console output + +**Examples:** +```bash +# Standard build +npx tsbuild + +# Build with JSON output for CI +npx tsbuild --json --quiet + +# CommonJS build +npx tsbuild --commonjs +``` + +### 2. Custom Directories + +```bash +npx tsbuild custom ... [options] +``` + +Compile specific directories to their corresponding `dist_` folders. + +**Examples:** +```bash +# Compile src and utils +npx tsbuild custom src utils +# Creates: ./dist_src/ and ./dist_utils/ + +# Multiple directories with options +npx tsbuild custom api models services --commonjs +``` + +### 3. TSFolders (Dependency-Aware) + +```bash +npx tsbuild tsfolders [options] +``` + +Automatically discovers and compiles all `ts_*` folders in dependency order: +1. Prioritizes `ts_interfaces` and `ts_shared` first +2. Reads `tspublish.json` for `order` property +3. Compiles in correct sequence + +**Example output:** ``` compiling in this order: [ 'ts_interfaces', 'ts_shared', 'ts_core', 'ts_utils', 'ts_modules' ] + +🔨 [1/5] Compiling ts_interfaces... +✅ [1/5] Task completed in 1234ms +... ``` -### EmitCheck Command - -Checks if TypeScript files can be emitted without actually emitting them: +### 4. Emit Check ```bash -npx tsbuild emitcheck [additional_patterns ...] +npx tsbuild emitcheck [more...] [options] ``` -This command: -1. Performs type checking on the specified TypeScript file(s) -2. Supports both direct file paths and glob patterns -3. Reports any errors that would prevent successful compilation -4. Exits with code 0 if all files can be emitted, or 1 if any cannot -5. Doesn't produce any output files +Validates TypeScript files can be compiled without actually emitting them. -Example usage with specific files: +**Examples:** ```bash +# Check specific files npx tsbuild emitcheck src/main.ts src/utils.ts -``` -Example usage with glob patterns: -```bash +# Check with glob patterns npx tsbuild emitcheck "src/**/*.ts" "test/**/*.ts" + +# CI/CD usage +npx tsbuild emitcheck "**/*.ts" --json ``` -### Check Command +**Exit codes:** +- `0` - All files can be emitted +- `1` - One or more files have errors -Performs type checking on TypeScript files specified by glob patterns without emitting them: +### 5. Type Check ```bash -npx tsbuild check [additional_patterns ...] +npx tsbuild check [more...] [options] ``` -This command: -1. Efficiently type checks TypeScript files matching the given glob patterns -2. Supports multiple glob patterns and direct file paths -3. Reports any type errors found in the matched files -4. Exits with code 0 if all files pass type checking, or 1 if any have errors -5. Doesn't produce any output files +Performs type checking without emitting files. Faster than emitcheck. -Example usage: +**Examples:** ```bash -npx tsbuild check ts/**/* -``` +# Check all TypeScript files +npx tsbuild check "ts/**/*.ts" -Example usage with multiple patterns: -```bash +# Check multiple patterns npx tsbuild check "src/**/*.ts" "test/**/*.ts" + +# Check with specific options +npx tsbuild check "**/*.ts" --disallowimplicitany ``` -## Compiler Options +## API Reference -Additional flags can be passed to any command to modify the compilation behavior: +### Core Functions -- `--skiplibcheck`: Skip type checking of declaration files (shows warning) -- `--disallowimplicitany`: Disallow variables to be implicitly typed as `any` (implicit any is allowed by default) -- `--commonjs`: Use CommonJS module format instead of ESNext +#### `compileFileArray(files, options?, argv?)` -Example: -```bash -npx tsbuild --skiplibcheck --disallowimplicitany +Basic compilation of file array. + +**Parameters:** +- `files: string[]` - File paths to compile +- `options?: CompilerOptions` - TypeScript compiler options +- `argv?: any` - CLI arguments object + +**Returns:** `Promise` - Compiled file results + +**Example:** +```typescript +import { compileFileArray } from '@git.zone/tsbuild'; + +await compileFileArray( + ['./src/index.ts', './src/utils.ts'], + { target: 'ES2022' } +); ``` -## Configuration with tsconfig.json +#### `compileFileArrayWithErrorTracking(files, options?, argv?, taskInfo?)` -`@git.zone/tsbuild` fully supports `tsconfig.json` for compiler configuration. All compiler options from your `tsconfig.json` will be respected and merged with tsbuild's defaults. +**⭐ RECOMMENDED for production** - Provides detailed error tracking and metrics. -### Option Priority (Merge Order) +**Parameters:** +- `files: string[]` - File paths to compile +- `options?: CompilerOptions` - TypeScript compiler options +- `argv?: any` - CLI arguments object +- `taskInfo?: ITaskInfo` - Task metadata for progress reporting -When multiple configuration sources are present, they are merged in the following order (later sources override earlier ones): +**Returns:** `Promise` - Detailed error summary -1. **Default compiler options** - Base defaults for all options -2. **tsconfig.json** - All compiler options from your project's `tsconfig.json` (if present) -3. **Protected defaults** - Critical options for build integrity (see below) -4. **Programmatic options** - Options passed to API functions -5. **CLI flags** - Command-line arguments (highest priority) +**IErrorSummary Interface:** +```typescript +interface IErrorSummary { + hasErrors: boolean; + errorCount: number; + fileCount: number; + errorsByFile: Record; + generalErrors: Diagnostic[]; +} +``` -### Protected Compiler Options +**Example:** +```typescript +import { compileFileArrayWithErrorTracking } from '@git.zone/tsbuild'; -To ensure build integrity and correct functionality, the following options are protected and cannot be overridden by `tsconfig.json` alone (but can be overridden programmatically or via CLI): +const result = await compileFileArrayWithErrorTracking( + ['./src/**/*.ts'], + { target: 'ES2022', strict: true } +); -- `outDir: 'dist_ts/'` - Required for path transformation logic -- `noEmitOnError: true` - Prevents broken builds from being emitted -- `declaration: true` - Ensures .d.ts files for library consumers -- `emitDecoratorMetadata: true` - Required for dependency injection frameworks -- `inlineSourceMap: true` - Provides consistent debugging experience +if (result.hasErrors) { + console.error(`❌ ${result.errorCount} errors in ${result.fileCount} files`); -### Working Without tsconfig.json + // Show errors by file + for (const [file, errors] of Object.entries(result.errorsByFile)) { + console.error(`\n${file}:`); + errors.forEach(err => console.error(` - ${err.messageText}`)); + } -`@git.zone/tsbuild` works perfectly fine without a `tsconfig.json` file. If no `tsconfig.json` is found, it will gracefully fall back to sensible defaults without errors. + process.exit(1); +} -Example `tsconfig.json`: +console.log('✅ Compilation successful!'); +``` + +#### `compileGlobStringObject(globObject, options?, cwd?, argv?)` + +**Most powerful API** - Compile multiple glob patterns to different destinations. + +**Parameters:** +- `globObject: Record` - Maps glob patterns to output directories +- `options?: CompilerOptions` - TypeScript compiler options +- `cwd?: string` - Working directory (defaults to `process.cwd()`) +- `argv?: any` - CLI arguments object + +**Returns:** `Promise` - Array of compilation results + +**Example:** +```typescript +import { compileGlobStringObject } from '@git.zone/tsbuild'; + +await compileGlobStringObject( + { + './ts/**/*.ts': './dist_ts', + './ts_web/**/*.ts': './dist_web', + './ts_node/**/*.ts': './dist_node' + }, + { + target: 'ES2022', + module: 'NodeNext' + } +); +``` + +#### `checkTypes(files, options?, argv?)` + +Type check files without emitting. Fast validation. + +**Parameters:** +- `files: string[]` - Files to check +- `options?: CompilerOptions` - Compiler options +- `argv?: any` - CLI arguments + +**Returns:** `Promise` - Error summary + +**Example:** +```typescript +import { checkTypes } from '@git.zone/tsbuild'; + +const result = await checkTypes(['./src/**/*.ts']); + +if (result.hasErrors) { + console.error('Type errors found!'); + process.exit(1); +} +``` + +#### `emitCheck(files, options?, argv?)` + +Validate files can be emitted without actually emitting. + +**Example:** +```typescript +import { emitCheck } from '@git.zone/tsbuild'; + +const result = await emitCheck(['./src/index.ts']); + +if (result.hasErrors) { + console.error('Cannot emit these files!'); +} +``` + +### TsBuild Class + +Object-oriented API with full control. + +**Constructor:** +```typescript +new TsBuild( + fileNames?: string[], + customOptions?: CompilerOptions, + argvArg?: any, + taskInfo?: ITaskInfo +) +``` + +**Methods:** +- `compile()` - Compile and emit files +- `compileWithErrorTracking()` - Compile with detailed error summary +- `checkTypes()` - Type check without emitting +- `emitCheck()` - Validate emit capability +- `mergeCompilerOptions()` - Merge options (public utility) + +**Example:** +```typescript +import { TsBuild } from '@git.zone/tsbuild'; + +const builder = new TsBuild( + ['./src/**/*.ts'], + { target: 'ES2022', strict: true } +); + +const result = await builder.compileWithErrorTracking(); + +if (result.hasErrors) { + console.error('Build failed!'); +} +``` + +## Configuration + +### tsconfig.json Support + +tsbuild **fully supports** all compiler options from `tsconfig.json`. Your project configuration is respected and intelligently merged. + +**Example tsconfig.json:** ```json { "compilerOptions": { - "experimentalDecorators": true, - "useDefineForClassFields": false, "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", + "strict": true, "esModuleInterop": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, "verbatimModuleSyntax": true } } ``` -## Default Compiler Options +### Configuration Priority (Merge Order) -By default, `@git.zone/tsbuild` uses the following compiler options: +When multiple configuration sources exist, they merge in this order (later overrides earlier): + +1. **Default Options** - tsbuild's sensible defaults +2. **tsconfig.json** - All options from your tsconfig.json (if present) +3. **Protected Defaults** - Critical options for build integrity +4. **Programmatic Options** - Options passed to API functions +5. **CLI Flags** - Command-line arguments (highest priority) + +**Example:** +```typescript +// tsconfig.json has: { "target": "ES2020" } +// You call: +await compileFileArray(files, { target: 'ES2022' }); + +// Result: Uses ES2022 (programmatic overrides tsconfig.json) +``` + +### Protected Options + +To ensure build integrity, these options are protected from tsconfig.json override (but can be overridden programmatically or via CLI): + +- **`outDir: 'dist_ts/'`** - Required for automatic path transformations +- **`noEmitOnError: true`** - Prevents broken builds from being emitted +- **`declaration: true`** - Ensures `.d.ts` files for library consumers +- **`emitDecoratorMetadata: true`** - Required for DI frameworks +- **`inlineSourceMap: true`** - Consistent debugging experience + +**Why?** These settings ensure tsbuild works correctly and produces consumable output. + +**Override if needed:** +```typescript +// Override via programmatic API +await compileFileArray(files, { + outDir: './custom_dist', + noEmitOnError: false // ⚠️ Not recommended +}); +``` + +### Default Compiler Options + +When no tsconfig.json exists, tsbuild uses these modern defaults: ```typescript { - declaration: true, - emitDecoratorMetadata: true, - experimentalDecorators: true, - inlineSourceMap: true, - noEmitOnError: true, - outDir: 'dist_ts/', - module: ModuleKind.NodeNext, - target: ScriptTarget.ESNext, + declaration: true, // Generate .d.ts files + emitDecoratorMetadata: true, // Support DI frameworks + experimentalDecorators: true, // Enable decorators + inlineSourceMap: true, // Debug-friendly + noEmitOnError: true, // Fail-fast on errors + outDir: 'dist_ts/', // Output directory + module: ModuleKind.NodeNext, // Modern Node.js modules + target: ScriptTarget.ESNext, // Latest JavaScript moduleResolution: ModuleResolutionKind.NodeNext, lib: ['lib.dom.d.ts', 'lib.es2022.d.ts'], - noImplicitAny: false, - esModuleInterop: true, - useDefineForClassFields: false, - verbatimModuleSyntax: true, - baseUrl: './', + noImplicitAny: false, // Flexible for quick development + esModuleInterop: true, // CJS/ESM interop + useDefineForClassFields: false, // Classic decorator behavior + verbatimModuleSyntax: true, // Explicit imports/exports + baseUrl: './' } ``` -These defaults are merged with your `tsconfig.json` options (if present), programmatic options, and CLI flags according to the priority order described above. +### CLI Flags -## Path Resolution +Override any option via command-line: -The package automatically detects and applies path mappings from your `tsconfig.json`. When it finds path mappings, it adjusts them to work with the compiled output by replacing `./ts_` with `./dist_ts_` in path aliases. +- `--skiplibcheck` - Skip declaration file checking (shows 5-second warning) +- `--confirmskiplibcheck` - Skip without warning +- `--disallowimplicitany` - Enable strict `any` checking +- `--commonjs` - Use CommonJS modules +- `--json` - Output JSON (for CI/CD) +- `--quiet` - Suppress console output -## Notes and Best Practices +**Examples:** +```bash +# Strict mode +npx tsbuild --disallowimplicitany -- Each glob pattern compilation runs in its own pass, which may cause duplicate error messages if shared files are included in multiple patterns -- Use the `--skiplibcheck` option cautiously as it will pause for 5 seconds with a warning before continuing -- If you need different output configurations for different file sets, use multiple calls to `compileGlobStringObject` +# CommonJS output +npx tsbuild --commonjs +# CI/CD pipeline +npx tsbuild --json --quiet > build-results.json +``` + +### Path Resolution + +tsbuild automatically transforms path mappings from your tsconfig.json: + +**tsconfig.json:** +```json +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@models/*": ["./ts_models/*"], + "@utils/*": ["./ts_utils/*"] + } + } +} +``` + +**Automatic transformation:** +``` +./ts_models/* → ./dist_ts_models/* +./ts_utils/* → ./dist_ts_utils/* +``` + +This ensures imports work correctly in compiled output. + +## Advanced Usage + +### Error Handling Patterns + +**Pattern 1: Simple (throw on error)** +```typescript +import { compileFileArray } from '@git.zone/tsbuild'; + +try { + await compileFileArray(['./src/**/*.ts']); + console.log('✅ Build successful'); +} catch (error) { + console.error('❌ Build failed:', error); + process.exit(1); +} +``` + +**Pattern 2: Detailed tracking (recommended)** +```typescript +import { compileFileArrayWithErrorTracking } from '@git.zone/tsbuild'; + +const result = await compileFileArrayWithErrorTracking(['./src/**/*.ts']); + +if (result.hasErrors) { + console.error(`\n❌ Compilation failed with ${result.errorCount} errors in ${result.fileCount} files\n`); + + // Group errors by file + for (const [file, errors] of Object.entries(result.errorsByFile)) { + console.error(`📄 ${file}:`); + errors.forEach(err => { + const line = err.file?.getLineAndCharacterOfPosition(err.start!); + console.error(` Line ${line?.line}: ${err.messageText}`); + }); + } + + process.exit(1); +} + +console.log('✅ All files compiled successfully!'); +``` + +**Pattern 3: CI/CD Integration** +```typescript +import { compileFileArrayWithErrorTracking } from '@git.zone/tsbuild'; + +const result = await compileFileArrayWithErrorTracking(['./src/**/*.ts']); + +// Output machine-readable JSON +console.log(JSON.stringify({ + success: !result.hasErrors, + errorCount: result.errorCount, + fileCount: result.fileCount, + timestamp: new Date().toISOString() +}, null, 2)); + +process.exit(result.hasErrors ? 1 : 0); +``` + +### Multi-Stage Builds + +Compile different parts of your project with different configurations: + +```typescript +import { compileGlobStringObject } from '@git.zone/tsbuild'; + +// Stage 1: Compile shared interfaces +await compileGlobStringObject( + { './ts_interfaces/**/*.ts': './dist_interfaces' }, + { declaration: true, emitDecoratorMetadata: false } +); + +// Stage 2: Compile Node.js code +await compileGlobStringObject( + { './ts_node/**/*.ts': './dist_node' }, + { target: 'ES2022', module: 'NodeNext' } +); + +// Stage 3: Compile browser code +await compileGlobStringObject( + { './ts_web/**/*.ts': './dist_web' }, + { target: 'ES2020', module: 'ESNext', lib: ['lib.dom.d.ts', 'lib.es2020.d.ts'] } +); +``` + +### Watch Mode Integration + +Integrate with file watchers for development: + +```typescript +import { compileFileArray } from '@git.zone/tsbuild'; +import chokidar from 'chokidar'; + +const watcher = chokidar.watch('./ts/**/*.ts'); + +watcher.on('change', async (path) => { + console.log(`📝 ${path} changed, recompiling...`); + + try { + await compileFileArray([path]); + console.log('✅ Recompiled successfully'); + } catch (error) { + console.error('❌ Compilation error:', error); + } +}); + +console.log('👀 Watching for changes...'); +``` + +### Custom Task Progress + +Track compilation progress in your UI: + +```typescript +import { compileFileArrayWithErrorTracking } from '@git.zone/tsbuild'; + +const taskInfo = { + taskIndex: 1, + totalTasks: 5, + taskName: 'Compiling Core Modules' +}; + +const result = await compileFileArrayWithErrorTracking( + ['./ts_core/**/*.ts'], + { target: 'ES2022' }, + undefined, + taskInfo +); + +// Output: 🔨 [1/5] Compiling Core Modules... +// ✅ [1/5] Task completed in 2345ms +``` + +## TypeScript Decorator Support + +tsbuild has **first-class decorator support** out of the box: + +```typescript +// Works automatically with no configuration +@Injectable() +class UserService { + constructor( + @Inject('CONFIG') private config: Config, + private logger: Logger + ) {} +} +``` + +The following options are enabled by default: +- `experimentalDecorators: true` +- `emitDecoratorMetadata: true` + +This means frameworks like **NestJS**, **TypeORM**, **Inversify**, and **Angular** work without extra setup. + +## CI/CD Integration + +### GitHub Actions + +```yaml +name: Build +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '18' + + - run: npm install + - run: npx tsbuild --json --quiet > build-results.json + + - name: Check build results + run: | + if ! cat build-results.json | jq -e '.success' > /dev/null; then + echo "Build failed!" + cat build-results.json | jq '.errors' + exit 1 + fi +``` + +### GitLab CI + +```yaml +build: + stage: build + script: + - npm install + - npx tsbuild + artifacts: + paths: + - dist_ts/ +``` + +### Package.json Scripts + +```json +{ + "scripts": { + "build": "tsbuild", + "build:watch": "tsbuild && chokidar 'ts/**/*.ts' -c 'tsbuild'", + "build:prod": "tsbuild --disallowimplicitany", + "typecheck": "tsbuild check 'ts/**/*.ts'", + "pretest": "tsbuild emitcheck 'test/**/*.ts'" + } +} +``` + +## Troubleshooting + +### Common Issues + +**"Cannot find module" errors in compiled output** + +This happens when path mappings aren't configured correctly. Make sure your tsconfig.json includes: + +```json +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@myapp/*": ["./ts/*"] + } + } +} +``` + +tsbuild automatically transforms these to work in the output directory. + +**Decorator errors** + +If you see decorator-related errors, ensure: +1. `experimentalDecorators: true` in tsconfig.json +2. `emitDecoratorMetadata: true` for DI frameworks +3. You're using a compatible TypeScript version (4.0+) + +**Build succeeds but types are wrong** + +Run with strict checking: +```bash +npx tsbuild --disallowimplicitany +``` + +This catches implicit `any` types that can hide bugs. + +**Slow compilation** + +Use `--skiplibcheck` to skip declaration file checking: +```bash +npx tsbuild --confirmskiplibcheck +``` + +⚠️ Only use this if you trust your dependencies' type definitions. + +### Debug Mode + +For troubleshooting, combine flags: + +```bash +# See exactly what's happening +npx tsbuild --json | jq '.' + +# Check types without emitting +npx tsbuild check "**/*.ts" + +# Verify emit capability +npx tsbuild emitcheck "**/*.ts" +``` + +## Best Practices + +### ✅ DO + +- **Use `compileFileArrayWithErrorTracking()`** for production builds +- **Enable strict mode** in tsconfig.json for better type safety +- **Organize code in `ts_*` folders** for automatic dependency ordering +- **Use protected defaults** - they exist for good reasons +- **Type check in CI/CD** with `npx tsbuild check` +- **Version lock** tsbuild in package.json + +### ❌ DON'T + +- **Don't override `noEmitOnError`** - broken builds cause runtime errors +- **Don't skip lib check** in production builds +- **Don't ignore type errors** - they indicate real problems +- **Don't mix module formats** - stick to NodeNext for Node.js projects +- **Don't use `--quiet` without `--json`** - you'll lose error information + +## Performance Tips + +1. **Use glob patterns** instead of explicit file lists +2. **Enable `--skiplibcheck`** for faster development (not production!) +3. **Compile in stages** for large multi-package projects +4. **Use tsfolders** for automatic dependency ordering +5. **Cache `dist_*` folders** in CI/CD pipelines + +## Migration Guide + +### From tsc + +**Before (package.json):** +```json +{ + "scripts": { + "build": "tsc" + } +} +``` + +**After:** +```json +{ + "scripts": { + "build": "tsbuild" + } +} +``` + +Your tsconfig.json continues to work! tsbuild respects all your settings. + +### From other build tools + +tsbuild is a drop-in replacement focused on TypeScript compilation. If you need bundling, combine with your bundler: + +```json +{ + "scripts": { + "build": "tsbuild && esbuild dist_ts/index.js --bundle --outfile=bundle.js" + } +} +``` + +## FAQ + +**Q: Does tsbuild bundle code?** +A: No, tsbuild compiles TypeScript to JavaScript. For bundling, use esbuild, webpack, or rollup after compilation. + +**Q: Can I use tsbuild with monorepos?** +A: Yes! Use `tsbuild tsfolders` to automatically compile all packages in dependency order. + +**Q: Does it work with decorators?** +A: Yes, decorator support is enabled by default (both `experimentalDecorators` and `emitDecoratorMetadata`). + +**Q: Can I disable the protected defaults?** +A: Yes, via programmatic API or CLI flags. But consider why they're protected first! + +**Q: Does tsbuild support incremental compilation?** +A: tsbuild respects TypeScript's incremental flag if you set it in tsconfig.json. + +**Q: Is tsbuild compatible with TypeScript 5.x?** +A: Yes, tsbuild works with all modern TypeScript versions. ## License and Legal Information -This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. +This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file. @@ -276,9 +886,9 @@ This project is owned and maintained by Task Venture Capital GmbH. The names and ### Company Information -Task Venture Capital GmbH +Task Venture Capital GmbH Registered at District court Bremen HRB 35230 HB, Germany For any legal inquiries or if you require further information, please contact us via email at hello@task.vc. -By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. \ No newline at end of file +By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 49df234..28eada2 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@git.zone/tsbuild', - version: '2.7.0', + version: '2.7.1', description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.' }