Diary

@ssig33

近況

  1. 新型コロナウイルス感染症にかかりました
  2. 東京大学空間科学情報研究センターの柴崎先生のところで研究員になりました
    • 副業でもすっかーということで大学ベンチャーに話を聞きにいったらその流れでなぜか大学のほうで働くことになった
      • まあ技術補助員とかそんなロールでの採用だろうと思ってたが何故か研究員ということになった、高卒でもいいんですねこういうの
    • 大学というところに行くのがはじめてなので万事勝手が分からずいろいろ周囲に迷惑をかけている気がする
    • ユビレジ辞めてません

コロナでリモート当たり前になったから無理なくこんな兼業ができるし、自分がコロナ感染して辛かったことを別にすればいまのところコロナがあってよかったなという気持ちがちょっとあります。

はーだるい

いいかげんいつまでも Hamachi を使ってるのもヤバい気がするが なんだかんだ VPN あれが一番楽だよなあ

ブログの見た目にこだわってしまった のでこのあと死亡するものと思われる

宇部興産専用道路みにいきたい

マジでエヴァンゲリオン面白く、宇部興産をみにいきたいという強い気持ちになった

Safari で dayjs 使ってた部分壊れてる、、、

useDarkMode 使ってダークモード対応などをしてみたが 捕捉できるタイミングがある程度データロード後なのでしょうがないとはいえ結構ブラウザがチラチラしてしまう。

しかしまあそのうちメディアクエリとかでダークモード対応してるサイトが当たり前になれば、ブラウザ側がブランクスクリーンを白から黒にするだろうな、とは思う(現状白いのはそのほうがチラチラしないからだろろうから)。

キャッシュ飛ぶまで数十秒かかります~ を許せるかどうかで、これを許せるようにサイト設計したほうが多分いろいろ楽なんだが、インフラの都合がそこまで露出してくるの嫌なんだよなー。

とはいえそこをどうにかするっていうことは Fastly 使うか自前の nginx 使うかとかそういう話にはなってきますが。

まあとりあえず一旦ここは vercel 受け入れた

vercel 受け入れられるならここ楽になるよな みたいなことが next.js 使ってると結構あって、いやまあでも vercel 受け入れられるかっていうと微妙じゃないですか?すくなくとも Fastly にロックインされるほうがまだナンボかマシと思える。

Fastly を受け入れればやることは SSR だけでたぶんこっちのほうがコードベースとしてはシンプルになると思うんだが、 vercel の開発者体験の高さは否定し難い。

fastly への複雑な感情について

SQL 手書きのほうが楽だよね みたいの現代だと結構あるとおもってて。 JSON とか protobuf とか生成するだけじゃん?みたいな。

ただ危険だよねえ、これ。分かってる人がそんな感じで書いたコードをみた分かってないひとがプリペアドステートメントつかわずに書いちゃうとか絶対おきる。 SQL 分かってる人も ORM に一旦変換する不毛なフェイズが必要なんだよなあ、結局。

辛いものが食べたい

非常にだるい

ラーメン二郎

COVID-19 があって一番嬉しかったこと

IT 企業各社が VPN の出口を AWS に置くことが多かったためか、 AWS からのアクセスを弾くサービスがかなり減ったこと。

近所のホームセンターいったらでかい缶ビールがあり それなりにうまかった

Hotwire

結局何を使おうがそんなに変わらなくて、 React だと material-ui がつかえていたところが Howtire だと Tailwind CSS になるというのが最大の問題だと思う。

Hotwire 的なアプローチと React のアプローチでそんなに開発者体験に差があるとも思わないんだけど、 React はリリースされてから 8 年近くが経過しており、その間に様々な積み上げがあり、特に material-ui はすごい。 8 年分を崩してやっていくほどの魅力が Hotwire というか turbolinks にあるかねえ、ないだろ。

表の画像を取得する API を作りたい

そんなこともあるかと思います。具体的には Slack にスッと表を貼りたいとかそういうときね。 Block Kit 使えばもしかしたらできるのかもしれないけど、あんなもん覚えたくないし Outgoing Webhook かなんかで一瞬で実装できるとよい。

