ググれカス!

あ、ググってここに来たの。ごめん。そりゃそうか。

◆ハイケイ

ブラウザによって処理可能なJavaScriptは違う。

上記から、ふたつの事柄が想起される。

  1. JavaScriptの仕様らしい仕様がなかった時代の話
  2. 仕様ができて、みんなノリ気になってからの話

JavaScriptがこの世にリリースされた際、それが動作するWebブラウザはひとつっきゃなかった。それから暫くして「便利だねぇ」っつって他のブラウザもJavaScript動くように追従してきたんだけど、各ブラウザベンダーがてんでに実装したら馬鹿げた事態になるでしょう。SQLみたいに、各ブラウザ向けのJavaScriptを書かねばならなくなる。エンジニアが死んじゃう。だから仕様(標準)を整理しようという話になり、ECMAScriptが策定された。

ECMAScriptという仕様にはバージョンがあって、バージョンを重ねれば当然に機能が追加されたりする。各ブラウザはECMAScriptの仕様に則ったJavaScriptが正常に動くよう実装を進めるわけだが、古いブラウザは古いJavaScriptしか動かないままになる。

古いブラウザを古いまま使うチンパン知能のクズ人間が大勢いるもんで、新しめのJavaScriptで書いても「動かないよぉ」とか苦情くる。そういう奴らは一列に並ばせてから順繰りに殴れば良いんだけど、いかんせん数が多いので殴る方も腕が持たなくなってくる。そこで、もっと簡単に殺せるように近頃は竹槍を使って喉元を突くようになった。

…ちがう。すごい間違えた。Babelを使ってそのへんの問題を解決するようになった。

◆余談:compatibility

どのブラウザがどのJavaScriptの機能を実装しているのかってのはコンパチテーブルと俺が勝手に呼んでいるサイトを参考にすればいい。

https://kangax.github.io/compat-table

上の「5」だの「6」だの「2016+」だのをクリックすれば、それぞれのFeature(機能)をどのブラウザが実装してんのかって一目瞭然。ChromeもFirefoxもEdgeもChromium EdgeもOperaもSafariもなんでも。昔のブラウザバージョンを確認したいなら「Show obsolete platforms」にチェックを入れれ。

このあいだ知って衝撃を受けたのは、Safari 12くんがString.prototype.matchAll使えないってやつ。マジ…ジョブズ許さん。

◆JavaScriptに限らないこと

Webの標準はScriptとStyleとHTMLの三本柱。ScriptはECMAScript。StyleはCSS。HTMLはHTML。

それぞれブラウザに依ってどこまで実装してるのかってのは、わからん。というので「hoge caniuse」みたいに「caniuse」を付けて検索すればCan I use...が出てきて確認できるます。

例えば「WebGPU caniuse」で検索すると、2021年1月現在、WebGPUが何一つ実装されていないことがわかる。丁寧に読めばかなり色々書いてあって親切。

HTMLで言えばDialog要素とかSafariで使うことが出来なくてキレてるし、CSSでいえばscroll-behaviorSafariで使うことが出来なくてキレてる。

…Safari!!!!!!!

scroll-behaviorはまだWDなので許せるっちゃ許せるが、Dialogは使わせろ。

え?IE?なにそれ?は?ゴメン知らないわキモっ。キッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッツ。

◆余談:MDN

Web標準についてググるのであれば、先頭に「mdn」と必ずつけること。HTMLタグリファレンスとかいうhttps対応してないくせに超クッソ激烈にSEO強いサイトは検索結果に出てくるんじゃねぇやい。検索除外かけたいくらい嫌い。HTMLタグリファレンスと侍エンジニア塾とTECH ACADEMYは間違ってクリックしちゃった時に指が砕け散りそうになるほどムカつく。

◆Babel

バベル。

最新のECMAScriptでは、コードを簡潔に書くことが出来る。古いECMAScriptで簡潔じゃないコードを書けばバグが埋まる。だもんで新しい記法で書きたいわけだけど、最新のECMAScriptで書くとブラウザに依って実装状況が違うから動かなくなることもある。

そして、古い記法が動かなくなるって事例はほぼ無い。後方互換性の担保が強い。

だから

  • 書く時はあたらしい記法
  • 公開する時は古い記法

にすれば大抵のブラウザで動くようになるだろう。そうしたい。どうすればいいのか。バベればいい。

書いたJavaScriptをBabelに通せば古い書き方にしてくれる。それがBabelの真髄。

◆どう使うのか

やりたいことは、JavaScriptを食わせてJavaScriptにすること。つまり、babelというプログラムに文字列を渡して文字列が返ってくればいい。あるいはフォルダごと全部バベるとか。

構文解析だのの機能を@babel/coreが持っていて、そいつでASTとか扱えるんだけど興味ないだろうし俺も詳しくないので説明しない。

ふわっとしたことだけ説明する。この記事の目的は概念の説明をすることだし、使い方書いてもどうせ一年もすれば陳腐化するし。公式ドキュメントをあたりくされ。

