Building Web Extensions with Reactjs - from 0 to publish!

2025-06-09

使用 Reactjs 构建 Web 扩展 - 从 0 到发布!

Web 扩展 - 你可能听说过,很可能已经在用了 - 例如?AdBlock、Grammarly、Save to Pocket 等等。在本文中,我们将使用 Reactjs 从头开始​​构建一个 Web 扩展。

我们将制作一个“新标签问候扩展”并将其发布在Chrome Web Store和上Firefox Addon Dashboard


步骤 1 - 创建应用程序:

让我们用CRA创建一个 React 应用程序:

npx create-react-app greetings-web-extension
cd greetings-web-extension

让我们做一些快速清理:在文件夹
下,删除除和之外src的所有其他内容App.jsindex.jsindex.css

从文件夹中 - 删除除和 之外public的所有内容index.htmlfavicon.ico

最后,我们应该有以下目录结构:

  • 问候网络扩展
    • 节点模块
    • 民众
      • 网站图标
      • 索引.html
    • 源码
      • App.js
      • 索引.css
      • index.js
    • .gitignore
    • 包.json
    • 自述文件.md
    • 其他的

第 2 步 - 准备应用程序:

快速修改几个文件如下:

  • /src/index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

Enter fullscreen mode Exit fullscreen mode
  • /src/index.css
html,
body,
#root {
  height: 100%;
}

body {
  margin: 0;
  text-align: center;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.App {
  height: 100%;
  background: linear-gradient(to bottom right, #7b4397, #dc2430);
  color: white;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
}
Enter fullscreen mode Exit fullscreen mode
  • /src/App.js
import React from "react";

const greetings = {
  morning: "Good morning",
  noon: "Good afternoon",
  evening: "Good evening",
  night: "Good night",
};
class App extends React.Component {
  constructor() {
    super();
    this.state = {
      greeting: greetings.morning,
    };
    this.startTime = this.startTime.bind(this);
  }

  componentDidMount() {
    this.startTime();
  }

  startTime() {
    let today = new Date();
    let h = today.getHours();
    let greeting;
    if (h > 6 && h < 12) {
      greeting = greetings.morning;
    } else if (h >= 12 && h < 17) {
      greeting = greetings.noon;
    } else if (h >= 17 && h < 20) {
      greeting = greetings.evening;
    } else {
      greeting = greetings.night;
    }
    this.setState({ greeting });
    setTimeout(this.startTime, 1000);
  }

  render() {
    return (
      <div className="App">
        <h1>{this.state.greeting}</h1>
      </div>
    );
  }
}

export default App;
Enter fullscreen mode Exit fullscreen mode
  • /公共/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="theme-color" content="#000000" />
  <meta name="description" content="Web site created using create-react-app" />
  <title>Greetings</title>
</head>
<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

步骤3-测试React App:

让我们快速测试一下现有的东西。
启动它npm start

您应该在浏览器中看到类似这样的内容:

问候截图

步骤 4——准备 Web 扩展:

我们首先需要的是一个manifest.json文件——它是我们正在构建的 Web 扩展的描述文件。

创建一个目录extrasmanifest.json在其下创建一个新文件并复制/粘贴以下内容:

{
  "name": "greetings",
  "offline_enabled": true,
  "short_name": "greetings",
  "description": "Everyday greetings",
  "version": "1.0.0",
  "chrome_url_overrides": {
    "newtab": "index.html"
  },
  "manifest_version": 2
}
Enter fullscreen mode Exit fullscreen mode
  • offline_enabled:呃!
  • chrome_url_overrides:我们希望此扩展程序能够newtab用覆盖我们的index.html。因此……

现在,让我们为我们的 react-app 创建一个构建:
INLINE_RUNTIME_CHUNK=false react-scripts build

为什么INLINE_RUNTIME_CHUNK=false
因为如果我们不这样做,最终index.html构建过程中会包含一个内联脚本。扩展程序建议使用外部脚本,不鼓励使用内联脚本。使用INLINE_RUNTIME_CHUNK环境变量,我们可以绕过上述问题。

上述命令将导致build在我们的项目根目录下生成一个文件夹。

现在,将manifest.json我们创建的文件复制/粘贴到这个新的构建文件夹中。(为什么我们不直接在构建文件夹中创建文件?因为每次运行构建命令时,构建文件夹都会被清除并重新创建。因此,我们将其保存在 下extras。)

步骤 5——测试扩展:

现在启动 Chrome 浏览器,进入chrome://extensions/并启用开发者模式。

现在单击Load unpacked按钮并指向我们项目的构建文件夹。

通过在 Chrome 中打开新标签页进行测试。

步骤 6 - 为 Chrome 和 Firefox 打包:

Chrome 的打包只需一个 zip 命令即可。Firefox
的打包可以使用推荐的工具web-ext。使用 全局安装即可npm i -g web-ext

为了帮助您省去复制/粘贴 manifest.json 文件、运行 Firefox 和 Chrome 打包命令等手动步骤,我创建了一个node.js可以完成这项工作的小脚本。

在项目根目录下创建一个新文件,我们称之为buildPackage.js。将以下内容放入其中。

const { execSync } = require("child_process");

// FILENAMES
const manifestFileName = "manifest.json";

// DIRECTORIES
const buildDir = "./build/";
const extensionDir = "./extras/";
const outputs = "./";

// OUTPUTS
const chromeOutput = "greetings-chrome.zip";

console.log("Building Extension Packages");

console.log("***COPYING MANIFEST FILE***\n\n");
execSync(
  `cp ${extensionDir}${manifestFileName} ${buildDir}${manifestFileName}`
);

execSync(`zip -r ${outputs}${chromeOutput} ${buildDir}`);
console.log("***CHROME BUILT SUCCESSFULLY***\n\n");

execSync(`web-ext build -s ${buildDir} -a ${outputs} --overwrite-dest`);
console.log("***FIREFOX BUILT SUCCESSFULLY***");
Enter fullscreen mode Exit fullscreen mode

修改package.json以将此脚本作为构建过程的一部分运行。在scriptspackage.json标签下,按如下所示进行修改:

“build”:“INLINE_RUNTIME_CHUNK = false react-scripts build && node buildPackage.js”,

现在使用触发构建脚本npm run build,您应该会看到在项目根目录中创建了 2 个新文件:

  1. Greetings-chrome.zip //适用于 Chrome
  2. Greetings-1.0.0.zip // 适用于 Firefox

步骤 7 - 发布:

铬合金:

  1. 前往Google Chrome 开发者信息中心
  2. 使用您的 Google 帐户登录或创建一个新帐户
  3. 点击“+ 新建项目”按钮
  4. 添加greetings-chrome.zip上一步创建的文件
  5. 填写所需信息并提交审核

(通常需要 12 小时左右才能发布)

火狐浏览器:

  1. 前往Mozilla 附加组件仪表板
  2. 使用您的 Mozilla 帐户登录或创建一个新帐户
  3. 点击提交新附加组件按钮
  4. 对于分发,选择On this site并继续
  5. 添加greetings-1.0.0.zip上一步创建的文件
  6. 填写所需信息并提交审核

(通常需要 6-10 分钟左右发布)


最后说明:

  • 您需要为扩展程序添加一个图标,请创建一个尺寸为 128x128 的图标(命名为 icon_128.png),并将其放在构建目录中。将以下内容添加到manifest.json
  "icons": {
    "128": "icon_128.png"
  },
Enter fullscreen mode Exit fullscreen mode
  • 在某些情况下,您的 Web 扩展程序可能需要存储和检索数据。虽然您可以使用浏览器本地存储 (localStorage),但我们强烈建议不要将其用于 Web 扩展程序。您应该为扩展程序使用更可靠的专用数据库存储区域。点击此处了解更多信息。
  • 这是我们创建的一个非常基本的扩展,通常,它可能会更复杂一些 - 包括 API 调用、存储、后台脚本等。所有这些都是可能的!
  • 尝试保持 Web 扩展轻量 - 这意味着扩展应该加载速度快、应该服务于单一目的、应该是可访问的,等等。

我创建了一个适用于 Chrome 和 Firefox 的 Web 扩展程序 - minimylist。如果您喜欢,欢迎查看并分享。


下次再见,再见!👋🏻

鏂囩珷鏉ユ簮锛�https://dev.to/yashsoni/building-web-extensions-with-reactjs-from-0-to-publish-54no
PREV
使用自定义非 root 用户运行 Docker 容器:同步主机和容器权限
NEXT
Nextless.js - 具有无服务器后端的 Next JS SaaS 样板模板