Compilation Hooks

يستخدم Compiler module المسمى Compilation لإنشاء compilations جديدة، أو builds جديدة. تملك instance من compilation وصولًا إلى كل modules وdependencies الخاصة بها، ومعظمها مراجع دائرية. وهي عمليًا compilation لكل modules الموجودة في dependency graph الخاص بالتطبيق. أثناء مرحلة compilation، يتم تحميل modules، وعمل seal لها، وتحسينها، وتقسيمها إلى chunks، وإنشاء hashes لها، واستعادتها.

يرث الصنف Compilation أيضًا من Tapable ويوفر lifecycle hooks التالية. يمكن الدخول إليها بالطريقة نفسها المستخدمة مع compiler hooks:

compilation.hooks.someHook.tap(/* ... */);

وكما هو الحال مع compiler، قد تكون tapAsync وtapPromise متاحتين أيضًا بحسب نوع hook.

buildModule

SyncHook

يُطلق قبل بدء build الخاص بـ module، ويمكن استخدامه لتعديل module.

  • Callback Parameters: module
compilation.hooks.buildModule.tap(
  "SourceMapDevToolModuleOptionsPlugin",
  (module) => {
    module.useSourceMap = true;
  },
);

rebuildModule

SyncHook

يُطلق قبل إعادة بناء module.

  • Callback Parameters: module

failedModule

SyncHook

يعمل عندما يفشل build الخاص بـ module.

  • Callback Parameters: module error

succeedModule

SyncHook

يُنفّذ عندما يتم بناء module بنجاح.

  • Callback Parameters: module

finishModules

AsyncSeriesHook

يُستدعى عندما يتم بناء كل modules بدون أخطاء.

  • Callback Parameters: modules

finishRebuildingModule

SyncHook

يُنفّذ عندما تنتهي إعادة بناء module، سواء نجحت أو انتهت بأخطاء.

  • Callback Parameters: module

seal

SyncHook

يُطلق عندما يتوقف compilation عن قبول modules جديدة.

unseal

SyncHook

يُطلق عندما يبدأ compilation بقبول modules جديدة.

optimizeDependencies

SyncBailHook

يُطلق في بداية تحسين dependencies.

  • Callback Parameters: modules

afterOptimizeDependencies

SyncHook

يُطلق بعد تحسين dependencies.

  • Callback Parameters: modules

afterChunks

SyncHook

5.83.0+

يُستدعى hook المسمى afterChunks بعد إنشاء chunks وmodule graph، وقبل تحسينهما. يوفر هذا hook فرصة لفحص chunk graph وتحليله وتعديله عند الحاجة.

هذا مثال على استخدام hook compilation.hooks.afterChunks.

  • Callback Parameters: chunks

optimize

SyncHook

يُطلق في بداية مرحلة optimization.

optimizeModules

SyncBailHook

يُستدعى في بداية مرحلة تحسين modules. يمكن لـ plugin الدخول إلى هذا hook لتنفيذ تحسينات على modules.

  • Callback Parameters: modules

afterOptimizeModules

SyncHook

يُستدعى بعد اكتمال تحسين modules.

  • Callback Parameters: modules

optimizeChunks

SyncBailHook

يُستدعى في بداية مرحلة تحسين chunks. يمكن لـ plugin الدخول إلى هذا hook لتنفيذ تحسينات على chunks.

  • Callback Parameters: chunks

afterOptimizeChunks

SyncHook

يُطلق بعد اكتمال تحسين chunks.

  • Callback Parameters: chunks

optimizeTree

AsyncSeriesHook

يُستدعى قبل تحسين dependency tree. يمكن لـ plugin الدخول إلى هذا hook لتنفيذ تحسين على dependency tree.

  • Callback Parameters: chunks modules

afterOptimizeTree

SyncHook

يُستدعى بعد اكتمال تحسين dependency tree بنجاح.

  • Callback Parameters: chunks modules

optimizeChunkModules

SyncBailHook

يُستدعى بعد تحسين tree، وفي بداية تحسين chunk modules. يمكن لـ plugin الدخول إلى هذا hook لتنفيذ تحسينات على chunk modules.

  • Callback Parameters: chunks modules

afterOptimizeChunkModules

SyncHook

يُستدعى بعد اكتمال تحسين chunk modules بنجاح.

  • Callback Parameters: chunks modules

shouldRecord

SyncBailHook

يُستدعى لتحديد هل يجب تخزين records أم لا. إرجاع أي شيء !== false سيمنع تنفيذ بقية hooks الخاصة بـ records، وهي record وrecordModules وrecordChunks وrecordHash.

reviveModules

SyncHook

يستعيد معلومات module من records.

  • Callback Parameters: modules records

beforeModuleIds

SyncHook

يُنفّذ قبل تعيين id لكل module.

  • Callback Parameters: modules

moduleIds

SyncHook

يُستدعى لتعيين id لكل module.

  • Callback Parameters: modules

optimizeModuleIds

SyncHook

يُستدعى في بداية تحسين id الخاصة بـ modules.

  • Callback Parameters: modules

afterOptimizeModuleIds

SyncHook

يُستدعى عندما تكتمل مرحلة تحسين id الخاصة بـ modules.

  • Callback Parameters: modules

reviveChunks

SyncHook

يستعيد معلومات chunk من records.

  • Callback Parameters: chunks records

beforeChunkIds

SyncHook

يُنفّذ قبل تعيين id لكل chunk.

  • Callback Parameters: chunks

chunkIds

SyncHook

يُستدعى لتعيين id لكل chunk.

  • Callback Parameters: chunks

optimizeChunkIds

SyncHook

يُستدعى في بداية مرحلة تحسين id الخاصة بـ chunks.

  • Callback Parameters: chunks

afterOptimizeChunkIds

SyncHook

يُطلق بعد انتهاء تحسين id الخاصة بـ chunk.

  • Callback Parameters: chunks

recordModules

SyncHook

يخزن معلومات module داخل records. يُطلق هذا hook إذا أرجع shouldRecord قيمة truthy.

  • Callback Parameters: modules records

recordChunks

SyncHook

يخزن معلومات chunk داخل records. لا يُطلق إلا إذا أرجع shouldRecord قيمة truthy.

  • Callback Parameters: chunks records

beforeModuleHash

SyncHook

يُستدعى قبل إنشاء hash للـ modules.

afterModuleHash

syncHook

يُستدعى بعد إنشاء hash للـ modules.

beforeHash

SyncHook

يُستدعى قبل إنشاء hash للـ compilation.

afterHash

SyncHook

يُستدعى بعد إنشاء hash للـ compilation.

recordHash

SyncHook

يخزن معلومات record hash داخل records. لا يُطلق إلا إذا أرجع shouldRecord قيمة truthy.

  • Callback Parameters: records

record

SyncHook

يخزن معلومات عن compilation داخل records. لا يُطلق إلا إذا أرجع shouldRecord قيمة truthy.

  • Callback Parameters: compilation records

beforeModuleAssets

SyncHook

يُنفّذ قبل إنشاء module assets.

additionalChunkAssets

SyncHook

ينشئ assets إضافية للـ chunks.

  • Callback Parameters: chunks

shouldGenerateChunkAssets

SyncBailHook

يُستدعى لتحديد هل يجب توليد chunk assets أم لا. إرجاع أي شيء !== false سيسمح بتوليد chunk assets.

beforeChunkAssets

SyncHook

يُنفّذ قبل إنشاء chunk assets.

additionalAssets

AsyncSeriesHook

ينشئ assets إضافية للـ compilation. يمكن استخدام هذا hook لتنزيل صورة، مثلًا:

compilation.hooks.additionalAssets.tapAsync("MyPlugin", (callback) => {
  download("https://img.shields.io/npm/v/webpack.svg", (resp) => {
    if (resp.status === 200) {
      compilation.assets["webpack-version.svg"] = toAsset(resp);
      callback();
    } else {
      callback(
        new Error("[webpack-example-plugin] Unable to download the image"),
      );
    }
  });
});

optimizeChunkAssets

AsyncSeriesHook

يحسّن أي chunk assets. يتم تخزين assets داخل compilation.assets. يملك Chunk خاصية files تشير إلى كل الملفات التي أنشأها chunk. وأي chunk assets إضافية تُخزن داخل compilation.additionalChunkAssets.

  • Callback Parameters: chunks

