场景
比如我们新建一个src > jquery-ui.js
,里面这样写:
export function ui() {
$('body').css('background','pink')
}
问题:
然后在src > index.js
引入这个ui方法,并且调用一次,看起来应该是可以实现ui里面的逻辑的,我们重新打包一下,这次我们直接使用开发环境的打包npm run dev
,发现控制台报错,说在jquery-ui中找不到这个$的定义,为什么?
重新审视:
webpack在第一篇就说明了它的定义,他是一个模块打包工具,他会将index.js
和jquery-ui.js
看成是两个不同的模块进行打包,又因为模块是有自身的作用域的,一般模块间是不能相互去干涉影响的耦合问题,这也是webpack的特性让问题能快速准确的找到对应的根源,所以对于打包jquery-ui.js
的时候,是不会使用index.js
模块里面的jquery的,所以报错,那我们怎么解决这个问题呢?
shimming
优化:
针对上面的问题,我们当然可以直接在jquery-ui.js
上面引入jquery库,虽然可以正确执行,但是如果这是一个插件库的话,你就不能随便加上这些另外的第三方库,那我们此时就需要使用webpack提供的shimming的跨模块的功能 ↓
webpack.common.js:
我们使用webpack提供的插件ProvidePlugin
完成这个功能,将变量$变成具有跨模块的功能,当webpack打包发现某模块中存在该变量并且没有对应导入,就会自动识别进行底层导入处理
// + 新增
const webpack = require('webpack');
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CleanWebpackPlugin(),
new webpack.ProvidePlugin({
$: 'jquery'
})
],
配置完成后,此时重新打包一下npm run dev
,发现没有报错了;配置很简单,只要你提出需要进行跨模块的变量对应配置第三方模块引入即可
来个shimming的实践demo
此时我们可以将src >jquery-ui.js
删除掉,清空src > index.js
的代码,我们来实现一个让各自模块的this指向window
首先我们看看index.js
里打印一下this,看看模块中this的指向是什么:
发现他是指向当前模块对象,那如果我想让其指向全局window怎么处理 ↓
安装imports-loader:
npm install imports-loader -D
配置webpack.common.js:
rules: [{
test: /\.js$/,
exclude: /node_modules/,
// + 新增更改
use: [{
loader: 'babel-loader'
},{
loader: 'imports-loader?this=>window'
}],
// loader: 'babel-loader', // - 注释
},
思路:
引入多个loader要使用use,然后我们在检测js结尾的文件进行打包先使用 imports-loader
更改当前文件的模块全局指向为window,在进行babel-loader进行编译打包
结果:
配置完成之后,我们重新打包npm run dev
,发现此时控制台输出的是这样的,说明已经改变了模块的全局指向:
总结与建议:
但是webpack是不建议使用全局变量!webpack背后的整个概念是允许更多的模块化前端开发。这意味着编写包含良好且不依赖于隐藏依赖关系的孤立模块(例如全局变量)。请仅在必要时使用这些功能
结语
还有很多有关shimming跨模块的技巧实例,具体可以去文档或者社区深入进行探讨:
https://webpack.js.org/guides/shimming/
之前讲到的几篇中都在 这里 可以阅读,建议去阅读英文官方文档,那里的内容比较全面,中文文档还存在部分内容没有翻译过来的,如果英文能力可以建议阅读 英文文档,如果英语不太好的话可以借助工具去阅读~
#下一篇【使用环境变量重新修改打包配置文件~】