本記事は、Giancarlo Buomprisco氏による「An Opinionated Coding Styleguide for Angular」(2020年3月9日公開)の和訳を、著者の許可を得て掲載しているものです。
#Angularコーディングスタイルガイド【個人的方法】
コードを書くための社内スタイルガイドは、開発チームがある時点、理想としてはプロジェクトの初期段階で定義し、合意すべき重要な決定事項です。
##はじめに
プロとしてコードを書いたことがあるなら、多くの、多くの開発者にとってスタイルがどれほど重要であるかをよく知っているはずです。私のキャリアの中でも、スタイルの議論に数え切れないほどの時間を費やしてきました。
しかし、なぜそれがそれほど重要なのでしょうか?**プログラマはコードを書くことより読むことの方がはるかに多いのです。**自分のためにも、特に仲間のためにも、このタスクをできるだけ単純化することが極めて重要です。
スタイルガイドは、最初のコードを書く前に定義するのが一般的ですが、だからと言ってプロジェクトのライフサイクル全体にわたり固定するべきではありません。実験と経験の積み重ねで得られる学びです。
また、毎日考えを変える必要があるという意味でもありません。プロジェクトの成長に合わせて、チームで評価し、議論し、決定する必要があるということです。
アルファ版の時代からAngularアプリを書いてきて、一緒に仕事をした人から強い影響を受け、たくさんの人のコードを読んだり、単に自分のプロジェクトで実験したりすることで、自分のスタイルを確立してきました。
この記事では、私がどのようにAngularアプリのスタイルを決定しているか、そしてその決定の論拠を紹介したいと思います。あなたやあなたのチームが採用したり、自分で作ったりするきっかけになればと思います。
また、このスタイルガイドを改善する提案も大歓迎です!
注意:このスタイルガイドは、技術的詳細やベストプラクティスに基づくものではなく、純粋にスタイルに関するものです。このスタイルガイドの目的は、単にコードの美しさや読みやすさを向上させることであり、パフォーマンスやデザインパターンなどを向上させるものではありません。
適切なスタイルガイドを適切なツールで補完する。
スタイルガイドを遵守するだけでなく、組織やオープンソースコミュニティの人にとって、コードの理解、保守、再利用が容易になるツールを使うことも重要です。私が愛用しているツールの1つはBit.devです。
Bit.devは、素晴らしいコンポーネントハブです。さまざまなAngularプロジェクトで再利用可能なコンポーネントをホストし、文書化し、管理する場所です。コンポーネントの分離と公開を担うオープンソースのツールBitと完璧に連携します。
例:Bit.devで共有Reactコンポーネントを検索する
##1. HTML折り返しと順序
Angularテンプレートには、通常のHTMLにかなりの数の構文が追加されていて、読みにくいことがあります。
まず提案したいのは、折り返しについてです。私は通常、すべてのファイルで1列あたり80文字を超えないようにしています。単純に、横方向より縦方向の方がずっと読みやすいからです。
次は、規則なしで書いた要素です。
ごちゃごちゃしていますよね?私がコンサルティングで担当したプロジェクトでは、ほとんどが同じような書き方をしていました。
上のスニペットを、簡単な規則に基づいて書き直し、読みやすくしてみましょう。
###HTMLタグの記述規則の定義
- 要素に2つ以上の属性がある場合、通常は1行に1つの属性しか書かない。
- 属性は特定の順序で書く。
- 属性が1つしかない場合を除き、終了タグは次の行に書く。
特定の順序を定義することをおすすめします。
- 構造的な指示
- アニメーション
- 静的プロパティ
- 動的プロパティ
- イベント
先の例を、個人的にはどのように書くかを見てみましょう。
さらに言えば、構造ディレクティブはいつもng-container
でだけ使うようにしています。
主観的な判断で属性の順番を変えてもいいとは思いますが、私は何よりもまず構造ディレクティブを表示することに強いこだわりがあります。
構造ディレクティブは、(他にいろいろ知る必要がある前に)次のことを教えてくれます。
- このフィールドは表示されているか?その理由は?
- このフィールドは繰り返されているか?
私の考えでは、これによりテンプレートの構造を読み、理解することが容易になります。
2. パイプ
パイプはとても強力です。テンプレートの値を変換したり、コンポーネントの重複やロジックを回避したりできます。また、再利用や組み合わせも容易で、書くのも簡単です。
しかし、読みやすく、見分けやすいでしょうか?イエスでありノーです。
これはとても主観的で些細なことですが、それでも共有する価値があると思います。私はテンプレートにパイプが出てくると、いつも括弧で囲む傾向があります。括弧による分割の感覚は、値が変換されていることを示す手がかりになり、一般的に見ても分かりやすいです。
複数のパイプを使う場合は、さらに重要かもしれません。
##3. ライフサイクルフック
###インターフェース
ライフサイクルフックインターフェースの追加は、必須ではありませんが推奨されているので、これに従うことを強くおすすめします。
###順序
私がライフサイクルフックを探す時、コンストラクタにすべてのフックがまとまっていて、他のクラスのメソッドと混同していないことを求めます。実行と同じ順序で定義されているのが理想です。
おすすめは次のことです。
- インターフェースを必ず追加する。
- コンストラクタの上に、パブリックプロパティとプライベートプロパティを追加する。
- コンストラクタのすぐ下、コンポーネントのメソッドの上に、メソッドを追加する。
- すべてのメソッドを近い場所に置く。
- 実行順に追加する。これを一貫させるのは少し難しいので、最重要事項ではないと思います。
###ロジック
私は通常、ライフサイクルフックに直接ロジックを書くことは避けています。その代わりに提案するのは、プライベートメソッドにロジックをカプセル化し、ライフサイクルフックでそれを呼び出すことです。
##4. コンポーネントのプロパティとメソッド
Angularは、コンポーネントの機能を拡張するため、コンポーネントのメソッドやプロパティにデコレータを使います。
デコレータの数はとても多いので、特定の順序を定義するのは大変です。重要なのは、同じデコレータを持つプロパティとメソッド同士を近くに置くことです。
次は、悪い例です。
私は次のように書きます。同じデコレータを持つプロパティのグループの間に空行があることに注目してください。これで読みやすくなると思います。
強い意見ではありませんが、デコレートされていないプライベートコンポーネントとパブリックコンポーネントのプロパティは、デコレートされたプロパティとは別に置くようにしましょう。
経験上、それらを混在させると混乱を招き、ごちゃごちゃした印象を与えます。
##5. 命名
命名は難しいですよね。
理解しやすく、明確で、検索しやすい名前を思い付くために、私はいつも2回以上考えます。
-
理解しやすい
一目見て何をするものか分かるか? -
明確である
例えば、1つのコンポーネントに複数のクリックイベントがある場合、そのイベントがどれを参照するのか分かるか?つまりonClickという名前はつけるべきではない。 -
検索しやすい
命名規則はSEOに少し似ている。ユーザー(チームメイトや私)が命名対象をどのように検索するか、ユーザーがより検索しやすくなるにはどのように書けば良いか?
###ファイル名
私はすべてのファイル名にハイフンを使うのが好きです。今ではTypescriptプロジェクトでは標準だと思いますが、Angularプロジェクトでさえ、かなりのバリエーションを見てきたので、これに言及する必要があると思っています。
例
sign-up.component.ts
profile-form.component.html
###ルートコンポーネント
私はルートコンポーネントの命名でpage
というサフィックスを付けることが多いです。
例えば、認証ページは通常auth-page.component.ts
と呼ばれます。これは、ルートコンポーネントであることを示し、通常router-outlet
経由で他のコンポーネントをラップして表示するために使います。
component
次は、私が守っているコンポーネントの命名規則です。
-
(プレフィックスを除いて)3語以内にする。特に理由はないが、見た目があまり良くないため。もちろん、この規則を守るのが難しい場合もある。
-
他のコンポーネントで既に使われている単語や文脈を繰り返さない。そうしてしまうと、IDEの検索機能を使う時に遅くなったり、他のファイルを間違って開いたりして、結局時間の無駄になり、フラストレーションの原因になる。
-
同時に、一般的になりすぎないようにする。例えば、component
settings
と言っても、何の設定か分からないので、さらに文脈を与えて手助けする(application-settings
、profile-settings
、organization-settings
など)。
小規模アプリケーションでは大したことではないが、大規模では違いが出る。
###イベント名
単純に見えますが、特に多くのイベントを持つ大規模コンポーネントでは違います。
次は、私が守っているイベントの命名規則です。
-
イベントや出力には、
on
というプレフィックスを付けない。代わりに、ハンドラーには付ける。 -
意味を考えさせないような名前にする。アクションそのものだけでなく、アクションが参照されるエンティティをいつも指定する。
valueがchanegeされたコンポーネントのイベントの場合、イベントのchange
はvalueChange
になる。
私の考えでは、これは明確で、何がchangeしたのか分かり、これがvalue
なのか、status
なのか、それ以外なのか、疑問に思わない名前である。 -
過去形を使うか(
valueChange
対valueChanged
)については議論の余地がある。反対意見の正当な理由を聞いたので、チームで議論する必要があるかもしれない。
どちらかの意見が正しいと思うなら、それでいいだろう。あなたの意見は?
##6. ESインポート
特にIDEを使って入力時に自動追加する場合、ファイルのインポートを順序付けて整理するのは難しいです。ファイルが大きくなると、かなり乱雑になります。
次は、私のインポートの整理方法です。
- 最初に、Angularインポート
- Rxインポート
- サードパーティー(必須ではない)
- 最後に、ローカルインポートとプロジェクトインポート
各グループの上にコメントを残すのもおすすめです。
###Opinionated Angularリポジトリ
Opinionated AngularというGithubリポジトリを追加しました。読みやすく美しいAngularコードを書くため、ここに私の考えをもっと書き込みます。
よかったら参加してください!
##まとめ⭐
- HTML要素を整理してラップする。1行に属性は1つだけ書き、属性はタイプ順に並べる。
- パイプを使う値は括弧で囲む。
- ライフサイクルフックはまとめて置き、実行順に並べる。
- 命名は、理解しやすく、明確で、検索しやすい名前にする。
- ESインポートを整理して順序付ける。
あなたのチームが実践している規則の秘訣をぜひ教えてください。また、説明が必要な場合や、不明確な点や間違っている点がある場合は、ぜひコメントをください!
この記事を楽しんでいただけたら嬉しいです。ソフトウェア開発、フロントエンド、RxJS、Typescriptなどに関する記事をお探しなら、Medium、Twitter、私のウェブサイトをフォローしてください!
##もっと見る
AngularとBitによるコンポーネント共有Bit入門
Angularコンポーネントの構築と共有
blog.bitsrc.io
【2020年版】Angularデベロッパーツール トップ11
凄く気に入っている、ぜひ試すべきAngularライブラリとツール
blog.bitsrc.io
Angularで大きいリストをレンダリングする3つの方法
Angularで大きいリストをレンダリングするために使えるテクニック概要
blog.bitsrc.io
##翻訳協力
この記事は以下の方々のご協力により公開する事ができました。改めて感謝致します。
Original Author: Giancarlo Buomprisco (gc@frontend.consulting)
Original Article: An Opinionated Coding Styleguide for Angular
Thank you for letting us share your knowledge!
選定担当: @gracen
翻訳担当: @gracen
監査担当: -
公開担当: @gracen
##ご意見・ご感想をお待ちしております
今回の記事はいかがでしたか?
・こういう記事が読みたい
・こういうところが良かった
・こうした方が良いのではないか
などなど、率直なご意見を募集しております。
頂いたお声は、今後の記事の質向上に役立たせて頂きますので、お気軽に
コメント欄にてご投稿ください。Twitterでもご意見を受け付けております。
皆様のメッセージをお待ちしております。