以下の内容はhttps://fs0414.hatenablog.com/entry/2025/11/02/032114より取得しました。


開発に使う推しライブラリ - 交換ブログvol.7

vol.7ですね。学生の頃はサッカーをやっていて、背番号は大体7番でした。今はアーセナル推し。
fujitani soraです。

2323-code.hatenablog.com

topi-log.hatenablog.jp

交換Blogずにふみさんが入ってくれました。
うれしい

初めましてはコラコンの時ですね。
2回目が12月にある

【先着500名】CoLab Conf(コラコン)【U35限定テックカンファレンス】 - connpass

技術よりのテーマですが、友人との軽めのブログ交換って感じなので、そこまで厳密なことを書いているわけではありません。
詳しいことを知りたくなったらReferenceへどうぞ

Biome

https://biomejs.dev/ja/

ToolChainの統一を掲げて出てきたTypeScriptのlint/formatライブラリですが、ぼくのRust langへの興味の起点になってくれたのがこのBiomeだったりします。
よく言及されるであろう、既存ライブラリと比べた時の速度に関しては、正直当初は「別に既存linterの速度で困ることはないし、そんなに早くなってもな...」と考えていました。
加えてBiome1系ではno-floating-promiseなどの安全性に強く作用するruleがサポートされていなかったこともあり、自分のコントロール範囲では導入を見送っていました。
考え方を変えたのは、TSKaigi2025 AI Coding Agent Enablement in TypeScriptのセッションを拝見してからです。

speakerdeck.com

人間とAIで速度に対する重要度が違うのは確かにそうで、人間が実行するツールと、実行コードが依存するツールとでは速度に対するプライオリティが違ったが、その差が縮まってくるようなニーズが生まれていると感じています。
Biome2系からは内部実装の変化もあり、上記で挙げた重要なruleへの対応や、GritQLによるcustom ruleのサポートも加速しています。
こうなってくると、依存がBiomeに統一されることや設計のシンプルさなども含めて、Biomeが今では第一選択肢に上がるようになりました。

一応、自分は別に既存ツールが嫌になったわけではないです。
Prettierとかにはたまにcontributionもさせていただいていますし。

そんなBiomeですが、やはり競合は多いようで、下記のエコシステムの変化を観測しています。

簡単には変えにくいRepositoryでTypeScriptを選択するときは、この辺りは検討する必要性がありそうですね

ast-grep

ast-grep | structural search/rewrite tool for many languages

抽象構文木を利用したgrep toolです。
通常のgrepでは文字列や正規表現によって検索を行います。よく使うのはfzf, rg, git grepとか。
対して、ast-grepではast構造を踏まえた抽象的な構造検索ができます。

ast-grep reference Pattern Syntaxより引用
Pattern Syntax | ast-grep

// Given this pattern

$_FUNC($_FUNC)

// it will match all function call with one argument or spread call
test(a)
testFunc(1 + 1)
testFunc(...args)

具体的な文字列ではなく、検索に変数を利用したastパターン検索が可能

下記はRails projectで運用したast-grepの例です。

  • erbでのxss脆弱性の可能性があるコードの検出
id: xss
message: Potential XSS vulnerability detected. User input is being rendered without proper escaping.
severity: hint
language: Html
note: |
  XSS (Cross-Site Scripting) occurs when user input is rendered in HTML without proper escaping.
  Use Rails' built-in escaping methods or sanitize user input before rendering.

rule:
  kind: text
  regex: "<%=\\s*raw\\s+"
# 検出されるコード例
<%= raw @user.bio %>
<%= raw user_input %>
<%= raw  content %>
<%=raw@variable%>
  • 変数を利用したpath traversal脆弱性の検出
id: path-traversal
message: Potential Path Traversal vulnerability detected. User input is being used to construct file paths without validation.
severity: hint
language: Ruby
note: |
  Path Traversal (Directory Traversal) occurs when user input is used to construct file paths
  without proper validation. This allows attackers to access files outside the intended directory.
  Validate and sanitize file paths, and use File.basename() or similar functions.

