フロントエンドの開発環境に Docker は不要(少なくともMacでは)

追記: 前提部分

開発環境を docker-compose で抽象することが最近のベストプラクティスだとされているが、フロントエンドをコンテナに突っ込むと無視できないIOボトルネックが発生する。

とくにwebpackのファイル監視からのビルドで発生する高頻度のIO処理を捌くために、フロントエンドだけはホスト環境に移したほうがいい、という主張。


これについて

speakerdeck.com

自分の意見

  • Web開発者の主要な開発環境である Docker for Mac は I/O がとにかく遅い (3x~5x)
    • data volume の driver やら cache を工夫しても遅い
  • npm install/webpack は 基本的に I/O ヘヴィー
    • とくに大規模開発時の watch => build がクリティカル
    • webpack.conifg の entry で自分が関与する部分以外コメントアウトして開発してることもある
  • フロントエンドの最終成果物(.js, .css, .html)に環境依存なプログラムが含まれない(含まれてたらおかしい)
  • そもそも JS という言語自体がクロスプラットフォームに配慮された言語なので、ホスト環境によるランタイム差がほぼない

ネイティブモジュール周りの既知の問題

  • fsevents: webpack や chokidar などの裏側でファイルシステム監視を行うモジュール。npm の lockfile がビルドした環境次第で optional dependencies の native module をうまく依存に含めることができず npm install で再現されないことがある。ファイル変更監視が低速化するだけで動くには動く。yarn でこれが起きたことはない。
  • node-sass: libsass の node バインディングだが、ややビルドが不安定。nodeのバージョン上げると大抵コケるのでキャッシュ捨てて再ビルドが必要。最近は css-in-js が流行ってるのでnode-sass見かけることが減った。
  • node-gyp: node本体のビルドツール(python2)。 python3 にパスが刺さってる状態でネイティブモジュールをビルドすると失敗する。node でネイティブモジュールを使う環境は python が python2 を指している必要があるが、これは他のビルドツールでも何かと要求される要件ではある。

これらを知っていればそこまでクリティカルにはならない。

運用どうするか

CircleCI、デプロイ時、初期セットアップの手数を少なくするためにとりあえずNodeイメージ経由でのフロントエンドのビルドタスクは用意する。開発環境では使わない。

他のプログラミング言語の人から本体のバージョンを固定することを強く要望されることがあるが(それらの言語が不安定なことが多い)、直近の Stable 使ってる限りは Node の実行に差が出ることは稀で、フロントエンドのビルドツールツェインに関してはそこはあまり抽象してメリットがあるレイヤーではない。が、自分の詳しくない領域の安心感がほしいのはわかるので、上述のビルドタスクを提供する。

node のインストールが困難な開発メンバーがいる場合はサポートする。たぶん二手ぐらいで終わるので、docker それ自体の導入より遥かに簡単。

Windows/WSL環境 の場合

すいません自分がWindowsでフロントエンド開発したことないです。

あんまり人権がある方ではないとは聞いてる。

サーバーサイド node の場合

他のサーバーサイドと環境と違ってビルドによる環境差がそこまでないので気にしなくていいと思っているが、 node はネイティブモジュールの数次第で、 imagemagick あたりが鬼門。こいつは常に鬼門。別環境に追い出したい。

node server を運用する際はこの限りではない。

というのが自分の意見です。