webpack打包之Library打包

什么是“Library”?

所谓Library即“库”,比如我们使用的lodash就是一个“函数库”,比如我们的常用的'antd'、'elementUI'这些就属于“组件库”,在实际的工作中,我们很有可能去封装自己的函数库或者是UI组件库或者是基于某个开源库做二次封装的业务组件库,那么我们怎么针对“库”进行打包的呢?

环境准备

创建一个名为'library'的文件夹,执行npm init -y,初始化一个npm环境。生成的package.json如下:

{
  "name": "library", // 库的名字
  "version": "1.0.0", // 库的版本
  "description": "", // 库的描述
  "main": "index.js", // 入口
  "scripts": { // npm指令
    "test": "echo \"Error: no test specified\" && exit 1" // 可以删掉,创建我们自己的指令
  },
  "keywords": [],
  "author": "yourname", // 库的作者
  "license": "ISC" // 协议,可以改成‘MIT’开源协议
}

在根目录下创建如下文件目录

|--src
  |--math.js
  |--string.js
  |--index.js 

其中内容如下

math.js

export function add (a, b) {
    return a+b
}
export function minus (a, b) {
    return a-b
}
export function multiply (a, b) {
    return a*b
}
export function division (a, b) {
    return a/b
}

string.js

export function join(a, b) {
    return a + ' ' + b
}

index.js

import * as math from './math'
import * as string from './string'
export default { math, string }

上面的代码中,我们就简单的实现了一个自己的库,其中包括加减乘除的数字运算和字符串的拼接,实际上,一个库的开发,就类似于一个业务系统,他也是需要被打包才能被使用,所以我们还需要webpack对其进行打包。

安装webpack并创建webpack.config.js配置文件

yarn add webpack webpack-cli -S

webpack.config.js

const path = require('path')

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.js'
    }
}

package.json中增加打包指令

"scripts": {
    "build": "webpack"
}

执行打包后,在根目录'dist'文件夹下生成了一个'library.js'的文件,如果是对于我们平常的业务代码,到这一步,我们已经完成了,但是我们是开发一个库的代码,是要给别人用的,别人用的形式可能是下面这样的

import library from 'library' // ESM

const library = require('library') // commonJs

于是我们在配置文件中加入一个配置项如下

module.exports = {
  output: {
    libraryTarget: 'umd'
  }
}

意思是,无论你使用什么样的引入方式,我们打包出来的库都支持。有时候我们还有可能是通过script标签进行引入的

<script src='library.js'></script>
// 在使用的时候,通过library这样的全局变量来使用,就像jquery那样

那么我们还需要在配置项中加入下面的配置

module.exports = {
  output: {
    library: 'library' // 名字随便取,代表我们全局暴露的变量
  }
}

关于libraryTarget和library的配置关系

实际上,在做library打包的时候是,libraryTargetlibrary是有一定的关系的,需要配合使用

  • library作为核心,代表要生成一个全局变量
  • libraryTarget意思是这个全局变量挂在哪里,如果是umd,那么二者是没有关系的,如果是this,就代表我们的库不再支持AMD,commonJS,esm等模块形式,而是将全局变量注入到全局的this上面。其中libraryTarget可以取值umdthiswindowglobal(nodeJs下)等值,一般我们在封装一个库的时候,会选择umd

在Library中使用第三方库

有时候,我们在封装自己的库的时候,不是所有的方法都自己写的,我们也会去引用一些第三方的组件库或者函数库,比如在上面的例子中,我们做下面的代码变更
// string.js
import _ from 'lodash'
export function join(a, b) {
    return _.join([a,b], ' ')
}
这时候打包,也是能正常打包的,但是,library文件却比之前大了很多,这是因为我们打包进了lodash这个库,但是用户在使用我们的库的时候,可能在业务代码中也会引入lodash这个库,这个时候,打包的代码,很可能就会打包出两份lodash,从而中造成一些问题,为了解决这个问题,我们需要这样去配置
module.exports = {
  externals: ['lodash']
}

做了上面配置后,我们发现,我的库打包后又变小了。

posted @ 2022-06-26 19:48  李小菜丶  阅读(757)  评论(0编辑  收藏  举报