大規模な Vue.js プロジェクトの構築と維持のための 10 のベスト プラクティス

大規模な Vue.js プロジェクトの構築と維持のための 10 のベスト プラクティス

これは、大規模なコードベースを持つ Vue プロジェクトに取り組んでいるときに私が開発したベスト プラクティスです。これらのヒントは、保守と共有が容易な、より効率的なコードを開発するのに役立ちます。

今年のフリーランスとしてのキャリアの中で、いくつかの大規模な Vue アプリケーションに取り組む機会がありました。私が話しているプロジェクトには、12 を超える Vuex ストア、多数のコンポーネント (場合によっては数百)、および多数のビュー (ページ) があります。コードを拡張可能にするための興味深いパターンをたくさん発見できたので、私にとっては実にやりがいのある経験でした。また、有名なスパゲッティコード問題につながるいくつかの悪い習慣も修正する必要がありました。

そこで今日は、大規模なコードベースを扱う場合に従うことをお勧めする 10 のベスト プラクティスを紹介します。

1. スロットを使用してコンポーネントを理解しやすくし、より強力にする

ある日、ポップアップを作成する必要がありました。一見すると、特に複雑なことはなく、タイトル、説明、いくつかのボタンがあるだけです。そこで、すべてを属性として扱うことにします。最後に、誰かがボタンをクリックしたときにイベントが発行されるように、3 つのプロパティを使用してコンポーネントをカスタマイズしました。とても簡単です! :汗_笑顔:

しかし、プロジェクトが拡大するにつれて、チームからはフォーム フィールド、さまざまなボタン (表示されるページによって異なります)、カード、フッター、リストなど、他にも多くの新しいものを表示するように依頼されました。このコンポーネントを拡張するためにプロパティを使い続けると、機能することがわかりました。しかし、神様、:weary: 私は間違っていました!コンポーネントは、無数のサブコンポーネントを含み、使用するプロパティが多すぎ、多数のイベントが発行されたため、すぐに複雑になりすぎて理解できなくなりました。 :volcano: どこかに変更を加えると、別のページの他の部分が壊れてしまうというひどい状況に遭遇したことがあります。保守可能なコンポーネントの代わりにフランケンシュタインの怪物を作ってしまいました!

しかし、最初からスロットに頼っていたら、状況はもっと良くなっていたかもしれません。最後に、この小さなコンポーネントを提供するためにすべてをリファクタリングしました。メンテナンスが簡単になり、理解が速くなり、スケーラビリティが大幅に向上しました。

<テンプレート>
  <div class="c-base-popup">
    <div v-if="$slots.header" クラス="c-base-popup__header">
      <スロット名="ヘッダー">
    </div>
    <div v-if="$slots.subheader" クラス="c-base-popup__subheader">
      <スロット名="サブヘッダー">
    </div>
    <div class="c-base-popup__body">
      <h1>{{ タイトル }}</h1>
      <p v-if="description">{{ 説明 }}</p>
    </div>
    <div v-if="$slots.actions" クラス="c-base-popup__actions">
      <スロット名="アクション">
    </div>
    <div v-if="$slots.footer" クラス="c-base-popup__footer">
      <スロット名="フッター">
    </div>
  </div>
</テンプレート>
<スクリプト> エクスポート デフォルト {
  小道具: {
    説明:
      タイプ: 文字列、
      デフォルト: null
    },
    タイトル:
      タイプ: 文字列、
      必須: true
    }
  }
} </スクリプト> 


私が言いたいのは、経験上、スロットをいつ使用するかを知っている開発者が構築したプロジェクトは、将来の保守性に大きな影響を与えるということです。これにより、発行されるイベントの数が減り、コードが理解しやすくなり、内部に必要なコンポーネントをより柔軟に表示できるようになります。

経験則として、子コンポーネントのプロパティを親コンポーネントに複製することになった場合は、その時点からスロットを使用する必要があることに注意してください。

2. Vuexストアを正しく整理する

多くの場合、新しいVue.js開発者がVuex学習を始めるのは、次の 2 つの問題に遭遇するためです。

  • ツリー構造内で物理的に離れすぎている別のコンポーネントから特定のコンポーネントのデータにアクセスする必要がある場合、または
  • コンポーネントの破壊から生き残るためにはデータが必要です。

ここで、最初のVuexストアを作成し、モジュールについて学習し、アプリケーション内でモジュールを整理し始めます。

問題は、モジュールを作成するときに従うべき単一のパターンがないことです。しかし、どのように整理したいかについてはよく考えることを強くお勧めします。私の理解するところによると、ほとんどの開発者は機能別に整理することを好みます。例えば:

  • 検証コード
  • ブログ
  • 受信トレイ
  • 設定

