Skip to content

build chrome extension with vite

vite 脚手架

特点

  • 支持原生 ES 模块、模块热更新(HMR,Hot Module Reload)
  • 使用 Rollup 打包代码
  • 将根目录 index.html 作为代码入口

vite 脚手架生成 React + TypeScript 项目

shell
pnpm create vite myext --template react-ts
cd myext
pnpm install
pnpm run dev

vite 脚手架生成项目在根目录有 tsconfig.json tsconfig.node.json 两个 tsconfig 配置文件,前者针对浏览器环境配置,后者是 构建工具/node。

ref: https://stackoverflow.com/questions/72027949/why-does-vite-create-two-typescript-config-files-tsconfig-json-and-tsconfig-nod

热更新

有两个阶段热更新

  • TypeScript modules => JavaScript/ESM
  • JavaScript/ESM => Chrome Extension

第一个阶段 vite 内置支持 模块热更新(HMR,Hot Module Reload); 第二个阶段部分 Chrome 内置支持,部分需要编码控制 vite 构建流程支持。

第一阶段热更新

设置第一阶段热更新,vite 监控 src 目录下文件变动,则重新构建,修改 package.json

json:
{
  "scripts": {
    "dev": "vite build --mode development --watch",
    "build": "tsc && vite build",
    // ...
  }
  // ...
}

注:修改 vite.config.ts、安装了新 npm 包,则需要手动重启执行一次 npm run dev 。

第二阶段热更新

Chrome 内置支持扩展部分模块热更新,以下模块变动情况时,需要在 Chrome 浏览器 Extensions 页面手动点击「重新加载」

  • The manifest
  • Service worker
  • Content Scripts (以及 host page)

以下变动则不需要

  • The popup
  • Options page
  • Other extension HTML pages

源码映射和断点调试

修改 tsconfig.json 配置

json:
{
  "compilerOptions": {
    "sourceMap": true,
    // ...
  }
}

修改 vite.config.ts 配置

typescript:
export default defineConfig(({ mode }) => {
  const isDev = mode === "development";
  console.log({ isDev, mode })

  return {
    build: {
      sourcemap: isDev ? "inline" : false,
    }
    // ...
  }
})

packge.json 修改 vite build 增加 --mode 参数强制为 development

json:
{
  "scripts": {
    "dev": "vite build --mode development --watch"
    // ...
  }
}

在需要断点调试的源码加上 console.log("some msg")
浏览器重载插件,启动相关插件/页面;
在 Chrome 浏览器 F12 console 快速定位输出 日志行,留意输出右侧将是 xx.js/xx.html 变为有对应源码文件和行数的 xx.ts/xx.tsx,
点击 xx.ts/xx.tsx 会自动跳转到对应源码上下文,在源代码标签页左侧点击添加红点即可设置断点调试。

将 Chrome 插件代码转换为 Safari 插件

shell
xcrun safari-web-extension-converter \
--project-location . \
--app-name <插件名,如 MyExtension> \
--bundle-identifier <苹果商店应用 bundle ID,如 com.compnay.my-extension> \
--objc \
--macos-only \
--no-prompt \
--no-open \
--force \
<chrome 插件构建输出后路径,如 dist/chrome-mv3>

ref: https://developer.apple.com/documentation/safariservices/converting-a-web-extension-for-safari?language=objc

多语言 i18n

本地化消息翻译翻译 messages.json 文件 中,key 取值必须满足以下范围 a-zA-Z0-9_

由于不允许空格,因此翻译文本变量均为骆驼峰样式,如 areYouOk

常见问题

xcode Info.plist 添加 ITSAppUsesNonExemptEncryption key 选项

避免每次审核需要手动确认符合加密算法出口管制合规要求。

ref: https://developer.apple.com/documentation/security/complying-with-encryption-export-regulations

xcode 上传 safari extension archive 提示 Potential Loss of Keychain Access

xcode archive 上传完成后弹窗提示:

Upload completed with warnings: App Store Connect Warning Potential Loss of Keychain Access. The previous version of software has an application-identifier value of ['<OLD_TEAM_ID>.<BUNDLE_ID>'] and the new version of software being submitted has an application-identifier of ['<NEW_TEAM_ID>>.<BUNDLE_ID>']. This will result in a loss of keychain access.

点 Done 关闭,在 App Store Connect 网站确认上传成功即可。

调试 safari extension background script

Develop - Web Extension Background Content - Xxx (extension name)

Cannot find module xxx or its corresponding type declarations 2307

vite.config.ts 中导入 node 模块 IDE 报错 Cannot find module 'path' or its corresponding type declarations.ts(2307)

解决:

  • 安装 node 类型声明包 npm i -D @types/node
  • tsconfig.node.json 配置 compilerOptions 选项增加 "types": ["node"]
  • 重启 IDE

Error: EBUSY: resource busy or locked

Widows 平台上间隔抛出 Error: EBUSY: resource busy or locked, lstat 'C:\DumpStack.log.tmp' 错误

解决:TBD.

在 vite.config.ts 中引用 import.meta.env 报错 undefined

解决:使用 node 进程环境变量代替,如 import.meta.env.MODE => process.env.MODE

另见

Cannot find namespace/name chrome

安装包 @types/chrome

修改 tsconfig.node.json

json:
{
  "compilerOptions": {
    "types": [
        "node",
        "chrome",
    ],
    // ...
  }
}

重启 VSCode IDE

Xxx is declared but its value is never read 6133

修改配置 tsconfig.json

json:
{
  "compilerOptions": {
    /* Linting */
    "noUnusedLocals": false,
    "noUnusedParameters": false
  }
}

改变商店应用属主

Web storeSupportHow
Safari App StoreYesinitiative transfer app in App Store Connect - General - App Information
Chrome Web StoreNo-
Edge Add-onsYes发送邮件申请官方协助处理 ext_dev_support@microsoft.com

See also

注册企业帐号

Web storeHowNotes
Safari App StoreD-U-N-S, Apple Developer Subscription fee USD 99/y-
Chrome Web StoreD-U-N-S, one-time fee USD 5-
Edge Add-onsD-U-N-S, plus company domain name and email-

Released under the CC-BY-NC-4.0