C#erがフロントエンドを軽く勉強してみた

## はじめに
### 3行
* マインスイーパーをtypescript(とreact/vue)で作った
* コード: https://github.com/debu-despot/simple-minesweeper
* 遊ぶ: https://debu-despot.github.io/simple-minesweeper/dist/

### お前 is 誰
C#信者のPG(実務7年目)です。
実務は専ら.NetやC++を使った業務系アプリや、研究開発等がほとんどでした。

……はい、過去形です。

1年ほど前にグループ異動となり、現在ではweb開発を中心にお仕事してます。
C#を使いたいです。
~~たまにVBAとか飛んできて発狂してます~~

### この記事は？
web開発と言えば日進月歩な最新技術のオンパレード、というイメージでしたが残念ながら私の職場ではそうでもありませんでした。
IEを崇める会ばかりから仕事を頂いき、手間を惜しまない真心こめた仕事がウリの素敵な職場です。
愚痴記事ではないのでどんな惨状かは割愛しますが、gitやnodejsを名前しか知らない上司が技術責任を負っている~~分かりやすい地獄~~、とだけ。

つまるところ仕事から得られる経験値が(少なくとも現代web技術に関しては)低いと言って差し支えないので手前で勉強するしかねぇ！ということで実際に軽く勉強してみた感想文です。