私としては、API から抽出したデータ モデルに従って整理すると理解しやすくなると思います。例えば:

  • ユーザー数
  • チーム
  • メッセージの内容
  • ウィジェット
  • 記事

どれを選ぶかはあなた次第です。心に留めておかなければならない唯一のことは、適切に整理されたVuexストアによって、長期的にはチームの生産性が向上するということです。これにより、新人がチームに参加した直後からコードベースを理解しやすくなります。

3. Vuex Actionsを使用してAPI呼び出しを行い、データを送信する

私の API 呼び出しのほとんどは、 Vuex vuex actionsで実行されます。なぜこの呼び出しの方が良いのか疑問に思うかもしれません。

なぜなら、それらのほとんどは、ストレージ ( vuex store ) に送信する必要があるデータを抽出するからです。さらに、カプセル化と再利用性も提供しており、非常に気に入っています。私がこれをする理由は他にもいくつかあります:

  • 記事のトップページを 2 つの異なる場所 (ブログとトップページなど) で取得する必要がある場合は、正しいパラメータを使用して適切なディスパッチャを呼び出すことができます。データは、スケジューラ呼び出し以外のコードが重複することなく取得、送信、返されます。
  • 最初のページが取得されるときにそれを取得しないようにするためのロジックを作成する必要がある場合は、それを 1 か所で実行できます。サーバーの負荷を軽減するだけでなく、どこでも機能すると確信しています。
  • これらのアクション (vuex アクション) で Mixpanel イベントのほとんどを追跡できるため、分析コードベースの保守が非常に簡単になります。すべての Mixpanel 呼び出しがアクション内で個別に実行されるアプリケーションがいくつかあります。 :joy: 何を追跡し、何を追跡しないか、いつ送信するかを追跡する必要がないので、このように作業するとどれほど楽しいことでしょう。

翻訳注: Mixpanel 、ユーザーが閲覧したページ数、 iPhoneアプリの分析、 Facebookアプリのインタラクション、電子メールの分析など、さまざまなユーザー行動を開発者が追跡できるようにするデータ追跡および分析会社です。 Firebaseに似た使用時点分析ツール。

4. mapState、mapGetters、mapMutations、mapActionを使用してコードベースを簡素化する

通常、コンポーネント内でstate/getterにアクセスしたり、 action/mutationを呼び出したりする必要がある場合は、複数の計算プロパティまたはメソッドを作成する必要はありません。 mapStatemapGettersmapMutationsmapActionsを使用すると、コードを短縮し、グループ化して簡素化し、ストレージ モジュールの全体像を 1 か所で把握できるようになります。

// 非PM
「vuex」から mapState、mapGetters、mapActions、mapMutations をインポートします。
エクスポートデフォルト{
  計算: {
    // ルートプロパティへのアクセス
    ...mapState("my_module", ["プロパティ"]),
    // ゲッターへのアクセス
    ...mapGetters("my_module", ["プロパティ"]),
    // ルート以外のプロパティへのアクセス
    ...mapState("my_module", {
      プロパティ: 状態 => state.object.nested.property
    })
  },
  メソッド: {
    // アクションへのアクセス
    ...mapActions("my_module", ["myAction"]),
    // ミューテーションへのアクセス
    ...mapMutations("my_module", ["myMutation"])
  }
}; 


これらの便利なヘルパーに関する必要な情報はすべて、公式のVuexドキュメントで入手できます。

5. APIファクトリーを使用する

私は通常、API エンドポイントを取得するためにどこからでも呼び出すことができるthis.$apiヘルパーを作成するのが好きです。プロジェクトのルートには、すべてのクラスを含む api フォルダーがあります (以下の 1 つを参照)。

API
├── auth.js
├── 通知.js
└── チーム.js 


各ノードは、そのカテゴリのすべてのエンドポイントをグループ化します。これは、プラグインを使用してNuxtアプリでこのパターンを初期化する方法です (これは、標準の Vue アプリのプロセスと非常によく似ています)。

// プロジェクト: API
"@/api/auth" から Auth をインポートします。
「@/api/teams」からTeamsをインポートします。
「@/api/notifications」から通知をインポートします。
エクスポートデフォルト(コンテキスト、注入)=> {
  プロセスクライアントの場合{
    const トークン = localStorage.getItem("トークン");
    // 定義されたときにトークンを設定する
    if (トークン) {
      context.$axios.setToken(トークン、「ベアラー」);
    }
  }
  // APIリポジトリを初期化する
  const リポジトリ = {
    認証: Auth(context.$axios)、
    チーム: チーム(context.$axios)、
    通知: Notifications(context.$axios)
  };
  inject("api", リポジトリ);
}; 


