Experiments
التجارب
boolean: false
أُدخل الخيار experiments في webpack 5 ليُتيح للمستخدمين تفعيل الميزات التجريبية وتجربتها.
الخيارات المتاحة:
asyncWebAssembly: يدعم WebAssembly الجديد وفق المواصفة المحدَّثة، فيجعل وحدة WebAssembly وحدةً غير متزامنة. وهو مُفعَّل افتراضياً حين يُضبطexperiments.futureDefaultsعلىtrue.backCompatbuildHttpcacheUnaffectedcssdeferImportfutureDefaultshtmllazyCompilationoutputModuletypescriptsourceImportsyncWebAssembly: يدعم WebAssembly القديم كما في webpack 4.layers: يُفعِّل طبقات الوحدات والـ chunks، أُزيل ويعمل بلا خيارات إضافية منذ5.102.0.topLevelAwait: يُحوِّل الوحدة إلى وحدةasyncحين يُستعمَلawaitعلى المستوى الأعلى. ابتداءً من webpack5.83.0(أمّا في الإصدارات السابقة فيمكنك تفعيله بضبطexperiments.topLevelAwaitعلىtrue)، صارت هذه الميزة مُفعَّلة افتراضياً، وأُزيلت وصارت تعمل بلا خيارات إضافية منذ5.102.0.
webpack.config.js
export default {
// ...
experiments: {
asyncWebAssembly: true,
buildHttp: true,
lazyCompilation: true,
outputModule: true,
sourceImport: true,
syncWebAssembly: true,
topLevelAwait: true,
},
};experiments.backCompat
فعِّل طبقة التوافق العكسي مع تحذيرات الإهمال (deprecation warnings) لكثير من واجهات webpack 4 البرمجية.
- النوع:
boolean
export default {
// ...
experiments: {
backCompat: true,
},
};experiments.buildHttp
حين يُفعَّل هذا الخيار، يستطيع webpack بناء الموارد البعيدة التي تبدأ بـ http(s):.
-
النوع:
-
(string | RegExp | ((uri: string) => boolean))[]اختصارٌ لـ
experiments.buildHttp.allowedUris. -
HttpUriOptions{ allowedUris: (string|RegExp|(uri: string) => boolean)[], cacheLocation?: false | string, frozen?: boolean, lockfileLocation?: string, upgrade?: boolean }
-
-
متاح: 5.49.0+
-
مثال
webpack.config.js
export default { // ... experiments: { buildHttp: true, }, };// src/index.js import pMap1 from "https://cdn.skypack.dev/p-map"; // مع تفعيل `buildHttp`، سيبني webpack pMap1 كأنّها وحدة محلية اعتيادية console.log(pMap1);
experiments.buildHttp.allowedUris
قائمة بالعناوين المسموح بها (URIs).
-
النوع:
(string|RegExp|(uri: string) => boolean)[] -
مثال
webpack.config.js
export default { // ... experiments: { buildHttp: { allowedUris: [ "http://localhost:9990/", "https://raw.githubusercontent.com/", ], }, }, };
experiments.buildHttp.cacheLocation
حدِّد موقع التخزين المؤقَّت للموارد البعيدة.
-
النوع
stringfalse
-
مثال
webpack.config.js
export default { // ... experiments: { buildHttp: { cacheLocation: false, }, }, };
افتراضياً يستعمل webpack <compiler-name.>webpack.lock.data/ للتخزين المؤقَّت، غير أنّ بإمكانك تعطيله بضبط قيمته على false.
لاحظ أنّه ينبغي إيداع الملفّات الموجودة تحت experiments.buildHttp.cacheLocation في نظام التحكّم بالإصدار، إذ لن يجري أيّ طلب شبكي أثناء بناء production.
experiments.buildHttp.frozen
جمِّد الموارد البعيدة وملفّ القفل (lockfile). أيّ تعديل على lockfile أو على محتوى المورد سيُفضي إلى خطأ.
- النوع:
boolean
experiments.buildHttp.lockfileLocation
حدِّد موقع تخزين lockfile.
- النوع:
string
افتراضياً يُولِّد webpack ملفّ <compiler-name.>webpack.lock. تأكّد من إيداعه في نظام التحكّم بالإصدار. وأثناء بناء production، سيبني webpack تلك الوحدات التي تبدأ بـ http(s): انطلاقاً من lockfile ومن الذاكرة المؤقَّتة الموجودة في experiments.buildHttp.cacheLocation.
experiments.buildHttp.proxy
حدِّد خادوم البروكسي المستعمَل لجلب الموارد البعيدة.
- النوع:
string
افتراضياً، سيستنتج webpack خادوم البروكسي من متغيّر البيئة http_proxy (لا يميِّز بين الحالة الصغيرة والكبيرة). كما تستطيع تحديده صراحةً عبر الخيار proxy.
experiments.buildHttp.upgrade
اكتشف التغيّرات في الموارد البعيدة وحدِّثها تلقائياً.
- النوع:
boolean
experiments.css
يُفعِّل دعم CSS الأصلي. لاحظ أنّها ميزة تجريبية لا تزال قيد التطوير، وستُفعَّل افتراضياً في webpack v6، لكن بإمكانك تتبّع تقدّمها على GitHub.
- النوع:
boolean
الميزات التجريبية:
-
دعم CSS Modules: سيُولِّد webpack اسماً فريداً لكلّ صنف CSS. استعمل الامتداد
5.103.0+.module.cssلتفعيل CSS Modules.يدعم webpack بشكل أصلي خاصية
composesالخاصة بـ CSS Modules، فيسمح لك بتركيب الأصناف من الملفّ نفسه، أو من وحدات CSS أخرى، أو من أصناف عامة (global):/* styles.module.css */ .base { color: blue; } .button { composes: base; padding: 10px; } .primary { composes: button; background: blue; } /* تركيب من وحدة CSS أخرى */ .composed { composes: className from "./other.module.css"; } /* تركيب من أصناف عامة */ .globalComposed { composes: global-class from global; } -
5.87.0+ تحليل الحقول الخاصّة بـ style في ملفّات
package.json: سيبحث webpack عن حقلstyleفي ملفّاتpackage.jsonويستعمله إن وُجد للاستيراد داخل ملفّات CSS.فمثلاً، إن أضفت
@import 'bootstrap';إلى ملفّ CSS لديك، فسيبحث webpack عنbootstrapفيnode_modulesويستعمل حقلstyleمنpackage.jsonهناك. وإن لم يجد حقلstyle، فسيستعمل حقلmainبدلاً منه حفاظاً على التوافق العكسي. -
Content hash لملفّات CSS: سيُولِّد webpack content hash لملفّات CSS ويستعمله في اسم الملفّ، وهذا مفيد للتخزين المؤقَّت طويل الأمد.
-
استخراج CSS: سيستخرج webpack الـ CSS إلى ملفّ منفصل. وتُغني هذه الإمكانية عن الحاجة إلى
mini-css-extract-pluginوcss-loader، إذ أنّها توفِّر دعماً أصلياً. -
استيرادات CSS: سيُضمِّن webpack استيرادات CSS داخل ملفّ CSS المُولَّد.
-
إعادة التحميل الساخن (HMR): يدعم webpack الـ HMR لملفّات CSS، أي أنّ التغييرات في ملفّات CSS ستظهر في المتصفّح من دون إعادة تحميل كاملة للصفحة.
-
5.107.0+ تحسين scope hoisting، أو module concatenation، لـ CSS Modules. حين يُفعَّل
optimization.concatenateModules، فإنّ وحدات CSS التي يكونexportTypeلهاtextأوcss-style-sheetأوstyleأوlinkتُدمَج في نسخة واحدة من الوحدة بدلاً من إبقائها نسخاً منفصلة عند الـ runtime. وهذا يُقلِّل الـ overhead ويُنتج مخرَجات أصغر للحزم الثقيلة بـ CSS. -
5.107.0+ يمكن استعمال معرّفات
@valueبوصفها مسارَ معامل لـ@importوداخل مراجعurl()، حتى يُعرَّف المسار أو الـ asset المشترك مرّة واحدة ويُعاد استعماله عبر عدّة أوراق أنماط. وتُقبل الصيغة المُغلَّفة بعلامتي اقتباس ("./x",'./x') والصيغة المُجرَّدة (./x)، وتُحلّ كلتاهما عبر مسار الـ assets الاعتيادي في webpack.@value path: "./other.module.css"; @import path; @value bg: "./image.png"; .a { background: url(bg); }
experiments.cacheUnaffected
يُفعِّل تخزيناً مؤقَّتاً إضافياً في الذاكرة (in-memory) للوحدات التي لم تتغيّر، والتي لا تُشير إلا إلى وحدات لم تتغيّر هي الأخرى.
- النوع:
boolean
القيمة الافتراضية مأخوذة من قيمة futureDefaults.
experiments.deferImport
فعِّل دعم اقتراح tc39 اقتراح import defer.
وهو يتيح تأجيل تقييم الوحدة إلى حين أوّل استعمال لها.
وهذا مفيد لتأجيل تنفيذ الشيفرة بشكل متزامن حين لا يكون استعمال import() ممكناً بسبب طبيعته غير المتزامنة.
- النوع:
boolean
تستلزم هذه الميزة أن تدعم بيئة الـ runtime Proxy (ES6).
يُفعِّل الصياغات الآتية:
import defer * as module from "module-name";
import * as module2 from /* webpackDefer: true */ "module-name2";
// أو باستعمال الاستيراد الديناميكي
import.defer("module-name3");
import(/* webpackDefer: true */ "module-name4");
export function f() {
// module-name تُقيَّم بشكل متزامن، ثمّ تُستدعى عليها doSomething().
module.doSomething();
}قيود التعليقات السحرية (/* webpackDefer: true */)
يُستحسَن وضع التعليق السحري بعد الكلمة المفتاحية from. قد تعمل المواضع الأخرى، غير أنّها لم تُختبر.
ووضع التعليق السحري بعد الكلمة المفتاحية import غير متوافق مع filesystem cache.
experiments.sourceImport
5.106.0+فعِّل دعم اقتراح tc39 Source Phase Imports.
يُقدِّم هذا الاقتراح طريقة لاستيراد وحدةٍ في مرحلة المصدر بدلاً من تقييمها فوراً. وفي webpack، هذا الدعم التجريبي مُطبَّق حالياً على وحدات WebAssembly: تحصل أوّلاً على WebAssembly.Module مُصرَّفة، ثمّ تُنشئ منها instance لاحقاً مع imports خاصّة بك. أمّا دعم استيرادات المصدر في JavaScript فمخطَّط له في إصدار قادم.
- النوع:
boolean
فعِّله إلى جانب asyncWebAssembly:
// webpack.config.js
export default {
// ...
experiments: {
asyncWebAssembly: true,
sourceImport: true,
},
};ثمّ استعمل صياغة source-phase الساكنة أو الديناميكية مع استيراد .wasm:
// الصيغة الساكنة
import source wasmModule from "./module.wasm";
// الصيغة الديناميكية
const wasmModule2 = await import.source("./module.wasm");
const instance = await WebAssembly.instantiate(wasmModule);ثمّة مثال كامل في مستودع webpack: examples/wasm-simple-source-phase.
import /* webpackDefer: true */ * as ns from "..."; // معلوم أنّه لا يعمل
import * as ns from /* webpackDefer: true */ "..."; // الموصى بهتأكّد من أنّ الـ loaders لديك لا تحذف التعليق السحري.
ويمكن ضبط TypeScript و Babel و SWC و Flow.js للحفاظ على التعليق السحري.
أمّا Esbuild فهو غير متوافق مع هذه الميزة (انظر evanw/esbuild#1439 و evanw/esbuild#309)، وإن كان قد يدعمها في المستقبل.
5.105.0+import.defer() صار مدعوماً الآن لـ ContextModule (حين يكون مسار الاستيراد تعبيراً ديناميكياً). انظر دليل التحميل الكسول للأمثلة.
experiments.futureDefaults
استعمل القيم الافتراضية لإصدار webpack الرئيسي القادم، واعرض تحذيرات في أيّ موضع قد يكون إشكالياً.
webpack.config.js
export default {
// ...
experiments: {
futureDefaults: true,
},
};experiments.html
5.107.0+يفعّل الدعم الأصلي لـ HTML modules. عند استيراد ملف .html من JavaScript، تمر مراجع الوسوم داخل الملف عبر pipeline العادية في webpack، وهذا يستبدل الدور الذي كان يؤديه html-loader لسنوات. يسجل هذا flag نوع module المسمى html داخل NormalModuleFactory ويفعّل سلوكيات HTML الموضحة أدناه.
- النوع:
boolean - الافتراضي:
false
webpack.config.js
export default {
// ...
experiments: {
html: true,
},
};بعد ذلك، استورد ملف HTML من JavaScript. يكون default export هو HTML المعالج كنص، مع حل كل مراجع assets عبر webpack:
// src/index.js
import page from "./page.html";
document.documentElement.innerHTML = page;Inline <style> tags
يتم تمرير كتل <style> المضمنة داخل HTML module عبر CSS pipeline في webpack كـ CSS modules افتراضية باستخدام exportType: "text". تُحل مراجع url() و@import نسبة إلى ملف HTML، ثم يُكتب نص CSS المعالج مرة أخرى داخل وسم <style> الأصلي في نص HTML الناتج.
<!-- src/page.html -->
<!doctype html>
<html>
<head>
<style>
@import "./reset.css";
body {
background: url("./bg.png");
}
</style>
</head>
<body>
...
</body>
</html>تتم معالجة <style type="text/css"> و<style> الذي لا يحتوي على الخاصية type. أما أي وسم يحمل type غير خاص بـ CSS فيمر بدون تغيير.
Inline <script> tags
يتم تمرير محتوى وسوم <script> المضمنة عبر entry pipeline نفسها المستخدمة مع <script src>. يصبح كل محتوى داخل <script> عبارة عن webpack entry مستقل: scripts الكلاسيكية المضمنة تُحزّم كـ CommonJS، أما محتوى <script type="module"> فيُحزّم كـ ESM. في HTML الناتج، يُعاد كتابة الوسم إلى <script src="…"> يشير إلى chunk المولّد، مع تفريغ المحتوى الداخلي.
<!-- src/page.html -->
<!doctype html>
<html>
<body>
<script type="module">
import { greet } from "./lib.js";
greet("world");
</script>
<script>
console.log("classic inline script");
</script>
</body>
</html>تنطبق هنا السلوكيات نفسها الخاصة بـ <script src> الخارجي:
- عند تفعيل
output.module، تتم ترقية وسوم<script>الكلاسيكية المضمنة تلقائيًا إلىtype="module"، مثل الترقية التلقائية في<script src>. - يعمل
webpackIgnoreأيضًا مع وسوم<script>المضمنة، ويترك المحتوى الأصلي كما هو. - قيم
typeغير الخاصة بـ JS، مثلapplication/ld+jsonوimportmap، تمر بدون تغيير.
<script src> and <link rel="modulepreload">
تصبح مراجع <script src> و<link rel="modulepreload"> داخل HTML module عبارة عن webpack entries حقيقية. ثم يُعاد كتابة URL الخاص بالـ chunk الناتج داخل نص HTML، لذلك تعمل أسماء الملفات التي تحتوي على hash بالطريقة نفسها التي تعمل بها مع JavaScript imports.
<!-- src/page.html -->
<!doctype html>
<html>
<head>
<link rel="modulepreload" href="./preloaded.js" />
</head>
<body>
<script src="./entry.js"></script>
<script src="./second.js"></script>
</body>
</html>هناك بعض السلوكيات التي يجب الانتباه لها:
- وسوم
<script src>المتعددة في الصفحة نفسها تشارك runtime واحدًا. داخل كل مجموعة، سواء كانت classic أوtype="module"، يحمل العنصر الرئيسي runtime وتعلن بقية العناصرdependOnعليه. - تبقى entries الخاصة بـ
<link rel="modulepreload">مستقلة ولا يتم استيرادها من scripts المجاورة، مما يحافظ على معنى "preload without execute". - عند تفعيل
output.module، تتم ترقية وسوم<script src>الكلاسيكية تلقائيًا إلى<script type="module" src>حتى تُحمّل chunks الخاصة بـ ES modules بالوضع الصحيح. - أنواع scripts غير الخاصة بـ JS، مثل
application/ld+jsonوimportmapوdata URIs، تمر بدون تغيير ولا تُحزّم كـ JS.
webpackIgnore magic comment
وضع تعليق HTML بالشكل <!-- webpackIgnore: true --> مباشرة قبل وسم معيّن يخبر webpack بتجاوز URL resolution لذلك الوسم في خصائص مثل src وhref وsrcset وما يشبهها. راجع الشرح الكامل ضمن magic comments.
experiments.lazyCompilation
صرِّف نقاط الدخول و import الديناميكية فقط حين تكون مستعملة. يمكن استعماله للويب أو لـ Node.js.
-
النوع
-
boolean -
object{ // عرِّف backend مخصَّصاً backend?: (( compiler: Compiler, callback: (err?: Error, api?: BackendApi) => void ) => void) | ((compiler: Compiler) => Promise<BackendApi>) | { /** * عميل مخصَّص. */ client?: string; /** * حدِّد المنفذ الذي يستمع إليه الخادوم. */ listen?: number | ListenOptions | ((server: Server) => void); /** * حدِّد البروتوكول الذي يستعمله العميل للاتصال بالخادوم. */ protocol?: "http" | "https"; /** * حدِّد طريقة إنشاء الخادوم الذي يُعالج طلبات EventSource. */ server?: ServerOptionsImport | ServerOptionsHttps | (() => Server); }, entries?: boolean, imports?: boolean, test?: string | RegExp | ((module: Module) => boolean) }backend: خصِّص الـ backend.entries: فعِّل التصريف الكسول لنقاط الدخول.imports5.20.0+: فعِّل التصريف الكسول للاستيرادات الديناميكية.test5.20.0+: حدِّد أيّ الوحدات المستوردة ينبغي تصريفها كسولياً.
-
-
متاح: 5.17.0+
-
مثال 1:
export default { // … experiments: { lazyCompilation: true, }, }; -
مثال 2:
export default { // … experiments: { lazyCompilation: { // عطِّل التصريف الكسول للاستيرادات الديناميكية imports: false, // عطِّل التصريف الكسول لنقاط الدخول entries: false, // لا تُصرِّف moduleB كسولياً test: (module) => !/moduleB/.test(module.nameForCondition()), }, }, };
experiments.outputModule
boolean
حين يُفعَّل هذا الخيار، سيُخرج webpack صياغة وحدات ECMAScript كلّما كان ذلك ممكناً. فعلى سبيل المثال، يستعمل import() لتحميل الـ chunks، و ESM exports لكشف بيانات الـ chunk، وغير ذلك.
export default {
experiments: {
outputModule: true,
},
};experiments.typescript
5.107.0+يفعّل الدعم الأصلي لـ TypeScript. عند تفعيل هذا flag، يترجم webpack ملفات .ts و.cts و.mts مباشرة، وكذلك data URIs المطابقة مثل data:text/typescript وdata:application/typescript، بدون أي loader خارجي. داخليًا، يستدعي webpack دالة Node.js المدمجة module.stripTypeScriptTypes.
- النوع:
boolean - الافتراضي:
false، ويتم تفعيله تلقائيًا بواسطةexperiments.futureDefaults.
export default {
experiments: {
typescript: true,
},
entry: "./src/index.ts",
};تفعيل هذا flag يضبط أيضًا إعدادات افتراضية مناسبة: rules افتراضية لـ .ts و.cts و.mts، وإضافة .ts إلى extension resolution قبل .js، وضبط extensionAlias بحيث يحاول import "./foo.js" أيضًا استخدام ./foo.ts، وكذلك تحويل .cjs / .mjs إلى .cts / .mts، ودعم tsconfig.json resolution، وإضافة مفتاح conditional exports باسم "typescript" حتى تستطيع packages داخل monorepo نشر مصادر .ts عبر package.json#exports.
لإجراء type checking، استخدم هذا flag مع tsc --noEmit أو fork-ts-checker-webpack-plugin. أما عند استخدام JSX أو صياغات TypeScript غير قابلة للإزالة فقط، فاستمر في استخدام ts-loader أو swc-loader.
يوفر مستودع webpack مثالين مرجعيين:
examples/typescriptلإعدادexperiments.typescriptالمدمج.examples/typescript-non-erasableلاستخدامts-loaderكبديل عندما تكون الصياغة غير القابلة للإزالة فقط مطلوبة.



