プロジェクトテンプレートのコンストラクタまたは大規模プロジェクトの管理の複雑さ

Rispaはみんなと友達になるためのツールです







背景



現代のフロントエンドは、複雑さへと積極的に移行しており、この複雑さを制御する必要があります。 そもそも、この問題は長い間存在しており、その解決策のいくつかは試され、さらには適応されてきましたが、具体的なアイデアが具体化し、形になっていることに注意してください。 以下で説明します。







私が現在働いている会社は、さまざまな顧客向けのフロントエンドを開発しており、プロジェクトの規模は非常に小さいものから非常に堅実なものまでさまざまです(たとえば、エンタープライズシステム)。 私たちは、大きなプロジェクトに適したソリューションは小さなプロジェクトにうまく適応しないという事実に直面しています。逆もまた同様です。小さなプロジェクトでうまく機能するという事実は、大きなプロジェクトの要件を満たしていません。







時代の精神では、プロジェクトのボイラープレートが必要であると言えます。これにより、さまざまなサイズのプロジェクトを効率的に構築して、複雑さを制御し、勝手に成長しないようにすることができます。 これは、プロジェクトのタイムラインの内訳または噂につながる可能性があります。 そして、もちろん、サポートと開発のコストを忘れないでください。







最初の実装では、プロジェクトを独立した部分に単純に分割し、プロジェクトでの作業を促進するツールの開発に重点を置いていました。 プロジェクトは、githubで公開されている一般的なモジュールと、プロジェクト自体にある特定のモジュールに基づいて形成された、lernaの制御下にあるモノリポジトリを表し始めました。 これらのモジュール間の通信にはイベントバスが使用され、一般に、この実装は安定して機能しました。 ただし、そのような構造には重大な欠点がありました。プロジェクトのフレームワーク内で変更する予定のないモジュールは、モノリポジトリの一部として接続する必要がありました。そうしないと、同じパッケージの異なるバージョンが異なる場所で受信されたためです。 もちろん、これは問題ではありませんが、configsを含むパッケージでない場合のみです。







2番目の重要な問題は、プラグインの記述方法の説明でした。すべてのモジュール性について、依然として強力に接続されており、モジュール間の通信の一般的な概念がなかったためです。 必要なのは、誰でもそのようなプラグインを書くための全体的な仕様であり、アプリケーションの開始レベルで依存関係を解決する問題を解決することもできます。







次に、これらの問題を排除するためのオプションについて説明し、理想的な結果を説明することから始めます。







免責事項



以下は究極の真実であると主張するものではなく、単なる別の意見です。 私たちは自分の道を探しており、少なくとも自分自身のために、世界を少し良く、より便利にしたいと思っています。







可能な完璧な結果



1.モジュール性



問題 :モノリシックアプリケーション。 現在、特定のモノリス内でクライアントコードを個別の部分に分割するための手順が既に実行されていますが、本質的にプロジェクトは統一されたままであり、明確な境界がないため、特定の部分をすばやく交換または削除することは困難です。







解決策 :プロジェクトを、明確に定義された境界と責任を持つ物理的に区切られたモジュールに分割します。 また、あるモジュールの動作を別のモジュールから設定する機能も必要です。







利益 :プロジェクトをコンストラクターとして組み立てることができます。 つまり、モジュール自体が既存のインフラストラクチャ内でのパフォーマンスを保証します。 ここでの良い例は、リンティングの設定です。 リンター自体の設定は、異なるパッケージのパーツにアセンブルできますが、使用するプラグインはプロジェクト自体に接続する必要があります。 リンターを接続する理想的なモジュールは、必要なすべてのプラグインをそれ自体にもたらし、プロジェクトで使用されると、接続に変更を加えます。 eslint



の場合eslint



これらはpackage.json



のコマンドと.eslintrc



config .eslintrc



です。







2.インタラクションインターフェイス



問題 :アプリケーションの内部構造が複雑になると、依存関係、プロジェクト構成、およびコマンドの実行が困難になります。







解決策 :プロジェクトを管理、拡張、サポートするためのシンプルで直感的なインターフェースを提供する、よく開発されたcli



アプリケーションが必要です。 チームは簡潔で直感的でなければなりません。







利益 :開発者は、日常的な操作(たとえば、インターフェイスの標準コンポーネントの作成)に費やす時間がはるかに少なくなります。







3.日常業務の自動化



問題 :ほとんどのテンプレートは、プロジェクトを生成するか、テンプレートを複製した直後に、プロジェクトへの参加を終了します。 プロジェクトのアトミックな部分を生成できるツールが追加される場合があります。







