1.组件库目标
首先,明确一波这次搭建的组件库的构建目标,是一个基于vue3+typescript的组件库。
2.项目初始化
首先使用vite 创建一个vue3,ts的项目
yarn create vite my-ui --template vue-ts
创建完毕后的目录如下
接下来,我们增加一些用于组件库的文件目录
编写一个组件Hello
// packages/components/Hello/index.vue
<template>
<h1>Hello {{ msg }}!</h1>
</template>
<script setup lang="ts">
defineProps<{ msg: string }>()
</script>
<script lang="ts">
// output component name
export default {
name: 'Hello'
}
</script>
为了让组件库既允许全局调用,也可以局部调用,我们需要为每一个组件定义一个VuePlugin的引用方式
import Hello from './index.vue'
Hello.install = function(Vue: any) {
Vue.component(Hello.name, Hello)
}
export default Hello
这下Hello组件就完成了,接下来就是在component主入口输出该组件
import Hello from './Hello';
const components = {
Hello,
};
const install = function (Vue: any) {
Object.values(components).forEach((component) => {
console.log(component);
Vue.component(component.name, component);
});
};
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export { default as Hello } from './Hello';
export default { install };
到这里,Hello组件的编写和导出就完成了。接下来我们尝试一下使用全局注册的方式来进行组件的使用。
这时候我们回到src/main.ts进行组件注册
import { createApp } from 'vue'
import App from './App.vue'
import MyUI from '../packages/components'
createApp(App).use(MyUI).mount('#app')
在app.vue使用Hello查看效果
<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
</script>
<template>
<Hello msg="world" />
</template>
组件库打包
这里我们可以参考vite的build:lib
首先在根目录增加一个script文件夹,创建一个lib.config.ts文件
import { defineConfig } from 'vite';
import path from 'path';
import vue from '@vitejs/plugin-vue';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
],
build: {
lib: {
entry: path.resolve(__dirname, '../packages/components/index.ts'),
name: 'my-ui',
fileName: (format: string) => `my-ui.${format}.js`,
},
rollupOptions: {
external: Object.keys(require('../package.json').peerDependencies),
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue',
},
},
},
},
});
修改package.json
{
"name": "my-ui",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"build:lib": "vite build --config ./script/lib.config.ts"
},
"devDependencies": {
"vue": "^3.2.25",
"@types/node": "^17.0.5",
"@vitejs/plugin-vue": "^2.0.0",
"typescript": "^4.4.4",
"vite": "^2.7.2",
"vue-tsc": "^0.29.8"
},
"peerDependencies": {
"vue": ">=3.2.25"
},
"files": [
"dist"
],
"main": "./dist/my-ui.umd.js",
"module": "./dist/my-ui.es.js",
"exports": {
".": {
"import": "./dist/my-ui.es.js",
"require": "./dist/my-ui.umd.js"
}
}
}
执行
yarn run build:lib
我们可以得到如下结果
这里会有一个问题,我们打包出来的库没有声明文件。
这时候可以用一个vite-plugin-dts来生成*.d.ts文件,接下来更改lib.config.ts文件
+ import dts from 'vite-plugin-dts';
plugins: [
vue(),
+ dts({
+ include: [
+ 'packages/**/*.ts',
+ 'packages/**/*.d.ts',
+ 'packages/**/*.tsx',
+ 'packages/**/*.vue',
+ ],
+ }),
],
接下来在package.json文件中配置types
{
"types": "./dist/packages/components/index.d.ts",
}
最后就是npm发布,这个我就不多赘述了。。
大功告成!有点累,下次再讲怎么实现组件库文档和预览效果。