coffee-scriptで書いていたwebアプリをES6(babel)に書きなおした。

全部を一気に書き直してハイ動いたーとやるのは無理なので、coffeeとES6のファイルが混在しても動かせるようにして、少しずつ書き直した。


書き直したのはこれ
React+Fluxxor+socket.ioでfluxなチャットを作った
https://github.com/shokai/node-flux-boilerplate

インストール

% npm install babel babelify browserify watchify -save-dev
とやっていたのだが、数日前にbabelが5から6にアップデートされて、babel-coreやbabel-preset-*など色々分割されて、大分色々変わってしまった。周辺ツールも対応の過渡期だったのでbabel5系を使うようにバージョンを指定した。

  "devDependencies": {
"babel": "~5",
"babelify": "~6",
"browserify": "~11",
"watchify": "~3.5"
}


クライアント側


coffeeで書いたReactのプログラムをbrowserifyでjsに変換して1ファイルに固めていたので、単純にtransformを複数指定してやったらES6とcoffeeを混在しても大丈夫になった。

% browserify --debug --extension=.cjsx --extension=.coffee --extension=.es6 -t babelify -t coffee-reactify client/app.jsx -o public/js/bundle.js

coffeeもES6もまとめてES5になってbundle.jsができる
もちろんwatchifyでも同様にES6/coffee混在可能。

babel6だったらたぶんこれで混在できる。browserifyやbabelifyも最新に上げてから
% browserify --debug --extension=.cjsx --extension=.coffee --extension=.es6 -t [ babelify --presets [ react es2015 ] ] -t coffee-reactify client/app.jsx -o public/js/bundle.js


サーバー側

サーバー側はregisterを使う。registerはrequire関数をhookして実行前に翻訳してくれるしくみなので、例えばbabel/registerを使うとcoffeeからES6をrequireして実行できる。

Require Hook · Babel
register.coffee

最初に起動するファイルがserver.coffeeの場合

こうやってアプリを起動している場合
% coffee server.coffee # 起動

babel/registerで動的にES6を実行できるようにする。server.coffeeのなるべく上の方で

require "babel/register"

を書いておくと、これで以後coffee内からES6をrequireするとbabelが逐次変換してくれるので、混ぜて書ける。
require "models/user" # user.coffeeが読み込まれる
require "controller/main.es6" # main.es6が読み込まれる

babel 6.x系だと別のnpmに切り出されて、babel-core/registerに変わった。


最初に起動するファイルがserver.es6の場合


最初に呼び出すファイルをES6で書きなおしたら、
% babel-node server.es6 # 起動

coffee-script/registerで動的にcoffeeを実行する。server.es6のなるべく上の方で
require("coffee-script/register");

以後ES6なスクリプトからcoffeeをimport/requireすると逐次変換して実行される。

同じファイル名の.coffeeと.es6があったらどうするか

拡張子まで書けば指定できる。
require("foo.es6");

ES6に統一し終わったら.coffeeファイルを消して、requireの拡張子も消せばok
require("foo");


npmの場合

coffeeで書いてES5にトランスパイルしてnpmjs.orgにリリースしているプロジェクトを部分的にES6で書き直す場合は、試してないけどたぶんビルドプロセスを
coffeeの変換の後にbabelの変換、という順に実行してbabel側のファイルで上書きしてやるようにすればいいのではないかと思う。