# @effected/lockfiles 中文文档

规范地址：https://npmcn.com/package/%40effected/lockfiles/

版本：0\.25\.0
npm 元数据更新时间：2026-11-12T19:05:48.401Z
中文译文更新时间：2026-11-13T08:56:34.221Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40effected/lockfiles
原文对照：https://npmcn.com/package/%40effected/lockfiles/?lang=original
项目主页：https://github.com/spencerbeggs/effected/tree/main/packages/lockfiles#readme
源码仓库：https://github.com/spencerbeggs/effected

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：204 kB，27 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=24\.11\.0
- 运行依赖：0 个
- peer 依赖：effect ~4\.1\.0，@effected/npm ^0\.34\.1，@effected/glob ^0\.22\.0，@effected/yaml ^0\.30\.0，@effected/jsonc ^0\.25\.0，@effected/semver ^0\.24\.0
- 首次发布：2026-07-16T17:32:07.941Z
- 最新版本发布：2026-11-12T19:05:47.978Z
- 近 30 天下载量：9221（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：62（近 12 个月 62 个）

## 中文简介

纯锁文件对包子,npm,pnpm和纱线Berry进行解析,形成一个统一的效应计划模型,对工作空间清单进行纯完整性检查.

## 安装

```sh
npm install @effected/lockfiles
```

也可以使用：`pnpm add @effected/lockfiles`、`yarn add @effected/lockfiles`、`bun add @effected/lockfiles`

## README

# @ 受影响/ 锁定文件

