குளோபல் ஸ்கோப்பின் குழப்பத்திலிருந்து ECMAScript மாட்யூல்களின் (ESM) நவீன சக்தி வரை, ஜாவாஸ்கிரிப்ட் மாட்யூல்களின் முழுமையான வரலாற்றை ஆராயுங்கள். உலகளாவிய டெவலப்பர்களுக்கான வழிகாட்டி.
ஜாவாஸ்கிரிப்ட் மாட்யூல் தரநிலைகள்: ECMAScript இணக்கம் மற்றும் பரிணாம வளர்ச்சி பற்றிய ஒரு ஆழமான பார்வை
நவீன மென்பொருள் மேம்பாட்டு உலகில், ஒழுங்கமைப்பு என்பது ஒரு விருப்பம் மட்டுமல்ல; அது ஒரு அத்தியாவசியம். அப்ளிகேஷன்கள் சிக்கலானதாக வளரும்போது, ஒரு ஒற்றைப்பெரிய கோட் தொகுப்பை நிர்வகிப்பது சாத்தியமற்றதாகிவிடும். இங்குதான் மாட்யூல்கள் வருகின்றன—இது டெவலப்பர்கள் பெரிய கோட் பேஸ்களை சிறிய, நிர்வகிக்கக்கூடிய மற்றும் மீண்டும் பயன்படுத்தக்கூடிய துண்டுகளாக உடைக்க அனுமதிக்கும் ஒரு அடிப்படைக் கருத்து. ஜாவாஸ்கிரிப்டைப் பொறுத்தவரை, ஒரு தரப்படுத்தப்பட்ட மாட்யூல் அமைப்புக்கான பயணம் நீண்ட மற்றும் சுவாரஸ்யமான ஒன்றாகும், இது ஒரு எளிய ஸ்கிரிப்டிங் கருவியிலிருந்து வலை மற்றும் அதற்கு அப்பாலும் சக்திவாய்ந்ததாக மாறிய மொழியின் சொந்த பரிணாம வளர்ச்சியைப் பிரதிபலிக்கிறது.
இந்த விரிவான வழிகாட்டி ஜாவாஸ்கிரிப்ட் மாட்யூல் தரநிலைகளின் முழுமையான வரலாறு மற்றும் தற்போதைய நிலையை உங்களுக்கு விளக்கும். குழப்பத்தைக் கட்டுப்படுத்த முயன்ற ஆரம்பகால பேட்டர்ன்கள், சர்வர் பக்கப் புரட்சியை இயக்கிய சமூகத்தால் இயக்கப்பட்ட தரநிலைகள் மற்றும் இறுதியாக, இன்றைய சுற்றுச்சூழல் அமைப்பை ஒன்றிணைக்கும் அதிகாரப்பூர்வ ECMAScript மாட்யூல்கள் (ESM) தரநிலை ஆகியவற்றை நாம் ஆராய்வோம். நீங்கள் import மற்றும் export பற்றி இப்போதுதான் கற்றுக்கொள்ளும் ஒரு இளநிலை டெவலப்பராக இருந்தாலும் சரி, அல்லது கலப்பின கோட் பேஸ்களின் சிக்கல்களைக் கையாளும் அனுபவமிக்க ஆர்க்கிடெக்டாக இருந்தாலும் சரி, இந்த கட்டுரை ஜாவாஸ்கிரிப்டின் மிக முக்கியமான அம்சங்களில் ஒன்றைப் பற்றிய தெளிவையும் ஆழமான நுண்ணறிவுகளையும் வழங்கும்.
மாட்யூல்-முந்தைய சகாப்தம்: குளோபல் ஸ்கோப்பின் கட்டுக்கடங்காத காலம்
எந்தவொரு முறையான மாட்யூல் அமைப்புகளும் இருப்பதற்கு முன்பு, ஜாவாஸ்கிரிப்ட் மேம்பாடு ஒரு ஆபத்தான செயலாக இருந்தது. கோட் பொதுவாக பல <script> டேக்குகள் வழியாக ஒரு வலைப்பக்கத்தில் சேர்க்கப்பட்டது. இந்த எளிய அணுகுமுறை ஒரு பெரிய, ஆபத்தான பக்க விளைவைக் கொண்டிருந்தது: குளோபல் ஸ்கோப் மாசுபாடு (global scope pollution).
ஒரு ஸ்கிரிப்ட் கோப்பின் மேல் மட்டத்தில் அறிவிக்கப்பட்ட ஒவ்வொரு வேரியபிள், ஃபங்ஷன் அல்லது ஆப்ஜெக்ட் குளோபல் ஆப்ஜெக்ட்டில் (உலாவிகளில் window) சேர்க்கப்பட்டது. இது ஒரு பலவீனமான சூழலை உருவாக்கியது, அங்கு:
- பெயர் முரண்பாடுகள்: இரண்டு வெவ்வேறு ஸ்கிரிப்டுகள் தற்செயலாக ஒரே வேரியபிள் பெயரைப் பயன்படுத்தக்கூடும், இது ஒன்று மற்றொன்றை மேலெழுத வழிவகுக்கும். இந்த சிக்கல்களை சரிசெய்வது பெரும்பாலும் ஒரு கனவாக இருந்தது.
- மறைமுக சார்புகள்:
<script>டேக்குகளின் வரிசை மிகவும் முக்கியமானதாக இருந்தது. மற்றொரு ஸ்கிரிப்டில் இருந்து ஒரு வேரியபிளைச் சார்ந்திருக்கும் ஒரு ஸ்கிரிப்ட், அதன் சார்புக்குப் பிறகு ஏற்றப்பட வேண்டும். இந்த கைமுறை வரிசைப்படுத்துதல் பலவீனமானதாகவும் பராமரிக்க கடினமானதாகவும் இருந்தது. - உள்ளடக்குதலின்மை: தனிப்பட்ட வேரியபிள்கள் அல்லது ஃபங்ஷன்களை உருவாக்க வழி இல்லை. எல்லாம் வெளிப்படையாக இருந்ததால், வலுவான மற்றும் பாதுகாப்பான கூறுகளை உருவாக்குவது கடினமாக இருந்தது.
IIFE பேட்டர்ன்: ஒரு நம்பிக்கைக் கீற்று
இந்த சிக்கல்களை எதிர்கொள்ள, புத்திசாலித்தனமான டெவலப்பர்கள் மாட்யூல் தன்மையை உருவகப்படுத்த சில பேட்டர்ன்களை உருவாக்கினர். இவற்றில் மிக முக்கியமானது உடனடியாக செயல்படுத்தப்படும் ஃபங்ஷன் எக்ஸ்பிரஷன் (Immediately Invoked Function Expression - IIFE) ஆகும். ஒரு IIFE என்பது வரையறுக்கப்பட்டு உடனடியாக செயல்படுத்தப்படும் ஒரு ஃபங்ஷன் ஆகும்.
இதோ ஒரு உன்னதமான உதாரணம்:
(function() {
// All the code inside this function is in a private scope.
var privateVariable = 'I am safe here';
function privateFunction() {
console.log('This function cannot be called from outside.');
}
// We can choose what to expose to the global scope.
window.myModule = {
publicMethod: function() {
console.log('Hello from the public method!');
privateFunction();
}
};
})();
// Usage:
myModule.publicMethod(); // Works
console.log(typeof privateVariable); // undefined
privateFunction(); // Throws an error
IIFE பேட்டர்ன் ஒரு முக்கியமான அம்சத்தை வழங்கியது: ஸ்கோப் உள்ளடக்குதல் (scope encapsulation). ஒரு ஃபங்ஷனில் கோடை வைப்பதன் மூலம், அது ஒரு தனிப்பட்ட ஸ்கோப்பை உருவாக்கியது, வேரியபிள்கள் குளோபல் நேம்ஸ்பேஸில் கசிவதைத் தடுத்தது. டெவலப்பர்கள் தாங்கள் வெளிப்படுத்த விரும்பும் பகுதிகளை (அவர்களின் பொது API) குளோபல் window ஆப்ஜெக்ட்டில் வெளிப்படையாக இணைக்க முடிந்தது. இது ஒரு பெரிய முன்னேற்றமாக இருந்தாலும், இது ஒரு கைமுறை மரபாகவே இருந்தது, சார்பு நிர்வாகத்துடன் கூடிய உண்மையான மாட்யூல் அமைப்பாக இருக்கவில்லை.
சமூகத் தரநிலைகளின் எழுச்சி: CommonJS (CJS)
ஜாவாஸ்கிரிப்டின் பயன்பாடு உலாவிக்கு அப்பால் விரிவடைந்ததால், குறிப்பாக 2009 இல் Node.js வந்தவுடன், ஒரு வலுவான, சர்வர் பக்க மாட்யூல் அமைப்புக்கான தேவை அவசரமானது. சர்வர் பக்க அப்ளிகேஷன்களுக்கு ஃபைல் சிஸ்டத்திலிருந்து மாட்யூல்களை நம்பகத்தன்மையுடனும் ஒத்திசைவாகவும் ஏற்ற வேண்டியிருந்தது. இது CommonJS (CJS) உருவாக்கத்திற்கு வழிவகுத்தது.
CommonJS, Node.js-க்கான இயல்புநிலைத் தரமாக மாறியது மற்றும் அதன் சுற்றுச்சூழல் அமைப்பின் ஒரு மூலக்கல்லாக உள்ளது. அதன் வடிவமைப்பு தத்துவம் எளிமையானது, ஒத்திசைவானது மற்றும் நடைமுறைக்குரியது.
CommonJS-ன் முக்கிய கருத்துக்கள்
- `require` ஃபங்ஷன்: ஒரு மாட்யூலை இம்போர்ட் செய்யப் பயன்படுகிறது. இது மாட்யூல் கோப்பைப் படித்து, அதை இயக்கி, `exports` ஆப்ஜெக்டைத் திருப்பியளிக்கிறது. இந்த செயல்முறை ஒத்திசைவானது, அதாவது மாட்யூல் ஏற்றப்படும் வரை இயக்கம் இடைநிறுத்தப்படும்.
- `module.exports` ஆப்ஜெக்ட்: ஒரு மாட்யூல் பொதுவில் வெளியிட விரும்பும் அனைத்தையும் கொண்டிருக்கும் ஒரு சிறப்பு ஆப்ஜெக்ட். இயல்பாக, இது ஒரு வெற்று ஆப்ஜெக்ட். நீங்கள் அதில் பண்புகளை இணைக்கலாம் அல்லது அதை முழுமையாக மாற்றலாம்.
- `exports` வேரியபிள்: `module.exports`-க்கான ஒரு சுருக்கமான குறிப்பு. நீங்கள் பண்புகளைச் சேர்க்க இதைப் பயன்படுத்தலாம் (எ.கா., `exports.myFunction = ...`), ஆனால் அதை மீண்டும் ஒதுக்க முடியாது (எ.கா., `exports = ...`), ஏனெனில் இது `module.exports`-க்கான குறிப்பை உடைத்துவிடும்.
- கோப்பு அடிப்படையிலான மாட்யூல்கள்: CJS-ல், ஒவ்வொரு கோப்பும் அதன் சொந்த தனிப்பட்ட ஸ்கோப்புடன் ஒரு மாட்யூல் ஆகும்.
CommonJS செயல்பாட்டில்
ஒரு பொதுவான Node.js உதாரணத்தைப் பார்ப்போம்.
`math.js` (மாட்யூல்)
// A private function, not exported
const logOperation = (op, a, b) => {
console.log(`Performing operation: ${op} on ${a} and ${b}`);
};
function add(a, b) {
logOperation('add', a, b);
return a + b;
}
function subtract(a, b) {
logOperation('subtract', a, b);
return a - b;
}
// Exporting the public functions
module.exports = {
add: add,
subtract: subtract
};
`app.js` (நுகர்வோர்)
// Importing the math module
const math = require('./math.js');
const sum = math.add(10, 5); // 15
const difference = math.subtract(10, 5); // 5
console.log(`The sum is ${sum}`);
console.log(`The difference is ${difference}`);
`require`-இன் ஒத்திசைவான தன்மை சர்வருக்கு சரியானதாக இருந்தது. ஒரு சர்வர் தொடங்கும் போது, அது உள்ளூர் டிஸ்க்கிலிருந்து அதன் அனைத்து சார்புகளையும் விரைவாகவும் கணிக்கக்கூடிய வகையிலும் ஏற்ற முடியும். இருப்பினும், இதே ஒத்திசைவான நடத்தை உலாவிகளுக்கு ஒரு பெரிய பிரச்சனையாக இருந்தது, அங்கு ஒரு மெதுவான நெட்வொர்க்கில் ஒரு ஸ்கிரிப்டை ஏற்றுவது முழு பயனர் இடைமுகத்தையும் முடக்கிவிடும்.
உலாவிக்கான தீர்வு: அசிங்க்ரோனஸ் மாட்யூல் டெஃபினிஷன் (AMD)
உலாவியில் உள்ள மாட்யூல்களின் சவால்களைச் சமாளிக்க, ஒரு வித்தியாசமான தரநிலை உருவானது: அசிங்க்ரோனஸ் மாட்யூல் டெஃபினிஷன் (AMD). உலாவியின் முக்கிய திரியைத் தடுக்காமல், மாட்யூல்களை ஒத்திசைவற்ற முறையில் ஏற்றுவதே AMD-யின் முக்கிய கொள்கையாகும்.
AMD-யின் மிகவும் பிரபலமான செயலாக்கம் RequireJS லைப்ரரி ஆகும். AMD-யின் தொடரியல் சார்புகளைப் பற்றி மிகவும் வெளிப்படையானது மற்றும் ஒரு ஃபங்ஷன்-ரேப்பர் வடிவமைப்பைப் பயன்படுத்துகிறது.
AMD-யின் முக்கிய கருத்துக்கள்
- `define` ஃபங்ஷன்: ஒரு மாட்யூலை வரையறுக்கப் பயன்படுகிறது. இது சார்புகளின் ஒரு வரிசையையும் ஒரு ஃபேக்டரி ஃபங்ஷனையும் எடுக்கும்.
- ஒத்திசைவற்ற ஏற்றுதல்: மாட்யூல் லோடர் (RequireJS போல) பட்டியலிடப்பட்ட அனைத்து சார்பு ஸ்கிரிப்டுகளையும் பின்னணியில் பெறுகிறது.
- ஃபேக்டரி ஃபங்ஷன்: அனைத்து சார்புகளும் ஏற்றப்பட்டவுடன், ஏற்றப்பட்ட மாட்யூல்கள் ஆர்குமென்ட்களாக அனுப்பப்பட்டு ஃபேக்டரி ஃபங்ஷன் செயல்படுத்தப்படுகிறது. இந்த ஃபங்ஷனின் ரிட்டர்ன் மதிப்பு மாட்யூலின் எக்ஸ்போர்ட் செய்யப்பட்ட மதிப்பாக மாறும்.
AMD செயல்பாட்டில்
AMD மற்றும் RequireJS-ஐப் பயன்படுத்தி நமது கணித உதாரணம் எப்படி இருக்கும் என்பது இங்கே.
`math.js` (மாட்யூல்)
define(function() {
// This module has no dependencies
const logOperation = (op, a, b) => {
console.log(`Performing operation: ${op} on ${a} and ${b}`);
};
// Return the public API
return {
add: function(a, b) {
logOperation('add', a, b);
return a + b;
},
subtract: function(a, b) {
logOperation('subtract', a, b);
return a - b;
}
};
});
`app.js` (நுகர்வோர்)
define(['./math'], function(math) {
// This code runs only after 'math.js' has been loaded
const sum = math.add(10, 5);
const difference = math.subtract(10, 5);
console.log(`The sum is ${sum}`);
console.log(`The difference is ${difference}`);
// Typically you would use this to bootstrap your application
document.getElementById('result').innerText = `Sum: ${sum}`;
});
AMD தடுப்புச் சிக்கலைத் தீர்த்தாலும், அதன் தொடரியல் CommonJS-ஐ விட விரிவானதாகவும் மற்றும் குறைவான உள்ளுணர்வு கொண்டதாகவும் அடிக்கடி விமர்சிக்கப்பட்டது. சார்பு வரிசை மற்றும் கால்பேக் ஃபங்ஷனின் தேவை பல டெவலப்பர்களுக்கு சிரமமாக இருந்த பாய்லர்பிளேட் கோடைச் சேர்த்தது.
ஒருங்கிணைப்பாளர்: யுனிவர்சல் மாட்யூல் டெஃபினிஷன் (UMD)
இரண்டு பிரபலமான ஆனால் பொருந்தாத மாட்யூல் அமைப்புகளுடன் (சர்வருக்கு CJS, உலாவிக்கு AMD), ஒரு புதிய சிக்கல் எழுந்தது. இரு சூழல்களிலும் வேலை செய்யும் ஒரு லைப்ரரியை எப்படி எழுதுவது? பதில் யுனிவர்சல் மாட்யூல் டெஃபினிஷன் (UMD) பேட்டர்ன் ஆகும்.
UMD ஒரு புதிய மாட்யூல் அமைப்பு அல்ல, மாறாக வெவ்வேறு மாட்யூல் லோடர்களின் இருப்பைச் சரிபார்க்க ஒரு மாட்யூலைச் சுற்றும் ஒரு புத்திசாலித்தனமான பேட்டர்ன் ஆகும். இது அடிப்படையில் கூறுகிறது: "ஒரு AMD லோடர் இருந்தால், அதைப் பயன்படுத்தவும். இல்லையெனில், ஒரு CommonJS சூழல் இருந்தால், அதைப் பயன்படுத்தவும். கடைசி முயற்சியாக, மாட்யூலை ஒரு குளோபல் வேரியபிளுக்கு ஒதுக்கவும்."
ஒரு UMD ரேப்பர் இது போன்ற ஒரு சிறிய பாய்லர்பிளேட் ஆகும்:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. CJS-like environments that support module.exports.
module.exports = factory();
} else {
// Browser globals (root is window).
root.myModuleName = factory();
}
}(typeof self !== 'undefined' ? self : this, function () {
// The actual module code goes here.
const myApi = {};
myApi.doSomething = function() { /* ... */ };
return myApi;
}));
UMD அதன் காலத்திற்கு ஒரு நடைமுறைத் தீர்வாக இருந்தது, லைப்ரரி ஆசிரியர்கள் எல்லா இடங்களிலும் வேலை செய்யும் ஒரு கோப்பை வெளியிட அனுமதித்தது. இருப்பினும், இது மற்றொரு சிக்கலான அடுக்கைச் சேர்த்தது மற்றும் ஜாவாஸ்கிரிப்ட் சமூகத்திற்கு அவசரமாக ஒரு ஒற்றை, நேட்டிவ், அதிகாரப்பூர்வ மாட்யூல் தரநிலை தேவை என்பதற்கான தெளிவான அறிகுறியாக இருந்தது.
அதிகாரப்பூர்வ தரநிலை: ECMAScript மாட்யூல்கள் (ESM)
இறுதியாக, ECMAScript 2015 (ES6) வெளியீட்டில், ஜாவாஸ்கிரிப்ட் அதன் சொந்த நேட்டிவ் மாட்யூல் அமைப்பைப் பெற்றது. ECMAScript மாட்யூல்கள் (ESM) இரு உலகங்களிலும் சிறந்ததாக வடிவமைக்கப்பட்டன: CommonJS போன்ற ஒரு சுத்தமான, அறிவிப்பு தொடரியல், உலாவிகளுக்கு ஏற்ற ஒத்திசைவற்ற ஏற்றுதலுக்கான ஆதரவுடன் இணைக்கப்பட்டது. உலாவிகள் மற்றும் Node.js முழுவதும் ESM முழு ஆதரவைப் பெற பல ஆண்டுகள் ஆனது, ஆனால் இன்று அது மாட்யூலர் ஜாவாஸ்கிரிப்ட் எழுதுவதற்கான அதிகாரப்பூர்வ, நிலையான வழியாகும்.
ECMAScript மாட்யூல்களின் முக்கிய கருத்துக்கள்
- `export` கீவேர்ட்: மாட்யூலுக்கு வெளியே அணுகக்கூடியதாக இருக்க வேண்டிய மதிப்புகள், ஃபங்ஷன்கள் அல்லது கிளாஸ்களை அறிவிக்கப் பயன்படுகிறது.
- `import` கீவேர்ட்: மற்றொரு மாட்யூலில் இருந்து எக்ஸ்போர்ட் செய்யப்பட்ட உறுப்பினர்களை தற்போதைய ஸ்கோப்பிற்குள் கொண்டு வரப் பயன்படுகிறது.
- நிலையான கட்டமைப்பு: ESM நிலையான முறையில் பகுப்பாய்வு செய்யக்கூடியது. இதன் பொருள், நீங்கள் சோர்ஸ் கோடைப் பார்த்து, அதை இயக்காமலேயே, கம்பைல் நேரத்தில் இம்போர்ட் மற்றும் எக்ஸ்போர்ட்களைத் தீர்மானிக்க முடியும். இது ட்ரீ-ஷேக்கிங் போன்ற சக்திவாய்ந்த கருவிகளை இயக்கும் ஒரு முக்கியமான அம்சமாகும்.
- இயல்பாக ஒத்திசைவற்றது: ESM-இன் ஏற்றுதல் மற்றும் இயக்கம் ஜாவாஸ்கிரிப்ட் இன்ஜினால் நிர்வகிக்கப்படுகிறது மற்றும் தடுக்காத வகையில் வடிவமைக்கப்பட்டுள்ளது.
- மாட்யூல் ஸ்கோப்: CJS போலவே, ஒவ்வொரு கோப்பும் ஒரு தனிப்பட்ட ஸ்கோப்புடன் அதன் சொந்த மாட்யூல் ஆகும்.
ESM தொடரியல்: பெயரிடப்பட்ட மற்றும் இயல்புநிலை எக்ஸ்போர்ட்கள்
ESM ஒரு மாட்யூலில் இருந்து எக்ஸ்போர்ட் செய்ய இரண்டு முதன்மை வழிகளை வழங்குகிறது: பெயரிடப்பட்ட எக்ஸ்போர்ட்கள் மற்றும் ஒரு இயல்புநிலை எக்ஸ்போர்ட்.
பெயரிடப்பட்ட எக்ஸ்போர்ட்கள்
ஒரு மாட்யூல் பல மதிப்புகளை பெயரால் எக்ஸ்போர்ட் செய்ய முடியும். பல தனித்துவமான ஃபங்ஷன்களை வழங்கும் யூட்டிலிட்டி லைப்ரரிகளுக்கு இது பயனுள்ளதாக இருக்கும்.
`utils.js`
export const PI = 3.14159;
export function formatDate(date) {
return date.toLocaleDateString('en-US');
}
export class Logger {
constructor(name) {
this.name = name;
}
log(message) {
console.log(`[${this.name}] ${message}`);
}
}
இவற்றை இம்போர்ட் செய்ய, நீங்கள் விரும்பும் உறுப்பினர்களைக் குறிப்பிட சுருள் பிரேஸ்களைப் பயன்படுத்துகிறீர்கள்.
`main.js`
import { PI, formatDate, Logger } from './utils.js';
// You can also rename imports
// import { PI as piValue } from './utils.js';
console.log(PI);
const logger = new Logger('App');
logger.log(`Today is ${formatDate(new Date())}`);
இயல்புநிலை எக்ஸ்போர்ட்
ஒரு மாட்யூலில் ஒன்று, மற்றும் ஒரே ஒரு, இயல்புநிலை எக்ஸ்போர்ட் இருக்கலாம். ஒரு மாட்யூலின் முதன்மை நோக்கம் ஒரு ஒற்றை கிளாஸ் அல்லது ஃபங்ஷனை எக்ஸ்போர்ட் செய்வதாக இருக்கும்போது இது பெரும்பாலும் பயன்படுத்தப்படுகிறது.
`Calculator.js`
export default class Calculator {
add(a, b) {
return a + b;
}
subtract(a, b) {
return a - b;
}
}
ஒரு இயல்புநிலை எக்ஸ்போர்டை இம்போர்ட் செய்வது சுருள் பிரேஸ்களைப் பயன்படுத்தாது, மேலும் இம்போர்ட் செய்யும் போது நீங்கள் விரும்பும் எந்தப் பெயரையும் கொடுக்கலாம்.
`main.js`
import MyCalc from './Calculator.js';
// The name 'MyCalc' is arbitrary; `import Calc from ...` would also work.
const calculator = new MyCalc();
console.log(calculator.add(5, 3)); // 8
உலாவிகளில் ESM-ஐப் பயன்படுத்துதல்
ஒரு வலை உலாவியில் ESM-ஐப் பயன்படுத்த, உங்கள் <script> டேக்கில் `type="module"` ஐச் சேர்த்தால் போதும்.
<!-- index.html -->
<script type="module" src="./main.js"></script>
`type="module"` உடன் உள்ள ஸ்கிரிப்டுகள் தானாகவே தள்ளிவைக்கப்படுகின்றன, அதாவது அவை HTML பாகுபடுத்துதலுடன் இணையாகப் பெறப்பட்டு, ஆவணம் முழுமையாக பாகுபடுத்தப்பட்ட பின்னரே செயல்படுத்தப்படுகின்றன. அவை இயல்பாகவே ஸ்டிரிக்ட் மோடிலும் இயங்கும்.
Node.js-ல் ESM: புதிய தரநிலை
Node.js-ல் ESM-ஐ ஒருங்கிணைப்பது ஒரு குறிப்பிடத்தக்க சவாலாக இருந்தது, ஏனெனில் சுற்றுச்சூழல் அமைப்பு CommonJS-ல் ஆழமாக வேரூன்றியுள்ளது. இன்று, Node.js ESM-க்கு வலுவான ஆதரவைக் கொண்டுள்ளது. ஒரு கோப்பை ஒரு ES மாட்யூலாகக் கருத Node.js-க்குச் சொல்ல, நீங்கள் இரண்டு விஷயங்களில் ஒன்றைச் செய்யலாம்:
- கோப்பிற்கு `.mjs` நீட்டிப்புடன் பெயரிடுங்கள்.
- உங்கள் `package.json` கோப்பில், `"type": "module"` என்ற புலத்தைச் சேர்க்கவும். இது அந்த ப்ராஜெக்டில் உள்ள அனைத்து `.js` கோப்புகளையும் ES மாட்யூல்களாகக் கருத Node.js-க்குச் சொல்கிறது. நீங்கள் இதைச் செய்தால், CommonJS கோப்புகளை `.cjs` நீட்டிப்புடன் பெயரிட்டுப் பயன்படுத்தலாம்.
ஒரு கோப்பை எவ்வாறு விளக்குவது என்பதை Node.js ரன்டைம் அறிந்துகொள்ள இந்த வெளிப்படையான கட்டமைப்பு அவசியம், ஏனெனில் இரண்டு அமைப்புகளுக்கும் இடையே இம்போர்ட் செய்வதற்கான தொடரியல் கணிசமாக வேறுபடுகிறது.
பெரும் பிளவு: நடைமுறையில் CJS vs. ESM
ESM எதிர்காலமாக இருந்தாலும், CommonJS இன்னும் Node.js சுற்றுச்சூழல் அமைப்பில் ஆழமாகப் பதிந்துள்ளது. பல ஆண்டுகளாக, டெவலப்பர்கள் இரண்டு அமைப்புகளையும் அவை எவ்வாறு தொடர்பு கொள்கின்றன என்பதையும் புரிந்து கொள்ள வேண்டும். இது பெரும்பாலும் "இரட்டை பேக்கேஜ் ஆபத்து" என்று குறிப்பிடப்படுகிறது.
முக்கியமான நடைமுறை வேறுபாடுகளின் ஒரு முறிவு இங்கே:
| அம்சம் | CommonJS (CJS) | ECMAScript மாட்யூல்கள் (ESM) |
|---|---|---|
| தொடரியல் (இம்போர்ட்) | const myModule = require('my-module'); |
import myModule from 'my-module'; |
| தொடரியல் (எக்ஸ்போர்ட்) | module.exports = { ... }; |
export default { ... }; அல்லது export const ...; |
| ஏற்றுதல் | ஒத்திசைவானது | ஒத்திசைவற்றது |
| மதிப்பீடு | `require` அழைப்பின் போது மதிப்பிடப்படுகிறது. மதிப்பு எக்ஸ்போர்ட் செய்யப்பட்ட ஆப்ஜெக்டின் ஒரு நகலாகும். | பாகுபடுத்தும் நேரத்தில் நிலையானதாக மதிப்பிடப்படுகிறது. இம்போர்ட்கள் எக்ஸ்போர்ட் செய்யப்பட்ட மதிப்புகளின் நேரடி, படிக்க-மட்டும் பார்வைகளாகும். |
| `this` சூழல் | `module.exports`-ஐக் குறிக்கிறது. | மேல் மட்டத்தில் `undefined`. |
| டைனமிக் பயன்பாடு | `require` கோடின் எங்கிருந்தும் அழைக்கப்படலாம். | `import` ஸ்டேட்மெண்ட்கள் மேல் மட்டத்தில் இருக்க வேண்டும். டைனமிக் ஏற்றுதலுக்கு, `import()` ஃபங்ஷனைப் பயன்படுத்தவும். |
இடைசெயல்பாடு: உலகங்களுக்கு இடையேயான பாலம்
ஒரு ESM கோப்பில் CJS மாட்யூல்களையோ அல்லது நேர்மாறாகவோ பயன்படுத்த முடியுமா? ஆம், ஆனால் சில முக்கியமான எச்சரிக்கைகளுடன்.
- CJS-ஐ ESM-க்குள் இம்போர்ட் செய்தல்: நீங்கள் ஒரு CommonJS மாட்யூலை ஒரு ES மாட்யூலுக்குள் இம்போர்ட் செய்யலாம். Node.js CJS மாட்யூலை ரேப் செய்யும், மேலும் நீங்கள் பொதுவாக அதன் எக்ஸ்போர்ட்களை ஒரு இயல்புநிலை இம்போர்ட் வழியாக அணுகலாம்.
// in an ESM file (e.g., index.mjs)
import legacyLib from './legacy-lib.cjs'; // CJS file
legacyLib.doSomething();
- ESM-ஐ CJS-லிருந்து பயன்படுத்துதல்: இது சற்று தந்திரமானது. ஒரு ES மாட்யூலை இம்போர்ட் செய்ய `require()`-ஐப் பயன்படுத்த முடியாது. `require()`-இன் ஒத்திசைவான தன்மை ESM-இன் ஒத்திசைவற்ற தன்மையுடன் அடிப்படையில் பொருந்தாது. அதற்கு பதிலாக, நீங்கள் டைனமிக் `import()` ஃபங்ஷனைப் பயன்படுத்த வேண்டும், இது ஒரு பிராமிஸைத் திருப்பியளிக்கிறது.
// in a CJS file (e.g., index.js)
async function loadEsModule() {
const esModule = await import('./my-module.mjs');
esModule.default.doSomething();
}
loadEsModule();
ஜாவாஸ்கிரிப்ட் மாட்யூல்களின் எதிர்காலம்: அடுத்து என்ன?
ESM-இன் தரப்படுத்தல் ஒரு நிலையான அடித்தளத்தை உருவாக்கியுள்ளது, ஆனால் பரிணாம வளர்ச்சி முடிவடையவில்லை. பல நவீன அம்சங்கள் மற்றும் முன்மொழிவுகள் மாட்யூல்களின் எதிர்காலத்தை வடிவமைக்கின்றன.
டைனமிக் `import()`
ஏற்கனவே மொழியின் ஒரு நிலையான பகுதியான `import()` ஃபங்ஷன், தேவைக்கேற்ப மாட்யூல்களை ஏற்ற அனுமதிக்கிறது. வலை அப்ளிகேஷன்களில் கோட்-ஸ்பிளிட்டிங்கிற்கு இது நம்பமுடியாத அளவிற்கு சக்தி வாய்ந்தது, அங்கு நீங்கள் ஒரு குறிப்பிட்ட வழி அல்லது பயனர் செயலுக்குத் தேவையான கோடை மட்டும் ஏற்றுவதன் மூலம் ஆரம்ப ஏற்றுதல் நேரங்களை மேம்படுத்துகிறீர்கள்.
const button = document.getElementById('load-chart-btn');
button.addEventListener('click', async () => {
// Load the charting library only when the user clicks the button
const { Chart } = await import('./charting-library.js');
const myChart = new Chart(/* ... */);
myChart.render();
});
டாப்-லெவல் `await`
சமீபத்திய மற்றும் சக்திவாய்ந்த ஒரு கூடுதலாக, டாப்-லெவல் `await` ஒரு `async` ஃபங்ஷனுக்கு வெளியே `await` கீவேர்டைப் பயன்படுத்த உங்களை அனுமதிக்கிறது, ஆனால் ஒரு ES மாட்யூலின் மேல் மட்டத்தில் மட்டுமே. ஒரு மாட்யூல் பயன்படுத்தப்படுவதற்கு முன்பு ஒரு ஒத்திசைவற்ற செயல்பாட்டை (உள்ளமைவுத் தரவைப் பெறுவது அல்லது ஒரு தரவுத்தள இணைப்பைத் தொடங்குவது போன்றவை) செய்ய வேண்டியிருக்கும் போது இது பயனுள்ளதாக இருக்கும்.
// config.js
const response = await fetch('https://api.example.com/config');
const configData = await response.json();
export const config = configData;
// another-module.js
import { config } from './config.js'; // This module will wait for config.js to resolve
console.log(config.apiKey);
இம்போர்ட் மேப்ஸ்
இம்போர்ட் மேப்ஸ் என்பது ஜாவாஸ்கிரிப்ட் இம்போர்ட்களின் நடத்தையைக் கட்டுப்படுத்த உங்களை அனுமதிக்கும் ஒரு உலாவி அம்சமாகும். அவை ஒரு பில்ட் ஸ்டெப் இல்லாமல், உலாவியில் நேரடியாக "பேர் ஸ்பெசிஃபையர்களை" (`import moment from 'moment'` போன்றவை) பயன்படுத்த உங்களை அனுமதிக்கின்றன, அந்த ஸ்பெசிஃபையரை ஒரு குறிப்பிட்ட URL உடன் மேப் செய்வதன் மூலம்.
<!-- index.html -->
<script type="importmap">
{
"imports": {
"moment": "/node_modules/moment/dist/moment.js",
"lodash": "https://unpkg.com/lodash-es@4.17.21/lodash.js"
}
}
</script>
<script type="module">
import moment from 'moment';
import { debounce } from 'lodash';
// The browser now knows where to find 'moment' and 'lodash'
</script>
ஒரு உலகளாவிய டெவலப்பருக்கான நடைமுறை ஆலோசனைகள் மற்றும் சிறந்த பழக்கங்கள்
- புதிய ப்ராஜெக்ட்களுக்கு ESM-ஐ ஏற்றுக்கொள்ளுங்கள்: எந்தவொரு புதிய வலை அல்லது Node.js ப்ராஜெக்டிற்கும், ESM உங்கள் இயல்புநிலைத் தேர்வாக இருக்க வேண்டும். இது மொழித் தரநிலை, சிறந்த டூலிங் ஆதரவை வழங்குகிறது (குறிப்பாக ட்ரீ-ஷேக்கிங்கிற்கு), மற்றும் மொழியின் எதிர்காலம் இதை நோக்கியே செல்கிறது.
- உங்கள் சூழலைப் புரிந்து கொள்ளுங்கள்: உங்கள் ரன்டைம் எந்த மாட்யூல் அமைப்பை ஆதரிக்கிறது என்பதை அறிந்து கொள்ளுங்கள். நவீன உலாவிகள் மற்றும் Node.js-இன் சமீபத்திய பதிப்புகள் சிறந்த ESM ஆதரவைக் கொண்டுள்ளன. பழைய சூழல்களுக்கு, உங்களுக்கு பேபல் போன்ற ஒரு டிரான்ஸ்பைலர் மற்றும் வெப்பேக் அல்லது ரோல்அப் போன்ற ஒரு பண்ட்லர் தேவைப்படும்.
- இடைசெயல்பாட்டில் கவனமாக இருங்கள்: ஒரு கலவையான CJS/ESM கோட் பேஸில் (இடம்பெயர்வுகளின் போது பொதுவானது) பணிபுரியும் போது, இரண்டு அமைப்புகளுக்கும் இடையில் இம்போர்ட் மற்றும் எக்ஸ்போர்ட்களை எவ்வாறு கையாளுகிறீர்கள் என்பதில் கவனமாக இருங்கள். நினைவில் கொள்ளுங்கள்: CJS ஆனது ESM-ஐ டைனமிக் `import()` வழியாக மட்டுமே பயன்படுத்த முடியும்.
- நவீன டூலிங்கைப் பயன்படுத்துங்கள்: வைட் (Vite) போன்ற நவீன பில்ட் கருவிகள் ESM-ஐ மனதில் கொண்டு அடித்தளத்திலிருந்து உருவாக்கப்பட்டுள்ளன, நம்பமுடியாத அளவிற்கு வேகமான மேம்பாட்டு சர்வர்கள் மற்றும் உகந்த பில்ட்களை வழங்குகின்றன. அவை மாட்யூல் ரெசல்யூஷன் மற்றும் பண்ட்லிங்கின் பல சிக்கல்களை எளிதாக்குகின்றன.
- ஒரு லைப்ரரியை வெளியிடும் போது: உங்கள் பேக்கேஜை யார் பயன்படுத்துவார்கள் என்பதைக் கருத்தில் கொள்ளுங்கள். பல லைப்ரரிகள் இன்று முழு சுற்றுச்சூழல் அமைப்பையும் ஆதரிக்க ESM மற்றும் CJS பதிப்பு இரண்டையும் வெளியிடுகின்றன. `package.json`-இல் உள்ள `exports` புலம் வெவ்வேறு சூழல்களுக்கு நிபந்தனைக்குட்பட்ட எக்ஸ்போர்ட்களை வரையறுக்க உங்களை அனுமதிக்கிறது.
முடிவுரை: ஒரு ஒருங்கிணைந்த எதிர்காலம்
ஜாவாஸ்கிரிப்ட் மாட்யூல்களின் பயணம் சமூக கண்டுபிடிப்பு, நடைமுறைத் தீர்வுகள் மற்றும் இறுதியில் தரப்படுத்தல் ஆகியவற்றின் ஒரு கதை. குளோபல் ஸ்கோப்பின் ஆரம்பகால குழப்பத்திலிருந்து, CommonJS-இன் சர்வர் பக்க கடுமை மற்றும் AMD-யின் உலாவி-மையப்படுத்தப்பட்ட ஒத்திசைவற்ற தன்மை வரை, ECMAScript மாட்யூல்களின் ஒருங்கிணைக்கும் சக்தி வரை, பாதை நீண்டதாக இருந்தாலும் பயனுள்ளது.
இன்று, ஒரு உலகளாவிய டெவலப்பராக, நீங்கள் ESM-இல் ஒரு சக்திவாய்ந்த, நேட்டிவ், மற்றும் தரப்படுத்தப்பட்ட மாட்யூல் அமைப்புடன் ஆயுதம் ஏந்தியுள்ளீர்கள். இது சிறிய வலைப்பக்கத்திலிருந்து மிகப்பெரிய சர்வர் பக்க அமைப்பு வரை எந்தவொரு சூழலுக்கும் சுத்தமான, பராமரிக்கக்கூடிய மற்றும் அதிக செயல்திறன் கொண்ட அப்ளிகேஷன்களை உருவாக்க உதவுகிறது. இந்த பரிணாம வளர்ச்சியைப் புரிந்துகொள்வதன் மூலம், நீங்கள் ஒவ்வொரு நாளும் பயன்படுத்தும் கருவிகளுக்கு ஆழமான பாராட்டுகளைப் பெறுவது மட்டுமல்லாமல், நவீன மென்பொருள் மேம்பாட்டின் எப்போதும் மாறிவரும் நிலப்பரப்பைக் கையாளவும் சிறப்பாகத் தயாராகிறீர்கள்.