文档章节

RequireJS 快速入门

wmy596
 wmy596
发布于 2015/04/10 14:29
字数 2208
阅读 19
收藏 0
点赞 0
评论 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

共有 人打赏支持
wmy596
粉丝 4
博文 23
码字总数 202
作品 0
广州
程序员
abei2017/hou-admin

一套免费的基于JQ + RequireJS + Semantic-UI的后台管理系统 感谢下面伙伴的支持 除了代码,还有诗和远方。扫码关注我的公众号。 Hou-Admin Hou-Admin是一套由JQ + RequireJS + Semantic-UI实...

abei2017 ⋅ 04/24 ⋅ 0

CommonJS/AMD/CMD/UMD概念初探

1、CommonJS是一种规范,NodeJS是这种规范的实现。 1.1、CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。 参考: http://www.commonjs.org/ http://javascript.ruanyifen...

easonjim ⋅ 2016/12/12 ⋅ 0

Gulp和Webpack工具的区别

引用知乎的回答:https://www.zhihu.com/question/37020798 怎么解释呢?因为 Gulp 和 browserify / webpack 不是一回事 Gulp应该和Grunt比较,他们的区别我就不说了,说说用处吧。Gulp / Gr...

easonjim ⋅ 2016/12/24 ⋅ 0

云 GIS 网络客户端开发平台 - iClient-JS

SuperMap iClient JavaScript (简称 iClient-JS )是云 GIS 网络客户端开发平台。基于现代 Web 技术栈全新构建,是 SuperMap 云四驾马车和在线 GIS 平台系列产品的统一 JS 客户端。集成了领先...

ahnan ⋅ 2017/12/04 ⋅ 5

Learning TypeScript 读书笔记3

Chap 4 TypeScript中的面向对象编程 1.面向对象开发的一些原则SOLID: 单一职责原则SRP: 开闭原则OCP: 里氏替换原则LSP: 接口隔离原则ISP: 依赖翻转原则DIP: 2.T雨棚script支持类class、接口...

GunnerAha ⋅ 06/09 ⋅ 0

深入理解javascript系列(十):模块化与闭包

如果想在所有的地方都能访问同一个变量,那么应该怎么办呢? 在实践中这种场景很多,比如全局的状态管理。 但前面我们介绍过,在实际开发中,不要轻易使用全局变量,那又该怎么办呢?模块化的...

Panthon ⋅ 06/14 ⋅ 0

JavaScript define

AMD的由来   前端技术虽然在不断发展之中,却一直没有质的飞跃。除了已有的各大著名框架,比如Dojo,JQuery,ExtJs等等,很多公司也都有着自己的前端开发框架。这些框架的使用效率以及开发...

architect刘源源 ⋅ 04/23 ⋅ 0

很全很全的 JavaScript 模块讲解

模块通常是指编程语言所提供的代码组织机制,利用此机制可将程序拆解为独立且通用的代码单元。所谓模块化主要是解决代码分割、作用域隔离、模块之间的依赖管理以及发布到生产环境时的自动化打...

一个敲代码的前端妹子 ⋅ 05/11 ⋅ 0

老铁们,福利来了

1. 这一月我没在写专栏文章,因为我干了一件小事,我业余时间都用来写教程了—一套pandas教程。 本来我是一边写教程一边在参加一个大数据竞赛,后来发现时间不够用了,索性把竞赛停了(本来还...

zhenhang.sun ⋅ 2017/08/26 ⋅ 0

这款Excel插件,是入门的选手逆袭的利器!

图文 | 雷哥 很多职场的朋友,看了很多Excel技巧,学了很多快捷键!可是,需要使用的时候,就是想不起来!还得去问度娘,你说工作效率怎么能够提高? 鉴于此,我给大家推荐一款Excel插件—方...

安伟星 ⋅ 2017/09/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

NFS介绍 NFS服务端安装配置 NFS配置选项

NFS介绍 NFS是Network File System的缩写;这个文件系统是基于网路层面,通过网络层面实现数据同步 NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netapp公司参与并主导...

lyy549745 ⋅ 6分钟前 ⋅ 0

Spring AOP 源码分析 - 筛选合适的通知器

1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析。本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出合适的通知器(Advisor...

java高级架构牛人 ⋅ 29分钟前 ⋅ 0

HTML-标签手册

标签 描述 <!--...--> 定义注释。 <!DOCTYPE> 定义文档类型。 <a> 定义锚。超链接 <abbr> 定义缩写。 <acronym> 定义只取首字母的缩写。 <address> 定义文档作者或拥有者的联系信息。 <apple......

ZHAO_JH ⋅ 30分钟前 ⋅ 0

SylixOS在t_main中使用硬浮点方法

问题描述 在某些使用场景中,应用程序不使用动态加载的方式执行,而是跟随BSP在 t_main 线程中启动,此时应用代码是跟随 BSP 进行编译的。由于 BSP 默认使用软浮点,所以会导致应用代码中的浮...

zhywxyy ⋅ 38分钟前 ⋅ 0

JsBridge原理分析

看了这个Github代码 https://github.com/lzyzsd/JsBridge,想起N年前比较火的Hybrid方案,想看看现在跨平台调用实现有什么新的实现方式。代码看下来之后发现确实有点独特之处,这里先把核心的...

Kingguary ⋅ 50分钟前 ⋅ 0

Intellij IDEA神器常用技巧五-真正常用快捷键(收藏级)

如果你觉得前面几篇博文太啰嗦,下面是博主多年使用Intellij IDEA真正常用快捷键,建议收藏!!! sout,System.out.println()快捷键 fori,for循环快捷键 psvm,main方法快捷键 Alt+Home,导...

Mkeeper ⋅ 50分钟前 ⋅ 0

Java 静态代码分析工具简要分析与使用

本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBugs,PMD,Jtest),最后从功能、特性等方面对它们进行分析和比较,...

Oo若离oO ⋅ 52分钟前 ⋅ 0

SpringBoot自动配置小记

spring-boot项目的特色就在于它的自动配置,自动配置就是开箱即用的本源。 不过支持一个子项目的自动配置,往往比较复杂,无论是sping自己的项目,还是第三方的,都是如此。刚接触会有点乱乱...

大_于 ⋅ 今天 ⋅ 0

React jsx 中写更优雅、直观的条件运算符

在这篇文字中我学到了很多知识,同时结合工作中的一些经验也在思考一些东西。比如条件运算符 Conditional Operator condition ? expr_if_true : expr_if_false 在jsx中书写条件语句我们经常都...

开源中国最帅没有之一 ⋅ 今天 ⋅ 0

vim编辑模式与命令模式

5.5 进入编辑模式 从编辑模式返回一般模式“Esc” 5.6 vim命令模式 命令 :“nohl”=no high light 无高亮,取消内容中高亮标记 "x":保存退出,和wq的区别是,当进入一个文件未进行编辑时,使...

弓正 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部