Shimming 预置依赖
webpack compiler 能够识别遵循 ES2015 模块语法、CommonJS 或 AMD 规范编写的模块。然而,一些 third party(第三方库) 可能会引用一些全局依赖(例如 jQuery 中的 $)。因此这些 library 也可能会创建一些需要导出的全局变量。这些 “broken modules(不符合规范的模块)” 就是 shimming(预置依赖) 发挥作用的地方。
Warning
我们不推荐使用全局依赖!webpack 背后的整个理念是使前端开发更加模块化。也就是说,需要编写具有良好的封闭性(well contained)、不依赖于隐含依赖(例如,全局变量)的彼此隔离的模块。请只在必要的时候才使用这些特性。
假设我们现在在index.js中引用了这样的模块:
index.js:
import $ from 'jquery'
import _ from 'lodash'
import { ui } from './ui'
ui()
const dom = $('<div>')
dom.html(_.join(['Niall','August'],'-'))
$('body').append(dom)
ui.js:
export function ui(){
$('body').css('background',_.join(['green'],''))
}
ui.js的作用就是将body
的背景颜色设置为green
,但是在ui.js中需要用到jquery的$
和lodash的_
,这种情况下,虽然webpack可以打包index.js,但是这个ui.js却并不能发挥它的作用,控制台会报以下错误:
解决方法:
为webpack提供预置依赖:
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// new BundleAnalyzerPlugin(),
new webpack.ProvidePlugin({
_: 'lodash',
$: 'jquery'
})
],
这里_: 'lodash'
让ProvidePlugin在打包一个文件时,如果发现了该文件中使用到了_
,那么就会向其中注入var _ = require('lodash')'
。
其实还有一种写法:
如果我们想在项目中随处使用_.join()
,那么我们可以这样写:
new webpack.ProvidePlugin({
_join: ['lodash','join'],
$: 'jquery'
})
这里的join: ['lodash','join']
会让ProvidePlugin向使用了join
的文件中注入:
var _join = require('lodash').join
ui.js:
export function ui(){
$('body').css('background',_join(['green'],''))
}
这样就能达到我们想要的效果了。
更多关于shimming的应用可以查看webpack官方说明。