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打包的时候是,libraryTarget
和library
是有一定的关系的,需要配合使用
library
作为核心,代表要生成一个全局变量libraryTarget
意思是这个全局变量挂在哪里,如果是umd
,那么二者是没有关系的,如果是this
,就代表我们的库不再支持AMD,commonJS,esm等模块形式,而是将全局变量注入到全局的this上面。其中libraryTarget
可以取值umd
、this
、window
、global
(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']
}
做了上面配置后,我们发现,我的库打包后又变小了。