首页
/ path/to/package.json

path/to/package.json

2026-09-04 18:45:41作者:乔或婵

path/to/package.json

example-library@3.4.6 (bug: 3.5.x): Pinned as there is a bug in version 3.5.x that prevents foo from doing bar.


这种“路径 + 包@版本 + 原因”的三元结构是有意设计的:

- **路径**:让读者能直接定位到写入 resolution 的那个 `package.json`;
- **包@版本**:与 `resolutions` 字段的 key/value 可交叉核对;
- **原因**:为未来“这个钉子为什么还能拔掉”留下判断依据,避免锁定项无人敢动。

在 [CONTRIBUTING.md](https://gitcode.com/GitHub_Trending/st/storybook/blob/e8044dbefad93f4fd48a5a378693428ab0e5dbc8/CONTRIBUTING.md?utm_source=gitcode_repo_files) 的仓库结构说明中,`RESOLUTIONS.md` 被列在根目录文件清单里(与 `CHANGELOG.md`、`MIGRATION.md` 并列),说明它是 Storybook 维护者流程的一部分,而非临时笔记。

## 根工作区的真实 resolutions 配置

Storybook 使用 Yarn 4 管理 monorepo(根 [package.json](https://gitcode.com/GitHub_Trending/st/storybook/blob/e8044dbefad93f4fd48a5a378693428ab0e5dbc8/package.json?utm_source=gitcode_repo_files) 中声明 `"packageManager": "yarn@4.18.0"`),工作区由 `agent-eval`、`code`(下含 `addons/*`、`builders/*`、`frameworks/*`、`lib/*`、`renderers/*`、`presets/*` 等子目录)与 `scripts` 组成。根 [package.json](https://gitcode.com/GitHub_Trending/st/storybook/blob/e8044dbefad93f4fd48a5a378693428ab0e5dbc8/package.json?utm_source=gitcode_repo_files) 的 `resolutions` 字段(第 45–75 行)是当前仓库锁定行为的“事实来源”,完整内容如下:

```json
"resolutions": {
    "@ai-sdk/anthropic": "^2.0.0",
    "@babel/runtime": "latest",
    "@babel/traverse": "latest",
    "@babel/types": "^7.28.4",
    "@playwright/test": "1.58.2",
    "@testing-library/jest-dom": "6.9.1",
    "@testing-library/user-event@npm:^14.4.0": "patch:@testing-library/user-event@npm%3A14.6.3#~/.yarn/patches/@testing-library-user-event-npm-14.6.3-15ecebe390.patch",
    "@testing-library/user-event@npm:^14.6.3": "patch:@testing-library/user-event@npm%3A14.6.3#~/.yarn/patches/@testing-library-user-event-npm-14.6.3-15ecebe390.patch",
    "@types/babel__traverse@npm:*": "patch:@types/babel__traverse@npm%3A7.20.6#~/.yarn/patches/@types-babel__traverse-npm-7.20.6-fac4243243.patch",
    "@types/babel__traverse@npm:^7.18.0": "patch:@types/babel__traverse@npm%3A7.20.6#~/.yarn/patches/@types-babel__traverse-npm-7.20.6-fac4243243.patch",
    "@types/node": "^22.19.1",
    "@types/react": "^18.0.0",
    "@typescript-eslint/types": "8.60.0",
    "@vercel/agent-eval-playground/react": "^19.2.0",
    "@vercel/agent-eval-playground/react-dom": "^19.2.0",
    "@vercel/agent-eval@npm:1.2.0": "patch:@vercel/agent-eval@npm%3A1.2.0#~/.yarn/patches/@vercel-agent-eval-npm-1.2.0-861deb21a0.patch",
    "@vitest/expect@npm:3.2.4": "patch:@vitest/expect@npm%3A3.2.4#~/.yarn/patches/@vitest-expect-npm-3.2.4-97c526d5cc.patch",
    "agent-eval/typescript": "5.9.3",
    "aria-query@5.3.0": "^5.3.0",
    "esbuild": "^0.28.0",
    "playwright": "1.58.2",
    "playwright-core": "1.58.2",
    "polka@npm:1.0.0-next.28/@polka/url": "1.0.0-next.29",
    "radix-ui@npm:^1.4.3": "1.6.0",
    "react": "^18.2.0",
    "react-joyride/type-fest": "~2.19",
    "rxjs": "^7.8.2",
    "typescript": "^6.0.3",
    "valibot": "^1.4.0"
}

从这份配置中可以读出几类典型用法:

  1. 锁定测试/构建基础设施的精确版本playwrightplaywright-core@playwright/test 三项同时固定为 1.58.2,保证工作区内任何子包引入的 Playwright 都解析到同一版本,避免浏览器二进制与 API 版本错位。
  2. 锁定工具链关键版本typescript 固定为 ^6.0.3esbuild^0.28.0react^18.2.0——monorepo 中 30 多个 workspace 共用一套类型与 React 运行时,resolution 是防止某个子包把主版本拉偏的最后一道闸。
  3. patch: 协议 + 本地补丁文件。Yarn 4 允许将某版本解析为“打过补丁的版本”,例如 @testing-library/user-event 无论上游声明 ^14.4.0 还是 ^14.6.3,都强制解析为 14.6.3 并应用 ~/.yarn/patches/@testing-library-user-event-npm-14.6.3-15ecebe390.patch 补丁。@vitest/expect@npm:3.2.4 的条目同理。注意 value 中 URL 编码形式(npm%3Anpm:)是 Yarn PnP 的寻址语法,不要手工改写。
  4. 带 scope 前缀的嵌套依赖覆盖polka@npm:1.0.0-next.28/@polka/url: "1.0.0-next.29" 表示“只覆盖 polka 1.0.0-next.28 所依赖的 @polka/url”,而不是全局覆盖——这是 resolutions 表达“精确版本”时最容易被误解的 key 形式。

此外,test-storybooks/ 下的多个独立测试项目(如 mcpyarn-pnpserver-kitchen-sinkstandalone-preview 等各自目录)的 package.json 也带有 resolutions 字段。这些项目位于工作区之外、单独安装依赖,因此锁定项直接写在各自 package.json 中——这正是 RESOLUTIONS.md 约定“以 package.json 路径为标题”的原因:锁定不止存在于根工作区一处。

resolutions 变更的自动化校验链路

仅靠人工维护登记簿容易失同步。Storybook 在 scripts/ecosystem-ci/ 下建立了一条机器可校验的链路,这是该文档约定背后真正的工程价值所在。

EXISTING_RESOLUTIONS:机器可读的“已登记集合”

scripts/ecosystem-ci/existing-resolutions.js 导出一个 Set,逐项枚举根 package.json resolutions 的全部 key(包括带 @npm: 限定的完整 key,如 '@types/babel__traverse@npm:*''polka@npm:1.0.0-next.28/@polka/url')。文件头注释明确了它的职责边界:

Set of resolutions from the root package.json that should NOT be copied to sandbox package.json. These are the "existing" resolutions that Storybook maintains, as opposed to resolutions that might be injected by ecosystem-ci repos.

即区分“Storybook 自己维护的存量锁定”与“ecosystem-ci 外部仓库临时注入的锁定”。

对称差测试:防止集合与配置漂移

scripts/ecosystem-ci/existing-resolutions.test.ts 用一个单元测试保证两者永不失同步:

it('EXISTING_RESOLUTIONS should match all keys in package.json resolutions', () => {
    const actualKeys = new Set(Object.keys(rootPkgJson.resolutions));
    const difference = actualKeys.symmetricDifference(EXISTING_RESOLUTIONS);

    expect(difference.size).toBe(0);
});
登录后查看全文
热门项目推荐
相关项目推荐