あとから@vue/cli 3 + Jest

まとめ

いろいろやって、結局丸一日くらいは掛かることが分かった。

気をつけるべきポイント

  • Babel がすでに入っているなら 7系 にちゃんと上げておく
  • @vue/cli は Webpack と一部概念が違う
  • 関係するツールが増えると当然だが検証時間は伸びる

狙い

大きなフレームワークが入っておらず、中途半端に JavaScript が散らかっている状態の小規模のプロジェクトがある。このうち一部のコードに対して

I/O 周り(HTTPS? や localStorageアクセス)に変更を施す必要がある

ことが分かった。そのため

  1. ビルドプロセスに手を入れる
  2. 既存のコードをテスタブルな状態にもっていく

を行う必要があると判断した。

方向

すでに動いているコードは以下の状態。

  • jQuery ベースのコードがある
  • ビルドプロセスを伴わない状態で Vue も採用されている

テストの欲しい変更を行うコードは Vue の方。そのため、

  • @vue/cli
    • webpack
  • jest

を入れることとした。

理由はimport / exportを書くとasset bundlerが必要になるから

I/O 周りのコードに対する変更を行いたいわけだが、このために

  • I/O 周りのコードを Model として分離する

こととした。

必要なのは View の方ではないので、Vue を利用して構築している部分から I/O 周りを分離し、Model だけをテスタブルにしたうえで変更を加えていくのはごく当たり前の判断と言ってよいと思う1。View 周りまで含んだコードをテスタブルな状態に持っていくのはコストが大きすぎる。幸い、Vue の場合は jQuery ベースよりは anonymous function だらけにはなりにくく、「継ぎ」2を作ればテスタブルな状態を作るのはそれほど難しくなさそうに見えた。

そして Model をテストするわけだが、ここで問題がある。

モダンな開発を行うに当たり、コードを責務の単位で分離したうえで import / export して作っていくのは当たり前のことである。しかし、import / export は Babel の領域ではなく、asset bundler の領域。

asset bundler と言えば Webpack … ?

Webpack の設定はしたくない。絶対にだ。

ということですでに Vue が入っているなら Webpack の面倒くささを避けるために @vue/cli だろうという当然の帰結。

やることリスト

  1. 既存の Babel があれば上げておく
  2. まず @vue/cli プロジェクトを別なところで作る
  3. .babelrc などは babel.config.js へ変更3
  4. package.json などなどを別プロジェクトからコピー
  5. webpack の multi entry は @vue/cli 側で multi page として再定義されているのでそっちを参考に
  6. .eslintrc.js を追加4
  7. Jestの導入(以下のようになる場合アリ)
    • [NG] @vue/cli-plugin-jest-unit
    • [OK] jest

意外とハマる

特に

  • Multi Page という @vue/cli 独自の概念
    • このために HtmlWebpackPlugin とか、あまり欲しくない知識が必要になる5
    • @vue/cli のデフォルト設定の entry 周りから multi entrypoints に持っていく方が面倒
  • @vue/cli が .eslintrc.js を無視してしまう問題
  • @vue/cli-plugin-jest-unit がなぜか babel-jest を適切に適用できない問題

辺り。

@vue/cli は抽象化のレベルがなかなかよいと思っていたのだが、やはりレイヤーが増えればややこしさは増える。まだまだ伸び代だらけだなぁ。Vue に関してはほぼ本家扱いと言ってよいのでそこまで心配は要らないだろうが、Babel, Webpack, Jest は繋ぎの部分の作り込みのレベルにバラツキがあるように見えるので注意が必要。

また Jest が Babel 7 と合わない時代もあったりしたようで、Babel と Webpack の migration は今後も面倒ごとになり続けそう。

参考

  1. この Model 相当のコードが複数箇所から参照されるのは分かっていたのでその判断を加速させたが、それがなくても分離はした方がよい。 

  2. sprout classとかアンチレガシーのプラクティスのこと。 

  3. @vue/cli-service, jest が自動で認識してくれる 

  4. @vue/cli 3.1.1 はバグで .eslintrc.js を無視するので直っているバージョンに上げておくこと 

  5. 読み込み用の HTML も不要だし、後始末が必要になったり。 

More