browserify.js 的模块加载

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,还能按需加载模块的项目。

原文地址:https://www.cnblogs.com/jasonxuli/p/5070926.html