🎉

【Plasmo】Vueでの開発が少し便利になりました

2023/07/21に公開

Plasmoはブラウザ拡張開発のためのフレームワークです。
以前、PlasmoをVueで使うための記事を書きました。

https://zenn.dev/udop/articles/991257f68a28c6

この記事の中で、Content Script UIのStyle周りが使いづらい、という話をしましたが、これを改善するIssueを立てました。好意的な反応がもらえたので、プルリクエストを出したところ採用してもらえました。最新のv0.81.0ですでに使うことができます。
というわけで、こんな内容の改善をしたよ、という記事です。

TL;DR

  • Vueファイルの<style>タグに記述したスタイルを、Content Script UIの要素に反映できるようにしました。

改善内容

当該のコミットがこちらです。

問題点

Content Script UI(以下、CSUI)は、React/Vue/Svelteファイルを記述するだけでブラウザ拡張のContentScriptとして挿入してくれるPlasmoの機能です。実際はCSUI用のテンプレートのtsファイルが用意されており、それをエントリーファイルとしてバンドルを行っています。

Plasmoは中でPercelというバンドラを使っています。Plasmoが使用しているVueファイルのTransformerは、@vue/compiler-sfcで.vueファイルをコンパイルしたのち、スクリプト部分はjsの、スタイル部分はcssのアセットとして出力します。CSUIはcssのアセットを、ContentScriptのcssとしてページに挿入します。
しかし、CSUIはデフォルトではCustom ElementのShadow DOM内に挿入されるため、ページ本体に挿入するContentScriptのスタイルは反映されません。これが問題でした。

方針

CSUIの要素にスタイルを反映させるためには、Shadow DOM内に<style>タグを挿入する必要があります。Plasmoはそのための柔軟な方法をすでに備えており、getStyleメソッドを定義しエクスポートすることでスタイルをCSUI内に挿入することができます。
しかし、getStyleメソッドを使用する方法では、Vueファイルのstyleブロックの中身を挿入することはできませんでした。スタイルはgetStyleメソッド内にインラインで書くか、別ファイルに記述するよりなく、VueのようなSFCを使うメリットが得られません。また、Vueのコンパイラを通らないため、scopedなどの機能の恩恵も受けられませんでした。

そのため、次の方針で改善を行いました。

  • CSUIのエントリファイル内で、Vueファイルの<style>タグのコンパイル結果をimportできるようにする。
  • getStyleタグがexportされていない場合、Vueファイルのstlyeブロックの中身が出力されるように、getStyleタグを上書きする。
  • getStyleメソッドをカスタマイズする場合でもVueファイルのスタイルが使用できるように、getStyleメソッドでvueファイルのスタイル文字列を扱えるようにする。

実際にどのような変更をしたのかについては、コミットの差分を見ていただければわかるのではないかと思います。

この変更により、vueファイルに記述したStyleが反映されるようになり、より自然な開発が可能になりました!scopedや、v-bindももちろん使用することができます。

余談

OSSに参加するのは初めての経験だったため、Issueを立てるのにもめっちゃ緊張しました。DeepL先生には足を向けて寝られません。幸い、オーナーのlousigv氏には快く対応していただきました。

ところで

Vueだけの機能にはしたくないと思ったので、SfcStyleContentという変数を生やしたりしていますが、筆者はSvelteに関する知識がなく、Svelteでは依然としてSFCのスタイルが機能しているかどうかはわかりません。これを読んでいるSvelteラブ勢の方がおりましたら、参加されてみるのは如何でしょうか。

Discussion