rule:
  any:
    - pattern: Rails.root.join($$$, $VAR, $$$)
    - pattern: File.join($$$, $VAR, $$$)
    - pattern: send_file $VAR
# 検出されるコード例
# パターン1: Rails.root.join with variable
Rails.root.join('uploads', params[:filename])
Rails.root.join('data', user_input, 'file.txt')

# パターン2: File.join with variable
File.join('/var/www', params[:path])
File.join(base_path, user_id, filename)

# パターン3: send_file with variable
send_file params[:file]
send_file user.document_path

このようなprojectのruleに沿わないルールや脆弱性のあるコードの検出を、各言語毎の対応に比べて、ast-grepという汎用的なツールの利用によって知識やリソースを横展開できることにはメリットがあると感じています。
最近はAgentのルールにmdを介してast-grepのルールを読み込ませることも試しており、AIとの親和性にも期待大。
ソースコード起因で発生したインシデントからのフィードバックをast-grep ruleとして記載しておくことで再発防止に繋がるケースも期待できそうです。

また、ast-grepの特徴として、ast構造を利用したコード書き換えの機能があります。
最近で活用した事例としては、Remix2.9で導入されたSingle Fetchによる破壊的変更への対応がありました。

asis

export async function loader() {
  const posts = await getPosts();
  return json({
    posts,
  });
}

tobe

export async function loader(params) {
  const posts = await getPost(params.id);
  return posts;
}

端的に言うと、jsonで囲う必要がなくなった。それによるno-unused-importsからの削除も必要。
必要なdiffが100fileほどあったこともあり、単純に手を動かすにはブチギレ作業でしたが、ast-grepのwrite optionを利用することで最小工数で修正を終えることができました。

rules:
  # json() の削除
  - id: remove-json-wrapper
    language: typescript
    rule:
      pattern: return json($OBJ)
    fix: return $OBJ
  
  # import { json } の削除
  - id: remove-json-import
    language: typescript
    rule:
      any:
        - pattern: import { json } from "@remix-run/node"
          # 他のimportがある場合は json のみ削除
    fix: ""
# search
ast-grep scan

# exec
ast-grep scan --update-all

NeoVimとの連携などもあり、個人的にはよく利用する推しツールです。

base64-chrome-transfer

github.com

これは自分の日曜大工成功例で、base64 encode/decodeをブラウザから簡単に行うためのChrome Extensionです。
ソースコードは、要件だけ伝えて改善していないこともあり、Denoで作った関数群をjsトランスパイルしてブラウザで動かせるようにするみたいな奇怪な操作をしています。いつか直す。

前提として、関わっているprojectで下記のようなつらみを感じていました。

  • GraphQLサーバであり、http req/resでやり取りされるIDがbase64 encodeされている
  • GraphQLのAPI実行にはApolloClientを使用しており、Webからlocalhost経由で実行していた。
  • 特定データをDatabaseClientから確認したいときにはresponseから生のIDを知りたい、requestを実行する際にはecodeされていることが必要、みたいな時に「terminalを開いて echo "Obj:12345" | base64 と実行して変換してから操作を行う」みたいなことをしていた
    • WebのBase64変換ツールからやってもいいが、terminalをRayCastに割り当ててすぐ開ける環境にはしているのでその方が速かった
    • また、似たようなBase64変換のChrome拡張はあるが、機能が足りなかったりオーバースペックだったりで合わなかったので作った

このWindowの行き来に心を痛めた僕が片手間に作ったのがbase64-chrome-transferです。

こんな感じでApolloClientから移動せずにChrome拡張機能として開くことができ、自作ツールで開発体験が向上したいい例になりました。

もっと自作やカスタムして不便なことを忘れていきたいですね

まとめ

意外と真面目に書いてしまった。
その他のツールだと今は、rv(Rust製のRuby Version Maneger)、mini.nvim(NeoVim Pluginのセットみたいな)、Temporal(JavaScriptの新しい日時操作API)なんかをチェックしています。
言うまでもないがClaude Codeとかも

次はふみさんですよろしく!!




以上の内容はhttps://fs0414.hatenablog.com/entry/2025/11/02/032114より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14