1.webpack的核心原理css
一切皆模块:在webpack中,css,html.js,静态资源文件等均可以视做模块;便于管理,利于重复利用;html
按需加载:进行代码分割,实现按需加载。node
2.
webpack
模块化原理:以js
为例,分析webpack
构建common.js
的模块化方式。webpack
①构建示例代码web
//b.js let b =3 export {b}; //a.js let b = require('./b.js') let a = b+123; //webpack.config.js let path = require("path") module.exports = { entry: './a.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'build')}, module: { loaders: [{ test: /\.js$/, loader: 'babel-loader', query: { presets: ['es2015']}}}}
②分析bundle.js
缓存
a.总体结构:整个bundle.js
整个是一个执行函数,传进去的参数是一个个的模块,也是一个的函数,经过函数的做用于达到模块化的效果。babel
(function (modules) {………………})([ //模块初始化 function (module, exports, __webpack_require__) { /* 模块a.js的代码 */}, function (module, exports, __webpack_require__) { /* 模块b.js的代码 */}]);
b.模块初始化闭包
//1.定义一个模块缓存的容器 var installedModules = {}; //2.webpack的require实现 function __webpack_require__(moduleId) {//传参是模块ID //3.判断模块是否缓存,如果缓存了就不用加载,直接返还这个已缓存的模块 if(installedModules[moduleId]) { return installedModules[moduleId].exports;} // 4.如果没有被缓存,则缓存这个模块 var module = installedModules[moduleId] = { i: moduleId, //模块ID l: false, //标识模块是否加载 exports: {} }; //5.执行模块函数,modules表明一系列的模块函数,要动态绑定module.exports,绑定this;能够交叉连续引用。 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // 6.标记模块已经被加载 module.l = true; // 7.返回该模块的exports return module.exports;} //8.require第一个 模块 return __webpack_require__(0); }
c.模块函数模块化
//a.js模块 function(module, exports, __webpack_require__) { "use strict"; var b = __webpack_require__(1);//重复调用 var a = b + 123;} //b.js模块 function(module, exports, __webpack_require__) { "use strict"; var b = 3; exports.b = b;}
d.下面是执行的流程图,指定一个初始模块,全部被引用的模块会响应的循环加载。函数
ps
几个小问题
1.在模块加载的时候,最后传递的一个参数是__webpack_require__
,是全局定义的函数,为何是全局的呢,由于自执行函数的this
指向全局。
2.commond.js
须要注意模块导出的问题
①exports
不能直接赋值,无用,由于源码中返回的是module.exports
;
②能够在exports
上增长属性,好比exports.fn=
;这样module.exports
会变化,最终导出的是module.exports
也会变化;
//node.js部分源码,node也是经过闭包实现模块的隔离 (function(exports,module,require,__dirname,__filename){ this = module.exports //this是指向module.exports的 module.exports = exports = {} return module.exports})()