मैंने एक सरल जावास्क्रिप्ट बंडलर बनाया और यह मेरी अपेक्षा से कहीं अधिक आसान निकला। मैंने इस पोस्ट में जो कुछ भी सीखा है उसे साझा करूंगा।
बड़े एप्लिकेशन लिखते समय, हमारे जावास्क्रिप्ट स्रोत कोड को अलग-अलग जेएस फाइलों में विभाजित करना अच्छा अभ्यास है, हालांकि कई स्क्रिप्ट टैग का उपयोग करके इन फ़ाइलों को अपने एचटीएमएल दस्तावेज़ में जोड़ने से नई समस्याएं आती हैं जैसे कि
वैश्विक नामस्थान का प्रदूषण।
दौड़ की स्थिति।
मॉड्यूल बंडलर विभिन्न फाइलों से हमारे स्रोत कोड को एक बड़ी फ़ाइल में जोड़ते हैं, जिससे हमें नकारात्मक पहलुओं से बचते हुए अमूर्तता के लाभों का आनंद लेने में मदद मिलती है।
मॉड्यूल बंडलर आम तौर पर इसे दो चरणों में करते हैं।
जैसा कि पहले उल्लेख किया गया है, यहां हम
यहां बताया गया है कि हम यह कैसे करेंगे (जावास्क्रिप्ट कोड आगे)
अपने टेक्स्ट एडिटर में एक बंडलर.जेएस फ़ाइल बनाएं और निम्नलिखित कोड जोड़ें:
const bundler = (entry)=>{ const graph = createDependencyGraph(entry) const bundle = createBundle(graph) return bundle }
बंडलर फ़ंक्शन हमारे बंडलर की मुख्य प्रविष्टि है। यह एक फ़ाइल (प्रविष्टि फ़ाइल) का पथ लेता है और एक स्ट्रिंग (बंडल) लौटाता है। इसके भीतर, यह createDependencyGraph फ़ंक्शन का उपयोग करके एक निर्भरता ग्राफ़ उत्पन्न करता है।
const createDependencyGraph = (path)=>{ const entryModule = createModule(path) /* other code */ }
createDependencyGraph फ़ंक्शन प्रविष्टि फ़ाइल का पथ लेता है। यह createModule फ़ंक्शन का उपयोग करके इस फ़ाइल का मॉड्यूल प्रतिनिधित्व उत्पन्न करता है।
let ID = 0 const createModule = (filename)=>{ const content = fs.readFileSync(filename) const ast = babylon.parse(content, {sourceType: “module”}) const {code} = babel.transformFromAst(ast, null, { presets: ['env'] }) const dependencies = [ ] const id = ID traverse(ast, { ImportDeclaration: ({node})=>{ dependencies.push(node.source.value) } } return { id, filename, code, dependencies } }
createAsset फ़ंक्शन एक फ़ाइल का पथ लेता है और इसकी सामग्री को एक स्ट्रिंग में पढ़ता है। फिर इस स्ट्रिंग को एक अमूर्त सिंटैक्स ट्री में पार्स किया जाता है। एक अमूर्त वाक्यविन्यास वृक्ष एक स्रोत कोड की सामग्री का एक वृक्ष प्रतिनिधित्व है। इसकी तुलना html दस्तावेज़ के DOM ट्री से की जा सकती है। इससे कोड पर कुछ कार्यक्षमता चलाना आसान हो जाता है जैसे कि खोजना, आदि।
हम बेबीलोन पार्सर का उपयोग करके मॉड्यूल से एक एस्ट बनाते हैं।
इसके बाद बेबल कोर ट्रांसपिलर की मदद से हम क्रॉस ब्राउज़र संगतता के लिए कोड सामग्री को प्री-ईएस2015 सिंटैक्स में परिवर्तित करते हैं।
बाद में हमारी स्रोत फ़ाइल (निर्भरता) की प्रत्येक आयात घोषणा को खोजने के लिए बैबल से एक विशेष फ़ंक्शन का उपयोग करके एएसटी का पता लगाया जाता है।
फिर हम इन निर्भरताओं (जो सापेक्ष फ़ाइल पथों के स्ट्रिंग टेक्स्ट हैं) को एक निर्भरता सरणी में धकेलते हैं।
इसके अलावा हम इस मॉड्यूल को विशिष्ट रूप से पहचानने के लिए एक आईडी भी बनाते हैं और
अंत में हम इस मॉड्यूल का प्रतिनिधित्व करने वाला एक ऑब्जेक्ट लौटाते हैं। इस मॉड्यूल में एक आईडी, एक स्ट्रिंग प्रारूप में हमारी फ़ाइल की सामग्री, निर्भरता की एक सरणी और पूर्ण फ़ाइल पथ शामिल है।
const createDependencyGraph = (path)=>{ const entryModule = createModule(path) const graph = [ entryModule ] for ( const module of graph) { module.mapping = { } module.dependencies.forEach((dep)=>{ let absolutePath = path.join(dirname, dep); let child = graph.find(mod=> mod.filename == dep) if(!child){ child = createModule(dep) graph.push(child) } module.mapping[dep] = child.id }) } return graph }
हमारे createDependencyGraph फ़ंक्शन में वापस, अब हम अपना ग्राफ़ बनाने की प्रक्रिया शुरू कर सकते हैं। हमारा ग्राफ़ ऑब्जेक्ट्स की एक सरणी है जिसमें प्रत्येक ऑब्जेक्ट हमारे एप्लिकेशन में उपयोग की गई प्रत्येक स्रोत फ़ाइल का प्रतिनिधित्व करता है।
हम अपने ग्राफ़ को एंट्री मॉड्यूल के साथ आरंभ करते हैं और फिर उसे लूप करते हैं। हालाँकि इसमें केवल एक आइटम है, हम प्रविष्टि मॉड्यूल (और अन्य मॉड्यूल जो हम जोड़ेंगे) की निर्भरता सरणी तक पहुँचकर सरणी के अंत में आइटम जोड़ते हैं।
निर्भरता सरणी में मॉड्यूल की सभी निर्भरताओं के सापेक्ष फ़ाइल पथ होते हैं। सरणी को लूप किया जाता है और प्रत्येक सापेक्ष फ़ाइल पथ के लिए, निरपेक्ष पथ को पहले हल किया जाता है और एक नया मॉड्यूल बनाने के लिए उपयोग किया जाता है। इस चाइल्ड मॉड्यूल को ग्राफ़ के अंत में धकेल दिया जाता है और प्रक्रिया फिर से शुरू हो जाती है जब तक कि सभी निर्भरताएँ मॉड्यूल में परिवर्तित नहीं हो जातीं।
साथ ही प्रत्येक मॉड्यूल एक मैपिंग ऑब्जेक्ट दे रहा है जो प्रत्येक निर्भरता सापेक्ष पथ को चाइल्ड मॉड्यूल की आईडी पर मैप करता है।
मॉड्यूल के दोहराव और अनंत परिपत्र निर्भरता को रोकने के लिए प्रत्येक निर्भरता पर एक मॉड्यूल पहले से मौजूद है या नहीं, इसकी जांच की जाती है।
अंत में हम अपना ग्राफ लौटाते हैं जिसमें अब हमारे एप्लिकेशन के सभी मॉड्यूल शामिल हैं।
निर्भरता ग्राफ पूरा होने के बाद, एक बंडल बनाने में दो चरण शामिल होंगे
हमें अपने मॉड्यूल ऑब्जेक्ट को स्ट्रिंग्स में बदलना होगा ताकि हम उन्हें बंडल.जेएस फ़ाइल में लिखने में सक्षम हो सकें। हम मॉड्यूलस्ट्रिंग को एक खाली स्ट्रिंग के रूप में प्रारंभ करके ऐसा करते हैं। इसके बाद हम अपने ग्राफ के माध्यम से लूप करते हैं और प्रत्येक मॉड्यूल को मॉड्यूल स्ट्रिंग में कुंजी मान जोड़े के रूप में जोड़ते हैं, जिसमें मॉड्यूल की आईडी कुंजी होती है और एक सरणी जिसमें दो आइटम होते हैं: सबसे पहले, मॉड्यूल सामग्री को फ़ंक्शन में लपेटा जाता है (जैसा कि पहले बताया गया है, इसे गुंजाइश देने के लिए) ) और दूसरा एक ऑब्जेक्ट जिसमें उसकी निर्भरता का मानचित्रण होता है।
const wrapModules = (graph)=>{ let modules = ‘’ graph.forEach(mod => { modules = `${http://mod.id}: [ function (require, module, exports) { ${mod.code} }, ${JSON.stringify(mod.mapping)}, ],`; }); return modules }
यह भी ध्यान दें, प्रत्येक मॉड्यूल को लपेटने वाला फ़ंक्शन तर्क के रूप में आवश्यकता, निर्यात और मॉड्यूल ऑब्जेक्ट लेता है। ऐसा इसलिए है क्योंकि ये ब्राउज़र में मौजूद नहीं हैं, लेकिन चूंकि ये हमारे कोड में दिखाई देते हैं इसलिए हम इन्हें बनाएंगे और इन मॉड्यूल में भेज देंगे।
यह कोड है जो बंडल लोड होते ही चालू हो जाएगा, यह हमारे मॉड्यूल को आवश्यकता, मॉड्यूल और मॉड्यूल.एक्सपोर्ट ऑब्जेक्ट प्रदान करेगा।
const bundle = (graph)=>{ let modules = wrapModules(graph) const result = ` (function(modules) { function require(id) { const [fn, mapping] = modules[id]; function localRequire(name) { return require(mapping[name]); } const module = { exports : {} }; fn(localRequire, module, module.exports); return module.exports; } require(0); })({${modules}})`; return result; }
हम तुरंत बुलाए गए फ़ंक्शन एक्सप्रेशन का उपयोग करते हैं जो हमारे मॉड्यूल ऑब्जेक्ट को एक तर्क के रूप में लेता है। इसके अंदर हम अपने require फ़ंक्शन को परिभाषित करते हैं जो अपनी आईडी का उपयोग करके हमारे मॉड्यूल ऑब्जेक्ट से एक मॉड्यूल प्राप्त करता है।
यह फ़ाइल पथ स्ट्रिंग को आईडी पर मैप करने के लिए एक विशेष मॉड्यूल के लिए विशिष्ट स्थानीय आवश्यकता फ़ंक्शन का निर्माण करता है। और एक खाली निर्यात संपत्ति के साथ एक मॉड्यूल ऑब्जेक्ट
यह हमारे मॉड्यूल कोड को चलाता है, लोकलरेक्वायर, मॉड्यूल और एक्सपोर्ट ऑब्जेक्ट को तर्क के रूप में पास करता है और फिर नोड जेएस मॉड्यूल की तरह ही मॉड्यूल.एक्सपोर्ट लौटाता है।
अंत में हम अपने प्रवेश मॉड्यूल (सूचकांक 0) पर require को कॉल करते हैं।
हमारे बंडलर का परीक्षण करने के लिए, हमारी बंडलर.जेएस फ़ाइल की कार्यशील निर्देशिका में एक इंडेक्स.जेएस फ़ाइल और दो निर्देशिकाएं बनाएं: एक स्रोत और एक सार्वजनिक निर्देशिका।
सार्वजनिक निर्देशिका में एक Index.html फ़ाइल बनाएं, और बॉडी टैग में निम्नलिखित कोड जोड़ें:
Module bundler
स्थिर नाम = "डेविड"
डिफ़ॉल्ट नाम निर्यात करें
also create a hello.js file and add the following code
'./name.js' से नाम आयात करें
स्थिरांक नमस्ते = document.getElementById(“रूट”)
hello.innerHTML = “हैलो” नाम
Lastly in the index.js file of the root directory import our bundler, bundle the files and write it to a bundle.js file in the public directory
const createBundle = require(“./bundler.js”)
स्थिरांक रन = (आउटपुट, इनपुट)=>{
लेट बंडल = क्रिएटबंडल(एंट्री)
fs.writeFileSync(बंडल, 'utf-8')
}
रन(“./public/bundle.js”, “./src/hello.js”)
Open our index.html file in the browser to see the magic. In this post we have illustrated how a simple module bundler works. This is a minimal bundler meant for understanding how these technologies work behind the hood. please like if you found this insightful and comment any questions you may have.
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3