こんにちは、開発の村上です。
最近はJavaScriptを書いていたのですが、以前から名前だけ知ってたけど実態はよく知らなかったライブラリやフレームワークをひと通り調べてみたので
今回はJavaScriptの開発ツールやフレームワークなどの環境について書きたいと思います。
今回対象にするものは以下です。
・エディタ
・JavaScript上位互換言語
・PhantomJS
・Knockout.js
他にもBackboneやReqiureJSなどいくつか調べたのですが、長くなるので今回は対象外にしました。また別の機会に。
エディタ
JavaScriptは書こうと思えばメモ帳でも書けます。実際、過去にメモ帳でSJISで書いてる方にお会いしたことがあります。が、心の安定が欲しい方はマネしちゃいけません。
JavaScriptは仕様が複雑なので、素直にIDEを利用することをオススメします。
JetBrains社のWebStorm(もしくは上位互換製品)、MicroSoftのVisual Studioがオススメかと思います。私はJetBrainsのPhpStormを使っていますが、もうPHPやJSを書く時は手放せません。
Visual Studioのバージョンは2012以上が良いようです。とあるライブラリの作者の方がライブコーディングで使っていたのを見ましたが、JSONの補完などかなり良さげでした。
JavaScript上位互換言語
「JavaScriptを生成してくれる言語」です。JSは規模に関わらず、簡単にカオスになる言語だと思います。
なので、そのままJSを書くよりは上位互換言語を使った方が書きやすいですし、心の安定を保てるんじゃないでしょうか。
上位互換言語はDartやJSX, HaxeやCoffeeScriptなど、たくさんあります。
私はMicrosoftが開発しているTypeScriptを使っています。
他の言語を使ったことが無いので機能比較はできないのですが、以下がTypeScriptを採用した理由です。
・可読性の高いJSが生成される
・classがあって型があってコンパイラがいる
・JavaScriptそのままでも書ける
そもそもJSをあまり書いたことが無かったので、コンパイラがいてくれることでそれなりに安心感を得られました。
しかし、TypeScriptでは困ったことにJSファイルの改行コードがCR+LFで生成します。さすがMicrosoftさんですね。Gitで自動的にLFに変換してるのでまぁいいんですが、CR+LFで喜ぶのってどういう場合なんでしょう?
実際のTypeScriptのコードは以下のようになります。ちなみにバージョンは0.8.3です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class User { user: string; constructor(user: string) { this.user = user; } hello() { return "Hello, " + this.user; } } var name = "Allied"; var user = new User(name); // これは引数の型が合わないのでコンパイルエラーになります var zero: number = 0; //var user = new User(zero); alert(user.hello()); |
このコードをコンパイルすると、以下のJSが生成されます。
1 2 3 4 5 6 7 8 9 10 11 12 |
var User = (function () { function User(user) { this.user = user; } User.prototype.hello = function () { return "Hello, " + this.user; }; return User; })(); var name = "Allied"; var user = new User(name); alert(user.hello()); |
PhantomJS
テスト用のツールです。
JavaScriptではJasmineやQUnitなどのテストフレームワークがありますが、いちいちブラウザで実行しないといけません。
いちいちブラウザに画面を切り替えて操作するのは嫌ですよね。ね。私は嫌です。それに、ブラウザで見なくてはいけないとなると、CIツールとの相性も良くないです。
PhantomJSはコマンドベースでJavaScriptのテストを実行出来るようにしてくれるツールです。
HTTPのヘッダなどが無くなるので、ブラウザでテストするより高速で動作します。コマンドで動くのでCIで動かすことも簡単に出来るようになります。
RequireJS単体で動かすこともできますし、以下のコマンドを叩くとJasmineのテストを実施して結果を表示してくれます。
phantomjs /path/to/jasmine/examples/run-jasmine.js SpecRunner.html
Jasmineのサンプルをいじって失敗するようにしました。すると、こんな結果を出してくれます。
Player
1 test(s) FAILED:
Player tells the current song if the user has made it a favorite.
Expected spy persistFavoriteStatus to have been called with [ false ] but actual calls were [ true ]
こういったツールが使えるとテストが楽になりそうです。
Knockout.js
今回の記事で取り上げるものはこれで最後です。
実際に案件で採用して使っているJavaScriptのフレームワークで、MVVMモデルを採用しているフレームワークです。
個人的に思うKnockoutの良いところは、簡単に使いやすい、HTMLファイルがそんなに汚れない、ファイルサイズが軽いことじゃないでしょうか。
ファイルサイズはminifyした状態で大体40KBです。
Backboneは60KB近くありますし、jQueryやunderscore.jsも必要です。
AngularJSはminifyしても80KB近くあります。
MVVMモデルを採用しているので Model, View, ViewModel で構成されています。
Modelは描画用データ、ViewはDOMでいいと思います。すごくざっくり簡単に言うと、です。
ViewModelはViewとModelのヒモ付を行なってくれるものです。
と言っても理解しづらいので、非常に簡単なものですがサンプルを載せます。
HTML
1 2 3 |
<h2>Hello</h2> name: <input type="text" data-bind="value: name" /> <p data-bind="visible: name().length > 0, text: greet"></p> |
JavaScript
1 2 3 4 5 6 7 8 9 10 |
var ViewModel = function(name) { this.name = ko.observable(name); this.greet = ko.computed(function() { return "Hello, " + this.name(); }, this); }; var viewModel = new ViewModel('allied'); ko.applyBindings(viewModel); |
this.name = ko.observable() で、nameという値がknockoutの監視対象データに設定されます(Model)
HTMLのタグで data-bind=”value: name” とするとthis.nameの値が表示され、この値を変更するとModelの値も変更されます(View)
ko.applyBindings(viewModel) とすると、ViewとModelがヒモ付きます(ViewModelの設定)
これだけのコードですが、画面上でテキストの内容を変えると自動的に紐付いたModelのデータが書き換わります。
Modelの内容を書き換えるとそれに応じてViewの内容も変わってくれるので、値の変更をbindして操作する必要がなくなるので非常に楽になります。
しかし、今回採用してものすごく困ったのですが、KnockoutはTypeScriptとの相性が現状では良くないです。
Knockoutの定義ファイルはありますが、Knockoutの仕様に沿った記述をしようとするとTypeScriptがエラーになってコンパイルが通らないことが何度かありました。
監視対象にするモデル(上記ソース内はViewModel)をclassにしたかったのですが、残念ながら出来ませんでした。
TypeScriptは他にも理由があって使っていますが、お互いの利点は生かしきれなかった気がします(もしかしたら自分が分からなかっただけで実は出来るかもしれません)
JSは気がつくと新しいものが出てきますね。次回はAngularJSについて書きたいと思います。
ではまた。
フロントエンドだったりバックエンドだったりサーバだったり その時の流行りと気分でいろいろ迷走してます。