理解用requireJs 来实现javascript的模块化加载

这是我看到的一片关于requirejs的初学者的文章,写的不错,下面结合自己的理解记录一下:

原文:http://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/

Modular programming is used to break large applications into smaller blocks of manageable code. Module based coding eases the effort for maintenance and increases reusability. However, managing dependencies between modules is a major concern developers face throughout the application development process. RequireJS is one of the most popular frameworks around for managing dependencies between modules. This tutorial examines the need for modularized code, and shows how RequireJS can help.

Loading JavaScript Files

Large applications often require a number of JavaScript files. Generally, they are loaded one by one using<script> tags. Additionally, each file can potentially be dependent on other files. The most common example would be jQuery plugins, which are all dependent upon the core jQuery library. Therefore, jQuery must be loaded before any of its plugins. Let’s look at a simple example of JavaScript file loading in real applications. Assume we have the following three JavaScript files.

purchase.js

function purchaseProduct(){
  console.log("Function : purchaseProduct");

  var credits = getCredits();
  if(credits > 0){
    reserveProduct();
    return true;
  }
  return false;
}

  products.js

function reserveProduct(){
  console.log("Function : reserveProduct");

  return true;
}

  credits.js

function getCredits(){
  console.log("Function : getCredits");

  var credits = "100";
  return credits;
}

  In this example, we are trying to purchase a product. First, it checks whether enough credits are available to purchase the product. Then, upon credit validation, it reserves the product. Another script, main.js, initializes the code by calling purchaseProduct(), as shown below.

var result = purchaseProduct();

  

What Can Go Wrong?

In this example, purchase.js depends upon both credits.js and products.js. Therefore, those files need to be loaded before calling purchaseProduct(). So, what would happen if we included our JavaScript files in the following order?

<script src="products.js"></script>
<script src="purchase.js"></script>
<script src="main.js"></script>
<script src="credits.js"></script>

  Here, initialization is done before credits.js is loaded. This will result in the error shown below. And this example only requires three JavaScript files. In a much larger project, things can easily get out of control. That’s where RequireJS comes into the picture.

Introduction to RequireJS

RequireJS is a well known JavaScript module and file loader which is supported in the latest versions of popular browsers. In RequireJS we separate code into modules which each handle a single responsibility. Additionally, dependencies need to be configured when loading files. Let’s get started by downloadingRequireJS. Once downloaded, copy the file to your project folder. Let’s assume our project’s directory structure now resembles the following image.

All the JavaScript files, including the RequireJS file, are located inside the scripts folder. The filemain.js is used for initialization, and the other files contain application logic. Let’s see how the scripts are included inside the HTML file.

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

  This is the only code required to include files using RequireJS. You might be wondering what happened to the other files and how they are included. The data-main attribute defines the initialization point of the application. In this case, it is main.js. RequireJS uses main.js to look for other scripts and dependencies. In this scenario all the files are located in same folder. Using logic, you can move the files to any folder you prefer. Now, let’s take a look at main.js.

require(["purchase"],function(purchase){
  purchase.purchaseProduct();
});

  

In RequireJS, all code is wrapped in require() or define() functions. The first parameter of these functions specifies dependencies. In the previous example, initialization is dependent on purchase.js, since it defines purchaseProduct(). Note that the file extension has been omitted. This is because RequireJS only considers .js files.

The second parameter to require() is an anonymous function which takes an object that is used to call the functions inside the dependent file. In this scenario, we have just one dependency. Multiple dependencies can be loaded using the following syntax.

require(["a","b","c"],function(a,b,c){
});

  

Creating Applications with RequireJS

In this section we are going to convert the plain JavaScript example discussed in the previous section into RequireJS. We already covered main.js, so let’s move on to the other files.

purchase.js

define(["credits","products"], function(credits,products) {

  console.log("Function : purchaseProduct");

  return {
    purchaseProduct: function() {

      var credit = credits.getCredits();
      if(credit > 0){
        products.reserveProduct();
        return true;
      }
      return false;
    }
  }
});

  

First, we declare that purchase functionality depends on credits and products. Inside the return statement, we can define the functions of each module. Here, we have called the getCredits() andreserveProduct() functions on the objects passed. product.js and credits.js are similar, and are shown below.

