vite + vanilla-ts で作る超シンプルな Chrome 拡張機能
2024-12-01Chrome 拡張機能の作り方は様々ですが、今回は vite + vanilla-ts の構成で超シンプルな Chrome 拡張機能を作成してみます。
この記事内での前提条件
- Node.js :
v22.11.0 - npm :
10.9.0 - Vite:
6.0.1
create-vite でプロジェクトを作成
まずは create-vite を使ってプロジェクトを作成します。
npm create vite@latest simple-chrome-ex-template -- --template vanilla-ts
simple-chrome-ex-template ディレクトリ配下の構成は下記のようになります。 (npm i 実行後)
❯ tree . -I 'node_modules'
.
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── counter.ts
│ ├── main.ts
│ ├── style.css
│ ├── typescript.svg
│ └── vite-env.d.ts
└── tsconfig.json
これをベースに Chrome 拡張機能を作成していきます。
不要なファイルの削除
まず、拡張機能として不要なファイルを削除していきます。
今回は拡張機能のアイコンをクリックした際に何かしらの処理が走るようなシンプルな拡張機能を作成するため、 UI に関するファイルは不要となります。
なので
index.htmlsrc/style.csssrc/typescript.svgpublic/vite.svg
また、拡張機能のメイン処理を src/main.ts に記述するため、 src/counter.ts も削除します。
結果、下記のようになります。
❯ tree . -I 'node_modules'
.
├── package-lock.json
├── package.json
├── public
├── src
│ ├── main.ts
│ └── vite-env.d.ts
└── tsconfig.json
Chrome 拡張機能として最低限必要なファイルを追加
Chrome 拡張機能として動作させるために、下記のファイルを追加します。
public/manifest.jsonpublic/images/icon-16.pngpublic/images/icon-32.pngpublic/images/icon-48.pngpublic/images/icon-128.png
manifest.json は下記のように記述します。
{
"manifest_version": 3,
"name": "Simple Chrome Extension",
"description": "A simple Chrome extension",
"version": "1.0",
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
},
"action": {
"default_title": "Open the popup"
},
"permissions": ["tabs"],
"background": {
"service_worker": "assets/main.js"
}
}
また、各 public/images/icon-{N}.png は適当なアイコン画像を NxN px で用意します。
ImageMagic がインストールされている環境であれば、下記コマンドで画像を生成します。
mkdir -p public/images
for n in 16 32 48 128; do
magic -size ${n}x${n} xc:white public/images/icon-${n}.png
done
拡張機能の実装
src/main.ts に拡張機能のメイン処理を記述します。
拡張機能の実装に際しては Chrome Extension API を使用するので、 @types/chrome をインストールしておきます。
npm i -D @types/chrome
API リファレンス | Chrome for Developers
そして、 src/main.ts に下記のように記述します。
chrome.action.onClicked.addListener((tab) => {
if (!tab.id || !tab.url) return;
openCurrentPageInNewTab(tab.url);
});
const openCurrentPageInNewTab = (url: string) => {
chrome.tabs.create({ url: url });
};
機能としては、拡張機能のアイコンをクリックした際に、現在のタブの URL を取得し、新しいタブでその URL を開くというものです。
また、 public/manifest.json では assets/main.js を参照するようにしていたので、 npm run build 時にハッシュが付与されない main.js として出力されるように、下記内容で vite.config.js を作成します。
// vite.config.js
import { defineConfig } from "vite";
export default defineConfig({
build: {
rollupOptions: {
input: {
main: "./src/main.ts",
},
output: {
entryFileNames: "assets/[name].js",
chunkFileNames: "assets/[name]-[hash].js",
assetFileNames: "assets/[name]-[hash].[ext]",
},
},
},
});
ここまでできたら、 npm run build を実行すると dist ディレクトリにビルドされたファイルが出力されます。
あとは Chrome の拡張機能設定画面の 「パッケージ化されていない拡張機能を読み込む」 から dist ディレクトリを選択すれば、拡張機能が読み込まれます。
Template Repository として公開してます
今回作成したプロジェクトは GitHub で Template Repository として公開しています。
これをベースに、あなただけの Chrome 拡張機能をサクッと作ってみましょう