আরও দ্রুত পৃষ্ঠা লোড করার জন্য আধুনিক ব্রাউজারে আধুনিক কোড ব্যবহার করুন

এই কোডল্যাবে, এই সাধারণ অ্যাপ্লিকেশনের পারফর্ম্যান্স উন্নত করুন যা ব্যবহারকারীদের র‍্যান্ডম বিড়ালকে রেটিং দিতে দেয়। কতটা কোড ট্রান্সপাইল করা হয়েছে তা কমিয়ে কীভাবে জাভাস্ক্রিপ্ট বান্ডেল অপ্টিমাইজ করা যায় তা জানুন।

অ্যাপের স্ক্রিনশট

স্যাম্পেল অ্যাপে, আপনি প্রতিটি বিড়ালকে কতটা পছন্দ করেন তা বোঝাতে একটি শব্দ বা ইমোজি বেছে নিতে পারেন। আপনি একটি বোতামে ক্লিক করলে, অ্যাপটি বর্তমান বিড়ালের ছবির নিচে বোতামের ভ্যালু দেখায়।

পরিমাপ করুন

কোনও অপ্টিমাইজেশন যোগ করার আগে ওয়েবসাইটটি পরীক্ষা করে দেখা সবসময়ই ভালো:

  1. সাইটের প্রিভিউ দেখতে, অ্যাপ দেখুন বিকল্পে প্রেস করুন। তারপর ফুল-স্ক্রিন পূর্ণ স্ক্রিন বিকল্পে প্রেস করুন।
  2. DevTools খুলতে `Control+Shift+J` (বা Mac-এ `Command+Option+J`) প্রেস করুন।
  3. নেটওয়ার্ক ট্যাবে ক্লিক করুন।
  4. ক্যাশে বন্ধ করুন চেকবক্স বেছে নিন।
  5. অ্যাপটি আবার লোড করুন।

আসল বান্ডেল সাইজের অনুরোধ

এই অ্যাপ্লিকেশনের জন্য ৮০ কেবির বেশি ব্যবহার করা হয়েছে! বান্ডেলের কোনও অংশ ব্যবহার করা হচ্ছে না কিনা তা খুঁজে দেখার সময়:

  1. কমান্ড মেনু খুলতে Control+Shift+P (বা Mac-এ Command+Shift+P) প্রেস করুন। কমান্ড মেনু

  2. কভারেজ ট্যাব দেখতে Show Coverage লিখে Enter প্রেস করুন।

  3. কভারেজ ট্যাবে, কভারেজ ক্যাপচার করার সময় অ্যাপ্লিকেশন রিলোড করতে রিলোড করুন বিকল্পে ক্লিক করুন।

    কোড কভারেজ সহ অ্যাপ আবার লোড করুন

  4. প্রধান বান্ডেলের জন্য কতটা কোড লোড করা হয়েছে এবং তার মধ্যে কতটা ব্যবহার করা হয়েছে তা দেখুন:

    বান্ডেলের কোড কভারেজ

বান্ডেলের অর্ধেকের বেশি (৪৪ কেবি) ব্যবহারই করা হয়নি। এর কারণ হল, এর মধ্যে থাকা অনেক কোড পলিফিল দিয়ে তৈরি যাতে অ্যাপ্লিকেশনটি পুরনো ব্রাউজারেও কাজ করে।

@babel/preset-env ব্যবহার করুন

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

অ্যাপ্লিকেশনে নিম্নলিখিত ES2015 ফিচার ব্যবহার করা হয়:

এছাড়াও, নিম্নলিখিত ES2017 ফিচার ব্যবহার করা হয়:

src/index.js-এ সোর্স কোড দেখে নিন এবং এই সমস্ত কিছু কীভাবে ব্যবহার করা হয় তা জানুন।

এইসব ফিচার Chrome-এর লেটেস্ট ভার্সনে কাজ করে, কিন্তু যেসব ব্রাউজারে এগুলি কাজ করে না, সেগুলির ক্ষেত্রে কী হবে? Babel, যা অ্যাপ্লিকেশনে অন্তর্ভুক্ত, এটি হল সবচেয়ে জনপ্রিয় লাইব্রেরি যা কোড কম্পাইল করতে ব্যবহৃত হয় যেটিতে নতুন সিনট্যাক্স রয়েছে এমন কোডে যা পুরানো ব্রাউজার এবং পরিবেশ বুঝতে পারে। এটি দুটি উপায়ে এই কাজ করে:

  • নতুন ES2015+ ফাংশন এমুলেট করার জন্য পলিফিল অন্তর্ভুক্ত করা হয়েছে যাতে ব্রাউজার সাপোর্ট না করলেও এটির API ব্যবহার করা যায়। Array.includes পদ্ধতির পলিফিল -এর একটি উদাহরণ এখানে দেওয়া হল।
  • ES2015 কোড (বা তার পরের ভার্সন) পুরনো ES5 সিনট্যাক্সে পরিবর্তন করতে প্লাগ-ইন ব্যবহার করা হয়। যেহেতু এগুলি সিনট্যাক্স সম্পর্কিত পরিবর্তন (যেমন, অ্যারো ফাংশন), তাই এগুলি পলিফিলের মাধ্যমে এমুলেট করা যায় না।

কোন Babel লাইব্রেরি অন্তর্ভুক্ত আছে তা দেখতে package.json দেখুন:

"dependencies": {
  "@babel/polyfill": "^7.0.0"
},
"devDependencies": {
  //...
  "babel-loader": "^8.0.2",
  "@babel/core": "^7.1.0",
  "@babel/preset-env": "^7.1.0",
  //...
}
  • @babel/core হল মূল Babel কম্পাইলার। এর মাধ্যমে, প্রোজেক্টের রুটে .babelrc-এ সব Babel কনফিগারেশন সংজ্ঞায়িত করা হয়।
  • babel-loader-এ webpack বিল্ড প্রসেসে Babel অন্তর্ভুক্ত থাকে।

এখন webpack.config.js-এ দেখুন যে কীভাবে babel-loader-কে নিয়ম হিসেবে অন্তর্ভুক্ত করা হয়েছে:

module: {
  rules: [
    //...
    {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: "babel-loader"
    }
  ]
},
  • @babel/polyfill যেকোনও নতুন ECMAScript ফিচারের জন্য প্রয়োজনীয় সব পলিফিল প্রদান করে যাতে সেগুলি এমন পরিবেশে কাজ করতে পারে যেখানে সেগুলি কাজ করে না। এটি আগে থেকেই src/index.js.-এর একেবারে উপরে ইমপোর্ট করা আছে
import "./style.css";
import "@babel/polyfill";
  • @babel/preset-env শনাক্ত করে যে টার্গেট হিসেবে বেছে নেওয়া যেকোনও ব্রাউজার বা এনভায়রনমেন্টের জন্য কোন ট্রান্সফর্ম ও পলিফিল প্রয়োজন।

Babel কনফিগারেশন ফাইল, .babelrc দেখুন, এটি কীভাবে অন্তর্ভুক্ত করা হয়েছে তা দেখতে:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "last 2 versions"
      }
    ]
  ]
}

এটি Babel ও webpack সেট-আপ। আপনি যদি webpack-এর পরিবর্তে অন্য কোনও মডিউল বান্ডলার ব্যবহার করেন, তাহলে আপনার অ্যাপ্লিকেশনে কীভাবে Babel অন্তর্ভুক্ত করবেন তা জানুন।

.babelrc-এ targets অ্যাট্রিবিউট কোন ব্রাউজারকে টার্গেট করা হচ্ছে তা শনাক্ত করে। @babel/preset-env ব্রাউজারলিস্টের সাথে ইন্টিগ্রেট করে, যার অর্থ হল আপনি এই ফিল্ডে ব্যবহার করা যেতে পারে এমন মানানসই কোয়েরির সম্পূর্ণ তালিকা ব্রাউজারলিস্ট ডকুমেন্টেশনে খুঁজে পেতে পারেন।

"last 2 versions" ভ্যালু প্রতিটি ব্রাউজারের শেষ দুটি ভার্সনের জন্য অ্যাপ্লিকেশনে কোড ট্রান্সপাইল করে।

ডিবাগিং

ব্রাউজারের সব Babel টার্গেট এবং অন্তর্ভুক্ত করা সব ট্রান্সফর্ম ও পলিফিল সম্পূর্ণভাবে দেখতে, .babelrc:-এ debug ফিল্ড যোগ করুন

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "last 2 versions",
        "debug": true
      }
    ]
  ]
}
  • টুল বিকল্পে ক্লিক করুন।
  • লগ বিকল্পে ক্লিক করুন।