هذا مثال يضيف banner لكل chunk.

compilation.hooks.optimizeChunkAssets.tapAsync(
  "MyPlugin",
  (chunks, callback) => {
    for (const chunk of chunks) {
      for (const file of chunk.files) {
        compilation.assets[file] = new ConcatSource(
          "/**Sweet Banner**/",
          "\n",
          compilation.assets[file],
        );
      }
    }

    callback();
  },
);

afterOptimizeChunkAssets

SyncHook

تم تحسين chunk assets.

  • Callback Parameters: chunks

هذا مثال plugin من @boopathi يطبع بالضبط ما دخل في كل chunk.

compilation.hooks.afterOptimizeChunkAssets.tap("MyPlugin", (chunks) => {
  for (const chunk of chunks) {
    console.log({
      id: chunk.id,
      name: chunk.name,
      includes: chunk.getModules().map((module) => module.request),
    });
  }
});

optimizeAssets

AsyncSeriesHook

يحسّن كل assets المخزنة داخل compilation.assets.

  • Callback Parameters: assets

afterOptimizeAssets

SyncHook

تم تحسين assets.

  • Callback Parameters: assets

processAssets

AsyncSeriesHook

معالجة assets.

Hook parameters:

  • name: string — اسم plugin.
  • stage: Stage — المرحلة التي ستدخل إليها. راجع قائمة المراحل المدعومة أدناه.
  • additionalAssets?: true | (assets, [callback]) => (void | Promise<void>) — callback للـ assets الإضافية. راجع أدناه.

Callback parameters:

  • assets: { [pathname: string]: Source } — كائن عادي يكون مفتاحه pathname الخاص بالـ asset، وقيمته بيانات asset ممثلة بواسطة Source.

مثال:

compilation.hooks.processAssets.tap(
  {
    name: "MyPlugin",
    stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS, // راجع أدناه لمراحل أكثر
  },
  (assets) => {
    console.log("List of assets and their sizes:");
    for (const [pathname, source] of Object.entries(assets)) {
      console.log(`${pathname}: ${source.size()} bytes`);
    }
  },
);

Additional assets

بالإضافة إلى name وstage، يمكنك تمرير خيار additionalAssets 5.8.0+، وهو يقبل إما القيمة true أو callback يستقبل assets كأول argument:

  1. true — يشغّل callback المقدم مرة أخرى للـ assets التي تضيفها plugins لاحقًا.

    في هذا الوضع، قد يُستدعى callback عدة مرات: مرة للـ assets المضافة قبل المرحلة المحددة، ومرات إضافية للـ assets التي تضيفها plugins لاحقًا في هذه المرحلة أو المراحل التالية.

    compilation.hooks.processAssets.tap(
      {
        name: "MyPlugin",
        stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
        additionalAssets: true,
      },
      (assets) => {
        // ستُستدعى هذه الدالة عدة مرات مع كل دفعة من assets
      },
    );
  2. (assets, [callback]) => (void | Promise<void>) — يشغّل callback المحدد على assets التي تضيفها plugins لاحقًا في هذه المرحلة أو المراحل التالية. يجب أن يحترم callback نوع tap method المستخدمة؛ مثلًا عند استخدام tapPromise() يجب أن يرجع promise.

    compilation.hooks.processAssets.tap(
      {
        name: "MyPlugin",
        stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
        additionalAssets: (assets) => {
          // قد تُستدعى هذه الدالة عدة مرات للـ assets المضافة في مراحل لاحقة
        },
      },
      (assets) => {
        // ستُستدعى هذه الدالة مرة واحدة للـ assets التي أضافتها plugins في مراحل سابقة
      },
    );

قائمة مراحل معالجة assets

