zoukankan      html  css  js  c++  java
  • js模块加载之AMD和CMD

    当我写这篇文章的时候,sea.js已经逐渐退出历史的舞台,详细链接。不过任何新事物的出现都是对旧事物的取其精华,去其糟粕,所以了解一下以前模块的加载也是一件好事。

    js模块化的原因自不比多说,看看HUX同学的js模块加载七日谈就知道了,将的非常详细。

    一 .CMD模块加载规范

         一个js文件就是一个模块,定义如下:define(factory);

      factory可以使一个函数,一个对象,或者一个字符串。

      1.factory是一个函数

      define(function(require,exports,module){

        var a = reuire('./a');//执行到此处时模块a同步下载并且执行,这个就是和AMD模式的不同之处

        a.dosomething();

        exports.foo = function(){};

      });

      或者

      define(function(require,exports,module){

        var a = reuire('./a');//执行到此处时模块a同步下载并且执行,这个就是和AMD模式的不同之处

        a.dosomething();

        return {

              foo:function(){}

            }

      });

      另外,在require方法中还有一个异步加载方式:

      require.async('./b',function(b){

        b.dosomething();

      });

      这里b模块异步加载,对于那些不是需要及时调用的模块可以考虑。

      2.factory是一个对象,字符串的时候表示该模块的接口就死该对象。

      define({

        name:'leilie',

        say:function(){}

      });或者,

      define("hello ,llei");

      define函数也接受2个以上的参数:

      //id是模块标识符,depends是依赖的模块。

      define(id,[depends],function(require,exports,module){

        //代码

      });

      然而,这种方式的模块定义并不是CMD规范,而是Modules/Transport 规范,也许你也看出来了,既然有了depends参数,为何factory函数还有require,这就是CMD和

      AMD的区别。

      sea.js的用法

      seajs完全遵守CMD规范,可以在官方链接中找到详细的文档。

    二.AMD规范

      玉伯大牛有一个链接将的非常好,介绍了模块的发展。

      AMD也是利用define函数来加载的,具体定义如下:

      define(id,[depends],factory);////id是模块标识符,depends是依赖的模块

      模块标识符

      第一个参数,id,是个字符串,它指的是定义中模块的名字,这个参数是可选的。如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了  该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。

      依赖

      第二个参数,dependencies,是个定义中模块所依赖模块的数组。依赖模块必须根据模块的工厂方法优先级执行,并且执行的结果应该按照依赖数组中的位置顺序以参数的

      依赖的模块名如果是相对的,应该解析为相对定义中模块。换句话来说,相对名解析为相对与模块的名字,并非相对于寻找该模块的名字的路径。

      本规范定义了截然不同的三种特殊的依赖关键字。如果"require","exports", 或 "module"出现在依赖列表中,参数应该按照CommonJS模块规范自由变量去解析。

      依赖参数是可选的,如果忽略此参数,它应该默认为["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。

      工厂方法

      第三个参数,factory,为模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。

      如果工厂方法返回一个值(对象,函数,或任意强制类型转换为true的值),应该为设置为模块的输出值。

    三 二者的不同之处

      define(["require"], function(require) {

         // 在这里,模块 a 已经下载并执行好 //

         var a = require("./a") // 此处仅仅是取模块 a 的 exports,然而,其实你并不想运行a那么这是不合理的

      });

      针对上面的不合理之处,那么直接使用CMD规范不就好了,然而:

    1. 不能直接压缩:require是局部变量,意味着不能直接的通过压缩工具进行压缩,若require这个变量被替换,加载器与自动化工具将无法获取模块的依赖。
    2. 模块书写有额外约定:路径参数不能进行字符串运算,不能使用变量代替,否则加载器与自动化工具无法正确提取路径。

       

  • 相关阅读:
    选择排序——Selection Sort
    Android使用AIDL跨进程通信
    Android Gradle Plugin Version和Gradle Version 对应关系
    error: device unauthorized —— android studio 链接不上虚拟机
    Touch事件传递机制 Android
    Activity生命周期
    Error:Could not determine the class-path for interface com.android.builder.model.AndroidProject.
    Error:fatal: Not a git repository (or any of the parent directories): .git
    Installation failed with message...It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.
    Ajax 学习总结
  • 原文地址:https://www.cnblogs.com/bdbk/p/4906604.html
Copyright © 2011-2022 走看看