requirejs は JavaScript ファイルおよびモジュール ローダーです。 requireJS を使用すると、各モジュール間の依存関係を管理しながら、JavaScript コードをファイルとモジュールに分離できます。
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 つの問題を解決するために生まれました:
js ファイルの非同期読み込みを実現して、Web ページの応答が失われないようにします。
コードの作成とメンテナンスを容易にするために、モジュール間の依存関係を管理します。
2. require.js の読み込み
require.js を使用するための最初のステップは、公式 Web サイトから最新バージョンをダウンロードすることです。
ダウンロード後、jsサブディレクトリ配下に置くと読み込めると思われます。
このファイルを読み込むと Web ページが応答しなくなる可能性があると考える人もいるかもしれません。解決策は 2 つあります。
async 属性は、Web ページが応答しなくなるのを避けるために、このファイルを非同期でロードする必要があることを示します。 IE はこの属性をサポートしておらず、defer のみをサポートしているため、defer とも記述されます。
data-main 属性は、Web プログラムのメイン モジュールを指定するために使用されます。
上記の例では、js ディレクトリ内の main.js が最初に require.js によって読み込まれます。 require.js のデフォルトのファイル拡張子は js であるため、main.js は main と省略できます。
require.js をロードしたら、次のステップは独自のコードをロードすることです。独自のコード ファイルが main.js であり、これも js ディレクトリの下に配置されていると仮定します。次に、次のように記述します:
<script src="js/require.js" data-main="js/main"></script>
1つはWebページの下部にロードすること、もう1つは次のように記述することです:
<script src="js/require.js" defer async="true" ></script>
メインモジュールの書き方
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、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" } });
上記のコードは、デフォルトでは、パスは main.js (js サブディレクトリ) と同じディレクトリにあります。これらのモジュールが js/lib ディレクトリなどの他のディレクトリにある場合、モジュールを記述する方法は 2 つあります。
1 つは、パスを 1 つずつ指定することです。
require.config({ baseUrl: "js/lib", paths: {"jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min"} });
もう一つは、ベースディレクトリ(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(['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结构加载完成后再运行。
require(['domready!'], function (doc) { // called once the DOM is ready });
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文件
本篇介绍了用前端js模块化编写require.js,想要更多相关学习内容请关注php中文网。
相关推荐:
以上がフロントエンドjsでrequire.jsをモジュール化する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。