2021年に作ったモノや技術をふりかえる

f:id:laiso:20211224210727j:plain

前回までのあらすじ:2020年に作ったソフトウェアや開発技術をふりかえる - laiso

Write Code Every Day

プログラマーの人にありがちな趣味だと思うんだけどWrite Code Every Day (John Resig - Write Code Every Day)を2008年ぐらいからやっていて、昼に仕事でコード書いて夜になったら自分の楽しみのために何か作るか〜というのを繰替えして生活してる。

John Resig の記事との違いは今読みながら比較していたんだけどGitHubに上げるっていう部分はやらなくなってしまった。クレデンシャルとかハードコードしてるやつとか半分他人のコードコピペしたやつとかの清書がめんどくさいというのがあるし、クローラーなどは自分だけが使うぶんにはいいけど公開した方が迷惑になる——みたいなジャンルのコードが結構あって段々省くようになってしまった。

作ったソフトウェアもポートフォリオとして収めてゆくゆくは個人開発で一発当てるぞ! という自意識を持っていたんだけど最近はとりあえず自分や知り合いだけが使えるプロトタイプをたくさん作ってすぐ捨てるという行動になってる。

便利なものを思い付いても実際に作ってみるまで便利か分からんから作りながら考えてるみたいな状態なので、まずは他人に使ってもらうためのエネルギーをかけずに作ること自体を目的にしだした。

YouTubeを観るやつ(Google Drive/Serverless Next.js Component etc)

コーディングってものづくりするクリエイターのイメージがあると思うんだけど、僕は「ブラウザとかアプリケーションを操作してウェブサービスを使う」という行動と同じ目的でスクリプト書いてサービスを使うっていうのをよくやってて、この時は「消費者としてプログラムをインターフェイスにしてコンテンツにアクセスしてるな」っていう気持ちでいる。

YouTubeTwitterを見るツールもその類で何個も作って使っていて、今年はYouTube関連のものを多く作った気がする。

チャンネルは個人とかグループとかが開設してて事務所に所属して出演者たちがプロデューサー兼監督兼編集兼なりを全部自分たちでやってるようなのを好んでる。芸能人やテレビ番組的に作られてるやつはあんまり観てない。VTuberやTuberやゲーマーがやってるストリーミング配信も多い。

ライブ配信はたいてい長時間に及んで全部観てられないので、多くの人は切り抜き動画っていうファンが善意で編集して複製してる動画が主流のようだった。ただ僕は複製しないでも見たいところだけ見られるツールがあればいいんじゃ? と思ったので、自分で作ることにした。

まずはYouTubeライブチャットリプレイコメントを取得して*1自分のGoogle Driveに保存しておくことで動画の任意の箇所を検索して再生できるようにした。これのフロントエンドにNext.jsを使った。

最初は Vercel でホストして動かしていたんだけど転送量などの無料プランの制限の限界が来たのでAWSに引越した。AWSにしたことで料金も月5ドル以下になった。

この過程で制限を越えたままVercelを使い続けるとアカウントのすべてのアプリケーションが HTTP 402 Payment Required を返すようになるというのを知った(Payment Requiredなのは来訪したユーザーじゃなくて管理者なのでは?という話もある)。刃牙の家っぽい。

「402 Payment Requiredやlaisoォ!!」 *2

ヘルプページによると一度402の刑になると30日間凍結されるらしいから待っていたんだけど、全然解除されなかったので反省文を2回ほど送ったところ今は解除してもらえた。

ちょうどAmplify Console がISRに対応したというニュースが来た頃で*3 Amplifyで組んでいたんだけどうまく動かなかったので、ソースコードを見に行って中身がServerless Next.js Componentであることが分かったので直接使うことにした。

直接使ったらうまく動かなかった部分も分かったのでついでに直してプルリクエストしたら取り込んでもらえた。ので以下を書いた。

デスクトップ版

ライブチャットリプレイの取得はChrome拡張でYouTube上に組込むバージョンや、オンブラウザで動いてElectron 経由でSQLite3に保存して全文検索かけるリアルタイムバージョンも作ってみたんだけどやはりデータ容量や検索速度を気にしなくていいぶんGoogle Driveを使い続けるのがよさそうだった。安いし。

でもこの時にVue3をいっしょに試した。Vue 3にする場合、コンポーネントライブラリの選択が曲者で、いろいろ探した末 Element Plus に落ち着いた。

Chrome拡張やElectronは数年ぶりに使ったんだけどどちらもIPCのAPIがこなれてて使いやすくなっていたので、また何か作りたい。

