zoukankan      html  css  js  c++  java
  • requirejs笔记

    1.RequireJS是一个工具库,主要用于客户端的模块管理.它可以让客户端的代码分成一个个模块.实现异步或动态加载,从而提高代码的性能和可维护性.它的模块管理遵循AMD规范(Asynchronous Module Definition).
    2.基本思想:通过define方法,将代码定义为一个模块用require方法实现代码的模块加载.

    3.将require.js嵌入网页,然后就能在网页中进行模块化编程了.
    <script data-main="js/main" src="js/require.js"></script>
    data-main属性:页面的入口js.路径main.js相对于页面
    4.define方法:定义模块.(requireJS要求每个独立模块放在一个单独的文件里.)
        4.0:定义模块不依赖其他模块,是个独立模块.
        4.1:定义模块依赖其他模块,非独立模块.
        4.2:三个参数.
        
        独立模块:define({
            method1:function(){},
            method2:function(){}
        })
        或者:
        define(function(){
            return{
                method1:function(){},
                method2:function(){}
            }
        })
        建议使用后一种写法,这种自由度更高一些.
        define定义的模块可以返回任何值,不限于对象.

        非独立模块:
        define(["module1","module2"],function(m1,m2){

        })
        第一个参数是数组,它的成员是当前模块所依赖的模块.
        比如当前模块就是依赖于"module1.js","module2.js".只有先加载这两个模块,新模块才能正常运行.这个写法表示module1和module2模块就在当前目录.等同于['./module1','./module2'].
        第二个参数是一个函数,但前面的数组的所有成员加载成功后,他将被调用.它的参数与数组的成员一一对应.
        define(['module1','module2'],function(m1,m2){
            return {
                method:function(){
                    m1.methodA();
                    m2.methodB();
                }
            }
        });

        如果依赖额模块很多,参数与模块一一对应的写法非常麻烦.
        define(['dep1','dep2','dep3','dep4','dep5','dep6'...],
        function('dep1','dep2','dep3','dep4','dep5','dep6'...){

        });
        为了避免上面代码那样繁琐的写法.可以这样写:
        define(function(require){
            var dep1=require('dep1');
            var dep2=require('dep2');
            var dep3=require('dep3');
            var dep4=require('dep4');
            var dep5=require('dep5');
            var dep6=require('dep6');
            var dep7=require('dep7');
            .........
            .........
        });

        define([模块名称,][依赖模块],function(参数){

        });
        注意:requireJs会自动根据文件名(不含后缀名,即不含.js)来给定义的模块命名,如果你显示的给定义的一个模块命名了,那么在日后改动了文件名或模块名,requireJs将无法加载.因此:不要显示的定义模块名,让文件名成为默认的模块名,方便requireJs管理.

        define()实际运用的例子1:
        define(["math","grap"],function(math,graph){
            return{
                plot:function(x,y){
                    return graph.drawPie(math.randomGrid(x,y));
                }
            }
        });

        define()实际运用的例子2:
            判断是否是IE而加载zepto或jQuery.
        define(('__proto__' in{} ?['zepto']:['jquery']),function($){
        return $;
        });

    5.require方法:调用模块.
        require(['foo','bar'],function(foo,bar){
            foo.doSomething();
        });

        require方法的第一个参数,是一个表示依赖关系的数组.
        require([window.JSON?undefined:'util/json2'],function(JSON){
            JSON=JSON||window.JSON;
            console.log(JSON.parse('{"JSON":"HERE"}'));
        });
        上面代码:加载JSON模块时,首先判断浏览器是否原生支持JSON对象.如果是的,则将undefined传入回调函数,否则加载util目录下的json2模块.
        require方法也可以用在define方法内部.
        define(function(require){
            var otherModule=require("otherModule");
        });
        下面的例子显示了如何动态加载模板.
        define(function(require){
            var isReady=false,foobar;
            require(['foo','bar'],function(foo,bar){
                isReady=true;
                foobar=foo()+bar();
            });

            return{
                isReady:isReady,
                foobar:foobar
            }
        });
        上面代码定义的模块,内部加载了foo和bar两个模块,在没有加载完成前,isReady属性为fale,加载完成后就变成了true.因此,可以根据isReady属性的值,决定下一步的动作.
        下面的例子是模块的输出结果是一个promise对象.
        define(['lib/Deferred'],function(Deferred){
            var defer=new Deferred();
            require(['lib/templates/?index.html','lib/data/?stats'],function(template,data){
                defer.resolve({template:template,data:data});
            });
            return defer.promise();
        });
        上面define方法返回一个promise对象,可以再改对象的then方法,指定下一步的动作.
        如果服务器端采用JSONP模式,则可以直接在require中调用,方法是指定JSONP中调用,方法是指定JSONP的callback参数define.

        require(['http://someapi.com/foo?callback=define'],function(data){
            console.log(data);
        });
        require方法允许添加第三个参数,错误处理的回调函数
        require(["backbone"],
                function(){Backbone}{
                    return Backbone.View.extend(/*.....*/);
                    },
                function(err){
                    //....
                    }
        )

        require对象还允许指定一个全局性的Error事件的监听函数.所有没有被上面的方法捕获的错误,都会被触发这个监听函数.
        requirejs.onError=function(err){
            //...
        }

        ==============AMD模式小结===========
        define和require这两个定义模块,调用模式的方法,合称AMD模式.它的模块定义的方法非常清晰,不会污染全局环境.能够清楚的显示依赖关系.
        AMD模式可以用于浏览器环境,并且允许非同步加载模块,也可以根据需要动态加载模块.

    6.require方法本身也是一个对象,它带有一个config方法,用来配置require.js运行参数.
        require.config({
            paths:{
                jquery:[]
            }
        });

    7.配置require.js:config方法
    require.config({
        paths:{
            jquery:[
                '//cdnjs.cloudflart.com/ajax/libs/jquery/2.0.0/jquery.min.js',
                'lib/jquery'
            ],
            gys:'gys',
            people:'people'
        }
    });

    paths
        :参数指定各个模块的位置.这个位置可以是同一个服务器上的相对位置,也可以是外部网址.可以为每个模块定义多个位置,如果第一个位置加载失败,则加载第二个位置,上面的事例就表示如果cds加载失败,则加载服务器上的备用脚本.注意的是,指定本地路径时,可以省略文件最后的js后缀名.

    require(['jquery'],function($){
        //......
    });

    上面代码加载jquery模块,因为jquery的路径已经在paths参数中定义了,所以就会到事先设定的位置下载.

    baseUrl:
        baseUrl参数指定本地模块位置的基准目录,即本地模块的路径是相对于哪个目录的.该属性通常有require.js加载时的data-main属性指定.
    shim:
        有些库不是AMD兼容的,这时就需要指定shim属性的值.shim可以理解成'垫片',用来帮助require.js加载非AMD规范的库.
    require.config({
        paths:{
            'bockbone':'vendor/backbone',
            'underscore':'vendor/underscore'
        },
        shim:{
            'backbone':{
                deps:['underscore'],//被依赖
                exports:'backbone' //输出符号
            },
            'underscore':{
            exports:"_" //输出符号
            }
        }
    });

    上面backbone和underscore就是非AMD规范的库.shim指定他们的依赖关系(backbone依赖于underscore),以及输出符号(backbone为Backbone,underscore为"_").

    8.插件
        require允许使用插件,加载各种格式的数据.
        define(['backbone','text!abc.html'],function(Backbone,abc){
            //.....
        });
        上面代码加载的第一个模块时backbone,第二个模块则是一个文本,用'text!'表示.该文本作为字符串,存在回调函数的abc变量中.





    ===================利用r.js打包项目=================
    9.因为过多的模块亲求会降低网站的速度,这个时候就需要吧那些零散的项目合并起来.
    有两种方式
        第一种通过cmd的命令行在node环境下打包处理
        第二种:造node环境下执行配置文件.
    讲第二种:

    原先的文件目录
        1
            js
                gys.js
                gysExt.js
                index.js
                news.js
                people.js
                peopleExt.js
                require.js
            build.js
            index.html
            news.html
            r.js

    描述:index.js依赖gysExt.js; gysExt.js依赖gys.js
         news.js依赖于peopleExt.js;peopleExt.js依赖于people.js

         build.js是配置文件:
         代码如下:
         ({
             appDir:"./",
             baseUrl:"js",
             dir:"../2",
             paths:{
                 jquery:'empty:'
             },
             modules:[
                 {name:"index"},
                 {name:"news"}
             ]
         })

    在cmd下,切换到1目录下,执行命令:node r.js -o build.js
    结过如下

  • 相关阅读:
    原码、反码、补码之间的相互关系
    在用 JavaScript 工作时,我们经常和条件语句打交道,这里有5条让你写出更好/干净的条件语句的建议。
    冒泡排序最佳情况的时间复杂度
    path的join和resolve的使用区别
    SCSS入门
    webpack 前后端分离开发接口调试解决方案,proxyTable解决方案
    JS中原型链的理解
    30分钟,让你彻底明白Promise原理
    状态码常用对照表
    前端性能优化方案都有哪些?
  • 原文地址:https://www.cnblogs.com/guoyansi19900907/p/5284284.html
Copyright © 2011-2022 走看看