專案緣起
在 Alpha Camp 擔任實習助教的一個好處,是可以參加大約每兩週舉辦一次的 Meetup — 不僅可以聽到他人分享獨特的專案和技術,有時也能給自己一些機會去挑戰和探索自己未知的領域。
一個多月前,公佈了隔一次的主題是「製作 Google Chome 套件」,且開放有興趣的與會者自己摸索和製作,最後再與大家分享。當時內心馬上冒出了兩種心情和想法:
- 眉頭一皺:這是什麼領域?會用到什麼技術?該製作什麼主題的套件?
- 內心雀躍:好酷的未知領域,如果能自己做出個好用的套件,一定很棒!
老實說,內心雀躍的心情馬上壓過所有的情緒,因此我很快就做出了決定。但馬上面臨的是主題挑選 — 在向朋友們收集可能的需求,但沒有找到合適的主題後,我開始思考著:「我在開發網路應用程式的過程中,是什麼行為不時吃掉了我很多時間?」 這可能就是我的需求,也可能會是其他開發著的需求 — 一個 Side Proeject 因此誕生。
專案介紹
前端切版時,我自己常見的需求有兩個:「依照設計規格產生並放置 Placeholder 圖片」及「找尋可以免費使用或商用的圖片置入」,這兩個需求都不是會花費我很多時間的行為,但每次在找尋網站、連結、閱讀使用文件的一點小時間,累積起來卻會顯得很沒有效率,因此這次的 Chrome 套件分為三大功能,並分別透過以下幾個使用者故事來簡述功能:
產生 Placeholder 圖片
- 使用者在點擊 Popup 按鈕後,可以看到 Placeholder 圖片的產生器
- 使用者在產生器上輸入 Placeholder 圖片的規格(包含:尺寸、檔案格式、背景顏色、圖片上顯示的文字)設定後,可以獲得圖片的連結
- 使用者在獲得 Placeholder 圖片後,可以點擊「Copy」按鈕自動複製連結
- 使用者在獲得 Placeholder 圖片後,可以點擊「Open」按鈕在新的頁面開啟該圖片,以方便右鍵下載
免費圖片快搜器
- 使用者在點擊 Popup 按鈕後,可以看到免費圖片的快速搜尋器
- 使用者在搜尋器輸入照片關鍵字後,可以點擊任意一個網站(Pixabay、Pexels、Unsplash、Picjumbo)的按鈕開啟新頁面獲得搜尋結果
- 使用者在搜尋器輸入照片關鍵字後,可以點擊「Search All」按鈕,一次開啟四個頁面,分別獲得四個網站的搜尋結果
產生圖片尺寸連結報表
- 使用者可以在圖片上點擊右鍵,並選擇「ShowImageURL」選項,產生一個包含該圖片所有可供使用的尺寸連結
- 使用者可以在報表上看到圖片尺寸的資訊及該尺寸的圖片連結
- 使用者可以在報表上點擊需要的連結,直接複製連結
開發 Google Chrome 套件
Chrome 套件是設計用來增加瀏覽器使用體驗的軟體,而當初套件系統被設計時有一個很重要的目標:開發 Chrome 套件應該要像開發網頁一樣簡單 — 因此現在可以透過熟悉的 HTML、CSS、JavaScript 來開發這些套件。
Chrome 套件架構
在製作套件以前,需要先認識一個套件的組成元素和架構,大致包含了:
- Manifest
- Background Script
- UI Elements
- Content Script
- Options Page
Manifest
一個 JSON 格式的檔案 — 名為 manifest.json — 包含了套件資訊:例如版本、名稱、介紹、提供的檔案,及相關權限的設定。
建立 Manifest 檔案
在 manifest.json 檔案中做基本設定
👉manifest_version: 目前 manifest 檔案使用的格式版本(目前官方最新版為 2)
👉version: 此套件的版本資訊(初次完成的版本可設定為 1)
👉name: 套件名稱
👉description: 套件簡短介紹
👉icons: 提供套件將使用到的各尺寸圖像檔
👉permission: 設定套件會使用到的 Chrome API 和網頁權限
(此處有程式碼無法顯示,請由文末連結回到原文查看,謝謝)
Background Script
在背景中監聽「瀏覽器的事件」,並在監聽到特定的事件後,執行相對應的行為和程序 — 類似 Controller 的角色 — 事件類型很多種,例如:套件第一次被安裝完成、開啟或關閉了分頁等。
設定 Background Scripts
在 manifest.json 檔案中設定 background 屬性和其相關設定
👉scripts: 設定使用哪個背景腳本檔案(在此用 background.js)
👉persistent: 設定背景腳本是否持續運行(官方建議 false: 根據事件開啟和關閉)
(此處有程式碼無法顯示,請由文末連結回到原文查看,謝謝)
在 manifest 做好設定後,就能在 background.js 檔案中,初始化並設定事件監聽器,以此專案為例子,在檔案中監聽兩個事件:
- 監聽套件第一次被安裝完成 👉 在右鍵選單中,建立一個新的選單項目
- 監聽右鍵選單某項目被點擊 👉 確認為指定項目,並傳送訊息給內容腳本
(此處有程式碼無法顯示,請由文末連結回到原文查看,謝謝)
UI Elements
套件的使用者介面有許多種選擇,常見的 UI 包含:
- Browser Action 或 Page Action
- 在網址列右邊的小 icon,顯示著套件功能是否已被啟用
- 可能包含 popup — 在點擊 icon 後跳出的一個由渲染 HTML 檔案所呈現的視窗,此 HTML 檔案可以和 CSS 與 JavaScript 檔案連結(如下圖)
- 兩者主要差別在於設定 Page Action 時,套件僅能在特定頁面上被啟用;設定 Browser Action 時,套件則能在所有頁面上被啟用
設定 Browser Action
在 manifest.json 檔案中設定 browser_action 屬性和其相關設定
👉default_popup: 設定 Popup 的 HTML 檔案
👉default_icon: 設各尺寸的 icon 圖片檔案(Chrome 會自動採用最適合的尺寸)
(此處有程式碼無法顯示,請由文末連結回到原文查看,謝謝)
- Context Menu
可以設定右鍵選單項目,並附加某項目被點擊的事件監聽器。
設定 Context Menus
在 manifest.json 檔案中
👉permission 屬性裡要求取得 context menus 的使用權限
👉icons 屬性設定顯示在選單項目上的 16x16 圖檔
(此處有程式碼無法顯示,請由文末連結回到原文查看,謝謝)
在專案 background.js 檔案中,透過 chrome.contextMenus
上:
create()
方法建立一個新的選單項目onClicked
事件監聽任意選單項目被點擊
🧙♂️有趣的 ContextType
👉創建選單項目時,可在「contexts」屬性指定只在特定情況下點擊右鍵才顯示該清單項目
👉在此設定「image」代表只有在圖片上點擊右鍵才符合條件
👉其他可以設定的條件:「link 連結、video 影片、all 所有條件」等
(此處有程式碼無法顯示,請由文末連結回到原文查看,謝謝)
Content Scripts
Content Scripts 是一個 JavaScript 檔案,其藉由讀取和操作網頁中的 DOM(Document Object Model)來與該網頁互動,也能監聽該網頁的事件。兩點注意事項:
- DOM 會同時被網頁中的 JavaScript 和 Content scripts 使用 — 但能想像兩者是在獨立空間被執行,因此功能和變數不會互相干擾,也無法彼此取得
- 由於 Content scripts 是在網頁中運行,而非執行在套件上,因此需要透「訊息的傳遞(message passing)」來和套件本體互動(如下圖)
設定 Content Scripts 在 manifest.json 檔案中 👉permission 屬性裡要求取得 activeTab 權限:套件被觸發時,獲取當下頁面的權限 👉設定 content_scripts 屬性和其相關設定: - js:要使用和執行的 JavaScript 檔案 - matches:指定在到訪特定連結的頁面才執行 content scripts❗️在此先不設定 CSS 檔案原因:只想在監聽到使用者「想產生圖片連結報表(點擊右鍵選單列 ShowImageURL)」時,才套用給報表用的 CSS 檔案。詳請見 background.js
在專案中 content.js 檔案裡,我們發揮了 content script 的功能:
- 監聽網頁中的右鍵事件和讀取 DOM:獲取使用者想產生報表的那張圖片
- 監聽來自 background.js(套件主體)的訊息:接收 background script 確認使用者點擊右鍵「想產生某張圖片的 URL 報表」的訊息
- 操作 DOM:獲得確認訊息後,產生一張 URL 報表,並覆寫原本的網頁
使用 Chrome APIs
開發 Chrome 套件有趣之處在於,套件除了能透過 Web API 和網頁互動外,也可以透過 Chrome APIs 與 Chrome 瀏覽器有不同目的性的互動 — 這讓套件能發揮的空間更廣、更多元:
📍在前面專案的介紹中,其實已經用到不少 Chrome API
- Chrome.contextMenu:新增右鍵選單項目,並可只在特定情況下才顯示
- Chrome.tabs:和瀏覽器的 tab 系統互動,如:開啟、修改、管理頁面
📍其他有趣或實用的 Chrome API
- chrome.bookmarks:可以和 Chrome 瀏覽器的書籤互動
- chrome.cookies:可以取得和修改 cookies 資訊
- chrome.fontSettings:管理 Chrome 瀏覽器的字體設定
- chrome.storage:類似 localStorage 的概念,可以存取、追蹤特定的使用者資訊
❗️注意事項
👉API 就像是應用程式的介面,透過 API 能接處和使用到應用程式的功能
👉因此在套件中每使用一個 API,就需要先在 manifest 檔案裡請求使用該 API 的權限
👉在 manifest.json 中請求權限:於 permissions 屬性上的陣列中加入 API 名稱
上傳 Chrome 套件
- 前往套件管理頁面:在 Chrome 網址列輸入 chrome://extensions/
- 開啟「開發人員模式」
- 點選「LOAD UNPACKED 載入未封裝擴充功能」,並選擇套件所在資料夾
🤠成功載入套件:
使用 DevTools
在開發網路應用程式時,很常會使用 DevTools 來 Debug 程式碼,在開發 Chrome 套件時,一樣也能使用 DevTools 來檢查 Popup— 只是開啟的位置和方式不同:
- 在網址列右邊的套件 icon 上按下右鍵
- 選取 Inspect Popup(檢查彈出式視窗)
開發 Chrome 套件須知
就像在開發網路應用程式時,須注意跨瀏覽器支援的狀況,使用 Chome APIs 和其相關功能、屬性等時,也需要留意「Chrome 瀏覽器版本」支援的情況 — 可以透過官方文件查閱:
Bonus:上架 Chrome Web Store
完成作品後,如果有興趣開放給大家免費或付費使用,可以上架到「Chrome Web Store 線上應用程式商店」 — 由於每個套件性質和內容不同,建議參考官方提供的👉上架流程指南。在此分享這次上架大致走過的流程:
1. 前往 Chrome Developer Dashboard
選擇「Add new item」開始新增一個套件
2. 上傳套件
上傳的格式只接受 ZIP 檔案,須先行將套件資料夾壓縮
3. 填寫和提供上架商店所需資訊
提供上架商店所需的套件介紹、Icon、宣傳圖、類型、上架國家、收費與否、語言等資訊。若為公司所上架的官方套件,也需要在「Websites」欄位提供公司的網站或相關連結以供驗證。
4. 帳戶驗證:一次性費用
初次上架需付一筆一次性的註冊(驗證帳戶)費用:
👉 一次性費用:5 美金
👉 付費後可上架:20 個套件
5. 上架成功*
資料填妥且付款成功後,回到 Chrome Developer Dashboard 就能確認套件是否已經上架成功:
6. Go Live 🎉
套件成功上架商店了👉點我進商店
上架商店注意事項
Google 在 2018 年 10 月宣布將提高 Chrome Web Store 套件的審查標準,因此套件在正式被發佈到商店前,可能需要經過一系列的審查— 詳細報導請參考這篇。簡單來說,一切都回到設計套件的初衷:提升使用者在使用 Chrome 瀏覽器的體驗 — 包含提升透明度與使用者擁有的控制。為加快審查速度,兩個我覺得文章中有提到很重要的點:
- 程式碼是否有好的可讀性與功能性(Performance Evaluation)
- 套件請求的權限範圍是否已盡可能最小化
若是開發更大型的專案,則建議要額外參考 Content Policies 及 Page Performance 相關文件。
😃本次上架等待的審查時間約 3 天
查看作品
GitHub 程式碼與介紹 👇
Chrome 線上應用程式商店 👇
開發心得分享
開發初期
在正式開發套件以前,先參考了許多教學影片,包含 Udemy 上的免費課程和 YouTube 實作影片等,跟著教學影片實作的確能在短時間內製作出簡單的成品。然而,畢竟每個人的套件功能和複雜性都不同,且這套系統有特殊的架構關係,因此在開發自己的專案初期,時常碰壁:「不知道預期的功能該怎麼做,甚至在成功找到方法並運用後,卻沒有任何效果或反應 🤨」只好停下腳步,深呼吸,喝著咖啡,思考著問題的癥結點:
「太快地想做出成品,但對於套件的架構和基本運作方式卻還不夠了解」
停下腳步,找尋方向
了解到問題根本的原因後,我一方面重新打開 Chrome 開發者文件,從套件的介紹、架構和功能的說明重新認識起,也透過文件中的影片,去理解運作和設計的原理;另一方面,也和另一位實習助教 Danny 討論開發的心得,彼此交換遇到的問題和解決方式 — 讓我在接下來的開發更有方向和頭緒。
後續開發
在後續的開發路上,陸陸續續還是有遇到不少實作上問題,但好在自己開始對於官方文件和查找資料的方向有多一些的瞭解,且腦中有比較清楚的架構,因此在解決問題上就更有效率了。
說到面對問題,即使在 Meetup 分享完作品後,還是發現了一些預期外的 Bug,例如:「每當瀏覽的網站上有出現表格時,都自動帶有如下圖 URL 報表的樣式!」當時還一度以為自己專案看太久,眼睛花了 🤩 硬是睡了一覺,確定還在,才打開程式碼和官方文件來 Debug 😂
近期心情記事
從學期一到現在剛好五個月的時間,Alpha Camp 學期三的課程也告一個段落了,時間真的很快。一路從當初對於網頁開發懵懵懂懂,學期二學習前端開發,到👇學期三學習後端和更深入的知識與概念,很開心自己走到了這一步:
學期三的大主題 👉Node.js / Express / MongoDB / MySQL / Git / 網站佈署/ 同步與非同步學期三的實作 👉餐廳清單 / Todo List / 幹畫產生器 / 家庭記帳本(MongoDB|MySQL)/ 縮網址學期三額外實作 Side Project 👉查詢天氣:認識同步與非同步 / Chrome 套件 / 台灣天氣概況:串接中央氣象局 API
我必須承認,在這個學期的學習過程中,內心充滿著很複雜的情緒,許多片段就像在製作 Chrome 套件的過程 — 面對學習和轉職道路上的困難和挑戰,有興奮感、成就感、想要追求更好的使命,但也不時面對挫折。有一兩次正一邊優化前端切版來達到自己的要求時,眼匡卻不知道為何冒著淚水。為了不想被咖啡店員工發現,還趕緊把淚水吸回去 (開玩笑的 😅)
或許不是所有身旁的親戚和朋友都能理解這感受,即使他們試著想要關心,也很難訴說出這些心情,但很開心在 AC 遇到了同儕,彼此打氣、激勵、切磋,遇到挑戰和難題,就停下腳步,思考方向,拍拍彼此的肩膀,再出發 — 抱著「相信自己終究能做到的信念」繼續往前邁進!學期四 I’m coming
好文轉自MikeHuang–[筆記]從零開始製作chrome套件到上架商店
如果你喜歡他的文章,歡迎回到他的Medium【麥克的半路出家筆記】看更多