ギガッ

「独自ツール開発してYouTube動画観てる」というのを人と話してて、それを他の人でもできるようにするにはどうすればいいんだろう? と思って作ってみたのがこれ(新しめのチャンネルに対応してない)。ネタバラシすると「草」で検索して並び替えてるだけ。

そういえばVercelの無料枠を使いきったのはGIGAZINEで紹介されたせいだった。GIGAZINEゆるせねぇ・・

自然言語解析(Mecab/Gensim etc)

上記はgrep草ことAIなんですけど、チャットの投稿のメッセージには時間とテキストがあるのでテキストを解析したら再生時間 XX:XX 秒の特定の箇所に話題のメタデータを付けたりコメントの感情が変化したことを検知できるのでそれを使ってなんかできないかなーと思っていろいろ試していた。

基本戦略としては形態素解析でバラしてWord2vecで分類してっていうのとシンプルなネガポジ判定なんですけど、テキストが短か過ぎるのかあんまり予想どうりの結果にはならなかった。もうちょっと基礎知識があれば改善できるかもしれない。Gensimっていうライブラリをよく使った

NotionのページをFlutterアプリにするやつ(Server-Driven UI/Flutter)

AirbnbがGraphQLでネイティブアプリのコンポーネントを動的に組替えてるっていう記事に触発されて似たようなの作りたいと思って書いてたアプリ。

仕組みは簡単でNotion APIで接続したユーザーが共有したページとDatabaseのブロックデータを取ってこられるので、定義に従って用意されたFlutterアプリのコンポーネントで再生するというもの。

Notionのページ情報には他のページへのリンクも含まれるのでFlutterのNavigateをうまく使うと画面遷移も組替えることができる。宣言的UI万歳。

ただ

  • Notion APIがまだ対応してないパーツがある(カラム分けやRemarkや)
  • Authorizationがネイティブアプリで使いづらい

という諸問題もあり、完成できてない。

パーツは待っていれば対応されそうだけど、Authorizationは例えばユーザーが notion.so で権限を許可したら→中間サーバーにリダイレクトして→myapp://にまたリダイレクトして→アプリのメモリ内に存在するUUIDをチェックして——というフローがもうちょっとなんとかスマートに実装できないのかねと気になってる。

Flutterについては以下の本を副読本に買った

Riverpod

よくあるProviderを使ったコンポーネント間のデータ管理しか作ったことなかったんだけど、次世代のState-Managementフレームワークとして聞いていたRiverpodを導入してみた。結構前の記憶なので忘れちゃったけどReact HooksのプリミティブなAPI使っているようなイメージだった気がする。便利だった。

FlutterKaigi 2021 で知ったんだけど、Riverpodの代替としてGetXというパッケージを使っている人たちもいるらしく、そっちも気になってる。

従来型SPA代替技術(Hotwire/Livewire/Inertia.js)

ウェブアプリケーションフレームワーク界隈では最近はSPA代替技術の開発が盛り上っていてRails 7.0には標準でHotwireが使えるようになった。

Stradaはまだリリースされてなく。噂では来年になるらしい*4

SPA代替技術は先行するLaravelのLivewirePhoenixLiveViewASP.NETBlazorあたりとセットで「JavaScript以外で動的なUI書く」のを語られることが多い(flutter_webも入れていいかもしれない)。

JavaScript以外で書くと言っても多くの処理はクライアントサイドのJavaScriptライブラリのエンジンが肩代わりしていて、フレームワークのユーザー側に簡単なレールが提示されてそれに則ってUIを作るというスタイルが一般的になっている。

プログラミング言語の話に終始しがちだけど重要なのはAPIサーバー/クライアント/UIバインディングの定型的なコードをなくしてる点だと思った。その点でスキーマコードジェネレーター系も同カテゴリに入れていいのかもしれない。ReactやVueのコンポーネントをサーバーサイドのテンプレートファイルにすることを目指すInertiaも意欲的なので注目してる。

個人開発という点ではHotwireの筋の善し悪し以前にPostgreSQL/MySQLサーバーの維持コストが嵩みがちなのでRailsやLaravelの出番はあまりなかった。後述の新興DBaaS勢が今後目立ってくるようになったら試しに組合せて運用してみるかもしれない。

Twitter(俺だけ)便利ツール

YouTubeと同じくコンテンツ消費のためにプログラミングしてる例なんだけど、僕はTwitterが公式に用意してるフォローの機能を使わずにリストとか検索系のAPIを叩いて利用しているのでそれを今年も保守していた。

