React+webpackでHello Worldを表示するまで

最低限必要なものを準備して、「Hello World」を表示するまでのざっくりとした流れです。
毎度調べるのが面倒なのでまとめました。

#環境
Node.js 12.16.1
npm 6.14.6

#下準備
ディレクトリを作成し移動します。
移動したら```npm init```しておきます。

```shell

mkdir project-name
cd project-name
```

#インストール
必要なものをインストールしていきます。
webpackとreactだけでも動きますが、ES6で書きたいのでbabelも入れます。
ついでにsassも入れておきます。

```shell

# webpack
npm install --save-dev webpack webpack-cli webpack-dev-server clean-webpack-plugin html-webpack-plugin

# react
npm install --save-dev react react-dom

# babel
npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/register

# sass
npm install --save-dev node-sass css-loader sass-loader style-loader

```
#babelの設定

.babelrc というファイルを作成し、以下を記述します。
これでreactのコード内でES6の構文や機能を使えるようになります。

```json:.babelrc
{
  "presets": [
    "@babel/preset-env", "@babel/preset-react"
  ]
}
```

#webpackの設定
webpack.config.js を作成し、以下を記述します。
後述しますが、srcディレクトリの中にテンプレート用のファイルを作成し、そのパスをHtmlWebpackPluginに指定しています。

```javascript:webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: __dirname + '/src/index.jsx',
  plugins: [
    new CleanWebpackPlugin({
      cleanAfterEveryBuildPatterns:['build']
    }),
    new HtmlWebpackPlugin({
      template: 'src/templates/index.html'
    }),
  ],
  output: {
    path: __dirname + '/build',
    filename: '[name].[contenthash].js'
  },
  resolve: {
    extensions: ['.js', '.jsx']
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.(sa|sc|c)ss$/,
        exclude: /node_modules/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: { url: false }
          },
          'sass-loader'
        ]
      }
    ]
  }
}
```
#package.jsonの設定
webpackを使用する設定を追記します。
```npm start```でwebサーバーを起動、```npm run-script build```でビルドできるようになります。

```json:package.json
{
  "name": "project-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.jsx",
  "scripts": {
    // ここを編集
    "clean": "rm -rf ./node_modules package-lock.json && npm i",
    "build": "webpack -p",
    "start": "webpack-dev-server -d --content-base ./public"
  }
  ...
}
```

#Hello Worldを表示
表示用のテンプレートを作成します。

```html:src/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
```

reactで文字を表示。

```javascript:src/index.jsx
import React from "react"
import ReactDOM from "react-dom"

ReactDOM.render(
  <h1>Hello World!</h1>,
  document.getElementById("root")
)
```

```npm start```でサーバーを起動して、http://localhost:8080 にアクセスします。
「Hello World!」と表示されれば完了です。

#最終的な構成
src/components内にコンポーネントを追加して、index.jsxでインポートして使います。

```
├─ node-modules
├─ public // テンプレート用の画像など
├─ src
│   ├─ components // 作成したコンポーネントを保存
│   ├─ templates
│   │   └─ index.html
│   └─ index.jsx
├─ .babelrc
├─ package.json
├─ package-lock.json
└─ webpack.config.js
```

#おまけ
##共通の定数を設定する
使い回したい定数をまとめて別ファイルに書いて、必要な時に取り出します。

```javascript:constants.js
export const MINYEAR = 1970
export const MAXYEAR = 2021
```

```javascript:index.jsx
import * as CONST from "./constants"

console.log(CONST.MINYEAR) // 1970
```

#参考
参考にさせていただきました。ありがとうございます。

[Babelとwebpackを使ってES6でReactを動かすまでのチュートリアル](https://qiita.com/akirakudo/items/77c3cd49e2bf39da79dd)
[webpackとBabelの基本を理解する(4) ―React編―](https://qiita.com/koedamon/items/8fb75a7c001da40c7bea)