از کش طولانی مدت استفاده کنید

چگونه وب‌پک به ذخیره‌سازی دارایی‌ها کمک می‌کند

نکته بعدی (بعد از بهینه‌سازی حجم برنامه که زمان بارگذاری برنامه را بهبود می‌بخشد) ذخیره‌سازی موقت (caching) است. از آن برای نگه‌داشتن بخش‌هایی از برنامه روی کلاینت و جلوگیری از دانلود مجدد آنها در هر بار استفاده کنید.

از نسخه‌بندی بسته و هدرهای حافظه پنهان استفاده کنید

رویکرد رایج برای انجام ذخیره‌سازی موقت (caching) به شرح زیر است:

  1. به مرورگر بگویید که یک فایل را برای مدت زمان بسیار طولانی (مثلاً یک سال) ذخیره کند:

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

    اگر با عملکرد Cache-Control آشنا نیستید، به پست عالی Jake Archibald در مورد بهترین شیوه‌های ذخیره‌سازی مراجعه کنید.

  2. و وقتی فایل تغییر نام داد، آن را تغییر نام دهید تا مجبور به دانلود مجدد شود:

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

این رویکرد به مرورگر می‌گوید که فایل JS را دانلود کند، آن را ذخیره کند و از نسخه ذخیره شده استفاده کند. مرورگر فقط در صورتی که نام فایل تغییر کند (یا یک سال بگذرد) به شبکه متصل می‌شود.

با webpack، شما همین کار را انجام می‌دهید، اما به جای شماره نسخه، هش فایل را مشخص می‌کنید. برای گنجاندن هش در نام فایل، از [chunkhash] استفاده کنید:

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

اگر به نام فایل برای ارسال به کلاینت نیاز دارید، از HtmlWebpackPlugin یا WebpackManifestPlugin استفاده کنید.

افزونه HtmlWebpackPlugin یک رویکرد ساده اما با انعطاف‌پذیری کمتر است. در طول کامپایل، این افزونه یک فایل HTML تولید می‌کند که شامل تمام منابع کامپایل شده است. اگر منطق سرور شما پیچیده نیست، پس باید برای شما کافی باشد:

<!-- 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'
      }
    };
    

    وقتی webpack برنامه را می‌سازد، [name] را با نام یک قطعه کد جایگزین می‌کند. اگر قسمت [name] را اضافه نکنیم، باید قطعات کد را بر اساس هش آنها از هم تشخیص دهیم - که کار بسیار سختی است!

  2. تبدیل فیلد entry به یک شیء:

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

    در این قطعه کد، "main" نام یک تکه است. این نام به جای [name] از مرحله 1 جایگزین خواهد شد.

    تا الان، اگر برنامه را بسازید، این بخش شامل کل کد برنامه خواهد بود - درست مثل اینکه ما این مراحل را انجام نداده‌ایم. اما این موضوع در عرض یک ثانیه تغییر خواهد کرد.

  3. در webpack 4 ، گزینه optimization.splitChunks.chunks: 'all' را به پیکربندی webpack خود اضافه کنید:

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

    این گزینه امکان تقسیم هوشمند کد را فراهم می‌کند. با استفاده از آن، وب‌پک اگر کد فروشنده (vendor code) بزرگتر از 30 کیلوبایت شود (قبل از فشرده‌سازی و gzip)، آن را استخراج می‌کند. همچنین کد مشترک را استخراج می‌کند - این قابلیت در صورتی که ساخت شما چندین بسته (bundle) تولید کند (مثلاً اگر برنامه خود را به مسیرها (routes) تقسیم کنید ) مفید است.

    در webpack 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 برای webpack 4). در مورد webpack 4، اگر وابستگی‌ها کوچک باشند، ممکن است بسته vendor ایجاد نشود - و این اشکالی ندارد:

$ 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 تغییر کند.

برای حل این مشکل، بیایید فایل زمان اجرا را به یک فایل جداگانه منتقل کنیم. در webpack 4، این کار با فعال کردن گزینه optimization.runtimeChunk انجام می‌شود:

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

در webpack 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 اضافی

برای اینکه اوضاع از این هم بهتر شود، سعی کنید زمان اجرای webpack را در پاسخ HTML به صورت inline وارد کنید. یعنی به جای این:

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

این کار را انجام دهید:

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

زمان اجرا کوتاه است و inline کردن آن به شما کمک می‌کند تا یک درخواست HTTP را ذخیره کنید (این مورد در HTTP/1 بسیار مهم است؛ در HTTP/2 اهمیت کمتری دارد، اما همچنان ممکن است مؤثر باشد).

در اینجا نحوه انجام آن آورده شده است.

اگر HTML را با HtmlWebpackPlugin تولید کنید

اگر از HtmlWebpackPlugin برای تولید یک فایل HTML استفاده می‌کنید، 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 را با استفاده از منطق سرور سفارشی تولید می‌کنید

با وب‌پک ۴:

  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>
        …
      `);
    });
    

یا با وب‌پک ۳:

  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>
        …
      `);
    });
    

کد بارگذاری تنبل که الان به آن نیاز ندارید

گاهی اوقات، یک صفحه بخش‌های کم‌اهمیت‌تر و بیشتری دارد:

  • اگر یک صفحه ویدیویی را در یوتیوب بارگذاری کنید، بیشتر به ویدیو اهمیت می‌دهید تا نظرات. در اینجا، ویدیو از نظرات مهم‌تر است.
  • اگر در یک سایت خبری مقاله‌ای را باز کنید، بیشتر به متن مقاله اهمیت می‌دهید تا تبلیغات. در اینجا، متن از تبلیغات مهم‌تر است.

