Ripple CLI 版本演进与脚手架实战:从 @ripple-ts/cli 的 CHANGELOG 看项目创建流程实现
2026/9/16 14:18:10 网站建设 项目流程

Ripple CLI 版本演进与脚手架实战:从 @ripple-ts/cli 的 CHANGELOG 看项目创建流程实现

【免费下载链接】ripplethe elegant TypeScript UI framework项目地址: https://gitcode.com/GitHub_Trending/ripple25/ripple

本文以 packages/cli/CHANGELOG.md 为主线,梳理 Ripple 官方 CLI(@ripple-ts/cli)的版本演进脉络与每次关键变更的技术动机,并结合 CLI 源码与basic模板文件,还原npx @ripple-ts/cli create背后的完整脚手架流程:模板下载、package.json 改写、样式框架集成与包管理器版本锁定。读完后你将能够熟练使用该 CLI 创建 Ripple 应用,并理解每条变更记录对应仓库中的哪些代码实现。

一、@ripple-ts/cli 定位与当前版本

@ripple-ts/cli是 Ripple 提供的交互式项目脚手架工具,用于快速创建新的 Ripple 应用。从 packages/cli/package.json 可以看到以下关键事实:

  • 包名@ripple-ts/cli,当前仓库内版本为0.3.127(与 CHANGELOG 顶部版本一致);
  • bin入口指向./dist/index.js,即发布后可执行命令为@ripple-ts/cli
  • 运行环境要求engines.node >= 22.0.0——这一点与 CHANGELOG 中0.3.20的变更("chore: drop Node 20 support")相互印证,当前 CLI 仅支持 Node 22 及以上版本;
  • 依赖了commander(命令行解析)、prompts(交互式提问)、degit(模板下载)、ora(加载指示)、kleur(终端着色)等库,从依赖结构看,CLI 的核心职责就是“交互式参数收集 + 模板下载复制 + 工程化改写”。

另外,仓库还提供了语法更简洁的入口 packages/create-ripple/src/index.js,其实现只有一行import '@ripple-ts/cli';,即create-ripple只是对@ripple-ts/cli的二进制转发包装,两个入口能力完全等价。

二、使用方法与命令参数

根据 packages/cli/README.md 与 packages/cli/src/index.js,CLI 支持的使用方式如下:

# 无需预先安装,直接运行 npx @ripple-ts/cli <command> # 交互式创建项目 npx @ripple-ts/cli create # 带参数创建 npx @ripple-ts/cli create my-app --yes --no-git

参数说明(以 packages/cli/src/index.js 中的 commander 定义为准):

