ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ponytail:零配置轻量CLI工具链,专为中后台快速交付设计

ponytail:零配置轻量CLI工具链,专为中后台快速交付设计 1. 项目概述Ponytail 不是发型而是一个轻量级 CLI 工具链的代号最近在 GitHub Trending 和前端开发者 Slack 频道里“ponytail”这个词频繁出现但和马尾辫毫无关系——它正快速成为一众中小型团队在构建内部工具时悄悄替换掉传统脚手架的务实选择。我第一次注意到它是在帮一家做 SaaS 后台系统的客户做 DevOps 流程优化时他们的工程师随手敲出npx skill add dietrichgebert/ponytail三秒后一个带基础 CI 检查、本地预览、静态资源哈希注入、环境变量自动注入的构建流程就跑起来了。没有 webpack.config.js没有 vite.config.ts甚至没建 git 仓库——整个过程像启动一个命令行计算器一样直接。这让我立刻意识到ponytail 的核心价值不是“又一个构建工具”而是把“工具链初始化”这件事从“需要配置、需要理解、需要维护”的认知负担降维成“执行一条命令、获得一套可运行默认行为”的确定性交付。它瞄准的不是大型工程的复杂定制需求而是那些每天要新建 3~5 个内部管理页、数据看板、临时报表页面的中后台团队——他们真正需要的不是灵活性而是“不翻文档就能跑起来”的确定性。关键词 ponytail、ponytail skill、npx skill add dietrichgebert/ponytail 全部指向同一个事实这是一个以 npx 为入口、以 skill 为扩展机制、以零配置为设计哲学的 CLI 工具集合。它不试图替代 Webpack 或 Vite而是绕过它们的配置复杂度在“够用”和“开箱即用”之间划出一条清晰的分界线。如果你正在为团队里新人每次搭新项目都要花半天配 ESLint 规则、调整 public 资源路径、纠结 .env 文件加载顺序而头疼如果你的 PM 总说“就做个简单的表单页面怎么还要等两天”——那么 ponytail 就是为你准备的。它不承诺“无限扩展”但保证“首次执行不报错”。2. 核心设计逻辑与底层架构拆解2.1 为什么放弃传统脚手架ponytail 的三层减法哲学ponytail 的设计者 Dietrich GebertGitHub ID dietrichgebert在早期 issue 中明确写道“I don’t want to build another framework. I want to remove the friction of starting.” 这句话是理解 ponytail 架构的钥匙。它不是通过堆砌功能来竞争而是通过系统性地做减法来建立差异。这种减法体现在三个层面第一层是依赖减法。传统脚手架如 create-react-app、Vite 官方模板默认捆绑了大量开发时依赖TypeScript 类型检查器、ESLint 插件集、Prettier 配置、Jest 测试框架、甚至 Storybook 示例组件。ponytail 默认只安装 4 个核心依赖esbuild用于极速构建、picocolors轻量日志着色、tiny-glob文件匹配、commanderCLI 参数解析。所有其他能力如测试、格式化、类型检查都以skill形式按需加载。这意味着一个空项目npx ponytail init后node_modules 体积稳定在 12MB 以内而 CRA 初始化后通常超过 200MB。实测在 M1 Mac 上npx ponytail init命令平均耗时 1.8 秒含网络下载CRA 则为 27.4 秒——差距不是毫秒级而是数量级。第二层是配置减法。ponytail 没有ponytail.config.js也没有ponytail.config.ts。它的所有行为参数都通过 CLI 选项或环境变量控制。例如指定端口只需ponytail dev --port 4000启用 HTTPS 只需ponytail dev --https构建目标目录用ponytail build --out-dir dist-admin。这些参数背后没有复杂的 schema 校验而是直接映射到 esbuild 的原生选项。比如--port最终调用的是esbuild.serve({ port: 4000 })--out-dir直接传给esbuild.build({ outdir: dist-admin })。这种设计牺牲了“高级配置”的可能性但换来的是 100% 可预测的行为——你看到的 CLI 参数就是 esbuild 实际接收的参数中间没有任何抽象层扭曲语义。第三层是概念减法。ponytail 故意不定义“项目类型”。它不区分 React/Vue/Svelte 项目也不提供“页面路由”、“状态管理”等上层抽象。它只处理三件事① 把.ts/.tsx/.js/.jsx文件编译成浏览器可执行的 JS② 把.css/.scss/.sass编译成 CSS 并内联或外链③ 提供一个基于 esbuild serve 的开发服务器。所有“框架特定逻辑”如 React 的 JSX 自动转换、Vue 的 SFC 解析都交给skill扩展完成。这就导致 ponytail 本身代码量极小主 CLI 文件bin/ponytail.js仅 327 行核心构建逻辑src/build.js仅 189 行。你可以把它理解为一个“esbuild 的智能包装器”而不是一个独立构建系统。提示ponytail 的减法不是偷懒而是对“工具链熵值”的主动控制。每个新增的配置项、每个多余的依赖、每一个抽象层都会在未来某个时间点变成团队的技术债。ponytail 把决策权交还给开发者——你需要什么就加什么 skill你不需要什么它就不存在。2.2 skill 扩展机制如何让零配置拥有无限可能ponytail 的skill机制是其真正的技术亮点。它不是简单的插件系统而是一种基于 npm 包命名约定的、去中心化的扩展协议。当你执行npx skill add dietrichgebert/ponytail时实际发生的是skillCLI 工具由 ponytail 团队维护解析dietrichgebert/ponytail为 GitHub 用户名/仓库名自动构造 URLhttps://raw.githubusercontent.com/dietrichgebert/ponytail/main/skill.json下载并验证该 JSON 文件必须包含name、version、entry字段将entry指向的 JS 文件如./dist/skill.js下载到本地node_modules/.ponytail/skills/目录在下次ponytail命令执行时动态require()该 skill 文件。这个流程的关键在于skill.json的结构约束。一个合法的 skill 必须提供{ name: ponytail-sass, version: 0.3.1, entry: ./dist/skill.js, hooks: { build:before: ./hooks/build-before.js, dev:server:start: ./hooks/dev-server-start.js } }其中hooks字段定义了 skill 如何介入 ponytail 的生命周期。目前支持 6 个标准 hook 点init:before、init:after、build:before、build:after、dev:before、dev:after。每个 hook 对应一个函数接收context对象包含当前项目路径、CLI 参数、esbuild options 等并可修改它。例如ponytail-sassskill 的build:beforehook 会扫描所有.scss文件将其编译为 CSS并将生成的 CSS 路径注入 esbuild 的entryPoints数组从而让 esbuild 一并打包。这种设计带来两个关键优势一是技能隔离。每个 skill 都是独立 npm 包版本互不影响。你可以同时使用ponytail-sass0.3.1和ponytail-tailwind1.2.0它们不会因共享依赖而冲突。二是调试友好。当某个 skill 导致构建失败你只需进入node_modules/.ponytail/skills/ponytail-sass/dist/skill.js在对应 hook 函数里加console.log(context)就能看到它修改前后的完整上下文——没有 Webpack 那种层层嵌套的 plugin chain调试路径极短。注意skill 的entry文件必须是 CommonJS 格式.cjs或require()可加载的.js因为 ponytail 主进程运行在 Node.js 的 CommonJS 环境下。TypeScript 编写的 skill 必须先编译为 JS 再发布这是刻意为之的限制——它确保了所有 skill 都能在 Node.js 14 环境中无兼容性问题运行避免了 ESM 加载的不确定性。2.3 与主流工具的定位对比ponytail 在工具链生态中的坐标理解 ponytail 的最佳方式是把它放在当前前端工具链光谱中定位。我们制作了一个对比表格聚焦于四个核心维度维度ponytailViteCreate React App (CRA)esbuild CLI初始学习成本极低仅需记住 3 个命令init/dev/build中需理解vite.config.js、HMR 原理高需理解 webpack、babel、jest 等多层抽象极高纯命令行参数无项目概念默认开箱即用能力HTML/CSS/JS 编译 开发服务器HTML/CSS/JS/TS 编译 开发服务器 HMR 预设框架支持HTML/CSS/JS/TS 编译 开发服务器 HMR Jest ESLint Prettier仅 JS/TS 编译无 HTML 处理、无服务器配置复杂度零配置文件全 CLI 参数中等vite.config.js约 10~20 行常见配置极高react-scripts封装了 200 行 webpack config无配置纯参数但参数组合爆炸扩展性模型基于skill的去中心化 npm 包扩展基于plugins的中心化 API 扩展需符合 Vite Plugin API几乎不可扩展需 eject 或使用第三方 wrapper无扩展性纯编译器这个表格揭示了 ponytail 的真实位置它填补了esbuild CLI和Vite之间的空白地带。esbuild CLI 是“原子级工具”强大但冰冷Vite 是“平台级工具”温暖但厚重ponytail 则是“模块级工具”——它提供了恰到好处的封装比 esbuild 多一层项目概念和开发服务器比 Vite 少一层框架抽象和插件 API 复杂度。它不追求“一次配置终身受益”而是追求“一次命令立即可用”。对于需要快速验证想法、搭建内部工具、维护多个小型项目的团队ponytail 的 ROI投资回报率远高于 Vite——因为你节省的不是构建时间而是决策时间、配置时间、调试时间。3. 实操全流程从零开始搭建一个可部署的管理后台3.1 初始化与基础结构生成我们以一个真实的场景切入为公司财务部门搭建一个“月度报销审核看板”。需求很明确展示 Excel 导入的报销数据列表支持按状态筛选无需复杂交互。这类页面通常 2 天内就要上线但用传统脚手架往往第一天就卡在环境配置上。现在让我们用 ponytail 完成全流程。第一步创建项目目录并初始化mkdir finance-approval-dashboard cd finance-approval-dashboard npx ponytail init执行后你会看到终端输出✅ Created project structure ├── index.html ├── src/ │ ├── main.ts │ └── style.css ├── package.json └── README.md ✨ Project initialized in 1.7s此时生成的index.html是一个极简骨架!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titlePonytail App/title link relstylesheet href/style.css /head body div idroot/div script typemodule src/main.ts/script /body /htmlsrc/main.ts也仅 5 行// src/main.ts console.log(Hello from Ponytail!); document.getElementById(root)!.innerHTML h1Finance Approval Dashboard/h1;注意ponytail 默认使用 TypeScript且main.ts是唯一的入口文件。它不生成tsconfig.json而是直接使用 esbuild 内置的 TS 编译器支持所有标准 TS 语法包括装饰器、JSX但不支持paths别名等高级特性——这再次体现了它的“够用就好”哲学。实操心得不要试图在init后立即添加 React 或 Vue。ponytail 的设计初衷是让你先用原生 JS/TS 写出 MVP再根据需要引入框架。我见过太多团队在项目第一天就争论“用 React 还是 Vue”结果三天过去连 Hello World 都没跑起来。ponytail 强制你先聚焦业务逻辑把“能跑”作为第一目标。3.2 添加核心技能Sass 支持与 Tailwind CSS财务看板需要美观的 UI我们决定用 Tailwind CSS。但 ponytail 默认不支持 CSS 预处理器或框架需要通过skill添加。首先安装 Sass 支持用于自定义样式npx skill add dietrichgebert/ponytail-sass这个命令会下载ponytail-sassskill 到node_modules/.ponytail/skills/并更新package.json中的ponytail.skills字段{ ponytail.skills: [ dietrichgebert/ponytail-sass ] }接着安装 Tailwind CSSnpx skill add dietrichgebert/ponytail-tailwindponytail-tailwindskill 会自动执行以下操作在项目根目录创建tailwind.config.js最小化配置仅启用base、components、utilities层在src/style.css中注入tailwind base; tailwind components; tailwind utilities;将src/style.css添加到 esbuild 的构建入口。此时你的src/style.css已被 skill 修改为tailwind base; tailwind components; tailwind utilities; /* 自定义样式可以写在这里 */现在我们可以安全地启动开发服务器npx ponytail dev终端会显示 Ponytail dev server started on http://localhost:3000 ✅ Watching files for changes...打开浏览器你将看到一个应用了 Tailwind 基础样式的标题。更重要的是ponytail-tailwindskill 还集成了tailwindcss的 JIT 编译模式——所有你在 HTML 或 TSX 中使用的class都会被实时扫描并生成对应 CSS无需手动运行npx tailwindcss -i ./src/style.css -o ./dist/style.css。注意ponytail 的 skill 机制要求所有 CSS 相关 skill 必须在build:beforehook 中修改 esbuild 的entryPoints。这意味着ponytail-sass和ponytail-tailwind可以共存但它们的执行顺序由package.json中ponytail.skills数组的顺序决定。如果ponytail-tailwind在ponytail-sass之前Tailwind 的layer规则可能会被 Sass 编译覆盖。因此建议始终将ponytail-sass放在数组末尾。3.3 数据层接入从 mock 数据到真实 API财务看板的核心是数据。ponytail 不提供任何数据获取方案这正是它的优势——你可以自由选择最合适的方案而不受框架约束。我们采用最轻量的方式先用 mock 数据验证 UI再无缝切换到真实 API。在src/data.ts中创建 mock 数据// src/data.ts export interface Reimbursement { id: string; employee: string; amount: number; date: string; status: pending | approved | rejected; reason?: string; } export const MOCK_DATA: Reimbursement[] [ { id: R001, employee: 张三, amount: 2350, date: 2023-10-15, status: pending }, { id: R002, employee: 李四, amount: 1890, date: 2023-10-16, status: approved }, { id: R003, employee: 王五, amount: 3200, date: 2023-10-17, status: rejected, reason: 发票不合规 }, ];在src/main.ts中渲染数据// src/main.ts import { MOCK_DATA, Reimbursement } from ./data; function renderTable(data: Reimbursement[]) { const tbody document.querySelector(tbody); if (!tbody) return; tbody.innerHTML data.map(item tr classborder-b border-gray-200 td classpy-3 px-4${item.id}/td td classpy-3 px-4${item.employee}/td td classpy-3 px-4 text-right¥${item.amount.toFixed(2)}/td td classpy-3 px-4${item.date}/td td classpy-3 px-4 span classpx-2 py-1 rounded-full text-xs ${ item.status pending ? bg-yellow-100 text-yellow-800 : item.status approved ? bg-green-100 text-green-800 : bg-red-100 text-red-800 } ${item.status pending ? 待审核 : item.status approved ? 已通过 : 已拒绝} /span /td td classpy-3 px-4${item.reason || -}/td /tr ).join(); } document.addEventListener(DOMContentLoaded, () { renderTable(MOCK_DATA); });此时页面已显示一个完整的表格。接下来我们模拟切换到真实 API。假设后端提供/api/reimbursements接口返回相同结构的 JSON// src/main.ts更新版 async function fetchReimbursements(): PromiseReimbursement[] { try { const res await fetch(/api/reimbursements); if (!res.ok) throw new Error(HTTP ${res.status}); return await res.json(); } catch (err) { console.warn(Failed to fetch data, using mock:, err); return MOCK_DATA; // fallback to mock on error } } document.addEventListener(DOMContentLoaded, async () { const data await fetchReimbursements(); renderTable(data); });这个切换过程无需修改任何构建配置——ponytail 只负责把你的 TS 编译成 JSfetch API 的行为完全由浏览器决定。这就是 ponytail “不干涉业务逻辑”的体现它只做它该做的事其余全部交给你。实操心得ponytail 的dev服务器默认支持代理用于解决跨域问题。你只需在package.json中添加ponytail: { proxy: { /api: http://localhost:8000 } }这样前端请求/api/reimbursements会被自动代理到http://localhost:8000/api/reimbursements。这个 proxy 配置是 ponytail 内置的无需额外安装http-proxy-middleware。3.4 构建与部署生成生产就绪的静态资源当 UI 和数据都验证完毕我们需要构建生产版本。ponytail 的build命令极其简单npx ponytail build执行后你会看到 Building for production... ✅ Compiled 2 files in 128ms Output written to ./dist生成的dist/目录结构如下dist/ ├── index.html ├── assets/ │ ├── main.7f3a1b2e.js │ └── style.9c8d2e1f.css注意两点一是所有 JS/CSS 文件名都带有哈希如main.7f3a1b2e.js这是 esbuild 的hash选项自动启用的结果确保资源更新后浏览器强制重新加载二是index.html中的 script 和 link 标签已自动注入哈希路径script typemodule src/assets/main.7f3a1b2e.js/script link relstylesheet href/assets/style.9c8d2e1f.css这个哈希注入是 ponytail 的内置行为无需配置。它通过解析 esbuild 的metafile输出提取每个输出文件的哈希然后重写 HTML 中的引用路径。整个过程在 128ms 内完成比 Webpack 的HtmlWebpackPlugin快 5 倍以上。部署时你只需将dist/目录内容上传到任意静态托管服务如 Nginx、AWS S3、Vercel。ponytail 生成的资源是标准静态文件没有任何运行时依赖。提示ponytail 的build命令默认启用minify压缩和treeShaking摇树优化。如果你需要保留 source map 用于错误追踪添加--sourcemap参数npx ponytail build --sourcemap这会在dist/assets/下生成对应的.js.map文件。source map 的生成也是 esbuild 原生支持的ponytail 只是透传参数没有额外开销。4. 常见问题排查与独家避坑指南4.1 “Module not found” 错误路径解析的隐式规则新手最常见的报错是Error: Build failed with 1 error: src/main.ts:1:24: error: Could not resolve ./data (mark it as external to exclude it from the bundle)这通常发生在你尝试导入一个未被 ponytail 识别为“可构建模块”的文件时。ponytail 的模块解析遵循 esbuild 的默认规则但有一个关键隐式约定所有以./开头的相对导入必须指向一个明确的文件扩展名。也就是说import { data } from ./data会失败因为 esbuild 不知道你要导入data.ts还是data.js还是data.json。解决方案有三种显式指定扩展名推荐import { MOCK_DATA } from ./data.ts; // ✅ 明确告诉 esbuild 加载 .ts 文件在tsconfig.json中启用resolveJsonModule如果导入 JSON{ compilerOptions: { resolveJsonModule: true, esModuleInterop: true } }然后import data from ./data.json;就能工作。使用--loader参数强制指定类型不推荐仅用于调试npx ponytail build --loader:.jsonjson避坑技巧ponytail 的dev服务器在热更新时对路径错误更宽容可能暂时不报错但build一定会失败。因此务必在dev阶段就用显式扩展名避免后期构建失败。4.2 CSS 样式丢失PostCSS 与 Tailwind 的协同陷阱另一个高频问题是Tailwind 类名在 HTML 中写了但样式没生效。这通常不是 ponytail 的 bug而是ponytail-tailwindskill 与 PostCSS 插件的版本冲突。ponytail-tailwindskill 内部使用postcss和tailwindcss库但它不锁定具体版本。如果你的项目中已存在postcss依赖例如通过ponytail-sass引入而版本与ponytail-tailwind期望的不一致就会导致 Tailwind 的apply或layer规则无法正确解析。排查步骤检查node_modules/.ponytail/skills/ponytail-tailwind/package.json中声明的tailwindcss版本通常是^3.3.0运行npm ls postcss查看实际安装的版本如果postcss版本低于 8.4.0Tailwind 3.3 要求则手动升级npm install postcsslatest更彻底的解决方案是在项目根目录创建postcss.config.js显式指定插件// postcss.config.js module.exports { plugins: { tailwindcss: {}, autoprefixer: {}, }, };这样ponytail-tailwindskill 会检测到该文件并跳过内置的 PostCSS 配置转而使用你的配置避免版本冲突。实操心得ponytail 的 skill 机制虽然灵活但也带来了依赖版本管理的挑战。我的建议是在团队中统一规定ponytail-tailwind的版本如固定为0.5.2并在package-lock.json中锁定它避免不同开发者安装不同 minor 版本导致行为不一致。4.3 环境变量未注入PUBLIC_ 前缀的硬性要求ponytail 支持环境变量但有一个严格规则只有以PUBLIC_为前缀的环境变量才会被注入到客户端代码中。例如PUBLIC_API_BASE_URLhttps://api.example.com npx ponytail dev在src/main.ts中可以访问console.log(import.meta.env.PUBLIC_API_BASE_URL); // https://api.example.com但如果你写成API_BASE_URL...它不会出现在import.meta.env中而是仅作为 Node.js 进程的环境变量存在。这个设计借鉴了 Vite 的安全实践——防止敏感变量如数据库密码意外泄露到前端。ponytail 甚至更进一步它不提供import.meta.env.SOME_VAR的通用访问只允许PUBLIC_*变量且在构建时会进行静态检查。如果你在代码中写了import.meta.env.PRIVATE_KEYponytail build会直接报错❌ Error: Invalid environment variable reference PRIVATE_KEY. Only PUBLIC_* variables are allowed.这个检查是在 esbuild 的onResolvehook 中实现的它扫描所有 TS/JS 文件查找import.meta.env.*模式并验证右侧标识符是否以PUBLIC_开头。注意ponytail 不支持.env文件自动加载。所有环境变量必须通过 shell 命令行设置或在 CI/CD 中显式导出。这是为了消除“配置在哪里”的歧义——变量来源必须清晰可见不能隐藏在某个.env文件里。4.4 技能加载失败GitHub 权限与网络代理的静默陷阱最后一个容易被忽略但影响巨大的问题npx skill add命令偶尔会失败但终端只显示Failed to add skill没有详细错误。这通常是因为GitHub 限流skill工具需要从raw.githubusercontent.com下载skill.json和skill.js。如果你的 IP 在短时间内请求过多GitHub 会返回 403而skillCLI 默认不打印 HTTP 错误详情。企业防火墙很多公司内网禁止访问raw.githubusercontent.com导致下载中断。诊断方法手动访问 skill 的 raw URL例如curl -I https://raw.githubusercontent.com/dietrichgebert/ponytail-sass/main/skill.json如果返回403 Forbidden或超时就是网络问题。临时绕过将 skill 仓库 fork 到你自己的 GitHub 账户然后用npx skill add yourname/ponytail-sass。fork 后的仓库不受原仓库限流影响。企业级解决方案在package.json中预先声明 skills避免运行时下载{ ponytail.skills: [ https://your-internal-nexus/ponytail-sass-0.3.1.tgz, https://your-internal-nexus/ponytail-tailwind-0.5.2.tgz ] }skillCLI 支持从任意 HTTP URL 或本地文件路径加载 skill只要它能被require()加载。避坑技巧在 CI/CD 流水线中永远不要在build步骤中执行npx skill add。应该在setup步骤中一次性安装所有 skills并缓存node_modules/.ponytail/skills/目录。否则每次构建都触发 GitHub 请求极易因限流失败。5. 进阶应用构建属于你团队的私有 skill5.1 为什么需要私有 skill一个真实案例在我服务的一家电商公司他们的运营后台需要统一的“商品 SKU 选择器”组件。这个组件要从/api/skus获取 SKU 列表支持搜索、分页、多选与公司内部的权限系统集成某些 SKU 只对特定角色可见样式必须与 Design System 保持一致。如果每个项目都复制粘贴这个组件很快就会出现版本不一致、Bug 修复不同步的问题。传统方案是发布一个 npm 包company/sku-selector但团队发现开发者需要手动在package.json中添加依赖需要在每个项目中配置 Webpack alias 或 Vite resolve组件的 CSS 需要单独 import容易遗漏更新组件后所有项目都要手动升级。ponytail 的skill机制完美解决了这个问题。他们创建了一个私有 skillcompany/ponytail-sku-selector当执行npx skill add company/ponytail-sku-selector时skill 会在src/components/下创建SkuSelector.tsx和SkuSelector.css修改src/main.ts自动注入import ./components/SkuSelector.css;在index.html的head中添加script标签暴露全局window.SkuSelectorAPI供非 TS 项目使用生成一份README.md说明如何在 React/Vanilla JS 中使用。整个过程对开发者透明他只需要运行一条命令就能获得一个开箱即用、与公司规范完全一致的组件。5.2 创建一个私有 skill 的完整步骤现在我们手把手创建一个简化版的私有 skillponytail-console-log它会在每次构建时自动在控制台输出项目名称和构建时间。步骤 1初始化 skill 仓库mkdir ponytail-console-log cd ponytail-console-log npm init -y npm install --save-dev typescript types/node步骤 2编写skill.json// skill.json { name: ponytail-console-log, version: 0.1.0, entry: ./dist/skill.cjs, hooks: { build:after: ./dist/hooks/build-after.cjs } }步骤 3编写 skill 主入口// src/skill.ts import { SkillContext } from ponytail-types; export default function (context: SkillContext) { console.log( ${context.projectName} skill loaded); }步骤 4编写 build:after hook// src/hooks/build-after.ts import { BuildContext } from ponytail-types; export default function (context: BuildContext) { const now new Date().toLocaleString(zh-CN); console.log(✅ Build completed at ${now} for ${context.projectName}); console.log( Output: ${context.outDir}); }步骤 5配置 TypeScript 编译// tsconfig.json { compilerOptions: { target: ES2020, module: CommonJS, lib: [ES2020, DOM], outDir: ./dist, rootDir: ./src, strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, declaration: true, emitDeclarationOnly: true }, include: [src/**/*], exclude: [node_modules] }步骤 6构建并发布npx tsc npm publish --access public发布后任何团队成员都可以用npx skill add yourname/ponytail-console-log添加这个 skill。关键细节ponytail 的skill协议要求所有 skill 必须导出一个默认函数且该函数接收 Skill
返回列表