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

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

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

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

পরিমাপ

কোন অপ্টিমাইজেশান যোগ করার আগে একটি ওয়েবসাইট পরিদর্শন করে শুরু করা সর্বদা একটি ভাল ধারণা:

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

মূল বান্ডিল আকার অনুরোধ

এই অ্যাপ্লিকেশনের জন্য 80 KB এর বেশি ব্যবহার করা হয়েছে! বান্ডিলের অংশগুলি ব্যবহার করা হচ্ছে না কিনা তা খুঁজে বের করার সময়:

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

  2. Show Coverage এবং কভারেজ ট্যাব প্রদর্শন করতে Enter টিপুন।

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

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

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

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

অর্ধেক বান্ডিল (44 KB) এমনকি ব্যবহার করা হয় না. এর কারণ হল অ্যাপ্লিকেশনটি পুরানো ব্রাউজারগুলিতে কাজ করে তা নিশ্চিত করতে পলিফিলগুলির মধ্যে অনেকগুলি কোড রয়েছে৷

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

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

নিম্নলিখিত ES2015 বৈশিষ্ট্যগুলি অ্যাপ্লিকেশনটিতে ব্যবহৃত হয়:

নিম্নলিখিত ES2017 বৈশিষ্ট্যটিও ব্যবহার করা হয়:

এই সবগুলি কীভাবে ব্যবহার করা হয় তা দেখতে src/index.js এর সোর্স কোডে বিনা দ্বিধায় ডুব দিন৷

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

  • পলিফিলগুলিকে নতুন 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 কম্পাইলার। এটির সাহায্যে, সমস্ত Babel কনফিগারেশন প্রকল্পের মূলে একটি .babelrc এ সংজ্ঞায়িত করা হয়েছে।
  • babel-loader ওয়েবপ্যাক নির্মাণ প্রক্রিয়ার মধ্যে বাবেলকে অন্তর্ভুক্ত করে।

এখন 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"
      }
    ]
  ]
}

এটি একটি ব্যাবেল এবং ওয়েবপ্যাক সেটআপ। আপনি যদি ওয়েবপ্যাকের চেয়ে আলাদা মডিউল বান্ডলার ব্যবহার করেন তবে কীভাবে আপনার অ্যাপ্লিকেশনটিতে বাবেলকে অন্তর্ভুক্ত করবেন তা শিখুন

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

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

ডিবাগিং

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

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

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

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

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

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

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

ব্যাবেল ব্যবহৃত রূপান্তর প্লাগইনগুলির একটি তালিকাও লগ করে:

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

যে একটি চমত্কার দীর্ঘ তালিকা! এই সমস্ত প্লাগইন যা ব্যাবেলকে সমস্ত টার্গেট করা ব্রাউজারগুলির জন্য যেকোনো ES2015+ সিনট্যাক্সকে পুরানো সিনট্যাক্সে রূপান্তর করতে ব্যবহার করতে হবে৷

যাইহোক, ব্যাবেল ব্যবহার করা হয় এমন কোনো নির্দিষ্ট পলিফিল দেখায় না:

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

এর কারণ হল সম্পূর্ণ @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";

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

পলিফিলের তালিকা স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত

অ্যাপ্লিকেশন বান্ডিল আকার উল্লেখযোগ্যভাবে হ্রাস করা হয়.

বান্ডেলের আকার 30.1 KB এ কমে গেছে

সমর্থিত ব্রাউজারগুলির তালিকা সংকুচিত করা হচ্ছে

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

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

আনা বান্ডিল জন্য বিশদ বিবরণ দেখুন.

30.0 KB এর বান্ডেল সাইজ

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

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

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

