一、shimming(垫片的定义):
1、先举一个简单的例子
现在有两个JS文件:
//一个index.js,内容如下
import _ from 'lodash';
import $ from 'jquery';
import {ui} from './jquery-ui';
ui();
/**其他业务代码*/
//一个我们模仿的第三方模块jqurey-ui.js文件:
import $ from 'jquery';
export function ui() {
$('body').css('background', 'red');
}
两个文件的关系:jqurey-ui.js是一个第三方模块,jqurey-ui.js模块依赖于jQuery,
但是这个模块中并没有导入jQuery;我们在index.js中导入了这个模块,
并且在index.js中我们还引入了lodash模块和jquery模块;
此时,我们去执行导入的UI函数可以运行吗?
答案是不可以执行,会报错,这是因为前段模块化存在变量隔离的原因,
在index.js中导入的jQuery并不能在jquery-ui.js中生效;
也就是本模块导入的变量、类、函数,只在本模块生效,不会对导入模块生效;
2、针对上面的情况,我们需要解决导入的模块缺少jQuery依赖的问题,怎么解决哪?
(1)我们可以手动在第三方模块中导入依赖模块,但是好像不现实,因为一般这些模块都是在node_modules中的,我们手动更改第三方模块,可能会导致一些问题,这个方案抛弃;
(2)现在我们已经知道,这个模块缺少jQuery依赖,我们想的是怎么样才能方便安全的把jQuery导入到这个模块中去,那么能否在webpack打包的时候,让webpack帮我们添加哪?这个思路貌似可行,webpack也给我们提供了这么一个插件:webpack.ProvidePlugin插件;
3、webpack.ProvidePlugin插件的简单使用:
// 在webpack.common.js中使用webpack.ProvidePlugin插件
// 1、引入webpack
const webpack = require('webpack');
// 2、在插件的配置节点 plugins中配置插件
plugins: [new HtmlWebpackPlugin({
template: './src/index.html'
}), new CleanWebpackPlugin(), new webpack.ProvidePlugin({
'$': 'jquery',
})],
插件的配置意义:webpack.ProvidePlugin插件的意思是,
当webpack运行或者打包的时候发现一个模块中有用到 $ 这个字符串的时候,
webpack就会自动帮我们在该模块中引入jQuery,并且以 $ 符号命名,其实也就是在后台帮我们做了这样的引入:
import $ from 'jquery';
4、总结以上三点的shimming(垫片)的一个用法:垫片就是通过webpack的ProvidePlugin插件,帮我们在第三方模块中自动的添加该第三方模块需要的或者我们想要的东西;
二、使用imports-loader实现垫片:
1、首先,一个JS模块中的this指向的模块自身这个前置小知识点,现在我们想让整个模块中的this都指向window,我们不可能一个一个的去改变指向吧?也不能手动去向模块注入吧?最好的办法就是让webpack帮助我们实现;
2、imports-loader的使用:
(1)安装imports-loader:npm install imports-loader --save-dev;
(2)配置:
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: "babel-loader" },
{
loader: "imports-loader? ",
options: "this=>window"
}
],
}
注意:我们在给loader添加配置参数时,
老版webpack支持:loader:'imports-loader?this=>window'方式,
但是新版的webpack必须将参数配置在options中,否则会报错;
当webpack处理JS文件时,会首先将JS文件交给imports-loader处理,
JS模块中的this指向window,然后再交给babel-loader处理;
最后总结一下shimming(垫片):思想就是通过webpack向模块中注入全局性的变量,类,函数等;