WXT浏览器插件开发中文教程(3)----WXT全部入口项详解

前言

大家好,我是倔强青铜三 。是一名热情的软件工程师,我热衷于分享和传播IT技术,致力于通过我的知识和技能推动技术交流与创新,欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!!!

入口项

WXT 在捆绑扩展时,将 entrypoints/ 目录中的文件作为输入。这些文件可以是 HTML、JS、CSS 或 Vite 支持的任何变体(如 Pug、TS、JSX、SCSS 等)。

以下是一个入口项示例:

html 复制代码
📂 entrypoints/
   📂 popup/
      📄 index.html
      📄 main.ts
      📄 style.css
   📄 background.ts
   📄 content.ts

已列出与未列出

对于网络扩展,有两种类型的入口项:

  • 已列出 :在 manifest.json 中引用
  • 未列出 :不在 manifest.json 中引用

在 WXT 的其余文档中,已列出的入口项按名称引用。例如:

  • 弹出窗口
  • 选项
  • 背景
  • 内容脚本
  • 等等

一些"未列出"的入口项示例:

  • 扩展安装时显示的欢迎页面
  • 内容脚本注入到页面主世界中的 JS 文件

提示

无论入口项是已列出还是未列出,它都会被捆绑到扩展中,并在运行时可用。

添加入口项

入口项可以定义为单个文件或包含 index 文件的目录。

单个文件目录

html 复制代码
📂 entrypoints/
   📄 background.ts
html 复制代码
📂 entrypoints/
   📂 background/
      📄 index.ts

入口项的名称决定其类型,即已列出与未列出。在此示例中,"background" 是 背景入口项 的名称。

有关已列出入口项的完整列表及其文件名模式,请参阅 入口项类型 部分。

定义清单选项

大多数已列出的入口点需要添加到 manifest.json 的选项。但使用 WXT 时,无需在单独的文件中定义这些选项,而是 在入口项文件本身内定义这些选项

例如,以下是如何为内容脚本定义 matches

entrypoints/content.ts

ts 复制代码
export default defineContentScript({
  matches: ['*://*.wxt.dev/*'],
  main() {
    // ...
  },
});

对于 HTML 入口项,选项配置为 <meta> 标签。例如,要为 MV2 弹出窗口使用 page_action

html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta name="manifest.type" content="page_action" />
  </head>
</html>

请参阅 入口项类型 部分,以获取可在每个入口项内配置的选项列表及其定义方法。

构建扩展时,WXT 会查看入口项中定义的选项,并据此生成清单。

入口项类型

background脚本

Chrome 文档Firefox 文档

对于 MV2,background脚本作为脚本添加到后台页面。对于 MV3,background脚本变为服务工作线程。

文件名 输出路径
entrypoints/background.[jt]s /background.js
entrypoints/background/index.[jt]s /background.js

最小化并带有清单选项

ts 复制代码
export default defineBackground(() => {
  // 背景加载时执行
});
ts 复制代码
export default defineBackground({
  // 设置清单选项
  persistent: undefined | true | false,
  type: undefined | 'module',
  // 如果背景应从某些构建中移除,则设置 include/exclude
  include: undefined | string[],
  exclude: undefined | string[],
  main() {
    // 背景加载时执行,不能是异步的
  },
});

书签

Chrome 文档Firefox 文档

文件名 输出路径
entrypoints/bookmarks.html /bookmarks.html
entrypoints/bookmarks/index.html /bookmarks.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>标题</title>
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

内容脚本

Chrome 文档Firefox 文档

有关在内容脚本中创建 UI 和包含 CSS 的更多信息,请参阅 内容脚本 UI

文件名 输出路径
entrypoints/content.[jt]sx? /content-scripts/content.js
entrypoints/content/index.[jt]sx? /content-scripts/content.js
entrypoints/<name>.content.[jt]sx? /content-scripts/<name>.js
entrypoints/<name>.content/index.[jt]sx? /content-scripts/<name>.js
ts 复制代码
export default defineContentScript({
  // 设置清单选项
  matches: string[],
  excludeMatches: undefined | [],
  includeGlobs: undefined | [],
  excludeGlobs: undefined | [],
  allFrames: undefined | true | false,
  runAt: undefined | 'document_start' | 'document_end' | 'document_idle',
  matchAboutBlank: undefined | true | false,
  matchOriginAsFallback: undefined | true | false,
  world: undefined | 'ISOLATED' | 'MAIN',
  // 如果背景应从某些构建中移除,则设置 include/exclude
  include: undefined | string[],
  exclude: undefined | string[],
  // 配置 CSS 如何注入到页面
  cssInjectionMode: undefined | "manifest" | "manual" | "ui",
  // 配置内容脚本的注册方式
  registration: undefined | "manifest" | "runtime",
  main(ctx: ContentScriptContext) {
    // 内容脚本加载时执行,可以是异步的
  },
});

开发者工具

Chrome 文档Firefox 文档

请遵循 开发者工具示例 以添加不同的面板和窗格。

