Migrate to Plasmo

Plasmoフレームワークへの移行

Plasmoブラウザ拡張機能フレームワークは、宣言的なアプローチによりブラウザ拡張機能の構築を簡素化します。定型コードを排除し、理解、使用、およびオプトアウトが容易なファイルベースの構成システムを提供します。

このガイドでは、任意の拡張機能プロジェクトからPlasmoへの移行手順を説明し、必要な主な変更点を強調します。

Plasmo CLIのインストール

PlasmoフレームワークのメインドライバーはPlasmo CLIです。これは、ブラウザ拡張機能用に特化したコンパイラ、バンドラ、開発サーバー、およびパッケージャを含むNode.jsパッケージです。

pnpm install plasmo

開発サーバーを起動するには、plasmo devを実行します。拡張機能をビルドするには、plasmo buildを実行します。拡張機能をパッケージ化するには、plasmo packageを実行します。

manifest.json

Plasmoはmanifest.jsonpackage.jsonにマージし、最も基本的なプロパティを抽象化します。

Manifestフィールド抽象化
iconsassetsディレクトリのicon.pngを使用して自動生成されます
action, browser_actionspopup.tsx
options_uioptions.tsx
content_scriptscontents/*.{ts,tsx}, content.ts, content.tsx
backgroundbackground.ts
sandboxsandbox.tsx, Sandbox Pages
manifest_version--targetビルドフラグで設定、デフォルトは3
versionpackage.jsonversionフィールドで設定
namepackage.jsondisplayNameフィールドで設定
descriptionpackage.jsondescriptionフィールドで設定
authorpackage.jsonauthorフィールドで設定
homepage_urlpackage.jsonhomepageフィールドで設定

Plasmoはpackage.jsonmanifest.json間の共通メタデータを集中化し、静的ファイルへの参照(アクション、バックグラウンド、コンテンツスクリプトなど)を自動的に解決します。

これにより、名前、説明、OAuth、declarative_net_requestなど、重要なメタデータに集中できます。

さらに、これにより、フレームワークはさらに強力な機能を提供できます。

ポップアップ、オプション、新規タブページ

Plasmoは、React/Svelte/Vueコンポーネントを手動でマウントする必要性を排除します。

Plasmo以外の拡張機能プロジェクトでは、Reactコンポーネントをマウントするために、index.htmlテンプレートと関連するJavaScriptコードを作成します。

popup.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Popup</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="popup.js"></script>
  </body>
</html>
popup.jsx
import { createRoot } from "react"
 
import Popup from "./core/popup"
 
const root = document.getElementById("root")
createRoot(root).render(<Popup />)

TypeScript、LESS、またはSCSSを追加する場合は、追加のプラグインとローダー設定を使用してWebpack、Parcel、またはESBuildを使用する必要があります。

Plasmoフレームワークを使用すると、はるかにシンプルになります。ソースコードディレクトリpopup.tsxまたはoptions.tsxファイルを追加し、デフォルトのReactコンポーネントをエクスポートします。

Plasmoが残りの処理を行います。

popup.tsx
import Popup from "./core/popup"
 
export default Popup

PlasmoはCSS、SCSS、LESS、CSS Modules、PostCSSプラグインを組み込みでサポートしています。

たとえば、SCSSを使用したい場合は、ReactコンポーネントでSCSSファイルをインポートするだけで済みます。

popup.tsx
import Popup from "./core/popup"
 
import "./popup.scss"
 
export default Popup

オプションページ、新しいタブページ、サンドボックスページ、その他のカスタムページで、このようにしてReactコンポーネントをマウントできます。

カスタムページ

Plasmo以外の拡張機能プロジェクトでは、カスタムページを作成するには、通常、追加のHTMLテンプレートと関連するJavaScriptコードが必要です。

tabs/custom.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Custom Page</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="./custom.js"></script>
  </body>
</html>
tabs/custom.js
import { createRoot } from "react"
 
import CustomPage from "./core/custom-page"
 
const root = document.getElementById("root")
createRoot(CustomPage).render(<PopupApp />)

Plasmoでは、組み込みのタブページ機能を使用して、簡単にカスタムページを作成できます。ソースコードディレクトリに**tabs**フォルダを追加し、.tsxファイルを使用してカスタムページを追加します。

tabs/custom.tsx
import Hello from "./core/hello"
 
export default Hello

このページはchrome-extension://<extension-id>/tabs/custom.htmlで利用できます。

コンテンツスクリプト

Plasmo以外の拡張機能プロジェクトでは、manifest.jsonファイルでコンテンツスクリプトを指定し、JavaScriptで記述します。

manifest.json
{
  "content_scripts": [
    {
      "matches": ["https://*/*", "http://*/*"],
      "all_frames": true,
      "css": ["content.css"],
      "run_at": "document_start"
    }
  ]
}
content.js
console.log("Hello from content script!")

Plasmoでは、content.tsというファイル、またはcontentsというディレクトリ内にコンテンツスクリプトとその構成を指定できます。詳細は後述します!

