.sketchファイルからJSONファイルに展開⇔展開ファイルから.sketchファイルに戻す


Sketch 43 からファイルフォーマットが変わり、構造などのドキュメントデータはJSONファイルで管理されるようになりました。
👉 New file format in Sketch 43

以前同僚のエンジニアと「デザインのバージョン管理をする世界」 な話をしていたので、ついにGitで差分管理をする時代がくるのかなと期待をしています。

今までもとりあえずsketchファイルをGitで…と試みたのですが.sketchのファイルをそのままGitで共有してもただのバイナリファイルのため変更差分が取得できないため全く意味がないし、まるっとファイルをアップしなければならないため非常に重いです。
今回JSON化されたことで変更差分のテキストデータなどのみアップすればいいし、文字変更や角丸の数値など細かい内容をdiffで見ることができるようになります。

Sketch 43以降のファイルでは、ファイル名.sketch -> ファイル名.zip にリネームし展開するだけでSketchデータのファイル構造やビットマップデータを見ることができるので中の追加・変更されたファイルだけcommitすればOKということになりますね。

逆に JSONファイルからSketchファイルに戻そうと ファイル名.zip -> ファイル名.sketch を行いました。
するとどうでしょう…ファイル名.sketchを開こうとするとエラーが表示され開くことができNeee…
不可逆なものなのかなと諦めていたのですが、どうやら圧縮の方法が間違っていたようです。

👉 SketchファイルをZIPとして展開した後にSketchファイルに戻す方法

上記の方法でJSONファイル(展開データ)からSketchファイルにすることができました。
しばらくは展開データのみGitで共有し、ローカル上でSketchファイルを生成しなおして運用ということを試してみたいと思います。(できるかどうかは不明)

あ、そうそう。展開したままのデータだとJSONが1行にMinifyされているので、整形し直す必要があります。
これを毎回やるのが面倒なのでシェルスクリプトでサクッとできるようにしました。

Sketchファイルからディレクトリに展開する

sketch-to-json.sh
#!/bin/sh

if [ $# != 1 ]; then
  echo "Specify the sketch file and then execute."
  exit 1
fi

fileName=$1
fileData="${fileName}.sketch"

if [ -f ${fileData} ]; then
  unzip ${fileData} -d ${fileName}
  find . -name '*.json' -exec sh -c 'cat {} | jq -rS . > {}.1 && mv {}.1 {}' \;
  rm -rf ${fileName}/__MACOSX ${fileName}/.DS_Store
fi

※jqコマンドを使用します。
$ brew install jq

test.sketch を変換するのであれば sketch-to-json.sh を同じディレクトリに設置し以下のように実行します。
$ bash sketch-to-json.sh test

testというディレクトリが作成され、中のJSONファイルは整形されています。

展開されたディレクトリをSketchファイルにする

json-to-sketch.sh
#!/bin/sh

if [ $# != 1 ]; then
  echo "Specify the directory and then execute."
  exit 1
fi

directoryName=$1

if [ -d ${directoryName} ]; then
  cd ${directoryName} && zip -o ../${directoryName}.sketch -r *
fi

testディレクトリを変換するのであれば以下のようにします。
$ bash json-to-sketch.sh test

Sketchファイルが作成されます。

というわけで、うまくできるか分からないけど SketchデータのGitライフを試していきたいと思います。


以下 2017年05月12日追記。

SketchのPluginを作って頂きました

くっきーさん💎 (@littlebusters) ありがとうございます。

Sketch Exchanger - Sketch Plugin

👉 Download on GitHub

SketchからJSONとリソースファイルへの変換

  1. プラグインを実行します。
  2. 変換するSketchファイルを選択します。
  3. 選択したSketchファイルと同名のディレクトリを生成し、その中にJSONとリソースを格納します(実質はSkechファイルをunzipしたものです)。JSONファイルはjqで整形します。

JSONとリソースファイルからSketchへの変換

  1. プラグインを実行します。
  2. 変換するディレクトリ選択します。
  3. 選択したディレクトリと同ディレクトリへSketchファイルを生成し、ファイルを開きます。

試しにSketchファイルをGitで管理してみた

100MBを超えるデータだったけど問題なく共有できました。

  1. Sketchファイルを編集する。
  2. Sketchファイルを展開し、JSONファイルを内包したディレクトリ化する。
  3. 展開したディレクトリと内包されているファイルのみをcommit&pushする。
  4. 他の人がpullする。
  5. 展開されたディレクトリをSketchファイル化する。
  6. 差分が取り込まれちゃんと変更されてる 🙌

pros

  • 最新のデザインを管理できる。
  • こまめにcommitすれば作業ログが残る。
  • push&pullが圧倒的に速い。
    • 100MBのSketchファイルを編集してもpushするのは数KB〜数MBぐらいで済む。
  • rollbackして昔のデータに戻れる。
    • パターンとかたくさん作って、「あ、念のため残したいな」と思って別ページに置いとくとかしなくてもおk。
    • 「昔のあのデザイン必要だわ」にも対応できる。
  • 作業ごとにbranch切って作業してmergeすることができる(できるけどめっちゃconflictする)。

cons

  • commit毎にSketch→JSONに変換するのが面倒。(逆も面倒)
  • 特に変更差分をテキストで可視化し見る必要がなかった(普通に画像A→画像A'になったというほうがわかりやすい)
  • 他の人が編集した際に記録されるレイヤーの開閉情報とかも記録されてしまう
    • 全てのページでレイヤーの開閉をすると当然全てのJSONファイルに差分が発生する‥(結果100MB近くpushすることに‥)
  • 作業ごとにbranch切って作業してmergeすることができる
    • mergeするときに↑のようなレイヤーの開閉とか編集者が触ったかなりローカルな情報でconflictがめっちゃ発生する。
    • このconflictの解消がくっそ面倒。
  • 関係者に運用ルールを強いらないといけない。

結論

展開したSketchファイルをGit管理して一番良かったのは、push&pullが圧倒的に速いくなる。ということだけでした。
作業ログが残ったり、最新のデザインデータ管理しやすくなる点もおすすめポイントだ(他の方法でもそれは可能だけど)
consに挙げた内容が辛すぎて、すぐ取り入れるべきかと言われると「NO」だと思います。

ただ、実際に運用してみて、もっと手軽にできるのであればデザインデータもバージョン管理できるような世界はアリだと確信しました。
変更差分のみ取得できるようになったり、各アートボードごとの画像を書き出してどのような変更があったか見られるようにするなどの改良ができれば結構使われるんじゃないかなと思いました。

ファイルサイズが小さいうちはAbstractを使うのが一番いいかなぁといった感想。