2024/06/15追記
CRXJS Vite plugin は今も使えるらしく、そっちをつかったほうが楽そうです
参考記事:zenn.dev
React + TypeScript + ViteでGoogle Chrome拡張機能を作る方法をメモしておきます。
なお、以下の環境下での話になります。
// 環境 "vite": "^5.2.0", "typescript": "^5.2.2"
- TypeScriptでプロジェクトを作る
- @types/chromeを入れる
- manifest.jsonを追加する
- マルチページ構成にする
- トランスパイル後もファイル名を維持するようにする
- 参考リポジトリ
TypeScriptでプロジェクトを作る
まずプロジェクトを作成します(ここはViteのドキュメント通り)
npm create vite@latest myapp -- --template react-ts
@types/chromeを入れる
chrome API(例えばchrome.i18nやchrome.tabsなど)を使う場合、chrome
オブジェクトの型定義がなくてエラーになるので@typesをインストールします(TSではなくJSで作るなら不要です)。
npm i @types/chrome
manifest.jsonを追加する
viteのデフォルトの設定ではpublic/
ディレクトリのファイルはビルド時にトランスパイルされずにdist/
に同梱されますので、manifest.json
はpublic/
に置きます。
マルチページ構成にする
拡張機能の開発では複数のhtmlを生成したい場合があります。例えばアイコンをクリックしたときに出てくるpopup.htmlやオプションの設定画面options.htmlといった具合です。その場合はviteをマルチページアプリにすると対応できます。
例えばsrcの中にoptionsとpopupという2つのディレクトリをつくり、それぞれにindex.html等を入れるとします。
src ├── options │ ├── App.tsx │ ├── index.html │ └── main.tsx ├── popup │ ├── App.tsx │ ├── index.html │ └── main.tsx └── vite-env.d.ts
vitre.config.tsでそれぞれのindex.htmlを参照するように設定を変えます。
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { resolve } from 'path' const outDir = resolve(__dirname, 'dist') export default defineConfig({ plugins: [react()], build: { outDir: outDir, rollupOptions: { input: { popup: resolve(__dirname, 'src/popup/index.html'), option: resolve(__dirname, 'src/options/index.html'), background: resolve(__dirname, 'src/background.ts') } }, }, })
もしここでCannot find name '__dirname'.ts(2304)
のようなエラーが出ている場合はnodeのtypesを入れます。
npm i @types/node
また上記のconfigのもとでは、npm run build
したときのhtmlファイルは
dist ├── assets │ ├── background-B9WwJWnc.js │ ├── client-CYooLA_G.js │ ├── option-DptWORB2.js │ └── popup-CQLN0kRt.js └── src ├── options │ └── index.html └── popup └── index.html
という感じに生成されるようになります。
そのため、manifest.jsonをdistディレクトリに置いて拡張機能のパッケージにする場合、manifest.json
は
{ "manifest_version": 3, ... "action": { "default_popup": "./src/popup/index.html" }, "options_page": "./src/options/index.html" }
というふうにそれぞれのhtmlを参照するようにしてやればよい、ということになります。
なお、npm run dev
で起動するdev環境ではそれぞれ
http://localhost:5173/src/options/index.html http://localhost:5173/src/popup/index.html
というパスで確認できるようになります。
トランスパイル後もファイル名を維持するようにする
もし、バックグラウンドで動かす background.js
のようなものを作りたい場合、デフォルトのviteではビルド時にファイル名が書き換えられてしまうため、src/background.ts
はbackground-B9WwJWnc.js
のような[name]-[hash].js
形式の名前になってしまいます。
そこでvite.config.ts
のrollupOptions.output.entryFileNames
を'[name].js'
に設定することで名前が維持されるようになります。
rollupOptions: { ... input: { ... background: 'src/background.ts' // background.tsをビルドの対象に含める } output: { entryFileNames: '[name].js' // ビルド後もファイル名を維持するようにする } }
(参考:ビルドオプション | Vite)
参考リポジトリ
上記を全部入れたコードを置いておきます