使用RequireJS构建库

RequireJS是用于浏览器的AMD模块加载器,可以异步加载脚本和CSS文件。 您不再需要处理单个文件中脚本文件的顺序(例如index.html)。 取而代之的是,您只需将代码包装在模块定义中,RequireJS将处理依赖项,从而使您的代码更加结构化和组织良好。 它还具有优化工具,该工具可以对文件进行丑化和连接,以供生产使用。

该官方站点提供有关其API的大量文档 ,并且有许多示例存储库可为您提供帮助。 但是它有很多配置,一开始需要RequireJS很难。

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

本教程假定您对RequireJS有所了解。 如果您正在寻找入门书籍 ,请查看: 了解RequireJS进行有效的JavaScript模块加载

安装RequireJS

RequireJS可通过Bower获得:

bower install requirejs --save

或者您可以在github上获取文件。

对于RequireJS项目,还有一个基于Grunt的Yeoman生成器

定义AMD模块

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

文件: mylib.js

define(['jquery'], function($) {
    // $ is jquery now.

    return 'mylib';
});

而已。 请注意, define()采用依赖项数组的可选第一个参数,在这种情况下为['jquery'] 。 这是此模块的依赖项列表。 阵列中的所有模块将在此模块之前加载。 执行此模块时,参数是依赖项数组中的相应模块。

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

需要其他模块

让我们通过定义第二个模块并要求我们的第一个模块mylib.js了解其工作原理。

文件: main.js

define(['jquery', 'mylib'], function($, mylib) {
    // $ is jquery as usual
    // mylib is the string `mylib` because that's the return value
    // from the first module

    return {
        version: '0.0.1, jQuery version: ' + $.fn.jquery,
        mylibString: mylib
    }
});

您可以在依赖项数组中根据需要选择任意多个依赖项,并且所有模块都可以通过函数参数以相同的顺序使用。 在第二个模块中,我们需要jquerymylib模块,并仅返回一个对象,并公开一些变量。 该库的用户将使用该对象作为您的库。

配置RequireJS优化器:r.js

您可能想知道,仅通过查看依赖项数组中的字符串,RequireJS如何知道要加载的文件? 在我们的例子中,我们以字符串形式提供了jquerymylib ,而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

{
  "baseUrl": "../lib",
  "paths": {
    "mylib": "../main"
  },
  "include": ["../tools/almond", "main"],
  "exclude": ["jquery"],
  "out": "../dist/mylib.js"
  "wrap": {
    "startFile": "wrap.start",
    "endFile": "wrap.end"
  }
}

配置文件确实是RequireJS的主要内容。 一旦了解了这些参数的工作原理,就可以像专业人士一样使用RequireJS。

您可以做不同的事情,并使用配置文件来调整项目构建。 要总体上了解有关配置和RequireJS的更多信息,我建议参考docsWiki 。 还有一个示例配置文件 ,演示了如何使用构建系统,因此请确保也参考该文件。

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

node tools/r.js -o tools/build.js

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

build.js

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

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

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

在我们的例子,“MYLIB”映射到“../main”,是相对于baseUrl ,所以当我们需要“MYLIB”它加载文件“../lib/../mylib/main.js”。
注意,我们附加了baseUrl ,然后是paths设置,而不是模块名称,后跟.js后缀。 您可以在此处指定如何将模块映射到jquerymylib等文件。

包含 –我们要包含在优化过程中的模块。 包含的模块所需的依赖项被隐式包含。 在我们的例子中, main模块也依赖于mylibjquery ,因此不需要显式地包含它。 我们还包括almond ,我将在后面提到。

排除 –我们要从优化过程中排除的模块。 在我们的例子中,我们排除了jquery 。 内置库的使用者将提供一个jQuery库。 以后使用我们的库时,我们会看到这一点。

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

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

杏仁

生成的库在文件中不包含require.js,而是使用杏仁。 almond是AMD API的一个小型实现,它将替换require.js。

包装我们的图书馆

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

File: wrap.start

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD.
    define(['jquery'], factory);
  } else {
    // Browser globals.
    root.mylib = factory(root.$);
  }
}(this, function($) {

我们的模块包括mainmylib ,和almond都在这里中间wrap.startwrap.end

File: wrap.end

// Register in the values from the outer closure for common dependencies
  // as local almond modules
  define('jquery', function() {
    return $;
  });

  // Use almond's special top level synchronous require to trigger factory
  // functions, get the final module, and export it as the public api.
  return require('mylib');
}));

如果使用者使用AMD加载程序,则生成的文件将要求“ jquery”作为AMD依赖项。 如果使用者仅使用浏览器全局变量,则库将获取$全局变量并将其用于jQuery依赖项。

将库与RequireJS一起使用

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

文件: app.js

define(['jquery', 'mylib'], function($, mylib) {
  // $ is jquery
  // mylib is mylib that is:
  // {
  //   version: 'version 0.0.1 jQuery version: xxx',
  //   mylib: 'mylib'
  // }
});

这里没什么好想的,它是另一个需要jQuery和mylib的模块。 当使用define模块时,不会立即执行该模块,即不会立即执行其回调函数(在依赖项数组之后传递)。 这意味着我们的应用程序不只是从定义此模块开始。 现在,让我们看看如何配置RequireJS并实际执行此模块即我们的应用程序。

为浏览器配置RequireJS

我们将配置RequireJS并在一个文件中执行我们的应用模块。 尽管有不同的方法可以做到这一点。

文件: common.js

requirejs.config({
  baseUrl: '../lib',
  paths: {
    'jquery': 'jquery/dist/jquery.min',
    'underscore': 'underscore/dist/underscore',
    'backbone': 'backbone/backbone',
    'mylib': 'mylib/dist/mylib',
    'app': '../app'
  },
  shim: {
    'jquery': {
      exports: '$'
    },
    'backbone': {
      deps: ['jquery', 'underscore'],
      exports: 'Backbone',
    },
    'underscore': {
      exports: '_'
    }
  }
});

require(['app/app'], function(App) {
  // app module is available here
  // you can start your application now
  // this is immediately called because
  // we used `require` instead of `define`
  // to define this module.
});

baseUrlpaths配置与以前相同。 此处的附加配置值为:

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

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

要求与定义

稍后,我们使用require加载模块并立即执行它。 有时,对于何时使用哪个definerequire可能会感到困惑。 define定义一个模块,但不执行它, require定义一个模块并执行它-也就是说,它在执行自身之前加载并执行相关模块。 通常,你将有一个require作为主要输入模块,将依赖于通过定义额外的模块define

加载脚本

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

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

结论

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

我在本教程的上半部分(配置优化器)中使用了这个example-libglobal存储库,下半部分并不那么复杂,因此现在应该自己动手制作它。

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

From: https://www.sitepoint.com/building-library-with-requirejs/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值