假设我们现在希望建立一个函数库,其具有math和string两个模块,每个模块包含一些对应的处理函数。
math.js:
export function add (a, b){
return a + b
}
export function minus (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.config.js:
const path = require('path')
module.exports = {
mode: 'production',
entry:{
main: './src/index.js'
},
output:{
filename: 'library.js',
path: path.resolve(__dirname, 'dist')
},
...
}
打包后生成library.js,如果仅仅这样,那么别人在使用我们的库时,只有通过以下方式:
import library from './library'
console.log(library.math.add(1,3))
但是引入一个模块的方式多种多样,限制使用者按照import
来引入是不合适的。所以我们可以更改webpack.config.js:
...
output:{
filename: 'library.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'umd'
}
...
这里添加的配置项是什么意思呢?
libraryTarget 此配置的作用是控制 webpack 打包的内容是如何暴露的。libraryTarget: "umd"
- 这个选项会尝试把库暴露给前使用的模块定义系统,这使其和CommonJS、AMD兼容或者暴露为全局变量。
这个配置往往是和library配合使用的:
...
output:{
filename: 'library.js',
path: path.resolve(__dirname, 'dist'),
library: 'lib',
libraryTarget: 'umd'
}
...
这样配置之后,如果在 HTML 页面中使用script标签引入打包结果文件,那么变量library对应的值(lib
)将会是入口文件(entry file)的返回值:
//index.html
<body>
<script src="./library.js"></script>
<script type="text/javascript">
console.log(lib)
</script>
</body>
现在我们修改库中的string.js:
import _ from 'lodash'
export function join(a, b){
return _.join([a,b],' ')
}
如果用户在使用我们的库时:
import library from 'library'
import _ from 'lodash'
这就会造成lodash重复引入,为了优化此问题,我们可以修改webpack.config.js:
...
externals: [{
lodash: 'lodash'
}]
...
externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer’s environment)中的依赖。
防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。