Experiments

experiments

boolean: false

experiments option was introduced in webpack 5 to empower users with the ability to activate and try out experimental features.

Available options:

  • asyncWebAssembly: Support the new WebAssembly according to the updated specification, it makes a WebAssembly module an async module. And it is enabled by default when experiments.futureDefaults is set to true.
  • backCompat
  • buildHttp
  • cacheUnaffected
  • css
  • deferImport
  • futureDefaults
  • html
  • lazyCompilation
  • outputModule
  • syncWebAssembly: Support the old WebAssembly like in webpack 4.
  • layers: Enable module and chunk layers, removed and works without additional options since 5.102.0.
  • topLevelAwait: Transforms a module into an async module when an await is used at the top level. Starting from webpack version 5.83.0 (however, in versions prior to that, you can enable it by setting experiments.topLevelAwait to true), this feature is enabled by default, removed and works without additional options since 5.102.0.

webpack.config.js

export default {
  // ...
  experiments: {
    asyncWebAssembly: true,
    buildHttp: true,
    lazyCompilation: true,
    outputModule: true,
    syncWebAssembly: true,
    topLevelAwait: true,
  },
};

experiments.backCompat

Enable backward-compat layer with deprecation warnings for many webpack 4 APIs.

  • Type: boolean
export default {
  // ...
  experiments: {
    backCompat: true,
  },
};

experiments.buildHttp

When enabled, webpack can build remote resources that begin with the http(s): protocol.

  • Type:

    • (string | RegExp | ((uri: string) => boolean))[]

      A shortcut for experiments.buildHttp.allowedUris.

    • HttpUriOptions

      {
        allowedUris: (string|RegExp|(uri: string) => boolean)[],
        cacheLocation?: false | string,
        frozen?: boolean,
        lockfileLocation?: string,
        upgrade?: boolean
      }
  • Available: 5.49.0+

  • Example

    webpack.config.js

    export default {
      // ...
      experiments: {
        buildHttp: true,
      },
    };
    // src/index.js
    import pMap1 from "https://cdn.skypack.dev/p-map";
    
    // with `buildHttp` enabled, webpack will build pMap1 like a regular local module
    console.log(pMap1);

experiments.buildHttp.allowedUris

A list of allowed URIs.

  • Type: (string|RegExp|(uri: string) => boolean)[]

  • Example

    webpack.config.js

    export default {
      // ...
      experiments: {
        buildHttp: {
          allowedUris: [
            "http://localhost:9990/",
            "https://raw.githubusercontent.com/",
          ],
        },
      },
    };

experiments.buildHttp.cacheLocation

Define the location for caching remote resources.

  • Type

    • string
    • false
  • Example

    webpack.config.js

    export default {
      // ...
      experiments: {
        buildHttp: {
          cacheLocation: false,
        },
      },
    };

By default webpack would use <compiler-name.>webpack.lock.data/ for caching, but you can disable it by setting its value to false.

Note that you should commit files under experiments.buildHttp.cacheLocation into a version control system as no network requests will be made during the production build.

experiments.buildHttp.frozen

Freeze the remote resources and lockfile. Any modification to the lockfile or resource contents will result in an error.

  • Type: boolean

experiments.buildHttp.lockfileLocation

Define the location to store the lockfile.

  • Type: string

By default webpack would generate a <compiler-name.>webpack.lock file>. Make sure to commit it into a version control system. During the production build, webpack will build those modules beginning with http(s): protocol from the lockfile and caches under experiments.buildHttp.cacheLocation.

experiments.buildHttp.proxy

Specify the proxy server to use for fetching remote resources.

  • Type: string

By default, Webpack would imply the proxy server to use for fetching remote resources from the http_proxy (case insensitive) environment variable. However, you can also specify one through the proxy option.

experiments.buildHttp.upgrade

Detect changes to remote resources and upgrade them automatically.

  • Type: boolean

experiments.css

Enable native CSS support. Note that it's an experimental feature still under development and will be enabled by default in webpack v6, however you can track the progress on GitHub.

  • Type: boolean

