5

RequireJSと、それを使用して、モジュールで使用しようとしたときに未定義として表示されない依存関係をロードする方法を理解しようと、ぐるぐる回っています。

JohnPapaのPluralsight「SPAwithHTML5」コースから始めました。私が理解していなかったのは、requireJSでAMDの全体的なポイントは、非同期でロードするためにライブラリとそのデータメイン属性に責任を引き渡すことだと思ったときに、バンドルに含まれるスクリプトタグですべてのライブラリを指定する必要がある理由でした何が必要だったか。そのコースで提示されたソリューションについて二重に混乱したのは、データ全体に従わなかったということでした。主な設定は、RequireJSのドキュメントに記載されています。

数か月先に進むと、Durandalを含む「HotTowel」テンプレート、サンプルの「サービス」モジュール、RequireJSドキュメントに従ったセットアップ、およびかなり理解しやすいスターターアプリができました。警鐘を鳴らす唯一のことは、ほとんどのライブラリが通常の「scripts」フォルダにあり、Durandalがアプリケーションロジックとともに完全に別の「app」フォルダにあるという考えです。私がpluralsightSPAコースから1つのことを学び、requireJSで遊んでいるとしたら、単一のフォルダーから物を移動することは非常にすぐに面倒になります。

とにかく、新しいテンプレートは正常に機能します。モジュールの依存関係はうまく機能しており、ViewsとViewModelsはバインドされており、Durandalモジュール(つまり、appフォルダー)にモジュールの依存関係があるサンプルのロガーモジュールがうまく機能しています。ホットタオルテンプレートにあるコードに基づいて、jQueryとmockJsonを使用する別の単純なモジュールを追加するのは簡単なはずですよね?えーと、いや、そうではない。

これは、「app/services」フォルダー内のモジュール「dataservice.js」の開始に関する非常に簡単な宣言です。

