
Deno 源码仓库的开发者工具链详解tools/format.js、lint.js、wgpu_sync.js 与 copyright_checker.js 的原理与用法【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/deno本文基于 Deno 仓库的 tools/README.md 展开系统讲解 Deno 官方源码仓库tools/目录下的四类核心开发工具脚本代码格式化format.js、代码静态检查lint.js、WebGPU 上游同步wgpu_sync.js与版权头校验copyright_checker.js。结合各脚本的源码实现你将理解这些脚本在 CI 前的准入流程中扮演什么角色、底层如何并行调度 dprint / deno lint / clippy以及如何安全地执行上游 vendor 同步与版权合规检查。tools/ 目录定位Deno 开发的准入检查层tools/README.md 开篇一句话说明了该目录的定位Documentation for various tooling in support of Deno development.即tools/目录下的脚本共同服务于Deno 自身的开发流程其中 format.js 与 lint.js 被明确标注为代码提交前必须执行的前置步骤It is a prerequisite to run this before code check in。这与仓库根目录的 CLAUDE.md 中的开发约定相互印证- Before committing, make sure tools/format.js is run to format your code - ...tools/lint.js --js and fix any lint errors before committing - If you changed Rust code, make sure to run tools/lint.js and fix any lint也就是说对 Deno 贡献代码的标准流程是先 format再 lint全部通过后才提交。下面逐个脚本展开。format.js统一入口的代码格式化基本用法按 tools/README.md 的说明format.js 使用dprintRust 代码侧使用 rustfmt来格式化代码库运行方式为deno run --allow-read --allow-write --allow-run ./tools/format.js源码实现dprint 统一配置阅读 tools/format.js 可以发现脚本逻辑非常短核心是拼装并执行一条 dprint 命令const subcommand Deno.args.includes(--check) ? check : fmt; const configFile join(ROOT_PATH, .dprint.json); const cmd new Deno.Command(deno, { args: [ run, -A, --no-config, npm:dprint0.47.2, subcommand, --config configFile, ], cwd: ROOT_PATH, stdout: inherit, stderr: inherit, });从源码结构看有三个值得注意的设计点dprint 版本锁定通过npm:dprint0.47.2精确固定 dprint 版本保证所有开发者与 CI 看到一致的格式化结果避免“在我机器上是好的”式漂移。--check子命令脚本解析Deno.args当传入--check时向 dprint 转发check子命令只检测不修改否则执行fmt。这意味着你可以用deno run ./tools/format.js --check做“格式是否干净”的快速校验适合在提交前使用。统一配置源所有格式规则收敛在仓库根的 .dprint.json 中脚本本身不包含任何格式规则规则变更只需改一个配置文件。退出码透传Deno.exit(code)将 dprint 的退出码原样传出因此该脚本可以直接作为 CI 任务或 Git hook 的判定依据。lint.jsJS 与 Rust 双栈的静态检查调度器基本用法tools/README.md 说明 lint.js 使用deno lint与clippy检查代码库同样是提交前必跑步骤deno run --allow-read --allow-write --allow-run ./tools/lint.js文档还给出了一条实用技巧可以用 cargo 运行当前正在构建或已构建的本地 deno 可执行文件来执行这些工具脚本从而让工具链检查的是你正在开发的那个 Deno 版本而不是 PATH 里安装的版本cargo run -- run --allow-read --allow-write --allow-run ./tools/script这条建议对 Deno 内核贡献者尤其重要——比如验证新的 lint 规则时需要用包含该规则的那个构建去跑 tools/lint.js。参数与并行调度模型tools/lint.js 支持--js与--rs参数控制检查范围两个都不传则 JS 与 Rust 都检查let js Deno.args.includes(--js); let rs Deno.args.includes(--rs); if (!js !rs) { js true; rs true; }各检查项被推入promises数组后用Promise.allSettled(promises)并行执行任一失败则打印错误并以退出码 1 结束。JS 侧包含 6 类检查Rust 侧包含 3 类其中checkCopyright版权检查在同时启用--js与--rs时才跑。这种设计让tools/lint.js --js只查 JS 侧、--rs只查 Rust 侧方便在 CI 矩阵中拆分任务。clippy 侧deny 清单与分 crate 策略clippy()函数是 lint.js 中最复杂的部分。它首先定义了一组拒绝级 lint 规则const clippyDenyFlags [ --, -D, warnings, --deny, clippy::unused_async, --deny, clippy::print_stderr, --deny, clippy::print_stdout, --deny, clippy::large_futures, --deny, clippy::allow_attributes_without_reason, ];源码注释解释了为什么禁用print_stdout/print_stderrRust 标准输出宏在管道断开时例如deno test | head会 panic因此 Deno 代码库要求用logcrate 打诊断日志、用deno_print的drop_println!宏打 stdout。更细致的是脚本会实时捕获 clippy 的 stderr 流一旦匹配到clippy::print[-_]std(out|err)字样就额外打印这条提示把“报错原因 修复方向”直接喂给开发者。在 workspace 层面由于Cargo 的--all-features无法表达互斥的引擎后端脚本通过cargo metadata --no-deps解析出所有 workspace 成员的全部 feature剔除 QuickJS 与平台相关 V8 模式显式拼接--features传给 clippy并--exclude deno_coredeno_core则单独按固定 feature 集default,unsafe_runtime_options,unsafe_use_unprotected_platform,v8再跑一次 clippy。这种“分 crate、分 feature”的策略保证每个 crate 都在其真实的 feature 组合下被检查。此外 clippy 检查还会遵循buildMode()来自 tools/util.js传入--release时 clippy 也加--release使检查目标与实际构建模式一致。几个高信息量的内置约定检查除 deno lint 与 clippy 外lint.js 还内嵌了几个纯 JS 实现的“仓库宪法”检查ensureNoNonPermissionCapitalLetterShortFlags正则扫描 libs/cli_parser/src/defs.rs 中所有.short(X)声明断言大写短选项只能是权限相关标志A/E/I/N/R/S/W等并维护一份白名单。源码注释说明了动机大写短选项只关联权限是为了让用户审查命令时能“多一分警惕”。ensureDisallowedMethodsEnforced强制ext/、libs/、runtime/下每个 crate 都有clippy.toml且其中必须列出禁止直接调用的方法清单如std::fs::read、std::fs::write、std::path::Path::canonicalize、url::Url::to_file_path等libs 类 crate 还要额外禁止std::env::var、std::time::SystemTime::now等。这从静态层面保证 Deno 扩展必须走 ops 抽象访问文件系统/环境变量/时间而非直接调用 std。ensureNoUnusedOutFiles遍历tests/specs/下所有__test__.jsonc把其中output字段引用的.out文件从集合中删除剩下的即为“无人引用的 .out 文件”报错要求清理——防止测试快照膨胀。ensureNoNewTopLevelEntries通过gitLsFiles列出仓库顶层条目与白名单.cargo、cli、doc、ext、libs、runtime、tests、tools、x及各根配置文件比对新增任何顶层目录或文件都会被拒绝注释明确写着“Keep the root of the repository clean”且向白名单添加条目必须先讨论。ensureWorkflowYmlsUpToDate逐个运行.github/workflows/*.ts生成器带--lint确保所有.generated.yml工作流文件与其 TypeScript 源同步。文件收集层的 Git / Jujutsu 双兼容上述检查都依赖 tools/util.js 中的getSources(baseDir, patterns)收集文件。值得留意的是gitLsFiles的实现如果检测到.jj目录即仓库用 Jujutsu 管理会把 git pathspec 翻译成 jj 的glob:文件集包括把*.ext映射成**/*.ext、把结尾/的目录映射为**等归一化逻辑否则走git ls-files -z --exclude-standard --cached --modified --others。这让工具脚本在 git 与 jj 工作流之间无缝切换也说明 Deno 团队正在并行试验版本控制系统。wgpu_sync.js把 gfx-rs/wgpu 的 deno_webgpu 树 vendor 进来tools/README.md 对 wgpu_sync.js 的说明是wgpu_sync.jsstreamlines updatingdeno_webgpufrom gfx-rs/wgpu. It essentially vendors thedeno_webgputree with a few minor patches applied on top, somewhat similar togit subtree.即该脚本从上游 gfx-rs/wgpu 仓库整树拷贝vendordeno_webgpu到本仓库 ext/webgpu/ 目录再打少量补丁类似git subtree的语义。官方推荐的操作流程为四步更新 tools/wgpu_sync.js 中的COMMIT或V_WGPU运行./tools/wgpu_sync.js仔细复查改动必要时手工打补丁提交并发送 PR。源码走读同步流水线tools/wgpu_sync.js 的头部定义了同步的两个关键变量const COMMIT ae87ffe28041a7ebd82d8d3c2fa0e2343f0f0234; const REPO gfx-rs/wgpu; const V_WGPU 29.0.1; const TARGET_DIR join(ROOT_PATH, ext, webgpu);main()按固定顺序执行四个阶段await main(); // clearTargetDir → checkoutUpstream → patchCargo → patchReadme → format.jsclearTargetDirrm -r ext/webgpu/*清空本地 vendor 目录保证每次同步从干净状态开始这也是 README 要求“double check changes”的原因——上游文件被整体替换。checkoutUpstream通过 GitHub API 拉取指定COMMIT的 tarball再用tar --strip2只解压其中的deno_webgpu/子树到ext/webgpu/curl -L https://api.github.com/repos/gfx-rs/wgpu/tarball/${COMMIT} | \ tar -C ext/webgpu -xzvf - --strip2 gfx-rs-wgpu-ae87ffe/deno_webgpu/注意这一步依赖网络与 bash因此脚本 shebang 声明了--allow-read --allow-write --allow-run。patchCargo对 vendor 进来的ext/webgpu/Cargo.toml做正则替换把version对齐到根 Cargo.toml 中登记的deno_webgpu版本把authors/license/repository归并到 workspace 继承authors.workspace true等同时把根 Cargo.toml 的wgpu-core与wgpu-types版本统一改成V_WGPU。这一步保证 vendor 代码与本仓库 Cargo workspace 规范兼容。patchReadme幂等地向ext/webgpu/README.md注入/替换## Source段落声明该目录的 canonical source 在上游仓库、本副本由该脚本同步。脚本会先删除已有的 Source 段落再插入因此重复执行不会累积重复内容。最后调用tools/format.js对新拉入的代码统一跑一遍 dprint 格式化保证 vendor 代码也符合本仓库格式规范。这种“整树替换 确定性补丁 复用本仓库格式化”的模式是维护第三方 vendor 代码的典型做法上游升级时 diff 可控、补丁位置固定、格式统一。copyright_checker.js全仓版权头合规检查tools/README.md 对版权检查器的描述copyright_checker.jsis used to check copyright headers in the codebase. ... it will check all code files in the repository and report any files that are not properly licensed.运行方式deno run --allow-read --allow-run ./tools/copyright_checker.js源码走读检查规则与豁免清单阅读 tools/copyright_checker.js其核心逻辑是逐文件读取开头一段字节readFirstPartOfFile只读前 1KB避免为检查版权头而加载整个文件验证是否以期望的版权行开头const copyrightYear 2026; const COPYRIGHT_LINE Copyright 2018-${copyrightYear} the Deno authors. MIT license.;几个值得展开的规则细节文件类型与豁免清单通过getSources收集*.js、*.mjs、*.jsx、*.ts、*.tsx、*.rs、*.c以及所有Cargo.toml并用:!:排除模式跳过第三方 vendor 与测试数据例如cli/tsc/*typescript.jsTypeScript 编译器本体、cli/tsc/dts/**内置类型声明、ext/node/polyfills/deps/**、tests/registry/**、tests/wpt/suite/**等。这份清单本身就是“哪些代码属于 Deno 自研、哪些是引入的上游”的一份隐性边界描述。允许的版权行前缀ACCEPTABLE_LINES允许版权行之前出现// deno-lint-*指令、// Copyright*续行、// Ported*移植代码、空行或 shebang 行超过这些容忍范围仍不以版权行开头则报错并附上“出错的行是……”的诊断。Cargo.toml 单独处理期望以# Copyright 2018-2026 the Deno authors. MIT license.开头TOML 注释风格而 JS/TS/Rust/C 文件期望// Copyright ...C 风格注释。LICENSE.md 年份联动脚本最后还检查仓库根 LICENSE.md 是否包含Copyright 2018-2026 the Deno authors年份过期会单独报LICENSE.md has old copyright year。错误合并输出所有错误先收集、最后一次性console.error(errors.join(\n))输出注释解释原因是避免与并行运行的其他工具脚本的输出交错。该脚本还被tools/lint.js以模块方式复用import { checkCopyright } from ./copyright_checker.js所以跑tools/lint.js时会顺带完成版权检查。小结从 tools/README.md 到完整提交前检查清单回到 tools/README.md 的主线可以把整个工具链浓缩成一份可操作的提交前清单步骤命令底层工具检查/修改范围格式化deno run --allow-read --allow-write --allow-run ./tools/format.jsdprint 0.47.2配置 .dprint.json支持--check只检测全仓文本文件检查全量deno run --allow-read --allow-write --allow-run ./tools/lint.jsdeno lint clippy 多个内置约定检查 版权检查JS/TS 与 Rust 双栈检查仅 JS... ./tools/lint.js --jsdeno lint 工作流同步、顶层条目、.out 快照等检查JS/TS 侧用本地构建跑脚本cargo run -- run --allow-read --allow-write --allow-run ./tools/scriptcargo 构建中的 deno 二进制—WebGPU 上游同步修改COMMIT/V_WGPU后运行./tools/wgpu_sync.jscurl tar 正则补丁 format.jsext/webgpu/版权检查deno run --allow-read --allow-run ./tools/copyright_checker.js自研脚本全仓源码头 LICENSE.md从源码结构看这套工具链的设计哲学很清晰所有格式与静态检查规则收敛在单一入口脚本与单一配置文件中dprint 配置只有一个 .dprint.jsonclippy 规则集中在 tools/lint.js 的 deny 清单与各 crate 的clippy.toml上游 vendor 用可重放的脚本管理tools/wgpu_sync.js仓库结构本身也被当作被检查对象顶层条目白名单、工作流文件生成同步。对希望参与 Deno 开发或研究其工程实践的读者直接阅读 tools/ 目录下的这些脚本是理解 Deno 如何大规模维护一个 Rust JS 双栈代码库的最快入口。【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/deno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考