詳しく知りたいのであればBabelのUsage Guideを見るがいい。読んでも良くわからんかもしれんが。

▼バンドラツール(ビルドツール)(タスクランナー)

Babelをバンドラツールと組み合わせる。webpackとかparcelとかsnowpackとか。バンドラツールについては説明しない。したほうが良いんだろうか。しないけど。

タスクランナーであるgulpgruntもbabelに対応してるんだろうが知らん。まだ使ってるやついるの?

バンドラツールは、いまんとこ大概はNode.js上で動く。Node.jsについても説明しない。あ、Deno上でも動くよ。

バンドラツールは、我々が書いたコードを配信に向いた感じにしてくれる(あいまい)。配信に向いた感じの形状にJavaScriptを吐いてくれるわけだから、それをバベったりすればいいじゃん。

重要なことは、バンドラツールを叩いたらバベルまで自動でやってくれるってこと。Webアプリケーションのデプロイをするにあたり、全ての作業をコマンドで済ませることができれば自動化出来る。手作業によるリリースで事故らずに済む。

▼CLI

babelにはCLIツールが有る。@babel/cli。CLIについては説明しない。

…いやする。知らないってことは無いと思うが、CLIはコマンドラインツールです。このコマンドラインツールもNode.js上で動く。

コマンドラインってなにって…お前…

▼Web上でバベる

CLI使えば手動でBabelすることもできるし、それすらダルいならWeb上でもバベれる。Babelをちょっと試したいよってときは以下の公式サイトを試してみるがええわ。

https://babeljs.io/repl

よーし。パパ今日はバベっちゃうぞ^~。

class Rectangle {
  height;
  width;
}

const hoge = new Rectangle();
/repl.js: Support for the experimental syntax 'classProperties' isn't currently enabled (2:9):

  1 | class Rectangle {
> 2 |   height;
    |         ^
  3 |   width;
  4 | }
  5 | 

Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.
If you want to leave it as-is, add @babel/plugin-syntax-class-properties (https://git.io/vb4yQ) to the 'plugins' section to enable parsing.

エラーガデテル!!

アラホント!

プラグインが必要なことあるんで、左下の「Add Plugin」から追加すれば?今回で言えば「@babel/plugin-proposal-class-properties」だな。エラー文に書いてあるとおりだよ。

◆Polyfillってなに

  1. イマドキの記法を古い記法に置き換えること。
  2. 新しすぎてまだどのブラウザも実装してない機能を今の機能で代替すること。
  3. 仕様に則ってない実装を仕様に則った形にする。

が混ざった概念。特定のライブラリを指している用語ではない。さっき理解したと思うけど、Babelはライブラリの名前。「ポリフィる」と「バベる」も厳密には同じ概念ではない。Polyfillという用語はJavaScriptに限らず、CSSにもHTMLにも適用できる。

「Polyfillしてくれるライブラリ」というのが存在していて、大抵はひとつの機能を専任でポリフィってくれる。かたやBabelはECMAScriptのバージョンレベルでいろいろな機能を一括でポリフィってくれる。

それにしても、Babelが新しいコードを古いコードにトランスパイルするにあたり、変換ルールの対応表が必要になると思わんかね?その対応表は全てBabelライブラリの中に格納されている…わけではなく、各Polyfillとして提供されています。一緒くたにして扱うことが出来るようにはなってるんで、ひとつひとつのPolyfillをポチポチいれていくっていう苦行はしなくてもいいようになっている。

「@babel/polyfill」というdeprecated(非推奨)なライブラリがあったり、「core-js/stableつかえや」って書いてあったり、でもcore-js/stableだとIE11で動かないって報告があったり。闇ですね。闇っつーか沼っつーか。

◆Polyfill.ioってなに

HTMLのscriptタグを一行足すだけでポリフィれる世界もある。

Polyfill.io

「CREATE A POLYFILL BUNDLE」のページにあるURLをHTMLのheadにぺって貼ればいい。そのURLからPolyfillしてくれるjsを読み込むわけだけど、全部のPolyfillが読み込まれるわけではない。リクエスト時に送信されるUserAgentで必要なPolyfillを自動判別してくれたりするんすね。

あとNPM PACKAGEも用意されてるっぽいな。俺は使ったこと無いけど。

おまえ「べんりじゃね?」

んん。まぁ便利なんだけど、そりゃ罠もある。

例えば、「動かんのだけど」「画面が白いのだけど」「サイトが壊れるわ(しんみり)」みたいなトラブルの報告を受けた時にUserAgentがないと正確な原因切り分けができなくなるよね。Polyfill含めたソースが無いから環境の再現性が担保できなくなるかも。

あと、UserAgantって暫くしたら廃止される流れだと思う。

「あぁうごく~」じゃなくて、何がどういう理屈で以て動作するかってのを調べやがれ。できるだけ。

◆結論

そんな感じ。

良くわからなかったかもしれないんだけど、とりあえずは古いブラウザ使ってる人間を竹槍で刺すことから始めればいいと思う。それからBabelを使うんでも遅くはない。