elmで作った静的サイトをgithub pagesで公開してみた

最近ブログ書くのをサボっていたのでなにか書こうと思い、そうだ最近触っているElmについて書こう!と思い書きました。時間がかなり遡るのですが年末年始は実家に帰省していて、その際にElmを試しに触っていて簡単なサイトを作ってGithub Pagesで公開したので、その手順を書き残しておきます。

Elmとは

 ちょっと触っただけなので詳しくは説明できないのですが公式から抜粋すると以下の特徴があります。
- 実行時の例外が一切起きない
- virtual DOMを使用するがすべての値はイミュータブルなのでベンチマークがすごくいい
- セマンティックバージョンを強制できる
などの特徴があります。

完成品

Elmで書いて動いたものは下のサイトになります

https://jon20.github.io/mypage/

Githubは下になります

github.com

最終的にディレクトリは以下になりました。

.
├── README.md
├── elm-stuff
├── elm.json
├── package.json
├── src
│   ├── Main.elm
│   ├── assets
│   │   └── flog.jpg
│   ├── index.html
│   ├── index.js
│   └── main.scss
├── webpack.config.js
└── yarn.lock

Elmの準備

Elmのインストールに関しては割愛させていただきます。 Elmのインストールができたら対象のディレクトリでelm initを行ってください。
src配下にElmのファイルを書いていく形になります。 特にElmで書いたものが手元になければElm-lang.orgのQuick Sampleにあるカウンターアプリがあります。コードは下のIntroductionにかかれています。

guide.elm-lang.org

Htmlファイル

Javascript Interopに書かれているようなやり方になります。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="./assets/flog.jpg">
    <title>jon</title>
</head>
<body>
    <div id="elm"></div>
</body>
</html>

Javascriptファイル

汚いですが、idがelmの要素にelmを紐付ける形になります。

'use strict';
require('./main.scss');
import Image from './assets/flog.jpg'
const {
    Elm
} = require("./Main.elm")

const app = Elm.Main.init({
    node: document.getElementById('elm')
});

Webpackの使用

あんまりwebpack詳しくないのですが、色々参考にしながら作成しました。 必須になるプラグイン

だと思います... 画像とか扱う場合はfile-loaderが必要になると思います。
必要ない場合はfile-loaderらへんはコメントアウトしてください

const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  entry: './src/index.js',

  output: {
    path: __dirname + '/dist',
    filename: 'index.js'
  },

  resolve: {
    extensions: ['.js', '.elm', '.scss']
  },

  module: {
    rules: [{
        test: /\.html$/,
        exclude: /node_modules/,
        use: [{
          loader: 'html-loader',
        }, ]
      },
      {
        test: /\.(jpg|png)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'assets/',
          }
        }
      },
      {
        test: /\.elm$/,
        exclude: [/elm-stuff/, /node_modules/],
        use: {
          loader: 'elm-webpack-loader',
          options: {
            verbose: true,
          }
        }
      },
      {
        test: /\.scss$/,
        use: [{
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              url: true
            }
          },
          {
            loader: 'sass-loader',
          }

        ],

      }
    ],

    noParse: /\.elm$/
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html"
    })
  ],

  devServer: {
    inline: true,
    stats: 'errors-only'
  }
};

CIでビルド・公開周りを自動化

今回はTravis-CIを使いました。 masterにpushされたらyarn install走らせて、gh-pages branchにpushする形となっています。
yarn buildはpackage.jsonで定義されたスクリプトが走っています。

language: node_js
elm:
  - elm0.19.0
node_js:
  - "10"

cache:
  yarn: true
  directories:
    - "node_modules"

branches:
  only:
    - master

install:
  - yarn install
  - yarn build

script:
  - echo "Skipping tests"

deploy:
  provider: pages
  skip-cleanup: true
  github-token: $GITHUB_ACCESS_TOKEN
  target-branch: gh-pages
  local-dir: dist
  on:
    branch: master

まとめ

超ざっくりですがElmをgithub pagesで公開する手順を書きました。簡単にElmで作ったプロダクトがノーコストで公開できるので便利ですね。
WebpackらへんやCIらへんも一緒に試せるのでぜひ挑戦してみてください。
Quick Sampleをgithub pagesで公開するだけなら余分な所が多いので余力があったらサンプルを追加します...
あと、今回作ったものを読み込むときに一瞬ちらつくのですが読み込み順の問題なのかな...