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

我们需要定义一个 html 文件为index.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
  • 下载r.js - 您可以从下载页面下载r.js文件,并从r.js存储库页面下载源代码。

RequireJS - 配置

RequireJS 可以通过data-main属性传递 HTML 模板中的主要配置来初始化。RequireJS 使用它来了解要在应用程序中加载哪个模块。

例如 -

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

要包含 Require.js 文件,您需要在 html 文件中添加 script 标签。在 script 标签内,添加data-main属性以加载模块。这可以作为您的应用程序的主要入口点。scripts /main是包含 RequireJS 配置的应用程序的主 JavaScript 文件。

配置选项

以下是加载第一个应用程序模块时可以设置的配置选项 -

  • baseUrl - 它是通过 RequireJS 加载的所有模块的路由路径。baseUrl 由以“斜杠 (/)”开头的字符串表示,包含协议并以“.js”扩展名结尾。如果没有指定baseUrl,则RequireJS使用data-main属性路径作为baseUrl。

  • paths - 它指定相对于 baseUrl 的模块的路径映射。映射模块名称时,它会自动将 .js 扩展名添加到路径中。

  • shim - 它通过配置非 AMD 库的依赖项并导出其全局值,提供 RequireJS 中非 AMD 库的使用。

  • map - 对于给定的模块,应用程序通过共享其 id 来针对不同的目标使用不同版本的相同模块,以便在不同的条件下使用相同的代码。

  • config - 它通过使用config选项为模块提供配置,这可以通过使用特殊依赖项“module”并调用其module.config()函数来完成。

  • urlArgs - 查询字符串参数用于获取使用 RequireJS 加载的所有资源。当浏览器或服务器配置不正确时,它用于清除缓存。

  • waitSeconds - 它指定在加载脚本时等待的秒数。默认值为“7”秒,“0”则禁用超时。

  • packages - 它提供了用于配置加载模块的 CommonJS 包。

  • context - 它提供上下文加载的名称,允许在页面中加载不同的模块。

  • deps - 在加载 RequireJS 之前将 Require 指定为配置对象时需要的依赖项数组。

  • 回调- 它在加载依赖项后执行一个函数,并且在加载 RequireJS 之前将 Require 指定为配置对象时需要它。

  • xhtml -当此选项设置为true时,它​​用于通过使用document.createElementNS()方法创建脚本元素。

  • scriptType - 它定义文档中使用的脚本类型属性的值。默认类型是“text/javascript”。

  • SkipDataMain - 如果此选项设置为true,则在加载模块时跳过数据主属性扫描

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.
   }
   
);

模块加载

RequireJS - 定义函数

Define ()函数可用于加载模块(模块可以是对象、函数、类或加载模块后执行的代码)。您可以在同一页面中加载同一模块的不同版本。不同的版本可以按相同的顺序进行分析,即使它们以不同的顺序加载。

句法

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.jsplayer.js的 js文件,并分别放置以下代码 -

团队.js

define({
   player: "Sachin Tendulkar",
   team : "India"
});

播放器.js

define(function (require) {
   var myteam = require("./team");

   return {
      myfunc: function () {
         document.write("Name: " + myteam.player + ", Country: " + myteam.team);
      }
   };
});

输出

在浏览器中打开 HTML 文件;您将收到如下屏幕截图所示的输出 -

RequireJS 定义函数

单击“确定”按钮,您将从模块获得另一个输出 -

RequireJS 定义函数

RequireJS - 优化器

在本章中,我们将讨论 RequireJS 中的优化。RequireJS 中的优化器具有以下特征 -

优化器是Node 和 Nashornr.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.com/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() 路径并删除注释。

优化整个项目

优化器使用构建配置文件来优化所有cssjs文件。在以下示例中,将创建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 参数)复制到构建的输出文件夹(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
});  

下表显示了 jQuery 与 RequireJS 的结合使用来指定它们的依赖关系。

先生。 类型和描述
1 使用垫片配置

jQuery 使用 shim 配置来定义 jQuery 插件的依赖项。

2 从 CDN 加载 jQuery

jQuery 使用 CDN 来定义 jQuery 插件的依赖关系。

RequireJS-NodeJS

Node 适配器可以与 Require 和 Node 的搜索路径的实现一起使用。如果 RequireJS 没有使用模块配置,您可以使用现有的基于 Node 的模块,而无需更改它们。您可以使用npm命令将节点包安装到项目的node_modules目录中。

Node 只会从本地磁盘加载模块,并且只有在 RequireJS 加载模块时才会应用配置选项,例如地图、包、路径等。

安装节点

您可以使用以下命令安装节点适配器,该命令将安装最新版本文件 -

npm install requirejs

您也可以通过以下方式安装节点 -

  • 您可以从此链接下载r.js并将其保存在您的项目文件夹中。

  • 从r.js 存储库获取源代码或通过node dist.js安装它。

节点的使用

要使用该节点,您需要有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 () {};
});

优化器作为节点模块

Node 模块使用 RequireJS 优化器作为优化方法,通过使用函数调用而不是使用命令行工具。

例如 -

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 是一个基于 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 道场

RequireJS - CommonJS

模块格式由 CommonJS 定义。它的定义没有提供与其他 JavaScript 环境相同的浏览器选项。因此,CommonJS 规范推荐了Transport 格式异步 require。您可以轻松转换传统的 CommonJS 模块格式以与 RequireJS 一起使用。但是,所有模块都不会转换为新格式。下面列出了一些例外情况 -

  • 具有执行 require 调用的条件代码的模块。
  • 具有循环依赖关系的模块。

手动转换

可以使用以下语法将 CommonJS 模块手动转换为 RequireJS 格式 -

define(function(require, exports, module) {
   //place CommonJS module content here
});

转换工具

可以使用 r.js 文件中内置的 r.js 项目转换工具将 CommonJS 模块转换RequireJS格式。您应该指定要转换的文件的路径和输出文件夹,如下所示 -

node r.js -convert path/to/commonjs/modules/ path/to/output

设置导出值

CommonJS 中的某些系统允许通过将导出值指定为module.exports来设置导出值,但 RequireJS 支持从传递给定义的函数返回值的更简单方法。这样做的优点是您不需要导出和模块函数参数,因此您可以将它们从模块定义中删除,如下所示 -

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 包加载模块

通过设置 RequireJS 配置,了解使用 RequireJS 将模块加载到 CommonJS 包中的位置和包属性。

优化工具

RequireJS 中提供了优化工具,它可以将模块定义组合到优化的捆绑包中以供浏览器交付。它作为命令行工具运行,因此您可以将其用作代码部署的一部分。

RequireJS - 插件

RequireJS 包含一小组插件,允许加载各种类型的资源作为依赖项。以下是 RequireJS 中可用插件的列表 -

  • 文本
  • 准备就绪
  • 国际化
  • CSS加载

文本

文本插件用于异步加载基于文本的资源,主要用于在 JavaScript 文件中插入 HTML 内容使用文字的时候就可以加载了!在任何 require 或 Define 模块调用中添加前缀,并将文件扩展名传递给插件。与普通模块加载相比,文本插件使用 XHR 加载模块,并且不会将代码作为脚本标签添加到标头。

文本文件资源可以作为依赖项包含在代码中,如下所示:

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
   }
);

准备就绪

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!”时,该支持将自动加载。字首。要使用它,请下载它并将其放在主 JavaScript 文件所在的同一目录中。将此插件放置在名为“nls”的目录中以查找本地化文件。

例如,假设我们有一个名为country.js的js文件,其中包含以下内容,并将其放置在mydirectory/nls/country.js目录中:

define({
   
   "root": {
      "india": "india",
      "australia": "australia",
      "england": "england"
   }
});

您可以使用fr-fr locale 将特定翻译添加到文件中,上面的代码将更改为 -

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);
}