Phoenix 1.4rcを試す④ webpack編

[fukuoka.ex](https://fukuokaex.connpass.com/)代表のpiacereです
ご覧いただいて、ありがとうございます:bow:

革新的なアップデートてんこ盛りのPhoenix 1.4.0-rc.xを数回に分けて試す連載です

前回までの記事は、以下になります
　|> [<b>Phoenix 1.4rcを試す① アップデート紹介編</b>](https://qiita.com/piacere_ex/items/34a56a418a99701a0ac1)
　|> [<b>Phoenix 1.4rcを試す② インストール編（不具合時の復旧もあるよ）</b>](https://qiita.com/piacere_ex/items/f4fb3fecb359e798ef01)
　|> [<b>Phoenix 1.4rcを試す③ ローカルSSL開発編（Gigalixirのオマケ付）</b>](https://qiita.com/piacere_ex/items/28f2f655241d142980d8)

今回は、Phoenix 1.4.0の新機能である「webpack」を、Phoenix 1.4.0-rc.1にて試していきます（が、けっこうサッパリと終わります）

なお、Phoenixは、ElixirのWebフレームワークです

内容が、面白かったり、気に入ったら、「いいね」よろしくお願いします :wink:

<br>:stars::stars::stars:<b>　お知らせ：Elixir MeetUpを来週末10/26（金）に開催します（リモート視聴も）　</b>:stars::stars::stars:

[<b>「fukuoka.ex#16：蔵出し始めました！Elixir実践テクニック公開します① 」</b>](https://fukuokaex.connpass.com/event/105154/)を10/26（金）19時に開催します

今回のMeetUpから、「座談会＋モブプログラミング」という形で、fukuoka.exアドバイザーズ／キャストが、過去会で登壇したり、日頃研鑽している数々のElixir実践テクニックをダイレクトに伝えていきます

今回は、「Elixir＋Vue.jsで2倍速開発」と「ElixirでElixirコンパイラ開発」の2トラックにて、集まった皆さまと一緒にElixir実践テクニックをシェアしたいと思います

https://fukuokaex.connpass.com/event/105154
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/155423/98aabdbd-8cd7-426b-0062-05d5863ce3b8.png)](https://fukuokaex.connpass.com/event/105154)

私は、「Elixir＋Vue.jsで2倍速開発」のパーソナリティを担当しますが、これは人気連載である、[「Excelから関数型言語マスター」シリーズ](https://qiita.com/piacere_ex/items/6714e1440e3f25fb46a1)の続編でもあります

一応、リモート視聴にも対応していますが、福岡近辺にお住まいの方であれば、遊びに来ていただいて、参加型コンテンツを120%楽しんでいただくのが絶対オススメです

# webpackは標準でPhoenix PJに装備される

Phoenix 1.4から、フロントビルドツールが、これまでの「Brunch」から「webpack」に変更されます

[Phoenix 1.4rcを試す② インストール編](https://qiita.com/piacere_ex/items/f4fb3fecb359e798ef01)の際は、webpack無でPJ作成していたので、以下のように、webpack無を指定せず、作成してみます

```
mix phx.new phx14_webpack --no-ecto
…（ファイル作成ログが続く）…
Fetch and install dependencies? [Yn] （←Y、Enterを入力）
…（mix deps.getの実行と、この後のコマンド指示が続く）…
cd phx14_webpack
```

「assets」フォルダができており、その配下には、以下のようなwebpack用ファイルができています

```assets/webpack.config.js
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = (env, options) => ({
  optimization: {
    minimizer: [
      new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
      new OptimizeCSSAssetsPlugin({})
    ]
  },
  entry: {
      './js/app.js': ['./js/app.js'].concat(glob.sync('./vendor/**/*.js'))
  },
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, '../priv/static/js')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({ filename: '../css/app.css' }),
    new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
  ]
});
```

エントリーポイントは、同フォルダ内の「js/app.js」で、出力先は、1つ下の「../priv/static/js」と、いつものPhoenixにおけるJSフォルダ内にビルド結果が吐き出されます

なお、PhoenixのLiveReloadと連動しているので、PJ配下でファイル更新をすると、Phoenixビルドと同時に、webpackビルドも走ります

デフォルトのapp.jsの中身は、特に何も入っていません

```assets/js/app.js
// We need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into
// its own CSS file.
import css from "../css/app.css"

// webpack automatically bundles all modules in your
// entry points. Those entry points can be configured
// in "webpack.config.js".
//
// Import dependencies
//
import "phoenix_html"

// Import local files
//
// Local files can be imported directly using relative paths, for example:
// import socket from "./socket"
```

package.jsonも、以下の通り、普通にあります

```assets/package.json
{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "webpack --mode production",
    "watch": "webpack --mode development --watch"
  },
  "dependencies": {
    "phoenix": "file:../deps/phoenix",
    "phoenix_html": "file:../deps/phoenix_html"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "babel-loader": "^8.0.0",
    "copy-webpack-plugin": "^4.5.0",
    "css-loader": "^0.28.10",
    "mini-css-extract-plugin": "^0.4.0",
    "optimize-css-assets-webpack-plugin": "^4.0.0",
    "uglifyjs-webpack-plugin": "^1.2.4",
    "webpack": "4.4.0",
    "webpack-cli": "^2.0.10"
  }
}
```

webpack 4系が入っているようです

# <strike>Windowsだと動かない？…</strike>

<strike>どうやらWindowsだと、Phoenix起動時に以下のエラーが出て、止まってしまうようです</strike>

```
iex -S mix phx.server
[warn] Phoenix is unable to create symlinks. Phoenix' code reloader will run considerably faster if symlinks are allowed. On Windows, the lack of symlinks may even cause empty assets to be served. Luckily, you can address this issue by starting your Windows terminal at least once with "Run as Administrator" and then running your Phoenix application.
[info] Application phx14_webpack exited: Phx14Webpack.Application.start(:normal, []) returned an error: shutdown: failed to start child: Phx14WebpackWeb.Endpoint
    ** (EXIT) an exception was raised:
        ** (UndefinedFunctionError) function Plug.Cowboy.child_spec/1 is undefined (module Plug.Cowboy is not available)
…
```

<strike>シンボリックリンクが作れなくて落ちており、Administratorでrunasしてから起動すると直る、と書いているようですが、Winodws固有の問題っぽいので、深追いせず、放置することとします</strike>

【2018/10/22追記】

調べてみたら、plug_cowboyがロードされていないために、Phoenix起動が止まっていたようです

mix.exsのdepsに、以下を追加してください

mix.exsの「def deps do」配下に追記します（:phoenix～の記載の上行に追加）

```elixir:mix.exs
defmodule Phx14Webpack.Mixfile do
  use Mix.Project
…
  defp deps do
    [
      { :plug_cowboy, "~> 2.0" }, 
      …
```

ライブラリを取得します（要ネット接続）

```
mix deps.get
```

Phoenixを起動します

```
iex -S mix phx.server
```

下記ログのように、エラーは出ず、Phoenixは起動し、webpackによるビルドも走っていることが確認できます

```
[warn] Phoenix is unable to create symlinks. Phoenix' code reloader will run considerably faster if symlinks are allowed. On Windows, the lack of symlinks may even cause empty assets to be served. Luckily, you can address this issue by starting your Windows terminal at least once with "Run as Administrator" and then running your Phoenix application.
[info] Running Phx14WebpackWeb.Endpoint with cowboy 2.5.0 at http://localhost:4000
Interactive Elixir (1.7.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
Webpack is watching the files

iex(1)> Hash: b9641d0ecef2b0845a5b
Version: webpack 4.4.0
Time: 17309ms
Built at: 2018-10-22 03:54:53
                Asset       Size       Chunks             Chunk Names
       ../css/app.css   10.6 KiB  ./js/app.js  [emitted]  ./js/app.js
               app.js   7.23 KiB  ./js/app.js  [emitted]  ./js/app.js
       ../favicon.ico   1.23 KiB               [emitted]
../images/phoenix.png   13.6 KiB               [emitted]
        ../robots.txt  202 bytes               [emitted]
[../deps/phoenix_html/priv/static/phoenix_html.js] 2.17 KiB {./js/app.js} [built]
[./css/app.css] 39 bytes {./js/app.js} [built]
[./js/app.js] 493 bytes {./js/app.js} [built]
   [0] multi ./js/app.js 28 bytes {./js/app.js} [built]
    + 2 hidden modules
Child mini-css-extract-plugin node_modules/css-loader/index.js!css/app.css:
    [./node_modules/css-loader/index.js!./css/app.css] ./node_modules/css-loader!./css/app.css 288 bytes {mini-css-extract-plugin} [built]
    [./node_modules/css-loader/index.js!./css/phoenix.css] ./node_modules/css-loader!./css/phoenix.css 10.9 KiB {mini-css-extract-plugin} [built]
        + 1 hidden module
```

# 終わり

今回は、Phoenix 1.4.0の新機能である「webpack」について解説しました

次回も引き続き、Phoenix 1.4.0-rcの動作確認を順々に試していきます

# p.s.「いいね」よろしくお願いします

よろしければ、ページ左上の ![image.png](https://qiita-image-store.s3.amazonaws.com/0/155423/4d515047-cc48-382e-c2b1-3ad0cc50dbbf.png) や ![image.png](https://qiita-image-store.s3.amazonaws.com/0/155423/a4e3da58-70a3-4197-95a2-6a6906650d01.png) のクリックをお願いしますー:bow: