ModuleConcatenationPlugin

في الإصدارات القديمة، كان أحد الجوانب السلبية في bundling داخل webpack أن كل module داخل bundle يُغلّف داخل function closure مستقل. هذه الدوال الإضافية تجعل تنفيذ JavaScript أبطأ في المتصفح. بالمقارنة، أدوات مثل Closure Compiler وRollupJS تقوم بما يسمى hoisting أو concatenation لنطاق كل modules داخل closure واحد، وهذا يساعد الكود على التنفيذ بسرعة أعلى في المتصفح.

يفعّل هذا plugin السلوك نفسه داخل webpack. افتراضيًا، يكون هذا plugin مفعّلًا في وضع production، ومعطلًا في غير ذلك. إذا أردت تعطيل هذا التحسين في وضع production، اضبط خيار optimization.concatenateModules على false. ولتفعيل هذا السلوك في أوضاع أخرى، يمكنك إضافة ModuleConcatenationPlugin يدويًا أو استخدام خيار optimization.concatenateModules:

new webpack.optimize.ModuleConcatenationPlugin();

يُسمى سلوك الدمج هذا "scope hoisting".

يعتمد scope hoisting تحديدًا على صيغة ECMAScript Modules. لذلك قد يرجع webpack إلى bundling العادي حسب نوع modules التي تستخدمها، وبحسب شروط أخرى.

حالات إيقاف التحسين

كما يشرح المقال، يحاول webpack تطبيق scope hoisting جزئيًا. يمكنه دمج modules داخل نطاق واحد، لكنه لا يستطيع فعل ذلك في كل الحالات. إذا لم يستطع webpack دمج module، فهناك نتيجتان محتملتان: Prevent أو Root. تعني Prevent أن module يجب أن يبقى في نطاق مستقل. وتعني Root أن webpack سينشئ مجموعة modules جديدة. تحدد الشروط التالية النتيجة:

الشرطالنتيجة
ليس ES6 ModulePrevent
مستورد بواسطة غير importRoot
مستورد من chunk آخرRoot
مستورد بواسطة عدة module groups أخرىRoot
مستورد باستخدام import()Root
متأثر بـ ProvidePlugin أو يستخدم modulePrevent
مقبول من HMRRoot
يستخدم eval()Prevent
موجود في عدة chunksPrevent
export * from "cjs-module"Prevent

خوارزمية تجميع modules

يوضح pseudo JavaScript التالي الخوارزمية:

function tryToAdd(group, module) {
  if (group.has(module)) {
    return true;
  }
  if (!hasPreconditions(module)) {
    return false;
  }
  const nextGroup = group;
  const result = module.dependents.reduce(
    (check, dependent) => check && tryToAdd(nextGroup, dependent),
    true,
  );
  if (!result) {
    return false;
  }
  for (const dependency of module.dependencies) {
    tryToAdd(group, dependency);
  }
  group.merge(nextGroup);
  return true;
}

for (const module of modules) {
  const group = new ModuleGroup({
    root: module,
  });
  for (const dependency of module.dependencies) {
    tryToAdd(group, dependency);
  }
  if (group.modules.length > 1) {
    orderedModules = topologicalSort(group.modules);
    concatenatedModule = new ConcatenatedModule(orderedModules);
    chunk.add(concatenatedModule);
    for (const groupModule of orderedModules) {
      chunk.remove(groupModule);
    }
  }
}

تصحيح حالات إيقاف التحسين

عند استخدام webpack CLI، يعرض flag --stats-optimization-bailout أسباب إيقاف التحسين. وعند استخدام ملف إعدادات webpack، أضف الخيار التالي إلى كائن stats:

export default {
  // ...
  stats: {
    // Display bailout reasons
    optimizationBailout: true,
  },
};
·تعديل هذه الصفحة
السابق ›
MinChunkSizePlugin
‹ التالي
ModuleFederationPlugin

1 مساهم

RlxChap2