VueでChrome extensionを開発する
参考リンク
- Extensions - Chrome Developers
- GitHub - GoogleChrome/chrome-extensions-samples: Chrome Extensions Samples
- https://www.memory-lovers.blog/entry/2022/11/22/163000
- Create a project | CRXJS Vite Plugin
- Building for Production | Vite
- vite-plugin-mpa/main.ts at main · IndexXuan/vite-plugin-mpa · GitHub
- Chrome拡張機能を作ってみる | 2. 登場人物編 - くらげになりたい。
- 【Vue3+TypeScript+Vuetify+Vite】動的なテーマの切り替え - Qiita
CRXJSを使うと開発中のホットリロードが使えて良さそう
Chrome拡張の機能
公式ドキュメント: Extensions - Chrome Developers
サンプル集: GitHub - GoogleChrome/chrome-extensions-samples: Chrome Extensions Samples
Manifest V2 と V3について
Chrome extensionで現在利用できる仕様はManifest V2
とManifest V3
がある
Manifest V2
は近々廃止される予定なので新規でextensionを作る場合はManifest V3
を利用する
chrome extensionについて調べるとmanifestv2の情報が混在してるので注意
機能
- ポップアップ
- 設定
- バックグラウンド処理
がある
CRX JSを利用してプロジェクトを作成する
Create a project | CRXJS Vite Plugin
npm init vite@latest
Need to install the following packages:
create-vite@4.2.0
Ok to proceed? (y) y
✔ Project name: … vite-project
✔ Select a framework: › Vue
✔ Select a variant: › TypeScriptcd
cd vite-project
npm i @crxjs/vite-plugin@beta -D
vite.configをの内容を以下に変更
Cannot find module './manifest.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.ts(2732)
のエラーが出るが解決法がわからない。一旦無視でも動く
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { crx } from '@crxjs/vite-plugin'
import manifest from './manifest.json' assert { type: 'json' }
export default defineConfig({
plugins: [
vue(),
crx({ manifest }),
],
})
manifest.jsonを作成する
{
"manifest_version": 3,
"name": "CRXJS Vue Vite Example",
"version": "1.0.0",
"action": { "default_popup": "index.html" }
}
npm run dev
を実行してローカルで画面ひらけばOK
chromeでchrome://extensions/
を開く
Finderから vite-project/dist
フォルダを画面にドラッグドロップするとchrome拡張が追加される
追加した拡張機能をクリックすると、ポップアップで先ほどのローカルと同じ画面が開く
ポップアップ
manifest.jsonの action で内容を設定する
default_popupに利用するhtmlを指定する
{
"action": {
"default_title": "Chrome Extension",
"default_popup": "src/pages/popup/index.html",
"default_icon": {
"16": "public/icon_16.png",
"48": "public/icon_48.png",
"128": "public/icon_128.png"
}
}
}
Vueファイルをhtmlに変換したものをpopupに利用するため、以下の設定をする
src/pages/popupフォルダを作り以下を追加する。
<script setup lang="ts">
import OptionPage from '../../components/OptionPage.vue';
</script>
<template>
<OptionPage/>
</template>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Regex Url Blocker</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.ts"></script>
</body>
</html>
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
vite.configに以下の設定を追加
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { crx } from '@crxjs/vite-plugin'
import { resolve } from 'path'
import manifest from './manifest.json' assert { type: 'json' } // Node >=17
export default defineConfig({
plugins: [
vue(),
crx({ manifest }),
],
build: {
rollupOptions: {
input: {
popup: resolve(__dirname, 'src/pages/popup/index.html'),
},
},
}
})
これでビルド時にdist/src/pages/popup/index.htmlが作成される
オプションページ
ポップアップと同様の手順でsrc/pages/popupを追加
ポップアップ
distフォルダ内にポップアップ用のhtmlsrc/pages/popup/index.html
を作成するため以下の設定をする
manifest.jsonの action でポップアップページで参照するhtmlを指定
{
"action": {
"default_popup": "src/pages/popup/index.html"
}
}
npm install @types/node -D
を実行後
vite.configの内容を以下に変更
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { crx } from '@crxjs/vite-plugin'
import { resolve } from 'path'
import manifest from './manifest.json' assert { type: 'json' } // Node >=17
export default defineConfig({
plugins: [
vue(),
crx({ manifest }),
],
build: {
rollupOptions: {
input: {
popup: resolve(__dirname, 'src/pages/popup/index.html'),
},
},
}
})
src/pages/popupフォルダを作り以下を追加する。
App.vue
<script setup lang="ts">
import HelloWorld from '../../components/HelloWorld.vue';
</script>
<template>
<HelloWorld msg="popup page" />
</template>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>chrome extension template</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.ts"></script>
</body>
</html>
main.ts
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
npm run dev でポップアップ内に以下の画面が出ればOK
→ポップアップがうまく出ないので原因調査
ポップアップがうまく出ないので原因調査
→ファイル名をtypoしていた
オプションページ
ポップアップと同様の手順で作成する
vite.configに静的html作成の設定を追加
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { crx } from '@crxjs/vite-plugin'
import { resolve } from 'path'
import manifest from './manifest.json' assert { type: 'json' }
export default defineConfig({
plugins: [
vue(),
crx({ manifest }),
],
build: {
rollupOptions: {
input: {
popup: resolve(__dirname, 'src/pages/popup/index.html'),
option: resolve(__dirname, 'src/pages/option/index.html'),
},
},
}
})
src/pages/option配下にApp.vue,index.html,main.tsを作成する。
manifest.jsonにoptions_page項目を追加
{
"manifest_version": 3,
"name": "Chrome-extension-template",
"version": "1.0.0",
"action": {
"default_popup": "src/pages/popup/index.html"
},
"options_page": "src/pages/option/index.html"
}
npm run devを再実行し、右クリックからオプションを選択して画面が開けばOK
→今度は404になる
オプションページ
ポップアップと同様の手順で作成する
vite.configに静的html作成の設定を追加
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { crx } from '@crxjs/vite-plugin'
import { resolve } from 'path'
import manifest from './manifest.json' assert { type: 'json' }
export default defineConfig({
plugins: [
vue(),
crx({ manifest }),
],
build: {
rollupOptions: {
input: {
popup: resolve(__dirname, 'src/pages/popup/index.html'),
option: resolve(__dirname, 'src/pages/option/index.html'),
},
},
}
})
src/pages/option配下にApp.vue,index.html,main.tsを作成する。
App.vue
<script setup lang="ts">
import HelloWorld from '../../components/HelloWorld.vue';
</script>
<template>
<HelloWorld msg="option page" />
</template>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>chrome extension template</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.ts"></script>
</body>
</html>
main.ts
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
manifest.jsonにoptions_page項目を追加
{
"manifest_version": 3,
"name": "CRXJS Vue Vite Example",
"version": "1.0.0",
"action": { "default_popup": "src/pages/popup/index.html" },
"options_page": "src/pages/option/index.html"
}
npm run devを再実行し、リロード後右クリックからオプションを選択して画面が開けばOK