Chrome 擴充功能開發 - 使用 TypeScript、React、Tailwind CSS 和 Webpack 開發最小應用程式
介紹
在本部落格中,我們將探索如何使用 TypeScript、React、Tailwind CSS 和 Webpack 設定和開發 Chrome 擴充功能。我們將創建一個名為「NoteMe」的最小擴充✍️來測試我們的理解。我們的擴充功能將包括以下功能:
- 允許使用者為給定網站添加多個註解
- 使用戶能夠查看給定網站的已儲存筆記
- 提供刪除給定網站的註解的選項
- 將筆記本地保存在瀏覽器儲存中
- 可選擇與雲端儲存後端同步筆記
複習
在本部落格中,我們將學習如何使用現代技術建立 Chrome 擴充功能。本指南假設您已經對在本機開發期間建置和上傳 Chrome 擴充功能有一定的了解。如果您對此不熟悉或需要詳細的基礎知識演練,我建議您查看我之前的部落格:連結
擴展預覽
擴充功能將包括以下組件:
- 切換按鈕:開啟和關閉側邊欄的按鈕。
- 側邊欄:多功能面板,使用者可以: 寫新筆記。 查看已儲存的筆記。 刪除已儲存的筆記。 與後端同步筆記(程式碼中提供,但目前未連接後端)。
- 彈出視窗:一個小窗口,允許使用者將切換按鈕(用於開啟/關閉側邊欄)重新定位在螢幕上的預先指定位置 注意:雖然此實現中沒有後端集成,但程式碼包含將來連接後端的規定。
下面的螢幕截圖展示了擴展完成後的外觀:
先決條件
在深入學習本教學之前,請確保您的系統上安裝了以下工具:
- Node.js(v18.16 LTS 或更高版本)
- NPM(節點套件管理器,與 Node.js 捆綁)
- TypeScript
- Webpack
- VS 程式碼編輯器(或您選擇的任何程式碼編輯器)
從 40,000 英尺延伸
上圖提供了此擴充的內部工作原理的高級概述。以下是我們可以從圖中得到的一些關鍵點:
- 內容腳本直接與父網頁的 DOM 交互,使其能夠修改頁面的內容。
- 彈出視窗、背景和內容腳本透過Chrome的執行時間訊息系統相互通訊。
- 對於與Chrome 儲存或後端API 呼叫相關的任務,內容 或彈出腳本使用執行時間訊息系統將責任委託給後台工作人員。
- 後台腳本充當應用後端和Chrome儲存的唯一中介。它還使用運行時訊息傳遞將通知(如果有)轉發給其他腳本。
- 彈出視窗和內容腳本直接透過Chrome的執行時間訊息傳遞系統交換訊息。
擴充的設定
雖然 Chrome 擴充功能不強制要求特定的專案結構,但它們確實需要一個位於建置目錄根目錄的 manifest.json 檔案。利用這種靈活性,我們將定義一個自訂專案結構,幫助有效地組織不同的腳本。這種結構將能夠更好地跨腳本重複使用程式碼並最大程度地減少重複,從而簡化我們的開發流程。
第一步:建立專案的基本目錄結構
首先,我們將為該專案設定一個基礎目錄結構。您可以使用以下 bash 腳本來建立基本結構以及 manifest.json 檔案:
#!/bin/bash bash_script_absolute_path=$(pwd) declare public_paths=("public" "public/assets" "public/assets/images") declare source_paths=("src" "src/lib" "src/scripts" "src/scripts/background" "src/scripts/content" "src/scripts/injected" "src/scripts/popup" "src/styles") declare public_directory_path="public" declare manifest_file="manifest.json" declare project_name="note-me" create_directory () { if [ ! -d "" ]; then mkdir fi } create_file () { if [ ! -e "/" ]; then touch / fi } create_public_directories () { for public_path in "${public_paths[@]}"; do create_directory $public_path done } create_source_directories () { for source_path in "${source_paths[@]}"; do create_directory $source_path done } execute () { echo "creating project struture at "${bash_script_absolute_path} create_directory $project_name cd $bash_script_absolute_path"/"$project_name create_public_directories create_source_directories create_file $manifest_file $public_directory_path echo "done creating project struture at "${bash_script_absolute_path}" with project name "$project_name } execute
確保您的目錄結構類似於下面的螢幕截圖所示。
步驟 2:位於公用目錄中的manifest.json 檔案的結構應如下所示:
{ "manifest_version": 3, "name": "NoteMe", "version": "1.0", "description": "A Chrome extension built with React and TypeScript using Webpack.", "action": { "default_popup": "popup.html", "default_icon": "app-icon.png" }, "background": { "service_worker": "background.js", "type": "module" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], "run_at": "document_end" } ], "permissions": [ "storage", "activeTab", "scripting", "webNavigation" ], "host_permissions": ["<all_urls>"], "web_accessible_resources": [ { "resources": ["styles.css", "sidebar-open.png", "sidebar-close.png"], "matches": ["<all_urls>"] } ] }
注意事項:
- 檔案副檔名是.js,因為.ts檔會被編譯成.js文件,在Chrome環境下執行時需要。
- 匹配欄位使用
;作為其值,使擴充功能能夠在 Chrome 中載入的任何網頁上運行。 - 引用了三個圖片檔案:app-icon.png、sidebar-open.png、sidebar-close.png。您可以在本部落格末尾連結的儲存庫中找到這些文件。
- 專案建置後,manifest.json 檔案必須放置在 dist 目錄的根層級。為了確保這一點,我們需要配置 webpack 設定以在建置過程中適當地移動它。
步驟3:初始化npm並安裝依賴項
- 首先使用以下指令在專案中初始化 npm:npm init -y
- 將必要的開發依賴項加入到專案的 devDependencies 部分。運行以下命令: npm i --save-dev @types/chrome @types/react @types/react-dom autoprefixer copy-webpack-plugin css-loader mini-css-extract-plugin postcss postcss-loader style-loader tailwindcss ts-loader typescript webpackpackss webpack-cli webpack-dev-server
- 新增運行項目所需的運行時相依性: npm i --保存反應反應-dom
步驟 4:建立在manifest.json中引用的文件
建立在manifest.json中引用的以下檔案:backgroun.ts、content.ts和popup.html。
- background.ts:在 src/scripts/background 目錄中建立此檔案
- content.ts:在 src/scripts/content 目錄中建立此檔案
- popup.html 在公共目錄中建立此檔案
步驟5:更新彈出視窗和背景程式碼
在public目錄下的popup.html檔案中加入以下程式碼:
#!/bin/bash bash_script_absolute_path=$(pwd) declare public_paths=("public" "public/assets" "public/assets/images") declare source_paths=("src" "src/lib" "src/scripts" "src/scripts/background" "src/scripts/content" "src/scripts/injected" "src/scripts/popup" "src/styles") declare public_directory_path="public" declare manifest_file="manifest.json" declare project_name="note-me" create_directory () { if [ ! -d "" ]; then mkdir fi } create_file () { if [ ! -e "/" ]; then touch / fi } create_public_directories () { for public_path in "${public_paths[@]}"; do create_directory $public_path done } create_source_directories () { for source_path in "${source_paths[@]}"; do create_directory $source_path done } execute () { echo "creating project struture at "${bash_script_absolute_path} create_directory $project_name cd $bash_script_absolute_path"/"$project_name create_public_directories create_source_directories create_file $manifest_file $public_directory_path echo "done creating project struture at "${bash_script_absolute_path}" with project name "$project_name } execute
注意:
上面的程式碼安裝了兩個監聽器:
- 只要瀏覽器中安裝了擴充程序,由 chrome.runtime.onInstalled.addListener 註冊的函數就會執行。這可用於以預定義狀態初始化 Chrome 儲存體或後端(如果適用)。
- 每當後台腳本收到來自內容或彈出腳本的訊息時,就會執行由 chrome.runtime.onMessage.addListener 註冊的函數。
此外,import 語句從 src/lib 目錄引入監聽器。核心應用程式邏輯建構在 src/lib 中,可以在不同上下文(例如內容和後台腳本)之間重複使用。
第 6 步:瀏覽 src/lib 目錄
src/lib 目錄包含擴充的核心邏輯。以下是其結構和關鍵組件的概述:
- 組件目錄: 包含擴充功能中使用的所有 React 元件。
- lib/components/ContentApp.tsx: 充當內容腳本的容器元件。
- lib/components/NoteMePosition.tsx: 包含負責彈出腳本的組件。
- helpers.ts: 包括整個擴充中使用的輔助函數。
- 儲存模型.ts: 管理與 Chrome 本地儲存的互動。有關儲存資料結構的詳細信息,請參閱此文件以及 types.ts。
- 類型.ts: 定義擴充中使用的自訂類型。
- worker.ts: 包含後台事件監聽器的回呼。
詳細實作請參考倉庫中的實際代碼。
第7步:安裝React元件
在這一步驟中,我們掛載React元件進行渲染。這些組件安裝在兩個不同的腳本中:src/scripts/content/content.ts 和 src/scripts/popup/popup.ts。
彈出式腳本:位於 src/scripts/popup/popup.ts。
#!/bin/bash bash_script_absolute_path=$(pwd) declare public_paths=("public" "public/assets" "public/assets/images") declare source_paths=("src" "src/lib" "src/scripts" "src/scripts/background" "src/scripts/content" "src/scripts/injected" "src/scripts/popup" "src/styles") declare public_directory_path="public" declare manifest_file="manifest.json" declare project_name="note-me" create_directory () { if [ ! -d "" ]; then mkdir fi } create_file () { if [ ! -e "/" ]; then touch / fi } create_public_directories () { for public_path in "${public_paths[@]}"; do create_directory $public_path done } create_source_directories () { for source_path in "${source_paths[@]}"; do create_directory $source_path done } execute () { echo "creating project struture at "${bash_script_absolute_path} create_directory $project_name cd $bash_script_absolute_path"/"$project_name create_public_directories create_source_directories create_file $manifest_file $public_directory_path echo "done creating project struture at "${bash_script_absolute_path}" with project name "$project_name } execute
內容腳本:位於 src/scripts/content/content.ts。
{ "manifest_version": 3, "name": "NoteMe", "version": "1.0", "description": "A Chrome extension built with React and TypeScript using Webpack.", "action": { "default_popup": "popup.html", "default_icon": "app-icon.png" }, "background": { "service_worker": "background.js", "type": "module" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], "run_at": "document_end" } ], "permissions": [ "storage", "activeTab", "scripting", "webNavigation" ], "host_permissions": ["<all_urls>"], "web_accessible_resources": [ { "resources": ["styles.css", "sidebar-open.png", "sidebar-close.png"], "matches": ["<all_urls>"] } ] }
要點:
- 單獨的安裝腳本: 彈出視窗和內容腳本在不同的情境中執行
- 彈出腳本: 在載入它的 popup.html 網頁的上下文中運行。
- 內容腳本:在瀏覽器中載入的主網頁的上下文中運行。
-
內容腳本的 Shadow DOM:
- 內容腳本注入的樣式可能會影響父網頁的外觀。
- 為了防止這種情況,我們使用 Shadow DOM 來封裝樣式,確保它們在擴充中保持隔離。
- 這對於彈出腳本來說不是必需的,因為它在自己的隔離環境(popup.html)中運行。
第8步:編譯和建置的配置
加入編譯和建置擴充功能所需的配置
要成功編譯和建置擴展,我們需要設定以下檔案:
- postcss.config.js
- tailwind.config.js
- tsconfig.json
- webpack.config.js
要點:
- 預設設定: 只要有可能,都會提供預設設定來簡化流程並確保重點始終放在主要目標上 - 建立功能齊全的擴充。
- 儲存庫中的詳細資訊:這些檔案的完整配置和詳細設定請參考程式碼儲存庫。
這些組態處理 TypeScript 編譯、Tailwind CSS 整合以及擴充的整體 Webpack 建置流程。
測試擴展
- 產生 dist 目錄: 執行下列指令建立 dist 目錄:npm run build
-
上傳至 Chrome:
- 開啟 Chrome 並導覽至 chrome://extensions/。
- 啟用右上角的開發者模式。
- 點選載入已解壓縮的並選擇dist目錄。
-
驗證安裝:
- 載入後,擴充功能的圖示將預設出現在每個頁面的右下角。
-
功能檢查:
- 位置控制:使用彈出視窗中的控制項來變更圖示的位置。
- 註解功能:每個網站的註解都是獨立保存的,並且可以針對特定網站刪除而不影響其他網站。
-
後端模擬:
- 雖然目前沒有連接後端,但程式碼包含與後端整合的規定。
- 目前實作使用 setTimeout 模擬後端連接,並承諾模擬非同步互動。
以下是擴展測試期間捕獲的一些螢幕截圖。
重點
以下是此部落格的一些關鍵要點,
- 我們探索了 Chrome 環境的各種元件(例如內容腳本、彈出式腳本和後台工作人員)如何使用 Chrome 的執行時間訊息系統相互通訊。
- 我們學習如何從頭開始配置和建立 Chrome 擴展,包括設定專案結構、安裝依賴項和編寫核心功能。
- 我們發現了一些好的做法,例如:
- 增強跨腳本的程式碼可重複使用性,以實現可維護性和可擴充性。
- 在內容腳本中使用 Shadow DOM 來防止與父網頁的樣式衝突。
瞥見前方
將來,我計劃撰寫另一個博客,我們將探索將功能齊全的 Chrome 擴充功能發佈到 Chrome 線上應用程式商店的過程。該部落格的目標是:
- 開發一個足夠複雜的擴充來解決現實世界的問題。
- 示範將擴充功能發佈到 Chrome 應用程式商店的逐步流程。
感謝您花時間閱讀此部落格!您的興趣和支持對我來說意義重大。在繼續這趟旅程時,我很高興能分享更多見解。
編碼愉快!
github 連結:https://github.com/gauravnadkarni/chrome-extension-starter-app
本文原刊於Medium。
以上是Chrome 擴充功能開發 - 使用 TypeScript、React、Tailwind CSS 和 Webpack 開發最小應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務
