Appearance
这篇文章想要做什么
介绍如何使用vue3和vite构建组件库,它能在vue3和非vue3框架中使用,并且无需多套代码和额外的心智成本。
为什么要做这件事
在我们的项目中,我们使用了vue3和vue2两种框架,我们希望能够在两种框架中使用一套组件库,而不是维护两套组件库。
如何做到
在构建过程中我们需要两套vite配置,以下以vite.config.js和vite.vue.config.js为例,来构建包含vue3包的组件库提供给非vue3的框架使用,构建不包含vue包的组件库提供给vue3框架使用。
vite.config.js
js
build: {
minify: false,
outDir: resolve(__dirname, 'lib/global/dist'),
lib: {
formats: ['es', 'cjs'],
entry: resolve(__dirname, 'lib/index.ts'),
name: 'index',
fileName: 'index'
}
}
vite.vue.config.js
js
build: {
minify: false,
outDir: resolve(__dirname, 'lib/vue/dist'),
lib: {
formats: ['es', 'cjs'],
entry: resolve(__dirname, 'lib/vue-entry.ts'),
name: 'index',
fileName: 'index'
},
rollupOptions:{
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue',
}
}
}
}
构建的产物
这时候我们在dist文件夹下就有vue
和global
两个产物,区别在于是否包含vue3的库文件,导出的产物也有所不同。
配置package.json
为了支持多入口文件,我们需要添加exports;为了避免typescript在使用package/vue
时报错,我们需要加上typesVersions
的定义,你也可以参考这边回答
json
{
"name": "your package name here",
"version": "1.0.0",
"files": [
"global",
"vue"
],
"main": "./global/dist/index.js",
"exports": {
".": "./global/dist/index.mjs",
"./style": "./global/dist/style.css",
"./vue": "./vue/dist/index.mjs",
"./vue/style": "./vue/dist/style.css"
},
"scripts": {
"pre-release": "npm version prerelease && npm publish --tag beta",
"patch": "npm version patch && npm publish",
"minor": "npm version minor && npm publish",
"major": "npm version major && npm publish"
},
"private": false,
"author": "author name here",
"license": "ISC"
}
在项目中使用
js
import VueCom from 'package/vue'
import renderOutput from 'package'
优化的方向
添加单元测试
使用vitest
和@vue/test-utils
进行单元测试
类型支持
由于缺少类型文件,所以在typescript中使用不是很友好,我们可以使用vite-plugin-dts
生成vue组件的类型文件
js
// vite.config.js
plugins: [
dts({
// 构建使用的tsconfig,不包含测试的ts文件
tsConfigFilePath: resolve(__dirname, './tsconfig.lib.json'),
// 类型文件生成的文件目录
outputDir: resolve(__dirname, `${dist}/types`),
})
]
json
// package.json
{
...
"typesVersions": {
"*": {
"vue": [
"./vue/types/lib/vue-entry.d.ts"
]
}
},
"types": "./global/types/lib/index.d.ts",
...
}
总结
根据以上的配置,我们可以搭建一套基本的库文件开发体系,发布后的库可以在js/ts、vue3/非vue3框架中使用。其中类型文件和区分环境的产物无需额外的适配工作,我们只需要关注功能的开发即可。