Sketch + Node.js: menghasilkan ikon untuk banyak platform dan merek. Bagian 2



Ini adalah bagian kedua artikel tentang membuat alat yang dapat mengekspor semua ikon yang ditempatkan dalam file sketsa: dalam format yang berbeda, untuk platform yang berbeda, dengan kemungkinan pengujian A / B dari setiap ikon.

Anda dapat membaca bagian pertama dari tautan .



Terakhir kali, kami menyiapkan file Sketsa yang berisi semua ikon dengan gaya yang tepat dan dengan nama yang benar. Sekarang giliran menulis kode.

Cukuplah untuk mengatakan bahwa kami melalui trial and error. Setelah pemimpin tim kami Nihil Verma , yang meletakkan dasar-dasar naskah, mengembangkan kode sumber utama, saya memulai proses yang membutuhkan setidaknya tiga fase refactoring dan banyak modifikasi. Untuk alasan ini, saya tidak akan membahas detail pembuatan skrip dan fokus pada cara kerjanya hari ini, dalam bentuk akhirnya.

Buat skrip


Skrip build yang ditulis di Node.js cukup mudah dalam pekerjaannya: dengan mengimpor dependensi, mendeklarasikan daftar file Sketch untuk diproses (ini adalah daftar merek, yang masing-masing memiliki daftar file yang terkait dengannya) dan memastikan Sketch diinstal pada klien , skrip memproses merek pada gilirannya, melakukan serangkaian tindakan dengan masing-masing.

  1. Mengambil token desain yang sesuai untuk merek (kami membutuhkan nilai warna).
  2. File Sketsa terkait merek Clones, unzip mereka, mengekstraksi file JSON internal, dan memproses beberapa nilai internal mereka (lebih lanjut tentang ini nanti).
  3. Membaca metadata yang diperlukan dari file JSON ini ( document.json , meta.json dan halaman / pageUniqueID.json ). Kami tertarik pada daftar gaya umum dan sumber daya / ikon yang terkandung dalam file.
  4. Setelah beberapa manipulasi dengan file JSON, itu menciptakan kembali arsip dan, menggunakan file Sketch (dikloning dan diperbarui), mengekspor dan membuat file output akhir untuk tiga platform (iOS, Android, Mobile Web).

Bagian-bagian yang relevan dari skrip build dapat ditemukan di sini:

// ... modules imports here const SKETCH_FILES = { badoo: ['icons_common'], blendr: ['icons_common', 'icons_blendr'], fiesta: ['icons_common', 'icons_fiesta'], hotornot: ['icons_common', 'icons_hotornot'], }; const SKETCH_FOLDER_PATH = path.resolve(__dirname, '../src/'); const SKETCH_TEMP_PATH = path.resolve(SKETCH_FOLDER_PATH, 'tmp'); const DESTINATION_PATH = path.resolve(__dirname, '../dist'); console.log('Build started...'); if (sketchtool.check()) { console.log(`Processing Sketch file via ${sketchtool.version()}`); build(); } else { console.info('You need Sketch installed to run this script'); process.exit(1); } // ---------------------------------------- function build() { // be sure to start with a blank slate del.sync([SKETCH_TEMP_PATH, DESTINATION_PATH]); // process all the brands declared in the list of Sketch files Object.keys(SKETCH_FILES).forEach(async (brand) => {   // get the design tokens for the brand   const brandTokens = getDesignTokens(brand);    // prepare the Sketch files (unzipped) and get a list of them   const sketchUnzipFolders = await prepareSketchFiles({     brand,     sketchFileNames: SKETCH_FILES[brand],     sketchFolder: SKETCH_FOLDER_PATH,     sketchTempFolder: SKETCH_TEMP_PATH   });   // get the Sketch metadata   const sketchMetadata = getSketchMetadata(sketchUnzipFolders);   const sketchDataSharedStyles = sketchMetadata.sharedStyles;   const sketchDataAssets = sketchMetadata.assetsMetadata;   generateAssetsPDF({     platform: 'ios',     brand,     brandTokens,     sketchDataSharedStyles,     sketchDataAssets   });   generateAssetsSVGDynamicMobileWeb({     platform: 'mw',     brand,     brandTokens,     sketchDataSharedStyles,     sketchDataAssets   });   generateAssetsVectorDrawableDynamicAndroid({     platform: 'android',     brand,     brandTokens,     sketchDataSharedStyles,     sketchDataAssets   }); }); } 

Bahkan, kode pipa jauh lebih rumit. Alasan untuk kompleksitas ini terletak pada fungsi prepareSketchFiles , getSketchMetadata dan fungsi generateAssets[format][platform] getSketchMetadata . Di bawah ini saya akan mencoba menggambarkannya secara lebih rinci.

Mempersiapkan File Sketsa


Langkah pertama dalam proses perakitan adalah persiapan file Sketch, yang nantinya akan digunakan untuk mengekspor sumber daya untuk berbagai platform.

File yang terkait dengan merek tertentu (misalnya, dalam kasus Blendr, ini adalah icons_common.sketch dan file icons_blendr.sketch ) dikloning ke folder sementara (lebih tepatnya, ke dalam subfolder bernama setelah merek diproses) dan membuka ritsleting.

Kemudian file JSON diproses. Awalan ditambahkan ke nama sumber daya yang tunduk pada pengujian A / B - dengan demikian, saat mengekspor, mereka akan disimpan dalam subfolder dengan nama yang telah ditentukan (sesuai dengan nama unik percobaan). Anda dapat memahami apakah sumber daya tunduk pada pengujian A / B dengan nama halaman tempat penyimpanannya: jika ada, nama tersebut akan berisi awalan " XP_ ".



Dalam contoh di atas, sumber daya yang diekspor akan disimpan dalam subfolder dari " this__is_an_experiment " dengan nama file dari bentuk " icon-name [variant-name] .ext ".

Membaca Sketsa Metadata


Langkah penting kedua adalah mengekstrak semua metadata yang diperlukan dari file Sketch, atau lebih tepatnya, dari file JSON internal. Seperti yang kita lihat di atas, ini adalah dua file utama ( document.json dan meta.json ) dan file halaman ( halaman / pageUniqueId.json ).

