
जावास्क्रिप्ट डायनामिक टाइपिंग वाली भाषाओं में से एक है। ऐसी भाषाएं तेजी से अनुप्रयोग विकास के लिए सुविधाजनक हैं, लेकिन जब कई टीमें एक बड़ी परियोजना का विकास करती हैं, तो शुरू से ही एक प्रकार के चेकिंग टूल को चुनना बेहतर होता है।
आप टाइपस्क्रिप्ट कोड विकसित करना शुरू कर सकते हैं या इसे फ्लो प्रोजेक्ट में शामिल कर सकते हैं। टाइपस्क्रिप्ट Microsoft द्वारा विकसित जावास्क्रिप्ट का एक संकलित संस्करण है। टाइपस्क्रिप्ट के विपरीत प्रवाह, एक भाषा नहीं है, लेकिन एक उपकरण है जो आपको कोड का विश्लेषण करने और प्रकारों की जांच करने की अनुमति देता है। आप इन तरीकों के बारे में नेट पर कई लेख और वीडियो पा सकते हैं, साथ ही टाइपिंग का उपयोग कैसे शुरू करें, इस बारे में एक गाइड। इस लेख में हम आपको यह बताना चाहते हैं कि फ्लो हमें पसंद क्यों नहीं आया और हमने टाइपस्क्रिप्ट में कैसे स्विच करना शुरू किया।
थोड़ा सा इतिहास
2016 में, हमने अपने ईसीएम सिस्टम के लिए एक रिएक्ट / रेडक्स-आधारित वेब क्लाइंट विकसित करना शुरू किया। निम्न कारणों से टाइपिंग का परीक्षण करने के लिए फ्लो का चयन किया गया था:
- रिएक्ट और फ्लो एक ही कंपनी फेसबुक के उत्पाद हैं।
- प्रवाह अधिक सक्रिय रूप से विकसित हुआ।
- प्रवाह आसानी से परियोजना में एकीकृत है।
लेकिन परियोजना बढ़ी, विकास टीमों की संख्या में वृद्धि हुई, और फ़्लो का उपयोग करते समय कई समस्याएं सामने आईं:
- पृष्ठभूमि प्रकार की जाँच प्रवाह ने कई पीसी संसाधनों का उपयोग किया। नतीजतन, कुछ डेवलपर्स ने इसे बंद कर दिया और आवश्यकतानुसार चेक करना शुरू कर दिया।
- ऐसी परिस्थितियां थीं जब कोड को प्रवाह में लाने के लिए कोड के रूप में स्वयं को लिखने में अधिक समय लगता था।
- कोड प्रोजेक्ट में दिखाई देने लगा, केवल फ्लो टेस्ट पास करने के लिए। उदाहरण के लिए, अशक्त के लिए दोहरी जाँच:
foo() { if (this.activeFormContainer == null) { return; }
- अधिकांश डेवलपर्स ने विज़ुअल स्टूडियो कोड कोड संपादक का उपयोग किया, जिसमें फ्लो में टाइपस्क्रिप्ट के रूप में अच्छा समर्थन नहीं है। स्वतः पूर्णता (IntelliSense) हमेशा विकास के दौरान काम नहीं करता था, और कोड नेविगेशन अस्थिर था। मैं विजुअल स्टूडियो में C # लिखते समय उसी तरह की विकास सुविधा देना चाहूंगा।
कुछ डेवलपर्स को टाइपस्क्रिप्ट पर स्विच करने का प्रयास करने का विचार था। संक्रमण के विचार का परीक्षण करने और प्रबंधन को समझाने के लिए, हमने प्रोटोटाइप की कोशिश करने का फैसला किया।
प्रोटोटाइप
हम प्रोटोटाइप पर दो विचारों का परीक्षण करना चाहते थे:
- पूरे प्रोजेक्ट का अनुवाद करने की कोशिश करें।
- प्रोजेक्ट सेट अप करें ताकि आप समानांतर में फ्लो और टाइपस्क्रिप्ट दोनों का उपयोग कर सकें।
पहले विचार के लिए, एक उपयोगिता की आवश्यकता थी जो सभी प्रोजेक्ट फ़ाइलों को परिवर्तित कर देगी। नेटवर्क पर इनमें से एक पाया गया। विवरण के अनुसार, वह सबसे अधिक अनुवाद कर सकती है, लेकिन कुछ बदलावों को स्वयं संपादित करना होगा, या उपयोगिता को स्वयं जोड़ना होगा। हम कम संख्या में फ़ाइलों के साथ एक परीक्षण परियोजना को बदलने में सक्षम थे। लेकिन वास्तविक परियोजना संकलित नहीं की जा सकती थी, बहुत सारी फाइलों को संपादित करना आवश्यक था। हमने इस दिशा में आगे नहीं बढ़ने का निर्णय लिया, जैसे:
- अभी बहुत कुछ किया जाना बाकी था! और जब हम परियोजना को अंतिम रूप देंगे, शेष टीमें नई कार्यक्षमता विकसित करना, बग को ठीक करना, परीक्षण लिखना जारी रखेंगी। इसके अलावा, फ़ाइलों को मर्ज करने में बहुत समय लगेगा।
- यहां तक कि अगर हमने इस तरह से परियोजना का अनुवाद किया है, तो हमारे परीक्षकों को कितना काम करना होगा!
यद्यपि हमने इस विकल्प को छोड़ दिया, लेकिन हमने इस पर उपयोगी अनुभव प्राप्त किया। यह स्पष्ट हो गया कि प्रत्येक फ़ाइल का अनुवाद करने के लिए अनुमानित कार्य की आवश्यकता है। यहाँ एक सरल प्रतिक्रिया घटक का अनुवाद कैसा दिखता है।

जैसा कि आप देख सकते हैं, बहुत सारे बदलाव नहीं हैं। मूल रूप से, वे इस प्रकार हैं:
- निकालें // @ प्रवाह;
- एक अधिक परिचित इंटरफ़ेस के साथ प्रकार बदलें;
- पहुँच संशोधक जोड़ें;
- ts पुस्तकालयों से प्रकारों को बदलें (उदाहरण के लिए चित्र में: ईवेंट हैंडलर और स्वयं ईवेंट)।
दूसरे विचार पर कार्यान्वयन आगे के विकास की अनुमति देगा, लेकिन पहले से ही टाइपस्क्रिप्ट पर, और पृष्ठभूमि में मौजूदा कोड बेस को धीरे-धीरे अनुवाद करने के लिए। इससे कई फायदे हुए:
- अनुवाद करने में आसान, कुछ याद किए बिना डर।
- परीक्षण करने में आसान।
- परिवर्तनों को मर्ज करना आसान है।
लेकिन यह पूरी तरह से स्पष्ट नहीं था कि परियोजना को समानांतर में दो प्रकार के साथ काम करने के लिए कॉन्फ़िगर किया जा सकता है या नहीं। इंटरनेट पर एक खोज से कुछ भी ठोस नहीं हुआ, इसलिए उन्होंने इसे स्वयं सुलझाना शुरू कर दिया। सिद्धांत रूप में, फ्लो एनालाइज़र केवल js / jsx एक्सटेंशन वाली फ़ाइलों की जाँच करता है और एक टिप्पणी करता है:
टाइपस्क्रिप्ट कंपाइलर के लिए, फाइलों में एक्सटेंशन ts / tsx होना चाहिए। जिससे यह इस प्रकार है कि टाइपिंग के लिए दोनों दृष्टिकोण एक साथ काम करना चाहिए और एक दूसरे के साथ हस्तक्षेप नहीं करना चाहिए। इसके आधार पर, हमने परियोजना का वातावरण तैयार किया। पहले प्रोटोटाइप के अनुभव का उपयोग करते हुए, हमने कुछ फ़ाइलों का अनुवाद किया। परियोजना को संकलित किया, ग्राहक को लॉन्च किया - सब कुछ पहले की तरह काम किया!
हरी बत्ती
और एक ठीक दिन - स्प्रिंट प्लानिंग का दिन, हमारी टीम के पास काम की निम्नलिखित सूची के साथ, बैकलॉग में एक उपयोगकर्ता कहानी "टाइपस्क्रिप्ट पर स्विच करना शुरू करें" है:
- वेबपैक सेट करें।
- Tslint कॉन्फ़िगर करें।
- एक परीक्षण वातावरण सेट करें।
- टाइपस्क्रिप्ट में फ़ाइलों का अनुवाद करें।
वेबपैक सेटअप
पहला कदम यह है कि webpack को ts / tsx एक्सटेंशन के साथ फाइल को कैसे हैंडल करना है। ऐसा करने के लिए, हमने कॉन्फ़िगरेशन फ़ाइल के नियम अनुभाग में एक नियम जोड़ा। मूल रूप से इस्तेमाल किया ts-loader:
असेंबली को गति देने के लिए,
transpileOnly: true
चेकिंग को बंद कर दिया गया था:
transpileOnly: true
, क्योंकि कोड लिखते समय आईडीई पहले से ही त्रुटियों को इंगित करता है।
लेकिन जब हमने अपने Redux कार्यों का अनुवाद करना शुरू किया, तो यह स्पष्ट हो गया कि उन्हें काम करने के लिए
बैबल-प्लगइन-ट्रांसफॉर्म-क्लास-डिस्प्ले-नेम प्लगइन की आवश्यकता है। यह प्लगइन सभी वर्गों के लिए एक स्थिर डिस्प्लेनाम प्रॉपर्टी जोड़ता है। अनुवाद के बाद, केवल ts-loader क्रियाओं को संसाधित किया गया था, और इसने उन पर बैबिल प्लगइन्स को लागू नहीं होने दिया। परिणामस्वरूप, हमने ts-loader को छोड़ दिया और
babel / प्रीसेट-टाइपस्क्रिप्ट जोड़कर js / jsx के लिए मौजूदा नियम को बढ़ा दिया:
टाइपस्क्रिप्ट कंपाइलर को सही तरीके से काम करने के लिए, आपको tsconfig.json कॉन्फ़िगरेशन फ़ाइल को जोड़ने की आवश्यकता है, यह प्रलेखन से लिया गया था।
Tslint कॉन्फ़िगर करें
प्रवाह का उपयोग करते हुए लिखे गए कोड को एसेलिंट का उपयोग करके अतिरिक्त रूप से जांचा गया। टाइपस्क्रिप्ट में इसका समकक्ष, tslint है। प्रारंभ में, मैं सभी नियमों को एस्लिंट से tslint में स्थानांतरित करना चाहता था। Tslint-eslint-rules प्लगइन के माध्यम से नियमों को सिंक्रनाइज़ करने का प्रयास किया गया था, लेकिन अधिकांश नियम समर्थित नहीं हैं। टाइपस्क्रिप्ट-एस्लिंट-पार्सर का उपयोग करके ts फ़ाइलों की जांच करने के लिए एस्लिंट का उपयोग करना भी संभव है। लेकिन, दुर्भाग्य से, केवल एक पार्सर को एस्लिंट से जोड़ा जा सकता है। यदि आप सभी प्रकार की फ़ाइलों के लिए केवल ts-parser का उपयोग करते हैं, तो js फ़ाइलों और ts दोनों में बहुत सारी अजीब त्रुटियाँ दिखाई देती हैं। परिणामस्वरूप, हमने नियमों के अनुशंसित सेट का उपयोग किया, अपनी आवश्यकताओं के लिए विस्तारित किया:
// tslint.json "extends": ["tslint:recommended", "tslint-react"]
टाइपस्क्रिप्ट में एक फ़ाइल का अनुवाद करें
अब सब कुछ तैयार है, और आप फ़ाइलों का अनुवाद शुरू कर सकते हैं। शुरू करने के लिए, हमने एक छोटे रिएक्ट-घटक को स्थानांतरित करने का फैसला किया, जिसका उपयोग पूरे प्रोजेक्ट में किया जाता है। विकल्प "बटन" घटक पर गिर गया।

हमें अनुवाद प्रक्रिया के दौरान एक समस्या का सामना करना पड़ा: सभी तीसरे पक्ष के पुस्तकालयों में टाइपस्क्रिप्ट टाइपिंग नहीं होती है, उदाहरण के लिए, बेज-सीएन-लाइट। Microsoft से
TypeSearch संसाधन पर, इसके लिए टाइप लाइब्रेरी नहीं मिली। लगभग सभी आवश्यक पुस्तकालयों के लिए, हमने ts प्रकार के पुस्तकालयों को पाया और उनसे जुड़ा। एक समाधान आवश्यकता के माध्यम से कनेक्ट करना था:
const b = require('bem-cn-lite');
लेकिन एक ही समय में, प्रकार की कमी के साथ समस्या हल नहीं हुई थी। इसलिए, हमने
dts-gen उपयोगिता का उपयोग करते हुए, स्वयं प्रकारों के लिए एक "स्टब" उत्पन्न किया:
dts-gen -m bem-cn-lite
उपयोगिता ने एक्सटेंशन .d.ts के साथ एक फ़ाइल तैयार की है। फ़ाइल @types फ़ोल्डर में रखी गई थी और tsconfig.json को कॉन्फ़िगर किया गया था:
// tsconfig.json "typeRoots": [ "./@types", "./node_modules/@types" ]
अगला, प्रोटोटाइप के साथ सादृश्य द्वारा, हमने घटक का अनुवाद किया। परियोजना को संकलित किया, क्लाइंट को लॉन्च किया - यह सब काम किया! लेकिन परीक्षण टूट गए।
परीक्षण पर्यावरण सेटअप
एप्लिकेशन का परीक्षण करने के लिए, हम स्टोरीबुक और मोचा का उपयोग करते हैं।
स्टोरीबुक का उपयोग दृश्य प्रतिगमन परीक्षण (
लेख ) के लिए किया जाता है। परियोजना की तरह, यह वेबपैक का उपयोग करके बनाया गया है और इसकी अपनी कॉन्फ़िगरेशन फ़ाइल है। इसलिए, ts / tsx फ़ाइलों के साथ काम करने के लिए, इसे प्रोजेक्ट के कॉन्फ़िगरेशन के साथ सादृश्य द्वारा कॉन्फ़िगर किया जाना था।
जबकि हमने परियोजना के निर्माण के लिए ts-loader का उपयोग किया, हमने मोचा परीक्षण चलाना बंद कर दिया। इस समस्या को हल करने के लिए, परीक्षण वातावरण में ts-node जोड़ें:
// mocha.opts --require @babel/polyfill --require @babel/register --require test/index.js --require tsconfig-paths/register --require ts-node/register/transpile-only --recursive --reporter mochawesome --reporter-options reportDir=../../bin/TestResults,reportName=js-test-results,inlineAssets=true --exit
लेकिन बाबेल पर स्विच करने के बाद, आप इससे छुटकारा पा सकते थे।
समस्याओं
अनुवाद प्रक्रिया में, हमें जटिलता की बदलती डिग्री की बड़ी संख्या में समस्याओं का सामना करना पड़ा। वे मुख्य रूप से टाइपस्क्रिप्ट के साथ हमारे अनुभव की कमी से संबंधित थे। यहाँ उनमें से कुछ हैं:
- विभिन्न फ़ाइल प्रकारों से घटक / फ़ंक्शन आयात करें।
- उच्च क्रम के घटकों का अनुवाद।
- परिवर्तन इतिहास का नुकसान।
विभिन्न फ़ाइल प्रकारों से घटक / फ़ंक्शन आयात करें
विभिन्न फ़ाइल प्रकारों से घटकों / कार्यों का उपयोग करते समय, फ़ाइल एक्सटेंशन को निर्दिष्ट करना आवश्यक हो गया:
import { foo } from './utils.ts'
यह आपको वेबपैक और एस्लिंट कॉन्फ़िगरेशन फ़ाइलों में मान्य एक्सटेंशन जोड़ने की अनुमति देता है:
उच्च क्रम के घटकों का अनुवाद
सभी फ़ाइल प्रकारों में, हायर-ऑर्डर कंपोनेंट (HOC) के अनुवाद से सबसे अधिक समस्याएँ हुईं। यह एक फ़ंक्शन है जो इनपुट पर एक घटक लेता है और एक नया घटक देता है। इसका उपयोग मुख्य रूप से तर्क का पुन: उपयोग करने के लिए किया जाता है, उदाहरण के लिए, यह एक ऐसा कार्य हो सकता है जो तत्वों का चयन करने की क्षमता जोड़ता है:
const MyComponentWithSeletedItem = withSelectedItem(MyComponent);
या Redux लाइब्रेरी से सबसे प्रसिद्ध कनेक्ट। ऐसे कार्यों का टाइपिंग तुच्छ नहीं है और उन्हें प्रकारों के साथ काम करने के लिए एक अतिरिक्त पुस्तकालय को जोड़ने की आवश्यकता होती है। मैंने अनुवाद प्रक्रिया का विस्तार से वर्णन नहीं किया है, क्योंकि आप नेट पर इस विषय पर कई मैनुअल पा सकते हैं। संक्षेप में, समस्या यह है कि ऐसा फ़ंक्शन सार है: गुणों के किसी भी सेट के साथ कोई भी घटक इनपुट स्वीकार कर सकता है। यह शीर्षक के साथ एक बटन घटक हो सकता है और संपत्तियों पर क्लिक कर सकता है और उच्च और imgUrl गुणों के साथ एक चित्र घटक हो सकता है। इन गुणों का सेट हमें पहले से ज्ञात नहीं है, केवल उन गुणों को जो फ़ंक्शन स्वयं जोड़ता है, ज्ञात हैं। टाइपस्क्रिप्ट कंपाइलर को ऐसे कार्यों की मदद से प्राप्त घटकों का उपयोग करते समय कसम नहीं खाने के लिए, यह आवश्यक है कि फ़ंक्शन उन गुणों को "कट" करें, जो फ़ंक्शन दिए गए प्रकार से जोड़ता है।
ऐसा करने के लिए, आपको चाहिए:
- इन गुणों को इंटरफ़ेस में खींचें:
interface IWithSelectItem { selectedItem: number; handleSelectedItemChange: (id: number) => void; }
- घटक इंटरफ़ेस से IWithSelectItem इंटरफ़ेस में प्रवेश करने वाले सभी गुणों को निकालें। ऐसा करने के लिए, आप यूटिलिटी-टाइप लाइब्रेरी से डिफ <टी, यू> ऑपरेशन का उपयोग कर सकते हैं।
React.ComponentType<Diff<TPropsComponent, IWithSelectItem>>
परिवर्तन इतिहास का नुकसान
स्रोतों के साथ काम करने के लिए, उदाहरण के लिए, कोड समीक्षा, हम टीम फाउंडेशन सर्वर का उपयोग करते हैं। फ़ाइलों का अनुवाद करते समय, हम एक अप्रिय सुविधा में आ गए। एक बदले हुए फ़ाइल के बजाय, दो अनुरोध पूल में दिखाई देते हैं:
- रिमोट - फ़ाइल का पुराना संस्करण;
- बनाया - नया संस्करण।

यह व्यवहार देखा जाता है यदि फ़ाइल में कई बदलाव होते हैं (समानता <50%), उदाहरण के लिए, छोटी फ़ाइलों के लिए। इस समस्या को हल करने के लिए, हमने उपयोग करने की कोशिश की:
- git mv कमांड
- दो कमिट निष्पादित करें: पहला फ़ाइल एक्सटेंशन बदल रहा है, दूसरा तत्काल सुधार के साथ है।
लेकिन, दुर्भाग्य से, दोनों दृष्टिकोणों ने हमारी मदद नहीं की।
परिणाम
फ्लो या टाइपस्क्रिप्ट का उपयोग करें - हर कोई खुद के लिए निर्णय लेता है, दोनों दृष्टिकोणों में उनके पेशेवरों और विपक्ष हैं। हमने अपने लिए टाइपस्क्रिप्ट चुना। और आप अपने स्वयं के अनुभव से आश्वस्त थे: यदि आपने दृष्टिकोण में से एक को चुना और अचानक महसूस किया, तीन साल बाद भी कि यह आपको सूट नहीं करता है, तो आप इसे हमेशा बदल सकते हैं। और एक चिकनी संक्रमण के लिए, आप समानांतर में काम करने के लिए, हमारी तरह परियोजना को कॉन्फ़िगर कर सकते हैं।
लेखन के समय, हमने अभी तक पूरी तरह से टाइपस्क्रिप्ट पर स्विच नहीं किया है, लेकिन हमने पहले ही मुख्य भाग - परियोजना के "कोर" को फिर से लिखा है। कोड बेस में, आप सभी प्रकार की फ़ाइलों के अनुवाद के उदाहरणों को एक साधारण प्रतिक्रिया घटक से उच्च-क्रम के घटकों तक पा सकते हैं। इसके अलावा, सभी विकास टीमों के बीच प्रशिक्षण आयोजित किया गया था, और अब प्रत्येक टीम, अपने कार्य के हिस्से के रूप में, परियोजना का हिस्सा उन कर्तव्यों में स्थानांतरित करती है।
हम वर्ष के अंत से पहले संक्रमण को पूरा करने की योजना बनाते हैं, परीक्षण और एक स्टोरीबुक का अनुवाद करते हैं, और शायद हमारे कुछ नियम भी लिख सकते हैं।
मेरी व्यक्तिगत भावनाओं के अनुसार, मैं कह सकता हूं कि विकास में कम समय लगना शुरू हुआ, टाइप चेकिंग मक्खी पर की जाती है, जबकि सिस्टम लोड नहीं कर रहा है, और मेरे लिए त्रुटि संदेश व्यक्तिगत रूप से अधिक समझ में आता है।