その過程で「検索結果を綺麗にするために大量にMuteする」っていう機能が必要で、"AWS"で検索すると特定の動物園情報が来訪客が含まれたり"GCP"で検索すると医療情報やメイド喫茶が出てきたりするのから自分の欲しいクラウド関連のニュース関連だけに絞るためにやってる。

しかしTwitterのMuteの挙動上「Muteしたけど検索結果に残るアカウントある」とか「usernameはそもそも無視したい」などの問題があったので自分のプログラム側でフィルター処理を作ることにした。これの構築にSvelteKitを使ってる

SvelteKit特有の機能たしいて使ってないんだけどVercelアカウントはバキの家にされちゃったのでNetlifyにデプロイして便利に使ってる。Twitterログインはちょっと癖があった

本当は難しいツイ消し

ツイート全部消すのはAPI制限上難しい=最大何件までしか遡れない。っていう問題を聞いて、じゃあ世の中のツイ消しサービスはどうやって実装してるんだろうと思って調べていた。

簡単に説明するとTwitterアーカイブダウンロード機能でエクスポートできるJSONファイルにidが載っているのでそれをユーザーにアップロードさせてパースすることで1つ1つ削除APIを叩く。という方法を実現しているようだった。

この処理はぱっと想像してみてもサーバーのリソースを結構食いそうで、みんな有料機能として提供していた。

有料サービスを使ってもいいんだけどGitHubtwitter-cleanerというGoで書かれたプログラムを公開している人がいてそれを実行するのが良さそうだった。便利賞なので数ドルsponsorで送った。

動作確認していたら自分のツイート全部消えたけどまぁいいか。的な

チャットの話題提供BOT(Cloud AutoML)

f:id:laiso:20211224212219p:plain

チャットにインターネットのおたく(この場合パソコン愛好家の意です)がリンクをシェアするとそれについて各自が話出すみたいな作法があるんですけど、だいたい情報源のサイトやTwitterなりが限られているし話している話題も偏ってるから、おたくが好きそうな話題を自動でシェアできるようにならない? って思ってBOTを作っていた。

Slackのログをエクスポートしてきてリンクを抜き出しトレーニングデータにする、機械学習でいい感じに機械が学習。情報源となるニュースサイトのリンク一覧と付き合わせてニュースサイトに更新がある度に「このリンクは%ぐらいお宅のおたくが好む」っていう数字を出してくれるので、閾値を上まわったらそれをBOTがチャットに投稿する。という流れで実装した。

このトレーニングとモデルのデプロイにCloud AutoMLを利用した。

CSV掃き出してAPIで自動化するだけなので超簡単にできるんだけど、トレーニングするために僕のクレカに5000円づつチャージされていて遠い目になってきたので停止してしまった。

BOTの動作環境はCloudflare WorkersとDeno Deployを比較してCloudflare Workersにした。

エッジで動くアプリケーション

余談だけど今はブラウザ向けのJSは軽くして重い処理はサーバー側のBFFの裏のNode.jsに任せるっていうのが一般的だけど、こういうフロントのサーバーがCDNの軽いランタイムで動くようになるとNode.jsで書いてた重い処理の全面にHTTPベース完結する軽い層が必要だなとRemixを使っていて思った。Micro Frontendsの将来かもしれない。

日英日翻訳

f:id:laiso:20211224212407p:plain

機械翻訳を重ねがけして精度を上げるみたいなライフハックが話題になっていて*5、たしかに確かにやったことあるなーと思ったものの毎回フォーム操作するのが面倒だなと思ったので1クリックでできるようにした。

これに早くからVue3に対応していたIonicを使った。レスポンシブデザインなUI何も考えずに作れて楽だと思う。Angularでずっと使っていたけど最近はReactやVueでも書ける。

Compose Multiplatform

JetBrainsがAndroidJetpack Composeのマテリアルコンポーネントをデスクトップやウェブにも適用できるCompose Multiplatformっていうフレームワークを公開していて注目してる

出てきた時は「Kotlin版Flutterだ!」と思ったんだけどソリューション的にはElectronとかJavaFXでアプリケーションを書く時の代替手段になりそうだった。

次世代IDE Fleet のフロントエンドをこれで作っているのでは? と予想しているんだけど、公開されている情報は見あたらない(中の人がKotlinとC++で書いてると言ってるのは見た)

Kotlin経由でReactコンポーネント書くサンプル がお気に入り

DBaaS(PlanetScale/Supabase)

Firebase以降の新興のDBaaSが色々出てきていてPlanetScaleとSupabaseを定期的にチェックしてる

