js require.js のモジュール記述の簡単な分析

高洛峰
リリース: 2016-12-28 14:30:07
オリジナル
854 人が閲覧しました

requirejs は JavaScript ファイルおよびモジュール ローダーです。 requireJS を使用すると、各モジュール間の依存関係を管理しながら、JavaScript コードをファイルとモジュールに分離できます。

RequireJS の目標はコードのモジュール化を促進することであり、従来の「script」タグとは異なるスクリプト読み込みステップを使用します。 RequireJS を使用してモジュール式スクリプトを読み込むと、コードの読み込み速度と品質が向上します。

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 つの問題を解決するために生まれました:

Web ページが応答しなくなることを避けるために js ファイルの非同期読み込みを実現します。

コードの作成とメンテナンスを容易にするためにモジュール間の依存関係を管理します。

2. require.js の読み込み

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

ダウンロード後、jsサブディレクトリ配下に置くと読み込めると思われます。

このファイルを読み込むと Web ページが応答しなくなる可能性があると考える人もいるかもしれません。解決策は 2 つあります:

1 つは Web ページの下部にロードする方法で、もう 1 つは次のように記述することです:

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([&#39;moduleA&#39;, &#39;moduleB&#39;, &#39;moduleC&#39;], function (moduleA, moduleB, moduleC){
 // some code here
});
ログイン後にコピー

require() 関数は 2 つのパラメータを受け取ります。最初のパラメータ:

依存するモジュールを示す配列。上記の例は ['moduleA', 'moduleB', 'moduleC'] です。つまり、メイン モジュールはこれら 3 つのモジュールに依存します。関数、現在、指定されたモジュールが正常にロードされた後に呼び出されます。ロードされたモジュールはパラメータとしてこの関数に渡されるため、これらのモジュールはコールバック関数内で使用できます。

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

それでは、実際の例を見てみましょう。

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

require([&#39;jquery&#39;, &#39;underscore&#39;, &#39;backbone&#39;], function ($, _, Backbone){
    // some code here
});
ログイン後にコピー

require.js は最初に jQuery、underscore、backbone をロードしてから、コールバック関数を実行します。メインモジュールのコードはコールバック関数内に記述されます。

4. モジュールの読み込み

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

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

require.config({
 paths: {
 "jquery": "jquery.min",
 "underscore": "underscore.min",
 "backbone": "backbone.min"
 }
});
ログイン後にコピー

上記のコードは、3 つのモジュールのファイル名をデフォルトで main.js と同じディレクトリ (js サブディレクトリ) に指定します。これらのモジュールが js/lib ディレクトリなどの他のディレクトリにある場合、モジュールを記述する方法は 2 つあります。

1 つは、パスを 1 つずつ指定することです。

require.config({
 baseUrl: "js/lib",
 paths: {"jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min"}
});
ログイン後にコピー

もう 1 つは、ベース ディレクトリ (baseUrl) を直接変更する方法です。

require.config({
 baseUrl: "js/lib",
 paths: {
  "jquery": "jquery.min",
  "underscore": "underscore.min",
  "backbone": "backbone.min"
 }
});
ログイン後にコピー

モジュールが別のホスト上にある場合は、次のように URL を直接指定することもできます:

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([&#39;math&#39;], function (math){
  alert(math.add(1,1));
});
ログイン後にコピー

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

define([&#39;myLib&#39;], 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: {
  &#39;underscore&#39;: {
   exports: &#39;_&#39;
  },
  &#39;backbone&#39;: {
   deps: [&#39;underscore&#39;, &#39;jquery&#39;],
   exports: &#39;Backbone&#39;
  }
 }
});
ログイン後にコピー

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

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

shim: {
  &#39;jquery.scroll&#39;: {
    deps: [&#39;jquery&#39;],
    exports: &#39;jQuery.fn.scroll&#39;
  }
}
ログイン後にコピー

七、require.js插件

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

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

require([&#39;domready!&#39;], function (doc) {
 // called once the DOM is ready
});
ログイン後にコピー

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

define([
   &#39;text!review.txt&#39;,
   &#39;image!cat.jpg&#39;
  ],
  function (review, cat) {
   console.log(review);
   document.body.appendChild(cat);
  }
);
ログイン後にコピー

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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持PHP中文网!

更多浅析js的模块化编写 require.js相关文章请关注PHP中文网!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート