专栏名称: 奇舞精选
《奇舞精选》是由奇舞团维护的前端技术公众号。除周五外,每天向大家推荐一篇前端相关技术文章,每周五向大家推送汇总周刊内容。
目录
相关文章推荐
李楠或kkk  ·  其实,既然说 ai ... ·  2 天前  
题材挖掘君  ·  DeepSeek,最新核心标的+延伸方向(精 ... ·  2 天前  
题材挖掘君  ·  DeepSeek,最新核心标的+延伸方向(精 ... ·  2 天前  
闽南日报  ·  突发!松下电器将解散 ·  2 天前  
青澄财经  ·  追觅,悄悄“捡起”机器人? ·  2 天前  
青澄财经  ·  追觅,悄悄“捡起”机器人? ·  2 天前  
昌吉日报  ·  中奖名单公布! ·  3 天前  
51好读  ›  专栏  ›  奇舞精选

简化 Chrome 扩展程序开发:无需 CRA 即可添加 React

奇舞精选  · 公众号  · 科技自媒体  · 2024-09-26 20:05

主要观点总结

本文介绍了如何简化Chrome扩展开发并添加React,而不使用Create React App。首先,文章解释了为何不使用CRA在构建Chrome扩展时适用,然后介绍了项目设置、TypeScript安装、基本文件创建、清单文件、弹出窗口文件、Webpack配置和Tailwind CSS样式设计的过程。接着,文章详细说明了如何为弹出窗口添加React的步骤,包括安装React和ReactDOM、更新Webpack以支持React、将TypeScript组件转换为React组件、更新popup.html、更新tsconfig.json文件以及重新构建扩展。最后,文章解释了不使用Create React App的优点,并感谢读者的阅读。

关键观点总结

关键观点1: 项目设置和准备工作

创建新的Chrome扩展项目目录并初始化npm,安装TypeScript和必要的加载器。

关键观点2: TypeScript和Webpack配置

配置TypeScript和Webpack以处理.ts和.tsx文件的编译,以及处理CSS和JS文件的打包。

关键观点3: Tailwind CSS样式设计

安装Tailwind CSS并配置PostCSS,创建Tailwind CSS入口文件以应用样式。

关键观点4: 添加React到弹出窗口

安装React和ReactDOM,更新Webpack和TypeScript配置以支持React,将TypeScript组件转换为React组件。

关键观点5: 不使用Create React App的优点

控制和学习,更好地了解技术细节,适合Chrome扩展的开发需求。


正文

本文译者为 360 奇舞团前端开发工程师

原文标题:Simplify Chrome Extension Development: Add React without CRA

原文作者:Kristian Ivanov

原文地址:

https://dev.to/k_ivanow/simplify-chrome-extension-development-add-react-without-cra-5h4c

简介

我们都喜欢 React,对吧(除了 Primeagen)。它通过提供一种简单的方法来处理状态,以及访问一个巨大的 npm 模块和组件库,极大地简化了复杂 UI 的构建。它甚至提供了 Create React App (CRA),只需一个命令就可以快速引导并完成初始设置。

我是 Create React App 的粉丝。它非常适合大多数 web 应用程序,在看到许多从 CRA 弹出的应用程序或使用 gulp 构建/打包的应用后(有时我会觉得自己老了),即使不使用 TypeScript,我也逐渐欣赏它的简单性,以及它在我启动任何新项目时所带来的便利。

然而,在构建像 Chrome 扩展这样的项目时,CRA并不适用,生成的代码过于臃肿。此外,在扩展中,UI 可能只是项目的一部分,大部分逻辑被封装在后台/服务工作线程或内容脚本中。这意味着将大量冗余代码与 React 的使用方式绑定并不总是最佳选择。

另外,如果你开始时只是简单地在 UI 侧写了一些 HTML 和 Tailwind 代码来测试你的想法,然后为扩展的其他部分编写了一堆代码,然后决定让 UI 更易于维护和扩展,并将 React 添加到其中,这该怎么办?

在本指南中,我们将使用 TypeScript、Webpack 和 Tailwind 构建一个 Chrome 扩展,然后以更轻量的方式引入 React,而不使用 CRA。

设置

我最近想开始一个非常简单的 Chrome 扩展,探索一些潜在的 Mutation Observer 用例来定制页面。同时,我也想借此机会尝试 TypeScript,因为我已经有一段时间没有使用它了。

1 设置项目

首先,我们创建一个新的项目目录并用 npm 初始化它:

mkdir ts-chrome-extension
cd ts-chrome-extension
npm init -y

2 添加 TypeScript

安装 TypeScript:

npm install --save-dev typescript

安装完成后,我们需要创建一个 TypeScript 配置文件。该文件将告诉 TypeScript 编译器如何工作。创建 tsconfig.json 文件:

{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "es2015"],
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}

有关 tsconfig.json 文件的更多细节,请查看官方文档。

3 添加基本文件

创建文件夹和基本文件:

mkdir -p src/scripts && mkdir src/popup && touch src/manifest.json src/scripts/{background.ts,contentScript.ts} src/popup/{popup.html,popup.ts}

在此时,我们的文件夹结构应如下所示:

├── package.json
├── package-lock.json
├── popup.ts
├── src
│ ├── manifest.json
│ ├── popup
│ │ ├── popup.html
│ │ └── popup.ts
│ └── scripts
│ ├── background.ts
│ └── contentScript.ts
└── tsconfig.json

4 清单文件

清单文件是 Chrome 扩展的基础。它告诉 Chrome 扩展的功能以及在哪里找到其脚本。我们创建了清单文件,现在填充它:

{
"manifest_version": 3,
"name": "TypeScript Chrome Extension",
"version": "1.0",
"description": "A Chrome extension built using TypeScript.",
"action": {
"default_popup": "popup.html"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": [""],
"js": ["contentScript.js"]
}
],
"permissions": ["storage"]
}