エクスポートデフォルト$axios => ({
  パスワードを忘れた場合(メールアドレス)
    $axios.$post("/auth/password/forgot", { email }) を返します。
  },
  ログイン(メールアドレス、パスワード) {
    $axios.$post("/auth/login", { メールアドレス、パスワード }); を返します。
  },
  ログアウト() {
    $axios.$get("/auth/logout"); を返します。
  },
  レジスタ(ペイロード) {
    $axios.$post("/auth/register", ペイロード) を返します。
  }
}); 


これで、次のようにコンポーネントまたは Vuex アクションで簡単に呼び出すことができます。

エクスポートデフォルト{
  メソッド: {
    送信() {
      試す {
        this.$api.auth.login(this.email, this.password);
      } キャッチ(エラー){
        コンソールエラー(エラー);
      }
    }
  }
}; 


6. $config を使用して環境変数にアクセスする(特にテンプレートで便利)

おそらく、プロジェクトにはいくつかのファイルで定義されたグローバル構成変数があります。

設定
├── 開発.json
└── production.json 


特にテンプレートを使用している場合は、 this.$configヘルパーを使用してすばやくアクセスするのが好きです。いつものように、Vue オブジェクトの拡張は非常に簡単です。

// 非PM
「vue」からVueをインポートします。
// プロジェクト: コモンズ
「@/config/development.json」から開発をインポートします。
「@/config/production.json」からproductionをインポートします。
process.env.NODE_ENV === "production"の場合{
  Vue.prototype.$config = Object.freeze(production);
} それ以外 {
  Vue.prototype.$config = Object.freeze(開発);
} 

7. コミットコメントを書く際の慣例に従う

プロジェクトが拡大するにつれて、コンポーネントのコミット履歴を定期的に参照する必要が出てきます。チームがコミット メッセージの記述に関して同じ規則に従わない場合、各チーム メンバーが何をしているのか理解するのは難しくなります。

私は常にAngular commitメッセージ ガイドラインを使用し、推奨しています。私は取り組むすべてのプロジェクトでこれに従いますが、多くの場合、他のチームメンバーもこれに従う方が良いことにすぐに気づきます。

これらのガイドラインに従うと、メッセージが読みやすくなり、プロジェクト履歴を確認するときにコミットを追跡しやすくなります。簡単に言うと、仕組みは次のようになります:

git commit -am "<タイプ>(<スコー​​プ>): <件名>"
# ここにいくつかのサンプルがあります
git commit -am "docs(changelog): changelog を beta.5 に更新"
git commit -am "fix(release): 最新の rxjs と zone.js に依存する必要があります" 


規則の詳細については、 READMEファイルを参照してください。

8. プロジェクトを作成するときは常にパッケージのバージョンを固定する

わかっています...すべてのパッケージはセマンティック バージョン管理ルールに従う必要があります。しかし、現実には、そうではないものもあります。 :汗_笑顔:

依存関係の 1 つがプロジェクト全体を壊してしまい、夜中に目が覚めてしまうことを避けるために、すべてのパッケージのバージョンをロックダウンすると、朝のストレスが軽減されます。 :無実の:

意味は簡単です。 ^ で始まるバージョンの使用を避けてください。

{
  "名前": "私のプロジェクト",
  "バージョン": "1.0.0",
  「プライベート」:true、
  「依存関係」: {
    "axios": "0.19.0",
    "imagemin-mozjpeg": "8.0.0",
    "imagemin-pngquant": "8.0.0",
    "imagemin-svgo": "7.0.0",
    "nuxt": "2.8.1",
  },
  「devDependencies」: {
    "自動プレフィックス": "9.6.1",
    "babel-eslint": "10.0.2",
    "eslint": "6.1.0",
    "eslintフレンドリーフォーマッタ": "4.0.1",
    "eslint-loader": "2.2.1",
    "eslint-プラグイン-vue": "5.2.3"
  }
} 

9. 大量のデータを表示するときはVue仮想スクロールバーを使用する

特定のページに多数の行を表示したり、大量のデータをループしたりする必要がある場合、ページが非常に速くレンダリングされることに気付いたかもしれません。この問題を解決するには、 vue-virtual-scollerを使用できます。

npm で vue-virtual-scroller をインストールします 


リスト内の表示されている項目のみをレンダリングし、コンポーネントと DOM 要素を再利用して、可能な限り効率的にします。使い方はとても簡単で、滑らかに塗れます

<テンプレート>
  <リサイクルスクロール
    クラス="スクロール"
    :items="リスト"
    :item-size="32"
    キーフィールド="id"
    v-slot="{アイテム}"
  >
    <div class="ユーザー">
      {{アイテム名}}
    </div>
  </リサイクルスクロール>
</テンプレート> 


10. サードパーティのパッケージのサイズを追跡する

