SlideShare a Scribd company logo
ES6 in Practice
@teppeis
Firefox Dev Conf 2015
Nov 15
Hello!
• Teppei Sato, @teppeis
• Cybozu, Inc. / kintone
kintone.com
MUST BUY!
https://gihyo.jp/dp/ebook/2015/978-4-7741-7477-8
いまES6を正しく使うために
• ES6, ES7, ECMAScriptとは
• ES6 Modules
• ES6 ≠ Babel
• TypeScript
• Rollup
• HTTP/2
ほとんど

Modulesの話に

なっちゃいました :)
ECMAScript
ES6
ECMAScript
• ざっくり言えばJavaScriptの仕様
• Ecma Internationalが標準化 (ECMA-262)
• ISOでも標準化 (ISO/IEC 16262)
• TC39 (Technical Committee) が策定
• メンバーは全ブラウザベンダーとWeb関連企業
ECMAScript 6
• 2015年6月に公開されたESの最新仕様
• ES5から6年ぶりの大幅改定!
New syntax
• Arrow Function
• Classes
• Modules
• Block Scope (let/const)
• Extended Object
Literal
• Default Params
• Rest Params
• Spread Operator
• Destructuring
• Iterator
• Generator
• Template Literal
• Tail Call Optimization
New built-in classes and objects
• Promise
• Map
• Set
• WeakMap/WeakSet
• TypedArray
• Symbol
• Proxy/Reflect
Improvement of existing classes
• String
• RegExp
• Array
• Object
• Math
• Number
ES6 compatibility table
https://kangax.github.io/compat-table/es6/
ES6 or ES2015?
http://blog.cybozu.io/entry/9081
ES6 or ES2015?
• 正式にはECMAScript 2015
• 来年以降、ES2016, ES2017と

年次リリースされていくため(後述)
• でも、慣れ親しんでる&短いので

ES6もまだまだ使われてます
ES.next
The TC39 Process: Annual
• 機能単位で仕様を策定
• 各仕様提案の策定は5段階のStage
Stage 0: Strawman (idea)
Stage 1: Proposal (problem, solution and demo/polyfill)
Stage 2: Draft (initial spec)
Stage 3: Candidate (review and feedback)
Stage 4: Finished (two implementations at least)
• Stage 4を毎年ES201Xとしてリリース
Stage 0: Strawman
• アイデアレベル
• GitHubにPRすれば誰でも提案可能
• Send PR to github.com/tc39/ecma-262 !
Stage 4: Finished
• 仕様公開の準備完了
• 2つ環境で実装済み
ES2016?
ES2016 (ES7) はどうなる?
• 2016年6月に公開予定
• 主にES6のバグ修正
• 2016年1月のTC39 Meetingの時点で

Stage 4になっている提案
• Array#includes はFF, Chrome, WKで実装済み
• 他は exponential operator (**), async/await, SIMD
ES7言うな問題
• ES2016(ES7)にはほとんど新機能入らない
• ES6以降の提案仕様をまとめてES7と言いがち
• ES7 Decorator, ES7 Object.observe…
• ES.nextと言おう
• ブラウザに実装されてもキャンセルされる場合も
@domenic said
spec	version	numbers	are	bullshit	
es6,	es2015,	es2016…	who	cares?	
you	should	not.	
http://www.slideshare.net/domenicdenicola/the-state-of-javascript-2015
ES6 Modules
Good Points
• 1ファイル 1モジュール
• staticで宣言的なsyntax
• strictモード
• 循環参照に対応
Syntax
Default export/import
// export.js
export default function() {
return "foo";
}
// import.js
import foo from "./export.js";
foo();
Named export/import
// export.js
export function foo() {
return "foo";
}
export class Bar {}
export var baz = "baz";
// import.js
import {foo, Bar, baz} from "./export.js";
foo();
new Bar();
console.log(baz); // "baz"
Mixed
// export.js
export default function() {
return "Default";
}
export function foo() {
return "Named";
}
// import.js
import def, {foo} from "./export.js";
def(); // "Default"
foo(); // "Named"
Defaultがオススメ
• ES6 ModulesはDefault Exportが

