首页 >web前端 >js教程 >Chrome 扩展开发 - 使用 TypeScript、React、Tailwind CSS 和 Webpack 开发最小应用程序

Chrome 扩展开发 - 使用 TypeScript、React、Tailwind CSS 和 Webpack 开发最小应用程序

Patricia Arquette
Patricia Arquette原创
2024-12-29 02:26:15552浏览

介绍

在本博客中,我们将探索如何使用 TypeScript、React、Tailwind CSS 和 Webpack 设置和开发 Chrome 扩展。我们将创建一个名为“NoteMe”的最小扩展✍️来测试我们的理解。我们的扩展将包括以下功能:

  • 允许用户为给定网站添加多个注释
  • 使用户能够查看给定网站的已保存笔记
  • 提供删除给定网站的注释的选项
  • 将笔记本地保存在浏览器存储中
  • 可选择与云存储后端同步笔记

复习

在本博客中,我们将学习如何使用现代技术构建 Chrome 扩展程序。本指南假设您已经对在本地开发期间构建和上传 Chrome 扩展程序有一定的了解。如果您对此不熟悉或需要详细的基础知识演练,我建议您查看我之前的博客:链接

扩展预览

该扩展将包括以下组件:

  • 切换按钮:打开和关闭侧边栏的按钮。
  • 侧边栏:多功能面板,用户可以: 写新笔记。 查看保存的笔记。 删除已保存的笔记。 与后端同步笔记(代码中提供,但当前未连接后端)。
  • 弹出窗口:一个小窗口,允许用户将切换按钮(用于打开/关闭侧边栏)重新定位在屏幕上的预先指定位置 注意:虽然此实现中没有后端集成,但代码包含将来连接后端的规定。

下面的屏幕截图展示了扩展完成后的外观:

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

先决条件

在深入学习本教程之前,请确保您的系统上安装了以下工具:

  • Node.js(v18.16 LTS 或更高版本)
  • NPM(节点包管理器,与 Node.js 捆绑)
  • TypeScript
  • Webpack
  • VS 代码编辑器(或您选择的任何代码编辑器)

从 40,000 英尺延伸

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

上图提供了此扩展的内部工作原理的高级概述。以下是我们可以从图中得出的一些关键点:

  • 内容脚本直接与父网页的 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

确保您的目录结构类似于下面的屏幕截图所示。

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

步骤 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 webpack 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

注意:

上面的代码安装了两个监听器:

  1. 只要浏览器中安装了扩展程序,由 chrome.runtime.onInstalled.addListener 注册的函数就会执行。这可用于以预定义状态初始化 Chrome 存储或后端(如果适用)。
  2. 每当后台脚本收到来自内容或弹出脚本的消息时,由 chrome.runtime.onMessage.addListener 注册的函数就会执行。

此外,import 语句从 src/lib 目录引入监听器。核心应用程序逻辑构建在 src/lib 中,可以在不同上下文(例如内容和后台脚本)之间重用。

第 6 步:浏览 src/lib 目录

src/lib 目录包含扩展的核心逻辑。以下是其结构和关键组件的概述:

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

  • 组件目录: 包含扩展中使用的所有 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步:编译和构建的配置

添加编译和构建扩展所需的配置

要成功编译和构建扩展,我们需要配置以下文件:

  1. postcss.config.js
  2. tailwind.config.js
  3. tsconfig.json
  4. webpack.config.js

要点:

  • 默认设置: 只要有可能,都会提供默认设置来简化流程并确保重点始终放在主要目标上 - 构建功能齐全的扩展。
  • 存储库中的详细信息:这些文件的完整配置和详细设置请参考代码存储库。

这些配置处理 TypeScript 编译、Tailwind CSS 集成以及扩展的整体 Webpack 构建过程。

测试扩展

  1. 生成 dist 目录: 运行以下命令创建 dist 目录:npm run build
  2. 上传至 Chrome:    
    • 打开 Chrome 并导航至 chrome://extensions/。    
    • 启用右上角的开发者模式。    
    • 点击加载已解压的并选择dist目录。
  3. 验证安装:
    • 加载后,扩展程序的图标将默认出现在每个页面的右下角。
  4. 功能检查:
    • 位置控制:使用弹出窗口中的控件来更改图标的位置。
    • 注释功能:每个网站的注释都是独立保存的,并且可以针对特定网站删除而不影响其他网站。
  5. 后端模拟:
    • 虽然当前没有连接后端,但代码包含与后端集成的规定。
    • 当前实现使用 setTimeout 模拟后端连接,并承诺模拟异步交互。

以下是扩展测试期间捕获的一些屏幕截图。

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

Chrome Extension Development - Develop minimal app with TypeScript, React, Tailwind CSS and Webpack

要点

以下是此博客的一些关键要点,

  • 我们探索了 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn