新卒エンジニアが一年で読んだ技術書

年末ということで、私が一年で読んだ技術書を棚卸ししていく。一応ジャンルとしては3パターンに分けられると思ってて、

  1. 現場で使う技術
  2. 汎用的な技術や設計関連
  3. その他読み物とか色々

の構成で紹介していく。アフィリンクとかは貼らないから安心して欲しい。テキトーに本の書影だけ貼っておくので気になったら適宜探してほしい。

1. 現場で使う技術

私は学生時代、2年間開発のアルバイトをしていて、Web開発とかプログラミングのイロハ的な部分は全てそこで学んだ。主な技術要素としてはRuby,Rails,MySQLを使って開発をしていたので、これらについては実用レベルで使えると自負していた。しかし、配属先で使われていた技術は私が今まで使っていた技術といずれも被らなかった。具体的にはTypeScript,React,Next.js, NestJS, MongoDB。フレームワークからライブラリ、言語まで全てが未知の世界だった。早急にこれらの技術にキャッチアップする必要があった私は、同期で有志を募ってTS ,Reactの勉強会を始めることにした。そこで読んだ本をここで紹介する。

オライリー プログラミングTypeScript

言わずと知れたオライリーのTypeScript本だ。私はそれまで静的型付け言語に触れたことがなかったわけではないが、本格的に実務レベルで使用したことがなかった。そのため、とりあえずは信用できるオライリーのTypeScript本で言語仕様についての理解を深めることにした。基本的な型の紹介、合併型や共用体型、ジェネリクス、構造的型付けといった、静的型付け言語共通の知識やTS固有の機能について理解を深めることができた。仕事でTSを使うとなったらまず最初にお勧めしたい本だ。とはいえ、こんな分厚い本を一人で読むと挫折するだろうから勉強会とかで誰かと一緒に進めると良いだろう。

オライリー Reactハンズオンラーニング

これもオライリーの本。現在進行形で勉強会で使用しており、まだ読み終わってはいない。お勧めできるかと言われたら...うーん。微妙なところかもしれない。Reactを全く知らない初心者が読むならためになりそうだが、ある程度経験してる人が読んでもあまり新しい発見はないかもしれない。ぶっちゃけ、私はこの本の勉強会が始まる前に、実務でフロントエンドのタスクを振られて自分で検索しながら必死に食らいついていく過程でReactを理解できるようになった。なので、この本の恩恵をあまり感じられていないというのが正直なところだ。経験者なら公式のAPIリファレンスとかを読んだ方がためになりそうな気がする。 また、本のタイトルにハンズオンラーニングとあるが、特にハンズオン感はない。

オライリー ハンズオンNode.js

またもやオライリー、どんだけ好きだ。
これは勉強会で使用したわけではなく、自分で夜な夜な進めていた本だ。実務でNode.jsを書いていく中で、非同期処理やイベントといったNode.jsの基本的な概念についての理解が不足していると感じた。この本はそれを補ってくれるのに十分だった。Promiseとは、async/awaitとは、イベントループとは、streamとは。今までRubyを書いていて出会ったことのない新しい概念を学ぶことができた。これを読んでから「asyncとかよくわかんないけどとりあえずawait付けとけばいいっしょ!」のノリでコードを書くことはなくなった。特に2章、3章は定期的に読み直したい。仕事でNode.jsを使うことになったらまずお勧めしたい一冊だ。結構難易度は高い。 ちなみにこれを読むまで自分はPromiseで遅延実行を行ってるとか思ってた。

TypeScriptとReact/Next.jsでつくる実践Webアプリケーション開発

Next.jsについての知識をもっと付けたいなと思って読み始めた。最初の章のNext.jsのレンダリング方式の違いやReactのフックスについての説明はかなり勉強になった。後半にはハンズオンパートがあるが、コードに解説があるわけでもなく、書く量も膨大で写経を諦めてしまった。最初の章だけも自分にとっては読む価値があったので、後半のパートは読んでいない。フロントエンドのコンポーネント設計についても触れている箇所があったがちゃんと読めていない。

2. 汎用的な技術や設計関連

