Require.jsとDOMで<script>要素を作成するだけの違いは何ですか?[閉まっている]


138

<script>DOMで要素を作成するだけでRequire.JSとamdを使用する場合の違いは何ですか?

Require.JSについての私の理解は、依存関係をロードする機能を提供するということですが、これは<script>、必要な外部JSファイルをロードする要素を作成することによって簡単に行うことはできませんか?

たとえば、私が関数を持っているとしましょう。doStuff()これには関数が必要needMe()です。doStuff()は外部ファイルdo_stuff.jsneedMe()あり、は外部ファイルにありますneed_me.js

これをRequire.JSの方法で行います。

define(['need_me'],function(){
    function doStuff(){
        //do some stuff
        needMe();
        //do some more stuff
    }
});

これを行うには、単にスクリプト要素を作成します。

function doStuff(){
    var scriptElement  = document.createElement('script');
    scriptElement.src = 'need_me.js';
    scriptElement.type = 'text/javascript';
    document.getElementsByTagName('head')[0].appendChild(scriptElement);

    //do some stuff
    needMe();
    //do some more stuff
}

これらは両方とも機能します。ただし、2番目のバージョンでは、すべてのRequire.jsライブラリをロードする必要はありません。機能的な違いは特にありません...


1
ブラウザのキャッシュはどうですか、requirejsはそれを妨害しますか?
Muhammad Umer、2015年

2つの非常に類似したものの違いを求めているので、これを再開します。それ客観的に答えることができます、そして、私はそれがどこに意見が結びつくかを見ません。
RamenChef 2017年

回答:


43

これがajaxian.comの優れた記事で、なぜそれを使うのかについてです:

RequireJS:非同期JavaScriptロード

  • ある種の#include / import / require
  • ネストされた依存関係をロードする機能
  • 開発者にとって使いやすいが、展開を支援する最適化ツールに支えられている

2
私はそれらを読んだことがありましたが、それについてもっと考えたところで、ネストされた依存関係のアイデアは、単に<script>タグを書くだけでは達成できないことに気づきました。ありがとう。
maxedison、2011

37
「開発者にとっての使いやすさ」は、真実から遠くあり得ません。あなたやそのプロジェクトに参加する他の誰にとっても、それは間違いなく急な学習曲線を持っています。
Sahat Yalkabov 2013

3
@TwilightPony自分はそれほど明るくなく、requirejsは私にとって難しいことではなかったと思います。依存関係を心配する必要がなくなり、ページの速度が上がります。あなたのコードは、依存関係をどのように宣言するかという点で、サーバー側プログラミングとよりインラインになります。構文は最小限であり、設計によってクロージャ化されていたので、スクリプトを簡単に組み合わせるためのプロダクションのロードマップが設定されました。その上、デバッグは静的宣言のようなものです。それよりも簡単なことはわかりません。私が他の方法をやったのと同じように、他の方法はずっと難しくなります。
Jason Sebring

苦労しています。特に、グローバルオブジェクトに接続しようとするモジュールの場合。(Reactモジュール)...
geilt 2015

1
そのページのコメントは実際に、必要から逃げるべきではなく逃げるべきだと感じました。特にstevesouders.com/tests/require.phpに
Dave Kanter

52

DOMで要素を作成するだけの場合と比較して、Require.JSにはどのような利点がありますか?

この例では、スクリプトタグを非同期で作成しています。つまり、need_me.jsファイルの読み込みが完了する前にneedMe()関数が呼び出されます。これにより、関数が定義されていないキャッチされない例外が発生します。

代わりに、提案していることを実際に機能させるには、次のようにする必要があります。

function doStuff(){
    var scriptElement  = document.createElement('script');
    scriptElement.src = 'need_me.js';
    scriptElement.type = 'text/javascript';

    scriptElement.addEventListener("load", 
        function() { 
            console.log("script loaded - now it's safe to use it!");

            // do some stuff
            needMe();
            //do some more stuff

        }, false);

    document.getElementsByTagName('head')[0].appendChild(scriptElement);

}

おそらく、上記のように、RequireJSなどのパッケージマネージャーを使用するか、pure-JavaScript戦略を利用するのが最適な場合とそうでない場合があります。Webアプリケーションの読み込みは速くなりますが、サイトでの機能の呼び出しは、そのアクションが実行される前にリソースが読み込まれるのを待つ必要があるため、遅くなります。

Webアプリケーションが単一ページのアプリケーションとして構築されている場合は、実際にページを頻繁に再読み込みすることはあまりないことを考慮してください。これらの場合、すべてをプリロードすると、実際にアプリを使用するときのエクスペリエンスが速く見えるようになります。これらのケースでは、ページのヘッドまたはボディにスクリプトタグを含めるだけで、すべてのリソースを読み込むことができます。

ただし、ページからページへ遷移する従来のモデルに従ってWebサイトまたはWebアプリケーションを構築し、リソースが再ロードされる場合は、遅延読み込みアプローチがこれらの遷移の高速化に役立つ場合があります。


