处理远程托管代码违规行为

远程托管代码 (RHC) 是 Chrome 应用商店对浏览器执行的任何内容的称呼,这些内容是从扩展程序自身文件以外的其他位置加载的。例如 JavaScript 和 WASM。 __但不包括数据或 JSON 或 CSS 等内容。

为什么不再允许使用 RHC?

现在,使用 Manifest V3 的扩展程序需要将所使用的 所有 代码捆绑到扩展程序本身中。过去,您可以从网络上的任何网址动态注入脚本标记。

我被告知我的扩展程序包含 RHC。这是怎么回事?

如果您的扩展程序在审核期间因 Blue Argon 错误而被拒绝,则 我们的审核人员认为您的扩展程序正在使用远程托管代码。这通常是由于扩展程序尝试添加带有远程 资源(即来自开放式网络,而不是扩展程序中包含的文件)的脚本标记,或提取资源以直接执行而导致的。

如何发现 RHC

一旦您知道要查找的内容,发现 RHC 并不难。首先,检查您的项目中是否存在字符串“http://”或“https://”。如果您违反了 RHC 政策,则很可能可以通过查找这些字符串来找到违规代码。如果您有完整的构建系统,或者使用来自 npm 或其他第三方来源的依赖项,请确保搜索代码的 已编译 版本,因为这是应用商店评估的内容。如果您仍然无法 找到问题,则下一步是与 One Stop Support 联系。他们将能够概述具体违规行为,以及尽快发布扩展程序所需的内容。

如果库请求代码,该怎么办

无论代码来自何处,都不允许包含 RHC。这包括您并非自行编写,而只是在项目中用作依赖项的代码。一些开发者在使用 Firebase 时遇到了此问题,当时正在纳入远程代码以供 Firebase Auth 使用。即使这是一个第一方(即 Google 拥有的)库,RHC 也没有例外情况。您需要配置代码以移除 RHC,或者更新项目以从一开始就不包含该代码。如果您遇到问题,发现加载 RHC 的不是 您的 代码,而是您使用的库,那么最好的做法是与库的作者联系。让他们知道发生了这种情况,并要求他们提供解决方法或代码更新以移除 RHC。

如果您无法等待库更新,该怎么办

有些库会在收到通知后几乎立即发布更新,但有些库可能会被废弃,或者需要一段时间才能解决问题。根据具体违规行为中发生的 情况 ,您可能不需要等待他们采取行动,即可解除封锁并成功完成审核。您可以使用多种选项来快速恢复运行。

审核代码

确定 需要导致请求的代码吗?如果只需删除该代码,或者移除导致该代码的库,那么删除该代码即可完成任务。

或者,是否有其他库提供相同的功能?尝试 查看 npmjs.com、GitHub 或其他网站,了解是否有其他选项可以满足 相同的使用场景。

摇树(优化)

如果导致 RHC 违规的代码实际上未使用,则工具可能会自动删除该代码。现代构建工具(例如 webpackRollupVite,仅举几例)具有一项称为 “摇树 (优化)”的功能。在构建系统上启用后,摇树(优化)应会移除所有未使用的代码路径。这可能意味着您不仅拥有更合规的代码版本,而且还拥有更精简、更快速的版本!请务必注意,并非所有库都能够进行摇树(优化),但许多库都可以。某些 工具(例如 Rollup 和 Vite)默认启用摇树(优化)。您需要配置 webpack 才能启用摇树(优化)。如果您没有将构建系统作为扩展程序的一部分使用,但 确实 使用了代码库,那么我们强烈建议您考虑将构建工具添加到工作流中。构建工具可帮助您编写更安全、更可靠且更易于维护的项目。

如何实现摇树(优化)的具体细节取决于您的具体项目。 但以 Rollup 为例,您只需编译项目代码即可添加摇树(优化)。例如,如果您有一个仅登录 Firebase Auth 的文件,名为 main.js:

import { GoogleAuthProvider, initializeAuth } from "firebase/auth";

chrome.identity.getAuthToken({ 'interactive': true }, async (token) => {
  const credential = GoogleAuthProvider.credential(null, token);
  try {
    const app = initializeApp({ ... });
    const auth = initializeAuth(app, { popupRedirectResolver: undefined, persistence: indexDBLocalPersistence });
    const { user } = await auth.signInWithCredential(credential)
    console.log(user)
  } catch (e) {
    console.error(error);
  }
});

那么,您只需告知 Rollup 输入文件、加载节点文件所需的插件 @rollup/plugin-node-resolve,以及它生成的输出 文件的名称即可。

npx rollup --input main.js --plugin '@rollup/plugin-node-resolve' --file compiled.js

在终端窗口中运行该命令后,您将收到生成的 main.js 文件版本,所有内容都编译到一个名为 compiled.js 的文件中。

Rollup 可能很简单,但它也 非常 可配置。您可以添加各种 复杂的逻辑和配置,只需查看其文档即可。 添加此类构建工具将生成更小、更高效的代码,在这种情况下,还可以解决远程托管代码问题。

自动修改文件

远程托管代码进入代码库的一种越来越常见的方式是作为您包含的库的子依赖项。如果库 X 想要从 CDN importY,您仍然需要更新它,使其从本地来源加载。借助现代构建系统,您可以轻松创建插件来提取远程引用,并将其直接内嵌到代码中。

也就是说,对于如下所示的代码:

import moment from "https://unpkg.com/moment@2.29.4/moment.js"
console.log(moment())

您可以制作一个小型 Rollup 插件。

import { existsSync } from 'fs';
import fetch from 'node-fetch';

export default {
  plugins: [{