table image creator とか適当に検索してもあまりいい感じの結果が得られなかったので、数十秒考えた結果以下のようになった。

  1. HTML で普通に table を作る Web アプリを作る
  2. puppeteer でそれにアクセスして table の中身をスクショして画像を返すのを express で作る

で Slack に画像を貼る場合は、 Outgoing Webhook がきたら 2. にアクセスして画像を得て Gyazo に投げてその URL をリプライするという web アプリをさらに作ります(アクセス事に別の画像 URL を得たいのと、 puppeteer を使う重いアプリに Slack 接続者がみんなアクセスしてきたら嫌だから)。

で、できたのが以下のようなもの。

コロナ表

Web アプリが 3 個もあって大変ですが、 Cloud Run にデプロイしておけば運用コストはタダみたいなもんだし本当によかったですね。

もうちょっとスマートに実装したいところですが、とりあえず個々のアプリ自体はシンプルなのでこれでよしとします。

それでも Rails のアップデートをする

Rails 5.0 あたりから DHH らが考える Web 開発と自分の手元にあるソフトウェアの設計の乖離が激しくなっていると感じていて、まあはっきり言えば Rails のアップデートでうれしい、と感じる機会は減っている。

Web アプリケーションフレームワークは Rails のようなフルスタックなものより Sinatra/express 風のシンプルな DSL 風のものが好まれるようになっていて、歴史に Rails が残した影響が何かといえば「assets pipeline を導入したことにより、 Web フロントエンドを別言語から JS/CSS にコンパイルするという習慣を広く普及させた」ということになるのではないか、と感じている(GWT とかまあいろいろあったけど Rails 3.1 によって決定的にこういう考え方は普及したでしょう)。

Action Cable も Webpacker も Active Storage も Action Mailbox もつかってないし、 Action Text は正気の沙汰とは思えないし、 Rails が公式にサポートするずっと前からテストは並列化していた。データベース単位のコネクション切り替えを使うぐらいならリードオンリーなスレーブにつなぐマイクロサービスを導入するほうが楽だなと感じるしそのようにしている。

それでも Rails のアップデートには追従し続けていて、僕がメンテしている Web アプリケーションはだいたいどれも Rails 6.1 で全部テストが通っていて、年明けには多分 Rails 6.1 版をリリースする。

なんでこんなことをしているか、ということなのだけど。 Rails は目玉の機能以外にも当然いろいろと改善が行われていて、まあはっきりと言えばそれで互換性が壊れていく。互換性が壊れると手元のアプリも壊れることになるんだけど、それはだいたい「とても悪い書き方をしていて、意味不明なエッジケースを踏んでいるところ」が壊れる。

メンテナ達は互換性を壊したくて壊してるわけじゃないので、こういうものについて報告すればまあ Rails 側が直るんだけど、鉱山のカナリアのようなもの(?)で、 Rails のアップデートに最速についていくと悪いコードがそのタイミングで明らかになる。

そういうものを直すタイミングとして結構いいきっかけになるので Rails のアップデートには追従し続けている。しかし、まあ、その程度。

Rails の ActionMailer で正しく view の helper を使う

Rails の ActionMailer では Rails ActionMailer helper とかで検索すると、「ActionMailer で helper メソッドを使用するには add_template_helper を使おう」というような記事が複数ヒットする

他にもたくさんこう書かれている記事がある。しかしなんとこれは実は間違ったやり方である。 ActionMailer::Base を継承したクラスで add_template_helper というメソッドが使えるのは ActionMailer::Base が include AbstractController::Helpers しているからで、では AbstractController::Helpers を実際に見てみると実はなんと add_template_helper は private なメソッドで Rails の利用者が使うことを想定していない。

で、簡単に調べた限り Rails 3.0 の時からそのようになっていた

結果として、このメソッドはこのコミットで削除されてしまい、そしてそのまま Rails 6.1 でこのコミットはリリースされた。おそらく結構いろんなところで Rails 6.1 にするだけでメール送信まわりが壊れていると思うのだが(すくなくとも俺がメンテしてるアプリ 4 個で壊れた)、もちろんこれをコミットした人やこれをリリースした人が悪いのではなくて、 private メソッドを使うバッドノウハウを広げていた人やそれを無批判に採用していた人が悪い。俺も悪い(自分でそのコードを書いたことはないが気にしたこともなかった)。

ではどうすべきだったか、というと Rails 3.0 の時点でそうであったように、以下のように書くのがよい

class HogeMailer < ActionMailer::Base
  helper :hogehoge # 使いたいヘルパーファイルをこのように指定する
end

とっても有名な OSS について 10 年以上にわたって間違った、とても悪いノウハウが広まっていて特に訂正される気配もなかった、というお話でした。

SQL で 10 行に 1 個ずつデータを取得したい

何を言ってんだ?って感じですが時系列に記録されているデータの場合そういうこともあると思います、今あった。

columtype用途
bodySTRINGJSON がドカッと入ってる
created_atNUMBER作成日時が入っている

こんな雑なテーブルがあるとする。で、これにたいして created_at で並べたのにたいして 10 行に 1 個合計 50 行取得したい場合以下のようにすればよい。

select * from(
  select 
    JSON_EXTRACT_SCALAR(body, '$.nanika.nanika[0].nanika') as nanika, 
    created_at, 
    ROW_NUMBER() OVER (ORDER BY created_at DESC) as number
    from `garbage_table`
  )
where MOD(number, 10) = 0
imit 50;

今必要に迫られて書いたのがだいたいこんなんだったんですがもっとシンプルに書けるかもしれない。

常識的に考えればこんなクエリ吐いたりすることなんてまずないんですが、常識が通じないシチュエーションはあるし、そういう時 BigQuery であればこんなクエリにたいしてもすばやく結果を返してくれる。よかったですね。

React アプリ構築するときのディレクトリ構成とかについて最近やっていること

こんにちは。私は最近 React アプリを作る時以下のようなディレクトリ構成でやっていっています。

src/ ---> App.tsx
      |---> Components/ ---> Fuck/ ---> index.tsx
      |                  |          |-> useSomething.ts
      |                  |          |---> SubComponent/ ---> index.tsx
      |                  |
      |                  |-> Shit/ ---> index.tsx
      |
      |---> hooks/ ---> useGarbage.ts
      |             |-> useShit.ts
      |
      |---> store/ ---> index.ts
                    |-> modules/ ---> gomi.ts
                                  |-> unko.ts         

store 以下は redux を使う場合で Ducks っぽい奴がいます。しかし最近はもう useState で済まして redux 使わないことも多い(あんまり SSR しないなどの事情もあり)。

非常にシンプル、かつ Components 以下にとにかくなんでもコンポーネントを置いて、さらにコンポーネントの中は秩序をあまり求めない、というルール。サブコンポーネントを複数持った巨大なコンポーネントもいれば、 4 行ぐらいしかない超小さいのもあったりする。

Component について比較的よく見るのが「画面」と「それ以外」でさらに分類する、というようなやつで、僕も昔はそれをやっていたんですが辞めました。というのも何が「画面」なのかは恣意的な分類で意味がないという考えに至ったからです。よくある感じだと react-router で URL 振られているもののトップコンポーネントを「画面」とみなすとかそんなんでしょうか。しかしそれだけ特別扱いする理由もとくにないです。

またモバイルファーストなアプリの場合、モーダルのような挙動であらわれて完全に全画面占有しているものにたいして URL をふるかどうかっていうのも場合場合によって決まってくるし、あるいは PC 版では画面の一要素でしかないものがモバイル版では URL を振ったうえで全画面占有であるといったこともあり得ます。

React Native の場合はさらに難しく、 react-navigation を多段で使っているとかごく普通のことで、結局「画面」というのは極めて恣意的な分類であることがわかります。

というようなことを考えていくと React Component をなんらかのかたちで分類していくことは非常に恣意的で自転車小屋になりやすいのではないか、ということでとにかく全部 Components に入れるし中の実装にもルールとして干渉しない、というふうに今はやっています。 Components ディレクトリ以下にはたくさんディレクトリができますが、まあでもそれで困ってないです、今は。

ただこのあたり今ぼくが働いてる会社のチームの規模だとこれがいい、という話でスキルレベルがもっと分散してたらルールで縛るとか必要になるし、規模が大きいチームだともっとマイクロフロントエンド的な何かでやっていく必要がでてきたりもするでしょう。

まあでもこれくらいの脳筋でも案外どうにかなるっていうか結構快適ですよ。