ホームページ >ウェブフロントエンド >jsチュートリアル >require.js_javascriptスキルの使い方の詳しい説明

require.js_javascriptスキルの使い方の詳しい説明

WBOY
WBOYオリジナル
2016-05-16 15:35:592024ブラウズ

1. require.js を使用する理由

初期の頃、すべての Javascript コードは 1 つのファイルに記述されており、この 1 つのファイルをロードするだけで十分でした。その後、コードがどんどん増え、1 つのファイルでは不十分になり、複数のファイルに分割して順番にロードする必要がありました。以下の Web ページのコードを見たことがある人も多いと思います。

 <script src="1.js"></script>
  <script src="2.js"></script>
  <script src="3.js"></script>
  <script src="4.js"></script>
  <script src="5.js"></script>
  <script src="6.js"></script>

このコードは複数の js ファイルを順番に読み込みます。

この書き方には大きな欠点があります。まず、ロード時にブラウザは Web ページのレンダリングを停止します。ロードされるファイルが増えると、Web ページの応答が失われる時間が長くなります。次に、js ファイル間の依存関係により、ロード順序が厳密に保証される必要があります。上記の例のように、1.js は 2.js の前に置く必要があり、依存関係が最も大きいモジュールを最後にロードする必要があります。依存関係が複雑になると、コードの記述とメンテナンスが困難になります。

require.js は、次の 2 つの問題を解決するために生まれました:

(1) Web ページの応答が失われないように、js ファイルの非同期読み込みを実装します。

(2) モジュール間の依存関係を管理して、コードの作成とメンテナンスを容易にします。

2. require.js の読み込み

require.js を使用する最初のステップは、公式 Web サイトから最新バージョンをダウンロードすることです。

ダウンロード後、jsサブディレクトリ配下に配置されロードできるものとします。

<script src="js/require.js"></script>
このファイルを読み込むと Web ページが応答しなくなる可能性があると考える人もいるかもしれません。解決策は 2 つあり、1 つは Web ページの下部にロードする方法で、もう 1 つは次のように記述することです。

<script src="js/require.js" defer async="true" ></script>
async 属性は、Web ページが応答しなくなるのを避けるために、このファイルを非同期でロードする必要があることを示します。 IE はこの属性をサポートしておらず、defer のみをサポートしているため、defer とも記述されます。

require.js をロードしたら、次のステップは独自のコードをロードすることです。独自のコード ファイルが main.js であり、これも js ディレクトリの下に配置されていると仮定します。次に、次のように書きます:

 <script src="js/require.js" data-main="js/main"></script>
data-main 属性は、Web プログラムのメイン モジュールを指定するために使用されます。上記の例では、js ディレクトリ内の main.js が、require.js によって最初に読み込まれます。 require.js のデフォルトのファイル拡張子は js であるため、main.js は main と省略できます。

3. メインモジュールの書き方 前のセクションの main.js を「メイン モジュール」と呼びます。これは Web ページ全体のエントリ コードを意味します。これは C 言語の main() 関数に似ており、すべてのコードはここから実行を開始します。

main.jsの書き方を見てみましょう。

コードが他のモジュールに依存していない場合は、JavaScript コードを直接記述できます。

// main.js

alert("読み込み成功!");


ただし、この場合、require.js を使用する必要はありません。本当に一般的な状況は、メイン モジュールが他のモジュールに依存することです。この場合、AMD 仕様で定義されている require() 関数を使用する必要があります。

// main.js
  require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
    // some code here
  });
require() 関数は 2 つのパラメータを受け入れます。最初のパラメータは配列であり、依存するモジュールを示します。上記の例は ['moduleA', 'moduleB', 'moduleC'] です。つまり、メイン モジュールはこれら 3 つのモジュールに依存します。現在、この関数は上記で指定されたすべてのモジュールが正常にロードされた後に呼び出されます。ロードされたモジュールはパラメータとしてこの関数に渡されるため、これらのモジュールはコールバック関数内で使用できます。

