LoginSignup
4
4

More than 5 years have passed since last update.

elm0.19 + webpack4 + babel7 のサンプルをdockerで試したメモ

Last updated at Posted at 2018-09-13

概要

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はリポジトリをクローンしたもの。

ファイル

docker/elm/Dockerfile
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
docker/docker-compose.yml
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環境向けに少し書き足す。

elm-webpack-starter/webpack.config.js
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の場合は不要かもしれない。
webpackwebpack-serveでは記述する場所が異なっているので注意。*1*2

watch:true, 
watchOptions:{
  aggregateTimeout: 300,
  poll:1000
}
bin/up.sh
#!/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ができていることを確認する。

この時点のソース

参考

github.com/simonh1000/elm-webpack-starter

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4