- CLI
- 开发工具
- 前端构建
- 构建工具
- 代码生成
- 前端
【免费下载链接】angular-cli
CLI tool for Angular
本篇指南围绕当前开源仓库(angular-cli,即 Angular CLI 与 Angular DevKit 的 monorepo)的官方开发者文档 docs/DEVELOPER.md 展开,完整覆盖从环境准备、本地构建、将本地构建产物接入示例项目、断点调试、Bazel 单元测试与端到端测试,到 IDE 配置、CPU 性能分析、新增包以及 Windows 开发的全部流程。读完本文,你将掌握一套可直接复现的本地开发闭环:修改源码 → 本地构建出 tarball → 安装到示例项目验证 → 用调试器与测试套件定位问题。
环境准备:从 Fork 到安装依赖
在开始之前,先确认基础环境满足仓库要求。官方文档给出的步骤是:
- 如果还没有做过,先对 angular-cli 仓库创建一份自己的 fork;
- Windows 用户请先阅读文末的 Windows 章节,其中说明了为贡献代码而需要额外执行的步骤;
- 使用
git将 fork 后的仓库克隆到本地; - 安装 Node.js。开发文档要求Node
v20.19.0或更高版本,并且需要安装pnpm作为包管理器(安装方式:npm i -g pnpm@9); - 在仓库根目录执行
pnpm install安装全部依赖。
需要特别说明的是,Node 与 pnpm 的具体版本要求以仓库实际配置为准。当前仓库根目录的 package.json 中通过engines字段声明了更严格的约束("node": "^22.22.3 || ^24.15.0 || >=26.0.0"、"pnpm": "12.4.2"),同时声明"packageManager": "pnpm@12.4.2",并且pnpm-workspace.yaml设置了engineStrict: true,意味着版本不匹配时 pnpm 会直接拒绝安装。如果你的本地环境与开发文档的宽松要求之间存在差异,请以根 package.json 中当前声明的版本为准。
此外,这是一个 pnpm workspace 管理的 monorepo。根目录的 pnpm-workspace.yaml 列出了所有被纳入 workspace 的包(如packages/angular/cli、packages/angular_devkit/*、packages/schematics/angular、packages/ngtools/webpack、modules/testing/builder以及tests本身),并使用hoist: false关闭依赖提升、autoInstallPeers: false关闭 peer 依赖自动安装。这些配置与仓库底层基于 Bazel(rules_js)的构建体系保持一致,避免 pnpm 的node_modules布局与 Bazel 布局产生差异。
本地构建与安装 CLI:pnpm build --local
完成依赖安装后,即可构建本地版本:
pnpm build --local这条命令背后是根 package.json 中定义的脚本链路:"build": "pnpm --silent admin build",其中admin脚本通过 scripts/devkit-admin.mts 动态加载并执行build.mts;--local参数则对应 .bazelrc 中的build:local --//:enable_package_json_tar_deps配置,用于在本地构建时启用将各个包的package.json打进 tarball 的依赖。
构建完成后,会在dist/目录下生成一批 tarball(.tgz)。要真正用上这些本地构建的产物,需要切换到另一个用于复现问题的仓库(例如直接执行ng new生成的示例工程),然后把本地构建的包安装进去:
cd "${EXAMPLE_ANGULAR_PROJECT_REPO}" npm install -D ${CLI_REPO}/dist/*.tgz安装完成后,这个示例项目的构建就会使用前面本地构建出来的工具链,并包含你本地的所有改动。
本地安装的自动发现机制
Angular CLI 有一个贴心的设计:当你在示例项目里执行ng命令时,CLI 会自动检测项目内是否存在本地构建的安装,如果存在就优先使用它。因此,你只需要全局安装一次官方发布的 CLI 作为"兜底":
npm install -g @angular/cli之后在示例项目中运行任何ng命令,都会自动找到并优先使用本地构建的 CLI 版本,无需手动切换路径。这一点可以从 packages/angular/cli/package.json 中bin字段("ng": "bin/ng.js")与main字段("lib/cli/index.js")看到 CLI 入口的组织方式。
测试ng update时的注意事项
如果你正在测试ng update的行为,需要格外小心:把dist/*.tgz全部安装进项目,会把框架(@angular/core)也一并升级到最新版本,这样你就无法在"旧框架 + 新 CLI"的组合下测试升级流程。正确的做法是只单独安装 CLI 这一个包:
npm install -D ${CLI_REPO}/dist/_angular_cli.tgz这样项目其余部分保持原状,留给真正的ng update去完成升级。
调试 CLI 调用
调试 CLI 的首选方式是:先按上一节的方法为示例项目构建并安装本地 CLI,然后以 Node 调试模式运行ng命令:
node --inspect-brk node_modules/.bin/ng <command>--inspect-brk会在 CLI 启动的一瞬间触发断点,此时你可以用 IDE 支持的任意调试机制连接上来;最简单的做法是打开 Chrome 的chrome://inspect,然后点击node_modules/.bin/ng这个 Node 目标旁边的inspect链接。
一个需要了解的坑:CLI 在执行过程中会动态地require()其他文件,调试器在运行前并不知道全部源码文件,因此很难在 CLI 尚未加载的文件上提前设置断点。最实用的绕行方案是在你关心的文件里直接写一行debugger;语句,让执行停在该处,之后再正常地单步调试和设置断点。
测试体系:Bazel 单元测试与端到端测试
仓库内有两套可以在本地运行的测试套件。
单元测试(Unit tests)
- 运行全部测试:
pnpm bazel test //packages/... - 运行子集测试,需要给出完整的 Bazel 目标,例如:
pnpm bazel test //packages/schematics/angular:angular_test - 查看完整的测试目标列表,用 Bazel 查询:
pnpm bazel query "tests(//packages/...)"
这里的pnpm bazel对应根 package.json 中的"bazel": "bazelisk",即通过 Bazelisk 按仓库 .bazelversion 指定的版本启动 Bazel。调试某个具体测试时,把describe()改成fdescribe()、it()改成fit()即可聚焦执行单个测试,输出更干净、执行更快,不用跑无关用例。
Bazel 的 Jasmine 测试调试细节还可以参考仓库内的 docs/process/bazel.md:Linux 下 Bazel 测试默认在沙箱中运行,可以通过给规则加local = True或传--test_output=streamed强制本地执行;被shard_count分片的测试在聚焦少量用例时可能因某些分片执行 0 个测试而报错,被flaky标记的测试失败后会重跑——聚焦调试时可以用--config=debug与--config=no-sharding组合关掉分片和重跑(见 .bazelrc 中的test:debug与test:no-sharding配置,no-sharding会设置--flaky_test_attempts=1并禁用分片策略)。
端到端测试(End to end tests)
- 查看完整测试目标:
pnpm bazel query "tests(//tests/...)" - 运行子集测试,例如:
pnpm bazel test //tests:e2e_node22 --config=e2e --test_filter="tests/i18n/ivy-localize-*" - 调试失败用例,用
bazel run:pnpm bazel run //tests:e2e_node22 --config=e2e --test_arg="--glob=tests/basic/aot.ts" - 通过
--test_arg传递额外的e2e_runner选项,例如:--test_arg="--package-manager=yarn"
运行调试命令时 Node 会停下来等待调试器附加,你可以让 IDE 连上调试器设置断点、单步执行(也可见下文 IDE 特定用法)。--config=e2e同样定义在 .bazelrc 中:test:e2e --test_timeout=3600 --experimental_ui_max_stdouterr_bytes=2097152,并设置--flaky_test_attempts=2容忍偶发失败。
关于 e2e 运行器的可选参数,可以阅读 tests/e2e_runner.ts 顶部的注释说明,常用选项包括:
--debug:测试失败后阻塞线程,不删除临时目录,便于现场排查;--glob:按 glob 模式筛选要运行的测试(相对于tests/e2e/),默认是tests/**/*.js;--ignore:忽略匹配该 glob 的测试;--package-manager:指定测试使用的包管理器(默认npm,也支持yarn、pnpm、bun,见 tests/e2e/utils/packages.ts);--package:在运行测试前需要发布到本地 registry 的 npm 包(默认./dist/_*.tgz);--ng-snapshots/--ng-tag:在测试项目中安装 Angular 的 snapshot 构建或指定 tag 的构建;--shard/--nb-shards:按分片并行执行测试。
从 tests/e2e_runner.ts 的实现可以看到,e2e 运行时会先在临时目录起一个本地 npm registry(createNpmRegistry),然后依次执行setup(如 tests/e2e/setup/010-local-publish.ts 发布本地包、100-global-cli.ts安装全局 CLI)、initialize(创建测试项目)与test(在测试项目中逐条运行用例)三个阶段,最后自动清理临时目录。
IDE 特定用法
IntelliJ IDEA / WebStorm
在 IntelliJ 系列产品中打开该仓库时,直接Open仓库文件夹即可,不要选择Import Project——那会覆盖仓库里已有的配置。打开后,编辑器会自动识别 workspace 中的运行配置,用下拉框选择一个配置再点击Run即可启动。需要注意的是:执行调试目标时,务必点击Debug图标让 IDE 自动附加调试器;如果误点了Run,Node 会一直等待调试器附加而无限期挂起。
下图展示了 IntelliJ IDEA 中已自动识别的运行配置列表(选中Angular Application配置):
VS Code
在 Visual Studio Code 中调试 Angular CLI 行为时,可以先运行npm run build,然后使用如下 launch 配置:
{ "type": "node", "request": "launch", "name": "ng serve", "cwd": "<path to an Angular project generated with Angular-CLI>", "program": "${workspaceFolder}/dist/@angular/cli/bin/ng", "args": [ "<ng command>", ...other arguments ], "console": "integratedTerminal" }随后就可以在dist/@angular目录下的文件里设置断点了。仓库自带的 .vscode/settings.json 已预先排除了node_modules、bazel-out、dist、dist-schema等目录的监视与搜索,避免编辑器误入构建产物目录。
CPU 性能分析
排查性能问题时,CPU profile 非常有用。Node.js 16 及更高版本可以直接用命令行参数--cpu-prof生成 CPU profile:
node --cpu-prof node_modules/.bin/ng build生成.cpuprofile文件后,用 Chrome DevTools 打开即可分析:
- 在 Chrome 中打开
chrome://inspect; - 点击 "Open dedicated DevTools for Node";
- 切换到 "profiler" 标签页;
- 点击 "Load" 按钮并选择生成的
.cpuprofile文件; - 在左侧面板选中对应的文件查看火焰图与调用统计。
创建新包:devkit:package与模板管理
往这个 monorepo 里新增一个包,需要依次执行两条命令:
schematics devkit:package PACKAGE_NAME:更新 .monorepo.json 文件,并为新包创建基础文件(package.json、src/index等);pnpm admin templates:更新 README 以及其他可能受新包影响的模板文件。
这里的pnpm admin templates同样经由根 package.json 的admin脚本进入 scripts/devkit-admin.mts,再派发到templates.mts。如果是私有包(不对外发布),需要手动在新包的package.json中添加"private": true字段,然后重新运行一次模板管理脚本以同步模板输出。
Windows:使用 WSL 进行贡献
在 Windows 机器上为 Angular 贡献代码,官方推荐的路径是使用 Windows Linux 子系统(WSL):
- 以管理员身份在 PowerShell 中运行
wsl --install; - 重启机器;
- 在终端运行
wsl进入 WSL 环境; - 之后按本指南照常在 Linux 环境下继续开发。
官方明确说明:这一建议仅针对为 Angular 代码库本身贡献代码的场景——Angular 继续通过ngCLI 完整支持 Windows 原生开发,并且每次代码变更都会在 Windows 上严格测试。
小结
从 docs/DEVELOPER.md 可以看到,angular-cli 仓库为贡献者设计了一条清晰可复现的开发链路:pnpm install准备环境 →pnpm build --local产出dist/tarball → 安装到示例项目验证改动 →node --inspect-brk断点调试 →pnpm bazel test //packages/...与//tests:e2e_node22 --config=e2e分层回归。配合 docs/process/bazel.md、docs/README.md 以及 tests/e2e_runner.ts 等仓库内资料,你可以在不改动官方发布流程的前提下,安全地在本地迭代 CLI 源码并验证每一个改动。
- CLI
- 开发工具
- 前端构建
- 构建工具
- 代码生成
- 前端
【免费下载链接】angular-cli
CLI tool for Angular
相关推荐
OpenHuman 开发者指南:从源码构建、测试到发布的完整工作流
OpenHuman 开发者指南:从源码构建、测试到发布的完整工作流 OpenHuman 是一个面向 Mac、Windows、Linux 的开源个人 AI 桌面应
人工智能AI 应用本地部署AI Agent交互助手深度研究Jest 仓库贡献指南:从本地构建、集成测试到 Pull Request 的完整开发工作流
Jest 仓库贡献指南:从本地构建、集成测试到 Pull Request 的完整开发工作流 本文以 Jest 仓库的官方贡献文档 CONTRIBUTING.md
测试质量保障代码覆盖率开发工具FrankenPHP 开发者指南:从源码编译、测试到 GDB 调试的完整工作流
FrankenPHP 开发者指南:从源码编译、测试到 GDB 调试的完整工作流 本指南基于仓库 docs/pt br/CONTRIBUTING.md https
后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考