ফায়ারবেসের সাথে মডিউল বান্ডলার ব্যবহার করা

জাভাস্ক্রিপ্ট মডিউল বান্ডলার অনেক কিছুই করতে পারে, কিন্তু এর সবচেয়ে দরকারী বৈশিষ্ট্যগুলোর মধ্যে একটি হলো আপনার কোডবেসে এক্সটার্নাল লাইব্রেরি যুক্ত করা এবং ব্যবহার করার ক্ষমতা। মডিউল বান্ডলার আপনার কোডের ইম্পোর্ট পাথগুলো পড়ে এবং আপনার অ্যাপ্লিকেশন-নির্দিষ্ট কোডকে ইম্পোর্ট করা লাইব্রেরির কোডের সাথে একত্রিত (বান্ডল) করে।

ভার্সন ৯ এবং তার পরবর্তী সংস্করণগুলো থেকে, ফায়ারবেস জাভাস্ক্রিপ্ট মডিউলার এপিআই-কে মডিউল বান্ডলারের অপটিমাইজেশন ফিচারগুলোর সাথে কাজ করার জন্য অপ্টিমাইজ করা হয়েছে, যাতে আপনার চূড়ান্ত বিল্ডে অন্তর্ভুক্ত ফায়ারবেস কোডের পরিমাণ কমানো যায়।

import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, getRedirectResult } from 'firebase/auth';

const firebaseApp = initializeApp({ /* config */ });
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => { /* check status */ });

/**
 * getRedirectResult is unused and should not be included in the code base.
 * In addition, there are many other functions within firebase/auth that are
 * not imported and therefore should not be included as well.
 */

একটি লাইব্রেরি থেকে অব্যবহৃত কোড বাদ দেওয়ার এই প্রক্রিয়াটি ট্রি শেকিং নামে পরিচিত। হাতে করে এই কোড অপসারণ করা অত্যন্ত সময়সাপেক্ষ এবং ত্রুটিপূর্ণ হবে, কিন্তু মডিউল বান্ডলার এই অপসারণ প্রক্রিয়াটিকে স্বয়ংক্রিয় করতে পারে।

জাভাস্ক্রিপ্ট ইকোসিস্টেমে অনেক উন্নত মানের মডিউল বান্ডলার রয়েছে। এই নির্দেশিকাটি মূলত ফায়ারবেস-এর সাথে ওয়েবপ্যাক , রোলআপ এবং ইএসবিল্ড ব্যবহারের উপর আলোকপাত করে।

শুরু করুন

এই নির্দেশিকাটি অনুসরণ করার জন্য আপনার ডেভেলপমেন্ট এনভায়রনমেন্টে npm ইনস্টল করা থাকা আবশ্যক। npm ডিপেন্ডেন্সি (লাইব্রেরি) ইনস্টল এবং পরিচালনা করতে ব্যবহৃত হয়। npm ইনস্টল করতে, Node.js ইনস্টল করুন , যার মধ্যে npm স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত থাকে।

বেশিরভাগ ডেভেলপারই Node.js ইনস্টল করার পরেই সঠিকভাবে প্রস্তুত হয়ে যান। তবে, এনভায়রনমেন্ট সেট আপ করার সময় অনেক ডেভেলপারই কিছু সাধারণ সমস্যার সম্মুখীন হন। যদি আপনি কোনো ত্রুটির সম্মুখীন হন, তাহলে নিশ্চিত করুন যে আপনার এনভায়রনমেন্টে npm CLI আছে এবং আপনার যথাযথ পারমিশন সেট আপ করা আছে, যাতে আপনাকে sudo কমান্ড ব্যবহার করে অ্যাডমিনিস্ট্রেটর হিসেবে প্যাকেজ ইনস্টল করতে না হয়

package.json এবং Firebase ইনস্টল করা

একবার আপনার npm ইনস্টল হয়ে গেলে, আপনাকে আপনার লোকাল প্রজেক্টের রুটে একটি package.json ফাইল তৈরি করতে হবে। নিম্নলিখিত npm কমান্ডটি ব্যবহার করে এই ফাইলটি তৈরি করুন:

npm init

এটি আপনাকে একটি উইজার্ডের মাধ্যমে প্রয়োজনীয় তথ্য সরবরাহ করতে পরিচালিত করবে। ফাইলটি তৈরি হয়ে গেলে এটি দেখতে নিচের ছবির মতো হবে:

