この記事は、トム・グレコ、ダン・プリンス、ヤフィ・ベルハヌによって査読されました。 SetePointコンテンツを最高にするためにSitePointのピアレビュアーのすべてに感謝します! ほとんどすべての開発者が、レガシープロジェクトを維持または引き継ぐ経験があります。または、多分それは再び取り上げられた古いプロジェクトです。一般的な最初の考えは、コードベースを捨てて、ゼロから始めることです。コードは乱雑で文書化されていない場合があり、すべてを完全に理解するには数日かかる場合があります。しかし、適切な計画、分析、および優れたワークフローにより、スパゲッティコードベースをきれいで整理されたスケーラブルなものに変えることができます。
多くのプロジェクトを引き継ぎ、クリーンアップしなければなりませんでした。私がゼロから始めたことはたくさんありませんでした。実際、私は現在それを正確に行っています。私はJavaScriptに関して多くのことを学びました。コードベースを整理し、最も重要なことは、前の開発者で怒っていないことです。この記事では、私のステップを紹介して、私の経験をお話ししたいと思います。テクノロジーを知ることは良いスタートですが、本当の感触と理解を得るためには、ユニットテストを調べる時が来ました。単体テストは、機能をテストする方法とコードの方法であり、コードが意図したとおりに動作するようにします。読み取りと実行中の単体テストは、読み取り専用のコードよりもはるかに深い理解を与えます。それらがあなたのプロジェクトの単体テストではない場合、心配しないでください、私たちはそれに来るでしょう。
これは一貫性を確立することです。プロジェクトツールチェーンに関するすべての情報が得られたので、構造とロジックの接続方法がわかったので、ベースラインを作成する時が来ました。 .editorconfigファイルを追加して、コーディングスタイルガイドをさまざまなエディター、IDE、開発者の間で一貫させ続けることをお勧めします。
コヒーレントインデンテーション戦争)は、スペースやタブを使用する必要があるかどうかは関係ありません。コードベースはスペースで書かれていますか?スペースを続けます。タブ付き?それらを使用します。コードベースに混合インデンテーションがある場合にのみ、どちらを使用するかを決定する必要があります。意見は問題ありませんが、優れたプロジェクトは、すべての開発者が手間をかけずに動作できるようにします。 なぜこれが重要なのですか?誰もが編集者またはIDEを使用する独自の方法を持っています。たとえば、私はコード折りたたみの大ファンです。その機能がなければ、私は文字通りファイルで紛失しています。インデントが一貫性がない場合、この機能は失敗します。そのため、ファイルを開くたびに、作業を開始する前にインデンテーションを修正する必要があります。これは大きな時間の無駄です。
命名
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
すべてをリントする
<span>// Inconsistent naming makes it harder </span><span>// to scan and understand the code. It can also </span><span>// lead to false expectations. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const self = $(this); </span> <span>const _internalElement = $('.internal-element'); </span> <span>let $data = element.data('foo'); </span> <span>//... more logic. </span><span>} </span> <span>// This is much easier and faster to understand. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const $this = $(this); </span> <span>const $internalElement = $('.internal-element'); </span> <span>let elementData = $element.data('foo'); </span> <span>//... more logic. </span><span>} </span>
依存関係の更新
依存関係の更新は慎重に行う必要があります。依存関係が経験した変更に注意を払っていない場合、より多くのエラーを導入するのは簡単です。一部のプロジェクトは、固定バージョン(v1.12.5など)で動作する場合がありますが、他のプロジェクトはワイルドカードバージョン(v1.12.xなど)を使用しています。クイックアップデートが必要な場合は、次のようにバージョン番号が作成されます:major.minor.patch。セマンティックバージョンの仕組みに慣れていない場合は、ティムオックスリーのこの記事を読むことをお勧めします。
依存関係を更新するための一般的なルールはありません。各プロジェクトは異なり、そのように処理する必要があります。依存関係のパッチ番号を更新することはまったく問題ではないはずであり、マイナーも通常は問題ありません。依存関係の主要な数をぶつけるときのみ、正確に変化したものを調べる必要があります。たぶん、APIが完全に変更されており、アプリケーションの大部分を書き直す必要があります。それが努力する価値がない場合は、次のメジャーバージョンへの更新を避けます。
プロジェクトがNPMを依存関係マネージャーとして使用している場合(および競合他社はいません)、CLIから便利なNPM時代遅れのコマンドを使用して時代遅れの依存関係を確認できます。 Frontbookと呼ばれる私のプロジェクトの1つの例でこれを説明させてください。ここでは、すべての依存関係を頻繁に更新します。
あなたが見ることができるように、私はここに多くの主要な更新があります。それらすべてを一度に更新するわけではありませんが、一度に1つずつ更新します。確かに、これには多くの時間がかかりますが、それは何も壊れないことを保証する唯一の方法です(プロジェクトにテストがない場合)。
私があなたと一緒に持ってほしい主なメッセージは、クリーンアップがコードの大きなセクションを削除して書き直すことを意味するわけではないということです。もちろん、これは時々唯一の解決策ですが、それはあなたの最初で唯一のステップであるべきではありません。 JavaScriptは奇妙な言語になる可能性があるため、一般的に一般的なアドバイスを与えることは不可能です。あなたは常にあなたの特定の状況を評価し、実用的な解決策を把握する必要があります。
単体テストを使用すると、コードがどのように機能するかを理解し、偶然に何も壊れません。 JavaScriptの単体テストは独自の記事の価値があるので、ここではあまり詳しく説明することはできません。広く使用されているフレームワークは、カルマ、ジャスミン、モカ、またはAVAです。ユーザーインターフェイスもテストしたい場合は、nightwatch.jsとdalekjsが推奨されるブラウザー自動化ツールです。
単体テストとブラウザの自動化の違いは、前者がJavaScriptコード自体をテストすることです。これにより、すべてのモジュールと一般的なロジックが意図したとおりに機能することが保証されます。一方、ブラウザの自動化は、プロジェクトの表面(ユーザーインターフェイス)をテストし、要素が適切な場所にあり、期待どおりに機能するようにします。JavaScriptアーキテクチャは、もう1つの大きなトピックです。アーキテクチャのリファクタリングとクリーンアップは、それを行うことであなたがどれだけの経験を持っているかに要約されます。ソフトウェア開発には多くの異なる設計パターンがありますが、それらのすべてがスケーラビリティが関係する場合に適しているわけではありません。残念ながら、この記事のすべてのケースをカバーすることはできませんが、少なくともいくつかの一般的なアドバイスを与えることができます。
まず、プロジェクトですでに使用されているデザインパターンを把握する必要があります。パターンについて読んで、一貫していることを確認してください。スケーラビリティへのキーの1つは、方法論を混合しないパターンに固執することです。もちろん、プロジェクトのさまざまな目的のために異なる設計パターンを持つことができます(たとえば、データ構造または短い名前のヘルパー関数にSingletonパターンを使用し、モジュールのオブザーバーパターンを使用することはできませんが、1つのモジュールを1つのパターンと別のモジュールで記述しないでください。パターンが異なるもの。プロジェクトに実際にアーキテクチャがない場合(すべてが1つの巨大なapp.jsにあるだけかもしれません)、それを変更する時が来ました。一度にすべてをしないでくださいが、一枚一番です。繰り返しますが、物事を行う一般的な方法はなく、すべてのプロジェクトのセットアップは異なります。フォルダー構造は、サイズと複雑さに応じて、プロジェクト間で異なります。通常、非常に基本的なレベルで - 構造は、すべてのモジュールとロジックが初期化されるサードパーティライブラリ、モジュール、データ、エントリポイント(index.js、main.jsなど)に分割されます。
これにより、モジュール化につながります。
すべてをモジュラー化しますか?モジュール化は、偉大なJavaScriptスケーラビリティの質問に対する答えではありません。開発者が慣れ親しんでいるAPIの別のレイヤーを追加します。ただし、これは手間がかかる可能性があります。原則は、すべての機能を小さなモジュールに分割することです。それを行うことで、コードの問題を解決し、同じコードベース上のチームで作業する方が簡単です。すべてのモジュールには、正確に1つの目的とタスクが必要です。モジュールは、アプリケーションの外部ロジックについて知らず、さまざまな場所や状況で再利用できます。
これはそれほどモジュール式ではありません。すべてがしっかりと接続されており、他のピースに依存しています。より大きく、より複雑な機能でこれを想像してください。何かが壊れるので、これをデバッグする必要があります。 APIは応答しないかもしれませんが、JSONなどの内部で何かが変わりました。悪夢、そうではありませんか?
さまざまな責任を分けてみましょう:
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
さて、3つの新しいモジュールがあります。リファクタリングされたフェッチコールを見てみましょう
既に述べたように、小さなモジュールでコードベースを回すと、APIの別のレイヤーが追加されます。あなたがそれを望まないが、他の開発者があなたのコードを操作しやすくしやすくしたいなら、機能を大きく保つことは絶対に問題ありません。コードをより単純な部分に分解し、テスト可能なコードにもっと集中することができます。
組織化されたコミットワークフローがあります これがすべての仕組みに短い更新が必要な場合、Githubからバージョン制御ワークフローに興味深いガイドがあります。
最終的には、その否定性はすべて私をどこにも連れてこなかった。その結果、必要以上にリファクタリングし、時間を浪費し、おそらく物事を壊すことになります。これはあなたをますますイライラさせます。余分な時間を費やすかもしれませんし、すでに動作しているモジュールを書き直してくれたことに感謝しません。それだけの価値はありません。必要なことを行い、状況を分析します。モジュールに戻るたびにいつでも小さなビットをリファクタリングできます。 コードがそのまま記述される理由は常にあります。以前の開発者は、それを適切に行うのに十分な時間がなかったのかもしれませんし、もっとよく知りませんでした。私たちは皆そこにいました。 次のプロジェクトのチェックリストを作成するために、すべての手順をもう一度進めましょう。
保守可能なJavaScriptコードの書き込みに役立ついくつかのツールがあります。これらには、コード標準を実施し、コードの潜在的な問題を強調できるEslintのようなリナーが含まれます。 Visual Studioコードなどのコードエディターは、構文の強調表示や自動完了などの機能を提供することでも役立ちます。さらに、GITなどのバージョン制御システムは、コードの変更を追跡し、他の人とコラボレーションしやすくするのに役立ちます。オブジェクト指向プログラミング(OOP)は、メンテナンス可能なコードを書くのに役立つプログラミングパラダイムです。これにより、コードをオブジェクトに整理することができます。これには、データと関数の両方を含めることができます。これにより、特定のタスクを実行してコード全体で使用するオブジェクトを作成できるため、コードがよりモジュール化され、再利用可能になります。 OOPは、コードの実際の概念をモデル化できるようにするため、コードも理解しやすくなります。コード。これは、他の開発者(およびあなたの将来の自己)が、コードが何をしているのか、なぜ特定の決定が下されたのかを理解するのに役立ちます。これは、コードの機能を理解することが困難な複雑なコードベースで特に重要です。ただし、コメントは慎重に使用する必要があります。過度にコメントすることで、コードを乱雑にし、読みにくくすることができます。理想的には、コードは、特定の決定が行われた理由を説明するか、コードの複雑なセクションを明確にするためのコメントを備えた自明である必要があります。 JavaScriptコードはスケーラブルであり、コードを効率的に増加させることを可能にする方法でコードを設計することを伴います。これは、効率的なアルゴリズムとデータ構造の使用、グローバル変数の回避、DOM操作の最小化など、優れたプログラミングプラクティスに従うことで実現できます。さらに、コードがより小さな再利用可能なピースに分解されるコードへのモジュラーアプローチを使用すると、スケーラビリティも向上します。テストは、保守可能なJavaScriptコードを書く上で重要な役割を果たします。これは、コードが期待どおりに機能することを保証し、開発プロセスの早い段階でバグをキャッチするのに役立ちます。ユニットテスト、統合テスト、エンドツーエンドテストなど、使用できるテストにはいくつかの種類があります。これらのテスト方法の組み合わせを使用すると、コードが堅牢で信頼性があることを確認するのに役立ちます。 保守可能なJavaScriptコードを作成するための最新のベストプラクティスに追いついて、業界のブログを定期的に読んで、ウェビナーや会議に出席することで達成できます。 、およびオンラインコミュニティに参加しています。さらに、継続的な学習を実践し、コードを定期的にレビューしてリファクタリングすることも、最新のベストプラクティスを最新の状態に保つことができます。
ドキュメントは、頻繁に議論されているトピックです。プログラミングコミュニティの一部はすべてを文書化することを提唱していますが、別のグループは自己文書化コードが進むべき方法だと考えています。人生のほとんどのものと同様に、両方のバランスが良いとコードが読みやすくスケーラブルになると思います。ドキュメントにはjsdocを使用します。<span>// While this is valid JavaScript, the block can't
</span><span>// be properly folded due to its mixed indentation.
</span> <span>function foo (data) {
</span> <span>let property = String(data);
</span>
<span>if (property === 'bar') {
</span> property <span>= doSomething(property);
</span> <span>}
</span> <span>//... more logic.
</span> <span>}
</span>
<span>// Correct indentation makes the code block foldable,
</span><span>// enabling a better experience and clean codebase.
</span><span>function foo (data) {
</span> <span>let property = String(data);
</span>
<span>if (property === 'bar') {
</span> property <span>= doSomething(property);
</span> <span>}
</span> <span>//... more logic.
</span><span>}
</span>
<span>// Inconsistent naming makes it harder
</span><span>// to scan and understand the code. It can also
</span><span>// lead to false expectations.
</span><span>const $element = $('.element');
</span>
<span>function _privateMethod () {
</span> <span>const self = $(this);
</span> <span>const _internalElement = $('.internal-element');
</span> <span>let $data = element.data('foo');
</span> <span>//... more logic.
</span><span>}
</span>
<span>// This is much easier and faster to understand.
</span><span>const $element = $('.element');
</span>
<span>function _privateMethod () {
</span> <span>const $this = $(this);
</span> <span>const $internalElement = $('.internal-element');
</span> <span>let elementData = $element.data('foo');
</span> <span>//... more logic.
</span><span>}
</span>
リファクタリングはそれ自体で大きな使命です。常に変更をロールバックできるようにするには(何かを壊して後で気づいた場合にのみ)ロールバックできるように、すべてのアップデートをコミットすることをお勧めします。方法を書き直しますか? gitコミット(またはSVNを使用している場合はSVNコミット)。名前空間、フォルダー、またはいくつかの画像の名前を変更しましたか? gitコミット。あなたはアイデアを得ます。一部の人々がやることは退屈かもしれませんが、それは本当にあなたが適切に掃除して整理されるのに役立ちます。
リファクタリングの取り組み全体の新しいブランチを作成します。マスターで作業しないでください!クイック変更を行う必要があるか、バグ修正を生産環境にアップロードする必要がある場合があり、テストおよび終了するまで(おそらく未検証の)コードを展開したくない場合があります。したがって、常に別のブランチで作業することをお勧めします。
それを包みます
プロジェクトを分析します
開発者の帽子を一瞬片付け、それが何であるかを見るためにユーザーになります。
インデントを一貫させる。タブやスペースは重要ではありません
命名規則を施行します。
アーキテクチャとデザインのパターンが一貫していることを確認してください
デザインパターンを混ぜないで、すでにそこにあるものに固執します。
それをしたくない場合は、テスト可能なコードにもっと集中し、より単純なブロックに分解します。
適切に指定された関数を備えたバランスの取れた方法で関数とコードを文書化します。
メンテナブルJavaScript
の書き込みに関するよくある質問(FAQ)
メンテナンス可能なJavaScriptコードの書き込みに役立つツールを使用できますか?
メンテナブルJavaScriptコードを作成するための最新のベストプラクティスに追いつくにはどうすればよいですか?
以上がスパゲッティコードの解き:保守可能なJavaScriptの書き込みの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。