- 前端
- UI组件
【免费下载链接】react-intersection-observer
React implementation of the Intersection Observer API to tell you when an element enters or leaves the viewport.
react-intersection-observer是一个基于 TypeScript、采用 PNPM workspaces 管理的 React 开源仓库,其核心交付物是通过 Intersection Observer API 为骨架,结合仓库内真实的配置文件、源码与测试用例,完整梳理一条贡献者路径:从搭建本地开发环境、编写与测试代码、遵循提交规范,到最终由 CI 自动发布到 npm 的全过程。读完本文,你将掌握该仓库的开发命令、测试架构、代码规范与发布机制,能够直接上手提交高质量的 PR。
仓库概览:三个 workspace 应用的分工
整个仓库是一个 PNPM monorepo,由根目录 pnpm-workspace.yaml 声明apps/*与packages/*两个包分组:
packages: - apps/* - packages/*CONTRIBUTING.md 明确划分了三个工作区:
- packages/react-intersection-observer:对外发布的正式包,包含
useInViewHook 和InView组件。从源码 packages/react-intersection-observer/src/index.tsx 可以看到它实际导出四样东西:InView(渲染属性组件)、useInView(状态型 Hook)、useOnInView(副作用回调型 Hook)以及底层observe工具函数。 - apps/storybook:用于开发与测试的 Storybook 项目,端口固定为 9000,其
dev脚本为storybook dev -p 9000(见 apps/storybook/package.json),存放于 apps/storybook/stories 的 stories 覆盖了InView、useInView、useOnInView三种用法。 - apps/docs:基于 Blume 构建的文档站点,开发命令为
blume dev(见 apps/docs/package.json),其内容目录在 apps/docs/docs。
根目录 package.json 中的脚本把这三个工作区串成统一的开发入口,同时 turbo.json 为build、test、lint、typecheck、dev等任务定义了缓存与依赖关系(例如test依赖^build,dev关闭缓存并标记为persistent)。
本地开发环境搭建
1. 克隆与安装依赖
贡献的第一步是 fork 仓库、克隆到本地,然后用PNPM安装依赖:
pnpm install仓库根目录 package.json 通过packageManager字段锁定了pnpm@10.5.2,并在pnpm-workspace.yaml中声明了onlyBuiltDependencies(@biomejs/biome、esbuild、msw、simple-git-hooks),确保安装阶段需要执行构建脚本的依赖被正确允许。
2. 启动开发服务器
CONTRIBUTING.md 推荐直接启动全部应用:
pnpm dev该命令实际展开为(见根目录 package.json):
"dev": "pnpm --parallel --filter react-intersection-observer --filter storybook --filter docs dev"即并行启动包源码、Storybook 与文档站点三个dev任务。如果只想启动其中一个,可以分开执行:
pnpm dev:storybook pnpm dev:docspnpm dev:storybook对应pnpm --filter storybook dev,pnpm dev:docs对应pnpm --filter docs dev。包自身的 watch 构建则通过pnpm --filter react-intersection-observer dev:package(内部为tsup src/index.tsx --watch)完成。
语义化版本管理
CONTRIBUTING.md 声明项目遵循Semantic Versioning 2.0,版本号格式为<major>.<minor>.<patch>:
- major:破坏性变更(Breaking changes)或新功能;
- minor:向后兼容的功能增强;
- patch:Bug 修复与文档变更。
这一约定在仓库中有两处直接体现。一是 packages/react-intersection-observer/package.json 中当前版本为11.0.0;二是发布工作流 .github/workflows/release.yml 用pnpm exec bumpp ${{ inputs.version }} --yes执行版本号提升——version输入的可选项正是patch、minor、major以及prepatch、preminor、premajor、prerelease等预发布变体,与 SemVer 规范一一对应。
Pull Request 流程与提交规范
CONTRIBUTING.md 要求在每个 fork 分支上完成改动后,按以下清单提交 PR:
- 为改动添加测试;
- 确保全部测试通过;
- 若改动影响文档,同步更新
README.md; - 遵循下述提交信息约定。
Commit message 约定:Conventional Commits
提交信息遵循 Conventional Commits 规范,格式为:
<type>: <subject><type>表示变更类型:feat用于新功能,fix用于 Bug 修复,docs用于文档,chore用于不触碰代码本身的改动(如依赖更新);<subject>是对变更的简短描述。
这种格式化的提交信息让 CI 生成的发布说明(release notes)保持可读。仓库根目录还通过simple-git-hooks与lint-staged配置了 pre-commit 钩子:对*.{js,json,css,md,ts,tsx}文件自动执行biome check --fix(见根目录 package.json),从源头保证提交进度的代码已经过格式化。
代码风格与静态检查:Biome
CONTRIBUTING.md 指定项目使用Biome做格式化与 lint,打开 PR 前必须用 Biome 格式化改动。仓库的 biome.json 给出了实际配置:
- 启用 formatter,
indentStyle: space(空格缩进); - 启用 linter,采用
recommended规则集,并针对该库做了少量豁免,例如关闭noForEach、将noUnusedVariables降级为 warn、关闭noSvgWithoutTitle等。
对应的检查命令在包内为biome check .(见 packages/react-intersection-observer/package.json),仓库根目录提供聚合的pnpm lint。
测试:Vitest + Playwright Browser Mode + Node SSR 双项目
CONTRIBUTING.md 说明测试框架是Vitest,并强调了两点关键事实:组件测试运行在 Vitest Browser Mode(基于 Playwright),SSR 测试则运行在独立的 Node 项目中。执行:
pnpm test其背后是 packages/react-intersection-observer/vitest.config.ts 中定义的两个测试项目:
projects: [ { test: { name: "node", environment: "node", include: ["src/**/*.ssr.test.ts"], }, }, { test: { name: "browser", include: ["src/**/*.test.{ts,tsx}"], exclude: ["src/**/*.ssr.test.ts"], browser: { enabled: true, provider: playwright(), headless: true, instances: [{ browser: "chromium" }], }, }, }, ],也就是说:
- 文件名以
.ssr.test.ts结尾的测试(如 src/tests/useInView.ssr.test.ts,验证useInView在renderToString下无警告地渲染出false)走 Node 环境; - 其余
.test.{ts,tsx}文件(如 src/tests/useOnInView.test.tsx、src/tests/observe.test.ts)走 Chromium 浏览器的 Browser Mode,由 Playwright 驱动。
内置的 IntersectionObserver 测试工具
该仓库为测试做了专门的工程化铺垫:包额外导出一个react-intersection-observer/test-utils入口(见 packages/react-intersection-observer/package.json 的exports字段,源码位于 packages/react-intersection-observer/src/test-utils.ts)。它提供:
setupIntersectionMocking(mockFn):把window.IntersectionObserver替换为可记录的 mock,并跟踪被观察的元素集合;resetIntersectionMocking():重置 mock 与观察状态;mockAllIsIntersecting(value)/mockIsIntersecting(element, value):模拟所有(或指定)元素进入/离开视口,value既可以是布尔值,也可以是表示intersectionRatio的数字;intersectionMockInstance(element):拿到某个元素对应的(mock)Observer 实例,用于断言observe/unobserve调用。
测试环境(Jest 或 Vitest)下该工具会在beforeEach中自动启用 mock、在afterEach中自动重置;非测试环境调用时会输出一段提示,指导在测试 setup 文件中手动配置。这让「先写测试再提交」在仓库里有了现成的脚手架支撑。
底层实现与测试的呼应
observe.test.ts印证了 packages/react-intersection-observer/src/observe.ts 的核心设计——相同选项的 Observer 会被复用:
optionsToId(options)把root、rootMargin、threshold、scrollMargin、trackVisibility、delay等选项排序后拼成唯一字符串 ID,测试断言如optionsToId({ rootMargin: "10px 10px", threshold: [0, 1] })得到"root_0,rootMargin_10px 10px,threshold_0,1";- 同一 ID 对应的
IntersectionObserver实例存放在全局observerMap中复用,每个元素维护自己的回调数组; observe()返回的清理函数具备幂等性:重复调用只清理一次,只有当元素的回调全部移除后才unobserve,只有当实例没有任何元素时才disconnect并从observerMap删除。测试"should only clean up each observer callback once"正是对这一行为的验证。
此外,由于useOnInView(见 packages/react-intersection-observer/src/useOnInView.tsx)与useInView(见 packages/react-intersection-observer/src/useInView.tsx)都经由useIntersectionObserverRef(见 packages/react-intersection-observer/src/useIntersectionObserverRef.ts)调用底层observe,测试文件里还覆盖了 ref 生命周期、Strict Mode 下的重复挂载清理、ref 合并、同一元素多回调等边界场景,这些都可以作为新增测试的参考范式。
构建产物验证
CONTRIBUTING.md 建议在提交前构建包与两个应用:
pnpm build:all该命令的完整展开为(根目录 package.json):
"build:all": "pnpm build && pnpm --filter storybook build && pnpm --filter docs build"其中pnpm build指pnpm --filter react-intersection-observer build。包的构建由 packages/react-intersection-observer/tsup.config.ts 驱动:基于 tsup 同时产出esm/cjs双格式与类型声明(dts: true),主入口src/index.tsx输出到dist,测试工具入口src/test-utils.ts输出到test-utils。构建后还会执行attw --pack、publint与 size-limit 校验——packages/react-intersection-observer/package.json 中为InView、useInView、useOnInView、observe分别设置了1.5 kB、1.36 kB、1.12 kB、0.9 kB的体积预算,防止贡献导致包体膨胀。
发布流程:CI 上的 npm Trusted Publishing
CONTRIBUTING.md 特别强调:发布只发生在 CI,本地没有发布步骤。原因是仓库采用 npm 的 trusted publishing(信任发布者)机制,仓库内不存在任何 npm token,发布时自动附加 provenance(来源证明);从本地执行npm publish会被拒绝。
手动触发 Release 工作流
要发布一个版本,维护者在仓库的Actions选项卡中选择Release工作流,并从要发布的分支运行它。工作流有两个输入参数(见 .github/workflows/release.yml):
- version:选择版本增量,可选
patch、minor、major,以及prepatch、preminor、premajor、prerelease,默认patch; - tag:指定 npm dist-tag,默认
latest,预发布版本使用beta。
工作流的完整执行链条
release.yml中的 job 完整呈现了 CONTRIBUTING.md 描述的流程:
- 铸造 GitHub App token:因为
main分支受保护,而 GitHub Actions 应用不能作为用户仓库 ruleset 的 bypass actor,工作流通过actions/create-github-app-token@v2使用vars.RELEASE_APP_ID与secrets.RELEASE_APP_KEY铸造一个短期 token,用于推送版本提交;该 token 在 job 结束时自动失效。 - 检出代码:以
fetch-depth: 0全量检出,方便生成版本与发布说明。 - 环境准备:启用 corepack、安装 Node.js 24、更新 npm(trusted publishing 要求 npm 11.5.1+)、
pnpm install --frozen-lockfile锁定依赖。 - 提升版本并提交:执行
pnpm exec bumpp ${{ inputs.version }} --yes,在 bump 版本号的同时完成 commit 与 tag。 - 构建:在
packages/react-intersection-observer目录执行pnpm build。 - 发布到 npm:
npm publish --tag ${{ inputs.tag }}。注释明确写到 "No NODE_AUTH_TOKEN: npm authenticates through the OIDC token",即通过 job 的id-token: write权限完成 OIDC 认证,provenance 由 trusted publishing 自动证明。 - 创建 GitHub Release:
gh release create "v${{ steps.version.outputs.version }}" --generate-notes,基于 Conventional Commits 自动生成发布说明;pre*版本还会追加--prerelease标记。
这解释了 CONTRIBUTING.md 中「版本提交由 GitHub App 铸造的短期 token 推送,App ID 存放于RELEASE_APP_ID变量、私钥存放于RELEASE_APP_KEYsecret」的完整工程背景。
小结
对react-intersection-observer的贡献者而言,完整的工作流可以浓缩为四条主线:
- 开发:
pnpm install后用pnpm dev(或pnpm dev:storybook/pnpm dev:docs)并行启动包、Storybook 与文档站点; - 提交:遵循
<type>: <subject>的 Conventional Commits 规范,交给 pre-commit 钩子与 Biome 统一格式; - 测试:
pnpm test同时运行 Browser Mode(Playwright + Chromium)与 Node SSR 两套 Vitest 项目,借助react-intersection-observer/test-utils内置的 IntersectionObserver mock 编写确定性测试;提交前用pnpm build:all验证构建与体积预算; - 发布:无需本地 npm token,在 Actions 中运行 Release 工作流,选择
version与tag后,CI 完成 bump、构建、trusted publishing 与 GitHub Release 生成。
对源码级细节感兴趣的读者,可以继续深入 packages/react-intersection-observer/src/observe.ts 理解共享 Observer 机制,翻阅 packages/react-intersection-observer/src/tests学习测试范式,或对照 .github/workflows/release.yml 复现完整的发布流水线。
- 前端
- UI组件
【免费下载链接】react-intersection-observer
React implementation of the Intersection Observer API to tell you when an element enters or leaves the viewport.
相关推荐
React-Rails 贡献实战指南:从 Bug 报告、本地开发到测试与发布全流程
React Rails 贡献实战指南:从 Bug 报告、本地开发到测试与发布全流程 React Rails 是连接 React 与 Rails 视图、控制器、资
后端前端MAS 激活脚本完整指南:免费激活 Windows 和 Office 的三种方式
MAS 激活脚本完整指南:免费激活 Windows 和 Office 的三种方式 MAS(Microsoft Activation Scripts)是一个开源激
操作系统trackerslist 公共 BT 追踪器列表:4 步给种子下载提速
trackerslist 公共 BT 追踪器列表:4 步给种子下载提速 下载卡在 99.9%,做种只剩 1 个,速度个位数 KB——问题多半不在带宽,而是种子自
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考