キャッチアップ
JavaScriptビルド
ビルドから見るJSの今/2016春
Hitoshi Kondo
khit@jp.ibm.com
2
JavaScript/HTML活躍の場が広がっています。
Webアプリ
モバイルアプリ(ハイブリッド)
デスクトップアプリ(Electron, Windowsアプリ)
サーバーサイド(Node)
IoT(JSBoard, AWS Lambda, Cold Functions)
Jsonでストア(NoSQL)
3
JavaScript史のポイント
サーバーサイド利用含む
拡張仕様
統一仕様
ECMAScript
一部実装
進化
V4でES2015対応
初期乱世
DHTML
ActionScript
XHR&Ajaxで再興
モバイル、LLの台頭
Cordova
大規模開発やデスクトップ向けも
MV*
altJS
jQuery
JQM
Prototype
JavaScript
Isomorphic (i8c)な世界へ?
フロントとバックでコード(環境)共通化
4
知っていますか?
本来JavaScriptにコンパイルなどのビルドは必須ではありませんが…
いまどきのJavaScriptアプリではビルドが重要です。
5
なぜなら
 Automation
– 繰り返し作業はしたくない
– 手作業ミスをへらす
– ドキュメントとか楽したい
 品質をあげて生産性をあげる
– よりきっちりした文法で品質をあげる
– より洗練した新仕様で読みやすく
– コードミスのチェックで文法ミスに気づく
– テスト実行でロジックミスに気づく
– デザイナー(CSS)も楽したい
 パフォーマンスはどこでも重要
– 圧縮
– 統合
6
まとめると
開発/運用者が楽をするためにつくる仕組みが発展しています
CONTINUOUS INTEGRATION
7
 代謝の激しいフロントエンドを反映し、JSビルドの世界も盛り上がっています
 このチャートはビルドの現状を追うことでJSの現状をとらえることが目的です
– 各ツールの詳細な使い方はWeb上に良いリソースがたくさんあります(一部紹介してます)
このチャートの目的
8
JavaScriptビルド
CSSプリプロセッサー
UT/操作テスト 構文チェック
テンプレート処理
altJSコンパイル
ES2015コンパイル
圧縮/難読化
 JavaScriptビルドではこんなことをします。
モジュール管理
(依存性解決)
9
 ここ数年JS/HTML/CSSなどのフロントエンドリソース向けのビルドツールが盛
り上がる
– 2015あたりから主流はGruntからGulpに
 JSの進化に伴いビルドに必要なタスクも変わる
– プラグイン・エコシステムで最先端のビルド処理に対応
– 楽するためにはエコシステムを十分に活用できる活発さが重要
ビルドツール(タスクランナー)
10
ビルドツール(タスクランナー)- Grunt
 Node実装フロントエンド向けタスクランナーのさきがけ
– JSONでビルド定義
– プラグイン・エコシステムで様々なビルド処理に対応
11
ビルドツール(タスクランナー)- Gulp
 スピードや定義の書きやすさで主流に
– ビルド定義もJavaScriptロジックでかける
– プラグイン・エコシステムで様々なビルド処理に対応
– 処理間の受け渡しをStreamにすることでビルドスピード強化
– gulp-babelでES2015に対応したビルドコード対応
12
ビルドツール(タスクランナー)- Fly
 Node提供のES2015で記述できるビルドツール
– JavaScriptロジックでビルド定義
– ES2015のGeneratorを採用
– 関数名=タスク名になったり、requireいらなくなったり、よりシンプルに
– プラグイン・エコシステムで様々なビルド処理に対応
– 新参のためまだ少ないが主要プラグインはかなりカバーされてきている…
13
ここからはビルドツールで実行する代表的なタスクをみていきます
14
圧縮/難読化
 かつてのJavaScriptビルドの代名詞といえば…
Google Closure Compilerによる圧縮/難読化
– 空白改行・コメント行除去や関数変数名などのサイズ圧縮によるパフォーマンス向上
– あとは一応、アンチデバッグ、アンチウイルス、パターンマッチング回避
15
圧縮/難読化 – UglifyJS2など
 Nodeで実装された高速圧縮/難読化ツール
