news 2026/9/4 14:09:33

Vite 致谢页全解析:依赖鸣谢清单如何由 LICENSE.md 与 package.json 自动生成

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vite 致谢页全解析:依赖鸣谢清单如何由 LICENSE.md 与 package.json 自动生成

Vite 致谢页全解析:依赖鸣谢清单如何由 LICENSE.md 与 package.json 自动生成

【免费下载链接】viteNext generation frontend tooling. It's fast!项目地址: https://gitcode.com/GitHub_Trending/vi/vite

Vite 官方文档中的致谢页(Acknowledgements)并不是一份人工维护的静态名单——页面上的依赖包、作者与赞助信息全部由 VitePress 数据加载器在构建时从仓库文件自动读取和聚合。本文沿这条完整的"许可证汇总 → LICENSE.md → 致谢页"流水线逐环节展开,并解释 Vite "绝大多数依赖放入 devDependencies 再预打包"的依赖策略,帮助你在阅读这份鸣谢清单的同时,理解 Vite 核心包是如何保持轻量的。

一、致谢页包含什么:人、资金与包的完整清单

致谢页的页面结构由四个板块组成,这也是本文的骨架:

  • Contributors(贡献者):Vite 由一个国际化团队开发,核心成员见团队页;同时鸣谢所有通过代码、Bug 报告、文档及文档翻译帮助改进 Vite 的贡献者。
  • Sponsors(赞助者):页面通过 VitePress 主题提供的useSponsor可组合函数和VPSponsors组件动态渲染赞助商列表,支持渠道为 GitHub Sponsors 与 Open Collective。
  • Dependencies(依赖):又分两部分——Notable Dependencies(重点依赖,以卡片形式展示作者、描述与仓库/赞助链接)和Bundled Dependency Authors(被打包进发行产物的依赖的作者汇总表,按作者归组)。
  • Development Tools(开发工具):支撑 Vite 自身开发工作流的工具清单。
  • Past Notable Dependencies(历史重点依赖):记录 Vite 早期版本使用、如今已被替换的项目。

页面本身只是"展示层"(docs/acknowledgements.md 中大量使用v-for循环渲染数据数组),真正决定页面内容的是下一节的数据源文件。

二、数据源:一个构建期读取 node_modules 的 VitePress 数据加载器

致谢页所有动态数据来自 docs/_data/acknowledgements.data.ts。这个文件是一个标准的 VitePress data loader(导出{ watch, load }),构建文档时执行,其工作分三步:

