mirror of
https://github.com/codeaashu/claude-code.git
synced 2026-04-08 22:28:48 +03:00
claude-code
This commit is contained in:
165
prompts/03-build-config.md
Normal file
165
prompts/03-build-config.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Prompt 03: Create esbuild-Based Build System
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. This is the Claude Code CLI — a TypeScript/TSX terminal app using React + Ink. It was originally built using **Bun's bundler** with feature flags, but that build config wasn't included in the leak.
|
||||
|
||||
We need to create a build system that:
|
||||
1. Bundles the entire `src/` tree into a runnable output
|
||||
2. Aliases `bun:bundle` → our shim at `src/shims/bun-bundle.ts`
|
||||
3. Injects the `MACRO` global (via `src/shims/macro.ts` preload)
|
||||
4. Handles TSX/JSX (React)
|
||||
5. Handles ESM `.js` extension imports (the code uses `import from './foo.js'` which maps to `./foo.ts`)
|
||||
6. Produces output that can run under **Bun** (primary) or **Node.js 20+** (secondary)
|
||||
|
||||
## Existing Files
|
||||
|
||||
- `src/shims/bun-bundle.ts` — runtime `feature()` function (created in Prompt 02)
|
||||
- `src/shims/macro.ts` — global `MACRO` object (created in Prompt 02)
|
||||
- `src/shims/preload.ts` — preload bootstrap (created in Prompt 02)
|
||||
- `src/entrypoints/cli.tsx` — main entrypoint
|
||||
- `tsconfig.json` — has `"jsx": "react-jsx"`, `"module": "ESNext"`, `"moduleResolution": "bundler"`
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Install esbuild
|
||||
|
||||
```bash
|
||||
bun add -d esbuild
|
||||
```
|
||||
|
||||
### Part B: Create build script
|
||||
|
||||
Create `scripts/build-bundle.ts` (a Bun-runnable build script):
|
||||
|
||||
```ts
|
||||
// scripts/build-bundle.ts
|
||||
// Usage: bun scripts/build-bundle.ts [--watch] [--minify]
|
||||
|
||||
import * as esbuild from 'esbuild'
|
||||
import { resolve } from 'path'
|
||||
|
||||
const ROOT = resolve(import.meta.dir, '..')
|
||||
const watch = process.argv.includes('--watch')
|
||||
const minify = process.argv.includes('--minify')
|
||||
|
||||
const buildOptions: esbuild.BuildOptions = {
|
||||
entryPoints: [resolve(ROOT, 'src/entrypoints/cli.tsx')],
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
target: 'node20',
|
||||
format: 'esm',
|
||||
outdir: resolve(ROOT, 'dist'),
|
||||
outExtension: { '.js': '.mjs' },
|
||||
|
||||
// Inject the MACRO global before all other code
|
||||
inject: [resolve(ROOT, 'src/shims/macro.ts')],
|
||||
|
||||
// Alias bun:bundle to our runtime shim
|
||||
alias: {
|
||||
'bun:bundle': resolve(ROOT, 'src/shims/bun-bundle.ts'),
|
||||
},
|
||||
|
||||
// Don't bundle node built-ins or native packages
|
||||
external: [
|
||||
// Node built-ins
|
||||
'fs', 'path', 'os', 'crypto', 'child_process', 'http', 'https',
|
||||
'net', 'tls', 'url', 'util', 'stream', 'events', 'buffer',
|
||||
'querystring', 'readline', 'zlib', 'assert', 'tty', 'worker_threads',
|
||||
'perf_hooks', 'async_hooks', 'dns', 'dgram', 'cluster',
|
||||
'node:*',
|
||||
// Native addons that can't be bundled
|
||||
'fsevents',
|
||||
],
|
||||
|
||||
jsx: 'automatic',
|
||||
|
||||
// Source maps for debugging
|
||||
sourcemap: true,
|
||||
|
||||
minify,
|
||||
|
||||
// Banner: shebang for CLI + preload the MACRO global
|
||||
banner: {
|
||||
js: '#!/usr/bin/env node\n',
|
||||
},
|
||||
|
||||
// Handle the .js → .ts resolution that the codebase uses
|
||||
resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.json'],
|
||||
|
||||
logLevel: 'info',
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (watch) {
|
||||
const ctx = await esbuild.context(buildOptions)
|
||||
await ctx.watch()
|
||||
console.log('Watching for changes...')
|
||||
} else {
|
||||
const result = await esbuild.build(buildOptions)
|
||||
if (result.errors.length > 0) {
|
||||
console.error('Build failed')
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('Build complete → dist/')
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
```
|
||||
|
||||
**Important**: This is a starting point. You will likely need to iterate on the externals list and alias configuration. The codebase has ~1,900 files — some imports may need special handling. When you run the build:
|
||||
|
||||
1. Run it: `bun scripts/build-bundle.ts`
|
||||
2. Look at the errors
|
||||
3. Fix them (add externals, fix aliases, etc.)
|
||||
4. Repeat until it bundles successfully
|
||||
|
||||
Common issues you'll hit:
|
||||
- **npm packages that use native modules** → add to `external`
|
||||
- **Dynamic `require()` calls** behind `process.env.USER_TYPE === 'ant'` → these are Anthropic-internal, wrap them or stub them
|
||||
- **Circular dependencies** → esbuild handles these but may warn
|
||||
- **Re-exports from barrel files** → should work but watch for issues
|
||||
|
||||
### Part C: Add npm scripts
|
||||
|
||||
Add these to `package.json` `"scripts"`:
|
||||
|
||||
```json
|
||||
{
|
||||
"build": "bun scripts/build-bundle.ts",
|
||||
"build:watch": "bun scripts/build-bundle.ts --watch",
|
||||
"build:prod": "bun scripts/build-bundle.ts --minify"
|
||||
}
|
||||
```
|
||||
|
||||
### Part D: Create dist output directory
|
||||
|
||||
Add `dist/` to `.gitignore` (create one if it doesn't exist).
|
||||
|
||||
### Part E: Iterate on build errors
|
||||
|
||||
Run the build and fix whatever comes up. The goal is a clean `bun scripts/build-bundle.ts` that produces `dist/cli.mjs`.
|
||||
|
||||
**Strategy for unresolvable modules**: If modules reference Anthropic-internal packages or Bun-specific APIs (like `Bun.hash`, `Bun.file`), create minimal stubs in `src/shims/` that provide compatible fallbacks.
|
||||
|
||||
### Part F: Test the output
|
||||
|
||||
After a successful build:
|
||||
```bash
|
||||
node dist/cli.mjs --version
|
||||
# or
|
||||
bun dist/cli.mjs --version
|
||||
```
|
||||
|
||||
This should print the version. It will likely crash after that because no API key is configured — that's fine for now.
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun scripts/build-bundle.ts` completes without errors
|
||||
2. `dist/cli.mjs` exists
|
||||
3. `bun dist/cli.mjs --version` or `node dist/cli.mjs --version` prints a version string
|
||||
4. `package.json` has `build`, `build:watch`, `build:prod` scripts
|
||||
Reference in New Issue
Block a user