zoukankan      html  css  js  c++  java
  • requireJS的学习

    官方文档 http://www.requirejs.cn/

    参考链接 http://www.w3cschool.cc/w3cnote/requirejs-tutorial-1.html http://www.ruanyifeng.com/blog/2012/11/require_js.html

    http://www.zhihu.com/question/20351507

    进入主题:

    一 前奏, 让我们看一下为什么引入requireJs

    JS不是一种模块化编程语言,因此呢,我们用一堆函数去实现具有特定功能的模块

    function f1(){ //... }

    function f2(){ //.... }

    这是我们新手或者传统的做法,但是会有很多问题啦,首先,这么多函数变量,很明显污染了全局变量,说不定会和其他模块中的变量冲突呢。其次,他们之前的关系很不明确,js严格的读取顺序,多个文件互相依赖,依赖性最小的文件必须放在最前面,否则代码会报错。最后,多个js加载,若采用同步模式,无疑会影响浏览器的性能。

    ① 对于前者,我们有采用多层命名空间的嵌套,把模块定义为对象,这样新的命名空间解决了冲突问题

    var mod = new Object({ a:0; f1:function(){} f2:function(){} });

    这个做法不是很好,因为对象里面的属性我们可以随意更改,不安全

    然后有了立即执行函数的方法

    var mod = (function(){ a:0; var f1=function(){} var f2=function(){} return{ f1:f1; f2:f2; } })();

    关于模块的知识 请看http://www.ruanyifeng.com/blog/2012/10/javascript_module.html

    ②相互依赖的关系,我想文档记录和注释起到很大作用,但是还是很不明显啊,当出现下面的加载情况,晕菜了
     
    <script type="text/javascript" src="a.js"></script>
    <script type="text/javascript" src="b.js"></script>
    <script type="text/javascript" src="c.js"></script>
    <script type="text/javascript" src="d.js"></script>

    ③看一下加载对网页性能的影响

    index.html
    
    <!DOCTYPE html>
    <html>
        <head>
            <script type="text/javascript" src="a.js"></script>
        </head>
        <body>
          <span>body</span>
        </body>
    </html>
    
    a.is
    (function(){
        function fun1(){
          alert("it works");
        }
    
        fun1();
    })()
     
    执行的时候,html内容是一片空白的,即body并未被显示,当点击确定后,才出现,这就是JS阻塞浏览器渲染导致的结果。
     
    二 进入主题 规范 无规矩无以成方圆
     想写模块,考虑可拓展性,我们必须采用一种公用的规则,方便自己管理,方便他人使用。
    目前有CMD和AMD CMD通用模块定义规范详见https://github.com/seajs/seajs/issues/242 
    AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。 
    具体区别借知乎上的讨论 AMD 规范在这里:https://github.com/amdjs/amdjs-api/wiki/AMD CMD 
    规范在这里:https://github.com/seajs/seajs/issues/242 
    AMD 规范在这里:https://github.com/amdjs/amdjs-api/wiki/AMD
    CMD 规范在这里:https://github.com/seajs/seajs/issues/242

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

    这些规范的目的都是为了 JavaScript 的模块化开发,特别是在浏览器端的。
    目前这些规范的实现都能达成浏览器端模块化开发的目的

    区别:

    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 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。
    3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹
    4. 还有一些细节差异,具体看这个规范的定义就好,就不多说了。
     
     借一位网友的评论,我个人感觉requirejs更科学,所有依赖的模块要先执行好。如果A模块依赖B。当执行A中的某个操doSomething()后,再去依赖执行B模块require('B');如果B模块出错了,doSomething的操作如何回滚? 很多语言中的import, include, useing都是先将导入的类或者模块执行好。如果被导入的模块都有问题,有错误,执行当前模块有何意义? 
    加之周围人所在公司用的是requireJs, 因此我也就专心看AMD的requireJS 
     
    三 看看requireJS怎么写模块 
    实现js文件的异步加载,防止js加载阻塞页面渲染 
    使用程序调用的方式加载js,增强了模块之间的依赖,便于代码编写和可阅读性
    看下例子,把刚刚的例子拿出来,用requireJs写一下 
    index.html
    index.html
    <!DOCTYPE html>
    <html>
        <head>
            <script type="text/javascript" src="require.js"></script>
            <script type="text/javascript">
                require(["a"]);
            </script>
        </head>
        <body>
          <span>body</span>
        </body>
    </html>
    
    
    a.js
    define(function(){
        function fun1(){
          alert("it works");
        }
    
        fun1();
    })
     
    很明显,异步带来的好处,个人理解 异步就是开启多线程模式
     
     RequireJS是一个Javascript 文件和模块框架,可以从 http://requirejs.org/下载,如果你使用Visual Studio也可以通过Nuget获取。它支持浏览器和像node.js之类的服务器环境。使用RequireJS,你可以顺序读取仅需要相关依赖模块。 RequireJS所做的是,在你使用script标签加载你所定义的依赖时,将这些依赖通过head.appendChild()函数来加载他们。当依赖加载以后,RequireJS计算出模块定义的顺序,并按正确的顺序进行调用。这意味着你需要做的仅仅是使用一个“根”来读取你需要的所有功能,然后剩下的事情只需要交给RequireJS就行了。为了正确的使用这些功能,你定义的所有模块都需要使用RequireJS的API,否者它不会像期望的那样工作。
     ① requireJs的加载
     
    <script src="js/require.js" defer async="true" ></script>(IE支持defer 没有async)
    <script src="js/require.js" data-main="js/main"></script> (入口模块main.js) 
     
    ② 模块的编写
     RequireJS API 存在于RequireJS载入时创建的命名空间requirejs下。
    其主要API主要是下面三个函数:
     define– 该函数用户创建模块。每个模块拥有一个唯一的模块ID,它被用于RequireJS的运行时函数,define函数是一个全局函数,不需要使用requirejs命名空间. 
    define(['myLib'], function(myLib){ // define([依赖的模块],定义模块)
        function foo(){
          myLib.doSomething();
        }
        return {
          foo : foo
        };
      });
    require– 该函数用于读取依赖。同样它是一个全局函数,不需要使用requirejs命名空间. 
     
    require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){// require([依赖的模块], 定义函数
            // some code here
      });
    config– 该函数用于配置RequireJS.   

     

    require.config({
        paths: {
          "jquery": "lib/jquery.min",
          "underscore": "lib/underscore.min",
          "backbone": "lib/backbone.min"
        }
      });
     看一下例子:
     
    index.html
    <html>
    <head>
    <title>hi test!</title>
    </head>
    <body>
    <p>p1</p>
    <p>p2</p>
    <script type="text/javascript" src="a.js"></script>
    <script src="js/require.js" data-main="js/main" defer async="true" ></script>
    </body>
    </html>
    
    main.js  
    
      // main.js
    require.config({
        paths: {
          "math": "math"
        }
      });
      require(['math'], function (math){
        alert(math.add(1,1));
      });
    
    
     math.js   
    
      // math.js
      define(function (){
        var add = function (x,y){
          return x+y;
        };
        return {
          add: add
        };
      });
  • 相关阅读:
    重新进入学习模式
    第八章 函数
    第七章 用户输入和while语句
    第6章 字典
    第五章 if语句
    对前四章方法、函数、语句的总结
    完成四个章节的学习,我觉得有必要花一天的时间对各章节内的函数、方法、语句进行总结。明后天不再对新章节进行学习。
    第四章 操作列表
    第三章 列表简介
    C语言数据结构-折半查找
  • 原文地址:https://www.cnblogs.com/hhjiang14/p/4334600.html
Copyright © 2011-2022 走看看