هذه قائمة بالمراحل المدعومة، مرتبة حسب ترتيب المعالجة:

  • PROCESS_ASSETS_STAGE_ADDITIONAL — إضافة assets إضافية إلى compilation.
  • PROCESS_ASSETS_STAGE_PRE_PROCESS — معالجة أولية أساسية للـ assets.
  • PROCESS_ASSETS_STAGE_DERIVED — اشتقاق assets جديدة من assets الموجودة.
  • PROCESS_ASSETS_STAGE_ADDITIONS — إضافة أقسام إضافية إلى assets الموجودة، مثل banner أو كود تهيئة.
  • PROCESS_ASSETS_STAGE_OPTIMIZE — تحسين assets الموجودة بشكل عام.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT — تحسين عدد assets الموجودة، مثل دمجها.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY — تحسين توافق assets الموجودة، مثل إضافة polyfills أو vendor prefixes.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE — تحسين حجم assets الموجودة، مثل التصغير أو حذف المسافات.
  • PROCESS_ASSETS_STAGE_DEV_TOOLING — إضافة أدوات تطوير إلى assets، مثل استخراج source map.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE 5.8.0+ — تحسين عدد assets الموجودة، مثل تضمين assets داخل assets أخرى.
  • PROCESS_ASSETS_STAGE_SUMMARIZE — تلخيص قائمة assets الموجودة.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_HASH — تحسين hashes الخاصة بـ assets، مثل توليد hashes حقيقية من محتوى asset.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER — تحسين نقل assets الموجودة، مثل تجهيز ملف مضغوط gzip كـ asset منفصل.
  • PROCESS_ASSETS_STAGE_ANALYSE — تحليل assets الموجودة.
  • PROCESS_ASSETS_STAGE_REPORT — إنشاء assets لأغراض التقارير.

Assets info

لا يتم توفير metadata الخاصة بـ "asset info" تلقائيًا لهذا hook. إذا احتجتها، فعليك حل هذه metadata يدويًا باستخدام instance الخاصة بـ compilation وpathname الخاص بالـ asset. سيتم تحسين هذا في إصدار مستقبلي من webpack.

مثال:

compilation.hooks.processAssets.tap(
  {
    /** … */
  },
  (assets) => {
    for (const [pathname, source] of Object.entries(assets)) {
      const assetInfo = compilation.assetsInfo.get(pathname);
      // @todo: افعل شيئًا مع "pathname" و"source" و"assetInfo"
    }
  },
);

afterProcessAssets

SyncHook

يُستدعى بعد انتهاء hook processAssets بدون خطأ.

needAdditionalSeal

SyncBailHook

يُستدعى لتحديد هل يحتاج compilation إلى unseal لإضافة ملفات أخرى.

afterSeal

AsyncSeriesHook

يُنفّذ مباشرة بعد needAdditionalSeal.

chunkHash

SyncHook

يُطلق لإصدار hash لكل chunk.

  • Callback Parameters: chunk chunkHash

moduleAsset

SyncHook

يُستدعى عندما تتم إضافة asset من module إلى compilation.

  • Callback Parameters: module filename

chunkAsset

SyncHook

يُطلق عندما تتم إضافة asset من chunk إلى compilation.

  • Callback Parameters: chunk filename

assetPath

SyncWaterfallHook

يُستدعى لتحديد مسار asset.

  • Callback Parameters: path options

needAdditionalPass

SyncBailHook

يُستدعى لتحديد ما إذا كان asset يحتاج معالجة إضافية بعد إصداره.

childCompiler

SyncHook

يُنفّذ بعد إعداد child compiler.

  • Callback Parameters: childCompiler compilerName compilerIndex

normalModuleLoader

منذ webpack v5، تمت إزالة hook المسمى normalModuleLoader. للوصول إلى loader الآن، استخدم NormalModule.getCompilationHooks(compilation).loader بدلًا منه.

statsPreset

HookMap

هذا HookMap يشبه قائمة إجراءات تُطلق عند استخدام preset. يستقبل كائن options. عندما يدير plugin preset، يجب أن يغير الإعدادات داخل هذا الكائن بحذر بدون استبدال الإعدادات الموجودة.

  • Callback Parameters: options context

هذا مثال توضيحي لـ plugin:

compilation.hooks.statsPreset.for("my-preset").tap("MyPlugin", (options) => {
  if (options.all === undefined) options.all = true;
});

يضمن هذا plugin أنه بالنسبة للـ preset المسمى 'my-preset'، إذا كان خيار all غير معرّف، فستصبح قيمته الافتراضية true.