در چنین مواردی، با دانلود فقط مهم‌ترین موارد در ابتدا و بارگذاری تدریجی بخش‌های باقی‌مانده در مراحل بعدی، عملکرد بارگذاری اولیه را بهبود بخشید. برای این کار از تابع 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() مشخص می‌کند که می‌خواهید یک ماژول خاص را به صورت پویا بارگذاری کنید. وقتی webpack 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 ) وجود دارد، احتمالاً در هر درخواست بایت‌های اضافی ارائه می‌دهید. به عنوان مثال، وقتی کاربری از صفحه اصلی سایت شما بازدید می‌کند:

صفحه اصلی وب فاندامنتالز

آنها نیازی به بارگذاری کد برای رندر کردن مقاله‌ای که در صفحه دیگری است ندارند - اما آن را بارگذاری می‌کنند. علاوه بر این، اگر کاربر همیشه فقط از صفحه اصلی بازدید کند و شما تغییری در کد مقاله ایجاد کنید، webpack کل بسته را نامعتبر می‌کند - و کاربر مجبور خواهد شد کل برنامه را دوباره دانلود کند.

اگر برنامه را به صفحات (یا مسیرها، اگر برنامه تک صفحه‌ای باشد) تقسیم کنیم، کاربر فقط کد مربوطه را دانلود می‌کند. به علاوه، مرورگر کد برنامه را بهتر ذخیره می‌کند: اگر کد صفحه اصلی را تغییر دهید، webpack فقط بخش مربوطه را نامعتبر می‌کند.

برای برنامه‌های تک صفحه‌ای

برای تقسیم برنامه‌های تک صفحه‌ای بر اساس مسیرها، از import() استفاده کنید (به بخش «کد بارگذاری تنبل که در حال حاضر به آن نیاز ندارید» مراجعه کنید). اگر از یک چارچوب استفاده می‌کنید، ممکن است یک راه‌حل موجود برای این کار داشته باشد:

برای برنامه‌های چند صفحه‌ای سنتی

برای تقسیم برنامه‌های سنتی بر اساس صفحات، از نقاط ورودی وب‌پک استفاده کنید. اگر برنامه شما سه نوع صفحه دارد: صفحه اصلی، صفحه مقاله و صفحه حساب کاربری، باید سه ورودی داشته باشد:

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

برای هر فایل ورودی، webpack یک درخت وابستگی جداگانه می‌سازد و یک بسته نرم‌افزاری تولید می‌کند که فقط شامل ماژول‌هایی است که توسط آن ورودی استفاده می‌شوند:

$ 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 خواهند بود. برای حل این مشکل، در webpack 4، گزینه optimization.splitChunks.chunks: 'all' را به پیکربندی webpack خود اضافه کنید:

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

این گزینه امکان تقسیم هوشمند کد را فراهم می‌کند. با این گزینه، وب‌پک به طور خودکار به دنبال کدهای مشترک می‌گردد و آنها را در فایل‌های جداگانه استخراج می‌کند.

یا در webpack 3، از CommonsChunkPlugin استفاده کنید - این افزونه وابستگی‌های رایج را به یک فایل مشخص شده جدید منتقل می‌کند:

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

می‌توانید با مقدار minChunks بازی کنید تا بهترین مقدار را پیدا کنید. به‌طورکلی، بهتر است آن را کوچک نگه دارید، اما اگر تعداد تکه‌ها افزایش یابد، آن را افزایش دهید. به‌عنوان‌مثال، برای ۳ تکه، minChunks ممکن است ۲ باشد، اما برای ۳۰ تکه، ممکن است ۸ باشد - زیرا اگر آن را روی ۲ نگه دارید، ماژول‌های زیادی وارد فایل مشترک می‌شوند و آن را بیش از حد بزرگ می‌کنند.

مطالعه بیشتر

شناسه‌های ماژول را پایدارتر کنید

هنگام ساخت کد، webpack به هر ماژول یک شناسه (ID) اختصاص می‌دهد. بعداً، این شناسه‌ها در require() ها درون بسته استفاده می‌شوند. معمولاً شناسه‌ها را در خروجی ساخت درست قبل از مسیرهای ماژول مشاهده می‌کنید:

$ 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

به طور پیش‌فرض، شناسه‌ها با استفاده از یک شمارنده محاسبه می‌شوند (یعنی اولین ماژول شناسه ۰، دومی شناسه ۱ و غیره دارد). مشکل این است که وقتی یک ماژول جدید اضافه می‌کنید، ممکن است در وسط لیست ماژول‌ها ظاهر شود و شناسه تمام ماژول‌های بعدی را تغییر دهد:

$ 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 اکنون به جای ۴، شناسه ۵ دارد.

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

↓ ads.js اکنون به جای ۵، شناسه ۶ دارد

[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

با این رویکرد، شناسه یک ماژول فقط در صورت تغییر نام یا جابجایی آن ماژول تغییر می‌کند. ماژول‌های جدید روی شناسه سایر ماژول‌ها تأثیری نخواهند گذاشت.

برای فعال کردن افزونه، آن را به بخش plugins پیکربندی اضافه کنید:

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

مطالعه بیشتر

جمع‌بندی

  • بسته را ذخیره کنید و با تغییر نام بسته، نسخه‌های مختلف را از هم متمایز کنید.
  • بسته را به کد برنامه، کد فروشنده و کد زمان اجرا تقسیم کنید
  • برای ذخیره درخواست HTTP، زمان اجرا را درون‌خطی کنید
  • بارگذاری تنبل کدهای غیر بحرانی با import
  • تقسیم کد بر اساس مسیرها/صفحات برای جلوگیری از بارگذاری موارد غیرضروری