最新のブラウザに最新のコードを提供し、ページの読み込みを高速化する

すべての主要なブラウザで適切に動作するウェブサイトを構築することは、オープンなウェブ エコシステムの基本理念です。ただし、これには、ターゲットにする予定の各ブラウザで、記述するすべてのコードをサポートするという追加の作業が必要になります。新しい JavaScript 言語機能を使用する場合は、これらの機能をまだサポートしていないブラウザに対して下位互換性のある形式にトランスパイルする必要があります。

Babel は、新しい構文を含むコードを、さまざまなブラウザや環境(Node など)が理解できるコードにコンパイルするために最も広く使用されているツールです。このガイドでは、Babel を使用していることを前提としています。そのため、まだ行っていない場合には、設定手順に沿って Babel をアプリケーションに組み込む必要があります。アプリのモジュール バンドラとして webpack を使用している場合は、Build Systemswebpack を選択します。

Babel を使用してユーザーにとって必要なものだけをトランスパイルするには、次のことを行う必要があります。

  1. ターゲットに設定するブラウザを指定します。
  2. 適切なブラウザ ターゲットで @babel/preset-env を使用します。
  3. <script type="module"> を使用すると、トランスパイルされたコードを必要としないブラウザに送信されなくなります。

ターゲットに設定するブラウザを指定します

アプリケーションのコードのトランスパイル方法を変更する前に、アプリケーションにアクセスするブラウザを特定する必要があります。ユーザーが現在使用しているブラウザと、ターゲットとなる予定のブラウザを分析して、十分な情報に基づいて意思決定を下します。

@babel/preset-env を使用します

通常、コードをトランスパイルすると、ファイルのサイズが元の形式よりも大きくなります。コンパイルの量を最小限に抑えることで、バンドルのサイズを小さくして、ウェブページのパフォーマンスを向上させることができます。

Babel では、使用している特定の言語機能を選択的にコンパイルする特定のプラグインを含めるのではなく、プラグインをバンドルしたさまざまなプリセットを提供しています。@babel/preset-env を使用して、ターゲットとするブラウザに必要な変換とポリフィルのみを含めます。

Babel 構成ファイル .babelrcpresets 配列に @babel/preset-env を含めます。

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "targets": ">0.25%"
     }
   ]
 ]
}

含めるブラウザのバージョンを指定するには、targets フィールドに適切なクエリを browsers フィールドに追加します。@babel/preset-env は、ブラウザ ターゲティングのための異なるツール間で共有されるオープンソース設定であるブラウザリストと統合します。互換性のあるクエリの一覧については、browserslist のドキュメントをご覧ください。もう 1 つの方法は、.browserslistrc ファイルを使用してターゲットにする環境をリストすることです。

">0.25%" 値は、グローバル使用量の 0.25% 以上を占めるブラウザのサポートに必要な変換のみを含めるよう Babel に指示します。これにより、ごく一部のユーザーしか使用していないブラウザに対して、不要なトランスパイルされたコードがバンドルに含まれないようにすることができます。

ほとんどの場合、次の構成を使用するよりも、この方法のほうが適しています。

  "targets": "last 2 versions"

"last 2 versions" 値を指定すると、すべてのブラウザの直近の 2 つのバージョン用のコードがトランスパイルされます。つまり、Internet Explorer などの廃止されたブラウザに対してもサポートが提供されます。アプリケーションへのアクセスにこれらのブラウザが使用されることを想定していない場合、バンドルのサイズが必要以上に増加する可能性があります。

最終的には、ニーズに合ったブラウザのみをターゲットとするように、クエリの適切な組み合わせを選択する必要があります。

最新のバグの修正を有効にする

@babel/preset-env は、複数の JavaScript 構文機能をコレクションにグループ化し、指定されたターゲット ブラウザに基づいて有効または無効にします。適切に機能しますが、ターゲットのブラウザにバグが 1 つだけ含まれている場合は、構文機能のコレクション全体が変換されます。これにより、必要以上にコードが変換されることがよくあります。

元々は別のプリセットとして開発された @babel/preset-envバグ修正オプションは、一部のブラウザで壊れている最新の構文を、それらのブラウザで壊れていない最も近い同等の構文に変換することで、この問題を解決します。すべてのターゲット ブラウザで互換性を保証するために、構文を少し調整したほぼ同じ最新のコードが完成しました。この最適化を使用するには、@babel/preset-env 7.10 以降がインストールされていることを確認し、bugfixes プロパティを true に設定します。

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "bugfixes": true
     }
   ]
 ]
}

Babel 8 では、bugfixes オプションがデフォルトで有効になります。

<script type="module">

JavaScript モジュール(ES モジュール)は、すべての主要ブラウザでサポートされている比較的新しい機能です。モジュールを使用すると、他のモジュールからインポートおよびエクスポートできるスクリプトを作成できますが、@babel/preset-env と併用して、そのモジュールをサポートするブラウザのみをターゲットにすることもできます。

特定のブラウザのバージョンやマーケット シェアでクエリを実行するのではなく、.babelrc ファイルの targets フィールド内で "esmodules" : true を指定することを検討してください。

{
   "presets":[
      [
         "@babel/preset-env",
         {
            "targets":{
               "esmodules": true
            }
         }
      ]
   ]
}

Babel でコンパイルされた新しい ECMAScript 機能の多くは、JavaScript モジュールをサポートする環境ですでにサポートされています。これにより、実際にコードを必要とするブラウザにトランスパイルされたコードのみが使用されるようにするプロセスを簡素化できます。

モジュールをサポートするブラウザは、nomodule 属性を持つスクリプトを無視します。逆に、モジュールをサポートしていないブラウザは、type="module" を含むスクリプト要素を無視します。つまり、モジュールとコンパイル済みフォールバックをインクルードできます。

以下のように、アプリケーションの 2 つのバージョン スクリプトが含まれているのが理想的です。

  <script type="module" src="main.mjs"></script>
  <script nomodule src="compiled.js" defer></script>

モジュールをサポートするブラウザは、main.mjs を取得して実行し、compiled.js を無視します。モジュールをサポートしていないブラウザは、その逆を行います。

webpack を使用する場合は、アプリケーションの 2 つのバージョンに対して異なるターゲットを構成に設定できます。

  • モジュールをサポートするブラウザ専用のバージョン。
  • 従来のブラウザで動作するコンパイル済みスクリプトを含むバージョン。トランスパイルではより幅広いブラウザをサポートする必要があるため、ファイルサイズは大きくなります。

レビューに協力してくれた Connor Clark と Jason Miller に感謝します。