– Java実装のClosure Compilerに比較し高速な圧縮/難読化
– 難読化:関数や変数名などを短縮化
– AngularのDI機能など弊害発生ケースも
– ソースマップ対応
– デバッグツールで圧縮コードに対しブレークポイント設定できる
– CSSに対応したUglifyCSSもあり
– HTMLもあり html-minifier
16
圧縮/難読化 - ネタですが
 Sushify
– JavaScriptのコードを寿司のネタに握り直します。
– 鯖、鮭などお寿司屋さんの湯飲み風に難読化
– 日本人にしか読みづらい?
– 他にもKaomojify(顔文字), emojify(絵文字)、jojofy(ジョジョ化)とか
17
モジュール化
 JavaScript(ES5)ではモジュールの概念がないのでコード量が増えると大変
– CommonJSやrequireJSなど補完する動きが活発に
– Angularなど、フレームワーク自体がモジュール化&インポートの仕組みを提供するケースも
– ES2015ではこれらの仕様が正式提供される
18
モジュール化に関わるライブラリの関係
JavaScript
サーバーサイド利用含む
拡張仕様
統一仕様
ECMAScript
Node実装を
ブラウザでも使えるように
非同期モジュール
ロード仕様
ブラウザ上JSの
パッケージ管理
モジュール仕様あり
Nodeパッケージ管理
進化
V4でES2015対応
npm連携し
パッケージング
モジュール仕様あり
ES6的ビルド
※パッケージ≒モジュール
19
パッケージ管理 - Bower
 パッケージ管理ツール@ブラウザ界
– jQuery, Angular, React, UIライブラリなどフロントエンドアプリの利用パッ
ケージ管理が主体
– JSだけでなく、html/cssのライブラリも扱える
– bower.jsonに依存するパッケージを記述
– アプリはbower_componentsに展開されたパッケージをロードして使用
※パッケージ≒モジュール
20
パッケージ管理 - npm
 パッケージ管理ツール@Node界
– タスクランナー(Grunt/gulp)・モジュールシステム(browserify/webpack)・
テストスイート(karma)などの開発環境系の管理が主体
– package.jsonに依存するパッケージを記述
– node_modulesに取得パッケージが展開
– NodeアプリはcommonJSのrequireによりパッケージをロードできる
※パッケージ≒モジュール
21
モジュールビルド - browserify
 Node界の実装をブラウザ界でも使えるようにする魔法
– Nodeアプリが別モジュールをrequireしているところを書き換え1ファイルに
マージ
– デバッグ時はsourceMapをそのまま利用できる
– 同一ライブラリなどが複数個所でマージされないように(browserify-shim)
– npmパッケージが基本だがBowerのパッケージも利用できる(Debowerify)
22
モジュールロード - RequireJS
 AMD(Async Module Definition)モジュールの非同期ロードの仕組み
– ビルドではなく、ライブラリが実行時に非同期ロードを実現
– モジュールを実行する際、必要モジュールがまだロードされていない場合、非同
期でロード
– ビルドしなくても実行・デバッグできる
– Node界のrequire(commonJS)とは記法も挙動も違います(非同期)
23
モジュールビルドとロード - webpack
 いいとこどりの後発ツール。npmと連携し設定ファイルでビルド
– webpack.config.jsの設定に従ってnodeのrequire解決し、複数ファイルにマージ
– npmパッケージが基本だがBowerのパッケージも利用できる
– requireJS的非同期ロードにも対応
– プラグイン(xxloader)によりAltJSやCSS、画像、JSXなども対応できる
24
モジュールビルドとロード - jspm
 パッケージ管理+非同期ロード+ES2015トランスパイラ
– ユニバーサルなモジュールローダーSystemJSを利用
– ES2015 modules, AMD, CommonJSなどに対応するローダー
– ES2015で書ける(トランスパイル)
– ES2015のモジュール機構(import/export)を使える
– 開発中はビルドしない状態で実行・デバッグできる
– パッケージ管理もできる
25
トランスパイル AltJSとES2015
 JavaScriptをラップした言語で書いてJSに変換
