如何开发一个基于 Vue 的 ui 组件库(一)
栏目: JavaScript · 发布时间: 5年前
内容简介:在开发一个 ui 组件库时,肯定需要一边预览 demo,一边修改代码。常见的解决方案是像开发一般项目一样使用文艺一点儿地可能会用到
在开发一个 ui 组件库时,肯定需要一边预览 demo,一边修改代码。
常见的解决方案是像开发一般项目一样使用 webpack-dev-server
预览组件,比如通过 vue-cli
初始化项目,或者自己配置脚本。
文艺一点儿地可能会用到 parcel
来简化 demo 的开发配置(比如 muse-ui
)。
展示文档
作为一个 ui 组件库,也肯定要有自己的组件展示文档。
一般业界常见方案是自己开发展示文档...
但这样会带来一个组件库和文档如何同步的问题。
为何不用 vuepress?
由于 vuepress 支持在 markdown 中插入组件 ,所以我们其实可以很自然地边写文档边开发组件。
从开发步骤上来说,甚至可以先写文档说明,再具体地编写代码实现组件功能。这样一来文档即是预览 demo,与组件开发可以同步更新。
p.s. React 的组件文档可以试试这俩库:
类型声明
在开发和使用过程中如果对于一些对象、方法的参数能够智能提示,岂不美哉?
如何实现呢?
其实就是在相应文件夹中添加组件相关的类型声明( *.d.ts
),并通过 src/index.d.ts
导出。
{ "typings": "src/index.d.ts", } 复制代码
一开始将声明文件都放在 types/
文件夹下,但在实践中觉得还是放在当前文件夹下比较好。一方面有利于维护,另一方面是读取源码时也有类型提示。
如何打包
打包工具
和打包库一样,选了 rollup。
单文件组件
在开发中用不用 *.vue
这样的单文件组件来开发呢?
-
muse-ui
完全不写
<template>
只使用render
函数。 -
iview
、 element
、 vant
使用
.vue
文件,但样式单独写。 -
ant-design-vue
使用
.jsx
文件,样式也单独写。 -
vux
使用带
<style>
的.vue
文件,但在使用时必须用 vux-loader 。 -
cube-ui
使用带
<style>
的.vue
文件,但有一些配置。
讲道理,完全不写 <template>
有点儿麻烦,所以添加了 rollup-plugin-vue
插件用于打包 .vue
文件。
但碰到一个问题:如何打包 <style>
中的样式?
-
首先尝试不写
<style>
,直接在 js 里 import scss 文件。没问题,但是写组件时不直观,同一组件的代码也分散在了两个地方 - 接着尝试配置 rollup-plugin-vue ,碰到一个 source-map 报错的问题。我提了个 issue 。
加载方式
区分场景
为了区分不同的场景使用不同的 js,所以一共打包了三份 js( commonJs
、 es module
、 umd
),以及一份压缩后的 css( dist/tua-ui.css
)。
{ "main": "dist/TuaUI.cjs.js", "module": "dist/TuaUI.es.js", "browser": "dist/TuaUI.umd.js", } 复制代码
完整加载
大部分 ui 库都支持完整加载,和把大象装冰箱一样简单(但 vux 只支持按需加载):
- 引入 js
- 引入 css
- 安装插件
import TuaUI from '@tencent/tua-ui' import '@tencent/tua-ui/dist/tua-ui.css' Vue.use(TuaUI) 复制代码
因缺思厅的是 cube-ui 把基础样式也写成 Vue 插件
,导致按需引入的时候还要单独引入 Style
,emmmmmmmmm...
import { /* eslint-disable no-unused-vars */ Style, // <-- 不写这行按需引入时就没基础样式 Button } from 'cube-ui' 复制代码
按需加载
ui 库若是只能完整加载,显然会打包多余代码。
所以各种库一般都支持按需加载组件,大概分以下几种。
- muse-ui 、 iview 、 ant-design-vue 、 vant 通过 babel-plugin-import 插件实现。
- element 通过 babel-plugin-component (fork 自 babel-plugin-import )插件实现。
- vux 通过自己的 vux-loader 实现。
- cube-ui 通过配置 webpack 实现。
tree-shaking
webpack 其实在打包的时候是支持tree-shaking 的,那么我们能不能直接引用源码实现按需加载呢?
注意源码必须满足 es 模块规范(import、export)。
import { TuaToast } from '@tencent/tua-ui/src/' Vue.use(TuaToast) 复制代码
尝试打包,发现 tree-shaking
并没有起作用,还是打包了所有代码。
sideEffects
其实问题出在没有在 ui 库的 package.json
中声明 sideEffects
属性。
在一个纯粹的 ESM 模块世界中,识别出哪些文件有副作用很简单。然而,我们的项目无法达到这种纯度,所以,此时有必要向 webpack 的 compiler 提供提示哪些代码是“纯粹部分”。 —— 《webpack 文档》
注意:样式部分是有副作用的!即不应该被 tree-shaking
!
若是直接声明 sideEffects
为 false
,那么打包时将不包括样式!所以应该向下面这样配置:
{ "sideEffects": [ "*.sass", "*.scss", "*.css" ], } 复制代码
vuepress 组件样式
用 vuepress 写文档的时候,一般会在 docs/.vuepress/components/
下写一些全局组件。
开发时没啥问题,但是发现一个坑:打包文档时发现组件里的样式 <style>
全丢了。
猜一猜原因是什么?
这口锅就出在上一节的 sideEffects
,详情看这个 issue
。解决方案就是在 sideEffects
里加一条 "*.vue"
即可。
测试数据
下面咱们打包一下安装了 ui 库的项目,看看按需加载的效果怎么样。
-
Origin
- dist/js/chunk-vendors.71ea9e72.js ----- 114.04 kb
-
TuaToast
- dist/js/chunk-vendors.beb8cff5.js ----- 115.03 kb
- dist/css/chunk-vendors.97c93b2d.css ----- 0.79 kb
-
TuaIcon
- dist/js/chunk-vendors.25d8bdbd.js ----- 115.00 kb
- dist/css/chunk-vendors.eab6517c.css ----- 6.46 kb
-
TuaUI
- dist/js/chunk-vendors.6e0e6390.js ----- 117.39 kb
- dist/css/chunk-vendors.7388ba27.css ----- 8.04 kb
总结一下就是:
-
原始项目的 js 打包出来为
114.o4kb
-
只添加
TuaToast
后 js 增加了0.99kb
,css 增加了0.79kb
-
只添加
TuaIcon
后 js 增加了0.96kb
,css 增加了6.46kb
-
添加完整
TuaUI
后 js 增加了3.35kb
,css 增加了8.04kb
可以看出按需加载还是有效果的~
以上 to be continued...
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Serverless 组件开发尝试:全局变量组件和单独部署组件
- UI组件库从1到N开发心得-组件篇
- PJBreedsViewController 组件开发总结
- PJPickerView 组件开发总结
- Vue组件开发
- Laravel 后台开发常用组件
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。