Skip to content
⚠️ This article was written in 2018. Some content may be outdated.

2018年上半期:エンジニアリング体制の構築とVueの深化実践

2018年上半期の中心的な取り組みは3つでした:バックオフィスシステムのアーキテクチャ刷新、社内コンポーネントライブラリのゼロからの構築、そしてエンジニアリングパイプラインの整備です。技術選定の考え方と実際に踏んだ落とし穴を記録します。

H1 主要プロジェクト振り返り

バックオフィスシステム:Webpack 3→4 移行 + TypeScript 段階的導入

年初に2年稼働中のバックオフィスシステムを引き継ぎました。技術スタックはWebpack 3 + Vue 2.3で、ビルド時間は安定して45秒前後でした。選択肢は2つ:小手先の修正で継続するか、徹底的なエンジニアリング刷新を行うか。チームが今後複数のバックオフィスプロジェクトを並行管理する必要があることを考え、後者を選びました。

Webpack 4 アップグレードの主なメリットはバージョン番号ではなく、modeの仕組みとTree Shakingの改善にあります。移行の最大の障壁はプラグインエコシステムの互換性で、複数のWebpack 3プラグインがまだ4.xに対応しておらず、代替手段を探すか自前で対応する必要がありました。最終的にビルド時間は45秒から12秒に短縮され、主な貢献は以下の2点:

js
// webpack.config.js 主要設定
module.exports = {
  mode: "production",
  optimization: {
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          chunks: "all",
        },
      },
    },
  },
};

HardSourceWebpackPluginによる永続キャッシュとルートの遅延読み込みを加えることで、開発環境のホットリロード体験も大幅に向上しました。

TypeScriptの段階的移行はより長期的な取り組みです。レガシーコードはanyだらけで、一度に修正することは不可能です。戦略は:新モジュールにはTSを強制し、旧モジュールはallowJsを使って段階的にカバーする。6月末時点でコアモジュールのカバレッジは約60%。この過程での最大の気づきは、型システムは「制約」ではなくコンパイル時の契約書であるという理解です——特に複数人での協業においては、型定義そのものが最良のインターフェース仕様書になります。

コンポーネントライブラリ構築

上半期に社内共通コンポーネントライブラリの構築を開始しました。目標は新しいUIフレームワークを作ることではなく、Element UIをベースにビジネスレイヤーの共通コンポーネントをラップすること:権限ボタン、データ辞書セレクター、複合検索フォーム、汎用CRUDテーブルなど。

設計上のいくつかの重要な決定:

  • Propsドリブン、ビジネスロジック非侵入:コンポーネントはUIとデータフローのみを担当し、ビジネスロジックはslotとeventで委譲する
  • TypeScript型エクスポート:各コンポーネントは型定義も同時にエクスポートし、利用側で完全な型ヒントを提供
  • オンデマンドインポートbabel-plugin-componentと組み合わせてフルバンドルを避ける
ts
// コンポーネント型エクスポートの例
export interface CrudTableProps {
  columns: ColumnConfig[];
  fetchApi: (params: QueryParams) => Promise<PaginatedResult<any>>;
  rowKey?: string;
  toolbar?: ToolbarConfig[];
}

6月末時点で、コンポーネントライブラリは3つのバックオフィスプロジェクトの共通ユースケースの70%をカバーし、新プロジェクトの初期化時間を約40%短縮しました。

エンジニアリング改善

CI統合

以前はチームのデプロイが手動のnpm run buildとサーバーへのscpに依存しており、非常にリスクが高い状態でした。上半期にGitLab CIを導入し、lint → test → build → deployの4ステージを持つパイプラインを構築しました:

yaml
# .gitlab-ci.yml コアパイプライン
stages:
  - lint
  - test
  - build
  - deploy

lint:
  stage: lint
  script:
    - npm run lint
    - npm run type-check

build:
  stage: build
  script:
    - npm run build
  artifacts:
    paths:
      - dist/

デプロイ時はDingTalk通知と連携し、ビルド失敗時は自動的に関係開発者にメンションが届きます。インシデントの追跡が「誰がデプロイしたか」から「どのMRが原因か」に変わりました。

コード品質ツールチェーン

ESLint + Prettierの組み合わせをチームに定着させるのは予想より時間がかかりました——核心的な問題はルール自体ではなく、既存コードのフォーマットコストでした。最終的な戦略:lint-stagedを有効にして変更ファイルのみチェック、既存コードは一括フォーマットPRで処理。commitlintでコミットメッセージを標準化することで、コードレビューの効率が顕著に向上しました。

踏んだ落とし穴

1. TypeScriptとVueの互換性問題

Vue 2.xのTypeScriptサポートは完璧ではありません。vue-property-decoratorのデコレーター構文は特定のシナリオで型推論が失われます——特にmixinsとprovide/injectで。解決策:mixinsはできるだけcompositionスタイルで代替し、provide/injectには明示的な型宣言を行う。

2. Webpack 4のsideEffects設定

Tree Shakingが機能しない原因の追跡に半日かかりました。根本原因はpackage.jsonsideEffects: falseが宣言されていなかったこと。追加後にバンドルサイズがさらに15%削減されました。この教訓:ツールチェーンのアップグレードは設定ファイルを変えるだけでは不十分で、依存ライブラリのpackage.jsonも確認する必要があります。

3. Nuxt.js SSRの落とし穴

コンテンツサイトのSEOにNuxtを使ったとき、window is not definedが繰り返し発生しました。根本原因はサードパーティライブラリがモジュールのトップレベルでブラウザAPIにアクセスしていたこと。解決策:process.clientガードを使うか、mountedフックでrequireを使って動的にインポートする。この経験から学んだこと:SSRはフレームワークを変えるだけでは済まない——依存チェーン全体の対応が必要です。

H2 計画

技術的深化:

  • TypeScript高度な型システム:ジェネリック制約、条件型、テンプレートリテラル型をコンポーネントライブラリで実践
  • Reactエコシステムの追跡:React 16.7のHooks機能を深掘りし、社内プロジェクトで技術検証する予定
  • フロントエンドテスト体系:現状は散在したユニットテストのみ。コンポーネントライブラリの自動テスト + CI統合を目標とする

エンジニアリング体制:

  • フロントエンド監視にSentryを導入し、エラーキャプチャとパフォーマンス指標レポートをカバー
  • マイクロフロントエンド調査:バックオフィスシステムが増え続ける中、qiankun / single-spaの実現可能性を評価
  • ビルド環境のDocker化でチームのNodeバージョンとビルド依存を統一

技術的影響力:

  • チーム内で2〜3回のテック共有(Webpack最適化、TypeScript実践)
  • コンポーネントライブラリのドキュメントサイトを構築し、新メンバーのオンボーディングコストを低減

まとめ

  • バックオフィスシステムのWebpack 4アップグレードとTypeScript段階的移行を完了。ビルド効率73%向上
  • ビジネスコンポーネントライブラリを立ち上げ、3プロジェクトの共通シナリオをカバー
  • GitLab CIパイプラインとコード品質ツールチェーンを導入し、手動デプロイから脱却
  • Vue + TypeScript互換性、Webpack Tree Shaking、Nuxt SSRなどの実問題を解決
  • H2重点方向:React検証、テスト体系、監視体系、マイクロフロントエンド調査

MIT Licensed