今年歴史あるRailsプロジェクトのCoffeeScriptをJavaScriptにひたすら直す作業をしてたので、CoffeeScriptを使っていたがJavaScriptに移したくなった際の流れをまとました。
大まかな流れ
- CoffeeScriptに前処理をして変換後のJavaScriptが極力キレイになるようにする
-
decaffeinate
コマンドで変換処理を行う - 生成されたJavaScriptファイルに問題ないか確認(目視/実際に動かして)。一部修正を行う
- 古いCoffeeScriptのファイルを削除する
大まかな流れはこんな感じです。変換処理自体は手作業ではなくコマンドに任せます。が前処理をしておくと読みやすいJavaScriptになるので面倒でも手作業で下準備をします。
準備
decaffeinate
をインストールします。npm install --save-dev decaffeinate
なり yarn add --dev decaffeinate
ご自由に。
使い方ですがdecaffeinate <ファイル名/ディレクトリ名>
でCoffeeScriptからJavaScriptへの変換できます。
前処理を行う
多分これで全部ではないですが、ここを気にするだけでだいぶ違います。
暗黙のreturnを明示的にする
CoffeeScriptはRubyと同様に関数最後の式を関数の返り値とする特徴があります。そのためreturn
を付け加えないと望ましくない返り値を返している場合があります。
y = (x) ->
x * x
はJavaScriptに直すと
y = function(x) {
return x * x;
}
になりますし、多分こうなって欲しいかと思います。
ところが
y = (x) ->
console.log(x)
もJavaScriptに直すと
y = function(x) {
return console.log(x);
}
となってしまい、読み手を混乱させるかもしれません。
この必要なreturn
か不要なreturn
かを変換後に区別して直すのは非常に面倒なので変換前に処理します。
具体的にはreturn
が必要な箇所にはreturn x
のようにして何も返さない時には関数末にreturn
を加えます。return
が必要なケースでは別にreturn
付け加えなくても良いですが、一応確認をしたという意味でつけておくと無難です。
関数末のreturn
は不要であれば変換時に消えるのであとで削除する必要はありません。
クラス内部の変数をインスタンス変数に直す
CoffeeScriptでは以下のような書き方が可能です。
class X
x = 10 # メソッド外でも変数が定義できる
getX: () =>
return x
ところがこれをJavaScriptに変換すると結構読みにくいものになります。(どんなだったか忘れました)
そのため若干解釈が変わってしまいますが、インスタンス変数に直します。private
だよという意味を込めて_
から変数名を始めるようにしてもいいでしょう
class X
constructor: () =>
@_x = 10 # インスタンス変数に直す
getX: () =>
return @_x
変換処理を行う
decaffeinate
コマンドを実行します。ここは特に何もないので省略します。
ちなみに、let
const
の判断とかある程度アロー関数化とか変数展開とか分割代入とか結構よしなにやってくれます。
変換後の確認と修正
基本的に問題ないはずですが、一応動作確認しておきます。あとループ変数がvar
で1まとめになっていた気がするので最後直しておきます。スルーしてもいいですが、結構気になります。個人的にな感想ですがループの変換は結構微妙だったイメージです。
// Before
var x;
for(x = 0; x < 10; ++x) {
// 何か
}
for(x = 0; x < 10; ++x) {
// 何か
}
// After
for(let x = 0; x < 10; ++x) {
// 何か
}
for(let x = 0; x < 10; ++x) {
// 何か
}
まとめ
CoffeeScriptからJavaScriptへの変換時には、多少手間暇かけることで見やすいJavaScriptにすることができました。