@ effect/ tsconfig-json (英语)
可编译 tsconfig.json 处理效果: 文档和编译器- 选项计划, extends- 有 tsc 自身合并语义的链解析度,最近的配置发现和用于虚拟类型Script环境的可移植配置过滤器. 每个剖面都是JSONC——评论和后继逗号在任何地方都是合法的,完全像 tsc 对待它们一样——以及各种选择,这些计划不知道通过解码和编码,而不是被丢弃.
预
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/tsconfig-json
读取 tsconfig.json 正确的意思是复制 tsc 所做的, Tsc 所做的不仅仅是 JSON.parse 加号 Object.assign。一个 extends 目标解像模块: 赤光光光光光光的行走祖先 node_modules 目录, 一个软件包 exports 映射可以重定向或屏蔽它,并且 a tsconfig 字段可以完全指向别的地方。 合并链条是每个字段的,路径选项与宣布它们而不是你装入的配置相对应 ${configDir} 在顶端配置目录中替换一次。 这些规则取自TypeScript编译器的源头,并在这里编码为由数据驱动的测试,所以你得到的分辨率是分辨率tsc计算.
包在不导入的情况下完成全部任务 typescript,甚至不是一个类型。 它在字符串级别工作—— "target": "es2023" 通过计划、合并和发现保留一个字符串——而版本相接的数值表映射在 TsEnumCodec 作为普通数据表格,将真正的编译器所期望的数字形状转换为明确的最后一步,而不是随处携带的依赖。 输入错误总是通过打出错误通道失败, 递归 extends 行走带有循环和深度守护,因为一个配置文件是不可信的输入.
安装
npm install @effected/tsconfig-json @effected/jsonc @effected/walker effect
pnpm add @effected/tsconfig-json @effected/jsonc @effected/walker effect
需要节点.js~~24.11.0. effect v4, (英语), @effected/jsonc 财务报告和审定财务报表 @effected/walker 是同行的依赖关系;没有自己的运行时间依赖关系.
全体 @effected/* 软件包仅为无害环境管理:只公布出口地图 import 条件,所以 require() 包括解析 CJS 模式的工具 —— 与节点失败 ERR_PACKAGE_PATH_NOT_EXPORTED 而不是装入不存在的 CJS 建筑。 从ES模块导入.
所有IO通过 FileSystem 财务报告和审定财务报表 Path 从 effect 核心,不是平台包,所以消费者一次在边缘提供它们(@effect/platform-node 在节点上, @effect/platform-bun 测试提供了核心 Path.layer 外加来自 @effected/memfs ——未安装平台软件包.
快开始
解决一个配置及其全部 extends 链条 :
import { TsconfigLoader } from "@effected/tsconfig-json";
import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
import * as NodePath from "@effect/platform-node/NodePath";
import { Effect, Layer } from "effect";
const PlatformLive = Layer.mergeAll(NodeFileSystem.layer, NodePath.layer);
const resolved = await Effect.runPromise(TsconfigLoader.resolve("./tsconfig.json").pipe(Effect.provide(PlatformLive)));
console.log(resolved.extendedPaths);
// every config on the extends chain as normalized absolute paths, base-most first and your own config last
console.log(resolved.compilerOptions);
// the merged options after folding the whole chain — later configs win per field, paths replaced wholesale
TsconfigLoader.compilerOptions("./tsconfig.json") 是相同的管道 预测到合并的选项, 因为当有效选项是你想要的.
在您只有起始目录时先查找最近的配置 :
import { TsconfigDiscovery } from "@effected/tsconfig-json";
import { Effect, Option } from "effect";
const nearest = TsconfigDiscovery.findNearest(process.cwd());
// Effect<Option<string>, never, FileSystem | Path> — absence is Option.none(), never an error
将结果交给一个真实的编译器,将enum家族编码为它们的数值形式,或者将其缩小为可移植子集,一个虚拟的TypeScript环境可以安全地再利用:
import { PortableTsconfig, TsEnumCodec } from "@effected/tsconfig-json";
console.log(TsEnumCodec.encodeCompilerOptions({ target: "es2023", strict: true, lib: ["esnext"] }));
// { target: 10, strict: true, lib: [ 'lib.esnext.d.ts' ] }
console.log(PortableTsconfig.make(resolved).compilerOptions.noEmit);
// true — always forced, whatever the source config declared
console.log(PortableTsconfig.make(resolved, { includeTypes: true }).compilerOptions.types);
// carries the source config's `types` package names when it declares them, omitted when absent
includeTypes 选择进入,默认为 false 因为排放 types 让科技部要求这些 @types 软件包解析 — 虚拟环境中的硬错误, 无 node_modules。当环境实现时通过它 @types 本身; 在 TypeScript 自动包含所找到的任何内容的允许默认情况下离开 .
同步装入
邦德勒插件钩和配置工厂往往无法等待. TsconfigLoaderSync 在您提供的文件和路径操作上同步运行未变的加载器管道——软件包仍然导入没有 node:* 模块,而节点的内置直接满足操作:
import { existsSync, readFileSync } from "node:fs";
import * as path from "node:path";
import { TsconfigLoaderSync } from "@effected/tsconfig-json";
const options = {
fileSystem: { exists: existsSync, readFile: (p: string) => readFileSync(p, "utf8") },
path, // node:path satisfies SyncPath verbatim; path.win32 / path.posix force a convention
};
const compilerOptions = TsconfigLoaderSync.compilerOptions("./tsconfig.json", options);
// the merged options for the full extends chain — the same result TsconfigLoader.resolve computes
load 财务报告和审定财务报表 resolve 具有相同的同步形式。 失败是Aync管道自己打出来的错误 TsconfigParseError, (中文(简体) ), TsconfigExtendsError 或一个 PlatformError 包着任何你 readFile 扔了... 从来没有纤维失效的包裹.
TypeScript 7 和经典编译器 API
类型脚本 7 的本地 tsc 仅作为版本分贝的船舶 . export ——后面没有JS编译器API. 作为库驱动打字器的软件包( Name@typescript/vfs,语言服务,程序 API)既不能对 TypeScript 7 安装进行键入,也不能运行时装入 TypeScript 7 typescript 6岁时丧失了本地人 tsc 并打开工具链端点 ^7 未达到。 保持两者的食谱都从这里开始,因为这个软件包是去除所依赖的编译时间的一半.
- 键入到 tsconfig JSON 表格中,而不是编译器中。 公共选项类型
CompilerOptions.Type—— 说{ target: "es2022" }绳子一直向下,所以没有src或试验进口typescript,甚至不是一个类型。 德夫尔typescript留在7号线上,本地tsc --noEmit仍然运行类型检查和工具链^7同行保持满意. - 在一个运行时间接合时转换 .
TsEnumCodec.encodeCompilerOptions将字符串窗体映射到一个真正的编译器所期望的和返回的数值ProgrammaticCompilerOptions,形状 ats.CompilerOptions- 型号的API没有铸币。 只有一个呼叫网站知道一个编译器存在. 入境方向是CompilerOptionsFromProgrammatic一个计划,而不是一个功能: 把它当活的ts.CompilerOptions,数字化的正文或输出encodeCompilerOptions已验证CompilerOptions.Type回来时,有一个不可操作的数字失败解码而不是漏出. - 作为测试运行时间的经典安装, 其中 JS API 是真正需要的: 一个 dev- only
"typescript-classic": "npm:typescript@^6.0.3"外加维特resolve.alias绘图typescript对它。 面对消费者的同龄人可以选择^6——只运行时间,适用于编译器-触控模块的调用者. - 过
tsLibDirectory驾驶时明确@typescript/vfs它会定位lib.*.d.ts结束require.resolve("typescript"),在此设置下解决 TypeScript 7 安装,而该安装没有 lib 目录: 地图返回 空,沉默地,没有错误可循. 从您实际装入的模块中获取目录 .
{
"devDependencies": {
"typescript-classic": "npm:typescript@^6.0.3"
}
}
import { defineConfig } from "vitest/config";
export default defineConfig({
resolve: { alias: { typescript: "typescript-classic" } },
});
import { dirname } from "node:path";
import { TsEnumCodec } from "@effected/tsconfig-json";
import { createDefaultMapFromNodeModules } from "@typescript/vfs";
import ts from "typescript";
const fsMap = createDefaultMapFromNodeModules(
TsEnumCodec.encodeCompilerOptions({ target: "es2023", lib: ["esnext"] }),
ts,
dirname(ts.sys.getExecutingFilePath()),
);
console.log(fsMap.size);
// the lib files the loaded compiler ships; drop the third argument and this is 0
特征
TsconfigJson编号 :TsconfigJsonFromString——文档 schema及其JSONC字符串编码. 评论和后序逗号在每一段都是合法的;没有JSON限制路径.CompilerOptions- 用于compilerOptions:enum值对大小写不敏感地解码并编码为犬科小写,未知或被删除的选项在通过时能幸存回程.TsconfigLoader.load编号 :TsconfigLoader.resolve编号 :TsconfigLoader.compilerOptions——读出并解码一个配置,全部解决extends链式深度先与每个分支的循环堆栈(diamond 链是合法的),对于相对的,有根的和赤色的标靶来说,是深度守护和tsc的目标分辨率exports地图,或将解开的链条直下投影到其合并的选项.TsconfigLoaderSync—— 只同步主机的同步外观 :load, (中文(简体) ),resolve财务报告和审定财务报表compilerOptions超过消费供应{ fileSystem, path }操作,运行同一管线并投掷相同的打字错误.ResolvedTsconfig- 后面的纯合并引擎resolve: 每字段合并语义, 路径选项解析到声明配置目录, 最终${configDir}替换和pathsBase出处,完全没有文件系统访问.TsconfigDiscovery.findNearest- 离这里最近的tsconfig.json(或任何文件名通过)options.filename在起始目录上方或以上@effected/walker; 一个无法读取的祖先无法在它上方隐藏一个配置.TsEnumCodec——字符串qq 数字表作为零的平方数据typescript进口.encodeCompilerOptions返回导出的ProgrammaticCompilerOptions类型 - 数字形状ts.CompilerOptions期待,所以你把它交给一个ts.CompilerOptions- 成型的API没有铸件 - 与lib文件名格式中的条目,编译器将逐字解决;decodeCompilerOptions倒车.CompilerOptionsFromProgrammatic——与验证代码相同的表格,用于持有TypeScript程序拼音的呼叫者. 解码器接受数字化的enums,cononical的字符串,大小写变化的字符串,任何三和三的混合lib; 编码返回数字形式。 没有表格条目的数值失败解码为打入的策略问题,而不是通过,这是检查TsEnumCodec.decodeCompilerOptions故意不做.PortableTsconfig.make——允许列表投影到机器独立的类型语义选项,带有composite: false财务报告和审定财务报表noEmit: true强制:一个虚拟 TypeScript 环境(Twoslash, API Creator, 内存语言服务)的切片可以安全地继承. 可选{ includeTypes }参数带有源配置types包名也放在便携式形状上,用于一个虚拟环境可以解决的呼叫者@types软件包本身;typeRoots无论是哪种方式, 都保留, 因为它命名了机器专用、 配置位置依赖目录 .JsxConfig.fromCompilerOptions——JSX转换捆绑器可以配置,从解码选项投射:react-jsx编号 :react-jsxdev选择带有导入源的自动运行时间( 默认为react,tsc本身的默认),react选择经典,和preserve, (中文(简体) ),react-native或缺席jsx产量Option.none()。 。 。 .- 在所有地方打入失败: 文件格式错误是一个
TsconfigParseError一条断链就是一条TsconfigExtendsError带有not-found编号 :cycle编号 :depth编号 :empty理性和全解析链, IO 错误流经PlatformError没有什么是失败的缺陷.