2018-10-26追記
本記事は2017-05-03に投稿したものです。
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に入っていません。以下のコマンドでインストールします。
$ 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
として以下の構成をゴールとします。
~/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の設定ファイルを作成します。
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
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エレメントに対して<h1>Hello, world!</h1>
を設定します。
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('app')
);
app/dist/index.html
ブラウザで表示されるHTMLファイルです。app.jsでid="app"に対してレンダリングを行うよう記述しましたので、divエレメントを定義します。また、バンドルデータとなるbuild.jsを読み込む記述をしています。
<!DOCTYPE html>
<html lang="ja">
<meta charset="UTF-8">
<title>Reactjs Tutorial</title>
<head>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
nginxコンテナ
nginx/nginx.conf
nginxの設定ファイルを作成します。
PASTEBINのsample nginx.confを用います。
# curl -o nginx.conf https://pastebin.com/raw/7gbdCRDk
ダウンロードしたファイルの内容は以下のようになっています。
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
を実行するようにします。
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 > コンテナでデータを管理する > データ・ボリューム > ボリューム・ラベルをご参照ください。
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があるディレクトリで以下のコマンドを実行します。
# docker-compose up -d
ブラウザからhttp://<ホストPCのIP>/
でアクセスすると**Hello, world!**という文字列が表示されます。
以上でホストPCにあるapp/src/app.jsを編集していくことにより自動的にバンドルデータが生成されブラウザで確認することができます。
Conclusion
React.jsの学習のみであればCodepenを用いるだけで充分ですし、Dockerを使うにしてもnodeをベースとしたコンテナにwebpack-dev-serverを用いる方法もあります。
今回は開発~本番環境のデプロイメントまでを学習するため、開発環境として利便性のあるwebpack-dev-serverの選択は控えました。
React.jsの学習を進めていき、より開発効率の良い構成を模索していきます。