Skip to content

Commit 2a13885

Browse files
committed
feat: add bootstrap-lite
1 parent 04e93c8 commit 2a13885

File tree

3 files changed

+274
-0
lines changed

3 files changed

+274
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"lint:fix": "lerna run lint:fix --stream",
2727
"lint:commits": "commitlint --from=HEAD^1",
2828
"bootstrap": "node scripts/bootstrap.js",
29+
"bootstrap:lite": "node scripts/bootstrap-lite.js",
2930
"build": "lerna run build --stream",
3031
"build:watch": "lerna run build:watch --stream",
3132
"build:docs": "lerna run bundle --stream --scope docs-app",

scripts/README-bootstrap-lite.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# bootstrap-lite
2+
3+
A lightweight validation script optimized for AI tools and quick validation of code changes.
4+
5+
## ⚠️ Prerequisites
6+
7+
**You must run full bootstrap at least once before using bootstrap:lite:**
8+
9+
```bash
10+
npm run bootstrap
11+
```
12+
13+
`bootstrap:lite` is designed for **validating changes** in an already-bootstrapped repository. It won't work on a clean/fresh clone because it depends on existing build artifacts from dependencies.
14+
15+
## Usage
16+
17+
```bash
18+
npm run bootstrap:lite
19+
```
20+
21+
### Options
22+
23+
**Force rebuild (bypass cache):**
24+
25+
```bash
26+
npm run bootstrap:lite --force
27+
```
28+
29+
**With linting:**
30+
31+
```bash
32+
npm run bootstrap:lite --lint
33+
```
34+
35+
**Both force and lint:**
36+
37+
```bash
38+
npm run bootstrap:lite --force --lint
39+
```
40+
41+
## What it does
42+
43+
1. **Check TypeScript references consistency** - Verifies that package.json dependencies match tsconfig.build.json references
44+
2. **Build TypeScript types** - Generates `.d.ts` type declaration files in `types/` directories
45+
- **Note:** Type building inherently validates all types - the build will fail if there are any type errors, so you get validation for free!
46+
3. **Optional linting** - With `--lint` flag, runs linting on changed files only
47+
48+
## What it skips (vs full bootstrap)
49+
50+
- ❌ Clean step (no file deletion)
51+
- ❌ Babel builds (no transpilation to `lib/` and `es/` directories)
52+
- ❌ Icon generation
53+
- ❌ Token generation
54+
55+
## Performance
56+
57+
- **bootstrap:lite**: ~1-2 minutes ⚡ (or ~1 second with build cache!)
58+
- **bootstrap:lite --force**: ~1-2 minutes ⚡ (bypasses cache, rebuilds everything)
59+
- **bootstrap**: ~5-10 minutes 🐌
60+
61+
**Still 3-5x faster!**
62+
63+
### Why is it so fast?
64+
65+
TypeScript uses **incremental build cache** (`.tsbuildinfo` files). When you run `bootstrap:lite`:
66+
67+
1. **First run after changes**: Rebuilds only the packages you modified and their dependents (~1-2 minutes)
68+
2. **No changes**: TypeScript checks timestamps/content and skips building (~1 second) ⚡
69+
3. **With --force flag**: Bypasses cache and rebuilds everything (~1-2 minutes)
70+
71+
This is the magic of TypeScript's project references! The speed is legitimate - TypeScript is smart enough to skip unnecessary work.
72+
73+
## When to use
74+
75+
### Use `bootstrap:lite` for:
76+
77+
- ✅ AI tool backtesting and prompt validation
78+
- ✅ Quick validation during development
79+
- ✅ Building TypeScript types for IDE support
80+
- ✅ Checking if your TypeScript changes compile
81+
- ✅ Pre-commit checks (faster feedback)
82+
83+
### Use full `bootstrap` when:
84+
85+
- 🔨 You need to run the dev server (`npm run dev`) - requires Babel builds
86+
- 🔨 You need runtime JavaScript in `lib/` and `es/` directories
87+
- 🔨 You're testing actual runtime behavior
88+
- 🔨 You're preparing for release/publish
89+
- 🔨 You need icons or tokens generated
90+
91+
## Example workflow for AI backtesting
92+
93+
```bash
94+
# FIRST TIME ONLY: Bootstrap the project fully
95+
npm run bootstrap
96+
97+
# Now make code changes with AI
98+
# ...
99+
100+
# Quick validation of changes (much faster than full bootstrap)
101+
npm run bootstrap:lite
102+
103+
# If successful, run tests on specific package
104+
npm run test:vitest -- packages/ui-menu
105+
106+
# If all good, optionally test runtime behavior
107+
npm run dev
108+
```
109+
110+
## Technical details
111+
112+
The script:
113+
114+
- Runs `tsc -b tsconfig.references.json` to build TypeScript types across all packages
115+
- **Type validation happens automatically during the build** - TypeScript checks all types while generating `.d.ts` files, so if there are any type errors, the build fails
116+
- Uses TypeScript's project references for incremental builds
117+
- **Incremental build cache**: TypeScript stores build info in `.tsbuildinfo` files
118+
- Tracks file timestamps and content hashes
119+
- Rebuilds only changed files and their dependents
120+
- Can be bypassed with `--force` flag
121+
- Generates `.d.ts` files in `types/` directories
122+
- Skips Babel transpilation (no `lib/` or `es/` output)
123+
- Exits with code 1 on any validation failure
124+
125+
### Build cache behavior
126+
127+
-**Cache hit (nothing changed)**: ~1 second
128+
- 🔄 **Partial rebuild (some files changed)**: Seconds to minutes depending on how many packages affected
129+
- 🔨 **Full rebuild (--force or clean)**: ~1-2 minutes
130+
131+
## Exit codes
132+
133+
- `0` - All validations passed
134+
- `1` - TypeScript references mismatch OR type checking failed
135+
136+
Linting failures with `--lint` flag produce warnings but don't cause the script to exit with an error code.

