webpack と Babel – React入門

React入門」の今回は開発環境としてwebpackを導入する方法について解説を行います。

現在はBabelを利用してReactとES2015を利用することまでは解説しております。

参考 : BabelとES2015 – React入門

ただ、このままではES2015の重要な機能である import / export 機能を利用することができません。
(import / export は JavaScirptファイルを分割管理するための方法です)

追加でwebpackを利用することでimport / exportを利用してJavaScirptファイルを分割管理が可能になります。

import / export

まず、webpackの前にES2015で追加されたJavaScriptの新しい文法であるimport / exportについて解説を行います。

import / export はファイルを分割管理する手法であるため、JavaScriptファイルの呼び出し元と呼び出し先でそれぞれ記述が決まっています。
呼び出し元ではexportを、呼び出し先ではimportを利用します。

以下のように、呼び出し元を「bar.js」と定義をします。

export const myFunc = str => {
    console.log(str)
}

exportキーワードを関数や変数などのオブジェクトの前に指定することで他ページで読み込むことが可能になります。

次に、呼び出し先は「foo.js」と定義します。

import { myFunc } from './bar.js';
myFunc('webpack と Babel'); //webpack と Babel

呼び出し先ではimport構文を利用して、{ ... } 内に読み込みたいオブジェクトの名前を、fromの後に読み込みたいファイルを指定します。

そうすることでfoo.js内でbar.jsで定義した myFunc関数が が利用可能になります。

import / exportは関数だけでなくClassや変数、配列、オブジェクトなどでも利用できます。

このように関数などを特定のファイルで定義しておき、必要に応じて呼び出して利用します。

最近ではブラウザでネイティブにimport / exportの実装も始まっておりますが、環境によっては利用できないこともあります。

webpackを利用すればimport / exportに対応していないブラウザでも利用できる形に書き出してくれます。

webpackの利用

それでは、webpackを実際に利用してましょう。まずは適当な作業ファオルダを作成してください。ただし、作業ディレクトリには『webpack』などの後ほどインストールするnpmパッケージと同じ名前は利用しないでください。今回は『webpack_sample』としましょう。

初期ファイルの設定

webpack_sampleフォルダ内には以下のようにファイルを配置します。

.webpack_sample/
├── /src
│ └── app.jsx
├── /dest
└── index.html

各フォルダ/ファイルは以下のような用途で利用します。

srcフォルダ

実際に記述するソースファイルを格納しておいくフォルダ

src/app.js

Reactのコードを記述するファイル

app.jsには以下のコードを記述します。

import React from 'react';
import ReactDOM from 'react-dom';
  
ReactDOM.render(
  <h1>Hello, world!!</h1>,
  document.getElementById('app')
);

destフォルダ

JSXで書いたコードがJavaScriptに変換されて書き出されるフォルダ、ひとまずは空でも大丈夫。

index.html

確認用のHTMLファイル、以下のHTMLを記述します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>React Tutorial</title>
</head>
<body>
  <div id="app"></div>
  <script src="dest/app.js"></script>
</body>
</html>

webpackの設定

次にwebpack_sampleフォルダで以下のコマンドを打ってwebpackの設定を行います。

まず、以下のコマンドでpackage.jsonを作成します。

npm init -y

次にwebpackのインストールを行います。

npm install --save-dev webpack

次にwebpackでBabelを利用するためのツールとインストールします。

npm install --save-dev babel-loader babel-core 

次にBabelのpresetをインストールします。
今回はBableでJSXを変換するためのbabel-preset-reactとES2015+を変換するためのbabel-preset-envをインストールします。

npm install --save-dev babel-preset-react babel-preset-env

最後にreactreact-domのインストールを行います。
--save-devではなく--saveなので注意をしてください、ちなみにnpmのバージョンが5以上の場合は--saveは省略可能です。

npm install --save react react-dom

次にpackage.jsonを開き、以下のように"scripts"の箇所を変更し、"babel"を追加してください。

