আধুনিক জাভাস্ক্রিপ্ট নির্ভরতা এবং আউটপুট চালু করে কর্মক্ষমতা উন্নত করুন।
90% এরও বেশি ব্রাউজার আধুনিক জাভাস্ক্রিপ্ট চালাতে সক্ষম, কিন্তু লিগ্যাসি জাভাস্ক্রিপ্টের ব্যাপকতা আজও ওয়েবে পারফরম্যান্স সমস্যার একটি বড় উৎস।
আধুনিক জাভাস্ক্রিপ্ট
আধুনিক জাভাস্ক্রিপ্ট একটি নির্দিষ্ট ECMAScript স্পেসিফিকেশন সংস্করণে লেখা কোড হিসাবে চিহ্নিত করা হয় না, বরং সিনট্যাক্সে যা সমস্ত আধুনিক ব্রাউজার দ্বারা সমর্থিত। ক্রোম, এজ, ফায়ারফক্স এবং সাফারির মতো আধুনিক ওয়েব ব্রাউজারগুলি ব্রাউজারের বাজারের 90% এরও বেশি, এবং একই অন্তর্নিহিত রেন্ডারিং ইঞ্জিনের উপর নির্ভর করে এমন বিভিন্ন ব্রাউজার অতিরিক্ত 5% তৈরি করে। এর মানে হল যে গ্লোবাল ওয়েব ট্রাফিকের 95% ব্রাউজারগুলি থেকে আসে যা গত 10 বছর থেকে সর্বাধিক ব্যবহৃত জাভাস্ক্রিপ্ট ভাষার বৈশিষ্ট্যগুলিকে সমর্থন করে, যার মধ্যে রয়েছে:
- ক্লাস (ES2015)
- তীর ফাংশন (ES2015)
- জেনারেটর (ES2015)
- ব্লক স্কোপিং (ES2015)
- ধ্বংস করা (ES2015)
- বিশ্রাম এবং ছড়িয়ে পরামিতি (ES2015)
- অবজেক্ট শর্টহ্যান্ড (ES2015)
- অ্যাসিঙ্ক/অপেক্ষা (ES2017)
ভাষার স্পেসিফিকেশনের নতুন সংস্করণের বৈশিষ্ট্যগুলি সাধারণত আধুনিক ব্রাউজারগুলিতে কম সামঞ্জস্যপূর্ণ সমর্থন করে। উদাহরণস্বরূপ, অনেক ES2020 এবং ES2021 বৈশিষ্ট্য শুধুমাত্র ব্রাউজার মার্কেটের 70%-এ সমর্থিত—এখনও বেশিরভাগ ব্রাউজার, কিন্তু যথেষ্ট নয় যে এই বৈশিষ্ট্যগুলির উপর সরাসরি নির্ভর করা নিরাপদ। এর মানে হল যে যদিও "আধুনিক" জাভাস্ক্রিপ্ট একটি চলমান লক্ষ্য, ES2017-এ ব্রাউজার সামঞ্জস্যের বিস্তৃত পরিসর রয়েছে যেখানে সাধারণভাবে ব্যবহৃত বেশিরভাগ আধুনিক সিনট্যাক্স বৈশিষ্ট্যগুলি অন্তর্ভুক্ত রয়েছে । অন্য কথায়, ES2017 আজ আধুনিক সিনট্যাক্সের সবচেয়ে কাছের ।
লিগ্যাসি জাভাস্ক্রিপ্ট
লিগ্যাসি জাভাস্ক্রিপ্ট এমন কোড যা বিশেষভাবে উপরের সমস্ত ভাষা বৈশিষ্ট্যগুলি ব্যবহার করা এড়িয়ে যায়। বেশিরভাগ ডেভেলপার আধুনিক সিনট্যাক্স ব্যবহার করে তাদের সোর্স কোড লেখেন, কিন্তু ব্রাউজার সমর্থন বৃদ্ধির জন্য লিগ্যাসি সিনট্যাক্সে সবকিছু কম্পাইল করেন। লিগ্যাসি সিনট্যাক্সে কম্পাইল করা ব্রাউজার সমর্থন বাড়ায়, তবে প্রভাব প্রায়শই আমরা বুঝতে পারি তার চেয়ে কম। অনেক ক্ষেত্রে উল্লেখযোগ্য খরচ বহন করার সময় সমর্থন প্রায় 95% থেকে 98% পর্যন্ত বৃদ্ধি পায়:
লিগ্যাসি জাভাস্ক্রিপ্ট সাধারণত সমতুল্য আধুনিক কোডের চেয়ে প্রায় 20% বড় এবং ধীর। টুলিংয়ের ঘাটতি এবং ভুল কনফিগারেশন প্রায়শই এই ব্যবধানকে আরও প্রসারিত করে।
ইন্সটল করা লাইব্রেরিগুলি সাধারণত জাভাস্ক্রিপ্ট কোডের 90% এর জন্য দায়ী। পলিফিল এবং হেল্পার ডুপ্লিকেশনের কারণে লাইব্রেরি কোড একটি আরও বেশি উত্তরাধিকারী জাভাস্ক্রিপ্ট ওভারহেড বহন করে যা আধুনিক কোড প্রকাশের মাধ্যমে এড়ানো যেতে পারে।
npm-এ আধুনিক জাভাস্ক্রিপ্ট
সম্প্রতি, Node.js একটি প্যাকেজের জন্য এন্ট্রি পয়েন্ট সংজ্ঞায়িত করার জন্য একটি "exports"
ক্ষেত্রকে প্রমিত করেছে:
{
"exports": "./index.js"
}
"exports"
ক্ষেত্রের দ্বারা উল্লেখ করা মডিউলগুলি কমপক্ষে 12.8 এর একটি নোড সংস্করণ বোঝায়, যা ES2019 সমর্থন করে। এর মানে হল যে "exports"
ক্ষেত্র ব্যবহার করে উল্লেখ করা যেকোনো মডিউল আধুনিক জাভাস্ক্রিপ্টে লেখা যেতে পারে। প্যাকেজ গ্রাহকদের অবশ্যই একটি "exports"
ক্ষেত্রের মডিউলগুলিকে আধুনিক কোড এবং প্রয়োজনে ট্রান্সপিল ধারণ করতে হবে।
শুধুমাত্র আধুনিক
আপনি যদি আধুনিক কোড সহ একটি প্যাকেজ প্রকাশ করতে চান এবং ভোক্তারা যখন এটিকে নির্ভরতা হিসাবে ব্যবহার করেন তখন এটিকে ট্রান্সপিলিং পরিচালনা করার জন্য এটিকে ছেড়ে দিতে চান - শুধুমাত্র "exports"
ক্ষেত্রটি ব্যবহার করুন৷
{
"name": "foo",
"exports": "./modern.js"
}
উত্তরাধিকার ফলব্যাক সহ আধুনিক
আধুনিক কোড ব্যবহার করে আপনার প্যাকেজ প্রকাশ করার জন্য " "main"
সহ "exports"
ক্ষেত্রটি ব্যবহার করুন তবে লিগ্যাসি ব্রাউজারগুলির জন্য একটি ES5 + CommonJS ফলব্যাক অন্তর্ভুক্ত করুন৷
{
"name": "foo",
"exports": "./modern.js",
"main": "./legacy.cjs"
}
লিগ্যাসি ফলব্যাক এবং ESM বান্ডলার অপ্টিমাইজেশন সহ আধুনিক
একটি ফলব্যাক কমনজেএস এন্ট্রিপয়েন্ট সংজ্ঞায়িত করার পাশাপাশি, "module"
ক্ষেত্রটি একটি অনুরূপ লিগ্যাসি ফলব্যাক বান্ডেলকে নির্দেশ করতে ব্যবহার করা যেতে পারে, তবে একটি যা জাভাস্ক্রিপ্ট মডিউল সিনট্যাক্স ( import
এবং export
) ব্যবহার করে।
{
"name": "foo",
"exports": "./modern.js",
"main": "./legacy.cjs",
"module": "./module.js"
}
অনেক বান্ডলার, যেমন ওয়েবপ্যাক এবং রোলআপ, মডিউল বৈশিষ্ট্যগুলির সুবিধা নিতে এবং গাছ কাঁপানো সক্ষম করতে এই ক্ষেত্রের উপর নির্ভর করে৷ এটি এখনও একটি লিগ্যাসি বান্ডেল যাতে import
/ export
সিনট্যাক্স বাদ দিয়ে কোনো আধুনিক কোড থাকে না, তাই এই পদ্ধতিটি ব্যবহার করুন আধুনিক কোড একটি লিগ্যাসি ফলব্যাক সহ যা এখনও বান্ডেল করার জন্য অপ্টিমাইজ করা হয়েছে।
অ্যাপ্লিকেশনে আধুনিক জাভাস্ক্রিপ্ট
তৃতীয় পক্ষের নির্ভরতাগুলি ওয়েব অ্যাপ্লিকেশনগুলিতে সাধারণ উত্পাদন জাভাস্ক্রিপ্ট কোডের বিশাল সংখ্যাগরিষ্ঠতা তৈরি করে। যদিও npm নির্ভরতাগুলি ঐতিহাসিকভাবে লিগ্যাসি ES5 সিনট্যাক্স হিসাবে প্রকাশিত হয়েছে, এটি আর একটি নিরাপদ অনুমান নয় এবং নির্ভরতা আপডেটগুলি আপনার অ্যাপ্লিকেশনে ব্রাউজার সমর্থন ভাঙার ঝুঁকি তৈরি করে।
ক্রমবর্ধমান সংখ্যক এনপিএম প্যাকেজ আধুনিক জাভাস্ক্রিপ্টে স্থানান্তরিত হওয়ার সাথে সাথে, বিল্ড টুলিং তাদের পরিচালনা করার জন্য সেট আপ করা হয়েছে তা নিশ্চিত করা গুরুত্বপূর্ণ। আপনি যে এনপিএম প্যাকেজগুলির উপর নির্ভরশীল সেগুলি ইতিমধ্যেই আধুনিক ভাষার বৈশিষ্ট্যগুলি ব্যবহার করার একটি ভাল সুযোগ রয়েছে৷ পুরানো ব্রাউজারগুলিতে আপনার অ্যাপ্লিকেশন না ভেঙে npm থেকে আধুনিক কোড ব্যবহার করার জন্য অনেকগুলি বিকল্প উপলব্ধ রয়েছে, তবে সাধারণ ধারণাটি হল আপনার সোর্স কোডের মতো একই সিনট্যাক্স লক্ষ্যে বিল্ড সিস্টেম ট্রান্সপিল নির্ভরতা থাকা।
ওয়েবপ্যাক
ওয়েবপ্যাক 5 অনুসারে, বান্ডেল এবং মডিউলগুলির জন্য কোড তৈরি করার সময় সিনট্যাক্স ওয়েবপ্যাক কী ব্যবহার করবে তা এখন কনফিগার করা সম্ভব। এটি আপনার কোড বা নির্ভরতাকে স্থানান্তরিত করে না, এটি শুধুমাত্র ওয়েবপ্যাক দ্বারা উত্পন্ন "আঠালো" কোডকে প্রভাবিত করে। ব্রাউজার সমর্থন লক্ষ্য নির্দিষ্ট করতে, আপনার প্রকল্পে একটি ব্রাউজার তালিকা কনফিগারেশন যোগ করুন, অথবা সরাসরি আপনার ওয়েবপ্যাক কনফিগারেশনে করুন:
module.exports = {
target: ['web', 'es2017'],
};
অপ্টিমাইজড বান্ডিল তৈরি করতে ওয়েবপ্যাক কনফিগার করাও সম্ভব যা একটি আধুনিক ES মডিউল পরিবেশকে লক্ষ্য করার সময় অপ্রয়োজনীয় র্যাপার ফাংশন বাদ দেয়। এটি <script type="module">
ব্যবহার করে কোড-বিভক্ত বান্ডেলগুলি লোড করার জন্য ওয়েবপ্যাককে কনফিগার করে।
module.exports = {
target: ['web', 'es2017'],
output: {
module: true,
},
experiments: {
outputModule: true,
},
};
অপ্টিমাইজ প্লাগইন এবং BabelEsmPlugin-এর মতো লিগ্যাসি ব্রাউজারগুলিকে সমর্থন করার সময়ও অনেকগুলি ওয়েবপ্যাক প্লাগইন উপলব্ধ রয়েছে যা আধুনিক জাভাস্ক্রিপ্ট কম্পাইল এবং শিপিং করা সম্ভব করে৷
প্লাগইন অপ্টিমাইজ করুন
অপ্টিমাইজ প্লাগইন হল একটি ওয়েবপ্যাক প্লাগইন যা প্রতিটি পৃথক সোর্স ফাইলের পরিবর্তে চূড়ান্ত বান্ডিল কোডকে আধুনিক থেকে লিগ্যাসি জাভাস্ক্রিপ্টে রূপান্তরিত করে। এটি একটি স্বয়ংসম্পূর্ণ সেটআপ যা আপনার ওয়েবপ্যাক কনফিগারেশনকে সবকিছুই আধুনিক জাভাস্ক্রিপ্ট অনুমান করতে দেয় যাতে একাধিক আউটপুট বা সিনট্যাক্সের জন্য কোনো বিশেষ শাখা নেই৷
যেহেতু অপ্টিমাইজ প্লাগইন পৃথক মডিউলের পরিবর্তে বান্ডিলগুলিতে কাজ করে, তাই এটি আপনার অ্যাপ্লিকেশনের কোড এবং আপনার নির্ভরতাকে সমানভাবে প্রক্রিয়া করে। এটি এনপিএম থেকে আধুনিক জাভাস্ক্রিপ্ট নির্ভরতা ব্যবহার করা নিরাপদ করে তোলে, কারণ তাদের কোডটি বান্ডিল করা হবে এবং সঠিক সিনট্যাক্সে স্থানান্তরিত হবে। আধুনিক এবং লিগ্যাসি ব্রাউজারগুলির জন্য পৃথক বান্ডিল তৈরি করার সময় এটি দুটি সংকলন পদক্ষেপ জড়িত ঐতিহ্যগত সমাধানগুলির চেয়েও দ্রুত হতে পারে। বান্ডিলের দুটি সেট মডিউল/নোমডিউল প্যাটার্ন ব্যবহার করে লোড করার জন্য ডিজাইন করা হয়েছে।
// webpack.config.js
const OptimizePlugin = require('optimize-plugin');
module.exports = {
// ...
plugins: [new OptimizePlugin()],
};
Optimize Plugin
কাস্টম ওয়েবপ্যাক কনফিগারেশনের চেয়ে দ্রুত এবং আরও দক্ষ হতে পারে, যা সাধারণত আধুনিক এবং লিগ্যাসি কোডকে আলাদাভাবে বান্ডিল করে। এটি আপনার জন্য চলমান Babel পরিচালনা করে, এবং আধুনিক এবং উত্তরাধিকার আউটপুটগুলির জন্য পৃথক সর্বোত্তম সেটিংস সহ Terser ব্যবহার করে বান্ডিলগুলিকে ছোট করে। অবশেষে, জেনারেটেড লিগ্যাসি বান্ডিলগুলির দ্বারা প্রয়োজনীয় পলিফিলগুলি একটি ডেডিকেটেড স্ক্রিপ্টে নিষ্কাশন করা হয় যাতে সেগুলি নতুন ব্রাউজারগুলিতে কখনও সদৃশ বা অপ্রয়োজনীয়ভাবে লোড হয় না৷
BabelEsmPlugin
BabelEsmPlugin হল একটি ওয়েবপ্যাক প্লাগইন যা @babel/preset-env- এর সাথে কাজ করে আধুনিক ব্রাউজারগুলিতে কম ট্রান্সপিল কোড পাঠানোর জন্য বিদ্যমান বান্ডেলগুলির আধুনিক সংস্করণ তৈরি করতে। এটি মডিউল/নোমডিউলের জন্য সবচেয়ে জনপ্রিয় অফ-দ্য-শেল্ফ সমাধান, যা Next.js এবং Preact CLI দ্বারা ব্যবহৃত হয়।
// webpack.config.js
const BabelEsmPlugin = require('babel-esm-plugin');
module.exports = {
//...
module: {
rules: [
// your existing babel-loader configuration:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
plugins: [new BabelEsmPlugin()],
};
BabelEsmPlugin
ওয়েবপ্যাক কনফিগারেশনের বিস্তৃত অ্যারেকে সমর্থন করে, কারণ এটি আপনার অ্যাপ্লিকেশনের দুটি বড় আকারে পৃথক বিল্ড চালায়। দুইবার কম্পাইল করা বড় অ্যাপ্লিকেশনের জন্য কিছুটা অতিরিক্ত সময় নিতে পারে, তবে এই কৌশলটি BabelEsmPlugin
বিদ্যমান ওয়েবপ্যাক কনফিগারেশনে নির্বিঘ্নে একীভূত করতে দেয় এবং এটিকে উপলব্ধ সবচেয়ে সুবিধাজনক বিকল্পগুলির মধ্যে একটি করে তোলে।
নোড_মডিউল ট্রান্সপিল করতে ব্যাবেল-লোডার কনফিগার করুন
আপনি যদি আগের দুটি প্লাগইনের একটি ছাড়াই babel-loader
ব্যবহার করেন, তাহলে আধুনিক জাভাস্ক্রিপ্ট এনপিএম মডিউল ব্যবহার করার জন্য একটি গুরুত্বপূর্ণ পদক্ষেপ প্রয়োজন। দুটি পৃথক babel-loader
কনফিগারেশন সংজ্ঞায়িত করা ES2017-এ node_modules
এ পাওয়া আধুনিক ভাষার বৈশিষ্ট্যগুলিকে স্বয়ংক্রিয়ভাবে কম্পাইল করা সম্ভব করে, যখন এখনও আপনার প্রকল্পের কনফিগারেশনে সংজ্ঞায়িত ব্যাবেল প্লাগইন এবং প্রিসেটগুলির সাথে আপনার নিজস্ব প্রথম-পক্ষের কোড ট্রান্সপিল করে৷ এটি একটি মডিউল/নোমডিউল সেটআপের জন্য আধুনিক এবং লিগ্যাসি বান্ডিল তৈরি করে না, তবে এটি পুরানো ব্রাউজারগুলি না ভেঙে আধুনিক জাভাস্ক্রিপ্ট ধারণ করে এমন এনপিএম প্যাকেজগুলি ইনস্টল এবং ব্যবহার করা সম্ভব করে তোলে।
webpack-plugin-modern-npm এই কৌশলটি ব্যবহার করে এনপিএম নির্ভরতাগুলিকে কম্পাইল করতে যেগুলির package.json
এ একটি "exports"
ক্ষেত্র রয়েছে, যেহেতু এতে আধুনিক সিনট্যাক্স থাকতে পারে:
// webpack.config.js
const ModernNpmPlugin = require('webpack-plugin-modern-npm');
module.exports = {
plugins: [
// auto-transpile modern stuff found in node_modules
new ModernNpmPlugin(),
],
};
বিকল্পভাবে, আপনি কৌশলটি আপনার ওয়েবপ্যাক কনফিগারেশনে ম্যানুয়ালি প্রয়োগ করতে পারেন মডিউলগুলির package.json
.json-এ একটি "exports"
ক্ষেত্রের জন্য চেক করে যেমন সেগুলি সমাধান করা হয়েছে৷ সংক্ষিপ্ততার জন্য ক্যাশিং বাদ দিলে, একটি কাস্টম বাস্তবায়ন এইরকম দেখতে পারে:
// webpack.config.js
module.exports = {
module: {
rules: [
// Transpile for your own first-party code:
{
test: /\.js$/i,
loader: 'babel-loader',
exclude: /node_modules/,
},
// Transpile modern dependencies:
{
test: /\.js$/i,
include(file) {
let dir = file.match(/^.*[/\\]node_modules[/\\](@.*?[/\\])?.*?[/\\]/);
try {
return dir && !!require(dir[0] + 'package.json').exports;
} catch (e) {}
},
use: {
loader: 'babel-loader',
options: {
babelrc: false,
configFile: false,
presets: ['@babel/preset-env'],
},
},
},
],
},
};
এই পদ্ধতি ব্যবহার করার সময়, আপনাকে আধুনিক সিনট্যাক্স আপনার মিনিফায়ার দ্বারা সমর্থিত তা নিশ্চিত করতে হবে। Terser এবং uglify-es উভয়ের কাছেই সংকোচন এবং বিন্যাসকরণের সময় ES2017 সিনট্যাক্স সংরক্ষণ এবং কিছু ক্ষেত্রে তৈরি করার জন্য {ecma: 2017}
নির্দিষ্ট করার বিকল্প রয়েছে।
রোলআপ
রোলআপে একটি একক বিল্ডের অংশ হিসাবে একাধিক সেট বান্ডেল তৈরি করার জন্য অন্তর্নির্মিত সমর্থন রয়েছে এবং ডিফল্টরূপে আধুনিক কোড তৈরি করে। ফলস্বরূপ, আপনি সম্ভবত ইতিমধ্যেই ব্যবহার করছেন এমন অফিসিয়াল প্লাগইনগুলির সাথে আধুনিক এবং লিগ্যাসি বান্ডেল তৈরি করতে রোলআপ কনফিগার করা যেতে পারে।
@rollup/plugin-babel
আপনি যদি রোলআপ ব্যবহার করেন, getBabelOutputPlugin()
পদ্ধতি (Rolup-এর অফিসিয়াল Babel plugin দ্বারা প্রদত্ত) কোডটিকে পৃথক সোর্স মডিউলের পরিবর্তে জেনারেট করা বান্ডিলে রূপান্তরিত করে। রোলআপে একটি একক বিল্ডের অংশ হিসাবে একাধিক সেট বান্ডিল তৈরি করার জন্য অন্তর্নির্মিত সমর্থন রয়েছে, প্রতিটি তাদের নিজস্ব প্লাগইন সহ। একটি ভিন্ন ব্যাবেল আউটপুট প্লাগইন কনফিগারেশনের মাধ্যমে প্রতিটি পাস করে আপনি আধুনিক এবং উত্তরাধিকারের জন্য বিভিন্ন বান্ডিল তৈরি করতে এটি ব্যবহার করতে পারেন:
// rollup.config.js
import {getBabelOutputPlugin} from '@rollup/plugin-babel';
export default {
input: 'src/index.js',
output: [
// modern bundles:
{
format: 'es',
plugins: [
getBabelOutputPlugin({
presets: [
[
'@babel/preset-env',
{
targets: {esmodules: true},
bugfixes: true,
loose: true,
},
],
],
}),
],
},
// legacy (ES5) bundles:
{
format: 'amd',
entryFileNames: '[name].legacy.js',
chunkFileNames: '[name]-[hash].legacy.js',
plugins: [
getBabelOutputPlugin({
presets: ['@babel/preset-env'],
}),
],
},
],
};
অতিরিক্ত নির্মাণ সরঞ্জাম
রোলআপ এবং ওয়েবপ্যাক অত্যন্ত কনফিগারযোগ্য, যার মানে সাধারণত প্রতিটি প্রকল্পের কনফিগারেশন আপডেট করতে হবে নির্ভরতাগুলিতে আধুনিক জাভাস্ক্রিপ্ট সিনট্যাক্স সক্ষম করে। এছাড়াও উচ্চ-স্তরের বিল্ড টুল রয়েছে যা কনভেনশন এবং কনফিগারেশনের উপর ডিফল্টের পক্ষে, যেমন Parcel , Snowpack , Vite এবং WMR । এই টুলগুলির বেশিরভাগই অনুমান করে যে npm নির্ভরতা আধুনিক সিনট্যাক্স ধারণ করতে পারে, এবং উৎপাদনের জন্য তৈরি করার সময় উপযুক্ত সিনট্যাক্স স্তর(গুলি) এগুলিকে স্থানান্তরিত করবে।
ওয়েবপ্যাক এবং রোলআপের জন্য ডেডিকেটেড প্লাগইনগুলি ছাড়াও, আধুনিক জাভাস্ক্রিপ্ট বান্ডিলগুলি লেগসি ফলব্যাক সহ যেকোন প্রজেক্টে ডিভোলিউশন ব্যবহার করে যোগ করা যেতে পারে। ডিভোলিউশন হল একটি স্বতন্ত্র টুল যা একটি বিল্ড সিস্টেম থেকে আউটপুটকে লিগ্যাসি জাভাস্ক্রিপ্ট ভেরিয়েন্ট তৈরি করার জন্য রূপান্তরিত করে, যা বান্ডলিং এবং রূপান্তরগুলিকে একটি আধুনিক আউটপুট লক্ষ্যমাত্রা অনুমান করার অনুমতি দেয়।