首页 >web前端 >js教程 >用requirej构建图书馆

用requirej构建图书馆

Christopher Nolan
Christopher Nolan原创
2025-02-21 09:59:12862浏览

Building a Library with RequireJS

关键要点

  • RequireJS是一个用于浏览器的AMD模块加载器,它异步加载脚本和CSS文件,管理依赖项并构建代码结构。它还包含一个用于生产环境的优化工具。
  • 使用RequireJS时,代码需要包装在模块定义中。模块可以在其他模块中被引用,所有依赖项都将在模块本身加载之前加载。
  • RequireJS优化器r.js可以配置为将所有模块构建到单个文件中。此配置还可以使模块成为独立的全局库,既可以作为AMD模块使用,也可以在浏览器中作为全局导出使用。
  • RequireJS可用于构建库以及使用该库的应用程序。此过程涉及定义和使用AMD模块、配置r.js优化器以及在浏览器中配置RequireJS,从而生成结构良好且组织有序的代码。

RequireJS是一个用于浏览器的AMD模块加载器,可以异步加载脚本和CSS文件。您不再需要处理单个文件(例如index.html)中脚本文件的顺序。相反,您只需将代码包装在模块定义中,RequireJS将负责依赖项管理,使您的代码结构更清晰,组织更合理。它还有一个优化工具,可以压缩和连接用于生产环境的文件。

官方网站提供了关于其API的详尽文档,并且有很多示例代码库可以帮助您。但是,它有很多配置,一开始使用RequireJS会比较棘手。

在本文中,我们将学习如何通过使用AMD模块构建库、对其进行优化并使用RequireJS优化器将其导出为独立模块来使用RequireJS。稍后,我们将使用RequireJS构建应用程序并使用我们的库。

本教程假设您对RequireJS有一定的了解。如果您正在寻找入门指南,请查看:理解RequireJS以实现有效的JavaScript模块加载。

安装RequireJS

RequireJS可通过bower安装:

<code class="language-bash">bower install requirejs --save</code>

或者您可以从github获取文件。

还有一个基于Grunt的Yeoman生成器用于RequireJS项目。

定义AMD模块

我们将代码包装在define()中,这将使其成为一个AMD模块。

文件:mylib.js

<code class="language-javascript">define(['jquery'], function($) {
    // $现在是jquery。

    return 'mylib';
});</code>

就是这样。请注意,define()接受一个可选的第一个参数,即依赖项数组,在本例中为['jquery']。它是此模块的依赖项列表。数组中的所有模块都将在此模块之前加载。执行此模块时,参数是依赖项数组中的相应模块。

因此,在本例中,将首先加载jQuery,然后将其作为参数$传递到函数中,然后我们可以在模块中安全地使用它。最后,我们的模块返回一个字符串。返回值是在需要此模块时传递给函数参数的内容。

引用其他模块

让我们通过定义第二个模块并引用我们的第一个模块mylib.js来看看它是如何工作的。

文件:main.js

<code class="language-bash">bower install requirejs --save</code>

您可以在依赖项数组中引用任意数量的依赖项,并且所有模块都将按相同的顺序通过函数参数提供。在这个第二个模块中,我们引用了jquery和mylib模块,并简单地返回了一个对象,公开了某些变量。此库的用户将使用此对象作为您的库。

配置RequireJS优化器:r.js

您可能想知道,RequireJS仅通过查看依赖项数组中的字符串如何知道要加载哪个文件?在我们的例子中,我们提供了jquery和mylib作为字符串,RequireJS知道这些模块在哪里。mylib很简单,它是mylib.js,省略了.js。

jquery呢?这就是RequireJS配置的用途。您可以通过RequireJS配置提供广泛的配置。有两种方法可以提供此配置,因为我们使用的是RequireJS优化器,我将向您展示r.js方法。r.js是RequireJS优化器。

我们将向r.js提供一个配置,它将所有模块优化到单个文件中。我们提供的配置将使r.js将模块构建为独立的全局库,既可以作为AMD模块使用,也可以在浏览器中作为全局导出使用。

r.js可以通过命令行或作为Node模块运行。还有一个用于运行优化器的Grunt任务grunt-requirejs。

话虽如此,让我们看看我们的配置是什么样的:

文件:tools/build.js

<code class="language-javascript">define(['jquery'], function($) {
    // $现在是jquery。

    return 'mylib';
});</code>

配置文件实际上是RequireJS的核心。一旦您了解了这些参数的工作原理,您就可以像专业人士一样使用RequireJS。

您可以执行不同的操作,并使用配置文件调整项目构建。要了解有关配置和RequireJS的一般信息,建议您参考文档和wiki。还有一个示例配置文件,演示了如何使用构建系统,因此请务必也参考该文件。

