10 ماه از Elm تا Angular

10 ماه از زمانی که من از Elm به TypeScript Angular رفتم می گذرد و هنوز با موارد زیر دست و پنجه نرم می کنم:
من یک مقدار بازگشتی باطل می بینم و بلافاصله از عوارض جانبی آن نگران می شوم. من فوراً میخواهم اطمینان حاصل کنم که همه کدها را از آن حذف میکنیم، وابستگیهای واقعی تزریقشده را ذخیره میکنیم، مطمئن میشویم که تمام منطق تجاری برای تابع به طور جداگانه در توابع خالص آزمایش شده است.
همکاران من، که بسیاری از آنها در Side Effects Are Ok Actually Ville® بزرگ شدهاند، طیفی از واکنشها از کنجکاوی خفیف فکری گرفته تا ترحم واقعی برای من دارند. همه ما حول آزمایش کامل به عنوان یک نقطه تجمع گالوانیزه می کنیم که خوب است.
من عمداً از همه جاسوسها و تمسخرها اجتناب کردهام، و فقط در آزمونهای واحد در حد عقل، از مقالههای خرد استفاده میکنم. من مطمئن هستم که عوارض جانبی واقعی توسط آزمون های پذیرش در سرو پوشش داده می شود. من روش خود را در اینجا کمی شل کرده ام زیرا برخی از عوارض جانبی به راحتی قابل آزمایش نیستند (هنوز، در لیست من، خوب!) در Cypress. به عنوان مثال می توان به ثبت تجزیه و تحلیل و معیارها در New Relic یا ارسال بارهای بسیار مهم در RxJS BehaviorSubjects اشاره کرد.
با این اوصاف، من تمام تلاش خود را میکنم تا مطمئن شوم که تمام آن آزمایشهای عوارض جانبی به تنهایی انجام میشوند و تعداد کمی از آنها عمداً وجود دارد، زیرا 90٪ کد خالص است. این در یک زبان مبتنی بر کلاس که در آن انواع از TypeScript بسیار پیشرفت کردهاند، بسیار چالش برانگیز است، ایجاد توابع/روشهای کلاسی که void را برمیگردانند، بسیار آسان میکند، اما بقیه موارد کاملاً خوب تایپ میشوند. علاوه بر این، به نظر میرسد که «تغییرناپذیری بهطور پیشفرض» در اینجا یک امر فرهنگی است، و فکر نمیکنم فقط به این دلیل باشد که تعداد کمی از React آمدهاند. کلمه کلیدی فقط خواندنی به سختی یافت می شود. با این حال، در آزمایشهای واحد، جهشهای فراوانی را یا بهطور غیرمستقیم از طریق استفاده از جاسوسهای Jest یا به طور ضمنی از طریق مسخرههای دستی دیدهام.
من به طور مداوم کدی را می بینم که پس از آزمایش/آزمایش آخرین آزمایش انجام شده است. در حالی که من در یک تیم پلتفرم هستم و فقط یک رهبر فنی برای تیم خود هستم، هنوز هم مسئول انجام یک دوره گردی با همکاران هستم تا روابط عمومی را در پلتفرم ما از تیم های متعدد دیگر بررسی کنم. وقتی با چنین کدهایی روبرو می شوم، معمولاً کتابی می نویسم که برای زمینه روابط عمومی سفارشی شده است، تا به توسعه دهنده کمک کنم تا زندگی آزمایشی خود را آسان تر کند، و امیدوارم تعمیر و نگهداری کد را نیز انجام دهد.
برخی از مشکلات سندرم کپی پیست است که موافقان و مخالفانی دارد. نکات حرفه ای این است که ما راه های استاندارد مختلفی برای انجام کارها در قلمرو Angular خود داریم، و به همین دلیل کدهای زیادی را ارائه می دهد که تیم های مختلف می توانند از آن استخراج کنند که عالی است. با این حال، مشکل این است که برخی از آن “راه های انجام کارها” عالی نیستند. به طور خاص، بسیاری از آنها منطق تجاری و اثرات جانبی را با هم ترکیب میکنند و این کد را به چالشی برای تست واحد تبدیل میکند. در اینجا هیچ طرف گناهکاری وجود ندارد، فقط بسیاری از کسانی که یا هرگز این را نمی دانستند، یا مجبور نبوده اند که یک تست را با 20 مسخره فقط برای آزمایش 1 خط کد انجام دهند، سپس باید به تغییرات داخلی و کل آزمایش بروند. تعطیلات سوئیت
… اما به هر حال به تلاش ادامه می دهم. تعداد کمی، تعداد کمی، از کمک ابراز قدردانی کرده اند، بنابراین من به راه خود ادامه می دهم.
ما چند مورد داشتیم که نیاز به ایجاد قابلیتهای جدید داشتیم و میتوانید ببینید که برخی از همکاران من، یا برخی از توسعهدهندگان React که به پلتفرم ما منتقل شدهاند، روشی کاربردی برای انجام کارها دارند (مثلاً فقط توابع و انواع ، بدون کلاس، عوارض جانبی بسیار کمی گنجانده شده است). این امر بررسی کد را بسیار سخت میکند، زیرا از یک سو، Angular دارای یک API عمومی است که تقریباً یک دهه کار کرده است، بهروزرسانیها بسیار خوب پیش میروند، و همه ما از روش تجویزی برای ساخت مؤلفههای UI پیروی میکنیم. اما فراتر از اجزای UI، شما در جزئیات پیاده سازی انعطاف پذیری دارید. بله، تزریقات شما باید کلاسی باشند، اما جزئیات پیاده سازی اینطور نیست. وقتی ابتدا آزمایش را شروع میکنید و عمداً سعی میکنید منطق کسبوکار خود را با رندر اثرات جانبی/UI اجتناب کنید، متوجه میشوید که کلاسها شروع به ارزش صفر میکنند. بسیاری از آنها فقط روش های ثابت و بدون حالت هستند. مرحله بعدی فقط استفاده از توابع است.
برای کامپوننتها، مطمئناً، کلاسها برای آنها کار میکنند “زیرا Angular”، اما همچنین، آنها حالت دارند، بنابراین خوب است. از نظر تئوری عالی به نظر می رسد که “سیگنال ها را برای این نوع چیزها و RxJS را برای این نوع چیزها انتخاب کنید”، اما داشتن راه دیگری برای انجام کاری دارای معاوضه هایی است که ثبات را کاهش می دهد. این به این معنی است که خواندن کد کند میشود، زیرا نحوه برخورد کسی با چیزی از بخش به بخش دیگر متفاوت است. برخی از این پیاده سازی ها ممکن است معتبر، و بهتر، درست باشند، اما این هزینه دارد. من دائماً تلاش میکنم «راه زاویهای وجود دارد، و بعد این کار کاربردی سادهای که شما انجام دادید وجود دارد» و ما این موارد را بسیار بررسی میکنیم و مطمئن میشویم که دیگر برنامهنویسان روی پلتفرم آن را بکار میبرند، حفر میکنند و به طور مداوم از آن استفاده میکنند. سخت است.
خیلی بد است آزمایشی که Angular انجام داد تا کدشان شبیه Vue/Svelte به نظر برسد، جایی که هیچ کلاسی در آن استفاده نمیشد، و فقط توابع و بیتهای چارچوب قابل استفاده مجدد به سبک هوک بودند که هرگز به جایی نرسیدند. اگر به تکامل Angular نگاه کنید، به نظر می رسد که آنها دقیقاً همان سبک را ادامه می دهند، و فقط زیربناها را تغییر می دهند (حذف NgZone) + اضافه کردن چند نمونه اولیه مانند سیگنال ها. بنابراین “OOP خوب تایپ شده با تغییرناپذیری” به نظر می رسد که برای سال های آینده اینجا خواهد بود. این … غم انگیز است.
این احتمالاً بدترین و دردناک ترین توضیح برای من در زندگی حرفه ای ام برای دیگران است. از Elm و ReScript میآییم، سیستمهایی از نوع فوقالعاده قدرتمند داریم که کاملاً سالم یا نزدیک به صدا هستند. ReScript به طور خاص به تدریج مانند TypeScript تایپ می شود، اما بسیار دقیق تر و دقیق تر. واقعاً مفهومی از “any” TypeScript در هیچ یک از زبانها وجود ندارد، اما ReScript به اندازه کافی مقادیر ابتدایی سطح پایینتر را به شما میدهد که مانند یک TypeScript ناشناخته احساس میکنند که به نوبه خود منجر به خطاهای کامپایلر فراوان میشود، که خوب است. وقتی کامپایل شد، احساس امنیت می کنید.
این را با TypeScript مقایسه کنید، و any و “as MyType” در همه جا استفاده می شود. هر یک به دلایل معتبر مختلفی استفاده می شود: برنامه نویسی مبتنی بر نوع آموزش داده نشده است، آنچه می توانید با انواع انجام دهید، نحوه خواندن انواع، نحوه ایجاد انواع خود، آنها باید از ناشناخته استفاده کنند، اگر واقعا این کار را نمی کنند. نمی دانم و غیره
و استفاده از “as MyThing” به این دلیل است که باریک شدن نوع TypeScript بسیار دردناک است. شما باید در مورد توابع و اپراتورهای جاوا اسکریپت سطح پایین casting اطلاعات داشته باشید و آنها را به ترتیب خاصی انجام دهید تا کامپایلر به شما بینشی در مورد اینکه کجا باید ادامه دهید را بدهد. ROI به نظر نمی رسد برای کسی که من را نجات دهد وجود دارد. فکر میکنم این به این دلیل است که من سالها در زبانهای پویا و تایپشده گذراندهام و به دلیل کمبود انواع قوی، در دنیایی زندگی کردم که در آن تایپها تضمین میکردند که همیشه مشکل یک شخص پشتیبان است (یا… گاه به گاه. شرایط مسابقه)، بنابراین من دیده ام که اگر تلاش کنید، چقدر چیزهای خوبی می تواند باشد. برای مبارزه با این، من سعی کردم به شدت با Zod پیشرو باشم که تمام تبدیل نوع دردناک TypeScript را با 1 خط کد برطرف می کند.
چیزی که من نتوانستم بفهمم همه نوع ریخته گری ناامن و استفاده زیاد از Partial است. نوع ریختهگری به این دلیل است که ایجاد برخی از انواع/رابطهای بزرگتر مورد نیاز برای آزمایشهای واحد بهویژه بسیار دردناک است. ایده ایجاد توابع برای ایجاد انواع ایمن مانند شما در Elm/ReScript/Scala و غیره در اینجا عادی نشده است. «شرایط غیرممکن را غیرممکن کن» دائماً یک چیز جدید است که عالی است، اما در عین حال گویا. فشار ضربالاجل معمولاً هر چیزی را که فوراً مفید نیست، بیرون میکشد، که من دریافت میکنم. بنابراین، با توجه به اینکه TypeScript نیز یک زبان تایپ ساختاری است، آنها یک شی می سازند که “به اندازه کافی نزدیک” است و فقط از “as MyType” و voila استفاده می کند، TypeScript خوشحال است (خاموش است، اما… هی، خوشحال است و آزمون می گذرد. ). من تاکتیکهای مختلفی را در اینجا امتحان کردهام، و کمک چندانی به شما نمیکند.
جزئی هم آزار دهنده است. دلیل موجه این است که برخی از بارهای JSON تایپ شده ای که دریافت می کنیم به دلایلی غول پیکر هستند و توسعه دهندگان معمولاً فقط به قطعات کوچک نیاز دارند بنابراین از چیزهایی مانند Partial یا Pick برای آسان کردن تست و کدنویسی استفاده می کنند. TypeScript داده شده از مقادیر اختیاری پشتیبانی می کند، مانند Maybe در Elm یا Option در ReScript، و بسیاری از مقادیر به مقادیر پیش فرض نیاز ندارند زیرا Angular et all فقط به یک رشته خالی تبدیل می شوند. آنها درد مشابهی با زبانهای FP ندارند. خوانایی و درد نگهداری؟ بله، آن هم آنجاست.
در حالی که من طرفدار معماری شش ضلعی/پیازی نیستم، فکر میکنم برخی از آداپتورهای اینجا برای تبدیل JSON بکاند که ما به انواع رابط کاربری مفید دریافت میکنیم، بسیار کمک خواهد کرد. استفاده از انواع سادهتر، سفارشی برای نماهای UI شما ساخته شده است، و در 1 خط کد به JSON باز میگردند، زمانی که ما نیاز به ارسال چیزی به بکاند داریم. در حال حاضر ما با بک اند خود ازدواج کرده ایم که برای رابط کاربری طراحی نشده است، بنابراین کار با JSON سخت است. این یک سال طول می کشد. شاید باید تلاش کنم، idk.
به هر حال، احساس میکنم دارم کمک میکنم، اما… خشن است، درست است، اما نه بهعنوان «امگ من هر روز بدبخت خواهم شد». من از همکارانم لذت می برم، از کمک به همه کدنویس ها لذت می برم و آنها هم به من چیزهایی یاد می دهند. با این حال، من هنوز پروژه های جانبی را در Elm و ReScript انجام می دهم تا به خودم یادآوری کنم که برای چه چیزی فیلمبرداری می کنیم.