iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
Modern Web

你知道這是什麼嗎? Chrome Extension MV3 With Vite系列 第 21

你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 21 Extension 中的 ES6 Module

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20220921/20139636UfGIRS7E2T.jpg
Hi Dai Gei Ho~ 我是Winnie ~

在前面文章中,我們介紹到 Vite 主要運作核心為 ES6 Module ,透過ES6 Moduleimport/Export的寫法,可將功能模組化,以方便程式碼管理維護,提升程式碼的複用性,同時在各大瀏覽器的支援度也齊全(好讚。

但問題來了,不知道大家有沒有想過,在 Extension 中 也是完全支援 ES6 Module嗎?

嗯,答案是只有部分支援(聞到坑的味道),但先別緊張,在後面文章中我們會介紹如何用Chrome 相關方法來繞過不支援的問題。

所以在此之前,我們要先來看看如何在 Chrome Extension 中使用 ES6 Module 。

首先,先讓我們來看看平常ES6 Module是如何使用的。

Es6 Module

script 標籤

平常使用 ES6 Module,我們需要在html中 加上 <script type="module" src="./main.js">來作為模組進入點,此時這邊的 type 設置為 "module" 時,預設具有 defer 的特性,在相關javascript的檔案會以非同步的方式來載入,也就是會在 DOM 解析完畢後執行。

// index.html
<script type="module" src="./main.js">

export & import

在 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)

在 Extension 使用 ES6 Module

Popup / Option

從版本 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

由於 Background 為背後運行事件,因此沒有相關 html可以放置script,所以在這部分Chrome提供了在Manifest中宣告type:module的欄位, 這樣就可以如期在 Background 中使用。

使用方法如下:

  "background": {
    "service_worker": "background.js",
    "type": "module"
  }
  

唯一限制 Content Script

由於 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
今日歌曲分享-> 半島鐵盒


上一篇
你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 20 用 Vite 實現 套件自動更新
下一篇
你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 22 Content Script 中使用 ES6 Module (補充說明篇)
系列文
你知道這是什麼嗎? Chrome Extension MV3 With Vite30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言