Experiments

التجارب

boolean: false

أُدخل الخيار experiments في webpack 5 ليُتيح للمستخدمين تفعيل الميزات التجريبية وتجربتها.

الخيارات المتاحة:

  • asyncWebAssembly: يدعم WebAssembly الجديد وفق المواصفة المحدَّثة، فيجعل وحدة WebAssembly وحدةً غير متزامنة. وهو مُفعَّل افتراضياً حين يُضبط experiments.futureDefaults على true.
  • backCompat
  • buildHttp
  • cacheUnaffected
  • css
  • deferImport
  • futureDefaults
  • html
  • lazyCompilation
  • outputModule
  • sourceImport
  • syncWebAssembly: يدعم WebAssembly القديم كما في webpack 4.
  • layers: يُفعِّل طبقات الوحدات والـ chunks، أُزيل ويعمل بلا خيارات إضافية منذ 5.102.0.
  • topLevelAwait: يُحوِّل الوحدة إلى وحدة async حين يُستعمَل await على المستوى الأعلى. ابتداءً من webpack 5.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

حدِّد موقع التخزين المؤقَّت للموارد البعيدة.

  • النوع

    • string
    • false
  • مثال

    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. استعمل الامتداد .module.css لتفعيل CSS Modules.

    5.103.0+

    يدعم 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+

Enable native HTML module support. Importing a .html file from JavaScript runs its tag references through the normal webpack pipeline, replacing the role html-loader has played for years. The flag registers the html module type on NormalModuleFactory and unlocks the HTML behaviors described below.

  • Type: boolean
  • Default: false

webpack.config.js

export default {
  // ...
  experiments: {
    html: true,
  },
};

Then import the HTML file from JavaScript. The default export is the processed HTML as a string, with all asset references resolved through webpack:

// src/index.js
import page from "./page.html";

document.documentElement.innerHTML = page;

Inline <style> tags

Inline <style> blocks inside an HTML module are routed through webpack's CSS pipeline as virtual CSS modules with exportType: "text". url() and @import references are resolved relative to the HTML file, and the processed CSS text is written back into the original <style> tag in the emitted HTML string.

<!-- 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"> and <style> with no type attribute are processed. Anything with a non-CSS type is passed through unchanged.

Inline <script> tags

Inline <script> bodies are routed through the same entry pipeline used for <script src>. Each <script> body becomes its own webpack entry: classic inline scripts are bundled as CommonJS, and <script type="module"> bodies are bundled as ESM. The tag in the emitted HTML is rewritten to <script src="…"> pointing at the generated chunk, with the body cleared.

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

The same behaviors that apply to external <script src> apply here too:

  • When output.module is enabled, classic inline <script> tags are auto-upgraded to type="module", matching the auto-upgrade for <script src>.
  • webpackIgnore works on inline <script> tags as well, leaving the original body untouched.
  • Non-JS type values such as application/ld+json and importmap pass through unchanged.

<script src> and <link rel="modulepreload">

<script src> and <link rel="modulepreload"> references inside an HTML module become real webpack entries. The emitted chunk URL is rewritten back into the HTML string, so hashed filenames work the same way they do for 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>

A few behaviors to keep in mind:

  • Multiple <script src> tags on the same page share a single runtime. Within each group (classic or type="module"), the leader holds the runtime and the rest declare dependOn on it.
  • <link rel="modulepreload"> entries stay independent and are never imported by sibling scripts, preserving "preload without execute" semantics.
  • When output.module is enabled, classic <script src> tags are auto-upgraded to <script type="module" src> so the emitted ES-module chunks load in the correct mode.
  • Non-JS script types (application/ld+json, importmap, …) and data URIs flow through unchanged and are not bundled as JS.

webpackIgnore magic comment

Placing an HTML <!-- webpackIgnore: true --> comment immediately before a tag tells webpack to skip URL resolution for that tag's src, href, srcset, and similar attributes. See the full description under 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: فعِّل التصريف الكسول لنقاط الدخول.
      • imports 5.20.0+: فعِّل التصريف الكسول للاستيرادات الديناميكية.
      • test 5.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,
  },
};
Edit this page·
« Previous
Stats

1 Contributor

RlxChap2