كيفية مساعدة webpack في ميزة تخزين مواد العرض مؤقتًا
بعد تحسين حجم التطبيق، يمكن تحسين وقت تحميل التطبيق من خلال ميزة التخزين المؤقت. يمكنك استخدامها لحفظ أجزاء من التطبيق على العميل وتجنُّب إعادة تنزيلها في كل مرة.
استخدام عناوين ذاكرة التخزين المؤقت وإصدار الحِزمة
النهج الشائع لتنفيذ التخزين المؤقت هو:
إخبار المتصفّح بتخزين ملف في ذاكرة التخزين المؤقت لفترة طويلة جدًا (مثلاً، سنة):
# Server header Cache-Control: max-age=31536000
إذا لم تكن على دراية بوظائف
Cache-Control
، يمكنك الاطّلاع على مقالة Jake Archibald الممتازة حول أفضل ممارسات التخزين المؤقت.وإعادة تسمية الملف عند تغييره لفرض إعادة التنزيل:
<!-- 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"
}
مراجع إضافية
- لمحة عن أفضل ممارسات التخزين المؤقت، بقلم "جاك أرشيبالد"
استخراج التبعيات ووقت التشغيل في ملف منفصل
التبعيات
وعادةً ما تتغيّر متطلّبات التطبيق بمعدل أقل من رمز التطبيق الفعلي. وإذا نقلتها إلى ملف منفصل، سيتمكّن المتصفّح من تخزينها مؤقتًا بشكل منفصل، ولن يعيد تنزيلها في كل مرة يتغيّر فيها رمز التطبيق.
لاستخراج التبعيات في قطعة منفصلة، عليك اتّباع ثلاث خطوات:
استبدِل اسم ملف الإخراج بـ
[name].[chunkname].js
:// webpack.config.js module.exports = { output: { // Before filename: 'bundle.[chunkhash].js', // After filename: '[name].[chunkhash].js' } };
عندما ينشئ Webpack التطبيق، يستبدل
[name]
باسم قطعة. إذا لم نضيف الجزء[name]
، علينا التمييز بين الأجزاء حسب علامة التجزئة الخاصة بها، وهو أمر صعب جدًا.حوِّل الحقل
entry
إلى عنصر:// webpack.config.js module.exports = { // Before entry: './index.js', // After entry: { main: './index.js' } };
في هذا المقتطف، "main" هو اسم قطعة. سيتم استبدال هذا الاسم بدلاً من
[name]
من الخطوة 1.في الوقت الحالي، إذا أنشأت التطبيق، سيتضمّن هذا الجزء رمز التطبيق بالكامل، تمامًا كما لو لم ننفِّذ هذه الخطوات. ولكن سيتم تغيير ذلك بعد قليل.
في webpack 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>
مراجع إضافية
- دليل Webpack للتخزين المؤقّت على المدى الطويل
- مستندات Webpack حول وقت تشغيل Webpack وملف البيان
- "الاستفادة إلى أقصى حد من CommonsChunkPlugin"
- آلية عمل
optimization.splitChunks
وoptimization.runtimeChunk
تضمين وقت تشغيل webpack لتوفير طلب HTTP إضافي
لتحسين الأداء، جرِّب تضمين وقت تشغيل webpack في ملف 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 باستخدام منطق خادم مخصّص
مع webpack 4:
أضِف الرمز
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" }
تضمين محتوى القطعة في وقت التشغيل بطريقة ملائمة على سبيل المثال، باستخدام 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:
اجعل اسم وقت التشغيل ثابتًا من خلال تحديد
filename
:module.exports = { plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', minChunks: Infinity, filename: 'runtime.js' }) ] };
تضمين محتوى
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()
أنّك تريد تحميل وحدة معيّنة بشكل ديناميكي. عندما يرصد
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
، ما يُحسِّن من وقت التحميل الأوّلي.
بالإضافة إلى ذلك، سيؤدي ذلك إلى تحسين التخزين المؤقت. فإذا غيّرت الرمز في الجزء الرئيسي، لن يتأثّر ملف التعليقات.
مراجع إضافية
- مستندات Webpack لدالة
import()
- اقتراح JavaScript لتنفيذ
import()
بنية الجملة
تقسيم الرمز إلى مسارات وصفحات
إذا كان تطبيقك يتضمّن صفحات أو مسارات متعددة، ولكن لا يتضمّن سوى ملف JS واحد يحتوي على الرمز البرمجي (قطعة واحدة من main
)، من المرجّح أنك تعرض وحدات بايت إضافية في كل طلب. على سبيل المثال، عندما يزور أحد المستخدِمين الصفحة الرئيسية لموقعك الإلكتروني:
ولن يحتاجوا إلى تحميل الرمز لعرض مقالة على صفحة مختلفة، ولكن سيتم تحميله. بالإضافة إلى ذلك، إذا كان المستخدم يزور دائمًا الصفحة الرئيسية فقط، وأجريت تغييرًا في رمز المقالة، سيبطل Webpack الحزمة بأكملها، وسيضطر المستخدم إلى إعادة تنزيل التطبيق بأكمله.
إذا قسمنا التطبيق إلى صفحات (أو مسارات، إذا كان تطبيقًا مكوّنًا من صفحة واحدة)، لن ينزّل المستخدم سوى الرمز برمجي المعني. بالإضافة إلى ذلك، سيخزِّن المتصفّح رمز التطبيق في ذاكرة التخزين المؤقت بشكلٍ أفضل: إذا غيّرت رمز الصفحة الرئيسية، لن تلغي أداة webpack سوى المقطع المعني.
بالنسبة إلى التطبيقات من صفحة واحدة
لتقسيم التطبيقات المكوّنة من صفحة واحدة حسب المسارات، استخدِم import()
(اطّلِع على قسم "رمز التحميل البطيء
الذي لا تحتاج إليه الآن"). إذا كنت تستخدم إطار عمل،
قد يتضمّن حلًا حاليًا لهذه المشكلة:
- "تقسيم الكود
"
في مستندات
react-router
(لنظام React) - "التحميل البطيء
للمسارات" في مستندات
vue-router
(لنظام Vue.js)
بالنسبة إلى التطبيقات التقليدية المتعدّدة الصفحات
لتقسيم التطبيقات التقليدية حسب الصفحات، استخدِم نقاط الدخول في webpack. إذا كان تطبيقك يتضمّن ثلاثة أنواع من الصفحات: الصفحة الرئيسية وصفحة المقالة وصفحة حساب المستخدم، يجب أن يتضمّن ثلاثة إدخالات:
// 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 تلقائيًا عن الرمز المشترَك ويستخرجه إلى ملفات منفصلة.
أو في webpack 3، استخدِم CommonsChunkPlugin
– سيؤدي ذلك إلى نقل الملحقات الشائعة إلى ملف جديد محدّد:
module.exports = {
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2 // 2 is the default value
})
]
};
يمكنك تغيير قيمة minChunks
للعثور على القيمة الأفضل. بشكل عام،
يُفضَّل إبقاء حجمها صغيرًا، ولكن يجب زيادتها إذا زاد عدد الأجزاء. على سبيل المثال، إذا كانت هناك 3 أجزاء، قد يكون minChunks
هو 2، ولكن إذا كانت هناك 30 جزءًا، قد يكون minChunks
هو 8، لأنّه في حال إبقاءه على 2، ستتم إضافة عدد كبير جدًا من الوحدات إلى الملف المشترك، مما يؤدي إلى تضخيم حجمه بشكل كبير.
مراجع إضافية
- مستندات Webpack حول مفهوم نقاط الدخول
- مستندات Webpack حول ملف CommonsChunkPlugin
- "الاستفادة إلى أقصى حد من CommonsChunkPlugin"
- آلية عمل
optimization.splitChunks
وoptimization.runtimeChunk
جعل أرقام تعريف الوحدات أكثر ثباتًا
عند إنشاء الرمز، يخصّص 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()
]
};
مراجع إضافية
- مستندات Webpack حول ملف HashedModuleIdsPlugin
ملخّص
- تخزين الحِزمة مؤقتًا والتفريق بين الإصدارات من خلال تغيير اسم الحِزمة
- تقسيم الحِزمة إلى رمز التطبيق ورمز المورّد ووقت التشغيل
- تضمين وقت التشغيل لحفظ طلب HTTP
- تحميل الرمز غير المهم بشكل بطيء باستخدام
import
- تقسيم الرمز حسب المسارات أو الصفحات لتجنُّب تحميل المحتوى غير الضروري