React + Vite + Typescriptでchrome extensionを開発する

TL;DR

React + Vite + Typescriptでchrome extensionを作成するためのテンプレートを作成しました。

また、CRXJS vite pluginsを使う方法もありますが、こちらはviteのversionが3までしか対応しておらず、またメンテもされていなかったので基本的に依存はReact, vite, typescriptのみになっています。

illumination-k/chrome-extension-templates

作成したTemplateの機能・使い方

1. background, content-scripts, popupの一括ビルド

UIを構成する部分はReactを使っています。これらはpopup以下で管理されます。

その他のDOM操作を行うためのContent Scriptsはcontent-script以下で管理し、Service workerを利用するためのコードはbackground以下で管理してあります。

これらはpnpm buildでまとめてdist以下にビルドされ、Chrome extensionの開発者モードでアップロードすればすぐに利用できます。

alt text

2. formatter, linterのセットアップ

以下のツールを利用しています。

  • biomeによるTypescriptのformat, lint
  • dprintによる設定フィアル群 (markdown, json, yaml, toml)のformat, lint
  • sort-package-jsonによるpackage.jsonの順序のsort

これらはpnpm fmt, pnpm lintのような形で利用できます。

3. 基本的なGithub Actionsの設定

を行うCIをセットアップしてあります。

中身について

構成

以下のような構成になっています。 基本的には、background, content-scripts, popupは別ディレクトリで実装できるようにしており、buildで全てdist以下にまとめて配置します。

./
├── background/
│  └── background.ts
├── biome.json
├── content-scripts/
│  ├── content-scripts.ts
│  └── main.ts
├── dprint.json
├── LICENSE
├── package.json
├── pnpm-lock.yaml
├── popup/
│  ├── index.html
│  └── src/
│     ├── App.css
│     ├── App.tsx
│     ├── assets/
│     │  └── react.svg
│     ├── index.css
│     ├── main.tsx
│     └── vite-env.d.ts
├── public/
│  ├── manifest.json
│  └── vite.svg
├── README.md
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
├── vite-background.config.ts
├── vite-content.config.ts
└── vite.config.ts

manifests.json

version 3を使っています。また、reactで使う関係上public/manifest.jsonとして管理してあります。

illumination-k/chrome-extension-templates/public/manifest.json
{
  "name": "cext",
  "version": "1.0.0",
  "manifest_version": 3,
  "description": "A simple extension",
  "action": {
    "default_popup": "popup/index.html"
  },
  "permissions": [
    "scripting",
    "activeTab"
  ]
}

設定ファイル

vite.config.tsでPopupの設定を行なっています。 Reactを利用するのもここだけです。

illumination-k/chrome-extension-templates/vite.config.ts
import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      input: {
        popup: "./popup/index.html",
      },
      output: {
        entryFileNames: "assets/[name].js",
      },
    },
  },
});

vite-background.config.ts及びvite-content-scripts.config.tsはほぼ同じで、distに出力するアウトプットを設定してあるだけです。

illumination-k/chrome-extension-templates/vite-background.config.ts
import { defineConfig } from "vite";

export default defineConfig({
  build: {
    emptyOutDir: false,
    target: "node16",
    rollupOptions: {
      input: {
        background: "./background/background.ts",
      },
      output: {
        entryFileNames: "assets/[name].js",
      },
    },
  },
});

illumination-k/chrome-extension-templates/vite-content-scripts.config.ts
import { defineConfig } from "vite";

export default defineConfig({
  build: {
    emptyOutDir: false,
    rollupOptions: {
      input: {
        content: "./content-scripts/content-scripts.ts",
        "content-main": "./content-scripts/main.ts",
      },
      output: {
        entryFileNames: "assets/[name].js",
      },
    },
  },
});

この記事に関するIssueをGithubで作成する

Read Next