前言
我们知道,webpack默认只能解析js代码,要想解析其他类型的文件需要用到loader。
比如要打包使用css文件就需要用到css-loader,style-loader,这里我们一起研究下这两个loader的作用。
准备工作
main.css
body{
margin:0 auto;
padding:0 20px;
max-width:800px;
background:#f4f8fb;
}
webpack.config.js
module.exports = {
mode:'none',
entry:'./src/main.css',
output:{
filename:'bundle.js'
},
module:{
rules:[
{
test:/\.css$/,
use:'css-loader'
}
]
}
}
说明:这里用mode:'none’的原因是打包后的代码方便阅读
css-loader
小结:
css-loader只会把css模块加载到JS代码中,并不会使用这个模块
style-loader
加上style-loader的webpack.config.js内容如下
说明:webpack 多个loader的调用顺序是从后往前,而css-loader的作用是生成一个包含css代码的数组,style-loader的作用是使用这个数组,顺序不能颠倒,所以这里的loader引用顺序也不能颠倒
此时打包后的代码如下:
我们可以看到相比之前多了三个模块,这里我们一一探究这四个模块各自起了啥作用
模块1:
function(module,exports,__webpack_require_){
//引入模块2
var api = __webpack_require__(1);
//引入模块3
var content = __webpack_require__(2);
//处理模块3的内容
......
//定义操作选项options
var options = {};
options.insert = "head";
options.singleton = false;
//调用模块2
var update = api(content,options);
//导出模块1(当前模块)
module.exports = content.locals || {};
}
小结:模块1起一个把控全局的作用。模块1将模块2作为方法,模块3作为参数,调用它。下面我们继续探究模块2,3的作用
模块2
function(module, exports, __webpack_require__) {
"use strict";
//定义函数用来判断当前环境是否支持标准全局变量(widow、document)
var isOldIE = ......
//定义函数用来获取html head
var getTarget = .....
//定义数组用来存放即将插入html head中的style样式
var stylesInDom = [];
//定义函数根据标识符在stylesInDom数组中查找对应的索引
function getIndexByIdentifier.....
//定义函数将样式字符串还原成style语法
function modulesToDom.....
//定义函数创建style标签并插入head
function insertStyleElement......
//定义函数移除style标签
function removeStyleElement......
//定义函数处理样式字符串
var replaceText.....
.....
//导出一个函数 调用上面定义好的函数
module.exports = .....
}
小结:模块2定义了一个方法,用来将css模块插入style,最后将style插入head
模块3
function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
//引入模块4
var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);
// Imports
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(false);
// Module
//css字符串存入数组
___CSS_LOADER_EXPORT___.push([module.i, "body{\r\n margin:0 auto;\r\n padding:0 20px;\r\n max-width:800px;\r\n background:#f4f8fb;\r\n}", ""]);
//将包含css字符串数组导出
// Exports
__webpack_exports__["default"] = (___CSS_LOADER_EXPORT___);
}
小结:模块3负责调用模块4并将css字符串加入数组
模块4
function(useSourceMap){
//定义数组存放css内容
var list = [];
//定义函数list转字符串
list.toString.....
.....
}
小结:模块4处理css映射相关逻辑
总结:模块2负责将css字符串还原成有效的css dom,模块3调用模块4(模卡4处理css映射逻辑)以及将css变成字符串并返回,最后在模块1中以模块3的内容为参数调用模块2