解決策 :各モジュールには、プロジェクトにすばやく追加できるコンポーネントの特定のテンプレートセットが含まれている必要があります。







利益 :日常的なタスクの自動化の力は、テンプレートではなくプロジェクト自体の責任です 。 つまり、プロジェクトが複雑になればなるほど、必要なジェネレーターは複雑になりますが、それらを追加しても、たとえば、他のよりローカルなプロジェクトには影響しません。 ただし、必要に応じて、別のモジュールとして簡単に接続できます。







簡単に言うと、プロジェクト内のジェネレーターのセットは、インストールされているモジュールのセットによって決まります。







4.テンプレートの更新



問題 :特定のテンプレートでプロジェクトを開始した後、使用されるパッケージの更新とプロジェクトの構造は、プロジェクト開発者に残ります。







解決策 :依存関係を迅速に更新し、必要に応じてコードベースを移行する機能を提供する必要があります。







利益 :最新バージョンの移行は1か所でのみ行えます。 最終プロジェクトでは、プロジェクトの依存関係のバージョンは、必要に応じてコードベースの追加の移行で更新されます(このタスクはまだ解決されていないため、その定義と実装方法はあいまいです)。







仕組み



Rispaプロジェクトは、いくつかのレベルに分けることができます。









cli



アプリケーション



このアプリケーションの主な機能は、実行可能なコマンドのセットがプロジェクト自体に依存することです。 つまり、コマンドには2つのタイプがあります。







  1. プロジェクト管理チーム: ris add



    ris update



    ris assemble



    など。
  2. package.json



    scripts



    として記述されたプラグインからのコマンド。 これは、コマンドris run [plugin-name-or-alias] [command-name-from-scripts]



    拡張であり、 run



    は省略できます。


cliの詳細については、説明を参照してください。







モジュラーインフラストラクチャ



このようなインフラストラクチャを編成するための最も明らかな解決策は、最終プロジェクトでモノリポジトリ形式を使用することです。 lerna.js



ツールは元々使用されていましたが、たとえばjest



babel



などのライブラリ開発プロジェクトの管理により適しています。 使用された主な機能は、モノリポジトリ内の依存関係を解決することでしたが、現在、 yarn workspaces



の出現により、それらを使用するようになりました。プロジェクトをモノリポジトリとして最も効果的に整理する問題を解決できるからです。







アプリケーションのモジュール性の2番目の部分はrispa-coreと呼ばれます。 このパッケージは、プラグインの相互作用を整理する機能を提供し、プラグインを記述するための仕様も宣言します。







プラグイン



現在、かなり大きなプラグインが形成されていますが、主にReactプロジェクトのニーズに応えており、将来は他のフレームワークやビルドシステムのサポートを実装するために修正することができます。 以下にそれらの短いリストを示します。









実験的なプラグイン:









始め方



最初にcli



インストールする必要があります:







 $ yarn global add @rispa/cli
      
      





インストールが成功したら、 ris new



を実行して、新しいプロジェクトを作成し、質問に答え、プラグインを選択し、すべての依存関係がインストールされるのを待つ必要があります。







 $ ris new
      
      





サンプルコンソールビュー
 $ ris new [18:22:11] Enter project name [started] ? Enter project name: temp-project-name [18:22:22] Enter project name [completed] [18:22:22] Enter remote url [started] ? Enter remote url for project (optional): [18:22:24] Enter remote url [completed] [18:22:24] Generate project structure [started] [18:22:24] Generate project structure [completed] [18:22:24] Git init [started] Initialized empty Git repository in /opt/work/temp-project-name/.git/ [master (root-commit) f5af296] Create project 'temp-project-name' [18:22:24] Git init [completed] [18:22:24] Fetch plugins [started] [18:22:28] Fetch plugins [completed] [18:22:28] Select plugins to install [started] ? Select plugins: >(*) react-redux v4.1.3 - Rispa Redux plugin (*) webpack-javascript v4.1.3 - Rispa plugin which provide Webpack JavaScript configuration (*) babel v4.1.3 - Rispa Babel plugin (*) @rispa/react-config v4.1.3 - Rispa React Configuration (*) @rispa/routes v4.1.3 - rispa routes (*) react-server v4.1.7 - Rispa Server rendering plugin (*) react-client v4.1.3 - Rispa Client plugin (Move up and down to reveal more choices) [18:33:30] Select plugins to install [completed] [18:33:30] Install plugins [started] [18:33:30] Install plugin with name @rispa/react-config [started] ... success Saved lockfile. $ ris clean-cache [18:37:38] Read project configuration [started] [18:37:38] Read project configuration [completed] [18:37:38] Clean cache [started] [18:37:38] Clean cache [completed] Done in 240.41s. [18:37:39] Install project dependencies [completed] [18:37:39] Git commit [started] [master e3223c2] Bootstrap deps and install plugins [18:37:40] Git commit [completed]
      
      





