一、 Vue 组件库实现
实现一个组件库,需要注意什么
-
了解
package.json里的一些重要属性的意义 -
多使用
peerDependencies和external去避免重复的多打包 -
了解各个工具的用途:
- rollup 打包工具,非常适合打包库 - verdaccio 用来搭建一个 轻量化的私有 npm 库 - yarn workspace 工作区,负责 依赖管理,多包统一执行命令等功能 - changesets 配合工作区,负责 构建,发布,版本管理 等功能 - vuePress 负责笔记展示,生成静态网站,博客类的那种 - vitest 组件单元测试
Vue 文件打包
rollup-plugin-vue 把 vue 文件编译成 js 代码
vue-template-compiler 配合 rollup-plugin-vue 工作
yarn add rollup-plugin-vue vue-template-compiler -D
cross-env 用来配置环境变量
yarn add cross-env -D
"scripts": {
"dev": "cross-env NODE_ENV=development rollup -c -w"
},
npm link 去将组件库临时链接到全局node_modules 中
使用 Volar 插件,来让 Vue3 SFC(单文件组件) 的提示更爽
rollup 配置里,使用 rollup-plugin-typescript2 来支持 Vue3 SFC typescript
// 【注】 原本的 @rollup/plugin-typescript 会导致编译失败,它无法识别 vue3 setup ts
import typescript from 'rollup-plugin-typescript2'
export default [
{
plugins: [
typescript({
outDir: 'dist',
declaration: true,
}),
],
},
]
二、 私库搭建
verdaccio 是一个轻量化的私有 npm 库
# 安装
yarn global add verdaccio
# 启动本地仓库
verdaccio
启动后,程序会自动打印出配置文件地址
info --- Creating default config file in C:\Users\xxx\AppData\Roaming\verdaccio\config.yaml
修改配置文件里的 ip 和端口
# 0.0.0.0 是为了让同局域网的小伙伴可以输入你的 本地ip:4567 来访问。
listen: 0.0.0.0:4567
添加你的用户名,密码,邮箱(npm 官网注册的)
【注】由于不想使用
npm set registry http://0.0.0.0:4567去直接改变registry地址,所以下面全部使用 --registry 的形式。如果你改了registry,那么可以不加
# 使用 npm adduser 添加
npm adduser --registry http://0.0.0.0:4567
# 添加完成后,使用 npm who am i 查询
npm who am i --registry http://0.0.0.0:4567
接下来使用 publish 或者 add 去上传,拉取库包即可
神奇问题
上传了新版本的包,在项目中也重新拉取了新包,但是还是没变化,明明项目里的 node_modules 里的都是最新版本的了……
检查发现是 vite 的问题。 node_modules 里有一个 .vite 的文件, 打开页面时候 http 是会请求这里的文件,而这里的文件并没有实时更新到最新,所以导致了这个问题。
目前只查找到说删除 .vite 然后重新 yarn dev 可以更新,不知道有没有其他命令。
三、 使用 VuePress 创建组件库文档
VuePress 是一个以 Markdown 为中心的静态网站生成器。
1. 安装
yarn add vuepress@next -D
2. 在 package.json 中添加一些 scripts
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
3. 将 node_modules .temp .cache 添加进 .gitignore
VuePress 和 Vue3 项目结合
或许有的人会疑惑 vue3 和 vuepress 之间该怎么共存,是在 vuepress 中写 vue3 还是 vue3 中写 vuepress 呢?答案是共存关系,举个例子其实就是一个项目中有 react 和 vue 两种框架,两种框架运用互相独立,互不影响,只是之间通过打包,让其中一个项目能够直接访问另外一个项目的内容
ui 库一般是由文档展示模块 docs、组件展示模块 example、组件包模块 packages 构成。流程也就是:在 packages 中开发,在 example 中查看,在 docs 中展示。
【注】现已将 example 的内容迁移到 vue-press 根目录下
yarn create vite example --template vue-ts
在 VuePress 的 md 里展示 vue 自定义组件
// /docs/.vuepress/client.js
import { defineClientConfig } from '@vuepress/client'
import { VueButton } from '../../packages/vue-button'
export default defineClientConfig({
enhance({ app, router, siteData }) {
app.component('VueButton', VueButton)
},
})
其他具体的配置文件,可以看看官网 VuePress2
流程
packages 目录里创建组件,并开发打包,可以用 npm link 去临时链接。(目前不适合用这个方法了,还是使用 工作区 的概念,去给他整)
example 项目中去引入 packages 里的组件
docs 中去写 md 文档,里面同样去引入组件
四、 Monorepo 多包管理
monorepo 就是把多个工程放到一个 git 仓库中进行管理,他们可以共享同一套构建流程、代码规范,特别是如果存在模块间的相互引用的情况,查看代码、修改 bug、调试等会更加方便。
本来考虑用 lerna ,结果听说目前不维护了,而且有一个新的更好的替代方案 : Changesets
Changesets 的工作流程:
- 开发者在
Monorepo项目下进行开发,开发完成后,给对应的子项目添加一个changesets文件。项目的维护者后面会通过changesets来消耗掉这些文件并自动修改掉对应包的版本以及生成CHANGELOG文件,最后将对应的包发布出去。
【注】 初始化之后,config.json 文件里有一个 baseBranch 属性,值为你的 分支名。 如果值和你当前的分支名不一致,那么将无法执行一些命令(比如: add)
# 安装
yarn add @changesets/cli
# 初始化
yarn changeset init
# 添加一个changeset, 现在不加 add 也可以了
yarn changeset add
# 消耗changeset生成changelog
yarn changeset version
注,这玩意儿官配是 pnpm ,但你一定要用 yarn ,也是可以的。但是你根目录下的工作区的命名一定也得是 pnpm-workspace.yaml
// pnpm-workspace.yaml
packages: -'packages/*'
changeset 发包流程
- 每次分支工作完成,都需要构建
changeset,再把changesetpush上去
-
yarn changeset add -
选择需要发版的包
-
确定修改版本号(major/minor/patch) major: 主版本号,开发阶段为0 minor: 次版本号,开发阶段包有更改,则修改此版本号 patch: 修改bug则修改此版本号
-
添加发包原因
-
发包前,
git pull确保本地master分支为最新 -
master分支上执行yarn changeset version,会有changeset删除和文件修改,需要确认修改(确定版本号) -
git add .->git commit -m 'release'->git push -
master分支上执行yarn changeset publish开始发包,完成后需要git push --follow-tags打上 tag
changeset 缺陷
- changeset 文件名随机,如果文件多的时候,无法很好的去管理,辨别
踩坑
-
rollup 更新太慢。发现是由于 tsconfig.json 里的这个导致的 "types": [ "element-plus/global" ],
-
在 PnmTable.vue 文件下修改东西更新, rollup 最终生成的 dist 还是老样子, 需要在 rollup.config.js 文件下保存,才有用
-
element-plus 提示问题
tsconfig.json 里添加 "types": ["element-plus/global"] 就行
第一问 和 第二问 归根结底是因为,我使用的是 yarn link 的方式,本地文件有更改,就需要 rollup 打包然后才能在项目中展示, 使用了工作区,那么就可以完美解决这个问题