FigmaプラグインにCI/CDを導入したかったという話
この記事はFigma 開発 Advent Calendar 2022の15日目の記事です。
こんにちは、最近は主にデザイナーのたふみです🙌
仕事はとあるサービスのUIデザインを担当しつつ、唐突に別サービスのFigmaにコメントだけ書き散らして去っていくくせに何も決められない無責任ムーブマンをしています (ほんとにごめんなさい……)。
最近はデザインシステムの調整まわりに住んでいることが増えました。
さて、以前Friends of Figma Tokyoというイベントで登壇した際、設計したカラートークンの話と、そのサポートにプラグインがほしくなり開発した話をしました。
今日はその後日談と思ってもらえればと思います。 (本当はFigmaと分散システムの話をしたかったんですが、記事化する時間がないのとテーマから離れすぎている気がしたので断念しました…またいつか…)
継続的なプラグイン開発の難しさ
そもそもの前提として、私はチームの体力が十分でないうちはプラグインに頼らないといけないデザインシステムは組むべきではないと思っています。(これはFigma Tokens等の導入をしない決定を続けている理由の1つでもあります。)
弊デザインシステムと私の開発したプラグイン「Style Finder」は深い関係にはなく、手動でも(ギリギリ)管理できる範囲内の作業を効率化するための仕組みです。
とはいえその管理は実は行わなくても機能はするのですが、長期的に見れば使っていないデザイントークンが設定されていることは大きな負債となる可能性が排除できないため、プラグインの存在は重要とも言えます。
加えて、Style Finderはありがたいことに外部からもいろんな方に使っていただけているようで、もっと機能を充実させてほしいという声もあります。そのため、継続的な開発は必要です。
継続的な開発とは、新規機能の追加とメンテナンスの両方の意味を含みます。特に後者に関して、セキュリティなどの観点からも内部で使うライブラリのアップデート等は欠かせないという認識です。
現在、ライブラリのアップデートはRenovateを導入することで解決しています。(組織のリポジトリには実は入っていないのですが、個人のほうに入っているものをpushすることで対応しています。)
しかし、実は継続的なFigmaプラグイン開発には当初は考えていなかった難しさがありました。上記のリポジトリを見ての通り、いくつかのissueが解決されないまま放置され、Renovateも途中で止まってしまいました。これには理由があり、Figmaプラグインの開発では近年のWeb開発では当たり前なCI/CDの導入が難しいという問題があります。
CD
最近ではrelease tagを打ったらそれに応じてnpmへのpublishなり、main branchにmergeしたらVercelやCloud Build → Cloud Runが走るなりで、migrationはともかくとして、少なくともローカルでbuildしてdeployという流れは少なくなったように感じています (そしてそうするべきだと思っています)。
しかし、Figmaプラグインの公開・更新はローカルでbuildしたものをローカルのFigmaアプリからpublishしなければなりません。これは大きな障壁になると私は感じています。そして現状、これを解決する術はありません。
アプリケーションでも最近ではApp Store Connectの自動化などが可能になってきているらしいので、Figmaでもここに手を入れない理由はないと思います。
CI
個人的により厄介なのがCIでした。実は現在Style Finderのmain branchはうまく動きません。これはRenovateでVite 3.x系にあげた際にrollupのオプションmanualChunk
とinlineDynamicImports
が排他的なオプションになったためのようです。UI側のHTMLにjsをすべてまとめる、というのはVite 3.x系でも動くのですが、どうしてもsandbox側 (プラグインの裏側) のbundleがうまくVite 3.x系で解決できないことが問題です。(余談ですが、そもそもこの用途にViteを使うのはあまりおすすめできないかもしれません。)
しかし実はこんな状況でもCI上は通ってしまってました。なぜかというと、(今回はテストがない😭ですが)テストをpassしてbuildができるならOK、というワークフローを書いていたからです。しかしこれ以上のテストが難しいというのが現状だと私は考えています。
私はnpmライブラリ系ではここにさらにyalcを使用してpublishしたものがきちんとimportできるかどうかの簡単なテストを書いたりしますが、Figmaではそれが難しいです。
例えば、なにかの拍子に間違ってCommonJSではなくESM形式でbuildするようにしてしまったとしましょう。Sandbox側のコードを書き出したら、これを node
コマンドで実行すれば動かせそうです。
しかし御存知の通り、Figmaプラグインは特殊なグローバル変数が多く単純に実行するとエラーが多発します。そしてこのエラーはGoなどの言語であればビルドエラーとランタイムエラーで見分けが付きますが、JavaScriptだとそうはいきません。
また、UI側のHTMLはどうにもさらに検査が難しいことは想像していただけると思います。
どう解決するか
本来なら、ここでバーンと解決策を提示する予定… だったのですが、なかなか時間が取れず構想と試したことを書いておこうと思います。
アイデア1: mockする
最初に考えたのは、下記に従ってfigma関連のglobal objectsをmockしようと考えました。
しかし、プラグインを動かすという観点で、外からの振る舞いを検査したいのにmockではうまく解決ができないということは自明です。
(Node.js v18.8系のsnapshotを利用するとうまく扱えるかも…という目論見もありますが、まだ先の話になりそうです。)
アイデア2: Linterをかける
私の今考える現実的な落とし所は、eslintを生成物に対してかけることです。とはいっても普段みなさんが使っているルールではなく、
env:
browser: true
commonjs: true
es2021: true
overrides: []
parserOptions:
ecmaVersion: latest
# sourceType: module #ESMの場合
rules: {}
こういうような、parseだけ行うconfig (これは yarn init @eslint/config
で作成しています) を作り、これを使うという感じです。おそらくいくつかのグローバル変数を登録しておいて、それ以外については定義されていないことを検知したり、副作用がないことを検知したり (今回の場合は副作用が必須なので) もできる気がしています。
アイデア3: GitHub Actions内でFigmaを動かす
将来的には、現在できる範囲のこととしてFigmaをGitHub Actions内で動かすことが解決策だと考えています。本当はそこまでこの記事でたどり着きたかったのですが、残念ながら時間切れとなってしまいました。
mabl等のツールを使うのが一番手早いかなと考えています。しかしそこまでのコストをかける意味があるのかと言われると… 正直微妙です🤔
なんとも歯切れの悪い記事となってしまいましたが、お付き合いいただきありがとうございました。
明日16日は◇HirokiTaniさんの担当で、Widget関連の記事になりそうです。めちゃ楽しみですね!!
おわり
Discussion