使用Rollup打包Vue组件库

2,389 阅读2分钟

在之前的一篇文章中提到了封装Vue组件库的方法,包括webpackage和vue-cli的方法。

但是这两个方法都有缺点:

  • 无法打包ES模块
  • 无法生成Typescript类型声明文件
  • 生成包体积大

所以我决定重新研究下用rollup开发和打包vue组件库(Vue@3,Typescript,SCSS)的方法。

Rollup相比webpack更擅长打包库,它的配置也相对简单。我们先直接奉上配置文件:

import Path from 'path'
import { getBabelOutputPlugin } from '@rollup/plugin-babel'
import RollupPluginNodeResolve from '@rollup/plugin-node-resolve'
import RollupPluginCommonjs from '@rollup/plugin-commonjs'
import RollupPluginTypescript2 from 'rollup-plugin-typescript2'
import RollupPluginVue from 'rollup-plugin-vue'
import RollupPluginPostcss from 'rollup-plugin-postcss'
import RollupPluginDelete from 'rollup-plugin-delete'
import Autoprefixer from 'autoprefixer'
import PackageJson from './package.json'

export default [
  {
    input: 'src/index.ts',
    external: Object.keys(PackageJson.dependencies || {}),
    plugins: [
      RollupPluginDelete({
        targets: Path.resolve(__dirname, 'dist/*'),
        watch: true
      }),
      RollupPluginVue({
        css: false
      }),
      RollupPluginPostcss({ extract: true, plugins: [Autoprefixer] }),
      RollupPluginTypescript2(),
      RollupPluginNodeResolve(),
      RollupPluginCommonjs(),
      getBabelOutputPlugin({ configFile: Path.resolve(__dirname, 'babel.config.js') })
    ],
    output: {
      file: PackageJson.module,
      format: 'esm',
      sourcemap: true
    }
  }
]

处理文件

不同格式的文件需要不同的rollup插件处理:

  • rollup-plugin-vue:处理vue文件
  • RollupPluginPostcss:处理scss和css文件
  • RollupPluginTypescript2:处理ts文件和vue文件中的<script lang="ts">

抽取CSS

一个组件库通常会把CSS代码抽取到一个文件中,配置rollup-plugin-vuerollup-plugin-postcss即可实现:

RollupPluginVue({ css: false })
RollupPluginPostcss({ extract: true, plugins: [Autoprefixer] })

babel

由于ts文件会被rollup-plugin-typescript2处理,我们需要把处理后的代码再由babel处理,这里使用@rollup/plugin-babel提供的getBabelOutputPlugin方法,而不是直接使用这个插件:

RollupPluginCommonjs()
getBabelOutputPlugin({ configFile: Path.resolve(__dirname, 'babel.config.js') })

需要注意的是,getBabelOutputPlugin依赖@rollup/plugin-commonjs插件且需要放在其后。

babel的配置按照常规即可,比如:

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        modules: false,
        useBuiltIns: 'usage',
        corejs: 3,
        targets: {
          browsers: ['> 1%', 'last 2 versions', 'not dead']
        }
      }
    ]
  ],
  plugins: [
    [
      '@babel/plugin-transform-runtime',
      {
        corejs: 3
      }
    ]
  ]
}

Typescript类型声明(.d.ts)文件

Rollup官方的@rollup/plugin-typescript插件存在问题,即使在tsconfig.json中设置了"declaration": true也不会生成声明文件,因此我们使用第三方开发的rollup-plugin-typescript2插件。

依赖

组件库通常不包含常用的依赖(比如vue),设置external排除即可。

{
  external: Object.keys(PackageJson.dependencies || {})
}