概要
Elm0.18を使っていたが、作成されるソースが大きいと思っていたところ、elm0.19を勧めていただいたので勉強することにした。
手始めに、elm-webpack-starter : Elm 0.19 with Webpack 4, Hot Reloading & Babel 7のリポジトリをdockerで試せる環境を作成した。
2019/1/9 追記
webpack-serveが非推奨になり、webpack-dev-serverが再び推奨になったため、
webpack.config.jsを修正した記事を以下に追加した。
elm0.19 + webpack4 + webpack-dev-server のサンプルをdockerで試したメモ
開発環境
- Windows 10
- Vagrant 2.1.5
- Virtualbox 5.2.18
- Ubuntu 18.04 LTS (Bionic Beaver)
- Docker version 18.06.0-ce, build 0ffa825
- docker-compose version 1.22.0, build f46880fe
ディレクトリ構成
-
+ bin
- docker
- elm
- Dockerfile
- docker-compose.yml
+ elm-webpack-starter
※ elm-webpack-starterはリポジトリをクローンしたもの。
ファイル
FROM node:10.10.0
# コンテナ上の作業ディレクトリ作成
WORKDIR /app
# 後で確認出来るようにpackage.jsonを作成
RUN npm init -y
# dev-dependencies
## elmインストール
RUN yarn add --dev elm
RUN yarn add --dev elm-verify-examples
## sass
RUN yarn add --dev node-sass
## webpackインストール
RUN yarn add --dev webpack
RUN yarn add --dev webpack-cli
RUN yarn add --dev webpack-merge
RUN yarn add --dev webpack-serve
### 「History APIを利用して作成されるSPAのためのindexページをプロキシする」ミドルウェア
RUN yarn add --dev koa-connect-history-api-fallback
### plugins
RUN yarn add --dev html-webpack-plugin
RUN yarn add --dev mini-css-extract-plugin
RUN yarn add --dev clean-webpack-plugin
RUN yarn add --dev copy-webpack-plugin
## babelインストール
RUN yarn add --dev @babel/core
RUN yarn add --dev @babel/preset-env
RUN yarn add --dev babel-loader
### loaders
RUN yarn add --dev file-loader
RUN yarn add --dev url-loader
RUN yarn add --dev resolve-url-loader
RUN yarn add --dev css-loader
RUN yarn add --dev style-loader
RUN yarn add --dev sass-loader
RUN yarn add --dev elm-hot-webpack-loader
RUN yarn add --dev elm-webpack-loader
# dependencies
RUN yarn add purecss
# package.json
RUN sed -i -e "s/\(\"scripts\": {\)/\1\n \"prod\": \"webpack -p\"/g" /app/package.json
RUN sed -i -e "s/\(\"scripts\": {\)/\1\n \"build\": \"webpack\",/g" /app/package.json
RUN sed -i -e "s/\(\"scripts\": {\)/\1\n \"dev\": \"webpack-serve --port 3000\",/g" /app/package.json
RUN sed -i -e "s/\(\"scripts\": {\)/\1\n \"start\": \"npm run dev\",/g" /app/package.json
RUN sed -i -e "/test/d" /app/package.json
RUN sed -i -e "s/\(\"scripts\": {\)/\1\n \"test\": \"elm-test\",/g" /app/package.json
version: '3'
services:
elm:
build: ./elm
volumes:
- ../elm-webpack-starter/src:/app/src:z
- ../elm-webpack-starter/tests:/app/tests
- ../elm-webpack-starter/elm.json:/app/elm.json
- ../elm-webpack-starter/webpack.config.js:/app/webpack.config.js
- ../elm-webpack-starter/.babelrc:/app/.babelrc
ports:
- 3000:3000
- 3002:3002
environment:
- NODE_ENV=develop
command: [yarn, dev, --host, 0.0.0.0, --config, ./webpack.config.js ]
elm-webpack-starterのwebpack.config.js
をvagrant + docker環境向けに少し書き足す。
const path = require("path");
const webpack = require("webpack");
const merge = require("webpack-merge");
const history = require('koa-connect-history-api-fallback');
const CopyWebpackPlugin = require("copy-webpack-plugin");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
var MODE = process.env.npm_lifecycle_event === "prod" ? "production" : "development";
var filename = MODE == "production" ? "[name]-[hash].js" : "index.js";
var common = {
mode: MODE,
entry: "./src/index.js",
output: {
path: path.join(__dirname, "dist"),
publicPath: '/',
filename: filename
},
plugins: [
new HTMLWebpackPlugin({
template: "src/index.html",
inject: "body"
})
],
resolve: {
modules: [path.join(__dirname, "src"), "node_modules"],
extensions: [".js", ".elm", ".scss", ".png"]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.scss$/,
exclude: [/elm-stuff/, /node_modules/],
loaders: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.css$/,
exclude: [/elm-stuff/, /node_modules/],
loaders: ["style-loader", "css-loader"]
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
exclude: [/elm-stuff/, /node_modules/],
loader: "url-loader",
options: {
limit: 10000,
mimetype: "application/font-woff"
}
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
exclude: [/elm-stuff/, /node_modules/],
loader: "file-loader"
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "file-loader"
}
]
}
};
if (MODE === "development") {
console.log("Building for dev...");
module.exports = merge(common, {
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin()
],
module: {
rules: [
{
test: /\.elm$/,
exclude: [/elm-stuff/, /node_modules/],
use: [
{ loader: 'elm-hot-webpack-loader' },
{
loader: "elm-webpack-loader",
options: {
// add Elm's debug overlay to output
debug: true,
forceWatch: true
}
}
]
}
]
},
serve: {
inline: true,
stats: "errors-only",
content: [path.join(__dirname, "src/assets")],
add: (app, middleware, options) => {
app.use(history());
},
devMiddleware: {
watch:true,
watchOptions:{
aggregateTimeout: 300,
poll:1000
}
},
hotClient:{
host: {
client: '192.168.50.10',
server: '0.0.0.0',
},
port:{
server:3002,
client: 3002
}
},
},
watch:true,
watchOptions: {
ignored: /node_modules/,
aggregateTimeout: 300,
poll: 5000
},
});
}
以下の部分では、IPアドレス・ポートをdocker用に設定している。
hotClient:{
host: {
client: '192.168.50.10', // 仮想環境のIPアドレス
server: '0.0.0.0', // Dockerのコンテナ上で動かすのでワイルドカードIPアドレスを指定
},
// hot-reloadで使われるポートを固定
port:{
server:3002,
client: 3002
}
},
以下の部分では、ファイルの更新検知用のポーリングの設定をしている。
windowsでvirtual box ubuntuとdockerを組み合わせている場合、watch機能でファイル更新が検知されないため。
macを使っていたり、そもそもlinuxの場合は不要かもしれない。
webpack
とwebpack-serve
では記述する場所が異なっているので注意。*1*2
watch:true,
watchOptions:{
aggregateTimeout: 300,
poll:1000
}
#!/bin/bash
bin_dir=$(cd $(dirname $0) && pwd)
composeFile=${1:-"docker-compose.yml"}
cd $bin_dir/../docker && docker-compose -f $composeFile up
実行
仮想環境にログインし、以下を実行する。
clone https://github.com/simonh1000/elm-webpack-starter.git --depth 1
./bin/up.sh
http://192.168.50.10:3000 (仮想環境のIP:今回設定したポート)にアクセスし、hot loadができていることを確認する。