Figma API のおさらい – ファイル内のコンポーネントのアセットを1コマンドでZIP化してみる


こんにちは、みみです。

これは、Figma アドベントカレンダー 2021 22日目の記事です。

せっかくFigmaのアドベントカレンダーに参加したのでデザイナーぽい記事を書こうかなと思ったのですが、それっぽい記事をお世話になっているVektor, Inc.のアドベントカレンダーに書いたばっかり(VektorチームでFigmaを1年使ってみての所感と、Vektorブランドガイドラインのリリース | 株式会社ベクトル)なので、こちらは前々からやりたかったFigma APIをつかってゴニョゴニョしてみたのを書いてみようと思います。

デザイナーだけどFigma API何者か気になる、的な人にも分かるように書いてみた、つもりです。分からない処があったらそっと聞いてください。分かっている人で間違えを見つけたらそっと教えてください。Twitterはこちらです

Figma API についての公式ドキュメントはこちら
https://www.figma.com/developers/api


といってもですね、既に素敵なライブラリとかプラグインはいくつも存在するので、ちゃっちゃと作りたい人はそちらを活用するのをオススメします。

今回は、私が全然把握してなかったFigma APIの仕様を確認するのが主な目的で、指定したファイルのコンポーネントをアセットファイルをpngとsvgで書き出してZIPするのを1コマンドで出来るものを作ってみました。

ベースのラッパーはこちらを活用。

figma-js
https://github.com/jongold/figma-js

そして、基本的にこちらのライブラリを参考にして、ほぼ写経しながら学ばせてもらいました。

ohkimur/figma-assets-export: Export assets from Figma and download them as local files.
https://github.com/ohkimur/figma-assets-export

実は、最初はこのライブラリだけで楽勝じゃん、よーしReactでWebアプリかプラグインにしちゃうかーなどと妄想していたのですが、そもそもFigma APIの仕様が分かってないためにうまく活用出来ず。Reactで書こうとしたり、TypeScript化しようとしたり大分と右往左往したのですが、その辺りはFigmaアドベントカレンダー的には要らないと思うので割愛しますw

というわけで、いったん極シンプルに、JSでZIPが出来るものを作ってみました。

Figma APIのしくみを試してみよう

まずは、Figma APIがどんなものか、直接アクセスしてみます。

Figma API / GET file
https://www.figma.com/developers/api#get-files-endpoint

ここのページで右側にある黒いエリアの処にあるfile_keyに試してみたいFigmaのファイルのファイルキーを入力します。

Figma API のドキュメントの右側にあるお試しツール

ファイルIDは各FigmaのファイルURLのhttps://www.figma.com/file/xxxxxxxx/以下の文字列xxxxxxxxxの部分です。

アクセストークンというものが必要なのですが、Figmaにログインしていれば、「+ Get personal access token」というリンクをクリックすると自動で取得されます。

その状態で、「Submit API Request」ボタンを押してしばし待てば、Loading… エリアに何やら以下のような文字列がつらつらと書かれます。

{
  "document": {
    "id": "0:0",
    "name": "Document",
    "type": "DOCUMENT",
    "children": [
      {
        "id": "0:1",
        "name": "Page 1",
        "type": "CANVAS",
        // 中略
      }
    ]
  },
  "components": {
    "1:2": {
      "key": "xxxxx",
      "name": "color=Default",
      "description": "",
      "componentSetId": "1:5",
      "documentationLinks": []
    },
    "1:6": {
      "key": "xxxxx",
      "name": "color=Knockout",
      "description": "",
      "componentSetId": "1:5",
      "documentationLinks": []
    }
  },
  "componentSets": {
    "1:5": {
      "key": "xxxxx",
      "name": "photosynthesic_icon",
      "description": ""
    }
  },
  "schemaVersion": 0,
  "styles": {},
  "name": "figma_api_test",
  "lastModified": "2021-12-19T13:39:15Z",
  "thumbnailUrl": "xxxxx",
  "version": "1395982838",
  "role": "owner",
  "editorType": "figma",
  "linkAccess": "view"
}

といった感じで、JSON形式で指定したファイルの情報が返ってきます。

cURL(コマンドラインツール)で試したい人のために、コマンドも生成してくれるので、ターミナルかiTerm、VS Codeのターミナルでも良いのでコピペしてreturnしたら、同じ結果が得られるでしょう。

Figma Advent Calendar 2021 の3日目の記事 Figmaのコメント一覧をさっと取得したいなあ…… – Qiita で、綿貫さんがコメント一覧を取得するcURLを試してらっしゃるので参考になるかもです。

さて後は、この文字列から、必要な情報だけ抜き出して良きに計らえば良いのでざっと書いてみました(ほんとうはここがたいへんでしたがry)。

拙作リポジトリの試し方

という訳で、お試し用のファイルを作ってみたので、もしお暇な方がいらっしゃったらどうぞ。Duplicateしてお試しください。

figma_api_test – Figma
https://www.figma.com/file/MfHUbW7xefpYqEE4s7b5pI/figma_api_test?node-id=0%3A1

こちらのファイルからコンポーネント化されているアイコン2種類をSVGとPNGファイルでダウンロードしてきて同じファイル名のzip化することができます。

別にお手持ちのコンポーネントがある好きなFigmaファイルでも良いのですが、コンポーネントがあんまりに多すぎる場合にタイムアウトする気がしなくもないのでご利用は計画的に。何かあっても当方は一切の責任を負いかねます。試すならシンプルなファイルにしてみたほうが良いと思います。

拙作リポジトリ
https://github.com/miminari/figma-zipper

動作には Node (npm) が必要です。17系で作ってみています。

リポジトリをクローンまたはZIPダウンロードして展開したら

npm i

してください。

コードの本体はhttps://github.com/miminari/figma-zipper/blob/main/index.mjsです。

.env(dotenv)を設定する必要があります

Figma APIを使うには、最低限トークンとファイルのID(またはファイルのURL)が必要です。
トークンについてはアクセストークンを取得 – Figma | nju33などを参考に取得してみてください。

リポジトリを試すには.envファイルをリポジトリの直下に作成し、以下のように記述したらOKです。

FIGMA_TOKEN = xxxxxxxx
FIGMA_FILE_ID = xxxxxxxxxx

あとは

npm run zip

でzipファイルが生成されるはずです。やったね  🎉

Figma APIのエンドポイントを見つけてカスタムしてみよう

これだけだと、それでどうした?という感じなので、figma-jsの使い方をメモしておきます。

先ずはクライアントを呼び出し

これは、figma-jsのREADMEに書いてある通りに。

const client = Figma.Client({ personalAccessToken: process.env.FIGMA_TOKEN || '' });

ファイルのコンポーネントを取得

const file = await client.file(ここにファイルキー);
const fileComponents = file.data.components;

ここからはもう少し踏み込んで、オプションとかの扱い方を見てみましょう。

pngを2xで書き出したい(画像データの取得)

最初スケールの設定いれてなかったのですが、何も設定しないとPNGが1倍で出てくるので、2xにしてみました。

先ずは、Figma APIのドキュメントを見て、エンドポイントがあるか確認します(大体何でも取れるから確認しなくても良いけれど、構造理解のためにもみてみましょう)。

画像関連のエンドポイントについてはGET imageに書かれています。

「Query parameters」の一覧にある「scale」がそれっぽいですね。0.01〜4の数値で、画像の拡大縮小率を指定できる、とあります。動作が不安だったら、右側の黒いお試しツールで試すことができます。

で、今回はfigma-jsというラッパーを使っているので、こちらの仕様でどう書いたらいいか確認します。

figma-js > Interface FileImageParams > scale
https://jongold.github.io/figma-js/interfaces/fileimageparams.html#scale

同じく`scale`で、数値を渡したら良いらしいということが分かります。なのでこんな感じ。

const response = await client.fileImages(ここにファイルキー, {
                ids: [画像のID],
                format: PNG,
                scale: 2
            })

…ここでタイムアップ!

というところまでカスタムしてみた処で、アドベントカレンダーの期日が来てしまったので、今回はここまで。

次回?以降にやりたいことのメモを書いておきます。

Variantsの名前とコンポーネントの名前をちゃんとファイル名に入れたい

Variantsを使っていると、filenameが`color=Default.svg`みたいになっちゃうんですよね。これをちゃんとコンポーネントの名前とVariantsにしたいのですが、figma-jsが対応していないぽいので、自力でgotかaxiosか何か使ってAPI叩くところを作るか、figma-jsにPR投げないといけない感じ。

figma-jsもPublishしているコンポーネントだと取れる気がするので、まずはPublishしているファイルを作って試してみようと思います。そもそもPublishしていないデータを取れて良いのかという気がしたけれどトークン使うからまあ気にしなくて良いはず。

その他

  • 書き出したものを自動アップロードさせたい
  • 画像最適化したい
  • 保存形式を簡単に指定できるようにしたい
  • プラグイン化してみる?
  • TypeScript化
  • TestとLint入れる
  • リクエストがデカイとどうなるか検証(タイムアウト対策)

などなど…年末年始の遊びが充実しそうです。

Figmaからコンポーネント取ってきて画像ブロック化してくれるWordPressプラグインとかもできそうですが、需要が迷子ですね。コンポーネントを一気にCSSのインライン化してくれるとか、アイコンブロック化してくれるのとかいいかなあ…🤔


この記事を書いた人