BREAKING CHANGE(tswatch): refactor tswatch to a config-driven design (load config from npmextra.json) and add interactive init wizard; change TsWatch public API and enhance Watcher behavior

This commit is contained in:
2026-01-24 11:29:55 +00:00
parent 5a702055f4
commit 9fb3f6a872
20 changed files with 3686 additions and 4431 deletions

485
readme.md
View File

@@ -1,176 +1,264 @@
# @git.zone/tswatch
A TypeScript file watcher that automatically recompiles and executes your project when files change. Designed to streamline development workflows for various TypeScript project types.
A powerful, config-driven TypeScript file watcher that automatically recompiles and executes your project when files change. Built for modern TypeScript development with zero-config presets and deep customization options.
## Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
## Features
## Features
- 🔄 **Automatic recompilation** on file changes
- 🚀 **Multiple project modes**: npm packages, web elements, services, and websites
- 🌐 **Built-in development server** with live reload for web projects
- **Fast bundling** with esbuild integration
- 🛠️ **Flexible CLI and programmatic API**
- 📦 **Zero configuration** for standard project structures
- 🔄 **Config-driven architecture** - Define watchers, bundles, and dev server in `npmextra.json`
- **Zero-config presets** - Get started instantly with `npm`, `element`, `service`, `website`, and `test` presets
- 🧙 **Interactive wizard** - Run `tswatch init` to generate configuration interactively
- 🌐 **Built-in dev server** - Live reload, CORS, compression, SPA fallback out of the box
- 📦 **Smart bundling** - TypeScript, HTML, and assets with esbuild integration
- 🔁 **Debounced execution** - Configurable debounce prevents command spam
- 🛑 **Process management** - Automatic restart or queue mode for long-running commands
- 🎯 **Glob patterns** - Watch any files with flexible pattern matching
## Installation
Install `@git.zone/tswatch` globally or as a development dependency:
## 📦 Installation
```bash
# Global installation
# Global installation (recommended for CLI usage)
pnpm install -g @git.zone/tswatch
# As a dev dependency
pnpm install --save-dev @git.zone/tswatch
```
## Quick Start
## 🚀 Quick Start
### Using the Wizard
```bash
# Watch and run tests on changes (default behavior)
tswatch
# Watch a web element project with dev server
tswatch element
# Watch a service project
tswatch service
# Run the interactive wizard to create your configuration
tswatch init
```
## CLI Commands
The wizard will guide you through creating a `npmextra.json` configuration with your chosen preset or custom watchers.
### `tswatch` or `tswatch npm`
### Using Presets
Watches TypeScript files and runs `npm test` on changes. This is the default mode.
If you already have a configuration, just run:
```bash
tswatch
# or explicitly
tswatch npm
```
### `tswatch element`
This reads your config from `npmextra.json` under the `@git.zone/tswatch` key and starts watching.
Sets up a development environment for web components/elements:
- Starts a dev server on port 3002
- Bundles TypeScript to `dist_watch/`
- Enables live reload
- Watches all `ts*/` folders
## ⚙️ Configuration
tswatch uses `npmextra.json` for configuration. Add your config under the `@git.zone/tswatch` key:
```json
{
"@git.zone/tswatch": {
"preset": "npm"
}
}
```
### Available Presets
| Preset | Description |
|--------|-------------|
| `npm` | Watch `ts/` and `test/`, run `npm test` on changes |
| `test` | Watch `ts/` and `test/`, run `npm run test2` on changes |
| `service` | Watch `ts/`, restart `npm run startTs` (ideal for backend services) |
| `element` | Dev server on port 3002 + bundling for web components |
| `website` | Full-stack: backend + frontend bundling + asset processing |
### Full Configuration Schema
```json
{
"@git.zone/tswatch": {
"preset": "element",
"server": {
"enabled": true,
"port": 3002,
"serveDir": "./dist_watch/",
"liveReload": true
},
"bundles": [
{
"name": "main-bundle",
"from": "./ts_web/index.ts",
"to": "./dist_watch/bundle.js",
"watchPatterns": ["./ts_web/**/*"],
"triggerReload": true
},
{
"name": "html",
"from": "./html/index.html",
"to": "./dist_watch/index.html",
"watchPatterns": ["./html/**/*"],
"triggerReload": true
}
],
"watchers": [
{
"name": "backend-build",
"watch": "./ts/**/*",
"command": "npm run build",
"restart": false,
"debounce": 300,
"runOnStart": true
},
{
"name": "tests",
"watch": ["./ts/**/*", "./test/**/*"],
"command": "npm test",
"restart": true,
"debounce": 300,
"runOnStart": true
}
]
}
}
```
### Configuration Options
#### `ITswatchConfig`
| Option | Type | Description |
|--------|------|-------------|
| `preset` | `string` | Use a preset: `npm`, `test`, `service`, `element`, `website` |
| `watchers` | `IWatcherConfig[]` | Array of watcher configurations |
| `server` | `IServerConfig` | Development server configuration |
| `bundles` | `IBundleConfig[]` | Bundle configurations |
#### `IWatcherConfig`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `name` | `string` | *required* | Name for logging purposes |
| `watch` | `string \| string[]` | *required* | Glob pattern(s) to watch |
| `command` | `string` | - | Shell command to execute on changes |
| `restart` | `boolean` | `true` | Kill previous process before restarting |
| `debounce` | `number` | `300` | Debounce delay in milliseconds |
| `runOnStart` | `boolean` | `true` | Run the command immediately on start |
#### `IServerConfig`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | `boolean` | *required* | Whether the server is enabled |
| `port` | `number` | `3002` | Server port |
| `serveDir` | `string` | `./dist_watch/` | Directory to serve |
| `liveReload` | `boolean` | `true` | Inject live reload script |
#### `IBundleConfig`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `name` | `string` | - | Name for logging purposes |
| `from` | `string` | *required* | Entry point file |
| `to` | `string` | *required* | Output file |
| `watchPatterns` | `string[]` | - | Additional patterns to watch |
| `triggerReload` | `boolean` | `true` | Trigger server reload after bundling |
## 🛠️ CLI Commands
### `tswatch`
Runs with configuration from `npmextra.json`. If no config exists, launches the interactive wizard.
```bash
tswatch element
tswatch
```
### `tswatch service`
### `tswatch init`
Watches TypeScript files in `./ts/` and runs `npm run startTs` on changes. Ideal for backend services.
Force-run the configuration wizard (creates or overwrites existing config).
```bash
tswatch service
tswatch init
```
### `tswatch website`
## 💻 Programmatic API
Full website development mode:
- Bundles TypeScript files to `dist_serve/`
- Processes HTML files
- Handles assets
- Runs `npm run startTs` for server-side code
```bash
tswatch website
```
### `tswatch test`
Runs `npm run test2` whenever files change. Useful for projects with custom test scripts.
```bash
tswatch test
```
## Project Structure
tswatch expects certain project structures depending on the mode:
### NPM/Node Projects
```
project/
├── ts/ # TypeScript source files
├── test/ # Test files
└── package.json # With "test" script
```
### Element Projects
```
project/
├── ts/ # Backend TypeScript
├── ts_web/ # Frontend TypeScript
├── html/ # HTML templates
│ └── index.ts # Entry point
└── dist_watch/ # Output directory (auto-created)
```
### Website Projects
```
project/
├── ts/ # Backend TypeScript
├── ts_web/ # Frontend TypeScript
│ └── index.ts # Entry point
├── html/ # HTML files
│ └── index.html
├── assets/ # Static assets
└── dist_serve/ # Output directory
```
## Programmatic API
### Basic Usage
### Basic Usage with Config
```typescript
import { TsWatch } from '@git.zone/tswatch';
// Create and start a watcher
const watcher = new TsWatch('node');
// Create TsWatch with inline configuration
const watcher = new TsWatch({
watchers: [
{
name: 'my-watcher',
watch: './src/**/*',
command: 'npm run build',
restart: true,
debounce: 300,
runOnStart: true,
},
],
});
await watcher.start();
// Stop when done
// Later: stop watching
await watcher.stop();
```
### Available Watch Modes
### Load from Config File
The `TsWatch` class accepts the following modes:
```typescript
import { TsWatch } from '@git.zone/tswatch';
| Mode | Description |
|------|-------------|
| `node` | Runs `npm test` on changes (default) |
| `test` | Runs `npm run test2` on changes |
| `element` | Web component development with dev server |
| `service` | Runs `npm run startTs` for services |
| `website` | Full website mode with bundling |
| `echo` | Test mode that runs `npm -v` |
// Load configuration from npmextra.json
const watcher = TsWatch.fromConfig();
### Custom Watchers
if (watcher) {
await watcher.start();
}
```
For more granular control, use the `Watcher` class directly:
### Using ConfigHandler
```typescript
import { ConfigHandler } from '@git.zone/tswatch';
const configHandler = new ConfigHandler();
// Check if config exists
if (configHandler.hasConfig()) {
const config = configHandler.loadConfig();
console.log(config);
}
// Get available presets
const presets = configHandler.getPresetNames();
console.log(presets); // ['npm', 'test', 'service', 'element', 'website']
// Get a specific preset
const npmPreset = configHandler.getPreset('npm');
```
### Using Watcher Directly
For more granular control, use the `Watcher` class:
```typescript
import { Watcher } from '@git.zone/tswatch';
const customWatcher = new Watcher({
filePathToWatch: './src',
commandToExecute: 'npm run build',
timeout: 5000 // Optional timeout in ms
// Create from config object
const watcher = Watcher.fromConfig({
name: 'my-watcher',
watch: ['./src/**/*', './lib/**/*'],
command: 'npm run compile',
restart: true,
});
await customWatcher.start();
await watcher.start();
```
### Using Function Callbacks
@@ -179,79 +267,126 @@ await customWatcher.start();
import { Watcher } from '@git.zone/tswatch';
const watcher = new Watcher({
filePathToWatch: './src',
name: 'custom-handler',
filePathToWatch: './src/**/*',
functionToCall: async () => {
console.log('Files changed!');
// Your custom logic here
}
console.log('Files changed! Running custom logic...');
// Your custom build/test/deploy logic here
},
debounce: 500,
runOnStart: true,
});
await watcher.start();
```
### Watcher Options
## 📁 Project Structures
| Option | Type | Description |
|--------|------|-------------|
| `filePathToWatch` | `string` | Path to watch for changes |
| `commandToExecute` | `string` | Shell command to run on changes |
| `functionToCall` | `() => Promise<any>` | Async function to call on changes |
| `timeout` | `number` | Optional timeout in milliseconds |
### NPM Package / Node.js Library
## Development Server
```
project/
├── ts/ # TypeScript source files
├── test/ # Test files
├── package.json # With "test" script
└── npmextra.json # tswatch config
```
Element mode includes a built-in development server:
Config:
```json
{
"@git.zone/tswatch": {
"preset": "npm"
}
}
```
### Backend Service
```
project/
├── ts/ # TypeScript source files
├── package.json # With "startTs" script
└── npmextra.json
```
Config:
```json
{
"@git.zone/tswatch": {
"preset": "service"
}
}
```
### Web Component / Element
```
project/
├── ts/ # Backend TypeScript (optional)
├── ts_web/ # Frontend TypeScript
├── html/
│ ├── index.ts # Web entry point
│ └── index.html
├── dist_watch/ # Output (auto-created)
└── npmextra.json
```
Config:
```json
{
"@git.zone/tswatch": {
"preset": "element"
}
}
```
Access your project at `http://localhost:3002`
### Full-Stack Website
```
project/
├── ts/ # Backend TypeScript
├── ts_web/ # Frontend TypeScript
│ └── index.ts
├── html/
│ └── index.html
├── assets/ # Static assets
├── dist_serve/ # Output
└── npmextra.json
```
Config:
```json
{
"@git.zone/tswatch": {
"preset": "website"
}
}
```
## 🌐 Development Server
The built-in development server (enabled in `element` and `website` presets) features:
- **Live Reload** - Automatically refreshes browser on changes
- **CORS** - Cross-origin requests enabled
- **Compression** - Gzip compression for faster loading
- **SPA Fallback** - Single-page application routing support
- **Security Headers** - Cross-origin isolation headers
Default configuration:
- **Port**: 3002
- **Features**: CORS enabled, gzip compression, live reload
- **Serve directory**: `./dist_watch/`
- **Serve Directory**: `./dist_watch/`
- **Live Reload**: Enabled
Access your project at `http://localhost:3002` when running in element mode.
## 🔧 Configuration Tips
## Configuration Tips
1. **TypeScript Config**: Ensure your `tsconfig.json` is properly configured for your target environment
2. **Package Scripts**: Define appropriate scripts in `package.json`:
- `test`: For npm mode
- `test2`: For test mode
- `startTs`: For service/website modes
- `build`: For general compilation
3. **File Organization**: Keep TypeScript files in `ts/` (backend) and `ts_web/` (frontend) directories
## Common Use Cases
### Developing a Node.js Library
```bash
tswatch npm
```
Automatically runs tests when you modify source files.
### Building a Web Component
```bash
tswatch element
```
Get instant feedback with live reload while developing custom elements.
### Creating a Backend Service
```bash
tswatch service
```
Automatically restart your service on code changes.
### Full-Stack Web Application
```bash
tswatch website
```
Handle both frontend and backend compilation with asset processing.
1. **Use presets for common workflows** - They're battle-tested and cover most use cases
2. **Customize with explicit config** - Override preset defaults by adding explicit `watchers`, `bundles`, or `server` config
3. **Debounce wisely** - Default 300ms works well; increase for slower builds
4. **Use `restart: false`** for one-shot commands (like builds) and `restart: true` for long-running processes (like servers)
## License and Legal Information