RequireJS入门指导 (转)
最近在百度实习做的一个项目用到了 Require JS 这个库,之前从来没有了解过,经过一番大概的搜索后找到一篇非常不错的文章,看完后能够让你对 Require JS 的运行机制、使用方法以及为什么使用 Require JS 有一个基础的认识。下面我就对这篇文章进行一个简单的翻译,如果有错漏的地方希望指正。
原文链接:http://undefinedblog.com/primer-for-require-js/
谁适合读这篇文章
对 JavaScript 有一定的了解,写过一定规模的 JavaScript 代码,尤其能够掌握 JavaScript 匿名函数、回调等概念,并希望了解 Require JS 的用法、概念、意义等。
一些基本信息
Require JS(官网) 是一个 JavaScript 文件或模块的加载器,它可以根据不同页面对不同模块的需求,按照你的设置依次加载并执行所有的 JavaScript 文件。使用 Require JS 主要有两个目的:
- 解耦代码,方便代码重用和管理
- 加速页面加载,内置优化引擎(需服务器支持),自动异步加载依赖项,将所有需要加载的文件自动合并为一个文件,减少 HTTP 请求
Require JS 同时支持整合 jQuery、CommonJS、Node JS 等,而且对浏览器有不错的兼容性(IE 6+,你懂的)。
没有 Require JS 的时候
下面我们将以一个没有使用 Require JS 的模块开始,讲讲如何将你的代码解耦并使用 Require JS 来加载:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Phase </title>
</head>
<body>
<div>
<h1>Modular Demo </h1>
</div>
<div id="messagebox"></div> <script src="../Scripts/jquery-1.8.2.min.js" type="text/javascript"></script> <script type="text/javascript"> var baseUrl = '/api/messenger/'; function ShowMessage(id) {
$.ajax({
url: baseUrl + id,
type: 'GET',
dataType: 'json',
success: function(data) {
$("#messagebox").html(data);
}
});
} var id = ;
ShowMessage(id); </script>
</body>
</html>
以上是一个很简单而且很常见的 ajax 请求页面,可以看到这个页面里的代码虽然简单,但是耦合度很高,下面我们将其中的 JavaScript 代码解耦,把不同的模块独立出来。
//模块1,全局设置模块
var config = (function() {
var baseUrl = '/api/messenger/'; return {
baseUrl: baseUrl
};
})(); //模块2,请求数据模块
var dataservice = (function($, config) {
var callApi = function (url, type, callback) {
$.ajax({
url: url,
type: type,
dataType: 'json',
success: function (data) {
callback(data);
}
});
},
getMessage = function (id, callback) {
url = config.baseUrl + id;
callApi(url, 'GET', callback);
}; return {
getMessage: getMessage
};
})($, config); //模块3,封装的一个 messenger 模块,显示 ajax 放回的数据
var messenger = (function ($, dataservice) {
var showMessage = function(id) {
dataservice.getMessage(id, function(message) {
$("#messagebox").html(message);
});
}; return {
showMessage: showMessage
};
})($, dataservice); //模块4,匿名函数,传 id, 调用 messenger 的showMessage() 方法 (直接执行)
(function (messenger) {
var id = ;
messenger.showMessage(id);
})(messenger);
将这些代码放到原来的、没有重构前的页面中去,将实现同样的效果。但是我们将这些功能独立出来后,就可以很好的重复利用部分代码。
下面假设我们将这 4 个模块放到 4 个独立的 js 文件中:
- 模块1:config.js
- 模块2:dataservice.js
- 模块3:messenger.js
- 模块4:main.js
这样,在我们的 html 页面中,我们需要依次加载这 4 个模块:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Phase </title>
</head>
<body>
<div>
<h1>Modular Demo </h1>
</div>
<div id="messagebox"></div> <script src="../Scripts/jquery-1.8.2.min.js" type="text/javascript"></script> <script src="config.js" type="text/javascript"></script>
<script src="dataservice.js" type="text/javascript"></script>
<script src="messenger.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script> </body>
</html>
这个时候,代码一样可以工作的非常顺利,没有任何问题。但是需要考虑一个问题:js 文件的加载顺序。当一个模块2需要依赖模块1中的功能时,必须要求模块1加载完成后再执行模块2中的代码。对于简单的代码(如本文涉及的仅4个模块)还好考虑,若有数十个模块需要加载,那么依赖的顺序一旦处理出错,很可能就会报 xxx is undefined 错误。
这个时候就是 Require JS 需要大显身手的时候。
Require JS 的基础操作
定义模块
define(['jquery'],
function ($) {
var text = 'I am a module',
showMessage = function() {
$("#messagebox").html(text);
}; return {
showMessage: showMessage
};
}
);
可以看到,一个 JavaScript 模块(如上面提到的 config、dataservice、messenger 等),都被一个 define() 函数包起来。
其中 define() 函数接受 3 个参数:
- 模块名
- 依赖项,以数组形式传递
- 模块内容
但是注意,上面的模块定义中,我们并没有传 模块名 这个参数,理由如下:
Require JS 会自动根据文件名(不含后缀名,即不含 ".js")来给定义的模块命名,这样在最后优化(将所有的 js 文件合并为一个)时就能自动调用所有的文件。如果你显示的给定义的一个模块命名了,那么在日后进行修改时(比如改动了文件名或模块名),Require JS 将无法自动加载。因此最佳实践是:不要显式的定义模块名,让文件名成为默认的模块名,方便 Require JS 管理。
说完了第一个参数,再看看第二个参数 依赖项。依赖项我们传递的是一个字符串数组,每个字符串均代表要实现本模块的功能,需要预先加载的其他模块的模块名。如上例中我们的依赖项就是 jquery。
最后一个参数就是我们需要定义的模块内容。在上例中,我们的模块是一个 function,其中函数的形参即为对依赖项的引用。比如我们的模块有两个依赖项:
define(['moduleA','moduleB'],function(a,b){
//a.blabla(); b.blabla = ooxx;
});
就可以在模块中分别使用形参来调用我们依赖的模块。需要注意的一点是,依赖项的书写顺序和在模块定义的函数中的形参顺序要一致。
另外,Require JS 定义的模块并不一定是 function,也可以是普通的对象,详见 Require JS 文档。
将解耦后的代码改写为 Require JS 模块
我们在上面把一个简单的 ajax 调用解耦成 4 个独立的模块,下面我们就把这 4 个模块根据 Require JS 定义模块的风格进行改写。
//config.js
define([],
function () {
var baseUrl = '/api/messenger/'; return {
baseUrl: baseUrl
};
}
); //dataservice.js
define(['jquery', 'config'],
function ($, config) {
var
callApi = function (url, type, callback) {
$.ajax({
url: url,
type: type,
dataType: 'json',
success: function (data) {
callback(data);
}
});
}, getMessage = function (id, callback) {
url = config.baseUrl + id;
callApi(url, 'GET', callback);
}; return {
getMessage: getMessage
};
}
); //messenger.js
define(['jquery', 'dataservice'],
function ($, dataservice) {
var showMessage = function (id) {
dataservice.getMessage(id, function (message) {
$("#messagebox").html(message);
});
}; return {
showMessage: showMessage
};
}
); //main.js
(function() {
requirejs.config(
{
paths: {
'jquery': '../Scripts/jquery-1.8.2.min'
}
}
); require(
['messenger'],
function(messenger) {
var id = ;
messenger.showMessage(id);
}
);
})();
你可能注意到了 main.js 中定义模块的方式似乎不同于其它 3 个模块。没错,因为严格意义上来说,main.js 是调用了其它 3 个模块的功能并最终获得数据。因此下面就要引出怎么在定义了 Require JS 模块后最终设置和调用的问题。
设置和调用模块
Require JS 对于模块的设置和调用提供了两种方式:
1、定义一个 script 标签,并增加 data-main 属性,指向我们的设置文件;同时添加 src 属性,指向 require-js.js 文件(即主库)
<script data-main="main.js" src="require-js.js"></script>
2、先引入 Require JS 库,再显式的设置
<script src="require-js.js"></script>
<script>
require({
baseUrl : 'scripts', //设置查找所有模块的根目录
paths:'',//如果在 baseUrl 下没有找到相应的模块,则加上 paths 继续查找
shim:{},//加载依赖项,传对象
});
require(['dataservice.js']); //加载完上述所有依赖项后,再加载自己编写的模块
</script>
详细参数见 Require JS 文档。
以上就是 Require JS 的一些简单使用方法和实践,话再说回 iOS 开发……很快回归!
RequireJS入门指导 (转)的更多相关文章
- 新手入门指导:Vue 2.0 的建议学习顺序
起步 1. 扎实的 JavaScript / HTML / CSS 基本功.这是前置条件. 2. 通读官方教程 (guide) 的基础篇.不要用任何构建工具,就只用最简单的 <script> ...
- React-Native入门指导之iOS篇 —— 一、准备工作
React-Native 入门指导系列教程目录 一.准备工作 (已完成) 二.项目介绍与调试 三.CSS样式与Flex布局 四.常用UI控件的使用 五.JSX在React-Native中的应用 六.事 ...
- React-Native入门指导之iOS篇
React-Native 入门指导系列教程目录 一.准备工作 (已完成) 二.项目介绍与调试 三.CSS样式与Flex布局 四.常用UI控件的使用 五.JSX在React-Native中的应用 六.事 ...
- RequireJS入门(三)转
这篇来写一个具有依赖的事件模块event.event提供三个方法bind.unbind.trigger来管理DOM元素事件. event依赖于cache模块,cache模块类似于jQuery的$.da ...
- RequireJS入门(二) 转
上一篇是把整个jQuery库作为一个模块.这篇来写一个自己的模块:选择器. 为演示方便这里仅实现常用的三种选择器id,className,attribute.RequireJS使用define来定义模 ...
- RequireJS入门(一) 转
RequireJS由James Burke创建,他也是AMD规范的创始人. RequireJS会让你以不同于往常的方式去写JavaScript.你将不再使用script标签在HTML中引入JS文件,以 ...
- Linux上安装使用boost入门指导
Data Mining Linux上安装使用boost入门指导 获得boost boost分布 只需要头文件的库 使用boost建立一个简单的程序 准备使用boost二进制文件库 把你的程序链接到bo ...
- RequireJS入门与进阶
RequireJS由James Burke创建,他也是AMD规范的创始人. RequireJS会让你以不同于往常的方式去写JavaScript.你将不再使用script标签在HTML中引入JS文件,以 ...
- [安卓开发]App Widget开发入门指导
本节所要讲的主要内容包括Android桌面小部件.App Widget的开发入门指导,并通过一个简单实例的形式来直观的讲解App Widget. 一.Widget .App Widget .Web A ...
随机推荐
- poj 3522(最小生成树应用)
题目链接:http://poj.org/problem?id=3522思路:题目要求最小生成树中最大边与最小边的最小差值,由于数据不是很大,我们可以枚举最小生成树的最小边,然后kruskal求最小生成 ...
- C Primer Plus之存储类、链接和内存管理
存储时期即生存周期——变量在内存中保留的时间 变量的作用域和链接一起表明程序的哪些部分可以通过变量名来使用该变量. 注意:生存期和作用域是两个不同的概念. 作用域 作用域描述了程序中可以访问一个 ...
- MongoDB (三) MongoDB 安装
MongoDB安装在Windows上 在 Windows上,首先要安装 MongoDB下载最新发布的MongoDB: http://www.mongodb.org/downloads 确保得到正确的版 ...
- oci.dll文件是用来干嘛的? 如果没有安装ORACLE客户端提示oci.dll未加载
oracle数据库开发编程中,没有找到oci.dll,一般是系统的 path 设置有问题, 查找oci.dll, 然后加入到系统路径.oci.dll 可下载解压到系统盘的system32目录下.然后打 ...
- grep是模糊匹配
1. 我:我用的ps -nat|grep -i "80"|wc -l命令 我:解释详细点,,龙哥,对于我这种菜鸟:也是模糊匹配 :你用 grep "80" 会匹 ...
- Java多线程-线程的调度(合并)
线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法. join为非静态方法,定义如下:void join(): ...
- iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用
swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引 ...
- STM32的GPIO口的输出开漏输出和推挽输出
本文来自cairang45的博客,讲述了STM32的GPIO口的输出开漏输出和推挽输出, 作者博客:http://blog.ednchina.com/cairang45 本文来自: 高校自动化网(Ww ...
- qt之esc键
Esc键对大家来说实在熟悉不过的了,在Qt中Esc键也会默认的进行一些事件的触发,今天对Esc键测试了一下,突然发现不像我想象的那样,在QDialog中按下Esc键会默认调用reject()方法而不是 ...
- 271. Encode and Decode Strings
题目: Design an algorithm to encode a list of strings to a string. The encoded string is then sent ove ...