products.js

define(function(products) {
  return {
    reserveProduct: function() {
      console.log("Function : reserveProduct");

      return true;
    }
  }
});

  credits.js

define(function() {
  console.log("Function : getCredits");

  return {
    getCredits: function() {
      var credits = "100";
      return credits;
    }
  }
});

  

Both of these files are configured as independent modules – meaning they are not dependent on anything. The important thing to notice is the use of define() instead of require(). Choosing betweenrequire() or define() depends on the structure of your code, and will be discussed in the following section.

Using require() vs. define()

Earlier I mentioned that we can use both require() and define() to load dependencies. Understanding the difference between those two functions is essential to managing dependencies. The require() function is used to run immediate functionalities, while define() is used to define modules for use in multiple locations. In our example we need to run the purchaseProduct() function immediately. So, require()was used inside main.js. However, the other files are reusable modules and therefore use define().

Why RequireJS is Important

In the plain JavaScript example, an error was generated due to the incorrect order of file loading. Now, delete the credits.js file in the RequireJS example and see how it works. The following image shows the output of the browser inspection tool.

The difference here is that no code has been executed in the RequireJS example. We can confirm it since nothing is printed on the console. In the plain JavaScript example we had some output printed on the console before generating the error. RequireJS waits until all the dependent modules are loaded before executing the functionality. If any modules are missing, it doesn’t execute any code. This helps us maintain the consistency of our data.

Managing the Order of Dependent Files

RequireJS uses Asynchronous Module Loading (AMD) for loading files. Each dependent module will start loading through asynchronous requests in the given order. Even though the file order is considered, we cannot guarantee that the first file is loaded before the second file due to the asynchronous nature. So, RequireJS allows us to use the shim config to define the sequence of files which need to be loaded in correct order. Let’s see how we can create configuration options in RequireJS.

requirejs.config({
  shim: {
    ‘source1‘: [‘dependency1‘,‘dependency2‘],
    ‘source2‘: [‘source1‘]
  }
});

  RequireJS allows us to provide configuration options using the config() function. It accepts a parameter called shim which we can use to define the mandatory sequences of dependencies. You can find the complete configuration guide in the RequireJS API documentation.

