Dockerを使ったReact + Webpack + Babel の環境構築

JSXを使うために `React` + `Webpack` +  `Babel` 環境をDockerとdocker-composeを使って構築しました🐳`create-react-app`は使っていません。

*随時情報を更新する予定です。現在は細かいオプションなどについては説明していません。

<br>

#### 前提

Docker & docker-composeをインストール済み


#### 動作環境

- macOS Catalina 10.15.7
- Docker 20.10.2
- docker-compose 1.27.4

#### ディレクトリ構成

最終的には以下のような形になります。

```
react_webpack_babel
  ├── dist
  │   ├── bundle.js
  │   └── index.html
  ├── src
  │   └── index.jsx
  ├── node_modules
  ├── package.json
  ├── package-lock.json
  ├── webpack.config.js
  ├── Dockerfile
  └── docker-compose.yml
```

<br>

それではディレクトリを作成します。

```
mkdir react_webpack_babel
cd react_webpack_babel
```

<br>

`package.json`を作成し、`scripts`以下に`"dev": "webpack serve --host 0.0.0.0"`を追記します。

```
npm init -y
```

```json:package.json
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack serve --host 0.0.0.0"
}
```

<br>

必要なmoduleをインストールします。

```
npm i react react-dom
```

```
npm i -D webpack webpack-cli webpack-dev-server @babel/core @babel/preset-env @babel/preset-react babel-loader
```

`package.json`はこのような感じになるはずです。

```json:package.json
{
  "dependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  },
  "devDependencies": {
    "@babel/core": "^7.13.10",
    "@babel/preset-env": "^7.13.10",
    "@babel/preset-react": "^7.12.13",
    "babel-loader": "^8.2.2",
    "webpack": "^5.26.3",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  }
}
```

もし各moduleのバージョンが違っていて動作しない場合は、手動で上記のバージョンに書き直した後に`npm i`を実行してください。moduleの依存関係については割愛します🐞


<br>

`webpack.config.js`を作成します。

```javascript:webpack.config.js
const path = require("path");

module.exports = {
    mode: 'development',
    entry: path.resolve(__dirname, "src/index.jsx"),
    output: {
      filename: 'bundle.js',
      path: path.join(__dirname, "dist")
    },
    devServer: {
        compress: true,
        contentBase: path.join(__dirname, "dist"),
        watchContentBase: true,
        hot: true,
        port: 8080,
    },
    module: {
      rules: [{
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              "@babel/preset-env",
              "@babel/react"
            ]
          }
        }
      }]
    },
    target: ["web", "es5"],
    devtool: 'inline-source-map',
    resolve: {
      extensions: ['.js', '.jsx']
    }
};
```

<br>

ディレクトリと各ファイルを作成します。

```
mkdir src dist
```

```jsx:/src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello, React!</h1>,
  document.getElementById('root')
);
```

```html:/dist/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>React + Webpack + Babel</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>
```

<br>

`Dockerfile` `docker-compose.yml`を作成します。

```dockerfile:Dockerfile
FROM node:14.5.0-alpine
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
EXPOSE 8080
```

```yml:docker-compose.yml
version: '3'
services:  
  front:
    build: .
    ports: 
      - '8000:8080'
    volumes: 
      - .:/usr/src/app
    command: ['npm', 'run', 'dev']
```

<br>

docker-composeを使ってコンテナを起動します。

```
docker-compose up
```

<br>

`localhost:8000`にアクセスし、以下が表示されれば成功です。

![スクリーンショット 2021-03-18 1.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1016415/21767b77-f142-6121-0730-3492fe3a34f4.png)

<br>

読んでいただきありがとうございました！ご指摘やご意見などありましたらコメントしていただけると嬉しいです🐳