browserify
1.1、browserify简介
是什么 ?:a command-line tool that converts Node.js code to regular browser JavaScript code.
开发语言:Node.js
官方主页:http://browserify.org
源码仓库:https://github.com/browserify/browserify

Node.js流行起来以后,很多人都开始为Node.js编写模块, 随着编写的模块愈来越多,人们想把这些为Node.js开发的模块也能让它运行在Web浏览器中。Web浏览器Node.js都是JavaScript Runtime, 在ES6 Module出现之前,他们之间最大的不同是模块系统的不同,JavaScript没有官方统一的模块系统,这就导致了在不同的JavaScript Runtime之间的代码难以共用。

为了解决这个问题,我们有两种办法可以实现:

  • 使用UMD规范。
  • 使用browserify这个工具,把为Node.js开发的模块进行一个转换。

这两种办法中,使用UMD规范不够优雅, 我们还得记住这种奇怪的写法。而使用browserify这个工具转换这个非常容易。

1.2、通过包管理器安装browserify
包管理器安装命令
npmnpm install -g browserify
yarnyarn global add browserify
1.3、browserify命令

示例:

browserify xx.js  > yy.js
browserify xx.js -o yy.js
1.4、browserify到底做了什么?

假设,我们已经写好了两个Node.js的模块ABB模块引用了A模块。

A模块的代码如下:

module.exports = 'A';

B模块的代码如下:

var a = require('./A');
console.log(a);

现在,我们使用browserify命令做转换,如下:

browserify B.js > bundle.js

现在A.jsB.js两个文件中的代码都被打包进bundle.js中了, 这个bundle.js就可以在Web浏览器中运行了。

这是不是很神奇?浏览器环境中可没有modulemodule.exportsrequire这些的? 它是怎么执行的呢?要了解这个神奇的做法,就得看看转换后的bundle.js文件的内容,为了便于观看,我做了格式化,如下:

(function () {
    function r(e, n, t) {
        function o(i, f) {
            if (!n[i]) {
                if (!e[i]) {
                    var c = "function" == typeof require && require;
                    if (!f && c)return c(i, !0);
                    if (u)return u(i, !0);
                    var a = new Error("Cannot find module '" + i + "'");
                    throw a.code = "MODULE_NOT_FOUND", a
                }
                var p = n[i] = {exports: {}};
                e[i][0].call(p.exports, function (r) {
                    var n = e[i][1][r];
                    return o(n || r)
                }, p, p.exports, r, e, n, t)
            }
            return n[i].exports
        }

        for (var u = "function" == typeof require && require, i = 0; i < t.length; i++)o(t[i]);
        return o
    }

    return r
})()({
    1: [function (require, module, exports) {
        module.exports = 'A';
    }, {}],
    2: [function (require, module, exports) {
        var a = require('./A');
        console.log(a);
    }, {"./A": 1}]
}, {}, [2]);

生成的bundle.js文件写的有点绕,这主要是利用了JavaScript中的立即执行函数和函数可以且套定义的特点。 总的来说,它干了两件事情:

1、创造了moduleexportsmodule.exports对象、require函数,使得语法上不会出现错误了。

2、将每个模块的代码都放到function (require, module, exports) {}函数块中,并给这些模块标号。 所以,遇到require函数调用,就被替换为function (require, module, exports) {}函数调用了。