リモートホスト型コード(RHC)とは、Chrome ウェブストアで、拡張機能の独自のファイル以外の場所から読み込まれ、ブラウザによって実行されるものを指す用語です。JavaScript や WASM などです。データや JSON、CSS などのものは含まれません。
RHC が許可されなくなったのはなぜですか?
Manifest V3 拡張機能では、使用するすべてのコードを拡張機能自体にバンドルする必要があります。以前は、ウェブ上の任意の URL からスクリプトタグを動的に挿入できました。
拡張機能に RHC があると言われました。どうしましたか?
審査中に Blue Argon エラーが発生して拡張機能が不承認になった場合、審査担当者は拡張機能がリモートでホストされているコードを使用していると判断しています。これは通常、拡張機能がリモート リソース(拡張機能に含まれるファイルではなく、オープン ウェブから)を含むスクリプトタグを追加しようとしたり、直接実行するリソースをフェッチしようとしたりした結果です。
RHC を見分ける方法
RHC は、何を探すべきかわかっていれば、特に見つけるのが難しいわけではありません。まず、プロジェクトで「http://」または「https://」という文字列を探します。RHC 違反がある場合は、その検出結果を見つけることで、違反の場所を特定できる可能性があります。完全なビルドシステムがある場合や、npm などのサードパーティ ソースの依存関係を使用している場合は、コードのコンパイル済みバージョンを検索していることを確認してください。ストアで評価されるのはコンパイル済みバージョンです。それでも問題が見つからない場合は、One Stop Support にお問い合わせください。違反の具体的な内容と、拡張機能をできるだけ早く公開するために必要な手順を説明します。
ライブラリがコードをリクエストしている場合の対処方法
コードの出所に関係なく、RHC を含めることはできません。これには、作成したコードだけでなく、プロジェクトで依存関係として使用しているコードも含まれます。Firebase を使用している一部のデベロッパーは、Firebase Auth で使用するためにリモートコードを含めているときに、この問題が発生しました。これはファーストパーティ(Google 所有)のライブラリでしたが、RHC に例外は適用されませんでした。RHC を削除するか、最初からコードを含まないようにプロジェクトを更新するようにコードを構成する必要があります。RHC を読み込んでいるのが自分のコードではなく、使用しているライブラリであるという問題が発生した場合は、ライブラリの作成者に連絡するのが最善の方法です。この問題が発生していることを伝え、回避策またはコードの更新による削除を依頼します。
ライブラリの更新を待てない場合
ライブラリによっては、通知後すぐにアップデートがリリースされることもありますが、放置されたり、問題の解決に時間がかかったりすることもあります。特定の違反で何が発生しているかによっては、ブロックが解除されて審査が完了するまで待つ必要がない場合があります。迅速に復旧するためのオプションがいくつかあります。
コードを監査する
リクエストの原因となっているコードが必要であることを確認してください。削除するだけで済む場合や、原因となっているライブラリを削除できる場合は、そのコードを削除すれば完了です。
同じ機能を提供する別のライブラリはありますか?npmjs.com、GitHub などのサイトで、同じユースケースを満たす他のオプションを確認してみてください。
ツリー シェイキング
RHC 違反の原因となっているコードが実際には使用されていない場合、ツールによって自動的に削除される可能性があります。webpack、Rollup、Vite などの最新のビルドツールには、ツリー シェイキングと呼ばれる機能があります。ビルドシステムでツリー シェイキングを有効にすると、未使用のコードパスが削除されます。つまり、コードの準拠バージョンだけでなく、より効率的で高速なバージョンも作成できるということです。すべてのライブラリがツリー シェイクできるわけではありませんが、多くのライブラリはツリー シェイクできます。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 という名前の 1 つのファイルにコンパイルされています。
ロールアップはシンプルにすることもできますが、非常に柔軟に構成することもできます。複雑なロジックや構成を追加できます。詳しくは、ドキュメントをご覧ください。このようなビルドツールを追加すると、コードがより小さく効率的になり、この場合はリモート ホスト型コードの問題が解決します。
ファイルを自動的に編集する
リモートでホストされているコードがコードベースに侵入する一般的な方法として、組み込んでいるライブラリのサブ依存関係として侵入する方法があります。ライブラリ X が CDN からライブラリ import Y を取得する場合、ローカル ソースから読み込むように更新する必要があります。最新のビルドシステムを使用すると、リモート参照を抽出してコードに直接インライン化するプラグインを簡単に作成できます。
つまり、次のようなコードが与えられた場合、
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: [{ load: async function transform(id, options, outputOptions) { // this code runs over all of out javascript, so we check every import // to see if it resolves as a local file, if that fails, we grab it from // the network using fetch, and return the contents of that file directly inline if (!existsSync(id)) { const response = await fetch(id); const code = await response.text(); return code } return null } }] };
新しいプラグインでビルドを実行すると、コード、サブ依存関係、サブサブ依存関係などに関係なく、すべてのリモート import URL が検出されます。
npx rollup --input main.js --config ./rollup.config.mjs --file compiled.js
ファイルを手動で編集する
最も簡単な方法は、RHC の原因となっているコードを削除することです。任意のテキスト エディタで開き、違反している行を削除します。一般的に、この方法は脆弱で忘れられる可能性があるため、あまり推奨されません。「library.min.js」という名前のファイルが実際には library.min.js でない場合、プロジェクトのメンテナンスが難しくなります。生のファイルを編集する代わりに、patch-package などのツールを使用する方が、保守しやすいオプションです。これは、ファイル自体ではなく、ファイルへの変更を保存できる非常に強力なオプションです。これは、Git や Subversion などのバージョン管理システムを支えるものと同じ種類の パッチファイル上に構築されています。違反しているコードを手動で変更し、差分ファイルを保存して、適用する変更で patch-package を構成するだけです。チュートリアルの全文は、プロジェクトの README で確認できます。プロジェクトにパッチを適用する場合は、プロジェクトに連絡して、変更をアップストリームで行うようリクエストすることを強くおすすめします。patch-package を使用するとパッチの管理がはるかに簡単になりますが、パッチを適用する必要がないのが一番です。
コードが使用されていない場合の対処方法
コードベースが大きくなると、依存関係(または依存関係の依存関係など)によって、使用されなくなったコードパスが保持される可能性があります。これらのセクションのいずれかに RHC を読み込むか実行するコードが含まれている場合は、そのコードを削除する必要があります。使用済みか未使用かは関係ありません。使用されていない場合は、ツリーシェイキングするか、ライブラリにパッチを適用して削除する必要があります。
回避策はありますか?
一般的に、RHC は許可されていません。ただし、ごく一部のケースでは許可されています。これは、他のオプションではほぼ不可能な場合に限られます。
User Scripts API
ユーザー スクリプトは、通常はユーザーが提供する小さなコード スニペットで、TamperMonkey や Violentmonkey などのユーザー スクリプト マネージャーを対象としています。これらのマネージャーはユーザーが記述したコードをバンドルできないため、User Script API はユーザーが提供したコードを実行する方法を公開します。これは chrome.scripting.executeScript や他のコード実行環境の代わりにはなりません。ユーザーが何かを実行するには、デベロッパー モードを有効にする必要があります。Chrome ウェブストアの審査チームが、この機能が本来の目的以外の方法で使用されている(ユーザーが提供したコードなど)と判断した場合は、拒否されるか、ストアからリスティングが削除される可能性があります。
chrome.debugger
chrome.debugger API を使用すると、拡張機能は Chrome Devtools Protocol を操作できます。これは、Chrome の Devtools や他の多くのツールで使用されているのと同じプロトコルです。これにより、拡張機能はリモートコードをリクエストして実行できます。ユーザー スクリプトと同様に、chrome.scripting の代わりにはならず、ユーザー エクスペリエンスは大幅に向上します。使用中は、ウィンドウの上部に警告バーが表示されます。バナーを閉じるか閉じると、デバッグ セッションは終了します。
サンドボックス化された iframe
文字列をコードとして評価する必要があり、DOM 環境(拡張機能の Service Worker ではなく、コンテンツ スクリプトなど)にいる場合は、サンドボックス化された iframe を使用する方法もあります。拡張機能は、安全対策として、デフォルトで eval() などの機能をサポートしていません。悪意のあるコードは、ユーザーの安全性とセキュリティを危険にさらす可能性があります。しかし、コードが既知の安全な環境(ウェブの他の部分からサンドボックス化された iframe など)でのみ実行される場合、これらのリスクは大幅に軽減されます。このコンテキスト内では、eval の使用をブロックするコンテンツ セキュリティ ポリシーを解除して、有効な JavaScript コードを実行できます。
対象外のユースケースがある場合は、chromium-extensions メーリング リストを使用してチームに連絡し、フィードバックを得るか、新しいチケットを開いて One Stop Support からガイダンスをリクエストしてください。
判決に同意できない場合
ポリシーの適用は複雑な場合があり、審査には手動入力が伴います。そのため、Chrome ウェブストア チームがレビューの決定の変更に同意することがあります。審査に誤りがあったと思われる場合は、One Stop Support を使用して不承認に対する再審査を請求できます。