Skip to content

تله‌ها و نگهبانشان

This content is not available in your language yet.

هر چیزی که یک بار بی‌صدا خراب شد و دوباره خواهد شد. ستونِ نگهبان می‌گوید امروز چه چیزی می‌گیردش: تله‌ای که نگهبان دارد اینجا برای فهمیدنِ پیامِ همان نگهبان است، و تله‌ای که «—» دارد فقط همین سند و حواسِ تو را دارد — همان‌ها در CLAUDE.md هم هستند تا پیش از چشم باشند.

جایِ این سند: فاز ۹.۳ گفته بود جدول در conventions.md بنشیند. ننشست، چون آن سند «زبان، کامیت، کامنت» است و به انگلیسی نوشته شده تا هر تازه‌وارد بخواندش؛ فهرستِ تله‌ها نه قرارداد است نه انگلیسی. یک سند برای یک چیز.

تله نگهبان
dist ِ کهنه: آزمون و typecheck از src می‌خوانند، ولی pnpm e2e، pnpm size و node apps/cli/dist/darzsaz.mjs از بیلد — پس از تغییرِ کد اول pnpm -r build، وگرنه کدِ دیروز را سبز می‌بینی
tsconfig.json ِ هر بسته فقط فهرستِ برنامه‌هاست (files: []tsc --noEmit رویش هیچ نمی‌سنجد. tsc -p tsconfig.app.json یا pnpm typecheck pnpm typecheck
await ِ سطح بالا در هر ماژولِ بستهٔ وب بهینه‌سازیِ تکه‌های rolldown را برای کل ساخت خاموش می‌کند (۱۴ کیلوبایت و ۲۸ پرونده در فاز ۱)؛ درون تابع async بگذار لینت: topLevelAwait
pnpm run/exec با node_modules ِ ناهمگام نمی‌راند (verifyDepsBeforeRun: error): پس از دست زدن به package.json اول pnpm install خودِ pnpm
هر pnpm install می‌تواند کتابخانهٔ برنامه را دو نمونه کند: ‎@lingui/core‎ در web و ui دو i18n شد، بی هیچ آزمونِ افتاده؛ همتا در ریشه سنجاق است scripts/single-instance.mjs
اسکریپتی هم‌نامِ فرمانِ داخلیِ pnpm با pnpm <نام> اجرا نمی‌شودpnpm licenses خودِ pnpm را صدا می‌زند؛ نگهبان را با node scripts/… بران
pnpm --filter darzsaz ریشه را هم می‌گیرد — ریشه و CLI هم‌نام‌اند و ریشه pnpm -r می‌زند. CLI تنها: --filter ./apps/cli
بستهٔ ورک‌اسپیس در dependencies ِ CLI نه — جاسازی می‌شود و روی npm نیست؛ devDependencies scripts/release-check.mjs
رابط و چاپ دو فونت‌اند: یکان‌بخ فقط روی سایت؛ هر چه دانلود یا پخش می‌شود (گزارش چاپی، CLI روی npm) وزیرمتن — مجوزِ فونتِ تجاری پخشِ پرونده را نمی‌دهد scripts/licenses.mjs، site-fonts
نویسهٔ تازه در رابط ممکن است در فونتِ زیرمجموعه‌شده نباشد و بی‌صدا با فونت سامانه بیاید scripts/font-coverage.mjs
pkill -f <الگو> پوستهٔ خودش را هم می‌کشد اگر الگو در متنِ همان فرمان باشد
تله نگهبان
متغیر CSS ِ تعریف‌نشده خطا نمی‌دهد — کلِ اعلان را بی‌صدا باطل می‌کند. توکن‌های رقم‌دار --line-2/--panel-2/--bg-2 هستند (با خط تیره) scripts/css-vars.mjs
CSS در لایه است (reset, tokens, kit, app): جای پرونده لایه را تعیین می‌کند و برنامه همیشه بر کیت می‌چربد. CSS ِ بی‌لایه بر همه برنده است؛ قاعدهٔ عنصر (button {}) را در @layer reset بگذار apps/web/vite/css.ts + بیلد
قاعدهٔ CSS ِ کنترلِ خام پس از مهاجرت به کیت می‌ماند و به درونِ کیت می‌رسد (.field input) — با مهاجرت، قاعده را هم بردار kit/no-raw-button، kit-usage
min-height: 0 در ستونِ فلکسِ بی‌پیمایش: فرزندِ فلکس min-height: auto دارد؛ بی آن پنلِ overflow: auto کلِ صفحه را دراز می‌کند و پیمایش به پنجره می‌رود e2e/layout.spec.ts
رنگِ تیره در rgba روی بوم و صحنه: زمینهٔ نیمه‌شفافِ سخت‌کد در پوستهٔ روشن کنتراست را ۱٫۰۵ می‌کند (نوارِ سیاهِ نسل پنجم). --surface-overlay e2e/contrast.ts
axe و filter: پس‌زمینهٔ پشت filter: brightness() را نمی‌بیند و کنتراست را غلط می‌گیرد؛ رنگ واقعی بده (--accent-hover) e2e/contrast.ts
axe روی WebGL و SVG «incomplete» می‌دهد و سبز می‌ماند — سنجش با سیاه و سفیدِ مطلق در هر سه پوسته e2e/contrast.ts
jsx-a11y نقش application را نااندرکنشی می‌داند؛ کنترل واقعی بده (دکمه)، نه میان‌بر پنهان روی div لینت: jsx-a11y
ارقام هم‌عرض برای ستون است، نه متن روانtnum رقم «۱» را ۱۲۸٪ پهن‌تر می‌کند و «۳۰۰» شبیه «۳ ۰ ۰» می‌شود. فقط روی جدول و عددِ زنده
میان‌بر را با e.key نسنج — با چیدمانِ فارسی K «ن» است؛ shortcutKey(e) از apps/web/src/lib/keys.ts. میان‌برِ فهرستِ راهنما بی فرمان کار نمی‌کند
<text textAnchor="start"> در SVG جهت‌آگاه است — در راست‌به‌چپ «شروع» لبهٔ راست است؛ برچسبِ کنارِ نشان را middle کن
گزینهٔ حالت‌دار در منو «✓ » ِ چسبیده به برچسب نیستsection و checked در فرمان، که menuitemradio/menuitemcheckbox با aria-checked می‌شوند e2e/a11y.spec.ts
کامپایلر React (react-hooks ۷): مقدارِ هوک را مستقیم تغییر نده؛ در r3f از attach/props استفاده کن، نه scene.x = … در افکت لینت: react-hooks
immer: تابع تغییر نباید مقدار برگرداند ((p) => (p.x = v) می‌اندازد). بدنهٔ بلوکی خودِ immer، هنگام اجرا
immer و structuredClone: تابع هسته‌ای که structuredClone می‌کند (گونه، پیشنهاد ورق) را روی پیش‌نویس صدا نزن؛ از وضعیت ساده حساب کن و با Object.assign(draft, next) بنشان
پنجرهٔ دوم فقط پیرو است: وضعیت را از پنجرهٔ اصلی می‌گیرد و هرگز نمی‌نویسد — دو نویسنده روی یک پروژه یعنی رونویسیِ بی‌صدای کارِ یکی
تله نگهبان
پنل پیش‌نمای پنهان نقاشی نمی‌کند و requestAnimationFrame در تبِ پنهان اجرا نمی‌شود؛ عکسِ آنجا سیاه است. رندر را با darzsaz render یا pnpm e2e بسنج
عنصرِ تازهٔ three در JSX (<torusKnotGeometry>، مؤلفهٔ تازهٔ drei) کلاسش را در scene/three-catalogue.ts می‌خواهد — وگرنه فقط مرورگر با «not part of the THREE namespace» test/three-catalogue.test.ts
EffectComposer/پس‌پردازش drei انباشت رندر را می‌شکند؛ SoftShadows با three ۰٫۱۸۵ کار نمی‌کند
بنچمارک perf زیر بار دستگاه ۳۵–۴۰ میلی‌ثانیه می‌شود (آستانه ۳۴)؛ تنها اجرا کن: npx playwright test --project perf --no-deps
تله نگهبان
jsdom چیدمان و setPointerCapture ندارد؛ پرکننده‌ها در apps/web/test/setup.ts. چیزی که به چیدمان واقعی وابسته است فقط در Playwright دیده می‌شود
عکسِ مرجعِ آزمون تصویری فقط از کارِ دستیِ snapshots در CI می‌آید — رندرِ SwiftShader ِ دستگاه توسعه با تصویر رسمی یکی نیست؛ روی دستگاه آزمون کنار می‌رود، در CI نبودنش شکست است
mergeConfig آرایه‌ها را به هم می‌چسباند: در vitest.shared.ts آرایه‌ای که بسته‌ها خودشان می‌دهند (include، exclude) نگذار
Vitest ۴ و restoreMocks: فقط vi.spyOn را برمی‌گرداند؛ شمار و رفتارِ vi.fn() را mockReset ِ vitest.shared.ts پاک می‌کند
هشدارِ act در آزمون می‌اندازد: تغییرِ مستقیمِ فروشگاه وقتی جزئی گوشش است، درونِ act(() => …) apps/web/test/setup.ts
CSS Module در Vitest صادرهٔ نام‌دار ندارد مگر css.includeimport * as s + s.btn بی‌صدا undefined می‌شود؛ دسترسیِ پویا (s[x]) کلاسِ مرده را از knip پنهان می‌کند
چک‌باکس و فهرستِ React Aria ورودیِ پنهان دارند؛ در Playwright روی برچسب کلیک کن، نه .check()/.selectOption()
click() ِ Playwright خودش پیمایش می‌کند — گزینه‌ای که زیر لبهٔ منوی بُریده پنهان است با کلیک سبز می‌شود؛ «دیده می‌شود» را با toBeInViewport() بسنج
axe داخل iframe ِ sandbox می‌شکند («Target page has been closed»)؛ پیش‌نمای چاپ را از اسکن کنار بگذار
Playwright روی دستگاه توسعه کرومِ نصب‌شده را می‌خواهد (channel: 'chrome')؛ در CI تصویر رسمی scripts/test/chrome.test.mjs
برگهٔ برچسب page label-sheet است، نه page: آزمونی که برگه‌ها را با <section class="page"> می‌شمارد برچسب‌ها را نمی‌بیند

جزئیاتِ هر کدام در i18n.md و conventions.md.

تله نگهبان
Lingui بی‌زبانِ فعال هیچ‌چیز رندر نمی‌کند — نه خطا، نه هشدار، فقط DOM خالی؛ آزمون‌ها در test/setup.ts زبان را فعال می‌کنند
استخراج‌گر Lingui فقط i18n._ و شیءِ /*i18n*/ { id, message } را می‌شناسد، نه کمکی‌های خودت pnpm i18n:check
در جزء، i18n از useLingui() و عدد از useFmt() — ثابتِ سطح ماژول با زبانِ لحظهٔ بارگذاری قفل می‌شود و زیرِ memo متنِ زبانِ قبل می‌ماند لینت: web-i18n
برچسب ذخیره نکن — متنی که در وضعیت می‌ماند و بعد نشان داده می‌شود پیام است، نه رشتهٔ رندرشده (historyStep، errorMsg، partLabel)؛ دادهٔ کاربر با sayData استثناست لینت: sample-say
پیامِ /*i18n*/ شیء است، نه متن: message ِ آن را مستقیم نخوان — فارسیِ منبع بی‌صدا در برگهٔ انگلیسی می‌نشیند لینت: strings
دادهٔ کاربر یا نامِ محصول در JSX بی <bdi> در جهتِ دیگر می‌پیچد؛ در SVG unicodeBidi="plaintext"، و values ِ i18n._ با render(i18n, msg(D, …)) e2e/bidi.spec.ts، untypedValues
exactOptionalPropertyTypes: فیلد اختیاری را با ...(x === undefined ? {} : { x }) بده، نه x: undefined pnpm typecheck
تله نگهبان
اپ را اجرا کن و نگاه کن. چهار ایرادِ این نسل را هیچ آزمونی نگرفت و فقط نگاه به صفحه پیدا کرد (pnpm --filter @darzsaz/web dev)
Prettier پیش از ویرایش خودکار: متن پرونده را همان لحظه بخوان؛ قالب‌بندی چندخطی جایگزینی‌های حدسی را بی‌صدا رد می‌کند
هر ادعای عددی در سند با کد سنجیده می‌شود — مسیر، شمارهٔ خط و سقفِ اندازه scripts/doc-claims.mjs