JavaScript মডিউল হল একটি অপেক্ষাকৃত নতুন বৈশিষ্ট্য যা সমস্ত প্রধান ব্রাউজারে সমর্থিত। অন্যান্য মডিউল থেকে আমদানি এবং রপ্তানি করে এমন স্ক্রিপ্টগুলিকে সংজ্ঞায়িত করতে একটি 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 কনফিগারেশন পরিবর্তন করা যেতে পারে:

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

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

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

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 মান এখানে সত্য হিসাবে সেট করা হয়েছে যার অর্থ হল এই মডিউলে যে কোডটি আউটপুট করা হয়েছে তা হল একটি ছোট, কম কম্পাইল করা স্ক্রিপ্ট যা এই উদাহরণে কোনও রূপান্তরের মধ্য দিয়ে যায় না যেহেতু ব্যবহৃত সমস্ত বৈশিষ্ট্য ইতিমধ্যেই মডিউল সমর্থন করে এমন ব্রাউজারগুলিতে সমর্থিত।

ফাইলের একেবারে শেষে, একটি একক অ্যারেতে উভয় কনফিগারেশন রপ্তানি করুন।

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 এর সর্বশেষ সংস্করণ।

5.2 KB মডিউল নতুন ব্রাউজারগুলির জন্য নেটওয়ার্কে আনা হয়েছে৷

শুধুমাত্র মডিউলটি আনা হয়েছে, একটি অনেক ছোট বান্ডিল আকারের কারণে এটি মূলত আনট্রান্সপিলড! অন্য স্ক্রিপ্ট উপাদান ব্রাউজার দ্বারা সম্পূর্ণরূপে উপেক্ষা করা হয়.

আপনি যদি একটি পুরানো ব্রাউজারে অ্যাপ্লিকেশনটি লোড করেন, তবে সমস্ত প্রয়োজনীয় পলিফিল এবং রূপান্তর সহ শুধুমাত্র বড়, ট্রান্সপিলড স্ক্রিপ্ট আনা হবে। এখানে Chrome এর পুরানো সংস্করণে করা সমস্ত অনুরোধের জন্য একটি স্ক্রিনশট রয়েছে (সংস্করণ 38)৷

পুরানো ব্রাউজারগুলির জন্য 30 KB স্ক্রিপ্ট আনা হয়েছে৷

উপসংহার

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

,

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

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

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

পরিমাপ

কোন অপ্টিমাইজেশান যোগ করার আগে একটি ওয়েবসাইট পরিদর্শন করে শুরু করা সর্বদা একটি ভাল ধারণা:

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

মূল বান্ডিল আকার অনুরোধ

এই অ্যাপ্লিকেশনের জন্য 80 KB এর বেশি ব্যবহার করা হয়েছে! বান্ডিলের অংশগুলি ব্যবহার করা হচ্ছে না কিনা তা খুঁজে বের করার সময়:

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

  2. Show Coverage এবং কভারেজ ট্যাব প্রদর্শন করতে Enter টিপুন।

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

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

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

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

অর্ধেক বান্ডিল (44 KB) এমনকি ব্যবহার করা হয় না. এর কারণ হল অ্যাপ্লিকেশনটি পুরানো ব্রাউজারগুলিতে কাজ করে তা নিশ্চিত করতে পলিফিলগুলির মধ্যে অনেকগুলি কোড রয়েছে৷

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

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

নিম্নলিখিত ES2015 বৈশিষ্ট্যগুলি অ্যাপ্লিকেশনটিতে ব্যবহৃত হয়:

নিম্নলিখিত ES2017 বৈশিষ্ট্যটিও ব্যবহার করা হয়:

এই সবগুলি কীভাবে ব্যবহার করা হয় তা দেখতে src/index.js এর সোর্স কোডে বিনা দ্বিধায় ডুব দিন৷

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

  • পলিফিলগুলিকে নতুন 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 কম্পাইলার। এটির সাহায্যে, সমস্ত Babel কনফিগারেশন প্রকল্পের মূলে একটি .babelrc এ সংজ্ঞায়িত করা হয়েছে।
  • babel-loader ওয়েবপ্যাক নির্মাণ প্রক্রিয়ার মধ্যে বাবেলকে অন্তর্ভুক্ত করে।

