web-dev-qa-db-ja.com

JSが私の設定を無視していることを要求する

スクリプト用の非常に単純なディレクトリ構造があります。

_/js/        <-- located in site root
    libs/
        jquery-1.10.1.min.js
        knockout-2.2.1.js
        knockout.mapping.js
    models/
        model-one.js
        model-two.js
        ...
    require.js
    config.js
_

サイトエンジンはクリーンURLを使用するため、_<script>_で絶対パスを使用しています。

_<script type="text/javascript" data-main="/js/config.js" src="/js/require.js"></script>
_

RequireJS構成:

_requirejs.config({

    baseUrl: "/js/libs",

    paths: {
        "jquery":       "jquery-1.10.1.min",
        "knockout":     "knockout-2.2.1",
        "komapping":    "knockout.mapping"
    }

});
_

HTMLのどこか:

_require(["jquery", "knockout", "komapping"], function($, ko, mapping){
    // ...
});
_

したがって、問題は、RequireJSが構成ファイルで定義されているbaseUrlpathsを完全に無視することです。以下のコードで必要なすべてのモジュールで404エラーが発生します。ブラウザコンソールで、RequireJSがパス変換なしで_/js/_からこれらのモジュールを読み込もうとしていることがわかります。

_404: http://localhost/js/jquery.js
404: http://localhost/js/knockout.js
404: http://localhost/js/komapping.js
_

ただし、ページが読み込まれ、エラーが表示されたら、コンソールに入力して...

_> require.toUrl("jquery")
  "/js/libs/jquery-1.10.1.min"
_

なぜそうなのか?この問題を解決する方法は?

RequireJSを使用するのは初めてなので、非常に単純で明白なものをスキップしたような気がします。助けてください。

更新

この質問を発見しました: baseUrlを無視するRequire.js

それは間違いなく私の場合です。ネットワークパネルで、require(...)が独自の依存関係の読み込みを実行する前に、_config.js_が完全に読み込まれていないことがわかります。

しかし、require(...)は、それを呼び出すページに非常に固有であるため、configに配置したくありません。これまでに見たどの例でも、非同期性に関するこのような問題に気づいたことはありません。これらの例の作成者はどのようにそれらを機能させ続けますか?

15
Andrejs Kuzmins

解決しました。

問題は、data-main属性で定義された構成ファイルが他の依存関係と同じように非同期でロードされることでした。したがって、私のconfig.jsが誤って完全にロードされ、require呼び出しの前に実行されることはありませんでした。

このソリューションは、公式のRequireJS APIで説明されています: http://requirejs.org/docs/api.html#config

...また、require.jsがロードされる前にグローバル変数requireとして構成オブジェクトを定義し、値を自動的に適用することができます。

そこで、config.jsを変更して、適切な構成でグローバルrequireハッシュを定義しました。

var require = {
    baseUrl: "/js/libs",
    paths: {
        "jquery":       "jquery-1.10.1.min",
        "knockout":     "knockout-2.2.1",
        "komapping":    "knockout.mapping"
    }
};

require.jsの直前に含めました:

<script type="text/javascript" src="/js/config.js"></script>
<script type="text/javascript" src="/js/require.js"></script>

このアプローチでは、スクリプトの実行順序を制御できるため、次のrequire呼び出しの前にconfig.jsが常にロードされます。

これですべてが完全に機能します。

23
Andrejs Kuzmins

問題を修正しました。

構成が非同期でロードされていたため、requireステートメントが呼び出される前に構成パスが設定されませんでした。

RequireJSドキュメント ここにリンク に従って、require.js呼び出しの前にスクリプト呼び出しを構成に追加しました。そして、data-main属性を削除しました。

var require = {
    baseUrl: '/js',
    paths: {
        'jquery':      'vendor/jquery/jquery-2.0.3.min',
        'picker':      'vendor/pickadate/picker.min',
        'pickadate':   'vendor/pickadate/picker.date.min'
    },
    shim: {
        'jquery': {
            exports: '$'
        },
        'picker':    ['jquery'],
        'pickadate': {
            deps:    ['jquery', 'picker'],
            exports: 'DatePicker'
        }
    }
}

すべてが機能しています

4
Leon