দীর্ঘমেয়াদী ক্যাশে ব্যবহার করুন

কিভাবে ওয়েবপ্যাক সম্পদ ক্যাশে সাহায্য করে

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

বান্ডিল সংস্করণ এবং ক্যাশে হেডার ব্যবহার করুন

ক্যাশে করার সাধারণ পদ্ধতি হল:

  1. ব্রাউজারকে একটি ফাইলকে খুব দীর্ঘ সময়ের জন্য ক্যাশে করতে বলুন (যেমন, এক বছর):

    # Server header
    Cache-Control: max-age=31536000
    

    Cache-Control কী করে তা আপনি যদি পরিচিত না হন তবে ক্যাশে করার সেরা অনুশীলনের উপর জ্যাক আর্চিবল্ডের চমৎকার পোস্টটি দেখুন।

  2. এবং পুনরায় ডাউনলোড করতে বাধ্য করার জন্য ফাইলটির নাম পরিবর্তন করুন:

    <!-- Before the change -->
    <script src="./index-v15.js"></script>
    
    <!-- After the change -->
    <script src="./index-v16.js"></script>
    

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

ওয়েবপ্যাকের সাথে, আপনি একই কাজ করেন, তবে সংস্করণ নম্বরের পরিবর্তে, আপনি ফাইল হ্যাশ উল্লেখ করেন। ফাইলের নামের মধ্যে হ্যাশ অন্তর্ভুক্ত করতে, [chunkhash] ব্যবহার করুন:

// webpack.config.js
module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.[chunkhash].js' // → bundle.8e0d62a03.js
  }
};

ক্লায়েন্টকে পাঠাতে আপনার যদি ফাইলের নাম প্রয়োজন হয়, তাহলে HtmlWebpackPlugin বা WebpackManifestPlugin ব্যবহার করুন।

HtmlWebpackPlugin একটি সহজ, কিন্তু কম নমনীয় পদ্ধতি। সংকলনের সময়, এই প্লাগইনটি একটি এইচটিএমএল ফাইল তৈরি করে যাতে সমস্ত সংকলিত সংস্থান অন্তর্ভুক্ত থাকে। যদি আপনার সার্ভার যুক্তি জটিল না হয়, তাহলে এটি আপনার জন্য যথেষ্ট হওয়া উচিত:

<!-- index.html -->
<!DOCTYPE html>
<!-- ... -->
<script src="bundle.8e0d62a03.js"></script>

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

// manifest.json
{
  "bundle.js": "bundle.8e0d62a03.js"
}

আরও পড়া

একটি পৃথক ফাইলে নির্ভরতা এবং রানটাইম বের করুন

নির্ভরতা

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

একটি পৃথক খণ্ডে নির্ভরতা নিষ্কাশন করতে, তিনটি ধাপ সম্পাদন করুন:

  1. [name].[chunkname].js দিয়ে আউটপুট ফাইলের নাম প্রতিস্থাপন করুন :

    // webpack.config.js
    module.exports = {
      output: {
        // Before
        filename: 'bundle.[chunkhash].js',
        // After
        filename: '[name].[chunkhash].js'
      }
    };
    

    যখন ওয়েবপ্যাক অ্যাপটি তৈরি করে, এটি [name] একটি খণ্ডের নামের সাথে প্রতিস্থাপন করে। যদি আমরা [name] অংশ যোগ না করি, তাহলে আমাদের খণ্ডগুলির মধ্যে তাদের হ্যাশ দ্বারা পার্থক্য করতে হবে - যা বেশ কঠিন!

  2. entry ক্ষেত্রটিকে একটি বস্তুতে রূপান্তর করুন:

    // webpack.config.js
    module.exports = {
      // Before
      entry: './index.js',
      // After
      entry: {
        main: './index.js'
      }
    };
    

    এই স্নিপেটে, "প্রধান" একটি খণ্ডের নাম। এই নামটি ধাপ 1 থেকে [name] এর জায়গায় প্রতিস্থাপিত হবে।

    এখন পর্যন্ত, আপনি যদি অ্যাপটি তৈরি করেন, তাহলে এই অংশে পুরো অ্যাপ কোড অন্তর্ভুক্ত থাকবে – ঠিক যেমন আমরা এই পদক্ষেপগুলি করিনি। কিন্তু এটি এক সেকেন্ডে বদলে যাবে।

  3. ওয়েবপ্যাক 4 এ , আপনার ওয়েবপ্যাক কনফিগারেশনে optimization.splitChunks.chunks: 'all' বিকল্প যোগ করুন:

    // webpack.config.js (for webpack 4)
    module.exports = {
      optimization: {
        splitChunks: {
          chunks: 'all'
        }
      }
    };
    

    এই বিকল্পটি স্মার্ট কোড বিভাজন সক্ষম করে। এটির সাহায্যে, ওয়েবপ্যাক 30 kB (মিনিফিকেশন এবং gzip-এর আগে) থেকে বড় হলে ভেন্ডর কোড বের করবে। এটি সাধারণ কোডটিও বের করবে – যদি আপনার বিল্ড বেশ কয়েকটি বান্ডিল তৈরি করে (যেমন যদি আপনি আপনার অ্যাপকে রুটে বিভক্ত করেন ) তাহলে এটি কার্যকর।

    ওয়েবপ্যাক 3 এ , CommonsChunkPlugin যোগ করুন:

    // webpack.config.js (for webpack 3)
    module.exports = {
      plugins: [
        new webpack.optimize.CommonsChunkPlugin({
        // A name of the chunk that will include the dependencies.
        // This name is substituted in place of [name] from step 1
        name: 'vendor',
    
        // A function that determines which modules to include into this chunk
        minChunks: module => module.context && module.context.includes('node_modules'),
        })
      ]
    };
    

    এই প্লাগইনটি সমস্ত মডিউল নেয় যা node_modules অন্তর্ভুক্ত করে এবং সেগুলিকে vendor.[chunkhash].js নামে একটি পৃথক ফাইলে নিয়ে যায়।

এই পরিবর্তনের পরে, প্রতিটি বিল্ড একটির পরিবর্তে দুটি ফাইল তৈরি করবে: main.[chunkhash].js vendor.[chunkhash].js vendors~main.[chunkhash].js ওয়েবপ্যাক 4 এর ক্ষেত্রে, নির্ভরতা ছোট হলে ভেন্ডর বান্ডেল তৈরি নাও হতে পারে - এবং এটি ঠিক আছে:

$ webpack
Hash: ac01483e8fec1fa70676
Version: webpack 3.8.1
Time: 3816ms
                        Asset      Size  Chunks             Chunk Names
 ./main.00bab6fd3100008a42b0.js   82 kB       0  [emitted]  main
./vendor.d9e134771799ecdf9483.js  47 kB       1  [emitted]  vendor

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

ওয়েবপ্যাক রানটাইম কোড

দুর্ভাগ্যবশত, শুধুমাত্র বিক্রেতা কোড নিষ্কাশন যথেষ্ট নয়। আপনি যদি অ্যাপ কোডে কিছু পরিবর্তন করার চেষ্টা করেন:

// index.js
…
…

// E.g. add this:
console.log('Wat');

আপনি লক্ষ্য করবেন যে vendor হ্যাশও পরিবর্তিত হয়:

                           Asset   Size  Chunks             Chunk Names
./vendor.d9e134771799ecdf9483.js  47 kB       1  [emitted]  vendor

                            Asset   Size  Chunks             Chunk Names
./vendor.e6ea4504d61a1cc1c60b.js  47 kB       1  [emitted]  vendor

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

// vendor.e6ea4504d61a1cc1c60b.js
script.src = __webpack_require__.p + chunkId + "." + {
    "0": "2f2269c7f0a55a5c1871"
}[chunkId] + ".js";

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

এটি সমাধান করার জন্য, রানটাইমটিকে একটি পৃথক ফাইলে স্থানান্তর করা যাক। ওয়েবপ্যাক 4-এ, optimization.runtimeChunk বিকল্প সক্রিয় করে এটি অর্জন করা হয়:

// webpack.config.js (for webpack 4)
module.exports = {
  optimization: {
    runtimeChunk: true
  }
};

ওয়েবপ্যাক 3 এ, CommonsChunkPlugin এর সাথে একটি অতিরিক্ত খালি খণ্ড তৈরি করে এটি করুন:

// webpack.config.js (for webpack 3)
module.exports = {
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: module => module.context && module.context.includes('node_modules')
    }),
    // This plugin must come after the vendor one (because webpack
    // includes runtime into the last chunk)
    new webpack.optimize.CommonsChunkPlugin({
      name: 'runtime',
      // minChunks: Infinity means that no app modules
      // will be included into this chunk
      minChunks: Infinity
    })
  ]
};

এই পরিবর্তনের পরে, প্রতিটি বিল্ড তিনটি ফাইল তৈরি করবে:

$ webpack
Hash: ac01483e8fec1fa70676
Version: webpack 3.8.1
Time: 3816ms
                            Asset     Size  Chunks             Chunk Names
   ./main.00bab6fd3100008a42b0.js    82 kB       0  [emitted]  main
 ./vendor.26886caf15818fa82dfa.js    46 kB       1  [emitted]  vendor
./runtime.79f17c27b335abc7aaf4.js  1.45 kB       3  [emitted]  runtime

বিপরীত ক্রমে index.html এ তাদের অন্তর্ভুক্ত করুন - এবং আপনি সম্পন্ন করেছেন:

<!-- index.html -->
<script src="./runtime.79f17c27b335abc7aaf4.js"></script>
<script src="./vendor.26886caf15818fa82dfa.js"></script>
<script src="./main.00bab6fd3100008a42b0.js"></script>

আরও পড়া

একটি অতিরিক্ত HTTP অনুরোধ সংরক্ষণ করতে ইনলাইন ওয়েবপ্যাক রানটাইম

জিনিসগুলিকে আরও ভাল করতে, HTML প্রতিক্রিয়াতে ওয়েবপ্যাক রানটাইম ইনলাইন করার চেষ্টা করুন৷ অর্থাৎ, এর পরিবর্তে:

<!-- index.html -->
<script src="./runtime.79f17c27b335abc7aaf4.js"></script>

এটা কর:

<!-- index.html -->
<script>
!function(e){function n(r){if(t[r])return t[r].exports;…}} ([]);
</script>

রানটাইম ছোট, এবং এটি ইনলাইন করা আপনাকে একটি HTTP অনুরোধ সংরক্ষণ করতে সাহায্য করবে (HTTP/1 এর সাথে বেশ গুরুত্বপূর্ণ; HTTP/2 এর সাথে কম গুরুত্বপূর্ণ কিন্তু এখনও একটি প্রভাব ফেলতে পারে)।

এখানে এটা কিভাবে করতে হয়.

আপনি যদি HtmlWebpackPlugin দিয়ে HTML তৈরি করেন

আপনি যদি একটি HTML ফাইল তৈরি করতে HtmlWebpackPlugin ব্যবহার করেন, তাহলে আপনার যা দরকার তা হল InlineSourcePlugin :

const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineSourcePlugin = require('html-webpack-inline-source-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      inlineSource: 'runtime~.+\\.js',
    }),
    new InlineSourcePlugin()
  ]
};

আপনি যদি একটি কাস্টম সার্ভার লজিক ব্যবহার করে HTML তৈরি করেন