এখন 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"
      }
    ]
  ]
}

এটি একটি ব্যাবেল এবং ওয়েবপ্যাক সেটআপ। আপনি যদি ওয়েবপ্যাকের চেয়ে আলাদা মডিউল বান্ডলার ব্যবহার করেন তবে কীভাবে আপনার অ্যাপ্লিকেশনটিতে বাবেলকে অন্তর্ভুক্ত করবেন তা শিখুন

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

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

ডিবাগিং

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

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

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

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

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

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

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

ব্যাবেল ব্যবহৃত রূপান্তর প্লাগইনগুলির একটি তালিকাও লগ করে:

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

যে একটি চমত্কার দীর্ঘ তালিকা! এই সমস্ত প্লাগইন যা ব্যাবেলকে সমস্ত টার্গেট করা ব্রাউজারগুলির জন্য যেকোনো ES2015+ সিনট্যাক্সকে পুরানো সিনট্যাক্সে রূপান্তর করতে ব্যবহার করতে হবে৷

যাইহোক, ব্যাবেল ব্যবহার করা হয় এমন কোনো নির্দিষ্ট পলিফিল দেখায় না:

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

এর কারণ হল সম্পূর্ণ @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";

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

পলিফিলের তালিকা স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত

অ্যাপ্লিকেশন বান্ডিল আকার উল্লেখযোগ্যভাবে হ্রাস করা হয়.

বান্ডেলের আকার 30.1 KB এ কমে গেছে

সমর্থিত ব্রাউজারগুলির তালিকা সংকুচিত করা হচ্ছে

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

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

আনা বান্ডিল জন্য বিশদ বিবরণ দেখুন.

30.0 KB এর বান্ডেল সাইজ

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

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

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

JavaScript মডিউল হল একটি অপেক্ষাকৃত নতুন বৈশিষ্ট্য যা সমস্ত প্রধান ব্রাউজারে সমর্থিত। অন্যান্য মডিউল থেকে আমদানি এবং রপ্তানি করে এমন স্ক্রিপ্টগুলিকে সংজ্ঞায়িত করতে একটি 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 কনফিগারেশন পরিবর্তন করা যেতে পারে:

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

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

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

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 ব্যবহার করা হয়। এর মানে হল যে সমস্ত ব্রাউজারকে টার্গেট করার জন্য বাবেল সমস্ত প্রয়োজনীয় রূপান্তর এবং পলিফিলগুলি অন্তর্ভুক্ত করে যা এখনও 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 মান এখানে সত্য হিসাবে সেট করা হয়েছে যার অর্থ হল এই মডিউলে যে কোডটি আউটপুট করা হয়েছে তা হল একটি ছোট, কম কম্পাইল করা স্ক্রিপ্ট যা এই উদাহরণে কোনও রূপান্তরের মধ্য দিয়ে যায় না যেহেতু ব্যবহৃত সমস্ত বৈশিষ্ট্য ইতিমধ্যেই মডিউল সমর্থন করে এমন ব্রাউজারগুলিতে সমর্থিত।

ফাইলের একেবারে শেষে, একটি একক অ্যারেতে উভয় কনফিগারেশন রপ্তানি করুন।

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 এর সর্বশেষ সংস্করণ।

5.2 KB মডিউল নতুন ব্রাউজারগুলির জন্য নেটওয়ার্কে আনা হয়েছে৷

শুধুমাত্র মডিউলটি আনা হয়েছে, একটি অনেক ছোট বান্ডিল আকারের কারণে এটি মূলত আনট্রান্সপিলড! অন্য স্ক্রিপ্ট উপাদান ব্রাউজার দ্বারা সম্পূর্ণরূপে উপেক্ষা করা হয়.

আপনি যদি একটি পুরানো ব্রাউজারে অ্যাপ্লিকেশনটি লোড করেন, তবে সমস্ত প্রয়োজনীয় পলিফিল এবং রূপান্তর সহ শুধুমাত্র বড়, ট্রান্সপিলড স্ক্রিপ্ট আনা হবে। এখানে Chrome এর পুরানো সংস্করণে করা সমস্ত অনুরোধের জন্য একটি স্ক্রিনশট রয়েছে (সংস্করণ 38)৷

পুরানো ব্রাউজারগুলির জন্য 30 KB স্ক্রিপ্ট আনা হয়েছে৷

উপসংহার

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

,

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

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

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

পরিমাপ

কোন অপ্টিমাইজেশান যোগ করার আগে একটি ওয়েবসাইট পরিদর্শন করে শুরু করা সর্বদা একটি ভাল ধারণা:

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

মূল বান্ডিল আকার অনুরোধ

এই অ্যাপ্লিকেশনের জন্য 80 KB এর বেশি ব্যবহার করা হয়েছে! বান্ডিলের অংশগুলি ব্যবহার করা হচ্ছে না কিনা তা খুঁজে বের করার সময়:

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

  2. Show Coverage এবং কভারেজ ট্যাব প্রদর্শন করতে Enter টিপুন।

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

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

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

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

অর্ধেক বান্ডিল (44 KB) এমনকি ব্যবহার করা হয় না. এর কারণ হল অ্যাপ্লিকেশনটি পুরানো ব্রাউজারগুলিতে কাজ করে তা নিশ্চিত করতে পলিফিলগুলির মধ্যে অনেকগুলি কোড রয়েছে৷

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

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

নিম্নলিখিত ES2015 বৈশিষ্ট্যগুলি অ্যাপ্লিকেশনটিতে ব্যবহৃত হয়:

নিম্নলিখিত ES2017 বৈশিষ্ট্যটিও ব্যবহার করা হয়:

এই সবগুলি কীভাবে ব্যবহার করা হয় তা দেখতে src/index.js এর সোর্স কোডে বিনা দ্বিধায় ডুব দিন৷

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

  • পলিফিলগুলিকে নতুন 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 কম্পাইলার। এটির সাহায্যে, সমস্ত Babel কনফিগারেশন প্রকল্পের মূলে একটি .babelrc এ সংজ্ঞায়িত করা হয়েছে।
  • babel-loader ওয়েবপ্যাক নির্মাণ প্রক্রিয়ার মধ্যে বাবেলকে অন্তর্ভুক্ত করে।

এখন 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"
      }
    ]
  ]
}

এটি একটি ব্যাবেল এবং ওয়েবপ্যাক সেটআপ। আপনি যদি ওয়েবপ্যাকের চেয়ে আলাদা মডিউল বান্ডলার ব্যবহার করেন তবে কীভাবে আপনার অ্যাপ্লিকেশনটিতে বাবেলকে অন্তর্ভুক্ত করবেন তা শিখুন

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

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

ডিবাগিং

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

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

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

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

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

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

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

ব্যাবেল ব্যবহৃত রূপান্তর প্লাগইনগুলির একটি তালিকাও লগ করে:

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

যে একটি চমত্কার দীর্ঘ তালিকা! এই সমস্ত প্লাগইন যা ব্যাবেলকে সমস্ত টার্গেট করা ব্রাউজারগুলির জন্য যেকোনো ES2015+ সিনট্যাক্সকে পুরানো সিনট্যাক্সে রূপান্তর করতে ব্যবহার করতে হবে৷

যাইহোক, ব্যাবেল ব্যবহার করা হয় এমন কোনো নির্দিষ্ট পলিফিল দেখায় না:

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

এর কারণ হল সম্পূর্ণ @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";

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

পলিফিলগুলির তালিকা স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত

অ্যাপ্লিকেশন বান্ডিলের আকার উল্লেখযোগ্যভাবে হ্রাস পেয়েছে।

বান্ডিলের আকার হ্রাস 30.1 কেবি

