こんにちは! SmartHRのエンジニア、溝上といいます。
今回は通常の業務と合わせて行っている開発環境の改善、その一部である Sprockets 絶ちを紹介していけたらと思います。
前回やったことまとめ
- 修正方法の方針を大まかに決定
- gulp 導入
- sass のコンパイルを gulp に移譲
では今回は?
今回は CoffeeScript から ES2015 に乗り換えます!
... とはいえ SmartHR で使用している CoffeeScript はかなり多く、かつテストが不足しているため安全に乗り換えていくために以下のような方針で着手しました。
- CoffeeScript と ES2015 どちらでも書ける状態にする
- 基本的に ES2015 で新規を、CoffeeScript 修正時、ES2015 に変換できそうならする
- テスト環境を用意し、CoffeeScript に対してテストを追加、安全に ES に変換できる状態を作る
- トランスパイラを使って CoffeeScript を ES に変換する
この状態を作れれば細かなレビューを行いつつ徐々に ES 化していけるかな?と思います。
具体的な方法
CoffeeScript と ES2015 どちらでも書ける状態にする
gulp で CoffeeScript, ES のコンパイルを可能にします。
- どちらからでも他の script を読み込みたいので require を利用可能な状態を作ります
- ミニマムに導入するという方針に従いひとまず Browserify を使うことにします
- 将来的に Webpack に乗り換えることも検討
- CoffeeScript は一度JSに書き出し、 ES から require する形式を取ります
- ミニマムに導入するという方針に従いひとまず Browserify を使うことにします
テスト環境を用意し、CoffeeScript に対してテストを追加、安全に ES に変換できる状態を作る
Karma を利用して spec の実行環境を整えます。 同時にESLint、Flowtypeも導入して快適な環境を目指します。
- Karma + mocha + chai + sinon でテスト
- 1ファイル単位でテストしたいので spec からもrequireでテスト対象を読み込む方法を取ります
- ESLint、Flowtype の設定を考える
トランスパイラを使って CoffeeScript を ES に変換する
今回の場合は decafjs を利用することにします。
- decafjs を利用して CoffeeScript を ES に変換する
- 変換はまれにバグるのでテストは必須
設定各種サンプル
ではまとめて設定してしまいましょう。 適時、省略してますのでもしご利用頂く場合は参考程度にしていただけると幸いです。
すごーい! ながーい! あとはこれら登録した gulp タスクを適時ファイルの watch 時や gulp 起動時に実行するようにして完成です。
さてそれでは
watch まで設定すると...
こんな感じでテストが実行されます。 便利ですね。
設定内容詳細
.eslint: flowtype/require-valid-file-annotation
ESLint の対象ファイルに/* @flow */
が記述されていない場合エラーにしてくれる設定です。
Flowtype 使う場合は(個人的に)ほぼ必須で設定してしまって良いと思います。
.flowconfig: ignore
gulp-flowtype
などのように Flowtype のチェックに引っかかってしまう node_moddules が存在しています。
これらは個別に ignore に設定することで対応しました。
karma.conf.js: gulpでのwatchとタスク直接起動時に検証ブラウザを変更する
karma.conf.js では browsers: ['Chrome', 'Safari']
を設定しており、npm run test
実行時はこれらの設定が利用されます。
gulp から実行する際はこれらの設定を上書きし browsers: ['PhantomJS']
となりPhantomJSで実行します。
他のブラウザでのテストを追加したい場合はkarma-****-launcher
などの launcher を追加して対応出来ます。
次回
これで テストを書きつつ1ファイルずつ decaf を利用して移行していけるようになりました。 現在 spec を書きつつ業務の合間などで移行を行っています。
次回の内容は未定ですが、今回設定した各種テストなどをCircleCIで実行するために行ったことなどを話していこうと考えています!