文档章节

RequireJS 快速入门

wmy596
 wmy596
发布于 2015/04/10 14:29
字数 2208
阅读 21
收藏 0

说明:本文只提供快速入门内容,方便快速进入实战状态。更高级的配置,请参考官网文档。

当初之所以使用 RequireJS 等工具,是因为想提高js的加载速度,避免不必要的堵塞。但通过一段时间的使用,发现 RequireJS 更重要的作用是作为命名空间使用。

一、基本用法

RequireJS 官网文章不是中文的,篇幅不少(官方网址:http://requirejs.org)。网上的其他相关文章,有的讲的也很复杂。

其实,RequireJS 极其简单。如果你对 c# 或 java 语言的命名空间有一点点了解,那么,RequireJS 的用法和作用,可以用 c# 中的两行代码来类比说明:

1 using xx=wojilu.Core;
2 namespace MyApp {
3     public class MyClass {
4         public void MyTest() {}
5     }
6 }

RequireJS主要的功能,就是实现c#代码的第一行和第二行的功能:1)引入需要使用的命名空间(顺便加个别名也行);2)将自己的代码放到命名空间中,避免全局污染。

因为 javascript 天生的缺点,语言本身没有集成命名空间的概念,所以变量名、函数名很容易发生冲突。这些年,大家想尽了各种办法,给 js 添加命名空间的概念,其中最成熟的套路,就是 RequireJS 这种。

我们可以看到,在c#中只要两行代码的事情,在 js 中,得用多么复杂的类库,比如 RequireJS 去解决。

下面我们看一下 RequireJS 的具体写法,新建一个独立的 wojilu.test1.js 文件,然后输入如下代码:

1 define( ['wojilu.Core'], function(xx) {
2     return {
3         MyTest : function() { alert( 'wojilu1 module' );}
4     };
5 });

和上面的c#代码对比一下,RequireJS 同样也做了两件事情:
1、引入命名空间 wojilu.Core,同时给它取了一个别名 xx;
2、将自己的所有代码放在 define 中,避免全局化的污染冲突。

总之,RequireJS 定义了(define)一个命名空间,在定义的时候,顺便引用了需要使用其他命名空间。我们注意到,按照 RequireJS 的术语,它把命名空间叫做“模块”。注意,在这里,RequireJS 定义的模块(命名空间)是匿名的,没有取名,这是和c#不同的地方。

但这个不要紧,因为其他 js 在用到你这个 js 的时候,一般是根据文件名称加载的,同时可以通过上面的 xx 这种方式,给模块(命名空间)自定义别名,所以,取不取名,还真不是关键。

我们新建另外一个 wojilu.test2.js 文件,来使用 wojilu.test1.js:

1 define( ['wojilu.test1'], function( t1 ) {
2     return {
3         NewTest : function() { t1.MyTest();}
4     };
5 });

同样,也是通过文件名(不需要后缀名),引入了 wojilu.test1 命名空间,并给它取了别名 t1,然后在代码中使用 t1.MyTest() 方法。

按照 RequireJS 的规范,所有的模块定义,都必须放在 return {} 对象中。也就是说,你的代码都要写在 return 返回的 {} 对象里面。这会不会导致代码臃肿难看?当然不会。你可以重构一下,比如这样做:

01 define( ['wojilu.test1'], function( t1 ) {
02
03     function someFunc1() {
04         // 实际主要代码
05     }
06
07     function someFunc2() {
08         // 实际主要代码
09     }
10     // 通过 return 方式,将需要公开的函数暴露出来,供其他 js 调用
11     return {
12         NewTest : function() { t1.MyTest();},
13         fun1 : someFunc1,
14         fun2 : someFunc2
15     };
16 });

当然,要使用 RequireJS 的这些功能,你必须在页面中引用 require.js 文件

1 <script src="require.js"></script>

二、其他用法

上面的用法是标准用法,但 RequireJS 在加载其他 “模块/命名空间/js文件” 的时候,内部是通过传统的 <script src="some.js"></script> 来实现的,所以,你也可以把 RequireJS 仅仅当做 js 加载器使用。比如这行代码:

1 <script src="some.js"></script>

可以写成:

1 <script>require( ["some" ] );</script>


虽然仅仅是写法的变化,但带来了很多好处:
1、避免阻塞,提高了 js 的加载性能;
2、通过编程使用 require 方法加载,而不是<script>硬写,更加灵活。

三、基本配置

上面使用 RequireJS 的方式是这样处理的:

1 <script src="require.js"></script>

这种写法虽然简单,但其实并不推荐,一般的写法还要再加个属性:

1 <script data-main="js/main" src="js/require-jquery.js"></script>

就像一个c程序总有一个 main 方法作为入口一样,上面这种写法,做了几件事情:
1、加载了 require-jquery.js 文件。注意,官方提供了 RequireJS 和 jquery 的打包版本,推荐。
2、在加载之后,加载入口文件 js/main.js ,注意,main.js 写进去的时候,不需要后缀名。

你的所有其他 js 模块文件,都可以写在 main.js 里面,通过 main.js 加载。

四、加载的用法

到此为止,我们遇到了两个关键词,一个是 define ,可以用来定义模块(命名空间),第一部分我们讲了;还有一个是 require,可以直接加载其他 js。它除了简单的用法:

1 <script>
2 require( ["some" ] );
3 </script>

之外,还有和 define 类似的复杂用法:

1 <script> 
2 require(["aModule", "bModule"], function() { 
3     myFunctionA(); // 使用 aModule.js 中的函数 myFunctionA
4     myFunctionB(); // 使用 bModule.js 中的函数 myFunctionB
5 }); 
6 </script> 

总结一下,define 是你定义自己的模块的时候使用,可以顺便加载其他js;require 直截了当,供你加载用的,它就是一个加载方法,加载的时候,可以定义别名。

五、在 RequireJS 之前运行

有了 RequireJS 这个工具,我们可以将网页 <head> 中的所有 js 都挪到页脚,以提高 js 的加载速度。请在 www.wojilu.com 网页上右键查看 html 源码,看一下实际效果。

理论上,js 脚本都应该放到独立的 js 文件中,而不是直接嵌入网页内联执行,好处是方便浏览器缓存,不用每次都加载页面内容。但只要你不是有真正的代码洁癖,总有一些特殊时候,需要在加载 require.js 之前,运行一些script脚本。这时候,你可以使用 wojilu 目前的做法,把所有的代码都放在一个叫 _run 的函数中,比如在 require.js 加载代码上面一行:

1 <script>
2     _run(function () {
3         require(['wojilu.core.base'], function (x) { x.customSkin().backTop(); });
4     });
5 </script>

这行代码引用了 wojilu.core.base 文件,但因为是放在 _run 中的,所以并不是立刻执行,而是延迟到 require.js 加载之后执行。 run 表示运行,前面加上下划线,表示“延迟”运行。

至于wojilu如何做到这一点的,请自己阅读源码,其实思路是很简单的。

六、版本号

为了在js更新之后,及时通知客户端刷新缓存,我们一般需要给js加上版本号,具体说明,参看这里:http://www.wojilu.com/Common/Page/13 。在 RequireJS 中也可以给所有需要加载的 js 加上版本号,方法是给 require.js 提供一个配置文件。请在 requrie.js 加载之前,提供一个全局变量 require:

1 <script>
2     var require = {
3          urlArgs: 'v=版本号'
4     };
5 </script>
6 <script src="scripts/require.js"></script>

注意:不要把 require 变量写成 window.require ,据说在IE下会有问题。

RequireJS 还提供了其他丰富的配置选项,具体请访问官网查看。

七、其他问题

1、路径与后缀名

在 require 一个 js 文件的时候,一般不需要加上后缀名。如果加上后缀名,会按照绝对路径加载。没有后缀名,是按照下面的路径加载:

1 <script data-main="js/main" src="js/require-jquery.js"></script>

也就是默认加载 data-main 指定的目录,即 js/main.js 文件所在的目录。当然,你可以通过配置文件修改。

2、define 定义模块方法只能用在独立的js文件中,不能在页面中直接使用。
否则会报 Mismatched anonymous define() module 错误。

3、和其他第三方js类库是否冲突?

不会冲突。一般比较规范的类库,都会给自己的js加上命名空间。比如 wojilu 旧有的 wojilu.common.js ,其实就是放在 wojilu 命名空间中(当然是通过更原始的方式实现命名空间的)。

在通过 RequireJS 加载这些第三方的 js 的时候,完全不要有任何担忧。

当然,如果第三方类库能够使用 RequireJS 的方式进行改造,那是最好。比如 wojilu 中大多数js 都按照 RequireJS 的方式进行了改造。但是,如果你不改造,也是完全不要紧的。

4、在代码中 require 一个文件多次,是否会导致浏览器反复加载?

不会,这是 RequrieJS 的优点,即使你反复 require 它,它只加载一次。


本文转载自:http://www.wojilu.com/Forum1/Topic/4205

共有 人打赏支持
上一篇: oracle sql日期比较
下一篇: maven 环境搭建
wmy596
粉丝 5
博文 23
码字总数 202
作品 0
广州
程序员
私信 提问
RequireJS极简入门教程

RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular s......

程序员诗人
2017/03/30
0
0
RequireJS 入门指南

简介 如今最常用的JavaScript库之一是RequireJS。最近我参与的每个项目,都用到了RequireJS,或者是我向它们推荐了增加RequireJS。在这篇文章中,我将描述RequireJS是什么,以及它的一些基础...

oschina
2013/08/15
70.2K
37
使用 RequireJS 优化 Web 应用前端

基于 AMD(Asynchronous Module Definition)的 JavaScript 设计已经在目前较为流行的前端框架中大行其道,jQuery、Dojo、MooTools、EmbedJS 等纷纷在其最新版本中加入了对 AMD 的支持。本文...

IBMdW
2012/09/11
8.6K
16
使用 RequireJS 来优化你的 JavaScript 代码

RequireJS是一个提高你的javascript代码速度和质量的有效方法,同时它还让你的代码更容易阅读和维护。 在本文中,我会为你介绍RequireJS和应该如何使用它。我们讨论引入文件和定义模块,甚至...

oschina
2013/02/12
4.9K
11
教你5分钟学会用requirejs(必看篇)

转来:教你5分钟学会用requirejs(必看篇) requirejs是干啥的啊? 曾经,我们将一些js组件放到不同的文件,然后通过script标签引入,如果几个组件有依赖,那么要小心了,你必须将被依赖的放到...

spinachgit
10/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Cloud Consul综合整理

部分资料来自 该项目通过自动配置和Spring环境以及其他Spring编程模型习惯用法提供了Spring Boot应用程序的Consul集成。 通过一些简单的注释,您可以快速启用和配置应用程序内的通用模式,并...

Gm_ning
7分钟前
0
0
Springboot 2.0 - 集成redis

最近在入门SpringBoot,然后在感慨 SpringBoot较于Spring真的方便多时,顺便记录下自己在集成redis时的一些想法。 从springboot官网查看redis的依赖包 <dependency>           ...

别打我会飞
8分钟前
0
0
支付宝APP支付申请配置过程详解

第一步:你需要申请一个支付宝商家账户账号,登陆之后进入产品中心,进行APP支付产品接入,填写相关资料,等待审核。 第二步:进行APP支付申请信息完善 第三步:进入蚂蚁金服开放平台进行开发...

Code辉
12分钟前
0
0
避免过度同步(67)

过度使用同步会导致性能低下、死锁或其他不确定问题 在一个同步方法或代码块中,不要放弃对客户端的控制 即:在一个同步区域内部,不要调用被覆盖方法,或者是传入对象提供的方法 这些外来方...

Java搬砖工程师
13分钟前
0
0
Java获取文件类型/扩展名

import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.util.HashMap;import java.util.Map;public class FileTypeUtils { private fi......

Hzhodor
16分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部