@effected/jsonc

中文文档
0.25.0发布于 2026/11/10MITTypeScriptES Module构建来源已验证近 30 天下载 1.1万

零依赖 JSONC 解析,编辑和格式化为 Effect schemas.

中文使用文档
文档目录8 节
  1. 为什么 @ effect/jsonc
  2. 安装
  3. 快开始
  4. 在不丢失注释的情况下编辑
  5. 评论和往返
  6. Canonical JSON 和内容指纹
  7. 特征
  8. 许可证

@ effect/jsonc

npm License: MIT Node.js %3E%3D24.11.0 TypeScript 7.0

零依赖 JSONC 解析,编辑和格式化表示为效果计和纯函数. 将 JSONC 分析为纯值或偏移保留 AST, 将批注, 计算字节最小编辑, 格式, 通过路径修改, 将文档行走为 Stream,并直接解码为已验证域名计划.

预1.0.0。 。 。 . 此软件包是 @effected/* 在稳定基础上建造的工具包 效应v4(effect ~4.1.0) 并仍在 0.x 发展。 稳定效果 制作一个工具箱 1.0.0 可能,不是自动的。 为了保持你的 effect 财务报告和审定财务报表 @effect/* 该工具包在线上构建和测试、安装 @effected/pnpm-plugin-effected。 。 。 .

稳定:不稳定. 此软件包的 API 表面尚未考虑 完成并可能改变 0.x 释放 定一个确切的版本——甚至 标记软件包 稳定 在此之前 1.0.0 可以引入突破性更改 和精确的针 变成一个类型检查错误 而不是一个 跑步时间惊喜。 完全政策: 释放策略。 。 。 .

为什么 @ effect/jsonc

JSONC 是 JSON 有注释和后缀的逗号:后面的格式 tsconfig.json, VS 代码设置和大部分 JavaScript 工具链. 这些文件是由人类撰写的,人类在其中留下了评论. A 类 JSON.parse 接下来 JSON.stringify 圆通会摧毁每一个 所以任何重写工具 tsconfig.json 这样就把一个他们不认识的文件交给用户.

此软件包将源文本视为文档。 修改是按原始字节进行编辑,而不是从解析对象进行再序列化,因此,修改为一键后,每个注释、空白行和缩进选择都保持不变。 分析从错误中恢复,将每个诊断结果汇总为一个 JsoncParseError 携带 code, (中文(简体) ), offset, (中文(简体) ), length, (中文(简体) ), line 财务报告和审定财务报表 character 每个错误,而不是扔在第一个。 还有 Jsonc.schema 以域名 schema作曲,所以JSONC字符串在单步中解码为已验证值.

万事皆是纯粹的功能或阴谋. 没有IO,没有自有服务,没有运行时间依赖,除了 effect 本身:扫描仪、剖面仪和导航仪被销售到包中,带有归属性,而不是作为附属物被牵入。 唯一有效果的边缘是指纹散列,包裹船没有它的后端: JsoncFingerprint.hash 财务报告和审定财务报表 hashText 需要一个核心 Digest.Digest 服务effect/crypto(单位:千美元) R,由消费者在应用程序边缘提供,而其 hashResult 编号 : hashTextResult 双胞胎把摘要当作一个平庸的函数参数,这样一个同步的呼叫者就可以在完全没有运行时间的情况下指纹.

安装

npm install @effected/jsonc effect
pnpm add @effected/jsonc effect

需要节点.js~~24.11.0. effect v4 是一个对等依赖; 软件包本身没有添加其它运行时间依赖 .

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

快开始

准备你的计划 Jsonc.schema 将 JSONC 直接解码为已验证域值 :

import { Jsonc } from "@effected/jsonc";
import { Effect, Schema } from "effect";

const Config = Schema.Struct({ port: Schema.Number });
const ConfigFromJsonc = Jsonc.schema(Config);

const program = Effect.gen(function* () {
  return yield* Schema.decodeUnknownEffect(ConfigFromJsonc)(`{
    // dev server
    "port": 3000
  }`);
});

Effect.runPromise(program).then(console.log);
// { port: 3000 }

通过打入的信道输入失败, 绝不是抛出 :

import { Jsonc } from "@effected/jsonc";
import { Effect } from "effect";

Effect.runPromise(Effect.result(Jsonc.parse('{ "a": }'))).then(console.log);
// Failure with JsoncParseError:
// "JSONC parse failed with 1 error: ValueExpected at 1:8"
// The `errors` field carries one JsoncParseErrorDetail per recovered error,
// each with code, offset, length, line and character.

无法运行效果的同步边界( 普通配置加载器, 构建脚本) 调用 Jsonc.parseResult,同样的解析返回 a Result 直接装入 Effect.runSync(Effect.result(...))数字 :

import { Jsonc } from "@effected/jsonc";
import { Result } from "effect";

const result = Jsonc.parseResult('{ "port": 3000 // dev\n}');
console.log(Result.isSuccess(result) ? result.success : result.failure);
// { port: 3000 }

Jsonc.parse 定义如下: parseResult,以及 Jsonc.parseTree 从 Jsonc.parseTreeResult,所以对子从不分裂。 偏好效果变体在效果码内,在其中携带它们的追踪跨度.

在不丢失注释的情况下编辑

JsoncModifier.modify 返回 a JsoncEdit 阵列——抵消、长度和替换内容 JsoncEdit.applyAll 相接入于正文中. 只有编辑更改覆盖的字节 :

import { JsoncEdit, JsoncModifier } from "@effected/jsonc";
import { Effect } from "effect";

const source = `{
  // dev server
  "port": 3000
}`;

const program = Effect.gen(function* () {
  const edits = yield* JsoncModifier.modify(source, ["port"], 8080);
  return JsoncEdit.applyAll(source, edits);
});

Effect.runPromise(program).then(console.log);
// {
//   // dev server
//   "port": 8080
// }

生成的文本遵循它登陆的文件。 一个新的成员会用上一个兄弟会来排行,一个多行的值会被缩到其成员身上,每个生成的行会取出文件的行尾,所以一个有分页缩入的 CRLF 文件会保留一个. 过 formattingOptions 以设置缩进单位或线条结尾。 删除一个条目时与它保持一致,使一个空容器倒塌到 {} 或者说 []除非还有评论.

一个新成员走最后,除非 insertAfter 标出它应该跟随的同父异母兄弟的名字, 并且这个同父异母兄弟会留下一条评论. createParents 构建缺失的对象祖先而不是失败;它从不覆盖错误类型的值,也从不创建数组.

JsoncFormatter.format 生成同样类型的编辑阵列,用于白空间正常化,所以一个前题通过是diff而不是重写.

从 jsonc-effect 0.3.x吗? 图书馆的值已经超过 跟踪内容( e)jsonc- 效果# 62, (中文(简体) ), 因此编辑可以吞入一个值后的白空间或注释. @effected/jsonc 0.1.0 修正: 数值跨度精确覆盖值, 格式保留编辑 是字节准确的, 任何下游 AST -plus -trimEnd 工作变通可以删除.

评论和往返

没有保留评论 stringify 这是蓄意的,而不是疏忽. Jsonc.stringify 及其同步双胞胎 Jsonc.stringifyResult 发送 plain JSON – 注释在文档中直播并编辑层 (JsoncNode, (中文(简体) ), JsoncEdit, (中文(简体) ), JsoncFormatter),在平版JavaScript值中从未出现. 编码方向 Jsonc.schema, (中文(简体) ), Jsonc.fromString 财务报告和审定财务报表 Jsonc.JsoncFromString 同样的排放. 注释在解码后无法幸存 ——一旦一个文档被降为平版JavaScript值,评论就已经消失,没有诚实的编码器可以放回.

值 JSON 无法通过打入的信道表示失败, 而不是丢出 :

import { Jsonc } from "@effected/jsonc";
import { Result } from "effect";

const ok = Jsonc.stringifyResult({ port: 3000 });
console.log(Result.isSuccess(ok) ? ok.success : ok.failure);
// {
//   "port": 3000
// }

const bad = Jsonc.stringifyResult(0n);
console.log(Result.isFailure(bad) ? bad.failure.code : "");
// BigIntValue

保留注释需要原始源文本,这正是 JsoncModifier 财务报告和审定财务报表 JsoncFormatter 拿着 如果您需要将 JSONC 文件与它的注释完整地写出, 请编辑文本: 解析读取, 并修改以写入 .

Canonical JSON 和内容指纹

JsoncFingerprint 出产RFC 8785 Canonical JSON(JSON Canonicalization计划)和SHA-256指纹上方:紧凑输出,由UTF-16编码单元排序的对象键,ECMAScript编号序列化. 两种数值只在按键顺序排列上有所不同——和指纹相同. 与 Jsonc.stringify,随后 JSON.stringify嵌入式无代表物的下放/null语义学, canonicalization 拒绝更改文档 : a undefined,一个函数,一个符号,一个 bigint,非无限数,字符串或成员密钥中包含未发配代位词,或非平面对象(a) Date页:1 Map,类实例) JsoncCanonicalizeError 命名 JSON 指针 path 而不是被悄悄地抛下或作废. toJSON 方法被故意忽略——编码 Schema 课程和 Dates到平原JSON第一(同一个错误带有一个与文档无关的代码, InvalidDigest,关于同步调用器自身的消化功能——见下文:

import { JsoncFingerprint } from "@effected/jsonc";
import { Result } from "effect";

const ok = JsoncFingerprint.canonicalizeResult({ b: 2, a: 1 });
console.log(Result.isSuccess(ok) ? ok.success : "");
// {"a":1,"b":2}

const bad = JsoncFingerprint.canonicalizeResult({ a: { b: undefined } });
console.log(Result.isFailure(bad) ? `${bad.failure.code} at "${bad.failure.path}"` : "");
// UnrepresentableValue at "/a/b"

hash 财务报告和审定财务报表 hashText 将这种划线化通过一个内容文摘:小写-hex SHA-256的UTF-8字节的划线文字(Cononical text)hash或按给定的原始文本(hashText) (中文(简体) ). 两者都需要核心的 Digest.Digest 服务effect/crypto(单位:千美元) R - 这个软件包没有后端,所以提供 Digest.layerWebCrypto (任何使用 WebCrypto 的运行时间)或平台家庭层,例如 @effect/platform-node是因为 NodeCrypto.layerDigest 应用程序边缘:

import { JsoncFingerprint } from "@effected/jsonc";
import { Effect } from "effect";
import { Digest } from "effect/crypto";

const program = Effect.gen(function* () {
  const a = yield* JsoncFingerprint.hash({ b: 2, a: 1 });
  const b = yield* JsoncFingerprint.hash({ a: 1, b: 2 });
  return a === b;
});

Effect.runPromise(program.pipe(Effect.provide(Digest.layerWebCrypto))).then(console.log);
// true

hashResult 财务报告和审定财务报表 hashTextResult 是这两个双胞胎的同步双胞胎 没有纤维的呼叫者 Effect 在 —— 捆绑器插件的同步钩子, 缓存 read编号 :write 从主机内引用回调 。 他们同意字节的字节 Effect 表单。 由于a Digest 无法从同步回调中提供图层, 文摘本身就是参数: 通过 a JsoncDigest, (中文(简体) ), (bytes: Uint8Array) => Uint8Array。此套件仍没有从 node:* 并假设没有运行时间,所以一个节点消费者将平台绑在一行:

import { createHash } from "node:crypto";
import { JsoncFingerprint, type JsoncDigest } from "@effected/jsonc";
import { Result } from "effect";

const digest: JsoncDigest = (bytes) => createHash("sha256").update(bytes).digest();

const fingerprint = JsoncFingerprint.hashResult({ b: 2, a: 1 }, digest);
console.log(Result.isSuccess(fingerprint) ? fingerprint.success : "");
// 64 lowercase hex characters — the same answer `hash` gives

丢出或返回32字节以外的任何内容的文摘失败 JsoncCanonicalizeError是因为 InvalidDigest 路径中的代码 "" 而不是逃入主机,或散发出一个看似看似是错的宽度文摘,否则SHA-1绑定会产生40个六重字符. 没有检查可以抓住一个 不同 32字节算法;这是呼叫者要得到的正确性.

文摘总是64个小写十六进制字符,没有 sha256: 或其它算法前缀——相同的格式 @effected/sbom是因为 Sha256Digest schema解码,所以指纹会直接流入验证对象中,而这个包不会带有依赖边缘 sbom。 。 。 . hashText's(和 hashTextResult's' (英语) normalizeEol: true 选项规范化 \r\n 赤裸裸的 \r 改为 \n 在散列前——当同一文件内容必须用相同的指纹在有不同行中设置的核对结果之间找到它时; JsoncFingerprint.normalizeEol 暴露出与纯粹,全功能相同的正常化.

特征

  • Jsonc.parse 编号 : Jsonc.parseTree - 计算出纯值或保留抵消的误差 JsoncNode AST, 将每个恢复错误汇总为一个 JsoncParseError 而不是第一个失败.
  • Jsonc.parseResult 编号 : Jsonc.parseTreeResult - 同步点 Result 变量 parse 财务报告和审定财务报表 parseTree 对于在效果运行时间以外的调用者;效果表是用它们来定义的,因此对子永远不会有分化.
  • Jsonc.stringify 编号 : Jsonc.stringifyResult 价值水平 JSON 排放,可缩进,用打字失败 JsoncStringifyError 谁 code 名称模式 : CircularReference, (中文(简体) ), BigIntValue 或者说 TopLevelUnrepresentable。 。 。 .
  • Jsonc.stripComments ——纯正注释去除产生有效的JSON;通过一个替换字符来保持每个字节相冲的稳定.
  • Jsonc.equals 编号 : Jsonc.equalsValue ——语义等同,忽略了注释,白空间,格式化和对象键顺序,同时保持数组顺序显著.
  • Jsonc.schema 编号 : Jsonc.fromString 编号 : Jsonc.JsoncFromString 直接将 JSONC 解码成有效效果的域计划工厂 Schema 数值.
  • JsoncFormatter 编号 : JsoncModifier 计算最小字节 JsoncEdit 用于格式化和基于路径的修改的数组,因此调用者应用最小可能的 diff 而不是重新序列化文档.
  • JsoncVisitor ——将解析后的文件作为 Stream 参观活动 Stream.take 大量输入提前终止.
  • JsoncFingerprint - RFC 8785 Canonic JSON (英语:canonicalize 编号 : canonicalizeResult上面有SHA-256内容指纹(hash, (中文(简体) ), hashText),输入失败 JsoncCanonicalizeError 而不是默默地降低或改变非JSON值; hash编号 :hashText 需要一个核心 Digest.Digest 服务.
  • JsoncFingerprint.hashResult 编号 : JsoncFingerprint.hashTextResult - 同步点 Result 变量 hash 财务报告和审定财务报表 hashText 对于在效果运行时间以外的呼叫者,使用呼叫者自己的 JsoncDigest 而不是一个 Digest 层 这样同步主机钩子可以完全指纹.
  • JsoncParseError 编号 : JsoncModificationError 带有结构化、定位有效载荷而不是不透明信息的标记错误。 敌对输入(深筑巢穴,未终止的字元)通过错误通道失败,从不作为堆叠溢出.

许可证

麻省理工学院

版本与发布记录

@effected/jsonc 共发布 32 个版本,首次发布于 2026/07/17;过去 12 个月发布了 32 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.25.0latest2026/11/102 天前
0.24.02026/11/067 天前
0.23.02026/11/0310 天前
0.22.02026/11/0112 天前
0.21.02026/10/2915 天前
0.20.12026/10/2716 天前

关于 @effected/jsonc 的常见问题

@effected/jsonc 是什么?

零依赖 JSONC 解析,编辑和格式化为 Effect schemas.

如何安装 @effected/jsonc?

在项目目录运行 npm install @effected/jsonc,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:effect(~4.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@effected/jsonc 支持 TypeScript 吗?

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

@effected/jsonc 支持 ESM 还是 CommonJS?

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

@effected/jsonc 需要什么版本的 Node.js?

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

@effected/jsonc 可以商用吗?

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

@effected/jsonc 的下载量有多少?

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

@effected/jsonc 还在维护吗?

最新版本 0.25.0 发布于 2026/11/10(2 天前);至今共发布 32 个版本,其中过去 12 个月发布了 32 个;首次发布于 2026/07/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。