模块化与requirejs

前面一篇文章写过一些模块的原理和怎么实现模块化,但是在具体的项目当中怎么实现呢。我们这里介绍下require的使用。

在介绍require之前,先简单的介绍下AMD和CMD。

     AMD(Asynchronous Module Definition),CMD(Common Module Definition)这是这两个词的全称,看起来就是模块的定义的区别,实际上也就是在具体的应用中模块定义的位置不同。下面我们介绍require,完了应该对模块定义的位置能有一些理解。


就像上篇文章说的,我们实现了模块化,将不同的模块定义成不同的对象,不同的模块之前互不影响,而且我们还可以去引入一些模块的依赖关系而不是全部的一股脑的引入。require就是为了实现模块化的一个工具。那么使用require有哪些优点呢?

1、异步加载,我们知道js加载放到页面之前会阻塞页面,requirejs的执行时在异步的回调函数里,不会阻塞页面

2、模块的依赖,我们可以方便的管理依赖

3、面向对象,通过模块化我们可以方便的实现面向对象

4、文件管理,当我们的依赖发生变化或者文件变化时不再需要到每一个文件里去改变这个引用,只要在改一处即可,因为其他地方都是对我们模块定义的引用。

当然还有一些其他的优点,刚开始接触也就先介绍这一些了,下面我们来看怎么使用require

1、引入

       首先得第一步的先下载require并引入到页面

<script data-main='js/config.js'   src='js/require.js'></script>

require.js 是我们下载的require,那么config呢,当然很多也用main.js只是名字而已,只是觉得用config语义看起来明确,没错就是配置文件。这里的config.js可以省略后缀。

requirejs提供三个方法,requirejs,require和define,前两个是一样的,一般用require,我们看一个config文件

/*require.config  

baseUrl为'js',

baseUrl指的模块文件的根目录,可以是绝对路径或相对路径

*/

require.config({

     baseUrl:'js',

    paths: {

          jquery:'jquery-1.8.2.min',

          moduleA:'a.js'

    }

});

require.config时配置模块得一些信息,这里面有两个属性

baseUrl我们定义的目录,表示下面的一些文件可以从这个目录开始。

paths是一个对象,这里面就是定义我们项目中的模块了。前面属性名(key值)是模块的名字,后面的属性(value)是模块的文件位置.

2、模块的定义

     上面我们定义了模块的信息,那么这些模块的js应该怎么写来实现require的使用呢。就是用到了define方法来定义模块。我们来看一个模块的定义。

/*define的参数为匿名函数,该匿名函数返回一个对象*/

define(['jquery'],function($){

    return {

          a: function(){

                 $("body").append("模块A加载......");

         }

    }

})

define为定义模块的方法,有三个参数,第一个参数为模块名,一般都不用定义,第二个是数组,是当前模块的依赖,是否依赖其他的模块,第三个参数为回调函数,一般返回值为对象。

3、模块的定义和引入是完成了下面就是模块的使用了,我们看一个模块的使用

index.js

require(['config'],function(){

     require(["jquery",'a','b','c'],function($,ma,mb,mc){

        ma.a();

        mb.a();

        mc.a();

     })

})

最外层是应用config的配置,内层是模块的使用,前面数组是依赖或者引入的模块,函数的参数是这个引入的模块的应用时的名字,函数内是模块内函数的调用。

当然如果直接把模块的使用写在config的文件内,可以不需要声明config的调用。

那么是使用require的时候,我们要调用的模块必须要符合require使用的模块的要求,jquery源码里有这么一段,所以jquery我们直接使用

if ( typeof define === "function" && define.amd ) {

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

             return jQuery;

     });

}

那么其他的没有按照这种要求写的模块我们怎么使用呢,这里就要用到shim。

require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。

比如上面的moduleA,如果我们这样写

define(['jquery'],function($){

           return {

                 a: function(){

                       $("body").append("模块A加载......");

                }

          }

})

这样写的方式符合require模块的写法可以直接使用。

如果我们这样写呢

o = {  

      a:function(){ 

           $("body").append("模块A加载......"); 

      }   

}

也就是在这个js里只写了个对象,并没有返回也没有define。

那么在config里我们就需要用到这样的配置

require.config({

         baseUrl: 'js',

        paths:{

             "jquery":"jquery-2.1.0",

              "moduleA":"a",

          },

         shim:{

               'moduleA':{

                      deps:['jquery'],

                      exports:'o'

                }

         }

})

shim的deps是这个模块的依赖模块的引入,exports是这个A模块所要使用的返回值。后面的使用不变。

在简单些,如果我们将A写成这样

function a(){

      $("body").append("模块A加载......");

}

只是一个函数的定义呢,那么我们的shim里exports就要写成 

shim:{

      'moduleA':{

            deps:['jquery'],

            exports:'a'

       }

}

这时候模块A就是一个函数而已而不是一个对象了。

这里我们在看下AMD和CMD,这里我们的模块的引入都是在使用之前将全部的依赖的模块引入,AMD的依赖引入是提前执行,CMD则是就近执行,即在使用的时候执行。


参考文档

浅谈requireJS

JavaSript模块规范 - AMD规范与CMD规范介绍

RequireJS

require.js shim 配置

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容