1. 项目概述:一个面向开发者的轻量级自动化工具
最近在整理自己的开发环境和工作流时,发现很多重复性的、琐碎的任务占用了大量时间。比如,每次启动项目前要手动开启一堆服务,代码提交前要运行固定的检查脚本,或者在不同项目间同步一些通用配置。这些操作本身不复杂,但日复一日地做,累积起来就是巨大的时间消耗和精神内耗。我相信这也是很多开发者的共同痛点。
于是,我开始寻找一个足够轻量、灵活且易于定制的自动化工具,能够让我用最少的配置,把这些“脏活累活”管起来。我的核心诉求很简单:它应该像胶水一样,把分散的脚本和命令粘合起来,形成一个流畅的工作流,并且这个“胶水”本身要足够透明,不引入新的复杂性。
正是在这个背景下,我接触并深度使用了ByGroover/YangDuck这个项目。从名字上看,“YangDuck”可能有点趣味性,但它的内核非常务实。它不是一个试图管理你整个开发生命周期的庞然大物,而是一个专注于任务编排与自动化执行的轻量级运行器。你可以把它理解为一个增强版的、可编程的make工具,或者一个极度简化的本地 CI/CD 执行引擎。它的设计哲学深深吸引了我:约定优于配置,但绝不牺牲灵活性。
简单来说,YangDuck 允许你通过一个中心化的、易于阅读的配置文件(通常是duck.yaml或duck.yml),定义一系列任务(Task)。每个任务可以包含多个步骤(Step),步骤可以是执行 shell 命令、运行脚本、调用其他任务,甚至执行内置或自定义的操作。之后,你只需要通过一条简单的命令,如duck run <task-name>,就能触发整个工作流的自动执行。
它特别适合以下几类场景:
- 个人开发者:统一管理不同项目的启动、构建、测试、部署命令。
- 团队协作:为新成员提供标准化的项目上手流程(
duck run setup),确保环境一致。 - 复杂工作流:将需要按顺序执行的多个命令(如代码检查 -> 单元测试 -> 打包 -> 发布到测试环境)串联成一个原子操作。
- 跨平台兼容:通过抽象的命令定义,让同一套自动化脚本在 Windows(PowerShell/Cmd)、macOS 和 Linux(Bash)上都能运行。
接下来,我将结合自己近半年的使用经验,从设计思路、核心使用到高级技巧,为你完整拆解 YangDuck,分享如何用它来真正解放你的双手。
2. 核心设计理念与架构解析
为什么选择 YangDuck,而不是 Shell 脚本、Makefile 或者其他更流行的任务运行器(如 Gulp、Grunt 或现代的 Just、Task)?这需要从它的设计理念说起。理解这些,你才能更好地驾驭它,并将其价值最大化。
2.1 以“任务”为中心的声明式配置
YangDuck 的核心抽象是“任务(Task)”。所有自动化逻辑都围绕任务展开。它的配置文件采用 YAML 格式,这是一种对人类友好、对机器也易于解析的数据序列化语言。相比于 Shell 脚本的过程式编程,YAML 是一种声明式的配置方式。
声明式 vs 过程式:简单类比,过程式是告诉电脑“第一步打开冰箱,第二步拿出可乐,第三步关上冰箱”。而声明式是告诉电脑“我想要一杯放在冰箱里的可乐”,电脑自己决定如何实现。在自动化领域,声明式配置更关注“最终状态”或“要做什么”,而非具体每一步的细节,这使得配置更简洁、更易于理解和维护。
在duck.yaml中,一个任务的基本结构如下:
tasks: hello: desc: “一个简单的问候任务” steps: - run: echo “Hello, YangDuck!”这里定义了一个名为hello的任务,描述是“一个简单的问候任务”,它包含一个步骤:运行echo命令。你只需要声明任务的目标(输出问候语),而不需要关心命令是如何被解析和执行的(这是 YangDuck 运行时的工作)。
这种方式的优势在于:
- 可读性极高:无论是自己三个月后回看,还是团队新成员阅读,都能快速理解每个任务的目的。
- 易于版本控制:YAML 文件是纯文本,可以完美地纳入 Git 管理,任务定义的任何变更都有迹可循。
- 结构清晰:复杂的任务可以通过
steps列表清晰地分解为线性或并行的子步骤。
2.2 极简的依赖管理与环境抽象
一个常见的痛点是在执行任务前,需要确保特定的工具或环境已就绪。YangDuck 通过requires字段优雅地解决了这个问题。你可以在任务级别声明其依赖。
tasks: build-frontend: desc: “构建前端资源” requires: - node - npm steps: - run: npm ci - run: npm run build deploy: desc: “部署应用” requires: - docker steps: - run: docker build -t myapp . - run: docker push myapp:latest这里的requires并不是去帮你安装 Node.js 或 Docker,而是在任务执行前进行环境检查。如果检查失败(例如系统未安装node命令),YangDuck 会明确报错并停止执行,而不是让任务运行到一半因命令找不到而崩溃。这相当于为每个任务增加了前置校验,避免了因环境缺失导致的隐蔽错误。
更重要的是,这种设计将“环境准备”和“任务执行”解耦。环境准备可以由更专业的工具(如 asdf, nvm, 系统包管理器)或统一的 DevOps 流程负责,YangDuck 只负责在正确的环境中可靠地执行定义好的任务。这种“各司其职”的哲学,让它在复杂的工具链中能很好地扮演执行者的角色,而不越界。
2.3 内置的实用功能与可扩展性
除了运行 shell 命令,YangDuck 还提供了一些开箱即用的内置操作(Actions),这是它比简单封装 shell 脚本更强大的地方。例如:
- 提示与确认:在执行危险操作(如清理数据库、生产环境部署)前,可以要求用户手动确认。
steps: - confirm: “你确定要清理所有临时文件吗?此操作不可逆。” - run: rm -rf ./tmp/* - 条件执行:根据变量、环境或上一步的结果,决定是否执行某个步骤。
- 文件操作:内置了创建目录、复制文件等常见操作,比写 shell 命令更简洁且跨平台。
当内置功能无法满足需求时,YangDuck 支持通过插件(Plugin)机制进行扩展。插件可以用任何语言编写,只要遵循其调用规范。这意味着你可以将公司内部的工具、复杂的业务逻辑封装成插件,然后在duck.yaml中像使用内置命令一样调用它。这种可扩展性使得 YangDuck 能够融入任何技术栈,成为团队工作流的核心枢纽。
2.4 与同类工具的差异化思考
你可能听说过make。Makefile同样经典,但其语法(尤其是 Tab 缩进)对新手不友好,且其设计核心是文件依赖和增量编译,对于通用的任务运行略显笨重。YangDuck 的 YAML 配置学习成本更低,目标更纯粹(就是运行任务)。
像Just、Task这类现代任务运行器,理念与 YangDuck 相似。YangDuck 的优势在于其“中庸之道”:它比Just的功能更丰富(如内置的 confirm、更灵活的变量系统),又比Task在某些设计上更简洁。更重要的是,它的文档和默认配置对中文用户相对友好,社区反馈的响应也比较及时,这在解决实际问题时是个不小的优势。
我的选择心得:如果你的项目是纯 C/C++,make仍是首选。如果你需要极致的简洁和速度,Just很棒。如果你面对的是混合技术栈(前端、后端、脚本、数据库),需要清晰的结构、一定的内置功能和良好的可读性,YangDuck 是一个非常平衡和实用的选择。
3. 从零开始:配置与核心语法详解
了解了为什么选它,接下来我们看看怎么用它。我会以一个典型的全栈 Web 项目为例,带你一步步搭建一个完整的 YangDuck 自动化工作流。
3.1 安装与初始化
YangDuck 通常是一个单二进制文件。安装方式很简单,以 macOS 和 Linux 为例:
# 假设你从项目 Release 页面下载了 yangduck 二进制文件 curl -L -o yangduck <下载链接> chmod +x yangduck sudo mv yangduck /usr/local/bin/ # 或 ~/.local/bin/,确保其在 PATH 中 # 验证安装 duck --version在项目根目录下,执行初始化命令:
duck init这会生成一个默认的duck.yaml配置文件。我建议立即对这个文件进行个性化改造。
3.2duck.yaml文件结构深度解析
一个功能全面的duck.yaml通常包含以下几个部分:
# duck.yaml version: ‘1.0’ # 配置版本,用于未来可能的兼容性处理 env: APP_NAME: “my-awesome-app” BUILD_DIR: “./dist” # 可以读取系统环境变量,并提供默认值 NODE_ENV: ${NODE_ENV:-“development”} tasks: # 任务定义区,这是核心1. 环境变量(env): 这是配置的“全局变量”区。在这里定义的变量可以在所有任务的steps中通过{{.VAR_NAME}}的语法引用。例如,在步骤中可以使用run: echo “Building {{.APP_NAME}}…”。
注意:这里定义的变量优先级低于任务内部定义的变量,但高于系统环境变量(除非显式引用
${ENV_VAR})。这种分层设计便于管理不同作用域的配置。
2. 任务(tasks)定义: 每个任务都是一个字典(key-value)。Key 是任务名,Value 是任务的具体配置。一个完整的任务配置可以包含以下字段:
setup: desc: “初始化开发环境” # 描述,`duck list` 时会显示,非常重要 requires: [“git”, “node”, “docker”] # 环境依赖检查 env: # 任务级环境变量,会覆盖全局 env DB_URL: “localhost:5432/test” dir: “./backend” # 步骤的默认工作目录,非常实用! steps: # 步骤列表,按顺序执行 - run: pwd # 会输出 ./backend - run: npm install - run: docker-compose up -d db silent: false # 是否静默执行(不输出步骤命令本身)desc:务必为每个任务写清楚的描述。当项目任务很多时,duck list命令的输出就是你最好的文档。dir:这是一个关键但易被忽略的配置。它设置了该任务下所有run步骤的默认工作目录。对于多模块项目(如前后端分离),你可以为frontend和backend任务设置不同的dir,这样就不需要在每个run命令前加cd了,大大简化了配置。silent:默认为false,即 YangDuck 会先打印出要执行的命令,再执行它。这对于调试和审计非常有用。如果你觉得输出太吵,可以设为true,但建议只在非常稳定、无需关注细节的任务上使用。
3.3 步骤(Steps)的类型与高级用法
步骤是任务的骨骼。除了最基本的run,还有多种类型:
1. 命令执行(run): 最常用的步骤。可以直接写命令,也支持多行命令。
steps: - run: | echo “开始构建…” npm run build:prod echo “构建完成!”实操心得:对于复杂的多行命令,使用 YAML 的块标量符号(
|)可以保留换行符,使配置更清晰。注意缩进。
2. 任务调用(task): 可以实现任务的组合与复用。这是实现模块化配置的关键。
tasks: build: steps: - task: build-frontend - task: build-backend build-frontend: dir: “./frontend” steps: - run: npm run build build-backend: dir: “./backend” steps: - run: go build -o app .这样,执行duck run build就会依次构建前端和后端。你可以像搭积木一样组合小任务,形成复杂的工作流。
3. 交互确认(confirm): 安全阀门。在执行破坏性操作前必须使用。
steps: - confirm: “此操作将清空数据库 ‘{{.DB_NAME}}’。请输入 ‘yes’ 继续。” - run: psql -c “DROP DATABASE {{.DB_NAME}};”4. 条件判断(if): 根据变量或上一步结果决定执行路径。其条件表达式通常支持检查变量是否存在、是否等于某个值等。
steps: - name: 检查是否已安装依赖 # 给步骤起个名字,日志更清晰 run: command -v some-tool ignore_error: true # 即使命令失败(返回非0),也不停止任务 - if: “{{.LAST_EXIT_CODE}} != 0” # 判断上一步的退出码 run: echo “工具 some-tool 未安装,正在安装…” # 这里可以接安装命令 - if: “{{.LAST_EXIT_CODE}} == 0” run: echo “工具已就绪。”重要提示:
if条件判断是高级功能,不同版本语法可能略有差异。务必查阅你所使用版本的官方文档,并先在简单任务中测试其行为。
5. 循环(for): 对列表中的每一项重复执行步骤。这在批量处理时非常有用。
env: SERVICES: [“user-service”, “order-service”, “product-service”] tasks: restart-all: desc: “重启所有微服务” steps: - for: “service in {{.SERVICES}}” run: “docker-compose restart {{.service}}”3.4 变量系统的灵活运用
变量是让配置“活”起来的关键。YangDuck 的变量来源有多处,优先级从高到低如下:
- 步骤级
env(极少用) - 任务级
env - 全局
env - 系统环境变量(通过
${VAR}或$VAR语法引用) - YangDuck 内置变量(如
{{.TASK_NAME}},{{.ROOT_DIR}})
最佳实践:
- 将易变的内容变量化:如版本号、端口号、文件路径。这样只需修改一处
env,所有任务都会生效。 - 使用系统环境变量管理机密:数据库密码、API密钥等绝对不要硬编码在
duck.yaml中。应该通过{{.DB_PASSWORD}}引用,并在执行任务前通过.env文件或 shell 环境注入。# 在 shell 中设置 export DB_PASSWORD=“secret” duck run some-task # 或者使用 envsubst 配合 .env 文件(更安全) set -a; source .env; set +a duck run some-task - 利用内置变量:
{{.ROOT_DIR}}在需要绝对路径时非常有用。
4. 实战:构建一个全栈项目自动化工作流
现在,让我们把上述知识整合起来,为一个假设的“Node.js后端 + React前端 + PostgreSQL数据库”的全栈项目,设计一套从开发到部署的 YangDuck 自动化脚本。
4.1 项目结构与全局配置
假设项目结构如下:
my-project/ ├── duck.yaml # YangDuck 配置文件 ├── backend/ │ ├── package.json │ └── src/ ├── frontend/ │ ├── package.json │ └── src/ └── docker-compose.yml # 用于启动开发数据库我们的duck.yaml全局配置如下:
version: ‘1.0’ env: PROJECT_NAME: “fullstack-demo” # 开发环境默认配置 NODE_ENV: “development” BACKEND_PORT: 3000 FRONTEND_PORT: 8080 DB_PORT: 5432 # 构建输出目录 BACKEND_DIST: “./backend/dist” FRONTEND_DIST: “./frontend/build”4.2 开发环境任务集
首先,定义开发中最常用的任务。
tasks: # 核心开发命令:一键启动所有服务 dev: desc: “启动完整的开发环境(后端、前端、数据库)” requires: [“node”, “npm”, “docker-compose”] steps: - name: “启动开发数据库” run: docker-compose up -d db background: true # 在后台运行,不阻塞后续步骤 - name: “启动后端开发服务器” dir: “./backend” run: npm run dev background: true - name: “启动前端开发服务器” dir: “./frontend” run: npm start background: true - name: “提示信息” run: | echo “🎉 开发环境已启动!” echo “- 后端 API: http://localhost:{{.BACKEND_PORT}}” echo “- 前端应用: http://localhost:{{.FRONTEND_PORT}}” echo “- 查看日志: duck run logs”设计解析:
background: true是关键。它让docker-compose和npm run dev这类需要长期运行的服务在后台启动,这样duck run dev命令在启动所有服务后就会正常退出,不会一直挂住你的终端。你可以继续用这个终端做其他事情。- 最后一步的提示信息非常人性化,特别是团队新成员,运行后立刻知道如何访问服务。
- 我们依赖
docker-compose来管理数据库,保证了环境的一致性。
日志查看任务: 既然服务在后台运行,我们需要一个方便查看所有日志的方式。
logs: desc: “聚合查看所有开发服务的日志” steps: - run: | echo “=== 后端日志 (Ctrl+C 退出) ===” # 这里假设后端 dev 命令将日志输出到文件,或我们通过进程ID跟踪 # 更通用的做法是使用 docker-compose logs docker-compose logs -f backend db注意:在实际中,如果后端不是用 Docker 运行的,收集日志会更复杂。一种常见模式是让所有服务将日志输出到指定文件,然后
logs任务用tail -f去跟踪这些文件。
4.3 构建与测试流水线
接下来,定义代码提交前的检查与构建流程。
ci: desc: “本地CI流水线:检查代码风格、运行测试、构建产物” steps: - task: lint - task: test - task: build lint: desc: “代码风格检查” steps: - name: “检查后端代码” dir: “./backend” run: npm run lint - name: “检查前端代码” dir: “./frontend” run: npm run lint test: desc: “运行单元测试与集成测试” env: # 为测试设置独立的环境变量 NODE_ENV: “test” DB_HOST: “localhost-test” steps: - name: “启动测试数据库” run: docker-compose -f docker-compose.test.yml up -d - name: “运行后端测试” dir: “./backend” run: npm test - name: “运行前端测试” dir: “./frontend” run: npm test - name: “清理测试环境” run: docker-compose -f docker-compose.test.yml down build: desc: “构建生产环境产物” env: NODE_ENV: “production” steps: - name: “清理旧构建” run: | rm -rf {{.BACKEND_DIST}} {{.FRONTEND_DIST}} - name: “构建后端” dir: “./backend” run: npm run build - name: “构建前端” dir: “./frontend” run: npm run build - name: “生成构建报告” run: | echo “构建完成于: $(date)” > build-info.txt echo “后端大小: $(du -sh {{.BACKEND_DIST}} 2>/dev/null || echo ‘N/A’)” >> build-info.txt echo “前端大小: $(du -sh {{.FRONTEND_DIST}} 2>/dev/null || echo ‘N/A’)” >> build-info.txt cat build-info.txt设计解析:
ci任务是一个典型的任务编排示例。它本身不干具体活,只是按顺序调用lint,test,build这三个子任务。这模拟了 CI/CD 流水线的阶段。- 在
test任务中,我们通过env覆盖了全局的NODE_ENV,并使用了独立的docker-compose.test.yml来启动测试数据库,确保测试的隔离性。务必记得在测试完成后清理资源,避免残留容器占用资源。 build任务最后的“生成构建报告”步骤是一个很好的实践。它创建了一个简单的文本文件,记录了构建时间和产物大小,这些信息对于后续的部署或审计很有帮助。
4.4 部署与维护任务
最后,我们定义一些与部署和项目维护相关的任务。
deploy-staging: desc: “部署到预发布环境” requires: [“docker”, “aws”] # 假设使用 AWS CLI 进行部署 steps: - task: build # 首先确保使用最新的代码构建 - confirm: “即将部署 {{.PROJECT_NAME}} 到预发布环境。确认继续?” - name: “构建并推送 Docker 镜像” run: | docker build -t my-registry/staging-{{.PROJECT_NAME}}:latest ./backend docker push my-registry/staging-{{.PROJECT_NAME}}:latest - name: “更新预发布环境服务” run: | aws ecs update-service --cluster staging-cluster --service {{.PROJECT_NAME}}-service --force-new-deployment - run: echo “预发布环境部署已触发,请等待服务更新完成。” clean: desc: “深度清理项目,包括 node_modules、Docker 缓存等” steps: - confirm: “这将删除 node_modules、dist 等目录,并清理 Docker。确定吗?” - name: “删除前端依赖与构建” dir: “./frontend” run: | rm -rf node_modules build - name: “删除后端依赖与构建” dir: “./backend” run: | rm -rf node_modules dist - name: “清理 Docker” run: | docker system prune -f docker volume prune -f - run: echo “清理完成。建议重新运行 ‘duck run setup’ 初始化环境。” setup: desc: “为新贡献者初始化开发环境” steps: - name: “检查 Git” run: git --version - name: “安装后端依赖” dir: “./backend” run: npm ci # 使用 ci 而非 install,确保依赖锁一致 - name: “安装前端依赖” dir: “./frontend” run: npm ci - name: “启动开发数据库” run: docker-compose up -d db - name: “运行数据库迁移” dir: “./backend” run: npm run db:migrate - run: echo “🎉 环境初始化成功!现在可以运行 ‘duck run dev’ 启动开发服务器了。”设计解析:
deploy-staging任务展示了如何将构建和部署流程连接起来。它包含了人工确认环节,这是生产环境操作的必要安全措施。clean任务是一个“核弹”级别的清理工具,使用前必须确认。它对于解决一些棘手的依赖冲突或磁盘空间问题非常有效。同时,它给出了清晰的后续操作指引(重新运行setup)。setup任务是团队协作的基石。新成员克隆代码后,只需要运行duck run setup,就可以自动完成从安装依赖、启动基础设施到初始化数据库的所有步骤,极大降低了上手门槛,保证了环境一致性。
5. 进阶技巧与避坑指南
经过一段时间的深度使用,我积累了一些能让 YangDuck 发挥更大效能的技巧,也踩过一些坑。这里分享给你。
5.1 模块化与配置复用
当项目变大,或者你有多个相似项目时,一个庞大的duck.yaml会难以维护。此时,可以考虑模块化。
方法一:使用include(如果 YangDuck 版本支持)可以将通用任务提取到单独的 YAML 文件中。
# common-tasks.yaml tasks: lint-js: desc: “标准的 JavaScript 代码检查” steps: - run: npx eslint . # ... 其他通用任务在主配置中引入:
# duck.yaml version: ‘1.0’ include: - ./common-tasks.yaml tasks: my-project-task: steps: - task: lint-js # 引用引入文件中的任务方法二:配置继承与锚点(YAML 高级特性)YAML 本身支持锚点(&)和别名(*),可以用来复用配置块。
env: common-env: &common-env NODE_ENV: “production” LOG_LEVEL: “info” tasks: build-a: env: <<: *common-env # 合并 common-env 的内容 APP_NAME: “app-a” steps: […] build-b: env: <<: *common-env APP_NAME: “app-b” steps: […]5.2 错误处理与调试
1. 步骤失败处理: 默认情况下,一个步骤执行失败(返回非零退出码)会导致整个任务中止。有时我们需要忽略某些步骤的错误。
steps: - run: rm -f /tmp/some-lock.file # 删除一个可能不存在的锁文件 ignore_error: true # 即使文件不存在导致 rm 失败,也继续执行2. 调试输出:
- 使用
duck run -v <task-name>可以输出更详细的执行信息。 - 在步骤中,善用
echo或print命令输出关键变量的值,有助于排查问题。 - 给复杂的步骤添加
name属性,这样在日志中就能清晰地看到当前执行到哪一步了。
3. 模拟执行(Dry Run): 某些版本或通过插件支持--dry-run参数。它可以列出任务将要执行的所有步骤,而不实际运行,非常适合检查危险操作。
5.3 性能与最佳实践
- 任务粒度要适中:不要把所有东西塞进一个任务。一个任务最好只做一件明确的事(单一职责原则)。通过
task调用来组合它们。 - 善用
requires:在任务开始时进行环境检查,可以尽早失败,避免执行到一半才发现缺少关键工具。 - 谨慎使用
background: true:后台任务如果失败,可能不会立即被发现。对于后台启动的服务,最好有对应的健康检查步骤或提供一个独立的logs任务来监控。 - 配置文件纳入版本控制:
duck.yaml是项目的基础设施代码,必须和源代码一起提交到 Git。 - 文档化:
desc字段就是最好的文档。同时,可以在项目 README 中增加一个“常用命令”章节,列出核心的 YangDuck 任务。
5.4 我踩过的“坑”与解决方案
- 坑1:路径问题。在
run命令中使用相对路径时,其基准是当前工作目录还是dir设置?答:是dir设置的工作目录。如果没设置dir,则是执行duck命令时的目录。建议始终为任务设置明确的dir,或在命令中使用绝对路径(结合{{.ROOT_DIR}})。 - 坑2:环境变量覆盖。在任务中设置的
env会覆盖全局env,但有时你只是想追加而不是覆盖。解决方案:对于类似PATH这种需要追加的变量,可以在任务中这样写:PATH: “/custom/path:{{.PATH}}”。 - 坑3:复杂逻辑。YAML 不适合写复杂的逻辑判断或循环。解决方案:如果任务逻辑非常复杂,应该将其写成一个独立的 Shell 脚本或 Python 脚本,然后让 YangDuck 去调用这个脚本。YangDuck 的强项是编排,不是替代脚本语言。
- 坑4:跨平台兼容性。虽然 YangDuck 本身是跨平台的,但
run里的命令可能不是(如rm -rf在 Windows 上不工作)。解决方案:对于核心的、需要跨平台的任务,可以将命令封装在脚本中(如clean.sh和clean.ps1),然后在 YangDuck 中根据系统类型调用不同的脚本,或者使用跨平台的 Node.js/Python 脚本。
6. 总结:让自动化成为习惯
回顾使用 YangDuck 的这段时间,它带给我的最大价值并非完成了某个惊天动地的复杂部署,而是将那些琐碎、重复、容易出错的日常操作,变成了一个稳定、可靠、可重复的“习惯”。
我不再需要记住“启动项目前要先开数据库,再开后端,最后开前端”,也不需要翻找去年的笔记来回忆“那个项目的构建命令到底是什么参数”。这一切都固化在了duck.yaml里。新同事入职,我不再需要口述半小时环境搭建步骤,只需告诉他“克隆代码后,运行duck run setup和duck run dev”。
它就像一位不知疲倦的助理,严格地按照你预设的剧本执行每一个动作。而你要做的,只是花一点时间,把这份剧本写好。这份投入的回报是长期的:更少的上下文切换、更低的出错率、更快的 onboarding,以及最终,更专注于创造性的编码工作本身。
如果你也厌倦了在终端里反复输入那些相同的命令,不妨从一个小任务开始,试试用 YangDuck 把它自动化。比如,从一个自动打包部署前端静态资源的任务做起。当你第一次用duck run deploy完成一键部署时,那种顺畅感会让你觉得,这一切都是值得的。