9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Vue.js エンジニアなら webext-vitesse で Chrome 拡張を作っちゃおう

Last updated at Posted at 2022-05-17

この記事の超概要

  • テンプレートの構成を通して Chrome 拡張で何が作れるかを説明します。
  • webext-vitesse の開発体験の良さを知って欲しいです。

webext-vitesse とは

vita + Vue.js + typescript + WindiCSS で Chrome 拡張を作れるテンプレートです。

セットアップ

下記のスクリプトを実行

npx degit antfu/vitesse-webext my-webext
cd my-webext
pnpm i
pnpm dev

Chrome > 拡張機能を管理 > パッケージ化されていない拡張機能を読み込む

my-webext/dist/extension フォルダを選択すれば OK です。

src/ 以下の主要ディレクトリの役割

popup

拡張のアイコンをクリックしたときに表示される画面。
image.png

optionPage

設定情報などを表示するための画面。
image.png

contentScripts

html に差し込んで表示する要素。
image.png

background

中心となる処理を書く場所。Web アプリケーションでいうところの API サーバに近い。他の 3 つと異なり、CORS などの制約が無い。ブラウザの様々な機能を利用可能。

機能間の通信

前述した 4 機能は独立しており、通信には chrome.runtime API を使う必要があります。
webext-vitesse には chrome.runtime API をラップした webext-bridge というライブラリが含まれており、簡単に、型安全に通信処理を書くことが出来ます。

データを送るとき

src/background/main.ts
browser.tabs.onActivated.addListener(async({ tabId }) => {
  console.log('previous tab', tab)
  sendMessage('tab-prev', { title: tab.title }, { context: 'content-script', tabId })
})

データを受け取る時

src/contentScripts/index.ts
import { onMessage } from 'webext-bridge'  

onMessage('tab-prev', ({ data }) => {
  console.log(`[vitesse-webext] Navigate from page "${data.title}"`)
})

型定義

shim.d.ts
import { ProtocolWithReturn } from 'webext-bridge'

declare module 'webext-bridge' {
  export interface ProtocolMap {
    'tab-prev': { title: string | undefined }
    'get-current-tab': ProtocolWithReturn<{ tabId: number }, { title?: string }>
  }
}

データの保管

Chrome 拡張のストレージの説明は下記が分かりやすかったです。
https://qiita.com/dhun/items/cf18e43cb0376fcff302

webext-vitesse では src/composables/useStrageLocal.ts に定義された useStrageLocal 関数を使ってより簡単に strage.local にアクセスすることが出来ます。

src/options/Options.vue
<script setup lang="ts">
import { useStorageLocal } from '~/composables/useStorageLocal'

const storageDemo = useStorageLocal('webext-demo', 'Storage Demo', { listenToStorageChanges: true })
</script>

<template>
  <input v-model="storageDemo" class="border border-gray-400 rounded px-2 py-1 mt-2">
</template>

実際に作ってみたもの

Gitlab と Clockify を連携する拡張を作りました。自分用に作ったのでストアに公開はしていません。ソースコード
image.png

webext-bridge を使っているオススメ拡張

Chikamichi

履歴、ブックマーク、開いているタブを fuzzy 検索できる。ソースコード も大いに参考にさせて頂きました。

最後に

普段 Vue.js をよく触る方で、Chrome 拡張を作りたい人は是非使ってみてください。爆速で開発できます。

webext-vitesse は最新の vite 周りの技術セットがふんだんに使われているので、そのあたりも非常に参考になると思います。

モチベーション(裏話)

前述したように複数の Web サービスを連携させて業務効率アプリを作ろうとしました。どちらのサービスも API を公開しています。連携させるには、それぞれのサービスのアクセストークンを取得する必要がありました。アプリケーション側ではアクセストークンを管理したくありません。ユーザのローカル環境に保存できると嬉しいです。

最初は GAS で作っていましたが、GAS だとどうしてもクレデンシャル情報をサーバサイドに送る必要がありました。

この問題を解決するために Chrome 拡張を作ろうと思ったのがきっかけでした。

9
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?