Webpack打包组件库的姿势

最近开发了一个Vue插件,怎样分享受给其它开发者使用?项目A、项目B、项目C都要用到架构组开发的组件库,怎么实现不同项目组之间代码的同步。本文基于Webpack 讨论打包Vue组件库的正确方法。

打包格式

组件库的使用场景五花八门。有时候是直接使用<script>在HTML中直接引入库使用,有时候使用打包工具在编译构建。作为组件库,应该兼容这些使用场景。为了支持多种使用场景,我们需要选择合适的打包格式。常见的打包格式有CMD、AMD、UMD。CMD只能在Node环境执行,AMD只能在浏览器端执行,UMD 同时支持两种执行环境。显然,大多情况下我们应该选择UMD格式。Webpack中在output.libraryTarget中指定输出格式的设置项,其支持的格式有:

  • var: 以一个变量形式输出: var Library = xxx (default);
  • this:以 this 的一个属性输出: this[‘xxx’] = xxx;
  • commonjs:以 exports 的一个属性输出:exports[‘xxx’] = xxx;
  • commonjs2:以 module.exports 形式输出:module.exports = xxx;
  • amd:以AMD格式输出;
  • umd:同时以 AMD、CommonJS2和全局属性形式输出。

以下是webpack.config.js 中output设置的示例:

{
  path: path.resolve(__dirname, './lib'),
  publicPath: '/lib/',
  filename: 'index.js',
  library: ['vueLoading'],
  libraryTarget: 'umd',
  umdNamedDefine: true
}

明白了组件库输出的格式,但如果我们的组件库依赖其它组件库/框架,又该如何打包组件依赖呢?

打包依赖

以Vue为例,它应该是Vue的插件/组件库的外部依赖。组件库的使用者会自行导入Vue,打包的时候,不应该将 Vue打包进组件库。
在Webpack中,我们可以在externals设置Vue作为外部依赖,以避免将Vue重复打包进组件库,相应的设置如下:

externals: {
  vue: 'vue'
}

这意味着你的组件库需要vue依赖,这个依赖在用户的环境中必须存在且可用。

事实上,就这么简单,我们将打包的代码前几行拿出来看看:

(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if(typeof define === 'function' && define.amd)
    define("vueLoading", [], factory);
  else if(typeof exports === 'object')
    exports["vueLoading"] = factory();
  else
    root["vueLoading"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
...

详细示例可参考https://github.com/szriafan/vue-css-loading

注意:
虽然目前Webpack很火,但组件库不能声明只支持Webpack方式使用,忽略了其他选择。其实打包工具并不只有 webpack,还有 browserify、rollup 等。相比这下rollup打包出来的组件库更简洁漂亮。

发表评论

电子邮件地址不会被公开。 必填项已用*标注