というのと転職に向けて何かしらアウトプットした方がいいわな……っていうお試し記事です。(というかこっちが大本命) 
得意分野(C#)でない理由は私が初見の道具をどの程度使えるかの能力を(巧拙は別として)示すためです。


## 本編
### 何を作るか
今回は~~プログラマのお友達~~マインスイーパーを作りました。 
余談ですが言語を勉強するならGUIはマインスイーパー、CUIならBFインタプリタを作ってみるのがいいというのが持論です。
マインスイーパはシンプルながらも色んな要素を使う必要があって遊びながら~~飽きずに~~デバッグ出来るのでオススメです。 

コードはgithubに置きました
https://github.com/debu-despot/simple-minesweeper

作成したものは以下で遊べます。
https://debu-despot.github.io/simple-minesweeper/dist/

ただしブラウザの横幅が大きいと表示が崩れます。
開発時は妥協出来る範疇だったのですがgithub君でホスティングしたら遊べないレベルで崩れます。修正は~~面倒なので~~また今度します(多分)。
またPCのchromeでしか動作確認してません。


### 技術選定
作るものも決まったので次は何で作るか、ですがまずは無難にtypescript。
C系ばかり扱ってきた身としてはやっぱり型があるのが安心です。jsと違ってjsdoc書かずともインテリセンス効きますし。(vscode使用時)

typescriptだけでもいいのですが折角なので流行りのSPAフレームワークも使ってみようとreact、vueも追加。
他に人気そうなangularは軽く調べた感じ大規模向きで、googleトレンドで見ると右肩下がりなので除外。~~あと名前が覚えづらい~~

HTMLゴリゴリ書くのも嫌で、「じぇーど？みたいなHTML作れるのあったよなぁ」と思い出したので調べたら現在pugと名を変えていたので採用。名前が可愛いのも高評価です。 
まあほぼ動的に生成するつもりだったので本当に試してみるか、レベルですけども。

cssって書き方冗長で面倒ですよね。てことで、ベースはありものを使って足りない部分をscssで書くことに。 
ベースは[bahunya](https://kimeiga.github.io/bahunya/)を使用。ちょうどいい塩梅のコントラストでイカしたダークテーマ。何よりクラスレスなのが最高にクールです。
https://kimeiga.github.io/bahunya/

あとはこれらをまとめるのにwebpackを使う必要がありますが、面倒だったのでparcelを使うことにしました。
一応webpackやbabelの使い方は軽く勉強しましたけど、上記のものを全部使うとなると設定だけで~~飽きそう~~躓きそうだったので今回は妥協。 


使用技術をまとめると以下の通り

* typescript
* react + typescript
* vue + typescript
* pug
* sass
* parcel

### 作成
今回は、

* typescript版
* react + typescript版
* vue + typescript版

の3つを作成する予定です。

ざっくりとした工程は以下の通り。

1. マインスイーパー作成(typescript)
2. HTML作成(pug)
3. GUI作成(typescript)
4. GUI作成(typescript + react)
5. GUI作成(typescript + vue)


>ここから先はブツの作成から半年後くらいの私が書きます。 
>プライベートのアレコレで精神的に死んでました……。

#### 環境構築
nodeでparcelをインスコしたあととりあえず各ライブラリが動く状態まで持っていきます。
ついでにeslintやprettierも動くように。 

ここでめちゃくちゃ躓きました。 
記事書く予定だったのにメモとってないアホが居たので覚えている範囲で箇条書きすると、

* parcelのバージョンをいったりきたり
* tsconfigってどうやって書くん？
* vue3が動かないんだが？
  * 結局色々手動で入れたような覚えが
* scssも動かない
* eslint?tslint?
* eslintとprettierを連携させ……え、もうそれは古い方法？
* prettierのフォーマットの仕方が最高に気に食わない
  * vsくらいカスタマイズ出来たら良かったのに
  * 結局使ってません

他にも色々あったと思います。
parcelでこの有様なのでwebpackだったら十中八九投げてました。ありがとうございますparcel様。
テンプレート選ぶだけで全部構築してくれるVisual Studio様の有難みを再確認しました。全てに感謝。

#### マインスイーパー作成
まずはマインスイーパー部分を作っていきます。

マインスイーパーの見た目は皆さん知っての通りマスの集合体です。
なもんで適当にマスの中身作って、それを二次元配列にしてラップして～というのが手っ取り早そうですが、私は**多次元配列が嫌い**です。

嫌いな理由はいくつかありますが、LINQで扱おうとするとあまり綺麗なコードにならないのが大きな理由です。
ついでに言うと画像関係の仕事してたときは1次元で扱ってたのでそっちのが慣れています。

なので一次元配列を二次元表のようにも扱えるクラスを配列を継承して作成します。折角のtypescriptですしね。
ついでに将棋やチェスのようなボードゲームにも流用出来ます。作るかどうかは別として。

あとは更にこれをマインスイーパ用として発展させます。
実際にはデバッグしやすいようにGUI作成と平行してやってましたけども。

#### HTML作成(pug)
pugでちゃちゃっと作ります。
前述の通りほとんどは動的に作成するのでDOMを入れるdivと切り替え用のリンクだけ作成。
bahunyaでハンバーガーメニューが作れるのでサンプルをコピペしてリンクをポン置きするだけでそれっぽく見えます。

#### GUI作成(typescript)
ノリと勢いでテキトーにマインスイーパと一緒に作成。
必要なI/Fは

* 難易度選択
* 横幅入力
* 縦幅入力
* 地雷数入力
* ボード生成ボタン

で、これらを適当に作成して、見た目整えてイベント追加してデバッグ。 

ポップアップはデフォルトだと味気ないのでsweetalertを使わせていただきました。
https://sweetalert.js.org/guides/

あとはURLパラメータによって呼び出すレンダーを切り替えるようにして完了。

#### GUI作成(typescript + react)
上記で作ったts版と同じ振る舞いをするように作成。
折角なので部品に分けて作りました。

* 設定部分
* ボード部分
* 二つをまとめた全体

案外すんなり書けてたような気がします。 
初心者がすんなり書いたのって対外ゴリ押しだったりするよな、と思ってソース見返したら思ったよりもゴリ押してる見た目でした。 
renderの中にイベントや生成ロジック書いてるのが起因してるんだと思いますが、イベントや生成ロジックが実際のコントロールと物理的(?)に近い方が分かりやすいとも思うので好みの問題なような気もしますがどうでしょう。

#### GUI作成(typescript + vue)
react版と同じようにts版コピー+部品分けで作成。

これはヒーヒー言ってたのを覚えてます。

後述もしますがロジックとデザインが完全に分離してて、それらの繋ぎ方が分からなくてあうあう言ってました。
あとは今回vue3で書いた(と思う)のですが調べててvue2の情報が出てきてノイズだったり、対象が2なのか3なのか分からない情報があって、動かないんだが？案件が頻発してました。
まあ過渡期だった(今も？)のでしゃーないんですが。

## 所感
3行でまとめると

* web系は環境構築大変
* tsの触り心地はいい感じ
* vueよりreactの方が肌に合う

### 環境構築が大変
やっぱりフロントエンドというかweb系は環境構築が大変よね……、というのが率直な感想です。
取れる択が多いのが魅力ですけど実際にそれらを動かすのが大変というか慣れが必要というか。 

### tsについて
初めて本格的にtsを触りましたが案外すんなり使えました。
個人的にはjsよりもtsの方が好きです。(環境構築の手間は無視するものとする)
ただC#と比較した場合ではやっぱりC#の方が使いやすい、というのが正直なところです。
と言ってもそこまで差はないですが。 

C#とtsの簡単な個人的比較は以下の通り。

* tsはオーバーロード定義が面倒
  * これが一番のマイナス
* Array.prototypeがLINQと比べると弱い
  * 痒い所に手が届かなんだ……
* 関数の扱いはtsの方が楽
  * 戻り値書かなくていいのが楽
  * C#はオブジェクトとして扱えませんがデリゲートやら糖衣構文でほぼオブジェクトっぽく書けるのでそこまで大きくはないですが
* let,const相当の宣言を全ての言語で取り入れるべき
  * 読む側はめっちゃ楽だし書く方も意味分け出来て○

後半はtsというよりjsの利点ですが。


### reactとvue 
最初に言っておくと、tsでゴリゴリ書くのは面倒なのでもう一生やりたくないです。

それでreactとvueの比較ですが、私はreactの方が圧倒的に好きです。
決定な要因は**デザインとロジックの乖離**と、それによる**学習量**です。

vueはデザイン(template)とロジック(script)が乖離していて、極端な話をするとHTMLとjsが分離しているのと大差ないというのが正直な感想です。
それぞれの実装方法に加えて両者間での紐付けもあるので学習量が多いと感じました。~~この程度で多いとか頭弱い、とかの話するなら屋上へ行こうぜ~~

一方でreactはデザイン(render)とロジック(render以外)をほぼ同列に扱えるのでデザインの中でロジックを書けたり、逆にロジックの中でもデザイン出来るので自由に書けるのが取っつきやすかったです。覚えることもvueよりは少なく感じました。~~FB社のことは嫌いなので複雑な気持ちです~~


勿論これは好みの話でどっちが優れているとかそういう話ではないです。
今回は作ったのはおもちゃ程度のものなのでもっと規模の大きいものを作る場合にはまた違う評価になると思います。