[![npm](https://img.shields.io/npm/v/@effected%2Flockfiles?label=npm&color=cb3837)](https://www.npmjs.com/package/@effected/lockfiles) [![License: MIT](https://img.shields.io/badge/License-MIT-4caf50.svg)](https://opensource.org/licenses/MIT) [![Node.js %3E%3D24.11.0](https://img.shields.io/badge/Node.js-%3E%3D24.11.0-5fa04e.svg)](https://nodejs.org/) [![TypeScript 7.0](https://img.shields.io/badge/TypeScript-7.0-3178c6.svg)](https://www.typescriptlang.org/)

锁定文件解析 [效果](https://effect.website/) v4: 包( 包头)`bun.lock`页:1`package-lock.json`页:1`pnpm-lock.yaml`和纱线 Berry(`yarn.lock`(所有规范化为一个) `Lockfile` 设计模型,加上该模型的纯完整性检查与工作空间表以及两个锁文件比较后的纯性. 四种格式,一种模式,没有IO和外部运行时间依赖.

> **预`1.0.0`。 。 。 .** 此软件包是 `@effected/*` 在稳定基础上建造的工具包 效应v4(`effect` `~4.1.0`) 并仍在 `0.x` 发展。 稳定效果 制作一个工具箱 `1.0.0` 可能,不是自动的。 为了保持你的 `effect` 财务报告和审定财务报表 `@effect/*` 该工具包在线上构建和测试、安装 [`@effected/pnpm-plugin-effected`](https://www.npmjs.com/package/@effected/pnpm-plugin-effected)。 。 。 .
> 
> **稳定:不稳定.** 此软件包的 API 表面尚未考虑 完成并可能改变 `0.x` 释放 定一个确切的版本——甚至 标记软件包 _稳定_ 在此之前 `1.0.0` 可以引入突破性更改 和精确的针 变成一个类型检查错误 而不是一个 跑步时间惊喜。 完全政策: [释放策略](https://github.com/spencerbeggs/effected#release-strategy)。 。 。 .

## 为什么 @ 受影响/ 锁定文件

每个软件包管理器用不同的方言来写出其锁文件——JSONC为bun,JSON为npm,YAML为pnpm和纱线——每个软件包编码,工作空间边缘和完整性数据不同. 想要回答“哪个版本”的工具 `typescript` 在此解析 。 这个软件包将所有四个都正常化为一个模型,所以无论哪个软件包管理器生产文件,都会被问一次.

每一个切入点都把内容当作一个 **字符串**。该软件包完全不执行IO:读取文件,寻找工作空间根并检测Repo使用的哪个软件包管理器属于它的消费者,而保存它们意味着解析器是一个纯函数,你可以从固定器,网络响应或git blob中驱动. 输入错误总是通过打出错误的通道退出,绝不是缺陷,锁文件无法使用的两种方式是不同的标记而不是模糊 `reason` 绳子。 Yarn支持仅是Berry, 执行: 经典 v1 内容键入失败, 而不是被错误的正常化成看起来可信的东西 .

## 安装

```bash
npm install @effected/lockfiles @effected/jsonc @effected/npm @effected/semver @effected/yaml effect
```

```bash
pnpm add @effected/lockfiles @effected/jsonc @effected/npm @effected/semver @effected/yaml effect
```

需要节点.js~~24.11.0. `effect` v4, (英语), `@effected/jsonc`, (中文(简体) ), `@effected/npm`, (中文(简体) ), `@effected/semver` 财务报告和审定财务报表 `@effected/yaml` - JSONC 和 YAML 引擎、 共享的依赖指定词汇和 SemVer 范围检查器都通过这些兄弟姐妹到达, 所以没有外部 `effect` 财务报告和审定财务报表 `@effected/*` 到达你的树。 自动安装对等器的软件包管理器会将其拉入; 如果不安装, 将明确添加到您的清单中 .

全体 `@effected/*` 软件包仅为无害环境管理:只公布出口地图 `import` 条件,所以 `require()` 包括解析 CJS 模式的工具 —— 与节点失败 `ERR_PACKAGE_PATH_NOT_EXPORTED` 而不是装入不存在的 CJS 建筑。 从ES模块导入.

## 快开始

```ts
import { Lockfile, LockfileIntegrity, WorkspaceManifest } from "@effected/lockfiles";
import { Effect } from "effect";

declare const content: string; // lockfile text, read by the caller

const program = Effect.gen(function* () {
  // The only fallible boundary in the package.
  const lockfile = yield* Lockfile.parse(content, { format: "pnpm" });

  // pnpm workspace packages come back keyed by importer path; rewrite them
  // once you have read the manifests. Total and pure — no error channel.
  const named = lockfile.withImporterNames(new Map([["packages/core", "@acme/core"]]));

  // Total lookups over the model.
  const versions = named.packagesNamed("typescript").map((p) => p.version);

  // Pure integrity checking — no Effect, no error channel, no IO.
  const report = LockfileIntegrity.compare(named, [
    WorkspaceManifest.make({ name: "@acme/core", dependencies: { lodash: "^4.17.0" } }),
  ]);

  return { versions, workspaces: named.workspacePackages.length, valid: report.valid };
});

Effect.runPromise(program).then(console.log);
// { versions: [...resolved typescript versions], workspaces: <count>, valid: true | false }
```

## 格式

`format` 是一种文字 `filenameFor` 编号 : `fromFilename` 映射到字面文字和磁盘上的文件之间, 所以一个检测到包管理器的消费者就不需要硬码文件名 .

| 格式 | 文件名 | 读取 | 页:1 |
| --- | --- | --- | --- |
| `"bun"` | `bun.lock` | 约克 | 信任的依赖关系 `BunExtension` |
| `"npm"` | `package-lock.json` | 贾森 | `lockfileVersion` 3+ — v2 及更古老的失败键入 |
| `"pnpm"` | `pnpm-lock.yaml` | 也门 | `lockfileVersion` 9+ — 旧的已键入失败 。 保存在目录上的 `PnpmExtension`; 见下文 |
| `"yarn"` | `yarn.lock` | 也门 | 只有 Berry — 经典 v1 键入失败 |

### 支持的锁定文件版本

门在上 **锁定文件格式版本**,这是锁文件记录的唯一版本 :

| 格式 | 最低 | 旧投入 |
| --- | --- | --- |
| 小时 | `lockfileVersion` 第9条 | `LockfileParseError`, (中文(简体) ), `stage: "validation"` |
| 无 | `lockfileVersion` 3个 | `LockfileParseError`, (中文(简体) ), `stage: "validation"` |
| 面包,纱线 | 无门 | —— 说 |

这个 `cause` 是结构化的 `{ _tag: "UnsupportedLockfileVersion", format, lockfileVersion, minimumSupported, message }`,因此消费者可以区分"你的锁文件太老了"和"你的锁文件是错的",而不解析出道词. `isUnsupportedLockfileVersion` 是一个导出并缩小其范围 —— 在标签上有区别, 绝不在 `message`,这是摘要而不是合同:

```ts
import { isUnsupportedLockfileVersion, Lockfile } from "@effected/lockfiles";
import { Effect } from "effect";

declare const content: string;

const program = Lockfile.parse(content, { format: "pnpm" }).pipe(
  Effect.catchTag("LockfileParseError", (error) =>
    isUnsupportedLockfileVersion(error.cause)
      ? Effect.fail(`lockfileVersion ${error.cause.lockfileVersion}; need ${error.cause.minimumSupported}+`)
      : Effect.fail("malformed lockfile"),
  ),
);
// a pre-v9 pnpm lockfile takes the first branch, a truncated one the second
```

`cause` 刻意保持开放的通道:它携带着任何下放的解析引擎所抛出的东西,因此宣布它为封闭的联盟将呈现一个开放的通道作为详尽的通道. 前提就是它是什么 使它缩小诚实.

旧格式被拒绝而不是解析,因为它们无法回答模型现在提出的问题:pre-v9 pnpm没有 `snapshots:` npm v1/v2 树没有每层嵌入的记录,所以两者都会解码为无分辨率数据的行.

**已测试反对** pnpm 11.22.0,npm 11.19.0,bun 1.3.14和纱线 4.9.1——与大门分开的主张,是故意的. 一个锁文件没有记录哪个软件包管理器写它, 映射是多到一( pnpm 9, 10和 11 全部写格式) `9.0`因此,即使原则上也无法执行管理者版本要求.

## 错误

`Lockfile.parse` 这是唯一可谬误的入门点, 它失败了两种方式.

| 标记 | 手段 | 字段 |
| --- | --- | --- |
| `LockfileParseError` | 内容不是该格式的有效锁文件 . | `format`, (中文(简体) ), `stage` (单位:千美元)`"syntax"` 当文字本身没有分析的时候, `"validation"` 当时,它已分辨了,但无定形, `cause` (结构,从来没有弦) |
| `LockfileFramingError` | 文本解析了, 但无法在其中找到单个锁定文件 . | `format`, (中文(简体) ), `documents`, (中文(简体) ), `reason` (单位:千美元)`"noLockfileDocument"`, (中文(简体) ), `"noImporters"`, (中文(简体) ), `"unexpectedDocuments"`(中文(简体) ) |

框架错误存在的原因是 `pnpm-lock.yaml` 是一个YAML **流线**,而不是YAML文档。 pnpm 11 每当工作空间使用时, 在锁定文件前写一个配置依赖性序言 `configDependencies`,因此文件载有两个文件——序言宣布 `lockfileVersion`, (中文(简体) ), `importers` 财务报告和审定财务报表 `packages` 因此,一个只读第一个文档的解析器 得到一个锁文件 _验证_ 并描述一个空的工作空间。 这是一个错误的答案 完全像一个正确的答案。 这里的规则是定位和决定性,而不是heuristic: pnpm 将序言作前缀,所以锁文件是 **最后一个** 文档。 没有锁定文件的流未输入 。 它从不堕入空地 `Lockfile`。 。 。 .

线条定义了任何文档框架, 所以多文档 `yarn.lock` 内容失败 `"unexpectedDocuments"` 而不是默默不作声地摘掉第一份文件。 如果格式未说明规则,则该软件包拒绝猜测.

## 实例和决议

一行进去 `lockfile.packages` 是一个软件包 **实例**没有一个包裹。 在不同的同伴下安装两次的依赖是两行 `instanceId` 是那行的锁文件内在身份 带有逐字记录 当作是 **不透明**:在模型中查找一个id,从不分拆或图案相匹配,因为其拼写是格式的业务,每个管理器不同.

`resolved` 将每个从属名称——和每个对等名称的锁文件记录一个解析度——到 `instanceId` 它实际上决定了,这就是让消费者走 真正的图表,而不是重新溶解范围本身. `peerDependencies` 财务报告和审定财务报表 `peerDependenciesMeta` 将声明作为书面形式,默认为 `{}`。 。 。 .

```ts
import { Option } from "effect";

const [instance] = lockfile.packagesNamed("react-dom");
const reactId = instance?.resolved["react"];
const react = reactId === undefined ? Option.none() : lockfile.packageByInstanceId(reactId);
// Option.some(ResolvedPackage) — the version this particular react-dom instance resolved to
// Option.none() when the lockfile records no row under that id
```

`packageByInstanceId` 是寻找 而不是扫描 `lockfile.packages`:它用先呼法建立懒惰的指数,再用它,所以以边走一行的图形边缘保持线性而不是四相. 重复的id解析出第一行,因此一个畸形的锁文件给出了一个稳定的答案而不是迭代顺序.

`unresolvedEdges` 命名锁定文件的边缘 **记录** 但模型无法命名。 所列名字没有遗漏——没有答复,因此失踪 `resolved` 键不能被读取为“什么都没有”。 在信任空结果之前, 关乎完整性的门会检查数组 .

## 比较两个锁文件

`LockfileDiff.compare(before, after)` 报告两个解析的锁文件之间的移动情况——安装后更新工具报告的内容。 这是完全和纯洁的,像 `LockfileIntegrity.compare`:没有效果,没有错误频道,没有IO.

```ts
import { Lockfile, LockfileDiff } from "@effected/lockfiles";
import { Effect } from "effect";

declare const beforeText: string; // the lockfile before `pnpm update`
declare const afterText: string; // and after

const program = Effect.gen(function* () {
  const before = yield* Lockfile.parse(beforeText, { format: "pnpm" });
  const after = yield* Lockfile.parse(afterText, { format: "pnpm" });
  const diff = LockfileDiff.compare(before, after);

  for (const change of diff.catalogs) {
    // A side that does not exist, or a version that does not resolve, is absent.
    const from = change.version.before ?? "-";
    const to = change.version.after ?? "-";
    console.log(`${change.catalog}/${change.name} ${change.kind}: ${from} -> ${to}`);
  }
  return diff.importers.filter((change) => change.specifier.after?._tag !== "catalog");
});
// With a default catalog entry `lodash: ^4.17.21` resolved at 4.17.23 before
// and 4.17.24 after, and a new `zod` entry, this prints:
// default/lodash changed: 4.17.23 -> 4.17.24
// default/zod added: - -> 3.25.76
```

-   `catalogs` 持有一个 `CatalogChange` 每个目录条目添加、删除或更改: `catalog` (单位:千美元)`"default"` 对于每种格式的默认目录, `name`, (中文(简体) ), `specifier` 财务报告和审定财务报表 `version` 作为 `{ before, after }`, (中文(简体) ), `kind`,以及 `consumers` - 进口商通过下列途径填写条目: `catalog:`,从 `before` 一个已删除条目的锁文件.
-   `importers` 持有一个 `ImporterChange` 增加、删除或更改的每个进口依赖 `importer` 路径, `name` 财务报告和审定财务报表 `depType` 一起来. `specifier` 侧面是分类的,比如: `ImporterDependency`这样 `_tag` 告诉一个 `catalog:` 参考文献分开.
-   不存在的一面是不存在的,一个版本也是无法解决的. 记录是 `changed` 当它的描述符不同,或者当它的版本在两侧解决而不同时;一个版本仅在一侧解决,本身并不是变化.
-   `hasChanges` 实值 `false` 当两个阵列均为空时.

如果一个解析的版本在格式上存在不同,而比较则使其正常化,因此每个格式的答案都是一样的:

| 格式 | 目录条目版本 | 导入者依赖版本 |
| --- | --- | --- |
| 小时 | 记录在条目中 | 记录进口依赖(工作空间链接为: `link:<path>`(中文(简体) ) |
| 包头 | 该条目的消费者决心使用(不同意不给版本的消费者);没有消费者,当锁文件完全持有一个时,包的版本 | 读取通过进口商的解析边缘到其软件包条目 |
| 无 | \- (npm 没有目录) | 读取通过进口商的解析边缘到其软件包条目 |
| 线条 | —— 说 | \- (yarn记录没有进口商,所以两个线条锁文件比较为空) |

在一个目录的凸起显示 `catalogs`,并输入 `importers` 对已解析的版本已移动的消费者; 过滤器打开 `specifier.after?._tag !== "catalog"` 将两者分开,如上.

## 特征

-   `Lockfile.parse(content, { format })` —— 软件包唯一的易落边界; 失败 `LockfileParseError` 或者说 `LockfileFramingError`。 。 。 .
-   `Lockfile#withImporterNames(names)` ——pnpm的纯二级:一旦消费者读取了货单,就重写进口商-路径名和每个依赖边缘的两端.
-   `Lockfile#packagesNamed(name)`, (中文(简体) ), `Lockfile#packageByInstanceId(id)` (单位:千美元)`Option`\- 回答,在一个懒散的指数之上)和 `Lockfile#workspacePackages` - 整个看模型.
-   `LockfileFormat` 与 `filenameFor` 编号 : `fromFilename` ——格式字面及其映射到锁定文件文件名.
-   `LockfileIntegrity.compare(lockfile, manifests)` - 完全、纯完整性检查,无出错频道;报告载有 `valid`, (中文(简体) ), `missingWorkspaces`, (中文(简体) ), `extraWorkspaces` 财务报告和审定财务报表 `unsatisfiedConstraints`严格检查是设计上最好的: `workspace:` 编号 : `link:` 编号 : `file:` 其范围未被描述为SemVer的规格和行被跳过 .
-   `LockfileDiff.compare(before, after)` 总数,比较前后纯度:目录条目(`CatalogChange`)和进口依赖(`ImporterChange`) 添加、去除或更改,解决的版本在格式上实现正常化。 见 [比较两个锁文件](https://npmcn.com/package/%40effected/lockfiles/#readme-comparing-two-lockfiles)。 。 。 .
-   `WorkspaceManifest` ——完整性检查的显示输入形状:一个包名外加四个可选的依赖性记录. 故意是一种平庸的价值,而不是一个严格的表率模型,因此消费者可以从任何事物中获得.
-   `ResolvedPackage` - 一个包裹 _实例_: 名称、版本、可选完整性散列、工作空间旗和相对路径、依赖性地图、对等声明(`peerDependencies`, (中文(简体) ), `peerDependenciesMeta`),不透明 `instanceId`,则 `resolved` 名称到信息地图和 `unresolvedEdges` 模型无法命名 .
-   `isUnsupportedLockfileVersion` 编辑 `UnsupportedLockfileVersion` 类型 —— 缩小 a 的上游 `LockfileParseError.cause` 所以"太老"和"变形"在标签上被分开而不是在道具上.
-   `WorkspaceDependency` a 包括: `from`编号 :`to` 工作空间软件包之间的边缘 `depType` 拼写为 `@effected/npm`是因为 `DependencyField` 词汇及其宣布的制约.
-   `PnpmExtension` 财务报告和审定财务报表 `BunExtension` ——格式特定数据,如pnpm目录和bun信任的依赖性,保存在模型的可选性上 `extension` 字段.

## 许可证

[麻省理工学院](https://npmcn.com/package/%40effected/lockfiles/LICENSE)

## 常见问题

### @effected/lockfiles 是什么？

纯锁文件对包子,npm,pnpm和纱线Berry进行解析,形成一个统一的效应计划模型,对工作空间清单进行纯完整性检查\.

### 如何安装 @effected/lockfiles？

在项目目录运行 npm install @effected/lockfiles，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：effect（~4\.1\.0）、@effected/npm（^0\.34\.1）、@effected/glob（^0\.22\.0）、@effected/yaml（^0\.30\.0）、@effected/jsonc（^0\.25\.0）、@effected/semver（^0\.24\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @effected/lockfiles 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @effected/lockfiles 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @effected/lockfiles 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=24\.11\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @effected/lockfiles 可以商用吗？

@effected/lockfiles 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @effected/lockfiles 的下载量有多少？

根据 npm 官方下载统计，@effected/lockfiles 在 2026/10/13 – 2026/11/11 这 30 天内被下载 9,221 次，日均约 307 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @effected/lockfiles 还在维护吗？

最新版本 0\.25\.0 发布于 2026/11/13（今天）；至今共发布 62 个版本，其中过去 12 个月发布了 62 个；首次发布于 2026/07/17。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