说明:

  • Action and Popup "action" 键告诉 Chrome 弹出 HTML 的位置。用户点击扩展图标时,弹出窗口将加载。

  • Service Worker "service_worker" "background" 键中,用于后台任务。

  • Content Scripts :这些脚本允许扩展与网页进行交互。

  • Permissions "storage" 权限使扩展能够通过 Chrome 的存储 API 存储用户数据。

有关 Chrome 扩展的 manifest.json 的完整文档,在这里找到。

5 弹出窗口文件

由于我们还未使用 React,弹出窗口将简单地处理基本的 DOM 交互。

5.1 popup.html

span style="color: rgb(215, 58, 73);">html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Popuptitle>
head>
<body>
<div>
<h1>Hello, Chrome Extension!h1>
<button id="alertButton">Click mebutton>
div>
<script src="popup.js">script>
body>
html>

这是一个简单的 HTML 页面,包含一个按钮和对 popup.js 的脚本引用(将从 popup.ts 打包而来)。

5.2 popup.ts

该文件将处理弹出窗口的基本交互:

document.addEventListener('DOMContentLoaded', () => {
const alertButton = document.getElementById('alertButton');

if (alertButton) {
alertButton.addEventListener('click', () => {
alert('Button clicked!');
});
}
});

这个简单的脚本在 DOM 加载后等待,然后为按钮添加点击监听器,以触发警报。在我们添加 React 之前,此结构为弹出功能奠定了基础。

6 编译 TypeScript

接下来,我们将 TypeScript 文件编译为 JavaScript。运行以下命令:

npx tsc

这将会把 TypeScript 文件转换为 JavaScript。 popup.ts background.ts contentScript.ts 将被编译为 popup.js background.js contentScript.js 。但由于我们很快会添加 Webpack 来管理打包,因此这只是一个临时步骤。

7 添加 Webpack 进行打包

现在我们有了基本结构,我们需要 Webpack 来处理将所有脚本打包成 Chrome 可加载的优化文件。它可以处理图标的复制、将 ts 转换为 js、自动注入脚本或样式文件等等。

7.1 安装 Webpack 和必要的加载器

npm install --save-dev webpack webpack-cli ts-loader html-webpack-plugin mini-css-extract-plugin css-loader postcss postcss-loader copy-webpack-plugin
  • webpack : 核心打包工具。

  • ts-loader : 为 Webpack 转换 TypeScript。

  • html-webpack-plugin : 帮助生成带有注入脚本标签的 HTML 文件。

  • CSS and PostCSS Loaders : 用于处理 CSS(我们稍后将与 Tailwind 一起使用)。

  • CopyWebpackPlugin : 确保将 manifest.json 和任何其他资产(如图标)从 src 文件夹复制到 dist 文件夹。

7.2 Webpack 配置

接下来,我们需要配置 Webpack 来打包所有内容。创建 webpack.config.js 在项目根目录下:

const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';

return {
entry: {
popup: './src/popup/popup.ts',
background: './src/scripts/background.ts',
contentScript: './src/scripts/contentScript.ts',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new HtmlWebpackPlugin({
filename: 'popup.html',
template: 'src/popup/popup.html',
chunks: ['popup'],
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'src/manifest.json', to: 'manifest.json' },
// { from: 'src/icons', to: 'icons' }, // 复制任何其他资产
],
}),
],
mode: isProduction ? 'production' : 'development',
devtool: isProduction ? false : 'inline-source-map', // 在生产中禁用源映射
};
};

说明:

  • Entry Points : 我们指定了 popup.ts background.ts contentScript.ts 的入口点。

  • Output : 打包文件将输出到 dist 文件夹。

  • Loaders : 使用 ts-loader 处理 TypeScript,并使用 css-loader postcss-loader 处理 CSS(稍后我们将引入 Tailwind CSS)。

  • HtmlWebpackPlugin : 此插件自动将打包后的 popup.js 文件注入到 popup.html 文件中,确保我们的脚本正确链接。

7.3 使用 Webpack 打包扩展

让我们通过运行以下命令来打包所有内容:

npx webpack --mode development

这将把打包后的文件输出到 dist 目录中。

如果你在图标部分遇到问题,可以选择暂时删除它或放置一些占位的 .png 文件。