"scripts": {
  "build": "webpack -d",
  "start": "webpack -d -w",
  "release": "webpack -p"
},
"babel": {
  "presets": ["env","react"]
},

現在、package.jsonは以下のような状態のはずです。(nameが作業ディレクトリの名前)

{
  "name": "webpack_sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack -d",
    "start": "webpack -d -w",
    "release": "webpack -p"
  },
  "babel": {
    "presets": ["es2015","react"]
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "webpack": "^3.8.1"
  },
  "dependencies": {
    "react": "^16.0.0",
    "react-dom": "^16.0.0"
  }
}

次にpackage.jsonと同じ階層にwebpack.config.jsというファイルを作成し以下の内容を記述します。

const path = require('path');
	
module.exports = {
	entry: "./src/app.js",
	output: {
		path:path.resolve(__dirname, "dest"),
		filename: "app.js"
	},
	module: {
		loaders: [
			{
				test: /\.js$/,
				exclude: /node_modules/,
				loader: "babel-loader"
			}
		]
	}
};

こちらの内容を簡単に説明すると./src/app.jsの内容をbabel-loaderを利用して変換し./dest/app.jsに書き出すという設定が記述されています。

これで設定は完了です。
package.jsonに設定しておいたbuildコマンドを利用してちゃんとコンパイルできるか確認しましょう。

npm run build
<p>destディレクトリにapp.jsが書き出されて、index.htmlをブラウザで確認すると『Hello, world!!』と表示されれば成功です。</p>
<h3>webpackの利用</h3>
<p>webpackでちゃんとビルドできるのは確認できましたが、このままではコードを変更するたびにbuildコマンドを入力しなくてはいけません。</p>
<p>開発時はpackage.jsonに設定しておいたstartコマンドを利用することでwebpackがファイルの変更を監視しておき変更されるたびにコンパイルが実行されるようになります。</p>
<p>startコマンドは以下のように入力するか、</p>
npm run start

以下のように入力すれば実行できます。(startはrunの省略が許可されているコマンドのため)

npm start

ファイル分割

それでは、ファイル分割をしてみましょう。

コンポーネントの説明時に利用したコンポーネントの単位ごとにファイルを分割してみます。

app.js、MyComponent.js、MyH1.js、MyH2.jsを作成し、それぞれsrcディレクトリの直下に配置します。

app.js

import React from 'react';
import ReactDOM from 'react-dom';
import {MyComponent} from './MyComponent'
  
ReactDOM.render(
  <MyComponent />,
  document.getElementById('app')
);

MyComponent.js

import React from 'react';
import { MyH1 } from './MyH1'
import { MyH2 } from './MyH2' 
  
export function MyComponent() {
  return (
    <div>
      <myh1></myh1>
      <myh2></myh2>
    </div>
  )
};

MyH1.js

import React from 'react';
  
export function MyH1() {
  return (
    <h1>Hello, world!</h1>
  )
};

MyH2.js

import React from 'react';
  
export function MyH2() {
  return (
    <h2>texttext</h2>
  )
};

このようにファイルを分割で管理しておき必要なさいにimportで呼び出して利用することができます。

Reactを利用する場合は、ひとまずは1コンポーネント1ファイルになるような粒度にするように分割しておくとよいでしょう。

プロダクトビルド

書き出されたapp.jsはSourceMapファイルが付与されておりエラーの行数をコンパイル前のファイルの行数で教えてくれるなど便利なのですが、ファイルサイズが大きくなりこのままでは製品版には向きません。

本番公開用にはpackage.jsonに設定しておいたreleaseコマンドを利用します。

npm run release

このコマンドで生成されるdest/app.jsは無駄な処理やコードが取り除かれておりますので、こちらを製品版としてリリースしましょう。

これで、今回の「webpack と Babel」の解説は終了です。

次回はもっと簡単にReactの開発環境が可能な「CreateReactApp」について解説を行います。