statsNormalize

SyncHook

يُستخدم هذا hook لتحويل كائن options إلى صيغة متسقة يمكن استخدامها بسهولة بواسطة hooks اللاحقة. كما يضمن ضبط الخيارات الناقصة على قيمها الافتراضية.

  • Callback Parameters: options context

هذا مثال توضيحي لـ plugin:

compilation.hooks.statsNormalize.tap("MyPlugin", (options) => {
  if (options.myOption === undefined) options.myOption = [];

  if (!Array.isArray(options.myOption)) options.myOptions = [options.myOptions];
});

في هذا plugin، إذا كان myOption ناقصًا، يضبطه على array فارغة. كذلك يتأكد من أن myOption دائمًا array حتى لو كان معرّفًا في الأصل كقيمة واحدة.

statsFactory

يوفر هذا hook وصولًا إلى الصنف StatsFactory لخيارات محددة.

  • Callback Parameters: statsFactory options

StatsFactory.hooks.extract

HookMap

  • Callback Parameters: object data context

تحتوي data على الصنف. أما object فهو الكائن الذي يجب إضافة الخصائص إليه. ويوفر context معلومات سياقية، مثل الأصناف الموجودة في المسار.

مثال:

compilation.hooks.statsFactory.tap("MyPlugin", (statsFactory, options) => {
  statsFactory.hooks.extract
    .for("compilation")
    .tap("MyPlugin", (object, compilation) => {
      object.customProperty = MyPlugin.getCustomValue(compilation);
    });
});

StatsFactory.hooks.result

HookMap

يُستدعى مع النتيجة على كل مستوى.

  • Callback Parameters: result context

statsPrinter

يوفر هذا hook وصولًا إلى الصنف StatsPrinter لخيارات محددة.

  • Callback Parameters: statsPrinter options

StatsPrinter.hooks.print

HookMap

يُستدعى هذا hook عندما يجب طباعة جزء معين.

  • Callback Parameters: object context

StatsPrinter.hooks.result

HookMap

يُستدعى هذا hook للنص الناتج عن جزء معين.

  • Callback Parameters: result context

CssModulesPlugin.getCompilationHooks(compilation)

عند تفعيل experiments.css، يعرض CssModulesPlugin الداخلي مجموعة hooks لكل compilation لمؤلفي plugins. يمكنك الوصول إليها عبر static method باسم getCompilationHooks(compilation):

const webpack = require("webpack");

class MyCssPlugin {
  apply(compiler) {
    compiler.hooks.thisCompilation.tap("MyCssPlugin", (compilation) => {
      const hooks =
        webpack.css.CssModulesPlugin.getCompilationHooks(compilation);
      // ادخل إلى hooks هنا
    });
  }
}

orderModules

5.107.0+

SyncBailHook<[Chunk, Module[], Compilation], Module[] | undefined>

يُستدعى مرة واحدة لكل نوع CSS source، أي CSS imports وCSS modules، مع modules الخاصة بالـ chunk مرتبة مسبقًا حسب full module name. يمكن لـ taps إرجاع Module[] مرتبة لتجاوز topological sort الافتراضي لترتيب imports في webpack، أو إرجاع undefined للإبقاء على الترتيب الافتراضي.

هذا hook هو المخرج الموصى به عندما يظهر ترتيب webpack الطوبولوجي تحذير Conflicting order between css ... ولا يمكن حله بإعادة هيكلة imports. إرجاع array المرتبة مسبقًا، أو أي ترتيب deterministic، يسمح للـ build باختيار ترتيب ثابت بدون تغيير كود التطبيق.

  • Callback Parameters: chunk modules compilation
const webpack = require("webpack");

class CssOrderByPathPlugin {
  apply(compiler) {
    compiler.hooks.thisCompilation.tap(
      "CssOrderByPathPlugin",
      (compilation) => {
        const hooks =
          webpack.css.CssModulesPlugin.getCompilationHooks(compilation);

        // تصل modules مرتبة مسبقًا حسب full module name. أرجعها كما هي
        // لفرض ترتيب deterministic حسب مسار الملف عبر rebuilds
        // وتجنب تحذير conflicting-order.
        hooks.orderModules.tap(
          "CssOrderByPathPlugin",
          (_chunk, modules) => modules,
        );
      },
    );
  }
}

