news 2026/9/15 15:09:57

使用 Nx 构建 Bitwarden Monorepo:命令速查、项目配置与缓存机制实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 Nx 构建 Bitwarden Monorepo:命令速查、项目配置与缓存机制实战指南

使用 Nx 构建 Bitwarden Monorepo:命令速查、项目配置与缓存机制实战指南

【免费下载链接】clientsBitwarden client apps (web, browser extension, desktop, and cli).项目地址: https://gitcode.com/GitHub_Trending/cl/clients

本指南以 Bitwarden 客户端仓库中的 using-nx-to-build-projects.md 为骨架,系统讲解如何借助 Nx 在包含 web、浏览器扩展、桌面端与 CLI 的巨型 monorepo 中高效完成构建、测试、lint 与增量构建。读完本文,你将掌握 Nx 命令的完整用法、project.json中两类库的集成模式(Legacy Facade 与现代原生 Executor)、构建配置(Configuration)的选择逻辑,以及 Nx 缓存与依赖图的底层工作方式,能够独立在本地与 CI 中正确驱动 Bitwarden 全量构建。

认识 Nx 在 Bitwarden 仓库中的角色

Bitwarden 客户端代码库(README.md 中定义为 web、browser extension、desktop、cli 四大客户端应用)是一个庞大的 monorepo,包含apps/下的多个应用、libs/下的数十个共享库,以及bitwarden_license/下的商业授权代码。仓库引入 Nx 的核心目的,是让从 monorepo 中构建单个项目变得更加容易:统一命令入口、按依赖图精准调度、并通过缓存跳过未变更项目的重复构建。

使用 Nx 的基本模式是:先查阅项目目录下的project.json文件,了解该项目可用的命令(target)及其名称,再以npx nx [your_command] [your_project] [your_options]的形式执行。运行npx nx --help可查看大量可用选项。

需要特别注意的是,当前仓库的 Nx 实现仍在演进中(work in progress):CI 仍使用旧的 npm 构建流程,且存在许多通过兼容技巧接入 Nx 项目图的"legacy"库。这一点在阅读下文两类库的差异时会反复体现。

快速上手:常用命令速查

基本命令

以下命令完整覆盖了日常构建、测试、lint、serve 与批量操作:

# 构建一个项目 npx nx build cli npx nx build-native desktop # 部分应用有特殊的构建命令(如桌面端的原生模块) npx nx build state # 现代库与应用使用简单的小写 target 名称 npx nx build @bitwarden/common # 旧版库采用特殊命名约定,需携带 @bitwarden 前缀 # 测试一个项目 npx nx test cli # Lint 一个项目 npx nx lint cli # 监听模式运行/开发一个项目(仅对配置了 serve target 的项目生效) npx nx serve cli # 只构建所有相对 origin/main 有变更的项目(affected) nx affected --target=build --base=origin/main # 一次性对所有项目执行 build、test、lint npx nx run-many --target=build,test,lint --all # 大多数项目默认使用 "oss-dev" 配置,如需商业授权构建请追加 --configuration npx nx build cli --configuration=commercial-dev # 需要生产构建时,去掉 "dev" 后缀 npx nx build cli --configuration=oss # 或 "commercial" # 配置同样可以传递给 run-many # 例如:运行所有 Bitwarden 商业授权构建 npx nx run-many --target=build,test,lint --all --configuration=commercial # 产物统一输出到根级 /dist/ 目录 # 运行本地构建出的 CLI node dist/apps/cli/oss-dev/bw.js

结合仓库源码,可以对上述命令做如下深化理解:

  • npx nx build cliapps/cli/project.jsonbuildtarget 使用@nx/webpack:webpackexecutor,并通过defaultConfiguration: "oss-dev"(apps/cli/project.json)声明默认配置,因此不带--configuration时默认走 oss-dev 开发构建。
  • npx nx build-native desktop:桌面端应用在 apps/desktop/project.json 中定义了build-nativetarget,通过nx:run-commandsapps/desktop/desktop_native目录执行node build.js,用于编译 Rust 编写的原生模块,然后再由buildtarget 通过dependsOn: ["build-native"]并行编排build-mainbuild-preloadbuild-renderer三个子构建(apps/desktop/project.json)。
  • --configuration=commercial-dev:以 CLI 为例,commercial系列配置会把webpackConfigmaintsConfig整体切换到商业授权代码库 bitwarden_license/bit-cli/webpack.config.js 对应的入口(apps/cli/project.json)。

全局命令

# 查看所有项目 npx nx show projects # 仅运行受影响的项目(非常适合本地开发与 CI) npx nx affected:build npx nx affected:test npx nx affected:lint # 展示依赖图 npx nx dep-graph

