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

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

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

از نسخه سازی بسته نرم افزاری و هدرهای کش استفاده کنید

روش رایج انجام ذخیره سازی به این صورت است:

  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>
    

این رویکرد به مرورگر می‌گوید که فایل 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'
      }
    };
    

    وقتی وب‌پک برنامه را می‌سازد، [name] را با نام یک تکه جایگزین می‌کند. اگر قسمت [name] را اضافه نکنیم، باید بین تکه‌ها بر اساس هش آن‌ها تفاوت قائل شویم – که بسیار سخت است!

  2. فیلد entry را به یک شی تبدیل کنید:

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

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

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

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

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

    این گزینه تقسیم کد هوشمند را فعال می کند. با استفاده از آن، وب‌پک کد فروشنده را در صورتی که از 30 کیلوبایت بزرگتر شود (قبل از کوچک‌سازی و 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). در مورد بسته وب 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";

Webpack این زمان اجرا را در آخرین قطعه تولید شده، که در مورد ما 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 اهمیت کمتری دارد، اما ممکن است باز هم تأثیر بگذارد).

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

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

با وب پک 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>
        …
      `);
    });
    

کد Lazy-load که در حال حاضر به آن نیاز ندارید

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

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

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

یک صفحه اصلی 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() در داخل بسته استفاده می شوند. شما معمولاً شناسه ها را در خروجی ساخت درست قبل از مسیرهای ماژول می بینید:

$ 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

به‌طور پیش‌فرض، شناسه‌ها با استفاده از یک شمارنده محاسبه می‌شوند (یعنی ماژول اول دارای ID 0، ماژول دوم دارای ID 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 دارای شناسه 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

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

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

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

در ادامه مطلب

جمع بندی

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