ইন্টারনেট যুগের শুরুতে, ওয়েবসাইটগুলো অনেক সিম্পল ছিল এবং খুব ইন্টারেক্টিভ নয়। প্রযুক্তি, ডিভাইস, এবং প্রোগ্রামিং ল্যাঙ্গুয়েজের উন্নতির সাথে সাথে, সেগুলো আরও কমপ্লেক্স হয়ে উঠল এবং চিত্র, CSS স্টাইলশিটের মতো এসেটসহ বেশ কয়েক ফাইল নিয়ে গঠিত হয়ে গেল।
আপনার ওয়েবসাইট যত ইন্টারেক্টিভ, ততটুকু JavaScript কোড ব্যবহার করতে হয়। সellas কোড ব্যবহার করতে, আপনাকে সব HTML কোড ফাইলে script ট্যাগ দিয়ে ইনক্লুড করতে হতো। এমন পদ্ধতি error-prone কারণ আপনাকে প্রতিটি ফাইল মনে রাখতে হয়ে এবং সঠিক অর্ডার মেইনটেইন করতে হয়, না হলে আপনার কোড কাজ নাও করতে পারে। Webpack টুল দিয়ে এই সমস্যাগুলো দূর হয়। Webpacker হলো Webpack এবং একটি রেইলস অ্যাপ্লিকেশনের মধ্যে একটি ব্রিজ।
এই আর্টিকেল Webpacker-এ গভীরে ডুব মেরে এবং একটি ডিটেইলড এক্সপ্লানেশন দেয় যা আপনাকে বুঝতে সাহায্য করবে এই টুল কীভাবে হুডের নিচে কাজ করে। কন্টেন্ট যতটুকু সম্ভব মূল্যবান করা হয়, সেজন্য আমি এটি নিচের সেকশনগুলতে ভাগ করার সিদ্ধান্ত নিলাম:
- হাই-লেভেল ওভারভিউ (High-level overview) — গভীরে যাওয়ার আগে, আমি Webpack এবং Webpacker-এর হাই-লেভেল ওভারভিউ ব্যাখ্যা করব। আপনি এটাকে আরও অ্যাডভান্সড টপিকের প্রস্তুতি হিসেবে বিবেচনা করতে পারেন।
- স্ট্রাকচার এক্সপ্লানেশন (Structure explanation) — যেহেতু আমরা একাধিক ফাইল এক্সপ্লোর করব, জানা ভালো যে কেন নির্দিষ্ট স্ট্রাকচার ব্যবহার করা হয়েছে এবং এটি সাধারণ উদ্দেশ্যে কীভাবে প্রতিক্রিয়া জানায়।
- অ্যানাটমি এক্সপ্লানেশন (Anatomy explanation) — এই পার্টটি Webpack সেটআপের সবচোয়ে গুরুত্বপূর্ণ ফাইলগুলোর ইনভেস্টিগেশন কভার করে। কীভাবে সেগুলো কাজ করে সেটা জানা ডেভেলপমেন্ট প্রসেসকে ইফেক্টিভ এবং হ্যাসেল-ফ্রি করতে অত্যন্ত জরুরি।
- এনভায়রনমেন্ট-স্পেসিফিক সেটআপ (Environment specific setup) — লাস্ট পার্ট ব্যাখ্যা করে Webpacker কীভাবে ডেভেলপমেন্ট এবং প্রোডাকশন এনভায়রনমেন্টে কাজ করে।
এই আর্টিকেল পড়ার পর, আপনি জানবেন Webpack এবং Webpacker কী এবং কেন আমাদের রেইলস অ্যাপ্লিকেশনে এগুলো দরকার। Webpacker-এর ইন্টারন্যালসের গভীর ডাইভ আপনাকে বুঝতে সাহায্য করবে কীভাবে টুলটি Webpack-এর সাথে সংযুক্ত হয় এবং রেইলস অ্যাপ্লিকেশনের সাথে কীভাবে কমিউনিকেশন করে।
ডুব মারার আগে (Before Diving In)
গভীর জলে যাওয়ার আগে, আমাদের প্রথমে প্রস্তুতি নিতে হবে। হাই-লেভেল ওভারভিউ যেকোনো টেকনোলজির সাথে কাজ শুরু করার একটি চমৎকার উপায় কারণ এটি আমাদের একটি দেয়া টুলের উদ্দেশ্য এবং সেটা কী সমস্যা সমাধান করে সেটা বুঝতে সাহায্য করে তার ইন্টারন্যালসে যাওয়ার আগে।
Webpack
আমি ইতিমধ্যে বলেছি Webpack আমাদের JavaScript ফাইল কোড অর্গানাইজ করতে সাহায্য করে এরর এড়াতে এবং ওয়েবসাইটের পারফরম্যান্স উন্নত করতে। এটি কোডকে বান্ডেলে অর্গানাইজ করে।
একটি বান্ডেল হলো একটি ফাইল যেখানে একাধিক মডিউল বুদ্ধিমত্তাপूर्णভাবে প্লেস করা থাকে, ডিপেন্ডেন্সি গ্রাফকে রেসপেক্ট করে যেটা প্রথমে তৈরি হয়। এই প্রসেসের জন্য, আমরা নিশ্চিত হতে পারি যে আমাদের কোড প্রত্যাশা অনুযায়ী কাজ করবে এবং একটি দেয়া লাইব্রেরির কোড ইনভোক করার আগে, সেটা লোড হয়ে যাবে।
Webpack একমাত্র টুল নয় যা রেইলসের নিউইস্ট ভার্সনে ডিফল্টলি ব্যবহার হয়। প্রজেক্ট জেনারেট হলে, Babel এবং PostCSS-এর কনফিগারেশন ফাইলগুলোও তৈরি হয়। PostCSS হলো একটি টুল CSS কে JavaScript দিয়ে ট্রান্সফর্ম করার জন্য, এবং Babel হলো একটি JavaScript কম্পাইলার যা আমাদের মডার্ন JavaScript লিখতে দেয় ব্রাউজার সাপোর্ট নিয়ে চিন্তা না করে।
Webpacker
Webpacker হলো একটি টুল যা Webpack কে একটি রেইলস অ্যাপ্লিকেশনের সাথে ইন্টিগ্রেট করে। এটি JavaScript-লাইক অ্যাপ্লিকেশন কনফিগার এবং ডেভেলপ করা সহজ করে এবং প্রোডাকশন এনভায়রনমেন্টের জন্য সেগুলো অপ্টিমাইজ করে।
সোর্স কোড একটি জেম হিসেবে উপলব্ধ, এবং লাইব্রেরি একটি ডেভেলপমেন্ট সার্ভারের সাথে আসে যা অ্যাপ ডেভেলপমেন্টকে খুব দ্রুত করে কারণ আপনাকে জাভাস্ক্রিপ্ট ফাইলগুলোর পরিবর্তন দেখতে সার্ভার স্টপ এবং স্টার্ট করতে হয় না।
গভীর নিমজ্জন (The Deep Immersion)
এখন আপনি জানেন Webpack কেন তৈরি হয়েছিল এবং Webpacker রেইলস অ্যাপ্লিকেশনে কী ভূমিকা পালন করে, আমরা Webpacker-এর ইন্টারন্যালসে ফোকাস করতে পারি দেখতে এটি কীভাবে ফাইলগুলো অর্গানাইজ করে, ডেভেলপমেন্ট প্রসেস স্পিড আপ করে, এবং প্রোডাকশন এনভায়রনমেন্টের জন্য ফাইলগুলো অপ্টিমাইজ করে।
Webpacker রেইলসের নিউইস্ট ভার্সনে আউট-অফ-দ-বক্স উপলব্ধ। নতুন প্রজেক্ট তৈরি করার আগে, নিশ্চিত করুন Node ভার্সন ১০.১৭.০ বা তার বেশি কারণ webpacker:install কমান্ড rails new কমান্ডের সাথে অটোমেটিক্যালি ইনভোক হবে।
Webpacker ফাইল স্ট্রাকচার
ইনস্টল কমান্ড এক্সিকিউট হলে, নিচের ফাইলগুলো তৈরি হয়:
config/webpacker.yml— মেইন কনফিগারেশন ফাইল যেটা ডিফল্ট কনফিগারেশন এবং স্পেসিফিক এনভায়রনমেন্টের জন্য কনফিগারেশন ধারণ করেconfig/webpacker/— ডিরেক্টরি যেখানে নির্দিষ্ট এনভায়রনমেন্টের জন্য JavaScript কনফিগারেশন ফাইলগুলো তৈরি হয়bin/webpack— একটি এক্সিকিউটেবল ফাইল যা webpack ইনভোক করে বান্ডেল তৈরি করতেbin/webpack-dev-server— একটি এক্সিকিউটেবল ফাইল যা ডেভেলপমেন্ট সার্ভার শুরু করে, যা webpack রিলোড করে প্রতিবার আপনি বান্ডেলে ইনক্লুডেড JavaScript ফাইলগুলোর মধ্যে পরিবর্তন আনার সময়
কনফিগারেশন ফাইলের অ্যানাটমি (The Anatomy of the Configuration File)
Webpacker-এর মেইন কনফিগারেশন ফাইল config ডিরেক্টরির অধীনে রয়েছে, এবং এর নাম webpacker.yml। Webpacker-এর বিপরীতে, Webpack-এর কনফিগারেশন প্রতিটি এনভায়রনমেন্টের জন্য আলাদা সংরক্ষিত থাকে config/webpack ডিরেক্টরির অধীনে।
Webpacker
ডিফল্টভাবে, কনফিগারেশন ফাইলে অনেক এন্ট্রি রয়েছে — ডিফল্টগুলো, এবং প্রতিটি এনভায়রনমেন্টের জন্য সেকশন যেখানে আপনি স্পেসিফিক সেটিংস ওভাররাইড করতে পারেন। সবচোয়ে গুরুত্বপূর্ণ সেটিংগুলো দেখি:
source_path— আপনার অ্যাপ্লিকেশনে জাভাস্ক্রিপ্ট ফাইলগুলোর প্রাইমারি সোর্স। ডিফল্টভাবেapp/javascript-এ সেট করা থাকে, এবং সাধারণত এই ভ্যালু চেঞ্জ করার প্রয়োজন নেই।source_entry_path— source_path-এর অধীনে সেই ডিরেক্টরির নাম যেখানে আপনি প্যাক ফাইলগুলো রাখেন, অর্থাৎ এন্ট্রি পয়েন্ট। ডিফল্টভাবে এই সেটিংটি packs ডিরেক্টরিতে সেট করা থাকে।public_root_path— আপনার অ্যাপ্লিকেশনের সেই ডিরেক্টরির পাথ যা ব্রাউজার থেকে অ্যাক্সেসযোগ্য। একটি টিপিক্যাল রেইলস অ্যাপ্লিকেশনে, এটি public ডিরেক্টরি।public_output_path— Webpacker আপনার ফাইলগুলো কম্পাইল করলে, কম্পাইল করা সকল ফাইল এই ডিরেক্টরিতেpublic_root_path-এর অধীনে রাখবে। ডিফল্টভাবে ডিরেক্টরির নাম packs, কিন্তু আপনি যা ইচ্ছা নাম দিতে পারেন।webpack_compile_output— যদি ফ্ল্যাগটি true সেট করা থাকে, তবে ফাইল কম্পাইল হলে আউটপুট মেসেজ ডিসপ্লে হবে। কম্পাইল ফেল করলে এটি উপকারী, কারণ আপনি সেটা জানতে পারবেন এবং একশন নিতে পারবেন।
উল্লেখ্য যে ডেভেলপমেন্ট সেকশনে ডেভ সার্ভারের কনফিগারেশনও রয়েছে যা ডেভেলপমেন্ট এনভায়রনমেন্টে ফাইল কম্পাইল করতে ব্যবহৃত হয় সার্ভার রিস্টার্ট ছাড়া।
আপনি যদি রেইলস কনসোল বা কোড লেভেল থেকে কনফিগারেশন অ্যাক্সেস করতে চান, তবে Webpacker.manifest.config কল করতে পারেন, যা কনফিগারেশন ক্লাস ইন্সট্যান্স রিটার্ন করবে।
Webpack
প্রতিটি এনভায়রনমেন্টের তার কনফিগারেশন ফাইল রয়েছে, কিন্তু প্রতিটি ফাইলে মেইন এনভায়রনমেন্ট ফাইল ইম্পোর্ট করা থাকে: config/webpack/environment.js। এনভায়রনমেন্ট কনফিগারেশন ফাইলে কাস্টম প্লাগইন লোড করার জায়গা রয়েছে যা Webpack-এর ডিফল্ট বিহেভিয়ার মডিফাই করবে। আমরা আমাদের ফাইল কম্পাইল করার জন্য কাস্টম রুলও যোগ করতে পারি।
প্যাক ফাইলের অ্যানাটমি (The Anatomy of the Pack File)
প্যাক ফাইলগুলো app/javascript/packs ডিরেক্টরির অধীনে লোকেটেড। প্রতিটি প্যাক ফাইল Webpacker দ্বারা কম্পাইলেশন প্রসেস শুরু হলে একটি এন্ট্রি পয়েন্ট হিসেবে বিবেচিত হয়।
ডিফল্ট প্যাক ফাইল (The Default Pack File)
নতুন রেইলস প্রজেক্ট জেনারেট করলে, application.js নামে একটি ডিফল্ট প্যাক ফাইল তৈরি হয় নিচের কন্টেন্টসহ:
import Rails from "@rails/ujs"; import Turbolinks from "turbolinks"; import * as ActiveStorage from "@rails/activestorage"; import "channels"; Rails.start(); Turbolinks.start(); ActiveStorage.start();
আপনি দেখতে পাচ্ছেন, প্রথম ধাপ হলো দেয়া লাইব্রেরি ইম্পোর্ট করা এবং তারপর প্রয়োজনে এর ইনিশিয়ালাইজেশন মেথড কল করা। আপনি যখন import কল করেন, সিস্টেম দেয়া নোড মডিউল বা লোকাল লাইব্রেরি খুঁজে বের করে। স্ট্যান্ডার্ড অ্যাপ্রোচে, আপনাকে এক্সপ্লিসিটলি লাইব্রেরি ইনিশিয়ালাইজ করতে হয় না কারণ সেটা ইনিশিয়ালাইজ হয়ে যায় যখন আপনি পেজ সোর্সে script ট্যাগ দিয়ে ইনক্লুড করেন।
প্যাক ফাইলের জন্য ভালো প্র্যাকটিস (Good Practices for a Pack File)
যদিও আপনি প্যাক ফাইলে রেগুলার JavaScript কোড রাখতে এবং এক্সিকিউট করতে পারেন, এটি রিকমেন্ডেড নয় প্যাক ফাইলে JavaScript কোড রাখা। সেরা পদ্ধতি হলো ফাইলগুলো ক্লিন রাখা এবং শুধু লাইব্রেরি ইম্পোর্ট ও ইনিশিয়ালাইজ করা এখানে এবং অন্যান্য লজিক প্যাকস ডিরেক্টরির বাইরে রাখা।
প্যাক ফাইল অ্যাপ্লিকেশনে ইনক্লুড করা (Including Pack Files in the Application)
প্যাক ফাইলগুলো অটোমেটিক্যালি ওয়েবসাইটের সোর্সে ইনক্লুড হয় না। এসেট পাইপলাইনের কেসের মতো, আমাদের ভিউতে একটি স্পেশাল ট্যাগ ব্যবহার করতে হয়:
<%= javascript_packs_with_chunks_tag 'application' %>
এই মেথড কীভাবে কাজ করে? হুডের নিচে, এটি Webpacker কনফিগারেশন কল করে যেটা আপনার config/webpacker.yml ফাইলে ডেটা ধারণ করে। এটি এন্ট্রি পয়েন্ট ডিরেক্টরিতে application.js ফাইল খুঁজে বের করে, আমাদের কেসে app/javascript/packs। আপনি নিচের কোড কল করে ভেরিফাই করতে পারেন:
Webpacker.manifest.config.source_entry_path
যখন এন্ট্রিগুলো মিলে যায়, Webpacker javascript_include_tag মেথড কল করে, যা ActionView লাইব্রেরির একটি হেল্পার যা রেইলসে ডিফল্টলি উপলব্ধ। মেথডটি এক বা একাধিক সোর্স এক্সেপ্ট করে এবং স্ক্রিপ্ট ট্যাগ রিটার্ন করে যেটা আপনি সরাসরি আপনার ভিউতে অ্যাপ্লাই করতে পারেন।
ডেভেলপমেন্ট সার্ভার (The Development Server)
Webpacker ডেভেলপমেন্ট সার্ভারের এন্ট্রি পয়েন্ট হলো bin ফোল্ডারে রাখা এক্সিকিউটেবল ফাইল যার নাম webpack-dev-server। সার্ভার চালানোর প্রসেস পাঁচ ধাপ ধারণ করে:
- এনভায়রনমেন্ট সেট করা — Node এবং রেইলসের জন্য এনভায়রনমেন্ট নাম সেট করা হয়। যখন এনভায়রনমেন্ট স্পেসিফাইড নয়, প্রোগ্রাম অনুমান করে সার্ভার ডেভেলপমেন্ট এনভায়রনমেন্টে এক্সিকিউট হবে।
- কনফিগারেশন লোড করা —
config/webpacker.ymlফাইল আগের ধাপে সেট করা এনভায়রনমেন্টের সেটিংসহ লোড হয়। - কমান্ড অপশন ভ্যালিডেট করা — প্রোগ্রাম চেক করে আমরা সার্ভার কমান্ডে উপযুক্ত অপশন পাস করেছি কিনা। উদাহরণস্বরূপ, এটি এরর থ্রো করবে যখন
--httpsঅপশন দেওয়া হলেও আমরাconfig/webpacker.yml-এ সেটা স্পেসিফাই করিনি। - পোর্টের উপলব্ধতা ভেরিফাই করা — প্রোগ্রাম চেক করে দেয়া পোর্টটি ব্যবহার করার জন্য উপলব্ধ কিনা। যদি অন্য কোনো প্রোগ্রাম ইতিমধ্যে সেটা ব্যবহার করছে, তবে এটি এরর থ্রো করবে যাতে আপনি জানতে পারেন
config/webpacker.yml-এ webpack সার্ভার কনফিগারেশন আপডেট করতে হবে। - webpack serve কমান্ড এক্সিকিউট করা — যখন node_modules ডিরেক্টরি এক্সিস্ট করে, প্রোগ্রাম ডিরেক্টরির ভিতরে কমান্ড এক্সিকিউট করে, অন্যথায়, yarn দিয়ে এক্সিকিউট করে। প্রোগ্রাম কনফিগারেশন অপশন পাস করে কমান্ডে যেটা
config/webpack/ডিরেক্টরির একটি ফাইলকে পয়েন্ট করে।
সার্ভার এখন চলছে, এবং এটি আপনার কোড অন-দ-ফ্লাই কম্পাইল করে, তাই আপনাকে সার্ভার রিস্টার্ট করতে হয় না পরিবর্তনগুলো দেখতে এবং চেক করতে webpack নতুন কোডসহ বান্ডেল তৈরি করতে পেরেছে কিনা।
ডেভেলপমেন্ট সার্ভারের কোড খুব সিম্পল। এটি শুধু YAML ফরম্যাটে কনফিগারেশন ফাইল থেকে কনফিগ লোড করে এবং প্রপার কনফিগ JavaScript ফরম্যাটে সরাসরি webpack serve কমান্ডে পাস করে। আপনি হাতেও রান করতে পারেন, কিন্তু বিল্ট-ইন কমান্ডের সাথে আপনাকে প্রপার কমান্ড আর্গুমেন্টস কনসিডার করতে হয় না।
প্রোডাকশন এনভায়রনমেন্টের জন্য ফাইল কম্পাইল করা (Compiling Files for the Production Environment)
মান लीজিয়ে আপনি webpacker ব্যবহার করা অ্যাপ্লিকেশন ডিপ্লয় করতে চান। সেক্ষেত্রে, আপনি সহজে assets:precompile টাস্ক ইনভোক করতে পারেন কারণ Webpacker অটোমেটিক্যালি webpacker:compile টাস্ককে সেটার সাথে হুক করে।
webpacker:compile টাস্ক হুডের নিচে কীভাবে কাজ করে? চলুন খনন করি এবং দেখি। এটি নিচের কাজগুলো করে:
- মেইন কলকে দুটি ব্লকে র্যাপ করে নিশ্চিত করার জন্য যে
NODEএনভায়রনমেন্ট সেট করা আছে এবং Webpacker লগ স্ট্যান্ডার্ড আউটে আউটপুট হচ্ছে। - Webpack কল করে এবং তার লগগুলো পার্স করে ডিটারমাইন করতে একশন সফল হয়েছে কিনা।
আপনি এখন public/packs/js ডিরেক্টরি ভিজিট করতে পারেন কম্পাইল করা ফাইলগুলো দেখতে। সেগুলো সার্ভারে ডিপ্লয় করা উচিত।
সারসংক্ষেপ (Summary)
আমরা শিখলাম Webpacker হুডের নিচে কীভাবে কাজ করে। আপনি এটাকে Webpack লাইব্রেরি এবং একটি রেইলস অ্যাপ্লিকেশনের মধ্যে একটি ব্রিজ হিসেবে বিবেচনা করতে পারেন যা আপনাকে Ruby-তে Webpack কনফিগার করতে দেয় এবং আপনার অ্যাপ্লিকেশনে জাভাস্ক্রিপ্ট কোড সহজে ব্যবহার করতে দেয়।
পুরো আর্টিকেল সারাংশ করতে, Webpacker-এর মূল এলিমেন্টগুলো একবার আবার स्मরণ করি:
- কনফিগারেশন — এটি
config/webpacker.ymlফাইলে থাকে এবং আপনাকে আপনার জাভাস্ক্রিপ্ট ফাইল এবং প্যাকগুলো যেখানে রাখেন সেটা Webpacker-কে পয়েন্ট করতে দেয় - প্যাক — এটি একটি একক এন্ট্রি পয়েন্ট যেখান থেকে Webpacker কম্পাইলেশন শুরু করে। সেই ফাইলে ইম্পোর্ট এবং ইনিশিয়ালাইজ করা প্রতিটি লাইব্রেরি অটোমেটিক্যালি কম্পাইল হবে।
- ডেভেলপমেন্ট সার্ভার — একটি সিম্পল স্ক্রিপ্ট যা আপনাকে অন-দ-ফ্লাই ফাইল কম্পাইল করতে দেয়, তাই আপনাকে জাভাস্ক্রিপ্ট ফাইল মডিফাই করার প্রতিবার সার্ভার রিস্টার্ট করতে হয় না
- কম্পাইল টাস্ক — একটি সিম্পল রেক টাস্ক যা Webpack ইনভোক করে এবং পাবলিক ডিরেক্টরির অধীনে ফাইল কম্পাইল করে যাতে আপনি সেগুলো প্রোডাকশন সার্ভারে ডিপ্লয় করতে পারেন এবং এন্ড-ইউজারদের জন্য উপলব্ধ করতে পারেন
- ভিউ হেল্পার — হেল্পার যা আপনাকে কম্পাইল করা ফাইলগুলো ভিউতে ইনক্লুড করতে দেয়
অনেক ডেভেলপারের জন্য যাদের অভিজ্ঞতা কম, Webpacker একটু ম্যাজিক্যাল লাগে, কিন্তু আসলে এটি একটি সিম্পল লাইব্রেরি যা আমাদের Webpack কে রুবি-স্টাইলে ব্যবহার করতে সাহায্য করে।
P.S. Ruby Magic পোস্টগুলো প্রেস থেকে বের होतेই পেতে চাইলে, আমাদের Ruby Magic নিউজলেটার সাবস্ক্রাইব করুন এবং কখনো একক পোস্ট মিস করবেন না!