Angular.jsで収集された作品

この投稿は、Angularjsアプリケーションの構築の問題に専念します。 考えられる解決策を検討し、最終的に自分のプラグインを作成することにした理由を説明します。

それでは、最近アセンブリの問題を解決することは一般にどのように受け入れられていますか? Grunt / Gulpプラグイン、require.js、browserifyは最も一般的なオプションです。

しかし、ニュアンスがあります。 Angularアプリケーションを扱う場合、モジュールを適切にアセンブルするには、モジュール間の依存関係を宣言する必要があります。 例で説明します。

複数のファイルで構成される単純なアプリケーションがある場合:

app.js controllers.js services.js directives.js filters.js 

それは問題ありません。 同じGrunt / Gulpに接続の順序を手動で登録できます。

ただし、個々のサービス、コントローラー、ディレクティブなどが個別のファイルにあるアーキテクチャを実装する場合、つまり:

 app.js controllers/ FirstCtrl.js SecondCtrl.js services/ FirstSrv.js SecondSrv.js 

その後、多くの困難に遭遇します。 ほとんどの場合、Angularがエラーなしで機能するように、すべてのファイルをステッチする方法が困難になります。 それで、何ができるのでしょうか?


主な問題は、コントローラー、サービス、ディレクティブなどを宣言するときに、それらが属するモジュールを最初に指定する必要があることです。

 angular.module('App').controller('FirstCtrl',function($scope){...}); 

この場合、FirstCtrlコントローラーを作成するには、最初にAppモジュールが宣言されているファイルを接続する必要があります。

 angular.module('App',[]); 


一般に、良い方法では、テストの利便性の理由から、モジュールのコンポーネントは個別のモジュールに組み立てられる必要があります。

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

これは、すべてを個別に保存したい場合は、これらのモジュールの宣言で中間ファイルを作成する必要があることを意味します。

 app.js controllers/ module.js FirstCtrl.js SecondCtrl.js services/ module.js FirstSrv.js SecondSrv.js 

module.jsファイルには、それぞれが含まれます。

 angular.module('App.controllers',[]); 

そして

 angular.module('App.services',[]); 


そして、結局のところ、独自の構造を持つさらに独立したモジュールがあるかもしれません。

したがって、問題を解決するために、裸の連結は機能しませんコメントから )。 ただし、これはRequire.jsおよびBrowserifyライブラリを使用して実行できます。

Require.jsを使用して記述されたこのようなアプリケーションの例は、次のようになります 。 一方では、このアプローチの明らかな利点は、設計時に得られる柔軟性です。 ただし、必然的に、コードにはAMDラッパーと複数のrequire()が散らばっています。

そして、CommonJsを使用したbrowserifyはもう少し有利に見えます。 しかし、CommonJsはそれとCommonJsのためのものです。AMDブラウザーライブラリの場合、セットアップが困難になります( コメントでのアプローチの議論 )。 ただし、requireを使用して依存関係の手動宣言をキャンセルする人はいません。

これらすべての中で、Angularには依存関係を宣言する独自のモジュール構造が最初にありましたが、同時にビルド順序に影響を与えられないという事実に最も混乱しました。

それを念頭に置いて、私は独自のNgBuildソリューションを作成しました。 アイデアは非常に簡単でした。 構文ツリーを解析し、モジュールの依存関係の場所に示されている必要なファイルを含めるレイヤーを作成します。

 angular.module('App','/controllers.js','/services.js') 


処理後、次のものが得られます

 angular.module('App.controllers',[]);// controllers.js angular.module('App.services',[]);// services.js angular.module('App',['App.controllers','App.services']);//     ,     


自治体では、他の例や機能がgithubで説明されているので、ここでやめません。 さらに、このアプローチのマイナス面は明らかです-ネイティブのAngular.js構文に直接介入する必要があります

また、これに加えて、Angular.jsの構文を知っている場合、モジュールとその依存関係がどのように記述されているか、コードをスキャンするだけでなく、その分析に基づいてファイルを正しい順序に並べないことがわかっている場合、意図せずに質問が発生します。

実際、これらの考えはすでに別のNgConcatソリューションを書くための推進力になりました。 その本質は、アプリケーションの場所を指定するだけで済み、プラグインが残りの作業を自動的に実行するという事実に要約されました。

同時に、プロジェクト内で、必要に応じてモジュールとコンポーネントをレイアウトでき、同時にコードに不要なインクルードはありません。

Gulpのタスク例:

 gulp.task('concat',function(){ gulp.src('/**/*.js') .pipe(concat('app.js')) .pipe(gulp.dest('./build/')); }); 


とうなり声のために:

 grunt.initConfig({ concat: { default_options: { files: { 'build/app.js': 'test/src/complex/**/*.js' } } } }); 


sourcemapのサポートは十分ではありませんが、注釈を追加してテンプレートを1つのライブラリにビルドする機能を減らしたいという大きな要望があります。 私が近い将来に取り組むもの。

結果として、可能なオプションについてもう一度説明します。
シンプルな連結-実装が難しい、
Require.jsは安定したライブラリですが、追加のコードが必要です。
Browserify-コードはRequire.jsに比べてわずかに小さいですが、AMDモジュールの統合に問題があり、
NgBuildは基本的にRequire / Browserifyと同じですが、ライブラリはまだユーザーで大きくなりすぎていないため、落とし穴やバグが発生する可能性があります。
NgConcatは他のすべてのものよりもシンプルで便利ですが、当面は若くて壊れる可能性があるため、今のところ、それを大規模なプロジェクトに取り込むこと、またはそれを取ることをお勧めしませんバグを残して、容赦なく罰することはありません。

PSライブラリを作成するとき、 Astra構文ツリーを操作するためのモジュールも実装する必要がありました。 Astralよりも便利にしようとしたAPIに加えて、非同期で動作する機能が追加されました。 私の意見では、APIは理解できるはずですが、突然誰かが必要になり質問が生じた場合は、午後に連絡してください。
以上です。

Source: https://habr.com/ru/post/J223251/


All Articles