Vue组件库开发总结

29次阅读

共计 2713 个字符,预计需要花费 7 分钟才能阅读完成。

Vue 组件库开发总结

由于工作需要,最近在学习怎么开发一个 Vue 组件库。主要需要实现以下点:
1. 组件使用 npm 包引入
2. 实现按需引入及按需打包
项目中许多实现是参考的 element-ui,特别是 webpack 打包部分

组织项目

项目生成

项目生成是直接用的 vue-cli,在根目录下增加了一个 index.js,用于组件打包的入口文件, 两个 webpack 打包文件,以及一个组件的 json 文件,用于之后的按需引入的打包。组件放置在 src/cmps 中,目录结构如下图:

组件结构

由于我的组件把样式都写在了 vue 里面,所以没有单独的样式文件,就是一个 Vue 文件和一个 js 入口文件

组件编写

单个组件编写

vue 组件的编写需要按照官方的 vue 插件开发规范来。为了实现后续的按需打包,在每一组件的入口文件中,都需要定义 install 方法,并随组件一同暴露出来

import Button from './index.vue'
Button.intall = function (vue) {vue.component(Button.name, Button)
}
export default Button

所有组件输出编写

所有组件的输出就是将所有组件暴露出去,并加上一个对所有组件的 install 方法。其中 if(window && window.Vue) install(window.Vue) 是用来实现 script 标签引入的方式的。

import Input from 'src/cmps/input/index.js'
import Toast from 'src/cmps/toast/index.js'
import Button from 'src/cmps/button/index.js'

const cmps = [
  Input,
  Toast,
  Button
]

const install = vue => {
  cmps.map(cmp => {vue.component(cmp.name, cmp)
  })
}
if(window && window.Vue) install(window.Vue)

export default {
  install,
  Input,
  Toast,
  Button
}

组件打包

全量加载的打包

全量加载的打包首先是把 vue-cli 生成的 webpack 文件改一下打包的出入口文件和路径就行了。为了方便之后的按需加载的打包,出口文件我的路径放在了 lib 目录下。
为了实现 npm 包、script 标签等引入形式,libraryTarget 选择了 umd 模式。library 是 npm 包引入时的名称。entry 的写法是我为了用 dev 在本地测试组件是否可用而写的。externals 是为了去除在组件库和实际项目中会重复的库,比如 vue

entry: ENV == 'dev'? path.resolve(__dirname, './src/main.js'): path.resolve(__dirname, './index.js'),
output: {path: path.resolve(__dirname, './lib'),
  publicPath: '/dist/',
  filename: 'input-ui.js',
  library: 'input-ui',
  libraryExport: 'default',
  libraryTarget: 'umd'
},
externals: {vue: 'vue'}

package.json 中需要加入对主入口的说明

"main": "lib/input-ui.js"

按需加载的打包

按需加载的打包主要是参考了 element-ui 的代码。需要对每个组件单独打包,以及对所有组件全量打包。其实我没有明白这里的全量打包和上面说的量加载的全量打包有什么区别。好像是 libraryTarget 不一样,element-ui 中,全量打包的主入口文件的 libraryTarget 是 commonjs2,而按需打包中的主入口文件的 libraryTarget 是 umd。我这里的 libraryTarget 是随便写的,因为我其实并不需要用到采用 script 标签的引入方式。
按需加载的打包是将所有组件单独打包,和全量打包的差别也只是出入口的差别。

const entry = require('./comps.json')
module.exports = {
  entry ,
  output: {path: path.resolve(__dirname, './lib'),
    publicPath: '/dist/',
    filename: '[name].js',
    chunkFilename: '[id].js',
    libraryTarget: 'commonjs2'
  },

comps.json

{
  "input": "./src/cmps/input",
  "toast": "./src/cmps/toast",
  "button": "./src/cmps/button"
}

按需打包的使用

要使用按需打包,不仅组件库的打包需要做处理,项目中也需要做处理。通过上面的方式打包的组件库,在项目中可以使用 babel-plugin-component 来实现按需打包。
在.babelrc 中加入这个组件。libraryName 是需要按需打包的库名。由于我的简陋的组件中,没有引用单独的样式,所以 style 设成了 false,不然在引用组件时,还需要获取一个样式文件。之前提到为了方便按需打包,所以打包后的目录是 lib,这是由于 babel-plugin-component 默认的库的目录就是 lib,如果需要修改目录只需要加入 "libDir": "lib" 具体的 babel-plugin-component 的使用可以官方的 readme。

"plugins": [["component", {
  "libraryName": "input-ui",
  "style": false
}]]

然后就可以在项目中使用按需引入的方式来使用组件了

import {Input, Button} from 'input-ui'
Vue.component(Input.name, Input)
Vue.component(Button.name, Button)

npm 包发布

首先需要在 npm 官网注册账号。npmjs.com
然后添加用户 npm adduser 填入账号密码及邮箱。
通过 npm publish 发布包就行了。如果遇到报错说没有权限发布该包,基本上是因为这个包名已被使用。换个其他的名字就行了。而且每次发布包都需要修改版本号,不同发布两个相同的版本号。

最后

这是本人第一次写文章,而且本人水平有限,对 webpack 的打包,其实并不是很了解,所以写的有些乱,甚至可能有些错误,请大家及时指出,感谢。gitHub

正文完
 0