本文示例仓库地址:
https://github.com/liuchenyang0515/Library_pack
当自己写了一个js想让其他业务方引入,但是别人可能有很多种方式引入库文件,所以我们需要满足别人各种可能的引入方式。
可能是ES6 Module
方式导入
import library from 'library';
可能是commonjs
方式导入
const library = require('library');
也可能用amd
语法引入这个库文件
require(['library'], function() {
})
还可能直接用标签引入
<script src="./library.js">script>
来个例子,我们先新建3个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 math from './math'
import string from './string'
export { math, string }
此时我们可以在webpack
配置文件output
里面添加一项属性libraryTarget:'umd'
,这是什么意思呢?
UMD
的全称是Universal Module Definition
,也就是通用模块标准,它的目标是使一个模块能运行在各种环境下,不论是CommonJS
、AMD
、ES6 Module
或者非模块化环境都能正确引入到库文件
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'library.js',
libraryTarget: 'umd'
}
但是如果我想要别人在用标签引入的时候,能在全局访问到这个模块从而访问
math
和string
里面的函数应该怎么做呢?
在output
里面继续添加一项属性library:mylib
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'library.js',
library: 'mylib',
libraryTarget: 'umd'
}
引入这个
js
后发现mylib
是在window
里面的,直接可以打印,如果不配置这个属性library:mylib
,控制台会显示mylib is not defined
安装第三方模块npm i lodash -S
,修改string.js
import _ from 'lodash'
export function join(a, b) {
return _.join([a, b], ' ');
}
此时我的library.js
里面就有了lodash.js
,然而需求方的业务代码可能也有 需要引入lodash
模块,那么他的引入很可能如下
import library from 'library'
import _ from 'lodash'
这样需求方打包我们的代码和lodash
模块代码,这样就打包了2次lodash
,增大了体积。
我们可以这样做在module.exports
里面写上externals: ["lodash
"],代表打包过程需要忽略的库是lodash
。
接着打包看看
明显看得到前面72.8KB变成了1.64KB
但是这样我们打包出的库文件就不能直接用了,这里会依赖lodash
,所以引入library
的时候必须同时引入lodash
了。
import _ from 'lodash'
import library from 'library'
这样既避免了两次lodash
的打包,又能让我们的程序正确运行。
为了方便第三方引入,你可以在写文档的时候注明,引入本js
前必须引入lodash
,然后给一个引入示例,别人就看得懂了