先ほど自分で有志を募って勉強会を開いたと言ったが、それとは別で同じオフィスの同期と行っている勉強会がある。他は知らないが、かなり勉強会が盛んな会社だと思う(お金も出るし)。こちらの勉強会は、使う技術が同じとは限らない様々な部署の同期と行っているため、全員が共通して活かせるように固有の技術は扱わないようになっている。「汎用的な技術や設計関連」とふわふわした書き方をしているのはそのためだ。

プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則

新卒が読む本では割と定番?かなと思う。関心の分離とかDRY原則とか、三大美徳とかボーイスカウト原則とか、TDDとかDDDとか、あるいはUNIX哲学とか。プログラミングの現場でよく聞く格言とか思想が101個、解説付きで載っている。勉強会はそれぞれの原則を読んで、それについてディスカッションするという方式で進めていた。この本の魅力は、何と言っても網羅性の高さにあると思う。コードレビューで指摘される事柄については大体これらのどれかに帰着できるだろう。さらに言うと、ソフトウェア開発における名著から引っ張ってきている原則も多いし出典も明記されているので、気になったものについては出典元を読んでさらに知識を深めることができる。まさにガイドブックのような位置付けだと思う。勉強会でも最初にこの本を読んだことで、次に読む本についての方針を決めることができた。とりあえず技術的なサムシングを読まないといけないけど何から読めばいいか分からない!な新卒エンジニアが最初に読む本として強くお勧めできる。

現場で役立つシステム設計の原則

値とデータをバラバラに管理しちゃダメだよ、適切に値オブジェクトを作るんだよ、ドメインオブジェクトを作ってドメイン固有の知識を閉じ込めるだよ!と言う感じの本。基本的にオブジェクト指向における綺麗な設計の仕方について話している。
ちなみに、私自身にもあまり知識がないのでうまく要約できる自信がないので濁している。立ち位置としては、本格的なDDD本を読む前にオブジェクト思考の基礎〜DDDの基礎までの橋渡しをしている本というイメージ。

良いコード/悪いコードで学ぶ設計入門

上の本は基本設計にも踏み込んだ内容だったが、この本は詳細設計寄りで、具体的なコードを挙げてオブジェクト思考における良い設計のパターン、悪い設計のパターンを紹介してくれている。基本設計とかやらない新卒にはまずこっちの本の方が良いかもしれない。変数の名前とかコメントの書き方の良し悪し、複雑なコードを読みやすくするパターンなど、読んでそのまま使えるような実践的な内容が多い。まあ理解が不十分なパターンを手当たり次第導入しても地獄のようなコードになるので十分に理解することは必要だが。
これもかなり新卒にお勧めできる。

ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本

これは先述の勉強会とは別、部署の先輩方が始めた勉強会で題材になっていた本だ。私の配属先のプロダクトではDDDが導入されており、DDDなど遊戯王でしか聞いたことがない私は酷く困惑した。レビューで「これはドメイン知識なので〜」とか言われて全くピンと来なかった。この本は、そんなよく分からないDDDをコードベースで分かりやすく解説してくれている。値オブジェクト、エンティティ、ドメインサービス、リポジトリ。DDDの世界で出てくる聴き慣れない用語について一章一章丁寧に解説がなされている。DDD初心者はまず読んでおくと良い。サンプルコードはC#だが、別に癖のある言語ではないし、ハンズオン形式でもないのでやっていることが理解できれば良い。 あと関係ないが、DDDって少しでも間違ったことを言うと分厚いエリックエヴァンス本(聖典)をしっかり読み込んだ聖職者達からこっぴどく叩かれるイメージがあってあまりネット上で語りづらいなあと思っている。

1日1問、半年以内に習得 シェル・ワンライナー160本ノック

順番が前後してしまって申し訳ないが、これは同期とやっている勉強会で現在扱っている本。上の本とは性質が違うので最後に持っていきたかった。なぜこの本をやることになったかはあまり覚えていないが、全員が「コマンドを使いこなせていないのではないか」という意識を持ってたんじゃないかと思われる。まだ始まったばかりだが正直かなり面白い。sedとかawkとかのコマンドを組み合わせて要求を満たす処理を行う、まさにUNIX哲学を肌で感じることができる。個人的にsedコマンドをあまり使ったことがなかったので、「あ、あの強い人がよく使ってるやつを使えるようになったんだ!」感が嬉しい。あとawkの便利さ。もう何でもawkで何でもできちゃいそう。

3. その他読み物系

闘うプログラマー

革命的OS 、Windows NTを作ったMicrosoftプログラマー達の人間活劇。どこかで勧められているのを見て読んでみたが、うーん。正直私にはあまり合わなかった。フィーチャリングされてる人物のうち何人かは仕事に追われてプライベートが疎かになって離婚したり、あるいはプログラマーとしての仕事を辞めてしまったり。なんか仕事との向き合い方について考えさせられて悲しくなった。

問題解決のための「アルゴリズム×数学」が基礎からしっかり身につく本

競プロを本格的にやりたい数弱には良い本。二分探索の計算量でlogが出てくるのなんで?とかそういうのが理解できる。数学は学生のうちにしっかりやっときましょうね〜。

アルゴリズム的思考力が身につく! プログラミングコンテストAtCoder入門

この本を読んでページに載ってる参考問題とか全部解いてたら万年灰色だったのが一気に茶色までいけました。とても良い本。まだ途中までしか読めてないけど全部理解して解けるようになったら緑とかいけんのかな。

達人プログラマー(第2版)

まだ全部読めてない。全部読むのは年末年始休みのうちの課題とさせてほしい。個人的に印象に残ってるのは「プログラマーは一年に最低一つは新しい言語を学べ」ってやつ。

Rustの本をちょこちょこ

新しい言語を学べと言われたのでRustをちょこちょこ学んでるが、特に理解できた自信はないし成果物もないので載せない。来年はCLIツールとか作れたらいいね。

まとめ

改めてまとめてみたらめちゃくちゃ本読んでますね。これは将来有望ですね、たぶん。期待しないでください。
それでは皆様、良いお年を〜

23にして初めて人間失格を読んだ

どこかで見た「小中高生の読んでる本ランキング」みたいなやつで、太宰治の「人間失格」が中学生女子の読んでる本にランクインしていた。そういえば自分は人間失格を通ってきていない。たぶん思春期のうちに読んでおくべきだったんだろうな。ふらっと寄った本屋でそんなことを考え、買うことにした。もはや本コーナーが猫の額くらいしかない近所の下品なTSUTAYAで「この人を見よ」と、「もものかんづめ」と一緒に。

存外に薄い本だったのでサクッと読めた。せいぜい2,3日程度で読んだ。だが、正直言って何も心に触れるところがなかった。何というか、自分と全く別世界に生きる生物の思考回路をただ淡々と覗いている感じ。主観で書かれているが全く移入するところはなかった。やはり中学生のうちに読んでおくべきものだったのだろうか。今になってあの時の感性を取り返そうとしても遅かったのだろうか。そう思ってTwitterで感想を漁ってみると、「メンタルが病んでる時に読むと引き込まれる」とかそういう感想が多数を占めていた。

いや、あれで引き込まれるってどんな人間なんだ。津軽のような本州の端とはいえ豪農の家に生まれ、長兄ではないとはいえ恵まれた家庭に育ち、学校にほとんど行かなくても学業優秀、女にはモテてモテてしょうがない。こんな人間のどこに共感するところがあるのか全く理解不能だ。全編に渡って長々と自虐風自慢を聞かされたような気分だ。それも恵まれた人間の不幸自慢なんだから聞くに堪えない。

ただ、一つだけ学んだことがある。ここまで恵まれた環境、ステータスを持って生まれた人間であっても、メンタルが弱いとどうにもならないことだ。メンタルの強弱が先天的なものなのかは分からないが(少なくとも私はそう思っている)、私はメンタル薄弱で生まれなくて良かった。私はこの本を読んでも何も感じないし、たとえメンタルが弱った時に読んだとして全く同じ感想だろう。親に感謝したい。ありがとう。年末には洒落たお土産でも持って実家に帰ることにする。

たぶん二度とこの本を開くことはない。

Youtubeのショート動画を観れないようにする拡張機能を作った

前提

ショート動画なんどという物は何の役にも立たない、百害あって一理なし。古くはVine、今ではTiktokが代表的なショート動画投稿サービスであり、その人気はとどまるところを知らず、ついにはYoutubeも正式機能として実装するに至った。かくいう私も一時期Tiktokをインストールしていた。確かに面白い。面白いのだが、それ以上に危険性を感じた。画面を上下にスワイプするだけで過ぎていく無為な時間。女子がくねくね踊ってる動画が出るまで必須に指を動かし続けるのだ。 これがWebサービスとしてユーザーの利用時間をいかに増やすか考えた結果のUIであり、ユーザー体験なのだろう。それはそれで一つの正解だ。ただ、そんなものを作りたくないから私はエンタメ系のWebサービスを運営している企業は受けなかった。突き詰めれば人の射幸心をどれだけ煽って無駄なことに時間を使わせるか、ギャンブルと同じ原理になるからだ。まあそんなことはどうでもいい。

とにかく、彼らにどんな理由があろうが無為に過ぎていく私の時間が供養されるわけではない。私はTiktokをアンインストールした。そんなもの見る必要もないからだ。 しかし、Youtubeは別だ。観たいチャンネルがたくさんある。しかし、ショート動画に寄り道したが最後。Tiktokと同じ轍を踏むことになる。そこでだ。ショート動画を観れないようにするChrome拡張機能を作った。

導入

このリポジトリにコードを上げといたのでテキトーなディレクトリを作ってその中でgit cloneしてダウンロード。

github.com

Chrome拡張機能のページで「パッケージ化されていない拡張機能を読み込む」でそのディレクトリを選択すると導入できる。 拡張機能を公開するには5ドル必要だったが、そもそもショート動画などという人の時間をドブに捨てる中毒性の高い機能を作ったのはGoogleなので金は払いたくない。だからフリーでソースコードだけ公開した。

コード量が少ないので見てもらえば分かるが、やっていることは2つ。

  • 左のメニューバーに出てくるショート動画アイコンの削除。
  • ショート動画を開くとトップページに強制リダイレクト。

やっているのはこれだけだ。あとはホーム画面のおすすめに出てくるショート動画の欄も消したかったのだが、面倒なのでやめた。どうせショート動画を開けば強制リダイレクトされるからだ。 これで煩わしいショート動画にあなたの時間を奪われることはない。人の射幸心を煽るようなWebサービスには全く反吐が出る。

結論

YoutubeってiPadとかスマホとかで見る人多いし、そもそもアプリから観る人も多いからこれあんま役に立たねえよな。

sshでStrictHostKeyCheckingをnoにすることの問題点

最近、業務でSFTPに関連するコードを書いた。そこで、認証時の確認やknown_hostsについて詰まったところがあった。対処法をググるとStrictHostKeyCheckingをnoにする解決策が散見されたが、セキュリティ的にいかにも問題がありそうな設定だ。この記事ではこの設定のどこに問題があるかを順を追って説明していく。

sshは接続先が初めて接続するホストの場合、確認を出す。

ssh接続を初めてのホストに対して行おうとすると、こんな感じの確認が出る。

The authenticity of host '〜' can not be established.
ECDSA key fingerprint is SHA256:〜.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

ここに書かれているfingerprintとは何なのだろう。

fingerprint = 公開鍵のハッシュ値

ここで表示されているfingerprintというのは、ホストの公開鍵をハッシュ化したものだ。ssh接続では公開鍵認証方式を採用しているが、公開鍵認証を行うには前提として、接続元のクライアントが接続先の公開鍵を持っている必要がある。fingerprintは接続元のクライアントが接続先の公開鍵を持っていない場合に送られてくるものだ。「お前、このfingerprintのやつと接続しようとしてるけど問題ないか?」と聞かれている。一応、公開鍵そのままより人間が確認しやすいからという意味でハッシュ化しているらしいが、こんな英数字の羅列を見て「むむむ..??」となるのは変態くらいだ。

よって、この確認は煩わしいからといってStrictHostKeyCheckingをnoにしたがる輩がいる。そして、あろうことかこんな設定を.ssh/configに書き出すのだ。

host *
        StrictHostKeyChecking no

たとえ深く理解していなくてもこの設定を見たら何となくヤバい匂いを感じることができると思う。 確かに確認が出るのは煩わしい。しかし、確認を出すのは最初の一回きりなのだ。 さて、ここで確認の際にyes/noを入力するとそれぞれどうなるかを見ておく。

  • yesを選択した場合: .ssh/known_hostsに接続先ホストのホスト名、公開鍵を記入し、接続する。
  • noを選択した場合: 接続しない。

先ほど公開鍵認証方式では、接続先の公開鍵を入手していることが前提だと述べた。yesを押すと、.ssh/known_hostsに対象のホストとその公開鍵が保存される。つまり、次回またssh接続する時にはこのknown_hostsの公開鍵を認証に使用することができるのだ。つまり、確認されるのは最初の一回きりなのだ。そのくらいの労は厭わなくても良いのではないだろうか。

ちなみに、StrictHostKeyChecking noを設定するとどうなるか。確認せずに勝手にknown_hostsに接続先のホストと公開鍵が登録される。 ...便利じゃね?どうせfingerprintなんてよく見ずにyes押してるんだから、自動でやってくれるなら好都合だ。

では、まずい例を紹介する。

公開鍵が変わった場合

ちょっとした実験をしてみる。例えば、ssh接続できるサーバーがあったとして、.ssh/known_hostsのそのサーバの公開鍵から最後の一文字だけを取り除いてみる。このままssh接続をしようとすると、デフォルトの設定のままの場合、警告が出る。サーバから取得した公開鍵とクライアントのknown_hostsにある公開鍵が違うからだ。 しかし、例の設定をすると、警告が出ずに新たに.ssh/known_hostsにその公開鍵が追加されるのみだ。今回は実験的に手元のknown_hostsを変えた飲みだが、これは接続先のホストの公開鍵が変わっている場合でも同様だ。 公開鍵が変わっている、つまり接続先のホストが自分が本当に接続したいホストなのかどうかも分からない。さらには中間者攻撃とかをされても気付くことができないということだ。せっかくセキュアにssh接続しようというのにこんな設定を入れてしまっては元も子もない。

ということで

やめようね!

(CIとかテスト環境で仕方なく設定することはあるかもしれないが、それにしても Host * は避けられるしやめた方が良いと思う)

Twitterをやめてみたら良いことが色々あった

正確にはやめたわけではないが、TwitterをPCでもスマホでもログアウトの状態にしてみた。自分は活字中毒の傾向があり、Twitterはそんな自分が活字を摂取するためのお手頃なツールだった。それをやめた。するとどうなったか。まだ一週間程度だが、その結果についてまとめる。

1. 読書量が増えた

Twitterをやめたことで、別で活字を補給しなければならない。そこで電子書籍、紙の本を読む時間が格段に増えた。もともと積読は多かったのだが、本よりTwitterの方が手軽なので、もっぱらTwitterで活字欲を満たしていた。その頼みの綱のTwitterがいなくなった今、積読を崩していくのに十分な読書量を確保することができた。Twitterでやたらめったらに書き散らされた散文を読むよりも、本を読む方が学びが多く有意義な時間だ(かといってそうした散文を読む意義のない時間を否定するつもりもないのだが)。最近は積読になっていたスクラムに関する書籍を読んで、チームにおける自分の役割や今後のキャリアについて考えていた。

2. アクティブになった

TwitterのTLをダラダラと眺めているより、本を読む方がよっぽど集中力がいる。もちろん家でも読めるには読めるのだが、どうしても気が散ってしまう誘惑が多い。そこで、カフェに行く機会が増えた。自分は貧乏性なのでほとんど外食もしない。アウトドアな趣味もないし友達も少ないので、特に予定がなければ一日中家にいることが多い。そんな自分に外出する機会が生まれた。朝の早い時間からカフェに行き、お昼が近づいて人が多くなってくる時間まで読書を楽しむ。そうしたらあとは家に帰ればいい。人でゴミゴミした空間が嫌いなので、街に人が少ない時間に外出し、人が多くなってきたら帰宅するというリズムは呼吸にあっている。しばらく土日の午前中はこれをルーティンにしてみたい。 あと、読書だけしていても時間は過ぎないもので、満喫に行って漫画を読んだりする時間も増えた。ジャンプの有名漫画を一通り制覇するのが目標で、今はハンターハンターを読んでいる。ブリーチとかデスノートとかあの辺を全て網羅したい。

3. 他人のお気持ちに触れなくて良くなった

自分はTwitterにハマっていたが、どうしても苦手なことがあった。有名人の訃報の際のご冥福ツイート、悲惨な事件があった日の黙祷ツイートなどだ。そんなものは心の中で思っておけば良いと思っている。いちいちそんなものをツイートして残しておく必要なんかないと思っている。ただ、安倍首相暗殺の時のTwitterを眺めていて思ったのだが、世の中には共感性の高い人々が一定数いて、そうした人々は自分が知っている人間の不幸を知るや悲しい気持ちになるということだ。もちろん、自分だって身内や友達に不幸があれば悲しい。しかし、テレビで見ただけの会ったこともない有名人や政治家に不幸があったところでなんとも思わない。ただ、お悔やみしなければ自分の精神を保てない人々が一定数いるらしい。こうした人々のツイートを見ると自分は不快感を覚えてしまう。いや、そもそもTwitterが向いていないのかもしれない。

4. 自分が触れる情報量を減らすことができた

触れる情報量を減らすというとマイナスなことのように聞こえるかもしれない。しかし、これは不必要な情報というノイズに脳のリソースを割かれて無駄に負荷をかけてしまうのを回避できるということを表している。前々から自分には悩みが会った。自分の思考は浅いのではないか、自分は自分が本当に向き合うべき問題に頭を回せているか、ということだ。Twitterで多くの情報を受け取り、それらの各々について浅い思考で結論を下すことは簡単だ。しかし、それは何かをした気になっているというだけで、自分が本当に向き合うべき課題、より内面的な何かについて目を逸らすための行為に他ならない。例えば、誰かと誰かの試合で誰かが花束を意図的に落とす行為について論じる時間、あるいは感情を動かしている時間は自分にとって本当に必要な時間なのだろうか。(そもそもこの出来事を知ってしまっていること自体、自分が情報を絞れていないなと感じている。知らない方が良い情報だから。)エンジニアならコンピューティングリソースを無駄遣いして痛い目を見た経験があるはずだ。外部からの無駄な入力を受け取り、無駄な出力を出すために無駄な演算をして脳のリソースを無駄遣いすることの不毛さに目を向けるべきだ。

以上。 今のところ、いつTwitterにログインするかは決まっていない。もう少しTwitterから離れて考えを深めて、Twitterがもたらす正負の両側面を入念に検討したい。少なくとも何の考えなしに再開してしまうと、以前の自分のように徒に時間を浪費するだけになってしまいかねない。活字中毒というインプットに有利な特性を持っているのだから、これを有効に使い、Twitterとも上手く向き合っていきたいものだ。

create-react-appで作ったReactプロジェクトにESLint, Prettierを導入する

Reactで何か作りたいと思ったとき、create-react-appは非常に有用だ。たとえ本格的な開発ではないにしても、こうして作ったプロジェクトにはESLint, Prettierを導入して快適に開発したくなるものだ。TypeScriptを使っているなら特に。しかし、毎度のごとく導入方法を忘れてググる羽目になっているので、今回は自分の備忘録としてこの記事を書いている。あと、古い記事では現在非推奨になっているeslint-plugin-prettierを使っているものも多く、検索が面倒臭いというのもある。

バージョン情報

  • Node.js: v16.17.1
  • create-react-app: 5.0.1

1. create-react-appの導入

yarn教徒なのでコマンドは以下。

yarn create react-app hoge-app --template typescript

終わり。

2. ESLintの導入

次はESLintを導入する。先ほどeslint-plugin-prettierに触れたが、このプラグインはESLintというリンター、Prettierというフォーマッターを統合するようなプラグインだ。現在は非推奨の設定になっているためそれに準拠し、今回はこれらを統合せずにそれぞれ役割を分けて別で管理する。このプラグインを入れてしまうとリンターのエラーもフォーマッターのエラーも同様にVSCode上で赤文字で警告が出てしまい、煩わしいことこの上ない。リンターはあくまで文法、構文チェック、フォーマッターはコードの体裁チェックとはっきり分けておいた方が分かりやすい。

まずはインストール。

yarn add -D eslint

次にESLintの設定。インタラクティブに設定項目について選べるようになっているのでそれぞれ以下のように答えた。設定ファイルの拡張子はお好きに。

npx eslint --init

> @eslint/create-config@0.3.1
Ok to proceed? (y)  y

How would you like to use ESLint? … 
  To check syntax only
▸ To check syntax and find problems
  To check syntax, find problems, and enforce code style

 What type of modules does your project use? … 
▸ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

Which framework does your project use? … 
▸ React
  Vue.js
  None of these

 Does your project use TypeScript? ‣ Yes

Where does your code run? …  (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
Node

What format do you want your config file to be in? … 
  JavaScript
  YAML
▸ JSON

eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
? Would you like to install them now? ‣ Yes

Which package manager do you want to use? … 
  npm
▸ yarn
  pnpm

最終的にeslintrc.jsonは以下のように生成されていた。

{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "overrides": [
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
    }
}

rulesのところによしなに設定を書く。以下のサイトを眺めると良い。

eslint.org

3. Prettierの導入

最後はPrettierの導入。以下のコマンドを実行する。

yarn add -D prettier eslint-config-prettier

eslint-config-prettierはeslintのフォーマットに関する設定を全て無効化してくれる。これでprettierとの棲み分けができる。

eslintrc.jsonのextendsの最後にprettierを追加して設定が競合しないようにするのもお忘れなく。

    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended",
        "prettier" // 追加

あとは .prettierrc を作ってフォーマッターの設定を書いていく。ここは各自その時のフィーリングでよしなにやる。兎にも角にもリンターの設定は.eslintrc.json, フォーマッターの設定は .prettierrcと分離できた。

最後に

せっかく設定したので実行コマンドをpackage.jsonのscriptsに定義しておく。

 "scripts": {
    ...
    "lint": "eslint \"src/**/*.{ts,tsx}\" --fix",
    "lint:check": "eslint \"src/**/*.{ts,tsx}\"",
    "format": "prettier --write \"src/**/*.{ts,tsx}\"",
    "format:check": "prettier --check \"src/**/*.{ts,tsx}\""
    ...

はい、これで終わり。あとはCIに:checkのコマンドを組み込んだりして常にリントエラー、フォーマットエラーを弾けるような仕組み作りをしておくとなお良い。凝り出すと面倒だが、必要最小限の設定はこの程度で済む。あとは好きにいじろう。

新卒のペーペー目線で見たMongoDB

2週間の新卒研修を終え、ついに部署に配属された。事前に聞いてはいたものの、私の配属先のプロジェクトで使われている技術は私の技術スタックと全く被っていない。文字通り、一ミリも被っていない。言語からフレームワーク、DBに至るまで、だ。今日はそんな中からDBについて取り上げて色々と語ってみたいと思う。語ってみたいと言ってもまだ一週間しか触っていないので大したことは言えないのだが、少なくとも新しくプロジェクトに入った人間がそれをどのように感じたかということは残しておく価値があるかなあと思った次第だ。 さて、肝心のDBとはMongoDBだ。代表的なNoSQLの一種で、私も名前を聞いたことくらいはあった。しかし、今までRDBでやってきた私としては全く名前以外に全く馴染みはない。そんなMongoDBを一週間触った感想を少し述べたいと思う。

※あらかじめ断っておくが、MongoDBを触ってまだ一週間の人間なので知識に間違いがあるのはご容赦されたい。今後のためにもマサカリは真正面から受け止めるつもりだ。

1. 思ったより抵抗はない。

これは正直な感想として、想像していたよりも抵抗はない。NoSQLというとRDBというメインストリームから外れた異形の者たちという印象があったのだが、全然そんなことはない。データの形式はキーバリュー形式で、平たく言えば単なるJSONだ。値には配列も入るし自由度が高い。そしてクエリについてもそこまで抵抗はない。例えば以下のような感じだ。

db.test.findOne({ id: 1 })

どうだろうか?MongoDBを触ったことがなくても、なんとなく「testというテーブルからidが1のレコードを一つ引っ張ってきてるんだな」と分かる。形だけ見ればオブジェクト指向言語のコードのようだ。クエリ言語とプログラミング言語の差があまり感じられない。むしろMongoDBから入った人間がSQLを見た時の方がエキゾチシズムを感じることだろう。

2. 用語が耳慣れない

MongoDBで使われている用語は一般的なRDBのそれと異なる。対応関係は

  • テーブル → コレクション
  • カラム → フィールド
  • レコード → ドキュメント

といった具合だ。特に最後のドキュメントなんかはなかなか慣れない。ドキュメントと言えば「公式ドキュメント」等でも使うし一般的な言葉だ。MongoDBのデータ構造はRDBのようにシンプルな二次元表には収まらないので特殊な用語法を定義する必要があったのだろう。

3. システムを把握しづらい

これが本稿のメインだ(じゃあ先に言え)。例えば、RDBを採用しているシステムならER図を見てどんなテーブルがあるか、テーブルとテーブルはどのような関係かを確認して、システムの概要をざっくりと把握できる。あくまでざっくりと、だが。しかし、MongoDBではそれはできない。 理由は二つある。 まず一つに、外部キー制約などがないことだ。MongoDBのコレクションには他のコレクションとの関係を明確に示すような制約を課す機能がない。無論、コレクション同士を結合することはできるので特定のキーを外部キーとして定義することはできるのだが、それはMongoDBの機能ではない。人間が勝手にこのキーはあのコレクションとの間の関係を示す外部キーだ、と意味づけしているだけである。

第二に、フィールドがドキュメントごとに異なる。用語のせいでよく分からない?RDBで言うならば、「レコードごとにカラムが異なる」と言うことだ。これはもうパニックだ。先ほどはシステム全体の話をしたが、今度は一つのテーブルに着目するとしよう。RDBであればテーブルに定義されているカラムを見て、なるほどこのテーブルにはこんなカラムがあるのか。このカラムはNULLじゃダメ(必須)なのか。などなど、そのテーブルが何を表し、どんな役割を果たすのかを概ね把握できる。しかし、MongoDBはコレクションごとに値の内容が異なる。例えば一つのコレクションに

ドキュメント1: { "fruits": ["apple", "banana", "orange"] }
ドキュメント2: { "country": "Japan", "lang": "Japanese" }
ドキュメント3: { "hoge": true }

こんなバラバラのドキュメントが格納されていても何も言わない。何も聞かせてくれない。 フィールドの数からキーから何から何までバラバラだ。ドキュメントごとにフィールドが違うのだから、ER図のエンティティのように一つのコレクションの構造を統一的に表記することが難しい。「とりあえずテーブル定義見るか」ができない。

まとめ

まとめると、MongoDBは「ドキュメントがしっかりしていないと辛い」DBだと感じた。ここで言うドキュメントは文字通り文書のことだ。コレクションの中に好き勝手どんなJSONでもぶちこめてしまうので、このコレクションにはこうこうこういう役割があって、どんなデータを格納して、フィールドは...みたいな説明をしてくれないと収集がつかなくなりそうな気がする。コレクションの内容をページングしていって、どんどんとフィールドが変わっていく様は私にはカオスであった。それはまさしく清濁併呑のリヴァイアサンであった。この神のごとき寛容さを鎮めるには制約が必要だ。その機能がMongoDBの中に内包されているのか、それとも人間の祈りに依るものなのか。私にはまだ分からない。