文件名 输出路径
entrypoints/devtools.html /devtools.html
entrypoints/devtools/index.html /devtools.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

历史记录

Chrome 文档Firefox 文档

文件名 输出路径
entrypoints/history.html /history.html
entrypoints/history/index.html /history.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>标题</title>
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

新标签页

Chrome 文档Firefox 文档

文件名 输出路径
entrypoints/newtab.html /newtab.html
entrypoints/newtab/index.html /newtab.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>标题</title>
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

选项

Chrome 文档Firefox 文档

文件名 输出路径
entrypoints/options.html /options.html
entrypoints/options/index.html /options.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>选项标题</title>
    <!-- 自定义清单选项 -->
    <meta name="manifest.open_in_tab" content="true|false" />
    <meta name="manifest.chrome_style" content="true|false" />
    <meta name="manifest.browser_style" content="true|false" />
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

弹出窗口

Chrome 文档Firefox 文档

文件名 输出路径
entrypoints/popup.html /popup.html
entrypoints/popup/index.html /popup.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 在清单中设置 `action.default_title` -->
    <title>默认弹出窗口标题</title>
    <!-- 自定义清单选项 -->
    <meta
      name="manifest.default_icon"
      content="{
        16: '/icon-16.png',
        24: '/icon-24.png',
        ...
      }"
    />
    <meta name="manifest.type" content="page_action|browser_action" />
    <meta name="manifest.browser_style" content="true|false" />
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

沙盒

Chrome 文档

仅限 Chromium

Firefox 不支持沙盒页面。

文件名 输出路径
entrypoints/sandbox.html /sandbox.html
entrypoints/sandbox/index.html /sandbox.html
entrypoints/<name>.sandbox.html /<name>.html
entrypoints/<name>.sandbox/index.html /<name>.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>标题</title>
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

侧边面板

Chrome 文档Firefox 文档

在 Chrome 中,侧边面板使用 side_panel API,而在 Firefox 中则使用 sidebar_action API。

文件名 输出路径
entrypoints/sidepanel.html /sidepanel.html
entrypoints/sidepanel/index.html /sidepanel.html
entrypoints/<name>.sidepanel.html ``/<name>.html```
entrypoints/<name>.sidepanel/index.html ``/<name>.html```
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>默认侧边面板标题</title>
    <!-- 自定义清单选项 -->
    <meta
      name="manifest.default_icon"
      content="{
        16: '/icon-16.png',
        24: '/icon-24.png',
        ...
      }"
    />
    <meta name="manifest.open_at_install" content="true|false" />
    <meta name="manifest.browser_style" content="true|false" />
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

[未列出的 CSS](#未列出的 CSS "#unlisted-css")

按照 Vite 的指南设置首选的预处理器:vitejs.dev/guide/featu...

CSS 入口点总是未列出的。要将 CSS 添加到内容脚本,请参阅 内容脚本 文档。

文件名 输出路径
`entrypoints/<name>.(css scss
`entrypoints/<name>/index.(css scss
`entrypoints/content.(css scss
`entrypoints/content/index.(css scss
`entrypoints/<name>.content.(css scss
`entrypoints/<name>.content/index.(css scss
css 复制代码
body {
  /* ... */
}

未列出的页面

文件名 输出路径
entrypoints/<name>.html /<name>.html
entrypoints/<name>/index.html /<name>.html
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>标题</title>
    <!-- 如果页面应从某些构建中移除,则设置 include/exclude -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

页面可通过 /<name>.html 访问:

ts 复制代码
const url = browser.runtime.getURL('/<name>.html');
console.log(url); // "chrome-extension://<id>/<name>.html"

未列出的脚本

文件名 输出路径
entrypoints/<name>.[jt]sx? /<name>.js
entrypoints/<name>/index.[jt]sx? /<name>.js

最小化并带有选项

ts 复制代码
export default defineUnlistedScript(() => {
  // 脚本加载时执行
});
ts 复制代码
export default defineUnlistedScript({
  // 如果脚本应从某些构建中移除,则设置 include/exclude
  include: undefined | string[],
  exclude: undefined | string[],
  main() {
    // 脚本加载时执行
  },
});

脚本可从 /<name>.js 访问:

ts 复制代码
const url = browser.runtime.getURL('/<name>.js');
console.log(url); // "chrome-extension://<id>/<name>.js"

你需要负责在需要的地方加载/运行这些脚本。如果需要,别忘了将脚本及相关资源添加到 web_accessible_resources

最后感谢阅读!欢迎关注我,微信公众号倔强青铜三。欢迎点赞收藏关注,一键三连!!!

相关推荐
加班是不可能的,除非双倍日工资2 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip3 小时前
vite和webpack打包结构控制
前端·javascript
excel3 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国3 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼3 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy3 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
草梅友仁3 小时前
草梅 Auth 1.4.0 发布与 ESLint v9 更新 | 2025 年第 33 周草梅周报
vue.js·github·nuxt.js
ZXT4 小时前
promise & async await总结
前端
Jerry说前后端4 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化