figmaの吐き出すjsonがsketchのそれより数倍も見やすかった件

## まえおき

デザインプロトタイピングツール、まさに大航海時代て感じですよね。Sketch、AdobeXD, figma, FramerX, InVision, Prott... 色々あって選ぶのが大変です。

選ぶ基準は色々だと思いますが、その1つとして**「ハックしやすい環境を提供しているのか？」という視点を持っておくことは、有用なんじゃないかな**と思っています。

つまり、APIを公開しているだとか、プラグインを作れるだとか、開発者向けドキュメントがしっかりしているだとか、そういうところがしっかりしてるほうが、デザイナの便利ツールも増えるし、エンジニアも楽できるし、今後そのデザインツールをみんなで良くしていこうぜっていう機運もたかまりますし、エコシステムができあがった暁にはこの上なく便利になるので(仕事を奪われる！ということもあったりして...)。

## やること
ということで、今日は数あるデザインプロトタイピングツールの中でも、sketchとfigmaに関してどちらがエンジニアフレンドリーなのか？を検証していきたいと思います。

具体的には、だいぶニッチですが、同じデザインファイルをsketchとfigma両方でjsonファイルとして出力。それらを見比べながら、個人的に感じたpros/consをまとめてみます。

すでにタイトルでネタバレしている感もありますが、以下で詳しい内容を書いていきます。

## 前提

筆者は、仕事では主にsketchをメインで利用してきたエンジニアです。業務でちょっとしたsketch向けの効率化ツールを作っていたりします。今回は、周囲でfigmaニーズの高まりを感じ、その調査目的もあって記事を書いている感じです。

本記事の内容は、基本的にリバースエンジニアリングで推測の域なので、確実なことは言えないです。実際のところはご自身で確かめてみてもらえればと思います。

今回利用するデザインファイルは、sketch公式の[iOS UI Kit](https://www.sketch.com/elements)の一部を抜粋・編集したものを利用します。全く同じというわけではないですが、ほぼ同じです。ご参考までに：
https://github.com/mitolog/sketch-figma-compare/archive/master.zip
(ファイルサイズ6.4MB)

あと、sketch上のartboardとsymbolはfigmaだと、

 - artboard ≒ frame
 - symbol ≒ component

となるようですが、以下では基本的にartboard、symbolと呼ぶことにします。

## sketchでjsonを出力する

まずはjsonを出力するところから。

手順はとても簡単で、

1. sample.sketchファイルをコピー
2. 1でコピーしたファイルの拡張子を.zipに変更(sample.zipとする)
3. 2で作成したzipファイルをダブルクリック(解凍)

すると、以下のようなフォルダができます：

```
sample/
├── document.json
├── images
│   ├── 12b8d4227ac1a553ca929dc74a16fde1c719dfa0.png
│   ├── 176bcf26d32531ab125af9ed69c92aa9728a7965.png
├── meta.json
├── pages
│   ├── 2B9313BC-C589-4073-BA0C-AF0F39E34BA1.json
│   └── A9873CD6-3B3D-44B6-A39C-C19FBCA6CECB.json
├── previews
│   ├── library-preview.png
│   └── preview.png
└── user.json
```

`pages` フォルダ配下に、各ページにつき1つのjsonファイルが格納されています。今回だと `Apps`と、`Symbols`ページで、前者にartboard情報が、後者にsymbol情報が入っています。

更に、sketchには[sharedStyle](https://www.sketch.com/docs/styling/shared-styles/)という概念があり、ファイル内で共有したいテキストフォントや色の情報が、 `document.json` に入っています。

## figmaでsketchファイルを読み込む

[こちらの記事](https://note.mu/hikarutayama/n/n7c1f582dfa37)を参考に、sketchファイルをfigmaに放り込みます。といっても.sketchファイルをドラッグ&ドロップするだけ。what a easy...

読み込みが完了すると、以下のようなポップアップがでます。いくつかのフォントは読み込めませんでしたよと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/ce0103f4-ca26-651b-b13b-4d4140e693f6.png)

再現率はこんな感じです。フォントを読めてないのもあるでしょうし、元のsketchファイルが結構オーバーライドを多用してたので追えてない部分もあるかもしれないので、こんなものでしょうか。それでもマップのピンなどはベクターデータも読み込めてるのはすごいですね。

元のsketch上のデザイン：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/df759450-a5fc-8f8f-5a08-a9b39daa23a5.png)

figmaでパースして再現したデザイン：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/df949f8f-bf15-0cb5-afc8-1ce6102bbf90.png)

## figmaでjsonを出力する

figmaはweb api経由でjsonを取得できるようになっています。手順としては、

1. figma access tokenを取得([こちら](https://www.figma.com/developers/docs#access-tokens)から)
2. jsonにしたいfigmaのurlを取得 (`https://api.figma.com/v1/files/file-unique-key-here`の形式でok)
3. 1,2を使ってcurlでjsonを取得

```bash
curl -H 'X-Figma-Token:accesstokenkeyhere' https://api.figma.com/v1/files/file-unique-key-here -o sampleSketchOnFigma.json
```

## 比べてみる
前提として、同じsketchファイルを利用しています。

## ファイルサイズ、行数、検索性

ファイルサイズ、行数はほぼ一緒だが、検索性はfigmaがいいです。

まず、jsonファイル数、合計ファイルサイズ、合計行数で比較しました。

|   | sketch | figma | 備考 |
| --- | --- | --- | --- |
|  jsonファイル数 | 5 | 1 |  |
|  合計ファイルサイズ | 2.0MB | 1.7MB | すべてのjsonファイルの合計値概算 |
|  行数 | 11,1622 | 124,456行 | 同じprettierを利用 |

基本的に、リバースエンジニアリングする際、jsonを各種エディタで開き、prettierして、ファイル内で検索したり、雑にサンプルプログラム書いたり〜といったことを(僕の場合は)するので、ファイル数が少ない方が何かと手間が減り、検索性も増します。なので、この場合figmaの方が1ファイルで完結していて、扱いやすそうだな、という印象です。

合計行数はほぼ同じでしたが、ファイルサイズはfigmaのほうが小さかったです。figmaが小さいのは、単純にパースできてない/してない部分があるかもしれません。

一応試しに、
https://www.figmafinder.com/figma-atro-ui-kit-freebie

こちらをDLして、用意されている`.sketch`ファイルと`.fig`ファイル、それぞれjson出力してみたところ、figmaの方が1/3のサイズで収まっていました(ただ`.fig`ファイルはsketchの4倍くらいでかい)。

## jsonの読みやすさ

figmaの方が直感的で読みやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/e6afff4b-bb4e-d78c-d2f9-65374ce0e95f.png)

左がfigmaで右がsketchです。

figmaのほうは、文字列(stringのenum)で表現してくれている上に、[公式ドキュメント](https://www.figma.com/developers/docs#files)で各フィールドの取りうる値や形、意味などを解説してくれています。

それに対し、sketchはmagic numberで表現されていて、それが何を意味するかをいちいちsketch上でそれらしい設定を変更しながら確認していく必要があります。もしくは[JavascriptAPIドキュメント](https://developer.sketch.com/reference/api/)をよんで相当しそうな設定を見つけるか(なにかいい方法あれば教えて欲しいです)。

特に思想の違いがあらわれてるなと思ったのが、view間の相対的な位置関係を表す`Constraints`に関する情報。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/5594b656-d2aa-77c6-e85c-f2d090a83dd6.png)

figma(左)が、`"vertical": "TOP_BOTTOM"` というふうに誰でも理解できるよう文字列で表現しているのに対し、sketchでは、`"resizingConstraint": 18`です。初見だとファ？て感じですね。ただここは流石にfigmaより歴史のあるツール、先人(zendeskのエンジニアさん)が見事に解析してくれていました。

[Reverse engineering Sketch’s resizing functionality](https://medium.com/zendesk-engineering/reverse-engineering-sketchs-resizing-functionality-23f6aae2da1a)

なんと、2進数でANDビットマスクした数値を、10進数に変換したものを値として利用していました。ハードが得意なエンジニアや感がいい人ならもしかして、って思うかもしれないですが、少なくとも誰が読んでもわかるっていう感じじゃあないですね。

ちなみに、上記に関して、簡易的ですが、パース関数(typescript)を用意したので万が一ご入用の方は適宜ご活用ください。やってることは、10進数を引数にとり2進数のビット文字列に変換して、各ビットを見てどのConstraintが設定されているかを返すだけのものです。

https://github.com/mitolog/sketch-figma-compare/blob/master/parseResizingConstraint.ts

## APIの数の多さ

figmaの方がインタフェースを1つに統一していてわかりやすいです。

sketchの[公式APIドキュメント](https://developer.sketch.com/reference/api/)をみると、javascript APIを主にメンテしていくよとは言っているものの、以下の図をみておわかりのように、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/86f78d2e-f8de-1790-0b98-dba5bf3f54a5.png)

公式のjavascript APIでもかけるし、[CocoaScriptを介してsketchアプリに直接アクセス](https://developer.sketch.com/guides/cocoascript/)することもできるし、jsonも出力できるし、[SketchTool](https://developer.sketch.com/guides/sketchtool/)っていうcliも作っといたのでこれも使えるよ、etc...。

というように、**「色々用意しといたから好きにやってね」**という意図を感じざるをえないです。多分歴史的な経緯とかプラットフォームがmacOS縛りだからということもあると思いますが、これだとどこから手を付けていいかわからないですし、ものによってドキュメントもあったり無かったりでsketch運営チームのメンテ度合いが異なるので、ベストプラクティスが分かりにくくとっつきにくいなと感じます。

一方で、figmaの方は、新しいツールだからということもあると思いますが[公式ドキュメント](https://www.figma.com/developers)を見ると、

> you can use the Figma API to inspect a JSON representation of the file. Every layer or object in a file will be represented within the file by a node (subtree). You will then be able to access and isolate the object and any properties associated with it. In addition to accessing files and layers, you will be able to GET and POST comments to files.

とあるように、アプリケーションとのインタフェースをRESTful APIを介した**jsonに統一**しています。また、**jsonの各フィールドの解説ドキュメントも整備されているので、上記の`resizingConstraint`のように混乱しにくい**です。

## 各デザイン要素のidの付け方の違い

これもまたfigmaの方がより直感的に理解しやすい...。

sketchだと、固有idはこのようなuuidっぽい文字列ですが、

```
"do_objectID": "6EAE7D13-D737-4AC7-8257-617FEC34D669"
```

figmaだと以下のようになっています：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/87930129-c6ea-7084-1a8f-d41d6e3409c8.png)

ぱっとみ、何かしらルールに則って任意の番号を振っているように感じますね。この時点ですでにfigmaの方が好きです。なぜかというと、より直感的に理解しやすいからです。仮に上記idの数値部分をsketchのそれに置き換えると...

```
I_6EAE7D13-D737-4AC7-8257-617FEC34D669:0A3756D3-7B21-4CBA-896F-81D6A27F42DC;6EAE7D13-D737-4AC7-8257-617FEC34D669:897E7BBD-6A95-4DBD-B3EB-BAADA9325198
```

しんどくないですか。早々にスタックオーバーフローしそうです。

また、後述しますが、**figmaではこの`id`で基本的にartboardとsymbol、さらにsymbol内でのオーバーライドといった要素間の関係性を表現している**ようなのですが、sketchでは `do_objectID`, `symbolID`, `overrideValues`が複雑に絡まって表現されています。説明するのがめんどくさすぎる(且つ理解できてない部分もある)のでsketchでの紐づけ方は割愛します。

では、figmaのidの仕組みはどのようにシンプルなのかというと、上記画像の2つめの赤丸で囲んだ`"id": "I0:3;0:1316"`を例に説明すると、以下の通りです：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/40320a39-7ecd-c953-674a-5e648fb4f604.png)

伝わるでしょうか...。

四角い点線で囲んでいるものがchildren[0]の要素を現しています。で、idの`I0:3`は、artboard上の要素`0:3`を指しています。また先頭にある`I`は恐らくですが、`Instance`の頭文字なんじゃないかと推測しています。

さらに、`;`を区切りとして、`0:1316`が続いてます。これはもしかして別の要素のidでは。試しに、`"id": "0:1316"`でjsonファイル内を検索すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46489/5214152f-5ee1-3ca8-a3c2-2d3e34f80364.png)

1件ヒットしました。`0:1315`のsymbolの一部として登録されているようです。

つまり、`"id": "I0:3;0:1316"`の要素について日本語の文章で表すとすると「0:3のために実体化された0:1316」とかいう言い方になるでしょうか(伝われ..)。まぁ、要はartboard上でシンボルを実体化したものが、`"id": "I0:3;0:1316"`ということですね(逆にいうと、シンボルでないものは`I`がつかないです)。

idについてまとめると

 - figmaの方が直感的に理解しやすいので解析が捗る
 - figmaの方がartboardとsymbolの関係性を少ないフィールドで表現できている

ということかなと思います。

## フィールド数(ハックできる項目数)

これにはsketchのほうが圧倒的に多いです。

sketchアプリの方がデザインの表現力という意味ではできることが多いので、当然ながらjsonを見てもフィールド数は多いです。反面、**似たようなフィールドが多すぎてどの設定が優先されているのかわかりにくい**のも事実。

この辺は、figmaも今でこそシンプルですが、時とともにsketchと同じ壁にぶち当たるのではないか...という不安は拭いきれません。シンプルさを維持しつつ、いかに表現力をあげられるかがfigma開発チーム腕の見せどころなのではと思います。

## まとめ

まとめとして、エンジニア観点でsketchとfigmaを見たときに、jsonファイルに限ってどっちがハックしやすいかと言えば、現時点では以下の理由でfigmaの方が上かなと思いました：

 - ファイルが1つにまとまっているので色々手数が減って楽
 - 検索性が良い
 - 値がstringのenumで表現されていて、直感的に理解しやすい
 - APIがjsonに統一されている
 - jsonの各フィールドの解説ドキュメントが整備されている
 - 要素間の関係性が1つのフィールド(`id`)で完結するので、混乱しない

なんというか、**ハックされることを前提にjsonが作られている**のをfigmaの方が感じました。逆にsketchは、**内部で利用しているjsonをそのまま外部に出しておいたので、必要なら頑張ってパースしてみて**ていう意図を感じました。

個人的には、プラットフォームをmacに縛って特定のインタフェース(JSやCocoaScript)を用意されるよりは、プラットフォームは関係なく、jsonだけきれいにして用意しておくので後はよしなにしてね、という方が柔軟性があって好きです。

デザイナとしては、figmaはまだまだプラグインも少なく、細かい部分で出来ないことも多いとは思いますが、インタフェースをjsonに絞っていたり、開発言語がエンジニアに委ねられていたりと柔軟性が高いので、今後どんどん便利ツールが増えてくるんじゃないかなと予想しています。

ただ、sketchも[2019の後半にはonline化するよ](https://blog.sketchapp.com/sketch-raises-20m-in-series-a-funding-from-benchmark-ea298764d7d1)とのことで、それに合わせて内部構造のリニューアルと開発者むけ環境のリニューアルもありえるのかも...と個人的には期待しています。どのように変化するのか、今後も要注目ですね。

ではでは。