1. ホーム
  2. angularjs

[解決済み] AngularJSのモジュール宣言のベストプラクティス?

2022-05-16 07:39:15

質問

私のアプリには、たくさんのAngularモジュールが宣言されています。 私はもともと、このように"chained"構文を使用してそれらを宣言し始めました。

angular.module('mymodule', [])
    .controller('myctrl', ['dep1', function(dep1){ ... }])
    .service('myservice', ['dep2', function(dep2){ ... }])
    ... // more here

しかし、それではあまり読みやすくないと思い、このようにモジュール変数を使って宣言するようにしました。

var mod = angular.module('mymodule', []);

mod.controller('myctrl', ['dep1', function(dep1){ ... }]);

mod.service('myservice', ['dep2', function(dep2){ ... }]);
...

2番目の構文は私にとってはより読みやすく見えますが、唯一の不満は、この構文では mod という変数がグローバルスコープから外れてしまうことです。 もし、他の変数に mod という名前の他の変数があった場合、それはこの次の変数で上書きされます(そして、グローバル変数に関連する他の問題)。

そこで質問なのですが、これは最良の方法なのでしょうか? それとも、このようにするのが良いのでしょうか?

(function(){
    var mod = angular.module('mymod', []);
    mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
    mod.service('myservice', ['dep2', function(dep2){ ... }]);
    ...
})();

あるいは、気にするほど重要なことなのでしょうか? ただ、モジュール宣言のベストプラクティスが何なのか知りたいだけです。 事前にありがとうございます。

どのように解決するのですか?

モジュールを宣言する「最良の」方法

angularはグローバルスコープにあり、モジュールはその変数に保存されるため、モジュールにアクセスするには angular.module('mymod') :

// one file
// NOTE: the immediately invoked function expression 
// is used to exemplify different files and is not required
(function(){
   // declaring the module in one file / anonymous function
   // (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
   // which are very hard to dedect)
   angular.module('mymod', []);
})();


// another file and/or another anonymous function
(function(){   
 // using the function form of use-strict...
 "use strict";
  // accessing the module in another. 
  // this can be done by calling angular.module without the []-brackets
  angular.module('mymod')
    .controller('myctrl', ['dep1', function(dep1){
      //..
    }])

  // appending another service/controller/filter etc to the same module-call inside the same file
    .service('myservice', ['dep2', function(dep2){ 
    //... 
    }]);

  // you can of course use angular.module('mymod') here as well
  angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
      //..
  }])
})();

他のグローバル変数は必要ありません。

もちろん、これは好みによりますが、私はこれがベストプラクティスのようなものだと思います。

  1. グローバル スコープを汚染する必要がない。
  2. どこでもモジュールにアクセスでき、モジュールとその関数を自由に別のファイルに振り分けることができます。
  3. use strict"の関数形式を使用することができます。
  4. ファイルのロード順序はそれほど重要ではありません。

モジュールとファイルをソートするためのオプション

モジュールを宣言し、アクセスするこの方法は、非常に柔軟性があります。モジュールを関数型(別の回答で説明されているような)またはルートでソートすることができます。

/******** sorting by route **********/    
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...

最終的にどのように分類するかは、個人の好みと、プロジェクトの規模や種類の問題です。 私自身は、モジュールのすべてのファイルを同じフォルダ(ディレクティブ、コントローラ、サービス、フィルタのサブフォルダ)にまとめ、さまざまなテストファイルを含めることが好きです。そのため、中規模のプロジェクトでは、すべての基本的なルートとそのコントローラ、サービス、ディレクティブ、および多かれ少なかれ複雑なサブモジュールを含むベースモジュールを作成することにしています。

/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...

angular.module('app', [
  'app.directives',
  'app.filters',
  'app.controllers',
  'app.services',
  'myMapSubModule'
]);

angular.module('myMapSubModule',[
   'myMapSubModule.controllers',
   'myMapSubModule.services',
   // only if they are specific to the module
   'myMapSubModule.directives',
   'myMapSubModule.filters'
]);

非常に大きなプロジェクトの場合、私は時々、上記のようにルートでモジュールをグループ化したり、選択した主要ルートでグループ化したり、あるいはルートと選択したコンポーネントの組み合わせでグループ化したりしますが、それは実際に依存します。

EDITです。 ただ、関連することで、またごく最近に遭遇しましたので。 モジュールの作成は一度だけにしてください。 (angular.module-functionに2番目のパラメータを追加することで)。これはアプリケーションを混乱させ、検出するのが非常に難しい場合があります。

モジュールのソートに関する2015年のEDIT。 1年半のangularの経験から、アプリ内で異なる名前のモジュールを使用することによる利点は、AMDがまだAngularとうまく機能せず、サービス、ディレクティブ、フィルタがとにかくangularコンテキスト内でグローバルに利用できるため、やや限定的であることを付け加えます ( のように ). しかし、意味的、構造的な利点はまだあり、一行のコードでモジュールをコメントインまたはコメントアウトしてインクルード/除外できるのは便利かもしれません。

また、ほとんど タイプによってサブモジュールを分離することはあまり意味がありません。 (例: 'myMapSubModule.controllers') というように、サブモジュールを種類で分けることは、通常はお互いに依存しあっているため、ほとんど意味がありません。