声明:本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!
前言
前面咱们已经介绍了,什么是 Headless UI 无头组件库
了,以及如何去使用它,我相信同学们看完了之后能够已经在实际项目中运用自如了;
但是我的目的是带领大家能实现一个属于自己的,一个属于公司的、甚至属于公司和个人 KPI 的产物,那么接下来将会手摸手的一步一步指引大家去实现一个真正意义上的 Headless UI 无头组件库
;
让我们一起开始动手吧~
说明:为了更好符合国内的大部分用户群体,所以主要实现一个 vue3 的
Headless UI 无头组件库
!
一、初始化项目
1. 生成目录 & 初始化
1 | bash复制代码# 创建目录 |
2. 创建 pnpm-workspace.yaml
文件
1 | bash复制代码touch pnpm-workspace.yaml |
3. 修改 pnpm-workspace.yaml
1 | markdown复制代码packages: |
4. 新增 packages/vue
目录
1 | bash复制代码mkdir packages |
5. 新增 typescript
依赖
1 | bash复制代码# 安装到 my-project 根目录下 |
6. 新增 README.md
和 LICENSE
文件
1 | bash复制代码touch README.md LICENSE |
二、安装 eslint
和 simple-git-hooks
+ commitlint
等基本配置
- 配置
eslint
和@antfu/eslint-config
- 安装
1 | bash复制代码pnpm i eslint @antfu/eslint-config -Dw |
@antfu/eslint-config
是一个由 Anthony Fu 创建的 ESLint 配置包,它包含了 Vue 和 Vanilla JS 项目中常见的最佳实践规则,实际项目可安可不安。
2. 新建eslint.config.js
文件
3. 编辑eslint.config.js
文件:
1 | php复制代码import antfu from '@antfu/eslint-config' |
- 在
package.json
中script
添加脚本
1 | bash复制代码"lint": "eslint .", |
- 测试
- 配置
simple-git-hooks
和lint-staged
- 安装
1 | bash复制代码pnpm i simple-git-hooks lint-staged -Dw |
package.json
中添加脚本
1 | json复制代码script:{ |
- 配置
@commitlint/config-conventional
和@commitlint/cli
:
- 安装
1 | bash复制代码pnpm i @commitlint/config-conventional @commitlint/cli -Dw |
- 在
package.json
中添加配置和脚本
1 | json复制代码"commitlint": { |
4.执行
根据上面的配置,我们在每次修改文件 git 提交后,都会按照以下顺序执行:
npx simple-git-hooks
:执行 simple-git-hooks 命令;pnpm lint-staged
:执行 lint-staged 命令;eslint --fix
:执行 eslint 方法,检查所有的代码是否合格;- 正常提交
commit-msg
;
比较 simple-git-hooks
与 husky
1. 共同点:
- 都是用于管理 Git 钩子(Git hooks)的工具,它们可以帮助开发团队在代码提交、推送等操作时运行预定义的脚本或命令。
- 可以用来执行代码格式化、静态代码分析、单元测试等任务,以确保代码质量和一致性。
- 都提供了对本地 Git 钩子的支持,包括但不限于
pre-commit
、post-commit
、pre-push
等钩子。
2. 差异点:
功能和灵活性
:
+ `husky` 提供了更多的功能和灵活性,可以在提交前、提交后、推送前等不同的 Git 钩子上运行任务,并且支持与其他工具(如 lint-staged)的集成。
+ `simple-git-hooks` 则专注于简单的 Git 钩子管理,功能相对较少,主要用于运行基本的脚本任务。
配置和定制
:
+ `husky` 提供了更丰富的配置选项和定制能力,可以根据项目的需求定义更复杂的钩子行为。
+ `simple-git-hooks` 更注重简单易用,配置相对简单,适合对 Git 钩子管理要求不高的项目。
生态系统和支持
:
+ `husky` 在社区中有着更广泛的应用和支持,拥有更丰富的生态系统和插件,可以满足不同需求。
+ `simple-git-hooks` 的用户群体相对较小,生态系统相对简单。
总结:
选择使用
simple-git-hooks
还是husky
取决于项目的具体需求和团队的偏好。根据项目的规模、复杂度以及对 Git 钩子管理的需求,选择适合的工具可以提高开发流程的效率和代码质量。
三、配置package/vue
核心库
- 初始化
package/vue
1 | bash复制代码# 进入目录 |
- 安装用到的基本库
vue
: 这个就不解释了vue-tsc
: vue-tsc 是对TypeScript 自身命令行界面 tsc 的一个封装。它的工作方式基本和 tsc 一致。
1 | bash复制代码pnpm install vue vue-tsc -D |
- 配置工具库(可选)
@vueuse/core
:一个针对 Vue.js 生态系统的工具库,旨在提供一组通用的、经过测试的 Vue 3 组合式 API,帮助开发者更轻松地构建 Vue 应用程序。
1 | bash复制代码pnpm install @vueuse/core -D |
- 配置
tsconfig
typescript
:不解释@tsconfig/node18
: 是 TypeScript 中的一个预定义的配置文件,它适用于 Node.js 18 的项目。在 TypeScript 中,可以使用预定义的配置文件来简化项目的配置过程,而不必手动指定所有的编译选项。@vue/tsconfig
:一个 TypeScript 配置文件的包装库,用于简化在 Vue.js 项目中配置 TypeScript 的过程。这个包装库提供了一组预定义的 TypeScript 配置,旨在帮助开发者轻松地配置 TypeScript 在 Vue.js 项目中的使用。如果你们不需要它的配置,可以自己写。
1. 安装 typescript
、@tsconfig/node18
和 @vue/tsconfig
1 | bash复制代码pnpm install typescript @tsconfig/node18 @vue/tsconfig -D |
2. 添加 tsconfig
配置文件
tsconfig.json
:ts 配置,不解释
1 | json复制代码{ |
tsconfig.app.json
:定义项目中所需文件的基本ts编译规则
1 | json复制代码{ |
tsconfig.build.json
:主要用来打包所用的 ts 编译规则,执行 pnpm build 所需规则(代码与 tsconfig.app.json 类似)tsconfig.node.json
:专门用来配置vite.config.ts文件的编译规则
1 | json复制代码{ |
- 安装 vite 相关
vite
:这个就不解释了@vitejs/plugin-vue
:Vite 的一个插件,用于处理 Vue 单文件组件(SFC)。vite-plugin-dts
:一个 Vite 插件,用于自动生成 TypeScript 类型声明文件(.d.ts 文件)并将其输出到构建目录中。
1 | bash复制代码pnpm install vite @vitejs/plugin-vue vite-plugin-dts -D |
配置 vite.config.ts
1 | ts复制代码import { resolve } from 'node:path' |
- 新建 src & build 测试
创建 src
1 | bash复制代码mkdir src |
编辑 src/index.ts
1 | ts复制代码const a = '1111' |
添加 package.json 脚本
1 | json复制代码"build": "vite build", |
build 构建
1 | bash复制代码pnpm build |
结果就会生成了 dist目录,如下图的文件
因为我们要的是能开箱即用,所以 esm、cjs
的文件格式就要配置好
- 配置 exports 默认模块
1 | json复制代码"exports": { |
这样我们就可以直接在项目中使用 import 或者 require 来使用库了;
例如:
1 | ts复制代码import { add } from '@yi-ui/vue' |
在下面讲解的 docs文档 和 playground 也会使用到;
到这里一个最最基本的核心库就完成了最基本的搭建,下一步我们考虑的就是测试问题了
四、单元测试
为什么要用单元测试
因为我们写的是一个上层的工具库,所以单元测试是必不可少的;
毕竟单元测试可以验证库的每个功能模块是否按照预期工作;
在开发阶段就能发现和修复问题,而不是等到系统集成测试甚至上线后才发现,这样可以显著降低修复成本。
等等一系列的原因我们都必须得安排上;
因为咱们主要是开发一个 vue 相关的无头组件库,为了更好的适配,所以咱们的选择就必须是 vitest
了 。
vitest 配置
1. 安装
1 | bash复制代码cs package/vue |
2.新建 vitest.config.ts
1 | ts复制代码import { resolve } from 'node:path' |
3. 配置运行脚本:package.json
1 | bash复制代码"script": { |
4. 新建一个 src/index.test.ts 文件
1 | ts复制代码import { describe, expect, test, it } from 'vitest' |
5.执行 pnpm test
五、配置 docs
文档
为什么要用到文档
- 提高易用性与可理解性:
* 详细的文档能够帮助开发者快速上手,减少试错的时间,提升开发效率。
- 方便安装和配置:
* 文档应当包含安装指南、依赖说明、编译和构建步骤,确保任何技术水平的开发者都能顺利将其集成到他们的项目中。
- 示例与教程:
* 包含示例代码和教程的文档能够直观展示组件库的功能如何实际应用,对于初学者尤为重要。
- 维护和更新指南:
* 文档应包含版本更新日志、迁移指南等内容,方便开发者跟踪库的最新变化并适应升级过程。
- 社区建设与贡献者引导:
* 文档还应包含贡献指南、代码规范、提交PR和issue的流程等,鼓励社区成员参与到开源库的开发与维护工作中来。
安装配置 vitepress
新建 docs 目录
1 | bash复制代码mkdir docs |
安装 vitepress & tailwindcss
1 | bash复制代码pnpm i vitepress tailwindcss -D |
配置 package.json
1 | bash复制代码"scripts": { |
运行 pnpm docs:dev
到这里其实文档就基本配置好了~
但是还要与我们的核心库做关联,还要有一些基本config配置和样式等等,这些暂时不表,因为涉及的点太多,待后续完善。
六、配置playground
为什么要配置 playground
一句话概括就是:配置 playground 的主要目的是为了提供给开发者一个交互式的、即时反馈的环境,以更加便捷和直观的方式探索和学习该库的功能。
新建 vue3 项目
1 | bash复制代码mkdir playground |
初始化 vue3 项目
1 | bash复制代码 |
新建 nuxt 项目
1 | bash复制代码 |
引入package/vue核心库
配置 playground/vue3 和 nuxt 项目的 package.json
1 | json复制代码"dependencies": { |
使用 @yi-ui/vue
1 | ts复制代码import { add } from '@yi-ui/vue' |
七、打包构建
- 配置
其实我们在上面配置 package/vue 核心库的时候有添加了一个 build 命令,但是在子项目中 build 不是很方便;
所以为了统一多包管理,需要在根目录的 package.json 下配置一下
1 | json复制代码"scripts": { |
另外,我们还需要额外安装一下 rimraf
,来删除打包的产物 dist 等目录;
1 | bash复制代码pnpm install rimraf -Dw |
rimraf
:一个在 Node.js 环境中常用的 npm 包,用于递归删除文件和文件夹。其名称来源于 “rm -rf” 命令,这是在 Unix/Linux 系统中用于递归删除文件和文件夹的命令。
2.build 打包
1 | bash复制代码pnpm build |
八、发布 & 安装使用
- 登录 npm(按照提示输入用户名密码邮箱即可)
1 | bash复制代码npm login |
注意:
- 如果发布的
npm
包名为:@xxx/yyy
格式,需要先在npm
注册名为:xxx 的organization
,否则会出现提交不成功;- 发布到
npm group
时默认为private
,所以我们需要手动在每个packages
子包中的package.json
中添加如下配置;"publishConfig": { "access": "public" },
- 安装
changesets
因为我们的项目是一个 monorepo 多包项目,所以我们使用普通的办法显然不能了;
那么这时候搭配 pnpm workspace 的工具 changesets
就出现了
1. 安装 changesets
1 | css复制代码pnpm i @changesets/cli -Dw |
2. 初始化 changesets
1 | csharp复制代码pnpm changeset init |
3. 完成后项目会出现一个.changeset
的文件夹
1 | lua复制代码|-- my-project |
4. 配置 .changeset/config.json
1 | json复制代码{ |
5. 配置 package.json
的发布脚本
1 | json复制代码{ |
3.发布
1. 随便修改 package/vue
下 src/index.ts
的代码
2. 按照顺序执行
- 第一步:
pnpm changeset
+ 这里会让你去选择版本号、还有发版说明等等
- 第二步:
pnpm vp
+ 生成对应的md文档
至此就会在子包中生成你每次发布版本的 md 文档说明了,如下图:
3. 运行 pnpm release
的最终发布
Tips:
playground
和docs
目录下的包需要在package.json
中设置"private": true
,否则每次pnpm release
会把队友的包 `publish 至 npm,从而导致 release 失败。
4.安装使用
安装:
1 | bash复制代码pnpm install @yi-ui/vue |
使用:
1 | ts复制代码import { add } from '@yi-ui/vue' |
总结
其实上述的流程,只是一个很基本的搭建,还有更详细配置,例如文档、单元测试等等配置其实不止上述这一点,因为要和核心库做深度绑定;
但是为了不显得文章臃肿,咱们只是一笔带过的间接了解下其最基本的配置。
当然我们不可能就这样抛弃了,所以接下来的文章,将会实现一个最基本无头组件,以及如何耦合单元测试、文档等等。
Headless UI 往期相关文章:
感谢大家的支持,码字实在不易,其中如若有错误,望指出,如果您觉得文章不错,记得 点赞关注加收藏
哦 ~
关注我,带您一起搞前端 ~
本文转载自: 掘金