Framework
Content Scripts

コンテンツスクリプト

コンテンツスクリプトは、_分離されたワールド_内のウェブページのコンテキストで実行されます。これにより、さまざまな拡張機能からの複数のコンテンツスクリプトが互いの実行と競合することなく共存し、ページの JavaScript から分離された状態を維持できます。

.ts で終わるスクリプトには、フロントエンドランタイム (react/vue/svelte) がバンドルされず、UI スクリプトとして扱われません。一方、.tsx.vue、または .svelte で終わるスクリプトは、UI スクリプトとして扱われます。

使用例:

単一のコンテンツスクリプトの追加

🚨

Plasmo のデフォルトの Typescript 構成では、すべてのソースファイルがモジュールとして扱われるため、コードにインポートやエクスポートがない場合は、ファイルの先頭に export {} 行を追加する必要があります。(最初のコンテンツスクリプトを作成するときに、この警告が表示されます!)

content.ts ファイルを作成し、空のオブジェクトをエクスポートして、自由にコードを記述してください!

content.ts
export {}
console.log(
  "You may find that having is not so pleasing a thing as wanting. This is not logical, but it is often true."
)

拡張機能を再読み込みし、ウェブページを開いてから、そのインスペクターを開きます。

content-script-spock-quote

完全な例については、with-content-script (opens in a new tab) を参照してください。

複数のコンテンツスクリプトの追加

複数のコンテンツスクリプト用に contents ディレクトリを作成し、そこにコンテンツスクリプトを追加します。スクリプトの名前がその機能を表すようにしてください!

例については、with-many-content-scripts (opens in a new tab) を参照してください。

構成 (Config)

場合によっては、特定のページでコンテンツスクリプトを実行したいことがあります。コンテンツスクリプトから構成オブジェクトをエクスポートすることで、カスタムコンテンツスクリプト構成を提供できます。

content.ts
import type { PlasmoCSConfig } from "plasmo"
 
export const config: PlasmoCSConfig = {
  matches: ["<all_urls>"],
  all_frames: true
}

エクスポートされた PlasmoCSConfig 型のおかげで、この構成オブジェクトの操作は非常に簡単です 🥳。

構成と各プロパティの詳細については、Chrome の公式ドキュメント (opens in a new tab) を参照してください。

メインワールドへの注入

コンテンツスクリプトから window オブジェクトを変更するには、コードを「メインワールド」に注入する必要があります。

Plasmo v0.65.0 以降、Plasmo コンテンツスクリプトは構成内に world プロパティを指定できます。

content.ts
import type { PlasmoCSConfig } from "plasmo"
 
export const config: PlasmoCSConfig = {
  matches: ["<all_urls>"],
  world: "MAIN"
}

上記のスクリプトはメインワールドに注入されます。

メインワールドスクリプトを手動で注入するには、chrome.scripting.executeScript API を使用します。まず、package.json の 'manifest.permissions' 配列 にスクリプティング権限を手動で追加します。

package.json
{
  ...
  "manifest" : {
    "permissions": ["scripting"]
  }
}

次に、バックグラウンドサービスワーカーから chrome.scripting.executeScript を呼び出すことで、コンテンツスクリプトをメインワールドに注入します。

background.ts
chrome.scripting.executeScript(
  {
    target: {
      tabId // 注入先のタブ
    },
    world: "MAIN", // window オブジェクトにアクセスするための MAIN
    func: windowChanger // 注入する関数
  },
  () => {
    console.log("Background script got callback after injection")
  }
)

func キーには、プロジェクトの TS 関数を渡すことができます。拡張機能がバンドルされるときに、JS にトランスパイルされます。files キーを使用して、ビルドされたバンドルのルートからファイルを注入することもできます。

🚨

func のスコープは厳密にカプセル化されています。そのスコープ外で宣言された変数や、直接インポートされた変数は関数内で使用できません。ただし、args プロパティに渡された変数を使用できます。JSON でシリアライズ可能な値のみを使用してください。

例については、with-main-world (opens in a new tab) を参照してください。

外部APIとCORSの取得

コンテンツスクリプトはウェブページのコンテキスト内で実行されるため、同一オリジンポリシーの対象となります。CORS 制限を軽減するために、Plasmo メッセージングAPI を使用して、バックグラウンドサービスワーカーを介してリクエストをプロキシできます。

リソースのインポート

コンテンツスクリプトに外部アセットをインポートするには、url: スキーム を使用できます。

import myFile from "url:./path/to/my/file/something.js"

url: スキームは something.js アセットを自動的に解決し、ビルドされたバンドルの web_accessible_resources 宣言に追加します。上記の myFile 変数は、アセットへの URL を含む文字列になります。

> console.log(myFile)
 
chrome-extension://<your chrome ext id>/something.eb20bc99.js?1656000646313
 
> console.log(myFile.split("/").pop().split("?")[0])
 
something.eb20bc99.js

あるいは、data-base64 または data-text スキームを使用して、アセットをコードに直接インポートして埋め込むこともできます。小さなアセットの場合、これらのスキームは適切に機能するはずです。

🚨