Experimental features:

  • CSS Modules support: webpack will generate a unique name for each CSS class. Use the .module.css extension for CSS Modules.

    5.103.0+

    Webpack natively supports the CSS Modules composes property, allowing you to compose classes from the same file, other CSS modules, or global classes:

    /* styles.module.css */
    .base {
      color: blue;
    }
    
    .button {
      composes: base;
      padding: 10px;
    }
    
    .primary {
      composes: button;
      background: blue;
    }
    
    /* Compose from another CSS module */
    .composed {
      composes: className from "./other.module.css";
    }
    
    /* Compose from global classes */
    .globalComposed {
      composes: global-class from global;
    }
  • 5.87.0+ Style-specific fields resolution in package.json files: webpack will look for style field in package.json files and use that if it exists for imports inside CSS files.

    For example, if you add @import 'bootstrap'; to your CSS file, webpack will look for bootstrap in node_modules and use the style field in package.json from there. If style field is not found, webpack will use the main field instead to preserve backward compatibility.

  • Content hash for CSS files: webpack will generate a content hash for CSS files and use it in the filename. This is useful for long-term caching.

  • CSS extraction: webpack will extract CSS into a separate file. This functionality replaces the need for mini-css-extract-plugin and css-loader, as it provides native support.

  • CSS imports: webpack will inline CSS imports into the generated CSS file.

  • Hot Module Reload (HMR): webpack supports HMR for CSS files. This means that changes made to CSS files will be reflected in the browser without a full page reload.

experiments.cacheUnaffected

Enable additional in-memory caching of modules which are unchanged and reference only unchanged modules.

  • Type: boolean

Defaults to the value of futureDefaults.

experiments.deferImport

Enable support of the tc39 proposal the import defer proposal. This allows deferring the evaluation of a module until its first use. This is useful to synchronously defer code execution when it's not possible to use import() due to its asynchronous nature.

  • Type: boolean

This feature requires the runtime environment to have Proxy (ES6) support.

Enables the following syntaxes:

import defer * as module from "module-name";
import * as module2 from /* webpackDefer: true */ "module-name2";

// Or using dynamic import
import.defer("module-name3");
import(/* webpackDefer: true */ "module-name4");

export function f() {
  // module-name is evaluated synchronously, then call doSomething() on it.
  module.doSomething();
}

Limitations of magic comments (/* webpackDefer: true */)

It's suggested to put the magic comment after the from keyword. Other positions may work, but have not been tested.

Putting the magic comment after the import keyword is incompatible with the filesystem cache.

import /* webpackDefer: true */ * as ns from "..."; // known broken
import * as ns from /* webpackDefer: true */ "..."; // recommended

You should make sure your loaders do not remove the magic comment.

TypeScript, Babel, SWC, and Flow.js can be configured to preserve the magic comment.

Esbuild is not compatible with this feature (see evanw/esbuild#1439 and evanw/esbuild#309), but it may support this in the future.

5.105.0+

import.defer() is now supported for ContextModule (the import path is a dynamic expression). See the lazy loading guide for examples.

experiments.futureDefaults

Use defaults of the next major webpack and show warnings in any problematic places.

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

Compile entrypoints and dynamic imports only when they are in use. It can be used for either Web or Node.js.

  • Type

    • boolean

    • object

      {
        // define a custom backend
        backend?: ((
          compiler: Compiler,
          callback: (err?: Error, api?: BackendApi) => void
        ) => void)
          | ((compiler: Compiler) => Promise<BackendApi>)
          | {
            /**
             * A custom client.
             */
            client?: string;
      
            /**
             * Specify where to listen to from the server.
             */
            listen?: number | ListenOptions | ((server: Server) => void);
      
            /**
             * Specify the protocol the client should use to connect to the server.
             */
            protocol?: "http" | "https";
      
            /**
             * Specify how to create the server handling the EventSource requests.
             */
            server?: ServerOptionsImport | ServerOptionsHttps | (() => Server);
          },
        entries?: boolean,
        imports?: boolean,
        test?: string | RegExp | ((module: Module) => boolean)
      }
      • backend: Customize the backend.
      • entries: Enable lazy compilation for entries.
      • imports 5.20.0+: Enable lazy compilation for dynamic imports.
      • test 5.20.0+: Specify which imported modules should be lazily compiled.
  • Available: 5.17.0+

  • Example 1:

    export default {
      // …
      experiments: {
        lazyCompilation: true,
      },
    };
  • Example 2:

    export default {
      // …
      experiments: {
        lazyCompilation: {
          // disable lazy compilation for dynamic imports
          imports: false,
    
          // disable lazy compilation for entries
          entries: false,
    
          // do not lazily compile moduleB
          test: (module) => !/moduleB/.test(module.nameForCondition()),
        },
      },
    };

experiments.outputModule

boolean

Once enabled, webpack will output ECMAScript module syntax whenever possible. For instance, import() to load chunks, ESM exports to expose chunk data, among others.

export default {
  experiments: {
    outputModule: true,
  },
};
Edit this page·
« Previous
Stats

6 Contributors

EugeneHlushkowizardofhogwartschenxsananshumanvsnitin315burhanuday