সমর্থিত ব্রাউজারগুলির তালিকা সংকীর্ণ করা

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

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

আনার বান্ডিলের বিশদটি একবার দেখুন।

30.0 কেবি এর বান্ডিল আকার

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

<স্ক্রিপ্ট টাইপ = "মডিউল"> ব্যবহার করুন

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

জাভাস্ক্রিপ্ট মডিউলগুলি সমস্ত বড় ব্রাউজারগুলিতে সমর্থিত একটি তুলনামূলকভাবে নতুন বৈশিষ্ট্য। অন্যান্য মডিউলগুলি থেকে আমদানি ও রফতানি করে এমন স্ক্রিপ্টগুলি সংজ্ঞায়িত করতে একটি 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>

অনেকগুলি নতুন ইসমাস্ক্রিপ্ট বৈশিষ্ট্য ইতিমধ্যে এমন পরিবেশে সমর্থিত যা জাভাস্ক্রিপ্ট মডিউলগুলিকে সমর্থন করে (ব্যাবেল প্রয়োজনের পরিবর্তে)) এর অর্থ হ'ল ব্রাউজারে আপনার অ্যাপ্লিকেশনটির দুটি পৃথক সংস্করণ প্রেরণে বাবেল কনফিগারেশনটি সংশোধন করা যেতে পারে:

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

বাবেল সহ ইএস মডিউল ব্যবহার করে

অ্যাপ্লিকেশনটির দুটি সংস্করণের জন্য পৃথক @babel/preset-env সেটিংস থাকতে, .babelrc ফাইলটি সরান। অ্যাপ্লিকেশনটির প্রতিটি সংস্করণের জন্য দুটি পৃথক সংকলন ফর্ম্যাট নির্দিষ্ট করে ওয়েবপ্যাক কনফিগারেশনে বাবেল সেটিংস যুক্ত করা যেতে পারে।

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 ব্যবহার করা হয়। এর অর্থ হ'ল বাবেল প্রতিটি ব্রাউজারকে লক্ষ্য করার জন্য প্রয়োজনীয় সমস্ত ট্রান্সফর্ম এবং পলিফিল অন্তর্ভুক্ত করে যা এখনও ইএস মডিউলগুলিকে সমর্থন করে না।

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 মানটি এখানে সত্যে সেট করা হয়েছে যার অর্থ এই যে এই মডিউলটিতে আউটপুট করা কোডটি একটি ছোট, কম সংকলিত স্ক্রিপ্ট যা এই উদাহরণে কোনও রূপান্তরকরণের মধ্য দিয়ে যায় না কারণ ব্যবহৃত সমস্ত বৈশিষ্ট্য ইতিমধ্যে ব্রাউজারগুলিতে সমর্থিত যা মডিউলগুলিকে সমর্থন করে।

ফাইলের একেবারে শেষে, একক অ্যারে উভয় কনফিগারেশন রফতানি করুন।

module.exports = [
  legacyConfig, moduleConfig
];

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

মডিউলগুলি সমর্থন করে এমন ব্রাউজারগুলি nomodule বৈশিষ্ট্য সহ স্ক্রিপ্টগুলিকে উপেক্ষা করে। বিপরীতে, মডিউলগুলি সমর্থন করে না এমন ব্রাউজারগুলি type="module" সহ স্ক্রিপ্ট উপাদানগুলিকে উপেক্ষা করে। এর অর্থ আপনি একটি মডিউল পাশাপাশি সংকলিত ফ্যালব্যাক অন্তর্ভুক্ত করতে পারেন। আদর্শভাবে, অ্যাপ্লিকেশনটির দুটি সংস্করণ index.html হওয়া উচিত 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 একেবারে শীর্ষে আমদানি করুন:

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 বৈশিষ্ট্য।

এইচটিএমএল ডকুমেন্টে মডিউলগুলি পরিবেশন করা হচ্ছে

