Vant CLI 实战指南:基于 Rsbuild 打造现代化 Vue 组件库的完整工具链
【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant
Vant CLI 是 Vant 组件库配套的开源构建工具,它基于 Rsbuild 与 Vite 双引擎实现,覆盖组件库从本地开发、文档站点生成、单元测试到构建发布的全生命周期。本文将以其官方中文文档为主体,结合仓库源码(packages/vant-cli)深入讲解命令行工具、vant.config.mjs全部配置项、约定式目录结构以及底层实现原理,读完即可用它从零搭建一套支持按需引入、主题定制与 Tree Shaking 的生产级 Vue 组件库。
一、Vant CLI 是什么
Vant CLI 是一个基于 Rsbuild 实现的 Vue 组件库构建工具,通过它可以在几分钟内快速搭建一套功能完备的 Vue 组件库。官方将其定位为"组件库开发脚手架",其核心能力可概括为:
- 基于 Rsbuild 实现,享受愉悦的开发体验(HMR、按需编译等);
- 提供丰富的命令,涵盖从开发测试到构建发布的完整流程;
- 基于约定的目录结构,自动生成优雅的文档站点和组件示例,无需手写站点路由与示例注册代码;
- 构建后的组件库默认支持按需引入、主题定制、Tree Shaking,保证发布产物开箱即用的工程化能力。
从仓库根目录的 packages/vant-cli/package.json 可以看到,Vant CLI 自身正是用这套工具链开发维护的,其vant.config.mjs仅有一行配置即指定包管理器为 pnpm(见 packages/vant-cli/vant.config.mjs),是最直观的"自举"示例。
二、快速上手:两种安装方式
2.1 使用脚手架一键创建
执行以下命令可以快速创建一个基于 Vant CLI 的项目:
yarn create vant-cli-app该脚手架(create-vant-cli-app包)支持生成 Vue 2 与 Vue 3 两套模板,对应仓库中的 packages/create-vant-cli-app/generators/vue2 与 packages/create-vant-cli-app/generators/vue3 目录,每个模板都预置了docs/、src/示例组件、vant.config.mjs(vue3 模板为vant.config.mjs)以及package.json.tpl,创建完成后即可直接dev预览。
2.2 手动安装到现有项目
在已有项目中安装@vant/cli作为开发依赖:
# 通过 npm npm i @vant/cli -D # 通过 yarn yarn add @vant/cli -D # 通过 pnpm pnpm add @vant/cli -D # 通过 Bun bun add @vant/cli -D安装完成后,请将以下配置添加到package.json中:
{ "scripts": { "dev": "vant-cli dev", "test": "vant-cli test", "build": "vant-cli build", "prepare": "husky", "release": "vant-cli release", "build-site": "vant-cli build-site" }, "nano-staged": { "*.md": "prettier --write", "*.{ts,tsx,js,vue,less,scss}": "prettier --write" }, "prettier": { "singleQuote": true }, "browserslist": ["Chrome >= 51", "iOS >= 10"] }其中nano-staged+prettier用于提交前自动格式化,browserslist用于确定目标浏览器版本(详见后文)。
三、命令行工具详解
Vant CLI 内置一系列命令,可直接添加到 npm scripts 中使用,也可以通过 npx 直接执行:
npx vant-cli dev所有命令的注册入口集中在 packages/vant-cli/src/cli.ts,其内部基于commander实现,并通过动态import()按需加载命令模块,保证 CLI 本身启动轻量。已注册的命令包括dev、clean、build、release、build-site、commit-lint。
3.1dev:本地开发
运行本地开发环境。Vant CLI 会启动一个本地服务器,用于在开发过程中对文档和示例进行预览。
从源码看(packages/vant-cli/src/commands/dev.ts),dev命令核心只有两步:设置NODE_ENV=development,然后调用compileSite()编译文档站点。这意味着开发态预览的不只是组件示例,而是完整的文档站点(含左侧导航、手机模拟器等),这与"约定式目录自动生成文档站点"的特性直接相关。
3.2build:构建组件库
运行build命令会在es和lib目录下生成可用于生产环境的组件代码,目录产物细节见第四节"构建结果目录"。
发布 npm 时,请将以下配置加入package.json,使 npm 包能被正确识别:
{ "main": "lib/index.js", "module": "es/index.js", "files": ["es", "lib"] }从 packages/vant-cli/src/config/vite.package.ts 可以印证:build阶段使用 Vite 的 library 模式,以es/index.js为入口,按bundleOptions中配置的formats产出 UMD / ESModule / CJS 等多份产物到lib目录,文件名形如[name].js、[name].min.js、[name].es.js等;vue默认被 external 掉并映射为全局变量Vue。压缩使用 terser(注释明确说明其压缩效果优于 esbuild)。
3.3build-site:构建文档站点
在site目录生成可用于生产环境的文档站点代码。站点构建走的是 Rsbuild 链路,与dev共用同一套站点源码(packages/vant-cli/site),生产构建时自动注入publicPath、百度统计、HTML meta 等站点配置。
3.4release:发布组件库
发布组件库,发布前会自动执行build命令,并按流程发布 npm 包。
阅读 packages/vant-cli/src/commands/release.ts 可以还原其完整执行流程:
- 读取并打印当前包名与版本号;
- 交互式询问新版本号(基于
enquirer); - 根据版本号自动推断 npm tag:包含
beta用beta、alpha用alpha、rc用rc,否则用latest;也支持通过--tag <tag>强制指定; - 更新
package.json中的 version 字段; - 执行
packageManager run build构建(若构建失败,会自动把版本号回滚到上一个版本); - 执行
packageManager publish --tag <tag>发布(pnpm 下额外追加--no-git-checks); - 自动
git add -A && git commit,提交信息格式为release: <pkgName> v<version>;若带--gitTag选项还会创建并推送对应 git tag。
3.5commit-lint:提交信息校验
校验 commit message 的格式是否符合规范,需要配合husky在提交 commit 时触发,典型用法是在package.json中配置:
{ "husky": { "hooks": { "commit-msg": "vant-cli commit-lint $HUSKY_GIT_PARAMS" } } }其校验规则定义在 packages/vant-cli/src/commands/commit-lint.ts,正则如下:
/^(revert: )?(fix|feat|docs|perf|test|types|style|build|chore|release|refactor|breaking change)(\(.+\))?: .{1,50}/即允许的类型为fix、feat、docs、perf、test、types、style、build、chore、release、refactor、breaking change,可附带(作用域),描述 1~50 个字符;Merge开头的合并提交同样放行。规范化的提交信息是后续自动生成 changelog 的前提。
3.6 补充命令:clean
仓库中还提供了文档未单独列出的clean命令,用于清理es、lib、dist、site-dist全部构建产物(见 packages/vant-cli/src/commands/clean.ts),适合在切换构建配置或 CI 场景中配合使用。
四、配置指南:三份配置文件 + PostCSS + browserslist
Vant CLI 的配置体系由rsbuild.config.mjs、vite.config.mjs、vant.config.mjs三份文件 + PostCSS/browserslist 组成,各有分工。
4.1rsbuild.config.mjs:文档站点构建配置
Vant CLI 使用 Rsbuild 构建文档站点,你可以在vant.config.mjs的同级目录下创建 Rsbuild 配置文件,内容会被自动读取:
// rsbuild.config.mjs 或 rsbuild.config.ts export default { plugins: [ // 配置 Rsbuild 插件 ], dev: { // 与本地开发有关的选项 }, html: { // 与 HTML 生成有关的选项 }, // 其他选项 };4.2vite.config.mjs:组件库构建配置
Vant CLI 使用 Vite 构建组件库代码,你可以在vant.config.mjs的同级目录下创建 Vite 配置文件,并添加任意的 Vite 配置。
底层实现上,Vant CLI 会通过loadConfigFromFile从当前工作目录自动加载这份用户配置,再与内置的 library 模式配置做mergeConfig合并(见 packages/vant-cli/src/common/index.ts 中的mergeCustomViteConfig)。此外vant.config.mjs中还可以通过build.configureVite函数以编程方式进一步修改 Vite 配置。
4.3vant.config.mjs:打包配置 + 文档站点配置
vant.config.mjs是 Vant CLI 的核心配置文件,必须创建并置于项目根目录下。从源码看(packages/vant-cli/src/common/constant.ts),Vant CLI 会从当前目录向上查找第一个存在vant.config.mjs的目录作为项目根目录ROOT,因此务必保证该文件存在且位置正确。下面是一份基本配置的示例:
export default { // 组件库名称 name: 'demo-ui', // 构建配置 build: { site: { publicPath: '/demo-ui/', }, }, // 文档站点配置 site: { // 标题 title: 'Demo UI', // 图标 logo: 'https://fastly.jsdelivr.net/npm/@vant/assets/logo.png', // 描述 description: '示例组件库', // 左侧导航 nav: [ { title: '开发指南', items: [ { path: 'home', title: '介绍', }, ], }, { title: '基础组件', items: [ { path: 'my-button', title: 'MyButton 按钮', }, ], }, ], }, };以下逐一说明各项配置的含义、类型与默认值。
name
- Type:
string - Default:
''
组件库名称,建议使用中划线分割,如demo-ui。它会作为 UMD 产物的全局变量名和输出文件名前缀(见 vite.package.ts 中lib.name与fileName的使用)。
build.css.base
- Type:
string - Default:
'style/base.less'
全局样式文件的路径,可以为相对路径或绝对路径。相对路径基于src目录计算:
module.exports = { build: { css: { base: 'style/global.scss', }, }, };build.css.preprocessor
- Type:
string - Default:
'less'
CSS 预处理器配置,目前支持less和sass两种预处理器,默认使用less:
module.exports = { build: { css: { preprocessor: 'sass', }, }, };build.css.removeSourceFile
- Type:
boolean - Default:
false
是否在构建后移除样式文件的源代码(.less/.scss源文件):
module.exports = { build: { css: { removeSourceFile: true, }, }, };build.site.publicPath
- Type:
string - Default:
/
文档站点部署时的资源公共路径。一般来说文档网站会部署在一个域名的子路径上,如https://my.github.io/demo-ui/,此时publicPath需要与子路径保持一致,即/demo-ui/:
module.exports = { build: { site: { publicPath: '/demo-ui/', }, }, };build.srcDir
- Type:
string - Default:
src
组件源码目录名。配置后 Vant CLI 将基于该目录查找组件、计算build.css.base的相对路径:
module.exports = { build: { srcDir: 'myDir', }, };build.namedExport
- Type:
boolean - Default:
false
是否通过 Named Export 对组件进行导出。未开启时通过export default from 'xxx'导出组件内部默认模块;开启后通过export * from 'xxx'导出组件内部的所有模块与类型定义。对应源码 packages/vant-cli/src/compiler/gen-package-entry.ts 中genImports/genExports的分支逻辑。
build.packageManager
- Type:
'npm' | 'yarn' | 'pnpm' | 'bun' - Default:
yarn
指定使用的包管理器,release命令会据此拼接build与publish命令(如 pnpm 发布时追加--no-git-checks)。
build.bundleOptions
- Type:
BundleOptions[]
指定打包后产物的格式,由三个配置项控制:
type BundleOption = { // 是否压缩代码(注意 es 产物无法被 vite 压缩) minify?: boolean; // 产物类型,可选值为 'es' | 'cjs' | 'umd' | 'iife' formats: LibraryFormats[]; // 需要 external 的依赖(Vue 默认会被 external) external?: string[]; };该选项的默认值如下,即默认产出「未压缩 UMD + 压缩 UMD + 未压缩 ES/CJS(external 全部依赖)」三组产物:
const DEFAULT_OPTIONS: BundleOption[] = [ { minify: false, formats: ['umd'], }, { minify: true, formats: ['umd'], }, { minify: false, formats: ['es', 'cjs'], external: allDependencies, }, ];site.title
- Type:
string - Default:
''
文档站点的标题。
site.logo
- Type:
string - Default:
''
文档站点的 Logo(图片 URL)。
site.description
- Type:
string - Default:
''
标题下方的描述文案。
site.nav
- Type:
object[] - Default:
undefined
文档站点的左侧导航,数组中的每个对象表示一个导航分组:
module.exports = { site: { nav: [ { // 分组标题 title: '开发指南', // 导航项 items: [ { // 导航项路由 path: 'home', // 导航项文案 title: '介绍', // 是否隐藏当前页右侧的手机模拟器(默认不隐藏) hideSimulator: true, }, ], }, ], }, };注意path对应 docs 目录下的 markdown 文件名(如home对应docs/home.md),导航与文档由约定式目录自动关联。
site.versions
- Type:
object[] - Default:
undefined
文档站点多版本配置,当组件库存在多个版本的文档时,可以在顶部导航配置一个版本切换按钮:
module.exports = { site: { versions: [ { label: 'v1', link: '/v1/', }, ], }, };site.baiduAnalytics
- Type:
object - Default:
undefined
文档网站的百度统计配置,添加后会在构建文档站点时自动加载百度统计脚本:
module.exports = { site: { baiduAnalytics: { // 打开百度统计 ->『管理』->『代码获取』 // 找到下面这串 URL: "https://hm.baidu.com/hm.js?xxxxx" // 将 `xxxxx` 填写在 seed 中即可 seed: 'xxxxx', }, }, };site.hideSimulator
- Type:
boolean - Default:
false
是否隐藏所有页面右侧的手机模拟器,默认不隐藏。
site.simulator.url
- Type:
string - Default: 无
自定义手机模拟器的 iframe URL 地址。
site.htmlMeta
- Type:
Record<string, string> - Default:
undefined
配置 HTML 中的 meta 标签,对象的 key 为 name、value 为 content,可用于 SEO 优化。
site.headHtml
- Type:
string - Default:
undefined
在<head>标签中插入一段自定义的 HTML 内容。
site.enableVConsole
- Type:
boolean - Default:
false
是否在 dev 时开启 vConsole 调试,用于移动端 debug。
4.4 PostCSS 配置
通过根目录下的postcss.config.js文件可以对 PostCSS 进行配置。vant-cli默认的 PostCSS 配置如下(仓库中对应 packages/vant-cli/cjs/postcss.config.cjs):
module.exports = { plugins: { autoprefixer: {}, }, };4.5 browserslist
推荐在package.json中配置 browserslist 字段,该值会被autoprefixer用来确定目标浏览器版本,保证编译后代码的兼容性。在移动端浏览器中使用,可以添加如下配置:
{ "browserslist": ["Chrome >= 51", "iOS >= 10"] }五、约定式目录结构
Vant CLI 的核心设计之一是"约定优于配置":只要遵循约定的目录结构,文档站点、组件示例、构建产物便会自动生成。
5.1 源代码目录
基于 Vant CLI 搭建的组件库基本目录结构如下:
project ├─ src # 组件源代码 │ ├─ button # button 组件源代码 │ └─ dialog # dialog 组件源代码 │ ├─ docs # 静态文档目录 │ ├─ home.md # 文档首页 │ └─ changelog.md # 更新日志 │ ├─ vant.config.mjs # Vant CLI 配置文件 ├─ package.json └─ README.md其中docs/下每个 markdown 文件对应站点的一个页面,src/下每个含index.xxx入口文件的目录会被自动识别为组件——识别规则见 packages/vant-cli/src/common/index.ts 的getComponents():目录下存在index.js/ts/tsx/jsx/vue且内容包含export default或defineOptions才会被当作组件收录,从而进入构建与文档站点。
单个组件的目录如下:
button ├─ demo # 示例目录 │ └─ index.vue # 组件示例 ├─ index.vue # 组件源码 └─ README.md # 组件文档使用.vue文件编写组件时,编译后会生成对应的 JS 和 CSS 文件,且 JS 文件中会自动引入 CSS 文件。
如果需要将 JS 和 CSS 解耦、实现主题定制等功能,编写代码时就要使用独立的 JS 和 CSS 文件:
button ├─ demo # 组件示例 │ └─ index.vue # 组件示例入口 ├─ index.js # 组件入口 ├─ index.less # 组件样式,可以为 less 或 scss └─ README.md # 组件文档采用这种目录结构时,组件的使用者需要分别引入 JS 和 CSS 文件。通过引入样式源文件(less 或 scss)并修改样式变量,即可实现主题定制功能——这正是 Vant 本体(packages/vant/src 下各组件目录)采用的组织方式。
5.2 构建结果目录
运行build命令会在es和lib目录下生成生产代码,结构如下:
project ├─ es # es 目录下的代码遵循 esmodule 规范 │ ├─ button # button 组件编译后的代码目录 │ ├─ dialog # dialog 组件编译后的代码目录 │ └─ index.js # 引入所有组件的入口 (ESModule) │ └─ lib # lib 目录下的代码遵循 commonjs 规范 ├─ button # button 组件编译后的代码目录 ├─ dialog # dialog 组件编译后的代码目录 ├─ index.js # 引入所有组件的入口 ├─ index.less # 所有组件未编译的样式入口 ├─ index.css # 打包后的组件样式,用于 CDN 引入 ├─ [name].js # 打包后的组件脚本,UMD 格式 ├─ [name].es.js # 打包后的组件脚本,ESModule 格式 ├─ [name].min.js # 打包和压缩后的组件脚本,UMD 格式 └─ [name].es.min.js # 打包和压缩后的组件脚本,ESModule 格式单个组件编译后的目录如下:
button ├─ index.js # 组件编译后的 JS 文件 ├─ index.css # 组件编译后的 CSS 文件 ├─ index.less # 组件编译前的 CSS 文件,可以为 less 或 scss └─ style # 按需引入样式的入口 ├─ index.js # 按需引入编译后的样式 └─ less.js # 按需引入未编译的样式,可用于主题定制可以看到每个组件都同时产出编译后样式(style/index.js)与未编译样式源(style/less.js)两个按需引入入口:前者面向普通用户,后者面向主题定制用户。这也是"按需引入 + 主题定制 + Tree Shaking"三大能力在产物层面的落点。
5.3 生成类型声明
当组件库使用 TS 编写,且根目录下存在tsconfig.declaration.json时,Vant CLI 会自动生成.d.ts类型声明文件(对应仓库中 packages/vant/tsconfig.declaration.json 的实际用法)。参考格式:
{ "extends": "./tsconfig.json", "compilerOptions": { "declaration": true, "declarationDir": ".", "emitDeclarationOnly": true }, "include": ["es/**/*", "lib/**/*"], "exclude": ["node_modules", "**/test/**/*", "**/demo/**/*"] }成功生成类型声明后,请在package.json中添加类型入口声明:
{ "typings": "lib/index.d.ts" }六、延伸阅读
- 命令详解:packages/vant-cli/docs/commands.zh-CN.md
- 配置指南(含全部配置项说明):packages/vant-cli/docs/config.zh-CN.md
- 目录结构约定:packages/vant-cli/docs/directory.zh-CN.md
- 更新日志:packages/vant-cli/changelog.md
- CLI 入口与命令注册:packages/vant-cli/src/cli.ts
- 发布流程实现:packages/vant-cli/src/commands/release.ts
- 组件识别与目录约定实现:packages/vant-cli/src/common/index.ts
【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考