ওয়েবপ্যাক 4 সহ:

  1. রানটাইম খণ্ডের জেনারেট করা নাম জানতে WebpackManifestPlugin যোগ করুন:

    // webpack.config.js (for webpack 4)
    const ManifestPlugin = require('webpack-manifest-plugin');
    
    module.exports = {
      plugins: [
        new ManifestPlugin()
      ]
    };
    

    এই প্লাগইনের সাথে একটি বিল্ড একটি ফাইল তৈরি করবে যা এইরকম দেখায়:

    // manifest.json
    {
      "runtime~main.js": "runtime~main.8e0d62a03.js"
    }
    
  2. রানটাইম খণ্ডের বিষয়বস্তু একটি সুবিধাজনক উপায়ে ইনলাইন করুন। যেমন Node.js এবং Express সহ:

    // server.js
    const fs = require('fs');
    const manifest = require('./manifest.json');
    const runtimeContent = fs.readFileSync(manifest['runtime~main.js'], 'utf-8');
    
    app.get('/', (req, res) => {
      res.send(`
        …
        <script>${runtimeContent}</script>
        …
      `);
    });
    

অথবা ওয়েবপ্যাক 3 সহ:

  1. filename উল্লেখ করে রানটাইম নামটিকে স্ট্যাটিক করুন:

    module.exports = {
      plugins: [
        new webpack.optimize.CommonsChunkPlugin({
          name: 'runtime',
          minChunks: Infinity,
          filename: 'runtime.js'
        })
      ]
    };
    
  2. একটি সুবিধাজনক উপায়ে runtime.js বিষয়বস্তু ইনলাইন করুন। যেমন Node.js এবং Express সহ:

    // server.js
    const fs = require('fs');
    const runtimeContent = fs.readFileSync('./runtime.js', 'utf-8');
    
    app.get('/', (req, res) => {
      res.send(`
        …
        <script>${runtimeContent}</script>
        …
      `);
    });
    

অলস-লোড কোড যা আপনার এখন প্রয়োজন নেই

কখনও কখনও, একটি পৃষ্ঠায় কম বেশি গুরুত্বপূর্ণ অংশ থাকে:

  • আপনি যদি YouTube-এ একটি ভিডিও পৃষ্ঠা লোড করেন, তাহলে আপনি মন্তব্যের চেয়ে ভিডিওটির বিষয়ে বেশি যত্নশীল। এখানে, ভিডিওটি মন্তব্যের চেয়ে বেশি গুরুত্বপূর্ণ।
  • আপনি যদি একটি সংবাদ সাইটে একটি নিবন্ধ খোলেন, আপনি বিজ্ঞাপনের চেয়ে নিবন্ধটির পাঠ্যের প্রতি বেশি যত্নশীল হন। এখানে, বিজ্ঞাপনের চেয়ে পাঠ্যটি বেশি গুরুত্বপূর্ণ।

এই ধরনের ক্ষেত্রে, শুধুমাত্র সবচেয়ে গুরুত্বপূর্ণ জিনিসগুলি প্রথমে ডাউনলোড করে এবং পরে বাকি অংশগুলি অলসভাবে লোড করার মাধ্যমে প্রাথমিক লোডিং কর্মক্ষমতা উন্নত করুন৷ এর জন্য import() ফাংশন এবং কোড-বিভাজন ব্যবহার করুন:

// videoPlayer.js
export function renderVideoPlayer() { … }

// comments.js
export function renderComments() { … }

// index.js
import {renderVideoPlayer} from './videoPlayer';
renderVideoPlayer();

// …Custom event listener
onShowCommentsClick(() => {
  import('./comments').then((comments) => {
    comments.renderComments();
  });
});

import() নির্দিষ্ট করে যে আপনি গতিশীলভাবে একটি নির্দিষ্ট মডিউল লোড করতে চান। যখন ওয়েবপ্যাক import('./module.js') দেখে, এটি এই মডিউলটিকে একটি পৃথক খণ্ডে নিয়ে যায়:

$ webpack
Hash: 39b2a53cb4e73f0dc5b2
Version: webpack 3.8.1
Time: 4273ms
                            Asset     Size  Chunks             Chunk Names
      ./0.8ecaf182f5c85b7a8199.js  22.5 kB       0  [emitted]
   ./main.f7e53d8e13e9a2745d6d.js    60 kB       1  [emitted]  main
 ./vendor.4f14b6326a80f4752a98.js    46 kB       2  [emitted]  vendor
./runtime.79f17c27b335abc7aaf4.js  1.45 kB       3  [emitted]  runtime

এবং শুধুমাত্র তখনই ডাউনলোড করে যখন এক্সিকিউশন import() ফাংশনে পৌঁছায়।

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

আরও পড়া

কোডটিকে রুট এবং পৃষ্ঠাগুলিতে বিভক্ত করুন

যদি আপনার অ্যাপের একাধিক রুট বা পৃষ্ঠা থাকে, কিন্তু কোড সহ শুধুমাত্র একটি একক JS ফাইল থাকে (একটি main অংশ), তাহলে সম্ভবত আপনি প্রতিটি অনুরোধে অতিরিক্ত বাইট পরিবেশন করছেন। উদাহরণস্বরূপ, যখন একজন ব্যবহারকারী আপনার সাইটের হোম পেজে যান:

একটি WebFundamentals হোম পেজ

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

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

একক-পৃষ্ঠার অ্যাপের জন্য

রুট অনুসারে একক-পৃষ্ঠার অ্যাপগুলিকে বিভক্ত করতে, import() ব্যবহার করুন ( "অলস-লোড কোড যা আপনার এখন প্রয়োজন নেই" বিভাগটি দেখুন)। আপনি যদি একটি ফ্রেমওয়ার্ক ব্যবহার করেন তবে এটির জন্য একটি বিদ্যমান সমাধান থাকতে পারে:

ঐতিহ্যগত মাল্টি-পৃষ্ঠা অ্যাপের জন্য

পৃষ্ঠাগুলির দ্বারা ঐতিহ্যগত অ্যাপগুলিকে বিভক্ত করতে, ওয়েবপ্যাকের এন্ট্রি পয়েন্টগুলি ব্যবহার করুন৷ আপনার অ্যাপে যদি তিন ধরনের পেজ থাকে: হোম পেজ, আর্টিকেল পেজ এবং ইউজার অ্যাকাউন্ট পেজ, - এতে তিনটি এন্ট্রি থাকতে হবে:

// webpack.config.js
module.exports = {
  entry: {
    home: './src/Home/index.js',
    article: './src/Article/index.js',
    profile: './src/Profile/index.js'
  }
};

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

$ webpack
Hash: 318d7b8490a7382bf23b
Version: webpack 3.8.1
Time: 4273ms
                            Asset     Size  Chunks             Chunk Names
      ./0.8ecaf182f5c85b7a8199.js  22.5 kB       0  [emitted]
   ./home.91b9ed27366fe7e33d6a.js    18 kB       1  [emitted]  home
./article.87a128755b16ac3294fd.js    32 kB       2  [emitted]  article
./profile.de945dc02685f6166781.js    24 kB       3  [emitted]  profile
 ./vendor.4f14b6326a80f4752a98.js    46 kB       4  [emitted]  vendor
./runtime.318d7b8490a7382bf23b.js  1.45 kB       5  [emitted]  runtime

সুতরাং, যদি শুধুমাত্র নিবন্ধের পৃষ্ঠাটি Lodash ব্যবহার করে, তবে home এবং profile বান্ডেলগুলি এটিকে অন্তর্ভুক্ত করবে না - এবং হোম পেজে যাওয়ার সময় ব্যবহারকারীকে এই লাইব্রেরিটি ডাউনলোড করতে হবে না।

পৃথক নির্ভরতা গাছের যদিও তাদের ত্রুটি আছে। যদি দুটি এন্ট্রি পয়েন্ট Lodash ব্যবহার করে, এবং আপনি আপনার নির্ভরতাগুলিকে একটি বিক্রেতার বান্ডেলে স্থানান্তরিত না করেন, উভয় এন্ট্রি পয়েন্টে Lodash-এর একটি অনুলিপি অন্তর্ভুক্ত থাকবে। এটি সমাধান করার জন্য, ওয়েবপ্যাক 4-এ, আপনার ওয়েবপ্যাক কনফিগারে optimization.splitChunks.chunks: 'all' বিকল্পটি যোগ করুন:

// webpack.config.js (for webpack 4)
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
};

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

অথবা, ওয়েবপ্যাক 3-এ, CommonsChunkPlugin ব্যবহার করুন - এটি সাধারণ নির্ভরতাগুলিকে একটি নতুন নির্দিষ্ট ফাইলে স্থানান্তরিত করবে:

module.exports = {
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common',
      minChunks: 2    // 2 is the default value
    })
  ]
};

সেরা একটি খুঁজে পেতে minChunks মান সঙ্গে খেলতে নির্দ্বিধায়. সাধারণত, আপনি এটি ছোট রাখতে চান, তবে খণ্ডের সংখ্যা বাড়লে বৃদ্ধি করুন। উদাহরণস্বরূপ, 3টি খণ্ডের জন্য, minChunks 2 হতে পারে, কিন্তু 30টি খণ্ডের জন্য, এটি 8 হতে পারে – কারণ আপনি যদি এটি 2 এ রাখেন তবে অনেকগুলি মডিউল সাধারণ ফাইলে প্রবেশ করবে, এটিকে খুব বেশি স্ফীত করবে।

আরও পড়া

মডিউল আইডি আরও স্থিতিশীল করুন

কোড তৈরি করার সময়, ওয়েবপ্যাক প্রতিটি মডিউলকে একটি আইডি বরাদ্দ করে। পরবর্তীতে, এই আইডিগুলি বান্ডেলের ভিতরে require() s ব্যবহার করা হয়। আপনি সাধারণত মডিউল পাথের ঠিক আগে বিল্ড আউটপুটে আইডি দেখতে পান:

$ webpack
Hash: df3474e4f76528e3bbc9
Version: webpack 3.8.1
Time: 2150ms
                           Asset      Size  Chunks             Chunk Names
      ./0.8ecaf182f5c85b7a8199.js  22.5 kB       0  [emitted]
   ./main.4e50a16675574df6a9e9.js    60 kB       1  [emitted]  main
 ./vendor.26886caf15818fa82dfa.js    46 kB       2  [emitted]  vendor
./runtime.79f17c27b335abc7aaf4.js  1.45 kB       3  [emitted]  runtime

↓ এখানে

[0] ./index.js 29 kB {1} [built]
[2] (webpack)/buildin/global.js 488 bytes {2} [built]
[3] (webpack)/buildin/module.js 495 bytes {2} [built]
[4] ./comments.js 58 kB {0} [built]
[5] ./ads.js 74 kB {1} [built]
+ 1 hidden module

ডিফল্টরূপে, আইডিগুলি একটি কাউন্টার ব্যবহার করে গণনা করা হয় (যেমন প্রথম মডিউলটির আইডি 0, দ্বিতীয়টির আইডি 1 এবং আরও অনেক কিছু)। এর সাথে সমস্যা হল যে আপনি যখন একটি নতুন মডিউল যোগ করেন, তখন এটি মডিউল তালিকার মাঝখানে উপস্থিত হতে পারে, পরবর্তী সমস্ত মডিউলের আইডি পরিবর্তন করে:

$ webpack
Hash: df3474e4f76528e3bbc9
Version: webpack 3.8.1
Time: 2150ms
                           Asset      Size  Chunks             Chunk Names
      ./0.5c82c0f337fcb22672b5.js    22 kB       0  [emitted]
   ./main.0c8b617dfc40c2827ae3.js    82 kB       1  [emitted]  main
 ./vendor.26886caf15818fa82dfa.js    46 kB       2  [emitted]  vendor