শেষ কাজটি করা দরকার যা হ'ল এইচটিএমএল ফাইলটিতে উত্তরাধিকার এবং আধুনিক স্ক্রিপ্ট উভয় উপাদানকে আউটপুট করা। দুর্ভাগ্যক্রমে, প্লাগইন যা চূড়ান্ত এইচটিএমএল ফাইল তৈরি করে, HTMLWebpackPlugin , বর্তমানে মডিউল এবং নামকরণ স্ক্রিপ্ট উভয়ের আউটপুটকে সমর্থন করে না । Although there are workarounds and separate plugins created to solve this problem, such as BabelMultiTargetPlugin and HTMLWebpackMultiBuildPlugin , a simpler approach of adding the module script element manually is used for the purpose of this tutorial.

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

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

এখন ব্রাউজারে অ্যাপ্লিকেশনটি লোড করুন যা মডিউলগুলিকে সমর্থন করে, যেমন ক্রোমের সর্বশেষতম সংস্করণ।

5.2 কেবি মডিউলটি নতুন ব্রাউজারগুলির জন্য নেটওয়ার্কের উপরে আনা হয়েছে

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

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

30 কেবি স্ক্রিপ্ট পুরানো ব্রাউজারগুলির জন্য আনা হয়েছে

উপসংহার

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

,

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

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

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

পরিমাপ

