以下は、The Cat with a Dragon Tattoo によって2018/8/3にMediumに投稿され、現在1万Clap以上受けている記事、"[10 Things You Will Eventually Learn About JavaScript Projects]
(https://blog.usejournal.com/10-things-you-will-eventually-learn-about-javascript-projects-efd7646b958a)"=「JavaScriptプロジェクトでいずれは学ぶ10のこと」の日本語訳です。
特定のライブラリを超えた、しかしフロントエンド開発者を主眼とした学びがまとまっており、僕がまさに読みたかったものでした。著者に感謝を。
表示 - 非営利 - 継承 4.0 国際 (CC BY-NC-SA 4.0)
https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ja
JavaScriptは冒険です。
様々な業界で10年近く開発してきましたが、誰だってこれには同意してくれると思います。
フロントエンド開発は、プログラマーである私たちに、多くの選択の自由、柔軟性、創造の余地を与えてくれます。しかし代わりに、ちょっとした知識、計画、責任が求められます。
jQuery、require.js、Angular、React、ExtJs、その他思い出せない(または思い出したくない)何十ものプロジェクトを経験してきましたが、想像もしなかった酷いモノを見てきました。きっと皆さんもそうでしょう。
しかしどんな時代でも、まとまりのないプロジェクトをどうにか扱いやすく変えられる「共通のパターン」がありました。以下では、その中でも特に重要な10のパターンを記します。個人的な経験から導いた意見ですが、経験豊富なエンジニアの多くは頷いてくれるのではないでしょうか。これらのパターンは、どんなフレームワーク・方法論・チームの規模であっても、ドキュメンテーションやリファクタリングの必要性を減らし、エンジニアの目から零れる涙を減らし、プロジェクトの盤石な基礎となってくれるでしょう。
あなたに新しい発見があり、これらのパターンを便利だと感じ、またこれらを使って素晴らしい何かを作ってくれることを願います!
1.分割統治
聞いたことはありながら、多くの人がこのルールを過小評価しています。CommonJS、Webpack、Nodeではコードを複数のファイルに分割できます。でも、何故わざわざそんな事をするのでしょう?
一貫性
プロジェクトを1つのexportを持つファイルに分割すれば、プロジェクトが大きくなった時、検索や依存性の管理がずっと簡単になります。「ファイルの名前はそれがexportするものを示す」というルールは直感的で、脳みそを疲弊させずにアーキテクチャを概観することができます。
管理
各exportを独立ファイルに分割することで、必要なときに素早く移動できるようになり、分業が促進されます。ヘルパー関数がアプリケーションの他の場所で必要になれば、/shared
フォルダを作ってファイルを移動すれば良いわけです。そうすれば、また他の部分からも参照できます。
2.恥ずかしいくらい明確に
変数、関数、ファイルの名前は、自分の子供の名前だと思って時間をかけて決めましょう。変数x
とすれば今日の0.3秒が節約できるかもしれませんが、1ヶ月後には2日かけて意味を解明し、4日かけてリファクタすることになります。先々のことを考え、長い名前を恐れないようにしましょう。
ハック的な手法や、MITに入学したくなるような難しいやり方は避けましょう。その解決法は本当にスマートなのかもしれません。未来のあなたやチームメートも、コードの解読にたっぷり時間を費やした後で「賢いね!」と同意するかもしれません。しかし、物事をシンプルに保つことに集中し、なるべくドキュメントやコメントが必要ないようなコードを目指しましょう。
3.マジックナンバーやマジック文字列を解消する
どんなにやりたくなっても、マジックナンバー・マジック文字列は使ってはいけません。小さなもの、さして重要でないものでも、意味ある名前の変数に格納して、スコープの冒頭に置きましょう。
明示的にコードに書いた値は多くの場合どこかで再利用されます。すぐに変数に格納すれば、コードの重複は減り、修正は楽になり、値に意味を与えられます。
4.ネストと戦う
コードが横に120文字/縦に500行以上になるかif文が3層以上になったら、全力で分割しましょう。
深くネストされたif文を別々の関数、Promise、Observableに分割することで、条件文の複雑性を解消することができます。非同期呼び出しが多いなら、async/awaitも大幅にコードをシンプルにしてくれます。
5.configを頑張る
グローバル変数、APIエンドポイント、フィーチャートグル、サードパーティーの認証情報を使うなら、分離したconfigファイルに置きましょう。
WebでもNodeでも、config管理を助けてくれるconfigのようなパッケージが多数あります。あなたのアプリケーションはある時点でサーバーとローカル開発環境の両方で動くことになります。configファイルの作成は遅いより早いほうが簡単で、各環境ごとに挙動・使う認証情報・その環境で動く機能などなどを調整することができます。
6.フレームワークはあなたを助けるためにある
知っているから、人気だからという理由でフレームワークが使われている事がよくあります。
自分のプロジェクトにフレームワークが必要なのか、必要であればどれなのか、じっくり考えましょう。あなたのサイトがGitHubで10万starを獲得したフレームワークを活用していようがいまいが、エンドユーザーにとっては全くどうでも良いことです。
経験から、私はフレームワークを以下のように分類しています。
React
コンポーネントベースのWebアプリケーションで、アーキテクチャを完全にコントロールしたい場合に使えます。Reactエコシステムでの開発は、時間もかかり、事前に十分な計画が必要です。十分な知識がある場合に限り、Reactは多くのメリットをもたらします。
Angular / VueJS / Ember
信頼性の高いWebアプリケーションを素早く作りたい場合に使えます。引き換えに大きなブラックボックスを抱えることになります。これらのフレームワークは多くの仕事をしてくれるので、自前アーキテクチャの利点・欠点の両方がなくなります。構造が厳しく決められているため、多少間違いをおかしてもReactほど困ることは少ないでしょう。
jQuery / lodash / その類型
Webページを素早く作りたくて、何キロバイトかファイルが増えても良い場合に使えます。開発時間を劇的に短縮してくれますが、メンテナンス不能なコードも書けてしまうので注意が必要です。
Vanilla JS / フレームワークなし
WebページでもWebアプリケーションでも、開発と計画に多くの時間が使える場合に使えます。ピュアなJavaScriptは、実験的なこと...WebGL,Worker,深い最適化,ブラウザアニメーション...を行うのに合っています。最後には自分が新しいフレームワークを作ることになるでしょう。トランスパイラを使えば、より良く軽量なjQueryの代替物にもなります。
このリストは1つの提案として受け取ってください。フレームワークを使うか、何を使うか、プロジェクトにとってベストな選択をじっくり考えましょう。
7.プロトタイプでないなら、テストを書く
単体テスト、スモークテスト、EtoEテスト、ざっとした確認...。
プロジェクトがすぐに書き換えられるプロトタイプで無い限り、テストを書くべきです。コードベースが複雑になるにつれて、管理・メンテナンスは大仕事になります。テストはそれを肩代わりしてくれます。
未来のいつか、あなたはバグに遭遇し、青空を見上げて、テストを書いてくれた過去の自分に感謝することになります。新機能を追加したときに色々な所をひっそり壊してしまったことを、テストがなければ気づかなかっただろうからです。
8.バージョン管理システムを使う
プロトタイプだろうが、フルスケールの企業Webアプリケーションだろうが、小さな楽しい趣味プロジェクトだろうが、1行目のコードを書く瞬間からgitなどのバージョン管理システムを使いましょう。毎日コミットし、ブランチを使い、マージ・競合の解消・コミットの巻き戻しを学びましょう。意味のあるコミットメッセージを残しましょう。
バージョン管理によって、時間を移動し、壊したものを直し、過去の変更を見ることができます。この記事から1つだけ覚えてもらえるなら、日々バージョン管理システムの基本を学ぶこと、です。なぜなら、記事の残りの部分を無視して間違った道に進んでも、バージョン管理をしていれば直せるからです!それがなければ最初からやり直す運命になります。
9.確実な状態管理
状態管理のデザインパターンかライブラリを探して、自分の命がかかっているかのように齧りつきましょう。本当に命がかかる日がくるかもしれません。
フロントエンドエンジニアとして、通常私たちの大きな挑戦は2つだけです。データを表示することと、保管することです。長期間メンテナンスするという点では保管のほうが遥かに大変で、これを無視して開発するのと楽ができます。そして、数カ月後にプロジェクトは事実上メンテナンス不可能になるでしょう。
データの保管、すなわち状態管理は難しいものです。アプリケーションでは普通、サーバーがデータベースに持つデータとクライアントの画面に表示される内容が同期している必要があります。私たちのゴールは、その中間に置くJavaScriptで余計な複雑性を加えないことです。コンポーネントはサーバーと同じデータを提供し、ユーザーによる変更を同期させ、サーバー側の変更に追従しなければなりません。どうすればこれを実現できるでしょう?
React
Reactはとてもオープンなエコシステムを持っているため、ソリューションも十分にあります。FluxアーキテクチャにはRedux、observableベースならMobXがあります。それぞれメリット・デメリットがあります。使い始める前に各ライブラリの基礎を理解するようにしましょう。
Angular、Ember、VueJS
これらはビルドインで専用の状態管理の仕組みを持っており、コンセプトはObservableを基礎にしています。必須ではありませんが、追加のライブラリとしてngRx、Akita、Vuexがあります。
他のフレームワーク、Pure JavaScript
Redux、MobX、または独自のステート管理の仕組みを使えます。主なゴールは、アプリケーション全体で1つの「source of truth」(信頼できる情報源)を持つことです。この「情報源」は、サービスでも、ライブラリでも、単純なObservableでもありえます。
10.流行を疑う
最後に、コミュニティーに耳を傾け学びつつも、全ての記事、コメント、Mediumへの猫の長い投稿(訳注:この記事。著者のハンドルが猫)、あなたのコードへのフィードバックはよく吟味し、疑ってかかりましょう。フロントエンドの世界ではたくさんの新しいアイデアが勢いよく登場してきます。これらにはオープンな態度でありつつも、お祭り騒ぎを「追いかけるために追いかける」ことのないように気をつけましょう。こうした態度のために忘れさられてしまったプロジェクトが山ほどあります。
古く成熟したフレームワークで書かれたプロジェクトが、新しいものが出たからといって2つのフレームワークを混ぜたようなプロジェクトよりはるかに優れていることは珍しくありません。新しい流行の何かがアプリケーションや開発効率を少し向上させるとしても、一貫性には敵いません。メンテナンス性を保つために自分の最初の選択を守り、必要なときにだけ流行を取り入れましょう。
以上です!
ここまで読んでくれてありがとう。コメントであなたの意見や話を聞かせてくれるのを楽しみにしています。上述の通り、これらは私がJavaSriptとフロントエンド開発に関わる中で得られた一番大事な経験に過ぎません。私たちが経験する挑戦の大海のほんの一滴です。
これらのパターンがあなたの役に立ちますように。
(訳終)