Front-end entropy ही वास्तव आहे. कोडबेस एका रात्रीत कोसळत नाही. तो साचत जातो. एका मंगळवारी तुम्ही एक date-formatting library जोडता. सहा महिन्यांनंतर कोणीतरी दुसरी जोडतो कारण त्यांना पहिली सापडत नाही. तुम्ही आता सपोर्ट न करता येणाऱ्या ब्राउझर्ससाठी polyfills साचत जातात. Build tools एकमेकांवर थरारत जातात. अखेरीस, node_modules फोल्डर हे एका डिजिटल कचरा पेटीसारखे (junk drawer) बनते, जिथे भीतीपोटी काहीही फेकून देता येत नाही. तुम्ही अपडेट करणे थांबवता. मग तुम्ही पाहणेही थांबवता. तेव्हा प्रत्येक छोटा बदल हा एक जुगार ठरतो.
एका जुन्या प्रोजेक्टमध्ये Material UI अपडेट करण्याचा प्रयत्न करताना मला या अडचणीचा सामना करावा लागला. मी package.json उघडले आणि त्यातील अर्ध्या नोंदी तर मला ओळखताही आल्या नाहीत. डझनभर लायब्ररीज तिथे होत्या, काही वर्षे जुन्या होत्या, तर काही इतक्या अज्ञात होत्या की त्या कोणी आणि का जोडल्या आहेत हे शोधण्यासाठी मला git blame तपासावे लागले. मी नवीन Material UI व्हर्जनसाठी install कमांड चालवली आणि टर्मिनल peer dependency चे इशारे (warnings) देऊन भरून गेले. मला अपडेट करायचा असलेला पॅकेज ठीक होता, पण त्याच्या आसपासचे इकोसिस्टम (ecosystem) नव्हते. मला जाणवले की मी अपग्रेड करत नव्हतो, तर मी एखाद्या पडक्या अवशेषांचे उत्खनन करत होतो.
या गोंधळामुळे होणारा खर्च अभिमानापेक्षा जास्त असतो
Dependencies कडे दुर्लक्ष करणे ही केवळ बाह्य समस्या नाही. त्यामुळे वास्तविक आणि महागड्या समस्या निर्माण होतात.
Security risks (सुरक्षा धोके) हे स्पष्ट संकट आहे. सोडून दिलेल्या (abandoned) पॅकेजेसमध्ये अशा त्रुटी (vulnerabilities) असतात ज्या स्कॅनर्स दर आठवड्याला सूचित करतात. त्याहून वाईट म्हणजे, तुम्ही थेट इंस्टॉल केलेल्या लायब्ररीज कदाचित ठीक असतील, पण त्यांनी ओढलेल्या transitive dependencies कदाचित नसतील. तुम्हाला नकळत दुसऱ्याचे तांत्रिक कर्ज (technical debt) स्वीकारावे लागते.
Cost compounds with distance (वेळोवेळी वाढणारा खर्च). तुम्ही जितका जास्त वेळ थांबाल, तितका व्हर्जनमधील फरक वाढत जाईल. React च्या एका major व्हर्जनचा फरक हाताळणे हे काम आहे. पण तीन व्हर्जनचा फरक हा एक मायग्रेशन प्रोजेक्ट बनतो जो अनेक आठवडे खाऊ शकतो. तुम्हाला बग फिक्सेस, परफॉर्मन्स सुधारणा आणि आधुनिक टूल्ससोबतची सुसंगतता (compatibility) मिळत नाही. टीम शेवटी अशा मर्यादांच्या भोवती काम करू लागते ज्या आता अस्तित्वातच नाहीत.
Libraries die (लायब्ररीज कालबाह्य होतात). ज्या पॅकेजचे मेंटेनर्स सक्रिय नाहीत, ते आपोआप तुमचे खाजगी फोर्क (private fork) बनते. जेव्हा ते बिघडते, तेव्हा मध्यरात्री त्याचा मिनिफाइड सोर्स कोड (minified source code) वाचण्याचे काम तुम्हालाच करावे लागते. समुदाय (community) अधिक चांगल्या उपायांकडे वळलेला असतो आणि तुमची टीम एका मृत लायब्ररीला मेंटेन करण्यात अडकलेली असते.
Velocity craters (कामाचा वेग मंदावतो). नवीन डेव्हलपर्स त्यांचे पहिले काही दिवस अशा विचित्र APIs शिकण्यात घालवतात ज्यांची जागा आता वेब स्टँडर्ड्स किंवा मुख्य प्रवाहात असलेल्या पर्यायांनी घेतली आहे. फीचर्स रिलीज करण्याऐवजी, तुमचे सिनियर इंजिनिअर्स इतिहासकार बनतात, जे हे स्पष्ट करतात की हा प्रोजेक्ट अजूनही २०१५ मधील टास्क रनर का वापरत आहे.
एकही व्हर्जन बदलण्यापूर्वी ऑडिट करा
सर्वात मोठी चूक म्हणजे सर्व काही अपडेट करून टेस्ट पास होतील अशी आशा करणे. ऑडिटने सुरुवात करा. package.json घ्या आणि प्रत्येक एन्ट्रीची चौकशी करा.
चार प्रश्न विचारा:
- हे काय समस्या सोडवते?
- आपण याचा नेमका वापर कुठे करतो?
- याची अजूनही गरज आहे का?
- आता यापेक्षा चांगला पर्याय उपलब्ध आहे का?
तुम्हाला अनावश्यक गोष्टी (redundancy) आढळतील. कदाचित moment आणि date-fns दोन्ही लिस्टमध्ये असतील कारण दोन डेव्हलपर्सनी वेगवेगळ्या वेळी एकच समस्या सोडवली असेल. कदाचित Internet Explorer साठीचा polyfill अजूनही तिथे असेल, जरी तुमचे ॲनालिटिक्स दाखवत असतील की लेगसी ब्राउझर्सकडून शून्य ट्रॅफिक येत आहे. कदाचित fetch वरील कस्टम रॅपर (custom wrapper) डिलीट करता येईल कारण आधुनिक ब्राउझर्स हे edge cases मूळतः हाताळतात.
कधीकधी अपडेट करण्यापेक्षा रिप्लेसमेंट करणे जास्त फायदेशीर ठरते. तीन वर्षांच्या ब्रेकिंग चेंजेससह एका जुन्या चार्टिंग लायब्ररीशी झुंजण्यापेक्षा, एक स्थिर पर्याय वापरणे आणि काही कंपोनंट्स पुन्हा तयार करणे जास्त सोपे असू शकते. काही गोष्टी काढून टाकण्यास तयार राहा.
अदृश्य स्तर: Transitive Dependencies आणि Semver
Direct dependencies हा हिमखंडाचा (iceberg) केवळ दिसणारा भाग आहे. खरा भार खालील transitive dependencies मध्ये असतो, म्हणजेच ते पॅकेजेस ज्यांची तुमच्या पॅकेजेसना गरज असते. तुम्ही ते निवडलेले नसतात, पण ते तुमच्या बिल्डमध्ये कार्यान्वित होतात. ते तुमच्या बंडलचा आकार वाढवतात, अटॅक सरफेस (attack surface) वाढवतात आणि कधीकधी एकमेकांशी अशा प्रकारे संघर्ष करतात की ज्यामुळे गुंतागुंतीच्या बिल्ड एरर्स (build errors) येतात.
तुम्हाला semantic versioning चा अर्थ तो काय आहे यानुसार समजून घेणे आवश्यक आहे, तो काय असावा या आशेने नाही.
- Major updates: हे मायग्रेशन आहेत. जोपर्यंत अन्यथा सिद्ध होत नाही तोपर्यंत त्यांना ब्रेकिंग चेंजेस (breaking changes) समजा. changelog वाचा, वेळ राखून ठेवा आणि पूर्णपणे टेस्ट करा.
- Minor updates: हे नवीन फीचर्स जोडतात. ते सूक्ष्म पद्धतीने वर्तन (behavior) देखील बदलू शकतात. ते विनामूल्य किंवा विनासायास आहेत असे समजू नका.
- Patch updates: हे बग्स फिक्स करतात. ते सहसा सुरक्षित असतात, पण जर तुमचा कोड त्या बगवर अवलंबून असेल, किंवा जर पॅचने तुम्ही monkey-patching केलेला एखादा अंतर्गत भाग बदलला असेल, तर तुमचे कोड बिघडू शकते.
नियम माहित असल्यास, कोणत्याही गोष्टीला स्पर्श करण्यापूर्वी तुम्हाला धोक्याचे वर्गीकरण करण्यास मदत होते.
तुमच्या टूल्सचा वापर एका कारागिराप्रमाणे करा
जर तुम्ही Yarn वापरत असाल, तर काही इन-बिल्ट कमांड्स केवळ अंदाज लावण्याऐवजी एक प्रक्रिया तयार करतात.
प्रथम yarn outdated चालवा. हे तुम्हाला काय बदलले आहे याचा स्नॅपशॉट देते