PlanetScaleは個人開発者の文脈でいうとHeroku Postgres アドオンで格安でウェブアプリケーション動かしたかった人の選択肢として朗報だと思う。裏側にVitess クラスタがあって(たぶん)ユーザーとしてはネイティブのMySQLドライバーでORMからインターネット越しにアクセスできる。

Isomorphic JavaScript勢にも向いててLambdaでコネクションプーリングどうするのという問題もエンドポイントの向うで解決してくれていた

SupabaseはフロントエンジニアフレンドリーなSDKを提供するBaaSでそれがFirebaseとの差別化になっているようだ。

こちらもアジアリージョンにPostgreSQLサーバーを立ててくれてネイティブドライバでアクセスできる。クライアントサイドから使う時は基礎技術のPostgREST をベースにしたSDKを使ってDSLでアクセスし、認証認可もする。

このためフロントエンドがDB触るためにバックエンドAPI構築するっていう作業が省けるし、バックオフィスの管理画面は別途好きなウェブフレームワーク使うのとかできる(スキーマ管理がごちゃりそうだが……)。

コンポーネントが全部公開されててマイクロサービス思ち帰りセットになっているので、例えば自分のAWS環境にSupabaseと同じ環境を作ってDBはRDSにして使うってことができるのだと思う。

Ethereum

スマートコントラクトをデプロイしてWebアプリと連携して動かすっていう開発に再入門した。2018年ぐらいにもやっていたので開発環境自体は分っていたんだけど、色々こなれててフロントエンドエンジニアが触りやすく進化していた。

開発ツールはHardhatが使いやすかった。TypeScriptをサポートしていたりAPIクライアントにweb3.jsの代替としてethers.js を使っているのでドキュメントがあったりする。

ネットワークの入口となるノードサービスと開発プラットフォームはAlchemyを使うようにした。使ったことないけどクライアントサイドライブラリとかNFT便利API機能とか付加価値が付いてくるようだ。

ネットワークはなんとなくPolygonってやつ使ってる。理屈はよく分からんがwebpackとesbuildみたいな関係ではと解釈してる。

トークンにひもづくアセットはIPFSネットワーク上に置くのが通例らしい。Pinataをゲートウェイに使っている例が多かった。

Solidityを使ったアプリケーション開発は、翻訳なのでちょっとバージョンが古めだけど以下の本が良かった

ブロックチェーンを使って何かおもしろいものが作れそうかというとまだまだ知識が足りてないのでピンときてない。Web3ビジョナリストの言う利点は分かるけど、ユーザーとしての自分は特に求めてない、ぐらいの塩梅にある。ソフトウェア開発というより経済学とかの素養が必要なのか? と疑ってる。

でも今のところERCのプロポーザル見てるのが一番勉強になるかもしれない。

Solana

早い安いRustが書けるみたいな触れ込みで知って。Rustを書く理由を求めていたのでEthereumを一緒に入門した。Solidityなかなかいいなと最近思えてきたのであんあり動向をチェックしてない。

SQL

去年SQLを何回勉強しても分からないと書いたけど*6 実際に分からない=身についた感触がないのはデータベースを使ったプログラミング全般だと思ったので再入門した。

今年は以下2つの本を読んだら大分苦手意識が減った。

今まではORMのAPIレベルで思考していて、このAPIを使う時に発行されるSQLはこれで——という手順を踏んでいたけど実は逆で、SQLでもNoSQLでもクエリを基準に構造を考えることが重要だと思った。

  1. アプリケーションの機能に対してSELECT/INSERT/UPDATE/DELETEクエリを考える
  2. そのクエリがシンプルにできるテーブル設計を考える
  3. 考えたクエリをORMのAPIで再現する
  4. アプリケーションのプログラミング用に型付けする(DBの詳細は隠す)

というやり方に宗旨変えしたらうまく組めるようになった

MacBook Air(Apple M1)

一番安いMacBook Airを買った。

開発に使う場合、コンパイル速度とディスク容量が足りなくて困ってる。

とくに

がディスクを馬鹿食いしていて消したり入れたりして運用でカバーしてる。今ならProにしそう。

Xiaomi 11T Pro

iPhone 11 をずっと使っていたんだけどMNPを期にXiaomi 11T Proに機種変した。120W急速充電というので10分ぐらいで充電が完了するので、給電を習慣にしなくてよくなった。

まとめ

  • パソコンを使うこととコードを書くことが地続きの生活にある
  • WebのUI開発はもうひと段階の変化が起きそう
  • 良いお年を