34

私は現在 RequireJS の基礎を学んでおり、ビルド プロファイル、メイン ファイル、複数ページ プロジェクトでの RequireJS の使用に関していくつか質問があります。

私のプロジェクトのディレクトリ構造は次のとおりです。

httpdocs_siteroot/
    アプリ/
        phpファイル...
    メディア/
        css/
            cssファイル...
        js/
            ライブラリ/
                jquery.js
                require.js
                口ひげ.js
            電源/
                main.page1.js
                main.page2.js
                main.page3.js
            プラグイン/
                jquery.plugin1.js
                jquery.plugin2.js
                jquery.plugin3.js
            ユーティリティ/
                util1.js
                util2.js
        画像/

このプロジェクトは単一ページのアプリではないため、ページごとに個別のメイン ファイルを用意しています (ただし、同じメイン ファイルを使用するページもあります)。

私の質問は次のとおりです。

  1. RequireJS は、単一ページではないプロジェクトでも実用的ですか?

  2. オプティマイザーを使用しない場合、各メイン ファイルは基本的に同じ構成オプションで始まります。

    requirejs.config({
      paths: {
        'jquery': 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min'
      },
      baseUrl: '/media/js/',
      // etc...
    });
    require(['deps'], function() { /* main code */ });
    

    これを回避する方法はありますか?実際にビルドすることなく、各メイン ファイルに同じビルド プロファイルを含めるようにするにはどうすればよいでしょうか。

  3. r.js はhttpdocs_siterootの親ディレクトリに入れるべきですか?

  4. アプリのディレクトリ構造または RequireJS の使用に明らかな問題がありますか?

4

2 に答える 2

57

まず第一に、これは一意の解決策を持つ質問ではありません。私のために機能する RequireJS の使用方法を説明し、あなたのために機能する可能性があります:)

第二に、英語は私の母国語ではありません。言語に関する修正とヒントは非常に高く評価されます。お気軽にどうぞ:)

1) require js は、単一ページではないプロジェクトでも実用的ですか?

場合によります。たとえば、プロジェクトでページ間でコードを共有していない場合、RequireJS のヘルプは控えめになります。RequireJS の主なアイデアは、アプリケーションを再利用可能なコードのチャンクにモジュール化することです。アプリケーションがページ固有のコードのみを使用する場合、RequireJS を使用することはお勧めできません。

2) オプティマイザーを使用しない場合、各メイン ファイルは基本的に同じ構成オプションで始まります。これを回避する方法はありますか?実際にビルドすることなく、各メイン ファイルに同じビルド プロファイルを含めるようにするにはどうすればよいでしょうか。

私が見る唯一の方法は、メイン ファイルで構成を行うか、RequireJS を構成するモジュールを作成してから、そのモジュールを main.js の最初の依存関係として使用することです。しかし、これは注意が必要です。アプリケーションで多くの main.js ファイルを使用することはありません。ローダーとして機能するものだけを使用します (以下を参照)。

3) r.js は httpdocs_siteroot の親ディレクトリに配置する必要がありますか?

必ずしも。クライアントのものはすべてそこにあるので、/media ディレクトリ内に置くことができます。

4) アプリのディレクトリ構造または requirejs の使用に明らかな問題がありますか?

私はそうは言いません。一方で、構造が少し細分化されすぎているのかもしれません。たとえば、すべての「サードパーティのもの」を /vendor ディレクトリに入れることができます。しかし、これはただの砂糖です。あなたの構造はうまく機能し、正しいようです。主な問題は、複数のメイン ファイルでの requirejs.config() 呼び出しだと思います。

私はあなたが今抱えているのと同じ問題を抱えていて、最終的に次の解決策になりました:

1) AMD 非準拠のファイルを定義でラップしないでください。これは機能しますが、requirejs.config の「shim」プロパティを使用して同じ結果を得ることができます (以下を参照)。

2) 複数ページのアプリケーションでは、最適化された main.js ファイルからページ固有のモジュールを要求しないことが私の解決策です。代わりに、メイン ファイルからすべての共有コード (サード パーティと私自身) を要求し、ページ固有のコードを各ページにロードします。メイン ファイルは、すべての共有/lib ファイルをロードした後、ページ固有のコードを開始するローダーのみになります。

これは、requirejs を使用して複数ページのアプリケーションを構築するために使用するボイラープレートです。

ディレクトリ構造:

/src - すべてのクライアントのものを src ディレクトリ内に置いたので、このディレクトリ内でオプティマイザーを実行できます (これはメディア ディレクトリです)。

/src/vendor - ここに、require.js を含むすべてのサードパーティのファイルとプラグインを配置します。

/src/lib - アプリケーション全体または一部のページで共有されるすべての独自のコードをここに配置します。つまり、ページ固有ではないモジュールです。

/src/page-module-xx - 次に、ページごとに 1 つのディレクトリを作成します。これは厳密な規則ではありません。