content.tsファイルは次のようになります。

content.ts
import type { PlasmoCSConfig } from "plasmo"
 
export const config: PlasmoCSConfig = {
  matches: ["https://*/*", "http://*/*"],
  all_frames: true,
  css: ["~content.css"]
}
 
console.log("Hello from content script!")

manifest.jsoncontent.jsファイル間を行き来する必要がなくなります。追加の利点として、構成は完全に型付けされているため、IDEから貴重な自動補完を提供できます。

複数のコンテンツスクリプトを追加するには、contentsというディレクトリを作成し、上記の手順を繰り返します。このディレクトリ内のスクリプトには任意の名前を付けることができます。すべてが独自の構成を持つコンテンツスクリプトとして追加されます。

たとえば、ページの背景色を緑色に変更するコンテンツスクリプトを追加したいとします。これを行うには、contentsディレクトリにemerald-splash.tsというファイルを作成します。

contents/emerald-splash.ts
document.body.style.backgroundColor = "green"

コンテンツスクリプトファイルが構成をエクスポートしていないため、Plasmoはデフォルトの構成を使用します。

{
  "matches": ["<all_urls>"]
}

コンテンツスクリプトUI

ReactコンポーネントをWebページに挿入する場合、拡張機能には、Shadow DOMの作成、マウントする適切な要素の検索、MutationObserversなど、多くの定型コードが含まれている可能性があります。

これらをすべて抽象化して、コンポーネントの構築に集中し、残りの部分については心配する必要がなくなりました。

たとえば、シンプルなボタンのReactコンポーネントをWebページに挿入したいとします。これを行うには、contentsディレクトリにpress-me.tsxというファイルを作成します。

contents/press-me.tsx
export default function PressMeCSUI() {
  return <button>Press me</button>
}

Plasmoは、このコンポーネントをページに自動的に挿入し、ページのルート要素にマウントします。

特定の要素にコンポーネントを挿入したい場合は、ファイルからgetInlineAnchor関数をエクスポートできます。

contents/press-me.tsx
import type { PlasmoGetInlineAnchor } from "plasmo"
 
export const getInlineAnchor: PlasmoGetInlineAnchor = async () =>
  document.querySelector("#pricing")

要素を返すことで、Plasmoはその要素の隣にコンポーネントをマウントします。マウント動作、コンポーネントのレンダリング方法などを完全にカスタマイズできます。

この機能はコンテンツスクリプトUIと呼ばれます。そのAPIと動作の詳細については、ライフサイクルに関する技術ドキュメントを参照してください。

マウントする要素に対するコンポーネントの挿入位置も指定できます。

contents/press-me.tsx
import type { PlasmoGetInlineAnchor } from "plasmo"
 
export const getInlineAnchor: PlasmoGetInlineAnchor = async () => ({
      element: document.querySelector("#pricing"),
      insertPosition: "afterend"
})

バックグラウンドサービスワーカー

Plasmo以外のプロジェクトでは、バックグラウンドサービスワーカーを作成するには、manifest.jsonファイルでbackgroundプロパティを指定し、JavaScriptでサービスワーカーコードを記述する必要があります。

manifest.json
{
  "background": {
    "service_worker": "background.js"
  }
}
background.js
console.log("Hello from BGSW!")

Plasmoでは、background.tsファイルを作成することでバックグラウンドサービスワーカーを指定します。

background.ts
console.log("Hello from BGSW!")

標準的なサービスワーカーランタイムをターゲットとするモジュールをbackground.tsにインポートできます。たとえば、bip39モジュールを追加できます。

background.ts
import { generateMnemonic } from "bip39"
 
console.log(
  "Live now; make now always the most precious time. Now will never come again."
)
console.log(generateMnemonic())

Plasmoはbackground.tsファイルを自動的にバンドルし、manifest.jsonファイルにバックグラウンドサービスワーカーとして追加します。

環境変数

現在環境変数を使用している場合は、Plasmoでも引き続き使用できます。

Plasmoフレームワークは、追加の設定なしで環境変数をすぐに使用できます

オプトアウト

Plasmoフレームワークの抽象化の哲学は、最も一般的な構成と定型コードを削除することです。これにより、開発者はより高い抽象化レイヤー(React、Vue、Svelteなどの選択したUIライブラリ/フレームワーク)で作業できるようになります。これは、より強力で美しい拡張機能を作成するための道です。

Plasmoからのオプトアウトは、package.jsonファイルからplasmo依存関係を削除し、コンポーネントをカスタム設定に移動するほど簡単です。これは、Plasmoによって生成されたすべての接着コードがフレームワークコンパイラとバンドラレイヤーで注入されるため、機能コードの移植性が非常に高いためです。

必要に応じてPlasmoを自由に使用することもできます。すべてのChrome APIを利用でき、機能コードで直接使用できます。たとえば、メッセージングAPIを使用する代わりに、chrome.runtime.messaging APIを直接使用できます。コンテンツスクリプトと拡張機能ページについても同様です。