browserify的模块加载基本上和nodejs的类似:
nodejs 的模块加载是依次去读取文件然后用一个类eval() 函数执行并返回module.exports的结果。为了避免循环加载,在加载模块文件之前就在模块缓存中做了设置,使得循环加载中的回路中断。
比较起来,browserify的模块加载分两步,第一步需要在命令行中执行browserify module1.js module2.js module3.js > bundle.js,这会将所有模块聚合到bundle.js中,并生成一个依赖结构。
下面是bundle.js代码,多数被缩减的变量名我已经用含义较明确的词做了替换:
1 (function e(t, cache, indexArray) { 2 function s(i, u) { 3 if (!cache[i]) { 4 if (!t[i]) { // when? !moduleIndex==false ? 5 var req2 = typeof require == "function" && require; 6 if (!u && req2)return req2(i, !0); 7 if (req)return req(i, !0); 8 var f = new Error("Cannot find module '" + i + "'"); 9 throw f.code = "MODULE_NOT_FOUND", f 10 } 11 var modu = cache[i] = {exports: {}}; // set it to cache first to avoid loop loading. 12 t[i][0].call( 13 modu.exports, 14 function (path) { // the real "require" function. 15 var moduleIndex = t[i][1][path]; 16 return s(moduleIndex ? moduleIndex : path) // use s() to check cache first. 17 }, 18 modu, // pass module 19 modu.exports, // pase module.exports 20 e, 21 t, 22 cache, 23 indexArray 24 ) 25 } 26 return cache[i].exports 27 } 28 29 var req = typeof require == "function" && require; 30 for (var i = 0; i < indexArray.length; i++) // load module one by one. 31 s(indexArray[i]); 32 return s 33 })({ 34 1 : [ 35 function (require, module, exports) { 36 var test2 = require('./module2.js'); 37 var test3 = require('./module3.js'); 38 39 var test1 = function () { 40 test2(); 41 } 42 }, 43 {"./module2.js": 2, "./module3.js": 3} 44 ], 45 2: [ 46 function (require, module, exports) { 47 var test3 = require('./module3.js'); 48 49 var test2 = function () { 50 } 51 52 module.exports = test2; 53 }, 54 {"./module3.js": 3} 55 ], 56 3 : [ 57 function (require, module, exports) { 58 var test3 = function () { 59 } 60 61 module.exports = test3; 62 }, 63 {} 64 ] 65 }, 66 {}, // module cache 67 [1, 2, 3] // indexArray 68 );
和nodejs比较起来,browserify把文件加载和依赖关系生成放到了 bundle.js的产生阶段。在bundle.js真正的执行阶段,只需要依次执行依赖结构中的模块实体就好了。
比起首页中大量的<script>标签,browserify使得模块的依赖关系变得清晰,各个模块有自己的变量空间,全局空间不会受到污染。
但同步加载、不能动态按需加载是个缺点。
下面转向WebPack,据说可以替代Gulp,还能按需加载模块的项目。