/src/main.js : これは、アプリケーション全体の唯一のメイン ファイルです。そうなる:

  • シムを含むRequireJSを構成する
  • 共有ライブラリ/モジュールをロードする
  • ページ固有のメイン モジュールをロードする

これは、requirejs.config 呼び出しの例です。

requirejs.config({
        baseUrl: ".",
        paths: {
            // libraries path
            "json": "vendor/json2",
            "jquery": "vendor/jquery",
            "somejqueryplugion": "vendor/jquery.somejqueryplufin",
            "hogan": "vendor/hogan",

            // require plugins
            "templ": "vendor/require.hogan",
            "text": "vendor/require.text"
        },
        // The shim section allows you to specify 
        // dependencies between non AMD compliant files.
        // For example, "somejqueryplugin" must be loaded after "jquery".
        // The 'exports' attribute tells RequireJS what global variable
        // it must assign as the module value for each shim.
        // For example: By using the configutation below for jquery, 
        // when you request the "jquery" module, RequireJS will 
        // give the value of global "$" (this value will be cached, so it is
        // ok to modify/delete the global '$' after all plugins are loaded.
        shim: {
            "jquery": { exports: "$" },
            "util": { exports: "_" },
            "json": { exports: "JSON" },
            "somejqueryplugin": { exports: "$", deps: ["jquery"] }
        }
    });

そして、構成後、これらすべてのライブラリに対して最初の require() リクエストを作成し、その後、「ページ メイン」モジュールのリクエストを実行できます。

//libs
require([
    "templ",     //require plugins
    "text",
    "json",      //3rd libraries
    "jquery",
    "hogan", 
    "lib/util"  // app lib modules
 ],
    function () {
        var $ = require("jquery"),
            // the start module is defined on the same script tag of data-main.
            // example: <script data-main="main.js" data-start="pagemodule/main" src="vendor/require.js"/>
            startModuleName = $("script[data-main][data-start]").attr("data-start");

        if (startModuleName) {
            require([startModuleName], function (startModule) {
                $(function(){
                    var fn = $.isFunction(startModule) ? startModule : startModule.init;
                    if (fn) { fn(); }
                });
            });
        }
    });

上記の require() の本文からわかるように、require.js スクリプト タグには別の属性が必要です。data-start属性は、現在のページのモジュールの名前を保持します。

したがって、HTML ページでは、次の追加の属性を追加する必要があります。

<script data-main="main" data-start="pagemodule/main" src="vendor/require.js"></script>

これにより、「/vendor」および「/lib」ディレクトリ (共有リソース) 内のすべてのファイルを含む最適化された main.js が作成されますが、ページ固有のスクリプト/モジュールは含まれません。依存関係として main.js にハードコーディングされています。ページ固有のモジュールは、アプリケーションの各ページに個別にロードされます。

function()「ページ メイン」モジュールは、上記の「アプリ メイン」によって実行される を返す必要があります。

define(function(require, exports, module) {
    var util = require("lib/util");

    return function() {
        console.log("initializing page xyz module");
    };
});

編集

ビルド プロファイルを使用して、複数のファイルを持つページ固有のモジュールを最適化する方法の例を次に示します。

たとえば、次のページ モジュールがあるとします。

/page1/main.js

/page1/dep1.js

/page1/dep2.js

このモジュールを最適化しない場合、ブラウザはスクリプトごとに 1 つずつ、合計 3 つのリクエストを行います。r.js にパッケージを作成してこれら 3 つのファイルを含めるように指示することで、これを回避できます。

ビルド プロファイルの "modules" 属性:

...
"modules": [
   { 
      name: "main"  // this is our main file
   },
   {
        // create a module for page1/main and include in it
        // all its dependencies (dep1, dep2...)
        name: "page1/main",
        // excluding any dependency that is already included on main module
        // i.e. all our shared stuff, like jquery and plugins should not
        // be included in this module again.
        exclude: ["main"]
   }
]

これにより、すべての依存関係を含む別のページごとのメイン ファイルを作成します。しかし、すべての共有内容をロードするメイン ファイルが既にあるため、それらを page1/main モジュールに再度含める必要はありません。複数のスクリプト ファイルがあるページ モジュールごとにこれを行う必要があるため、構成は少し冗長です。

ボイラープレートのコードを GitHub にアップロードしました: https://github.com/mdezem/MultiPageAppBoilerplate。node と node 用の r.js モジュールをインストールし、build.cmd を実行するだけです (/build ディレクトリ内。そうしないと、相対パスを使用するため失敗します)。

私がはっきりしていることを願っています。何か変な感じがしたら教えてください ;)

よろしく!

于 2012-07-30T21:47:02.727 に答える
1
<script data-main="js/main" src="js/lib/require.js"></script>


// file: js/main

require(['./global.config'], function(){
    require(['./view/home'], function() {
        // do something
    });
});

これは私のプロジェクトで使用したものです。

于 2013-03-28T05:25:19.663 に答える