1. 静态名单 + 解析 LICENSE.md 得到"被打包依赖"全集。文件开头硬编码了三份名单(acknowledgements.data.ts#L5-L20):

// Notable dependencies to highlight (by package name) const notableDependencies = [ 'rolldown', 'postcss', 'lightningcss', 'chokidar', 'magic-string', ] // Dev tools used for development const devToolNames = [ 'eslint', 'oxfmt', 'typescript', 'vitest', 'playwright-chromium', ]

而"Bundled dependencies"并不在这里写死,而是由parseBundledDependenciesFromLicense()(acknowledgements.data.ts#L113-L126)从 packages/vite/LICENSE.md 中解析:

const bundledSection = content.split('# Bundled dependencies:\n')[1] // Match all ## headers which contain package names (comma-separated for grouped packages) const deps = [...bundledSection.matchAll(/^## (.+)$/gm)].flatMap((m) => m[1].split(',').map((n) => n.trim()), )

注意split(',')这一步:LICENSE.md 中的##标题可能是"pkg1, pkg2, pkg3"这样的逗号分组形式(例如当前的## braces, fill-range, is-number## mlly, ufo),解析器必须按逗号拆开才能还原出真实包名——这个细节与第三节 LICENSE.md 的生成逻辑严格对应。

2. 逐包读取 node_modules 中的 package.json。readPackageInfo()(acknowledgements.data.ts#L195-L219)依次尝试packages/vite/node_modules/<name>/package.json和仓库根node_modules/<name>/package.json,提取nameversiondescriptionauthorrepositoryfunding字段。包不存在时返回null并被过滤——注释说明原因:某些包可能只是可选 peer 依赖,并未真正安装。配套的两个归一化函数覆盖了 npm 元数据的各种"方言":

  • normalizeRepository()(acknowledgements.data.ts#L128-L159):将git+https://...ssh://user@host.com:org/repo.gitgithub:org/repogitlab:bitbucket:以及裸的owner/repo等形式统一成可用的 HTTPS 链接;
  • parseAuthor():同时支持对象形式和字符串形式("Name <email> (url)"),拆出姓名与个人主页;
  • normalizeFunding()funding字段无论是字符串、对象还是数组,统一取第一个 URL。

3. 按作者归组,生成"Bundled Dependency Authors"表。groupByAuthor()(acknowledgements.data.ts#L221-L264)把非重点的打包依赖(bundledDependencies中排除掉notableDependencies后的部分)按author字段分桶,包名与作者均按字母序排序。有一个展示层面的优化:若某作者名下所有包的fundingURL 完全一致,则把赞助链接提升到作者级别,包列表里就不再逐个重复显示 Sponsor 按钮。

最后,loader 通过watch: ['../../packages/vite/LICENSE.md'](acknowledgements.data.ts#L314-L319)声明了对 LICENSE.md 的监听——依赖集合变化导致 LICENSE.md 重新生成后,文档构建会自动重建该页数据,整个链路因此是自我同步的。

三、流水线上游:LICENSE.md 本身是构建时自动生成的

packages/vite/LICENSE.md并非手写。它的生成逻辑在 packages/vite/rollupLicensePlugin.ts:一个包装rollup-plugin-licensethirdParty钩子的构建插件,做四件事:

  1. 读取核心许可证:以仓库根 LICENSE(MIT)作为 "Vite core license" 段落写入文件开头;
  2. 排序与分组(rollupLicensePlugin.ts#L22-L43):依赖按名称排序;许可证全文相同的依赖被合并成一个## pkg1, pkg2, pkg3分组标题——这正是第二节数据加载器要按逗号切分的来源。若同组依赖的许可证与作者也完全一致,License:/By:/Repositories:元信息只打印一次;
  3. 输出汇总:在# Licenses of bundled dependencies段落中列出产物包含的全部许可证类型(当前为 Apache-2.0、BSD-2-Clause、CC0-1.0、ISC、MIT),随后是# Bundled dependencies:明细区;
  4. 落盘并提醒提交(rollupLicensePlugin.ts#L108-L116):只有内容变化时才写回LICENSE.md,并在终端打印黄色警告 "LICENSE.md updated. You should commit the updated file."。插件还覆盖了renderChunk/generateBundle钩子,在 watch 模式下直接跳过,避免开发期反复写文件。

该插件挂载在 packages/vite/rolldown.config.ts 的nodeConfig上(rolldown.config.ts#L134-L138):

plugins: [ shimDepsPlugin({ /* ... */ }), buildTimeImportMetaUrlPlugin(), licensePlugin( path.resolve(dirname, 'LICENSE.md'), 'Vite core license', 'Vite', ), // ... ]

这个nodeConfig打包src/node/index.tssrc/node/cli.tssrc/node/internalIndex.ts三个入口,并把pkg.dependenciespkg.peerDependencies的全部键名标记为external(rolldown.config.ts#L86-L99)——也就是说真正被内联进 dist 的只有 devDependencies,而rollup-plugin-license在生成报告时恰好只统计"实际被打包进来"的依赖,于是 LICENSE.md 的内容就精确等于"发行产物中包含的第三方代码",致谢页也因此得名 "Bundled" dependencies。

四、为什么有这么多"Bundled Dependencies":Vite 的依赖瘦身策略

packages/vite/package.json 末尾有这样一条注释,堪称理解致谢页的前提:

"//": "READ CONTRIBUTING.md to understand what to put under deps vs. devDeps!"

CONTRIBUTING.md 的 "Notes on Dependencies" 一节给出了完整规则:

  • 目标:Vite 追求轻量,包括对 npm 依赖数量和体积的敏感;
  • 核心机制:"We use Rolldown to pre-bundle most dependencies before publishing"——发布前用 Rolldown 把大部分依赖预打包进产物,因此即使某个依赖在运行时源码中被使用,默认也应放进devDependencies
  • 例外(必须进dependencies的情况):类型包(@types/*);含二进制文件无法被打包的依赖(如rolldownlightningcss);其自带类型会出现在 Vite 公开类型中的依赖(如rolldown);
  • 约束:由于 devDependencies 打包后从产物中"消失",源码中不能用普通require('somedep')(ESM 中会被忽略、发布后也找不到),而要写成(await import('somedep')).default的懒加载形式,兼顾启动性能与打包正确性;
  • 体积纪律:CONTRIBUTING 举了一个真实案例——http-proxy本身约 380 kB,而http-proxy-middleware会拖入约 3 MB 的传递依赖,相比之下在http-proxy之上写几行自定义中间件即可,这也是 Vite 选择自研中间件的原因。

对照 packages/vite/package.json#L71-L77 可以看到策略的实际结果——vite 的运行时dependencies只有 5 个:

"dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.7", "postcss": "^8.5.26", "rolldown": "~1.2.6", "tinyglobby": "^0.2.17" }

外加optionalDependencies中的fsevents(macOS 原生监听)。而devDependencies里则躺着chokidarmagic-stringes-module-lexersirvconnect等三十多个"运行时也用"的包——它们全部会被打进dist/node,并因此出现在 LICENSE.md 与致谢页中。

类型方面还有一个配套机制:为了让 Vite 能在 TypeScript 项目中被完整引用(例如供 VitePress 使用),需要把部分依赖的类型内联到packages/vite/src/types,然后用pnpm run build-types-check校验打包后的类型不依赖任何 devDependencies。此外,rolldown.config.ts 中还有一个bundleSizeLimit(55)插件(rolldown.config.ts#L388-L416),当module-runner产物超过约 55 kB 时直接令构建失败——"轻量"在这里是硬约束,不只是口号。

五、Notable Dependencies 与开发工具

数据文件中的两份静态名单对应页面两组卡片:

Notable Dependenciesrolldownpostcsslightningcsschokidarmagic-string。它们在源码中的位置可以从 import 关系直接印证:

  • rolldown是当前 Vite 的构建与转换引擎:从 optimizer/scan.ts、optimizer/index.ts(依赖预构建)到 build.ts、pluginContainer.ts、hmr.ts 等几十个核心模块都直接从rolldown导入插件与类型;
  • magic-string用于精确的源码改写,Vite 自己的构建配置就用它实现shimDepsPluginbuildTimeImportMetaUrlPlugin(rolldown.config.ts#L229-L299);
  • postcss是 CSS 处理管线核心,配合postcss-importpostcss-load-configpostcss-modules等(均在 devDependencies 中,打包时通过shimDepsPlugin剔除冗余 import,见 rolldown.config.ts#L101-L132 的注释);
  • lightningcss用于 CSS 压缩等原生加速路径;
  • chokidar是文件监听基础,仓库根 patches/ 目录中还维护着chokidar@3.6.0.patch等 pnpm patch,说明 Vite 会直接修补依赖行为而非整体替换。

Development Toolseslintoxfmttypescriptvitestplaywright-chromium,与根 package.json 的 devDependencies 一一对应。仓库脚本体现了它们的分工:pnpm lint(eslint 9 + typescript-eslint)、pnpm format(oxfmt,同时由lint-staged在 pre-commit 时执行)、pnpm typecheck(tsc 多项目配置)、pnpm test(vitest 单元测试 + 基于 Playwright 的test-serve/test-build集成测试,测试目标即 playground/ 下上百个场景目录)、pnpm docs(VitePress 构建本文所在文档站)。

六、Past Notable Dependencies:一份引擎演进的对照记录

acknowledgements.data.ts#L23-L55 中的pastNotableDependencies列出了 Vite 曾经依赖、如今已替换或移除的六个项目,其"replacement 备注"恰好勾勒出 Vite 底层的演进轨迹:

用途现状(据数据文件备注与 package.json 印证)
esbuildJS/TS 打包与压缩描述为 "now using Rolldown, Oxc, and LightningCSS";但 esbuild 仍保留为可选 peerDependency 与 devDependency(^0.27.0 \|\| ^0.28.0/^0.28.2),部分转换路径仍可能需要用户安装
rollupESM 打包器"now using Rolldown";rollup仍留在 devDependencies(^4.59.0),主要服务于构建工具链生态(如许可证插件rollup-plugin-license,其类型即来自rollup
http-proxyHTTP 代理"now using http-proxy-3",对应 devDependencies 中的http-proxy-3: ^1.23.3
acornJavaScript 解析器已从依赖中移除(解析能力由 Oxc 体系承接,可参见 plugins/oxc.ts 的存在)
fast-glob快速 glob 匹配"now using tinyglobby/fdir",对应运行时依赖tinyglobby: ^0.2.17
debug调试日志"now using obug",对应 devDependencies 中的obug: ^1.0.2

从源码结构看,"Rolldown 取代 esbuild/rollup"这一迁移已完成度很高:vite 的构建入口、模块图、HMR、SSR 转换等核心模块均直接面向rolldown的插件 API 编写,而不再经由 esbuild 或 rollup 中转。

七、给包作者的提示:你的 package.json 元数据决定你在致谢页的样子

原文档中有一个面向第三方包作者的说明,值得单独强调:

This section is automatically generated from theauthorandfundingfields in each package'spackage.json. If you'd like to update how your package appears here, you can update these fields in your package.

结合第二节的解析逻辑,其含义非常具体:如果你的包出现在 vite 的devDependencies中、被预打包进了dist/node(从而进入 LICENSE.md 的# Bundled dependencies:区),那么该包在package.json中声明的author(支持对象或"Name <email> (url)"字符串)将决定它是否以及以谁的名义出现在 "Bundled Dependency Authors" 表中,funding字段(字符串、对象或数组的第一个 URL)则决定作者行/包名旁是否出现 Sponsor 链接;repository字段会被normalizeRepository()归一化后展示。换言之,更新你所在包的authorfunding字段,就是更新它在 Vite 致谢页呈现方式的唯一途径——而 Vite 侧的整条链路(构建生成 LICENSE.md → 数据加载器解析 → 页面渲染)无需任何人工介入。

小结

Vite 的致谢页看似一份静态鸣谢名单,实际是一条完整的自动化管线:构建时rollupLicensePlugin将预打包依赖的许可证汇总写入 LICENSE.md,文档构建时 acknowledgements.data.ts 再解析该文件并结合 node_modules 中的package.json元数据生成卡片与作者表。这条管线背后,是 Vite "运行时依赖仅 5 个、其余全部预打包"的依赖纪律(CONTRIBUTING.md)与对产物体积的硬约束。理解这套机制后,你可以把致谢页当作观察 Vite 依赖演进的窗口——包括 esbuild 到 Rolldown、http-proxy 到 http-proxy-3 这样已经落地的替换。

【免费下载链接】viteNext generation frontend tooling. It's fast!项目地址: https://gitcode.com/GitHub_Trending/vi/vite

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 14:08:37

如何把 macOS 菜单栏整理清爽:用 Ice 三步找回被图标占满的屏幕

如何把 macOS 菜单栏整理清爽&#xff1a;用 Ice 三步找回被图标占满的屏幕 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice 如果你的 Mac 顶部图标越来越多——Wi-Fi、电池、时间、通知中心&#xf…

作者头像 李华
网站建设 2026/9/4 14:05:14

66.FPGA 高速接口精通之路:DDR3 完整读写工程 + 可综合源码 + 板级验证

摘要 接口设计是FPGA开发的基石,本文以DDR3控制器接口为例,从物理层时序、控制器架构到用户逻辑验证,系统讲解FPGA高速接口设计的完整方法论。通过一个可直接运行的DDR3读写测试工程,深入剖析地址映射、突发传输、时序收敛等关键环节,帮助读者建立从接口规范到板级验证的…

作者头像 李华
网站建设 2026/9/4 14:04:40

小家电芯片选型实战:从电源管理到加密防抄的全解析

1. 小家电芯片选型的底层逻辑&#xff1a;先搞懂"板子上到底需要几颗芯片"我在家电方案公司待了快十年&#xff0c;接手的杂牌项目比品牌项目多得多。很多人以为"小家电常用芯片"就是一颗主控MCU的事&#xff0c;实际拆开任何一个正在量产的电饭煲、筋膜枪…

作者头像 李华
网站建设 2026/9/4 14:04:07

网络工程师需要掌握的技能和知识点有哪些?

网络工程师需要掌握的技能和知识点相当广泛。首先&#xff0c;他们必须具备扎实的计算机和网络技术基础&#xff0c;这包括了解计算机和网络原理、网络协议、网络拓扑、网络硬件设备等。例如&#xff0c;他们需要熟悉TCP/IP协议&#xff0c;这是互联网的基础协议&#xff0c;对…

作者头像 李华
网站建设 2026/9/4 14:01:17

VMware 2026逃逸漏洞实战排查与修复教程(CVE-2026-59346/59347)

摘要&#xff1a;2026年9月3日Broadcom公开的VMSA-2026-0007安全公告&#xff0c;爆出两款影响主流桌面虚拟化产品的高危逃逸漏洞。CVE-2026-59346与CVE-2026-59347可让虚拟机内管理员权限攻击者突破虚拟化隔离&#xff0c;直接在宿主机执行恶意代码。本次漏洞最致命的点在于无…

作者头像 李华