LoginSignup
197
158

More than 5 years have passed since last update.

webpackとBabelの基本を理解する(2) ―Babel編―

Last updated at Posted at 2019-03-03

独学の内容をまとめたものです。誤りがございましたら、ご連絡いただけると幸いです。

リンク
1. webpackとBabelの基本を理解する(1) ―webpack編―
2. webpackとBabelの基本を理解する(2) ―Babel編―(本記事)
3. webpackとBabelの基本を理解する(3) ―webpackとBabel編―
4. webpackとBabelの基本を理解する(4) ―React編―
5. 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

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つのプリセットが用意されています。その他にもいろいろ開発されています。

利用したいプリセットをインストールした後、配列で名前を指定します。後ろから順に適用されます。下記のケースでは、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が行うのは構文の変換のみです。Promisegeneratorなど、新たに追加された機能の変換には対応していません。オプションで、useBuiltInsusageを指定すると、必要に応じて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";

ガイド: @babel/preset-env

設定ファイルを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に

197
158
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
197
158