# Step 18 — Phase 6.1: 构建脚本 **依赖**: Step 15(extension.ts 完成) **参考设计**: §15 ## 目标 搭建 esbuild 构建流程,替换 tsc 为打包构建,更新 package.json 脚本。 ## 文件变更 | # | 文件 | 操作 | 说明 | |---|------|------|------| | 1 | `scripts/build.mjs` | 新建 | esbuild 打包脚本 | | 2 | `package.json` | 修改 | 更新 build/vscode:prepublish 脚本 | ## 前置准备 ```bash npm install --save-dev esbuild@^0.28.1 ``` --- ## 1. `scripts/build.mjs` ```javascript import * as esbuild from 'esbuild'; import { copyFileSync, mkdirSync, existsSync, cpSync } from 'fs'; import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const rootDir = resolve(__dirname, '..'); const outDir = resolve(rootDir, 'out'); if (!existsSync(outDir)) { mkdirSync(outDir, { recursive: true }); } await esbuild.build({ entryPoints: [resolve(rootDir, 'src', 'extension.ts')], bundle: true, outfile: resolve(outDir, 'extension.js'), external: [ 'vscode', 'eslint', 'stylelint', 'child_process', 'fs', 'path', 'url', 'os', ], format: 'cjs', platform: 'node', target: 'node22', minify: true, sourcemap: false, treeShaking: true, }); const jarsSrc = resolve(rootDir, 'jars'); const jarsDest = resolve(outDir, 'jars'); if (existsSync(jarsSrc)) { cpSync(jarsSrc, jarsDest, { recursive: true, force: true }); } console.log('Build complete.'); ``` --- ## 2. `package.json` 脚本更新 ```json { "scripts": { "compile": "tsc -p ./", "watch": "tsc -watch -p ./", "build": "node scripts/build.mjs", "vscode:prepublish": "npm run build", "pretest": "npm run compile && npm run lint", "lint": "eslint src", "test": "vscode-test" } } ``` --- ## 关键逻辑 - `external`: vscode API、npm 包、Node 内置模块不打包 - `format: 'cjs'`: VSCode 扩展需要 CommonJS - `target: 'node22'`: 对应 VSCode 1.120+ 的 Node 版本 - `minify: true`: 产物压缩 - `treeShaking: true`: 移除未使用代码 - 复制 `jars/` 目录到 `out/` 供运行时加载 - `vscode:prepublish` 改为 `npm run build`(生产打包) --- ## 验收 - [ ] `npm run build` 成功执行 - [ ] `out/extension.js` 生成(单文件 bundle) - [ ] `out/jars/` 目录存在 - [ ] F5 启动扩展开发宿主功能正常