コンテンツにスキップ

body に React を埋め込む

1
2
$ npm i react react-dom
$ npm i -D @vitejs/plugin-react @types/react-dom

manifest.jsonを以下のように定義することでcontent_scriptsで tsx を扱うことができる。

manifest.config.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { defineManifest } from "@crxjs/vite-plugin";

export const manifest = defineManifest({
  manifest_version: 3,
  name: "Web Tweaks 2",
  version: "2.1.0",
  description: "",
  icons: {
    "16": "icons/16.png",
    "48": "icons/48.png",
    "128": "icons/128.png",
  },
  action: {
    default_popup: "index.html",
  },
  content_scripts: [
    {
      matches: ["https://qiita.com/*"],
      js: ["src/qiita.tsx"],
      run_at: "document_start",
    },
  ],
});
vite.config.ts
1
2
3
4
5
6
7
8
import { crx } from "@crxjs/vite-plugin";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import { manifest } from "./manifest.config";

export default defineConfig({
  plugins: [react(), crx({ manifest })],
});

以下をマージする。

tsconfig.json
1
2
3
4
5
{
  "compilerOptions": {
    "jsx": "react-jsx"
  }
}
src/qiita.tsx
1
2
3
4
5
6
7
import { createRoot } from "react-dom/client";
import { App } from "./App";

const container = document.createElement("div");
document.body.appendChild(container);

createRoot(container).render(<App />);
src/App.tsx
1
2
3
4
5
6
import { useState } from "react";

export function App() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount((c) => c + 1)}>{count}</button>;
}