webpack模块化原理简析
1.webpack的核心原理
一切皆模块:在webpack中,css,html.js,静态资源文件等都可以视作模块;便于管理,利于重复利用;
按需加载:进行代码分割,实现按需加载。
2.
webpack
模块化原理:以js
为例,分析webpack
构建common.js
的模块化方式。
-
①构建示例代码
//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
整个是一个执行函数,传进去的参数是一个个的模块,也是一个的函数,通过函数的作用于达到模块化的效果。(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})()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。