./runtime.79f17c27b335abc7aaf4.js  1.45 kB       3  [emitted]  runtime
   [0] ./index.js 29 kB {1} [built]
   [2] (webpack)/buildin/global.js 488 bytes {2} [built]
   [3] (webpack)/buildin/module.js 495 bytes {2} [built]

↓ আমরা একটি নতুন মডিউল যোগ করেছি...

[4] ./webPlayer.js 24 kB {1} [built]

↓ এবং দেখুন এটা কি করেছে! comments.js এখন 4 এর পরিবর্তে আইডি 5 আছে

[5] ./comments.js 58 kB {0} [built]

ads.js এখন 5-এর পরিবর্তে ID 6 আছে

[6] ./ads.js 74 kB {1} [built]
       + 1 hidden module

এটি পরিবর্তিত আইডি সহ মডিউলগুলি অন্তর্ভুক্ত বা নির্ভর করে এমন সমস্ত অংশগুলিকে বাতিল করে – এমনকি তাদের প্রকৃত কোড পরিবর্তিত না হলেও৷ আমাদের ক্ষেত্রে, 0 খণ্ড ( comments.js সহ খণ্ড) এবং main খণ্ড (অন্য অ্যাপ কোড সহ খণ্ড) অবৈধ হয়ে যায় - যেখানে শুধুমাত্র main হওয়া উচিত ছিল।

এটি সমাধান করতে, HashedModuleIdsPlugin ব্যবহার করে কীভাবে মডিউল আইডি গণনা করা হয় তা পরিবর্তন করুন। এটি কাউন্টার-ভিত্তিক আইডিগুলিকে মডিউল পাথের হ্যাশগুলির সাথে প্রতিস্থাপন করে:

$ webpack
Hash: df3474e4f76528e3bbc9
Version: webpack 3.8.1
Time: 2150ms
                           Asset      Size  Chunks             Chunk Names
      ./0.6168aaac8461862eab7a.js  22.5 kB       0  [emitted]
   ./main.a2e49a279552980e3b91.js    60 kB       1  [emitted]  main
 ./vendor.ff9f7ea865884e6a84c8.js    46 kB       2  [emitted]  vendor
./runtime.25f5d0204e4f77fa57a1.js  1.45 kB       3  [emitted]  runtime

↓ এখানে

[3IRH] ./index.js 29 kB {1} [built]
[DuR2] (webpack)/buildin/global.js 488 bytes {2} [built]
[JkW7] (webpack)/buildin/module.js 495 bytes {2} [built]
[LbCc] ./webPlayer.js 24 kB {1} [built]
[lebJ] ./comments.js 58 kB {0} [built]
[02Tr] ./ads.js 74 kB {1} [built]
    + 1 hidden module

এই পদ্ধতির সাথে, একটি মডিউলের ID শুধুমাত্র পরিবর্তন হয় যদি আপনি সেই মডিউলটির নাম পরিবর্তন করেন বা সরান। নতুন মডিউলগুলি অন্যান্য মডিউলের আইডিগুলিকে প্রভাবিত করবে না।

প্লাগইন সক্ষম করতে, এটি কনফিগারেশনের plugins বিভাগে যোগ করুন:

// webpack.config.js
module.exports = {
  plugins: [
    new webpack.HashedModuleIdsPlugin()
  ]
};

আরও পড়া

সাতরে যাও

  • বান্ডিলটি ক্যাশে করুন এবং বান্ডিলের নাম পরিবর্তন করে সংস্করণগুলির মধ্যে পার্থক্য করুন
  • বান্ডেলটিকে অ্যাপ কোড, ভেন্ডর কোড এবং রানটাইমে বিভক্ত করুন
  • একটি HTTP অনুরোধ সংরক্ষণ করতে রানটাইম ইনলাইন করুন
  • অলস-লোড import সহ অ-গুরুত্বপূর্ণ কোড
  • অপ্রয়োজনীয় জিনিস লোড করা এড়াতে রুট/পৃষ্ঠা দ্বারা কোড বিভক্ত করুন