さくらちゃんが使ってるElmアプリの環境構築方法

バーチャルヤギチューバーのさくらちゃんだよぉ ぶめぇええええ🐐🐐🐐🐐

![header](https://pbs.twimg.com/media/DvQAen_U0AAPls3?format=jpg&name=medium)

Elmでアプリを作るときって、CSSを入れようと思ったら elm reactor だけじゃ足りなくなって急にめんどくさくなりますよね。

はい、ということでですね、今日はさくらちゃんがふだん使っている、Elmアプリの環境構築方法について紹介していければと、はい思います。ぶめぇええええ🐐🐐🐐🐐

そうは言ってもですね、やることはですね、とても簡単ですね。
[elm-app-template](https://github.com/arowM/elm-app-template)っていうリポジトリをクローンしてちょちょいって感じですね。
さくらちゃんは優秀なので( ･ิω･ิ)

```bash
$ git clone https://github.com/arowM/elm-app-template.git
$ npm i
$ npm start
```

はい、以上です！ ってそんなわけあるか〜い。なんつってね ^\_^

## 要素技術

ここからは elm-app-template が採用している要素技術を簡単にご案内いたします。

* Elmコンパイラーのローカルインストール
* parcel
* [elm-mixin](https://package.elm-lang.org/packages/arowM/elm-mixin/latest/)
* CSS modules
* その他 PostCSS
* elm-analyse, elm-format

## Elmコンパイラーのローカルインストール

elm-app-template は、Elmコンパイラーをローカルインストールしています。
ここでいうローカルインストールとは、プロジェクトのディレクトリごとに独立してElmコンパイラーをインストールすることを意味します。

* メリット: 同じマシン内で、プロジェクトごとに別のバージョンのElmコンパイラーを気軽に使える
* メリット: 厳密にElmコンパイラーのバージョンを指定できるので別のチームメンバーがバージョン違いでごたごたすることがない
* デメリット: プロジェクトごとに最初にインストールする時間がかかる
    * 1分かからないくらいだけどね
    * npmの `package.json` の依存に入れてあるので、ふつうに他のパッケージと一緒に `npm i` を実行するだけだしね
* デメリット: プロジェクトの数ぶん容量を食う
    * それが問題になるような原始的なパソコン使ってる人いないよね
* デメリット: `elm install` とかのかわりに `npx elm install` とかしないといけない
    * 基本的なコマンドは npm script に書いてあるから、開発中に追加パッケージをインストールするときくらいしか気にしないでいいけどね
    * なんなら alias で `alias elm="npx elm"` とかしておけばいいしね

elm-app-template は上記のメリットとデメリットを鑑みて、npmによるローカルインストールを選択しています。

## parcel

なんかいい感じにいろいろディレクトリ内のファイルを走査していい感じにビルドしたり開発サーバーを立ち上げてくれるやつです。
設定もないので、特に語ることはありません。

## [elm-mixin](https://package.elm-lang.org/packages/arowM/elm-mixin/latest/)

地味にめちゃくちゃ便利なやつです。
Viewを書く時に、Attributeの再利用とかがめちゃくちゃ楽になります。
[スターください](https://github.com/arowM/elm-mixin/)。

ふつうの elm-html パッケージみたいに使える上に、`batch` が便利！

```elm
import Mixin exposing (batch, class, id)
import Mixin.Html exposing (div)

view =
    div
        [ class "foo"
        , batch
            [ id "bar"
            , class "baz"
            ]
        ]
        []
```

別パターン

```elm
import Mixin exposing (batch, class, id, lift)
import Html exposing (div)

view =
    lift div
        [ class "foo"
        , batch
            [ id "bar"
            , class "baz"
            ]
        ]
        []
```

## CSS modules

[気軽なやり方](https://qiita.com/arowM/items/ba08d0a705eef2626b69)でCSS moduleを使えます。
`src/style/` の中に置いたCSSファイルやSCSSファイルは、クラス名セレクターの先頭にファイル名が付与されます。

たとえば、`src/style/app.scss` っていうファイル:

```app.scss
.wrapper {
  border: solid 2px #999;
  border-radius: 0.4em;
}
```

これが下記の内容に書き換わります。

```scss
.app__wrapper {
  border: solid 2px #999;
  border-radius: 0.4em;
}
```

Elmプログラムの側では、`src/Main.elm` のように

```elm
import Html exposing (Html)
import Html.Attributes.Classname exposing (classMixinWith)
import Mixin exposing (Mixin)
import Mixin.Html as Mixin

view : Model -> Html Msg
view _ =
    Mixin.div
        [ class "wrapper"
        ]
        [ Html.text "test"
        ]

class : String -> Mixin msg
class =
    classMixinWith <| \name -> "app__" ++ name
```

というように専用の `class` 関数を用意すればいつもと特に変わらない使い心地でCSSに名前空間を擬似的に導入できます。
「CSS moduleなんていらないよ（●｀ε´●）」っていう人は次の項の `.postcssrc.js` でオフにすればいいだけです。

## その他 PostCSS

`.postcssrc.js` によく使う PostCSS のプラグイン設定をしてあります。

```.postcssrc.js
module.exports =
  {
    "modules": true,
    "plugins": {
      "autoprefixer": {},
      "postcss-flexbugs-fixes": {},
      "postcss-modules": {
        "generateScopedName": "[name]__[local]",
        "getJSON": () => null
      }
    }
  }
```

CSS modules の設定もここに書いてあるので、細かい設定をしたいときはここをいじります。

## elm-analyse, elm-format

定番のツールもローカルインストールで入れています。
これで、「あいつがcommitすると毎回elm-formatのバージョン違いで微妙に差分が変になる」みたいなトラブルがなくなります。

npm script も用意してあるので

```package.json
  "scripts": {
    "format": "elm-format src",
    "test": "elm-analyse && elm-format --validate src/"
  },
```

```bash
$ npm format
$ npm test
```

みたいに使えます。

[さくらちゃんの追悼写真集を手に入れる](https://amzn.to/38DyjWr)
[さくらちゃんをもっと見る](https://twitter.com/hashtag/%E3%81%95%E3%81%8F%E3%82%89%E3%81%A1%E3%82%83%E3%82%93%E6%97%A5%E8%A8%98?src=hash)
[他の記事を見る](https://qiita.com/arowM)