官方文档 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加载,若采用同步模式,无疑会影响浏览器的性能。

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

  1. 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

②相互依赖的关系,我想文档记录和注释起到很大作用,但是还是很不明显啊,当出现下面的加载情况,晕菜了

  1. <script type="text/javascript" src="a.js"></script>
  2. <script type="text/javascript" src="b.js"></script>
  3. <script type="text/javascript" src="c.js"></script>
  4. <script type="text/javascript" src="d.js"></script>

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

  1. index.html
  2.  
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <script type="text/javascript" src="a.js"></script>
  7. </head>
  8. <body>
  9. <span>body</span>
  10. </body>
  11. </html>
  12.  
  13. a.is
  14. (function(){
  15. function fun1(){
  16. alert("it works");
  17. }
  18.  
  19. fun1();
  20. })()
 
执行的时候,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 推崇依赖前置。看代码:

  1. // CMD
  2. define(function(require, exports, module) {
  3. var a = require('./a')
  4. a.doSomething()
  5. // 此处略去 100 行
  6. var b = require('./b') // 依赖可以就近书写
  7. b.doSomething()
  8. // ...
  9. })
  10.  
  11. // AMD 默认推荐的是
  12. define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
  13. a.doSomething()
  14. // 此处略去 100 行
  15. b.doSomething()
  16. ...
  17. })

虽然 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
  1. index.html
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <script type="text/javascript" src="require.js"></script>
  6. <script type="text/javascript">
  7. require(["a"]);
  8. </script>
  9. </head>
  10. <body>
  11. <span>body</span>
  12. </body>
  13. </html>
  14.  
  15. a.js
  16. define(function(){
  17. function fun1(){
  18. alert("it works");
  19. }
  20.  
  21. fun1();
  22. })
 
很明显,异步带来的好处,个人理解 异步就是开启多线程模式
 
 RequireJS是一个Javascript 文件和模块框架,可以从 http://requirejs.org/下载,如果你使用Visual Studio也可以通过Nuget获取。它支持浏览器和像node.js之类的服务器环境。使用RequireJS,你可以顺序读取仅需要相关依赖模块。 RequireJS所做的是,在你使用script标签加载你所定义的依赖时,将这些依赖通过head.appendChild()函数来加载他们。当依赖加载以后,RequireJS计算出模块定义的顺序,并按正确的顺序进行调用。这意味着你需要做的仅仅是使用一个“根”来读取你需要的所有功能,然后剩下的事情只需要交给RequireJS就行了。为了正确的使用这些功能,你定义的所有模块都需要使用RequireJS的API,否者它不会像期望的那样工作。
 ① requireJs的加载

  1. <script src="js/require.js" defer async="true" ></script>(IE支持defer 没有async)
  2. <script src="js/require.js" data-main="js/main"></script> (入口模块main.js)
 
② 模块的编写
 RequireJS API 存在于RequireJS载入时创建的命名空间requirejs下。
其主要API主要是下面三个函数:
 define– 该函数用户创建模块。每个模块拥有一个唯一的模块ID,它被用于RequireJS的运行时函数,define函数是一个全局函数,不需要使用requirejs命名空间. 
  1. define(['myLib'], function(myLib){ // define([依赖的模块],定义模块)
  2.     function foo(){
  3.       myLib.doSomething();
  4.     }
  5.     return {
  6.       foo : foo
  7.     };
  8.   });
require– 该函数用于读取依赖。同样它是一个全局函数,不需要使用requirejs命名空间. 

  1. require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){// require([依赖的模块], 定义函数
  2. // some code here
  3.   });
config– 该函数用于配置RequireJS.   
  1. require.config({
  2.     paths: {
  3.       "jquery": "lib/jquery.min",
  4.       "underscore": "lib/underscore.min",
  5.       "backbone": "lib/backbone.min"
  6.     }
  7.   });
 看一下例子:

  1. index.html
  2. <html>
  3. <head>
  4. <title>hi test!</title>
  5. </head>
  6. <body>
  7. <p>p1</p>
  8. <p>p2</p>
  9. <script type="text/javascript" src="a.js"></script>
  10. <script src="js/require.js" data-main="js/main" defer async="true" ></script>
  11. </body>
  12. </html>
  13.  
  14. main.js  
  15.  
  16. // main.js
  17. require.config({
  18. paths: {
  19. "math": "math"
  20. }
  21. });
  22. require(['math'], function (math){
  23. alert(math.add(1,1));
  24. });
  25.  
  26. math.js   
  27.  
  28. // math.js
  29. define(function (){
  30. var add = function (x,y){
  31. return x+y;
  32. };
  33. return {
  34. add: add
  35. };
  36. });

