0

次のように、クライアントサイトで使用することを目的としたjavascriptライブラリがあります。

  <script src="foo.js"></script>
  <div id="mydiv"></div>
  <script>
    (function() {
        foo(document.getElementById("mydiv");
    })();
  </script>

つまり、foo.js は、DOM 要素をパラメーターとして取得すると想定される関数 ("foo") をエクスポートします。

foo.js をいくつかの異なる「モジュール」(論理部分) に分割したいので、そのためにBroserifyまたはrequireJSを調べています。問題は、browserify (および私が見た限りでは requireJS) が foo の最上位関数をエクスポートしない場合、上記のように html ファイルから「foo」関数にアクセスできないことです。browserify を使用すると、最終的な js をビルドするときに-rオプションを使用できるようです。

browserify -r ./foo.js > bundle.js 

これにより、クライアント サイトで使用できるグローバルな要件が作成されます。ただし、このソリューションにはあまり満足していません。なぜなら、それはグローバル空間を汚染しており、私のスクリプトは他のサイトに埋め込まれているからです ( requireが衝突している可能性があります)。私はここで運が悪いのでしょうか?私は何かを逃していますか?必要なのは、開発を容易にするために異なる js ソース ファイルを結合し、最終的な JavaScript を 1 つだけインポートする方法だけだと思います。私のニーズに合ったより良い解決策はありますか?

M;

4

1 に答える 1

1

スクリプトを複数のファイルに分割する場合、それらのファイルは相互に通信できる必要があります。2 つの異なるスクリプト ファイルが相互に通信する唯一の方法は、それらに共通する唯一のものであるグローバル名前空間を経由することです。

私は Broserify に精通していませんが、requirejs の場合、スクリプトがグローバル名前空間を利用して通信する方法は、スクリプトが実行時にグローバルな「require」関数またはグローバルな「define」関数に自分自身への参照を渡すことです。その後、requirejs 自体がスクリプトを内部的に追跡するため、グローバル名前空間に他の影響を与える必要はありません。

いずれにせよ、スクリプトは、グローバル オブジェクトにプロパティを作成する宣言されていない変数に代入することで、常にグローバル名前空間に影響を与えることができます。

foo = function() {}; // creates global name as long as no other 'foo' is in scope
// or
window.foo = function() {}; // as long as no other 'window' variable is in scope

スクリプトのロード方法に関係なく、いつでもこれを行うことができます。他のスクリプトは、このグローバル名のプロパティを読み取ったり割り当てたりすることで、グローバル名「foo」を介して対話できるようになりました。

foo.prop1 = 'val1';
if(foo.preExistingProp) {
    // do something
}

requirejs のようなライブラリの主な目的は、スクリプトを開発しているときに、相対的な依存関係が変化する可能性があることです。スクリプト A にはスクリプト B と C が必要であり、スクリプト B にはスクリプト D が必要であると想像できます。スクリプトが有効にロードできる順序は複数あります。いくつかは次のとおりです。

D -> B -> C -> A
C -> D -> B -> A
D -> C -> B -> A

requirejs は依存関係ツリーを受け取り、それをその場で線形のロード順序に変換します。このツリーが変更されると、ロード順序が再計算され、有効性が維持されます。

この種の機能が必要な場合は、そのようなライブラリを使用することをお勧めしますが、グローバル名前空間に対する懸念は適切です。自分で管理する単純な線形ロード順序が必要な場合は、上記で概説したように、スクリプトをグローバル 'foo' 名と直接対話させることができます。

于 2013-10-21T01:32:57.910 に答える