我最近将我的一个项目——Twitter 极简主题——重写为 Next.js Chrome 扩展,因为我想使用 React 来开发弹出窗口。 使用 React 可以让我清晰地将扩展的弹出窗口组件及其应用逻辑与内容脚本分离,内容脚本是执行扩展功能所需的 CSS 和 JavaScript 文件。
您可能知道,有多种方法可以开始使用 React,从简单地添加脚本标签到使用推荐的工具链,例如Create React App、Gatsby 或 Next.js。 使用 Next.js 作为 React 框架,您会获得一些直接好处,例如使用 next export
获得的静态 HTML 功能。 虽然诸如预加载 JavaScript 和内置路由之类的功能很棒,但我重写 Chrome 扩展的主要目标是更好地组织代码,而这正是 Next.js 的优势所在。 它为您提供了最出色的开箱即用体验,无需太多不必要的文件和配置。 我尝试使用 Create React App 进行操作,但它有令人惊讶的样板代码,而我并不需要这些代码。
我认为将它转换为 Next.js Chrome 扩展可能很简单,因为它可以将 Next.js 应用程序导出为静态 HTML。 但是,其中有一些需要注意的地方,这篇文章就是为了告诉您这些需要注意的地方,以便您可以避免我犯的一些错误。
首先,如果您想直接查看代码,这里有GitHub 代码库。
您是 Chrome 扩展开发新手吗? Sarah Drasner 有一篇入门指南。
文件夹结构
next-export
是一个后处理步骤,它会编译您的 Next.js 代码,因此我们不需要在扩展中包含实际的 Next.js 或 React 代码。 这使我们能够将扩展保持在尽可能小的文件大小,这正是我们希望扩展最终发布到 Chrome 网上应用商店时所需要的。
因此,我的 Next.js Chrome 扩展的代码组织方式如下。 有两个目录——一个用于扩展的代码,另一个包含 Next.js 应用程序。
📂 extension
📄 manifest.json
📂 next-app
📂 pages
📂 public
📂 styles
📄 package.json
README.md
构建脚本
要在正常的 Web 项目中使用 next export
,您需要将 package.json
中的默认 Next.js 构建脚本修改为以下内容
"scripts": {
"build": "next build && next export"
}
然后,运行 npm run build
(或 yarn build
)将生成一个 out
目录。
但是,在这种涉及 Chrome 扩展的情况下,我们需要将输出导出到我们的 extension
目录,而不是 out
目录。 此外,我们必须重命名任何以下划线 (_
) 开头的文件,因为 Chrome 会发出警告,“以“_”开头的文件名保留供系统使用。”

因此,我们需要一个新的构建脚本,如下所示
"scripts": {
"build": "next build && next export && mv out/_next out/next && sed -i '' -e 's/\\/_next/\\.\\/next/g' out/**.html && mv out/index.html ../extension && rsync -va --delete-after out/next/ ../extension/next/"
}
sed
在 MacOS 上的工作方式与在 Linux 上不同。 MacOS 需要 '' -e
标志才能正常工作。 如果您使用的是 Linux,可以省略该标志。
资产
如果您在 Next.js 项目的 public
文件夹中使用任何资产,我们需要将它们也添加到 Chrome 扩展文件夹中。 为了组织,在 public
中添加一个 next-assets
文件夹可以确保您的资产不会直接输出到 extension
目录。
包含资产的完整构建脚本如下所示,它非常庞大
"scripts": {
"build": "next build && next export && mv out/_next out/next && sed -i '' -e 's/\\/_next/\\.\\/next/g' out/**.html && mv out/index.html ../extension && rsync -va --delete-after out/next/ ../extension/next/ && rm -rf out && rsync -va --delete-after public/next-assets ../extension/"
}
Chrome 扩展清单
激活 Chrome 扩展最常见的模式是在单击扩展时触发弹出窗口。 我们可以在清单 V3 中使用 action
关键字来实现。 并且在其中,我们可以指定 default_popup
,使其指向一个 HTML 文件。
这里我们指向 Next.js 中的 index.html
{
"name": "Next Chrome",
"description": "Next.js Chrome Extension starter",
"version": "0.0.1",
"manifest_version": 3,
"action": {
"default_title": "Next.js app",
"default_popup": "index.html"
}
}
action
API 在清单 V3 中取代了browserAction
和 pageAction
`。
Chrome 扩展不支持的 Next.js 功能
一些 Next.js 功能需要 Node.js Web 服务器,因此与服务器相关的功能,例如next/image
,不受 Chrome 扩展的支持。
开始开发
最后一步是测试更新的 Next.js Chrome 扩展。 从 next-app
目录运行 npm build
(或 yarn build
),同时确保 manifest.json
文件位于 extension
目录中。
然后,在新的 Chrome 浏览器窗口中转到 chrome://extensions
,启用*开发者模式*,然后单击*加载未打包*按钮。 选择您的 extension
目录,您就可以开始开发了!

总结
就是这样! 就像我说的,当我开始重写 Chrome 扩展时,这些都不是显而易见的。 但希望您现在已经了解了使用 Next.js 开发 Chrome 扩展的相对简单性。 希望它可以节省您为弄清楚它而花费的时间!
很棒的文章。 如何创建 Firefox 扩展? 它是否与您上面所做的类似? 另外,如何使用“浏览器”扩展 API 来创建适用于所有浏览器的通用扩展?
嗨 Abu! 是的,实际上,将 Chrome 扩展移植到 Firefox 现在非常兼容。 但是需要注意的是,他们目前对清单 V3 的计划不同
—— 移植 Google Chrome 扩展
假设我需要使用内容脚本,如何从内容脚本中访问组件?还是这不可行?
这可能实现,但配置起来非常困难,并且超出了本示例的范围。实际上,你不能在
content_scripts
内部导入模块——https://stackoverflow.com/a/58137279/7948880很棒的文章!我发现它很有帮助。
请注意,在您的示例中,您缺少对
/_next/
的一些引用,其中一个位于正则表达式中。我创建了一个基于 JavaScript 的快速脚本,它适用于所有平台。请在这里查看它的实际效果。
感谢 Weber!我喜欢你的脚本。
你能解释一下哪些引用丢失了吗?
嗨,托马斯
FYI,我设法通过将
manifest.json
包含在public
文件夹中来简化这一点。这样,它会在构建过程中自动复制。
我从午睡中醒来,意识到我必须做一个 Chrome 插件。我非常担心,直到我看到了这篇文章。非常简单,而且我成功运行了!这太棒了!谢谢!
很棒的帖子。非常感谢!
有一点我想稍微调整一下构建脚本。我花了一段时间才明白为什么在静态导出中链接到其他页面不起作用。
这是因为该脚本只移动了
index.html
文件。为了移动所有页面,我会将其更改为:谢谢!如果你想使用 Node.js,这里有一个 Webber 脚本的修改版本:https://github.com/typefully/minimal-twitter/blob/main/popup/sanitize.js