37
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

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

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

リンク
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編―

概要

この記事の概要

  • 目的
    • フロントエンドの環境構築に利用されるツールへの理解を深める
  • 本記事のゴール
    • ReactのJSX構文をコンパイルする方法を知る
  • 対象者
    • WEBフロント担当者
    • HTML,CSS,JavaScript(es2015含む)の基本的な構文を理解している人
    • npmの利用方法を理解している人
  • 環境・バージョン
    • Windows10
    • Node.js(推奨版) 10.15.01
    • npm 6.4.1
    • webpack 4.29.6
    • webpack-cli 3.2.3
    • babel-core 7.3.4
    • babel-cli 7.2.3
    • babel-loader 8.0.5
    • preset-env 7.3.4

React

Reactそのものの説明は割愛させていただきます。。。

React
React - Wikipedia

Reactは、es2015以降の構文の利用が推奨されていることに加え、JSXというそのままではブラウザで動作しない構文を取り入れています。
また、コンポーネントを組み合わせてアプリを開発するという考え方なので、ESモジュールの利用も必須です。
つまり、Babelとwebpackの利用が前提となってきます。

Create React App
Reactは事前準備が大変だからと、公式が用意してくれた環境構築用ツールです。筆者がちまちま説明してきた環境構築が、コマンド一つで完了します。
webpackやBabelより先に、Reactの勉強に取り組みたい方はこちらをご利用ください。
Create React App

ReactのPreset

インストール

BabelでReactのコードを変換するには、専用のPresetが必要です。

$ npm install @babel/preset-react --save-dev


# もちろんReact本体も必要なのでまとめて落としたい場合はこちら
$ npm install react react-dom @babel/preset-react --save-dev

設定

あくまで変換を行うのはBabelですから、基本的にbabel-loaderのオプションに追加します。webpack.config.jsは以下のようになります。

module.exports = {
  /* 略 */
  module: {
    rules: [
      {
        test: /\.js[x]?$/,  // .jsxも対象に含む
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              '@babel/preset-env',
              '@babel/preset-react' //ReactのPresetを追加
            ],
            plugins: ['@babel/plugin-syntax-jsx'] //JSXパース用
          }
        }
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json']  // .jsxも省略可能対象にする
  }
};

rules.test
babel-loaderの対象ファイルに.jsxが含まれるよう、正規表現で指定しています。

Presetの追加

options.presetsにReactのPresetを追加します。後ろに指定したものから実行されるので、preset-reactpreset-envの順で変換されるようにします。

@babel/preset-react

Pluginの追加

JSXパース用のプラグインを指定します。options.pluginsに、配列でプラグイン名を記述します。

PresetとPlugin
最初、PresetとPluginの違いがいまいち理解できていなかったのですが、PluginのコレクションがPresetだそうです。'@babel/plugin-syntax-jsx'は'@babel/preset-react'に含まれます。
最初から有効になっているプラグインのみ利用する場合は、Presetの指定のみで済みます。オプションのプラグインを利用したい場合は、Pluginで指定します。Presetに含まれていないプラグインを独自に追加することも可能です。
@babel/preset-envでは、具体的に個別のPlugin名をこちらが指定するのではなく、利用したい環境情報を伝えると必要なものを選んでくれるという方法をとっています。
実行順序は、Plugin→Presetです。また、Plugin内での順序は最初から(Presetとは逆)です。

Plugins | Babel
Difference between plugins and presets in .babelrc | stackoverflow

resolve.extensions

import文で拡張子を省略するには、予めresolve.extensions登録しておく必要があります。初期設定では['.wasm', '.mjs', '.js', '.json']です。
.jsxも対象にしたい場合は追加する必要があります。この際、設定値は上書きされることに注意してください。['.jsx']にしてしまうとJSXファイルだけが対象になってしまいます。

Reactのソースをコンパイルする

フォルダとファイルの準備

下記フォルダとファイルを準備します。

sample/
  ├ src/
  │   ├ component/
  │   │    └ panel.jsx
  │   └ index.js 
  ├ dist/
  │   ├ js/
  │   └ index.html
  └ webpack.config.js

テキストボックスに文字を入力してボタンを押すと、すぐ下のリストに追加されるだけの挙動です。

/**
 * /src/component/panel.jsx
 */
import React from 'react';

export default class Panel extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      list: []
    };
  }
  handleSubmit(e) {
    e.preventDefault();

    const input = '',
      list = this.state.list.slice();

    list.unshift(this.state.input);

    this.setState({
      input,
      list
    });
  }
  render() {
    return (
      <form>
        <input
          type="text"
          value={this.state.input}
          onChange={e => this.setState({ input: e.target.value })}
        />
        <button
          type="submit"
          onClick={this.handleSubmit.bind(this)}
        >
          add!
        </button>
        <ul>
          {this.state.list.map((v, i) => (
            <li key={i}>
              {v}
            </li>
          ))}
        </ul>
      </form>
    );
  }
}


/**
 * /src/index.js
 */
import React from 'react';
import ReactDOM from 'react-dom';
import Panel from './component/panel';

ReactDOM.render(
  <Panel />,
  document.getElementById('app')
);
<!-- /dist/index.html -->
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Test</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="./js/sample.js"></script>
  </body>
</html>

実行

Charenge!
webpack.config.jsとpackage.jsonで、以下の設定を自分でやってみよう!(手抜き)

  • /src/index.jsのコンパイル結果が/dist/js/sample.jsに出力されるようにしよう!
  • ブラウザ上で、コンパイル前のソースも確認できるようにしよう!
  • ソースコードを編集すると、自動でコンパイルされるようにしよう! インストールしたパッケージのソースは対象外にすることを忘れずにね!
  • npm scripts からバンドルを実行しよう!

それでは、IE11で実行結果を確認してみましょう。

webpack04.png

無事に動くということは、JSXがJavaScriptに変換され、es2015以降の構文がes5に変換されたということですね。

参考情報

Create React Appで環境構築 – React入門

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
37
Help us understand the problem. What are the problem?