الاستفادة من التخزين المؤقّت الطويل المدى

كيفية الاستفادة من webpack بشأن التخزين المؤقت لمادة العرض

الخطوة التالية (بعد تحسين حجم التطبيق الذي من تحسين وقت تحميل التطبيق في التخزين المؤقت. يمكنك استخدامه لإبقاء أجزاء من التطبيق على وتجنب إعادة تنزيلها في كل مرة.

استخدام إصدارات الحزمة وعناوين ذاكرة التخزين المؤقت

الطريقة الشائعة للتخزين المؤقت هي:

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

    كلمة "رئيسي" في هذا المقتطف عبارة عن اسم مقطع. سيتم استبدال هذا الاسم في مكان [name] من الخطوة 1.

    الآن، إذا أنشأت التطبيق، فسيتضمن هذا المقطع رمز التطبيق بالكامل - فقط كما لو أننا لم نفعل هذه الخطوات. لكن هذا سيتغير في غضون ثانية.

  3. في حزمة الويب 4، أضِف الخيار optimization.splitChunks.chunks: 'all'. في تهيئة webpack:

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

    يتيح هذا الخيار تقسيم الرموز الذكية. باستخدامها، ستقوم webpack باستخراج رمز البائع إذا فسيصبح أكبر من 30 كيلوبايت (قبل إجراء تصغير وملف gzip). كما أنّه يستخرج الرمز المشترك – ويكون هذا الأمر مفيدًا إذا أنتج تصميمك عدة حِزم (مثل في حال تقسيم تطبيقك إلى مسارات).

    في 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، قد لا يتم إنشاء حزمة البائع إذا كانت التبعيات صغيرة - ولا بأس بذلك:

$ 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

سيخزِّن المتصفح هذه الملفات مؤقتًا بشكل منفصل، وسيعيد تنزيل الرمز الذي تم تغييره فقط.

رمز بيئة تشغيل Webpack

ولا يكفي استخراج رمز المورّد فقط. إذا حاولت لتغيير شيء ما في رمز التطبيق:

// 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

ويحدث ذلك لأن حزمة webpack، بصرف النظر عن رمز الوحدات، تحتوي على وقت التشغيل: وهو جزء صغير من الرمز الذي يدير تنفيذ الوحدة. عند تقسيم الرمز إلى عدة ملفات، يبدأ هذا الجزء من التعليمة البرمجية بما في ذلك تعيين بين معرفات المقطع الملفات المقابلة:

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

تتضمّن حزمة Webpack بيئة التشغيل هذه في آخر مقطع تم إنشاؤه، وهو 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 إضافي

لتحسين الأمور، جرِّب تضمين وقت تشغيل حزمة الويب في ملف 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 باستخدام HtmlWebpackConnectionin

إذا كنت تستخدم 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 باستخدام منطق مخصّص للخادم

باستخدام Webpack 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>
        …
      `);
    });
    

أو باستخدام webpack 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() و code-splitting لهذا الغرض:

// 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')، وستنقل هذه الوحدة إلى وحدة تخزين منفصلة. chunk:

$ 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، ما يحسّن مدّة التحميل الأولية. والأكثر من ذلك، ستحسن التخزين المؤقت - إذا قمت بتغيير التعليمة البرمجية في المقطع الرئيسي، التعليقات لا يتأثر بها.

محتوى إضافي للقراءة

تقسيم الرمز إلى مسارات وصفحات

إذا كان تطبيقك يحتوي على مسارات أو صفحات متعددة، ولكن يتوفّر ملف JavaScript واحد فقط التعليمة البرمجية (مقطع 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 شجرة تبعية منفصلة وتنشئ حزمة تتضمّن فقط الوحدات المستخدَمة في هذا الإدخال:

$ 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.config.js (for webpack 4)
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
};

يتيح هذا الخيار تقسيم الرموز الذكية. باستخدام هذا الخيار، ستقوم webpack تلقائيًا البحث عن التعليمات البرمجية المشتركة واستخراجها إلى ملفات منفصلة.

أو في webpack 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، فسيتم إدراج عدد كبير جدًا من الوحدات في الملف الشائع، تضخيمها أكثر من اللازم.

محتوى إضافي للقراءة

جعل معرّفات الوحدات أكثر ثباتًا

عند إنشاء الرمز البرمجي، تُعيِّن حزمة webpack معرّفًا لكل وحدة. لاحقًا، أصبحت هذه المعرفات مستخدمة في 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

بشكل افتراضي، يتم حساب المعرفات باستخدام عداد (أي أن الوحدة الأولى تحتوي على المعرف 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 الآن المعرّف 5 بدلاً من 4

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

↓ أصبح لدى ads.js الآن رقم التعريف 6 بدلاً من 5

[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
  • قسِّم الرمز حسب المسارات/الصفحات لتجنُّب تحميل البيانات غير الضرورية.