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})()