{
  "name": "your-package-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {

  }
}

এই ফাইলটি বিভিন্ন কাজের জন্য দায়ী। আপনি যদি মডিউল বান্ডলিং এবং সাধারণভাবে জাভাস্ক্রিপ্ট কোড তৈরি করা সম্পর্কে আরও জানতে চান, তবে এই ফাইলটির সাথে পরিচিত হওয়া গুরুত্বপূর্ণ। এই গাইডের জন্য গুরুত্বপূর্ণ অংশটি হলো "dependencies" অবজেক্ট। এই অবজেক্টটিতে আপনার ইনস্টল করা লাইব্রেরি এবং তার ব্যবহৃত সংস্করণের একটি কী-ভ্যালু পেয়ার থাকবে।

npm install অথবা npm i কমান্ডের মাধ্যমে ডিপেন্ডেন্সি যোগ করা হয়।

npm i firebase

যখন আপনি npm i firebase চালান, তখন ইনস্টলেশন প্রক্রিয়াটি package.json আপডেট করে Firebase-কে একটি ডিপেন্ডেন্সি হিসেবে তালিকাভুক্ত করবে:

  "dependencies": {
    "firebase": "^9.0.0"
  },

কী (key) হলো লাইব্রেরির নাম এবং ভ্যালু (value) হলো ব্যবহারযোগ্য ভার্সন। ভার্সন ভ্যালুটি নমনীয় এবং এটি বিভিন্ন মান গ্রহণ করতে পারে। এটি সিমান্টিক ভার্সনিং বা সেমভার (semver) নামে পরিচিত। সেমভার সম্পর্কে আরও জানতে, এনপিএম-এর (npm) সিমান্টিক ভার্সনিং বিষয়ক গাইডটি দেখুন

সোর্স বনাম বিল্ড ফোল্ডার

আপনার লেখা কোড একটি মডিউল বান্ডলার দ্বারা পঠিত ও প্রক্রিয়াজাত হয় এবং তারপর একটি নতুন ফাইল বা একাধিক ফাইল হিসেবে আউটপুট করা হয়। এই দুই ধরনের ফাইলকে আলাদা করা গুরুত্বপূর্ণ। মডিউল বান্ডলার যে কোড পড়ে ও প্রক্রিয়াজাত করে, তা "সোর্স" কোড নামে পরিচিত। তারা যে ফাইলগুলো আউটপুট করে, সেগুলো বিল্ট বা "ডিস্ট" (ডিস্ট্রিবিউশন) কোড নামে পরিচিত।

কোডবেসগুলিতে একটি প্রচলিত ব্যবস্থা হলো, সোর্স কোডকে src নামের একটি ফোল্ডারে এবং বিল্ড করা কোডকে dist নামের একটি ফোল্ডারে সংরক্ষণ করা।

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js

উপরের উদাহরণ ফাইল কাঠামোতে, ধরে নিন যে index.js animations.js এবং datalist.js উভয়কেই ইম্পোর্ট করে। যখন কোনো মডিউল বান্ডলার সোর্স কোডটি প্রসেস করে, তখন এটি dist ফোল্ডারে bundle.js ফাইলটি তৈরি করে। এই bundle.js হলো src ফোল্ডারের ফাইলগুলোর এবং সেইসাথে ইম্পোর্ট করা লাইব্রেরিগুলোর একটি সমন্বয়।

আপনি যদি গিট-এর মতো সোর্স কন্ট্রোল সিস্টেম ব্যবহার করেন, তাহলে মূল রিপোজিটরিতে এই কোডটি সংরক্ষণ করার সময় dist ফোল্ডারটিকে উপেক্ষা করা একটি প্রচলিত রীতি।

প্রবেশ পথ

মডিউল বান্ডলারগুলোতে এন্ট্রি পয়েন্টের একটি ধারণা থাকে। আপনি আপনার অ্যাপ্লিকেশনটিকে ফাইলের একটি গাছ হিসেবে ভাবতে পারেন। একটি ফাইল অন্য ফাইল থেকে কোড ইম্পোর্ট করে এবং এভাবেই চলতে থাকে। এর মানে হলো, একটি ফাইল হবে এই গাছের মূল। এই ফাইলটিই এন্ট্রি পয়েন্ট নামে পরিচিত।