অ্যাপ্লিকেশনটি আবার লোড করুন এবং এডিটরের নিচে Glitch স্ট্যাটাস লগ দেখুন।

টার্গেট করা ব্রাউজার

Babel কম্পাইলেশন প্রসেস সম্পর্কে কনসোলে অনেক বিবরণ লগ করে, যার মধ্যে কোডটি যে সমস্ত টার্গেট এনভায়রনমেন্টের জন্য কম্পাইল করা হয়েছে সেগুলিও অন্তর্ভুক্ত।

টার্গেট করা ব্রাউজার

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

Babel, ব্যবহৃত ট্রান্সফর্ম প্লাগ-ইনের একটি তালিকাও লগ করে:

ব্যবহৃত প্লাগ-ইনের তালিকা

সে তো অনেক বড় তালিকা! এগুলি হল সেইসব প্লাগ-ইন যা Babel-এর প্রয়োজন হয় যাতে ES2015+ সিনট্যাক্সকে টার্গেট করা সব ব্রাউজারের জন্য পুরনো সিনট্যাক্সে পরিবর্তন করা যায়।

তবে, Babel ব্যবহৃত কোনও নির্দিষ্ট পলিফিল দেখায় না:

কোনও পলিফিল যোগ করা হয়নি

কারণ, সম্পূর্ণ @babel/polyfill সরাসরি ইমপোর্ট করা হচ্ছে।

আলাদা আলাদা করে পলিফিল লোড করুন

ডিফল্ট হিসেবে, Babel-এ সম্পূর্ণ ES2015+ এনভায়রনমেন্টের জন্য প্রয়োজনীয় প্রতিটি পলিফিল অন্তর্ভুক্ত থাকে, যখন @babel/polyfill কোনও ফাইলে ইমপোর্ট করা হয়। টার্গেট ব্রাউজারের জন্য প্রয়োজনীয় নির্দিষ্ট পলিফিল ইমপোর্ট করতে, কনফিগারেশনে useBuiltIns: 'entry' যোগ করুন।

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "last 2 versions",
        "debug": true
        "useBuiltIns": "entry"
      }
    ]
  ]
}

অ্যাপ্লিকেশন আবার লোড করুন। আপনি এখন অন্তর্ভুক্ত করা সব নির্দিষ্ট পলিফিল দেখতে পাবেন:

ইমপোর্ট করা পলিফিলের তালিকা

যদিও "last 2 versions"-এর জন্য শুধুমাত্র প্রয়োজনীয় পলিফিল এখন অন্তর্ভুক্ত করা হয়েছে, তবুও এটি একটি অত্যন্ত দীর্ঘ তালিকা! এর কারণ হল প্রতিটি নতুন ফিচারের জন্য টার্গেট ব্রাউজারে প্রয়োজনীয় পলিফিল এখনও অন্তর্ভুক্ত করা আছে। অ্যাট্রিবিউটের ভ্যালু পরিবর্তন করে usage করুন যাতে কোডে ব্যবহার করা হচ্ছে এমন ফিচারের জন্য প্রয়োজনীয় অ্যাট্রিবিউটই শুধু অন্তর্ভুক্ত করা হয়।

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "last 2 versions",
        "debug": true,
        "useBuiltIns": "entry"
        "useBuiltIns": "usage"
      }
    ]
  ]
}

এর মাধ্যমে, যেখানে প্রয়োজন সেখানে পলিফিল অটোমেটিক অন্তর্ভুক্ত করা হয়। এর অর্থ হল, আপনি src/index.js. থেকে @babel/polyfill ইমপোর্ট করার সুবিধা সরিয়ে দিতে পারবেন

import "./style.css";
import "@babel/polyfill";

এখন অ্যাপ্লিকেশনের জন্য শুধুমাত্র প্রয়োজনীয় পলিফিল অন্তর্ভুক্ত করা হয়েছে।

অটোমেটিক অন্তর্ভুক্ত করা পলিফিলের তালিকা

অ্যাপ্লিকেশন বান্ডেলের সাইজ উল্লেখযোগ্যভাবে কমে যায়।

বান্ডেলের সাইজ কমিয়ে ৩০.১ কেবি করা হয়েছে

যেসব ব্রাউজারে কাজ করে তার তালিকা ছোট করা হচ্ছে

ব্রাউজার টার্গেটের সংখ্যা এখনও অনেক বেশি এবং অনেক ব্যবহারকারীই Internet Explorer-এর মতো বন্ধ হয়ে যাওয়া ব্রাউজার ব্যবহার করেন না। কনফিগারেশন আপডেট করে নিম্নলিখিতটি করুন:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "last 2 versions",
        "targets": [">0.25%", "not ie 11"],
        "debug": true,
        "useBuiltIns": "usage",
      }
    ]
  ]
}

ফেচ করা বান্ডেলের বিবরণ দেখুন।

৩০.০ কেবি সাইজের বান্ডেল

অ্যাপ্লিকেশনটি খুব ছোট হওয়ায়, এইসব পরিবর্তনের ফলে খুব বেশি পার্থক্য হয়নি। তবে, ব্রাউজার মার্কেট শেয়ারের শতাংশ (যেমন ">0.25%") ব্যবহার করার পাশাপাশি, আপনার ব্যবহারকারীরা ব্যবহার করছেন না বলে আপনি নিশ্চিত এমন নির্দিষ্ট ব্রাউজার বাদ দেওয়া হল সাজেস্ট করা পদ্ধতি। এই বিষয়ে আরও জানতে জেমস কাইলের লেখা "শেষ ২টি ভার্সন" ক্ষতিকর হিসেবে বিবেচিত নিবন্ধটি পড়ে দেখুন।

<script type="module"> ব্যবহার করুন

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

জাভাস্ক্রিপ্ট মডিউল হল তুলনামূলকভাবে নতুন ফিচার যা সব প্রধান ব্রাউজারে কাজ করে। অন্যান্য মডিউল থেকে ইমপোর্ট ও এক্সপোর্ট করা স্ক্রিপ্ট সংজ্ঞায়িত করতে type="module" অ্যাট্রিবিউট ব্যবহার করে মডিউল তৈরি করা যেতে পারে। যেমন:

// math.mjs
export const add = (x, y) => x + y;

<!-- index.html -->
<script type="module">
  import { add } from './math.mjs';

  add(5, 2); // 7
</script>

অনেক নতুন ECMAScript ফিচার ইতিমধ্যেই এমন পরিবেশে কাজ করে যা জাভাস্ক্রিপ্ট মডিউল সাপোর্ট করে (Babel-এর প্রয়োজন হয় না।) এর অর্থ হল, Babel কনফিগারেশন পরিবর্তন করে আপনার অ্যাপ্লিকেশনের দুটি আলাদা ভার্সন ব্রাউজারে পাঠানো যেতে পারে:

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

Babel-এর সাথে ES মডিউল ব্যবহার করা

অ্যাপ্লিকেশনের দুটি ভার্সনের জন্য আলাদা @babel/preset-env সেটিংস রাখতে, .babelrc ফাইলটি সরিয়ে দিন। অ্যাপ্লিকেশনের প্রতিটি ভার্সনের জন্য দুটি আলাদা কম্পাইলেশন ফর্ম্যাট নির্দিষ্ট করে webpack কনফিগারেশনে Babel সেটিংস যোগ করা যেতে পারে।

webpack.config.js-এ লিগ্যাসি স্ক্রিপ্টের জন্য কনফিগারেশন যোগ করে শুরু করুন:

const legacyConfig = {
  entry,
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "[name].bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: {
          presets: [
            ["@babel/preset-env", {
              useBuiltIns: "usage",
              targets: {
                esmodules: false
              }
            }]
          ]
        }
      },
      cssRule
    ]
  },
  plugins
}

লক্ষ্য করুন যে "@babel/preset-env"-এর জন্য targets ভ্যালু ব্যবহার করার পরিবর্তে, false ভ্যালু সহ esmodules ব্যবহার করা হয়েছে। এর অর্থ হল, Babel-এ এমন সব প্রয়োজনীয় ট্রান্সফর্ম ও পলিফিল অন্তর্ভুক্ত থাকে যা এখনও ES মডিউল সাপোর্ট করে না এমন প্রতিটি ব্রাউজারকে টার্গেট করে।

webpack.config.js ফাইলের শুরুতে entry, cssRule ও corePlugins অবজেক্ট যোগ করুন। এইসব তথ্য মডিউল এবং ব্রাউজারে পরিবেশিত লিগ্যাসি স্ক্রিপ্ট, উভয়ের মধ্যেই শেয়ার করা হয়।

const entry = {
  main: "./src"
};

const cssRule = {
  test: /\.css$/,
  use: ExtractTextPlugin.extract({
    fallback: "style-loader",
    use: "css-loader"
  })
};

const plugins = [
  new ExtractTextPlugin({filename: "[name].css", allChunks: true}),
  new HtmlWebpackPlugin({template: "./src/index.html"})
];

এখন একইভাবে, নিচে দেওয়া মডিউল স্ক্রিপ্টের জন্য একটি কনফিগারেশন অবজেক্ট তৈরি করুন যেখানে legacyConfig সংজ্ঞায়িত করা আছে:

const moduleConfig = {
  entry,
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "[name].mjs"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: {
          presets: [
            ["@babel/preset-env", {
              useBuiltIns: "usage",
              targets: {
                esmodules: true
              }
            }]
          ]
        }
      },
      cssRule
    ]
  },
  plugins
}

এখানে মূল পার্থক্য হল, আউটপুট ফাইলের নামের জন্য .mjs ফাইল এক্সটেনশন ব্যবহার করা হয়। এখানে esmodules ভ্যালু true হিসেবে সেট করা হয়েছে, যার অর্থ হল এই মডিউলে আউটপুট হিসেবে দেখানো কোডটি হল একটি ছোট, কম কম্পাইল করা স্ক্রিপ্ট যা এই উদাহরণে কোনও ট্রান্সফর্মেশনের মধ্যে দিয়ে যায় না, কারণ ব্যবহৃত সব ফিচার আগে থেকেই মডিউল সাপোর্ট করে এমন ব্রাউজারে কাজ করে।

ফাইলের একদম শেষে, একটি অ্যারেতে দুটি কনফিগারেশন এক্সপোর্ট করুন।

module.exports = [
  legacyConfig, moduleConfig
];

এখন এটি ব্রাউজারের জন্য একটি ছোট মডিউল তৈরি করে যা এটিকে সমর্থন করে এবং পুরানো ব্রাউজারগুলির জন্য একটি বড় ট্রান্সপাইলড স্ক্রিপ্ট তৈরি করে।

যেসব ব্রাউজারে মডিউল কাজ করে, সেগুলি nomodule অ্যাট্রিবিউট সহ স্ক্রিপ্ট উপেক্ষা করে। বিপরীতভাবে, যেসব ব্রাউজারে মডিউল কাজ করে না, সেগুলি type="module" সহ স্ক্রিপ্ট এলিমেন্ট উপেক্ষা করে। এর অর্থ হল, আপনি একটি মডিউলের পাশাপাশি একটি কম্পাইল করা ফলব্যাক অন্তর্ভুক্ত করতে পারেন। সাধারণত, অ্যাপ্লিকেশনের দুটি ভার্সন index.html-এ এইভাবে থাকতে হবে:

<script type="module" src="main.mjs"></script>
<script nomodule src="main.bundle.js"></script>

যেসব ব্রাউজারে মডিউল কাজ করে সেগুলি main.mjs ফেচ ও এক্সিকিউট করে এবং main.bundle.js. ইগনোর করে। যেসব ব্রাউজারে মডিউল কাজ করে না সেগুলি এর বিপরীত কাজ করে।

মনে রাখা গুরুত্বপূর্ণ যে, সাধারণ স্ক্রিপ্টের মতো নয়, মডিউল স্ক্রিপ্ট সবসময় ডিফল্ট হিসেবে স্থগিত করা হয়। আপনি যদি চান যে সমতুল্য nomodule স্ক্রিপ্টও স্থগিত করা হোক এবং শুধুমাত্র পার্স করার পরে চালানো হোক, তাহলে আপনাকে defer অ্যাট্রিবিউট যোগ করতে হবে:

<script type="module" src="main.mjs"></script>
<script nomodule src="main.bundle.js" defer></script>

এখানে শেষ যে কাজটি করতে হবে তা হল মডিউল এবং লিগ্যাসি স্ক্রিপ্টে যথাক্রমে module এবং nomodule অ্যাট্রিবিউট যোগ করা, webpack.config.js-এর একেবারে উপরে ScriptExtHtmlWebpackPlugin ইমপোর্ট করুন:

const path = require("path");

const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");

এখন এই প্লাগ-ইন অন্তর্ভুক্ত করতে কনফিগারেশনে plugins অ্যারে আপডেট করুন:

const plugins = [
  new ExtractTextPlugin({filename: "[name].css", allChunks: true}),
  new HtmlWebpackPlugin({template: "./src/index.html"}),
  new ScriptExtHtmlWebpackPlugin({
    module: /\.mjs$/,
    custom: [
      {
        test: /\.js$/,
        attribute: 'nomodule',
        value: ''
    },
    ]
  })
];

এই প্লাগ-ইন সেটিংস সব .mjs স্ক্রিপ্ট এলিমেন্টের জন্য type="module" অ্যাট্রিবিউট এবং সব .js স্ক্রিপ্ট মডিউলের জন্য nomodule অ্যাট্রিবিউট যোগ করে।

HTML ডকুমেন্টে মডিউল দেখানো হচ্ছে

সবশেষে, HTML ফাইলে পুরনো ও আধুনিক স্ক্রিপ্ট এলিমেন্ট আউটপুট হিসেবে দেখাতে হবে। দুর্ভাগ্যবশত, যে প্লাগ-ইনটি ফাইনাল HTML ফাইল, HTMLWebpackPlugin তৈরি করে, সেটি বর্তমানে মডিউল এবং নোমডিউল স্ক্রিপ্ট, দুটিরই আউটপুট সাপোর্ট করে না। যদিও এই সমস্যা সমাধানের জন্য বিভিন্ন উপায় ও আলাদা প্লাগ-ইন তৈরি করা হয়েছে, যেমন BabelMultiTargetPlugin এবং HTMLWebpackMultiBuildPlugin, এই টিউটোরিয়ালের জন্য ম্যানুয়ালি মডিউল স্ক্রিপ্ট এলিমেন্ট যোগ করার সহজ পদ্ধতি ব্যবহার করা হয়েছে।

ফাইলের শেষে src/index.js-এ নিম্নলিখিতগুলি যোগ করুন:

    ...
    </form>
    <script type="module" src="main.mjs"></script>
  </body>
</html>

এখন মডিউল সাপোর্ট করে এমন ব্রাউজারে অ্যাপ্লিকেশন লোড করুন, যেমন Chrome-এর লেটেস্ট ভার্সন।

নতুন ব্রাউজারের জন্য নেটওয়ার্কের মাধ্যমে ৫.২ কেবি মডিউল ফেচ করা হয়েছে

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

আপনি পুরনো ব্রাউজারে অ্যাপ্লিকেশন লোড করলে, শুধু বড়, ট্রান্সপাইল করা স্ক্রিপ্ট, যার মধ্যে সব প্রয়োজনীয় পলিফিল ও ট্রান্সফর্ম আছে, তা ফেচ করা হয়। Chrome-এর পুরনো ভার্সনে (ভার্সন ৩৮) করা সব অনুরোধের স্ক্রিনশট এখানে দেওয়া হল।

পুরনো ব্রাউজারের জন্য ৩০ কেবি স্ক্রিপ্ট ফেচ করা হয়েছে

উপসংহার

টার্গেট করা ব্রাউজারের জন্য প্রয়োজনীয় পলিফিল প্রদান করতে কীভাবে @babel/preset-env ব্যবহার করতে হয় তা আপনি এখন জানেন। এছাড়াও, আপনি জানেন যে কীভাবে জাভাস্ক্রিপ্ট মডিউল কোনও অ্যাপ্লিকেশনের দুটি ভিন্ন ট্রান্সপাইল করা ভার্সন শিপিং করে পারফর্ম্যান্স আরও উন্নত করতে পারে। এই দুটি টেকনিক কীভাবে আপনার বান্ডেলের সাইজ উল্লেখযোগ্যভাবে কমাতে পারে তা ভালোভাবে বোঝার পরে, এগিয়ে যান এবং অপ্টিমাইজ করুন!