合并
webpack 模块化中的各个模块的代码不会污染全局
webpack在打包时通过入口文件将所有需要加载的模块合并到一个js文件中,把每一个模块的代码放到函数中,通过函数作用域的方式解决模块化中的代码污染全局。
// a.js
console.log('module a');
module.exports.a = '123'
console.log(this); // module.export
// 入口文件 index.js
console.log('index module');
var { a } = require('./a');
console.log(a);
合并之后生成的模块,key是模块的路径,value是一个函数,函数中是该模块的代码
// module
{
'./src/index.js': function (module, exports, require) {
console.log('index module');
var { a } = require('./a');
console.log(a);
},
'./src/a.js': function (module, exports, require) {
console.log('module a');
module.exports.a = 'a';
console.log(this); // module.export
},
}
执行
webpack会将代码放到立即执行函数中执行(避免全局污染),重写了require函数=__webpack_require。
代码会先执行__webpack_require 加载入口文件的函数并执行,这个函数相当于运行一个模块,并得到模块的导出结果。将函数所需要的参数都是提前定义好的变量和函数,最后将该模块导出的数据返回,返回的模块数据会返回到require执行的位置。
(function (modules) {
// __webpack_require 函数相当于运行一个模块,得到模块的导出结果。
function __webpack_require(moduleId) {
var func = modules[moduleId]; // 得到该模块对应的函数
var module = {
exports: {}
};
func.call(module.exports, module, module.exports, __webpack_require);
return module.exports;
}
__webpack_require('./src/index.js'); // __webpack_require 函数相当于运行一个模块,得到模块的导出结果。
})({
'./src/index.js': function (module, exports, require) {
console.log('index module');
var { a } = require('./src/a.js'); // {a: 'a'} 这里会调用__webpack_require 并返回这个模块导出的结果
console.log(a);
},
'./src/a.js': function (module, exports, require) {
console.log('module a');
module.exports.a = 'a';
console.log(this); // module.export
},
});
缓存
webpack同一个模块只会加载一边,不会被反复加载执行,所以需要缓存加载过的模块
moduleExports用于缓存加载过的模块导出的数据,判断如果当前模块被加载过,则返回当前这个模块缓存的数据,否则继续执行,并会在执行结束后缓存这个模块的导出结果
// 完整代码
(function (modules) {
var moduleExports = {}; //用于缓存模块的导出结果
// __webpack_require 函数相当于运行一个模块,得到模块的导出结果。
function __webpack_require(moduleId) {
if(moduleExports[moduleId]) {
return moduleExports[moduleId];
}
var func = modules[moduleId]; // 得到该模块对应的函数
var module = {
exports: {}
};
func.call(module.exports, module, module.exports, __webpack_require);
moduleExports[moduleId] = module.exports;
return module.exports;
}
__webpack_require('./src/index.js'); // __webpack_require 函数相当于运行一个模块,得到模块的导出结果。
})({
'./src/index.js': function (module, exports, require) {
console.log('index module');
var { a } = require('./src/a.js');
console.log(a);
},
'./src/a.js': function (module, exports, require) {
console.log('module a');
module.exports.a = 'a';
console.log(this); // module.export
},
});