前端出现了模块化,所以使得我们可以将前端的功能划分为一个一个的小模块,通过模块之间的相互引用来实现功能;这样的好处就是代码会更加容易阅读和维护;
但是浏览器是没有模块化的概念的,浏览器只能执行原始的js文件,不会做模块化的处理,因此webpack的出现主要是为了解决这个问题,当然它还可以解决其他的问题(浏览器的兼容,代码的转译等等)
webpack会默认以src/index作为入口文件进行文件之间的依赖关系分析,将所有的js文件(也就是一个一个的小模块)打包为一个js文件,同时还要避免命名冲入的问题;
webpack的模块加载实现思路大概是这样的:
例如文件index.js中引入了a.js模块
var a = require('./a.js')
console.log(a)
a.js
module.exports = 'a'
webpack从index.js入口文件进行打包编译之后输出一个main.js文件
(function (modules){
var moduleExports = {} // 模块结果缓存
// require函数的执行会返回一个模块的结果
function __webpack_require(moduleId){
// 判断有无缓存,如果有该模块的缓存,直接读取
if(moduleId){
return moduleExports[moduleId]
}
// 如果没有模块的缓存
var func = modules[moduleId] // 获取模块函数
var module = {
exports:{}
}
func(module, module.exports, __webpack_require); // 执行模块函数
var result = module.exports; // 获取导出结果
moduleExports[moduleId] = result // 将导出结果缓存
return result; // 返回导出结果
}
// 执行入口模块,并得到模块的导出结果
return __webpack_require('./src/index.js')
})({
'./src/a.js': function (module, exports){ // 每个模块文件以一个函数的形式进行传递,这样的好处就是避免的命名冲突;
eval("module.exports = \"a\";\n ")
},
'./src/index.js': function (module, exports, __webpack_require){
eval("var a = __webpack_require(\"./src/a.js\")\n")
}
})