多くの人が同じプロジェクトに取り組んでいる場合、誰も監視していないと、インストールされるパッケージの数はあっという間に信じられないほどの数にまで達する可能性があります。アプリの速度低下を回避するために (特に低速のモバイル ネットワークの場合)、 Visual Studio Codeの import-expense パッケージを使用します。この方法により、インポートしたモジュール ライブラリの大きさをエディターから直接確認でき、インポートしたモジュール ライブラリが大きくなりすぎたときに何が問題になったかを確認できます。

たとえば、最近のプロジェクトでは、lodash ライブラリ全体(縮小すると約 24kB)をインポートしました。問題は、プロジェクトではcloneDeep 1 つのメソッドのみが使用されていることです。輸入経費パッケージでこの問題を特定した後、次の方法で解決しました。

npm 削除 lodash
npm をインストール lodash.clonedeep 


次に、必要な場所に clonedeep 関数をインポートします。

「lodash.clonedeep」から cloneDeep をインポートします。 
JavaScript

さらに最適化するには、 Webpack Bundle Analyzerパッケージを使用して、インタラクティブでズーム可能なツリーマップを通じてWebpack出力ファイルのサイズを視覚化することもできます。

大規模な Vue.js プロジェクトの構築と保守に関する 10 のベスト プラクティスに関するこの記事はこれで終わりです。Vue.js プロジェクトの構築と保守に関するより実践的なコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue.js+boostrapプロジェクト実践(事例詳細説明)
  • Vue.jsでタブ切り替えと色変更操作を実装する解説
  • Vue.js での $emit の使用に関する詳細な説明
  • Vue.js スロットにおけるスコープ付きスロットの使用法の詳細な説明
  • Vue.jsはカレンダー機能を実装します
  • Vue.jsはタイムライン機能を実装します
  • Vue.jsは背景テーブルコンポーネントのカプセル化を管理します
  • Vue.js フロントエンドプロジェクト向け多言語ソリューションのアイデアと実践

<<:  CentOS で yum を使用して rabbitmq-server をインストールする方法

>>:  MySQL 集計関数のネストされた使用操作

推薦する

ナビゲーションバーのドロップダウンメニューのサンプルコードを実装するためのHTML+CSS

効果コード内の画像は自分で変更できますドロップダウンメニューのHTMLコード <ヘッダークラ​...

docker+jenkins+node.js の自動デプロイメント環境をゼロから構築する方法

このケースはCentOS 7システムに基づいていますDockerの使用経験がある人に適していますLi...

Zabbix は DingTalk のアラーム機能を画像付きで設定します

実装のアイデア:まず、アラーム情報にはitemidが必要です。これは前提条件です。情報に渡されるパラ...

JavaScript デザインパターン 責任連鎖パターン

目次概要コードの実装パラメータ定義成し遂げる責任連鎖パターンの実装改善概要責任チェーン パターンは、...

dockerfile-maven-plugin 使用ガイドの概要

目次pom 構成Setting.xml 構成ログインステータスログインが必要ですログインは必要ありま...

React-Dropzone をベースにアップロードコンポーネント機能を開発する (サンプルデモ)

今回はReact-Flaskフレームワーク上でアップロードコンポーネントを開発するスキルについてお話...

フォームで完全な選択または逆選択効果を実現する JavaScript

この記事では、フォームの完全選択または逆選択を実現するためのJavaScriptの具体的なコードを参...

JavaScript 配列メソッドの詳細な例

目次導入配列の作成作成方法詳しい説明方法参加する() push() と pop() shift() ...

ネイティブ js はカスタム スクロール バー コンポーネントを実装します

この記事の例では、カスタムスクロールバーコンポーネントを実装するためのjsの具体的なコードを参考まで...

IE6 で幅と高さがおかしいバグ

図に示すように: しかし、IE6で表示すると、right:1px:になります。 IE6 には、幅と高...

Vue を使用して 2 つのデータ セットの違いを比較する視覚化コンポーネントの詳細な説明

目次必要:要点:これまでの要点に従って、コンポーネントのプロパティを確立できます。コンポーネントの基...

960 グリッドシステムの基本原理と使用法

もちろん、CSS はフレームワークを必要とするほど高度ではないと考えて、反対の意見を持つ人もたくさん...

Linux で nginx を起動および再起動する方法

Nginx (エンジン x) は、IMAP/POP3/SMTP サービスも提供する高性能 HTTP ...

MySQL 8.0 Windows zip パッケージ版の詳細なインストール手順

MySQL 8.0 Windows zipのインストール手順は次のように紹介されています。準備する:...

デザインにおいて無視できないインタラクティブデザインにおける製品状態の分析

製品デザインのプロセスにおいて、デザイナーは常に写真を非常に美しくすることを好みます。仮想ページのコ...