参数说明默认值
[project-name]可选的位置参数,项目名未提供时进入交互式提问
-t, --template <template>指定模板basic一种(见 packages/cli/src/constants.js 中TEMPLATES只定义了basic
-p, --package-manager <pm>包管理器,支持 npm、yarn、pnpm、bun自动检测当前运行 CLI 所用的包管理器
--no-git跳过 Git 仓库初始化默认询问,--yes模式下默认执行git init
-y, --yes跳过所有提示并采用默认值

几个源码层面的行为细节值得注意:

  1. 无子命令即显示帮助:程序通过program.parse()启动,未提供子命令时由 commander 输出帮助信息;
  2. 包管理器自动检测:packages/cli/src/commands/create.js 中会先调用getCurrentPackageManager()探测当前实际执行 CLI 的包管理器,作为交互式选择或--yes模式下的默认值;
  3. --yes的隐式默认:从源码看,--yes模式下gitInit默认为true(执行git init),样式框架固定为vanilla,即不询问 Tailwind/Bootstrap;
  4. 目录冲突保护:若目标目录已存在且非空(isFolderEmpty判断),CLI 直接退出;
  5. 创建完成后的 Next steps:CLI 会按所选包管理器打印对应的install/dev命令,并提示访问http://localhost:3000、在src/目录中修改代码——端口 3000 与模板中 Vite 配置一致(见下文)。

项目名校验规则

在提供project-name位置参数时,CLI 会先走 packages/cli/src/lib/validation.js 的validateProjectName,规则与 npm 包命名约定对齐:

  • 长度不超过 214 个字符;
  • 仅允许小写字母、数字、连字符、点、下划线(正则/^[a-z0-9._-]+$/);
  • 不能以点或下划线开头,不能以点结尾,不能包含连续点;
  • 禁止使用node_modulesfavicon.icoconprncom1com9lpt1lpt9等保留名。

交互式提问模式下同样的校验逻辑被注入promptsvalidate回调中(见 packages/cli/src/lib/prompts.js)。

三、CHANGELOG 版本脉络

packages/cli/CHANGELOG.md 记录了@ripple-ts/cli从 0.2.210 到 0.3.127 的完整版本线(中间还出现过一次 1.0.x 的版本,下文专门说明)。绝大部分版本是 changesets 流程下随其他包联动产生的空条目,真正影响使用者的变更集中在以下几个节点,按时间从旧到新排列:

版本变更内容源码印证
0.3.4升级到 Vite 8templates/basic/package.json 中vite: ^8.1.5
0.3.9将 Tailwind 脚手架更新为 v4 CSS-first 配置packages/cli/src/lib/project-creator.js 中configureStyling
0.3.20移除 Node 20 支持packages/cli/package.json 中engines.node >= 22.0.0
0.3.26TypeScript 插件包更名为@tsrx/typescript-plugin,同步更新本地消费者、模板与 playground模板 devDependencies 与 tsconfigplugins字段
0.3.34为 typescript-plugin 增加prepare脚本,确保 dist 一定被构建并随包发布发布流程变更,保证main指向 dist 的包可用
0.3.48新模板启用 strict 检查,使被追踪的值在编辑器悬浮提示中保留 nullable 类型templates/basic/tsconfig.json 中"strict": true
0.3.51修复一次误操作:某个 minor changeset 意外触发了 major 1.0.0 发布,0.3.50 及相邻版本被回补修正CHANGELOG 中出现的## 1.0.1## 1.0.0空条目
0.3.67基础模板添加skipLibChecktemplates/basic/tsconfig.json 中"skipLibCheck": true
0.3.109生成的 pnpm 项目固定(pin)pnpm 11.15.1packages/cli/src/lib/project-creator.js 中getPackageManagerVersionpnpm@11.15.1
0.3.125目标无关的 TSRX 源码迁往独立的tsrx-org/tsrx后,CLI 改为直接消费其已发布包;新 Ripple 项目使用@tsrx/language-server、TSRX 编辑器身份与已发布的 TSRX 集成模板 devDependencies 中的@tsrx/*

其中 0.3.51 的条目值得多一句解释:CHANGELOG 里## 1.0.1/## 1.0.0两个紧随 0.3.52 的空版本,对应的正是那次 changesets 版本误升——“用 minor changeset 却 bump 出 major 1.0.0”。团队随后发布补丁包修复版本号,1.0.x 因此只留下了两个没有变更说明的空标题。这是一个很典型的 monorepo 发布事故现场,也说明该 CLI 的主版本线实际停留在 0.3.x。

四、关键变更的源码级解析

4.1 TSRX 工具链外置(0.3.125)

0.3.125 的变更是整个版本线中架构影响最大的一条:TSRX(Ripple 所使用的 TS 方言)中与目标平台无关的编译器/工具链源码被迁移到独立的tsrx-org/tsrx仓库并以 npm 包形式发布,Ripple CLI 从“随仓库内置”转为“消费已发布包”。

这一变化直接反映在 CLI 生成新项目的依赖注入逻辑中。packages/cli/src/lib/project-creator.js 的updateDependencyVersions会把模板中出现的以下包统一改写为latest

ripple、@ripple-ts/vite-plugin、@tsrx/prettier-plugin、 @tsrx/eslint-plugin、@tsrx/eslint-parser、@tsrx/language-server、@tsrx/typescript-plugin

对照 templates/basic/package.json,模板本身就声明了@tsrx/language-server@tsrx/typescript-plugin@tsrx/eslint-plugin@tsrx/eslint-parser@tsrx/prettier-plugin等 devDependencies,配合 templates/basic/tsconfig.json 中的"plugins": [{ "name": "@tsrx/typescript-plugin" }],可以确认:新创建的每个 Ripple 项目的编辑器智能提示(语言服务)与类型检查,都由 TSRX 侧独立发布的包承担,Ripple 仓库只保留运行时框架ripple与 Vite 集成@ripple-ts/vite-plugin

4.2 包管理器版本锁定(0.3.109)

0.3.109 的变更是“Update generated pnpm projects to pin pnpm 11.15.1”。实现位于 packages/cli/src/lib/project-creator.js 的updatePackageJson:当所选包管理器不是 npm 时,CLI 会向生成项目的package.json写入packageManager字段,取值来自getPackageManagerVersion

包管理器写入的 packageManager 字段
yarnyarn@4.0.0
pnpmpnpm@11.15.1
bunbun@1.3.0

这正是 changesets 风格的精确版本钉扎:生成的项目会携带核心包管理器(corepack)可识别的版本声明,保证不同开发者的工具链版本一致。pnpm 的值与 0.3.109 变更记录中的 “pin pnpm 11.15.1” 逐字对应。

4.3 Tailwind v4 CSS-first 脚手架(0.3.9)

0.3.9 将 Tailwind 脚手架更新为 v4 的 CSS-first 配置,源码见configureStyling:选择tailwind时,CLI 会:

  1. 覆写src/index.css@import "tailwindcss";——v4 不再需要tailwind.config.js,内容源自动检测,主题定制用 CSS 中的@theme
  2. src/index.ts头部注入import './index.css';
  3. 删除模板原vite.config.js并重新生成,加入@tailwindcss/vite插件与server.port: 3000
  4. 生成.vscode/settings.json,配置 Tailwind IntelliSense 对.tsrx文件的识别(tailwindCSS.includeLanguages将 tsrx 映射为 html、files.associations*.tsrx关联到 tsrx 语言),保证工具类 class 在 Ripple 组件文件中能被补全。

依赖版本上,Tailwind 写入 devDependencies 的固定版本是tailwindcss: ^4.1.12@tailwindcss/vite: ^4.1.12;若选择bootstrap,则向 dependencies 注入bootstrap: ^5.3.0并在入口注入其 CSS。这与 CHANGELOG 中 “update Tailwind scaffolding to v4 CSS-first config” 的记录完全对应。

4.4 Node 22 与 Vite 8(0.3.20 / 0.3.4)

0.3.20 移除 Node 20 支持后,packages/cli/package.json 的engines与 templates/basic/package.json 中生成项目的engines均声明node >= 22.0.0,即 CLI 本身与它生成的项目共享同一 Node 基线。0.3.4 升级 Vite 8 后,模板 devDependencies 固定为vite: ^8.1.5,templates/basic/vite.config.js 则以defineConfig形式注册ripple()插件并设置build.target: 'esnext'

五、create 命令的完整执行流程

结合 packages/cli/src/commands/create.js 与 packages/cli/src/lib/project-creator.js,一次create调用的完整调用链如下:

参数收集阶段(create.js 的createCommand

  1. 项目名:未提供则交互式提问(默认值my-ripple-app),提供则校验合法性;
  2. 目录检查:目标路径已存在且非空则退出;
  3. 模板:未提供则询问;当前TEMPLATES列表只有一项basic,packages/cli/src/lib/prompts.js 中promptTemplate会在选项数为 1 时自动跳过提问直接采用basic
  4. 包管理器:交互式模式下以检测到的包管理器为初始选项,四选一(npm/yarn/pnpm/bun);--yes模式直接取检测值或--package-manager显式值;
  5. Git 初始化与样式框架(vanilla/bootstrap/tailwind):--yes时分别取truevanilla,其余情况逐项询问。

项目落盘阶段(project-creator.js 的createProject

  1. 获取模板isLocalDevelopment()会向上探测 monorepo 根目录下的templates/目录(相对packages/cli/src/lib/上溯四级,对应仓库根),存在则直接使用本地 templates/basic 目录——这是仓库内开发调试路径;否则调用 packages/cli/src/lib/templates.js 的downloadTemplate,通过degitRipple-TS/ripple仓库main分支的templates/<name>子目录下载到系统临时目录(常量定义在 packages/cli/src/constants.js:GITHUB_REPOGITHUB_BRANCHGITHUB_TEMPLATES_DIRECTORY),下载失败会抛出带模板名的明确错误;
  2. 创建目录并复制mkdirSync递归建目录后cpSync复制,filter回调显式跳过node_modules与各类锁文件(package-lock.jsonyarn.lockpnpm-lock.yamlbun.lock),保证新项目从干净状态安装依赖;
  3. 改写 package.json:项目名替换为basename(projectName),模板占位版本0.0.0提升为1.0.0,写入 description,非 npm 场景写入packageManager字段,按选择注入样式依赖,并把 Ripple/TSRX 系依赖统一改写为latest
  4. 样式配置:即上文 4.3 所述的 Tailwind/Bootstrap 分支;
  5. Git 初始化gitInit为真时执行git init,失败仅告警不阻断(“Git initialization failed (optional)”);
  6. 清理:下载得到的临时模板目录无论成败都会被rmSync清理。

六、脚手架产物:basic 模板长什么样

综合模板文件与 CLI 的改写逻辑,create完成后你得到的最小 Ripple 应用包含:

templates/basic/package.json 的核心内容(经 CLI 改写后 name/version 变为实际项目信息):

{ "type": "module", "engines": { "node": ">=22.0.0" }, "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "lint": "eslint .", "typecheck": "tsrx-tsc --noEmit", "serve": "vite preview", "format": "prettier --write .", "format:check": "prettier --check ." }, "dependencies": { "ripple": "latest" }, "devDependencies": { "eslint": "^9.0.0", "@tsrx/eslint-plugin": "latest", "@tsrx/eslint-parser": "latest", "@tsrx/prettier-plugin": "latest", "@tsrx/language-server": "latest", "@tsrx/typescript-plugin": "latest", "@ripple-ts/vite-plugin": "latest", "prettier": "^3.6.2", "typescript": "^5.9.3", "vite": "^8.1.5" } }

注意typecheck脚本使用tsrx-tsc --noEmit,即类型检查由 TSRX 的工具链完成,而非原生tsc——这与 0.3.125 “消费已发布 TSRX 包”的变更一脉相承。

templates/basic/tsconfig.json体现了 0.3.48 与 0.3.67 两条变更记录的落地:"strict": true.ripple()追踪值在编辑器悬浮中保留 nullish 类型;"skipLibCheck": true跳过声明文件检查以提升 IDE 性能;"jsx": "preserve"+"jsxImportSource": "ripple"声明 JSX 由 Ripple 编译器接管(noEmit下仅做类型层处理);"plugins": [{ "name": "@tsrx/typescript-plugin" }]挂接 TSRX 语言插件。

templates/basic/vite.config.js只有两个要点:注册ripple()Vite 插件、开发服务器固定在 3000 端口——与 CLI 完成后打印的http://localhost:3000提示保持一致。

七、适用前提与限制小结

  • 适用前提:Node.js >= 22(CLI 与生成项目共同基线,来自两处 package.json 的engines声明);
  • 当前仅basic一个模板,--template传入其他值会被validateTemplate拒绝并打印可用列表;
  • 非 monorepo 场景下模板经degit从 GitHubmain分支拉取,属于网络依赖步骤;
  • README 中“Node.js 20.0.0 or higher”的旧表述与engines及 0.3.20 的变更记录不一致,以engines.node >= 22.0.0与 CHANGELOG 为准;
  • 生成的项目依赖 Ripple/TSRX 系包被统一钉为latest,意味着新项目永远跟踪各包最新稳定发布,这是 CHANGELOG 0.3.125 之后“消费已发布包”策略的直接产物。

整体来看,@ripple-ts/cli的 CHANGELOG 虽然条目稀疏,但每一条有说明的 patch 都能在当前仓库的源码与模板中找到对应实现:TSRX 工具链外置、pnpm 版本钉扎、Tailwind v4 CSS-first、strict/skipLibCheck 的模板演进、Node 22 基线与 Vite 8 升级。理解这条版本线,基本也就掌握了 Ripple 项目脚手架的全部工程化细节。

【免费下载链接】ripplethe elegant TypeScript UI framework项目地址: https://gitcode.com/GitHub_Trending/ripple25/ripple

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询