✅️2026/2/19 TypeScriptで楽にUserScriptを書きたい
UserScriptを書くのが辛い
→cosense-userscript-devを作った
次のような課題がある
JSしか動かない
かと言って、型なしで書くのはもっと辛い
エディタ上で開発できない
ブラウザへコピペしないといけない
リロードして読み込まないといけない
コードをGitで管理できない
Cosenseのhitstoryには残るが
泣く泣くこういう作業をしていて面倒くさい
エディタ上でTypeScriptで書く
コンパイルしてJavaScriptにする
JSをコピペしてCosense上に貼る
読み込むためにCosenseをリロードする
どうにかしようmrsekut.icon
イメージ、こういう感じで読み込めると嬉しい
code:script.js
fetch('http://localhost:3456/sample.js').then(r=>r.text()).then(eval)
やってみたがだめだった
JS→TS
普通にBun.build()で
CSPを回避する
CosenseのUserScriptでCSPを回避する
これで、tm用スクリプトを生成して読み込ませれば動くようになったmrsekut.icon*2
ただ、scriptを追加するたびにtmコードを編集するのがダルい
/_scripts エンドポイントを追加してローダー再生成をやめる
問題
以前のローダーはスクリプト一覧をハードコードしていた:
code:js
// loader.user.js(旧)— スクリプト名が直書き
loadScript('http://localhost:3456/bot.js');
loadScript('http://localhost:3456/sample2.js');
loadScript('http://localhost:3456/sample.js');
新しいスクリプトを scripts/ に追加するたびに bun run loader でローダーを再生成し、Tampermonkey に貼り直す必要があった。
解決
dev-server にスクリプト一覧を返す API エンドポイントを追加し、ローダーは起動時にそこから取得する。
dev-server.ts に/_scriptsエンドポイントを追加
dist/内の.jsの一覧を返す
code:_
$ curl http://localhost:3456/_scripts
"bot.js","copy_pages.js","open_pages.js","sample.js","sample2.js"
loader.user.jsのloadAllScriptsでそれを読み込む
ブラウザのリロードがダルいのでこれも自動化する
/_versionでversionを返すエンドポイントを作成
code:_
$ curl http://localhost:3456/_version
{"version":1771468380069}
ローダーがそれをポーリングして変更を検知したらリロードする
なぜ再 eval ではなくページリロードか?
cosense.PageMenu.addMenu() を再 eval すると同じメニューが重複登録される
DOM に追加した要素も重複する
ページ全体をリロードすればクリーンな状態から実行されるので副作用がない
本番適用を楽にしたいか?
上記でやってきたことは開発時の話で、完成したら結局コピペでcode:script.jsを貼る必要がある
例えば以下のような選択肢がある
A. Tampermonkeyで本番もホスティング
ローダーのURLを localhost → GitHub Pages/raw に切り替える
git が source of truth、履歴も残る
ただし Tampermonkeyが全端末に必要
これがキツイmrsekut.icon
B. CI → Cosense API で自動デプロイ
git pushをトリガーにGitHub ActionsでCosense APIを読んでページのコードブロックを更新
しかし、ページ書き込み系のAPIはなかったはずmrsekut.icon
強いて言えば、UserScript Page Edit APIはあるが、やや大仰になりそうか
C. 今まで通りコピペする
いったんこれでmrsekut.icon
関連
/villagepump/ElectronでUserScriptの試行錯誤をしたい