ডিবাগ জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন লাইক এ প্রো

আসসালামুআলাইকুম, আশা করি সবাই ভালো আছেন। আজকে কোড উইদ জুনায়েদ থেকে ইন্টারেস্টিং একটা টপিকের উপর পোস্ট নিয়ে হাজির হলাম। আমরা জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন ডিবাগিং এর জন্য console.log এর অনেক ব্যবহার করে থাকি। কিন্তু আপনি জানেন কি এর চাইতেও আর সহজে, আর ইন্ট্যারেক্টিভ উপায়ে জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন ডিবাগিং করা সম্ভব? তাহলে চলুন দেরী না করে সেটাই দেখার চেষ্টা করি এই পোস্টে।

আমরা এখানে মূলত দেখার চেষ্টা করবো কিভাবে গুগল ক্রোমের ডেভেলপার টুলস, স্পেসিফিকভাবে বললে Sources ট্যাব ইউজ করে আমরা জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন ডিবাগ করতে পারি। আমরা শুরুতে একটা প্লেইন HTML, CSS এবং JavaScript প্রোজেক্ট দিয়ে দেখার চেষ্টা করবো, তারপর মডার্ন জাভাস্ক্রিপ্ট অ্যাপ্লিকেশনে মডার্ন বিউল্ড টুলস দিয়ে কিভাবে কোনো অ্যাপ্লিকেশন ডেভেলপমেন্ট এবং প্রোডাকশন উভয় এনভারোমেন্টেই ডিবাগ করা যায় সেটা দেখার চেষ্টা করবো। তাহলে চলুন শুরু করা যাক!

প্লেইন HTML, CSS এবং JavaScript প্রোজেক্ট

প্রথমেই আমরা ব্যাসিক একটা HTML, CSS এবং JavaScript প্রোজেক্টের ক্ষেত্রে কিভাবে ডিবাগিং করতে পারি সেটা দেখার চেষ্টা করবো। এখানে আমার একটা প্লেইন প্রোজেক্ট আছে যেটার index.html ফাইলটি এখন আমরা সরাসরি ব্রাউজারে ওপেন করবো। এই প্রোজেক্টে মূলত নিচের এই তিনটা খুবই ব্যাসিক ফাইল আছে। এই প্রোজেক্টে একটা কাউন্টার আছে যেটার ভ্যালু Increment অথবা Decremenet করা যায়ঃ

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Counter Project</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="counter-container">
        <h1>Counter</h1>
        <p id="counter">0</p>
        <button id="increment-btn">Increment</button>
        <button id="decrement-btn">Decrement</button>
    </div>
    <script src="script.js"></script>
</body>
</html>

script.js

let count = 0;

document.getElementById("increment-btn").addEventListener("click", () => {
  count++;
  updateCounter();
});

document.getElementById("decrement-btn").addEventListener("click", () => {
  count--;
  updateCounter();
});

// Function to update the counter display
function updateCounter() {
  const counterElement = document.getElementById("counter");

  counterElement.textContent = count;

  // Example: Console log for debugging
  console.log("Current count:", count);
}

styles.css

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
}

.counter-container {
    text-align: center;
    padding: 20px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

#counter {
    font-size: 2em;
    margin: 20px 0;
}

button {
    padding: 10px 20px;
    margin: 5px;
    font-size: 16px;
    cursor: pointer;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 5px;
    transition: background-color 0.3s;
}

button:hover {
    background-color: #0056b3;
}

এখন আমরা গুগল ক্রোমে F12 দিয়ে অথবা খালি জায়গায় রাইট ক্লিক করে Inspect অপশন সিলেক্ট করে ক্রোমের ডেভটুলস ওপেন করবোঃ

তারপর ডেভটুলস থেকে আমরা Sources ট্যাব এ নেভিগেট করবো

Sources ট্যাবের ভিতরে বাম পাশে Page ট্যাব সিলেক্ট করলেই দেখবেন fils:// এর ভিটরে আমাদের প্রোজেক্টের সোর্স ফাইলগুলো আমাদের script.js ফাইলটাসহ অ্যাজ ইট ইজ দেখাচ্ছেঃ

আমরা এখন জাভাস্ক্রিপ্ট ফাইলে ক্লিক করে এটা ওপেন করেই এখান থেকেই নানাভাবে ডিবাগ করতে পারবোঃ

  • ব্রেকপয়েন্ট অ্যাড করাঃ আমরা এখন এই স্ক্রিপ্ট ফাইলের ভিতরে থাকা লাইন নাম্বারগুলোতে ক্লিক করে ব্রেকপয়েন্ট অ্যাড করতে পারবো। ব্রেকপয়েন্টের কাজ হচ্ছে স্পেসেফিক লাইনে কোড পজ করে দেওয়া। আপনি জাস্ট কোথায় কোড পজ করতে চাচ্ছেন সেটার লাইন নাম্বারে একটা ক্লিক করবেন। চলুন এখন আমরা একটা ফাংশনের ভিতরে ব্রেকপয়েন্ট অ্যাড করিঃ
  • Step Over, Step Into এবং স্ক্রিপ্ট এক্সিকিউশন রিজুইম করাঃ আমরা ডেভটুলে ডান পাশে থাকা প্লে/পজ, Step Over, Step Into এবং Step Out বাটনগুলো ইউজ করি লাইন বাই লাইন বা ফাংশন বাই ফাংশন কোড ডিবাগ করতে পারবো। আমরা যেহেতু ফাংশনের ভিতরে ব্রেকপয়েন্ট সেট করেছি তাই এই ফাংশন রান হওয়ার সময়েই ব্রেকপয়েন্টের জায়গায় কোড পজ হয়ে যাবে। এখন আমরা Step Over বাটন ইউজ করে পরবর্তি লাইনে যেতে পারবো, Step Into বাটন ইউজ করে একটা ফাংশনের ভিতরে জাম্প করতে পারবো এবং Step Out বাটন ইউজ করে একটা ফাংশন থেকে বের হয়ে যেতে পারবো। এভাবে আমরা স্টেপ বাই স্টেপ খুব সহজেই যেকোনো অ্যাপ্লিকেশন ডিবাগ করতে পারবোঃ
  • Scope, কল স্ট্যাক ইত্যাদি ইত্যাদি এক্সপ্লোর করাঃ আপনারা চাইলে কিন্তু এখান থেকে Scope এবং কল স্ট্যাকও এক্সপ্লোর করতে পারবেন কোড রান হওয়ার সময়। যেমন এখানে দেখবেন আমাদের updateCounter এই ফাংশনের ভিতরে ব্রেকপয়েন্ট সেট করায় সেখানেই কোড পজ হয়ে গিয়েছে। আবার এই ফাংশনটাকে বর্তমানে কল স্ট্যাকেও দেখা যাচ্ছে। আবার একইসাথে এই লাইনে আমাদের স্কোপে কি কি আছে সেগুলোও এখানে দেখতে পাচ্ছেন।
  • লগপয়েন্ট অ্যাড করাঃ আমরা এখন চাইলে Sources ট্যাব থেকেই সরাসরি লগপয়েন্ট অ্যাড করতে পারবো, লগ পয়েন্ট মূলত কোডে console.log লেখার মতোই। জাস্ট আপনি যে লাইনে লগপয়েন্ট অ্যাড করতে চান সে লাইনের নাম্বারে রাইট ক্লিক করে Add logpoint… অপশনে ক্লিক করবেনঃ

তারপর আপনি এখানে চাইলে console.log এর মতো করেই জাভাস্ক্রিপ্ট কনকাটিনেশন ইউজ করে অথবা ব্যাকটিক ``` ইউজ করে ফরম্যাট করে বিভিন্ন জিনিস লগ করতে পারবেন। যেমন আমরা যদি এই লাইনে count এর ভ্যালু কতো সেটা দেখতে চাই তাহলে এখানে সরাসরি লিখে এন্টার চাপবোঃ

`the value of count is ${count}`

ব্যাস এবার যতোবারই আপনার কোডের এই লাইন হিট করবে ততবারই আপনি আপনার এই লগটা Console এ দেখতে পাবেনঃ

ব্যাস এখন থেকে আপনার অ্যাকচুয়াল কোডে console.log লিখে লিখে ডিবাগিং এর দিন শেষ, এখন থেকে আপনি সরাসরি এখান থেকেই যাবতীয় ডিবাগিং এর কাজ করে ফেলতে পারবেন!

মডার্ন জাভাস্ক্রিপ্ট অ্যাপ্লিকেশনগুলোতে ডিবাগিং

আমরা এখন মডার্ন জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন ডেভেলপমেন্ট এর জন্য নানানরকম টুলস, বিউল্ড টুলস ব্যবহার করে থাকি। এসব অ্যাপ্লিকেশনের ক্ষেত্রেও আমরা সেইম Sources ট্যাব ইউজ করে ডিবাগিং করতে পারবো। বাট এখানে কিছু ট্রিকি পার্ট আছে! এই যেমন রিঅ্যাক্ট অ্যাপ্লিকেশনের ক্ষেত্রে আমরা JSX দিয়ে কম্পোনেন্টে ভাগ করে করে অ্যাপ্লিকেশন ডেভেলপ করি, আবার সেইম অ্যাপ্লিকেশনই প্রোডাকশনে বান্ডেল করে শিপ করি। সেক্ষেত্রে আমাদের ডেভেলপমেন্ট এনভারোমেন্ট এমনভাবে সেটআপ করতে হবে যাতে ব্রাউজার সেখান থেকে আমাদের অ্যাপ্লিকেশনের প্রয়োজনীয় সোর্স ফাইলগুলোকে ঠিকঠাক শো করতে পারে। আর আমরা ঠিক সেই টেকনিকটাই এখানে দেখার চেষ্টা করবো।

ডেভেলপমেন্ট মোডে রিঅ্যাক্ট অ্যাপ্লিকেশন ডিবাগ করাঃ আমরা create-react-app দিয়ে তৈরি করা খুবই সিম্পল একটা কাউন্টার অ্যাপ্লিকেশন তৈরি করেছি। এখানে মূলত App.js ফাইলটার ভিতরে একটা Counter নামে কম্পোনেন্ট আছে, যেটা আমাদের কাউন্টার রিলেটেড সব ইউআই লজিক হোল্ড করেঃ

App.js:

import Counter from "./components/Counter";

import "./App.css";

function App() {
  return (
    <div className="App">
      <Counter />
    </div>
  );
}

export default App;

components/Counter.js:

import React, { useState } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div style={styles.container}>
      <h1>React Counter</h1>
      <p style={styles.counterValue}>{count}</p>
      <button style={styles.button} onClick={increment}>
        Increment
      </button>
      <button style={styles.button} onClick={decrement}>
        Decrement
      </button>
    </div>
  );
};

const styles = {
  ...
};

export default Counter;

এখন আমরা সেইম টেকনিক ইউজ করেই এই মডার্ন অ্যাপ্লিকেশনটাকেও ব্রাউজারের ডেভটুলস থেকে Sources ট্যাবে গিয়ে ডিবাগ করতে পারবো। আপনি যদি Sources ট্যাবে গিয়ে এক্সপ্লোর করেন তাহলে দেখবেন এখানে আপনার সোর্স ফাইল একেবারে কম্পোনেন্ট টু কম্পোনেন্ট সব দেখিয়ে দিচ্ছেঃ

এভাবে সোর্স সবাই দেখে ফেললে আবার সমস্যা! তাই আমাদের মডার্ন টুলসগুলো সোর্স ম্যাপ কন্ট্রোল করার জন্য নানান অপশন দিয়ে থাকে যে আপনি আপনার সোর্স কোড এভাবে ওপেন করে দিতে চান নাকি সেটা ক্লোজড বা মিনিফাইড করে রাখতে চান। এদিকে create-react-app আবার এভাবে সোর্স কোড যাতে সবসময় দেখা যায় সেটা এনাবল করে রাখে। আর এই জিনিসটা মূলত করা হয় সোর্স ম্যাপের মাধ্যমে। আপনারা যে ডেভেলপমেন্ট বা প্রোডাকশন এনভারোমেন্টের জন্য বান্ডেলার ইউজ করেন, যেমন ওয়েবপ্যাক, এগুলো দিয়েই মূলত সোর্স ম্যাপ কিভাবে রাখবেন বা জেনারেট করবেন সেটা কন্ট্রোল করা যায়। আর আমাদের create-react-app এর ক্ষেত্রে সেটা কনফিগার করার জন্যও আলাদা অপশন আছে। তবে এখন যেহেতু সেটা বাই ডিফল্ট এনাবল করাই থাকে, আমরা এখন সরাসরি অ্যাপ্লিকেশন ডিবাগিং করতে পারবো এখান থেকেই।

এখন আমরা এখানে সিমপ্লি Counter.js কম্পোনেন্ট ফাইলের incement ফাংশনে একটা লগপয়েন্ট অ্যাড করবোঃ

এবার যখনি আপনি কাউন্ট increment করতে যাবেন, এই লগটা কনসোলে দেখতে পাবেনঃ

এভাবে আপনি এখান থেকে আর বাকি যে যে টুলসগুলো আমরা আগে দেখালাম সেগুলোও সেইম ওয়েতে ইউজ করতে পাবেন। হয়ে গেলো না অনেক সহজ ব্যাপারটা এখন?

প্রোডাকশন মোডে রিঅ্যাক্ট অ্যাপ্লিকেশন ডিবাগ করাঃ আমরা যদি আমাদের সেইম রিঅ্যাক্ট প্রোজেক্টটাই npm run build বিউল্ড করে বিউল্ড ভার্শনটা দেখি (cd build && npx http-server .) তাহলে ঐখানেও আমাদের সোর্স কোডগুলো দেখতে পাবো, আর একই উপায়ে সেগুলো ডিবাগও করতে পারবো। বাট এখানে একটা ক্যাচ আছে, ক্যাচটা হল প্রোডাকশন মোডে create-react-app সোর্সম্যাপও এনাবল করে রাখে। আপনি যদি অন্যকোনো বয়েলারপ্লেট বা ডেভ এনভারোমেন্ট ইউজ করে থাকেন, তখন প্রোডাকশনে সোর্স ম্যাপ নাও থাকতে পারে। অথবা আর ক্লিয়ারলি বললে প্রোডাকশনে সোর্স ম্যাপ না রাখাই বেটার যেহেতু এভাবে আপনি আপনার ফ্রন্টএন্ড কোডবেইজের লজিক অনেকটাই ওপেন করে দিচ্ছেন সবার সামনে। তো সেক্ষেত্রে ঐরকম এনভারোমেন্ট হলে আপনাকে সোর্স কোড এভাবে দেখতে হলে আপনাকে বিউল্ডের ক্ষেত্রে আলাদা করে সোর্স ম্যাপ দেখানোর মতো করে কনফিগার করে নিতে হবে। আবার create-react-app এই আমরা সেইম উল্টা (সোর্স ম্যাপ না রাখা) কাজটা করতে পারবো .env ফাইলে নিচের এনভারোমেন্ট ভ্যারিয়েবল সেট করার মাধ্যমেঃ

GENERATE_SOURCEMAP=false

এবার আবার build ডিরেক্টরি ক্লিয়ার করে npm run build দিয়ে বিউল্ড ভার্শনটা দেখলে (cd build && npx http-server .) Sources ট্যাবে গিয়ে দেখবেন সেই আপনার সোর্স ফাইলগুলো আর আগেরমতো দেখাচ্ছে না, জাস্ট একটা মিনিফাইড স্ক্রিপ্ট দেখতে পাচ্ছেন যেটা থেকে কোড বুঝা খুবই টাফ এবং ডিবাগিং করাও টাফঃ

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

তবে এখানে বিশেষভাবে একটা বিষয় খেয়াল করবেন যে create-react-app দিয়ে তৈরি করা অ্যাপ্লিকেশনগুলোতে বাই ডিফল্ট সোর্স ম্যাপ এনাবল করা থাকে, অর্থাৎ আপনার ইউজাররা চাইলেই আপনার কোডবেইজ এক্সপ্লোর করতে পারবে। তো সেক্ষেত্রে create-react-app দিয়ে কোন অ্যাপ্লিকেশন তৈরি করে প্রোডাকশন এনভারোমেন্টে রাখার সময় সতর্ক থাকতে হবে, স্পেশালি দরকার না থাকলে GENERATE_SOURCEMAP=false করে রাখাই উত্তম!

ওয়েবপ্যাকে সোর্স ম্যাপ কনফিগার করাঃ তো আমরা যে সোর্স ম্যাপ নিয়ে এতক্ষণ কথা বললাম সেটা ওয়েবপ্যাকের কনফিগারেশন ফাইল থেকে খুব সহজেই এনাবল/ডিজাবল করে নিতে পারবেন। ওয়েবপ্যাকের অফিশিয়াল ডকে গেলে devtool রিলেটেড অসংখ্য কনফিগারেশন অপশন পাবেন যেগুলো ইউজ করে আমরা আমাদের প্রোজেক্টের জন্য সোর্স ম্যাপ রাখবো কি রাখবো না সেটা কনফিগার করতে পারবোঃ

// webpack.config.js
module.exports = {
    // Other configuration options...
    devtool: 'eval-source-map', // For development
};

একইভাবে আমরা বিউল্ড এনভারোমেন্টের উপর ডিপেন্ড করে প্রোডাকশনের জন্য সোর্স ম্যাপ যাতে জেনারেট না হয়, আর ডেভেলপমেন্ট এর সময় যাতে জেনারেট হয় সেটা ডিফাইন করে দিতে পারবো। সোর্স ম্যাপ জেনারেট না করতে চাইলে সেক্ষেত্রে devtool ম্যানশন না করলে অথবা ম্যানশন থাকলে সেটাকে false সেট করে দিলেই এনাফ হবে।

আশা করি আজকের এই কুইক জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন ডিবাগিং টেকনিক নিয়ে করা পোষ্টটি আপনাদের ভালো লেগেছে! কোন কিছু জিজ্ঞাসা করার থাকলে অবশ্যই অবশ্যই সেটা জানাতে ভুলবেন না। আর পরবর্তি এমন আরো বিভিন্ন বিষয়ের উপরে ভিডিও বা কন্টেন্ট দেখতে চাইলে আমাদের সাথেই থাকুন, কোড উইদ জুনায়েদ সাবস্ক্রাইব করে রাখুন। ধন্যবাদ!

শেয়ার করুন

লেখাটি ভাল লাগলে সোশ্যাল মিডিয়ায় শেয়ার করুন। আপনার কলিগ, বন্ধু কিংবা প্রিয় কারও কাজে লাগতে পারে। জানেন তো, শেয়ারিং ইজ কেয়ারিং!

সাবস্ক্রিপশন সেন্টার

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