ChromeからReactのソースコードを編集できるExtensionを作る
更新日:2022年8月26日

Visual Editorの作成を友達と進めているがもっと簡単なものがChrome拡張で実現できるのではないかと思い付いたので作っていく
やること
Chrome拡張機能
要素の上で右クリックしてReactのソースコードを特定
ファイルを画面に表示する(sandpack使う)
編集して保存する
保存するためにはアクティベートが必要
Chrome拡張作成に参考になりそうなリンク
Chrome拡張公式のGetting Started: https://developer.chrome.com/docs/extensions/mv3/getstarted/
CRXJS Vite Pluginを使って爆速でChrome拡張機能を作るチュートリアル(V3対応): https://dev.classmethod.jp/articles/eetann-chrome-extension-by-crxjs/
Chrome拡張 つくりかた 令和最新版: https://r7kamura.com/articles/2022-05-07-chrome-extension-dev-2022
とりあえず CRXJS Vite Pluginを使って開発の足場を作っていく
https://crxjs.dev/vite-plugin/getting-started/vanilla-js/create-project
をもとにscaffoldingしてvanillaで進めていくとなんとなく開発環境ができた。
Chrome拡張のAPIを参考にやりたいことができるか見ていく
https://developer.chrome.com/docs/extensions/reference/
https://developer.chrome.com/docs/extensions/mv3/manifest/
パーミッションで関係ありそうなところを見ていく
https://developer.chrome.com/docs/extensions/mv3/declare_permissions/
コンテキストメニュー: https://developer.chrome.com/docs/extensions/reference/contextMenus/
ファイル書き込み: https://developer.chrome.com/docs/extensions/reference/fileSystemProvider/
やることをまとめる
調べてきたら解像度が上がってきたのでまとめる
content scriptというページ上で実行できるスクリプトを走らせて、過去の記事で書いたようにfiberを使ってソースコードを特定する。具体的にはcontextMenusを使って右クリックした対象のHTMLからReactコンポーネントを特定し、ソースコードの場所をゲットする

ソースコードをfileSystemProviderを使って読み込み、https://sandpack.codesandbox.io/ を使って画面上にエディターとして表示させる。下からういーんってエディターが出てくる感じにしたい。
sandpackのonSave的なイベントを起点にfileSystemProviderを使って対象のソースコードに書き込みを行う。エディターはういーんって下に下がる。
あとは自動で開発サーバーなりなんなりのHRMが動くだろうからソースコードに反映されるという仕組み。
これでブラウザから離れることなく対象のコンポーネントをブラウザ上で編集できるということになる。
実装していく
まずはcontentsスクリプト上でfiberを動かすところまで実装
content scriptの実行はこんな感じでvite.config.tsを書いたらいけた
import { defineConfig } from "vite";
import { crx } from "@crxjs/vite-plugin";
export default defineConfig({
plugins: [
crx({
manifest: {
manifest_version: 3,
name: "React Chrome Editor",
version: "1.0.0",
content_scripts: [
{
js: ["src/content.ts"],
matches: ["<all_urls>"],
},
],
},
}),
],
server: {
port: 8080,
},
});
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ にアクセスしても値が返ってこない
https://stackoverflow.com/questions/20499994/access-window-variable-from-content-script
とりあえずソースファイルの取得はできた。
fileSystemProvider を使ってパスからファイルを読み込む<-ここから
https://vscode.dev/ の動きが参考になるはず
https://web.dev/file-system-access/
ファイルの読み込みができたら sandboxでコードを表示するが、devtoolsに表示する方がいいかも?
https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools
現在選択している要素はこれで取得した方がいいかも?
いろいろ調べて考えが変わった
React dev toolsみたいなものを作るのが良さそう。
インスクターで要素を選択したらファイルが開き、編集するみたいな流れ
ファイルを読み込む、書き込む権限がない場合は権限取得の必要がある
ファイルの読み込みや権限などについては知見が得られた。
コンテントスクリプトでやるよりもdevtoolsの拡張を作成した方が筋が良さそう
雛形として下記のレポジトリが良さそう
https://github.com/jacksteamdev/crx-react-devtools
PanelApp.tsx 上で開発を進めていく。PanelAppのコンポーネント上で右クリック->Inspectでコンソールが開く。
インスペクタの動きはreact-dev-toolsを参考にする
devtoolsについての概要
https://developer.chrome.com/docs/extensions/mv3/devtools/
開発ツールの開発についてめちゃ参考になる記事
https://qiita.com/moajo/items/8241719479987697ca37
今回やりたいことに近い機能がDevtoolsにあることを今知った。
https://developer.chrome.com/docs/devtools/workspaces/
MobXのChrome Extensionの動きも良さそう

いずれにしても一旦やりやすい方法でいいからイメージできるところまで実装するべき。
一旦Content Scriptでできるところまでやってみる?
いろいろわかった。
content-script.tsとcontent-main-world.tsはpostMessageで通信して、
content-script.tsとdevtools.tsはchrome.runtimeのMessageで通信するんだ
devtools側でファイルを書き換えたりことが難しいことがわかった。
セキュリティの問題でcontent script上でディレクトリーを選択し、ファイルに対する操作を行う必要がある。
なのでdevtools側ではエディターを表示する、描画する文字列を送る、編集した文字列を送るという処理を行う。
また、インスペクタやワークスペースのマウントはdevtools側にあるが、起動をするだけでメインの処理はcontentsスクリプト側で行うことになる。
なんとなく構成ができた

なんかいい感じの欲しかったものができた
とりあえず欲しかったものができた。要素を特定して、ソースを表示して、編集できるものができた。 あとはReact-devtoolsがある前提なのでreact-devtools-inlineを内包した方がいいと思うけど、なんかエラーがいっぱい出て面倒だったのでそこは後々改善する必要がある。

まだなんか公開するというレベルではないので、後々何かしら他の人も使える物にしたいとは思っている。