هذا الـhook من نوع SyncBailHook؛ لذلك تُعتمد نتيجة أول tap يعيد قيمة غير undefined، ولا تُستدعى بقية taps في ذلك الاستدعاء.

HtmlModulesPlugin.getCompilationHooks(compilation)

5.109.0+

عند تفعيل experiments.html، يتيح HtmlModulesPlugin الداخلي مجموعة hooks خاصة بكل عملية تصريف لحقن صفحات HTML الناتجة وتحويلها. يمكنك الوصول إليها عبر الدالة الساكنة getCompilationHooks(compilation):

const webpack = require("webpack");

class MyHtmlPlugin {
  apply(compiler) {
    compiler.hooks.thisCompilation.tap("MyHtmlPlugin", (compilation) => {
      const hooks =
        webpack.html.HtmlModulesPlugin.getCompilationHooks(compilation);
      // سجّل taps على الـhooks هنا
    });
  }
}

injectTags

AsyncSeriesWaterfallHook<[HtmlTagDescriptor[], { outputName, html }]>

تُستدعى مع قائمة الوسوم الإضافية المراد حقنها في كل صفحة، وتكون فارغة في البداية، ومع HTML الحالي. أضف واصفات الوسوم إلى القائمة ثم أعدها، وسيتولى webpack تحويلها إلى HTML ووضعها في أماكنها. تعمل قبل output.html.csp، ولذلك تُحسب تجزئات وسوم <script> و<style> المضمنة المحقونة كما تُحسب لوسوم الصفحة الأصلية.

يقبل كل HtmlTagDescriptor الخصائص التالية:

  • tag ‏(string): اسم الوسم، مثل 'script' أو'link' أو'meta'.
  • attrs ‏(object): السمات؛ تُخرج true سمة منطقية بلا قيمة، بينما تحذفها false وundefined.
  • children ‏(string): المحتوى الداخلي، ويُتجاهل مع العناصر الفارغة مثل <link> و<meta>.
  • injectTo ‏('head' | 'body' | 'head-prepend' | 'body-prepend'): موضع الحقن، وقيمته الافتراضية 'head'.
  • voidTag ‏(boolean): يجبر الوسم على أن يكون عنصرًا فارغًا بلا وسم إغلاق. وإذا حُذف، تُستنتج قيمته من اسم الوسم.
hooks.injectTags.tap("MyHtmlPlugin", (tags) => {
  tags.push({
    tag: "meta",
    attrs: { name: "theme-color", content: "#2b3a42" },
  });
  return tags;
});

transformTags

AsyncSeriesHook<[HtmlMutableTag[], { outputName, html }]>

تُستدعى مع وسوم <script> و<link> و<style> و<meta> الموجودة في الصفحة، سواء أنشأها webpack أم حُقنت لاحقًا، على هيئة واصفات قابلة للتعديل. عدّل attrs لإضافة nonce أو سمة data-* أو لتبديل defer وasync، أو اضبط remove: true، أو غيّر injectTo لنقل الوسم بين <head> و<body>؛ وسيعيد webpack كتابة الوسوم المعدلة. استخدم injectTags لإضافة وسوم جديدة، ولا تعِد ترتيب المصفوفة نفسها.

transformHtml

AsyncSeriesWaterfallHook<[string, { outputName: string }]>

تُستدعى مع HTML النهائي لكل صفحة ناتجة بعد حل جميع العناصر النائبة وقبل كتابة الصفحة مباشرةً. أعد HTML بعد تحويله، كتصغيره مثلًا:

hooks.transformHtml.tapPromise("MyHtmlPlugin", async (html, { outputName }) =>
  html.replace("<!-- banner -->", "..."),
);

htmlEmitted

AsyncSeriesHook<[{ outputName: string }]>

تُستدعى مرة واحدة بعد اكتمال أصل HTML لكل صفحة، لتعمل كإشعار بعد الإخراج.

·تعديل هذه الصفحة
السابق ›
Compiler Hooks

1 مساهم

RlxChap2