require() は moduleA、moduleB、および moduleC を非同期的にロードします。ブラウザは応答を失いません。指定されたコールバック関数は、前のモジュールが正常にロードされた後でのみ実行され、依存関係の問題が解決されます。

以下、実際の例を見てみましょう。

メイン モジュールが jquery、underscore、backbone の 3 つのモジュールに依存すると仮定すると、main.js は次のように記述できます:

  require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
    // some code here
  });
require.js は、まず jQuery、アンダースコア、バックボーンをロードしてから、コールバック関数を実行します。メインモジュールのコードはコールバック関数内に記述されます。

4. モジュールのロード 前のセクションの最後の例では、メイン モジュールの依存モジュールは ['jquery', 'underscore', 'backbone'] です。デフォルトでは、require.js は、これら 3 つのモジュールが main.js と同じディレクトリにあり、ファイル名がそれぞれ jquery.js、underscore.js、backbone.js であると想定し、自動的にロードします。

require.config() メソッドを使用すると、モジュールの読み込み動作をカスタマイズできます。 require.config()はメインモジュール(main.js)の先頭に記述されます。パラメータはオブジェクトであり、このオブジェクトの paths 属性は各モジュールのロード パスを指定します。

上面的代码给出了三个模块的文件名,路径默认与main.js在同一个目录(js子目录)。如果这些模块在其他目录,比如js/lib目录,则有两种写法。一种是逐一指定路径。

require.config({
    paths: {
      "jquery": "lib/jquery.min",
      "underscore": "lib/underscore.min",
      "backbone": "lib/backbone.min"
    }
  });

另一种则是直接改变基目录(baseUrl)。

require.config({
    baseUrl: "js/lib",
    paths: {
      "jquery": "jquery.min",
      "underscore": "underscore.min",
      "backbone": "backbone.min"
    }
  });

如果某个模块在另一台主机上,也可以直接指定它的网址,比如:

require.config({
    paths: {
      "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
    }
  });

require.js要求,每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。

五、AMD模块的写法

require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。

具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。

假定现在有一个math.js文件,它定义了一个math模块。那么,math.js就要这样写:

// math.js
  define(function (){
    var add = function (x,y){
      return x+y;
    };
    return {
      add: add
    };
  });

加载方法如下:

  // main.js
  require(['math'], function (math){
    alert(math.add(1,1));
  });

如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。

define(['myLib'], function(myLib){
    function foo(){
      myLib.doSomething();
    }
    return {
      foo : foo
    };
  });

当require()函数加载上面这个模块的时候,就会先加载myLib.js文件。

六、加载非规范的模块

理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如jQuery)符合AMD规范,更多的库并不符合。那么,require.js是否能够加载非规范的模块呢?回答是可以的。这样的模块在用require()加载之前,要先用require.config()方法,定义它们的一些特征。举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。

require.config({
    shim: {
      'underscore':{
        exports: '_'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }
    }
  });

require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。

比如,jQuery的插件可以这样定义:

 shim: {
    'jquery.scroll': {
      deps: ['jquery'],
      exports: 'jQuery.fn.scroll'
    }
  }

七、require.js插件

require.js还提供一系列插件,实现一些特定的功能。

domready插件,可以让回调函数在页面DOM结构加载完成后再运行。

 shim: {
    'jquery.scroll': {
      deps: ['jquery'],
      exports: 'jQuery.fn.scroll'
    }
  }

text和image插件,则是允许require.js加载文本和图片文件。

define([
    'text!review.txt',
    'image!cat.jpg'
    ],
    function(review,cat){
      console.log(review);
      document.body.appendChild(cat);
    }
  );

类似的插件还有json和mdown,用于加载json文件和markdown文件。

以上就是本文的全部所述,希望本文分享对大家有所帮助。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。