最も使いやすいようにデザインされている
• Named Exportは、バインディング名を知らな
いとimportできない
• まずはシンプルな1module 1exportから
Static and Declarative
Staticであるメリット
• 実行前にパース時点で依存関係がわかる
• 実行前に各種SyntaxErrorを投げられる
• Browserify系バンドルツールを書きやすい
• 最適化しやすい
重複したexport default
SyntaxError!
// export.js
export default function() {
return "foo1";
}
export default function() {
return "foo2";
}
存在しないモジュールをimport
SyntaxError!
// import.js
import foo from "./missing-module.js";
存在しないバインディングをimport
// export.js
export function foo() {
return "foo";
}
// import.js
import bar from "./export.js";
SyntaxError!
注意:
• default exportのプロパティと

named exportは異なる
Default export property
// export.js
export default {
foo: "Default Property"
};
export var foo = "Named";
// import.js
import def, {foo} from "./export.js";
console.log(def.foo); // "Default Property"
console.log(foo): // "Named"
Strict Mode
Script or Module
• ES6では実行前にScriptかModuleか指定
• Moduleの場合:
• 強制strictモード ("use strict"; 不要)
• トップレベルthisはundefined (非window)
• トップレベル変数がグローバルにならない
Strict mode in Modules
// in module
console.log(this); // undefined
var foo = 1; // module local, not global
// Error!
with (obj) {}
// Error!
var obj = {a: 1, a: 1};
ところで
Script or Module、
どうやって指定するの?
そもそも、
ブラウザからどうやって
モジュール読むんだっけ?
Node.jsからは?
モジュール名の識別子は
Node/CommonJSと同じルール?
拡張子.jsは不要?
既存のCommonJSモジュール
と相互運用できる?
動的にモジュールを読むときは?
RequireJSみたいにフックできる?
まだです…
https://flic.kr/p/4ZaDRz
ES6 Modules
• ES6で最も熱望された機能
• ES6で最も実装が遅れそうな機能
• 半分しか仕様が決まってない
ES6 Modules
• ES6で定義
• Syntax
• Semantics
• ES6で未定義
• Loader
• Dynamic API
whatwg/loader
github.com/whatwg/loader
• ブラウザのローダーを中心に議論中
• Dave Herman (Mozilla)
ブラウザでの読み込み方法(案)
<!-- external file -->
<script type="module" src="./path/to/module.js"></
script>
<!-- inline -->
<script type="module">
import foo from "./path/to/module.js";
foo();
</script>
<!-- 従来の普通のscript要素ではmoduleを使えない -->
識別子(案)
// 相対URL
import foo from "./path/to/module.js";
// 絶対URL
import foo from "https://example.com/path/to/module.js";
jsc shellでES6 Modules体験
• JavaScriptCoreが初期実装 (Constellation++)
• http://nightly.webkit.org/
• Download the latest binary for Mac OS
$ WebKit.app/Contents/Frameworks/10.11/ 

JavaScriptCore.framework/Versions/A/Resources/jsc 

-m ./module.js
Roadmap of Loader
https://github.com/whatwg/loader/blob/master/roadmap.md
ES6 Modules in Node.js
議論はまだ開始せず
• npmはNode.js待ち
• Node.jsはV8待ち
• V8はwhatwg/loader待ち
論点: CommonJSとの相互運用
• ES6 Modules importでCommonJSを読む
• CommonJS require()でES6 Modulesを読む
CommonJSはStaticに解析できない
// module.js
if (someCondition) {
exports.foo = "foo";
}
// import.js
import foo from "./module.js";
Babel
BabelのCommonJS変換
• 識別子の解釈はNode.jsと同じ
• CommonJSとの相互運用を重視