最后,我们实际上运行了优化器。正如我之前所说,您可以通过命令行或Node以及Grunt任务运行它。请参阅r.js自述文件以了解如何在不同的环境中运行优化器。

<code class="language-javascript">define(['jquery', 'mylib'], function($, mylib) {
    // $照常是jquery
    // mylib是字符串`mylib`,因为这是第一个模块的返回值
    //

    return {
        version: '0.0.1, jQuery版本:' + $.fn.jquery,
        mylibString: mylib
    }
});</code>

这将在dist/mylib.js中生成构建文件

build.js

接下来,让我们看看这些参数的实际含义。

baseUrl – 所有模块查找的根路径。

paths – 相对于baseUrl的模块名称的路径映射。

在我们的示例中,“mylib”映射到“../main”,它相对于baseUrl,因此当我们引用“mylib”时,它加载文件“../lib/../mylib/main.js”。请注意,我们附加了baseUrl,然后是paths设置,然后是模块名称,后跟.js后缀。您可以在其中指定模块如何映射到文件,例如jquery和mylib。

include – 我们想要包含在优化过程中的模块。包含的模块所需的依赖项会隐式包含。在我们的例子中,main模块依赖于mylib和jquery,它们也将被包含在内,因此无需显式包含它。我们还包含稍后将提到的almond。

exclude – 我们想要从优化过程中排除的模块。在我们的例子中,我们排除了jquery。构建库的使用者将提供一个jQuery库。稍后我们将看到这一点。

out – 优化的输出文件的名称。

wrap – 将构建包包装在wrap指定的开始和结束文本中。优化的输出文件如下所示:wrap.start 包含的模块 wrap.end。wrap.start和wrap.end是其内容包含在输出中的文件名称。

almond

构建的库不包含require.js文件,而是使用almond。almond是一个小型AMD API实现,它将替换require.js。

包装我们的库

在r.js配置中,我们使用wrap.start和wrap.end文件包装了我们的库。我们还在库中包含了almond,这些将使我们的库独立,因此它们可以通过浏览器全局变量使用,也可以通过requirejs作为AMD模块使用。

文件:wrap.start

<code class="language-bash">bower install requirejs --save</code>

我们包含的模块main、mylib和almond位于wrap.start和wrap.end的中间。

文件:wrap.end

<code class="language-javascript">define(['jquery'], function($) {
    // $现在是jquery。

    return 'mylib';
});</code>

如果使用者使用AMD加载器,则构建的文件将请求“jquery”作为AMD依赖项。如果使用者只使用浏览器全局变量,则库将获取$全局变量并将其用于jQuery依赖项。

使用RequireJS使用库

我们的库已经完成了,现在让我们通过构建一个requirejs应用程序来实际使用它。

文件:app.js

<code class="language-javascript">define(['jquery', 'mylib'], function($, mylib) {
    // $照常是jquery
    // mylib是字符串`mylib`,因为这是第一个模块的返回值
    //

    return {
        version: '0.0.1, jQuery版本:' + $.fn.jquery,
        mylibString: mylib
    }
});</code>

这里没有什么特别的,它只是另一个引用jQuery和mylib的模块。当使用define定义模块时,它不会立即执行,也就是说,它的回调函数(在依赖项数组之后传递)不会立即执行。这意味着我们的应用程序不会仅仅通过定义此模块而启动。现在让我们看看如何配置RequireJS并实际执行这个模块,即我们的应用程序。

为浏览器配置RequireJS

我们将在一个文件中配置RequireJS并执行我们的app模块。不过,也有不同的方法可以做到这一点。

文件:common.js

<code class="language-javascript">{
  "baseUrl": "../lib",
  "paths": {
    "mylib": "../main"
  },
  "include": ["../tools/almond", "main"],
  "exclude": ["jquery"],
  "out": "../dist/mylib.js",
  "wrap": {
    "startFile": "wrap.start",
    "endFile": "wrap.end"
  }
}</code>

baseUrl和paths配置与之前相同。这里附加的配置值是:

shim: 配置传统“浏览器全局”脚本的依赖项和导出,这些脚本不使用define()来声明依赖项并设置模块值。例如,Backbone不是AMD模块,但它是一个浏览器全局变量,它将Backbone导出到我们已在exports中指定的全局命名空间。在我们的示例中,模块还依赖于jQuery和Underscore,因此我们使用deps指定它。deps数组中的脚本在加载Backbone之前加载,加载后,exports值将用作模块值。