これで、新しく生成されカスタマイズされたプロジェクトができました。 ただし、その中に単一のルートはありません。 追加する必要があります。 これを行うには、 feature-plugin



ジェネレーターを使用しfeature-plugin



。これは、新しいモジュールを作成し、それを@rispa/routes



登録します。 いくつかの質問に答えると、プラグインが生成されてプロジェクトに接続され、依存関係が更新されます。







 $ ris g feature-plugin
      
      





サンプルコンソールビュー
 $ ris g feature-plugin [19:07:27] Read project configuration [started] [19:07:27] Read project configuration [completed] [19:07:27] Scan plugins [started] [19:07:27] Scan plugins [completed] [19:07:27] Init generators [started] [19:07:28] Init generators [completed] [19:07:28] Check generator [started] [19:07:28] Check generator [completed] [19:07:28] Select plugin [started] [19:07:28] Select plugin [skipped] [19:07:28] Enter plugin name [started] ? Enter plugin name: home [19:07:38] Enter plugin name [completed] [19:07:38] Run generator [started] ? Enter package name: @project/home ? Enter plugin router path: / [19:07:58] Run generator [completed] [19:07:58] Bootstrap plugin dependencies [started] ... [19:08:26] Read project configuration [started] [19:08:26] Read project configuration [completed] [19:08:26] Clean cache [started] [19:08:26] Clean cache [completed] Done in 28.54s. [19:08:27] Bootstrap plugin dependencies [completed]
      
      





プラグインを構成したら、ページのメインコンポーネントを配信する必要があります。 再び生成ris g container



使用します。このプロセスでは、生成を生成するプラグインを選択するよう求められます。 ところで、すべてのジェネレーターを表示するには、 ris g



指定するだけです。プロジェクトで使用可能なジェネレーターのリストが表示されます。







 $ ris g container
      
      





サンプルコンソールビュー
 $ ris g container [19:12:20] Read project configuration [started] [19:12:20] Read project configuration [completed] [19:12:20] Scan plugins [started] [19:12:20] Scan plugins [completed] [19:12:20] Init generators [started] [19:12:20] Init generators [completed] [19:12:20] Check generator [started] [19:12:20] Check generator [completed] [19:12:20] Select plugin [started] ? Select plugin: @project/home [19:12:25] Select plugin [completed] [19:12:25] Enter plugin name [started] [19:12:25] Enter plugin name [skipped] [19:12:25] Run generator [started] ? How should it be called? Home [19:12:29] Run generator [completed] [19:12:29] Bootstrap plugin dependencies [started] [19:12:29] Bootstrap plugin dependencies [skipped]
      
      





ここで、作成したコンテナにルートを関連付ける必要があります。これは、 /packages/home/src/register.js



ファイルで/packages/home/src/register.js



ます。







 import Home from './containers/Home/Home' // import reducer, { action } from './redux/reducer' // import { match } from '@rispa/redux' const registerReducer = () => { // store.injectReducer('reducerName', reducer) } const registerWhen = () => { // when(match('/'), action) } const registerModule = context => { registerReducer(context) registerWhen(context) return Home } export default registerModule
      
      





これで、プロジェクトを開始し、アセンブリの完了後にブラウザでプロジェクトを確認できます。







 $ ris server start-dev
      
      





おわりに



Rispaを使用すると、問題を解決してプロジェクトの開始を簡素化し、ワークフローを最適化できます。 機能の拡張と新しいフレームワークのサポート、さらにrispa-cli + rispa-core



形式でのベース自体の他の可能なアプリケーションの検索で、さらなる開発が見られます。







このプロジェクトのアイデアが気に入った場合、たとえば、モノリポジトリの上にプラグインインフラストラクチャを編成する機能、プロジェクトで動作する環境やモードへのエクスカーション、またはクライアントアプリケーションのアーキテクチャに関するエクスカーションに関するプラグインインフラストラクチャの編成機能などについて他に読みたいことそれはリアクション固有であり、かなり標準のままです。 プロジェクトは開発中であり、異なる環境ですべてをテストする方法がないため、問題を通して説明できる問題は除外されません。 開発者の利益のためにこのプロジェクトを開発するために、このプロジェクトに参加したい人も招待します。







将来の計画





便利なリンク






All Articles