Shimming এমন একটি কৌশল যা নির্দিষ্ট গ্লোবাল ভেরিয়েবল বা API প্রত্যাশা করা মডিউলগুলোর সামঞ্জস্য নিশ্চিত করে। Webpack ইকোসিস্টেমে, shimming বাস্তবায়িত হয় ProvidePlugin, imports-loader এবং exports-loader-এর মাধ্যমে, যা সোর্স কোড পরিবর্তন না করেই legacy লাইব্রেরি সংযুক্ত করতে দেয়। Webpack Documentation (2026)-এর মতে, shimming মডুলার সিস্টেম সমর্থন করে না এমন jQuery প্লাগইন এবং অন্যান্য নির্ভরতা একীভূত করার জন্য একটি মূল হাতিয়ার হিসেবে রয়ে গেছে।
মূল বিষয়
Shimming এমন একটি সফটওয়্যার কৌশল যা মডিউলের সোর্স কোড পরিবর্তন না করেই কোড এবং পরিবেশের মধ্যে একটি সামঞ্জস্য স্তর স্থাপন করে। JavaScript বিল্ডের প্রেক্ষাপটে, shimming তখনই সমস্যা সমাধান করে যখন কোনো মডিউল গ্লোবাল ভেরিয়েবল (window.$, global.process) অ্যাক্সেস করে, যা মডুলার পরিবেশে উপস্থিত নেই।
Polyfill অনুপস্থিত কার্যকারিতা শূন্য থেকে বাস্তবায়ন করে, পরিবেশে নতুন ক্ষমতা যোগ করে। উদাহরণস্বরূপ, core-js পুরনো ব্রাউজারগুলোর জন্য Array.prototype.flatMap যোগ করে। Shim বিদ্যমান কলগুলোকে উপলব্ধ বাস্তবায়নের দিকে পুনঃনির্দেশ করে বা প্রত্যাশিত গ্লোবাল অবজেক্ট প্রতিস্থাপন করে। Webpack-এ, ProvidePlugin স্বয়ংক্রিয়ভাবে import $ from 'jquery' এমন প্রতিটি জায়গায় ঢুকিয়ে দেয় যেখানে গ্লোবাল ভেরিয়েবল $-এর রেফারেন্স পাওয়া যায়, কোডে কোনো পরিবর্তন ছাড়াই।
প্রধান পার্থক্য লক্ষ্যে। Polyfill যা নেই তা যোগ করে, আর shim বিদ্যমান কোডকে যে পরিবেশে এটি চলে তার সাথে সামঞ্জস্যপূর্ণ করে তোলে। তাদের মধ্যে পছন্দ নির্ভর করে কোন সমস্যা সমাধান করা হচ্ছে তার উপর: API-এর অনুপস্থিতি বা ইন্টারফেসের অসামঞ্জস্য।
Webpack প্রতিটি মডিউলকে নিজস্ব স্কোপসহ একটি বিচ্ছিন্ন একক হিসেবে প্রক্রিয়া করে। যদি কোনো লাইব্রেরি গ্লোবাল ভেরিয়েবল jQuery কে window.$ হিসেবে অ্যাক্সেস করে, তাহলে বিল্ডটি ত্রুটি দিয়ে শেষ হবে, কারণ মডুলার কনটেক্সটে এই ভেরিয়েবলটি নেই। ProvidePlugin কম্পাইলেশন পর্যায়ে সমস্যার সমাধান করে: কোডে আইডেন্টিফায়ার $ শনাক্ত হলে প্লাগইন স্বয়ংক্রিয়ভাবে ফাইলের শুরুতে import $ from 'jquery' ঢুকিয়ে দেয়।
// মূল কোড (legacy মডিউল গ্লোবাল jQuery অ্যাক্সেস করে)
$('.element').hide();
// ProvidePlugin প্রক্রিয়াকরণের পর (Webpack import ঢুকিয়ে দেয়)
import $ from 'jquery';
$('.element').hide();
উপরন্তু, imports-loader স্পষ্টভাবে নির্দিষ্ট করতে দেয় যে একটি মডিউলকে কোন নির্ভরতা গ্রহণ করা উচিত। এটি তখন কার্যকর যখন লাইব্রেরি উপরের স্তরে this ব্যবহার করে, প্রত্যাশা করে যে this module.exports-এর পরিবর্তে window-কে নির্দেশ করে।
ProvidePlugin Webpack-এর অন্তর্নির্মিত প্লাগইন যা নির্দিষ্ট আইডেন্টিফায়ারের রেফারেন্স শনাক্ত করলে স্বয়ংক্রিয়ভাবে মডিউল লোড করে। কনফিগারেশনটি একটি অবজেক্ট যেখানে কী হলো ভেরিয়েবলের নাম, আর মান হলো মডিউলের পথ এবং এক্সপোর্ট করা ফিল্ড।
// webpack.config.js
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
_: 'lodash',
'window.$': 'jquery',
}),
],
};
ProvidePlugin অ্যারে সিনট্যাক্সের মাধ্যমে আংশিক ইমপোর্ট সমর্থন করে। উদাহরণস্বরূপ, [lodash, debounce] lodash থেকে শুধুমাত্র debounce ফাংশন ইমপোর্ট করে, যা চূড়ান্ত বান্ডেলের আকার কমায়। এটি মোবাইল প্রজেক্টের জন্য বিশেষভাবে গুরুত্বপূর্ণ, যেখানে প্রতিটি কিলোবাইট লোড সময়কে প্রভাবিত করে।
imports-loader মডিউলের শুরুতে প্রয়োজনীয় ইমপোর্ট যোগ করে, আর exports-loader মডিউলগুলোর জন্য এক্সপোর্ট মান নির্ধারণ করে যেগুলো স্পষ্টভাবে module.exports ব্যবহার করে না। এই লোডারগুলো পৃথক ফাইলের স্তরে কাজ করে, ProvidePlugin-এর মতো বিশ্বব্যাপী নয়।
// webpack.config.js — imports-loader-এর সেটিং
module.exports = {
module: {
rules: [
{
test: /legacy-module\.js$/,
use: [
{
loader: 'imports-loader',
options: {
imports: [
'jquery',
'$',
],
},
},
],
},
],
},
};
exports-loader ব্যবহার করা হয় যখন লাইব্রেরি কোনো গ্লোবাল ভেরিয়েবলে মান বরাদ্দ করে, কিন্তু মডুলার সিস্টেমের মাধ্যমে তা এক্সপোর্ট করে না। লোডার মানটি বের করে সেটিকে মডুলার এক্সপোর্টে রূপান্তর করে, যা অন্য মডিউলগুলোকে import-এর মাধ্যমে এটি ইমপোর্ট করতে দেয়।
Shimming webpack.config.js-এ প্লাগইন এবং লোডারের সংমিশ্রণের মাধ্যমে কনফিগার করা হয়। সাধারণ পরিস্থিতিতে গ্লোবাল ভেরিয়েবলের জন্য ProvidePlugin এবং স্কোপ পরিবর্তন প্রয়োজন এমন নির্দিষ্ট মডিউলগুলোর জন্য imports-loader অন্তর্ভুক্ত থাকে।
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
globalObject: 'this',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules\/(?!legacy-lib)/,
use: [
{
loader: 'imports-loader',
options: {
type: 'commonjs',
imports: ['jquery', '$'],
},
},
],
},
],
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
],
};
output-এ globalObject ফিল্ড উপরের স্তরে this-এর রেফারেন্সের জন্য কনটেক্সট নির্ধারণ করে। ব্রাউজার পরিবেশের জন্য, 'this' মান window-কে নির্দেশ করে, আর React Native বা Node.js-এর জন্য — global-কে। সঠিক মান নির্বাচন লক্ষ্য পরিবেশে রানটাইম ত্রুটি প্রতিরোধ করে।
Shimming একটি শক্তিশালী কিন্তু বিপজ্জনক হাতিয়ার। ভুল কনফিগারেশনে বান্ডেলে কোডের নকল, নামের দ্বন্দ্ব এবং অপ্রত্যাশিত রানটাইম ত্রুটি দেখা দেয়। ডেভেলপাররা প্রায়ই ভুলে যায় যে ProvidePlugin কম্পাইলেশন পর্যায়ে কাজ করে এবং ভেরিয়েবলের ডাইনামিক রেফারেন্স প্রক্রিয়া করতে পারে না।
যদি দুটি প্লাগইন jQuery-এর ভিন্ন সংস্করণ ব্যবহার করে, তাহলে ProvidePlugin শুধুমাত্র তাদের একটি প্রতিস্থাপন করবে, যা কনফিগারেশনে প্রথমে নির্দিষ্ট করা থাকে। দ্বিতীয় লাইব্রেরি একটি অসামঞ্জস্যপূর্ণ সংস্করণ পাবে, যা ডিবাগ করা কঠিন ত্রুটি ঘটাবে। সমাধান — প্রতিটি লাইব্রেরির জন্য স্পষ্ট সংস্করণসহ exports-loader ব্যবহার করা বা নকল মডিউল বাদ দিতে webpack.IgnorePlugin প্রয়োগ করা।
আরেকটি সাধারণ ভুল — এমন মডিউল shim করার চেষ্টা করা যা ডাইনামিক কনটেক্সটে CommonJS সিঙ্ক্রোনাস require কল ব্যবহার করে। ProvidePlugin শুধুমাত্র স্ট্যাটিক আইডেন্টিফায়ার প্রক্রিয়া করে, তাই ডাইনামিক রেফারেন্স ম্যানুয়ালি বা NormalModuleReplacementPlugin দিয়ে প্রতিস্থাপন করতে হবে।
shimming-এর ভুল সেটিং বান্ডেলের আকার উল্লেখযোগ্যভাবে বাড়াতে পারে। যদি ProvidePlugin কয়েক ডজন গ্লোবাল ভেরিয়েবলের জন্য কনফিগার করা থাকে, তাহলে Webpack প্রজেক্টের সব ফাইলে সংশ্লিষ্ট ইমপোর্ট ঢুকিয়ে দেবে, সেগুলি প্রতিটি নির্দিষ্ট ফাইলে ব্যবহার হচ্ছে কি না তা নির্বিশেষে। এটি অতিরিক্ত কোড তৈরি করে, বিশেষ করে হাজার হাজার মডিউলসহ বড় প্রজেক্টে।
shimming সমস্যা নির্ণয়ের জন্য webpack-bundle-analyzer ব্যবহার করুন — বান্ডেলের গঠন ভিজ্যুয়ালাইজ করার একটি হাতিয়ার। যদি jQuery বা অন্য কোনো লাইব্রেরি বান্ডেলে একাধিকবার দেখা যায়, তবে সম্ভবত ভিন্ন সংস্করণ দ্বন্দ্ব করছে বা ProvidePlugin প্যাকেজের ভিন্ন সংস্করণে নিয়ে যাওয়া বেশ কয়েকটি আইডেন্টিফায়ারের জন্য কনফিগার করা আছে। সমাধান — resolve.alias-এর মাধ্যমে নির্ভরতার সংস্করণ একীভূত করা এবং নিশ্চিত করা যে সব shim করা আইডেন্টিফায়ার একই মডিউলকে নির্দেশ করে।
shimming প্রয়োগের আগে, লাইব্রেরি মডুলার সিস্টেম সমর্থনকারী সংস্করণে আপডেট করা সম্ভব কিনা তা মূল্যায়ন করুন। অনেক legacy প্যাকেজের আধুনিক বিকল্প রয়েছে যেগুলোর shimming প্রয়োজন হয় না। উদাহরণস্বরূপ, jQuery প্লাগইন ব্রাউজারের নেটিভ API দিয়ে প্রতিস্থাপন করা যায়: $.ajax → fetch, $.each → Array.forEach। রিফ্যাক্টরিং রক্ষণাবেক্ষণে দীর্ঘমেয়াদী সুবিধা দেয়, আর shimming একটি অস্থায়ী সমাধান যা কনফিগারেশন জটিল করে।
যদি আপডেট সম্ভব না হয়, তবে NormalModuleReplacementPlugin বিবেচনা করুন, যা সোর্স কোড পরিবর্তন না করেই রিজলিউশন স্তরে একটি মডিউলকে অন্যটির সাথে প্রতিস্থাপন করতে দেয়। এই প্লাগইনটি লোডার প্রয়োগের আগে, নির্ভরতা গ্রাফ নির্মাণের পর্যায়ে কাজ করে এবং কনটেক্সট নির্বিশেষে মডিউলের সব রেফারেন্স প্রক্রিয়া করে। সম্পূর্ণ লাইব্রেরি প্রতিস্থাপনের জন্য এটি পয়েন্টওয়াইজ লোডারের চেয়ে পরিচ্ছন্ন সমাধান।
ব্রাউজারে নেটিভ ES মডিউল-এর বিকাশ এবং import maps-এর আবির্ভাবের সাথে, কিছু shimming পরিস্থিতি Webpack ছাড়াই সমাধান করা যায়। Import maps বিল্ড পর্যায় ছাড়াই ব্রাউজার স্তরে মডিউলের নাম গতিশীলভাবে পুনঃনির্দেশ করতে দেয়। তবে এই পদ্ধতি React Native এবং ব্রাউজার ESM ছাড়া অন্যান্য পরিবেশে সমর্থিত নয়, তাই Webpack-এর মাধ্যমে shimming production বিল্ডের জন্য প্রাসঙ্গিক রয়ে গেছে, যেখানে নির্ভরতা এবং তাদের সংস্করণের উপর সম্পূর্ণ নিয়ন্ত্রণ প্রয়োজন। Import maps এবং Webpack shims-এর মধ্যে পছন্দ লক্ষ্য প্ল্যাটফর্ম এবং পুরনো ব্রাউজারের সাথে সামঞ্জস্যের প্রয়োজনীয়তার উপর নির্ভর করে।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Shimming সামঞ্জস্য নিশ্চিত করতে কোড যোগ করে, আর tree shaking অব্যবহৃত কোড সরিয়ে দেয়। এই কৌশল দুটি লক্ষ্যে বিপরীত: shimming বান্ডেলের আকার বাড়ায়, tree shaking কমায়। Production বিল্ডে দুটোই ক্রমানুসারে প্রয়োগ করা হয়।
হ্যাঁ, shimming Webpack থেকে স্বাধীন একটি কৌশল হিসেবে বিদ্যমান — উদাহরণস্বরূপ, HTML-এ গ্লোবাল স্ক্রিপ্টের মাধ্যমে বা পুনঃএক্সপোর্টসহ ES মডিউলের মাধ্যমে। তবে Webpack সবচেয়ে সুবিধাজনক অটোমেশন হাতিয়ার প্রদান করে: ProvidePlugin এবং লোডার, যেগুলোতে কোডে ম্যানুয়াল পরিবর্তনের প্রয়োজন হয় না।
ProvidePlugin বিল্ডের গতিকে প্রভাবিত করে না, কারণ এটি AST কম্পাইলেশন পর্যায়ে কাজ করে। imports-loader এবং exports-loader প্রতিটি ফাইল প্রক্রিয়ায় সামান্য সময় যোগ করে। শত শত ফাইলে ব্যবহার করলে পার্থক্য মোট বিল্ড সময়ের 5–15% হতে পারে।
যদি সব নির্ভরতা ES মডিউল এবং মডুলার সিস্টেম সমর্থন করে, তাহলে shimming অপ্রয়োজনীয়। shimming ছাড়লে কনফিগারেশন সহজ হয়, বান্ডেলের আকার কমে এবং নামের দ্বন্দ্বের ঝুঁকি হ্রাস পায়। caniuse.com-এ নির্ভরতা যাচাই করার পরামর্শ দেওয়া হয়।
TypeScript-এ shim করা ভেরিয়েবলের জন্য অতিরিক্ত টাইপ ঘোষণার প্রয়োজন। declare const $: any যোগ করা বা @types/jquery-এর মাধ্যমে টাইপ ইনস্টল করা প্রয়োজন। ProvidePlugin TypeScript কম্পাইলেশনের পর JavaScript স্তরে ইমপোর্ট ঢুকিয়ে দেয়, তাই টাইপ আলাদাভাবে যাচাই করা হয়।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন