Hi Dai Gei Ho~ 我是Winnie ~
在前面文章中,我們介紹到 Vite 主要運作核心為 ES6 Module ,透過ES6 Moduleimport/Export
的寫法,可將功能模組化,以方便程式碼管理維護,提升程式碼的複用性,同時在各大瀏覽器的支援度也齊全(好讚。
但問題來了,不知道大家有沒有想過,在 Extension 中 也是完全支援 ES6 Module嗎?
嗯,答案是只有部分支援(聞到坑的味道),但先別緊張,在後面文章中我們會介紹如何用Chrome 相關方法來繞過不支援的問題。
所以在此之前,我們要先來看看如何在 Chrome Extension 中使用 ES6 Module 。
首先,先讓我們來看看平常ES6 Module是如何使用的。
平常使用 ES6 Module,我們需要在html中 加上 <script type="module" src="./main.js">
來作為模組進入點,此時這邊的 type 設置為 "module" 時,預設具有 defer 的特性,在相關javascript的檔案會以非同步的方式來載入,也就是會在 DOM 解析完畢後執行。
// index.html
<script type="module" src="./main.js">
在 ES6 Module 功能中主要是由 export 和 import 所構成:
由於每個檔案都是一個獨立的模組,因此如果希望外部能夠讀取模組內部的變數、function,此時可以透過 export/ export default 來匯出。這樣就可以在另一個模組中用 import 引入使用。
這邊注意: export default 只能有一個,export 可以有多個
// greeting.js
export const name = 'winnie';
// main.js
import { name } from './greeting.js;
console.log('Hi', name)
從版本 61 開始,Chrome增加了對 ES6 Module的支持,所以只要是在 Extension 中被定義為 HTML 頁面中,也就可以透過上述<script type="module" src="...">
方法來使用。
以Popup為例:
在Manifest 定義的檔案進入點為 .html
"action": {
"default_popup": "popup.html"
}
所以在 popup.html中,就可以透過type="module"
來使用
// popup.html
<script type="module" src="./popup.js">
同樣的option page也是如此。
由於 Background 為背後運行事件,因此沒有相關 html可以放置script,所以在這部分Chrome提供了在Manifest中宣告type:module
的欄位, 這樣就可以如期在 Background 中使用。
使用方法如下:
"background": {
"service_worker": "background.js",
"type": "module"
}
由於 Cotent Script 為注入網頁的程式碼,主要執行於他人網頁之中,沒有 .html
可以定義,同時Chrome也還沒提出相關方法支援,所以到目前為止,是唯一一個 在Extension 中是 無法使用 ES6 Module 的 Context。
如果使用了,則會出現以下錯誤:
Uncaught SyntaxError: Unexpected identifier
這在當時已用 Vite 與 Vue3 開發 Extension 的我 真的是晴天霹靂卡霹靂拉拉 波波力那貝貝魯多
於是又看到了文件這樣說
Disclaimer
First of all, it’s important to say that content scripts don’t support modules as of January 2018. This workaround sidesteps the limitation by embedding module script tag into the page that leads back to your extension.
查了許多資料,都是指出 Content Script 從2018不支援,但可以透過 動態注入 <script>
方式來引用。
首先要在 Manifest 中 "web_accessible_resources"
定義要注入的檔案
關於 web_accessible_resources 詳細用法 可看 -> Day 18 getURL 取得公開資源
"content_scripts": [ {
"js": [
"content.js"
]
}],
"web_accessible_resources": [
"main.js",
]
接著在content.js
中創建 <script>
,且透過setAttribute 指定 type 為 module
//content.js
const script = document.createElement('script');
script.setAttribute("type", "module");
接著,透過 chrome.runtime.getURL('main.js')
取得存在 Extension 端的 main.js 資源 指定給 src 。
//content.js
script.setAttribute("src", chrome.runtime.getURL('main.js'));
最後在插入當前網頁的<head>
中
//content.js
const head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
head.insertBefore(script, head.lastChild);
即可在Content Script中使用 Es6 Module。
但這邊需注意: 此時所有的功能邏輯都將會在main.js中處理,而content.js則僅此 創建 script的功能而已,在裡面無法使用任何ES6 Module語法。
以上就是關於 如何在 Chrome Extension 中使用 ES6 Module,那今天文章先到這邊了,謝謝願意花時間看此篇文章的你,如果文章有錯誤的地方,再麻煩不吝嗇的給予指教,感謝!!
誰最容易被絆倒? 答案是 鐵盒XDDD
今日歌曲分享-> 半島鐵盒