请注意,您也可以在此应用程序项目中使用r.js,这将需要单独的配置。但不要为此感到困惑。我不会详细介绍如何操作,但这与我们对库所做的类似。请参阅示例构建配置以了解更多信息。

require与define

稍后我们将使用require加载模块并立即执行它。有时define和require可能会混淆使用哪个。define定义一个模块,但不执行它,require定义一个模块并执行它——也就是说,它在执行自身之前加载并执行依赖模块。通常,您将有一个require作为主入口模块,它将依赖于通过define定义的其他模块。

加载脚本

通常,您会在index.html中包含所有脚本文件。现在我们使用RequireJS,我们只需要包含RequireJS并指定我们的data-main,它是我们应用程序的入口点。设置配置选项或分离在index.html中使用的主模块的方法有很多种。您可以在此处找到更多信息。

<code class="language-bash">bower install requirejs --save</code>

结论

在本文中,我们使用RequireJS构建了一个库和一个使用该库的应用程序。我们学习了如何配置r.js优化器以及如何在浏览器中配置RequireJS。最后,我们学习了如何使用RequireJS定义和使用AMD模块。这使我们的代码结构良好且组织有序。

在本教程的前半部分(配置优化器),我使用了这个example-libglobal存储库,后半部分并不复杂,因此您现在应该能够自己动手了。

官方RequireJS网站是最终文档,但请务必查看github上的示例存储库以及该存储库中的示例项目,这些项目演示了RequireJS应用程序的使用。

关于使用RequireJS构建库的常见问题解答(FAQ)

RequireJS在JavaScript开发中的主要目的是什么?

RequireJS是一个JavaScript文件和模块加载器。它针对浏览器使用进行了优化,但也可以在其他JavaScript环境中使用。RequireJS的主要目的是鼓励在JavaScript中使用模块化编程。它帮助开发人员管理JavaScript文件之间的依赖关系并模块化其代码。这导致更好的代码组织、可维护性和可重用性。它还可以提高代码的速度和质量。

RequireJS如何处理JavaScript文件依赖关系?

RequireJS使用异步模块定义 (AMD) API 来处理 JavaScript 模块。这些模块可以异步加载,这意味着它们不会阻塞其他脚本在加载时运行。当您使用 RequireJS 定义模块时,您会指定其依赖项。然后,RequireJS 会确保在模块本身之前加载这些依赖项。

如何使用RequireJS定义模块?

要在RequireJS中定义模块,您可以使用define()函数。此函数接受两个参数:一个依赖项数组和一个工厂函数。依赖项是模块所依赖的文件的路径。工厂函数是您编写模块代码的地方。一旦所有依赖项都加载完毕,就会调用此函数。

如何在代码中使用用RequireJS定义的模块?

要使用用RequireJS定义的模块,您可以使用require()函数。此函数接受两个参数:一个依赖项数组和一个回调函数。依赖项是您要使用的模块的路径。回调函数是您使用模块的地方。一旦所有模块都加载完毕,就会调用此函数。

我可以将RequireJS与其他JavaScript库(如jQuery)一起使用吗?

是的,您可以将RequireJS与其他JavaScript库(如jQuery)一起使用。RequireJS有一个内置功能,用于加载不使用define()来声明依赖项并设置模块值的传统非模块化脚本,称为“shim”。使用shim,您可以为不使用define()来声明依赖项和设置模块值的脚本指定依赖项和导出。

如何使用RequireJS优化我的代码?

RequireJS带有一个名为r.js的优化工具。此工具将您的JavaScript文件及其依赖项组合并压缩到单个文件中。这减少了HTTP请求的数量和文件的大小,这可以大大提高网页的加载时间。

RequireJS中define()和require()的区别是什么?

define()函数用于定义模块,而require()函数用于加载模块。这两个函数都接受一个依赖项数组和一个函数作为参数。但是,传递给define()的函数用于创建模块值,而传递给require()的函数用于在模块加载后运行代码。

我可以在Node.js中使用RequireJS吗?

是的,您可以在Node.js中使用RequireJS。但是,Node.js有自己的模块系统,因此您可能不需要RequireJS。如果您想在浏览器和Node.js中都使用相同的代码,或者如果您更喜欢AMD API,那么RequireJS可能是一个不错的选择。

如何处理RequireJS中的错误?

RequireJS提供了一个onError回调来处理错误。当加载模块时出现错误时,会调用此回调。您可以使用此回调来记录错误或从中恢复。

我可以使用RequireJS加载CSS文件吗?

是的,您可以使用require-css插件使用RequireJS加载CSS文件。此插件允许您加载和等待CSS文件,就像您使用JavaScript模块一样。

以上是用requirej构建图书馆的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn