diff --git a/README-ir.md b/README-ir.md index 66596be..0519108 100644 --- a/README-ir.md +++ b/README-ir.md @@ -21,31 +21,31 @@
-- [گیت/Git](#git) +- [گیت (Git)](#git) - [برخی از قوانین Git](#some-git-rules) - - [گردش‌کار گیت/Git workflow](#git-workflow) + - [گردش کار گیت (Git Workflow)](#git-workflow) - [نگارش بهتر متن کامیت‌ها](#writing-good-commit-messages) -- [مستندات](#documentation) -- [متغیرهای محیطی/Environments](#environments) - - [ایجاد محیط‌های توسعه‌ی یکپارچه/Consistent dev environments](#consistent-dev-environments) - - [وابستگی‌های یکسان و هماهنگ/Consistent dependencies](#consistent-dependencies) -- [وابستگی‌ها/Dependencies](#dependencies) -- [تست کردن/Testing](#testing) -- [ساختار و نام‌گذاری/Structure and Naming](#structure-and-naming) -- [سبک کدنویسی/Code style](#code-style) - - [برخی از دستورالعمل‌های code style](#code-style-check) - - [اعمال استانداردهای سبک کدنویسی](#enforcing-code-style-standards) -- [ثبت وقایع/Logging](#logging) -- [ای‌پی‌آی/API](#api) +- [مستندات (Documentation)](#documentation) +- [متغیرهای محیطی (Environments)](#environments) + - [ایجاد محیط‌های توسعه‌ی یکپارچه (Consistent Dev Environments)](#consistent-dev-environments) + - [وابستگی‌های یکسان و هماهنگ (Consistent Dependencies)](#consistent-dependencies) +- [وابستگی‌ها (Dependencies)](#dependencies) +- [تست کردن (Testing)](#testing) +- [ساختار و نام‌گذاری (Structure and Naming)](#structure-and-naming) +- [سبک کدنویسی (Code Style)](#code-style) + - [برخی اصول Code Style](#code-style-check) + - [اعمال استانداردهای کدنویسی](#enforcing-code-style-standards) +- [ثبت وقایع (Logging)](#logging) +- [ای‌پی‌آی (API)](#api) - [طراحی API](#api-design) - - [امنیت ای‌پی‌آی/API security](#api-security) - - [مستندسازی ای‌پی‌آی/API documentation](#api-documentation) -- [دسترس‌پذیری/Accessibility](#a11y) -- [مجوزدهی/Licensing](#licensing) + - [امنیت ای‌پی‌آی (API security)](#api-security) + - [مستندسازی ای‌پی‌آی (API documentation)](#api-documentation) +- [دسترس‌پذیری (Accessibility)](#a11y) +- [مجوزها (Licensing)](#licensing) -## 1. گیت/Git +## 1. گیت (Git)

@@ -55,77 +55,77 @@ ### 1.1 برخی از قوانین Git -مجموعه‌ای از قوانین وجود دارد که باید آن‌ها را به خاطر داشته باشید: +در کار با Git، رعایت مجموعه‌ای از قوانین و اصول ضروری است که در ادامه به آن‌ها اشاره شده است: -- کار را در برنچ feature انجام دهید +- کار را در برنچ `feature` انجام دهید _چرا:_ -> این روش باعث می‌شود که تمام کارها به صورت مجزا در یک برنچ اختصاصی انجام شوند، نه در برنچ اصلی. این کار به شما امکان را می‌دهد تا چندین درخواست Pull Request بدون سردرگمی ارسال کنید. همچنین می‌توانید به طور مکرر کد را به‌روزرسانی کنید، بدون اینکه برنچ اصلی را با کد ناپایدار و ناتمام آلوده کنید. [توضیحات بیشتر ...](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow) +> کار بر روی برنچ‌ feature باعث می‌شود تمام تغییرات به صورت مجزا و در یک برنچ اختصاصی اعمال شوند. این روش به شما این امکان را می‌دهد که چندین Pull Request ارسال کنید بدون اینکه دچار سردرگمی شوید. همچنین، می‌توانید کد خود را مکرراً به‌روزرسانی کنید، بدون اینکه برنچ اصلی را با کدهای ناپایدار و ناتمام آلوده کنید. ([توضیحات بیشتر ...](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)) - از برنچ `develop` انشعاب بگیرید _چرا:_ -> به این ترتیب، می‌توانید مطمئن شوید که کد برنچ master تقریباً همیشه بدون مشکل build می‌شود و معمولاً می‌توان آن را مستقیماً برای releases استفاده کرد (این کار ممکن است برای برخی پروژه‌ها بیش از حد لازم باشد). +> با انشعاب از برنچ `develop،` می‌توانید مطمئن باشید که کد موجود در برنچ `master` همیشه پایدار و قابل `build` است و معمولاً می‌توان آن را مستقیماً برای انتشار/releases استفاده کرد (البته این رویکرد ممکن است برای برخی از پروژه‌ها بیش از حد یا فراتر از نیاز باشد). -- هرگز مستقیماً به برنچ `develop` یا `master` پوش نکنید. بلکه یک درخواست Pull Request ایجاد کنید. +- هرگز به برنچ `develop` یا `master` مستقیماً Push نکنید، بلکه یک درخواست Pull Request ایجاد کنید. _چرا:_ -> این کار به اعضای تیم اطلاع می‌دهد که یک feature تکمیل شده است. همچنین امکان بررسی آسان کد توسط سایرین را فراهم می‌کند و فضایی برای بحث درباره feature پیشنهادی ایجاد می‌کند. +> هرگز به برنچ‌های `develop` یا `master` مستقیماً Push نکنید. به جای آن، یک Pull Request ایجاد کنید. این کار به اعضای تیم اطلاع می‌دهد که یک feature تکمیل شده است و امکان بررسی کد توسط سایرین و بحث درباره تغییرات را فراهم می‌کند. -- برنچ `develop` محلی/local خود را قبل از پوش کردن یک feature، ابتدا بروزرسانی و مورد بازبینی تعاملی (interactive rebase) قرار دهید، سپس درخواست Pull Request ایجاد کنید. +- قبل از Push کردن یک فیچر و ایجاد Pull Request، ابتدا برنچ `develop` محلی/local خود را به‌روزرسانی کنید و یک ری‌بیس (Rebase) تعاملی انجام دهید. _چرا:_ -> ری‌بیس (Rebase) برنچ درخواست‌شده (`master` یا `develop`) را merge می‌کند و کامیت‌هایی که به‌صورت locally انجام داده‌اید را به بالای تاریخچه اعمال می‌کند، بدون اینکه کامیت merge ایجاد کند (در صورتی که تعارضی وجود نداشته باشد). نتیجه آن یک تاریخچه تمیز و مرتب خواهد بود. [توضیحات بیشتر ...](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) +> قبل از ارسال Pull Request، برنچ `develop` یا `master` محلی خود را به‌روزرسانی کرده و Rebase تعاملی انجام دهید. Rebase تغییرات محلی شما را به بالای تاریخچه انتقال می‌دهد و از ایجاد Commitهای غیرضروری جلوگیری می‌کند. این کار باعث تمیز و مرتب شدن تاریخچه Commitها می‌شود. ([توضیحات بیشتر ...](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)) -- تعارضات احتمالی را در حین rebase و قبل از ایجاد درخواست Pull Request برطرف کنید. -- برنچ‌های feature ایجاد شده در local و remote را پس از ادغام حذف کنید. +- تعارضات احتمالی را در حین `rebase` برطرف کنید و سپس Pull Request ایجاد کنید. (این کار به شفافیت و کیفیت کد کمک می‌کند.) +- برنچ‌های `feature` ایجاد شده، پس از اتمام کار و ادغام باید حذف شوند (در `local` و `remote`). _چرا:_ -> لیست برنچ‌های شما را با برنچ‌های بی‌استفاده درهم می‌آمیزد (شلوغ می‌کند). حذف برنچ‌های feature باعث می‌شود که هر برنچ تنها یک‌بار به برنچ اصلی (`master` یا `develop`) ادغام شود. برنچ‌های feature باید فقط تا زمانی که کار هنوز در حال انجام است وجود داشته باشند. +> حذف برنچ‌های ادغام شده باعث می‌شود لیست برنچ‌ها شلوغ نشود و هر برنچ تنها یک بار به برنچ اصلی (`master` یا `develop`) ادغام شود. برنچ‌های `feature` فقط باید تا زمانی که کار هنوز در حال انجام است، وجود داشته باشند. -- قبل از ایجاد درخواست Pull Request، مطمئن شوید که برنچ feature شما با موفقیت build می‌شود و همه testها (شامل بررسی‌های سبک/استایل کد) با موفقیت انجام می‌شود. +- قبل از ایجاد Pull Request، مطمئن شوید که برنچ `feature` شما به درستی `build` می‌شود و تمامی تست‌ها (از جمله بررسی سبک و استایل کدنویسی) موفقیت‌آمیز هستند. _چرا:_ -> شما قصد دارید که کد خود را به یک برنچ stable اضافه کنید. اگر testهای برنچ feature شما ناموفق باشند، احتمال زیادی وجود دارد که build برنچ مقصد نیز شکست بخورد. علاوه بر این، قبل از ایجاد درخواست Pull Request، نیاز است که بررسی سبک و استایل کد را انجام شود. این کار باعث بهبود خوانایی کد می‌شود و احتمال ترکیب شدن تغییرات قالب‌بندی با تغییرات واقعی را کاهش می‌دهد. +> زمانی‌که شما تصمیم دارید کد خود را به یک برنچ stable اضافه کنید، اگر تست‌های برنچ `feature` محلی/local ناموفق باشند، احتمال زیادی وجود دارد که `build` برنچ مقصد نیز با خطا مواجه شود. علاوه بر این، قبل از ایجاد درخواست Pull Request، ضروری است که بررسی سبک و استایل کدنویسی انجام گردد. زیرا این کار باعث بهبود خوانایی و استانداردسازی کد می‌شود و از شکست احتمالی `build` برنچ مقصد جلوگیری می‌کند. - [از فایل](./.gitignore) `.gitignore` استفاده کنید. _چرا:_ -> این فایل از قبل دارای لیستی از فایل‌های سیستمی است که نباید همراه با کد شما به مخزن remote ارسال شوند. علاوه بر این، پوشه‌ها و فایل‌های تنظیمات برای بیشتر ویرایشگرهای مورد استفاده و همچنین پوشه‌های dependency رایج را نیز مستثنی می‌کند. +> فایل `.gitignore` فایل‌ها و دایرکتوری‌هایی که نباید به مخزن `remote` ارسال شوند (مانند فایل‌های سیستمی و تنظیمات ویرایشگرها) را مستثنی می‌کند. این کار از ارسال فایل‌های غیرضروری جلوگیری می‌کند. - از برنچ‌های `develop` و `master` محافظت کنید. _چرا:_ -> این کار از برنچ‌های آماده برای production در برابر دریافت تغییرات غیرمنتظره و غیرقابل بازگشت محافظت می‌کند. توضیحات بیشتر ... [GitHub](https://help.github.com/articles/about-protected-branches/), [Bitbucket](https://confluence.atlassian.com/bitbucketserver/using-branch-permissions-776639807.html) and [GitLab](https://docs.gitlab.com/ee/user/project/protected_branches.html) +> این کار از برنچ‌های آماده برای production در برابر دریافت تغییرات غیرمنتظره و غیرقابل بازگشت محافظت می‌کند. توضیحات بیشتر را برای [GitHub](https://help.github.com/articles/about-protected-branches/), [Bitbucket](https://confluence.atlassian.com/bitbucketserver/using-branch-permissions-776639807.html) و [GitLab](https://docs.gitlab.com/ee/user/project/protected_branches.html) بخوانید. -### 1.2 گردش‌کار گیت/Git workflow +### 1.2 گردش کار گیت (Git Workflow) -به خاطر دلایل ذکرشده در بالا، ما از [Feature-branch-workflow](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow) همراه با [Interactive Rebasing](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) و برخی عناصر [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows#gitflow-workflow) (نام‌گذاری و داشتن یک develop branch). استفاده می‌کنیم. مراحل اصلی به شرح زیر هستند: +با توجه به دلایل اشاره‌شده، ما از روش [Feature Branch Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow) به همراه [Interactive Rebasing](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) و برخی عناصر [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows#gitflow-workflow) (مانند نام‌گذاری شاخه‌ها و استفاده از برنچ `develop`) بهره می‌بریم. مراحل کلی آن به‌صورت زیر است: -- برای یک پروژه جدید، یک مخزن گیت (Git repository) را در پوشه پروژه مقداردهی اولیه کنید. **برای ویژگی‌ها/تغییرات بعدی، این مرحله باید نادیده گرفته شود.** +- برای یک پروژه جدید، یک مخزن گیت (Git repository) را در پوشه پروژه ایجاد کنید. برای ویژگی‌ها یا تغییرات بعدی، دیگر نیازی به انجام این مرحله نیست. ```sh cd git init ``` -- یک شاخه جدید برای توسعه یک feature یا رفع یک bug ایجاد کنید و به آن منتقل شوید. +- یک شاخه جدید برای توسعه یک `feature` یا رفع یک `bug` ایجاد کنید و به آن سوئیچ کنید. ```sh git checkout -b ``` -- تغییری در آن ایجاد کنید. +- اعمال تغییرات در فایل‌ها و ثبت آن‌ها ```sh git add ... @@ -134,17 +134,17 @@ git commit _چرا:_ -> کامند `git add ... ` - شما باید فقط فایل‌هایی را اضافه کنید که یک تغییر کوچک و منسجم را تشکیل می‌دهند. +> با دستور `git add ...` باید تنها فایل‌هایی را اضافه کنید که یک تغییر کوچک و منسجمی را تشکیل می‌دهند. -> کامند `git commit` یک ویرایشگر باز می‌کند که به شما اجازه می‌دهد مقادیر subject را از body در کامیت خود از هم جدا کنید. +> دستور `git commit` یک ویرایشگری را باز می‌کند که در آن می‌توانید متن کامیت خود را با جداسازی بخش موضوع (`subject`) از بدنه (`body`) بنویسید. -> در _بخش 1.3_ بیشتر درباره آن بخوانید. +> در _بخش 1.3_ درباره‌ی آن توضیح بیشتری داده شده است. _نکته:_ -> می‌توانید به جای آن از دستور `git add -p` استفاده کنید که به شما این امکان را می‌دهد تمام تغییرات اعمال‌شده را یک به یک بررسی کنید و تصمیم بگیرید که آیا آنها را در کامیت وارد کنید یا نه. +> می‌توانید به‌جای این دستور، از `git add -p` استفاده کنید تا تغییرات را به صورت مرحله‌به‌مرحله (hunk-by-hunk) بررسی کرده و تصمیم بگیرید کدام بخش در کامیت قرار بگیرد. -- با مخزن remote همگام‌سازی کنید تا تغییراتی که از دست داده‌اید را دریافت کنید. +- برنچ لوکال خود را با مخزن `remote` همگام‌سازی کنید تا تغییرات جدید را دریافت کنید. ```sh git checkout develop @@ -153,9 +153,9 @@ git pull _چرا:_ -> این کار به شما فرصت می‌دهد که با conflictها در سیستم خود در حین rebasing برخورد کنید، به جای اینکه یک درخواست Pull Request ایجاد کنید که حاوی conflictها باشد. +> این کار به شما این فرصت را می‌دهد که با conflictها در سیستم خود در حین rebasing و پیش از ارسال Pull Request مواجه شوید، به جای آنکه یک درخواست Pull Request ایجاد کنید که حاوی conflict و تضاد باشد. -- برنچ feature خود را با استفاده از interactive rebase با آخرین تغییرات از برنچ develop به‌روزرسانی کنید. +- برنچ `feature` خود را با استفاده از interactive rebase با آخرین تغییرات از برنچ `develop`، به‌روزرسانی کنید. ```sh git checkout @@ -164,16 +164,16 @@ git rebase -i --autosquash develop _چرا:_ -> می‌توانید از `--autosquash` استفاده کنید تا تمام کامیت‌های خود را به یک کامیت ترکیب کنید. هیچ‌کس نمی‌خواهد برای یک ویژگی در شاخه develop چندین کامیت داشته باشد. [توضیحات بیشتر ...](https://robots.thoughtbot.com/autosquashing-git-commits) +> با گزینه‌ی `--autosquash` می‌توانید تمام کامیت‌های خود را در برنچ `feature` در یک کامیت ترکیب کنید تا تاریخچه مرتب‌تری داشته باشید. زیرا هیچ‌کس تمایل ندارد برای یک ویژگی، چندین کامیت پراکنده در برنچ `develop` داشته باشد. ([توضیحات بیشتر ...](https://robots.thoughtbot.com/autosquashing-git-commits)) -- اگر conflicts ندارید، این مرحله را رد کنید. در غیراینصورت، [آنها را حل کنید](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/) و rebase را ادامه دهید. +- اگر با conflictای مواجه شدید، [آن را برطرف کنید](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/) و rebase را ادامه دهید، در غیر این صورت، می‌توانید این مرحله را نادیده بگیرید. ```sh git add ... git rebase --continue ``` -- برنچ خود را push کنید. rebase تاریخچه را تغییر می‌دهد، بنابراین باید از `-f` برای اجبار تغییرات به برنچ remote استفاده کنید. اگر شخص دیگری روی برنچ شما کار می‌کند، از گزینه کمتر مخرب `--force-with-lease` استفاده کنید. +- برنچ خود را پس از ری‌بیس `push` کنید. از آنجا که rebase تاریخچه‌ی برنچ را تغییر می‌دهد، Git جلوی Push عادی را می‌گیرد؛ بنابراین باید از `-f` برای اعمال اجباری تغییرات استفاده کنید. اگر افراد دیگری نیز روی برنچ شما کار می‌کنند، بهتر است از گزینه کمتر مخرب `--force-with-lease` استفاده کنید. ```sh git push -f @@ -181,17 +181,17 @@ git push -f _چرا:_ -> وقتی که rebase انجام می‌دهید، تاریخچه برنچ feature خود را تغییر می‌دهید. در نتیجه، گیت `git push` معمولی را رد می‌کند. به جای آن باید از فلگ `-f` یا `--force` استفاده کنید. [توضیحات بیشتر ...](https://developer.atlassian.com/blog/2015/04/force-with-lease/) +> وقتی که rebase انجام می‌دهید، گیت تاریخچه برنچ feature محلی را تغییر می‌دهید. در نتیجه، گیت جلوی Push عادی با استفاده از دستور `git push` را می‌گیرد. بنابراین باید از فلگ `-f` یا `--force` برای اعمال اجباری تغییرات استفاده کنید. ([توضیحات بیشتر ...](https://developer.atlassian.com/blog/2015/04/force-with-lease/)) -- یک درخواست Pull Request ایجاد کنید. -- درخواست Pull Request توسط یک بررسی کننده پذیرفته، ادغام و بسته خواهد شد. -- در صورت اتمام کار، برنچ feature محلی/local خود را حذف کنید. +- پس از Push کردن برنچ، یک Pull Request خود را ایجاد کنید. +- یک نفر از اعضای تیم یا مسئول بررسی کد، درخواست Pull Request را پس از بررسی، پذیرفته و آن را ادغام (Merge) کند، درنتیجه این درخواست بسته خواهد شد. +- در صورت اتمام کار،برنچ `feature` محلی خود را حذف کنید. ```sh git branch -d ``` -تمام برنچ‌های local را که در مخزن remote وجود ندارند را حذف کنید. (این کار باعث می‌شود که برنچ‌های که دیگر وجود ندارند، از مخزن local حذف شوند، در نتیجه محیط توسعه شما تمیز و مرتب‌ باقی می‌ماند.) +جهت حذف تمام برنچ‌های محلی که دیگر در مخزن remote وجود ندارند، از دستور زیر استفاده کنید. (برای تمیز نگه‌داشتن محیط توسعه و حذف برنچ‌های قدیمی) ```sh git fetch -p && for branch in `git branch -vv --no-color | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done @@ -201,233 +201,232 @@ git fetch -p && for branch in `git branch -vv --no-color | grep ': gone]' | awk ### 1.3 نگارش بهتر متن کامیت‌ها -داشتن یک راهنمای مناسب برای ایجاد کامیت‌ها و پایبندی به آن، کار با گیت و همکاری با دیگران را بسیار آسان‌تر می‌کند. در اینجا چند قانون کلی وجود دارد:([منبع](https://chris.beams.io/posts/git-commit/#seven-rules)): +داشتن راهنمای مناسب و پایبندی به آن برای نوشتن پیام‌های کامیت، همکاری با دیگران و نگهداری پروژه را بسیار ساده‌تر می‌کند. در اینجا چند قانون کلی وجود دارد ([منبع](https://chris.beams.io/posts/git-commit/#seven-rules)): -- موضوع (subject) را از بدنه (body) جدا کنید و بین این دو یک خط خالی قرار دهید. +- موضوع (`subject`) را از بدنه (`body`) جدا کنید و بین این دو بخش یک خط خالی بگذارید. _چرا:_ -> گیت به اندازه کافی هوشمند است که خط اول پیام کامیت شما را به‌عنوان خلاصه تشخیص دهد. در واقع، اگر به‌جای استفاده از git log از git shortlog استفاده کنید، یک لیست طولانی از پیام‌های کامیت خواهید دید که شامل شناسه کامیت و تنها خلاصه پیام است. +> گیت به اندازه کافی هوشمند است که خط اول پیام کامیت شما را به‌عنوان خلاصه تشخیص دهد. اگر به‌جای استفاده از `git log` از `git shortlog` استفاده کنید، فقط این خط اول (خلاصه) را به همراه شناسه کامیت خواهید دید. -- طول خط موضوع (subject) را به ۵۰ کاراکتر محدود کنید و بدنه پیام را در ۷۲ کاراکتر بشکنید. +- طول خط موضوع (`subject`) را تا 50 کاراکتر محدود نگه دارید و بدنه‌ی پیام (`body`) را حداکثر در 72 کاراکتر قرار دهید. _چرا:_ -> کامیت‌ها تا حد ممکن باید جزئی و متمرکز باشند؛ نیازی به طولانی‌نویسی در آن‌ها نیست. [توضیحات بیشتر ...](https://medium.com/@preslavrachev/what-s-with-the-50-72-rule-8a906f61f09c) +> این کار باعث می‌شود کامیت‌ها تا حد ممکن متمرکز و خوانا باشند؛ نیازی به طولانی‌نویسی نیست. ([توضیحات بیشتر](https://medium.com/@preslavrachev/what-s-with-the-50-72-rule-8a906f61f09c)) -- حرف اول موضوع (subject) را با عبارت بزرگ (Capitalize) شروع کنید. -- موضوع (subject) را با نقطه تمام نکنید. -- از [وجه امری](https://en.wikipedia.org/wiki/Imperative_mood) در موضوع (subject) استفاده کنید. +- حرف اول موضوع (`subject`) را با عبارت بزرگ (Capitalize) شروع کنید. +- موضوع (`subject`) را با نقطه تمام نکنید. +- از [وجه امری](https://en.wikipedia.org/wiki/Imperative_mood) در موضوع (`subject`) استفاده کنید. _چرا:_ -> به جای نوشتن پیام‌هایی که فقط بیانگر/توصیف‌کننده کاری است که کامیت‌کننده انجام داده، بهتر است این پیام‌ها را به عنوان دستورالعمل‌هایی در نظر بگیرید که بیان می‌کنند پس از اعمال کامیت در مخزن، چه چیزی قرار است انجام شود. (توضیح مترجم: پیام‌های کامیت باید بر نتیجه و هدف تمرکز کنند، نه صرفاً بر عملیات انجام‌شده.) [توضیحات بیشتر ...](https://news.ycombinator.com/item?id=2079612) +> به جای نوشتن پیام‌هایی که فقط بیانگر یا توصیف‌کننده کاری هستند، بهتر است متن کامیت را به عنوان یک دستورالعمل‌ در نظر بگیرید تا مشخص کنند که پس از ادغام کامیت در مخزن، چه کاری قرار است انجام شود. ([توضیحات بیشتر ...](https://news.ycombinator.com/item?id=2079612)) -- از قسمت بدنه (body) برای توضیح **چه کاری** و **چرا** انجام شده، استفاده کنید، نه **چگونگی** انجام آن. +- از قسمت بدنه (`body`) برای توضیح چرایی و چیستی کار انجام‌شده استفاده کنید، نه چگونگی انجام آن. -## 2. مستندات +## 2. مستندات (Documentation)

Documentation

-- از این [قالب](./README.sample.md) برای فایل `README.md` استفاده کنید؛ اگر بخش‌هایی وجود دارد که پوشش داده نشده‌اند، با خیال راحت آن‌ها را اضافه کنید. -- برای پروژه‌هایی که بیش از یک مخزن (repository) دارند، لینک به مخازن دیگر را در فایل‌های `README.md` مربوطه قرار دهید.. -- با پیشرفت پروژه، فایل `README.md` را به‌روز نگه دارید. -- کد خود را کامنت‌گذاری کنید. سعی کنید با هر بخش اصلی کد، به‌وضوح توضیح دهید که قصد دارید چه کاری انجام دهید. -- اگر درباره کد یا روش مورد استفاده شما در گیت‌هاب یا استک‌اورفلو بحثی باز وجود دارد، لینک آن را در کامنت خود بگنجانید. -- از کامنت‌ها به‌عنوان توجیهی برای کد ضعیف استفاده نکنید. کد خود را تمیز نگه دارید. -- از کد تمیز به‌عنوان بهانه‌ای برای عدم کامنت‌گذاری استفاده نکنید. -- با پیشرفت کد، کامنت‌ها را نیز متناسب به‌روز نگه دارید. +- از این [ساختار](./README.sample.md) برای فایل `README.md` پروژه خود استفاده کنید؛ اگر بخش‌هایی وجود دارد که پوشش داده نشده است، می‌توانید آن‌ها را به‌دلخواه اضافه کنید. +- اگر پروژه‌تان چندین مخزن (repository) دارد، لینک هر مخزن را در فایل‌های `README.md` مربوطه درج کنید. +- با پیشرفت پروژه، فایل `README.md` را به‌روز نگه دارید تا همیشه منعکس‌کننده آخرین وضعیت باشد. +- برای درک بهتر بخش‌های اصلی کد، کد خود را کامنت‌گذاری کنید، همچنین سعی کنید که به‌وضوح توضیح دهید که قصد انجام چه کاری را دارید. +- اگر درباره کد یا روش مورد استفاده شما در گیت‌هاب یا استک‌اورفلو بحثی باز وجود دارد، لینک آن را در کامنت خود بگنجانید، تا سایر توسعه‌دهندگان بتوانند به بحث ایجاد شده دسترسی داشته باشند. +- کامنت‌ها نباید توجیهی برای کد ضعیف باشند. کد خود را تا حد امکان تمیز بنویسید. +- در عین حال از ارائه توضیحات تکمیلی در قالب کامنت، به این بهانه که کد تمیز می‌باشد، غافل نشوید. +- با پیشرفت کد، کامنت‌ها را هم به‌روز کنید تا با وضعیت فعلی پروژه همخوانی داشته باشند. -## 3. متغیرهای محیطی/Environments +## 3. متغیرهای محیطی (Environments)

Environments

-- در صورت نیاز، environmentهای جداگانه‌ای برای `development`، `test` و `production` تعریف کنید. +- در صورت نیاز، برای مراحل مختلف پروژه مانند `development`، `test` و `production،` محیط‌های جداگانه تعریف کنید. _چرا:_ -> در محیط‌ها (environments) مختلف ممکن است data، tokens، APIs، ports و... متفاوتی نیاز باشند. ممکن است بخواهید یک حالت `development` ایزوله داشته باشید که به APIهای جعلی متصل می‌شود و داده‌های قابل پیش‌بینی برمی‌گرداند، که این کار هم تست‌های خودکار و هم تست‌های دستی را بسیار ساده‌تر می‌کند. یا شاید بخواهید Google Analytics را فقط در محیط `production` فعال کنید و به همین ترتیب. -> [توضیحات بیشتر ...](https://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth) +> هر محیط‌ (environment) مختلف ممکن است data، tokens، APIs، ports و... متفاوتی نیاز داشته باشند. به‌عنوان مثال، می‌توانید در حالت `development` از APIهای جعلی با داده‌های قابل پیش‌بینی استفاده کنید تا تست‌های دستی و خودکار ساده‌تر شوند. یا شاید بخواهید Google Analytics را فقط در محیط `production` فعال کنید و به همین ترتیب. ([توضیحات بیشتر ...](https://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth)) -- پیکربندی‌های مختص هر محیط اجرایی را از متغیرهای محیطی (environment variables) بارگذاری کنید و هرگز آن‌ها را به‌عنوان مقادیر ثابت در کد قرار ندهید. [به این نمونه نگاه کنید](./config.sample.js). +- پیکربندی‌های مختص هر محیط را به عنوان مقادیر ثابت در کد قرار ندهید، بلکه از متغیرهای محیطی (environment variables) برای جدا کردن پیکربندی هر محیط استفاده کنید ([به این نمونه نگاه کنید](./config.sample.js)). _چرا:_ -> در این فایل‌ها ممکن است tokens، passwords و دیگر اطلاعات ارزشمند وجود داشته باشند. پیکربندی/کانفیگ شما باید به‌درستی از بخش‌های داخلی برنامه جدا باشد، به گونه‌ای که کد در هر لحظه ممکن است عمومی شود. +> متغیرهای محیطی ممکن است شامل توکن‌ها، رمزعبورها و سایر اطلاعات حساس باشند. قرار دادن این اطلاعات در کد باعث می‌شود در صورت عمومی شدن کد، این اطلاعات نیز فاش شوند. _چگونه:_ -> فایل‌های `.env` را برای ذخیره متغیرهای خود استفاده کنید و آن‌ها را به `.gitignore` اضافه کنید تا از مخزن مستثنی شوند. در عوض، یک فایل `.env.example` کامیت کنید که به‌عنوان راهنما برای توسعه‌دهندگان عمل کند. برای محیط production، باید همچنان متغیرهای محیطی را به روش استاندارد تنظیم کنید. [بیشتر بخوانید](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f) +> از فایل‌های `.env` برای ذخیره متغیرهای محیطی استفاده کنید و آن‌ها را در فایل `.gitignore` قرار دهید تا به مخزن remote ارسال نشوند. در عوض، یک فایل `.env.example` را کامیت کنید تا توسعه‌دهندگان دیگر از آن به‌عنوان راهنما استفاده کنند. برای محیط `production` همچنان به شیوه استاندارد متغیرهای محیطی را تنظیم کنید. ([توضیحات بیشتر](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f)) -- توصیه می‌شود قبل از شروع برنامه، متغیرهای محیطی را اعتبارسنجی کنید. [این نمونه را مشاهده کنید](./configWithTest.sample.js) که از `joi` برای اعتبارسنجی مقادیر ارائه‌شده استفاده می‌کند. +- پیش از اجرای برنامه، متغیرهای محیطی را (مثلاً با استفاده از کتابخانه‌ای مانند `joi`) اعتبارسنجی کنید تا خطاهای احتمالی زودتر شناسایی شوند. ([نمونه](./configWithTest.sample.js)) _چرا:_ -> این کار می‌تواند دیگران را از ساعت‌ها مشکل‌یابی/troubleshooting نجات دهد. +> این کار باعث می‌شود خطاهای احتمالی را زودتر شناسایی کنید و از هدررفتن ساعت‌ها مشکل‌یابی/troubleshooting توسط دیگران جلوگیری می‌کند. > -### 3.1 ایجاد محیط‌های توسعه‌ی یکپارچه/Consistent dev environments: +### 3.1 ایجاد محیط‌های توسعه‌ی یکپارچه (Consistent Dev Environments): -- نسخه‌ی Node خود را در بخش `engines` در فایل `package.json` تنظیم کنید.. +- نسخه‌ی Node را در بخش `engines` در فایل `package.json` وارد کنید. _چرا:_ -> این کار به دیگران اطلاع می‌دهد که پروژه با کدام نسخه‌ی Node کار می‌کند. [توضیحات بیشتر ...](https://docs.npmjs.com/files/package.json#engines) +> در بخش `engines`، نسخه‌ی Node را مشخص کنید تا سایر توسعه‌دهندگان بدانند پروژه با کدام نسخه کار می‌کند. ([توضیحات بیشتر ...](https://docs.npmjs.com/files/package.json#engines)) -- همچنین از `nvm` استفاده کنید و یک فایل `.nvmrc` در ریشه‌ی پروژه‌ی خود ایجاد کنید. فراموش نکنید که به آن در مستندات اشاره کنید. +- علاوه‌براین، از `nvm` استفاده کنید و یک فایل `.nvmrc` در ریشه‌ی پروژه ایجاد کنید و در مستندات به آن اشاره کنید. _چرا:_ -> هر کسی که از `nvm` استفاده می‌کند، می‌تواند به سادگی با اجرای کامند `nvm use` به نسخه‌ی مناسب Node سوئیچ کند. [توضیحات بیشتر ...](https://github.com/creationix/nvm) +> تا هر کسی که از `nvm` استفاده می‌کند، بتواند به سادگی با اجرای `nvm use` بتواند به نسخه‌ی مناسب Node سوئیچ کند. ([توضیحات بیشتر ...](https://github.com/creationix/nvm)) -- تنظیم یک اسکریپت `preinstall` که نسخه‌های Node و npm را بررسی کند، ایده‌ی خوبی است. +- می‌توانید یک اسکریپت `preinstall` تنظیم کنید تا نسخه‌های Node و npm را بررسی کند. _چرا:_ -> برخی وابستگی‌ها/dependencies ممکن است در صورت نصب توسط نسخه‌های جدیدتر npm با خطا مواجه شوند. +> زیرا برخی وابستگی‌ها (dependencies) ممکن است در صورت نصب توسط نسخه‌های جدیدتر npm دچار خطا شوند. - در صورت امکان از Docker استفاده کنید. _چرا:_ -> این کار می‌تواند یک محیط سازگار در کل فرآیند کاری شما فراهم کند، بدون نیاز به تنظیمات یا وابستگی‌های پیچیده. [توضیحات بیشتر ...](https://hackernoon.com/how-to-dockerize-a-node-js-application-4fbab45a0c19) +> این کار می‌تواند یک محیط سازگار در کل فرآیند کاری شما فراهم کند، بدون نیاز به تنظیمات یا وابستگی‌های پیچیده. ([توضیحات بیشتر …](https://hackernoon.com/how-to-dockerize-a-node-js-application-4fbab45a0c19)) -- از پکیج‌های محلی/local به‌جای پکیج‌های نصب‌شده به‌صورت گلوبالی/globally استفاده کنید. +- از پکیج‌های محلی (local) به‌جای پکیج‌های سراسری (globally) استفاده کنید. _چرا:_ -> این کار به شما اجازه می‌دهد پکیج‌های خود را با همکارانتان به اشتراک بگذارید، به جای اینکه انتظار داشته باشید آن‌ها را به‌صورت گلوبالی روی سیستم خود نصب کرده باشند. +> این کار به شما اجازه می‌دهد پکیج‌های استفاده شده را با همکارانتان به اشتراک بگذارید، به جای آنکه انتظار داشته باشید آن‌ها به‌صورت سراسری روی سیستم خود نصب کرده باشند. -### 3.2 وابستگی‌های یکسان و هماهنگ/Consistent dependencies: +### 3.2 وابستگی‌های یکسان و هماهنگ (Consistent Dependencies): - اطمینان حاصل کنید که اعضای تیم دقیقاً همان وابستگی‌ها (dependencies) را مانند شما دریافت کنند. _چرا:_ -> زیرا می‌خواهید که کد، در هر محیط توسعه‌ای به همان شکل مورد انتظار عمل کند و یکسان باشد. [توضیحات بیشتر ...](https://kostasbariotis.com/consistent-dependencies-across-teams/) +> برای اطمینان از این‌که پروژه در هر محیطی یکسان اجرا می‌شود و خطاهای پیش‌بینی‌نشده رخ ندهد. ([توضیحات بیشتر ...](https://kostasbariotis.com/consistent-dependencies-across-teams/)) _چگونه:_ -> از `package-lock.json` در نسخه 5 از `npm` یا بالاتر، استفاده کنید. +> در نسخه‌های 5 یا بالاتر `npm`، از فایل `package-lock.json` استفاده کنید. -_من npm@5 ندارم:_ +_اگر از `npm` قدیمی‌تر از نسخه 5 استفاده می‌کنید:_ -> در این صورت می‌توانید از `Yarn` استفاده کنید و اطمینان حاصل کنید که این موضوع را در فایل `README.md`. پس از هر به‌روزرسانی وابستگی‌ها، lock file و `package.json` باید نسخه‌های یکسانی داشته باشند. [توضیحات بیشتر ...](https://yarnpkg.com/en/) +> می‌توانید از `Yarn` بهره ببرید، مطمئن شوید در فایل `README.md` به این موضوع اشاره شده است. پس از هر به‌روزرسانی وابستگی‌ها، فایل lock file و فایل `package.json` باید با یکدیگر همخوانی داشته باشند. ([توضیحات بیشتر ...](https://yarnpkg.com/en/)) -_من اسم `Yarn` را دوست ندارم:_ +_اگر `Yarn` را نمی‌پسندید:_ -> متأسفانه انتخاب دیگری ندارید. برای نسخه‌های قدیمی‌تر `npm`, هنگام نصب وابستگی جدید از `—save --save-exact` استفاده کنید و قبل از انتشار پروژه، فایل `npm-shrinkwrap.json` ایجاد کنید. [توضیحات بیشتر ...](https://docs.npmjs.com/files/package-locks) +> متأسفانه راه دیگری ندارید. در نسخه‌های قدیمی `npm`، هنگام نصب وابستگی جدید از `--save --save-exact` استفاده کنید و قبل از انتشار، فایل `npm-shrinkwrap.json` را بسازید. ([توضیحات بیشتر ...](https://docs.npmjs.com/files/package-locks)) -## 4. وابستگی‌ها/Dependencies +## 4. وابستگی‌ها (Dependencies)

modules

-- بر روی پکیج‌های فعلی خود را که در حال حاضر در دسترس هستند، پیگیری و نظارت کنید: به عنوان مثال، از دستور `npm ls --depth=0` استفاده کنید. (توضیحات مترجم: با استفاده از دستور `npm ls --depth=0` در محیط خط فرمان، می‌توانید فهرستی از پکیج‌های سطح اول (بدون نمایش وابستگی‌های زیرمجموعه‌ای) را مشاهده کنید. این کار به شما کمک می‌کند تا بدانید چه بسته‌هایی در حال حاضر در پروژه‌تان نصب هستند و از وضعیت آن‌ها مطلع باشید.) [توضیحات بیشتر ...](https://docs.npmjs.com/cli/ls) -- بررسی کنید آیا هیچ‌یک از پکیج‌های شما بی‌استفاده یا نامربوط (غیرضروری یا غیرکاربردی) شده‌اند: با استفاده از ابزار `depcheck` [توضیحات بیشتر ...](https://www.npmjs.com/package/depcheck) +- پکیچ‌های نصب‌شده را ردیابی و نظارت کنید: به عنوان مثال، با اجرای دستور `npm ls --depth=0`، می‌توانید فهرست پکیج‌های سطح اول پروژه‌تان را مشاهده کنید و از وضعیت آن‌ها مطلع شوید. (این کار کمک می‌کند بدانید چه کتابخانه‌هایی در حال حاضر در پروژه نصب هستند و آیا همه آن‌ها مورد استفاده قرار می‌گیرند یا خیر.) ([توضیحات بیشتر ...](https://docs.npmjs.com/cli/ls)) +- پکیج‌های بی‌استفاده یا نامربوط را با استفاده از ابزار depcheck شناسایی کنید. ([توضیحات بیشتر ...](https://www.npmjs.com/package/depcheck)) _چرا:_ -> ممکن است یک کتابخانه بی‌استفاده را در کد خود داشته باشید که باعث افزایش حجم نهایی برنامه شود. وابستگی‌های بی‌استفاده را پیدا کرده و حذف کنید. +> با استفاده از ابزار `depcheck` می‌توانید کتابخانه‌های غیرضروری را که تنها باعث افزایش حجم پروژه شده‌اند را بیابید و حذف کنید. -- قبل از استفاده از یک وابستگی، آمار دانلود آن را بررسی کنید تا ببینید آیا توسط جامعه به‌طور گسترده‌ای استفاده می‌شود یا خیر: با استفاده از ابزار `npm-stat`. [توضیحات بیشتر ...](https://npm-stat.com/) +- قبل از استفاده از یک پکیچ، با بهره‌گیری از `npm-stat` می‌توانید میزان دانلود و محبوبیت یک پکیج را در جامعه برنامه‌نویسان بسنجید. ([توضیحات بیشتر ...](https://npm-stat.com/)) _چرا:_ -> استفاده بیشتر (از پکیج‌ها) معمولاً به معنای داشتن تعداد بیشتری از مشارکت‌کنندگان است که اغلب منجر به نگهداری بهتر می‌شود و همه این‌ها باعث می‌شود که باگ‌ها سریع‌تر کشف و اصلاحات سریع‌تر توسعه داده شوند. +> هرچه جامعه استفاده‌کنندگان بزرگ‌تر باشد، احتمال نگهداری بهتر و کشف سریع‌تر باگ‌ها بیشتر خواهد بود. -- پیش از استفاده از یک وابستگی، بررسی کنید که آیا آن وابستگی نسخه‌های منظم و پایداری ارائه می‌دهد و تعداد زیادی نگهدارندگان (maintainers) دارد یا نه. به عنوان مثال، می‌توانید از دستور `npm view async` استفاده کنید. [توضیحات بیشتر ...](https://docs.npmjs.com/cli/view) +- پیش از افزودن یک وابستگی جدید، نسخه‌های منظم و فعال بودن تیم نگهدارنده (maintainers) را بررسی و ارزیابی کنید. به عنوان مثال، می‌توانید از دستور `npm view async` کمک بگیرید. ([توضیحات بیشتر ...](https://docs.npmjs.com/cli/view)) _چرا:_ -> داشتن تعداد زیادی از مشارکت‌کنندگان زمانی مؤثر است که نگهدارندگان بتوانند اصلاحات و تغییرات را به سرعت merge کنند. +> اگرچه تعداد بالا و فعالیت مداوم نگهدارندگان، می‌تواند روند رفع باگ‌ها و توسعه را تسهیل بکند، اما اگر مشارکت‌کنندگان نتوانند اصلاحات (`fixes`) و وصله‌ها (`patches`) را با سرعت کافی ادغام (`merge`) کنند، داشتن مشارکت‌کننده‌ی زیاد چندان مؤثر نخواهد بود. -- اگر به وابستگی کمتر شناخته شده‌ای (غیرمشهور) نیاز دارید، قبل از استفاده از آن، با تیم خود مشورت کنید. -- همیشه مطمئن شوید که برنامه شما با آخرین نسخه از وابستگی‌هایش بدون هیچگونه مشکلی/خرابی کار می‌کند: از دستور `npm outdated` استفاده کنید. [توضیحات بیشتر ...](https://docs.npmjs.com/cli/outdated) +- اگر قصد دارید از کتابخانه‌ای کمتر شناخته‌شده (غیرمشهور) استفاده کنید، ابتدا با اعضای تیم خود مشورت نمایید. +- همیشه از به‌روزبودن وابستگی‌ها با آخرین نسخه، اطمینان حاصل کنید. می‌توانید با اجرای دستور `npm outdated` وضعیت نسخه‌های فعلی پکیج‌ها را بررسی کنید. ([توضیحات بیشتر ...](https://docs.npmjs.com/cli/outdated)) _چرا:_ -> بروزرسانی‌ وابستگی‌ها (dependencies) گاهی شامل تغییرات مخرب می‌شوند. هر زمان که بروزرسانی‌ها نمایش داده می‌شوند، حتماً release note ها را بررسی کنید. وابستگی‌های (dependencies) خود را یکی‌یکی بروزرسانی کنید، زیرا اگر مشکلی پیش بیاید، عیب‌یابی آن آسان‌تر خواهد بود. از ابزارهای کاربردی مانند موارد زیر استفاده کنید: [npm-check-updates](https://github.com/tjunnone/npm-check-updates). +> پیش از بروزرسانی، حتماً Release Notes را مطالعه کرده و اگر تغییرات مخربی وجود دارد، آن‌ها را به‌صورت مرحله‌به‌مرحله اعمال کنید تا در صورت بروز مشکل، عیب‌یابی آسان‌تر باشد. ابزاری مانند [npm-check-updates](https://github.com/tjunnone/npm-check-updates) نیز در این زمینه مفید است. -- بررسی کنید که آیا بسته موردنظر مشکلات امنیتی شناخته‌شده‌ای دارد یا خیر؛ به عنوان مثال، با استفاده از [Snyk](https://snyk.io/test?utm_source=risingstack_blog). +- همواره پیش از اضافه کردن یا بروزرسانی یک پکیج، مشکلات امنیتی احتمالی آن را بررسی کنید. برای نمونه، [Snyk](https://snyk.io/test?utm_source=risingstack_blog) به شما گزارش‌های امنیتی مربوط به پکیج موردنظر را ارائه می‌دهد. -## 5. تست کردن/Testing +## 5. تست کردن (Testing)

testing

-- در صورت نیاز، یک environment به نام `test` (برای حالت تست) ایجاد کنید. +- در صورت نیاز، یک محیط تست (test environment) ایجاد کنید. _چرا:_ -> گاهی تست end to end در حالت `production` ممکن است کافی به نظر برسد، اما در موارد خاص نیاز به محیط تست جداگانه‌ای وجود دارد. مثلاً ممکن است نخواهید اطلاعات تحلیلی در حالت `production` فعال شود و داشبورد افراد را با داده‌های تست آلوده کنید. (توضیحات مترجم: چون داده‌های تستی ممکن است اطلاعات واقعی را تحت تأثیر قرار دهد، مثلا باعث شلوغی و ایجاد داده‌های غیرضروری شوند و یا مانع از درک دقیق اطلاعات واقعی توسط کاربران یا تیم تحلیل شوند.) مثال دیگر این است که ممکن است API شما در حالت تولید محدودیت‌ تعداد درخواست (rate limit) داشته باشد و پس از تعداد مشخصی درخواست، فراخوانی APIها توسط تست را مسدود کند. +> در برخی پروژه‌ها، تست End-to-End در محیط `production` ممکن است کافی به نظر برسد، اما مواقعی پیش می‌آید که یک محیط تست جداگانه ضروری است. به‌عنوان مثال، ممکن است مایل نباشید در حالت `production` داده‌های آزمایشی ایجاد کنید یا اطلاعات تحلیلی کاربران را تحت تأثیر قرار دهید. همچنین ممکن است API شما در حالت `production` دارای محدودیت تعداد درخواست (rate limit) باشد که اجرای تست‌ها را در آن دشوار کند. -- فایل‌های تست خود را در کنار ماژول‌های مورد آزمایش با استفاده از الگوی نام‌گذاری خاصی `*.test.js` یا `*.spec.js` قرار دهید، مانند `moduleName.spec.js`. +- فایل‌های تست را در کنار فایل اصلی قرار دهید. با استفاده از الگوی نام‌گذاری خاصی مانند `*.test.js` یا `*.spec.js`، مانند `moduleName.spec.js`. _چرا:_ -> برای پیدا کردن یک تست واحد، در ساختار پوشه‌ها جستجو و پیمایش نکنید. [توضیحات بیشتر ...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc) +> تا به‌راحتی قابل یافتن باشند و نیاز به جستجو و پیمایش در ساختار پروژه نباشد. ([توضیحات بیشتر ...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)) -- برای جلوگیری از سردرگمی، فایل‌های تست اضافی خود را پر یک پوشه جداگانه قرار دهید. +- ممکن است برخی از تست‌ها به فایل‌های پیاده‌سازی خاصی مربوط نباشد، دراین‌صورت آن‌ها را در یک دایرکتوری مجزا قرار دهید. _چرا:_ -> برخی از فایل‌های تست مستقیماً به فایل پیاده‌سازی خاصی مرتبط نیستند. باید این فایل‌ها را در پوشه‌ای قرار دهید که احتمالاً توسط سایر توسعه‌دهندگان به راحتی یافت شود: پوشه `__test__`. این نام `__test__` هم اکنون یک استاندارد است و توسط اکثر فریم‌ورک‌های تست جاوااسکریپت تشخیص داده می‌شود. +> ممکن است برخی از تست‌ها به فایل‌های پیاده‌سازی خاصی مربوط نباشد، دراین‌صورت آن‌ها را در یک دایرکتوری مجزا مانند `__test__` قرار دهید. این نام‌گذاری `__test__` هم اکنون یک استاندارد است و در اکثر فریم‌ورک‌های تست جاوااسکریپت نیز شناخته شده می‌باشند. -- کد قابل تست بنویسید، از اثرات جانبی (side effect) خودداری کنید، اثرات جانبی را جدا کنید، و توابع خالص (pure functions) بنویسید. +- کدهایی بنویسید که منطقی واضح داشته باشند و بتوان آن‌ها را مستقل از هر عامل خارجی (side effect) آزمایش کرد و نتیجه یکسان بدهد (pure functions). _چرا:_ -> هر بخش از منطق کسب‌وکار (business logic) باید به صورت مستقل و جداگانه مورد آزمایش و تست قرار گیرد تا مطمئن شوید که هر قسمت به درستی کار می‌کند. باید "تأثیر عوامل تصادفی یا فرآیندهای غیرقابل‌پیش‌بینی را در کد به حداقل برسانید" [توضیحات بیشتر ...](https://medium.com/javascript-scene/tdd-the-rite-way-53c9b46f45e3) +> هر بخش از منطق کسب‌وکار (business logic) باید به صورت مستقل و جداگانه مورد آزمایش و تست قرار گیرد تا مطمئن شوید که آن بخش‌ها به درستی کار می‌کند. باید "تأثیر عوامل تصادفی یا فرآیندهای غیرقابل‌پیش‌بینی را در کد به حداقل برسانید" [توضیحات بیشتر ...](https://medium.com/javascript-scene/tdd-the-rite-way-53c9b46f45e3) -> یک تابع خالص (pure function) تابعی است که همیشه برای ورودی یکسان، خروجی یکسانی را باز می‌گرداند. برعکس، یک تابع ناخالص (impure function) تابعی است که ممکن است اثرات جانبی داشته باشد یا برای تولید یک مقدار به شرایط خارجی وابسته باشد، که این امر باعث می‌شود کمتر قابل پیش‌بینی باشد. [توضیحات بیشتر ...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc) +> یک تابع خالص (pure function) تابعی است که همیشه برای ورودی یکسان، خروجی یکسانی را باز می‌گرداند. برعکس، یک تابع ناخالص (impure function) تابعی است که ممکن است اثرات جانبی داشته باشد یا برای تولید یک مقدار به شرایط خارجی وابسته باشد، که این امر باعث می‌شود کمتر قابل پیش‌بینی باشد. [توضیحات بیشتر ...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc) -- از یک static type checker استفاده کنید +- از یک Static Type Checker استفاده کنید _چرا:_ -> گاهی ممکن است به یک Static type checker نیاز داشته باشید. این ابزارها، سطحی از قابلیت اطمینان را برای کد شما به ارمغان می‌آورند. [توضیحات بیشتر ...](https://medium.freecodecamp.org/why-use-static-types-in-javascript-part-1-8382da1e0adb) +> ابزارهایی مانند Flow یا TypeScript می‌توانند با بررسی نوع (Type) متغیرها و توابع، سطح اطمینان کد را بالا ببرند و از بروز خطاهای پیش‌بینی‌نشده جلوگیری کنند. ([توضیحات بیشتر ...](https://medium.freecodecamp.org/why-use-static-types-in-javascript-part-1-8382da1e0adb)) -- قبل از آنکه درخواست pull request به برنچ `develop` را ارسال کنید، تست‌ها را به‌صورت locally اجرا کنید. +- پیش از آنکه درخواست pull request به برنچ `develop` ارسال کنید، تست‌ها را به‌صورت locally اجرا کنید. _چرا:_ -> قطعاً نمی‌خواهید کسی باشید که باعث شکست فرایند بیلد برنچ آماده‌ی production شده است. تست‌های خود را پس از `rebase` و پیش از ارسال به شاخه feature-branch به مخزن ریموت اجرا کنید. +> همیشه پیش از ارسال Pull Request، تست‌ها را در سیستم محلی (local) خود اجرا کنید و مطمئن شوید که هیچ موردی باعث شکست فرآیند Build در برنچ `develop` یا `production` نمی‌شود. -- تست‌های خود را از جمله دستورالعمل‌های مربوطه در بخش مناسب فایل `README.md` پروژه را مستندسازی کنید. +- در فایل `README.md` (یا هر مستند دیگری که پروژه استفاده می‌کند)، نحوه اجرای تست‌ها و نیازمندی‌های مرتبط را توضیح دهید. _چرا:_ -> این مستندات مانند یک یادداشت راهنما است که برای توسعه‌دهندگان دیگر، کارشناسان DevOps، یا تیم تضمین کیفیت (QA) و هر کسی که با کد شما کار می‌کند، مفید خواهد بود. +> این مستندات مانند یک یادداشت راهنما است که برای سایر اعضای تیم، کارشناسان DevOps، یا تیم تضمین کیفیت (QA) و هر کسی که با کد شما کار می‌کند، مفید خواهد بود. -## 6. ساختار و نام‌گذاری/Structure and Naming +## 6. ساختار و نام‌گذاری (Structure and Naming)

Structure and Naming

-- فایل‌های خود را بر اساس ویژگی‌های محصول / صفحات / کامپوننت‌ها سازمان‌دهی کنید، نه بر اساس نقش‌ها. همچنین فایل‌های تست را در کنار آن‌ها قرار دهید. +- از سازمان‌دهی فایل‌ها بر اساس نقش (مانند قرار دادن همه فایل‌های `controllers` در یک پوشه و تمام فایل‌های `models` در پوشه‌ای دیگر) خودداری کنید. همچنین فایل‌های تست همان بخش را هم در همان پوشه بگذارید. -**بد** +**ساختار نامطلوب** ``` . @@ -439,7 +438,7 @@ _چرا:_ | └── user.js ``` -**خوب** +**ساختار مطلوب** ``` . @@ -455,37 +454,35 @@ _چرا:_ _چرا:_ -> به جای داشتن لیست طولانی از فایل‌ها، ماژول‌های کوچک ایجاد کنید که هر کدام یک مسئولیت خاص را دربرمی‌گیرند، از جمله تست آن‌ها و موارد دیگر. این کار باعث می‌شود دسترسی به فایل‌ها ساده‌تر شده و بتوانید به سرعت و با یک نگاه فایل‌های مورد نظر را پیدا کنید. +> به جای داشتن یک لیست طولانی از فایل‌ها، با داشتن ماژول‌های کوچک با مسئولیت‌های مشخص و خاص، می‌توانید دسترسی به فایل‌ها را ساده‌تر کرده و زمان جستجو را برای پیدا کردن یک فایل کاهش دهید. -- فایل‌های تست اضافی خود را در یک پوشه‌ی جداگانه به نام test قرار دهید تا از سردرگمی جلوگیری شود. +- اگر تستی وجود دارد که به یک فایل خاص مرتبط نیست، آن را در پوشه‌ای با نام‌های متداولی مانند `test` یا `__test__` قرار دهید. _چرا:_ -> این کار برای سایر توسعه‌دهندگان یا کارشناسان DevOps تیم شما موجب صرفه‌جویی در زمان می‌شود. +> این کار از سردرگمی جلوگیری کرده و باعث می‌شود سایر هم‌تیمی‌ها یا کارشناسان DevOps راحت‌تر بتوانند فایل‌های تست را پیدا کرده و نیز موجب صرفه‌جویی در زمان می‌شود. -- از یک پوشه به نام `./config` برای تنظیمات استفاده کنید و فایل‌های پیکربندی جداگانه برای محیط‌ها (environments) مختلف ایجاد نکنید. +- از یک پوشه به نام `./config` برای تنظیمات استفاده کنید و از ایجاد فایل‌های پیکربندی جداگانه برای هر محیط (`development`، `test`، `production`) خودداری کنید. _چرا:_ -> زمانی که یک فایل کانفیگ را برای اهداف مختلف (مانند پایگاه داده، API و غیره) تجزیه می‌کنید، قرار دادن آن‌ها در پوشه‌ای با نام مشخص مانند `config` منطقی است. فقط به خاطر داشته باشید که برای محیط‌های مختلف فایل‌های جداگانه نسازید، زیرا با افزایش استقرارهای برنامه، نام‌های محیط جدیدی مورد نیاز می‌شود و مدیریت آن پیچیده خواهد شد. +> در صورت افزایش استقرار (deployment)های برنامه، ممکن است محیط‌های بیشتری به پروژه اضافه شود و مدیریت آن‌ها پیچیده شود. بهتر است تنظیمات را در یک پوشه‌ی مشخص مانند `config` قرار دهید و مقادیر مورد نیاز را از طریق متغیرهای محیطی (environment variables) دریافت کنید. ([توضیحات بیشتر ...](https://medium.com/@fedorHK/no-config-b3f1171eecd5)) -> مقادیر مورد استفاده در فایل‌های کانفیگ باید از طریق متغیرهای محیطی (environment variables) فراهم شوند. [توضیحات بیشتر ...](https://medium.com/@fedorHK/no-config-b3f1171eecd5) - -- اسکریپت‌های خود را در یک پوشه به نام `./scripts` قرار دهید. این شامل اسکریپت‌های `bash` و `node` است. +- اسکریپت‌های `bash`، `node` و یا هر اسکریپت اجرایی دیگری را در پوشه‌ی `./scripts` نگه دارید. _چرا:_ -> احتمالاً به بیش از یک اسکریپت نیاز خواهید داشت، مانند production build, development build, database feeders, database synchronization و غیره. +> معمولاً به بیش از یک اسکریپت نیاز خواهید داشت (مانند اسکریپت ساخت نسخه production، ساخت نسخه توسعه development، اسکریپت‌های مرتبط با پایگاه داده و غیره). -- خروجی بیلد خود را در یک پوشه به نام `./build` قرار دهید. `build/` را به `.gitignore` اضافه کنید. +- فایل‌های تولیدشده (مانند فایل‌های bundle، کامپایل‌شده، و ترنسپایل‌شده) را در پوشه‌ی `./build` قرار دهید و در فایل `.gitignore` نیز آن را مستثنی کنید. _چرا:_ -> نام‌گذاری آن به سلیقه شما بستگی دارد، `dist` نیز گزینه خوبی است. اما با تیم خود این نام‌گذاری را هماهنگ کنید. فایل‌هایی که در این پوشه قرار می‌گیرند معمولاً تولید شده‌اند (bundled, compiled, transpiled) یا به این پوشه منتقل شده‌اند. چیزی که می‌توانید تولید کنید، هم‌تیمی‌های شما نیز باید قادر به تولید آن باشند؛ بنابراین نیازی به ارسال آن‌ها به مخزن ریموت نیست، مگر اینکه هدف خاصی داشته باشید. +> نام‌گذاری آن به سلیقه شما بستگی دارد، `dist` نیز گزینه خوبی است، ولی این نام‌گذاری را با تیم خود هماهنگ کنید. فایل‌هایی که در این پوشه قرار می‌گیرند، قابل تولید مجدد هستند و هم‌تیمی‌ها شما نیز باید قادر به تولید آن باشند؛ در نتیجه نیازی به قراردادن آن‌ها در مخزن گیت نیست، مگر در شرایط خاص. -## 7. سبک کدنویسی/Code style +## 7. سبک کدنویسی (Code Style)

Code style @@ -493,121 +490,121 @@ _چرا:_ -### 7.1 برخی از اصول code style +### 7.1 برخی اصول Code Style -- برای پروژه‌های جدید از سینتکس جاوااسکریپت مدرن (استیج ۲ و بالاتر) استفاده کنید. برای پروژه‌های قدیمی، با سینتکس موجود سازگار بمانید مگر اینکه قصد به‌روزرسانی آن را داشته باشید. +- در پروژه‌های جدید از ویژگی‌های جدید جاوااسکریپت (Stage 2 و بالاتر) بهره ببرید. برای پروژه‌های قدیمی، در صورت عدم تمایل به مهاجرت، سینتکس قبلی را حفظ کنید، مگر اینکه قصد به‌روزرسانی آن را داشته باشید. _چرا:_ -> این موضوع به تصمیم شما بستگی دارد. ما از مبدل‌ها (ترنسپایلرها) برای بهره‌گیری از مزایای سینتکس جدید استفاده می‌کنیم. استیج ۲ با تغییرات جزئی احتمالا بخشی از استاندارد خواهد شد. +> این موضوع به تصمیم شما بستگی دارد. بهره‌گیری از ترنسپایلرها (مانند Babel) استفاده از قابلیت‌های جدید زبان را آسان می‌کند. ویژگی‌های Stage 2 معمولاً با تغییرات جزئی بخشی از استاندارد زبان خواهند شد. -- اطمینان حاصل کنید که بررسی سبک کدنویسی (code style) به عنوان بخشی از فرآیند build پروژه انجام شود. (تا هماهنگی و استاندارد بودن کدها در تمام مراحل توسعه حفظ شود.) +- از اجرای بررسی سبک کدنویسی (Code Style) به‌عنوان بخشی از فرآیند Build پروژه، اطمینان حاصل کنید. _چرا:_ -> متوقف کردن build برنامه یکی از روش‌های اعمال سبک کدنویسی در کد است. این کار از بی‌توجهی به سبک کدنویسی جلوگیری می‌کند. این روش را برای کد سمت client و server اجرا کنید. [توضیحات بیشتر ...](https://www.robinwieruch.de/react-eslint-webpack-babel/) +> اگر خطاهای مربوط به سبک کدنویسی جلوی Build را بگیرند، توسعه‌دهندگان مجبور می‌شوند قوانین را رعایت کنند. این روش هم در کد سمت کاربر (Client) و هم در سمت سرور (Server) قابل اجراست. ([توضیحات بیشتر ...](https://www.robinwieruch.de/react-eslint-webpack-babel/)) -- برای اعمال سبک کدنویسی از [ESLint - ابزار بررسی سبک کدنویسی جاوااسکریپت](http://eslint.org/) استفاده کنید. +- برای بررسی و اعمال سبک کدنویسی از [ESLint](http://eslint.org/) استفاده کنید. _چرا:_ > ما `eslint` را ترجیح می‌دهیم، اما شما می‌توانید انتخاب دیگری داشته باشید. این ابزار قوانین بیشتری را پشتیبانی می‌کند، همچنین قابلیت تنظیم و افزودن قوانین سفارشی را دارد. -- ما از کد استایل [Airbnb](https://github.com/airbnb/javascript) برای جاوااسکریپت استفاده می‌کنیم، [بیشتر بخوانید](https://www.gitbook.com/book/duk/airbnb-javascript-guidelines/details). از کد استایلی که پروژه یا تیم شما نیاز دارد استفاده کنید (تا کدهایتان با استانداردهای تعیین‌شده هماهنگ باشند). -- ما هنگام استفاده از [FlowType](https://flow.org/) از [قوانین بررسی سبک تایپ Flow برای ESLint](https://github.com/gajus/eslint-plugin-flowtype) استفاده می‌کنیم. +- ما از کد استایل [Airbnb](https://github.com/airbnb/javascript) برای جاوااسکریپت استفاده می‌کنیم، [بیشتر بخوانید](https://www.gitbook.com/book/duk/airbnb-javascript-guidelines/details). شما نیز می‌توانید هر کد استایلی که با نیاز پروژه یا تیمتان همخوانی دارد، به کار بگیرید. +- هنگام استفاده از [FlowType](https://flow.org/)، از پلاگین‌های مربوط به بررسی [سبک کدنویسی Flow برای ESLint](https://github.com/gajus/eslint-plugin-flowtype) بهره ببرید. _چرا:_ -> ابزار Flow سینتکس‌های جدیدی را معرفی می‌کند که نیاز به رعایت سبک کدنویسی خاصی دارند و باید بررسی شوند. +> با استفاده از Flow اعضای تیم باید سبک کدنویسی خاصی را رعایت کنند. -- از فایل `.eslintignore` برای مستثنی کردن فایل‌ها یا پوشه‌ها از بررسی کد استایل استفاده کنید. +- برای مستثنی‌کردن فایل‌ها و پوشه‌ها از بررسی سبک کدنویسی، از فایل `.eslintignore` استفاده کنید. _چرا:_ -> برای مستثنی کردن چند فایل از بررسی سبک کدنویسی، لازم نیست کدتان را با کامنت‌های `eslint-disable` شلوغ کنید. +> به‌جای شلوغ کردن کد با کامنت‌های `eslint-disable`، برای مستثنی‌کردن فایل‌ها و پوشه‌ها از بررسی سبک کدنویسی، از فایل `.eslintignore` استفاده کنید. -- قبل از ارسال یک Pull Request، تمام کامنت‌های `eslint-disable` خود را حذف کنید. +- تمام کامنت‌های `eslint-disable` خود را پیش از ارسال یک Pull Request حذف کنید. _چرا:_ -> طبیعی است که هنگام کار بر روی یک بخش از کد، برای تمرکز بیشتر روی منطق، بررسی سبک را غیرفعال کنید. فقط به خاطر داشته باشید که کامنت‌های `eslint-disable` را حذف کرده و قوانین را رعایت کنید. +> ممکن است گاهی برای افزایش تمرکز روی یک بخش از منطق کد (Logic)، موقتاً بررسی سبک را غیرفعال کنید؛ اما به خاطر داشته باشید که پیش از ارسال Pull Request، این کامنت‌ها را جهت مطابقت کد با استانداردهای مشخص شده، حذف کنید. -- بسته به حجم و اندازه کار، از کامنت‌های `//TODO:` استفاده کنید یا یک تیکت باز کنید. +- با در نظر داشتن حجم و اندازه کار، از کامنت‌های `//TODO:` یا ایجاد یک تیکت، استفاده کنید. _چرا:_ -> استفاده از کامنت‌های `//TODO:` به شما و همکارانتان کمک می‌کند تا وظایف کوچک مانند بازنویسی یک تابع یا به‌روزرسانی یک توضیح را به خاطر بسپارید. برای وظایف بزرگ‌تر، از فرمت `//TODO(#3456)` استفاده کنید که توسط قوانین lint اعمال می‌شود، که شماره‌ی داخل پرانتز به یک تیکت باز اشاره دارد. +> استفاده از کامنت‌های `//TODO:` به شما و همکارانتان کمک می‌کند تا وظایف کوچک مانند بازنویسی یک تابع یا به‌روزرسانی یک توضیح را به خاطر بسپارند. برای وظایف بزرگ‌تر، از فرمت `//TODO(#3456)` که توسط قوانین `lint` اعمال می‌شود، استفاده کنید، که شماره‌ی داخل پرانتز به یک تیکت باز در سیستم مدیریت پروژه اشاره می‌کند. -- همیشه کامنت‌ها را به‌روز و مرتبط با تغییرات کد نگه دارید. بخش‌های کامنت‌شده کد را حذف کنید. +- همیشه کامنت‌ها را با تغییرات کد بروز نگه دارید. همچنین کدهایی که کامنت‌شده‌اند را نیز حذف کنید. _چرا:_ -> کد شما باید تا حد ممکن خوانا باشد؛ هر چیزی که حواس را پرت می‌کند، حذف کنید. اگر یک تابع را بازنویسی کردید، تابع قدیمی را فقط کامنت نکنید، بلکه آن را حذف کنید. +> کد باید تا حد امکان خوانا باشد؛ بخش‌هایی از کد که استفاده نمی‌شوند را حذف کنید و کامنت‌ها را مطابق با تغییرات جدید به‌روزرسانی کنید. مثلاً اگر یک تابع را بازنویسی کردید، تابع قدیمی را فقط کامنت نکنید، بلکه آن را حذف کنید. -- از کامنت‌ها، لاگ‌ها یا نام‌های نامرتبط یا طنزآمیز پرهیز کنید. +- از نام‌ها یا کامنت‌های طنزآمیز یا غیرمرتبط پرهیز کنید. _چرا:_ -> اگرچه در فرآیند build برنامه آن‌ شوخی‌ها ممکن است (و بهتر است بگویم باید) حذف شود، اما گاهی source code شما به شرکت یا مشتری دیگری منتقل می‌شود که ممکن است آن‌ها چنین شوخی‌هایی را نپسندند. +> اگرچه در فرآیند build برنامه، ممکن است آن کامنت‌ها و شوخی‌ها به صورت خودکار حذف شوند، اما در برخی موارد سورس کد به سایر شرکت‌ها یا مشتری‌ها منتقل می‌شود که ممکن است آن‌ها این نوع شوخی‌ها را نپسندند. -- نام‌ها را به گونه‌ای انتخاب کنید که قابل جست‌وجو و دارای تفاوت‌های معنادار باشند و از نام‌های کوتاه‌شده و مخفف بپرهیزید. برای توابع، از نام‌های طولانی و توصیفی استفاده کنید. نام تابع باید یک فعل یا عبارت فعلی باشد و هدف آن را به وضوح بیان کند. +- نام‌ها را به گونه‌ای انتخاب کنید که قابل جست‌وجو و معنادار باشند، از انتخاب نام‌های کوتاه‌شده و مخفف بپرهیزید. برای توابع، از نام‌های توصیفی و فعل‌محور استفاده کنید. نام تابع باید یک فعل یا عبارت فعلی باشد و هدف آن را به وضوح بیان کند. _چرا:_ > این کار (استفاده از نام‌های کامل و توصیفی) باعث می‌شود کد خواناتر و درک آن راحت‌تر و ساده‌تر شود. -- توابع خود را در فایل بر اساس «قانون نزولی» (Step-down Rule) سازمان‌دهی کنید؛ به این صورت که توابع سطح بالاتر در بالای فایل و توابع سطح پایین‌تر در زیر آن‌ها قرار گیرند. +- توابع را بر اساس «قانون نزولی» (Step-Down Rule) سازمان‌دهی کنید؛ به این صورت که توابع سطح بالاتر را در بالای فایل و توابع سطح پایین‌تر را در پایین فایل قرار دهید. _چرا:_ -> این کار کد را خواناتر و درک آن بهتر می‌کند +> این کار خوانایی کد را افزایش می‌دهد. ### 7.2 اعمال استانداردهای سبک کدنویسی -- از فایل [.editorconfig](http://editorconfig.org/) استفاده کنید که به توسعه‌دهندگان کمک می‌کند تا سبک‌های کدنویسی یکسانی را بین ویرایشگرها و IDEهای مختلف پروژه تعریف و حفظ کنند. +- از فایل `.editorconfig` استفاده کنید ([لینک](http://editorconfig.org/)) که به شما و سایر اعضای تیم کمک کند تا سبک‌های کدنویسی یکسانی را میان ویرایشگرها و IDEهای مختلف پروژه تعریف و حفظ کنید. _چرا:_ -> پروژه EditorConfig شامل یک فرمت فایل برای تعریف سبک‌ و استال‌های کدنویسی است که شامل مجموعه‌ای از افزونه‌ها برای ویرایشگرهای متنی است، که به ویرایشگرها این امکان را می‌دهد تا فرمت فایل را بخوانند و از استایل‌های تعریف‌شده پیروی کنند. فایل‌های EditorConfig خوانا هستند و به‌خوبی با سیستم‌های کنترل نسخه کار می‌کنند. +> پروژه `EditorConfig` دربرگیرنده‌ی یک فایل برای تعریف سبک‌ و استال‌های کدنویسی است که شامل مجموعه‌ای از افزونه‌ها برای ویرایشگرها و IDEی مختلف است؛ که این امکان را می‌دهد که ویرایشگرها و IDEی مختلف از استایل‌های تعریف‌شده پیروی کنند. -- ویرایشگر خود را طوری تنظیم کنید که به شما در مورد خطاهای سبک کدنویسی اطلاع دهد. از [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) و [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) همراه با پیکربندی ESLint خود استفاده کنید. [توضیحات بیشتر ...](https://github.com/prettier/eslint-config-prettier#installation) +- ویرایشگر را به شیوه‌ای راه‌اندازی و تنظیم کنید که برای خطاهای سبک کدنویسی (Code Style) هشدار دهد. از ترکیب پلاگین‌های [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) و [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) در تنظیمات ESLint خود استفاده کنید. ([توضیحات بیشتر ...](https://github.com/prettier/eslint-config-prettier#installation)) - استفاده از Git hooks را مدنظر قرار دهید. _چرا:_ -> استفاده از Git hooks به‌طور قابل‌توجهی بهره‌وری توسعه‌دهندگان را افزایش می‌دهد. با اعمال تغییرات، انجام commit و ارسال (push) به محیط‌های staging یا production، بدون نگرانی از خراب شدن build برنامه، می‌توانید با اطمینان بیشتری کار کنید. [توضیحات بیشتر ...](http://githooks.com/) +> با اجرای خودکار تست‌ها و بررسی Code Style پیش از Commit یا Push کردن تغییرات، می‌توانید مشکلات احتمالی را زودتر شناسایی کنید و از شکست Build پروژه در محیط‌‌های Staging یا Production جلوگیری کنید. ([توضیحات بیشتر ...](http://githooks.com/)) -- از Prettier همراه با یک precommit hook استفاده کنید. +- از Prettier همراه با precommit hook استفاده کنید. _چرا:_ -> اگرچه `prettier` به‌خودی‌خود قدرتمند است، اجرای دستی آن به‌عنوان یک تسک npm برای قالب‌بندی کد چندان کارآمد نیست. در اینجا `lint-staged` (و `husky`) وارد عمل می‌شوند. درباره پیکربندی `lint-staged` [اینجا](https://github.com/okonet/lint-staged#configuration) و پیکربندی `husky` [اینجا](https://github.com/typicode/husky) بیشتر بخوانید.. +> اگرچه `prettier` به‌خودی‌خود قدرتمند است، اما اجرای دستی `prettier` چندان کارآمد نیست. با بهره‌گیری از `lint-staged` و `husky`، می‌توانید هنگام Commit، کد را به‌صورت خودکار قالب‌بندی کنید. درباره پیکربندی `lint-staged` ([اینجا](https://github.com/okonet/lint-staged#configuration)) و پیکربندی `husky` ([اینجا](https://github.com/typicode/husky)) می‌توانید بیشتر مطالعه کنید. -## 8. ثبت وقایع/Logging +## 8. ثبت وقایع (Logging)

Logging

-- از استفاده از console.log در سمت کلاینت در محیط production خودداری کنید. +- استفاده از `console.log` در سمت کلاینت و در محیط Production خودداری کنید. _چرا:_ -> حتی اگر فرآیند build برنامه شما می‌تواند (و باید) آن‌ لاگ‌ها را حذف کند، اطمینان حاصل کنید که ابزار بررسی استایل کدنویسی شما درباره‌ی باقی‌مانده‌های console.log هشدار می‌دهد. +> حتی اگر فرآیند Build شما لاگ‌ها را حذف می‌کند (که بهتر است حتماً این کار را انجام دهد)، به ابزار بررسی سبک کدنویسی (Lint) خود اجازه دهید باقی‌مانده‌های `console.log` را تشخیص و به شما هشدار دهد. -- برای تولید لاگ‌های خوانا در محیط production، بهتر است از کتابخانه‌های logging مناسب (مانند [winston](https://github.com/winstonjs/winston) یا [node-bunyan](https://github.com/trentm/node-bunyan)) استفاده کنید. +- برای تولید لاگ‌های خوانا در محیط production، بهتر است از کتابخانه‌های لاگ مناسب استفاده کنید (مانند [winston](https://github.com/winstonjs/winston) یا [node-bunyan](https://github.com/trentm/node-bunyan)). _چرا:_ -> این کار عیب‌یابی را آسان‌تر و دلپذیرتر می‌کند، چون می‌توانید از قابلیت‌هایی مانند رنگ‌بندی، افزودن زمان به لاگ‌ها، ثبت لاگ‌ها در فایل علاوه بر کنسول و حتی ثبت لاگ‌ها در فایل‌هایی که به‌صورت روزانه ایجاد و بایگانی می‌شوند، استفاده کنید. [توضیحات بیشتر ...](https://blog.risingstack.com/node-js-logging-tutorial/) +> به‌جای `console.log`، از کتابخانه‌هایی نظیر Winston یا node-bunyan استفاده کنید. این ابزارها امکاناتی مانند رنگ‌بندی، زمان‌بندی، و ثبت لاگ‌ها در فایل (علاوه بر کنسول) و حتی ثبت روزانه و بایگانی آن‌ها را در اختیار شما می‌گذارند. این قابلیت‌ها فرایند عیب‌یابی را آسان‌تر و کارآمدتر می‌کند. ([توضیحات بیشتر ...](https://blog.risingstack.com/node-js-logging-tutorial/)) -## 9. ای‌پی‌آی/API +## 9. ای‌پی‌آی (API) @@ -619,44 +616,48 @@ _چرا:_ _چرا:_ -> هدف این است که رابط‌های RESTfulی طراحی کنیم که منطقی و ساده باشند تا اعضای تیم و مشتریان بتوانند به‌سادگی و به‌صورت یکنواخت از آن‌ها استفاده کنند. +> هدف از این بخش، طراحی رابط‌های RESTful است که منطقی و ساده باشند تا اعضای تیم و مشتریان بتوانند به‌سادگی و به‌صورت یکنواخت از آن‌ها استفاده کنند. _چرا:_ -> نبود هماهنگی و سادگی می‌تواند هزینه‌های یکپارچه‌سازی و نگهداری را به طور چشمگیری افزایش دهد؛ به همین دلیل طراحی `API` در این داکیومنت گنجانده شده است. +> نبود هماهنگی و سادگی می‌تواند هزینه‌های یکپارچه‌سازی و نگهداری را به‌طور چشمگیری افزایش دهد. به همین دلیل، طراحی API در این مستند گنجانده شده است. -- ما عمدتاً از طراحی مبتنی بر منابع (Resource-Oriented Design) پیروی می‌کنیم که سه عنصر اصلی دارد: منابع (Resource)، مجموعه‌ها (Collection) و URLها. - - یک منبع شامل داده‌هایی است که می‌تواند به صورت تو در تو (nested) سازمان‌دهی شود و متدهایی برای عملیات روی آن وجود دارد. - - گروهی از منابع، یک مجموعه نامیده می‌شود. - - آدرس اینترنتی (URL) که مکان آنلاین یک منبع یا مجموعه را مشخص می‌کند. +- ما عمدتاً از طراحی مبتنی بر منابع (Resource-Oriented Design) پیروی می‌کنیم که شامل سه عنصر اصلی است: + 1. منابع (Resources): + - شامل داده‌هایی هستند که می‌توانند به‌صورت تو در تو (nested) سازمان‌دهی شوند. + - برای هر منبع، متدهایی برای انجام عملیات مختلف تعریف می‌شود. + 2. مجموعه‌ها (Collections): + - گروهی از منابع (Resources)، یک مجموعه (Collections) را تشکیل می‌دهند. + 3. آدرس‌های اینترنتی (URLs): + - مکان آنلاین یک منبع (Resource) یا مجموعه (Collection) را مشخص می‌کنند. _چرا:_ -> این یک طراحی بسیار شناخته‌شده برای توسعه‌دهندگان است (که اصلی‌ترین مصرف‌کنندگان API هستند). علاوه بر خوانایی و سهولت استفاده، این روش به ما اجازه می‌دهد کتابخانه‌ها و connectorهای عمومی بنویسیم بدون این‌که نیاز به شناخت جزئیات خاص هر API داشته باشیم. +> این شیوه یک استاندارد شناخته‌شده در بین توسعه‌دهندگان (مصرف‌کنندگان اصلی API) است. علاوه بر خوانایی و سادگی استفاده، اجازه می‌دهد کتابخانه‌ها و اتصال‌دهنده‌های عمومی بسازیم، بدون این‌که از ابتدا بدانیم API دقیقاً چه می‌کند. -- برای URL‌ها از kebab-case استفاده کنید. -- برای پارامترهای query string یا فیلدهای منابع از camelCase استفاده کنید. -- از اسامی جمع به صورت kebab-case برای نام منابع در URLها استفاده کنید. -- همیشه از اسامی جمع برای نامگذاری URLهایی که به یک مجموعه اشاره دارند استفاده کنید: `/users`. +- در طراحی مسیرهای (URL) از kebab-case استفاده کنید. +- برای پارامترهای موجود در Query String یا فیلدهای منبع، از camelCase استفاده کنید. +- نام منابع در URL باید به صورت kebab-case و جمع (plural) باشد. +- همیشه از اسامی جمع برای آدرس (URL)‌هایی که به یک مجموعه اشاره می‌کنند استفاده کنید: `/users` _چرا:_ -> اساساً، این کار خوانایی را بهتر کرده و URLها را هماهنگ نگه می‌دارد. [توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-plural-nouns-and-concrete-names) +> به این دلیل که خوانایی بیشتری دارد و آدرس‌ها را یکدست نگه می‌دارد. ([برای اطلاعات بیشتر...](https://apigee.com/about/blog/technology/restful-api-design-plural-nouns-and-concrete-names)) -- در سورس کد، اسامی جمع را به متغیرها و پراپرتی‌ها با پسوند «List» تبدیل کنید. +- در سورس کد، اسامی جمع را به متغیرها و پراپرتی‌هایی با پسوند «List» تبدیل کنید. (مانند `userList` به جای `users`) _چرا:_: -> استفاده از اسامی جمع در URL مناسب است، اما در سورس کد ممکن است نامحسوس و مستعد خطا باشد. +> استفاده از اسامی جمع در URL مناسب است، اما در سورس کد ممکن است به دلیل شباهت ظاهری به اسامی مفرد، منجر به اشتباهات و خطاهای برنامه‌نویسی شود. (تفاوت بین `user` و `users` تنها یک حرف `'s'` است که می‌تواند در خواندن و نگهداری کد مشکلاتی ایجاد کند. با افزودن پسوند `List`، نام متغیرها و ویژگی‌ها واضح‌تر و خواناتر می‌شوند و احتمال بروز خطا کاهش می‌یابد.) -- همیشه از مفاهیم مفرد استفاده کنید که با یک مجموعه شروع شده و به یک شناسه ختم می‌شوند: +- همیشه در طراحی URLها، ابتدا نام مجموعه (collection) را به صورت جمع ذکر کنید و سپس با استفاده از یک شناسه یکتا (identifier)، به یک منبع خاص در آن مجموعه اشاره کنید: ``` /students/245743 /airports/kjfk ``` -- از تولید URLهایی مانند زیر اجتناب کنید: +- از URLهایی مانند این اجتناب کنید: ``` GET /blogs/:blogId/posts/:postId/summary @@ -664,7 +665,7 @@ GET /blogs/:blogId/posts/:postId/summary _چرا:_ -> این URL به جای ارجاع به یک منبع (resource)، به یک ویژگی (property) اشاره می‌کند. شما می‌توانید ویژگی مورد نظر را به‌عنوان یک پارامتر در درخواست ارسال کنید تا پاسخ دریافتی مختصرتر و بهینه‌تر باشد. +> این نوع URL به جای اشاره به یک منبع (resource)، به یک ویژگی (property) یا خلاصه‌ای از منبع اشاره می‌کند. در RESTful APIها، URLها باید منابع (resource) را نمایندگی کنند، نه ویژگی‌های خاص آن‌ها را. برای دسترسی به ویژگی‌های خاص یا خلاصه‌ای از یک منبع، می‌توانید از کوئری پارامترها (query parameters) استفاده کنید تا بتوانید پاسخ را بر اساس نیاز خود تنظیم و محدود کنید. (به عنوان مثال، بهتر است به صورت `GET /blogs/:blogId/posts/:postId?fields=summary` استفاده شود. به این دلیل‌که URL به منبع `postId` در مجموعه `posts` مربوط به `blogId` اشاره می‌کند و با استفاده از کوئری پارامتر `fields=summary` مشخص شده است که فقط خلاصه‌ی مطلب، مورد نظر است.) - افعال را از URLهای منابع خود حذف کنید. @@ -672,7 +673,7 @@ _چرا:_ > زیرا اگر برای هر عملیات resource از یک فعل استفاده کنید، به زودی با لیستی بزرگ از URLها مواجه خواهید شد که الگوی ثابتی ندارند و یادگیری را برای توسعه‌دهندگان دشوار می‌کنند. علاوه بر این، ما از افعال برای چیز دیگری استفاده می‌کنیم. -- از افعال برای موارد غیر منبع (non-resources) استفاده کنید. در این حالت، API شما هیچ منبعی برنمی‌گرداند. در عوض، یک عملیات را اجرا کرده و نتیجه را برمی‌گرداند. این‌ها عملیات CRUD (ایجاد، بازیابی، به‌روزرسانی و حذف) **نیستند**: +- معمولاً از اسامی (nouns) در مسیرهای URL برای اشاره به منابع استفاده می‌شود. با این حال، در مواردی که نیاز به انجام عملیاتی دارید که به منبع خاصی مرتبط نیست (Non-resource) و در واقع یک عملکرد یا تابع را اجرا کرده و نتیجه را برمی‌گرداند، می‌توانید از افعال (verbs) در مسیرهای URL استفاده کنید. این عملیات‌ها مربوط به CRUD (ایجاد، دریافت، به‌روزرسانی، حذف) نیستند: ``` /translate?text=Hallo @@ -680,59 +681,59 @@ _چرا:_ _چرا:_ -> زیرا برای CRUD ما از متدهای HTTP بر روی URLهای `resource` یا `collection` استفاده می‌کنیم. افعالی که درباره آن‌ها صحبت می‌کنیم در واقع کنترلرها `Controllers` هستند. شما معمولاً تعداد زیادی از این‌ها را توسعه نمی‌دهید. [توضیحات بیشتر ...](https://github.com/byrondover/api-guidelines/blob/master/Guidelines.md#controller) +> برای عملیات‌های CRUD، از متدهای HTTP مانند `GET`، `POST`، `PUT` و `DELETE` بر روی URLهای منابع (resource) یا مجموعه‌ها (collection) استفاده می‌کنیم. اما در مواردی که عملیاتی خاص انجام می‌دهید که به منبع خاصی مرتبط نیست، استفاده از افعال در مسیرهای URL می‌تواند مناسب باشد. این نوع مسیرها معمولاً به عنوان "کنترلر" شناخته می‌شوند و تعداد آن‌ها در APIها معمولاً کم است. ([برای اطلاعات بیشتر...](https://github.com/byrondover/api-guidelines/blob/master/Guidelines.md#controller)) -- اگر بدنه درخواست (request body) یا پاسخ (response) از نوع `JSON` است، لطفاً برای نام‌گذاری پراپرتی‌های JSON از `camelCase` پیروی کنید تا یکپارچگی و سازگاری حفظ شود. +- اگر درخواست (Request Body) یا پاسخ (Response) در قالب `JSON` است، از `camelCase` برای نام پراپرتی‌های JSON پیروی کنید تا یکپارچگی و انسجام حفظ شود. _چرا:_ -> این یک راهنما و دستورالعمل برای پروژه JavaScript است، که فرض بر این است که زبان برنامه‌نویسی مورد استفاده برای تولید و تجزیه JSON، جاوااسکریپت می‌باشد. +> این راهنما و دستورالعمل برای پروژه‌ای مبتنی بر جاوااسکریپت تنظیم شده است. در نتیجه، فرض بر این است که تولید و پردازش `JSON` هم در همین زبان انجام می‌شود و پیروی از `camelCase` منطقی است. -- با وجود اینکه یک منبع (resource) مفهومی یکتا و مفرد است که مشابه با یک نمونه شیء یا رکورد پایگاه داده است، شما نباید از نام جدول (`table_name`) برای نام‌گذاری منبع و از نام ستون (`column_name`) برای پراپرتی‌های منبع استفاده کنید. به عبارت دیگر، نام‌گذاری منابع و پراپرتی‌های آن‌ها نباید مستقیماً از ساختار پایگاه داده مشتق شود؛ بلکه باید بر اساس مفاهیم و نیازهای دامنه‌ی کاربرد طراحی شود تا از وابستگی به جزئیات پیاده‌سازی جلوگیری شود. +- هرچند یک منبع (resource) مفهومی یکتا و مفرد است که مشابه با یک نمونه شیء یا رکورد در پایگاه داده می‌باشد، اما نباید از نام جدول‌های پایگاه داده (`table_name`) برای نام‌گذاری منابع و از نام ستون‌ها (`column_name`) برای ویژگی‌های منابع استفاده کنید. _چرا:_ -> زیرا هدف شما نمایش منابع است، نه جزئیات ساختار پایگاه داده. +> هدف اصلی شما ارائه منابع به کاربران است، نه افشای جزئیات ساختار پایگاه داده. افشای مستقیم نام جدول‌ها و ستون‌ها می‌تواند امنیت سیستم را به خطر بیندازد و همچنین انعطاف‌پذیری API را در مواجهه با تغییرات داخلی کاهش دهد. با انتزاع‌سازی و استفاده از نام‌گذاری‌های مستقل از پایگاه داده، می‌توانید APIهایی منسجم‌تر، امن‌تر و قابل نگهداری‌تر ایجاد کنید. -- دوباره تکرار می‌کنم، فقط از اسم‌ها در URL خود هنگام نام‌گذاری منابع استفاده کنید و سعی نکنید عملکرد آن‌ها را توضیح دهید. +- مجدداً تأکید می‌شود، در نام‌گذاری مسیر (URL) فقط از «اسم» استفاده کنید و از توضیح عملکرد آن بپرهیزید. _چرا:_ -> فقط از اسامی در URLهای منبع استفاده کنید و از نوشتن مواردی مانند `/addNewUser` یا `/updateUser` خودداری کنید. همچنین از ارسال عملیات منابع به‌عنوان پارامتر اجتناب کنید. +> فقط از اسامی در URLهای منبع استفاده کنید و از مسیرهایی نظیر `/addNewUser` یا `/updateUser` خودداری کنید. همچنین از ارسال عملیات منبع به‌عنوان یک پارامتر خودداری کنید. -- عملکردهای CRUD را با استفاده از متدهای HTTP توضیح دهید: +- عملیات‌های CRUD را با متدهای HTTP شرح دهید: _چگونه:_ -> متد `GET`: برای دریافت از یک resource استفاده می‌شود. +> متد `GET`: برای بازیابی نمایشی از یک منبع. -> متد `POST`: برای ایجاد منابع (resources) جدید و زیرمنابع (sub-resources) به کار می‌رود. +> متد `POST`: برای ایجاد منابع و زیرمنابع جدید. -> متد `PUT`: برای به‌روزرسانی منابع موجود استفاده می‌شود. +> متد `PUT`: برای به‌روزرسانی منابع موجود. -> متد `PATCH`: برای به‌روزرسانی جزئی منابع موجود به کار می‌رود؛ به‌طوری‌که فقط فیلدهای ارائه‌شده را به‌روزرسانی کرده و سایر فیلدها را بدون تغییر باقی می‌گذارد. +> متد `PATCH`: برای به‌روزرسانی منابع موجود. فقط فیلدهای ارائه‌شده را به‌روزرسانی می‌کند و بقیه را دست‌نخورده می‌گذارد. -> متد `DELETE`: برای حذف منابع موجود استفاده می‌شود. +> متد `DELETE`: برای حذف منابع موجود. -- برای منابع تو در تو (Nested Resources)، توصیه می‌شود رابطه بین آن‌ها را در ساختار URL منعکس کنید. به‌عنوان مثال، برای نمایش ارتباط بین یک کارمند و شرکت مربوطه، می‌توانید از شناسه‌ها (`id`) در URL استفاده کنید. +- برای منابع تو در تو (Nested Resources)، توصیه می‌شود رابطه بین آن‌ها را از طریق شناسه‌ها (`id`)، در ساختار URL منعکس کنید. به‌عنوان مثال، با استفاده از `id` ارتباط یک کارمند با شرکت را نشان دهید. _چرا:_ -> این روش دسترسی به منابع مرتبط را آسان‌تر می‌کند. +> این رویکردی طبیعی برای قابل پیمایش کردن منابع است. _چگونه:_ -> درخواست `GET /schools/2/students` , باید لیست تمام دانش‌آموزان مدرسه با شناسه ۲ را برگرداند. +> درخواست `GET /schools/2/students` باید لیست تمام دانش‌آموزان مدرسه 2 را بازگرداند. -> درخواست `GET /schools/2/students/31` , باید جزئیات دانش‌آموز با شناسه ۳۱ را که متعلق به مدرسه ۲ است، برگرداند. +> درخواست `GET /schools/2/students/31` باید اطلاعات دانش‌آموز شماره 31 مدرسه 2 را بازگرداند. -> درخواست `DELETE /schools/2/students/31` , باید دانش‌آموز با شناسه ۳۱ را که متعلق به مدرسه ۲ است، حذف کند. +> درخواست `DELETE /schools/2/students/31` باید دانش‌آموز شماره 31 مدرسه 2 را حذف کند. -> درخواست `PUT /schools/2/students/31` , باید اطلاعات دانش‌آموز با شناسه ۳۱ را که متعلق به مدرسه ۲ است، به‌روزرسانی کند. +> درخواست `PUT /schools/2/students/31` باید اطلاعات دانش‌آموز شماره 31 را به‌روزرسانی کند. از `PUT` روی مسیر منبع (resource) استفاده می‌کنیم نه روی مسیر مجموعه (collection). -> درخواست `POST /schools` , باید یک مدرسه جدید ایجاد کرده و جزئیات مدرسه تازه ایجاد شده را برگرداند. از POST بر روی URLهای مجموعه‌ای (Collection) استفاده کنید. +> درخواست `POST /schools` باید یک مدرسه جدید بسازد و جزئیات مدرسه تازه ایجاد شده را برگرداند. از `POST` روی آدرس مجموعه (collection) استفاده می‌کنیم. -- برای نسخه‌دهی، از یک شماره ترتیبی ساده با پیشوند `v` استفاده کنید (مانند v1، v2) و آن را تا حد امکان در ابتدای URL قرار دهید تا دامنه بالاتری را (برای تاثیرگذاری) داشته باشد: +- از یک عدد ترتیبی ساده با پیشوند `v` برای نسخه‌دهی استفاده کنید (مثال: `v1`, `v2`) و این نسخه را در ابتدای URL قرار دهید تا بیشترین دامنه تأثیرگذاری را داشته باشد: ``` http://api.domain.com/v1/schools/3/students @@ -740,9 +741,9 @@ http://api.domain.com/v1/schools/3/students _چرا:_ -> وقتی APIهای شما به‌طور عمومی برای سایر اشخاص ثالث در دسترس هستند، اعمال تغییرات ناسازگار (breaking changes)، می‌تواند باعث اختلال در عملکرد محصولات یا خدماتی شود که از APIهای شما استفاده می‌کنند. استفاده از نسخه‌بندی در URL می‌تواند از بروز چنین مشکلاتی جلوگیری کند. [توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-tips-versioning) +> وقتی APIهای شما به‌طور عمومی برای اشخاص دیگر در دسترس هستند، انجام تغییرات ناسازگار (breaking changes)، می‌تواند باعث ایجاد اختلال در عملکرد محصولات یا خدماتی شود که از این APIهای استفاده می‌کنند. استفاده از نسخه‌دهی در URL می‌تواند از بروز چنین مشکلاتی جلوگیری کند. ([توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-tips-versioning)) -- پیام‌های پاسخ (Response) باید خودتوضیح‌دهنده باشند، به‌طوری‌که گیرنده بتواند به‌راحتی مفهوم آن‌ها را درک کند. یک پیام خطای مناسب ممکن است شبیه به این باشد: +- پیام‌های پاسخ (Response) باید به‌خوبی توصیف‌کننده باشند، به‌طوری‌که گیرنده بتواند به‌راحتی مفهوم آن‌ها را درک کند. یک پیام خطای خوب می‌تواند به این شکل باشد: ```json { @@ -775,82 +776,92 @@ _چرا:_ _چرا:_ -> توسعه‌دهندگان در زمان‌های بحرانی که در حال عیب‌یابی و حل مشکلات پس از انتشار برنامه‌هایی که با استفاده از APIهای شما ساخته‌اند و در دست کاربران قرار گرفته‌اند، به خطاهای خوب و خوش‌طراحی‌شده وابسته هستند. +> توسعه‌دهندگان در زمان‌هایی که نیاز به عیب‌یابی و حل مشکلات دارند، به پیام‌های خطای طراحی‌شده و واضح متکی هستند. این پیام‌ها می‌توانند اطلاعات کافی برای رفع سریع مشکلات ارائه دهند. + +_توجه: پیام‌های مربوط به خطای امنیتی را تا حد ممکن کلی و مبهم نگه دارید. به‌عنوان مثال، به جای گفتن «رمز عبور اشتباه است»، از عبارتی مثل «نام کاربری یا رمز عبور اشتباه است» استفاده کنید تا از افشای اطلاعات جزئی و ناخواسته جلوگیری کنید (در این صورت به کاربر اطلاع نداده‌اید که نام کاربری درست است و تنها رمز عبور اشتباه است)._ -_توجه: پیام‌های استثنا مربوط به امنیت را تا حد ممکن عمومی و ساده نگه دارید. به عنوان مثال، به جای اینکه بنویسید «رمز عبور اشتباه است»، می‌توانید پیام «نام کاربری یا رمز عبور نامعتبر است» را بازگردانید. این کار باعث می‌شود که به‌طور ناخودآگاه به کاربر اطلاع ندهید که نام کاربری درست است و تنها رمز عبور اشتباه است._ +- از این کدهای وضعیت HTTP (Status Code) برای توصیف وضعیت پاسخ‌ها استفاده کنید تا نشان دهید آیا همه چیز درست انجام شده، خطایی از سمت کلاینت رخ داده، یا مشکلی در API وجود دارد: -- از این کدهای وضعیت (status codes) برای ارسال همراه با پاسخ‌های خود استفاده کنید تا مشخص کنید آیا **همه چیز درست انجام شده است یا خیر**، آیا **کلاینت اشتباهی انجام داده** یا **مشکل از API بوده است**. +_کدام یک:_ - _کدام یک:_ - > پاسخ `200 OK` نشان‌دهنده موفقیت برای درخواست‌های `GET`, `PUT` یا `POST` است. +> کد `200 OK` برای نشان دادن موفقیت عملیات‌های `GET`، `PUT` یا `POST` - > کد `201 Created` برای زمانی است که یک نمونه جدید ایجاد می‌شود. ایجاد یک نمونه جدید با استفاده از متد `POST` کد وضعیت `201` را برمی‌گرداند. +> کد `201 Created` برای مواقعی که یک نمونه جدید ساخته شده است (مثلاً پس از ایجاد منبع با متد `POST`، کد `201` برگردانید) - > پاسخ `204 No Content` نشان‌دهنده موفقیت است، اما محتوایی برای ارسال در پاسخ وجود ندارد. از آن در زمانی استفاده کنید که عملیات `DELETE` با موفقیت انجام شده است. +> کد `204 No Content` برای نشان دادن موفقیت عملیات اما بدون داشتن محتوای بازگشتی (مثلاً بعد از موفقیت در `DELETE`) - > پاسخ `304 Not Modified` برای به حداقل رساندن انتقال اطلاعات زمانی که گیرنده قبلاً نسخه‌های کش‌شده را دارد، استفاده می‌شود. +> کد `304 Not Modified` برای کاهش حجم انتقال داده زمانی که گیرنده قبلاً نسخه کش‌شده را دارد - > کد `400 Bad Request` برای زمانی است که درخواست پردازش نشده است، زیرا سرور نمی‌تواند بفهمد که مشتری چه چیزی درخواست کرده است. +> کد `400 Bad Request` برای زمانی که درخواست پردازش نشده است، زیرا سرور متوجه منظور کلاینت نشده است. (درخواست کلاینت قابل پردازش نیست.) - > کد `401 Unauthorized` برای زمانی است که درخواست فاقد اعتبارنامه‌های معتبر است و باید با اعتبارنامه‌های مورد نیاز دوباره ارسال شود. +> کد `401 Unauthorized` برای زمانی که درخواست شامل اعتبارنامه (Credentials) معتبر نیست و باید با اعتبارنامه جدید تکرار شود - > کد `403 Forbidden` به این معنی است که سرور درخواست را فهمیده است، اما از اعطای مجوز خودداری می‌کند. +> کد `403 Forbidden` زمانی که سرور درخواست را می‌فهمد ولی از انجام آن امتناع می‌کند - > کد `404 Not Found` نشان می‌دهد که منبع درخواستی پیدا نشده است. +> کد `404 Not Found` زمانی که منبع درخواستی پیدا نشود - > کد `500 Internal Server Error` نشان می‌دهد که درخواست معتبر است، اما سرور به دلیل برخی شرایط غیرمنتظره نمی‌تواند آن را انجام دهد. +> کد `500 Internal Server Error` نشان می‌دهد درخواست معتبر بوده اما سرور به‌دلیل شرایط پیش‌بینی‌نشده قادر به انجام آن نیست - _چرا:_ - > بیشتر ارائه‌دهندگان API از تعداد کمی از کدهای وضعیت HTTP استفاده می‌کنند. برای مثال، API سرویس Google GData تنها از ۱۰ کد وضعیت، Netflix از ۹ کد، و Digg تنها از ۸ کد وضعیت استفاده می‌کنند. البته، این پاسخ‌ها معمولاً شامل بدنه‌ای هستند که اطلاعات بیشتری را ارائه می‌دهد. در کل، بیش از ۷۰ کد وضعیت HTTP وجود دارد. اما اکثر توسعه‌دهندگان همه این ۷۰ کد را به خاطر ندارند.بنابراین، اگر شما کدهای وضعیتی را انتخاب کنید که خیلی رایج نیستند، توسعه‌دهندگان مجبور می‌شوند به جای ادامه کار روی برنامه خود، وقتشان را صرف جستجو در ویکی‌پدیا کنند تا متوجه شوند شما چه چیزی را سعی دارید به آن‌ها بگویید. [توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors) +_چرا:_ -- تعداد کل منابع/دیتا را در پاسخ (response) خود اعلام کنید. -- پارامترهای `limit` و `offset` را بپذیرید. +> اکثر ارائه‌دهندگان API از مجموعه محدودی از کدهای HTTP استفاده می‌کنند. برای مثال، API سرویس Google GData تنها از 10 کد وضعیت، Netflix از ۹ کد، و Digg تنها از 8 کد وضعیت استفاده می‌کنند. البته این پاسخ‌ها دربردارنده اطلاعات بیشتری در بدنه (Body) هستند. بیش از 70 کد وضعیت HTTP وجود دارد اما استفاده از کدهای وضعیت متداول باعث می‌شود توسعه‌دهندگان بدون نیاز به جستجوی اطلاعات اضافی، راحت‌تر با API کار کنند. ([توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)) -- مقدار داده‌ای که یک منبع در پاسخ ارائه می‌دهد نیز باید مورد توجه قرار گیرد. مصرف‌کننده API همیشه به تمام اطلاعات مربوط به یک منبع نیاز ندارد. از پارامتر fields استفاده کنید که لیستی از فیلدها را به صورت جدا شده با کاما دریافت می‌کند تا مشخص کند کدام فیلدها در پاسخ گنجانده شوند: +- در پاسخ (Response)، تعداد کل منابع را اعلام کنید. +- پارامترهای `limit` و `offset` را برای کنترل اندازه پاسخ (Response) پشتیبانی کنید. +- توجه داشته باشید که ممکن است کاربر همیشه به نمایش کامل منبع نیاز نداشته باشد. برای محدود کردن فیلدهای موردنظر، از پارامتر `fields` استفاده کنید که مقادیر آن با کاما جدا می‌شوند: ``` GET /students?fields=id,name,age,class ``` -- پشتیبانی از صفحه‌بندی (pagination)، فیلتر کردن (filtering) و مرتب‌سازی (sorting) نیازی نیست از ابتدا برای همه منابع (resourceها) فعال باشد. منابعی که این قابلیت را دارند، باید به طور مستند (از طریق Document) مشخص شوند. +- پیاده‌سازی قابلیت «صفحه‌بندی» (Pagination)، «فیلتر کردن» (Filtering) و «مرتب‌سازی» (Sorting) در ابتدای کار برای همه منابع ضروری نیست. اما منابعی که این قابلیت‌ها را دارند باید مستند (از طریق Document) شوند. -### 9.2 امنیت ای‌پی‌آی/API security +### 9.2 امنیت ای‌پی‌آی (API security) -این موارد برخی از بهترین روش‌های امنیتی پایه هستند: +این‌ها برخی از بهترین روش‌های امنیتی پایه هستند: -- از احراز هویت پایه (Basic Authentication) استفاده نکنید، مگر اینکه از یک اتصال امن (HTTPS) استفاده کنید. توکن‌های احراز هویت نباید در URL منتقل شوند: `GET /users/123?token=asdf....` +- از احراز هویت پایه (Basic Authentication) تنها در ارتباطات امن (HTTPS) استفاده کنید. توکن‌های احراز هویت (Authentication token) نباید در URL ارسال شوند: + +``` +GET /users/123?token=asdf.... +``` _چرا:_ -> زیرا توکن یا شناسه کاربری و رمز عبور به صورت متن ساده (clear text) در شبکه ارسال می‌شوند (اگرچه به صورت Base64 کدگذاری شده است، اما Base64 یک کدگذاری برگشت‌پذیر است). بنابراین، روش احراز هویت پایه ایمن نیست. [توضیحات بیشتر ...](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) +> اطلاعات احراز هویت مانند شناسه کاربری و رمز عبور و یا توکن، حتی اگر کدگذاری شده باشد (Base64)، به‌عنوان متن ساده قابل خواندن است (زیرا قابل بازگشایی است) و امنیت کافی ندارد. بنابراین، روش احراز هویت پایه (Basic Auth) ایمن نیست. ([توضیحات بیشتر ...](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)) + +- توکن‌ها باید در هر درخواست، از طریق هدر Authorization ارسال شوند: + +```bash +Authorization: Bearer xxxxxx, Extra yyyyy +``` -- توکن‌ها باید با استفاده از هدر Authorization در هر درخواست منتقل شوند: `Authorization: Bearer xxxxxx, Extra yyyyy`. -- کدهای Authorization باید مدت‌زمان کوتاهی معتبر باشند. -- هرگونه درخواست بدون TLS را رد کنید. به درخواست‌های HTTP (بدون TSL) پاسخ ندهید تا از تبادل داده‌های ناامن جلوگیری شود. اگر پاسخ می‌دهید، از کد وضعیت `403 Forbidden` استفاده کنید. -- استفاده از نرخ محدودیت (Rate Limiting) را در نظر بگیرید. +- مدت اعتبار کد احراز هویت (Authorization Code) باید کوتاه باشد. +- هرگونه درخواست غیر ایمن (غیر TLS) را رد کرده و به آن پاسخ ندهید. به درخواست‌های HTTP با کد `403 Forbidden` پاسخ دهید تا از هرگونه تبادل ناامن جلوگیری کنید. +- محدودیت نرخ درخواست (Rate Limiting) را اعمال کنید. _چرا:_ -> برای حفاظت از API در برابر تهدیدات بات‌هایی که ممکن است هزاران بار در ساعت API شما را فراخوانی می‌کنند. باید محدودیت نرخ (rate limit) را از همان مراحل اولیه پیاده‌سازی مد نظر قرار دهید. +> برای محافظت از API در برابر ربات‌هایی که می‌توانند هزاران بار در ساعت درخواست ارسال کنند، بهتر است محدودیت نرخ درخواست‌ (Rate Limiting) را از همان ابتدای پیاده‌سازی مدنظر قرار دهید. -- تنظیم مناسب هدرهای HTTP می‌تواند به ایمن‌سازی برنامه وب شما کمک کند. [توضیحات بیشتر ...](https://github.com/helmetjs/helmet) -- API شما باید داده‌های دریافت‌شده را به فرم استانداردشان تبدیل کند یا آن‌ها را رد کند. در صورت وجود داده‌های نادرست یا ناقص، کد وضعیت 400 Bad Request را همراه با جزئیات خطا در پاسخ بازگردانید. -- تمام داده‌های مبادله‌شده با REST API باید توسط خود API اعتبارسنجی شوند. -- JSON خود را سریالایز (Serialize) کنید. +- هدرهای HTTP را به‌درستی تنظیم کنید تا امنیت وب‌اپلیکیشن شما افزایش یابد. ([اطلاعات بیشتر...](https://github.com/helmetjs/helmet)) +- داده‌های دریافت‌شده را به فرم استاندارد تبدیل کنید یا در صورت خطا یا نامعتبر بودن، آن درخواست را با کد وضعیت `400 Bad Request` همراه با جزئیات خطا، رد کنید. +- تمام داده‌هایی که با REST API مبادله می‌شوند، باید توسط خود همان API اعتبارسنجی شوند. +- داده‌های JSON خود را سریال‌سازی (Serialize) کنید. _چرا:_ -> یکی از نگرانی‌های اصلی کار با JSON، جلوگیری از اجرای کدهای جاوااسکریپت دلخواه از remote در مرورگر است... یا اگر از node.js در سمت سرور استفاده می‌کنید. بسیار مهم و حیاتی است که از یک سریالایزر JSON مناسب استفاده کنید تا داده‌های ورودی کاربر به درستی کدگذاری شوند و از اجرای داده‌های ورودی کاربر در مرورگر جلوگیری شود. +> این کار از اجرای کدهای مخرب جاوااسکریپت که ممکن است از طریق داده‌های JSON ارسال شوند، جلوگیری می‌کند. در نتیجه بسیار مهم است که از سریالایزر معتبر JSON استفاده کنید تا مانع اجرای داده‌های ارسال‌شده از کاربر در مرورگر یا سرور شود. -- نوع محتوا (Content-Type) را اعتبارسنجی کنید و بیشتر از `application/*json` (هدر Content-Type) استفاده کنید. +- نوع محتوا (Content-Type) را اعتبارسنجی کنید و عموماً از `application/*json` استفاده کنید. _چرا:_ -> به عنوان مثال، پذیرش نوع `application/x-www-form-urlencoded` به مهاجم اجازه می‌دهد یک فرم ایجاد کند و یک درخواست POST ساده ارسال کند. سرور هرگز نباید نوع محتوا (Content-Type) را فرض کند. عدم وجود هدر Content-Type یا وجود یک Content-Type غیرمنتظره باید منجر به رد محتوا توسط سرور با یک پاسخ `4XX` شود. +> به‌عنوان مثال، اگر `application/x-www-form-urlencoded` را بپذیرید، مهاجم می‌تواند با ساخت یک فرم ساده، درخواست POST ارسال کند. سرور نباید نوع محتوای ارسالی را حدس بزند. در صورت فقدان یا نامعتبر بودن هدر Content-Type، سرور باید آن درخواست را با کد `4XX` رد کند. -- پروژه API Security Checklist را بررسی کنید. [توضیحات بیشتر ...](https://github.com/shieldfy/API-Security-Checklist) +- برای بررسی فهرست امنیتی APIها، به [API Security Checklist](https://github.com/shieldfy/API-Security-Checklist) مراجعه کنید. @@ -891,89 +902,89 @@ Content: { id : 12 } -## 10. دسترس‌پذیری/Accessibility ([a11y](https://www.a11yproject.com/)) +## 10. دسترس‌پذیری (Accessibility) ([a11y](https://www.a11yproject.com/))

Accessibility

-### 10.1 پیاده‌سازی روش‌های دسترسی‌پذیری +### 10.1 پیاده‌سازی روش‌های دسترس‌پذیری -برای اطمینان از حفظ سطح مشخصی از دسترسی‌پذیری، **از ابتدای پروژه خود** مراحل زیر را انجام دهید: +برای اطمینان از حفظ دسترس‌پذیری، از همان ابتدا این قوانین را در پروژه خود اعمال کنید: _چرا:_ -> محتوای وب [به‌طور پیش‌فرض دسترسی‌پذیر](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML)است. ما این ویژگی را زمانی به خطر می‌اندازیم که امکانات پیچیده ایجاد می‌کنیم. در نظر گرفتن دسترسی‌پذیری از ابتدا بسیار آسان‌تر از بازپیاده‌سازی این ویژگی‌ها در آینده است تا تأثیر آن را کاهش دهیم. +> محتوای وب [به‌طور پیش‌فرض دسترسی‌پذیر](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML) است. این ویژگی زمانی به خطر می‌افتد که پیچیدگی‌های غیرضروری ایجاد شود. در نظر گرفتن دسترس‌پذیری از ابتدا بسیار آسان‌تر از تلاش برای بازبینی و اصلاح آن در مراحل بعدی است. -- با استفاده از ابزارهایی مانند [lighthouse](https://developers.google.com/web/tools/lighthouse#devtools) برای [دسترسی‌پذیری](https://web.dev/lighthouse-accessibility/) یا افزونه [axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)برنامه‌ریزی‌هایی را جهت انجام ممیزی‌های منظم انجام دهید. بر اساس نیازهای پروژه خود، بر روی یک امتیاز حداقلی توافق کنید. امتیازدهی در این ابزارها بر اساس [ارزیابی تأثیر کاربر در axe](https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md#wcag-21-level-a--aa-rules) می‌باشد. +- با استفاده از ابزارهایی مانند [lighthouse](https://developers.google.com/web/tools/lighthouse#devtools) یا افزونه [axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US) برنامه‌ریزی‌هایی جهت بررسی ادواری [دسترسی‌پذیری](https://web.dev/lighthouse-accessibility/) به طور منظم انجام دهید. بر اساس نیاز پروژه، اهداف و امتیازات حداقلی‌ای برای دسترس‌پذیری تعیین و توافق کنید و این امتیازات را بر اساس [تأثیر کاربر](https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md#wcag-21-level-a--aa-rules) ارزیابی کنید. -> **نکته:** [برخی بررسی‌های مهم](https://web.dev/lighthouse-accessibility/#additional-items-to-manually-check) باید به‌صورت دستی انجام شوند، مانند ترتیب منطقی تب‌ها. ابزارهای فوق این موارد را به عنوان تست‌های دستی یا راهنمایی‌شده در کنار نتایج خودکار فهرست می‌کنند. در axe باید نتایج خودکار خود را ذخیره کنید تا این موارد را مشاهده کنید. +> **نکته:** برخی از [بررسی‌های ضروری](https://web.dev/lighthouse-accessibility/#additional-items-to-manually-check) باید به‌صورت دستی انجام شوند، مانند ترتیب منطقی تب‌ها. این ابزارها معمولاً این موارد را به‌عنوان تست‌های دستی فهرست می‌کنند. در axe باید نتایج بررسی خودکار را ذخیره کنید تا این موارد را مشاهده کنید. -- یک Linter مرتبط با دسترس‌پذیری نصب کنید: - - در ری‌اکت: [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y) - - در انگولار: [Angular Codelyzer](https://github.com/mgechev/codelyzer) - - در ویو: [eslint-plugin-vuejs-accessibility](https://github.com/vue-a11y/eslint-plugin-vuejs-accessibility) +- یک لینتر (Linter) مرتبط برای بررسی دسترس‌پذیری نصب کنید: + - برای React: از [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y) استفاده کنید. + - برای Angular: از [Angular Codelyzer](https://github.com/mgechev/codelyzer) بهره ببرید. + - برای Vue: از [eslint-plugin-vuejs-accessibility](https://github.com/vue-a11y/eslint-plugin-vuejs-accessibility) استفاده کنید. _چرا:_ -> یک لینتر به‌طور خودکار بررسی می‌کند که سطح پایه‌ای از دسترسی‌پذیری در پروژه شما رعایت شده است و راه‌اندازی آن نسبتاً آسان است. +> این افزونه‌ها به‌صورت خودکار بخشی از الزامات اولیه دسترس‌پذیری را کنترل می‌کنند و پیاده‌سازی آن‌ها ساده است. -- با استفاده از [axe-core](https://www.youtube.com/watch?v=-n5Ul7WPc3Y&list=PLMlWGnpsViOMt24a-Y_dybv68H-kj6Un6&t=1649s) یا ابزارهای مشابه، تست‌های دسترسی‌پذیری را راه‌اندازی و اجرا کنید. -- اگر از Storybook استفاده می‌کنید، این [راهنما](https://storybook.js.org/blog/accessibility-testing-with-storybook/) را دنبال کنید. +- با استفاده از ابزارهایی مانند [axe-core](https://www.youtube.com/watch?v=-n5Ul7WPc3Y&list=PLMlWGnpsViOMt24a-Y_dybv68H-kj6Un6&t=1649s) یا مشابه آن، می‌توانید تست‌های دسترسی‌پذیری را راه‌اندازی و اجرا کنید. +- اگر از Storybook استفاده می‌کنید، دستورالعمل‌های [آن](https://storybook.js.org/blog/accessibility-testing-with-storybook/) را دنبال کنید. _چرا:_ -> گنجاندن بررسی‌های دسترس‌پذیری در تست‌ها به شما کمک می‌کند تا هر تغییری که بر دسترس‌پذیری پروژه و امتیاز ممیزی تأثیر می‌گذارد، شناسایی کنید. +> این تست‌ها به شناسایی تغییراتی که ممکن است بر دسترس‌پذیری تأثیر منفی بگذارند کمک می‌کنند. -- از یک دیزان سیستم دسترسی‌پذیر مانند [React Spectrum](https://react-spectrum.adobe.com/react-spectrum/) یا [Material Design](https://material.io/design) استفاده کنید. +- از دیزاین سیستم‌های منطبق بر دسترسی‌پذیری مانند [React Spectrum](https://react-spectrum.adobe.com/react-spectrum/) یا [Material Design](https://material.io/design) بهره ببرید. _چرا:_ -> این کامپوننت‌ها به صورت پیش‌فرض از سطح بالایی از دسترس‌پذیری برخوردار هستند. +> این کامپوننت‌ها به‌صورت پیش‌فرض از سطح بالایی از دسترس‌پذیری برخوردار هستند. -### 10.2 برخی از قوانین پایه دسترس‌پذیری که باید به پروژه خود اضافه کنید: +### 10.2 قوانین پایه دسترس‌پذیری -- اطمینان حاصل کنید که نام لینک‌ها دسترس‌پذیر هستند. از aria-label برای توصیف لینک‌ها استفاده کنید. +- از دسترس‌پذیر بودن نام لینک‌ها اطمینان حاصل کنید. از `aria-label` برای توصیف لینک‌ها استفاده کنید. _چرا:_ -> لینک‌هایی که غیرقابل دسترس می‌باشند، برای دسترس‌پذیری موانعی ایجاد می‌کنند. +> لینک‌های نامفهوم و غیرقابل دسترس می‌توانند برای دسترس‌پذیری موانعی ایجاد کنند. -- اطمینان حاصل کنید که لیست‌ها به‌درستی ساختاربندی شده باشند و عناصر لیست به صورت معنایی استفاده شده‌اند. +- اطمینان حاصل کنید که لیست‌ها به‌درستی ساختاربندی شده باشند تا معتبر و قابل درک باشند. _چرا:_ -> لیست‌ها باید دارای عناصر والد و عناصر فرزند باشند تا معتبر باشند. صفحه‌خوان‌ها (Screen Readers) به کاربران اطلاع می‌دهند که وقتی به یک لیست می‌رسند، لیست شامل چند آیتم است. +> لیست‌ها باید دارای عناصر والد و فرزند باشند تا معتبر و قابل درک باشند. صفحه‌خوان‌ها (Screen Readers) کمک می‌کند تا اطلاعات دقیق‌تری در مورد تعداد آیتم‌ها و ساختار لیست ارائه دهند. -- اطمینان حاصل کنید که ترتیب سرفصل‌ها (Heading Order) از نظر معنایی صحیح است. +- از رعایت ترتیب معنایی سرفصل‌ها (Heading Order) اطمینان حاصل کنید. _چرا:_ -> سرفصل‌ها ساختار صفحه را منتقل می‌کنند. هنگامی که به درستی اعمال شوند، پیمایش صفحه آسان‌تر می‌شود. +> سرفصل‌ها ساختار کلی صفحه را منتقل می‌کنند. وقتی به‌درستی استفاده شوند، پیمایش در صفحه برای کاربر آسان‌تر می‌شود. -- اطمینان حاصل کنید که عناصر متنی دارای کنتراست کافی با پس‌زمینه‌ی صفحه هستند. +- از کُنتراست (تضاد رنگی) مناسب میان متن و پس‌زمینه اطمینان حاصل کنید. _چرا:_ -> برخی افراد با بینایی کم، کنتراست پایین را تجربه می‌کنند؛ به این معنی که تفاوت زیادی بین مناطق روشن و تاریک وجود ندارد. همه چیز تقریباً با همان میزان روشنایی ظاهر می‌شود، که تشخیص خطوط، حاشیه‌ها، لبه‌ها و جزئیات را دشوار می‌کند. متنی که از نظر روشنایی بسیار نزدیک به پس‌زمینه باشد، ممکن است سخت خوانده شود. +> افرادی که دچار ضعف بینایی هستند به کنتراست (تضاد رنگی) بالایی نیاز دارند تا بتوانند خطوط، حاشیه‌ها و جزئیات متن را به‌راحتی تشخیص دهند. اگر رنگ متن بیش از حد به رنگ پس‌زمینه نزدیک باشد، به سختی آن متن قابل خواندن خواهد بود. -- برای تصاویر، متن جایگزین (Alt Text) ارائه دهید. +- برای تصاویر، متن جایگزین کوتاه و توصیفی (Alt Text) ارائه دهید. _چرا:_ -> صفحه‌خوان‌ها نمی‌توانند تصاویر را به کلماتی تبدیل کنند که برای کاربر خوانده شود، حتی اگر تصویر فقط شامل متن باشد. در نتیجه، ضروری است که تصاویر دارای متن جایگزین کوتاه و توصیفی باشند تا کاربران صفحه‌خوان به‌وضوح محتوای تصویر و هدف آن را درک کنند. +> صفحه‌خوان‌ها قادر به تفسیر و توضیح تصاویر به کلمات خوانا نیستند؛ حتی اگر تصویر فقط حاوی متن باشد. بنابراین، متن جایگزین (Alt Text) به کاربران کمک می‌کند تا محتوای تصویر و هدف آن را درک کنند. -قوانین بیشتری درباره دسترس‌پذیری را می‌توانید [اینجا](https://dequeuniversity.com/rules/axe) پیدا کنید. +برای آشنایی بیشتر با دیگر قوانین دسترس‌پذیری می‌توانید به [این منبع](https://dequeuniversity.com/rules/axe) مراجعه کنید. -## 11. مجوزدهی/Licensing +## 11. مجوزها (Licensing)

Licensing

-اطمینان حاصل کنید که از منابعی استفاده می‌کنید که حق استفاده از آن‌ها را دارید. اگر از کتابخانه‌ها استفاده می‌کنید، به مجوزهای MIT، Apache یا BSD توجه کنید، اما اگر این کتابخانه‌ها را تغییر می‌دهید، حتماً جزئیات مجوز را بررسی کنید. استفاده از تصاویر و ویدئوهای دارای حق کپی‌رایت (Copyrighted) ممکن است مشکلات قانونی ایجاد کند. +هنگام استفاده از منابع مختلف، اطمینان حاصل کنید که حق استفاده از آن‌ها را دارید. اگر از کتابخانه‌ها استفاده می‌کنید، حتماً جوازهای (License) مبتنی بر MIT، Apache یا BSD را بررسی کنید؛ اما اگر تغییری در آن‌ها ایجاد می‌کنید، جزئیات مجوز را با دقت مطالعه نمایید. همچنین استفاده از تصاویر و ویدیوهای دارای حق تکثیر (کپی‌رایت) ممکن است مشکلات حقوقی ایجاد کنند. ---