michimani.net

vite + vanilla-ts で作る超シンプルな Chrome 拡張機能

2024-12-01

Chrome 拡張機能の作り方は様々ですが、今回は vite + vanilla-ts の構成で超シンプルな Chrome 拡張機能を作成してみます。

この記事内での前提条件

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 に関するファイルは不要となります。

なので

また、拡張機能のメイン処理を 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 拡張機能として動作させるために、下記のファイルを追加します。

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 として公開しています。

michimani/simple-chrome-ex-template: This is a template project for Chrome Extension using vite + vanilla-ts.

これをベースに、あなただけの Chrome 拡張機能をサクッと作ってみましょう


comments powered by Disqus