نظرة عامة على خط الأنابيب
ينفّذ pnpm codegen الأمر codegen/src/index.ts، وخط الأنابيب الكامل كالتالي:
رقم إصدار package.json │ ▼loadTokenFiles() تحميل tokens/*.json، تحقق Ajv الهيكلي، تسطيح flatten │ يعيد LoadedTokenFile[] (كل ملف يحوي namespace / isDark / flat) ▼resolveTokens() تحليل ref (متضممنًا الكشف عن الحلقات) + دمج الوضع الداكن │ يعيد { tokenSet, orphanDarkPaths, refMap } ▼loadSpecs() تحميل specs/*.json (تحقق schema)loadCases() تحميل cases/*.json (تحقق schema) │ ▼تجميع CodegenInput { tokens: tokenSet, specs, cases, version } │ ▼حذف مجلد dist/ بالكامل وإعادة بنائه │ ▼تنفيذ الأهداف الخمسة بالترتيب ──► android ← ios ← harmony ← c ← docs │ كل target.generate(input) يعيد GeneratedFile[] ▼الكتابة على القرص ملفًا ملفًا وفق dist/<outDir>/<relativePath>ملف الدخول codegen/src/index.ts
Section titled “ملف الدخول codegen/src/index.ts”الثوابت
Section titled “الثوابت”| الثابت | القيمة |
|---|---|
ROOT |
جذر المستودع (مستويان أعلى import.meta.dirname) |
DIST |
<ROOT>/dist |
targets |
[androidTarget, iosTarget, harmonyTarget, cTarget, docsTarget]، بترتيب ثابت |
main()
Section titled “main()”function main(): voidالدخول الوحيد (لا يُصدِّر index.ts أي كيان، وmain() دالة داخلية، تُستدعى مباشرةً في نهاية الملف). الخطوات:
- يقرأ
readVersion()رقم الإصدار منpackage.json - يحمل
loadTokenFiles()الرموز - يحلل
resolveTokens(files)ويأخذtokenSet - يحمّل
loadSpecs()/loadCases()العقود والحالات - يجمع
CodegenInput - عند
existsSync(DIST)ينفذrmSync(DIST, { recursive: true })— حذف أولًا ثم بناء، لضمان عدم بقاء مخلفات في المنتجات - يستدعي
generate(input)لكل هدف، ويكتب الملفات وفقdist/<outDir>/<relativePath>، مع طباعة سجل[target] pathلكل منتج - سطر أخير يلخّص عدد الأهداف وعدد الملفات والإصدار
يذكر تعليق رأس الملف الخط الأحمر 1 صراحةً: توليد هيكل الرموز فقط، دون توليد أي تنفيذ للواجهة.
الواجهات الأساسية (codegen/src/types.ts)
Section titled “الواجهات الأساسية (codegen/src/types.ts)”فيما يلي الواجهات الأربع الأكثر استخدامًا في خط الأنابيب؛ المرجع الكامل لجميع تصديرات الأنواع الـ 16 في تعريفات الأنواع types.ts.
CodegenTarget
Section titled “CodegenTarget”interface CodegenTarget { name: string // بادئة السجل، مثل 'android' outDir: string // اسم الدليل الفرعي تحت dist، مثل 'android' generate(input: CodegenInput): GeneratedFile[]}ينفذ كل هدف لمنصة هذه الواجهة. إضافة منصة جديدة = إضافة هدف جديد وإدراجه في مصفوفة targets.
CodegenInput
Section titled “CodegenInput”interface CodegenInput { tokens: TokenSet // مجموعة رموز الوضع الفاتح محلَّلة + تغطية الوضع الداكن specs: ComponentSpec[] // غير مُستهلكة حاليًا من أي هدف (محجوزة لتوليد توثيق/اختبارات المكوّنات مستقبلًا) cases: ComponentCases[] // مثل ما سبق version: string // رقم إصدار package.json، يُكتب في تعليق رأس كل منتج}GeneratedFile
Section titled “GeneratedFile”interface GeneratedFile { relativePath: string // مسار الإخراج بالنسبة إلى dist/<outDir>/ content: string}TokenSet
Section titled “TokenSet”interface TokenSet { tokens: ResolvedToken[] // رموز الوضع الفاتح (مرتبة حسب path معجميًا) byPath: Map<string, ResolvedToken> // بحث سريع حسب المسار dark: DarkOverrides // path ← قيمة تغطية الوضع الداكن}العدد الإجمالي للمنتجات
Section titled “العدد الإجمالي للمنتجات”| الهدف | عدد الملفات |
|---|---|
| android | 2 (LhTokens.kt + LhDarkTokens.kt) |
| ios | 2~3 (+ LhShadow.swift عند وجود رموز ظلال) |
| harmony | 2~3 (+ LhShadow.ets) |
| c | 2 |
| docs | 3 |
لا تُولَّد ملفات الظلال في ios / harmony إلا عند وجود رموز shadow، لذلك يتغير العدد الإجمالي للملفات تبعًا لمحتوى الرموز، والمعتمد هو ما في dist/ فعلًا.
الوحدات ذات الصلة
Section titled “الوحدات ذات الصلة”| الوحدة | المسؤولية |
|---|---|
| load.ts | التحميل والتحقق الهيكلي |
| resolve.ts | تحليل المراجع ودمج الوضع الداكن |
| format.ts | تحليل القيم المحايدة والتنسيق لكل طرف |
| tree.ts | تحويل المسطح إلى متداخل |
| render.ts | عرض القوالب |
| types.ts | جميع تعريفات الأنواع |
| targets/ | الأهداف الخمسة للمنصات |
| templates/ | 7 قوالب handlebars |
Copyright © 2024-2026 FengMo WenXue