requireJS的学习的更多相关文章

  1. gulp + angular + requirejs 简单学习

    一.安装gulp(已经安装了node环境) npm  install -g gulp 二.在package.json文件中配置依赖插件 { "name": "xxxx&q ...

  2. 前端JS框架系列之requireJS基础学习

    1 背景 伴随着项目功能的不断扩充,客户体验的不断完善,实现交互逻辑的JS代码变得越来越多.起初,为了管理JS代码,我们把JS从页面中解放出来独立成文件,接着又把相似的交互代码提取到公共的JS页面中. ...

  3. requireJS入门学习

    前言 最近网上.群里各种随便看,随便学.暑期实习还没找到,昨天开题过了,好好学习吧.最近一直看到前端的ADM,CMD规范,然后网上各种找资料看,看了好几个牛人的博客,写的很好,然后自我感觉了解了点,介 ...

  4. 透彻掌握Promise的使用,读这篇就够了

    透彻掌握Promise的使用,读这篇就够了 Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. ...

  5. 前端基础进阶(十三):透彻掌握Promise的使用,读这篇就够了

    Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. 在实际的使用当中,有非常多的应用场景我们不能 ...

  6. 【requireJS源码学习01】了解整个requireJS的结构

    前言 现在工作中基本离不开requireJS这种模块管理工具了,之前一直在用,但是对其原理不甚熟悉,整两天我们来试着学习其源码,而后在探寻其背后的AMD思想吧 于是今天的目标是熟悉requireJS整 ...

  7. 【requireJS源码学习03】细究requireJS的加载流程

    前言 这个星期折腾了一周,中间没有什么时间学习,周末又干了些其它事情,这个时候正好有时间,我们一起来继续学习requireJS吧 还是那句话,小钗觉得requireJS本身还是有点难度的,估计完全吸收 ...

  8. 【requireJS源码学习02】data-main加载的实现

    前言 经过昨天的学习,我们大概了解到了requireJS的主要结构,这里先大概的回顾一下 首先从总体结构来说,require这里分为三块: ① newContext之前变量声明或者一些工具函数 ② n ...

  9. 开始学习requirejs+easyui的使用.

    开始学习requirejs+easyui的使用. 目录结构: |-project |-easyui01 |-js |-main.js |-index.html |-libs libs目录下放入的是ea ...

随机推荐

  1. js学习笔记 -- await/ async

    await 暂停async function函数,等待Promise处理完成,若Promise 状态为fulfilled,其回调resolve的参数作为await的值,Promise 状态为rejec ...

  2. oracle数据库代码块

    --申明变量.游标 declare a ):'; --逻辑 begin INSERT into TEMP_DSF.TEST VALUES (a); end; tips:mysql不支持匿名块.仅在存储 ...

  3. Robotframework测试相关库

    一. 官网地址 http://robotframework.org/#libraries 二.几类测试所用到的常用库初步整理 1. UI自动化测试 Selenium2Library.BuiltIn(自 ...

  4. Not so Mobile UVA - 839

    题目链接:https://vjudge.net/problem/UVA-839 题目大意:输入一个树状天平,根据力矩相等原则,判断是否平衡.  如上图所示,所谓力矩相等,就是Wl*Dl=Wr*Dr.  ...

  5. 性能测试工具LoadRunner03-LR之Virtual User Generator 脚本创建以及回放设置

    vuser_init,Action,vuser_end说明 vuser_init 录制的一般是业务流程开始之前的初始化工作(如登录,服务器初始化) Action 录制的一般是业务流程操作的事件 vus ...

  6. c3p0 数据连接池 流行开源

    注意事项:配置文件规定命名,不能更改   c3p0-config <?xml version="1.0" encoding="UTF-8"?>< ...

  7. 在rails 中返回 zip 文件

    在平日的开发当中我们一般只返回html,json 等等,但是偶尔情况下也会使用到其他文件的返回,比如 pdf ,csv 文件 今天在开发中使用的是将大量的文字返回给用户. ## 知识点 `Tempfi ...

  8. php关于网页乱码问题

    指定浏览器打开网页的编码格式: <meta http-equiv="Content-Type" content="text/html; charset=gb2312 ...

  9. pat1033. To Fill or Not to Fill (25)

    1033. To Fill or Not to Fill (25) 时间限制 10 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 ZHANG, Gu ...

  10. 搭建MHA

    安装MySQL 5.7 yum源的配置文件如下 [mysql57-community] name=MySQL 5.7 Community Server baseurl=http://repo.mysq ...