如何开发一个Vue组件库

发布于: 6/14/2022 阅读大约需要3分钟

前置条件

  1. Vue 基础知识
  2. TypeScript 基础及配置(Vue3、TS项目必备)
  3. 打包器相关知识(如Rollup、Gulp、Webpack)
  4. 语义化版本知识
  5. 知道如何发布与维护一个npm包

🎊 开始

项目结构

先参考各组件库发布物项目结构
image.png
可以看出这些成熟的组件库都将打包产物分为了 lib, es, dist 这三类文件夹, 分别对应 umd, es, 与CDN引用方式.
那么参考一个成熟的组件库架构进行开发学习是一个不错的方法, 下面我们就参考 Element-Plus项目结构来搭建自己的组件库.

技术栈

我们通常可以从以下方面来考虑我们项目具体需要安装的开发依赖

  1. 构建工具
  2. 打包处理
  3. 库类型及包管理工具
  4. CI/CD
  5. 单元测试
  6. 开发预览
  7. 开发语言
  8. 样式预处理库
  9. 工具库
  10. 代码规范*
  11. 文档生成*
  12. 个人其他技术喜好

首先,我们根据我们想要构建的组件库的大致功能以及库大小来决定整个库的项目结构及形式.
目前, vuetifyelement-plus均使用 monorepo仓库来维护代码,而 and-design-vue则使用传统的 multirepo的形式,所以我们可以拥抱新技术选择 monorepo结构来进行开发。
组件库使用 monorepo的好处在于其可以在一个仓库中同时维护组件库及其文档,又可以进行独立部署与发布。 所以我们可以选择以下方式来搭建一个 monorepo的组件库

  • yarn workspace + lerna
  • pnpm workspace + changesets

其次, 构建工具的选择, 目前可供选择的构建工具比较多, 比如

  • webpack
  • vite
  • rollup
  • gulp

因为开发组件的时候通常需要预览项目,所以vite可以算是开发vue组件的必须项了,同时由于组件库可能涉及多个工作流程(比如项目构建、单元测试、类型生成、静态资源处理、文件目录调整等),需要一个单独的打包脚本来处理这些任务。 而 gulp又很适合自动化工作流这类工作, 所以通常会搭配使用gulp来进行打包操作。
当然,熟悉 rollup或者 webpack 的同学也可以直接使用 rollupwebpack
同时,我们还需要TypeScript相关的库来对 Vue SFC 进行编译

  • vue-tsc
  • vue
  • @vitejs/plugin-vue-jsx
  • @vitejs/plugin-vue

然后,再根据我们所熟悉的样式预处理器来安装样式相关依赖

  • less + less-loader
  • sass + sass-loader
  • postcss + autoprefixer

代码规范方面我们可以选择 eslint + prettier + stylelint,提交规范以及变更日志可以选择 “
时间处理库方面我们有以下几种选择

  • dayjs
  • momentjs
  • datefn

如果还需要一些便捷的开发工具库还可以补充安装以下依赖

  • vue-use: Vue 工具库
  • lodash: 常用js库
  • async-validator: 表单验证库

两个插件
unplugin-vue-components
用来自动帮你引用你组件中依赖的其他组件,且支持TS.
目前知名的组件库都有用到该插件, 比如 Ant Design Vue, Element Plus, Vuetify
比如

<template>
  <div>
    <HelloWorld msg="Hello Vue 3.0 + Vite" />
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

将会自动帮你转换为下面代码

<template>
  <div>
    <HelloWorld msg="Hello Vue 3.0 + Vite" />
  </div>
</template>

<script>
import HelloWorld from './src/components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

unplugin-auto-import
支持TS, 自动按需引用API, 由 unplugin 驱动.
比如,使用该插件前,我们的写法

import { computed, ref } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)

使用插件后:

const count = ref(0)
const doubled = computed(() => count.value * 2)