1. Elm のインストール
elm はコマンドとしても使うので、グローバルにインストールする。また、自動でフォーマットを整形してくれる elm-format も一緒にインストールしておく。
yarn global add elm elm-format
elm-format はコマンドを直接起動するのではなく、エディタのプラグインとして実行する。 Visual Studio Code では、歯車マーク→設定→右上の「設定(JSON)を開く」で開く、settings.json に以下の記述を追加する。
// Elm "[elm]": { "editor.formatOnSave": true },
これにより、elm ファイルを保存すると自動的に elm-format が起動し、自動整形される。
2. elm 環境の構築
いきなり electron に行く前に、まず Elm 単体でのテストをしてみる。ただし、今後のことを考えて、webpack は導入したい。調べたら、elm-webpack-loader というものを見つけた。さらにQiita にこれを使った導入記事 webpackでElm + Sassな開発環境を作る〜ついでにHMR〜 - Qiita を見つけた。とりあえずこれと同じようにやってみて構成を確認してみる。
まず、テストするフォルダを作成し、そこに入る。
mkdir -p elm-webpack-test cd elm-webpack-test
まず、elm init
で Elm を初期化する。
hkob@hMBP ~/e/elm-webpack_test> elm init Hello! Elm projects always start with an elm.json file. I can create them! Now you may be wondering, what will be in this file? How do I add Elm files to my project? How do I see it in the browser? How will my code grow? Do I need more directories? What about tests? Etc. Check out <https://elm-lang.org/0.19.1/init> for all the answers! Knowing all that, would you like me to create an elm.json file now? [Y/n]: Okay, I created it. Now read that link!
各作業でどのファイルが書き変わるのかを確認できるように、git リポジトリにしてこまめにコミットしてみる。
git init
gibo dump Elm Node macOS VisualStudioCode Vim > .gitignore
とりあえずここまでをコミットしておく。
まず、このフォルダでyarn init
として yarn の初期化をする。
hkob@hMBP ~/e/elm-webpack_test (master)> yarn init yarn init v1.22.4 warning ../../package.json: No license field question name (elm-webpack_test): question version (1.0.0): question description: question entry point (index.js): question repository url: question author (Hiroyuki KOBAYASHI <メールアドレス>): question license (MIT): question private: success Saved package.json ✨ Done in 22.31s.
3. 各種ライブラリの構築
まず、webpack 関連のライブラリを devDevelopments にインストールする。
yarn add webpack webpack-cli webpack-dev-server -D
Qiita の参考サイトではエントリーポイントの Javascript に ES6 を使いたいとのことで、babel を入れていた。せっかくなので同じように入れてみる。
yarn add @babel/core @babel/preset-env babel-loader -D
babel の設定ファイルである.babelrc
を作成する。
touch .babelrc
中身は Qiita のサイトを参考に記述する。
{ "presets": [ "@babel/preset-env" ] }
次に SASS 関係のライブラリを導入する。
yarn add node-sass sass-loader css-loader style-loader -D
最後に elm を webpack で読み込むローダー(elm-webpack-loader)を導入する。また、HMR(ホットリロード)用には別にローダー(elm-hot-webpack-loader)があるようなので、こちらも導入する。
yarn add elm-webpack-loader elm-hot-webpack-loader -D
ここまでインストールしたら、package.json に scripts を追加しておく。最終的な package.json はこんな感じになった。この結果、yarn build でデプロイができ、yarn dev では webpack-dev-server が起動する。webpack-dev-server はファイル更新を監視し、開発ように webpack を自動実行してくれるサーバである。これを使って、HMR を実現する。
{ "name": "elm-webpack_test", "version": "1.0.0", "main": "index.js", "author": "Hiroyuki KOBAYASHI <hkob@metro-cit.ac.jp>", "license": "MIT", "scripts": { "build": "webpack --mode production", "dev": "webpack-dev-server" }, "devDependencies": { "@babel/core": "^7.9.6", "@babel/preset-env": "^7.9.6", "babel-loader": "^8.1.0", "css-loader": "^3.5.3", "elm-hot-webpack-loader": "^1.1.6", "elm-webpack-loader": "^6.0.1", "node-sass": "^4.14.1", "sass-loader": "^8.0.2", "style-loader": "^1.2.1", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.11.0" } }
4. webpack.config.js の記述
webpack.config.js については、Qiita に詳細な説明が書いてあるので省略する。最終的な webpack.config.js だけ掲載しておく。
const path = require('path'); const webpack = require('webpack'); module.exports = (env, argv) => { return { plugins: [ new webpack.HotModuleReplacementPlugin() ], entry: './src/index.js', output: { filename: 'main.js', path: path.resolve(__dirname), }, devServer: { hot: true, stats: 'errors-only', port: 3000, host: '0.0.0.0', historyApiFallback: { rewrites: [ { from: /.*/, to: '/' } ] } }, module: { rules: [ { test: /\.elm$/, exclude: [/elm-stuff/, /node_modules/], use: [ { loader: 'elm-hot-webpack-loader' }, { loader: 'elm-webpack-loader', options: { cwd: __dirname, optimize: (argv.mode == 'production') ? true : false, debug: (argv.mode == 'development') ? true : false } } ] }, { test: /\.s[ac]ss$/i, use: [ 'style-loader', 'css-loader', 'sass-loader', ], }, { test: /\.js$/, exclude: [/elm-stuff/, /node-modules/], loader: 'babel-loader' } ] } } }
5.エントリーポイントの javascript と index.html の作成
index.html
は以下の通りになる。main.js を script で body に描画しているだけである。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div id="elm"></div> <script src="/main.js"></script> </body> </html>
エントリーポイントの src/index.js
は以下のようになる。Main.elm を読み込み、html の elm id の部分で Elm.main.int を実行する。また、CSS として sass/main.sass も読み込んでいる。Qiita の記事では scss だったが、試しに sass にしてみた(少しぐらいはアレンジしたい)。
import { Elm } from './Main.elm' import './sass/main.sass' Elm.Main.init({ node: document.getElementById('elm') })
src/Main.elm
は Hello elm を描画するだけのものである。さすがに elm のシンタックスハイライトはないらしい。
module Main exposing (main) import Html exposing (..) import Html.Attributes exposing (..) main = div [ class "container" ] [ h1 [] [ text "hello elm!!" ] ]
最後に src/sass/main.sass
を記述する。フォルダがないので、先に作っておく。
mkdir -p src/sass
src/sass/main.sass
はこんな感じになる。scss と違って、yaml や haml っぽいので、Ruby 使いには、こっちの方が馴染みがある。
.container display: flex justify-content: center align-items: center h1 font-size: 48px color: #42ba09
6. 開発環境のテスト
package.json
に書いたように、yarn dev
で開発環境が立ち上がる。
hkob@hMBP ~/e/elm-webpack_test (master)> yarn dev yarn run v1.22.4 warning ../../package.json: No license field $ webpack-dev-server ℹ 「wds」: Project is running at http://0.0.0.0:3000/ ℹ 「wds」: webpack output is served from / ℹ 「wds」: Content not from webpack is served from /Users/hkob/elm/elm-webpack_test ℹ 「wds」: 404s will fallback to /index.html ℹ 「wdm」: Compiled successfully.
ブラウザで http://localhost:3000/ にアクセスすると、以下の画面が表示される。
ホットリロードの設定ができているので、Main.elm を書き換えたり、main.sass を書き換えりすると、ブラウザの読み込みをすることなく画面が書き変わる。
今回の Elm + Webpack のアプリを Electron に変えてみようと思う。そのために、前回の Electron + Webpack の結果を参考とする。とりあえずここまでを git にコミットしておく。