项目:my-ts-axios | 版本:v1.2 | 生成日期:2026-10-06 | 依据:源码分析
依赖清单是一个库工程最诚实的自白:它暴露了作者对"自己写"与"借力"的边界判断。my-ts-axios 的运行时依赖面极为克制——package.json 的 dependencies 字段不存在,唯一的功能性依赖是 optionalDependencies 里的 form-data(缺失时自动降级,见 ADR-007),库源码只 import Node 内置模块;而开发依赖多达 36 个,覆盖构建、测试、示例、质量四条工具链。本篇把这一个可选依赖与 36 个开发依赖逐个解析:每个依赖的版本、用途、使用位置(import 或 require 的真实落点)、选型理由、替代方案与升级风险。统计口径说明:版本号取自 package.json 中的语义化范围(^ 前缀,实际安装版本以 package-lock.json 为准);"使用位置"以全库检索为准(src/test/examples/scripts 及根配置文件),只被间接加载(如 @types 声明包、prettier 被 lint-staged 以命令行方式调用)的会显式说明。重点依赖(Rollup 插件体系、Jest 生态、Vite 示例工程、Express 服务栈)在第 3 节逐段展开,第 4 节给出整体健康度评估。与《14-配置与环境详解》的分工:那篇讲"配置文件怎么写",本篇讲"依赖为什么在、是否有风险";与《06-部署运行》的分工:那篇讲"命令怎么跑",本篇讲"命令背后装了什么"。
四张表按工具链分组,表的行内不再展开论证——理由列只给"一句话选型逻辑",完整推演看第 3 节对应小节。阅读两张表的正确姿势是先扫"使用位置"列:任何一行的位置若是 examples/ 或 scripts/,意味着该依赖不进入库产物、风险被隔离在工具层;位置若是 src/,则该依赖的任何行为变化都会直接传导到运行时——本库满足这一条件的只有 form-data 一行,而它恰好被 optionalDependencies 与 try/catch 探测双重保护。另一种读法是盯"升级风险"列:标"低"的行几乎不需要维护动作,标"同步"或"配套"的行提示了升级时的联动面,标"锚点"或加粗提示的行则是勿动的版本钉子。
| 依赖 | 版本 | 用途 | 使用位置 | 选型理由 | 替代方案 | 升级风险 |
|---|---|---|---|---|---|---|
| form-data | ^4.0.0 | Node 端 multipart 表单构造(含流式附加与 getHeaders) | src/core/adapters/http.ts 顶部 try/catch require(可选探测);toNodeFormData 搬运 | Node 原生无 Web FormData(Node 18 起实验、20 才稳定),该包是事实标准;optional 装配让未安装环境降级字符串发送 | Node 18+ 全局 FormData(行为对齐后可移除依赖);busboy(更底层,需自行封装) | v5 若改导出形态或 getHeaders 行为,try/catch 探测需重验;浏览器构建中该模块被 alias 到 shims,升级不影响浏览器产物 |
| 依赖 | 版本 | 用途 | 使用位置 | 选型理由 | 替代方案 | 升级风险 |
|---|---|---|---|---|---|---|
| rollup | ^4.24.0 | 库产物打包(CJS/ESM/UMD 三形态 + sourcemap) | rollup.config.mjs 全文;scripts 的 build/start | 多格式输出、external 控制与 tree-shaking 精细,库构建事实标准 | esbuild build API(快但 UMD 支持弱)、tsup(封装好但定制 external/alias 灵活性低) | v5 大版本若有配置契约变化,双构建任务需回归;产物 diff 需跑 smoke-dist |
| @rollup/plugin-node-resolve | ^16.0.0 | 裸模块说明符解析(node_modules 定位) | rollup.config.mjs 第 25、30 行插件链 | 官方插件,与 rollup 版本同拍 | 手写 resolve 插件(不值得) | 大版本与 rollup 主版本存在配套关系,需同步升级 |
| @rollup/plugin-commonjs | ^28.0.0 | CJS 依赖转 ESM(form-data 等以 CJS 发布) | 同上 | 官方插件,处理 Node 生态 CJS 包的互操作 | 无(若全部依赖 ESM 化可移除,生态不支持) | 转换边界 bug 会体现在浏览器 UMD 产物,需 smoke 兜底 |
| @rollup/plugin-typescript | ^12.1.0 | 构建期 TS 编译(类型检查 + 转译) | 同上;两构建共享 tsconfig: './tsconfig.json' | 与 tsc 声明输出共用一份 tsconfig,口径一致 | 先 tsc 再 babel/rollup(两段式,配置分裂) | 与 typescript 5.9 的兼容矩阵需留意;编译错误在构建期暴露 |
| @rollup/plugin-json | ^6.1.0 | import JSON 支持 | 同上 | 官方全家桶成员;当前源码未直接 import JSON,属保守保留 | 可删除(惰性依赖) | 无实质风险;删除前需确认无隐式 JSON import |
| @rollup/plugin-alias | ^5.1.0 | 浏览器构建把 Node 内置模块与 form-data 映射到 shim | rollup.config.mjs 第 20~23、29 行 | 双端构建的核心机关(ADR-007) | rollup 内置 output.globals 只解决 UMD 全局名,不能替换模块路径 | 低;alias 规则错误会让浏览器产物引用真实内置模块(构建失败可见) |
| rimraf | ^6.0.0 | 跨平台清空 dist | scripts prebuild | Windows/macOS/Linux 一致的 rm -rf | node -e fs.rmSync(零依赖替代) | 低 |
| typescript | ^5.9.0 | 语言编译器:tsc --noEmit 检查、声明输出、rollup 内编译 | scripts build:types、@rollup/plugin-typescript、ts-jest | strict 模式全量类型检查是本库质量主张的一部分 | —(语言本体) | 5.x 内小版本低风险;大版本可能改变声明输出形状,需 diff dist/types |
| 依赖 | 版本 | 用途 | 使用位置 | 选型理由 | 替代方案 | 升级风险 |
|---|---|---|---|---|---|---|
| jest | ^29.7.0 | 测试运行器 + 覆盖率(istanbul)+ 四项硬门槛 | package.json jest 段、scripts test | 覆盖率门槛与 setup 体系成熟;CI 直接消费 | vitest(快,但 jasmine-ajax 兼容问题原样存在,迁移是无关扰动) | 30 大版本发布后迁移需重验 boot.ts 兼容层 |
| ts-jest | ^29.2.0 | Jest 内 TS 转译(保留类型检查) | jest.transform 第 70~74 行 | 与 jest/typescript 版本三角稳定 | @swc/jest(快,丢类型检查) | 随 jest/typescript 升级需同步 |
| jest-environment-jsdom | ^29.7.0 | jsdom 测试环境(xhr 适配器、cookie、AxiosHeaders 依赖 DOM) | jest.testEnvironment: 'jsdom' | Jest 28 起独立成包,xhr 适配器测试的物理前提 | happy-dom(更轻,jasmine-ajax 未验证) | 必须与 jest 主版本严格同版本号 |
| jasmine-ajax | ^4.0.0 | 接管 XMLHttpRequest,断言请求头/体并回放伪造响应 | test/boot.ts 第 20~22 行加载;test/xhr.spec.ts、test/xsrf.spec.ts 等 | 成熟 XHR mock 生态,保真度高于手写 mock(ADR-009) | 手写 XHR mock 类;nock(只覆盖 Node http,不覆盖 xhr) | 4.x 锁定 jasmine 全局接口,升级需重验 boot.ts |
| jasmine-core | ^3.4.0 | 为 jasmine-ajax 提供独立 jasmine 运行环境 | test/boot.ts 第 7~12 行 JasmineCore.core(JasmineCore) | jasmine-core@3 的模块导出即 jasmine-require 命名空间,是兼容引导的前提(见 boot.ts 第 9 行注释) | 升级 4/5 需重写引导层 | 全仓最脆的版本锚点:3.x 被注释显式锚定,勿随手升级 |
| @types/jasmine-ajax | ^3.1.4 | jasmine-ajax 的 TS 类型 | test/*.spec.ts 的 installMockAdaptor 等调用 | 类型面完整 | — | 低 |
| @types/jest | ^29.5.14 | describe/it/expect 全局类型 | 全部 spec 文件 | 标配 | — | 随 jest 同步 |
| @types/node | ^20.14.0 | Node 内置模块与 process 类型(http 适配器、helpers、scripts) | src/core/adapters/http.ts、src/helpers/progressStream.ts 等 | 与 engines >=14 不冲突(类型取 20 是开发环境口径,见《14》3 节) | — | 高版本类型可能收紧 stream 泛型签名 |
| @types/qs | ^6.9.0 | 示例工程中 qs 的类型 | examples/config/App.vue、examples/more/App.vue 的 import qs from 'qs' | 示例 TS 文件类型检查需要 | 示例改 JS 可删 | 低 |
| 依赖 | 版本 | 用途 | 使用位置 | 选型理由 | 替代方案 | 升级风险 |
|---|---|---|---|---|---|---|
| vite | ^8.1.5 | 示例工程 dev server(HMR)+ 多页面构建 | examples/vite.config.ts;scripts dev/examples:build | dev 体验最好;多入口扫描 + alias 到 node-stub 衔接库源码(见《00》3 节) | webpack-dev-server、esbuild serve(都要手写更多胶水) | 主版本很新(8.x),插件与 Node 版本要求高(开发建议 Node 20+);升级注意 rollupOptions 契约 |
| @vitejs/plugin-vue | ^6.0.8 | Vue 3 SFC 编译 | vite.config.ts plugins | Vue 官方插件 | — | 与 vite 主版本存在配套矩阵 |
| vue | ^3.5.40 | 示例页面框架 | examples/*/main.ts、App.vue(ref/createApp) | 示例只需轻量响应式展示 | 原生 DOM 脚本(会失去示例的组件组织) | 低(示例层) |
| express | ^4.21.0 | mock API 服务(Vite 插件内挂载)+ 8088 跨域服务器 | examples/plugins/mock-api.ts 第 2 行、examples/server2.js 第 1 行、routes/*.js | 路由组织与八组示例一一对应,教学直白 | 原生 http(路由手写量大)、hono/koa | 5.x 迁移是 Express 生态已知大坑,示例层锁定 4.x 合理 |
| body-parser | ^1.20.3 | 解析 JSON/urlencoded 请求体 | mock-api.ts 第 3 行、server2.js 第 2 行 | express 4.x 内置 json() 即其同源实现,显式引入便于跨版本一致 | express.json()(4.16+ 内置) | 低 |
| cookie-parser | ^1.4.7 | 解析 cookie(XSRF-TOKEN-D 种植与回读演示) | mock-api.ts 第 4 行、server2.js 第 3 行 | XSRF 示例需要 | 手写 cookie 解析 | 低 |
| connect-multiparty | ^2.2.0 | 解析 multipart 文件上传 | mock-api.ts 第 5 行(import multipart) | 上传示例(progress/postForm 演示)需要服务端落盘解析 | busboy/multer(multer 更主流,但基于 busboy 的 API 不同) | 维护活跃度一般;仅示例层,风险可控 |
| qs | ^6.13.0 | 示例中构造复杂 query 串 | examples/config/App.vue 第 4 行、examples/more/App.vue 第 5 行 | 与库内 paramsSerializer 对照演示 | URLSearchParams(表达力弱于 qs 的嵌套) | 低 |
| atob | ^2.1.2 | 老版本 Node 的 atob 补齐(Basic Auth 示例路由) | examples/routes/more.js 第 1 行 require | Node 16 前无全局 atob,保险引入 | Buffer.from(..., 'base64')(现代写法可替换) | 极低;示例层惰性依赖 |
| 依赖 | 版本 | 用途 | 使用位置 | 选型理由 | 替代方案 | 升级风险 |
|---|---|---|---|---|---|---|
| eslint | ^9.0.0 | 静态检查 | eslint.config.mjs;scripts lint、CI Lint 步骤 | flat config 是 9.x 的现行形态 | — | 9.x 内小版本稳 |
| typescript-eslint | ^8.0.0 | TS 解析器 + recommended 规则集 | eslint.config.mjs 的 tseslint.config | 合并包(原 parser/plugin 二合一),配置最短 | @typescript-eslint/parser+plugin 分装 | 与 eslint/typescript 兼容矩阵同步 |
| eslint-config-prettier | ^10.0.0 | 关闭与 prettier 冲突的格式规则 | eslint.config.mjs 第 2、17 行 | 关注点分离:eslint 管正确性、prettier 管风格 | eslint-plugin-prettier(把格式塞回 eslint,慢且报错噪音大) | 低 |
| prettier | ^3.3.0 | 格式化(semi:false, singleQuote:true) | package.json prettier 段、lint-staged | 零争论格式化 | — | 4.x 若改默认风格会放大 diff,届时锁配置 |
| husky | ^9.1.0 | git hooks 管理 | scripts prepare、.husky/pre-commit(npx lint-staged) | 轻量 hooks | simple-git-hooks、lefthook | v9 的初始化脚本形式与 v8 不同 |
| lint-staged | ^15.2.0 | 只检查暂存文件(prettier --write + eslint --fix) | package.json lint-staged 段 | 提交提速 | 全量 lint(慢) | 低 |
| commitizen | ^4.3.0 | 交互式规范提交 | scripts commit(git-cz) | 配合 commitlint 形成"写时引导 + 校验时拦截"闭环 | 手写提交信息靠自觉 | 低 |
| cz-conventional-changelog | ^3.3.0 | commitizen 的 conventional 适配器 | package.json config.commitizen | 与 commitlint 规则同源 | cz-customizable | 低 |
| @commitlint/cli | ^19.8.0 | 提交信息校验 | package.json commitlint 段(extends config-conventional) | 提交规范的拦截端 | — | 低 |
| @commitlint/config-conventional | ^19.8.0 | conventional 规则集 | 同上 | 社区标准 | 自定义规则 | 低 |
rollup.config.mjs 一共用了五个官方插件,它们的排布本身就是一份"库打包最小完备集"的教材。typescript 插件排在 resolve/commonjs 之前(第 25、30 行),承担构建期类型检查——这意味着 npm run build 天然是一次全量类型回归,类型错误会在打包前暴露;两个构建任务共享同一份 tsconfig: './tsconfig.json',与独立运行的 build:types(tsc --declaration --emitDeclarationOnly 输出 dist/types)保持同一口径,避免了"打包器转译一版、声明文件另一版"的漂移。alias 插件是浏览器构建的灵魂:第 20~23 行把 http/https/zlib/stream/form-data 五个模块名全部映射到 src/shims/node-builtins.ts,让 UMD 产物零 external、自包含(完整论证见 ADR-007 与《14-配置与环境详解》2.2 节);注意它只出现在 browserPlugins,Node 构建走的是 external 声明(第 15 行)——同一个依赖问题在两个构建里给出了相反的答案,这正是"产物面向的运行时不同"的直接表达。commonjs 插件处理 Node 生态仍以 CJS 发布的包(典型如 form-data)在 ESM 化打包流程中的互操作;resolve 插件负责裸说明符定位;json 插件当前源码并无 import JSON 的实际消费点,属于保守保留的惰性依赖,删除需要先全库确认无隐式 JSON 引入。这套插件组合的验证闸门是 scripts/smoke-dist.cjs:三种产物逐一以消费者身份加载并断言导出面,任何插件升级引入的产物形变都会被它拦下。
测试链的形态是"jest + ts-jest + jsdom"三件套加一个特例。jest 29.7 提供运行器、istanbul 覆盖率与四项硬门槛(branches 80 / functions 85 / lines 90 / statements 90,ADR-010);ts-jest 在 transform 段把 TS 转译并保留类型检查——测试代码的类型错误同样会挂 CI,这把测试代码也纳入了类型契约。jest-environment-jsdom 必须与 jest 主版本严格同号(Jest 28 起独立发包),它是 xhr 适配器、cookie 读取、AxiosHeaders 等 DOM 相依代码的物理前提。特例是 jasmine-ajax + jasmine-core 3.x:jest-circus 取代内置 jasmine 后,jasmine-ajax 失去了宿主,test/boot.ts 手动引导一个独立 jasmine-core 环境供给它使用(引导细节与两条"不要做"见 ADR-009 与《09-测试与质量保障》第 3 节)。这个组合的代价是把 jasmine-core 锚定在 3.x——package.json 里 "jasmine-core": "^3.4.0" 的 3 不是笔误,boot.ts 第 9 行注释明示"jasmine-core@3 的模块导出本身就是 jasmine-require 命名空间",升级 4/5 会破坏引导层。评估测试链健康度时的关键判断是:脆弱点被注释显式登记了,这比"看起来很稳"重要得多。
vite ^8.1.5 只服务 examples(dev server 与多页面构建),不参与库产物。它的两个独有机关值得展开。其一,多入口扫描:examples/vite.config.ts 第 8~14 行用 readdirSync 扫描每个含 index.html 的子目录生成 rollupOptions.input,新增示例页零配置接入(《11-扩展开发指南》SOP 六依赖这一点)。其二,示例页直接 import 库源码:示例里的 import axios from '../../src' 不需要先跑库构建,靠的是 resolve.alias 把 stream/http/https/url/zlib 指到 examples/shared/node-stub.ts——与 Rollup 浏览器构建的 shim 机制同构但独立实现,两份 stub 的存在是有意为之的解耦(示例层不依赖构建产物,库构建也不被示例牵连),代价是 shim 面需要两处维护(见《13》远期方向的关联讨论)。@vitejs/plugin-vue 6 + vue 3.5 提供 SFC 编译与轻量响应式(示例页只用 ref/createApp 级别的 API)。Vite 8 是全仓最年轻的大版本依赖,对 Node 版本要求也最高(README 明示开发需 Node 20+),这是示例链(而非库链)的约束——库运行时 engines 只有 >=14.0.0。
示例的服务端由四个包组成,各有不可替代的戏份。express 4.21 是骨架:八组路由(examples/routes/*.js)经 examples/plugins/mock-api.ts 的 Vite 插件挂进 dev server 的 configureServer 钩子,同时拉起 8088 端口的独立跨域服务器 examples/server2.js(CORS 预检与跨域 cookie 演示的真实靶机)。body-parser 与 cookie-parser 提供 JSON 体解析与 cookie 解析——后者支撑 XSRF 演示:mock 路由种植 XSRF-TOKEN-D cookie,浏览器端 xhr/fetch 适配器读取后回写 X-XSRF-TOKEN 头,链路两端都在本仓库内闭环。connect-multiparty 解析 multipart 上传(进度与 postForm 示例的服务端落盘),它在 npm 上的维护活跃度一般,但仅在示例层使用、不进入库产物,风险被隔离。qs 与 atob 是两个小配角:前者在 config/more 两个示例页构造复杂 query 与库内 paramsSerializer 对照,后者为老 Node 补齐 atob 全局供 Basic Auth 路由解码。整条服务栈的选型标准是"教学直白优先于生产先进"——Express 4 的路由形态与八组示例一一对应,一眼可查。
把四条链放回同一张网里看,有三个值得写下来的观察。观察一:每条链都有一个"最深依赖",且互不共享。 构建链的最深依赖是 typescript(rollup 插件与 ts-jest 都要消费它),测试链的最深依赖是 jasmine-core,示例链的最深依赖是 vite,质量链的最深依赖是 eslint——四条链只在 typescript 上交汇,这意味着除 TS 升级外的任何单链升级都不会跨链传导,升级的影响半径被依赖结构天然切小。观察二:版本策略是"双端不同拍"。 库侧(engines >=14)保守、工具侧激进(vite 8 / eslint 9 / typescript 5.9 全是各自主线的大版本早期),这符合"运行时兼容性是承诺、开发体验紧跟主线"的库工程惯例,但也意味着贡献者本机的 Node 版本必须满足工具侧要求(README 明示 20+),与库运行时要求形成两套口径——《06-部署运行》第 1 节的环境要求表正是这两套口径的合并陈述。观察三:全仓没有锁死精确版本(无 package-lock 之外的 pin),但有三个"事实钉子"。 jasmine-core 3.x、jest ↔ jest-environment-jsdom 的严格同号、rollup ↔ 官方插件的配套矩阵——它们没有被 --save-exact 固定,而是靠注释与约定维系,这是整张依赖网里最需要人的注意力持续在场的部分;若未来引入 Renovate/dependabot 类自动升级工具(《13》条目 8 缺口一的延伸),这三个钉子应显式列入 ignore 列表或需要人工审批的分组。
质量链分两段。提交前:husky 9 的 pre-commit 触发 lint-staged,对 {src,test}/**/*.ts 执行 prettier --write 与 eslint --fix(package.json lint-staged 段);提交时:commitizen(git-cz)交互式生成 conventional 格式信息,@commitlint/cli 按 config-conventional 校验。静态检查:eslint 9 flat config(eslint.config.mjs)+ typescript-eslint 8 的 recommended 集,ignores 显式排除 dist/coverage/examples/rollup.config.mjs/eslint.config.mjs;三条规则定制都有注释可查——no-explicit-any 关闭(HTTP 载荷语义大量使用 any)、no-require-imports 关闭(boot.ts 兼容层与 http 适配器的可选依赖探测需要 require)、no-unused-vars 放行下划线前缀。eslint-config-prettier 负责让 eslint 不与 prettier 争格式。typescript 5.9 是唯一贯穿四条链的依赖:tsc --noEmit 检查、build:types 声明输出、rollup 内编译、ts-jest 转译——它的一致性地位使版本升级必须整仓回归(dist/types 的 diff 是最直接的观察面)。
综合评估给出五个结论。结论一:运行时依赖面是满分形态。 dependencies 字段不存在,唯一的 form-data 以 optionalDependencies 表达"装了更好、没装能跑"(try/catch 探测 + 降级字符串发送),npm 安装体积与供应链面都被压到最小——对一个 HTTP 库而言,"不给用户带包"本身是核心竞争力(对比:官方 axios 的 form-data/follow-redirects/proxy 是 dependencies,曾数次因传递依赖问题发版)。结论二:最脆弱的锚点被显式登记。 jasmine-core 3.x 是全仓唯一"升级即破坏"的依赖,但 boot.ts 注释与 ⚠️ 级别的约束都已写明,风险从"未知"降级为"已知且受控"。结论三:最年轻的依赖集中在示例层。 vite 8、@vitejs/plugin-vue 6 都是大版本早期的形态,而它们只影响 examples 与 CI 的 examples:build 步骤,库产物与之零耦合——示例层的激进换来库层的稳健,边界划得正确。结论四:升级风险存在两处联动面。 其一 jest ↔ ts-jest ↔ jest-environment-jsdom ↔ @types/jest 的四角同步(升级 jest 必须整组同升,并重验 boot.ts);其二 rollup ↔ @rollup/plugin-* 的配套矩阵(升级 rollup 需要同步 node-resolve 16 一组,并以 smoke-dist 观察产物 diff)。结论五:待改进项有两个,均为低成本。 @rollup/plugin-json 与 atob 是两个惰性依赖(前者无 import 消费点、后者可用 Buffer 原生写法替代),删除可轻微缩短安装树;但两者都无害,是否清理属于卫生学而非风险管理。总体判断:这是一份克制的、可审计的、事故有化石的依赖清单,健康度在同类学习项目中属于第一梯队;⚠️ 待确认:package-lock.json 的实际锁定版本未逐包核对(本文版本号均为 package.json 声明范围),如需精确审计请以 npm ls 输出为准。