কোনও অপ্টিমাইজেশন যুক্ত করার আগে কোনও ওয়েবসাইট পরিদর্শন করে শুরু করা সর্বদা একটি ভাল ধারণা:

  1. সাইটের পূর্বরূপ দেখতে, দেখুন অ্যাপ্লিকেশন টিপুন। তারপরে ফুলস্ক্রিন টিপুন ফুলস্ক্রিন .
  2. ডিভটুলগুলি খোলার জন্য `কন্ট্রোল+শিফট+জে (বা` কমান্ড+বিকল্প+জে `ম্যাক) টিপুন।
  3. নেটওয়ার্ক ট্যাবে ক্লিক করুন।
  4. অক্ষম ক্যাশে চেকবক্সটি নির্বাচন করুন।
  5. অ্যাপটি পুনরায় লোড করুন।

আসল বান্ডিল আকারের অনুরোধ

এই অ্যাপ্লিকেশনটির জন্য 80 টিরও বেশি কেবি ব্যবহৃত হয়! বান্ডিলের অংশগুলি ব্যবহার করা হচ্ছে না কিনা তা জানার সময়:

  1. কমান্ড মেনুটি খুলতে Control+Shift+P (বা ম্যাকের উপর Command+Shift+P ) টিপুন। কমান্ড মেনু

  2. Show Coverage প্রবেশ করুন এবং কভারেজ ট্যাবটি প্রদর্শন করতে Enter হিট করুন।

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

    কোড কভারেজ সহ অ্যাপ্লিকেশন পুনরায় লোড করুন

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

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

অর্ধেকেরও বেশি বান্ডিল (44 কেবি) এমনকি ব্যবহার করা হয় না। এটি কারণ হ'ল অ্যাপ্লিকেশনটি পুরানো ব্রাউজারগুলিতে কাজ করে তা নিশ্চিত করার জন্য পলিফিলগুলির মধ্যে অনেকগুলি কোড রয়েছে।

@বাবেল/প্রিসেট-এনভি ব্যবহার করুন

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

নিম্নলিখিত ES2015 বৈশিষ্ট্যগুলি অ্যাপ্লিকেশনটিতে ব্যবহৃত হয়:

নিম্নলিখিত ES2017 বৈশিষ্ট্যটি পাশাপাশি ব্যবহৃত হয়:

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

এই সমস্ত বৈশিষ্ট্যগুলি ক্রোমের সর্বশেষ সংস্করণে সমর্থিত, তবে অন্যান্য ব্রাউজারগুলির কী কী তাদের সমর্থন করে না? অ্যাপ্লিকেশনটিতে অন্তর্ভুক্ত ব্যাবেল হ'ল সর্বাধিক জনপ্রিয় গ্রন্থাগার যা কোড সংকলন করতে ব্যবহৃত হয় যা কোডে নতুন সিনট্যাক্স ধারণ করে যা পুরানো ব্রাউজার এবং পরিবেশগুলি বুঝতে পারে। এটি দুটি উপায়ে এটি করে:

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

কোন বাবেল লাইব্রেরি অন্তর্ভুক্ত রয়েছে তা দেখতে 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 হ'ল মূল বাবেল সংকলক। এটির সাথে, সমস্ত বাবেল কনফিগারেশনগুলি প্রকল্পের মূলে একটি .babelrc -তে সংজ্ঞায়িত করা হয়।
  • babel-loader ওয়েবপ্যাক বিল্ড প্রক্রিয়াতে বাবেল অন্তর্ভুক্ত রয়েছে।

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

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

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

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

এটি একটি বাবেল এবং ওয়েবপ্যাক সেটআপ। আপনি যদি ওয়েবপ্যাকের চেয়ে আলাদা মডিউল বান্ডিলার ব্যবহার করে থাকেন তবে কীভাবে আপনার অ্যাপ্লিকেশনটিতে বাবেলকে অন্তর্ভুক্ত করবেন তা শিখুন

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

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

ডিবাগিং

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

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

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

লক্ষ্যযুক্ত ব্রাউজার

বাবেল সংকলন প্রক্রিয়া সম্পর্কে কনসোলে বেশ কয়েকটি বিবরণ লগ করে, কোডটি সংকলিত সমস্ত লক্ষ্য পরিবেশ সহ।

লক্ষ্যযুক্ত ব্রাউজার

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

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

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

এটি একটি দীর্ঘ দীর্ঘ তালিকা! এগুলি সমস্ত প্লাগইন যা সমস্ত লক্ষ্যযুক্ত ব্রাউজারগুলির জন্য কোনও ES2015+ সিনট্যাক্সকে পুরানো সিনট্যাক্সে রূপান্তর করতে বাবেলকে ব্যবহার করতে হবে।

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

কোনও পলিফিল যুক্ত করা হয়নি

এটি কারণ পুরো @babel/polyfill সরাসরি আমদানি করা হচ্ছে।

স্বতন্ত্রভাবে পলিফিলগুলি লোড করুন

ডিফল্টরূপে, বাবেল একটি সম্পূর্ণ 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";

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

পলিফিলগুলির তালিকা স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত

অ্যাপ্লিকেশন বান্ডিলের আকার উল্লেখযোগ্যভাবে হ্রাস পেয়েছে।

বান্ডিলের আকার হ্রাস 30.1 কেবি

সমর্থিত ব্রাউজারগুলির তালিকা সংকীর্ণ করা

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

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

আনার বান্ডিলের বিশদটি একবার দেখুন।

30.0 কেবি এর বান্ডিল আকার

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

<স্ক্রিপ্ট টাইপ = "মডিউল"> ব্যবহার করুন

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

জাভাস্ক্রিপ্ট মডিউলগুলি সমস্ত বড় ব্রাউজারগুলিতে সমর্থিত একটি তুলনামূলকভাবে নতুন বৈশিষ্ট্য। অন্যান্য মডিউলগুলি থেকে আমদানি ও রফতানি করে এমন স্ক্রিপ্টগুলি সংজ্ঞায়িত করতে একটি 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>

অনেকগুলি নতুন ইসমাস্ক্রিপ্ট বৈশিষ্ট্য ইতিমধ্যে এমন পরিবেশে সমর্থিত যা জাভাস্ক্রিপ্ট মডিউলগুলিকে সমর্থন করে (ব্যাবেল প্রয়োজনের পরিবর্তে)) এর অর্থ হ'ল ব্রাউজারে আপনার অ্যাপ্লিকেশনটির দুটি পৃথক সংস্করণ প্রেরণে বাবেল কনফিগারেশনটি সংশোধন করা যেতে পারে:

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

বাবেল সহ ইএস মডিউল ব্যবহার করে

অ্যাপ্লিকেশনটির দুটি সংস্করণের জন্য পৃথক @babel/preset-env সেটিংস থাকতে, .babelrc ফাইলটি সরান। অ্যাপ্লিকেশনটির প্রতিটি সংস্করণের জন্য দুটি পৃথক সংকলন ফর্ম্যাট নির্দিষ্ট করে ওয়েবপ্যাক কনফিগারেশনে বাবেল সেটিংস যুক্ত করা যেতে পারে।

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 ব্যবহার করা হয়। এর অর্থ হ'ল বাবেল প্রতিটি ব্রাউজারকে লক্ষ্য করার জন্য প্রয়োজনীয় সমস্ত ট্রান্সফর্ম এবং পলিফিল অন্তর্ভুক্ত করে যা এখনও ইএস মডিউলগুলিকে সমর্থন করে না।

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 মানটি এখানে সত্যে সেট করা হয়েছে যার অর্থ এই যে এই মডিউলটিতে আউটপুট করা কোডটি একটি ছোট, কম সংকলিত স্ক্রিপ্ট যা এই উদাহরণে কোনও রূপান্তরকরণের মধ্য দিয়ে যায় না কারণ ব্যবহৃত সমস্ত বৈশিষ্ট্য ইতিমধ্যে ব্রাউজারগুলিতে সমর্থিত যা মডিউলগুলিকে সমর্থন করে।

ফাইলের একেবারে শেষে, একক অ্যারে উভয় কনফিগারেশন রফতানি করুন।

module.exports = [
  legacyConfig, moduleConfig
];

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

মডিউলগুলি সমর্থন করে এমন ব্রাউজারগুলি nomodule বৈশিষ্ট্য সহ স্ক্রিপ্টগুলিকে উপেক্ষা করে। বিপরীতে, মডিউলগুলি সমর্থন করে না এমন ব্রাউজারগুলি type="module" সহ স্ক্রিপ্ট উপাদানগুলিকে উপেক্ষা করে। এর অর্থ আপনি একটি মডিউল পাশাপাশি সংকলিত ফ্যালব্যাক অন্তর্ভুক্ত করতে পারেন। আদর্শভাবে, অ্যাপ্লিকেশনটির দুটি সংস্করণ index.html হওয়া উচিত 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 একেবারে শীর্ষে আমদানি করুন:

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 বৈশিষ্ট্য।

এইচটিএমএল ডকুমেন্টে মডিউলগুলি পরিবেশন করা হচ্ছে

শেষ কাজটি করা দরকার যা হ'ল এইচটিএমএল ফাইলটিতে উত্তরাধিকার এবং আধুনিক স্ক্রিপ্ট উভয় উপাদানকে আউটপুট করা। দুর্ভাগ্যক্রমে, প্লাগইন যা চূড়ান্ত এইচটিএমএল ফাইল তৈরি করে, HTMLWebpackPlugin , বর্তমানে মডিউল এবং নামকরণ স্ক্রিপ্ট উভয়ের আউটপুটকে সমর্থন করে না । Although there are workarounds and separate plugins created to solve this problem, such as BabelMultiTargetPlugin and HTMLWebpackMultiBuildPlugin , a simpler approach of adding the module script element manually is used for the purpose of this tutorial.

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

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

এখন ব্রাউজারে অ্যাপ্লিকেশনটি লোড করুন যা মডিউলগুলিকে সমর্থন করে, যেমন ক্রোমের সর্বশেষতম সংস্করণ।

5.2 কেবি মডিউলটি নতুন ব্রাউজারগুলির জন্য নেটওয়ার্কের উপরে আনা হয়েছে

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

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

30 কেবি স্ক্রিপ্ট পুরানো ব্রাউজারগুলির জন্য আনা হয়েছে

উপসংহার

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