2021年8月22日日曜日

JS:Babel

1.Babelとは

Babel(読み方:「バベル」)は、次の世代のJavaScriptの標準機能をブラウザのサポートを待たずに使えるようにするNode.js製のツールである。次の世代の標準機能を使って書かれたコードを、それらの機能をサポートしないブラウザでも動くコードに変換する。

JavaScriptのコードを新しい書き方から古い書き方に変換するツールである。
具体的には、JavaScriptの言語仕様であるES2015以上の仕様のJavaScriptで記述すると、古いブラウザでは動作しない。そこで、Babelを使ってES2015・ES2016といった仕様で記述したJavaScriptファイルを互換性のあるEXMAScript5に変換する。

主に、es2015以降の新しい構文をes5の構文に変換するのに利用されています。もちろん、設定によってはes2018→es2015といった記述方法も可能です。その他にも、ReactのJSXやTypeScriptの変換にも使われます。

2.インストール

package.jsonがある場所で以下のコマンドを実行する。babel-cliはbabelをcliで実行するための本体モジュールで、babel-preset-envはES6の内容をES5に変換する情報のようなもの。

npmで三つのパッケージをインストールします。

$ npm install @babel/core @babel/cli @babel/preset-env --save-dev

@babel/core: Babel本体

@babel/cli: コマンドライン操作用

@babel/preset-env: 変換内容設定用


3..babelrcによる設定

Babelはそのままでは何も変換してはくれないので、どのように変換するのかを事前に設定します。作業フォルダのルートに.babelrcを作成し、JSON形式で設定情報を追記していきます。

{

  "presets": ["@babel/preset-env"]

}


4.プリセット(Presets)の基本

プリセットは、Babelが変換処理を行う際に利用するプラグインのコレクションです。設定情報を基に、コンパイルに必要なプラグインのリストをBabel本体に渡す役割をしているそうです。公式では下記4つのプリセットが用意されています。その他にもいろいろ開発されています。

  • @babel/preset-env: ECMAScript用
  • @babel/preset-flow: Flow用
  • @babel/preset-react: React用
  • @babel/preset-typescript: Typescript用


利用したいプリセットをインストールした後、配列で名前を指定します。後ろから順に適用されます。下記のケースでは、typescript → react → env の順で実行されます。

{

  "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"]

}

各プリセットにて詳細な設定をしたい場合は、配列で囲みます。0番目に名前、1番目に設定情報です。

{

  "presets": [

    ["@babel/preset-env", {<@babel/preset-envの設定値>}],

    "@babel/preset-react",

    "@babel/preset-typescript"

  ]

}


4.1.@babel/preset-env

@babel/preset-envは、出力したいECMAScriptのバージョンを指定するためのプリセットです。基本的には、サポートしたい範囲(ブラウザバージョンやブラウザシェア、サポートの可否など)を指定します。指定内容に応じて適切なバージョンのJSに変換されるようにしてくれます。特に何も指定しない場合は、一律es5の構文に変換されます。

下記の設定は、Chrome40以上・iOS10以上をサポート対象とした場合です。es5で出力されました。


{

  "presets": [

    ["@babel/preset-env", {

        "targets": [

          "chrome 40",

          "iOS 10"

        ]

      }

    ]

  ]

}

cover 80% in JPは、ブラウザシェア率を基に日本で80%のユーザをカバーするという指定です。es5で出力されました。モダンブラウザの新しいバージョンを指定すると、es2015以降のバージョンで出力されます。


4.2.PolyfillとuseBuiltInsオプション

初期設定では、@babel/preset-envが行うのは構文の変換のみです。Promiseやgeneratorなど、新たに追加された機能の変換には対応していません。オプションで、useBuiltInsにusageを指定すると、必要に応じてPolyfill(代替コード)に変換してくれます。(初期値はfalse)

{

  "presets": [

    ["@babel/preset-env", {

        "targets": [...],

        "useBuiltIns": "usage"

      }

    ]

  ]

}


@babel/polyfill

2019年2月現在、「useBuiltIns:'usage'」の項目には「experimental(実験的)」とあります。お使いの環境でうまく動かなかった場合は、@babel/polyfillと「useBuiltIns:'entry'」の合わせ業もあります。


@babel/polyfillをインストール

$ npm install @babel/polyfill --save

アプリ(サイト)内の一箇所にだけ、下記インポート文を記述します。複数個所に記述するとエラーとなるそうです。この記述は、必要に応じて個別のpolyfillのインポート文に書き換えられます。


// 記述する内容

import "@babel/polyfill";


// 最終的に個別のimport文に変換される

import "core-js/modules/es7.string.pad-start";

import "core-js/modules/es7.string.pad-end";


4.3.設定ファイルをpackage.jsonにまとめる

設定ファイルを増やしたくない場合は、package.jsonにまとめることも可能です。babelという項目を追加します。記述方法は.babelrcの場合と同様です。またwebpack同様、コマンドをscriptsに登録して利用することも可能です。


{

  "name": "sample",

  "version": "1.0.0",

  "main": "index.js",

  "scripts": {

    "build": "babel ./src/index.js --out-file ./dist/index.js"

  },

  "devDependencies": {

    "@babel/cli": "^7.2.3",

    "@babel/core": "^7.2.4",

    "@babel/preset-env": "^7.3.4",

    "webpack": "^4.29.6",

    "webpack-cli": "^3.2.3"

  },

  "babel": {

    "presets": ["@babel/preset-env", {

        "targets": [...],

        "useBuiltIns": "usage"

      }

    ]

  }

}

以上がBabelの基本(の一部)となります。設定方法一つとっても手段が多種多様で迷います。。。