クライアントのJavaScriptは急速に変化しています。ライブラリ、フレームワーク、パッカーはすぐに現れ、互いに置き換えられます。 ただし、これにもかかわらず、多くのキー操作はどのクライアントアプリケーションでも同じです。 そして、現代のフロントエンドフレームワークでは、その多様性すべてに共通点が多くあります。
この記事は、 Contoso Expressプロジェクトのコードに基づいています。
この記事のいくつかのトピックを詳しく知ることができるリソースのリスト。
ちょっとした歴史
Web標準はゆっくりと変化します。たとえば、HTML 5の最新バージョンは2年前に承認され、以前のXHTMLは2000年に初めて登場しました。 新しいバージョン間のギャップは14年でした。 同時に、新しいバージョンには根本的に新しいものは何もありません。 CSSも急速に発展していません:2012年にflexboxレイアウトについて初めて聞いたとき、4年が経ちましたが、IE11での部分的なサポートと以前のバージョンでの不在に満足しているなら、使用できるようです。 JavaScriptでも見た目ほど速く変化していません。最近のES6アップデートの前に、以前のメジャーバージョン5.0は6年前にリリースされました。 同時に、新しい標準が出現しても、すぐに使用を開始できるという意味ではありません。 すべての主要なブラウザがサポートを開始するまでに時間がかかります(IEの場合、待つことはできません)。
ただし、クライアントアプリケーションの要件は常に増加しています。 グーグルは、2005年にGoogle MapsとGmailクライアントをリリースすることで水準を引き上げました。これは、かつてないレベルの使いやすさを備えたインタラクティブSPA(シングルページアプリケーション)です。 そのようなアプリケーションは書くのが難しく、すべての企業がそれを購入できるわけではありません。 それらは比較的最近(3〜4年前)広く使用されています。
主要なブラウザーでサポートされる複雑なSPAアプリケーションを作成するには、さまざまな補助的な手法を使用する必要があり、この分野では常に変化が起こっています。
SPA
SPAは最新のWebアプリケーションの標準になりつつあり、最高レベルのユーザーエクスペリエンスを提供します。 アプリケーションは、ページが最初にロードされたときにメインリソース(スタイル、コード、マークアップ)をロードします。その後、クライアントで後続の状態変更が発生します。 サーバーからのデータはAJAXリクエストを介してロードされ、HTMLはHTMLテンプレートに基づいて、またはJS(React)から直接クライアントでレンダリングされます。
これは、状態を変更するたびにサーバーから更新されたページを再ロードする必要がある従来のアーキテクチャとは異なります。
Webアプリケーションは、複数のSPAモジュールのセットとして記述したり、クラシックラウンドトリップモードで動作するパーツと組み合わせたりできます。 Contosoでは、認証ページはポストバックを通じて機能し、残りのアプリケーションはSPAとして作成されます。
スタイルプリプロセッサ
CSS構文には、プリプロセッサによって排除される多くの欠点があります-CSSアドオン言語:LESS / SASS / Stylus
標準CSSの大幅な改善:
.my-class { background-color: blue; div { background-color: red; // -> .my-class div { background-color: red; } } }
@myPadding = 10px; .my-class { padding-top: @myPadding; // 10px padding-bottom: @myPadding + 5px; // 15px }
.error { color: red; font-weight: bold; } .admin-error { border: 1px solid black; .error // -> .error styles inserted here }
プリプロセッサを使用すると、特にスタイルが多数ある場合に、スタイルの記述と保守が簡単になります。 ContosoはLESSを使用しますが、現在はSASSの方が一般的ですが、両者の違いはそれほど大きくありません。
CSSフレームワークの選択
CSSフレームワークは、要素の配置(グリッドシステム)を簡単にする一連のテンプレートスタイルを提供し、デフォルトのスタイル設定(デフォルトではHTMLの見栄えが良い)をオーバーライドし、モーダルウィンドウ、ナビゲーションメニュー、日付ピッカーなどのJSが有効なウィジェットのセットを提供しますd。
主なオプション:
ブートストラップは主要な選択であり、最初の大規模なCSSフレームワークです。 もともとはTwitterによって作成されたもので、デスクトップとモバイルの両方の開発に適しています。 コンポーネントの大規模なセット。 人気が高いため、ブートストラップのサイトはステレオタイプに見えるかもしれません。
Foundationは、一般的な選択肢であり、コンポーネントの適切な選択であり、便利な位置決めシステムです。
セマンティックUI-よく設計された要素クラスのセマンティクス(命名)に焦点を当てていますが、モバイル開発にはあまり適していません。
マテリアルデザインはフレームワークではありませんが、会社の製品(Android)で使用されているGoogleスタイルのガイドラインです。 React Material UIおよび他のJSフレームワークには、この設計の実装があります。
さらに、類似のFont Awesomeで最も人気のあるフォント形式のアイコンセットでライブラリを使用できます。
ContosoはFont AwesomeとBootstrapを使用します 。
クライアントJSフレームワークの選択
主なオプションを見てみましょう。
JQueryは、さまざまなブラウザ用の単一のインターフェイスでDOM要素を簡単に直接操作できるライブラリであり、十分に文書化されており、AJAX要求とプラグインの記述をサポートしています。 複雑なクライアントアプリケーションの作成にはあまり適しておらず、リアクティブデータバインディング機能を提供しません。
クライアントJSライブラリの反応性は、データ(モデル)と表示(HTMLビュー)を動的にリンクする機能です。 モデルが変更されると、表示は自動的に(反応的に)変更され、逆も同様です。表示状態の変更(入力値が変更された)によりモデルが変更されます。 Vue.jsを使用した単純な反応の例へのjsfiddleリンクは、すべてのDOM操作を手動で行うよりもはるかに簡単であることを評価します。
Angular 1.Xは、最初の大人気のリアクティブフレームワークです(Knockoutなど、他にもありました)。 Angularは、反応性に加えて、アプリケーションの構造化、再利用可能なコンポーネント(ディレクティブ)のサポートなどを提供します。 残念ながら、Angular 1.xは不必要に混乱を招き、多くの松葉杖を持ち、特に反応性の研究と開発が困難です。 パフォーマンスの問題があります。 当初、Angularは独立したオープンソースライブラリでした。 その後、Googleによって開発および保守されます。 Angularは2014年にピークに達し、Reactによって積極的に置き換えられています。
React -Angularとは異なり、クライアントマッピングを生成するように設計されたフレームワークではなく、ライブラリです。 仮想DOM手法を使用して、レンダリングを高速化します。 これにより、Reactはパフォーマンスに大きな影響を与えることなく、データが変更されるたびに表示を完全に再レンダリングできます。
Reactは、データが常に一方向に変化するFluxアーキテクチャで使用することをお勧めします。 まず、モデルデータが開始され、それらにマッピングが構築され、ディスプレイがモデルの状態を変更するイベントを生成します。これにより、ディスプレイの更新が必要になります。 これにより、アプリケーションで状態がどのように変化するかを理解しやすくなり、開発が大幅に促進されます。
Reactでは、JSコードを使用してXML(HTML)構文を操作できるJSXを使用します。 これは、従来のHTMLテンプレートの代わりに使用されます。 JSXを使用すると、JSのすべての機能を使用してテンプレートを生成できますが、レイアウトデザイナとのサポートおよびコラボレーションがより困難になる可能性があります。 Reactはfacebookによって作成され、彼らのプロジェクトのいくつかで使用されています。
Angular 2.xは最新のフレームワークです(最終リリースは2016年9月)。 複雑なクライアントアプリケーション、優れたパフォーマンスの開発に焦点を当てています。 これはゼロから作成されており、Angular 1.xとはほとんど似ていません。 反応性がはるかに簡単に実装されます。ネイティブHTML属性がバインディングに使用されます(たとえば、ngクリックではなくクリック)。 多くの高度なTypeScript機能を使用します。たとえば、Dependency Injectionは、クラスコンストラクターと変数型(C#/ Javaなど)を介して実装されます。 デコレータは頻繁に使用されます。 Angularはサードパーティのライブラリが必要です(zone.js)。ポリファイルを使用し、多くの標準ブラウザ機能をオーバーライドします。 現時点では、システムの状態を整理するための標準的なプラクティスがどうなるかはまだ明確ではありません。 Angular 2はFluxアーキテクチャ(たとえばReduxを使用)で動作しますが、Fluxは唯一の真のアーキテクチャとしては推奨されません。
VueJSは、React / Angularの優れた代替手段です。 単純なものから複雑なものまで(原則的に)原則に従います。 基本的なリアクティブ機能を備えたVueから始めるのは非常に簡単ですが、同時に、複雑なSPAを構築するために必要なすべてを追加することでVueを拡張できます。 Vueは簡単に統合でき、高速で直感的です。 長い間、彼はGitHubのJSトレンドリポジトリリストに常に存在しており、これには十分な理由があります。 テンプレート構文はAngular2に似ています。 Fluxアーキテクチャを備えたVuexは、状態の保存に使用されます。 Vueの2番目のバージョンはまもなく登場します。特に、パフォーマンスが改善され(Virtual DOMを使用)、JSXを使用するオプションがオプションで追加されます。
その他 -多くのフレームワーク/ライブラリがあります。 他のオプションを検討することに興味がある場合は、さまざまなMV *フレームワークでの簡単なTODOアプリケーションシートの実装が収集されているTodoMVC Webサイトをご覧ください。
何を選ぶか
特定のプロジェクトに依存します。 洗練されたSPAアプリケーションを最初から構築することを計画している場合は、今日最も人気のあるオプションとしてReactを試してください。 しかし、新しい概念を学習し、環境をセットアップするには時間がかかります。
プロジェクトの開発に合わせて拡張できるシンプルなソリューションが必要な場合、Vueは素晴らしいオプションですが、あまり人気がなく、著名な開発会社によってサポートされていません。
すぐにリリースされない複雑なアプリケーションがあり、将来志向であれば、Angular2を試すことができます。
Angular1で新しいプロジェクトを開始することはお勧めしません。これにはVueを使用することをお勧めします。多くの点で同様の構文がありますが、作業ははるかに単純で便利です。
まだパフォーマンスの問題があります。 さまざまなフレームワークを比較する多くの記事が、この問題に多くの時間を費やしています。 ほとんどのアプリケーションでは、クライアントのパフォーマンスは問題にならないことを理解する必要があります。大量のデータを動的にレンダリングする必要がある場合、またはアプリケーションが低パフォーマンスのモバイルデバイスでアクティブに使用される場合、パフォーマンスが重要です。 それにもかかわらず、ここにさまざまなJSフレームワークのテストの表があります 。
別の選択基準は、特定のフレームワーク用のプラグイン/ライブラリのセットです。 この点で、React / Angular1は明らかにリーダーですが、VueJのヘルパーコンポーネントライブラリは既に多くありますが、Angular2の数は最近のリリース後に急速に増加するはずです。 Awesome Listsリポジトリには、興味のあるフレームワークのリソースのすばらしい(楽しい)リストがあります。
将来的には、React / Vueの実装機能を使用してクライアントアプリケーションを作成するさまざまな側面について説明します。 Contosoでは、 Reactを使用してメインバージョンが作成され、Vueに代替ブランチがあり、Angular2に実装されたブランチも追加したかったのですが、残念ながら、フレームワークのエコシステムは安定していません(Angular2を使用するライブラリとツールはまだ完全に新しいリリースに適応していません) 。
構造
クライアント部分の構造は、選択したフレームワークに依存します。 Contosoでは、クライアント実装(React / Vue) の共通部分は次のとおりです。
サービス -APIを介してデータにアクセスするためのモジュール。 必要に応じて、追加のデータ変換がここで行われます。
フォーマッタ (フォーマッタ)-クライアントでフォーマットデータ(日付、通貨、表示名など)を提供します。
ヘルパー (ヘルパー) -AJAXリクエスト、設定へのアクセス、ポップアップメッセージの表示など、クライアントの一般的な操作を実行します。
さらに、選択したフレームワークに応じて実装される部分があります。
コンポーネント -クライアントインターフェイスの構成要素 。 最新のフレームワークはすべて、コンポーネントツリーとしてUIの作成をサポートしていますが、具体的な実装は異なります。 通常、コンポーネントは機能(Project、UserAccount、Ordersなど)に応じてフォルダーにグループ化されます。
状態(データ)とシステムイベントは別々に保存されます。Reactの場合、これらはフォルダー 'actions'、 'store'、 'reducers'、Vueの場合はフォルダー 'vuex'です。
ルーティング
Webアプリケーションの従来の構成では、異なるルート(URL)がサーバーから異なるページをロードします。 SPAアプリケーションでは、すべてのデータがすぐにロードされます。 別のページに移動しても、サーバーから新しいページが読み込まれることはなく、URLは変わりません。
これはユーザーにとってあまり便利ではありません。現在のリンクをブラウザーに保存できず、ページ間の移動に進む/戻るボタンを使用できません。
SPAにルーティングを追加する方法はいくつかあります。
- ハッシュタグ-古いブラウザ(IE9)をサポートするために使用され、アドレスはwww.mysite.com/#/product/listのようになります
- HTML5 History APIを使用すると、アドレスは通常のWebアプリケーションwww.mysite.com/product/listと同じように見えます
各クライアントフレームワークには、ルーティング用の個別のライブラリがあります。
Contosoは、History API(pushState)モードを使用します。
クライアントでルーティングを使用するには、サーバーで少し設定する必要があります。 不明なサーバールートはすべて、アプリケーションのメインページにリダイレクトする必要があります。 次に、サーバーからの最初のページのロード後、クライアントルーティングが機能します。
AJAXリクエスト
これは、選択したJSフレームワークにあまり依存しないタスクです。 VueおよびAngular用に特別に設計されたライブラリがありますが、それらの使用はオプションです。 AJAXライブラリは非常に多く存在するため、いくつかの優れたオプションを提供します。
プロジェクトがまだ何かにJQueryを使用している場合は、AJAXリクエストに使用できます。 Contosoでは、 jQueryはpromiseにラップされ、httpHelperモジュールを通じて使用されます。
別の良いオプションはaxiosです。 このライブラリには便利なAPIがあり、Promiseをサポートします。これはフルスタック開発にとって非常に重要であり、サーバーとクライアントの両方で同じように機能します。
JSからXMLHttpRequestを直接使用することは困難であるため、ネイティブFetchメソッドを置き換えるように提案されています。これはすべての主要なブラウザーでまだサポートされていませんが、このような場合にはいつものように、同じAPIで動作するフェッチポリフィルポリフィルを持つライブラリがあります。
すべてのAJAXリクエストで実行できるアクションがいくつかあります。
UIをブロックして、AJAX要求が完了してシステムステータスが更新されるまで、ユーザーが他のアクションを実行できないようにすることができます。
要求中にエラーが発生した場合、デフォルトでは、すべての要求に対して一般的なメッセージ(「サーバーエラー」など)を表示できます。
オプションで、すべてのAJAX要求のローカルロギングをブラウザコンソールに追加できます。
検証
クライアントでの検証は、サーバーでの検証とは異なります。 サーバーで、すべての受信パラメーターを検証する必要があります。 クライアントでデータが検証されたこと、または悪意のあるユーザーのリクエストではなく、クライアントコードからの呼び出しであることを信頼することはできません。
クライアントの状況は異なりますが、ユーザーが間違いを犯す可能性のある場所のみを検証する必要があります。 ただし、たとえば、サードパーティのコンポーネントを使用して日付を入力し、そこに間違った日付や空の日付を入力することが不可能な場合、検証する必要はありません。 同時に、どのエラーをどのように表示するかについてさらに考える必要があります。
クライアント検証は通常、使用されるクライアントフレームワークと密接に関連しています。 モデル内のデータのチェックに結び付けられ、エラーはモデルデータの状態に動的に依存します。
Contosoでは、Reactでは検証に補助ライブラリは使用されませんが、Vueでは「vue-validator」パッケージが使用されます。
構成
通常、クライアントには多数の構成設定はありませんが、それでも必要です。 たとえば、クライアントのデータの書式設定(日付、氏名、通貨)の設定、オプションですべてのAJAX要求をコンソールに記録するためのフラグなどを使用できます。
便宜上、サーバー構成からクライアント構成値を読み取り、クライアントで補助モジュールを使用できます。補助モジュールは、別のAJAX要求を通じてサーバーから値を減算します。
Contosoでは、これはそのように実装されています。「helpers / clientConfig」ファイルを参照してください。
エラー処理
クライアントエラーの主な原因はAJAXリクエストです。 クライアント部分とサーバー部分の両方を開発している場合、クライアントに表示できるエラーテキストをすぐに転送する方が簡単な場合があります。 APIを個別に開発する場合、エラーはHTTPコードまたはカスタム文字列コードを使用して処理されます;これは、AJAXリクエストを行うサービスメソッドですぐに行うのが最適です。
他のエラーはほとんどの場合まったく処理されず、処理すべきではないと想定されます。発生した場合、ユーザーはページの再読み込みを推測します。
ただし、 実稼働環境では、クライアントからエラーをログに記録できます。これには、 logentriesなどのいくつかのサービスがあります。
パッキング
大規模なクライアントアプリケーションを作成する場合、ブラウザを多数の小さなモジュールに分割する必要がありますが、ブラウザは多数のファイルでうまく機能しません(HTTP2はこれを修正します)。 したがって、コードまたはスタイルを持つ複数のファイルを1つまたは複数のアセンブリ(バンドル)に結合する場合、クライアントビルドのプラクティスがあります。 このために、さまざまなツールが使用されます。
タスクマネージャー (タスクランナー)は、JSファイルの結合と圧縮、SASS / LESSのコンパイル、ファイルのコピー、名前変更など、幅広いタスク用に設計されています。 必要な作業は、CLI(コンソール)を介して個別に実行できるタスクに分割されます。 さまざまなタスクを実行するには、特定のマネージャーに対してプラグインが使用されます。 最も人気のあるタスクマネージャーはGulpとGruntです。 最近、タスクマネージャーとそのプラグインを使用せずに、npmツールを使用してスクリプトを実行し、Nodeでスクリプト自体を記述する傾向があります。
クライアントアセンブリの一般的なタスクに加えて、モジュールバンドラーはJavaSrcriptファイルの依存関係を分析し、それに応じて元のアセンブリを結合します。 たとえば、module2.jsをインポートするmodule1.jsがあり、さらにmodule3.jsとlodashがインポートされる場合。 元のアセンブリでは、モジュールは目的の順序になります(ダッシュ、3、2、1)。 モジュールビルダーは、デフォルトで、外部モジュールを「node_modules」フォルダー内のnpmパッケージとして表示することを想定しています。
今日最も人気のあるのはWebPackです。 このタイプの最初のツールはBrowserifyで 、 WebPackよりも簡単ですが、より多くの構成が必要です。 ロールアップの人気が高まっています-インポートにES6構文を使用する場合、外部ライブラリのどの部分を使用するかを決定し、それらのみを含めることができるため、クライアントアセンブリのサイズを小さくできます。
Contosoは、クライアントビルド、npm、またはコンソール自体にWebPackを使用してタスクを実行します。 WebPackは、モジュールの結合、TypeScriptのES5へのトランスコンパイル、LESSからCSSへのスタイルの変換、単一のファイルへの結合、ビルド製品のためのJSとCSSの縮小を行います。
開発のために、WebPackを監視モードで実行する必要があります。クライアントファイルを変更すると、アセンブリが再構築され、ブラウザーでページをリロードする必要があります。
webpack --watch //-w shorter
WebPackでは、一部のJSフレームワークでHotReloadモードをサポートできます。これは、ページを完全にリロードせずにJSとCSSを更新する場合です。 ReactおよびVueでサポートされていますが、構成が難しく、正しく機能しない場合があります。 Contosoでは使用されません。
私はコメントを喜んでコメントします。
お楽しみに!