চলুন আগের ফাইল কাঠামোর উদাহরণটি আবার দেখি।

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js
// src/index.js
import { animate } from './animations';
import { createList } from './datalist';

// This is not real code, but for example purposes only
const theList = createList('users/123/tasks');
theList.addEventListener('loaded', event => {
  animate(theList);
});

src/index.js ফাইলটিকে এন্ট্রি পয়েন্ট হিসেবে বিবেচনা করা হয়, কারণ এখান থেকেই অ্যাপ্লিকেশনের জন্য প্রয়োজনীয় সমস্ত কোডের ইম্পোর্ট শুরু হয়। মডিউল বান্ডলাররা বান্ডলিং প্রক্রিয়া শুরু করার জন্য এই এন্ট্রি পয়েন্ট ফাইলটি ব্যবহার করে।

ওয়েবপ্যাকের সাথে ফায়ারবেস ব্যবহার করা

ফায়ারবেস অ্যাপ এবং ওয়েবপ্যাকের জন্য কোনো নির্দিষ্ট কনফিগারেশনের প্রয়োজন নেই। এই অংশে একটি সাধারণ ওয়েবপ্যাক কনফিগারেশন আলোচনা করা হয়েছে

প্রথম ধাপ হলো npm থেকে webpack-কে একটি ডেভেলপমেন্ট ডিপেন্ডেন্সি হিসেবে ইনস্টল করা।

npm i webpack webpack-cli -D

আপনার লোকাল প্রজেক্টের রুটে webpack.config.js নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত কোডটি যোগ করুন।

const path = require('path');

module.exports = {
  // The entry point file described above
  entry: './src/index.js',
  // The location of the build folder described above
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  devtool: 'eval-source-map',
};

এরপর নিশ্চিত করুন যে আপনার Firebase একটি ডিপেন্ডেন্সি হিসেবে ইনস্টল করা আছে।

npm i firebase

এরপর আপনার কোডবেসে Firebase চালু করুন। নিচের কোডটি একটি এন্ট্রি পয়েন্ট ফাইলে Firebase ইম্পোর্ট ও ইনিশিয়ালাইজ করে এবং Firestore Lite ব্যবহার করে একটি 'city' ডকুমেন্ট লোড করে।

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

পরবর্তী ধাপ হলো ওয়েবপ্যাক বিল্ড চালানোর জন্য একটি এনপিএম স্ক্রিপ্ট যোগ করাpackage.json ফাইলটি খুলুন এবং "scripts" অবজেক্টে নিম্নলিখিত কী-ভ্যালু পেয়ারটি যোগ করুন।

  "scripts": {
    "build": "webpack --mode=development"
  },

webpack চালু করতে এবং বিল্ড ফোল্ডার তৈরি করতে নিম্নলিখিত কমান্ডটি চালান।

npm run build

অবশেষে, dist বিল্ড ফোল্ডারটি পরীক্ষা করুন। এতে bundle.js নামের একটি ফাইল থাকার কথা, যেটিতে আপনার বান্ডেল করা অ্যাপ্লিকেশন এবং ডিপেন্ডেন্সি কোড রয়েছে।

প্রোডাকশনের জন্য আপনার ওয়েবপ্যাক বিল্ড অপ্টিমাইজ করার বিষয়ে আরও তথ্যের জন্য, তাদের 'মোড' কনফিগারেশন সেটিং সম্পর্কিত অফিসিয়াল ডকুমেন্টেশন দেখুন।

রোলআপের সাথে ফায়ারবেস ব্যবহার করা

ফায়ারবেস অ্যাপস এবং রোলআপের জন্য কোনো নির্দিষ্ট কনফিগারেশনের প্রয়োজন নেই। এই অংশে রোলআপের একটি সাধারণ কনফিগারেশন আলোচনা করা হয়েছে।

প্রথম ধাপ হলো রোলআপ (Rollup) এবং এনপিএম (npm) দিয়ে ইনস্টল করা ডিপেন্ডেন্সিগুলোর সাথে ইম্পোর্ট ম্যাপ করার জন্য ব্যবহৃত একটি প্লাগইন ইনস্টল করা।

npm i rollup @rollup/plugin-node-resolve -D

আপনার লোকাল প্রজেক্টের রুটে rollup.config.js নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত কোডটি যোগ করুন।

import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
  // the entry point file described above
  input: 'src/index.js',
  // the output for the build folder described above
  output: {
    file: 'dist/bundle.js',
    // Optional and for development only. This provides the ability to
    // map the built code back to the original source format when debugging.
    sourcemap: 'inline',
    // Configure Rollup to convert your module code to a scoped function
    // that "immediate invokes". See the Rollup documentation for more
    // information: https://rollupjs.org/guide/en/#outputformat
    format: 'iife'
  },
  // Add the plugin to map import paths to dependencies
  // installed with npm
  plugins: [nodeResolve()]
};

এরপর আপনার কোডবেসে Firebase চালু করুন। নিচের কোডটি একটি এন্ট্রি পয়েন্ট ফাইলে Firebase ইম্পোর্ট ও ইনিশিয়ালাইজ করে এবং Firestore Lite ব্যবহার করে একটি 'city' ডকুমেন্ট লোড করে।

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

পরবর্তী ধাপ হলো রোলআপ বিল্ডটি চালানোর জন্য একটি এনপিএম স্ক্রিপ্ট যোগ করাpackage.json ফাইলটি খুলুন এবং "scripts" অবজেক্টে নিম্নলিখিত কী-ভ্যালু পেয়ারটি যোগ করুন।

  "scripts": {
    "build": "rollup -c rollup.config.js"
  },

রোলআপ চালাতে এবং বিল্ড ফোল্ডার তৈরি করতে, নিম্নলিখিত কমান্ডটি চালান।

npm run build

অবশেষে, dist বিল্ড ফোল্ডারটি পরীক্ষা করুন। এতে bundle.js নামের একটি ফাইল থাকার কথা, যেটিতে আপনার বান্ডেল করা অ্যাপ্লিকেশন এবং ডিপেন্ডেন্সি কোড রয়েছে।

প্রোডাকশনের জন্য আপনার রোলআপ বিল্ড অপ্টিমাইজ করার বিষয়ে আরও তথ্যের জন্য, প্রোডাকশন বিল্ডের প্লাগইন সম্পর্কিত তাদের অফিসিয়াল ডকুমেন্টেশন দেখুন।

esbuild-এর সাথে Firebase ব্যবহার করা

Firebase অ্যাপ এবং esbuild-এর জন্য কোনো নির্দিষ্ট কনফিগারেশনের প্রয়োজন নেই। এই অংশে esbuild-এর একটি সাধারণ কনফিগারেশন আলোচনা করা হয়েছে।

প্রথম ধাপ হলো esbuild-কে একটি ডেভেলপমেন্ট ডিপেন্ডেন্সি হিসেবে ইনস্টল করা।

npm i esbuild -D

আপনার লোকাল প্রজেক্টের রুটে esbuild.config.js নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত কোডটি যোগ করুন।

require('esbuild').build({
  // the entry point file described above
  entryPoints: ['src/index.js'],
  // the build folder location described above
  outfile: 'dist/bundle.js',
  bundle: true,
  // Replace with the browser versions you need to target
  target: ['chrome60', 'firefox60', 'safari11', 'edge20'],
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  sourcemap: 'inline',
}).catch(() => process.exit(1))

এরপর আপনার কোডবেসে Firebase চালু করুন। নিচের কোডটি একটি এন্ট্রি পয়েন্ট ফাইলে Firebase ইম্পোর্ট ও ইনিশিয়ালাইজ করে এবং Firestore Lite ব্যবহার করে একটি 'city' ডকুমেন্ট লোড করে।

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

পরবর্তী ধাপ হলো esbuild চালানোর জন্য একটি npm স্ক্রিপ্ট যোগ করাpackage.json ফাইলটি খুলুন এবং "scripts" অবজেক্টে নিম্নলিখিত কী-ভ্যালু পেয়ারটি যোগ করুন।

  "scripts": {
    "build": "node ./esbuild.config.js"
  },

অবশেষে, dist বিল্ড ফোল্ডারটি পরীক্ষা করুন। এতে bundle.js নামের একটি ফাইল থাকার কথা, যেটিতে আপনার বান্ডেল করা অ্যাপ্লিকেশন এবং ডিপেন্ডেন্সি কোড রয়েছে।

প্রোডাকশনের জন্য esbuild অপ্টিমাইজ করার বিষয়ে আরও তথ্যের জন্য, মিনিফিকেশন এবং অন্যান্য অপ্টিমাইজেশন সম্পর্কিত তাদের অফিসিয়াল ডকুমেন্টেশন দেখুন।