2.4  কম্পাইলিং বনাম পলিফিলিং

 

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

const getProfile = username=>{
    return fetch(`https://api.github.com/users/${username}`)
    .then((response)=> response.json())
    .then(({data})=>({
        name: data.name,
        location: data.location,
        company: data.company,
        blog: data.blog.includes('https') ? data.blog : null
    }))
    .catch((e)=> console.warn(e))
}

 

কোডটি Babel দ্বারা কম্পাইল হবার পর এমন দেখাবে

var getProfile = function getProfile(username) {
    return fetch('https://api.github.com/users/' + username).then(function (response) {
        return response.json();
    }).then(function (_ref) {
        var data = _ref.data;
        return {
            name: data.name,
            location: data.location,
            company: data.company,
            blog: data.blog.includes('https') ? data.blog : null
        };
    }).catch(function (e) {
        return console.warn(e);
    });
};
 

আপনি লক্ষ্য করবেন যে বেশিরভাগ ES6 কোড যেমন অ্যারো ফাংশন এবং টেমপ্লেট স্ট্রিংগুলা পুরানো ES5 জাভাস্ক্রিপ্টে কম্পাইল করা হয়েছে। উপরের কোডে দুটি প্রপার্টি  রয়েছে যা কম্পাইল হয়নি একটি হল fetchএবং অন্যটি includesBabel-এর লক্ষ্য হল আমাদের পরবর্তী জেনারেশনের কোডগুলোকে নিয়ে সকল ব্রাউজার উপযোগী কোডে রুপান্তর করা। আপনি মনে করতে পারেন যে fetch এবং includes কে indexOf এবং XMLHttpRequest এর মতো নেটিভ কিছুতে কম্পাইল করা যেত কিন্তু বিষয়টি মোটেও এমন নয়। Babel কখনও কম্পাইল করার  সময় ব্রাউজারের গ্লোবাল অবজেক্টে বা জাভাস্ক্রিপ্ট প্রিমিটিভে নতুন ফাংশনালিটি যোগ করে না।

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

অ্যারো ফাংশন, কম্পাইলড না পলিফিলড হবে? Babel অ্যারো ফাংশনগুলিকে নিয়মিত ফাংশনে রূপান্তর করতে পারে, তাই সেগুলি কম্পাইল করা যেতে পারে। ক্লাস সম্পর্কে কি? কম্পাইলড  না  পলিফিলড? অ্যারো ফাংশনের মতো ক্লাসের প্রোটোটাইপগুলিকে রেগুলার ফাংশনে ট্রান্সফর্ম করা যেতে পারে, তাই সেগুলিও কম্পাইলড হবে । তাহলে  প্রমিস কি?এটি কম্পাইলড না পলিফিলড হবে? Babel কোনোভাবেই প্রমিসগুলিকে  এমনকোনো  নেটিভ সিনট্যাক্সে রূপান্তর করতে পারে না যা ব্রাউজারগুলি বুঝতে পারে। তারমানে এটি পলিফিলিং হবে। তাহলে ডিস্ট্রাকচারিং কি কম্পাইলড না পলিফিলড? Babel ডট নোটেশন ব্যবহার করে প্রতিটি ডিস্ট্রাকচার অবজেক্টকে রেগুলার ভেরিয়েবলে পরিণত করতে পারে। সুতরাং, ডিস্ট্রাকচারিং কম্পাইলড হবে। তাহলে includes কি কম্পাইল বা পলিফিল? এটি একটু কঠিন কারণ এটি আমাদের সাধারণ নিয়ম অনুসরণ করে না। কেউ যুক্তি দিতে পারে যে includes, indexOf ব্যবহার করে includesকে ট্রান্সফর্ম করতে পারে যা সমস্ত ব্রাউজার সমর্থন করবে। কিন্তু আসলে তা নয়। includes এখানে পলিফিলড হবে।

কখন কম্পাইলড হচ্ছে আর কখন পলিফিলড হচ্ছে তা মুখস্ত করার চেষ্টা করার পরিবর্তে আমি মনে করি দুটি ধারণার পিছনের সাধারণ নিয়মগুলি বোঝা গুরুত্বপূর্ণ। কোনো একটি  নির্দিষ্ট ফীচারের জন্য আমাদের পলিফিলিং করা উচিত কিনা তা জানতে হলে, Babel ওয়েবসাইট দেখুন।

উদাহরন
  • map এর ক্ষেত্রে পলিফিলিং

পলিফিলিং এর আগে

javascript
const arr = [1,2,3,4];
const newArr = arr.map(elem => {
    return elem * 2
});
console.log(newArr);

Output: [2, 4, 6, 8]

পলিফিলিং বাস্তবায়ন

Array.prototype.pMap = function(callback) {
  let res = [];
     for (let i = 0; i < this.length; i++) {
        res.push(callback(this[i], i, this));
    }
    return res;
  }
  • forEach এর ক্ষেত্রে পলিফিলিং

 পলিফিলিং এর আগে

 let arr1 = [1,2,3,4,5];
arr1.forEach(function(word) {
  console.log(word);
 });
output:
1
2
3
4
5

পলিফিলিং বাস্তবায়ন

Array.prototype.pForEach = function(callback) {
  for (let i = 0; i < this.length; i++) {
   callback(this[i], i, this);
 }
}
  • filter এর ক্ষেত্রে পলিফিলিং

পলিফিলিং এর আগে

 const arr2 = [1,2,3,4]
const result = arr2.filter(elem => elem < 3);
console.log(result);

output: [ 1, 2 ]

পলিফিলিং বাস্তবায়ন

Array.prototype.pFilter = function(callback) {
  let res = [];
   for (let i = 0; i < this.length; i++) {
    if(callback(this[i], i, this)) {
        res.push(this[i]);
    }
  }
  return res;
}
  • indexOf এর ক্ষেত্রে পলিফিলিং

পলিফিলিং এর আগে

let arr4 = [1,2,3,4,1];
let result4 = arr4.indexOf(1, 1);
console.log(result4)
output: 4

পলিফিলিং বাস্তবায়ন

Array.prototype.pIndexOf = function(search, start) {
  for (let i = (start || 0); i < this.length; i++) {
    if (this[i] === search) { return i; } }
  return -1;
}
  • Arrow Function কম্পাইলিং

পলিফিলিং এর আগে

const getProfile = username => {
  console.log(username)
}
getProfile('John')

output:John

কম্পাইলিং এর পরে

getProfile will remail getProfile not getprofile1

var getProfile1 = function getProfile(username) {
  console.log(username)
}

 

এসো নিজে করি
  • forEach এবং map মধ্যে পার্থক্য কি?
  • এদের মধ্যে কোনটি polyfilled এবং কেন?
    • Arrow functions
    • Async functions
    • Promise
    • Destructuring
    • Array#findIndex
    • Classes
    • Array.from
  • এদের মধ্যে কোনগুলো compiled করা হয়েছে এবং কেন?
    • constants
    • default parameters
    • map
    • function bind
    • indexOf
    • fill
    • some
    • every
    • reduce
    • spread
    • filter
  • compiling এবং polifilling এর মধ্যে প্রধান পার্থক্য
  • কোন কোন অংশ compile এবং polyfilled করা হয়েছে?
    const getProfile = username => {
      return fetch(`https://api.github.com/users/${username}`)
        .then((response) => response.json())
        .then(({ data }) => ({
          name: data.name,
          location: data.location,
          company: data.company,
          blog: data.blog.includes('https') ? data.blog : null
        }))
        .catch((e) => console.warn(e))
    }