LoginSignup
106
50

More than 5 years have passed since last update.

CoffeeScript 2という新たなる希望

Last updated at Posted at 2017-09-10

CoffeeScriptは滅びぬ!何度でも蘇るさ!

CoffeeScriptがいかに駄目かを理解している皆さんならご存じの通り、これまでのCoffeeScriptには重大な欠点があった。それは「CoffeeScriptはECMAScript5(ES5)のaltJSである」と言うことだ。ES5以前のJavaScriptが駄目すぎるため、そこがCoffeeScriptの限界になってしまっていた。駄目な奴は何をやっても駄目なのだ。

ECMAScript2015以降(ES2015+)において、JavaScriptは目覚ましい発展を遂げた。ジェネレーター、テンプレートリテラル、class構文、モジュールベース、async/await等多くの機能が追加された。いくつかの機能は既にCoffeeScriptに存在していたものであったが、ジェネレーターのような全く無い物は新たに追加する必要があった。しかし、追加されたCoffeeScriptのジェネレーターを見ればわかるとおり、ジェネレーターはジェネレーターとして出力するしか無く、ジェネレーターに対応した最新のブラウザでしか動作しないコードになってしまった。そのためかどうかわからないが、ES5以前には全く存在しないimport/exportやasync/awiat等の追加は難しくなっていたようだ。

しかし、それで滅びるようなCoffeeScriptでは無い。altJSとしてのターゲットがES5であることが問題であれば、ES2015+に変更すれば良いのだ。そして出てきたのがCoffeeScript 2だ。バージョンが上がっただけでないかと言うかも知れないが、最初に述べた重大な欠点が修正されている。そう、「CoffeeScript 2はECMASCript2015以降(ES2015+)のaltJSである」と言えるようになっている事だ。CoffeeScript 2はコンパイル後の出力でES2015+のコードを吐き出す。最新のNode.jsなどES2015+に対応したJavaScriptエンジンであればそのまま実行することが可能だ。1

CoffeeScript 2の使い方

使い方はCoffeeScriptと同じだ。既に2系が正式リリースされているため、インストールはcoffeescriptと指定するだけでよい。

npm install -g coffeescript
coffee -c example.coffee

example.coffeeはexample.jsとなり、Node.jsや最新のブラウザでそのまま実行できるだろう。もし、レガシーなブラウザや、対応環境が少ないimport/export文、JSXの使用を想定しているのであれば、Babelと組み合わせて使うこともできる。

npm install babel-core babel-preset-env babel-preset-react --save-dev
echo '{ "presets": ["env", "react"] }' > .babelrc
coffee -c -t example.coffee

Babelのコマンドを別途叩く必要は無い。CoffeeScriptがBabelでのトランスパイルも行ってくれる。

CoffeeScript 2の新機能と1.xからの変更点

2からの新機能と1.xからの変更点を見ていきたいと思う。

新機能

非同期関数(async/await)

関数内でawaitを使用していれば、非同期関数とみなす。1.xからあったyieldがあればジェネレーター関数と見なすのと同じような動作になる。

タグ付けされたテンプレートリテラル

タグ付けされたテンプレートリテラルを使用できる。

モジュール(import/export)

モジュールとして使用するためにimport/exportの構文が用意される。import/exportはそのまま出力されるため、モジュールに対応していない環境では、Babelでの変換が必要になる。

JSX

JSX表記に対応している。ただし、JSX表記はJSX表記としてそのまま出力されるため、Babelでの変換が必要になる。

型アノテーション

型アノテーションを記載できる。変換後はFlowに対応した型アノテーションの記述になる。

1.xからの変更点

ES2015+にあるものはES2015+のネイティブとして出力

ES2015+でネイティブ表現可能なものはそのまま出力される。そのため、ES5にコンパイルしていた1.xとは細部の動作が一部異なる場合がある(【※】が付いているもの)。

  • 関数引数と分割代入のデフォルト値 【※】
  • ファットアロー関数(=>) 【※】
  • クラス構文 【※】
  • 展開(#{...})がある文字列リテラル(テンプレートリテラルとして変換)
  • スプレッド演算子(...)2
  • 分割代入

ファットアロー(=>)なジェネレーター関数は作成できない

ジェネレーター関数は1.xの時からある機能であり、ファットアローに対しても使用することができた。しかし、ファットアローのジェネレーター関数はES2015+に存在しない機能であるため、ファットアローをそのまま出力するCoffeeScript 2では使用できなくなった。3

superのみが使えない

1.xではsuperのみで親クラスのメソッドを引数そのままで呼び出せたが、2では通常の関数と同じくsuper()と呼び出す必要がある。また、ES2015+と同じく子クラスのconstructorでは最初にsuper()の呼び出しは必須になった。

CoffeeScriptは本当にオワコンなのか?

ECMAScript2015のリリース、静的型付けのためのTypeScriptの流行、トレンドの推移としてはCoffeeScriptは落ち目であり、「CoffeeScriptはオワコン」とか言っているQiitaの記事も見られる。あえて言おう、(リンク先の記事は)カスであると!また、新たな時代が始まる、それがCoffeeScript 2だ。本当に良いものはバージョン2になって初めてその力を発揮する。Java 24、Ruby 25、TypeScript 2、Solaris 26、HTTP/2等々、2から本気を出しているものは数多い。そう、本番はこれからなのだ。

時代は巡る。やれ、静的型付けだ、null安全だ、と言っている輩も、動的型付けこそ至高、ダック・タイピングこそ正義、という真理7をそのうち理解することだろう。そしてTypeScriptの時代は終わり、再びCoffeeScript 2の時代がやってくる、たぶん。


  1. Node.js 7.6以上で動作するES2015+をターゲットにしている。ただし、Node.jsが対応していないimport/exportのモジュール機能とJSXについてはそのまま出力されるためBabelと組み合わせた変換が必要になる。 

  2. 提案中で正式未採用のobjectリテラルに対しても使用できるが、ES2015+で正式採用まではBabelと同じpolyfillになる。 

  3. ECAMScriptの仕様書提案にGenerator arrow functions (=>*)があるので、採用されればいずれ復活するかも知れない。 

  4. Javaは1.2からJava 2になり、最新のJavaもJava 2を(2はいつの間にか消したけど)そのまま継承している。 

  5. Rubyが大きく変わったのは1.9からだろとかそういうことは言わない。 

  6. Solarisは2.0、2.1、とずっと2.xが続いたが、いつの間にか2.の部分が無くなった。でも2のままだ。 

  7. 君が持つ「真理」と私が持つ「真理」が同一であるとは限らないがな。 

106
50
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
106
50