define(["dependency1","dependency2","source1","source2"], function() {

);

  Under normal circumstances these four files will start loading in the given order. Here, source2 depends onsource1. So, once source1 has finished loading, source2 will think that all the dependencies are loaded. However, dependency1 and dependency2 may still be loading. Using the shim config, it is mandatory to load the dependencies before source1. Hence, errors will not be generated.

Conclusion

I hope this tutorial helps you get started with RequireJS. Although it seems simple, it is really powerful in managing dependencies in large scale JavaScript applications. This tutorial alone is not enough to cover all the aspects of RequireJs, so I hope you learn all the advanced configurations and techniques using the official website.

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, likeSimply JavaScript.

Comments on this article are closed. Have a question about JavaScript? Why not ask it on our forums?

时间: 2024-10-14 06:59:11

理解用requireJs 来实现javascript的模块化加载的相关文章

该如何理解AMD ,CMD,CommonJS规范--javascript模块化加载学习总结

是一篇关于javascript模块化AMD,CMD,CommonJS的学习总结,作为记录也给同样对三种方式有疑问的童鞋们,有不对或者偏差之处,望各位大神指出,不胜感激. 本篇默认读者大概知道require,seajs的用法(AMD,CMD用法),所以没有加入使用语法. 1.为何而生: 这三个规范都是为javascript模块化加载而生的,都是在用到或者预计要用到某些模块时候加载该模块,使得大量的系统巨大的庞杂的代码得以很好的组织和管理.模块化使得我们在使用和管理代码的时候不那么混乱,而且也方便了

RequireJS 模块化加载框架使用

RequireJS 是一个遵循 AMD 规范的模块化加载框架 与上文seajs一样,这里简单介绍其相关用法 同样的,首先是下载好 require.js --> http://requirejs.org/docs/download.html#requirejs AMD规范是预加载,也就是说会马上将所有模块全加载. 写法跟seajs也类似,只不过 当需要包含模块时,一般会将模块名置入第一个参数.而不是直接require  详见 (新版本的也有CMD版require包含依赖的方式,但本质还是一样,下面

RequireJS与SeaJS模块化加载示例

web应用越变的庞大,模块化越显得重要,尤其Nodejs的流行,Javascript不限用于浏览器,还用于后台或其他场景时,没有Class,没有 Package的Javascript语言变得难以管理,于是出现CommonJS项目,提出了一些规范模块化的写法,在Nodejs中普遍应用,同样浏览器端也出现了类似的解决方案,并结合浏览器异步加载的特性,有RequireJS提出的AMD(Asynchronous Module Definition)规范,以及SeaJS提出的CMD(Common Modu

再唠叨JS模块化加载之CommonJS、AMD、CMD、ES6

Javascript模块化编程,已经成为一个迫切的需求.理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块. Javascript社区做了很多努力,在现有的运行环境中,实现"模块"的效果. CommonJS CommonJS定义的模块分为:  模块引用(require)    模块输出(exports)       模块标识(module) CommonJS Modules有1.0.1.1.1.1.1三个版本: Node.js.SproutCore实现了 Mo

SeaJS 模块化加载框架使用

SeaJS 是一个遵循 CMD 规范的模块化加载框架 CommonJS,CMD,AMD等规范后文会提到,这里主要先了解如何在代码中使用. 如果你有使用过nodejs ,那么理解起来就容易多了. 我们通过sea.js来加载我们定义的模块(这会儿遵循CMD规范)并使用相应的数据. 首先,当然是要下载sea.js,可以直接去http://seajs.org/docs/#downloads 直接下载代码包,解压后 在 /dist/目录下可以 找到 sea.js CMD规范是懒加载,按需加载,也就是在re

document.ready和onload的区别——JavaScript文档加载完成事件

文章转自:http://blog.csdn.net/kk5595/article/details/5713209 页面加载完成有两种事件,一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件),二是onload,指示页 面包含图片等文件在内的所有元素都加载完成.(可以说:ready 在onload 前加载!!!) 我的理解: 一般样式控制的,比如图片大小控制放在onload 里面加载; 而:jS事件触发的方法,可以在ready 里面加载; 更多内容戳这里:http://blog.

如何构建一个微型的CMD模块化加载器

前言 前端模块化是一个老生常谈的话题,模块化的好处是不言而喻,比如易于代码复用.易于维护.易于团队开发d等云云.对于前端模块加载器,以前仅仅止步于会用的阶段,为了加深对前端模块化的理解,大概花了一周的时间来学习.调研并尝试自己实现一个简易版的符合CMD规范的加载器. 设计 加载器是按照CMD规范进行设计的,具体的CMD规范就不列出了,详情请见CMD规范. 入口函数 use(ids, callback) 模块定义函数 define(factory) 模块加载函数 require(id) 取得模块接

收藏文章 写的很好 可惜有些还是看看不懂额。。。RequireJS进阶:模块的定义与加载

文 RequireJS进阶:模块的定义与加载 javascript requirejs 两仪 2014年12月01日发布 推荐 4 推荐 收藏 15 收藏,6.9k 浏览 概述 模块不同于传统的脚本文件,它良好地定义了一个作用域来避免全局名称空间污染.它可以显式地列出其依赖关系,并以函数(定义此模块的那个函数)参数的形式将这些依赖进行注入,而无需引用全局变量.RequireJS的模块是模块模式的一个扩展,其好处是无需全局地引用其他模块. RequireJS的模块语法允许它尽快地加载多个模块,虽然

webdriver定位页面元素时使用set_page_load_time()和JavaScript停止页面加载

原文:https://my.oschina.net/u/2344787/blog/400507?p={{page}} 引言: 在使用webdriver的get方法打开页面时,可能页面需要加载的元素较多导致加载时间很长,而时间过长会导致后面的操作无法进行,甚至直接报错:所以在页面加载到一定时间,实际需要定位的元素很大可能上已经加载出来时,需要停止页面的加载,进而进行下面的操作: 例如:get 汽车之家页面时会等待很长时间,其实页面基本元素都已加载,可进行后续操作 可以通过set_page_load