ہر ڈویلپمنٹ ٹیم کی ایسی ہی ایک کہانی ہوتی ہے۔ ایک پل ریکویسٹ (pull request) آدھے دن تک کھلی رہتی ہے۔ اس لیے نہیں کہ لاجک (logic) خراب ہے یا API کنٹریکٹ بدل گیا ہے، بلکہ اس لیے کہ دو ریویورز (reviewers) اس بات پر اختلاف کرتے ہیں کہ کیا آبجیکٹ لٹرلز (object literals) میں ٹریلنگ کومہ (trailing commas) ہونا ضروری ہے۔ بحث بڑھتی جاتی ہے۔ کوئی اسٹائل گائیڈ کا لنک پوسٹ کرتا ہے۔ کوئی دوسرا کسی مختلف گائیڈ کا حوالہ دیتا ہے۔ جب تک کوڈ مرج (merge) ہوتا ہے، اس عمل میں شامل ہر شخص ان فیچرز کے بارے میں اپنا سیاق و سباق (context) کھو چکا ہوتا ہے جن پر وہ اصل میں کام کر رہے تھے۔
یہ لڑائیاں مہنگی پڑتی ہیں۔ یہ سینئر انجینئرز کے گھنٹوں کا وقت ضائع کرتی ہیں، ساتھیوں کے درمیان معمولی رنجشیں پیدا کرتی ہیں، اور جونیئر ڈویلپرز کو یہ سمجھنے پر مجبور کرتی ہیں کہ سافٹ ویئر انجینئرنگ کا زیادہ تر حصہ سیمیکولن (semicolons) پر بحث جیتنا ہے۔ سب سے برا حصہ؟ پروڈکٹ کو اس سے کوئی فرق نہیں پڑتا۔ آپ کے صارفین کو کبھی اس بات کا احساس نہیں ہوگا کہ کہیں اسپیس (space) ہے یا ٹیب (tab)۔ انہیں اس بگ (bug) کا احساس ہوگا جسے آپ نے اس لیے ٹھیک نہیں کیا کیونکہ آپ کوٹیشن مارکس (quote marks) پر بحث کرنے میں مصروف تھے۔
مستقل مزاجی (Consistency) اہمیت رکھتی ہے۔ ایک ایسا کوڈ بیس (codebase) جو ایسا لگے کہ اسے ایک ہی شخص نے لکھا ہے، اسے پڑھنا، ریویو کرنا اور ڈی بگ (debug) کرنا آسان ہوتا ہے۔ غلطی اسے دستی طور پر (by hand) نافذ کرنے کی کوشش کرنے میں ہے۔
بورنگ کاموں کو خودکار بنائیں
اس کا حل سادہ ہے۔ فارمیٹنگ سے انسانی فیصلے کو مکمل طور پر ختم کر دیں۔ اسے ایسے ٹولز کے حوالے کر دیں جن میں انا (ego) نہیں ہوتی اور جو تھکتے نہیں ہیں۔
تین ٹولز اس کام کو بہترین طریقے سے انجام دیتے ہیں۔
Prettier آپ کے کوڈ کو لیتا ہے اور اسے خودکار طور پر ری فارمیٹ کرتا ہے۔ یہ اجازت نہیں مانگتا۔ آپ لائن کی لمبائی، کوٹ اسٹائل (quote styles)، یا کسی طویل فنکشن سگنیچر (function signature) کو لائنوں میں کیسے توڑنا ہے، اس کے بارے میں سوچنا چھوڑ دیتے ہیں۔ آپ فائل سیو کرتے ہیں، اور Prettier اسے مستقل مزاج (consistent) بنا دیتا ہے۔
ESLint ان مسائل کو حل کرتا ہے جنہیں Prettier نہیں چھوتا۔ یہ غیر استعمال شدہ ویری ایبلز (unused variables)، ناقابل رسائی کوڈ (unreachable code)، React hooks میں مِسنگ ڈیپینڈنسیز (missing dependencies)، اور ایسے پیٹرنز کو پکڑتا ہے جو تاریخی طور پر بگ (bugs) کا باعث بنتے ہیں۔ جب اسے صحیح طریقے سے کنفیگر کیا جائے، تو یہ فارمیٹنگ سے دور رہتا ہے اور اصل کوڈ کی کوالٹی پر توجہ دیتا ہے۔
Husky ایک pre-commit hook انسٹال کرتا ہے جو آٹومیٹڈ چیک پاس ہونے تک کسی بھی چیز کو آپ کی ریپوزٹری (repository) میں داخل ہونے سے روک دیتا ہے۔ یہ آپ کے Git پائپ لائن کو مشوروں کے باکس کے بجائے ایک گیٹ کیپر (gatekeeper) میں بدل دیتا ہے۔
ملا کر یہ ایک مضبوط لوپ (loop) بناتے ہیں۔ آپ مقامی طور پر (locally) جیسے چاہیں کوڈ لکھیں۔ جب آپ اسے کمٹ (commit) کرتے ہیں، تو یہ ٹولز اسے صاف اور چیک کرتے ہیں۔ صرف تب ہی کوڈ آپ کی مشین سے باہر نکلتا ہے۔
یہ مخصوص اسٹیک کیوں کام کرتا ہے
آپ ESLint کے رولز کو دستی طور پر ٹیون کرنے میں ہفتوں گزار سکتے ہیں۔ اس خواہش سے بچیں۔ یہاں مقصد اسٹائل پر بحث روکنا ہے، نہ کہ اسٹائل گائیڈ کی دیکھ بھال کے لیے ایک نیا فل ٹائم کام پیدا کرنا۔
Prettier جان بوجھ کر مخصوص اصولوں پر مبنی (opinionated) بنایا گیا ہے۔ یہ محدود کنفیگریشن آپشنز پیش کرتا ہے کیونکہ ہر آپشن مستقبل کی ایک بحث ہے۔ اس کی ڈیفالٹ سیٹنگز مناسب ہیں۔ چند مخصوص اوور رائڈز (overrides) منتخب کریں، انہیں ایک بار لکھ لیں، اور آگے بڑھ جائیں۔
ESLint، اگر اسے آزاد چھوڑ دیا جائے، تو یہ کوڈ کی کوالٹی اور فارمیٹنگ رولز جیسے سیمیکولن کا استعمال اور انڈنٹ سائز (indent size) دونوں کو نافذ کرنے کی کوشش کرے گا۔ اس سے Prettier کے ساتھ رگڑ پیدا ہوتی ہے کیونکہ دونوں ٹولز ایک ہی کیریکٹرز کو ایڈٹ کرنے کی کوشش کریں گے۔ eslint-config-prettier پیکج اس مسئلے کو ان تمام ESLint رولز کو غیر فعال کر کے حل کرتا ہے جو Prettier کے ساتھ ٹکراتے ہیں۔ ذمہ داریوں کی یہ تقسیم انتہائی اہم ہے۔ Prettier ظاہری شکل (cosmetics) کا ذمہ دار ہے، جبکہ ESLint لاجک (logic) کا۔
صرف continuous integration (CI) میں چیک چلانا بہت دیر ہو جاتی ہے۔ جب تک CI فیل ہوتا ہے، آپ پہلے ہی گندا کوڈ کمٹ کر چکے ہوتے ہیں، دوسرے کام کی طرف منتقل ہو چکے ہوتے ہیں، اور ممکنہ طور پر ایک پل ریکویسٹ کھول چکے ہوتے ہیں۔ اسے ٹھیک کرنے کے لیے ایک اور کمٹ، ایک اور پش (push)، اور انتظار کے ایک اور چکر کی ضرورت ہوتی ہے۔ Husky اس فیڈ بیک لوپ کو سیکنڈوں میں سمیٹ دیتا ہے۔ Lint-staged اسے تیز بناتا ہے کیونکہ یہ پورے ریپوزٹری کو اسکین کرنے کے بجائے صرف ان فائلوں پر ٹولز چلاتا ہے جنہیں آپ نے اصل میں تبدیل کیا ہوتا ہے۔
مرحلہ وار سیٹ اپ
درج ذیل سیٹ اپ ایک جدید JavaScript یا React پروجیکٹ کے لیے ہے، لیکن معمولی تبدیلیوں کے ساتھ یہ پیٹرن TypeScript، Vue، یا Node پر بھی لاگو کیا جا سکتا ہے۔ ہر مرحلہ اپنے پروجیکٹ روٹ (project root) سے چلائیں۔
سب سے پہلے سب کچھ dev dependencies کے طور پر انسٹال کرنے سے شروع کریں:
npm install -D prettier eslint husky lint-staged eslint-config-prettier