– LL的すっきりしたコードに
– 型チェックでバグ減らす
 EcmaScript 2015 次期言語仕様
– 未サポートブラウザでも動作するように現仕様(ES5)に変換
– より洗練された将来性のあるコードで開発できる
AltJS
ES2015(ES6)
 JavaScript(ES5)コードは自由すぎる or 冗長すぎる
26
トランスパイル - AltJS
 JSがRuby,Python的な簡潔なコードでかける
– ()とか{}とか;とか省略してインデントで
– クラスと継承
– アロー式 etc..
27
トランスパイル - AltJS
 JSが型付言語に
– 型定義とインターフェース、コンパイル時の型チェック
– クラス、継承、import etc..
– ES2015仕様もサポート
28
トランスパイル - EcmaScript2015 (EcmaScript6)
 JSが準拠する言語仕様
– 次期標準として2015/6に公開
– クラス、継承、import、Promise、アロー式 etc..
– 各ブラウザは順次対応中
https://kangax.github.io/compat-table/es6/
 ES2015でコード開発して変換するためのトランスパイラ
– バベルことでブラウザの対応状況を気にせず次期の洗練されたAPIが使える
– babelifyでimport/export->require->browserifyで結合
29
各AltJSとES6の関係
JavaScript
ECMAScript5
トランスパイル トランスパイル
トランスパイル
with
Extend
(互換)
サポート
 AltJSとES6、カバー範囲は被る
– 特徴は異なる → 用途や採用予定ライブラリとの関係から選択
30
CSSプリプロセッサー
 CSSはメンテナンスしにくい
– Not DRY / ロジック組めない → 無駄に大きくなるし、ミスしがち
 ファイルは分割して@importできるけど…
– パフォーマンス考えるとJSと同じくビルドでマージしたい。
less, Sass, stylus
31
CSSプリプロセッサー : AltCSS
 CSSをラップしてメンテナンスしやすく (AltCSS)
– 80%は同等の機能を提供
– 変数、制御構文、式、関数でロジック組める
– Mixin、ネスト、importファイルの連結、圧縮
– コンパイルしてcssを出力
– 多数のEditor、IDEがサポート
– compass, Bourbon (Sassプラグイン)、 nib (stylusエクステンション)
– ベンダープレフィックス、Sprite、Grid etc..
32
CSSプリプロセッサー : PostCSS
 次期CSS仕様の先取り+独自エコシステム
– Babel的にCSS4を先行サポート (cssnext プラグインパック)
– less, Sass, stylus的CSS拡張 (PreCSS プラグインパック)
– 独自のプラグインシステムによるエコシステム
– 後方互換(Autoprefixer)、ショートカットや、圧縮(cssnano)、lintなど
– コンパイル超速
– lessからSassになったBootstrapは次期v5でPostCSS移行かも
33
CSSプリプロセッサー : Autoprefixer
 ベンダープレフィックス自動付与ツール
– ブラウザの独自/先行拡張用のベンダープレフィックスを付与してくれる
– -webkit-linear-gradient/-moz-linear-gradientとか
– CSS3導入期に各ブラウザごとに増殖
– 時とともに必要なくなれば外すこと
– ここ一年開発停止中のcompassに替わる…
– AutoprefixerはCan I Useのデータベースから最新状況反映
– PostCSS, nodeなどいろんな実装で提供
34
Linter
 JavaScript (HTML CSS)はコンパイルしなくてよい
– コンパイルチェックを通らないので単純ミスが発生しやすい
 コードをチェックすることで品質向上
– 構文ミスチェック
– プロジェクトのコード標準化
– エディタ組み込みのケースも多し
35
Linter - JSHint / JSLint / JSCS
 JavaScriptコードチェックの元祖(JSLint)と定番(JSHint)
– 必要十分で高速な静的チェック
– JSHint/JSCSはチェック対象の設定可能
– 様々なエディタにも組み込みあり
 もちろんcsslintやhtmllint, jsonlintもある
36
Linter - ESLint
 ES2015対応のプラガブルLint
– ES2015にも対応できる豊富なルール
– プラグインによるルール・エコシステム搭載
– React JSX記法
– ES2016以降の構文チェックすらあり
– カスタムルール
– エラー箇所が特定しやすい
– Shareable Configで設定をnpmパッケージとして共有
37
MV*フレームワークとビルド
 JavaScriptアプリの複雑/大規模化
 MV*的な構造化によるメンテナンス性向上が求められる時代に
 画面(view)とデータをバインドするフレームワークが次から次に出ています
– 構造化だけでなく幅広く機能提供し囲い込むのが流行り
– テンプレート部分はビルドが必要なケースあり
38
MV*フレームワーク史のポイント
View-Modelバインド
双方向バインド
多機能提供
UIエコシステム
ロールによる構造化 VirtualDOM
パフォーマンス追求
集中と軽量化
パフォーマンス追求
一方向データフロー
メンテナンス性追求
ES2015対応
Isomorphic
フロント/バックでのコード共通化
39
MV*フレームワークとビルド - Angular
 構造化とデータバインドを中心に多用な機能提供
– Model<->Viewの双方向でデータバインド
– dirty-checking バインドデータ量がパフォーマンスに直影響
– DIによるモジュールの注入やRouterによるSPA遷移などいろいろ提供
– ng-のUIモジュールがコミュニティで多数公開
– テストフレームワークや開発ツールなどの提供
– 次期2.0では双方向バインドの廃止によるパフォーマンス改善など大転換
– ng-などの独特の指定方法を排除し、コンポーネントとして汎用定義
– AltJS、特にTypeScriptを推奨
– ビルド時にトランスパイル
40
MV*フレームワークとビルド - React
 2015大ヒットのView主体のフレームワーク
– VirtualDOM:DOMツリーの差分更新でメンテナンス性とパフォーマンスを両立
– Flux:データの流れを一方向にして役割を明快にするアーキテクチャ
– 実装は乱立しているがReduxが大ヒット中
– JSX:JSとテンプレートは無理して切り離さずJSモジュール内にカプセル化
– コミュニティでReactコンポーネントが多数公開
– JSX記法で記述したテンプレートをプリコンパイル : Reactify
41
MV*フレームワークとビルド – Riot, Mithril, Aurelia
 ここまでのフレームワークの弱点を克服する新世代
– VirtualDOMなど優れた仕組みは継承
– Mithril : MV*のフルスタックFW
– モデルの変更ではなく、イベント終了をトリガーにすることで描画高速化
– JSXライクなMSXでViewをコンポーネント内にカプセル化 : Mithrilify
– Riot : ReactのようにViewに特化した軽量FW
– HTMLのコードブロックにJSを埋め込む形でコンポーネント(.tag)作成
– .tagはriot.mountでロードするか、Riotifyなどでトランスコンパイル
42
MV*フレームワークとビルド – Riot, Mithril, Aurelia
– Aurelia : CoCを基本思想とするAngular2.0ライクなフルスタックFW
– Angular2同様に一方向バインドがデフォルト
– ES2015サポート : Babelでのトランスパイル
– 依存性解決はjspmを採用
– UIエコシステム
43
参考:ライブラリ選定にあたって
 選定のポイント : できる限りリアルタイムの情報を調査
– 将来性につながる情報のチェック
– バージョンアップ状況や仕様サポート状況、ライバルとの関係など
– 旧バージョン/現バージョンの情報量、google trendsや更新頻度
– エコシステムが十分に活用できるか?(情報量、プラグイン数、Doc)
– パフォーマンス重視?開発規模により開発生産性重視?実績重視?
– アプリの特徴を前提に自前検証が一番かもしれませんが…
– 定番TODOアプリでのベンチマーク http://matt-esch.github.io/mercury-perf/
44
UT/テスト
 ビルド前にテストを流し問題のないことを確認する
