前置条件
- Node.js 20.19.4 或更高版本(CI 使用 Node 22)。
- 通过仓库检入版本使用 Yarn 3.6.1。
- Android 开发需要 Android Studio / JDK 17;RN 0.73/0.74 兼容 fixture 固定使用
- iOS 开发需要 Xcode 和 CocoaPods。
- 只有重新生成已检入 WebAssembly bundle 时才需要 Emscripten。
Gradle 8.3(本地可通过 GRADLE_EXECUTABLE 指定)。
安装
yarn install --immutable
根目录是库包,example/ 是 React Native 消费者应用。
核心质量门禁
yarn prepare
yarn typecheck
yarn lint
yarn test --runInBand
yarn test:native-operations
Web 门禁
yarn test:web
yarn test:web:browser
yarn test:web:metro
yarn test:package
yarn test:sdk
test:web检查 WebAssembly 往返和补丁 magic。test:web:browser在 Chrome 中运行公开 Worker API。test:web:metro证明 Metro 选择.web入口,而不是原生 TurboModule facade。test:package将真实 tarball 安装到干净消费者,验证 browser、ESM、CommonJS、test:sdk将准备好的 RN tarball 安装到隔离 Vite 消费者,验证/web与/toolkit、test:web:package构建并检查独立 Web tarball,在无 RN 依赖的干净消费者中验证包根与/toolkit。test:web:registry验证版本不存在、内容不符、网络失败与 provenance 策略等发布保护。
TypeScript 与可选 peer 行为。
生产资源加载和真实字节往返。
原生健壮性与兼容性
FUZZ_RUNS=2000 yarn test:fuzz
scripts/test-rn-android-compatibility.sh 0.73.11 old
scripts/test-rn-android-compatibility.sh 0.73.11 new
scripts/test-rn-android-compatibility.sh 0.74.7 new
scripts/test-rn-android-compatibility.sh 0.86.0 new
scripts/test-rn-ios-compatibility.sh 0.73.11 old
scripts/test-rn-ios-compatibility.sh 0.73.11 new
scripts/test-rn-ios-compatibility.sh 0.74.7 new
scripts/test-rn-ios-compatibility.sh 0.86.0 new
本地 Clang runtime 支持时,fuzz 门禁使用 libFuzzer、AddressSanitizer 与 UndefinedBehaviorSanitizer;否则运行确定性 sanitizer 语料。兼容 fixture 会使用所选 React Native artifact 直接编译真实 Android 模块源码,不依赖源码文本断言。 test:native-operations 会确定性覆盖 job 进度、取消、限制、畸形补丁、原子目标行为 和临时文件清理。
可复现的 Web 与原生性能基准命令:
yarn benchmark:web
BENCHMARK_OUTPUT=/tmp/web-wasm.json yarn benchmark:web
yarn benchmark:native
BENCHMARK_OUTPUT=/tmp/native-core.json yarn benchmark:native
每个输入尺寸都在独立进程中运行。两份报告都会记录峰值常驻内存;Web 报告还会记录 往返结束后仍存活的常驻、external 和 ArrayBuffer 内存。修改 buffer 所有权或补丁 格式前,可运行不阻塞 PR 的大文件 profiling:
BENCHMARK_OUTPUT=/tmp/web-large.json yarn benchmark:large:web
BENCHMARK_OUTPUT=/tmp/native-large.json yarn benchmark:large:native
大文件 profiling 使用 16、64、128 MiB fixture,可能消耗数 GiB 内存,因此不会作为 pull request 门禁。手动运行 Native Core Benchmark 时可以传入逗号分隔的尺寸列表, 以获得共享 Runner 基线。解读结果时应遵循大文件演进路线 中的范围和验收标准。
发布包 canary 会直接从 npm 安装,并有意使用当前 Vite 与 Expo 工具链;它们是定时 CI,不是发版门禁。可用 yarn test:registry:vite 和 yarn test:registry:expo 手动执行,并通过 PACKAGE_SPEC 验证指定 tag 或 tarball。
依赖安全
发布包没有 npm runtime dependency;React 与 React Native 都是可选 peer。 Dependabot 会把常规 npm、Ruby 与 Actions 更新分组,控制评审数量;对于 API 兼容 的叶子依赖,锁文件会直接固定到已修复版本。
yarn npm audit --all --recursive
示例与根工具链已升级到 React Native 0.86、CLI 20.2 与 release-it 20。升级后有 漏洞的 tmp、ip 链已不再安装;锁文件固定了已修复的 tar、 fast-xml-parser、socks 以及审计指出且 API 兼容的叶子覆盖。依赖变更后仍应 检查 GitHub Dependabot alerts,不能只根据 lockfile override 推断告警已经关闭。
站点与文档
yarn site:build
yarn site:test
yarn site:test:browser
静态输出写入 site-dist/,由 GitHub Pages 工作流部署。构建脚本把 docs/ 下的 Markdown 渲染到站点。英文页位于 docs/ 根部,中文镜像位于 docs/zh-CN/; 公开行为或 API 改动时应同步两种语言。
重新构建 WebAssembly
修改 cpp/ 后,激活 Emscripten 工具链并运行:
yarn build:web
yarn test:web
yarn test:web:browser
将两个重新生成的模块与 C 源码改动一起提交。Node 兼容的 web/bsdiffpatch.mjs 为 /node 和 CLI 保留 NODEFS;专用浏览器 web/bsdiffpatch.browser.mjs 为 /web Worker 图排除 Node runtime 分支。不要为了 隐藏打包器警告而互相替换两者。
原生验证
Android CI 编译旧架构边界与新架构源码,并在 pull request 中通过 RN 0.86 新架构 运行 API 24、31 设备测试。iOS 会编译 Pod 兼容 fixture,并在 Simulator 运行 RN 0.86 新架构;React Native 0.82 及以上已不再提供旧架构运行时。设备测试会断言 实际架构、跨平台 golden patch、损坏补丁拒绝、job 进度、取消、限制和输出清理。
native-benchmark.yml 属于手动与定时基础设施,只上传 Linux/macOS JSON 基线; 共享 Runner 波动较大,因此不会阻塞 pull request。
本地示例命令见仓库 CONTRIBUTING.md。
发布检查清单
- 执行核心、Web 和站点门禁。
- 运行
yarn test:package、yarn test:sdk,并检查npm pack --dry-run。 - 确认公开文档与导出的 TypeScript 声明一致。
- 确认中英文指南描述同一套公开行为。
- 准备好的
package.json版本确定后,使用yarn release --no-increment创建 - GitHub Release 发布后会触发
npm-publish.yml。工作流校验 tag 与 - 对外发布前验证 npm 包和 GitHub Release。
pack 命令会运行 prepack contract 检查;也可直接运行 node scripts/check-package-contract.mjs。
release commit、tag 和 GitHub Release;仅在维护者明确授权时运行。
package.json 版本一致,执行发布门禁,通过 npm Trusted Publishing 发布, 并验证 provenance 证明。
npm 包的 Trusted Publisher 已按以下值配置完成:
- Provider:GitHub Actions。
- Organization or user:
JimmyDaddy。 - Repository:
react-native-bs-diff-patch。 - Workflow filename:
npm-publish.yml。 - Environment:留空。
正常发布无需再修改 npm 侧配置,工作流也不使用长期 npm token。
上面的清单针对已有的 react-native-bs-diff-patch 包。独立的 bs-diff-patch-web 使用 web-v0.5.0 tag 命名空间独立发布,不替代、不弃用也不重新发布 React Native 包。Node 文件系统操作、CLI 及其发布工具继续属于 react-native-bs-diff-patch。 首版本地发布、随后配置 Trusted Publishing、独立 web-npm-publish.yml 和同内容重试规则 见独立 Web 包设计。
npm 发布失败后的恢复
对于已有 tag 和已发布的 GitHub Release(以下示例使用 v0.5.0),恢复流程会复用已有 release。重试失败的 npm-publish.yml 前,先检查 registry:
npm view react-native-bs-diff-patch@0.5.0 version \
dist.attestations.provenance.predicateType --registry=https://registry.npmjs.org/
如果 0.5.0 已经存在,不要再次运行 npm publish,只补做 provenance 和 registry 消费者检查,例如 PACKAGE_SPEC=react-native-bs-diff-patch@0.5.0 yarn test:sdk,以及适用的 yarn test:registry:vite 或 yarn test:registry:expo。只有官方 registry 查询明确返回 E404 时才可继续重试;网络错误、403、超时或其他不确定结果都必须停止恢复流程。修复发布工具或 fixture 后,将修复合并到 main,再从 main 重试已有 GitHub Release:
gh workflow run npm-publish.yml --ref main -f release_tag=v0.5.0
gh run list --workflow npm-publish.yml --limit 5
gh run watch <run-id>
重试完成后,先检查 workflow run、provenance 元数据和 registry smoke 输出,再宣布版本可用。
手动 workflow 只接受已经发布的 GitHub Release。它会从精确的 refs/tags/<release_tag> checkout 并确认 HEAD 就是该 tag 的 commit,然后检查 release tag 与 package.json 版本一致、tag 和 workflow commit 可从 main 到达,以及 npm 中尚不 存在该版本。质量门禁期间可以临时使用 workflow commit 中的 test-sdk-consumers harness, 打包前恢复 tag 中的脚本,并断言 tracked tree 干净。完整门禁、npm OIDC Trusted Publishing、 provenance 校验和发布包 smoke test 均保留在 workflow 中。
npm 12 的跨版本 fixture 必须通过官方 registry(https://registry.npmjs.org/)解析精确的 包版本,并比对预期的 SHA-512 SRI。不要恢复下载 URL fixture,也不要为了绕过 npm 默认的 URL 策略而削弱完整性断言。
不要移动或删除已有 tag,不要对同一版本再次运行 release-it,也不要修改 npm Trusted Publisher 配置。重试只修复已有 GitHub Release 的发布路径,不会创建第二个 release。