
هذا هو الجزء الثاني من المقالة حول إنشاء أداة يمكنها تصدير جميع الرموز الموضوعة في ملف رسم: بتنسيقات مختلفة ، للأنظمة الأساسية المختلفة ، مع إمكانية اختبار A / B لكل رمز.
يمكنك قراءة الجزء الأول
من الرابط .

آخر مرة ، قمنا بإعداد ملفات Sketch التي تحتوي على جميع الرموز في الأنماط الصحيحة والأسماء الصحيحة. حان دور رمز الكتابة.
يكفي أن نقول أننا ذهبنا من خلال التجربة والخطأ. بعد قيام قائد فريقنا
Nihil Verma ، الذي وضع أسس البرنامج النصي ، بتطوير الكود المصدري الرئيسي ، بدأت عملية تتطلب ثلاث مراحل على الأقل من إعادة التوطين والعديد من التعديلات. لهذا السبب ، لن أخوض في تفاصيل إنشاء البرنامج النصي والتركيز على كيفية عمله اليوم ، في شكله النهائي.
بناء السيناريو
النص البرمجي للبناء المكتوب على Node.js واضح إلى حد ما في عمله: من خلال استيراد التبعيات ، إعلان قائمة بملفات Sketch للمعالجة (قائمة العلامات التجارية ، ولكل منها قائمة بالملفات المتعلقة به) والتأكد من تثبيت Sketch على العميل ، يعالج البرنامج النصي العلامات التجارية بدوره ، ويقوم بسلسلة من الإجراءات مع كل منها.
- يأخذ رموز التصميم المناسبة للعلامات التجارية (نحتاج إلى قيم الألوان).
- استنساخ ملفات Sketch المرتبطة بالعلامات التجارية وفك ضغطها واستخراج ملفات JSON الداخلية ومعالجة بعض قيمها الداخلية (المزيد حول هذا لاحقًا).
- يقرأ البيانات الوصفية اللازمة من ملفات JSON هذه ( document.json و meta.json والصفحات / pageUniqueID.json ). نحن مهتمون بقوائم الأنماط والموارد / الرموز الشائعة الموجودة في الملفات.
- بعد المزيد من التلاعب بملفات JSON ، تقوم بإعادة إنشاء الأرشيف ، وباستخدام ملفات Sketch (المستنسخة والمحدثة) ، تقوم بتصدير وإنشاء ملفات الإخراج النهائية لثلاث منصات (iOS و Android و Mobile Web).
يمكن العثور على الأجزاء ذات الصلة من البرنامج النصي للبناء هنا:
// ... 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 }); }); }
في الواقع ، رمز خط الأنابيب أكثر تعقيدًا بكثير. يكمن سبب هذا التعقيد في
prepareSketchFiles
و
getSketchMetadata
generateAssets[format][platform]
وظائف
generateAssets[format][platform]
. أدناه سأحاول وصفها بمزيد من التفاصيل.
إعداد ملفات رسم
تتمثل الخطوة الأولى في عملية التجميع في إعداد ملفات Sketch ، والتي سيتم استخدامها فيما بعد لتصدير الموارد لمختلف المنصات.
الملفات المرتبطة بعلامة تجارية معينة (على سبيل المثال ، في حالة Blendr ، هذه هي
icons_common.sketch وملفات icons_blendr.sketch ) يتم استنساخها في مجلد مؤقت (بشكل أكثر دقة ، في مجلد فرعي مسمى باسم العلامة التجارية التي تتم معالجتها) ثم فك ضغطها.
ثم تتم معالجة ملفات JSON. تتم إضافة بادئة إلى اسم الموارد الخاضعة لاختبار A / B - وبالتالي ، أثناء التصدير ، سيتم حفظها في مجلد فرعي باسم محدد مسبقًا (مطابق لاسم فريد للتجربة). يمكنك أن تفهم ما إذا كان المورد يخضع لاختبار A / B من خلال اسم الصفحة التي تم تخزينه عليها: إذا كان ، فسيحتوي الاسم على البادئة "
XP_ ".

في المثال أعلاه ، سيتم تخزين الموارد التي تم تصديرها في مجلد فرعي من "
this__is_an_experiment " مع اسم ملف النموذج "
اسم رمز [اسم البديل] . نص".
قراءة رسم البيانات الوصفية
الخطوة المهمة الثانية هي استخراج جميع البيانات الأولية اللازمة من ملفات Sketch ، أو بالأحرى من ملفات JSON الداخلية. كما رأينا أعلاه ،
فهذان ملفان رئيسيان (
document.json و
meta.json ) وملفات صفحة (
pages / pageUniqueId.json ).
يتم استخدام ملف
document.json للحصول على قائمة الأنماط الشائعة التي تظهر تحت خاصية كائن
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 } }, ...
نقوم بتخزين المعلومات الأساسية حول كل نمط في كائن تنسيق قيمة المفتاح. سيتم استخدامه لاحقًا عندما نحتاج إلى استخراج اسم النمط استنادًا إلى معرّف فريد (خاصية
do_objectID
في 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, }; });
الآن نذهب إلى ملف
meta.json والحصول على قائمة الصفحات. نحن مهتمون بمعرفهم
unique-id
:
{ "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]" } } },
ثم نقرأ ملفات JSON المقابلة لكل صفحة في مجلد
الصفحات (أكرر أن أسماء الملفات من النموذج
[pageUniqueId] .json )
ونفحص الموارد المخزنة في هذه الصفحة (تبدو مثل الطبقات). وبالتالي ، نحصل على
اسم وعرض / ارتفاع كل أيقونة ، وبيانات
تعريفية مبدئية لأيقونة هذه الطبقة ، وإذا كنا نتعامل مع صفحة
التجربة ، ثم اسم
اختبار A / B ومتغير هذا الرمز.
ملاحظة : يحتوي كائن page.json على جهاز شديد التعقيد ، لذا لن أتطرق إليه. إذا كنت مهتمًا بما هو داخلي ، فإنني أنصحك بإنشاء ملف رسم فارغ جديد ، وإضافة بعض المحتوى إليه وحفظه ؛ ثم أعد تسمية امتداده إلى ZIP ، وقم بفك ضغطه وفحص أحد الملفات الموجودة في مجلد الصفحات.
في عملية معالجة اللوحات الفنية ، سنقوم أيضًا بإنشاء
قائمة بالتجارب (والموارد ذات الصلة). سنحتاج إليها لتحديد الأشكال المختلفة للأيقونة المستخدمة في أي تجربة - يتم إرفاق أسماء الأشكال المختلفة للأيقونة بالكائن "الأساسي".
لكل ملف رسم
assetsMetadata
بعلامة
assetsMetadata
يتم معالجته ، نقوم بإنشاء كائن بيانات
assetsMetadata
يشبه هذا:
{ "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 ...
كما ترون ، في التجربة ، يمكن أن يتطابق رمز واحد (في هذه الحالة ،
شريط التنقل - تحرير ) مع العديد من الموارد. في الوقت نفسه ، قد يظهر الرمز نفسه تحت نفس الاسم في ملف رسم آخر مرتبط بالعلامة التجارية.
هذا مفيد للغاية : نستخدم هذه الخدعة لتجميع مجموعة من الرموز الشائعة ، ثم تحديد خيارات محددة وفقًا للعلامة التجارية. لهذا السبب أعلنا ملفات Sketch المرتبطة بعلامة تجارية معينة كصفيف:
const SKETCH_FILES = { badoo: ['icons_common'], blendr: ['icons_common', 'icons_blendr'], fiesta: ['icons_common', 'icons_fiesta'], hotornot: ['icons_common', 'icons_hotornot'], };
في هذه الحالة ، يكون للنظام أهمية أساسية. في الواقع ، في دالة
getSketchMetadata
التي يطلق عليها البرنامج النصي ، فإننا لا
assetsMetadata
عناصر
assetsMetadata
في وقت واحد كملف قائمة. بدلاً من ذلك ، نقوم بإجراء دمج عميق للكائنات - نقوم
assetsMetadata
كائن
assetsMetadata
واحد.
بشكل عام ، هذا ليس أكثر من دمج "منطقي" لملفات Sketch ومواردها في ملف واحد. ومع ذلك ، فإن المنطق ليس بهذه البساطة كما يبدو. فيما يلي رسم تخطيطي أنشأناه في محاولة لمعرفة ما يحدث عندما تكون الرموز التي تحمل الاسم نفسه (وربما تخضع لاختبار A / B) في ملفات مختلفة مرتبطة بنفس العلامة التجارية:

إنشاء ملفات جاهزة بتنسيقات مختلفة للأنظمة الأساسية المختلفة
المرحلة الأخيرة من عمليتنا هي إنشاء ملفات الرموز مباشرة بتنسيقات مختلفة للأنظمة الأساسية المختلفة (PDF لنظام التشغيل iOS و SVG / JSX للويب و VectorDrawable لنظام Android).
كما ترون من عدد المعلمات التي تم تمريرها إلى دالات
generateAssets[format][platform]
، فإن هذا الجزء من خط الأنابيب هو الأكثر تعقيدًا. هذا هو المكان الذي تبدأ فيه العملية بالتفكك والتغيير وفقًا للنظام الأساسي. فيما يلي سترى المسار المنطقي للبرنامج النصي ككل وكيف ينقسم الجزء المتعلق بتوليد الموارد إلى ثلاث عمليات متشابهة ولكنها مختلفة:

لإنشاء موارد جاهزة مع الألوان الصحيحة التي تتوافق مع العلامة التجارية التي تتم معالجتها ، سنحتاج إلى إجراء المزيد من التلاعب بملفات JSON. نمر بجميع الطبقات التي يتم تطبيق النمط العام عليها ، ونستبدل قيم الألوان بالألوان من رمز تصميم العلامة التجارية.
لإنشاء ملفات لنظام Android ، تحتاج إلى تنفيذ إجراء إضافي (حوله لاحقًا بقليل): نقوم بتغيير خاصية
fill-rule
لكل طبقة من
even-odd
إلى
non-zero
(يتم التحكم في هذا بواسطة خاصية
windingRule
لكائن JSON ، حيث 1 تعني "فردي / متساوي" و 0 هي "لا تساوي الصفر").
بعد القيام بهذه العمليات ، نقوم بتجميع ملفات JSON مرة أخرى في ملف Sketch قياسي لمعالجة وتصدير الموارد مع الخصائص المحدثة (الملفات المستنسخة والمحدثة هي ملفات Sketch عادية ، ويمكن فتحها وعرضها وتعديلها وحفظها ، إلخ. )
بعد ذلك ، نستخدم SketchTool (ملفوفة
تحت Node ) لتصدير جميع الموارد تلقائيًا بتنسيقات مناسبة للأنظمة الأساسية. بالنسبة لكل ملف من الملفات المرتبطة بالعلامة التجارية (أو بالأحرى إصداراتها المستنسخة والمحدثة) ، فإننا نقوم بتشغيل الأمر التالي:
sketchtool.run(`export slices ${cloneSketchFile} --formats=svg --scales=1 --output=${destinationFolder} --overwriting`);
كما تعتقد ، يقوم هذا الأمر بتصدير الموارد إلى مجلد الوجهة بتنسيق معين ، باستخدام القياس اختياريًا (نحتفظ بالمقياس الأصلي في الوقت الحالي). المفتاح هنا هو خيار
-overwriting
: مثلما نفعل
assetsMetadata
لكائنات
assetsMetadata
(المقابلة لملفات Sketch "المنطقية") ، عند التصدير ندمج العديد من الملفات في دليل واحد (يتعلق بالعلامة التجارية / النظام الأساسي). هذا يعني أنه إذا كان المصدر - المحدد بواسطة اسم الطبقة - موجودًا بالفعل في ملف Sketch السابق ، فسيتم الكتابة فوقه أثناء التصدير التالي. مرة أخرى ، هذا ليس أكثر من عملية دمج عادية.
ومع ذلك ، في هذا المثال ، قد تتحول بعض الموارد إلى "أشباح". يحدث هذا عندما يتعرض الرمز الموجود في الملف لاختبار A / B ، ولكن يتم الكتابة فوقه في الملف التالي. بعد ذلك ، يتم تصدير الملفات المختلفة إلى المجلد الوجهة ، ويكون لها ارتباط مطابق للمورد في كائن
assetsMetadata
(بيانات ذات خصائص وخصائصها) ، لكن لا يرتبط بأي مورد أساسي (بسبب الدمج العميق لكائنات
assetsMetadata
). سيتم حذف هذه الملفات في وقت لاحق ، قبل إتمام العملية.
كما ذكرنا سابقًا ، تتطلب المنصات المختلفة تنسيقات إخراج مختلفة. تتوافق ملفات iOS مع ملفات PDF ، ويمكننا تصديرها مباشرة باستخدام أمر SketchTool. ملفات JSX مطلوبة من أجل Mobile Web و VectorDrawable لنظام Android. لهذا السبب ، نقوم بتصدير الموارد بتنسيق SVG إلى مجلد مؤقت وبعد ذلك نقوم بمعالجتها.
ملفات PDF لنظام التشغيل iOS
من الغريب أن PDF هو التنسيق الوحيد (؟) الذي يدعمه Xcode و OS / iOS لاستيراد موارد المتجهات وتقديمها (
فيما يلي شرح موجز لاختيار Apple).
نظرًا لأننا نستطيع التصدير مباشرة إلى PDF عبر SketchTool ، لا توجد خطوات إضافية مطلوبة: فقط قم بحفظ الملفات مباشرة إلى مجلد الوجهة ، وهذا كل شيء.
رد / JSX ملفات الويب
في حالة الويب ، نستخدم مكتبة SVGR Node ، التي تسمح لك بتحويل SVG إلى مكونات React. ومع ذلك ، نريد أن نفعل شيئًا مفاجئًا: "تلوين الأيقونة ديناميكيًا" في وقت التشغيل (يتم أخذ الألوان من الرموز). للقيام بذلك ، قبل التحويل ، نقوم بتغيير قيم
fill
للمتجهات التي تم تطبيق النمط العام عليها سابقًا على القيم من الرموز المميزة المتوافقة مع هذا النمط.
لذلك إذا كان ملف
badge-feature-like.svg الذي تم تصديره من Sketch يبدو كما يلي:
<?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>
بعد ذلك
سيبدو رمز المورد /
الشارة-feature-like.js النهائي كما يلي:
/* 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> ); };
كما ترون ، استبدلنا لون
fill
الثابتة بلون ديناميكي يأخذ قيمًا من الرموز المميزة (يمكن إتاحتها لمكون React
<Icon/>
عبر واجهة برمجة تطبيقات السياق ، ولكن هذه قصة مختلفة).
هذا الاستبدال ممكن بفضل بيانات تعريف Sketch عن أصول كائن الأصول
assetsMetadata
: يمكنك الانتقال من خلال الطبقات بشكل متكرر ، يمكنك إنشاء محدد DOM (على سبيل المثال أعلاه ،
#Icons
#badge-feature-like #circle
#Icons
#badge-feature-like #circle
) واستخدامه للبحث عن عقدة في شجرة SVG واستبدال قيمتها
fill
السمة (لهذا نحن بحاجة إلى مكتبة
cheerio ).
VectorDrawable الملفات لالروبوت
يدعم Android الرسومات المتجهة باستخدام تنسيق
VectorDrawable المخصص. عادة ما يتم التحويل من SVG إلى VectorDrawable
مباشرة في Android Studio . ومع ذلك ، أردنا أتمتة العملية بالكامل ، لذلك كنا نبحث عن وسيلة لتحويل باستخدام التعليمات البرمجية.
بعد أن درسنا العديد من الأدوات والمكتبات ،
استقرنا على
svg2vectordrawable . لا يدعم فقط بنشاط (في أي حال ، أكثر نشاطا من أي شخص آخر) ، ولكن أيضا أكثر وظيفية من بقية.
الحقائق هي أن VectorDrawable و SVG ليسا متماثلين في وظائفهم: بعض وظائف SVG (على سبيل المثال ، التدرجات الشعاعية والإبراز المعقدة) غير مدعومة من VectorDrawable ، في حين أن البعض الآخر بدأ يتم دعمه مؤخرًا (بدءً من Android API 24). إحدى المشكلات الناشئة عن ذلك هي أن الإصدارات الأقدم (حتى 24)
لا تدعم القيمة الزوجية لسمة قاعدة التعبئة . ومع ذلك ، نحن في Badoo نحتاج إلى دعم Android 5 والإصدارات الأحدث. لهذا السبب ، في إحدى المراحل السابقة ، وصلنا
fill
كل متجه في ملفات Sketch إلى قيمة
non-zero
.
من حيث المبدأ ، يمكن للمصممين تنفيذ هذا الإجراء يدويًا:

لكن هذا سهل النسيان وارتكب خطأ. لذلك ، قررنا إضافة خطوة إضافية إلى عملية Android ، حيث يتم تحويل جميع المتجهات في JSON تلقائيًا إلى
non-zero
. يتم ذلك بحيث يتم تصدير الأيقونات إلى SVG بالتنسيق المطلوب ، ويكون كل كائن VectorDrawable تم إنشاؤه مدعومًا بواسطة الأجهزة على Android 5.
يشبه ملف
badge-feature-like.xml النهائي هذا:
<!-- 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>
في ملفات VectorDrawable ، نقوم بإدراج أسماء متغيرة لألوان
fill
، المقترنة برموز التصميم من خلال الأنماط الشائعة في تطبيقات Android.

تجدر الإشارة إلى أن Android Studio لديه متطلبات صارمة لتنظيم الموارد: لا توجد مجلدات فرعية وأحرف كبيرة في الأسماء! لذلك كان علينا التوصل إلى تنسيق جديد لأسماء الرموز: في حالة الموارد التي سيتم اختبارها ، فإنها تبدو بشكل من هذا القبيل:
ic_icon-name__experiment-name__variant-name
.
JSON قاموس بمثابة مكتبة الموارد
بعد حفظ ملفات الموارد بالتنسيق النهائي ، يبقى فقط لجمع كل المعلومات الوصفية التي تم الحصول عليها أثناء التجميع وحفظه في "قاموس" لاستخدامه عندما يتم استيراد الموارد واستخدامها بواسطة قاعدة الشفرة في الأنظمة الأساسية المختلفة.
بعد استخراج قائمة مسطحة من الأيقونات من كائن
assetsMetadata
نمر خلالها ،
assetsMetadata
كل منها:
- هل هذا مورد منتظم (على سبيل المثال ،
tabbar-livestream
) ؛ إذا كان الأمر كذلك ، فما عليك سوى ترك الأمر ؛
- إذا كان هذا خيارًا لاختبار A / B (على سبيل المثال ، تجربة / tabbar-livestream [البديل] ) ، فنحن نربط اسمه ومساره وأسماء اختبار A / B ومتغير
abtests
المورد الأساسي (في حالتنا هو tabbar-livestream ) ، وبعد ذلك نقوم بحذف السجل الخاص بالمتغير من القائمة / الكائن (فقط عنصر "الأساس" مهم) ؛
- إذا كان "شبح" ، فاحذف الملف وقم بإزالة الإدخال من القائمة / الكائن.
بعد الانتهاء من هذه العملية ، سيحتوي القاموس على قائمة بجميع الرموز الأساسية (واختبارات A / B ، إن وجدت) ، وفقط لهم. تتضمن المعلومات الخاصة بكل منها الاسم والحجم والمسار ، وإذا كان الرمز خاضعًا لاختبار A / B ، فإن المعلومات المتعلقة بخياراتها المختلفة.
يتم حفظ القاموس بتنسيق JSON في مجلد الوجهة
للعلامة التجارية والنظام
الأساسي . هنا ، على سبيل المثال ، هو ملف
الأصول.json الذي تم إنشاؤه لتطبيق Blendr لـ 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" } } }, ... } }
الآن كل ما تبقى هو حزم جميع مجلدات
الأصول في أرشيفات ZIP لتسهيل التنزيل.
يؤدي
تتكرر العملية الموضحة في المقالة ، بدءًا من استنساخ ملفات Sketch ومعالجتها إلى تصدير الموارد وتحويلها إلى تنسيقات تدعمها الأنظمة الأساسية وحفظ معلومات التعريف المجمّعة في مكتبة الموارد ، مع كل علامة تجارية تم الإعلان عنها في البرنامج النصي للبناء.
فيما يلي لقطة شاشة توضح مظهر
src ومجلدات
dist بعد اكتمال العملية:

في هذه المرحلة ، باستخدام أمر واحد بسيط ، يمكنك تحميل جميع الموارد (JSON و ZIP وملفات الموارد) إلى وحدة التخزين عن بُعد وإتاحتها لجميع الأنظمة الأساسية للتنزيل والاستخدام في قاعدة الشفرة.
لا تتعدى كيفية تلقي الأنظمة الأساسية ومعالجتها للموارد (باستخدام البرامج النصية المخصصة التي تم إنشاؤها خصيصًا لهذا الغرض) نطاق هذه المقالة. ومن المحتمل أن يتم تغطية هذا السؤال في أحد الوظائف التالية بواسطة أحد زملائي.
الخلاصة (والدروس المستفادة)
أنا دائما أحب رسم. لسنوات عديدة ، كان البرنامج الأداة الافتراضية للمطورين والمصممين. لذلك ، كنت فضوليًا للغاية لتعلم أدوات الدمج مثل
html-sketchapp وغيرها من الأدوات المشابهة التي يمكننا استخدامها في سير العمل وخطوط أنابيبنا.
أنا ،
مثل كثيرين غيرهم ،
سعيت دائمًا إلى هذه العملية (المثالية):

ومع ذلك ، يجب أن أعترف أنني بدأت أشك في أن Sketch هي أداة مناسبة ، لا سيما بالنظر إلى نظام التصميم. لذلك ، بدأت أنظر إلى الخدمات الأخرى ، مثل Figma مع واجهات برمجة التطبيقات المفتوحة و Framer X مع التكامل المريح مع React ، لأنني لم أشعر بحركة Sketch نحو التكامل مع الشفرة (مهما كانت).
لذلك ، أقنعني هذا المشروع. ليس تماما ، ولكن في نواح كثيرة.
على الرغم من أن Sketch لا تفتح واجهات برمجة التطبيقات الخاصة بها ، فإن جهاز الهيكل الداخلي لملفاته يعمل كنوع من واجهة برمجة التطبيقات "غير الرسمية". يمكن للمنشئين استخدام أسماء مشفرة أو إخفاء مفاتيح في كائنات JSON ، لكن بدلاً من ذلك يلتزمون بمصطلح تسمية واضح ومقروء ومفهوم. لا أعتقد أن هذا حادث.
حقيقة أن ملفات Sketch يمكن إدارتها بهذه الطريقة قد فتحت الطريق أمامي للعديد من التطورات والتحسينات في المستقبل: من الإضافات إلى التحقق من اسم الطبقات ونمطها وهيكل الطبقات للأيقونات إلى التكامل مع Wiki وتوثيق نظام التصميم الخاص بنا (المتبادل). من خلال إنشاء تطبيقات Node على
Electron أو
Carlo ، يمكننا تسهيل المصممين لإكمال العديد من المهام الروتينية.
( , ) , Sketch- Cosmos « » — - Cosmos. , ( ; , — ). , — , , .
, Sketch- , , MVP-, . , , . , , -, — , . , .
:
,
. ,
.
, , — . , , , (, A/B-), Node.js Sketch.
! .
(Mobile Web), ,
(Android)
(iOS), .
, ! .