- RequireJS 教程
- RequireJS - 首页
- RequireJS - 概述
- RequireJS - 环境设置
- RequireJS - 配置
- RequireJS - AMD 模块
- RequireJS - 定义函数
- RequireJS - 优化器
- RequireJS - jQuery
- RequireJS - NodeJS
- RequireJS - Dojo
- RequireJS - CommonJS
- RequireJS - 插件
- RequireJS 有用资源
- RequireJS 快速指南
- RequireJS - 有用资源
- RequireJS - 讨论
RequireJS 快速指南
RequireJS - 概述
RequireJS 是一个 JavaScript 库和文件加载器,它管理 JavaScript 文件之间的依赖关系以及模块化编程。它还有助于提高代码的速度和质量。
RequireJS 由 David Mark 开发,其初始版本 v1.0.0 于 2009 年发布。它是一个开源项目,版本 2.3.3 是其最新的稳定版本。
为什么要使用 RequireJS?
它是一个在 MIT 许可证下的开源 JavaScript 库。
它提供异步模块加载。
它能够加载嵌套的依赖关系。
如果您有很多小文件,则无需担心跟踪依赖项的顺序。
它提供对插件的支持并加载多个 JavaScript 文件。
RequireJS 的特性
它管理 JavaScript 文件之间的依赖关系,并提高代码的速度和质量。
它将模块组合并压缩成一个脚本,以获得优化的体验。
它降低了大型应用程序中的代码复杂性。
它在编译时从不同模块收集不同的 JavaScript 文件。
它允许轻松调试,因为它从普通脚本标签加载文件。
RequireJS - 环境设置
在本章中,我们将了解如何为 RequireJS 设置环境。为此,您需要下载最新版本的 RequireJS 库。您可以下载 压缩版本 或 详细版本。
下载后,我们需要将 require.js 文件包含在您的 libs 文件夹中,并且项目的结构应如下所示:
projectname/
|--index.html
|--libs/
|---main.js
|---require.js
|---helper/
|----util.js
我们需要定义一个名为 index.html 的 html 文件,其中加载 RequireJS,如下所示。
<html>
<head>
<script data-main = "libs/main" src = "libs/require.js"></script>
</head>
<body>
<h1> RequireJS Sample Page </h1>
</body>
</html>
请注意,脚本标签中只包含带有 RequireJS 调用的 require.js 来加载脚本。
Node 中的 RequireJS
有两种方法可以获取 Node 适配器。
npm - 您可以从命令提示符安装最新版本的 requirejs,如下所示。
npm install requirejs
RequireJS - 配置
RequireJS 可以通过在 HTML 模板中通过 data-main 属性传递主配置来初始化。RequireJS 使用它来了解在您的应用程序中加载哪个模块。
例如:
<script data-main = "scripts/main" src = "scripts/require.js"></script>
要包含 Require.js 文件,您需要在 html 文件中添加 script 标签。在 script 标签内,添加 data-main 属性以加载模块。这可以作为应用程序的主要入口点。scripts/main 是应用程序的主要 JavaScript 文件,其中包含 RequireJS 配置。
配置选项
以下是加载第一个应用程序模块时可以设置的配置选项:
baseUrl - 它是通过 RequireJS 加载的所有模块的路由路径。baseUrl 由以“斜杠 (/)”开头的字符串指示,包含协议并以“.js”扩展名结尾。如果没有指定 baseUrl,则 RequireJS 使用 data-main 属性路径作为 baseUrl。
paths - 它指定相对于 baseUrl 的模块的路径映射。在映射模块名称时,它会自动向路径添加 .js 扩展名。
shim - 通过配置其依赖项并导出其全局值,它提供了将非 AMD 库与 RequireJS 一起使用的功能。
map - 对于给定的模块,应用程序使用不同版本的相同模块来实现不同的目标,通过共享其 ID 来利用相同代码满足不同条件。
config - 它通过使用 config 选项为模块提供配置,这可以通过使用特殊的依赖项“module”并调用其 module.config() 函数来完成。
urlArgs - 查询字符串参数用于获取使用 RequireJS 加载的所有资源。当浏览器或服务器配置不正确时,它用于缓存清除。
waitSeconds - 它指定在脚本加载超时之前等待的秒数。默认值为“7”秒,“0”禁用超时。
packages - 它提供用于配置加载模块的 CommonJS 包。
context - 它提供上下文加载的名称,允许在页面中加载不同的模块。
deps - 它是加载 RequireJS 之前将 Require 指定为 config 对象时所需的依赖项数组。
callback - 加载依赖项后执行函数,并且在加载 RequireJS 之前将 Require 指定为 config 对象时需要此函数。
xhtml - 当此选项设置为 true 时,它用于通过使用 document.createElementNS() 方法创建脚本元素。
scriptType - 它定义文档中使用的脚本类型属性的值。默认类型为“text/javascript”。
skipDataMain - 如果此选项设置为 true,则在加载模块时跳过 data-main 属性扫描。
RequireJS - AMD 模块
RequireJS 中的模块是一个作用域对象,在全局命名空间中不可用。因此,全局命名空间不会被污染。RequireJS 语法允许更快地加载模块,而无需担心跟踪依赖项的顺序。您可以在同一页面中加载同一模块的多个版本。
定义模块
模块使用 define() 函数定义;相同的函数也用于加载模块。
简单的名称/值对
如果模块只是一组名称和值对,则可以使用以下语法:
define({
state: "karnataka",
city: "bangalore"
});
定义函数
模块也可以为框架使用函数,而无需依赖项。这可以通过使用以下语法来完成:
define(function () {
//Do setup work here
return {
state: "karnataka",
city: "bangalore"
}
});
定义具有依赖项的函数
如果模块具有依赖项,则第一个参数(依赖项名称数组)、第二个参数(定义函数)和定义模块的返回对象的放置位置在以下语法中显示:
define(["./mnc", "./startup"],
function(mnc, startup) {
return {
state: "karnataka",
city: "bangalore",
addCompany: function() {
mnc.decrement(this);
startup.add(this);
}
}
}
);
将模块定义为函数
模块不必只返回对象,函数中的任何有效值也可以返回。以下语法用于将模块定义为函数:
define(["./mnc", "./startup"],
function(mnc, startup) {
return function(title) {
return title ? (window.title = title) :
startup.storeName + ' ' + mnc.name;
}
}
);
使用名称定义模块
在某些情况下,您可能必须将名称作为第一个参数包含在 define() 中。这可以通过使用以下语法来完成:
define("js2/title",
["js1/mnc", "js1/startup"],
function(mnc, startup) {
//Define js2/title object in here.
}
);
define() 函数可以用来加载模块(模块可以是对象、函数、类或加载模块后执行的代码)。您可以在同一页面中加载同一模块的不同版本。即使这些版本以不同的顺序加载,也可以按相同的顺序进行分析。
RequireJS - 定义函数
模块加载
语法
define(['module1', 'module2'], function (module1, module2) {
//define the module value by returning a value
return function () {};
});
在定义模块时,您可以传递模块名称列表,并且可以使用 RequireJS 在执行模块之前检索这些模块。这些模块可以作为 定义函数的参数传递。
示例
以下示例显示了在加载模块时 define() 函数的使用。创建一个名为 index.html 的 html 文件,并将以下代码放在其中:
<!DOCTYPE html>
<html>
<head>
<title>Define() Function</title>
<script data-main = "main" src = "require.js"></script>
</head>
<body>
<h2>RequireJS Define() Function Example</h2>
</body>
</html>
创建一个名为 main.js 的 js 文件,并在其中添加以下代码:
define(function (require) {
var myteam = require("./team");
var mylogger = require("./player");
alert("Player Name : " + myteam.player);
mylogger.myfunc();
});
现在,再创建两个名为 team.js 和 player.js 的 js 文件,并分别放置以下代码:
team.js
define({
player: "Sachin Tendulkar",
team : "India"
});
player.js
define(function (require) {
var myteam = require("./team");
return {
myfunc: function () {
document.write("Name: " + myteam.player + ", Country: " + myteam.team);
}
};
});
输出
在浏览器中打开 HTML 文件;您将收到如下面的屏幕截图所示的输出:
点击“确定”按钮,您将从模块获得另一个输出:
RequireJS - 优化器
在本章中,我们将讨论 RequireJS 中的优化。RequireJS 中的优化器具有以下特性:
借助 UglifyJS(默认使用)或 Closure Compiler(Java 使用)将脚本文件组合在一起
将 CSS 文件组合在一起。
优化器是 Node 和 Nashorn 的 r.js 适配器的一个组件。它被开发为构建过程的一部分,而不是开发过程的一部分。
示例
在将 r.js 下载到您的项目文件夹后,文件夹的结构应如下所示:
projectfolder/
|-->index.html
|-->CSS/
|--->main.css
|--->other.css
|-->libs
|--->require.js
|--->main.js
|--->dependent1.js
|--->dependent2.js
|--->dependent3.js
您的 HTML 文件将如下所示:
<html>
<head>
<script data-main = "libs/main" src = "libs/require.js"></script>
</head>
<body>
<h1> RequireJS Sample Page </h1>
</body>
</html>
您的 main.js 文件将如下所示:
require(["dependent1", "dependent2", "dependent3"], function (dependent1, dependent2,
dependent3) {
});
您的 main.css 文件将如下所示:
@import url("other.css");
.app {
background: transparent url(../../img/app.png);
}
优化器的基本设置
您可以使用命令行参数或配置文件构建属性来设置项目,两者可以互换。
以下是命令行的语法:
node r.js -o baseUrl = . paths.jquery = content/path/jquery name = main out = main-built.js
以下是构建配置文件的语法:
({
baseUrl: ".",
paths: {
jquery: "content/path/jquery"
},
name: "main",
out: "main-built.js"
})
之后,您可以将构建配置文件名称传递给命令行中的优化器,如下所示:
node r.js -o build.js
命令行参数语法存在一些缺点。组合使用命令行参数或配置文件构建属性可以克服这些缺点。
优化单个 JS 文件
要优化单个 JS 文件,您需要创建一个 JS 文件,其中包含其所有依赖项的内容。您的文件应如下所示:
({
baseUrl: "js/shop",
paths: {
"jquery": "jquery",
"backbone": "backbone",
"underscore": "underscore"
},
shim: {
"backbone": {
"department": ["underscore", "jquery"],
"dependent": "Backbone"
},
"underscore": {
exports: "_"
}
},
name: "../main",
out: "../built/js/main.js"
})
现在,您可以创建包含应用程序所有依赖项的main.js文件。此文件在 HTML 文件中用于通过一个请求加载所有 JS 文件。请注意,创建的文件不应位于源代码目录中;这些文件应位于项目的副本中。
CDN 资源的使用
优化器不会使用网络资源/CDN(内容分发网络)加载脚本。如果需要使用 CDN 加载脚本,则需要将这些文件映射到模块名称并将文件下载到本地文件路径。您可以使用特殊单词“empty”在构建配置文件的路径配置中,如下面的语法所示:
({
baseUrl: "js",
name: "mainCDN",
out: "js/mainCDN-built.js",
paths: {
jquery: "empty:"
}
})
主文件将如下所示:
requirejs.config({
paths: {
'jquery': 'https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.7.1/jquery.min'
}
});
require(['jquery'], function ($) {
});
优化单个 CSS 文件
CSS 文件使用以下参数直接在命令行中进行优化,如下所示:
node ../../r.js -o cssIn = main.css out = main-built.css
CSS 文件也可以在构建文件中使用相同的属性进行优化,如下所示:
... cssIn:"main.css", out:"main-built.css" ...
以上两种方法都是允许的,并且都会创建一个名为projectfolder/css/mainbuild.css的文件。此文件将包含 main.css 的内容、正确调整的 url() 路径以及已删除的注释。
优化整个项目
优化器使用构建配置文件来优化所有css和js文件。在以下示例中,创建了build.js文件。
({
baseUrl: "js/shop",
appDir: '.',
paths: {
"jquery": "jquery",
"backbone": "backbone",
"underscore": "underscore"
},
shim: {
"backbone": {
"deps": ["underscore", "jquery"],
"exports": "Backbone"
},
"underscore": {
exports: "_"
}
},
optimizeCss: "standard.keepLines",
modules: [
{
name: "app"
}
],
dir: "../built"
})
build.js文件指示 RequireJS 将所有应用程序文件夹(appDir 参数)复制到输出文件夹 built(dir 参数),并将所有优化应用于输出文件夹中的文件。运行以下命令以在应用程序文件夹中构建配置文件:
node r.js -o build.js
RequireJS - jQuery
RequireJS 使用 jQuery 作为另一个依赖项,并将其注册为小写字母的命名模块jquery,并且默认情况下,还在使用 AMD/RequireJS 时通过全局函数$和jQuery注册自身。
加载 jQuery
require(['jquery'], function($) {
//code here
}
您可以加载多个自定义库以及 jQuery,如下所示:
require(['custom_library_path','jquery'], function(load_library,$) {
//related code of $ and load_library
});
下表显示了使用 RequireJS 指定 jQuery 依赖项的方法。
| 序号 | 类型和描述 |
|---|---|
| 1 | 使用 Shim 配置
jQuery 使用 shim 配置来定义 jQuery 插件的依赖项。 |
| 2 | 从 CDN 加载 jQuery
jQuery 使用 CDN 来定义 jQuery 插件的依赖项。 |
RequireJS - NodeJS
Node 适配器可以与 Require 和 Node 的搜索路径的实现一起使用。如果 RequireJS 未使用模块配置,则可以使用现有的基于 Node 的模块,而无需更改它们。您可以使用 npm 命令在项目的node_modules目录中安装节点包。
Node 仅从本地磁盘加载模块,并且仅在 RequireJS 加载模块时应用 map、packages、paths 等配置选项。
安装 Node
您可以使用以下命令安装 Node 适配器,该命令将安装最新的发行版文件:
npm install requirejs
您也可以通过以下方式安装 Node:
Node 的用法
要使用 node,您需要拥有require('requirejs')并将require函数在配置中移动到顶层 main.js 文件。
例如:
var requirejs = require('requirejs');
requirejs.config({
//load the mode modules to top level JS file
//by passing the top level main.js require function to requirejs
nodeRequire: require
});
requirejs(['name1', 'name2'],
function (name1, name2) {
//by using requirejs config, name1 and name2 are loaded
//node's require loads the module, if they did not find these
}
);
使用 AMD 或 RequireJS 构建节点模块
您可以使代码模块与 RequireJS 和 Node 一起工作,而无需库的用户,然后使用amdefine包来完成此工作。
例如:
if (typeof define !== 'function') {
var define = require('amdefine')(module);
}
define(function(require) {
var myval = require('dependency');
//The returned value from the function can be used
//as module which is visible to Node.
return function () {};
});
优化器作为节点模块
节点模块使用 RequireJS 优化器作为optimize方法,通过使用函数调用而不是使用命令行工具。
例如:
var requirejs = require('requirejs');
var config = {
baseUrl: '../directory/scripts',
name: 'main',
out: '../build/main-built.js'
};
requirejs.optimize(config, function (buildResponse) {
//The text output of the modules specify by using buildResponse
//and loads the built file for the contents
//get the optimized file contents by using config.out
var contents = fs.readFileSync(config.out, 'utf8');
}, function(err) {
//code for optimization err callback
});
RequireJS - Dojo
Dojo 是一个基于 AMD 模块架构的 JavaScript 工具包,它提供额外的模块来为 Web 应用程序添加额外功能,并节省 Web 应用程序开发过程中的时间和规模。
示例
以下示例显示了 Dojo 与 RequireJS 一起使用的用法。创建一个名为index.html的 html 文件,并将以下代码放在其中:
<!DOCTYPE html>
<html>
<head>
<title>RequireJS Dojo</title>
<script data-main="app" src="lib/require.js"></script>
</head>
<body>
<h2>RequireJS Dojo</h2>
<p>
Hello... ...
</p>
</body>
</html>
创建一个名为app.js的js文件,并在其中添加以下代码:
require ({
//You can configure loading modules from the lib directory
baseUrl: 'lib',
paths: {
//mapping of package
dojo: 'http://sfoster.dojotoolkit.org/dojobox/1.7-branch/dojo'
}
}, [
//modules which we are using here
'dojo/dom'
], function(dom) {
//using the 'byId' method from dom module
var mydojo = dom.byId('dojo_val')
mydojo.innerHTML = "The text is displaying via dojo/dom";
}
);
输出
在浏览器中打开 HTML 文件;您将收到以下输出:
RequireJS - CommonJS
模块格式由 CommonJS 定义。它在不提供浏览器与其他 JavaScript 环境相同选项的情况下定义。因此,CommonJS 规范推荐传输格式和异步 require。您可以轻松地转换传统的 CommonJS 模块格式以与 RequireJS 一起使用。但是,并非所有模块都将转换为新格式。一些例外情况如下:
- 具有条件代码以执行 require 调用的模块。
- 具有循环依赖关系的模块。
手动转换
CommonJS 模块可以使用以下语法手动转换为 RequireJS 格式:
define(function(require, exports, module) {
//place CommonJS module content here
});
转换工具
CommonJS 模块可以使用r.js 项目转换器工具转换为 RequireJS 格式,该工具内置于r.js文件中。您应该指定要转换的文件的路径和输出文件夹,如下所示:
node r.js -convert path/to/commonjs/modules/ path/to/output
设置导出值
CommonJS 中的一些系统允许通过将导出值分配为module.exports来设置导出值,但 RequireJS 支持更简单的从传递给 define 的函数中返回值的方法。这样做的好处是您不需要 exports 和 module 函数参数,因此您可以像下面这样将它们从模块定义中删除:
define(function (require) {
var name = require('name');
//Define the module as exporting a function
return function () {
name.doSomething();
};
});
替代语法
指定依赖项的另一种方法是通过依赖项数组参数define()。但是,依赖项数组中名称的顺序应与传递给定义函数define()的参数顺序匹配,如下所示:
define(['name'], function (name) {
return function () {
name.doSomething();
};
});
从 CommonJS 包加载模块
要了解模块在 CommonJS 包中使用 RequireJS 加载的位置和包属性,请设置 RequireJS 配置。
优化工具
RequireJS 中存在优化工具,它可以将模块定义组合在一起,形成浏览器交付的优化包。它作为命令行工具运行,因此您可以将其用作代码部署的一部分。
RequireJS - 插件
RequireJS 包含一小组插件,这些插件允许将各种类型的资源加载为依赖项。以下是 RequireJS 中可用插件的列表:
- text
- domReady
- i18n
- CSS 加载
text
text插件用于异步加载基于文本的资源,主要用于将 HTML 内容插入 JavaScript 文件中。当您在任何 require 或 define 模块调用中使用text!前缀并将文件扩展名传递给插件时,可以加载它。与正常的模块加载相比,text插件使用 XHR 加载模块,并且不会将代码作为script标签添加到标题中。
文本文件资源可以作为代码中的依赖项包含在内,如下所示:
require(["mymodule", "text!mymodule.html", "text!mymodule.css"],
function(mymodule, html, css) {
//the html and css variables will be the text
//of the mymodule.html file and mymodule.css files respectively
}
);
domReady
RequireJS 可用于在 DOM 准备好之前加载脚本,开发人员仅在脚本完全加载后才能与 DOM 交互。有时,脚本可以在 DOM 准备好之前加载。因此,为了克服此问题,RequireJS 提供了一种现代方法,称为DOMContentLoaded事件,该事件在 DOM 准备好后调用 domReady 函数。
require(['domReady'], function(domReady) {
domReady(function() {
//the domReady function is called when DOM is ready
//which is safe to manipulate DOM nodes in this function
});
});
i18n
它可以与提供i18n捆绑包支持的多个语言环境一起使用,这些捆绑包将在模块或依赖项指定“i18n!”前缀时自动加载。要使用此功能,请下载它并将其放在主 JavaScript 文件所在的同一目录中。将此插件放在名为“nls”的目录中以找到您的本地化文件。
例如,假设我们有一个名为country.js的 js 文件,其内容如下,并将其放在mydirectory/nls/country.js目录中:
define({
"root": {
"india": "india",
"australia": "australia",
"england": "england"
}
});
您可以通过使用fr-fr语言环境向文件添加特定的翻译,以上代码将更改为:
define({
"root": {
"title": "title",
"header": "header",
"description": "description"
},
"es-es": true
});
接下来,在mydirectory/nls/es-es/country.js处指定具有以下内容的文件:
define({
"root": {
"title": "título",
"header": "cabecera",
"description": "descripción"
},
"es-es": true
});
您可以通过在main.js文件中使用模块配置将其传递给插件来设置语言环境,如下所示:
requirejs.config({
config: {
//set the config for the i18n plugin
i18n: {
locale: 'es-es'
}
}
});
使用 RequireJS 加载 CSS
您可以使用一些插件通过简单地附加到标题链接来加载 CSS 文件以加载 CSS 文件。
可以使用您自己的函数加载 CSS,如下所示:
function myCss(url) {
var mylink = document.createElement("mylink");
mylink.type = "text/css";
mylink.rel = "stylesheet";
mylink.href = url;
document.getElementsByTagName("head")[0].appendChild(mylink);
}