2012-07-26 7 views
33

現在、RequireJSの基礎を習得しており、ビルドプロファイル、メインファイル、および複数ページプロジェクトでのRequireJSの使用に関するいくつかの質問があります。次のように複数ページプロジェクトでRequireJSビルドプロファイル+ r.jsを使用する方法

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

 
httpdocs_siteroot/ 
    app/ 
     php files... 
    media/ 
     css/ 
      css files... 
     js/ 
      libs/ 
       jquery.js 
       require.js 
       mustache.js 
      mains/ 
       main.page1.js 
       main.page2.js 
       main.page3.js 
      plugins/ 
       jquery.plugin1.js 
       jquery.plugin2.js 
       jquery.plugin3.js 
      utils/ 
       util1.js 
       util2.js 
     images/ 

このプロジェクトは、単一ページのアプリではないので(いくつかのページが同じメインファイルを使用しますが)、私は、ページごとに別々のメインファイルを持っています。

私の質問は以下のとおりです。

  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の使い方に間違いがありますか?

+0

私は短いと長い答えがありますが、私はいくつかの詳細が必要です:どのくらいのページ?各ページに固有のコードはほとんどないか、多くのコードです(各ページに10kbのコードを書いてみましょう)。 – devundef

+0

requirejsプラグインを使用していますか、どのプラグインですか? – devundef

+0

通常、mainjsファイルあたり10kb未満です。私はちょうどinit'ing jqueryプラグインのようなもののためにそれを使用します。多くのページがあるだろう...私は20と成長を言うだろう。だからおそらく約15のmainjsファイルと成長しています。そして、私が使用しているプラ​​グインは、jqueryプラグインがAMD準拠の定義呼び出しでラップされています。 – AndyPerlitch

答えて

57

まず、これは独自の解決策ではありません。私は、私のために働くRequireJSの使い方を説明し、あなたのために働くかもしれません:)

次に、英語は母国語ではありません。言語に関する訂正やヒントは非常に高く評価されます。気軽に、みんな:)

1)シングルページではないプロジェクトには実用的ですか?

によって異なります。たとえば、プロジェクト間でページ間でコードが共有されていない場合、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:これは、アプリケーション全体の唯一のメインファイルです。これは以下となります。シム

  • 負荷共有ライブラリ/モジュール
  • 含む

    • のconfigure 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> 
    

    を、私たちは「/ベンダー」内のすべてのファイルが含まれている最適化されたmain.jsで終わるだろうと」依存関係としてmain.jsにハードコードされていないため、/ libディレクトリ(共有リソース)はページ固有のスクリプト/モジュールではありません。ページ固有のモジュールは、アプリケーションの各ページに別々にロードされます。

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

    define(function(require, exports, module) { 
        var util = require("lib/util"); 
    
        return function() { 
         console.log("initializing page xyz module"); 
        }; 
    }); 
    

    EDIT

    は、複数のファイルを持っているページ固有のモジュールを最適化するために、ビルドプロファイルを使用する方法の一例です。例えば

    、我々は以下のページモジュールを持っているとしましょう:

    /page1/main.js

    /page1/dep1.js

    /page1/dep2.js

    このモジュールを最適化しないと、ブラウザはスクリプトごとに1つずつ、3つの要求を行います。 r.jsにパッケージを作成し、これら3つのファイルをインクルードするように指示することで、これを避けることができます。ビルドプロファイルの「モジュール」属性に

    ... 
    "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モジュールにそれらを再度入れる必要はありません。 configは、スクリプトファイルが複数あるページモジュールごとにこれを行う必要があるため、少し冗長です。

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

    私は明らかになったと思います。何か変な音がする場合は教えてください)

    よろしく!

  • +0

    偉大な答えをありがとう!私はまだそれをもう少し読んで、実際にそれを得るためにgithubの定型文をチェックしなければならないが、私はすぐにいくつかの質問をするだろうと確信している! – AndyPerlitch

    +0

    @AndyPerlitch、おかげさまで改訂のおかげでよかったです。 – devundef

    +0

    DOMと対話する必要があるすべてのページモジュールで$(document).ready()関数を使用していますか?それは次のようになります。 は( 機能(){ return関数(){ $(ドキュメント).ready(関数(){ //がもの を行うと}); } } )を定義します。 少し冗長に見えます...ページの最後にrequireスクリプトを置くことはできますか?私は、必要なドキュメントが頭の中に置くと言うことを知っているので、私は確信していません – AndyPerlitch

    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 
        }); 
    }); 
    

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

    関連する問題