rollup 打造vue业务组件库

665 阅读3分钟

rollup 打造vue业务组件库

rollup

Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。

为什么选用rollup作为打包工具

对比项目中常用的webpack来讲rollup具有下列优势

  1. 配置较webpack简单很多
  2. 支持打es包,webpack也可以,但是配置繁琐
  3. 更好的支持tree-shaking
  4. 包体积较小

但是相对于webpack来说,rollup在处理静态资源方面没有webpack那么强大,但是我们现在打包的是组件库,不会设计到太多静态资源的处理,以及为了减少组件库包的体积,我们选用rollup作为打包工具

搭建组件库

搭建项目

用vue-cli创建一个项目,这样方便我们之后的组件调试预览

vue create xxx-ui && cd xxx-ui

建好项目后,在项目中安装rollup打包工具

yarn add rollup -D

在项目中新建rollup.config.js来做rollup的打包配置

打包配置

首先介绍几个插件

  1. rollup-plugin-vue 解析vue文件
  2. @rollup/plugin-commonjs 转化第三方库es => commonjs
  3. @rollup/plugin-node-resolve 查找外部模块
  4. rollup-plugin-terser rollup压缩代码插件
  5. @rollup/plugin-babel rollup babel处理

更多rollup插件请点击rollup插件

rollup打包配置如下

import vue from 'rollup-plugin-vue'
import commonJs from '@rollup/plugin-commonjs'
import babel from '@rollup/plugin-babel'
import { terser } from 'rollup-plugin-terser'
import image from '@rollup/plugin-image'
import resolve from '@rollup/plugin-node-resolve'
import json from '@rollup/plugin-json'
export default {
  input: './packages/index.js',
  output: {
    format: 'es',
    file: './dist/index.es.js'
  },
  plugins: [
    json(),
    resolve(),
    commonJs(),
    vue(),
    babel({
      exclude: 'node_modules/**',
      extensions: ['.js', '.vue'],
      babelHelpers: 'runtime'
    }),
    image(),
    terser()
  ]
}

组件编写

在项目根目录增加packages文件夹,对应打包入口文件。在该文件夹下写组件

vue.use源码

export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

从源码可以看出,vue的组件注册可以通过两种方式,一种是插件是一个对象,里面包含install方法,另一种是组件本身就是一个方法,当执行vue.use()的时候,会根据插件的类型来做出对应的处理

packages中新建index.js,并新建一个button文件夹用来写测试组件

index文件内容为

import Button from './Button/index.vue'

const components = [Button]

const install = function (Vue) {
  // 判断是否安装
  if (install.installed) return
  // 遍历注册全局组件
  components.map(component => Vue.component(component.name, component))
}

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue)
}

export default {
  // 导出的对象必须具有 install,才能被 Vue.use() 方法安装
  install,
  // 以下是具体的组件列表
  Button,
}

button文件夹中新增index.vue

<template>
  <div>
    <button>
      <slot>确认</slot>
    </button>
  </div>
</template>

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

这样我们的测试组件已经写完了,接下来打包测试下

测试组件

package.json中修改scripts,我们的这个项目只是作为测试组件用,所以不需要进行打包,将打包命令改为rollup打包组件库

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "rollup -c -w",
    "lint": "vue-cli-service lint",
  },
}

src/main.js中引入组件库

import xui from './dist/index.es.js'

Vue.use(xui)

新建一个测试页面

<template>
  <div class="home">
    <a-button>测试</a-button>
  </div>
</template>

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

执行yarn serve,打开浏览器可以看到,页面上出现一个名为测试的按钮,一个简单的组件库就搭建完成了。