• javascript的模块发展


    谨以此文记录了解js模块的过程

    随着ES6的出现,js模块已经成为正式的标准了。曾经为了解决js模块问题而发展起来的民间秘籍,requireJs(AMD)、SeaJs(CMD)、Node(CommonJs),已经或者不久的将来会成为历史。了解历史也是很重要的,因为正式标准就是以民间秘籍为基础而发展起来的,有些规范仍然被广泛应用于开发中(CommonJS)。再者,进入有些公司,你的工作可能是继承前辈们的代码,为了不至于始终一脸懵,认识一下这些东西是很重要的。

    关于js模块的发展历史

    github上玉伯发表的issue:地址

    CommonJs模块规范

    • 用于同步加载模块
    • 主要应用于服务端

    关于CommonJS的说明:commonjs

    Node参考CommonJS实现了一套模块系统,npm上有大量的CommonJS的包,ECMAScript取代CommonJS可能还需要一些时日。

    CommonJs对模块的定义很简单,主要分为模块引用、模块定义和模块标识。

    模块引用

    使用require()方法,该方法接收模块标识,引入一个模块的API到当前上下文。

    var math = require("math");
    math.add();

    模块定义

    上下文提供exports对象用于导出当前模块的方法或者变量,并且它是唯一导出的出口。module对象,代表模块自身,exports是module的属性。将方法挂载在exports对象上作为属性即可定义导出的方式。

    exports.add = function () {
        var sun = 0,
            i = 0,
            args = arguments,
            l = args.length;
    
        while (i < 1) {
            sum += args[i++];
        }
        return sum;
    }

    模块标识

    模块标识是传递给require()方法的参数,它必须是符合小驼峰命名的字符串,或者以.,..开头的相对路径,或者绝对路径。它可以没有文件名后缀.js。

    优势

    1. 语法简单,只需要定义module.exports属性,剩下的模块代码与标准Javascript无差异。引用模块的方法也很简单,只需要使用require函数
    2. CommonJS是Node.js默认的模板格式,所以我们可以是用成千上万的包

    缺点

    1.  最大的缺点就是不显示的支持浏览器,(浏览器端的javascript不支持module变量和export属性,当然也有方法可以在浏览器中使用CommonJS模块,可以查看这里)由此也产生了另外的用于前端浏览器的规范AMD

    AMD与requireJS

    AMD是CommonJS的一个延伸,制定了能够在前端应用的模块规范。

    • 异步加载模块
    • 主要用于浏览器

    github中AMD的定义——地址

    规范

    // 模块定义
        // id和dependencies都是可选的
        // factory是模块的实际代码
        define(id, dependencies, factory);
    
        define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
            exports.verb = function () {
                return beta.verb();
                //Or:
                return require("beta").verb();
            }
        });
        // 不带id(名称)
        define(["alpha"], function (alpha) {
            return {
                verb: function () {
                    return alpha.verb() + 2;
                }
            };
        });
        // 不带名称和依赖
        define({
            add: function (x, y) {
                return x + y;
            }
        });
    
        // 引用模块
        // module是要加载的模块
        // callback在加载完成之后运行
        require([module], callback)
        require(['a', 'b'], function (a, b) {
            //modules a and b are now available for use.
        });

    优势

    1. 自动处理依赖,无序考虑引入顺序
    2. 异步加载模块,避免阻塞

    requireJS

    requireJS实现了AMD规范,具体使用方法请移步——中文API

    CMD与SeaJS

    CMD是玉伯在学习requireJs的过程中,自己提出的一个规范。SeaJs作为实现该规范的工具,一度成为与requireJs并肩的工具(当然主要是在国内)

    玉伯在2015年宣布Seajs已死。ES2015正式发布了。不再需要民间力量修补这个漏洞了。

    ES6Module

    以上所有规范都是ES6之前产生的,为ES6奠定了基础。ES6汲取了CommonJS和AMD的优点:

    • 与CommonJS类似,语法简单,一个文件是一个模块
    • 与AMD类似,同样支持异步加载模块

    语法

    http://es6.ruanyifeng.com/#docs/module

    总结

    CommonJS规范,语法简单、同步加载、主要应用于服务端。目前在Node中仍然占据重要地位。

    AMD规范,作为CommonJS的延伸,语法略微复杂一些,异步加载,主要应用于浏览器。

    ES6 Module作为javascript内置的模块标准,虽然浏览器目前并不完全支持,但是有Babel等转换器,帮助转换ES6语法到ES5语法,从现在开始学习并应用ES6,也许是比较好的选择。

    参考

    1. js模块发展历史——地址
    2. 知乎上玉伯关于CMD和AMD的区别的回答——地址
    3. require.js——中文官网
    4. 《深入理解es6》
    5. exploringJs——https://exploringjs.com/es6/
  • 相关阅读:
    js- 类数组对象
    js- caller、 callee
    ES6 声明变量的6种方法
    Vue 之 element-ui upload组件的文件类型
    js中call、apply和bind的区别
    Vue 之 Vue.nextTick()
    DocumentFragment --更快捷操作DOM的途径
    Js 编程题汇总
    &#65279
    网站添加变量后变成空白
  • 原文地址:https://www.cnblogs.com/Jamie1032797633/p/11041937.html
Copyright © 2020-2023  润新知