独学の内容をまとめたものです。誤りがございましたら、ご連絡いただけると幸いです。
リンク
- webpackとBabelの基本を理解する(1) ―webpack編―
- webpackとBabelの基本を理解する(2) ―Babel編―(本記事)
- webpackとBabelの基本を理解する(3) ―webpackとBabel編―
- webpackとBabelの基本を理解する(4) ―React編―
- webpackとBabelの基本を理解する(5) ―Sass編―
概要
この記事の概要
- 目的
- フロントエンドの環境構築に利用されるツールへの理解を深める
- 本記事のゴール
- Babelで最新のJS構文を環境に応じたバージョンに変換する方法を知る
- 対象者
- WEBフロント担当者
- HTML,CSS,JavaScript(es2015含む)の基本的な構文を理解している人
- npmの利用方法を理解している人
- 環境・バージョン
- Windows10
- Node.js(推奨版) 10.15.01
- npm 6.4.1
- babel-core 7.3.4
- babel-cli 7.2.3
- preset-env 7.3.4
Babel
JavaScriptのコンパイラです。トランスパイラとも呼ばれています。公式サイトはcompilerと呼んでいます。
主に、es2015以降の新しい構文をes5の構文に変換するのに利用されています。もちろん、設定によってはes2018→es2015といった記述方法も可能です。その他にも、ReactのJSXやTypeScriptの変換にも使われます。
Babelの導入
インストール
npmで三つのパッケージをインストールします。
$ npm install @babel/core @babel/cli @babel/preset-env --save-dev
- @babel/core: Babel本体
- @babel/cli: コマンドライン操作用
- @babel/preset-env: 変換内容設定用
.babelrcによる設定
Babelはそのままでは何も変換してはくれないので、どのように変換するのかを事前に設定します。作業フォルダのルートに.babelrc
を作成し、JSON形式で設定情報を追記していきます。
sample/
├ src/
│ ├ component/
│ │ └ test.js
│ └ index.js
├ dist/
├ webpack.config.js
└ .babelrc
ひとまず、.babelrc
に下記設定情報を書きます。(解説は後述)
{
"presets": ["@babel/preset-env"]
}
コンパイルする
下記内容で、before.js
を用意します。
es2015で配列に対してスプレッド演算子が導入されましたが、es2018ではオブジェクトでも利用できるようになりました。もちろんレガシーなブラウザでは使えません。
/**
* before.js
*/
{
const data = {
hoge: 'hoooooo',
fuga: 'gaaaaaa',
piyo: 'piiiii'
};
const { hoge, ...other } = data;
console.log(hoge, other);
}
const hoge = 'mumumu';
そして、同フォルダ内で下記コマンドを実行します。
$ npx babel before.js --out-file after.js
同じフォルダ内にafter.js
が作成されます。
いろいろコードが増えていますが、es2015で導入されたconst
が、var
に変換されていたり、スプレッド構文が分解されていたりします。
/**
* after.js
*/
"use strict";
function _objectWithoutProperties(source, excluded) {...}
function _objectWithoutPropertiesLoose(source, excluded) {...}
{
var data = {
hoge: 'hoooooo',
fuga: 'gaaaaaa',
piyo: 'piiiii'
};
var _hoge = data.hoge,
other = _objectWithoutProperties(data, ["hoge"]);
console.log(_hoge, other);
}
var hoge = 'mumumu';
ブロックはそのままなのですが、var
はブロックスコープに対応していません。その為、ブロック内の変数hoge
は、グローバル変数hoge
と名前が衝突しないよう、アンダーバーが追加されています。
import/export
Babelではファイルのバンドルまでは行わない為、import/export文はNode.jsのrequire文に置き換えられるのみです。
Babelがどんな風に変換されるかは、オンラインで確認できます。
BABEL REPL
Presets
プリセット(Presets)の基本
プリセットは、Babelが変換処理を行う際に利用するプラグインのコレクションです。設定情報を基に、コンパイルに必要なプラグインのリストをBabel本体に渡す役割をしているそうです。2019年2月現在、公式では下記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"
]
}
@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以降のバージョンで出力されます。
環境の指定方法は多岐にわたるので、こちらもあわせてご確認ください。
Browserslist
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";
設定ファイルを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の基本(の一部)となります。設定方法一つとっても手段が多種多様で迷います。。。
次回は、Babelでバベりつつwebpackでバンドっていきたいと思います。
参考情報
今更のバベる。 Babel 7を試してみたメモ
@babel/preset-envのuseBuiltInsを使ってpolyfillする
.babelrcと.eslintはpackage.jsonに