🧊

Node学園 21時限目 -ES Modules Meetup- に行ってきたメモ #tng21

そしてLTで発表もしてきました。
発表資料はコレです。

0からはじめるFlow

この記事の末尾に、発表後の補足も少し加えてます。

今日こそわかる ES Modules by @teppeis

You don't know ES Modules

あなたはまだ本当のES Modulesを知らない・・・!

歴史のおさらい

  • Moduleパターン
  • AMD(`define` -> `require`)
  • CommonJS(Node.jsでおなじみ同期)

これらの問題

  • 動的である
    • 何に依存してるか実行されるまでわからない
    • Browserify, Webpackではそもそも動的にロードできない
  • 標準ではない
    • 特定の3rdパーティに依存することになる
    • ライブラリ作る度にそれ用の対応が・・
  • 拡張できない
  • 循環参照

そこでES Modules

  • `export( default)` -> `import`
  • パース時に依存解決してくれる
  • なんたってWeb標準
  • モジュールとして定義すれば、`use strict`強制
  • `default`をつけないで、変数をそのまま`export`もできる
    • けどその場合、なんて名前で`import`すればいいかわからない
    • 1ファイル1モジュールからやるのオススメ
  • GitHub - rollup/rollup: Next-generation ES6 module bundler
  • Edgeは静的にパースして先にメモリ割当とかやってくれる
  • ESではシンタックスだけを規定
    • 読み込み方法とかパスは規定しない

ScriptとModule

  • ES6的には、パースターゲットとして2種類ある
  • 実行側が指定する
  • Module
    • `use strict`強制
    • 変数はモジュール内でローカルに
    • TopLevel`this`が`undefined`
    • `await`も予約語
    • HTMLコメントが書けなくなる

ECMAScriptで決めてないこと

  • Moduleの指定方法
  • パス解決
    • 絶対URL、`/`、`./`、`../`からの相対URL以外はSyntaxError
    • `import 'lodash'`はダメで、`import './lodash.js'`まで必要
    • 今やれてるのはNode.jsの文化的なアレ、やりたいならフックで
  • Loader API
  • このへん決めてるのは GitHub - whatwg/loader: Loader Standard
  • ブラウザでの挙動は GitHub - whatwg/html: HTML Standard
    • `<script type="module">`
    • 非対応ブラウザではただのデータブロックになる
    • `<script />`ごとのスコープになる
    • `defer`属性がついたのと同じになる
    • `async`属性はオプショナル
    • `crossorigin`属性がないと、Cookieが乗らない
  • CDNのような外部オリジンの`import`には、CORSヘッダが必須
  • `new Worker('worker.js', { type: 'module' })`すると、中で`importScript()`できなくなる
  • モジュールはrealm(≒ frame)単位でメモ化される
    • よって同一モジュールへのリクエストは1度のみ

いつ決まるのか

  • ブラウザへの実装状況はまだまだ・・
  • 論点はいろいろある
  • ES Modulesの検出方法
    • ブラウザは`type="module"`
    • Node.jsでどうしよう
    • `use module`とか`.mjs`にしようとか`package.json`に書くとか
    • なんしかめっちゃ揉めてる
  • パス解決
  • CommonJSとの互換性

7月のTC39のミーティングで一波乱あるらしい・・・!

ECMAScript as a Living Standard by @azu

ECMAScript as a Living Standard

  • ECMAScriptはただの大きなプロジェクトと思って良い
    • Nodeと違ってフォーマルw
  • ES2015から1年ごとのリリースサイクルになった
    • このベースを作ったのがまず功績
  • GitHub - asciidwango/js-primer: JavaScriptの入門書 を書いてる
  • ES 2016
    • `Generator`が`new`できなくなった
    • `Array.includes`が入った
    • などなど
  • 仕様が変わるときのコミットには、以下の目印が
    • Normalative
    • Layerling
    • Editorial

TC39

  • ECMAScriptを策定する企業の集まり
  • 挙動が変わるものは、Consensusが必要になる
  • 既存のWebで使われてるものは難しい
  • maximally minimalという考え方で落とし所を探ったり
  • Stage: 実装段階
    • `0`から`4`
    • `4`になったら次の`ES20**`に入る
    • 最近だと`async/await`がStage3にいる
  • 開発者がこのプロセスに参加できる
    • ブラウザのフラグON/OFFとか
    • Babelで試すとか
  • 開発者のフィードバック重要
    • Issueを立てたり
    • ES Discussに投げたり

ECMAScriptは大きなGitHubプロジェクト

  • P/RやIssueでやり取りされる
  • ミーティング内容も公開されてる
  • コミットを追えばわかる!


🍕がきたのでメモはここで途切れている...

発表の補足など

最初のアンケート

ざっと覚えてる限りだと来場者約100人で、

  • Flowの名前知ってる人: 6割くらい
  • 触ったことある人: 1割ちょいくらい
  • がっつり触ってる人: 3人

でしたw

`passPerPreset`

@t_wada 神に教えていただきました。

`プラグイン、プリセットの処理順を指定できる機能`というのはざっくりしすぎで、正しくは、

  • そもそもプラグイン、プリセットの処理順は、元から`.babelrc`に書いた順になってる
  • 高速化のため、BabelのASTのトラバーサルは基本的には1度になった
  • なのでASTで末端を削る系のプラグインと処理する系のプラグインがいると、衝突する恐れがある
  • そこでこの`passPerPreset`が指定されると、その指定の単位で複数回トラバースするようになる
  • そうすると衝突事故を回避できる!がその分パフォーマンスは犠牲になる

だそうです。
なので、処理順というより処理の段取りの指定ができる機能という解釈が正しいのかな?
ありがとうございます!

Decoratorに対応してないのはそもそも

まだStage1で、JavaScriptじゃないから・・という話を @yosuke_furukawa 会長に聞いた。

ただFlowには実は`esproposal.decorators`ってオプションがあって、クラスプロパティへのDecoratorだけは見てくれるんですよね・・。
クラス自体とメソッドへのDecoratorは、非対応!って言われる。