define(['jquery'],
function ($) {
    var init - function....

もちろん、コードブロック内でアクセスしようとすると、$に対して「undefined」が表示されます。ですから、あまりにも多くの紛らわしい文献を読んだ後(その多くは「これはjquery xxxxで変更されたので、もう関係ありません」というコメントで終わります)私は次の質問があります:

  1. ネットワークトラフィックを監視すると、jQueryライブラリが正しくダウンロードされていることがわかります。BundleConfig.csで定義されている「ベンダー」バンドルにmockJSONを追加すると、jQueryがそこにあり、ブラウザで待機しています。自分でモジュール定義を与えていません。モジュールのドキュメントで「未定義」の参照を取り除くには、次のようなものを追加する必要があることを意味しているようです。

    require.config({
        paths: {
            'text': 'durandal/amd/text',
            jquery: '../Scripts/jquery-1.9.1'
        }
    });
    

    (「text」宣言はすでに存在します。jqueryエイリアスを追加しました)これにより、モジュールに「undefined」ではなく関数が含まれるようになります。これにより、すでに作成したスクリプトの2番目のコピーが発生することを除いて問題の一部が解決されます。 HotTowellテンプレートの「ベンダー」バンドルのためにダウンロードされたように見えます。明らかな理由でjQueryのコピーを2つダウンロードしたくないので、これを修正するにはどうすればよいですか?

  2. mockJSONライブラリを「ベンダー」バンドルに追加しました。これは通常、$。mockJSONを使用して参照されます。これを有効にするために何もできません。'require.config({paths:'宣言でjqueryに対して行ったのと同じプロセスを使用してスクリプトへの参照をハックしたとしても、'ライブラリが2回ダウンロードされる'問題は言うまでもなく、未定義になります。 。モジュールでそのライブラリを使用できるように、ライブラリの依存関係を定義するにはどうすればよいですか?

  3. このすべての苦痛は、requireJSが非同期モジュールのダウンロードに関するものであるという事実と関係があると思いますが、jQueryとmockjsonは同期しているため、他の方法(ハードコードされた参照のバンドル)でダウンロードする必要がありますが、それでもrequireJSを意味しますモジュールには依存関係としてそれらを示す方法が必要であり、私が試したことは何も機能していません。これが同期/非同期の問題であるという私の仮定は正しいですか?デュランダルでjQueryと理想的にはjqueryプラグインを使用するサンプルアプリを少なくとも1つ見つけたいと思っていましたが、表示されるのは、他のものではなくデュランダルモジュールを使用するモジュールコードだけです。これらすべてのライブラリがrequireJSのメインルートの外にあるという事実は、参照を取得するために'../'文字列を含むパスに頼らなければならないため、おそらく問題を悪化させています。

  4. requireJSがdefineコマンドで「設定より規約」を使用していることを理解しています。モジュールIDを見逃した場合、data-mainを使用して指定された定義済みルートフォルダーからのモジュールソースファイル名とパスに基づいたIDを想定します。ただし、Durandalは、コード内で「entrance」と呼ばれるモジュールを参照しています。このモジュールはルートフォルダーではなく、「Durandal / transitions / entry.js」というフォルダーにあるため、このモジュールへの参照が「Durandal / transitions/entrance」ではなく「entrance」である理由について混乱しています。どこでエイリアスされていますか?

  5. 最後に(hoorah)defineステートメントの最初の引数(文字列配列)として依存関係を指定することと、それらの依存関係を省略することの違いの微妙な違いを理解していませんが、モジュールファクトリでは、varsystemのようなものを指定する最初の引数になります= require('../ system')-なぜあるフォームを別のフォームよりも優先して使用するのでしょうか。サンプルアプリケーション全体で2つのタイプが混在しているのがわかりますが、その理由がわかりません。

PS:このエントリを編集すると、1から5までの番号が付けられた5つの質問が表示されます。表示すると、1から4としてレンダリングされます。どのフォーマットを試しても、奇妙なHTMLエディタとレンダリングのバグがあります。修正できなかったので、コメントを投稿してください。1から5までの質問が2つではなく、1から5までの質問が5つあるかのように投稿してください。

4

4 に答える 4

2

うわー、それはたくさんの質問です!

durandal Google グループのこの投稿をチェックしてください: https://groups.google.com/forum/#!searchin/durandaljs/papa/durandaljs/Ku1gwuvqPQQ/gupgNqGIK1MJ

スレッドの興味深い点は、ホット タオル テンプレートの作成者であるジョン パパが、スクリプト タグまたはバンドルを使用してすべてのサードパーティ ライブラリを事前にロードし、独自のモジュールだけに require/AMD アプローチを使用することを推奨していることです。独自のモジュールは、jquery ($) とノックアウト (ko) のグローバル プロパティを参照する必要があります。

サードパーティのモジュールを事前にロードしてから require/AMD を介してロードすると、グローバル バージョンを使用するコードと AMD バージョンを使用するコードで予測できないバグが発生する可能性があると思います。(これは特にノックアウトでよく見られるようです)。

このアプローチは、私が認めているほどアーキテクチャ的にクリーンではありませんが、5 日間 durandal に頭を悩ませていたので、既知のサードパーティのライブラリを前もってロードすることを好み始めています。

于 2013-03-01T15:51:03.250 に答える
1

ああ、ピートのために!私はこれをすべて通り抜けることができませんでした。

jQuery やノックアウトなどを注入することに心血を注いでいる場合は、これを main.js の 6 行目あたり、物事を進める define の前に置きます。

var root = this; // グローバル名前空間、window

// 以下はすでにバンドル経由でロードされています
// これらをルート オブジェクトに配置します。それらをサービスとして追加します。
define('jquery', [], function () { return root.jQuery; });
define('ko', [], function () { return root.ko; });
define('breeze', [], function () { return root.breeze; });
define('Q', [], function () { return root.Q; });
define('moment', [], function () { return root.moment; });
define('sammy', [], function () { return root.Sammy; });
define('toastr', [], function () { return root.toastr; });

満足し?:)

于 2013-03-02T02:10:37.710 に答える
0

後発者の価値のために。Durandal は、この問題に関するドキュメントを改善しました。以下のページの「依存関係の構成」セクションでは、define(alias, globalVariable) を使用してモジュールを登録することと、パスと shim 戦略を使用することの違いについて説明しています。

どちらも機能しますが、パスとシムを使用する場合、すべての依存関係を同様の方法で登録する必要があります。これは、「jQuery.fn.extend...」を使用するプラグインに特に当てはまります。

http://durandaljs.com/documentation/Conversion-Guide/

于 2013-10-07T11:44:21.533 に答える
0

簡単なコードの答えは以下です。どこか (おそらくデュランダル内) が、jQuery を使用するモジュールが依存関係として宣言することなく、jQuery を利用できるようにしています (デュランダル コードのどこかに define ステートメントがあると思いますが、特定のサンプルがなければ、これを実現するのは難しいと思います。ほとんどないと思います。 jQuery やプラグインを使用している人もいます (皮肉)。うまくいけば、John Papa の今後の「ホット タオル」コースで、これらの質問/問題のいくつかを扱うことができます。jQuery 自体だけでなく、プラグインも同様です。

** jQuery プラグインの問題 (私のチームが尋ねたすべての質問の背後にある本当の問題) を解決する秘訣は、requireJS へのスクリプト参照によってポイントされる main.js ファイルの先頭にある次のコマンドです。

require.config({
paths: {
    'text': 'durandal/amd/text',
    'mockjson': '../Scripts/jquery.mockjson.js'
},
shim: {
    'mockjson': {
        deps: ['jquery'],
        exports: ['mockJSON']
    }
}

});

mockJSON ライブラリをバンドルに追加する必要があることに注意してください (「vendor」を使用しましたが、新しいバンドルを追加することもできます)。ここでの重要なポイントは、jQuery プラグインであるため、いずれかの依存関係として宣言してはならないことです。それを必要とするモジュール(または少なくともそれが私にとってはうまくいきます)。

元の質問が長くなって申し訳ありませんが、現実には、これらの質問への回答が必要なチームがあり、ウェブ上でそれらを見つけることができず、執筆時点ではジョンパパのコードキャンパーアプリしか持っていません-優れたコースがあり、さまざまなライブラリを接続するために多くの配管コードを記述したい場合に最適な出発点となるアプリ (私たちはそうしません。コードは何を理解するための優れた方法ですが、生産性を高める必要があります) Durandal のような新しいフレームワークは、はるかに単純な「コーディングより規約」アプローチを通じてコーディングを行っています)。私たちのチームのこのコースの問題は、コードを掘り下げると、答えが見つかるよりも多くの質問が発生することです (たとえば、「ライブラリをすべてを 1 つの大きなフォルダーに移動するのではなく、独自のサブフォルダーに移動すると、requireJS が「You're loading libraries behind my back. Let me do it and don't do it before my back.」というエラーをスローするのはなぜですか。 、「バンドルに含まれておらず、使用法/意図が説明されていない「more.info.txt」ファイルにあるとのみ検索で表示される一部のライブラリを使用してもコードがうまくいかないように見えるのはなぜですか?」; 「モジュールの命名規則が明確な理由もなくドット区切りとスラッシュ区切りで異なるのはなぜですか (または、少なくとも 1 つも説明されていません)」アプリの進化中に削除されなかった未使用の破片です)?""

申し訳ありませんが、Ward は、これらのものがどのように組み合わされ、どのように機能しているかを理解しようとすることが重要だとは考えていないようです (それが、私が行った 5 つの質問を行った理由です。私のチーム全体が尋ねている質問であり、どの質問でも説明されていません)。 jquery と require に関する「カット アンド ペースト」の回答は、Web で見つけました)。トレーナーとして、私は彼が「実際には関係のない Pluralsight コースから切り抜きと過去のコードをいくつか教えてください」と理解してくれることを期待していました。理解する必要はありません。私がここでやろうとしていたことではありません。利用可能な資料が、グループ全体が苦労している多くの質問に答えない場合は、説明しようとするのが理にかなっています。あなたが理解していないことは何ですか。悪い!

誰かがまともなrequireJSコースを書く機会がここにあると思います;-)

于 2013-03-02T07:36:16.460 に答える