• Javascript模块规范(CommonJS规范&&AMD规范)



    Javascript模块化编程(AMD&CommonJS)

    前端模块化开发的价值:https://github.com/seajs/seajs/issues/547

    模块的写法

    查看

    AMD规范

    背景一:

    目前,通行的Javascript模块规范共有两种:CommonJSAMD
    在CommonJS中,有一个全局性方法require(),用于加载模块。假定有一个数学模块math.js,就可以像下面这样加载。

    var math = require('math');

    然后,就可以调用模块提供的方法:

    var math = require('math');
    math.add(2,3); // 5

    但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。还是上一节的代码,如果在浏览器中运行,会有一个很大的问题

    var math = require('math');
    math.add(2, 3);

    第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。
    这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。
    因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD(Asynchronous Module Definition)规范诞生的背景。
    AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
    目前,主要有两个Javascript库实现了AMD规范:require.jscurl.js

    背景二:烦琐的文件依赖(https://github.com/seajs/seajs/issues/547)

    基于 util.js,我开始开发 UI 层通用组件,这样项目组同事就不用重复造轮子了。

    其中有一个最被大家喜欢的组件是 dialog.js,使用方式很简单。

    <script src="util.js"></script>
    <script src="dialog.js"></script>
    <script>
      org.CoolSite.Dialog.init({ /* 传入配置 */ });
    </script>

    可是无论我怎么写文档,以及多么郑重地发邮件宣告,时不时总会有同事来询问为什么 dialog.js 有问题。通过一番排查,发现导致错误的原因经常是

    <script src="dialog.js"></script>
    <script>
      org.CoolSite.Dialog.init({ /* 传入配置 */ });
    </script>

    在 dialog.js 前没有引入 util.js,因此 dialog.js 无法正常工作。同样不要以为我上面的故事是虚构的,在我待过的公司里,至今依旧有类似的脚本报错,特别是在各种快速制作的营销页面中。

    使用AMD,只要在dialog里引入util就可以了。

    CommonJS规范和AMD规范的兼容性

    CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。来自
    CommonJS是一种规范,NodeJS是这种规范的实现。CommonJS有很多实现,其中不乏很多大名鼎鼎的项目,比如 说:Apache的CouchDBnode.js等。但这些项目大 部分只实现了CommonJS的部分规范。

    AMD&&CMD&&CommonJS

    著作权归作者所有。
    商业转载请联系作者获得授权,非商业转载请注明出处。
    作者:玉伯
    链接:http://www.zhihu.com/question/20351507/answer/14859415
    来源:知乎

    AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
    CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
    类似的还有 CommonJS Modules/2.0 规范,是 BravoJS 在推广过程中对模块定义的规范化产出。
    还有不少⋯⋯

    区别:

    1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

    2. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:

    // CMD
    define(function(require, exports, module) {
    var a = require('./a')
    a.doSomething()
    // 此处略去 100 行
    var b = require('./b') // 依赖可以就近书写
    b.doSomething()
    // ... 
    })
    
    // AMD 默认推荐的是
    define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
    a.doSomething()
    // 此处略去 100 行
    b.doSomething()
    ...
    }) 

    虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。
     
    Sea.js 通过异步加载模块,这对页面性能非常有益。Sea.js 还提供了 combo、flush 等插件,配合服务端,可以很好地对页面性能进行调优。

    SeaJS是异步加载模块的没错, 但执行模块的顺序也是严格按照模块在代码中出现(require)的顺序。

    Node.js

    Node.js是JavaScript在服务器端的一个运行环境,也是一个工具库,用来与服务器端其他软件互动。它的JavaScript解释器,采用了Google公司的V8引擎。
    教程:http://www.nodebeginner.org/index-zh-cn.html
    http://javascript.ruanyifeng.com/nodejs/basic.html

    MVC框架angularjs&backbone

    http://segmentfault.com/blog/news/1190000000379723
    路由啥的

    requirejs的用法(http://www.requirejs.cn/)

    模块不同于传统的脚本文件,它良好地定义了一个作用域来避免全局名称空间污染。它可以显式地列出其依赖关系,并以函数(定义此模块的那个函数)参数的形式将这些依赖进行注入,而无需引用全局变量。RequireJS的模块是模块模式的一个扩展,其好处是无需全局地引用其他模块。

    RequireJS的模块语法允许它尽快地加载多个模块,虽然加载的顺序不定,但依赖的顺序最终是正确的。同时因为无需创建全局变量,甚至可以做到在同一个页面上同时加载同一模块的不同版本。

    如果模块存在依赖:则第一个参数是依赖的名称数组;第二个参数是函数,在模块的所有依赖加载完毕后,该函数会被调用来定义该模块,因此该模块应该返回一个定义了本模块的object。依赖关系会以参数的形式注入到该函数上,参数列表与依赖名称列表一一对应。

  • 相关阅读:
    leetcode 63 简单题
    leetcode 712
    500 问的数学基础
    转载一份kaggle的特征工程:经纬度、特征构造、转化率
    散度
    在线学习在CTR上应用的综述
    广告的计费方式
    矩阵2范数与向量2范数的关系
    text_CNN笔记
    F1
  • 原文地址:https://www.cnblogs.com/darr/p/4345379.html
Copyright © 2020-2023  润新知