使用 Webpack4.0 打包组件库并发布到 npm

6,523 阅读3分钟

本文将会介绍如何将自己写的组件库打包成第三方库,发布到 npm 上,同时支持在原生 js / React/ Vue 下使用。Webpack4 的升级指南可以参考下 Webpack4.0 升级配置,本文不做赘述。

本文首发于 www.lvdawei.com/post/pack-a…

使用 Webpack4.0 打包

// src/index.js
exports default function Tree() {
    console.log('Hello Tree')
}

假设我们有上面的 index.js 文件,我们想要把打它打包成一个 tree.js 和一个 tree.min.js 包,并且我希望我既可以通过 <script src="../dist/tree.js"></script> 直接 new Tree() ,又可以通过 import Tree from 'tree'let Tree = require('tree') 引入,怎么做呢?这就要使用 Webpack 来处理了。

Webpack 不仅可以打包 React / Vue 相关的项目工程,也可以单独打包 js 组件。先来看下入口与出口的配置:

module.exports = {
  //...
  mode: "none",
  entry: {
    tree: "./src/index.js",
    "tree.min": "./src/index.js"
  },
  output: {
    filename: "[name].js",
    libraryExport: "default",
    library: "Tree",
    libraryTarget: "umd"
  }
  //...
};

mode

Webpack4.0 会在默认情况下开启 mode=production,这会无差别的压缩我们的 tree.jstree.min.js,这不是我们想要的,禁用它。

entry

entry 里面我们配置两个入口 tree"tree.min",让 webpack 可以打包出两个文件,我们可以针对两个入口做不同的处理。

output

outputfilename 表示打包出来文件名叫什么。libraryExport=default 表示打包出来的组件直接对外暴露 default 属性,否则我们调用的时候需要 new Tree.default(),这不是我们希望的调用方式。library=Tree 表示对外暴露的组件叫什么,如果这个地方修改成了 library=Bar,那我们调用的时候就是 new Bar()libraryTarget=umd 表示采用 UMD (Universal Module Definition) 的方式打包 js,同时支持在 CommonJS、AMD 和全局变量使用。

optimization

怎么对 tree.min.js 压缩,但不对 tree.js 压缩呢?请看下面的配置部分:

// ...
  optimization: {
        minimize: true,
        minimizer: [
            new UglifyJSPlugin({
                include: /\.min\.js$/,
            }),
        ],
    },
// ...

通过 include 设置只压缩 min.js 结尾的文件,是不是很简单。这样我们就得到了 dist/tree.min.jsdist/tree.js 两个文件。下面我们开始发布代码到 npm。

发布组件库到 npm 上

发布之前

发布之前,还有件事需要做,在项目根目录新建 index.js,添加内容

if (process.env.NODE_ENV === "production") {
  module.exports = require("./dist/tree.min.js");
} else {
  module.exports = require("./dist/tree.js");
}

修改 package.jsonmainindex.js,指定我们通过 import / require 的时候入口文件位置。

注册 npm

想要发布代码到 npm 上,需要先注册一个账号,你可以直接打开官网注册,这里我们选择更 cooooool 的方式注册。

npm adduser

依次输入 Username、Password、Email 完成注册。

登录 npm

注册好账号之后需要在 Terminal 上登录 npm,在 Terminal 中直接注册的同学就不需用登录了。

npm login

输入 Username、Password、Email 完成登录。

发布到 npm

npm publish

发布的包名就是你的 package.jsonnameversion。有冲突的话需要换一个哦。

最后

本文其实是笔者近期在开源的一个树形选择控件 @widgetjs/tree 摸索出来的打包经验总结。为了简化配置,突出重点,省略了一些生产环境需要添加的较为繁琐的细节,正式的生产模式配置可以在 github 上找到,也欢迎使用,多多提出意见。