8 اشتباه رایج در توسعه وب
من اخیراً به یک شرکت راه اندازی کوچک پیوستم که در ایجاد و ارائه یک برنامه تحت وب برای یک مطالعه مهم بالینی که تمرکز آن برCOVID-19 است ، کمک کردم. تنها مشکل مهلت اجرای پروژه در دو هفته بود! این فقط به نظر ترسناک و استرس زا بود ، اما من تصمیم گرفتم این چالش را بپذیرم.
علاوه بر مهلت پیش رو ، توسعه دهنده اصلی که مسئولیت اصلی آن را به عهده داشت ، تحت فشار قرار گرفتند. در نتیجه ، خروجی کد کاملاً خراب بود و یک آشفتگی کامل بود. دامنه این پروژه برای تیمی متشکل از دو توسعه دهنده به سادگی غیرواقعی بود که در یک بازه زمانی کوتاه مدیریت کنند.
در پایان ، حداقل محصول مناسب به کار گرفته شد و با سکسکه های جزئی کار می کرد ، اما اکنون به دلیل نامرتب نوشتن کد ، به یک اصلاح اساسی و اصلاح مجدد نیاز دارد. این یک کار دلهره آور است که به زمان زیادی نیاز دارد اما به درآمد اضافی برای شرکت منجر نمی شود.
اگر پروژه به درستی تنظیم شده باشد و از بهترین روش ها استفاده شود ، می توان از همان ابتدا به راحتی از آن اجتناب كرد.
پس از کار بر روی بسیاری از پروژه های متنوع ، لیستی از موارد ضروری خودم را ایجاد کرده ام تا از یک پروژه موفق و تجربه عالی توسعه دهنده اطمینان حاصل کنم.
برای صرفه جویی در وقت ارزشمند شما در پروژه های توسعه وب خود در آینده ، اطمینان حاصل کنید که از این هشت اشتباه رایج در توسعه وب جلوگیری کنید.
. . .
1. بلافاصله ابزارهای کیفیت کد را فعال نمی کنید
هنگام شروع کار بر روی یک پروژه جدید ، همیشه باید یکی از اولین وظایف موجود در لیست کارهای شما باشد. اطمینان حاصل کنید که ابزارهای کیفیت کد بر اساس نیازهای پروژه در دسترس هستند. بعداً از آن سپاسگزار خواهید بود.
هنگامی که من به پروژه مذبور پیوستم ، هیچ چیز تنظیم نشده و کد متناقض بود ، با استفاده مخلوط از نقل قول ها ،بلوک های .catch()، و مسائل مختلف قالب بندی از دست رفته بود.
ESLint شما را از تولید خطاهایی مانند این موارد که در وهله اول می توان از آن جلوگیری کرد ، نجات می دهد. پس از اجرای یک اسکریپت بر روی پروژه برای اولین بار با پیکربندی نظر داده شده ، 200+ اخطار و خطا در انتظار رفع بود.
من می دانم ، می دانم ، انجام تنظیمات دقیقاً مطابق آنچه لازم است دشوار است. علاوه بر این ، صاحب پروژه می خواهد نتایج واقعی را ببیند و به اینکه شما وقت گرانبهایی را برای پیکربندی ابزارهای توسعه صرف می کنید اهمیتی نمی دهد. اما در دراز مدت چنین سرمایه گذاری شایسته ای است و نباید به تأخیر بیفتد. در پایان ، هنگامی که پروژه ای تمیز و عاری از خطا داشته باشید ، برای شما مفیدتر خواهد بود ، بهره وری شما را بیشتر می کند.
من توصیه می کنم بسته به نیاز خود از همه یا برخی از این بسته ها برای پیکربندی استفاده کنید:
· eslint یا @typescript-eslint برای تنظیم قاعده پایه .
· eslint-plugin-import برای اضافه کردن تمیز و مرتب.
· eslint-plugin-jest برای نوشتن تست های واحد بهتر و دقیق تر.
· eslint-plugin-node برای توسعه back-end و بررسی ویژگی های نسخه گره پشتیبانی شده.
· eslint-plugin- قول می دهد که بلوک های .catch()و سایر اقدامات بد را هنگام کار با کد ناهمزمان از دست ندهید.
· eslint-plugin-jsx-a11y برای نوشتن کد قابل دسترسی در صورت استفاده از React.
· eslint-plugin-unicorn برای قوانین مفید متفرقه.
در بالای پیکربندی های پیشنهادی که به شما یک تنظیم قاعده پایه می دهد ، من قوانین اضافی مانند eqeqeq ، prefer-template ، prefer-constو no-varرا اضافه می کنم ، که در پیکربندی توصیه شده خارج از جعبه وجود ندارد.
به غیر از اجتناب از اشکالات ناخوشایند و نوشتن کد بد ، شما می توانید با پیروی از پیشنهادات پرزها و جستجوی اسناد ESLint در مورد دلیل وجود یک قانون خاص و ضرورت آن ، دانش باورنکردنی کسب کنید.
از طرف دیگر ، Prettier اطمینان حاصل می کند که کل تیم با همان دستورالعمل های قالب بندی سبک سبک مطابقت دارند و خوانایی به دست آمده نیز در وقت شما صرفه جویی می کند. تنظیمات پیش فرض پیکربندی ارائه شده توسط Prettier در خارج از جعبه عالی است ، بنابراین من معمولاً فقط باید تنظیمات جزئی انجام دهم. این یک فایل پیکربندی حداقل .prettierrc.jsonاست که تمایل دارم با آن شروع کنم:
{
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all"
}
پس از راه اندازی ESLint و Prettier ، شما یک خط پایه اساسی از ابزارهای کیفیت کد در دسترس دارید که تجربه توسعه دهنده شما را بسیار بهبود می بخشد.
. . .
2. استفاده از وابستگی های قدیمی
بسته های مختلف پروژه شما نسخه های اصلی متعددی را پشت سر می گذارد. وابستگی های pack.json بیش از یک سال است که ارتقا نیافته است. شما می توانید به روزرسانی را به تأخیر بیندازید و امیدوار باشید که هرگز مجبور به انجام آن نخواهید شد. اما باور کنید ، به محض کاهش پشتیبانی از نسخه قدیمی Node.js یا آسیب پذیری کد جدید در وابستگی های قدیمی که از آن استفاده می کنید ، کشف خواهید شد. علاوه بر این ، شما دوست دارید از جدیدترین ویژگی های یک کتابخانه استفاده کنید ، اما نمی توانید چون با یک نسخه وابسته قدیمی گیر کرده اید.
هر زمان که من یک پروژه جدید ایجاد می کنم یا به یک پروژه موجود می پیوندم ، یکی از اولین کارهایی که انجام می دهم بررسی pack.json برای وابستگی های قدیمی است. اطمینان حاصل کنید که این وابستگی ها حداقل تا حدودی به روز هستند تا اشکالات احتمالی و آسیب پذیری های امنیتی در کتابخانه های شخص ثالث شما برطرف شود. برای پروژههای موجود، اگر یک دلیل خوب وجود دارد که چرا وابستگی تا به امروز وجود ندارد، از توسعه دهنده مسئول اصلی سوال کنید.
من شخصاً در پروژه هایی که روی آنها کار می کنم یک فایل packed.md اختصاصی ایجاد می کنم که به این شکل است:
مسائل مربوط به ارتقا وابستگی
"postcss-cli": "^7.1.2"
نسخه اصلی ۸ نیازمند postcss به عنوان وابستگی همتا میباشد که منجر به شکستگی در هنگام توسعه میشود.
"sapper": "0.28.0"
قفلشده نگه دارید تا زمانی که مسائل مربوط به CSS در v ۰.۲۸.۱ برطرف شود.
به این ترتیب ، هر یک از همکاران پروژه در مورد مسائل مربوط به ارتقا وابستگی مطلع می شوند.
همیشه هنگام بروز مشکلات وابستگی یا حل برخی از مشکلات ، این پرونده را به روز نگه دارید. در حالت ایده آل ، پرونده خالی می ماند و همه چیز می تواند مطابق انتظار ارتقا یابد.
. . .
3. نوشتن نامها و نظرات متغیر به زبانی غیر از انگلیسی
قانون ساده: اگر شما یا دیگران که کد شما را می خوانند برای درک اینکه چه اتفاقی در کد می افتد ، باید "Google Translate" را بچرخانید ، این اتلاف وقت ارزشمند توسعه است. ترجمه کد نباید بخشی از توسعه دهنده وب باشد
در پروژه MVP، نهادهایی که از طریق انتهای Node.js از MongoDB می آمدند ، برخی از زمینه ها به زبان آلمانی و برخی دیگر به انگلیسی بود ، در حالی که قسمت جلویی آن بیشتر از زبان انگلیسی استفاده می کرد. این امر مستلزم نگاشت غیرضروری زیادی از یک نامگذاری به کنوانسیون دیگر بود. استفاده از مختصر نویسه امکان پذیر نبود و به راحتی می شد فراموش کرد کدام حوزه کدام یک است. علاوه بر این ، هر توسعه دهنده ای که ممکن است به تیم بپیوندد و یک بومی زبان آلمانی نباشد ، در درک استفاده از هر زمینه مشکل دارد.
به حفظ کامل کد کد به زبان انگلیسی پایبند باشید. جدا از نام متغیرهایی که در زبانهای دیگر مانند آلمانی عجیب به نظر می رسند ، شما توسعه دهندگان بین المللی را از درک آنچه در کد اتفاق می افتد مستثنی می کنید. هر زمان که بخواهید کلمات را به زبان انگلیسی غیر از انگلیسی در رابط کاربری خود نمایش دهید ، می توانید از کتابخانه هایی مانند Format.jsبرای رفع نیازهای بین المللی استفاده کنید.
. . .
4. کنوانسیون های مختلف نامگذاری در کل پروژه
سعی کنید از مخلوط کردن نامگذاری های مختلف برای HTML ، CSS و کد JavaScript خودداری کنید. از kabab-case ، snake_case و camelCase در کل کد استفاده نکنید در غیر اینصورت سریع گیج می شوید و بهره وری خود را از دست می دهید.
درباره کنوانسیون های مختلف نامگذاری و دلیل وجود آنها بیاموزید. من به شما توصیه می کنم که به قوانین برنامه نویسی زبانی که استفاده می کنید پایبند باشید. روشهای بومی جاوا اسکریپت مانند .toLowerCase() با camelCaseنوشته شده اند ، پس چرا متغیرهای خود را با پوششهای مختلف می نویسید؟ در حالی که جاوا اسکریپت از camelCase استفاده می کند ، به یاد داشته باشید که از kabab-case برای نشانه گذاری HTML و سبک های CSS استفاده کنید.
. . .
5. استفاده از نامهای متغیر بی معنی
من مطمئن هستم که قبلاً کدی مشابه این کد مشاهده کرده اید:
?
چه مقادیری در اینجا ذخیره می شود؟ آیا Gabriel نام یا نام خانوادگی شخصی است؟ x چیست که نقشه برداری شود؟ آیا حتی یک آرایه است؟ چه چیزی متغیر را نگه می دارد؟
برای رمزگشایی از آنچه شما و دیگران نوشتید ، لازم نیست انرژی ارزشمند شناختی را هدر دهید. در عوض باید بر روی رفع اشکال و پیاده سازی ویژگی های جدید تمرکز کنید.
ممکن است فکر کنید نوشتن نام و عبارات متغیر کوتاه و رمزآلود جالب است ، اما اینگونه نیست. کدنویسی نوشتن کمترین شخصیت نیست بلکه تولید منطقی تجاری است که فهم آن آسان ، ارزشمند است و پس از نوشتن نیازی به اصلاح مجدد ندارد.
بیایید نگاهی به یک مثال خوب بیندازیم:
const firstName = 'Gabriel';
const greetings = students.map((student) => `Hello, ${student.firstName}!`);
در اینجا ، ما می توانیم خیلی بیشتر بر اساس نامگذاری و وضوح متغیرهای خوب فرض کنیم ، که به معنای سربار شناختی کمتر برای توسعه دهنده است.
خود و همكاران آینده شما متشكر خواهند بود وقتی كه هنوز بفهمند هر خط كدی چه می كند - حتی یك سال بعد.
. . .
6. خروج از console.logs و To-Dos پراکنده در سراسر کد
این به طور همزمان برای توسعه دهنده و تجربه کاربر مضر است:
Console.log(‘hello from indexing function’);
Console.Log(‘Result’,result.data);
پیام های console.log() در ابزارهای توسعه برای خواندن هر کاربر ممکن است خجالت آور و غیرحرفه ای باشد. از طرف توسعه دهنده ، پیدا کردن مواردی که باید تغییر شود بدون اطلاعات دقیق و console.log() ، که ممکن است لازم باشد یا نباشد ، باعث حواس پرتی و دلسردی می شود.
من توصیه می کنم از قانون بدون کنسول ESLint استفاده کنید و در صورت لزوم آن را پیکربندی کنید. من تمایل دارم که console.log() را به عنوان یک خطا علامت گذاری کنم و از آن در رابطه با قلاب های قبل از انجام مرحله پرز استفاده کنم تا مرتکب اشتباهات پرز نشود. هنگامی که می خواهید اطلاعات ورود به سیستم را ادامه دهید ، می توانید console.info() را برای نشان دادن هدف خاص نیاز به خروجی اطلاعات در آن نقطه استفاده کنید.
اگر نمی توانید console.logs خود را در این کد رها کنید ، می توانید افزونه ای مانند babel-plugin-transform-remove-console یا terser-webpack-plugin را انتخاب کنید تا پیام های کنسول را برای شما بر اساس محیط از بین ببرد.
کارها را ترجیحاً در ابزارهای مدیریت مخزن به صورت جداگانه در نظر بگیرید. اطمینان حاصل کنید که اطلاعات کافی را در اختیار توسعه دهنده دیگری قرار دهید تا بدون نیاز به همگام سازی با شما ، روی آن کار کند.
علاوه بر این ، هنگام ایجاد مشكلات ، هر برنامه نویس از آنها آگاه خواهد بود .
. . .
7. مخلوط کردن همگام سازی / انتظار ، وعده ها و نحو برگشت تماس
تولید اشتباهات در کد ناهمزمان می تواند به اشکالاتی منجر شود که تشخیص آنها بسیار دشوار است ، بنابراین اطمینان حاصل کنید که هر بار به یک پارادایم پایبند باشید.
بیایید نگاهی به نمونه ای از پروژه واقعی MVP بیندازیم:
export const saveLogAuthToken = async (token) => {
const jwtToken = jwt.verify(token, JWT_SECRET);
if (!jwtToken) return false;
const logoutToken = new logAuthToken({ token, expires: jwtToken.exp });
await logoutToken.save().catch((err) => {
console.log(err);
});
return true;
};
حتی برای من با بیش از چهار سال تجربه حرفه ای ، که بفهمم کد بر اساس نتایج مختلف چگونه در اینجا جریان می یابد.
مثال کد بالا دانش از دست رفته در مورد نحوه async / انتظار را نشان می دهد.
کد با کاربردهای async / انتظار شروع می شود ، که برای نوشتن کدهای خوانا و مختصر بسیار مناسب است ، اما بعد نامشخص می شود:
چه زمانی عملکرد درست می شود؟
وقتی وارد بلوک گرفتن متد logoutToken.Save() می شویم چه چیزی برمی گردد؟
با چند تغییر ساده می توان جریان کد را به شدت بهبود بخشید:
برای جلوگیری از پیام معروف UnhandledPromiseRejectionWarning در Node.js ، کد باید در بلوک try / catch قرار گیرد.
بلوک .catch()را در logoutToken.save() حذف کنید زیرا خطاها در دستور try / catch قرار می گیرند.
یا از async/ انتظار یا از نحو Promises استفاده کنید. همچنین می تواند ایده خوبی باشد که نه تنها در صورت عدم موفقیت jwt.verify() غلط بازگشت را در نظر بگیرید بلکه به جای آن به صراحت خطایی ایجاد کنید.
این اشتباهات در طراحی کد می تواند کشنده باشد - مخصوصاً وقتی هیچ آزمایشی برای این قطعه کد نوشته نشده باشد.
. . .
8. عدم تست واحد یا پایان به پایان برای منطق پیچیده تجارت
این بسیار رایج است به طوری که در بین جامعه توسعه وب یک شوخی در حال اجرا است. من هنوز به یاد دارم که در اولین کارم کار می کردم و آزمایشات واحد صفر برای پروژه نوشته شده بود. وقتی در این باره سوال کردم ، همه گفتند: "داشتن یک تست آزمایشی بسیار خوب است ، اما وقت کافی نیست."
از آنجا که آزمون های آزمایشی یا پایان به پایان برای مشتری ارزش افزوده ندارند ، اغلب از آنها صرف نظر می شود و از آنها غفلت می شود. یک عبارت رایج این است: "ما در آینده وقتی وقت خواهیم داشت این کار را انجام خواهیم داد" ، و سپس حدس بزنید چه؟ هرگز این اتفاق نمی افتد.
در شرکت دوم که من در آن کار کردم ، تقریباً هیچ تست واحدی برای قسمت جلویی پروژه نوشته نشده بود. در آن زمان ، من به عنوان یک توسعه دهنده باتجربه تر بودم و انگیزه انجام کار تیم و خودم را داشتم ، بنابراین هر وقت کار زودتر از انتظار انجام می شد ، شروع به اجرای آزمایشات واحد در اینجا و آنجا کردم.
برای یک کار که مجبور به انجام آن شدم ، موارد بسیار بالقوه زیادی وجود داشت ، بنابراین من شروع به استفاده از "توسعه آزمون محور" (TDD) کردم و تست ها را قبل از کد واقعی نوشتم. اگرچه من مجبور شدم علاوه بر منطق تجارت ، تست های واحدی را بنویسم ، اما به دلیل داشتن "کمربند ایمنی" در آزمون های واحدی که تمام خطاهای احتمالی و موارد لبه دار را به دست می آورد ، سرانجام مسئله را در حدود 30٪ سریعتر به پایان رساندم. پوشش آزمون از جستجوی اشکال در مکان نامناسب نیز جلوگیری می کند.
خط پایین: در صورت امکان تست های واحدی را بنویسید - مخصوصاً برای قطعه های پیچیده کد - و از آزمایشات پایان به انتها ، حداقل برای قسمتهای مهم یک برنامه ، استفاده کنید.
. . .
جمع بندی
اگرچه من می دانم که فشار زمانی به تنهایی می تواند دلیل برخی از توسعه دهندگان برای فراتر بردن استانداردهای کیفیت کد باشد ، اما من توصیه می کنم فشار بیاورید در حالی که هنوز در ارائه کد تمیز نهایت تلاش خود را می کنید.
حداقل زمانی که صرفاً با تکثیر قطعه کد و هک کردن آن تا زمان کار صرفه جویی می کنید ، به عنوان بدهی فنی شروع به جمع شدن می کند و پس از آن رفع آن حتی بیشتر طول می کشد.
نوشتن تمیزترین کد همیشه امکان پذیر نیست ، اما اجازه ندهید این باعث دلسردی شما شود. بالاخره ما فقط انسان هستیم و اشتباه می کنیم.
آیا قبلاً مرتکب این اشتباهات یا اشتباهات مشابه شده اید؟ در زیر نظر بدهید!
مطلبی دیگر از این انتشارات
ساختار پوشه بندی مناسب برای پروژه های مقیاس بزرگ در React.js
مطلبی دیگر از این انتشارات
من می خواهم برنامه نویس شوم - قسمت نهم
مطلبی دیگر از این انتشارات
اشتراک گذاری لوکال هاست در بستر اینترنت