测试弹出窗口

点击按钮会弹出警报,可能会弹出两次。为什么会这样?

Webpack 可以注入脚本标签。检查一下你在 dist 文件夹中的 popup.js ,你会发现 popup.js 被注入了两次(一次来自 HTML 文件本身,一次来自 Webpack)。

span style="color: rgb(215, 58, 73);">html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Popuptitle>
<script defer src="popup.js">script>
head>
<body>
<div>
<h1>Hello, Chrome Extension!h1>
<button id="alertButton">Click mebutton>
div>
<script src="popup.js">script>
body>
html>

要解决这个问题,只需删除 src/popup 文件夹中的 标签,确保它看起来像这样:

span style="color: rgb(215, 58, 73);">html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Popuptitle>
head>
<body>
<div>
<h1>Hello, Chrome Extension!h1>
<button id="alertButton">Click mebutton>
div>
body>
html>

不用担心,Webpack 仍会在内部添加它。

8 添加 Tailwind 进行样式设计

Tailwind CSS 是一个以实用优先的 CSS 框架,让你可以在不为每个组件编写自定义 CSS 的情况下为用户界面进行样式设计。

多年来,人们对它越来越喜欢。虽然自己添加一些基本样式会更简单,但当你知道会在这个项目上花费时间时,Tailwind 使得后期扩展更容易,并能保持一致性,以便其他人加入时使用(相同的类名总是意味着相同的样式,而如果是自己实现的,font-size-small 可能会有多种含义)。

8.1 安装 Tailwind

npm install tailwindcss postcss postcss-loader autoprefixer

8.2 配置 Tailwind 和 PostCSS

接下来,我们需要初始化 Tailwind 和配置 PostCSS。通过以下命令初始化 Tailwind:

npx tailwindcss init

这将在项目根目录创建一个 tailwind.config.js 文件。打开该文件并修改,以包含 Tailwind 应该应用样式的路径(在我们的案例中,位于 src 文件夹内):

module.exports = {
content: ['./src/**/*.{ts,tsx,html}'],
theme: {
extend: {},
},
plugins: [],
};

content 键告诉 Tailwind 在你的文件中查找类。

接下来,在根目录中创建 postcss.config.js 文件,并配置它以使用 Tailwind 和 Autoprefixer:

module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

8.3 创建 Tailwind CSS 入口文件

src/styles 中创建一个名为 tailwind.css 的新文件。我们将在这里导入基本的 Tailwind 样式:

@tailwind base;
@tailwind components;
@tailwind utilities;

此文件将包括所有的 Tailwind 实用类。

8.4 修改 Webpack 配置以处理 CSS

我们需要确保 Webpack 知道如何使用 PostCSS 处理 CSS 文件。我们之前已经安装了 postcss-loader css-loader ,现在只需确保它们正确配置。

将以下配置更改为:

{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
}

这样可以确保 Webpack 在我们在弹出窗口中包含 Tailwind CSS 时进行处理。接下来,我们将继续实现这个功能。

8.5 在弹出窗口中导入 Tailwind

要开始使用 Tailwind,我们需要在 popup.ts 文件顶部添加以下导入语句:

import '../styles/tailwind.css';

8.6 添加简单的 Tailwind 样式

更新 popup.html 文件,使用一些 Tailwind 类进行基本样式设置。这样,我们的 popup.html 应该看起来像这样:

span style="color: rgb(215, 58, 73);">html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Popuptitle>
head>
<body class="bg-gray-100 p-4 w-80">
<div class="flex flex-col items-center">
<h1 class="text-xl font-bold mb-4">Hello, Chrome Extension!h1>
<button id="alertButton" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Click me
button>
div>
<script src="popup.js">script>
body>
html>

这为弹出窗口添加了背景色、居中内容和样式化的按钮。运行 npx webpack --mode development 重新构建它,看看效果。

9 为弹出窗口添加 React

现在我们有了一个功能性的扩展,包含 Tailwind 样式和 TypeScript 的语法优点。为了应对更复杂的 UI,比如加载和卸载数据、处理选项卡等,我们将添加 React。

9.1 安装 React 和 ReactDOM

npm install react react-dom @types/react @types/react-dom

9.2 更新 Webpack 以支持 React

我们需要更新 Webpack,以便它可以处理 .tsx 文件(使用 TypeScript 的 React)。记住,这正是我们设定的主要目标。 为此,请修改 webpack.config.js 文件,将 React 添加为入口点:

entry: {
popup: './src/popup/popup.tsx', // 更新为指向新的 React 组件
...
},
resolve: {
extensions: ['.ts', '.tsx', '.js'], // 添加 .tsx 以解析 React 文件
},
module: {
rules: [
{
test: /\.tsx?$/, // 同时处理 .ts 和 .tsx 文件
...

9.3 将 popup.ts 转换为 React 组件

现在我们将把 popup.ts 转换为一个 React 组件。将 popup.ts 重命名为 popup.tsx ,并更新为一个基本的 React 组件:

import React from 'react';
import { createRoot } from






请到「今天看啥」查看全文