– ユニットテスト:コードレベルでのテスト
– 画面操作テスト:End2End環境でのユーザー操作のテスト
– カバレッジ取得 :メソッドや分岐などの視点でテストでのカバー率をチェック
 動作仕様としてテストコードから作成する:TDD
45
UT – Jasmine他
 *Unit以後の主流JS テストFW
– アサートモジュールやテストダブルを含むオールインワン・テストFW
– テストダブル:Spyでモック作成や関数の実行チェック
– angular-mockなどMV*FW側でmockが提供される場合も
– Jasmine-nodeでNodeでもテストコード実行できる
– 他にMocha系(sinon, power-assert)も人気
46
テストランナー - Karma
 テストFWやブラウザを指定し実行するテストランナー
– ES2015にも対応できる豊富なルール
– JasmineのテストコードをES2015で書いて、トランスパイルして…
– プラグインによるエコシステム搭載
– レポート、browserifyなどの事前処理
– カバレッジ取得(karma-coverage)
– 様々なブラウザランチャー
– 様々なテストFWプラグイン
– Angularと特に相性良し
47
操作テスト – Selenium
 業界標準の画面操作テストツールSeleniumと仲間たち
– マルチブラウザ、マルチ言語、 10年超実績の定番
– JSON Wire Protocolでブラウザを操作
– クライアントAPI実装が多数存在(レコードツールもあり)
– WebdriverJS:W3C標準 Web Driver仕様の実装
– WebdriverIO : ES2015対応 Generatorでテストが書ける
– Appium : Android, iOS向けドライバー
– Protractor
– WebdriverJSベース。Angular向けの拡張機能+αを提供
48
他にもいろいろ
 実行トリガー
– Wath
 JSDoc
– jsdoc (gulp-jsdoc)
 画像最適化
– imagemin, spritesmith
 キャッシュ対策
– rev-replace
49
参考資料
各公式サイトは特に記載してません。
 フロントエンド ビルドツール比較
http://b.hatena.ne.jp/entry/s/speakerdeck.com/bevacqua/front-end-ops-
tooling
 Gulp
https://speakerdeck.com/axross/gulpwoshi-utobi-nu-gadekiruyo-
kantannashao-jie-tohanzuon
https://speakerdeck.com/cognitom/gulp-dot-js-cheatsheet
 Fly
http://www.slideshare.net/deepblue_will/new-generation-build-system-fly
50
参考資料
各公式サイトは特に記載してません。
 Autoprefixer
http://kojika17.com/2014/01/autoprefixer.html
 PostCSS
https://speakerdeck.com/jmblog/postcss-tohahe-ka
 Uglify
http://www.peterbe.com/plog/advanced-closure-compiler-vs-uglifyjs2
http://www.slideshare.net/hasegawayosuke/javascript-51570525
 Webpack
http://liginc.co.jp/web/js/149577
 Browserifyなど
http://tsuchikazu.net/javascript-module/
51
参考資料
各公式サイトは特に記載してません。
 jspm
https://speakerdeck.com/guybedford/package-management-for-es6-
modules
 altJS
http://www.slideshare.net/NeilGreen1/type-script-vs-coffeescript-vs-es6
 Dart
https://docs.google.com/presentation/d/1cETXGhfPb6M2ugRjciWLBL4HjOLc
XPu2e3RHkHDRoEI/edit
 less, sass, stylus
http://www.slideshare.net/verekia/deep-dive-into-css-preprocessors
52
参考資料
各公式サイトは特に記載してません。
 Lint系
http://www.sitepoint.com/comparison-javascript-linting-tools/
http://qiita.com/mysticatea/items/f523dab04a25f617c87d
 Jasmine
http://www.slideshare.net/itokami1123/javascript-jasmine
 JasmineとMocha
https://gist.github.com/taichi/4482819
 Karma
https://speakerdeck.com/sebarmeli/karma-js-test-runner
 Selenium
http://www.slideshare.net/NozomiIto/osssselenium
53
Thanks

キャッチアップJavaScriptビルド - ビルドから見るJSの今/2016春