--- title: Docker+webpackを用いたReact.js開発環境の構築 tags: Docker docker-compose webpack React author: s0tter slide: false --- **2018-10-26追記** 本記事は2017-05-03に投稿したものです。 [Create React App](https://github.com/facebook/create-react-app)が出る前にwebpack環境構築しようと試行錯誤した記録なので、今となっては参考になる要素が少ないかもしれませんのでご留意ください。 --- React.jsの学習を行う環境をDockerで構築します。 - ホストPCでコーディングする - webpackがコードを監視し、babel-loaderでビルドする - ビルドしたバンドルデータをnginxが公開する ## 環境について | 環境 | バージョン | |:-------------------|:---------------------------------------------| | CentOS Atomic Host | CentOS Linux release 7.3.1611 | | Docker | Docker version 1.12.6, build 96d83a5/1.12.6 | | docker-compose | docker-compose version 1.11.2, build dfed245 | docker-composeはCentOS Atomic Hostに入っていません。以下のコマンドでインストールします。 ```shell-session $ curl -L https://github.com/docker/compose/releases/download/1.11.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose $ docker-compose --version docker-compose version 1.11.2, build dfed245 ``` ## ディレクトリ構成 作業ホームを`~/reactjs`として以下の構成をゴールとします。 ```text ~/reactjs |- app | |- dist | | |- bundle.js | | `- index.html | `- src | `- app.js |- docker-compose.yml |- nginx | |- Dockerfile | `- nginx.conf `- webpack |- Dockerfile `- webpack.config.js ``` ## ファイルの作成 ### webpackコンテナ #### webpack/webpack.config.js webpackの設定ファイルを作成します。 ```js:webpack.config.js const path = require('path'); module.exports = { entry: { bundle: './src/app.js' }, output: { path: path.join(__dirname, 'dist'), filename: '[name].js' }, module: { loaders: [ { loader: 'babel-loader', exclude: /node_modules/, test: /\.js[x]?$/, query: { cacheDirectory: true, presets: ['react', 'es2015'] } } ] } }; ``` webpackのコンテナを作成するDockerfileを定義します。 - Dockerイメージのベースを`node:7.9.0`とします。 - 作業ディレクトリを`/app`とします。 - ホストPCに配置した`webpack.config.js`をコンテナ側の作業ディレクトリ`/app`に配置します。 - npmを初期化し、webpackをはじめとする今回必要なパッケージをインストールします。 - コンテナが作られた際に`webpack -d --watch`を実行するように定義します。 #### webpack/Dockerfile ```dockerfile:Dockerfile FROM node:7.9.0 WORKDIR /app COPY ./webpack.config.js /app/webpack.config.js RUN npm init -y RUN npm install -g webpack RUN npm install --save react react-dom RUN npm install --save-dev babel-loader babel-core babel-preset-es2015 babel-preset-react CMD ["webpack", "-d", "--watch"] ``` #### app/src/app.js React.jsのコードです。id="app"のDOMエレメントに対して`

Hello, world!

`を設定します。 ```js:app.js import React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render(

Hello, world!

, document.getElementById('app') ); ``` #### app/dist/index.html ブラウザで表示されるHTMLファイルです。app.jsでid="app"に対してレンダリングを行うよう記述しましたので、divエレメントを定義します。また、バンドルデータとなるbuild.jsを読み込む記述をしています。 ```html:index.html Reactjs Tutorial
``` ### nginxコンテナ #### nginx/nginx.conf nginxの設定ファイルを作成します。 [PASTEBIN](https://pastebin.com/)のsample nginx.confを用います。 ```shell-session # curl -o nginx.conf https://pastebin.com/raw/7gbdCRDk ``` ダウンロードしたファイルの内容は以下のようになっています。 ```nginx:nginx.conf user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; server { listen 8080; root /wwwroot; } } ``` #### nginx/Dockerfile nginxのコンテナを作成するDockerfileを定義します。 - Dockerイメージのベースを`nginx:1.13.0`とします。 - nginx.confで定義されているドキュメントルート`/wwwroot`ディレクトリを作成します。 - ホストPCに配置した`nginx.conf`をコンテナ側の`/etc/nginx/nginx.conf`にコピーします。 - コマンド`service nginx start`を実行するようにします。 ```dockerfile:Dockerfile FROM nginx:1.13.0 RUN mkdir /wwwroot COPY ./nginx.conf /etc/nginx/nginx.conf RUN service nginx start ``` ### docker-compose webpack, nginxのDockerfileをdocker-composeでまとめます。 webpackコンテナのwebpack.config.jsで`/app/src/app.js`を監視し、バンドルを`/app/dist`に出力するように定義しましたので、`volumes`でホスト側の`app/src`と`app/dist`にマウントします。`src`は読み取り専用**ro**、`dist`はwebpackが書き出すので**z**オプションを付けています。 nginxコンテナではドキュメントルートを`/wwwroot`としており、webpackが生成するバンドルは`app/dist`へマウントしましたので、nginxコンテナでもマウントします。この時nginx側では読むだけですので**ro**オプションを付けています。また、nginxコンテナ側でnginxを8080ポートとして実行するように設定しました。ホスト側では80番ポートとなるようポートフォワード設定を行います。 > **Note** zオプションを付けることでボリュームラベルを付与することができます。ボリュームラベルを付与しないとSELinuxがファイル更新を妨ぎます。 詳しくは[Docker-docs-ja 1.9beta > コンテナでデータを管理する > データ・ボリューム > ボリューム・ラベル](http://docs.docker.jp/engine/userguide/dockervolumes.html#id6)をご参照ください。 ```yaml:docker-compose.yml version: '2' services: nginx: build: context: ./nginx image: reactjs_nginx container_name: reactjs_nginx_container ports: - "80:8080" volumes: - ./app/dist:/wwwroot:ro webpack: build: context: ./webpack image: reactjs_webpack container_name: reactjs_webpack_container volumes: - ./app/src:/app/src:ro - ./app/dist:/app/dist:z ``` ## Docker起動 docker-compose.ymlがあるディレクトリで以下のコマンドを実行します。 ```shell-session # docker-compose up -d ``` ブラウザから`http://<ホストPCのIP>/`でアクセスすると**Hello, world!**という文字列が表示されます。 以上でホストPCにあるapp/src/app.jsを編集していくことにより自動的にバンドルデータが生成されブラウザで確認することができます。 ## Conclusion React.jsの学習のみであれば[Codepen](https://codepen.io/)を用いるだけで充分ですし、Dockerを使うにしてもnodeをベースとしたコンテナにwebpack-dev-serverを用いる方法もあります。 今回は開発~本番環境のデプロイメントまでを学習するため、開発環境として利便性のあるwebpack-dev-serverの選択は控えました。 React.jsの学習を進めていき、より開発効率の良い構成を模索していきます。