JavaScript
Node.js
webpack
React
babel

React 環境設定(ほぼwebpackの設定)[React 16, Webpack4, babel]

普段はReactNativeやRailsのコードを書いていますが、サーバーサイドのNodeは扱っていないため、勉強のため構築した環境のメモを記載しておきます。
主にwebpackの設定を中心に、調べた限り書いていきます。また、今回のは最低限の設定です。HMRの設定やLintの設定などはありませんのでご了承ください。その辺りはまたの機会で記事にしようと思います。

環境

nodeのバージョンは以下の通り。

$ node -v
8.11.2
$ yarn -v
1.7.0

作業フォルダの作成

$ mkdir project-dir
$ cd project-dir
$ yarn init

これで作業フォルダとその直下にpackage.jsonが作成されます。

パッケージインストール

$ yarn add --dev babel-core babel-loader 
$ yarn add --dev webpack webpack-cli
$ yarn add --dev react react-dom
$ yarn add --dev babel-plugin-transform-react-jsx babel-preset-env babel-preset-react

各パッケージのバージョンは次のようになりました。

package.json
{
  ...

  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-plugin-transform-react-jsx": "^6.24.1",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "react": "^16.4.0",
    "react-dom": "^16.4.0",
    "webpack": "^4.10.2",
    "webpack-cli": "^3.0.1"
  }
}

動作確認用ファイルの作成

動作確認用にファイル作っていきます。ファイル構成は以下の通り。

/----- index.html
  |--- index.js
  |--- App.js
  |--- package.json
  |--- webpack.config.js
  |--- yarn.lock
  -- dist
       |-- ...

まずは元となるindex.htmlを作業フォルダ直下に作成します。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div id="root"></div>
    <script type="text/javascript" src="./dist/bundle.js"></script>
  </body>
</html>

webpackでビルドされたファイルを./dist/bundle.jsに出力するので、そのJSファイルを読み込んでいます。

次にindex.jsと「Hello, world!」を表示するReactコンポーネントを作成します。

index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
App.js
import React from 'react'

export default class App extends React.Component {
  render () {
    return <h1>Hello, world!</h1>
  }
}

Webpackの設定

webpack.config.jsを作成し、Webpackの設定をしていきます。

webbpack.config.js
module.exports = {
  devtool: 'inline-source-map',
  mode: 'development',
  entry: './index.js',
  output: {
    filename: 'bundle.js',
  },
  module: {
    rules: [{
      test: /\.js?$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['env', 'react'],
        },
      },
    }]
  }
}

package.jsonにスクリプトを用意しておきます。これでyarn webpackをターミナルから、たたけばビルドが行われます。

package.json

{
  ...
  "license": "MIT",
  "scripts": {
    "webpack": "webpack --mode development"
  },
  "devDependencies": {
    ...
  }
}

次を実行し、index.htmlをブラウザから開くと「Hello, world!」が表示されていれば成功です。

$ yarn webpack

Webpackの設定について

それでは、webpack.config.jsの各プロパティの説明をしていきます。

mode

ビルド時に指定した環境にあった最適化が行われます。

modeオプションを設定せずに、以下のようにコマンドラインからの指定もできます。

$ webpack --mode=production

設定値はdevelopment,production,noneの3つです。設定した場合の機能は次の内容になります。有効となるプラグインですが、まだ殆ど調べていないので名前だけ列挙しておきます。

  • development
    • process.env.NODE_ENVの値がdevelopmentになる
    • 以下が有効になる
      • NamedChunksPlugin
      • NamedModulesPlugin : HMR時に、モジュールを相対パスで参照できる
  • production
    • process.env.NODE_ENVの値がproductionになる
    • 以下が有効になる
      • FlagDependencyUsagePlugin
      • FlagIncludedChunksPlugin
      • ModuleConcatenationPlugin
      • NoEmitOnErrorsPlugin
      • OccurrenceOrderPlugin
      • SideEffectsFlagPlugin
      • UglifyJsPlugin

entry

ビルドの起点となる箇所の設定ができます。関連のモジュールやライブラリとの依存関係を判別するため必要となるそうです。設定しない場合は、./srv/index.jsが設定値となります。

書き方は次の形式になります。

const config = {
  entry: './path/entry-file.js'
};

この書き方は以下の簡略です。

const config = {
    entry: {
    main: './path/entry-file.js'
  }
};

key: valueの形式で設定でき、複数指定してページ毎やモジュール単位などで依存関係を分けることもできます。

output

ビルドしたファイルの配置先を設定できます。設定しない場合は./dist/main.jsになります。

以下の2つを設定できます。

  • filename : 出力ファイルの名前。
  • path : 出力するディレクトリの絶対パス。__dirname + /distみたいに設定。

module

Loaderなどのモジュールを設定できます。rulesの中にLoaderの設定を用意する形になります。
今回は、babel-loaderを利用するため設定しています。

Ruleの設定は次の通りです。

  • test : 変換する対象ファイルを正規表現で設定できる。
  • exclude : 変換対象の除外とするファイルを文字列で設定できる。
  • use : 利用するLoaderやその詳細を設定できる。
    • loader : Loaderのモジュール名。
    • options : Loaderのオプション設定。今回は、babel-preset-env(ES6記法)、babel-preset-react(Reactの記法)を利用する設定をしています。

devtool

source mapの生成を設定できます。source mapを使用するとデバッグが楽になります。

  • inline-source-map : data URLでsource mapをまとめます。

source mapを設定しないままビルドして、ブラウザの開発ツールでコードを確認してみると、

Screen Shot 2018-06-10 at 23.31.09.png

のようになって、元のコードから変わってしまっています。

次に、devtool: 'inline-source-map'を設定してビルドしてみると、dist配下にbundle.js.mapが作成されている。先程と同じ様に開発ツールから確認してみると、

Screen Shot 2018-06-10 at 23.32.33.png

このように、元のコードのままになっているので、デバッグでの確認がしやすくなります。

参考文献