File document.json digunakan untuk mendapatkan daftar gaya umum yang muncul di bawah properti objek layerStyles :

 { "_class": "document", "do_objectID": "45D2DA82-B3F4-49D1-A886-9530678D71DC", "colorSpace": 1, ... "layerStyles": {  "_class": "sharedStyleContainer",  "objects": [    {      "_class": "sharedStyle",      "do_objectID": "9BC39AAD-CDE6-4698-8EA5-689C3C942DB4",      "name": "features/feature-like",      "value": {        "_class": "style",        "fills": [          {            "_class": "fill",            "isEnabled": true,            "color": {              "_class": "color",              "alpha": 1,              "blue": 0.10588235408067703,              "green": 0.4000000059604645,              "red": 1            },            "fillType": 0,            "noiseIndex": 0,            "noiseIntensity": 0,            "patternFillType": 1,            "patternTileScale": 1          }        ],        "blur": {...},        "startMarkerType": 0,        "endMarkerType": 0,        "miterLimit": 10,        "windingRule": 1      }    },    ... 

Kami menyimpan informasi dasar tentang setiap gaya dalam objek format nilai kunci. Ini akan digunakan nanti ketika kita perlu mengekstrak nama gaya berdasarkan ID unik (properti do_objectID di Sketch):

 const parsedSharedStyles = {}; parsedDocument.layerStyles.objects.forEach((object) => { parsedSharedStyles[object.do_objectID] = {  name: object.name,  isFill: _.get(object, 'value.fills[0].color') !== undefined,  isBorder: _.get(object, 'value.borders[0].color') !== undefined, }; }); 

Sekarang kita pergi ke file meta.json dan mendapatkan daftar halaman. Kami tertarik pada unique-id dan name unique-id mereka:

 { "commit": "623a23f2c4848acdbb1a38c2689e571eb73eb823", "pagesAndArtboards": {  "EE6BE8D9-9FAD-4976-B0D8-AB33D2B5DBB7": {    "name": "Icons",    "artboards": {      "3275987C-CE1B-4369-B789-06366EDA4C98": {        "name": "badge-feature-like"      },      "C6992142-8439-45E7-A346-FC35FA01440F": {        "name": "badge-feature-crush"      },      ...      "7F58A1C4-D624-40E3-A8C6-6AF15FD0C32D": {        "name": "tabbar-livestream"      }      ...    }  },  "ACF82F4E-4B92-4BE1-A31C-DDEB2E54D761": {    "name": "XP_this__is_an_experiment",    "artboards": {      "31A812E8-D960-499F-A10F-C2006DDAEB65": {        "name": "this__is_an_experiment/tabbar-livestream[variant1]"      },      "20F03053-ED77-486B-9770-32E6BA73A0B8": {        "name": "this__is_an_experiment/tabbar-livestream[variant2]"      },      "801E65A4-3CC6-411B-B097-B1DBD33EC6CC": {        "name": "this__is_an_experiment/tabbar-livestream[control]"      }    }  }, 

Kemudian kita membaca file JSON yang sesuai dengan setiap halaman di folder halaman (saya ulangi bahwa nama file dalam bentuk [pageUniqueId] .json ) dan mempelajari sumber daya yang tersimpan di halaman ini (mereka terlihat seperti lapisan). Dengan demikian, kita mendapatkan nama , lebar / tinggi setiap ikon, Sketsa metadata untuk ikon lapisan ini, dan jika kita berurusan dengan halaman percobaan , maka nama uji A / B dan varian ikon ini.

Catatan : objek page.json memiliki perangkat yang sangat kompleks, jadi saya tidak akan memikirkannya. Jika Anda tertarik dengan apa yang ada di dalamnya, saya menyarankan Anda untuk membuat file Sketsa kosong yang baru, menambahkan beberapa konten ke dalamnya dan menyimpannya; kemudian ganti ekstensi untuk ZIP, unzip dan periksa salah satu file di folder halaman.

Dalam proses pemrosesan artboards, kami juga akan membuat daftar eksperimen (dan sumber daya terkait). Kita akan membutuhkannya untuk menentukan variasi ikon mana yang digunakan dalam percobaan mana - nama variasi ikon dilampirkan pada objek "dasar".

Untuk setiap file Sketsa assetsMetadata merek yang sedang diproses, kami membuat objek assetsMetadata yang terlihat seperti ini:

 { "navigation-bar-edit": {  "do_objectID": "86321895-37CE-4B3B-9AA6-6838BEDB0977",  ...sketch_artboard_properties,  "name": "navigation-bar-edit",  "assetname": "navigation-bar-edit",  "source": "icons_common",  "width": 48,  "height": 48  "layers": [    {      "do_objectID": "A15FA03C-DEA6-4732-9F85-CA0412A57DF4",      "name": "Path",      ...sketch_layer_properties,      "sharedStyleID": "6A3C0FEE-C8A3-4629-AC48-4FC6005796F5",      "style": {        ...        "fills": [          {            "_class": "fill",            "isEnabled": true,            "color": {              "_class": "color",              "alpha": 1,              "blue": 0.8784313725490196,              "green": 0.8784313725490196,              "red": 0.8784313725490196            },          }        ],        "miterLimit": 10,        "startMarkerType": 0,        "windingRule": 1      },    },  ],  ... }, "experiment-name/navigation-bar-edit[variant]": {  "do_objectID": "00C0A829-D8ED-4E62-8346-E7EFBC04A7C7",  ...sketch_artboard_properties,  "name": "experiment-name/navigation-bar-edit[variant]",  "assetname": "navigation-bar-edit",  "source": "icons_common",  "width": 48,  "height": 48  ... 

Seperti yang Anda lihat, dalam percobaan, ikon tunggal (dalam hal ini, bilah-bilah navigasi ) dapat berhubungan dengan banyak sumber. Pada saat yang sama, ikon yang sama dapat muncul dengan nama yang sama di file Sketsa lain yang terkait dengan merek. Ini sangat berguna : kami menggunakan trik ini untuk mengkompilasi serangkaian ikon yang umum, dan kemudian mengidentifikasi opsi spesifik sesuai dengan merek. Itulah sebabnya kami mendeklarasikan file Sketsa yang terkait dengan merek tertentu sebagai array:

 const SKETCH_FILES = { badoo: ['icons_common'], blendr: ['icons_common', 'icons_blendr'], fiesta: ['icons_common', 'icons_fiesta'], hotornot: ['icons_common', 'icons_hotornot'], }; 

Dalam hal ini, ketertiban sangat penting mendasar. Bahkan, dalam fungsi getSketchMetadata dipanggil oleh skrip, kami tidak mengembalikan objek assetsMetadata satu per satu sebagai file daftar. Sebaliknya, kami melakukan penggabungan objek yang mendalam - kami menggabungkannya dan mengembalikan objek assetsMetadata tunggal.

Secara umum, ini tidak lebih dari penggabungan "logis" file Sketch dan sumber dayanya ke dalam satu file. Namun, logikanya tidak sesederhana kelihatannya. Berikut adalah diagram yang kami buat dalam upaya untuk mencari tahu apa yang terjadi ketika ikon dengan nama yang sama (dan mungkin dikenakan pengujian A / B) dalam file yang berbeda dikaitkan dengan merek yang sama:



Pembuatan file siap pakai dalam berbagai format untuk platform berbeda


Tahap terakhir dari proses kami adalah secara langsung membuat file ikon dalam berbagai format untuk platform yang berbeda (PDF untuk iOS, SVG / JSX untuk Web dan VectorDrawable untuk Android).

Seperti yang dapat Anda lihat dari jumlah parameter yang diteruskan ke fungsi generateAssets[format][platform] hasilAsset, bagian dari pipa ini adalah yang paling kompleks. Di sinilah proses mulai putus dan berubah tergantung pada platform. Di bawah ini Anda akan melihat alur logis skrip secara keseluruhan dan bagaimana bagian yang terkait dengan pembuatan sumber daya dibagi menjadi tiga proses yang serupa tetapi berbeda:



Untuk membuat sumber daya siap pakai dengan warna yang benar sesuai dengan merek yang sedang diproses, kita perlu melakukan beberapa manipulasi lagi dengan file JSON. Kami melewati semua lapisan yang menerapkan gaya umum, dan mengganti nilai warna dengan warna dari token desain merek.

Untuk menghasilkan file untuk Android, Anda perlu melakukan tindakan tambahan (kira-kira nanti): kami mengubah properti fill-rule dari setiap lapisan dari even-odd menjadi non-zero (ini dikendalikan oleh properti windingRule dari objek JSON, di mana 1 berarti "aneh / genap" , dan 0 adalah "tidak sama dengan nol").

Setelah melakukan manipulasi ini, kami mengemas file JSON kembali ke file Sketch standar untuk memproses dan mengekspor sumber daya dengan properti yang diperbarui (file yang diklon dan diperbarui adalah file Sketsa biasa, mereka dapat dibuka, dilihat, diedit, disimpan, dll. )

Setelah itu, kami menggunakan SketchTool (dibungkus dengan Node ) untuk secara otomatis mengekspor semua sumber daya dalam format yang sesuai untuk platform. Untuk setiap file yang terkait dengan merek (atau lebih tepatnya, versi yang diklon dan diperbarui), kami menjalankan perintah berikut:

 sketchtool.run(`export slices ${cloneSketchFile} --formats=svg --scales=1 --output=${destinationFolder} --overwriting`); 

Seperti yang Anda duga, perintah ini mengekspor sumber daya ke folder tujuan dalam format tertentu, opsional menggunakan penskalaan (kami menjaga skala asli untuk saat ini). Kuncinya di sini adalah opsi -overwriting : sama seperti kita melakukan penggabungan yang mendalam dari objek assetsMetadata (sesuai dengan file sketsa "logis"), ketika mengekspor kita menggabungkan banyak file ke dalam satu direktori (terkait dengan merek / platform). Ini berarti bahwa jika sumber daya - diidentifikasi dengan nama lapisan - sudah ada di file Sketch sebelumnya, itu akan ditimpa selama ekspor berikutnya. Sekali lagi, ini tidak lebih dari operasi penggabungan normal.

Namun, dalam contoh ini, beberapa sumber daya bisa berubah menjadi "hantu". Ini terjadi ketika ikon dalam file mengalami pengujian A / B, tetapi ditimpa dalam file berikutnya. Kemudian file varian diekspor ke folder tujuan, memiliki tautan yang sesuai dengan sumber daya dalam objek assetsMetadata (dengan kunci dan properti mereka), tetapi tidak terkait dengan sumber daya dasar apa pun (karena penggabungan mendalam dari objek assetsMetadata ). File seperti itu akan dihapus nanti, sebelum menyelesaikan proses.



Seperti yang telah disebutkan, platform yang berbeda membutuhkan format output yang berbeda. File iOS sesuai dengan PDF, dan kami dapat langsung mengekspornya menggunakan perintah SketchTool. File JSX diperlukan untuk Mobile Web, dan VectorDrawable untuk Android. Untuk alasan ini, kami mengekspor sumber daya dalam format SVG ke folder sementara dan setelah itu kami memprosesnya.

PDF untuk iOS


Anehnya, PDF adalah satu-satunya (?) Format yang didukung Xcode dan OS / iOS untuk mengimpor dan merender sumber daya vektor ( inilah penjelasan singkat tentang pilihan Apple).

Karena kita dapat langsung mengekspor ke PDF melalui SketchTool, tidak diperlukan langkah-langkah tambahan: cukup simpan file langsung ke folder tujuan, dan hanya itu.

Bereaksi / File Web JSX


Dalam kasus Web, kami menggunakan Node perpustakaan SVGR, yang memungkinkan Anda untuk mengkonversi SVG ke komponen Bereaksi. Namun, kami ingin melakukan sesuatu secara tiba-tiba: “secara dinamis mewarnai” ikon saat runtime (warna diambil dari token). Untuk melakukan ini, sebelum mengonversi, kami mengubah nilai fill untuk vektor yang gaya umum sebelumnya diterapkan ke nilai dari token yang sesuai dengan gaya ini.

Jadi jika file badge-feature-like.svg yang diekspor dari Sketch terlihat seperti ini:

 <?xml version="1.0" encoding="UTF-8"?> <svg width="128px" height="128px" viewBox="0 0 128 128" version="1.1" xmlns="<a href="http://www.w3.org/2000/svg">http://www.w3.org/2000/svg</a>" xmlns:xlink="<a href="http://www.w3.org/1999/xlink">http://www.w3.org/1999/xlink</a>"> <!-- Generator: sketchtool 52.2 (67145) -<a href="http://www.bohemiancoding.com/sketch"> http://www.bohemiancoding.com/sketch</a> --> <title>badge-feature-like</title> <desc>Created with sketchtool.</desc> <g id="Icons" fill="none" fill-rule="evenodd">  <g id="badge-feature-like">    <circle id="circle" fill="#E71032" cx="64" cy="64" r="64">    <path id="Shape" fill="#FFFFFF" d="M80.4061668,..."></path>  </g> </g> </svg> 

maka ikon sumber daya terakhir / badge-feature-like.js akan terlihat seperti ini:

 /* This file is generated automatically - DO NOT EDIT */ /* eslint-disable max-lines,max-len,camelcase */ const React = require('react'); module.exports = function badge_feature_like({ tokens }) { return (  <svg data-origin="pipeline" viewBox="0 0 128 128">    <g fill="none" fillRule="evenodd">      <circle fill={tokens.TOKEN_COLOR_FEATURE_LIKED_YOU} cx={64} cy={64} r={64} />      <path fill="#FFF" d="M80.4061668,..." />    </g>  </svg> ); }; 

Seperti yang Anda lihat, kami mengganti warna fill statis dengan warna dinamis yang mengambil nilai dari token (mereka dapat dibuat tersedia untuk komponen <Icon/> Bereaksi melalui API Konteks, tetapi ini adalah cerita yang berbeda).

Penggantian ini dimungkinkan berkat metadata Sketsa untuk aset assetsMetadata objek: melalui lapisan secara rekursif, Anda dapat membuat pemilih DOM (untuk contoh di atas, #Icons #badge-feature-like #circle ) dan menggunakannya untuk mencari simpul di pohon SVG dan mengganti nilainya. fill atribut (untuk ini kita perlu perpustakaan cheerio ).

File VectorDrawable untuk Android


Android mendukung grafik vektor menggunakan format vektor VectorDrawable kustom. Biasanya mengkonversi dari SVG ke VectorDrawable dilakukan langsung di Android Studio . Namun, kami ingin mengotomasi proses sepenuhnya, jadi kami mencari cara untuk mengonversi menggunakan kode.

Setelah mempelajari berbagai alat dan perpustakaan, kami memutuskan svg2vectordrawable . Itu tidak hanya didukung secara aktif (dalam hal apapun, lebih aktif daripada orang lain), tetapi juga lebih fungsional daripada yang lain.

Kenyataannya adalah bahwa VectorDrawable dan SVG tidak sama dalam fungsinya: beberapa fungsi SVG (misalnya, gradien radial dan sorotan kompleks) tidak didukung oleh VectorDrawable, sementara yang lain mulai didukung baru-baru ini (dimulai dengan Android API 24). Salah satu masalah yang muncul dari ini adalah bahwa versi yang lebih lama (hingga 24) tidak mendukung nilai genap-genap atribut aturan-isi . Namun, kami di Badoo membutuhkan dukungan untuk Android 5 dan di atasnya. Itulah sebabnya, pada salah satu tahap sebelumnya, kami fill setiap vektor pada file Sketch menjadi non-zero .

Pada prinsipnya, desainer dapat melakukan tindakan ini secara manual:



Tapi ini mudah dilupakan dan dibuat kesalahan. Oleh karena itu, kami memutuskan untuk menambahkan langkah tambahan ke proses untuk Android, di mana semua vektor di JSON secara otomatis dikonversi ke non-zero . Hal ini dilakukan agar ketika mengekspor ikon ke SVG mereka sudah dalam format yang diperlukan, dan setiap objek yang dibuat VectorDrawable didukung oleh perangkat di Android 5.

File badge-feature-like.xml jadi terlihat seperti ini:

 <!-- This file is generated automatically - DO NOT EDIT --> <vector xmlns:android="<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>" android:width="128dp" android:height="128dp" android:viewportWidth="128" android:viewportHeight="128"> <path  android:fillColor="?color_feature_liked_you"  android:pathData="M64 1a63 63 0 1 0 0 126A63 63 0 1 0 64 1z" /> <path  android:fillColor="#FFFFFF"  android:pathData="M80.406 ..." /> </vector> 

Dalam file VectorDrawable, kami menyisipkan nama variabel untuk warna fill , yang dikaitkan dengan token desain melalui gaya umum di aplikasi Android.



Perlu dicatat bahwa Android Studio memiliki persyaratan ketat untuk mengatur sumber daya: tidak ada subfolder dan huruf kapital dalam nama! Jadi kami harus membuat format baru untuk nama ikon: dalam hal sumber daya yang akan diuji, mereka terlihat seperti ini: ic_icon-name__experiment-name__variant-name .

Kamus JSON sebagai Perpustakaan Sumber Daya


Setelah file sumber daya disimpan dalam format final, hanya mengumpulkan semua meta-informasi yang diperoleh selama perakitan dan menyimpannya ke dalam "kamus" untuk digunakan ketika sumber daya diimpor dan digunakan oleh basis kode berbagai platform.

Setelah mengekstraksi daftar datar ikon dari objek assetsMetadata kita memeriksanya, memeriksa masing-masing:

  • Apakah ini sumber daya reguler (misalnya, tabbar-livestream ); jika demikian, biarkan saja;
  • jika ini merupakan opsi untuk pengujian A / B (misalnya, percobaan / tabbar-streaming langsung [varian] ), kami mengaitkan namanya, jalur, nama uji A / B dan varian dengan properti abtests
    sumber daya dasar (dalam kasus kami adalah tabbar-livestream ), setelah itu kami menghapus catatan tentang opsi dari daftar / objek (hanya elemen "basis" yang penting);
  • jika itu adalah "hantu", maka hapus file dan hapus entri dari daftar / objek.

Setelah menyelesaikan proses ini, kamus akan berisi daftar semua ikon dasar (dan tes A / B mereka, jika ada), dan hanya mereka. Informasi tentang masing-masing dari mereka termasuk nama, ukuran, jalur dan, jika ikon tunduk pada pengujian A / B, informasi tentang berbagai pilihannya.

Kamus disimpan dalam format JSON di folder tujuan untuk merek dan platform . Di sini, misalnya, adalah file assets.json yang dihasilkan untuk aplikasi Blendr untuk Mobile Web:

 { "platform": "mw", "brand": "blendr", "assets": {    "badge-feature-like": {    "assetname": "badge-feature-like",    "path": "assets/badge-feature-like.jsx",    "width": 64,    "height": 64,    "source": "icons_common"  },  "navigation-bar-edit": {    "assetname": "navigation-bar-edit",    "path": "assets/navigation-bar-edit.jsx",    "width": 48,    "height": 48,    "source": "icons_common"  },  "tabbar-livestream": {    "assetname": "tabbar-livestream",    "path": "assets/tabbar-livestream.jsx",    "width": 128,    "height": 128,    "source": "icons_blendr",    "abtest": {      "this__is_an_experiment": {        "control": "assets/this__is_an_experiment/tabbar-livestream__control.jsx",        "variant1": "assets/this__is_an_experiment/tabbar-livestream__variant1.jsx",        "variant2": "assets/this__is_an_experiment/tabbar-livestream__variant2.jsx"      },      "a_second-experiment": {        "control": "assets/a_second-experiment/tabbar-livestream__control.jsx",        "variantA": "assets/a_second-experiment/tabbar-livestream__variantA.jsx"      }    }  },  ... } } 

Sekarang yang tersisa adalah mengemas semua folder aset ke dalam arsip ZIP agar lebih mudah diunduh.

Ringkasan


Proses yang dijelaskan dalam artikel, dari mengkloning dan memanipulasi file Sketch hingga mengekspor dan mengkonversi sumber daya ke format yang didukung oleh platform dan menyimpan informasi meta yang dikumpulkan di perpustakaan sumber daya, diulangi dengan setiap merek yang diumumkan dalam skrip build.

Berikut ini adalah tangkapan layar yang memperlihatkan tampilan folder src dan dist setelah proses selesai:



Pada tahap ini, menggunakan satu perintah sederhana, Anda dapat mengunggah semua sumber daya (JSON, ZIP dan file sumber daya) ke penyimpanan jarak jauh dan membuatnya tersedia untuk semua platform untuk diunduh dan digunakan dalam basis kode.

Bagaimana tepatnya platform menerima dan memproses sumber daya (menggunakan skrip khusus yang dibuat khusus untuk tujuan ini) tidak melampaui ruang lingkup artikel ini. Dan pertanyaan ini mungkin akan dibahas dalam salah satu posting berikut oleh salah satu kolega saya.

Kesimpulan (dan pelajaran yang didapat)


Saya selalu menyukai Sketch. Selama bertahun-tahun, program ini telah menjadi alat default untuk pengembang dan perancang. Oleh karena itu, saya sangat penasaran untuk mempelajari alat integrasi seperti html-sketchapp dan alat serupa lainnya yang dapat kami gunakan dalam alur kerja dan saluran pipa kami.

Saya, seperti banyak orang lain , selalu berjuang untuk proses (ideal) seperti itu:



Namun, saya harus mengakui bahwa saya mulai ragu bahwa Sketch adalah alat yang cocok, terutama mengingat sistem desain. Oleh karena itu, saya mulai melihat layanan lain, seperti Figma dengan API terbuka dan Framer X dengan integrasi yang mudah dengan React, karena saya tidak merasakan gerakan Sketch menuju integrasi dengan kode (apa pun itu).

Jadi, proyek ini meyakinkan saya. Tidak sepenuhnya, tetapi dalam banyak hal.

Meskipun Sketch tidak membuka API-nya, perangkat struktur internal file-nya berfungsi sebagai semacam API “tidak resmi”. Pembuat dapat menggunakan nama terenkripsi atau menyembunyikan kunci dalam objek JSON, tetapi sebaliknya mereka mematuhi konvensi penamaan yang jelas, mudah dibaca, dan konseptual. Saya rasa ini bukan kecelakaan.

Fakta bahwa file Sketsa dapat dikelola dengan cara ini telah membuka jalan bagi saya untuk banyak pengembangan dan peningkatan di masa depan: mulai dari plugin untuk memeriksa nama, stilisasi dan struktur lapisan untuk ikon hingga integrasi dengan Wiki kami dan dokumentasi sistem desain kami (mutual). Dengan membuat aplikasi Node di Electron atau Carlo , kita dapat membuatnya lebih mudah bagi desainer untuk menyelesaikan banyak tugas rutin.

( , ) , Sketch- Cosmos « » — - Cosmos. , ( ; , — ). , — , , .

, Sketch- , , MVP-, . , , . , , -, — , . , .

: , . , .

, , — . , , , (, A/B-), Node.js Sketch.

! .


(Mobile Web), , (Android) (iOS), .

, ! .

Source: https://habr.com/ru/post/id442886/


All Articles