強気に解釈して今動くことを優先
Babel export
// source
export default {foo: 1};
// transpiled (with babel v5)
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = { foo: 1 };
module.exports = exports["default"];
Babel import
// source
import foo from "./module.js"
foo();
// transpiled
"use strict";
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { "default":
obj };
}
var _moduleJs = require("./module.js");
var _moduleJs2 = _interopRequireDefault(_moduleJs);
(0, _moduleJs2["default"])();
CommonJSとの相互変換
// module.js
function React() {}
React.Component = ...
module.exports = React;
// import.js
import Ract, {Component} from "react";
問題点
• staticなsyntax errorが失われている
• default exportとnamed exportを併用不可
Babel 6 Shock
https://flic.kr/p/5oHM46
module.exportsに入れなくなった
// source
export default {foo: 1};
// transpiled (with babel v6)
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = { foo: 1 };
// module.exports = exports["default"]; これが消えた
// import with CommonJS
var foo = require("./foo").default; // .defaultが必要に
Babel Risk
https://flic.kr/p/87pcQk
Babel Risk
• ES6 Modulesは仕様未決定が多い分、

Babelの独自解釈成分が強い
• Babelの解釈変更やNode.js/ブラウザの

正式実装で、今書いているBabel版ES6
Modulesのコードが動かなくなる可能性
@sebmck said
https://speakerdeck.com/sebmck/javascript-transformation-jsconf-2015?slide=52
TypeScript
TypeScript export
// source
export default {foo: 1};
// transpired
exports.__esModule = true;
exports["default"] = { foo: 1 };
TypeScript import
// export.ts
function foo() {return 1;}
export = foo;
// import.ts
import foo from "./export";
// Error!
ES6 Modules in TypeScript
• 旧形式のモジュールは旧形式でロード、

ES6モジュールはES6形式でロード
• 文法が2種類あるのはスマートではないが、

相互運用の独自解釈が少ないため堅牢
• 旧形式が独自なのでES6への移行に動機
Transpilers for ES6
トランスパイラを使う理由
• 生産性の高い機能を

実行環境に実装される前から使いたい
• 標準化されているから(altJSとは違って)

相互運用性があり将来も動作するはず
ES6 Modulesを今使う?
• 標準化はまだ途中、相互運用性はツール依存、
将来動作しない可能性も
• staticな文法の利点が薄い
• 結局Browserifyする
• リスクリターンをよく考慮しましょう
Rollup
Rollup
• Next-generation ES6 Module Bundler
• staticな文法を最大限活用
• 最適化で未使用のバインディングを削除
http://rollupjs.org/
jsnext:main in package.json
{
"name": "my-package",
"version": "0.1.0",
"main": "dist/index.js",
"jsnext:main": "src/index.js"
}
https://github.com/rollup/rollup/wiki/jsnext:main
jsnext:main
• ES6コードとCommonJSコードを両方とも

npmパッケージに載せる仕組み
• staticな強みと、後方互換による資産の活用、

両方のメリットを活かせる
• Node.js/npmの未来へのヒント?
ES6 Modules with HTTP/2
生ES6 Modulesは速い?遅い?
• ブラウザにES6 Modulesがネイティブに実装さ
れたら、依存は実行時に解決される
• 非同期にリクエストを大量になげる通信コスト
HTTP/1.x では遅い
• 多量のTCP接続: 多量の依存ファイル
• ラウンドトリップタイム: 深いネストした依存
• これまでのRequireJS等と同じ問題
• r.js: 本番環境用の事前ビルドツールで解決
HTTP/2で解決?
• 多量のTCP接続: 多重化で解決!
• ラウンドトリップタイム: 解決できず…
ラウンドトリップタイムの解決
• ただのServer Pushではキャッシュ制御に難点
• クライアントで制御: ServiceWorker
• サーバーで制御: H2O cache-aware server pusher
• 現実世界での探求はまだまだこれから!
http://teppeis.hatenablog.com/entry/2015/05/es6-modules-and-http2
Conclusion
Conclusion
• 「ES6はいまから使える」言い過ぎた :)
• ES6/ES7を正しく理解しよう
• BabelとES6の違いを正しく認識しよう
• ES6 Modulesはこれからだ!
MUST BUY!
https://gihyo.jp/dp/ebook/2015/978-4-7741-7477-8
Thanks!

More Related Content

ES6 in Practice