affected系列命令是 Nx 增量能力的核心体现:它会基于 git 历史(默认基线main,见 nx.json)计算自基线以来变更的项目集合,只对受影响的子集执行对应 target,从而显著缩短本地与 CI 的构建时间。

项目配置入口:project.json 与两类库集成模式

仓库中的库(library)依据 Nx 迁移进度分为两种集成模式,理解二者的差异是正确构建的前提。

Legacy Libraries(旧版库,Facade 门面模式)

绝大多数现有库仍采用门面(facade)模式:其project.json将 target 委托给既有的 npm scripts,从而保持引入 Nx 之前构建方式的向后兼容。这些库被视为技术债务(tech debt),Platform 团队正着力于将其升级为现代模式。典型示例见 libs/common/project.json。

这类库使用nx:run-scriptexecutor 调用既有的 npm scripts:

{ "targets": { "build": { "executor": "nx:run-script", "options": { "script": "build" } } } }

例如 libs/common/package.json 中定义的真实脚本为:cleanrimraf dist)、buildnpm run clean && tsc)、build:watchnpm run clean && tsc -watch)、testjest)。也就是说,npx nx build @bitwarden/common最终等价于在libs/common下执行npm run build,其产物默认输出到libs/common/dist/

旧版库的标准命令集合

  • nx build <library>—— 构建库
  • nx build:watch <library>—— 构建并监听文件变更
  • nx clean <library>—— 清理构建产物
  • nx test <library>—— 运行测试
  • nx lint <library>—— 运行 lint

注意旧版库的命名约定:项目名携带@bitwarden前缀(如@bitwarden/common),与tsconfig.base.json中路径映射(如"@bitwarden/state": ["./libs/state/src/index.ts"],见 tsconfig.base.json)保持一致。

Modern Libraries(现代库,原生 Nx Executor)

较新的库(如libs/state)直接使用 Nx 原生 executor,以获得更好的性能与缓存能力:

{ "targets": { "build": { "executor": "@nx/js:tsc", "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/libs/state" } } } }

以 libs/state/project.json 为例,其buildtarget 使用@nx/js:tsc,通过tsConfig: "libs/state/tsconfig.lib.json"指定编译选项,outputs声明产物路径dist/libs/state,从而使 Nx 能够将该输出纳入缓存管理;testlint则分别使用@nx/jest:jest@nx/eslint:lint原生 executor。现代库使用简单的小写 target 名(如buildtestlint),且项目名不带@bitwarden前缀。

应用级构建配置:Configuration 与特殊 Target

除了库之外,应用(application)的project.json往往更复杂,本节以三个典型应用说明。

CLI:webpack + 四种配置

apps/cli/project.json 的build使用@nx/webpack:webpack,定义了四种 configuration:

配置mode输出路径入口与配置来源
oss-dev(默认)developmentdist/apps/cli/oss-devapps/cli/src/bw.ts
ossproductiondist/apps/cli/oss同上
commercial-devdevelopmentdist/apps/cli/commercial-devbitwarden_license/bit-cli/src/bw.ts
commercialproductiondist/apps/cli/commercial同上

由此可印证原文档的规则:去掉 "dev" 后缀即得到生产构建;而商业授权构建需要额外--configuration=commercial[-dev]

Browser 扩展:多浏览器 × 多 Manifest 版本

apps/browser/project.json 是配置最丰富的应用,其build通过env环境变量(BROWSERMANIFEST_VERSIONNODE_ENV)区分 chrome、edge、firefox(含 MV2/MV3)、opera、safari(含 MV2/MV3)等 12 个开源配置,外加commercial-*系列商业授权变体;servetarget 则通过nx:run-commands直接调用webpack --watch(apps/browser/project.json),并设置NODE_OPTIONS="--max-old-space-size=8192"以支撑大体积打包。

Desktop:特殊 Target 编排

apps/desktop/project.json 展示了"部分应用有特殊构建命令"的实例:除标准build外,还定义了build-native(编译 Rust 原生模块)、build-mainbuild-preloadbuild-renderer等独立 target,build通过dependsOn与并行commands数组统一编排它们(apps/desktop/project.json)。这类应用不能简单地用npx nx build desktop理解全部流程,需要先查看project.json确认命令名称。

当你运行一条 Nx 命令时发生了什么

原文档用一张 Mermaid 流程图完整刻画了命令执行链路,本文完整保留并逐段解读:

从仓库源码可以进一步印证图中的"读取 workspace 配置"环节:

  • nx.json 声明了缓存目录cacheDirectory: ".nx/cache"、默认基线defaultBase: "main"namedInputs(区分defaultproductionsharedGlobals三组输入集合)、最大并行度parallel: 4,以及四条插件配置:@nx/js@nx/js:tscconfigName: tsconfig.lib.json)、@nx/jest/plugin@nx/eslint/plugin,以及 Bitwarden 自研的@bitwarden/nx-plugin(用于提供自定义生成器与 executor,见 libs/nx-plugin/package.json)。
  • 图中提到 ESLint 读取.eslintrc.json,但仓库根级实际采用扁平化配置 eslint.config.mjs(现代库如libs/statelintFilePatterns同样由@nx/eslint:lint驱动),具体以仓库当前版本为准。
  • 图中 Legacy 路径输出到libs/LIB/dist/、现代库输出到dist/libs/LIB/、webpack 应用输出到dist/apps/<app>/,这与前文libs/common/package.jsonlibs/state/project.json的实际输出路径完全一致。

缓存与性能

Nx 自动缓存

Nx 会自动缓存构建输出,并且只重建真正发生变更的部分:

# 首次运行:构建所有内容 npx nx build cli # 第二次运行:命中缓存(明显更快) npx nx build cli

缓存机制的实现细节体现在 nx.json 的targetDefaults.build中:inputs: ["production", "^production"]定义了构建的输入集合(production输入会排除*.spec.tstsconfig.spec.json,见 nx.json),outputs: ["{options.outputPath}"]让 Nx 明确知道产物位置,cache: true开启缓存。只有当输入哈希一致时才能命中缓存并跳过执行;任何输入变更都会导致缓存失效并重新构建。

清空缓存

# 清空全部缓存 npx nx reset

当需要验证干净构建、或缓存出现异常时使用npx nx reset,它等价于清理.nx/cache缓存目录并重置 Nx 状态。

深入阅读指引

  • Nx 官方入门文档与命令参考(npx nx --help可查看本机安装版本的全部选项);
  • 仓库级构建配置:nx.json;
  • 应用级配置示例:apps/cli/project.json、apps/browser/project.json、apps/desktop/project.json;
  • 两类库配置对比:libs/common/project.json(Legacy 门面模式)与 libs/state/project.json(现代原生 executor);
  • 旧版库实际 npm 脚本:libs/common/package.json;
  • 路径映射与依赖解析:tsconfig.base.json;
  • 自研 Nx 插件:libs/nx-plugin/package.json;
  • 依赖图可视化:npx nx dep-graph

【免费下载链接】clientsBitwarden client apps (web, browser extension, desktop, and cli).项目地址: https://gitcode.com/GitHub_Trending/cl/clients

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 15:08:52

怎么做网页链接图片怎么选

3步搞定网页链接图片怎么做:避开高价坑,选型全解析 找建站公司怕被坑高价,这是很多运营推广人员的噩梦。你只想要一个能点击跳转的网页链接图片,对方却报价几千块,还塞给你一堆用不上的“高级功能”。到底怎么做网页链接图片,同时 怎么选…

作者头像 李华
网站建设 2026/9/15 15:04:50

Mac 窗口管理只要 3 步快捷键:用 Loop 告别手动拖拽

Mac 窗口管理只要 3 步快捷键&#xff1a;用 Loop 告别手动拖拽 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop Loop 是一款免费开源的 Mac 窗口管理工具&#xff0c;支持径向菜单、键盘快捷键和窗口自…

作者头像 李华
网站建设 2026/9/15 15:03:29

Vue聊天室@功能实现:vue-tribute组件配置与实战指南

简介&#xff1a;一个名为vue-tribute-demo的基于Vue与Tribute实现的聊天室提及功能示例项目&#xff0c;面向需要在Web应用中添加动态用户标记能力的JavaScript/Vue开发者。项目覆盖了触发后的异步用户查询、匹配列表的动态渲染、选中用户后的数据回填&#xff0c;以及取消提及…

作者头像 李华
网站建设 2026/9/15 15:03:07

博客网站需要的功能图解步骤避坑指南

博客网站需要的功能图解步骤避坑指南 上周三凌晨两点,我盯着屏幕上的需求变更单,血压瞬间飙升。客户指着后台管理界面说:“把这里改成圆角,字体再大一号,那个侧边栏我要挪到左边去。”我回复:“好,今晚上线。”结果建站公司的项目经理第二天早上才回我消息,说开发排期要一周。那一周里,我的博客流量掉了15%,因…

作者头像 李华
网站建设 2026/9/15 15:02:29

Flutter跨端开发实战:一套代码搞定iOS与Android的全链路经验

选 Flutter 这件事&#xff0c;最开始其实是有点“被逼无奈”的。我们团队当时接了一个工具类 App&#xff0c;要求同时上 iOS 和 Android&#xff0c;预算只有一份&#xff0c;人力也只有两个人&#xff0c;一个偏前端一个偏后端。原生双端并行开发&#xff0c;不说两套代码维…

作者头像 李华