WebpackでReactを始める

2019-06-16

React(リアクト)を始めるためWebpack(ウェブパック)に関する設定をして、簡単なReact(リアクト)プロジェクトを生成してみます。

概要

会社でReact(リアクト)で新しいプロジェクトをするこのになりました。それで久しぶりにReact(リアクト)を最初から設定するチャンスが出ってその内容をまとめることにしました。このブログポストではReact(リアクト)でプロジェクトを始める時Webpack(ウェブパック)を設定する方法について説明します。

このブログで使ったソースコードはギットハブ(Github)で確認出来ます。

プロジェクト準備

下記のコマンドを使ってプロジェクトを準備します。

mkdir react_start
cd react_start
npm init -y

インストール

下記のコマンドでReact(リアクト)でプロジェクトを作る時、必要なライブラリをインストールします。

npm install --save react react-dom
npm install --save-dev webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader @babel/core @babel/preset-env @babel/preset-react rimraf

インストールしたものが結構あります。一つずつみてみましょう。

  • react, react-dom: React(リアクト)で開発する時必ず必要なライブラリです。
  • webpack: Webpack(ウェブパック)ライブラリです。
  • webpack-cli: Webpack(ウェブパック)をコマンドで操作するためのライブラリです。
  • html-webpack-plugin: Webpack(ウェブパック)でHTMLを扱うためのプラグインです。
  • webpack-dev-server: Webpack(ウェブパック)でローカルで開発するためのテストサーバーです。
  • babel-loader: Webpack(ウェブパック)でbabel(バベル)を扱うためのライブラリです。
  • @babel/core: babel(バベル)でコンパイルする予定です。
  • @babel/preset-env: babel(バベル)でコンパイルする時ターゲットを指定するためのライブラリです。
  • @babel/preset-react: React(リアクト)をbabel(バベル)でコンパイルするためのライブラリです。
  • rimraf: Macとウィンドウズで同じコマンドでフォルダを削除するためのライブラリです。

package.json設定

下記のようにWebpack(ウェブパック)を実行するためのスクリプトを追加します。

{
  "name": "react_start",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start": "webpack-dev-server --mode development",
    "prebuild": "rimraf dist",
    "build": "webpack --progress --mode production"
  },
  "author": "dev.yakuza@gmail.com",
  "dependencies": {
    "react": "16.8.6",
    "react-dom": "16.8.6"
  },
  "devDependencies": {
    "@babel/core": "7.4.5",
    "@babel/preset-env": "7.4.5",
    "@babel/preset-react": "7.0.0",
    "babel-loader": "8.0.6",
    "cross-env": "5.2.0",
    "html-webpack-plugin": "3.2.0",
    "rimraf": "2.6.3",
    "webpack": "4.33.0",
    "webpack-cli": "3.3.4",
    "webpack-dev-server": "3.7.1"
  }
}

スクリプトを一つ一つみてみます。

  • webpack-dev-server --mode development,: npm startやnpm run startで実行されるスクリプトです。Webpack(ウェブパック)の開発サーバーをdevelopmentモードで実行します。Webpack(ウェブパック)を実行する時は必ずモード(developmentproduction)を設定する必要があります。
  • "prebuild": "rimraf dist",: npm run buildでbuildスクリプトを実行するとbuildスクリプトが実行される前このスクリプトが実行されます。prepostでスクリプトが実行される前と後に実行したいスクリプトを実行することが出来ます。私はビルド後生成されるフォルダーを削除して再生成するため使ってます。
  • "build": "webpack --progress --mode production": npm run buildで実行されるスクリプトです。Webpack(ウェブパック)をproductionモードで実行してバンドリング(bundling)します。–progressはビルドする姿をモニタリングするためのオプションです。

Webpack設定

下記のようにReact(リアクト)でプロジェクトを進めるためWebpack(ウェブパック)をルートフォルダーのwebpack.config.js名前で生成します。

// react_start/webpack.config.js
const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    'js/app': ['./src/App.jsx'],
  },
  output: {
    path: path.resolve(__dirname, 'dist/'),
    publicPath: '/',
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: ['babel-loader'],
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
  ],
};

Webpack(ウェブパック)の設定を一つずつ見て見ましょう。

const path = require('path');

絶対パスを参照するためpathを読んできます。

const HtmlWebpackPlugin = require('html-webpack-plugin');

Webpack(ウェブパック)でHTMLを扱うためのプラグインを読んできます。

entry: {
    'js/app': ['./src/App.jsx'],
},

バンドルファイル(bundle)を作るため開始ファイル(entry)を設定します。生成されるバンドルファイル(bundle)はjsフォルダー下でapp.jsの名前で生成されます。このファイルは./src/App.jsxを元にしてバンドリング(一つのファイルで集める)します。

output: {
    path: path.resolve(__dirname, 'dist/'),
    publicPath: '/',
},

生成されるバンドルファイル(bundle)は./dist/フォルダに生成されます。publicPathを指定してHTMLなど他のファイルで生成されるバンドルを参照する時、/を基準にして参照します。(ex> <script type="text/javascript" src="/js/app.js"></script>)

module: {
  rules: [
    {
      test: /\.(js|jsx)$/,
      use: ['babel-loader'],
      exclude: /node_modules/,
    },
  ],
},

React(リアクト)ファイルであるjsxjsはbabel(バベル)を使ってビルドします。

plugins: [
  new HtmlWebpackPlugin({
    template: './src/index.html',
    filename: 'index.html',
  }),
],

最後に./src/index.htmlファイルをdistフォルダーにindex.htmlでファイルを生成します。ファイルを生成数時、Webpack(ウェブパック)が作ったバンドルファイル(/js/app.js)をHTMLに追加して生成します。

babel設定

babelを設定するため.babelrcを生成して下記のように修正します。

{
  "presets": [
    [
      "@babel/preset-env",
      { "targets": { "browsers": ["last 2 versions", ">= 5% in KR"] } }
    ],
    "@babel/react"
  ]
}

babel(バベル)でコンパイルする時、targetを指定します。ブラウザの上位バーゾン2つ(例: IE 11, 10)と韓国(KR)で5%以上のシェアを持ってるブラウザを対応してコンパイルするように設定しました。日本だったらJPを使って設定することができます。また "@babel/react"を使ってReact(リアクト)もコンパイルできるように設定しました。

HTML生成

React(リアクト)を使うHTMLファイルを./src/index.htmlに生成して下記のように修正します。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

私たちは<div id="app"></div>中にReact(リアクト)を追加する予定です。

React生成

最後にReact(リアクト)ファイルを作ります。./src/App.jsxを生成して下記のように修正します。

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  return <h1>Hello World!</h1>;
};
ReactDOM.render(<App />, document.getElementById('app'));

確認

下記のコマンドで私たちが生成して設定した内容がうまく動いてるか確認します。

npm start

そしてブラウザを開いてhttp://localhost:8080/に移動するとHello World!が見えることが確認できます。package.jsonのスクリプトである"start": "webpack-dev-server --mode development","start": "webpack-dev-server --mode development --open",ように--openのオプションを追加するとnpm startでWebpack(ウェブパック)の開発サーバーを実行すると自動的ブラウザが立ち上がってhttp://localhost:8080/に移動します。

実行された開発サーバーをストップして、下記のコマンドでビルドしてみましょう。

npm run build

問題なく実行されたら./dist/フォルダが生成されてその下にindex.html/js/app.jsが生成されることが確認できます。また、index.htmlを開いてみたら私たちが作ったindex.htmlと違って<script type="text/javascript" src="/js/app.js"></script>が追加されたことが確認できます。

Buy me a coffeeBuy me a coffee
Posts