10

RequireJSの使用が理にかなっている他のいくつかの非常に指摘された理由:

  1. 独自の依存関係の管理は、かなりの規模のプロジェクトでは急速にバラバラになります。
  2. 小さなファイルをいくつでも持つことができ、依存関係やロード順の追跡を気にする必要はありません。
  3. RequireJSを使用すると、ウィンドウオブジェクトに触れることなく、モジュール化されたアプリ全体を作成できます。

このGistでのrmurpheyのコメントから引用

抽象化の層は、学習し、それに順応するのが悪夢になることがありますが、それが目的を果たし、うまく機能する場合、それは理にかなっています。


9
それらすべてのrequireおよびdefineステートメント、構成ファイル、AMD仕様を実装していない他のシステムやライブラリとの衝突などを管理する必要があります。node-webkitプロジェクトでRequire.JSを使用してみました。あらゆる段階で私と戦った...単純にスクリプトを特定の方法で注文することとは対照的です...もちろん、Require.JSで遅延読み込みができるので、私はそれを機能させようとしました。:)
jmort253 2014年

@ jmort253に完全に同意します。最初は苦労しましたが、今はとても気に入っています。3つのポイントはすべて正解です。ライブラリをAMD化することはそれほど難しいことではありません...またはシムを使用してください。
レジェンド

0

これはより具体的な例です。

60ファイルのプロジェクトで作業しています。それを実行する2つの異なるモードがあります。

  1. 連結されたバージョンの1つの大きなファイルをロードします。(製造)

  2. 60ファイルすべてをロード(開発)

ローダーを使用しているため、Webページにスクリプトが1つだけあります

<script src="loader.js"></script>

デフォルトはモード1です(1つの大きな連結ファイルをロードします)。モード2(個別のファイル)でinを実行するには、いくつかのフラグを設定します。それは何でもかまいません。クエリ文字列のキー。この例では、これを行います

<script>useDebugVersion = true;</script>
<script src="loader.js"></script>

loader.jsは次のようになります

if (useDebugVersion) {
   injectScript("app.js");
   injectScript("somelib.js");
   injectScript("someotherlib.js");
   injectScript("anotherlib.js");
   ... repeat for 60 files ...
} else {
   injectScript("large-concatinated.js");
}

ビルドスクリプトは、次のような.shファイルです。

cat > large-concantinated.js app.js somelib.js someotherlib.js anotherlib.js

等...

新しいファイルが追加された場合、開発を行っているため、おそらくmode#2を使用しますinjectScript("somenewfile.js")。loader.jsに行を追加する必要があります

次に、後で生産するために、ビルドスクリプトにsomenewfile.jsを追加する必要があります。忘れがちなエラーメッセージが表示される手順。

AMDに切り替えることで、2つのファイルを編集する必要がなくなります。loader.jsとビルドスクリプトを同期させる問題はなくなりました。r.jsまたはwebpackそれを使用して、ビルドするコードを読み取ることができますlarge-concantinated.js

また、依存関係も処理できます。たとえば、次のように2つのファイルlib1.jsとlib2.jsをロードしました。

injectScript("lib1.js");
injectScript("lib2.js");

lib2にはlib1が必要です。それは何かのようなコードを内部に持っています

lib1Api.installPlugin(...);

ただし、挿入されたスクリプトは非同期で読み込まれるため、正しい順序で読み込まれる保証はありません。これらの2つのスクリプトはAMDスクリプトではありませんが、require.jsを使用すると、依存関係を伝えることができます

require.config({
    paths: {
        lib1: './path/to/lib1',
        lib2: './path/to/lib2',
    },
    shim: {
        lib1: {
            "exports": 'lib1Api',
        },
        lib2: {
            "deps": ["lib1"],
        },
    }
});

私はこれを行うlib1を使用するモジュール

define(['lib1'], function(lib1Api) {
   lib1Api.doSomething(...);
});

これでrequire.jsがスクリプトを挿入し、lib2がlib1に依存することを伝えたため、lib1がロードされるまでlib2を挿入しません。また、lib2とlib1の両方がロードされるまで、lib1を使用するモジュールは開始されません。

これにより、開発がスムーズになり(ビルド手順がなく、読み込み順序を心配する必要もありません)、プロダクションが快適になります(追加されたスクリプトごとにビルドスクリプトを更新する必要がありません)。

追加のボーナスとして、webpackのbabelプラグインを使用して、古いブラウザーのコードでbabelを実行できます。この場合も、そのビルドスクリプトを維持する必要はありません。

Chrome(選択したブラウザー)がimport実際にサポートを開始した場合は、おそらく開発用に切り替えますが、実際には何も変更されません。それでも、webpackを使用して連結ファイルを作成でき、すべてのブラウザーのコードに対してbabelを実行できます。

これはすべて、スクリプトタグを使用せず、AMDを使用することで得られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.