2

RequireJS を使用して JS をいくつかの大きな JS ファイルにモジュール化して、依存関係をオンデマンドでロードできるようにしようとしていますが、ページをロードするときに単一の JS を大量にダウンロードする必要はありません。

例として、JS ファイルは次のようになります。

  • js/main.js
  • js/views/category1/js1.js
  • js/views/category1/js2.js
  • js/views/category2/js1.js
  • js/views/category2/js2.js

アプリケーションの一部 (例: カテゴリ 1 のすべて) は特定のタイプのユーザーのみが使用し、カテゴリ 2 も同様であるため、ユーザーごとにすべてをロードするのは意味がありません。

それぞれの js1.js および js2.js ファイルからのすべてのコードを含む 2 つの動的に読み込まれたモジュール (category1.js & category2.js) を作成するために、r.js のビルド構成を試みています。

({
appDir: './',
baseUrl: './js',
dir: './dist',
modules: [
    {
        name: 'main',
        exclude: [
            "category1",
            "category2"
        ]
    },
    {
        name: "category1",
        include: [
            "views/category1/js1",
            "views/category1/js2"
        ],
        create: true
    },
    {
        name: "category2",
        include: [
            "views/category2/js1",
            "views/category2/js2"
        ],
        create: true
    }
],
fileExclusionRegExp: /^(r|build)\.js$/,
writeBuildTxt: false,
optimizeCss: 'standard',
removeCombined: true,
paths: {
    jquery: 'lib/jquery',
    underscore: 'lib/underscore',
    backbone: 'lib/backbone/backbone'
},
shim: {
    underscore: {
        exports: '_'
    },
    backbone: {
        deps: [
            'underscore',
            'jquery'
        ],
        exports: 'Backbone'
    }
}
})

ただし、コンパイルされた出力をロードするときに、ブラウザーは、views/category1/js1、views/category1/js2 などを見つけることができないと不平を言っています。

RequireJS で複数の小さな JS ファイルからいくつかの高レベルのモジュールを作成できるかどうかさえわかりません。誰もこれを経験したことがありますか?

編集

main.js:

require.config({
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        }
    },
    paths: {
        jquery: 'lib/jquery',
        underscore: 'lib/underscore',
        backbone: 'lib/backbone/backbone'
    }
});

require([
    'views/app',
    'router'
], function(AppView, Router) {
    new Router();
    Backbone.history.start();
});

index.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <script data-main="js/main" src="js/lib/require/require.js"></script>
</head>
<body></body>
</html>

JS1、JS2 などのファイルは router.js から参照されています。

4

1 に答える 1

2

持っrequire(['A'], ...)ているdefine(['A'], ...場合、RequireJS はその構成を検査して名前を解決しA、モジュールのロードに使用する URL を作成しますA。次のようなものをロードしようとする場合があります。

http://localhost/js/A.js

ABCが という名前のバンドルに含まれるようにモジュールを最適化するcategory1と、次の可能性があります。

  1. バンドルcategory1が読み込まれ、 に対してリクエストが行われAます。Aがロードされたときに見つかったので、これは問題ありcategory1ません。

  2. バンドルはまだロードされていませんが、 に対してリクエストが行われていAます。A最適化を行わない場合と同じように解決されるため、これは問題です。しかし、ここで問題が発生しました。モジュールを最適化した場合、Aは外部では使用できなくなりますcategory1( が であるためremoveCombined) true

解決策は、ランタイム構成で RequireJS に、ロードするモジュールがバンドルに含まれていることを伝えることです。bundlesこれにはオプションを使用します。例えば:

bundles: {
  category1: ['A', 'B', 'C']
}

Aこれは RequireJS に、「モジュールをロードしたいときにロードするcategory1と、そこにあることがわかります」と伝えます。

バンドル内のすべてのモジュールをリストする必要はないことに注意してください。たとえば、モジュールがありX、それをロードする唯一のモジュールが同じバンドルの一部であることがわかっている場合は、モジュールとして にリストする必要はありませんbundles

于 2016-08-17T23:02:29.123 に答える