এই পার্টে আমরা কী বানাবো?
Part 1-এ আমরা পুরো Connectify-এর ব্লুপ্রিন্ট বানিয়েছি — কী বানাবো, কেন বানাবো, ডেটা কেমন হবে, State কোথায় থাকবে। এবার সময় এসেছে সেই প্ল্যানটাকে একটা রানিং প্রজেক্টে রূপ দেওয়ার।
এই পার্টে আমরা চারটা কাজ করব:
- Vite দিয়ে React প্রজেক্ট বুটস্ট্র্যাপ করব
- Tailwind CSS v4 সেটআপ করব
- Part 1-এ ডিজাইন করা Feature-based ফোল্ডার স্ট্রাকচারটা বাস্তবে তৈরি করব
- Path Alias আর Environment Variables ঠিকভাবে কনফিগার করব
মনে রাখবেন — এই ধাপগুলো শুধু "সেটআপ" মনে হলেও, এখানে নেওয়া প্রতিটা সিদ্ধান্ত পরবর্তী প্রতিটা পার্টে প্রভাব ফেলবে। তাই প্রতিটা কমান্ড আর কনফিগারেশনের পেছনের কারণটাও বুঝে নেওয়া জরুরি — শুধু কপি-পেস্ট করে গেলে হবে না।
১. প্রি-রিকুইজিট — কম্পিউটার রেডি আছে তো?
শুরু করার আগে এই দুইটা জিনিস ইন্সটল থাকা লাগবে:
| টুল | ন্যূনতম ভার্সন | চেক করার কমান্ড |
|---|---|---|
| Node.js | 20.19+ অথবা 22.12+ | node -v |
| npm (Node-এর সাথেই আসে) | 10+ | npm -v |
কেন Node.js-এর ভার্সন নিয়ে এত সতর্কতা? — Vite-এর সাম্প্রতিক ভার্সনগুলো (Vite 6+) আধুনিক JavaScript ফিচার ব্যবহার করে, যেগুলো পুরনো Node.js ভার্সনে (যেমন 18-এর নিচে) কাজ করে না। ভার্সন মিলিয়ে না নিলে
npm create viteকমান্ড দেওয়ার সময়ই এরর দেখাবে। যদি Node.js ইন্সটল করা না থাকে বা ভার্সন পুরনো হয়, nodejs.org (opens in a new tab) থেকে LTS ভার্সন নামিয়ে নিন, অথবাnvm(Node Version Manager) ব্যবহার করুন — একাধিক প্রজেক্টে একাধিক Node ভার্সন সামলানোর জন্য এটা industry-standard পদ্ধতি।
কোড এডিটর হিসেবে VS Code ব্যবহার করছেন ধরে নিচ্ছি। যদি নতুন হন, এই তিনটা এক্সটেনশন ইন্সটল করে নিন — সামনে অনেক কাজে লাগবে:
- ES7+ React/Redux/React-Native snippets — দ্রুত কম্পোনেন্ট বয়লারপ্লেট লিখতে
- Tailwind CSS IntelliSense — Tailwind ক্লাস অটোকমপ্লিট ও প্রিভিউ
- ESLint — কোড লেখার সময়ই ভুল ধরিয়ে দেয়
২. Vite দিয়ে প্রজেক্ট বুটস্ট্র্যাপ
কেন Vite? (Create React App না কেন?)
কয়েক বছর আগে পর্যন্ত React প্রজেক্ট শুরু করার স্ট্যান্ডার্ড উপায় ছিল Create React App (CRA)। কিন্তু CRA এখন deprecated (মানে, আর মেইনটেইন হয় না) — React-এর নিজস্ব অফিসিয়াল ডকুমেন্টেশনও এখন আর CRA রেকমেন্ড করে না।
Vite জনপ্রিয় হওয়ার পেছনে টেকনিক্যাল কারণ আছে, যেটা বোঝাটা জরুরি:
- Development-এ: CRA প্রতিবার dev server চালু করার সময় পুরো অ্যাপটাকে bundle (একত্র) করে ফেলত, তারপর সার্ভ করত। প্রজেক্ট বড় হলে এটা ধীরে ধীরে অসহনীয় স্লো হয়ে যেত। Vite এর বদলে ব্রাউজারের নেটিভ ES Modules সুবিধা ব্যবহার করে — মানে dev server চালু হয় প্রায় সাথে সাথেই, কারণ পুরো bundle আগে থেকে তৈরি করতে হয় না। কোনো ফাইল বদলালে, শুধু সেই ফাইলটাই ব্রাউজারে আপডেট হয় (Hot Module Replacement / HMR) — পুরো পেজ রিলোড হয় না, তাই state হারায় না।
- Production build-এ: Vite ব্যবহার করে Rollup (বা তার Rust-based দ্রুত ভার্সন Rolldown), যা কোড অপ্টিমাইজ করে অনেক ছোট bundle তৈরি করে।
সংক্ষেপে — Vite মানে দ্রুত ডেভেলপমেন্ট এক্সপেরিয়েন্স, আর অপ্টিমাইজড প্রোডাকশন বিল্ড, দুটোই একসাথে।
প্রজেক্ট তৈরি করা
টার্মিনাল খুলে যেখানে প্রজেক্ট রাখতে চান, সেই ফোল্ডারে গিয়ে চালান:
npm create vite@latest connectify -- --template reactএখানে connectify হলো প্রজেক্টের নাম (ফোল্ডারের নাম হবে এটাই), আর --template react মানে বলে দিচ্ছি আমরা plain JavaScript (JSX) দিয়ে React ব্যবহার করব — TypeScript না।
TypeScript ব্যবহার করব না কেন? — এই কোর্সের লক্ষ্য React-এর architectural pattern গুলো (Context, Reducer, Custom Hooks, API integration) গভীরভাবে বোঝা। TypeScript শেখাটা একটা আলাদা, গুরুত্বপূর্ণ স্কিল — কিন্তু দুটো একসাথে শিখতে গেলে মূল কনসেপ্টগুলো থেকে মনোযোগ সরে যেতে পারে। এই প্যাটার্নগুলো একবার ভালোভাবে রপ্ত হয়ে গেলে,
--template react-tsদিয়ে পরে TypeScript-এ ট্রানজিশন করাটা তুলনামূলক সহজ।
কমান্ড চালানোর পর প্রজেক্ট ফোল্ডারে ঢুকে ডিপেন্ডেন্সি ইন্সটল করুন:
cd connectify
npm install
npm run devnpm run dev চালানোর পর টার্মিনালে একটা localhost URL (সাধারণত http://localhost:5173) দেখাবে। ব্রাউজারে খুললে ডিফল্ট Vite + React স্টার্টার পেজ দেখতে পাবেন। এখানেই বুঝবেন সেটআপ ঠিকমতো হয়েছে।
এই মুহূর্তে যা তৈরি হলো
connectify/
├── public/ # স্ট্যাটিক ফাইল (favicon ইত্যাদি), সরাসরি সার্ভ হয়, বিল্ড হয় না
├── src/
│ ├── assets/ # ছবি, ফন্ট — import করে ব্যবহার হয়
│ ├── App.jsx
│ ├── App.css
│ ├── main.jsx # অ্যাপের এন্ট্রি পয়েন্ট
│ └── index.css
├── index.html
├── package.json
└── vite.config.js # Vite-এর কনফিগারেশন ফাইলmain.jsx ফাইলটাই আসল শুরুর বিন্দু — এখানে ReactDOM.createRoot(...) দিয়ে React অ্যাপটাকে index.html-এর <div id="root">-এর ভেতরে "মাউন্ট" করা হয়। এই ফাইলটা আমরা একটু পরেই এডিট করব, যখন Provider গুলো wrap করব।
৩. Tailwind CSS v4 সেটআপ
স্টাইলিং-এর জন্য আমরা Tailwind CSS ব্যবহার করব — এটা একটা utility-first CSS ফ্রেমওয়ার্ক, মানে আলাদা .css ফাইলে ক্লাস লেখার বদলে, JSX-এর ভেতরেই ছোট ছোট পূর্ব-নির্ধারিত ক্লাস (flex, p-4, text-lg) বসিয়ে UI বানানো যায়।
ইন্সটলেশন
Tailwind CSS v4-এ ইন্সটলেশন প্রক্রিয়া আগের ভার্সনগুলোর চেয়ে সহজ — কারণ এখন এটার নিজস্ব first-party Vite প্লাগিন আছে:
npm install tailwindcss @tailwindcss/vitevite.config.js-এ প্লাগিন যোগ করা
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [react(), tailwindcss()],
});src/index.css-এ Tailwind import করা
@import "tailwindcss";ব্যস, এতটুকুই। এখানে একটা গুরুত্বপূর্ণ পরিবর্তনের কথা বলে রাখা দরকার — Tailwind CSS v4-এ আর tailwind.config.js ফাইলের দরকার নেই। v3-এ থিম কাস্টমাইজেশন (কালার, ফন্ট, স্পেসিং) একটা JavaScript কনফিগ ফাইলে লিখতে হতো। v4-এ এটা এখন CSS-first configuration — মানে থিম টোকেনগুলো সরাসরি CSS ফাইলে @theme ডিরেক্টিভ দিয়ে ডিফাইন করা হয়:
@import "tailwindcss";
@theme {
--color-brand: #6366f1;
--color-brand-dark: #4338ca;
--font-display: "Hind Siliguri", sans-serif;
}--color-brand ডিফাইন করার সাথে সাথেই Tailwind স্বয়ংক্রিয়ভাবে bg-brand, text-brand, border-brand — এই ক্লাসগুলো ব্যবহারযোগ্য করে দেয়। আলাদা করে extend: { colors: { brand: ... } } লেখার প্রয়োজন নেই।
main.jsx-এ index.css ইম্পোর্ট করা আছে কিনা নিশ্চিত করুন (Vite-এর ডিফল্ট টেমপ্লেটে এটা এমনিতেই থাকে):
import "./index.css";npm run dev আবার চালিয়ে দেখুন — Tailwind ক্লাস এখন কাজ করার কথা।
৪. Feature-Based Folder Structure বাস্তবায়ন
এবার Part 1-এ প্ল্যান করা ফোল্ডার স্ট্রাকচারটা তৈরি করে ফেলি। টার্মিনাল থেকে একসাথে সব ফোল্ডার বানিয়ে ফেলা যাক:
cd src
mkdir -p app
mkdir -p features/auth/context features/auth/hooks features/auth/components
mkdir -p features/posts/context features/posts/hooks features/posts/components
mkdir -p features/profile/context features/profile/hooks features/profile/components
mkdir -p components/ui
mkdir -p hooks
mkdir -p lib
mkdir -p utils
mkdir -p pages
cd ..এই কমান্ডগুলো চালানোর পর src/ ফোল্ডারটা দেখতে হবে এরকম:
src/
├── app/
├── features/
│ ├── auth/
│ │ ├── context/
│ │ ├── hooks/
│ │ └── components/
│ ├── posts/
│ │ ├── context/
│ │ ├── hooks/
│ │ └── components/
│ └── profile/
│ ├── context/
│ ├── hooks/
│ └── components/
├── components/
│ └── ui/
├── hooks/
├── lib/
├── utils/
├── pages/
├── assets/
├── App.jsx
├── main.jsx
└── index.cssপ্রতিটা ফোল্ডারের দায়িত্ব — একটা রেফারেন্স টেবিল
সামনের পার্টগুলোতে কোথায় কী ফাইল রাখব, সেটা নিয়ে যেন কনফিউশন না হয়, তাই এখানেই স্পষ্ট করে রাখি:
| ফোল্ডার | কী থাকবে | উদাহরণ |
|---|---|---|
app/ | অ্যাপ-লেভেল সেটআপ — সব Provider wrap করা, রাউট কনফিগারেশন | App.jsx, routes.jsx |
features/*/context/ | সেই ফিচারের Context, Provider, Reducer | AuthContext.jsx, authReducer.js |
features/*/hooks/ | সেই ফিচারের সাথে সম্পর্কিত কাস্টম হুক | useAuth.js |
features/*/components/ | সেই ফিচারের UI কম্পোনেন্ট, যেগুলো অন্য ফিচারে ব্যবহার হয় না | LoginForm.jsx, PostCard.jsx |
components/ui/ | সম্পূর্ণ জেনেরিক, ফিচার-নিরপেক্ষ UI বিল্ডিং ব্লক | Button.jsx, Avatar.jsx, Modal.jsx |
hooks/ | গ্লোবালি রিইউজেবল হুক, কোনো নির্দিষ্ট ফিচারের সাথে বাঁধা না | useDebounce.js, useLocalStorage.js |
lib/ | থার্ড-পার্টি লাইব্রেরির কনফিগারেশন/ইনস্ট্যান্স | axios.js |
utils/ | Pure ফাংশন — কোনো React hook বা state ছাড়া, শুধু ইনপুট নিয়ে আউটপুট দেয় | timeAgo.js, formatNumber.js |
pages/ | রাউটের সাথে সরাসরি ম্যাপ হওয়া টপ-লেভেল কম্পোনেন্ট | HomePage.jsx, LoginPage.jsx |
components/ui/আরfeatures/*/components/-এর মধ্যে পার্থক্য কী? — এই প্রশ্নটা নতুন ডেভেলপারদের প্রায়ই কনফিউজ করে। সহজ নিয়ম: "এই কম্পোনেন্টটা কি Connectify সম্পর্কে কিছু জানে?"Button.jsxকখনো জানে না এটা কোন অ্যাপে ব্যবহার হচ্ছে — এটা শুধু একটা বাটন, যেকোনো প্রজেক্টে কপি করে বসিয়ে দেওয়া যায়। কিন্তুPostCard.jsxজানে "Post" জিনিসটা কী,post.likedByপ্রপার্টি আছে — এটা Connectify-নির্দিষ্ট, তাইfeatures/posts/components/-এ থাকবে।
৫. Path Alias — ../../../ লেখার যন্ত্রণা থেকে মুক্তি
ফোল্ডার স্ট্রাকচার যত গভীর হয়, ইম্পোর্ট পাথও তত কুৎসিত হয়ে যায়:
// এভাবে লিখতে হবে যদি Path Alias না থাকে 😫
import Button from "../../../../components/ui/Button";
import { useAuth } from "../../../auth/hooks/useAuth";এই সমস্যার সমাধান Path Alias — একটা শর্টকাট সিম্বল (সাধারণত @) ডিফাইন করে দেওয়া, যেটা src/ ফোল্ডারকে পয়েন্ট করে। তাহলে উপরের ইম্পোর্টগুলো হয়ে যায়:
// Path Alias দিয়ে ✅
import Button from "@/components/ui/Button";
import { useAuth } from "@/features/auth/hooks/useAuth";এটা শুধু দেখতে পরিষ্কার তাই না — ফাইল অন্য ফোল্ডারে সরালেও (../../../ গুনে গুনে ঠিক করার বদলে) @/-দিয়ে শুরু হওয়া ইম্পোর্ট পাথ অপরিবর্তিত থাকে, রিফ্যাক্টরিং অনেক সহজ হয়ে যায়।
vite.config.js-এ Alias কনফিগার করা
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import path from "path";
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});এখানে path.resolve(__dirname, "./src") মানে — অপারেটিং সিস্টেম নির্বিশেষে (Windows/Mac/Linux) সঠিকভাবে src ফোল্ডারের সম্পূর্ণ পাথ বের করা। path মডিউলটা Node.js-এর সাথেই বিল্ট-ইন আসে, আলাদা করে ইন্সটল করার দরকার নেই।
VS Code-এ IntelliSense কাজ করানোর জন্য — jsconfig.json
শুধু vite.config.js-এ alias কনফিগার করলে অ্যাপটা রান তো করবে, কিন্তু VS Code বুঝবে না @/ আসলে কোথায় পয়েন্ট করছে — ফলে অটোকমপ্লিট আর "Go to Definition" কাজ করবে না। এটা ঠিক করতে প্রজেক্টের রুটে jsconfig.json ফাইল বানান:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"]
}এখন VS Code জানবে @/features/auth/hooks/useAuth-এর মানে আসলে src/features/auth/hooks/useAuth। এডিটর রিস্টার্ট করলে এটা কার্যকর হবে।
৬. Environment Variables — API URL হার্ডকোড করবেন না কখনো
Connectify যখন Backend API-এর সাথে কথা বলবে (Part 3 থেকে শুরু), তখন একটা Base URL লাগবে, যেমন http://localhost:3000। এই URL-টা কোডের ভেতরে সরাসরি লিখে ফেলা (hardcoding) একটা কমন ভুল, যেটা এড়ানো উচিত।
কেন হার্ডকোড করা উচিত না?
চিন্তা করুন — Development-এ আপনার API চলছে localhost:3000-এ, কিন্তু Production-এ (যখন অ্যাপটা আসল সার্ভারে ডিপ্লয় হবে) API চলবে হয়তো https://api.connectify.com-এ। যদি URL-টা কোডের ভেতরে হার্ডকোড করা থাকে, তাহলে প্রতিবার ডিপ্লয় করার আগে ম্যানুয়ালি কোড বদলাতে হবে — যেটা ভুল হওয়ার ঝুঁকি বাড়ায়, আর টিমে কাজ করলে প্রতিটা ডেভেলপারের নিজস্ব লোকাল সেটআপও ভিন্ন হতে পারে।
Environment Variable এই সমস্যার সমাধান — কনফিগারেশন ভ্যালুগুলোকে কোড থেকে আলাদা করে একটা .env ফাইলে রাখা, যেটা পরিবেশ (environment) ভেদে বদলাতে পারে।
.env ফাইল তৈরি করা
প্রজেক্টের রুটে (যেখানে package.json আছে, ঠিক সেখানে) একটা .env ফাইল বানান:
VITE_API_BASE_URL=http://localhost:3000/apiনামের শুরুতে
VITE_কেন বাধ্যতামূলক? — নিরাপত্তার কারণে। Vite ইচ্ছাকৃতভাবে শুধুVITE_প্রিফিক্স দেওয়া ভ্যারিয়েবলগুলোই ব্রাউজারে (client-side কোডে) এক্সপোজ করে। এর পেছনের যুক্তিটা গুরুত্বপূর্ণ —.envফাইলে যদি কোনো সিক্রেট কী (যেমন ডেটাবেজ পাসওয়ার্ড) থেকে যায়, সেটা যেন ভুলবশত ব্রাউজারে (মানে যে কেউ Dev Tools খুলে দেখতে পাবে) পাঠিয়ে না দেওয়া হয়।VITE_প্রিফিক্স না থাকা ভ্যারিয়েবলগুলো ফ্রন্টএন্ড কোডেundefinedদেখাবে — এটা একটা ইচ্ছাকৃত সুরক্ষা।
কোডে ব্যবহার করা
Vite প্রজেক্টে environment variable অ্যাক্সেস করা হয় import.meta.env দিয়ে — Node.js-এর পরিচিত process.env এখানে কাজ করে না, কারণ Vite ব্রাউজার-নেটিভ ES Modules ব্যবহার করে, আর process জিনিসটা ব্রাউজারে থাকে না।
const baseURL = import.meta.env.VITE_API_BASE_URL;
console.log(baseURL); // http://localhost:3000/api.gitignore-এ .env যোগ করা — এটা স্কিপ করবেন না
.env ফাইলটা কখনো Git-এ commit করা উচিত না — কারণ ভবিষ্যতে এখানে সিক্রেট কী, টোকেন ইত্যাদি থাকতে পারে, যেগুলো পাবলিক GitHub রিপোজিটরিতে চলে গেলে বড় সিকিউরিটি সমস্যা তৈরি করে। Vite-এর ডিফল্ট .gitignore-এ এটা এমনিতেই থাকে, কিন্তু একবার চেক করে নিন:
# .gitignore
.env
.env.localতাহলে টিমমেট বা ভবিষ্যতের নিজের জন্য কীভাবে জানাবেন কী কী Environment Variable লাগবে? এর সমাধান — একটা .env.example ফাইল বানানো, যেটা Git-এ commit করা যাবে (কারণ এতে আসল ভ্যালু নেই, শুধু কী কী ভ্যারিয়েবল লাগবে তার তালিকা):
# .env.example
VITE_API_BASE_URL=নতুন কেউ প্রজেক্ট ক্লোন করলে, এই ফাইলটা কপি করে .env বানিয়ে নিজের ভ্যালু বসিয়ে নেবে — এটা একটা স্ট্যান্ডার্ড ওপেন-সোর্স প্র্যাকটিস।
এখন যেহেতু আমাদের Backend সার্ভার এখনো তৈরি হয়নি (সেটা Part 3-এ বানাবো),
VITE_API_BASE_URL-টা এখনই ব্যবহার না করলেও চলবে। এখানে শুধু প্যাটার্নটা সেটআপ করে রাখলাম, যাতে Part 3-এ সরাসরি ব্যবহার শুরু করতে পারি।
৭. এক নজরে — এই পার্ট শেষে প্রজেক্ট কেমন দেখতে
connectify/
├── .env # (gitignored)
├── .env.example
├── .gitignore
├── jsconfig.json # Path Alias-এর জন্য IDE সাপোর্ট
├── index.html
├── package.json
├── vite.config.js # Tailwind প্লাগিন + Path Alias কনফিগার করা
├── public/
└── src/
├── app/
├── features/
│ ├── auth/{context,hooks,components}/
│ ├── posts/{context,hooks,components}/
│ └── profile/{context,hooks,components}/
├── components/ui/
├── hooks/
├── lib/
├── utils/
├── pages/
├── assets/
├── App.jsx
├── main.jsx
└── index.css # @import "tailwindcss";একবার যাচাই করে নিন সবকিছু ঠিক আছে কিনা:
npm run devব্রাউজারে অ্যাপ লোড হচ্ছে, কোনো এরর নেই, Tailwind ক্লাস কাজ করছে — তাহলে Part 2 সফলভাবে শেষ।
এই পার্টের সারাংশ
আমরা এই পার্টে যা করলাম, প্রতিটাই একটা নির্দিষ্ট ভবিষ্যৎ সমস্যা প্রতিরোধ করার জন্য:
| কাজ | কী সমস্যা প্রতিরোধ করলাম |
|---|---|
| Vite দিয়ে বুটস্ট্র্যাপ | ধীরগতির dev server, দুর্বল build performance |
| Tailwind v4 CSS-first config | আলাদা JS কনফিগ ফাইল মেইনটেইনের ঝামেলা |
| Feature-based ফোল্ডার | প্রজেক্ট বড় হলে ফাইল খুঁজে না পাওয়ার সমস্যা |
Path Alias (@/) | ../../../ টাইপ ভঙ্গুর, দুর্বোধ্য ইম্পোর্ট পাথ |
| Environment Variables | Production/Development URL হার্ডকোড করার ভুল, সিক্রেট leak হওয়ার ঝুঁকি |
পরের পার্টে (Part 3) আমরা একটা Mock Backend বানাবো json-server দিয়ে — যাতে Part 1-এ ডিজাইন করা API Contract অনুযায়ী রিয়েল রিকোয়েস্ট-রেসপন্স নিয়ে কাজ করতে পারি, আসল Backend ছাড়াই। সাথে lib/axios.js-এ একটা কেন্দ্রীয় Axios instance বানাবো, যেটা Part 7 পর্যন্ত পুরো কোর্স জুড়ে ব্যবহার হবে।