scripts/bootstrap-lite.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#! /usr/bin/env node
2+
/* eslint-disable no-console */
3+
4+
/*
5+
* The MIT License (MIT)
6+
*
7+
* Copyright (c) 2015 - present Instructure, Inc.
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in all
17+
* copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+
* SOFTWARE.
26+
*/
27+
28+
/**
29+
* bootstrap-lite.js
30+
*
31+
* A lightweight validation script optimized for AI tools to quickly validate
32+
* code changes without doing full builds. This is much faster than full bootstrap.
33+
*
34+
* PREREQUISITES:
35+
* - You must run full `npm run bootstrap` at least once before using this script
36+
* - This script is for validating changes in an already-bootstrapped repository
37+
* - It won't work on a clean repository as it depends on existing build artifacts
38+
*
39+
* What it does:
40+
* 1. Check TypeScript references consistency
41+
* 2. Build TypeScript types (.d.ts files) - also validates types during build
42+
* - Uses TypeScript's incremental build cache for speed (rebuilds only changed files)
43+
* 3. Optional: Run linting on changed files
44+
*
45+
* What it skips (vs full bootstrap):
46+
* - Clean step
47+
* - Babel builds (transpilation to lib/ and es/)
48+
* - Icon generation
49+
* - Token generation
50+
*
51+
* Options:
52+
* --force Bypass TypeScript build cache and rebuild all types from scratch
53+
* --lint Run linting on changed files
54+
*/
55+
56+
const { execSync } = require('child_process')
57+
const chalk = require('chalk')
58+
59+
const opts = { stdio: 'inherit' }
60+
61+
function log(message, type = 'info') {
62+
const prefix = {
63+
info: chalk.blue('ℹ'),
64+
success: chalk.green('✓'),
65+
warning: chalk.yellow('⚠'),
66+
error: chalk.red('✖')
67+
}[type]
68+
console.log(`${prefix} ${message}`)
69+
}
70+
71+
function runStep(name, command) {
72+
log(`${name}...`, 'info')
73+
const startTime = Date.now()
74+
try {
75+
execSync(command, opts)
76+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2)
77+
log(`${name} completed in ${elapsed}s`, 'success')
78+
return true
79+
} catch {
80+
log(`${name} failed`, 'error')
81+
return false
82+
}
83+
}
84+
85+
function bootstrapLite() {
86+
const startTime = Date.now()
87+
log('Starting bootstrap-lite (fast validation for AI tools)...', 'info')
88+
console.log('')
89+
90+
// Step 1: Check TypeScript references consistency
91+
if (
92+
!runStep(
93+
'Checking TypeScript references',
94+
'node scripts/checkTSReferences.js'
95+
)
96+
) {
97+
process.exit(1)
98+
}
99+
console.log('')
100+
101+
// Step 2: Build TypeScript types
102+
// This generates .d.ts files AND validates types (build fails if type errors exist)
103+
log('Building TypeScript types (this also validates types)...', 'info')
104+
const args = process.argv.slice(2)
105+
const forceRebuild = args.includes('--force')
106+
const buildCommand = forceRebuild
107+
? 'tsc -b tsconfig.references.json --force'
108+
: 'npm run build:types'
109+
110+
if (forceRebuild) {
111+
log('Force rebuild enabled - bypassing TypeScript build cache', 'warning')
112+
}
113+
114+
if (!runStep('Building TypeScript types', buildCommand)) {
115+
process.exit(1)
116+
}
117+
console.log('')
118+
119+
// Step 3: Optional - Lint changed files only
120+
if (args.includes('--lint')) {
121+
if (!runStep('Linting changed files', 'npm run lint:changes')) {
122+
log('Linting failed but continuing...', 'warning')
123+
}
124+
console.log('')
125+
}
126+
127+
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2)
128+
console.log('')
129+
log(`✨ bootstrap-lite completed successfully in ${totalTime}s!`, 'success')
130+
console.log('')
131+
log(
132+
'Note: This builds types but skips Babel transpilation. For full builds, run: npm run bootstrap',
133+
'info'
134+
)
135+
}
136+
137+
bootstrapLite()

0 commit comments

Comments
 (0)