背景
現代のフロントエンドは、複雑さへと積極的に移行しており、この複雑さを制御する必要があります。 そもそも、この問題は長い間存在しており、その解決策のいくつかは試され、さらには適応されてきましたが、具体的なアイデアが具体化し、形になっていることに注意してください。 以下で説明します。
私が現在働いている会社は、さまざまな顧客向けのフロントエンドを開発しており、プロジェクトの規模は非常に小さいものから非常に堅実なものまでさまざまです(たとえば、エンタープライズシステム)。 私たちは、大きなプロジェクトに適したソリューションは小さなプロジェクトにうまく適応しないという事実に直面しています。逆もまた同様です。小さなプロジェクトでうまく機能するという事実は、大きなプロジェクトの要件を満たしていません。
時代の精神では、プロジェクトのボイラープレートが必要であると言えます。これにより、さまざまなサイズのプロジェクトを効率的に構築して、複雑さを制御し、勝手に成長しないようにすることができます。 これは、プロジェクトのタイムラインの内訳または噂につながる可能性があります。 そして、もちろん、サポートと開発のコストを忘れないでください。
最初の実装では、プロジェクトを独立した部分に単純に分割し、プロジェクトでの作業を促進するツールの開発に重点を置いていました。 プロジェクトは、githubで公開されている一般的なモジュールと、プロジェクト自体にある特定のモジュールに基づいて形成された、lernaの制御下にあるモノリポジトリを表し始めました。 これらのモジュール間の通信にはイベントバスが使用され、一般に、この実装は安定して機能しました。 ただし、そのような構造には重大な欠点がありました。プロジェクトのフレームワーク内で変更する予定のないモジュールは、モノリポジトリの一部として接続する必要がありました。そうしないと、同じパッケージの異なるバージョンが異なる場所で受信されたためです。 もちろん、これは問題ではありませんが、configsを含むパッケージでない場合のみです。
2番目の重要な問題は、プラグインの記述方法の説明でした。すべてのモジュール性について、依然として強力に接続されており、モジュール間の通信の一般的な概念がなかったためです。 必要なのは、誰でもそのようなプラグインを書くための全体的な仕様であり、アプリケーションの開始レベルで依存関係を解決する問題を解決することもできます。
次に、これらの問題を排除するためのオプションについて説明し、理想的な結果を説明することから始めます。
免責事項
以下は究極の真実であると主張するものではなく、単なる別の意見です。 私たちは自分の道を探しており、少なくとも自分自身のために、世界を少し良く、より便利にしたいと思っています。
可能な完璧な結果
1.モジュール性
問題 :モノリシックアプリケーション。 現在、特定のモノリス内でクライアントコードを個別の部分に分割するための手順が既に実行されていますが、本質的にプロジェクトは統一されたままであり、明確な境界がないため、特定の部分をすばやく交換または削除することは困難です。
解決策 :プロジェクトを、明確に定義された境界と責任を持つ物理的に区切られたモジュールに分割します。 また、あるモジュールの動作を別のモジュールから設定する機能も必要です。
利益 :プロジェクトをコンストラクターとして組み立てることができます。 つまり、モジュール自体が既存のインフラストラクチャ内でのパフォーマンスを保証します。 ここでの良い例は、リンティングの設定です。 リンター自体の設定は、異なるパッケージのパーツにアセンブルできますが、使用するプラグインはプロジェクト自体に接続する必要があります。 リンターを接続する理想的なモジュールは、必要なすべてのプラグインをそれ自体にもたらし、プロジェクトで使用されると、接続に変更を加えます。 eslint
の場合eslint
これらはpackage.json
のコマンドと.eslintrc
config .eslintrc
です。
2.インタラクションインターフェイス
問題 :アプリケーションの内部構造が複雑になると、依存関係、プロジェクト構成、およびコマンドの実行が困難になります。
解決策 :プロジェクトを管理、拡張、サポートするためのシンプルで直感的なインターフェースを提供する、よく開発されたcli
アプリケーションが必要です。 チームは簡潔で直感的でなければなりません。
利益 :開発者は、日常的な操作(たとえば、インターフェイスの標準コンポーネントの作成)に費やす時間がはるかに少なくなります。
3.日常業務の自動化
問題 :ほとんどのテンプレートは、プロジェクトを生成するか、テンプレートを複製した直後に、プロジェクトへの参加を終了します。 プロジェクトのアトミックな部分を生成できるツールが追加される場合があります。
解決策 :各モジュールには、プロジェクトにすばやく追加できるコンポーネントの特定のテンプレートセットが含まれている必要があります。
利益 :日常的なタスクの自動化の力は、テンプレートではなくプロジェクト自体の責任です 。 つまり、プロジェクトが複雑になればなるほど、必要なジェネレーターは複雑になりますが、それらを追加しても、たとえば、他のよりローカルなプロジェクトには影響しません。 ただし、必要に応じて、別のモジュールとして簡単に接続できます。
簡単に言うと、プロジェクト内のジェネレーターのセットは、インストールされているモジュールのセットによって決まります。
4.テンプレートの更新
問題 :特定のテンプレートでプロジェクトを開始した後、使用されるパッケージの更新とプロジェクトの構造は、プロジェクト開発者に残ります。
解決策 :依存関係を迅速に更新し、必要に応じてコードベースを移行する機能を提供する必要があります。
利益 :最新バージョンの移行は1か所でのみ行えます。 最終プロジェクトでは、プロジェクトの依存関係のバージョンは、必要に応じてコードベースの追加の移行で更新されます(このタスクはまだ解決されていないため、その定義と実装方法はあいまいです)。
仕組み
Rispaプロジェクトは、いくつかのレベルに分けることができます。
-
cli
アプリケーション、 - プロジェクトのモジュール性をサポートするインフラストラクチャ、
- プラグインモジュール:
- 一般的な機能
- プロジェクト固有のロジック。
cli
アプリケーション
このアプリケーションの主な機能は、実行可能なコマンドのセットがプロジェクト自体に依存することです。 つまり、コマンドには2つのタイプがあります。
- プロジェクト管理チーム:
ris add
、ris update
、ris assemble
など。 -
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プロジェクトのニーズに応えており、将来は他のフレームワークやビルドシステムのサポートを実装するために修正することができます。 以下にそれらの短いリストを示します。
-
rispa-config
プロジェクト構成のリポジトリ。プロジェクトに常に存在し、すべてのプラグインで単純な依存関係として接続されます。 -
rispa-server
起動、圧縮の構成、CORSサポート、およびデフォルトのルーティングに関連するルーチン全体を担当します。 同時に、ルートや他のミドルウェアを接続することにより、他のプラグインの機能を拡張できます。 -
rispa-client
ブラウザーで実行されるクライアントアプリケーションを直接担当します。 現在はReact固有のクライアントであるため、将来的にはプラットフォーム全体の動作を保証する部分のみが存在し、React部分は別のプラグインに移動します。 -
rispa-webpack
によるプロジェクトの全体的なアセンブリを担当しますが、構成は既存のプラグインからの部分で組み立てられます。 -
rispa-eslint-config
プロジェクト内のリンターの接続と操作を担当します。これは単なるドロップイン依存関係です。 -
rispa-generator
プロジェクトのジェネレーターの作業を担当します。ジェネレーター自体も、プロジェクトにインストールされているすべてのプラグインから組み立てられます。
実験的なプラグイン:
-
rispa-render-static
現在開発中の静的サイトに既存のアプリケーションをレンダリングするためのプラグイン。 -
rispa-render-simple
は、フレームワークなしでページをレンダリングするためのプラグインです。初期実装ではパグが使用され、おそらく最終バージョンもカスタマイズ可能です。
始め方
最初に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
形式でのベース自体の他の可能なアプリケーションの検索で、さらなる開発が見られます。
このプロジェクトのアイデアが気に入った場合、たとえば、モノリポジトリの上にプラグインインフラストラクチャを編成する機能、プロジェクトで動作する環境やモードへのエクスカーション、またはクライアントアプリケーションのアーキテクチャに関するエクスカーションに関するプラグインインフラストラクチャの編成機能などについて他に読みたいことそれはリアクション固有であり、かなり標準のままです。 プロジェクトは開発中であり、異なる環境ですべてをテストする方法がないため、問題を通して説明できる問題は除外されません。 開発者の利益のためにこのプロジェクトを開発するために、このプロジェクトに参加したい人も招待します。
将来の計画
- サポートされているフレームワークのリストの拡張; Angular、vue.jsを追加する予定です。
- ヤードとプラグインのTypeScriptへの移動とすべてのインターフェイスの入力の完了。
- プラグインの詳細なドキュメントを追加。
- クライアントでのプラグインインフラストラクチャの実装。
便利なリンク
- githubのプロジェクト編成
- 基本情報rispa.ioを含むプロジェクトページ
- その翼の下ですべてがCSSSRで生まれた会社