chrome-extension with Vue

chrome-extension with Vue

Google Chrome Extension with Vue

google chrome

前言

話說開始研究 extension 之前需要有點Javascript的基礎,後續的內容也比較容易理解。

瀏覽器擴充功能其實算是老掉牙的東西了,不過我剛好會寫一點 Vue ,所以我在想有沒有辦法把Vue 整個 instance 塞到擴充套件裡面所以,加上有開發 的需求,就開始研究之路

前置作業

你可能會需要一個 Vue 的工具方便作業,在 github 上面,已經有人提供了完整的 Vue Template 可以使用,所以,最快的方式就是用 Vue CLI 的方式去安裝。

1
vue init kocal/vue-web-extension my-extension

然後,我們的第一個擴充功能就這樣做完了呢,裝起來就會 Hello World !好棒棒!(打完收工結束)

這個 Template 本身支援的項目有,

  • Mozilla’s web-extension polyfill
  • Vuex
  • Vue Router
  • Axios
  • ESLint
  • Prettier

除了 Vue 之外

雖然這個東西很方便,但是基本上你還是得理解擴充功能之間的溝通關係,這些東西說起來有點冗長,具體來說可以參考一下官方文件:

https://github.com/mozilla/webextension-polyfill

當然,這種相容性擴充不意外的是 Mozilla 自己推出的。

##啟動

1
npm run watch:dev

雖然他提供了 popup, options 與 background 三種運作方式,但,如果我是想要在特定頁面做手腳呢?這個時候,你必須要回頭去參考官方文件,在 manifest.json 需要額外做出一些設定,

然後你在 src/ 目錄底下,就能新增一個 content.js 的檔案,來做你想要做的事情。不過,你可能會發現,即便在 src/ 放好了 content.js,但是好像不會動?是,你還是需要去修改 webpack.config.js 檔案,要把 content.js 放入 entry 區段中。

大概是這樣

1
2
3
4
5
6
7
entry: {
'background': './background.js',
'popup/popup': './popup/popup.js',
'options/options': './options/options.js',
// 你需要新增在這邊
'content': './content.js'
}

關於 content.js 與 content.css

如果你的 content.js 當中,有使用到 Vue Components 的話,他會自動把樣式全部打包到 content.css 底下,這一點相當方便。

1
2
3
import Vue from 'vue';
import MyComponent from './myComponent.vue';
// ... 後略

關於各種元件溝通

首先呢,你所看到的 popupoptions 頁面,基本上都可以看做是各別獨立的 Vue Instance 來看。所以,倘若你的 content.js 需要跟 popup 溝通,那麼你需要的是靠 background.js 來當中間人。

https://developer.chrome.com/extensions/background_pages

這個中間人可以幫你做一些溝通,利用 chrome.runtime 這一類的元件來透過瀏覽器的運作過程之間的訊息往返,具體可以使用。

  • chrome.runtime.onMessage.addListener 用來監聽訊息。
  • chrome.runtime.sendMessage, chrome.tabs.sendMessage 用來發送訊息。

這兩件事情是比較入門款的操作,實際可以使用的行為還是請參考官方文件 runtime, tabs 說明。在官方文件總覽的 Architecture 區塊,也有大概介紹了元件之間的溝通方式,想要更瞭解細部操作的人可以閱讀一下

https://developer.chrome.com/extensions/overview

回到 Vue 本身

既然解決了溝通方式,那麼原本就使用 Vue 開發的人應該就沒有什麼困難點了。比較不一樣的地方在於,擴充功能本身的溝通,即便你本身有使用 Vuex 之類的工具,你在整個 App 裡面,還是要有地方去監聽從其他地方送回來的東西(如果你有需要的話)。

1
2
3
4
5
6
7
// 也就是說,你可能需要在 mounted 放入一些監聽動作
mounted () {
chrome.runtime.onMessage.addListener(data => {
// 我拿到別的地方送來的 data
// 然後我可以更新 Vuex 或是其他的東西
});
}

至此,你倘若有使用 Vuex 的話,就可以不用每一個元件的 mounted 都放監聽動作,否則,在你需要監聽更動或是需要的地方,都還是得加入這件事情,不然元件本身應該是不會反應的。若是不想,那麼拋去給 EventBus 也是可以,但是操作方法雷同,使用 Vuex 還是比較省事一點。

關於 Polyfill

上述所提到的 chrome.runtime 是特別針對 Google Chrome 所使用,如果你是在 Mozilla Firefox 開發的話,那麼你可能需要使用 browser.extension 來呼叫。如果你有安裝相容性擴充的話,你只要寫成這樣,

1
2
3
4
browser = require('webextension-polyfill');
browser.runtime.onMessage.addListener(data => {
// ... 中略
});

這樣就可以了。而你在 Vue Template 當中,看他的範例會這樣寫,

1
global.browser = require('webextension-polyfill');

所謂的 global 在這個開發工具中,等同於最外部的 window 的意思,換句話說,就是在全域中放入一個叫做 browser 的東西。那麼,你在任何地方使用 global.browser,就等同於 window.browser 的意思。

寫在文末

因為公司有產品開發的需求想說就升入研究一下,發現extension可以取得瀏覽器非常大的權限,像是cookie瀏覽紀錄等等,似乎都是搜集資訊的手段,越研究越發現很多extension感覺都很恐怖.

ps. Firefox 的附加元件,如果你要安裝自行開發的版本,需要進入 about:debugging 才能安裝。