- 开发工具
- CLI
【免费下载链接】degit
Straightforward project scaffolding
本指南围绕 degit 这一"直接了当的项目脚手架"(straightforward project scaffolding)工具展开,系统讲解它如何以快照(tar archive)方式替代传统git clone完成仓库拷贝,涵盖 CLI 用法、支持的仓库来源、缓存机制、别名系统、ESM 编程接口与degit.json后置动作。读完本文,你将能够熟练用 degit 快速搭建项目模板、按需过滤文件、离线复用缓存,并基于源码理解其"tar 优先、SSH 兜底"的传输架构。
degit 是什么:以快照代替历史记录的拷贝工具
degit 的核心功能是拷贝 Git 仓库的快照。当你执行degit some-user/some-repo时,它会在 https://github.com/some-user/some-repo 上找到最新提交,并把对应的 tar 文件下载到平台对应的缓存目录(如果本地没有的话)。相比git clone,这种方式快得多,因为你不需要下载完整的 Git 历史,只取某个提交时刻的完整文件树。
从架构上看,degit 是"单包 TypeScript CLI + 库":它通过内部 git 后端解析 ref(分支/标签/提交),默认下载 tar 快照,当 tar 获取或解压失败时回退到 SSH 克隆。公共 HTTPS 来源不需要本地存在git二进制,但 SSH/私有仓库仍然依赖git出现在PATH中。这一"tar 优先、git 兜底"的设计在 src/core/orchestrator.ts 的doCloneToDestination中有直接体现:默认走 tar 模式,捕获到COULD_NOT_DOWNLOAD错误且未启用--cache时才切换到 git 克隆。
环境要求与安装
degit 要求Node.js 20 或更高版本(见 package.json 中engines字段的声明),通过 npm 全局安装:
npm install -g degit安装后degit可执行文件由 package.json 的bin字段声明,指向仓库根目录的degit脚本,构建产物输出到dist/(由 tsdown.config.ts 配置)。本地开发时也可以使用 Bun(仓库使用bun@1.3.14作为包管理器),常见流程是bun install、bun run build后运行测试。
快速上手
下载 GitHub 仓库的默认分支到当前目录:
degit user/repo下载到新目录:
degit user/repo my-new-project degit -r user/repo只下载指定文件:
degit user/repo my-project --files README.md,src/index.ts指定 tag、分支或提交:
degit user/repo#v1.0.0CLI 的完整参考(基本语法为degit <src>[#ref] [<dest>] [options])、ESM API 以及degit.json动作见 docs/USAGE.md;发布的帮助文本见 assets/help.md。
CLI 参考:支持的来源与 ref 语法
支持的来源
degit 支持GitHub、GitLab、Bitbucket 和 Sourcehut四类托管平台,来源解析逻辑集中在 src/domain/repo.ts:
| 平台 | 示例 |
|---|---|
| GitHub | degit user/repo、degit github:user/repo、degit https://github.com/user/repo、degit git@github.com:user/repo |
| GitLab | degit gitlab:user/repo、degit https://gitlab.com/user/repo、degit git@gitlab.com:user/repo |
| GitLab 自托管 | degit gitlab://git.example.com/user/repo |
| Bitbucket | degit bitbucket:user/repo、degit https://bitbucket.org/user/repo、degit git@bitbucket.org:user/repo |
| Sourcehut | degit git.sr.ht/user/repo、degit https://git.sr.ht/user/repo、degit git@git.sr.ht:user/repo |
从源码看,resolveSource 会根据前缀(https://、ssh://、git@、gitlab://、git.sr.ht/或provider:user/repo冒号形式)解析出站点、传输方式与仓库路径;不支持的主机会抛出UNSUPPORTED_HOST错误(src/domain/repo.ts)。各平台对应的 tar 归档 URL 模板定义在providerArchiveTemplates(src/domain/repo.ts),例如 GitHub 为${repo.url}/archive/${hash}.tar.gz,GitLab 为${repo.url}/-/archive/${hash}/${repo.name}-${hash}.tar.gz。
指定 tag、分支或提交
在任何来源后追加#ref即可:
degit user/repo#dev # 分支 degit user/repo#v1.2.3 # 发布标签 degit user/repo#1234abcd # 提交哈希省略 ref 时,degit 解析仓库的默认分支。在 src/core/orchestrator.ts 的selectHead中可以看到默认分支的判定顺序:优先HEAD类型引用,其次按main、master顺序匹配分支名,最后取第一个 branch 类型的哈希。
创建新目录与空目录约束
如果省略dest,degit 解压到当前目录。目标目录必须为空,除非使用--force。--repo-name(-r)则按仓库名创建目录:
degit user/repo my-new-project degit -r user/repo该约束在 src/core/orchestrator.ts 的clone方法中通过checkDirIsEmpty(dest, this.force, ...)强制校验。
克隆子目录
把子目录追加到来源中:
degit user/repo/subdirectory也可以直接粘贴完整的 GitHub URL:
degit https://github.com/user/repo/tree/main/subdirectory这是通过 parseWebPath 实现的:遇到tree/blob(GitHub)、-/tree/-/blob(GitLab)、src(Bitbucket)等标记时,标记后的路径段会解析为 ref 与子目录。tar 模式下,resolveArchiveSubdir 会先枚举归档内容、在顶层目录下定位子目录,找不到时抛出MISSING_SUBDIR。对于 GitLab 嵌套组,degit 会先尝试两段的user/repo解释,失败后把整个路径当作嵌套组处理(对应 generateGitlabRepoCandidates 生成候选项目,再由 tryGitlabProject 逐个尝试)。
克隆指定文件
使用--files(-F)只保留指定文件或目录,路径用逗号分隔或重复该标志:
degit user/repo my-project --files README.md,src/index.ts degit user/repo my-project -F README.md -F src/index.ts缺失或越界的路径会被跳过并给出警告;如果请求的路径一个都没解析到,则保留整个目标目录。文件过滤由 src/operations/filesystem.ts 中的keepFiles在克隆完成后执行。
完整选项表
| 选项 | 短选项 | 说明 |
|---|---|---|
--help | -h | 显示帮助文本 |
--version | -V | 显示版本号 |
--cache | -c | 只使用本地缓存,不访问网络 |
--force | -f | 允许克隆到非空目标目录 |
--files <paths> | -F <paths> | 只保留列出的文件或目录 |
--repo-name | -r | 克隆到以仓库命名的目录 |
--verbose | -v | 输出额外的进度信息 |
--mode <mode> | -m | tar(默认)或git。--mode=git为兼容而保留,会打印弃用提示 |
注意--mode=git仅是兼容路径,tar 快照才是默认且推荐的方式(assets/help.md 也有同样说明)。
缓存机制
degit 把下载的 tar 快照缓存在平台对应的目录:
- Linux/BSD:
$XDG_CACHE_HOME/degit或~/.cache/degit - macOS:
~/Library/Caches/degit - Windows:
%LOCALAPPDATA%\degit或~/AppData/Local/degit
缓存根目录的解析逻辑在 src/shared/utils.ts 的resolveBase中:Windows 优先取LOCALAPPDATA,macOS 固定在~/Library/Caches/degit,其他平台优先XDG_CACHE_HOME,回退到~/.cache/degit。
默认情况下,degit 先从网络解析最新 ref,网络不可达时回退到缓存版本;--cache则跳过网络请求、只用本地缓存。缓存目录按site/user/repo/组织,内含<hash>.tar.gz、map.json(ref 到 commit hash 的映射)与access.json(各 ref 的访问时间)等文件,见 src/transports/tar/cache.ts 的readCachedRefs/updateCache。当 ref 指向的 commit hash 发生变化时,旧的 tar 文件会被清理以节省空间(src/transports/tar/cache.ts)。
私有仓库与 HTTPS 代理
私有仓库是自动处理的:degit 默认走 HTTPS tarball 路径,当无法获取或解压快照时回退到 SSH 克隆;SSH/私有仓库仍要求git在PATH中。此外,如果你设置了https_proxy环境变量,degit 在获取 tar 归档时会使用它(构造函数中读取process.env.https_proxy,见 src/core/orchestrator.ts;代理请求通过https-proxy-agent实现,见 src/shared/utils.ts)。
别名系统
保存别名:
degit alias github:user/repo myRepo使用别名:
degit myRepo管理别名:
degit unalias myRepo degit ls # 列出已保存的别名别名存储在 degit 缓存目录内的aliases.json中(src/aliases.ts)。实现上,saveAlias/removeAlias直接读写该 JSON 文件,resolveAlias在构造函数解析来源前先做别名替换(src/core/orchestrator.ts);degit ls会按键名排序输出name -> repo形式。
交互模式
不带任何参数运行degit会启动交互式选择器:提示输入来源、目标目录以及是否使用缓存;如果目标目录非空,还会询问是否覆盖。这一交互流程由 src/bin.ts 实现,单元测试见 test/unit/bin.test.ts。
ESM API:在 Node 脚本中编程使用
degit 也能作为库在 Node 脚本中使用,入口是 src/index.ts:
import degit from 'degit'; const emitter = degit('user/repo', { cache: true, force: true, verbose: true, }); emitter.on('info', (info) => { console.log(info.message); }); emitter.on('warn', (info) => { console.warn(info.message); }); await emitter.clone('path/to/dest'); console.log('done');degit(src, opts)返回一个基于EventEmitter的实例(src/core/orchestrator.ts),公开类型从 src/domain/types.ts 导出。
构造函数选项
| 选项 | 类型 | 说明 |
|---|---|---|
aliases | Record<string, string> | 解析src时使用的别名映射 |
cache | boolean | 只使用本地缓存,不访问网络 |
fetch | FetchFn | 自定义(url, dest, proxy?) => Promise<void>下载函数 |
files | string[] | 只保留列出的文件或目录 |
force | boolean | 允许克隆到非空目标 |
git | GitClient | 自定义 git 客户端,用于 ref 解析与兜底克隆 |
mode | 'tar' \| 'git' | 克隆模式,tar为默认 |
verbose | boolean | 输出额外进度信息 |
事件
返回的 emitter 暴露两个事件通道:
info— 进度与成功消息。warn— 非致命问题,例如跳过的路径或回退提示。
事件对象至少包含message,还可能包含code、dest、repo、url、ref和subdir字段。事件类型定义见 src/domain/types.ts,错误码(如MISSING_REF、COULD_NOT_DOWNLOAD、MISSING_SUBDIR)以DegitError形式在 src/shared/utils.ts 中定义并贯穿各传输层抛出。
degit.json 后置动作:模板自动定制
初始克隆完成后,degit 会在目标目录顶层查找degit.json并执行其中定义的动作。JSON Schema 位于 schemas/degit.schema.json,可用于编辑器自动补全与校验。动作处理由 src/operations/directives.ts 实现,并从 src/core/orchestrator.ts 的runDirectives触发;执行期间会用 src/shared/utils.ts 的stashFiles/unstashFiles暂存已有目标文件,动作完成后再恢复。
clone:克隆另一个仓库
把另一个仓库克隆进目标目录,保留已有文件:
[ { "action": "clone", "src": "user/another-repo" }, { "action": "clone", "src": "user/another-repo", "files": ["README.md", "src/index.ts"] } ]被克隆的仓库自身也可以定义degit.json动作(嵌套执行)。
search_replace:基于正则的批量替换
替换列出的文件中所有匹配正则的内容。replacement字段是环境变量的名称,其值作为替换字符串:
[ { "action": "search_replace", "files": ["package.json", "README.md"], "pattern": "\\{\\{project_name\\}\\}", "replacement": "PROJECT_NAME" } ]files可以是单个路径或路径数组,路径相对目标目录解析;超出目标目录的路径会被跳过。search_replace只触碰显式列出的文件。
remove:删除文件
删除一个或多个文件:
[ { "action": "remove", "files": ["LICENSE"] } ]files条目支持 glob 模式,因此可以成批删除而不必逐个列出。由于 glob 可能匹配到比预期更多的文件,只有设置allowGlobs: true时才会处理 glob 模式;目标目录之外的匹配会被跳过。
[ { "action": "remove", "files": [".github/**/*.md"], "allowGlobs": true } ]为什么不直接用git clone --depth 1
degit 与浅克隆的关键差异:
- 模板不会残留属于模板本身的
.git目录——用git clone很容易忘记重新git init。 - degit 缓存归档,首次下载后可以离线复用。
- 输入更少(
degit user/repo对比git clone --depth 1)。 - 通过
degit.json支持可组合的后置动作。 - 内置子目录、文件过滤与别名支持。
Agent 技能与进阶阅读
degit 还提供了面向支持SKILL.md的 Agent 的可复用技能,可通过以下命令安装:
# 项目级安装 npx skills add Rich-Harris/degit --skill degit # 全局安装 npx skills add Rich-Harris/degit --skill degit -g安装后可以让 Agent 代为下载仓库或模板:该技能会帮助它选择合适的来源、ref 与目标目录,处理私有仓库与别名,并在目标目录非空时避免未经确认的覆盖。完整技能说明见 skills/degit/SKILL.md。
进一步阅读:
- docs/USAGE.md — CLI 完整参考、ESM API 与
degit.json动作 - docs/ARCHITECTURE.md — 仓库架构与数据流(含目录结构、核心组件与安全考量)
- docs/CONTRIBUTING.md — 贡献指南、开发环境与 CI 检查
- docs/SECURITY.md — 安全策略与漏洞报告流程
- docs/CHANGELOG.md — 版本发布记录
- schemas/degit.schema.json —
degit.json动作的 JSON Schema - assets/help.md — 发布的 CLI 帮助文本
- 开发工具
- CLI
【免费下载链接】degit
Straightforward project scaffolding
相关推荐
Paseo 插件快速上手:从脚手架、RPC 到工作区面板的完整实战指南
Paseo 插件快速上手:从脚手架、RPC 到工作区面板的完整实战指南 导读 本文是基于 Paseo 官方插件快速入门文档( public docs/plugi
如何5分钟部署大麦自动抢票神器:2026终极智能购票解决方案
如何5分钟部署大麦自动抢票神器:2026终极智能购票解决方案 还在为抢不到热门演唱会门票而烦恼吗?大麦网抢票总是秒光?本文将为你介绍一款基于Python+Sel
GUI 自动化RPAWox 插件开发实战指南:从脚手架到打包的完整工作流(SKILL 深度解析)
Wox 插件开发实战指南:从脚手架到打包的完整工作流(SKILL 深度解析) Wox 是一个跨平台启动器,其插件生态覆盖 Node.js 与 Python 两种
桌面应用AI 应用插件系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考