Printable

AutomaticPrefetchPlugin

The AutomaticPrefetchPlugin discovers all modules from the previous compilation upfront while watching for changes, trying to improve the incremental build times. Compared to PrefetchPlugin which discovers a single module upfront.

webpack.config.js

module.exports = {
  // ...
  plugins: [new webpack.AutomaticPrefetchPlugin()],
};

BannerPlugin

Adds a banner to the top of each generated chunk.

const webpack = require('webpack');

new webpack.BannerPlugin(banner);
// or
new webpack.BannerPlugin(options);

Options

{
  banner: string | function, // the banner as string or function, it will be wrapped in a comment
  raw: boolean, // if true, banner will not be wrapped in a comment
  entryOnly: boolean, // if true, the banner will only be added to the entry chunks
  test: string | RegExp | [string, RegExp], // Include all modules that pass test assertion.
  include: string | RegExp | [string, RegExp], // Include all modules matching any of these conditions.
  exclude: string | RegExp | [string, RegExp], // Exclude all modules matching any of these conditions.
  footer?: boolean, // if true, the banner will be placed at the end of the compilation
  stage?: number, // the stage of the compilation in which the banner should be injected
}

Usage

import webpack from 'webpack';

// string
new webpack.BannerPlugin({
  banner: 'hello world',
});

// function
new webpack.BannerPlugin({
  banner: (yourVariable) => {
    return `yourVariable: ${yourVariable}`;
  },
});

// It will add the banner message after minimizers and any asset manipulation
new webpack.BannerPlugin({
  raw: true,
  banner: '/* banner is a string */',
  stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT,
});

Placeholders

Since webpack 2.5.0, placeholders are evaluated in the banner string:

import webpack from 'webpack';

new webpack.BannerPlugin({
  banner:
    'fullhash:[fullhash], chunkhash:[chunkhash], name:[name], filebase:[filebase], query:[query], file:[file]',
});

ChunksWebpackPlugin

GitHub Workflow Status (branch) Coverage Status Npm downloads

The chunks-webpack-plugin creates HTML files with entry points and chunks relations to serve your webpack bundles. It is suitable with multi-page applications that contain multiple entry points.

Since webpack 4, SplitChunksPlugin offers the possibility to optimizes all chunks. It can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks. See the webpack documentation of splitChunks.chunks for details.

splitChunks.chunks option can be set to automatically generate new chunks associated with an entry point. For example, entry points a.js and b.js share common code with the file vendors~a~b.js.

With multiple entry points, it can be difficult to identify relation between the auto-generated chunks and entry points.

chunks-webpack-plugin parses the webpack compilation entry points to get all files associated with the entry points. Then, it generates HTML files which include all assets filtered by an entry point and thechunks-manifest.json file.

Zero configuration

It works without configuration. For advanced usage, see the using configuration section.

Installation

chunks-webpack-plugin is available on npm as chunks-webpack-plugin and as chunks-webpack-plugin on GitHub.

npm install chunks-webpack-plugin --save-dev
yarn add chunks-webpack-plugin --dev

[!WARNING] Plugin chunks-webpack-plugin@10 is ESM only. [!NOTE] Minimum supported Node.js version is 16.20.0 and Webpack >=5.10.3.

Example

The project includes a minimalist example in the ./example directory. Run the npm run build:example command to execute the Webpack example and see the plugin's implementation in action.

Basic usage

chunks-webpack-plugin will generate two HTML files for each entry point. Each filename contains the entry point name, the {{entry}} placeholder is automatically replaced.

  • {{entry}}-styles.html: contains all HTML <link> tags
  • {{entry}}-scripts.html: contains all HTML <script> tags

First, let's add the plugin to the webpack configuration.

webpack.config.js

import ChunksWebpackPlugin from 'chunks-webpack-plugin';

export default {
  plugins: [new ChunksWebpackPlugin()]
};

HTML files are built in the output path directory with the rest of the webpack compilation.

Now you can include the generated HTML files into your HTML page templates. You can do it with e.g. Twig.

main-styles.html

<link rel="stylesheet" href="main.css" />

main-scripts.html

<script defer src="main.js"></script>

Using a configuration

You can pass a configuration object to chunks-webpack-plugin to override the default settings.

filename

Type:

type filename = string;

Default: '[name]-[type].html'

Tells the plugin whether to personalize the filename of the generated files. Files are processed by the webpack compilation and generated in the output path directory. The placeholder [name] is automatically replaced by entry points names and [type] by styles|scripts.

new ChunksWebpackPlugin({
  filename: 'templates/[name]-[type].html'
});

[!NOTE] The filename can contain directories, which will be created automatically.

templateStyle

Type:

type templateStyle = (name: string, entryName: string) => string;

Default:

(name) => `<link rel="stylesheet" href="${name}" />`;

Tells the plugin whether to personalize the default template for the HTML <style> tags. For example, add additional attributes or a CDN prefix.

export default {
  plugins: [
    new ChunksWebpackPlugin({
      templateStyle: (name) => `<link rel="stylesheet" href="https://cdn.domain.com${name}" />`
    })
  ]
};

templateScript

Type:

type templateScript = (name: string, entryName: string) => string;

Default:

(name) => `<script defer src="${name}"></script>`;

Tells the plugin whether to personalize the default template for the HTML <script> tags. For example, add additional attributes or a CDN prefix.

export default {
  plugins: [
    new ChunksWebpackPlugin({
      templateScript: (name) => `<script defer src="https://cdn.domain.com${name}"></script>`
    })
  ]
};

generateChunksManifest

Type:

type generateChunksManifest = boolean;

Default: false

Tells the plugin whether to generate the chunks-manifest.json. The file contains the list of all chunks grouped by entry points. See the chunks-manifest.json example.

export default {
  plugins: [
    new ChunksWebpackPlugin({
      generateChunksManifest: true
    })
  ]
};

generateChunksFiles

Type:

type generateChunksFiles = boolean;

Default: true

Tells the plugin whether to generate the HTML files.

export default {
  plugins: [
    new ChunksWebpackPlugin({
      generateChunksFiles: false
    })
  ]
};

[!WARNING] When set to false, HTML files will not be generated. It can only be useful together with generateChunksManifest option set to true for custom generation of the HTML files.


Multiple entrypoints example

Multiple entrypoints example

Example of the webpack configuration with multiple entry points which share common code with the splitChunks option.

import ChunksWebpackPlugin from 'chunks-webpack-plugin';
import path from 'node:path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  entry: {
    home: 'home.js',
    news: 'news.js'
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist')
  },
  plugins: [new ChunksWebpackPlugin()],
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
};

The plugin will generate all files in the output path directory:

home-styles.html

<link rel="stylesheet" href="vendors~home~news.css" />
<link rel="stylesheet" href="home.css" />

home-scripts.html

<script defer src="vendors~home~news.js"></script>
<script defer src="home.js"></script>

news-styles.html

<link rel="stylesheet" href="vendors~home~news.css" />
<link rel="stylesheet" href="news.css" />

news-scripts.html

<script defer src="vendors~home~news.js"></script>
<script defer src="news.js"></script>

License

chunks-webpack-plugin is licensed under the MIT License.

Created with ♥ by @yoriiis.

CommonsChunkPlugin

The CommonsChunkPlugin is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points.

By separating common modules from bundles, the resulting chunked file can be loaded once initially, and stored in cache for later use. This results in page speed optimizations as the browser can quickly serve the shared code from cache, rather than being forced to load a larger bundle whenever a new page is visited.

new webpack.optimize.CommonsChunkPlugin(options);

Options

{
  name: string, // or
  names: string[],
  // The chunk name of the commons chunk. An existing chunk can be selected by passing a name of an existing chunk.
  // If an array of strings is passed this is equal to invoking the plugin multiple times for each chunk name.
  // If omitted and `options.async` or `options.children` is set all chunks are used, otherwise `options.filename`
  // is used as chunk name.
  // When using `options.async` to create common chunks from other async chunks you must specify an entry-point
  // chunk name here instead of omitting the `option.name`.

  filename: string,
  // The filename template for the commons chunk. Can contain the same placeholders as `output.filename`.
  // If omitted the original filename is not modified (usually `output.filename` or `output.chunkFilename`).
  // This option is not permitted if you're using `options.async` as well, see below for more details.

  minChunks: number|Infinity|function(module, count) => boolean,
  // The minimum number of chunks which need to contain a module before it's moved into the commons chunk.
  // The number must be greater than or equal 2 and lower than or equal to the number of chunks.
  // Passing `Infinity` creates the commons chunk, but moves no modules into it.
  // By providing a `function` you can add custom logic. (Defaults to the number of chunks)

  chunks: string[],
  // Select the source chunks by chunk names. The chunk must be a child of the commons chunk.
  // If omitted all entry chunks are selected.

  children: boolean,
  // If `true` all children of the commons chunk are selected

  deepChildren: boolean,
  // If `true` all descendants of the commons chunk are selected

  async: boolean|string,
  // If `true` a new async commons chunk is created as child of `options.name` and sibling of `options.chunks`.
  // It is loaded in parallel with `options.chunks`.
  // Instead of using `option.filename`, it is possible to change the name of the output file by providing
  // the desired string here instead of `true`.

  minSize: number,
  // Minimum size of all common module before a commons chunk is created.
}

Examples

Commons chunk for entries

Generate an extra chunk, which contains common modules shared between entry points.

new webpack.optimize.CommonsChunkPlugin({
  name: 'commons',
  // (the commons chunk name)

  filename: 'commons.js',
  // (the filename of the commons chunk)

  // minChunks: 3,
  // (Modules must be shared between 3 entries)

  // chunks: ["pageA", "pageB"],
  // (Only use these entries)
});

You must load the generated chunk before the entry point:

<script src="commons.js" charset="utf-8"></script>
<script src="entry.bundle.js" charset="utf-8"></script>

Explicit vendor chunk

Split your code into vendor and application.

module.exports = {
  //...
  entry: {
    vendor: ['jquery', 'other-lib'],
    app: './entry',
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      // filename: "vendor.js"
      // (Give the chunk a different name)

      minChunks: Infinity,
      // (with more entries, this ensures that no other module
      //  goes into the vendor chunk)
    }),
  ],
};
<script src="vendor.js" charset="utf-8"></script>
<script src="app.js" charset="utf-8"></script>

Move common modules into the parent chunk

With Code Splitting, multiple child chunks of an entry chunk can have common dependencies. To prevent duplication these can be moved into the parent. This reduces overall size, but does have a negative effect on the initial load time. If it is expected that users will need to download many sibling chunks, i.e. children of the entry chunk, then this should improve load time overall.

new webpack.optimize.CommonsChunkPlugin({
  // names: ["app", "subPageA"]
  // (choose the chunks, or omit for all chunks)

  children: true,
  // (select all children of chosen chunks)

  // minChunks: 3,
  // (3 children must share the module before it's moved)
});

Extra async commons chunk

Similar to the above one, but instead of moving common modules into the parent (which increases initial load time) a new async-loaded additional commons chunk is used. This is automatically downloaded in parallel when the additional chunk is downloaded.

new webpack.optimize.CommonsChunkPlugin({
  name: 'app',
  // or
  names: ['app', 'subPageA'],
  // the name or list of names must match the name or names
  // of the entry points that create the async chunks

  children: true,
  // (use all children of the chunk)

  async: true,
  // (create an async commons chunk)

  minChunks: 3,
  // (3 children must share the module before it's separated)
});

Passing the minChunks property a function

You also have the ability to pass the minChunks property a function. This function is called by the CommonsChunkPlugin and calls the function with module and count arguments.

The module argument represents each module in the chunks you have provided via the name/names property. module has the shape of a NormalModule, which has two particularly useful properties for this use case:

  • module.context: The directory that stores the file. For example: '/my_project/node_modules/example-dependency'
  • module.resource: The name of the file being processed. For example: '/my_project/node_modules/example-dependency/index.js'

The count argument represents how many chunks the module is used in.

This option is useful when you want to have fine-grained control over how the CommonsChunk algorithm determines where modules should be moved to.

new webpack.optimize.CommonsChunkPlugin({
  name: 'my-single-lib-chunk',
  filename: 'my-single-lib-chunk.js',
  minChunks: function (module, count) {
    // If module has a path, and inside of the path exists the name "somelib",
    // and it is used in 3 separate chunks/entries, then break it out into
    // a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
    return module.resource && /somelib/.test(module.resource) && count === 3;
  },
});

As seen above, this example allows you to move only one lib to a separate file if and only if all conditions are met inside the function.

This concept may be used to obtain implicit common vendor chunks:

new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks: function (module) {
    // this assumes your vendor imports exist in the node_modules directory
    return module.context && module.context.includes('node_modules');
  },
});

Manifest file

To extract the webpack bootstrap logic into a separate file, use the CommonsChunkPlugin on a name which is not defined as entry. Commonly the name manifest is used. See the caching guide for details.

new webpack.optimize.CommonsChunkPlugin({
  name: 'manifest',
  minChunks: Infinity,
});

Combining implicit common vendor chunks and manifest file

Since the vendor and manifest chunk use a different definition for minChunks, you need to invoke the plugin twice:

[
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: function (module) {
      return module.context && module.context.includes('node_modules');
    },
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: 'manifest',
    minChunks: Infinity,
  }),
];

More Examples

CompressionWebpackPlugin

npm node tests cover discussion size

Prepare compressed versions of assets to serve them with Content-Encoding.

Getting Started

To begin, you'll need to install compression-webpack-plugin:

npm install compression-webpack-plugin --save-dev

or

yarn add -D compression-webpack-plugin

or

pnpm add -D compression-webpack-plugin

Then add the plugin to your webpack config. For example:

webpack.config.js

const CompressionPlugin = require("compression-webpack-plugin");

module.exports = {
  plugins: [new CompressionPlugin()],
};

Finally, run webpack using the method you normally use (e.g., via CLI or an npm script).

Options

test

Type:

type test = string | RegExp | (string | RegExp)[];

Default: undefined

Include all assets that pass test assertion.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      test: /\.js(\?.*)?$/i,
    }),
  ],
};

include

Type:

type include = string | RegExp | (string | RegExp)[];

Default: undefined

Include all assets matching any of these conditions.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      include: /\/includes/,
    }),
  ],
};

exclude

Type:

type exclude = string | RegExp | (string | RegExp)[];

Default: undefined

Exclude all assets matching any of these conditions.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      exclude: /\/excludes/,
    }),
  ],
};

algorithm

Type:

type algorithm =
  | string
  | ((
      input: Buffer,
      options: CompressionOptions,
      callback: (
        error: Error | null | undefined,
        result:
          | string
          | ArrayBuffer
          | SharedArrayBuffer
          | Uint8Array
          | readonly number[]
          | {
              valueOf(): ArrayBuffer | SharedArrayBuffer;
            }
          | {
              valueOf(): string | Uint8Array | readonly number[];
            }
          | {
              valueOf(): string;
            }
          | {
              [Symbol.toPrimitive](hint:%20%22string%22): string;
            },
      ) => void,
    ) => void);

Defines the compression algorithm or function to use. Defaults to gzip.

[!NOTE]

If you use a custom function for the algorithm option, the default value of compressionOptions will be an empty object {}.

string

The algorithm is based on the Node.js zlib module.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      algorithm: "gzip",
    }),
  ],
};

function

Allow you to specify a custom compression function.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      algorithm(input, compressionOptions, callback) {
        return compressionFunction(input, compressionOptions, callback);
      },
    }),
  ],
};

compressionOptions

Type:

interface compressionOptions {
  flush?: number;
  finishFlush?: number;
  chunkSize?: number;
  windowBits?: number;
  level?: number;
  memLevel?: number;
  strategy?: number;
  dictionary?: Buffer | TypedArray | DataView | ArrayBuffer;
  info?: boolean;
  maxOutputLength?: number;
}

Default: { level: 9 }

Compression options for algorithm.

You can find all available options in the zlib documentation.

[!NOTE]

If you use a custom function for the algorithm option, the default value of compressionOptions will be an empty object {}.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      compressionOptions: { level: 1 },
    }),
  ],
};

threshold

Type:

type threshold = number;

Default: 0

Only assets larger than this size (in bytes) are processed.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      threshold: 8192,
    }),
  ],
};

minRatio

Type:

type minRatio = number;

Default: 0.8

Only assets that compress better than this ratio are processed (minRatio = Compressed Size / Original Size). For example, if you have a image.png file with a size of 1024 bytes, and its compressed version is of 768 bytes, the minRatio is 0.75. In other words, assets will be processed only when the ratio of Compressed Size / Original Size is less than the specified minRatio.

You can use a value of 1 to process assets that are smaller than or equal to the original size.

Use a value of Infinity to process all assets, even if they are larger than the original size or their original size is 0 bytes (useful when you are pre-zipping all assets for AWS).

Use a value of Number.MAX_SAFE_INTEGER to process all assets even if they are larger than the original size, excluding assets with their original size is 0 bytes.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      // Compress all assets, including files with `0` bytes size
      // minRatio: Infinity

      // Compress all assets, excluding files with `0` bytes size
      // minRatio: Number.MAX_SAFE_INTEGER

      minRatio: 0.8,
    }),
  ],
};

filename

Type:

type filename = string | ((pathdata: PathData) => string);

Default: "[path][base].gz"

The target asset filename.

string

For example, given an asset path: assets/images/image.png?foo=bar#hash:

[path] is replaced with the directories of the original asset, including the trailing / (assets/images/).

[file] is replaced with the path of the original asset (assets/images/image.png).

[base] is replaced with the base name ([name] + [ext]) of the original asset (image.png).

[name] is replaced with the name of the original asset (image).

[ext] is replaced with the extension of the original asset, including the . (.png).

[query] is replaced with the query of the original asset, including the ? (?foo=bar).

[fragment] is replaced with the fragment (in the concept of URL it is called hash) of the original asset (#hash).

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename: "[path][base].gz",
    }),
  ],
};

function

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename(pathData) {
        // The `pathData` argument contains all placeholders - `path`/`name`/`ext`/etc
        // Available properties described above, for the `String` notation
        if (/\.svg$/.test(pathData.filename)) {
          return "assets/svg/[path][base].gz";
        }

        return "assets/js/[path][base].gz";
      },
    }),
  ],
};

deleteOriginalAssets

Type:

type deleteOriginalAssets =
  | boolean
  | "keep-source-map"
  | ((name: string) => boolean);

Default: false

Determines whether the original (uncompressed) assets should be deleted after compression.

  • If set to true , all original assets will be deleted.

  • If set to "keep-source-map", all original assets except source maps (.map files) will be deleted.

  • If a function is provided, it will be called with each asset’s name and should return true to delete the asset or false to keep it.

Example:

module.exports = {
  plugins: [
    new CompressionPlugin({
      deleteOriginalAssets: (assetName) =>
        // Delete all assets except images
        !assetName.endsWith(".png") && !assetName.endsWith(".jpg"),
    }),
  ],
};

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      deleteOriginalAssets: true,
    }),
  ],
};

To exclude sourcemaps from compression:

module.exports = {
  plugins: [
    new CompressionPlugin({
      exclude: /.map$/,
      deleteOriginalAssets: "keep-source-map",
    }),
  ],
};

Using a custom function:

module.exports = {
  plugins: [
    new CompressionPlugin({
      exclude: /.map$/,
      deleteOriginalAssets: (name) => {
        if (/\.js$/.test(name)) {
          return false;
        }

        return true;
      },
    }),
  ],
};

Examples

Using Zopfli

Prepare compressed versions of assets using the zopfli library.

[!NOTE]

@gfx/zopfli requires at least Node.js version 8.

To begin, you'll need to install @gfx/zopfli:

$ npm install @gfx/zopfli --save-dev

webpack.config.js

const zopfli = require("@gfx/zopfli");

module.exports = {
  plugins: [
    new CompressionPlugin({
      compressionOptions: {
        numiterations: 15,
      },
      algorithm(input, compressionOptions, callback) {
        return zopfli.gzip(input, compressionOptions, callback);
      },
    }),
  ],
};

Using Brotli

Brotli is a compression algorithm originally developed by Google, and offers compression superior to gzip.

Node.js v10.16.0 and later includes native support for Brotli compression in its zlib module.

You can take advantage of this built-in support for Brotli in Node 10.16.0 and later by just passing in the appropriate algorithm to the CompressionPlugin:

webpack.config.js

const zlib = require("node:zlib");

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename: "[path][base].br",
      algorithm: "brotliCompress",
      test: /\.(js|css|html|svg)$/,
      compressionOptions: {
        params: {
          [zlib.constants.BROTLI_PARAM_QUALITY]: 11,
        },
      },
      threshold: 10240,
      minRatio: 0.8,
      deleteOriginalAssets: false,
    }),
  ],
};

[!NOTE] Brotli’s BROTLI_PARAM_QUALITY option is functionally equivalent to zlib’s level option. You can find all Brotli’s options in the relevant part of the zlib module documentation.

Using Zstandard

Zstandard (zstd) is a fast lossless compression algorithm, targeting real-time compression scenarios at zlib-level and better compression ratios.

Node.js 22.15.0 and later includes native support for Zstandard compression in its zlib module.

You can take advantage of this built-in support for zstd in Node 22.15.0 and later by just passing in the appropriate algorithm to the CompressionPlugin:

webpack.config.js

const zlib = require("node:zlib");

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename: "[path][base].zst",
      algorithm: "zstdCompress",
      test: /\.(js|css|html|svg)$/,
      compressionOptions: {
        params: {
          [zlib.constants.ZSTD_c_compressionLevel]: 10,
        },
      },
      threshold: 10240,
      minRatio: 0.8,
      deleteOriginalAssets: false,
    }),
  ],
};

You can find all Zstandard's options in the relevant part of the zlib module documentation.

Multiple compressed versions of assets for different algorithm

webpack.config.js

const zlib = require("node:zlib");

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename: "[path][base].gz",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8,
    }),
    new CompressionPlugin({
      filename: "[path][base].br",
      algorithm: "brotliCompress",
      test: /\.(js|css|html|svg)$/,
      compressionOptions: {
        params: {
          [zlib.constants.BROTLI_PARAM_QUALITY]: 11,
        },
      },
      threshold: 10240,
      minRatio: 0.8,
    }),
  ],
};

Contributing

We welcome contributions!

Please take a moment to read our contributing guidelines if you haven't yet done so.

CONTRIBUTING

License

MIT

ContextExclusionPlugin

Context refers to a require with an expression such as require('./locale/' + name + '.json').

The ContextExclusionPlugin allows you to exclude context. Provide RegExp as an argument when initializing the Plugin to exclude all context that matches it.

webpack.config.js

module.exports = {
  plugins: [new webpack.ContextExclusionPlugin(/dont/)],
};

ContextReplacementPlugin

Context refers to a require with an expression such as require('./locale/' + name + '.json'). When encountering such an expression, webpack infers the directory ('./locale/') and a regular expression (/^.*\.json$/). Since the name is not known at compile time, webpack includes every file as module in the bundle.

The ContextReplacementPlugin allows you to override the inferred information. There are various ways to configure the plugin:

Usage

new webpack.ContextReplacementPlugin(
  resourceRegExp: RegExp,
  newContentResource?: string,
  newContentRecursive?: boolean,
  newContentRegExp?: RegExp
)

If the resource (directory) matches resourceRegExp, the plugin replaces the default resource, recursive flag or generated regular expression with newContentResource, newContentRecursive or newContextRegExp respectively. If newContentResource is relative, it is resolved relative to the previous resource.

Here's a small example to restrict module usage:

new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /de|fr|hu/);

The moment/locale context is restricted to files matching /de|fr|hu/. Thus only those locales are included (see this issue for more information).

Content Callback

new webpack.ContextReplacementPlugin(
  resourceRegExp: RegExp,
  newContentCallback: (data) => void
);

The newContentCallback function is given a data object of the ContextModuleFactory and is expected to overwrite the request attribute of the supplied object.

Using this callback we can dynamically redirect requests to a new location:

new webpack.ContextReplacementPlugin(/^\.\/locale$/, (context) => {
  if (!/\/moment\//.test(context.context)) return;

  Object.assign(context, {
    regExp: /^\.\/\w+/,
    request: '../../locale', // resolved relatively
  });
});

Other Options

The newContentResource and newContentCreateContextMap parameters are also available:

new webpack.ContextReplacementPlugin(
  resourceRegExp: RegExp,
  newContentResource: string,
  newContentCreateContextMap: object // mapping runtime-request (userRequest) to compile-time-request (request)
);

These two parameters can be used together to redirect requests in a more targeted way. The newContentCreateContextMap allows you to map runtime requests to compile requests in the form of an object:

new ContextReplacementPlugin(/selector/, './folder', {
  './request': './request',
  './other-request': './new-request',
});

CopyWebpackPlugin

npm node tests cover discussion size

Copies existing individual files or entire directories to the build directory.

Getting Started

To begin, you'll need to install copy-webpack-plugin:

npm install copy-webpack-plugin --save-dev

or

yarn add -D copy-webpack-plugin

or

pnpm add -D copy-webpack-plugin

Then add the plugin to your webpack configuration. For example:

webpack.config.js

const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        { from: "source", to: "dest" },
        { from: "other", to: "public" },
      ],
    }),
  ],
};

[!NOTE]

copy-webpack-plugin is not designed to copy files generated during the build process. Instead, it is meant to copy files that already exist in the source tree, as part of the build process.

[!NOTE]

If you want webpack-dev-server to write files to the output directory during development, you can enable the writeToDisk option or use the write-file-webpack-plugin.

[!NOTE]

You can get the original source filename from the Asset Objects in the webpack stats API.

Options

The plugin's usage:

webpack.config.js

const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        { from: "source", to: "dest" },
        "path/to/source", // Absolute or relative path, can be files, directories or globs. See examples below.
      ],
      options: {
        concurrency: 100,
      },
    }),
  ],
};

Patterns

from

Type:

type from = string;

Default: undefined

Glob or path from where we copy files. Globs follow the fast-glob pattern-syntax. Note: Globs must be a string.

[!WARNING]

Don't use directly \\ in from option if it is a glob (i.e path\to\file.ext) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use / instead, or use Node's path utilities to normalize paths.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        "relative/path/to/file.ext",
        "relative/path/to/dir",
        path.resolve(__dirname, "src", "file.ext"),
        path.resolve(__dirname, "src", "dir"),
        "**/*",
        {
          from: "**/*",
        },
        // If absolute path is a `glob` we replace backslashes with forward slashes, because only forward slashes can be used in the `glob`
        path.posix.join(
          path.resolve(__dirname, "src").replaceAll("\\", "/"),
          "*.txt",
        ),
      ],
    }),
  ],
};
For windows

If you're using an absolute file or folder path in the from option on Windows, you can use windows path segment (\\)

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, "file.txt"),
        },
      ],
    }),
  ],
};

However, when writing glob expressions, always use forward slashes. See the fast-glob manual for more details.

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          // If absolute path is a `glob` we replace backslashes with forward slashes, because only forward slashes can be used in the `glob`
          from: path.posix.join(
            path.resolve(__dirname, "fixtures").replaceAll("\\", "/"),
            "*.txt",
          ),
        },
      ],
    }),
  ],
};

The behavior of the context option varies depending on whether the from value is a glob, file or dir. See more examples.

to

Type:

type to =
  | string
  | ((pathData: { context: string; absoluteFilename?: string }) => string);

Default: compiler.options.output

string

Specifies the output path.

[!WARNING]

Don't use directly \\ in the to path (i.e path\to\dest) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use / instead, or use Node's path utilities to normalize paths.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "**/*",
          to: "relative/path/to/dest/",
        },
        {
          from: "**/*",
          to: "/absolute/path/to/dest/",
        },
        {
          from: "**/*",
          to: "[path][name].[contenthash][ext]",
        },
      ],
    }),
  ],
};
function

Allows to modify the writing path.

[!WARNING]

Don't use directly \\ in to (i.e path\to\newFile) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use / instead, or use Node's path utilities to normalize paths.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to({ context, absoluteFilename }) {
            return "dest/newPath/[name][ext]";
          },
        },
      ],
    }),
  ],
};

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to({ context, absoluteFilename }) {
            return Promise.resolve("dest/newPath/[name][ext]");
          },
        },
      ],
    }),
  ],
};

context

Type:

type context = string;

Default: options.context|compiler.options.context

Defines the base directory used for two purposes:

  1. It is prepended to the from path.

  2. It is removed from the beginning of the result path(s).

[!WARNING]

Don't use directly \\ in to (i.e path\to\newFile) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use / instead, or use Node's path utilities to normalize paths.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.txt",
          to: "dest/",
          context: "app/",
        },
      ],
    }),
  ],
};

The context can be an absolute or relative path. If it's relative, then it will be converted to an absolute path based on compiler.options.context.

You should explicitly define context when from uses a glob pattern. Otherwise, the plugin sets it automatically based on the nature of from:

  • If from is a file, then context defaults to the file’s directory. The result path will be just the filename alone.

  • If from is a directory, context is set to the same directory. The result paths include the directory’s contents (including subdirectories), relative to it.

The use of context is illustrated by these examples.

globOptions

[!WARNING]

The onlyDirectories does not work because the plugin is designed to copy files, not directories alone.

Type:

type globOptions = import("tinyglobby").GlobOptions;

Default: undefined

Allows you to configure the glob pattern matching library used by the plugin. See the list of supported options To exclude files from being copied, use the globOptions.ignore option

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "public/**/*",
          globOptions: {
            dot: true,
            gitignore: true,
            ignore: ["**/file.*", "**/ignored-directory/**"],
          },
        },
      ],
    }),
  ],
};

filter

Type:

type filter = (filepath: string) => boolean;

Default: undefined

[!NOTE]

To ignore files by path (e.g., by extension or name), prefer using the [globOptions.ignore] option.

webpack.config.js

const fs = require("node:fs").promise;

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "public/**/*",
          filter: async (resourcePath) => {
            const data = await fs.promises.readFile(resourcePath);
            const content = data.toString();

            if (content === "my-custom-content") {
              return false;
            }

            return true;
          },
        },
      ],
    }),
  ],
};

toType

Type:

type toType = "dir" | "file" | "template";

Default: undefined

Determines the type of the to option — whether it's a directory, file, or template. Sometimes it is hard to say what is to, example path/to/dir-with.ext. If you want to copy files in directory you should explicitly set the type to dir. In most cases, the plugin will automatically determine the correct type, so you typically don't need to set this option manually.

NameTypeDefaultDescription
'dir'stringundefinedUsed to has no extension or ends with a '/'.
'file'stringundefinedUsed when to is a file path that is not a directory or template.
'template'stringundefinedUsed when to contains a template pattern
'dir'

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "path/to/file.txt",
          to: "directory/with/extension.ext",
          toType: "dir",
        },
      ],
    }),
  ],
};
'file'

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "path/to/file.txt",
          to: "file/without/extension",
          toType: "file",
        },
      ],
    }),
  ],
};
'template'

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/",
          to: "dest/[name].[contenthash][ext]",
          toType: "template",
        },
      ],
    }),
  ],
};

force

Type:

type force = boolean;

Default: false

Overwrites files that already exist in compilation.assets (typically added by other plugins or loaders).

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/**/*",
          to: "dest/",
          force: true,
        },
      ],
    }),
  ],
};

priority

Type:

type priority = number;

Default: 0

Allows to specify the priority of copying files with the same destination name. Files for patterns with higher priority will be copied later. To enable overwriting, the force option must be set to true. webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        // Copied second and will overwrite "dir_2/file.txt"
        {
          from: "dir_1/file.txt",
          to: "newfile.txt",
          force: true,
          priority: 10,
        },
        // Copied first
        {
          from: "dir_2/file.txt",
          to: "newfile.txt",
          priority: 5,
        },
      ],
    }),
  ],
};

transform

Type:

type transform =
  | {
      transformer: (input: string, absoluteFilename: string) => string | Buffer;
      cache?: boolean | TransformerCacheObject | undefined;
    }
  | ((input: string, absoluteFilename: string) => string | Buffer);

Default: undefined

Allows you to modify the contents of a file before it is written to the output directory.

function

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          // The `content` argument is a [`Buffer`](https://nodejs.org/api/buffer.html) object, it could be converted to a `String` to be processed using `content.toString()`
          // The `absoluteFrom` argument is a `String`, it is absolute path from where the file is being copied
          transform(content, absoluteFrom) {
            return optimize(content);
          },
        },
      ],
    }),
  ],
};
object
NameDefaultDescription
transformerundefinedAllows you to modify the contents of the file.
cachefalseEnables caching for transform. You can use transform: { cache: { key: 'my-cache-key' } } to manually invalidate the cache when needed.
transformer

Type:

type transformer = (input: string, absoluteFilename: string) => string;

Default: undefined

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          // The `content` argument is a [`Buffer`](https://nodejs.org/api/buffer.html) object, it could be converted to a `String` to be processed using `content.toString()`
          // The `absoluteFrom` argument is a `String`, it is absolute path from where the file is being copied
          transform: {
            transformer(content, absoluteFrom) {
              return optimize(content);
            },
          },
        },
      ],
    }),
  ],
};

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          transform: {
            transformer(content, path) {
              return Promise.resolve(optimize(content));
            },
          },
        },
      ],
    }),
  ],
};
cache

Type:

type cache =
  | boolean
  | {
      keys: Record<string, any>;
    }
  | {
      keys: (
        defaultCacheKeys: Record<string, any>,
        absoluteFilename: string,
      ) => Promise<Record<string, any>>;
    }
  | undefined;

Default: false

webpack.config.js

Enable or disable caching and configure its behavior. By default, the cache directory is located at: node_modules/.cache/copy-webpack-plugin.

boolean

Enables/Disable transform caching.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          transform: {
            transformer(content, path) {
              return optimize(content);
            },
            cache: true,
          },
        },
      ],
    }),
  ],
};
object

Enables transform caching and setup invalidation keys.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          transform: {
            transformer(content, path) {
              return optimize(content);
            },
            cache: {
              keys: {
                // May be useful for invalidating cache based on external values
                // For example, you can invalid cache based on `process.version` - { node: process.version }
                key: "value",
              },
            },
          },
        },
      ],
    }),
  ],
};

You can setup invalidation keys using a function.

Simple function:

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          transform: {
            transformer(content, path) {
              return optimize(content);
            },
            cache: {
              keys: (defaultCacheKeys, absoluteFrom) => {
                const keys = getCustomCacheInvalidationKeysSync();

                return {
                  ...defaultCacheKeys,
                  keys,
                };
              },
            },
          },
        },
      ],
    }),
  ],
};

Async function:

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          transform: {
            transformer(content, path) {
              return optimize(content);
            },
            cache: {
              keys: async (defaultCacheKeys, absoluteFrom) => {
                const keys = await getCustomCacheInvalidationKeysAsync();

                return {
                  ...defaultCacheKeys,
                  keys,
                };
              },
            },
          },
        },
      ],
    }),
  ],
};

transformAll

Type:

type transformAll = (
  data: {
    data: Buffer;
    sourceFilename: string;
    absoluteFilename: string;
  }[],
) => string[];

Default: undefined

Allows you to modify the contents of multiple files and save the combined result into a single file.

[!NOTE]

The to option must be specified and point to a file. Only the [contenthash] and [fullhash] template strings are allowed in the filename.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/**/*.txt",
          to: "dest/file.txt",
          // The `assets` argument is an array of assets matched by the pattern `from` ("src/**/*.txt")
          transformAll(assets) {
            const result = assets.reduce((accumulator, asset) => {
              // The asset content can be obtained from `asset.source` using `source` method.
              // The asset content is a [`Buffer`](https://nodejs.org/api/buffer.html) object, it could be converted to a `String` to be processed using `content.toString()`
              const content = asset.data;

              accumulator = `${accumulator}${content}\n`;
              return accumulator;
            }, "");

            return result;
          },
        },
      ],
    }),
  ],
};

noErrorOnMissing

Type:

type noErrorOnMissing = boolean;

Default: false

Doesn't generate an error if file(s) are missing.

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, "missing-file.txt"),
          noErrorOnMissing: true,
        },
      ],
    }),
  ],
};

info

Type:

type info =
  | Record<string, any>
  | ((item: {
      absoluteFilename: string;
      sourceFilename: string;
      filename: string;
      toType: ToType;
    }) => Record<string, any>);

Default: undefined

Allows to add assets info.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        "relative/path/to/file.ext",
        {
          from: "**/*",
          // Terser skip this file for minification
          info: { minimized: true },
        },
      ],
    }),
  ],
};

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        "relative/path/to/file.ext",
        {
          from: "**/*",
          // Terser skip this file for minimization
          info: (file) => ({ minimized: true }),
        },
      ],
    }),
  ],
};

Options

concurrency

type:

type concurrency = number;

Default: 100

Limits the number of simultaneous requests to fs.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [...patterns],
      options: { concurrency: 50 },
    }),
  ],
};

Examples

Different variants of from (glob, file or dir).

Consider the following file structure:

src/directory-nested/deep-nested/deepnested-file.txt
src/directory-nested/nested-file.txt
From is a Glob

Everything that you specify in from will be included in the result:

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/directory-nested/**/*",
        },
      ],
    }),
  ],
};

Result:

src/directory-nested/deep-nested/deepnested-file.txt,
src/directory-nested/nested-file.txt

If you don't want the result paths to start with src/directory-nested/, then you should move src/directory-nested/ to context, such that only the glob pattern **/* remains in from:

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "**/*",
          context: path.resolve(__dirname, "src", "directory-nested"),
        },
      ],
    }),
  ],
};

Result:

deep-nested/deepnested-file.txt,
nested-file.txt
From is a Dir

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, "src", "directory-nested"),
        },
      ],
    }),
  ],
};

Result:

deep-nested/deepnested-file.txt,
nested-file.txt

Technically, this is equivalent to using **/* with a predefined context set to the specified directory

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "**/*",
          context: path.resolve(__dirname, "src", "directory-nested"),
        },
      ],
    }),
  ],
};

Result:

deep-nested/deepnested-file.txt,
nested-file.txt
From is a File
module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(
            __dirname,
            "src",
            "directory-nested",
            "nested-file.txt",
          ),
        },
      ],
    }),
  ],
};

Result:

nested-file.txt

Technically, this is a filename with a predefined context equal to the file's directory path.dirname(pathToFile).

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "nested-file.txt",
          context: path.resolve(__dirname, "src", "directory-nested"),
        },
      ],
    }),
  ],
};

Result:

nested-file.txt

Ignoring files

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.posix.join(
            path.resolve(__dirname, "src").replaceAll("\\", "/"),
            "**/*",
          ),
          globOptions: {
            ignore: [
              // Ignore all `txt` files
              "**/*.txt",
              // Ignore all files in all subdirectories
              "**/subdir/**",
            ],
          },
        },
      ],
    }),
  ],
};

Flatten copy

Removes all directory references and copies only file names.

[!WARNING]

If files have the same name, the result is non-deterministic.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/**/*",
          to: "[name][ext]",
        },
      ],
    }),
  ],
};

Result:

file-1.txt
file-2.txt
nested-file.txt

Copy in new directory

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          // When copying files starting with a dot, must specify the toType option
          // toType: "file",
          to({ context, absoluteFilename }) {
            return `newdirectory/${path.relative(context, absoluteFilename)}`;
          },
          from: "directory",
        },
      ],
    }),
  ],
};

Result:

"newdirectory/file-1.txt",
"newdirectory/nestedfile.txt",
"newdirectory/nested/deep-nested/deepnested.txt",
"newdirectory/nested/nestedfile.txt",

Skip running JavaScript files through a minimizer

Useful if you need to simply copy *.js files to destination "as is" without evaluating and minimizing them using Terser.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        "relative/path/to/file.ext",
        {
          from: "**/*",
          // Terser skip this file for minimization
          info: { minimized: true },
        },
      ],
    }),
  ],
};
yarn workspaces and monorepos

When using yarn workspaces or monorepos, relative copy paths from node_modules can be broken due to the way packages are hoisting. To avoid this, you should explicitly specify where to copy the files from; by using require.resolve.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: `${path.dirname(
            require.resolve(`${moduleName}/package.json`),
          )}/target`,
          to: "target",
        },
      ],
    }),
  ],
};

Contributing

We welcome all contributions!

If you are new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.

CONTRIBUTING

License

MIT

DefinePlugin

The DefinePlugin replaces variables in your code with other values or expressions at compile time. This can be useful for allowing different behavior between development builds and production builds. If you perform logging in your development build but not in the production build you might use a global constant to determine whether logging takes place. That's where DefinePlugin shines, set it and forget it rules for development and production builds.

new webpack.DefinePlugin({
  // Definitions...
});

Usage

Each key passed into DefinePlugin is an identifier or multiple identifiers joined with ..

  • If the value is a string it will be used as a code fragment.
  • If the value isn't a string, it will be stringified (including functions).
  • If the value is an object all keys are defined the same way.
  • If you prefix typeof to the key, it's only defined for typeof calls.

The values will be inlined into the code allowing a minification pass to remove the redundant conditional.

new webpack.DefinePlugin({
  PRODUCTION: JSON.stringify(true),
  VERSION: JSON.stringify('5fa3b9'),
  BROWSER_SUPPORTS_HTML5: true,
  TWO: '1+1',
  'typeof window': JSON.stringify('object'),
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
});
console.log('Running App version ' + VERSION);
if (!BROWSER_SUPPORTS_HTML5) require('html5shiv');
if (!PRODUCTION) {
  console.log('Debug info');
}

if (PRODUCTION) {
  console.log('Production log');
}

After passing through webpack with no minification results in:

if (!true) {
  console.log('Debug info');
}
if (true) {
  console.log('Production log');
}

and then after a minification pass results in:

console.log('Production log');

Feature Flags

Enable/disable features in production/development build using feature flags.

new webpack.DefinePlugin({
  NICE_FEATURE: JSON.stringify(true),
  EXPERIMENTAL_FEATURE: JSON.stringify(false),
});

Service URLs

Use a different service URL in production/development builds:

new webpack.DefinePlugin({
  SERVICE_URL: JSON.stringify('https://dev.example.com'),
});

Runtime values via runtimeValue

function (getterFunction, [string] | true | object) => getterFunction()

It is possible to define variables with values that rely on files and will be re-evaluated when such files change in the file system. This means webpack will rebuild when such watched files change.

There're two arguments for webpack.DefinePlugin.runtimeValue function:

  • The first argument is a function(module, key, version) that should return the value to be assigned to the definition.

  • The second argument could either be an array of file paths to watch for or a true to flag the module as uncacheable. Since 5.26.0, it can also take an object argument with the following properties:

    • fileDependencies?: string[] A list of files the function depends on.
    • contextDependencies?: string[] A list of directories the function depends on.
    • missingDependencies?: string[] A list of not existing files the function depends on.
    • buildDependencies?: string[] A list of build dependencies the function depends on.
    • version?: string | () => string A version of the function.
const fileDep = path.resolve(__dirname, 'sample.txt');

new webpack.DefinePlugin({
  BUILT_AT: webpack.DefinePlugin.runtimeValue(Date.now, {
    fileDependencies: [fileDep],
  }),
});

The value of BUILT_AT would be the time at which the 'sample.txt' was last updated in the file system, e.g. 1597953013291.

DllPlugin

The DllPlugin and DllReferencePlugin provide means to split bundles in a way that can drastically improve build time performance. The term "DLL" stands for Dynamic-link library which was originally introduced by Microsoft.

DllPlugin

This plugin is used in a separate webpack configuration exclusively to create a dll-only-bundle. It creates a manifest.json file, which is used by the DllReferencePlugin to map dependencies.

  • context (optional): context of requests in the manifest file (defaults to the webpack context.)
  • format (boolean = false): If true, manifest json file (output) will be formatted.
  • name: name of the exposed dll function (TemplatePaths: [fullhash], [chunkhash], [contenthash], & [name] )
  • path: absolute path to the manifest json file (output)
  • entryOnly (boolean = true): if true, only entry points will be exposed
  • type: type of the dll bundle
new webpack.DllPlugin(options);

Creates a manifest.json which is written to the given path. It contains mappings from require and import requests to module ids. It is used by the DllReferencePlugin.

Combine this plugin with output.library option to expose (aka, put into the global scope) the dll function.

DllReferencePlugin

This plugin is used in the primary webpack config, it references the dll-only-bundle(s) to require pre-built dependencies.

  • context: (absolute path) context of requests in the manifest (or content property)
  • extensions: Extensions used to resolve modules in the dll bundle (only used when using 'scope').
  • manifest : an object containing content and name or a string to the absolute path of the JSON manifest to be loaded upon compilation
  • content (optional): the mappings from request to module id (defaults to manifest.content)
  • name (optional): an identifier where the dll is exposed (defaults to manifest.name) (see also externals)
  • scope (optional): prefix which is used for accessing the content of the dll
  • sourceType (optional): how the dll is exposed (libraryTarget)
new webpack.DllReferencePlugin(options);

References a dll manifest file to map dependency names to module ids, then requires them as needed using the internal __webpack_require__ function.

Modes

This plugin can be used in two different modes, scoped and mapped.

Scoped Mode

The content of the dll is accessible under a module prefix. i.e. with scope = 'xyz' a file abc in the dll can be access via require('xyz/abc').

Mapped Mode

The content of the dll is mapped to the current directory. If a required file matches a file in the dll (after resolving), then the file from the dll is used instead.

Because this happens after resolving every file in the dll bundle, the same paths must be available for the consumer of the dll bundle. i.e. if the dll contains lodash and the file abc, require('lodash') and require('./abc') will be used from the dll, rather than building them into the main bundle.

Usage

webpack.vendor.config.js

const path = require('path');

new webpack.DllPlugin({
  context: __dirname,
  name: '[name]_[fullhash]',
  path: path.join(__dirname, 'manifest.json'),
});

webpack.app.config.js

new webpack.DllReferencePlugin({
  context: __dirname,
  manifest: require('./manifest.json'),
  scope: 'xyz',
  sourceType: 'commonjs2',
});

Examples

Vendor and User

Two separate example folders. Demonstrates scope and context.

References

Source

Tests

EnvironmentPlugin

The EnvironmentPlugin is shorthand for using the DefinePlugin on process.env keys.

Usage

The EnvironmentPlugin accepts either an array of keys or an object mapping its keys to their default values.

new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']);

This is equivalent to the following DefinePlugin application:

new webpack.DefinePlugin({
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
  'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
});

Usage with default values

Alternatively, the EnvironmentPlugin supports an object, which maps keys to their default values. The default value for a key is taken if the key is undefined in process.env.

new webpack.EnvironmentPlugin({
  NODE_ENV: 'development', // use 'development' unless process.env.NODE_ENV is defined
  DEBUG: false,
});

Example:

Let's investigate the result when running the previous EnvironmentPlugin configuration on a test file entry.js:

if (process.env.NODE_ENV === 'production') {
  console.log('Welcome to production');
}
if (process.env.DEBUG) {
  console.log('Debugging output');
}

When executing NODE_ENV=production webpack in the terminal to build, entry.js becomes this:

if ('production' === 'production') {
  // <-- 'production' from NODE_ENV is taken
  console.log('Welcome to production');
}
if (false) {
  // <-- default value is taken
  console.log('Debugging output');
}

Running DEBUG=false webpack yields:

if ('development' === 'production') {
  // <-- default value is taken
  console.log('Welcome to production');
}
if ('false') {
  // <-- 'false' from DEBUG is taken
  console.log('Debugging output');
}

Use Case: Git Version

The following EnvironmentPlugin configuration provides process.env.GIT_VERSION (such as "v5.4.0-2-g25139f57f") and process.env.GIT_AUTHOR_DATE (such as "2020-11-04T12:25:16+01:00") corresponding to the last Git commit of the repository:

const child_process = require('child_process');
function git(command) {
  return child_process.execSync(`git ${command}`, { encoding: 'utf8' }).trim();
}

new webpack.EnvironmentPlugin({
  GIT_VERSION: git('describe --always'),
  GIT_AUTHOR_DATE: git('log -1 --format=%aI'),
});

DotenvPlugin

The third-party DotenvPlugin (dotenv-webpack) allows you to expose (a subset of) dotenv variables:

// .env
DB_HOST=127.0.0.1
DB_PASS=foobar
S3_API=mysecretkey
new Dotenv({
  path: './.env', // Path to .env file (this is the default)
  safe: true, // load .env.example (defaults to "false" which does not use dotenv-safe)
});

EslintWebpackPlugin

npm node tests coverage discussion size

This version of eslint-webpack-plugin only supports webpack 5. For the webpack 4, see the 2.x branch.

This plugin uses ESlint to find and fix problems in your JavaScript code during the Webpack build process.

Getting Started

To begin, you'll need to install eslint-webpack-plugin:

npm install eslint-webpack-plugin --save-dev

or

yarn add -D eslint-webpack-plugin

or

pnpm add -D eslint-webpack-plugin

[!NOTE]

You also need to install eslint >= 8 from npm, if you haven't already:

npm install eslint --save-dev

or

yarn add -D eslint

or

pnpm add -D eslint

Then add the plugin to your webpack configuration. For example:

const ESLintPlugin = require("eslint-webpack-plugin");

module.exports = {
  // ...
  plugins: [new ESLintPlugin(options)],
  // ...
};

Options

You can pass ESLint Node.js API options.

[!NOTE]

The config option you provide will be passed to the ESLint class. This is a different set of options than what you'd specify in package.json or eslint.config.js (since ESLint v9.0.0, formerly .eslintrc). See the ESlint docs for more details.

[!WARNING]

In eslint-webpack-plugin version 1 the options were passed to the now-deprecated CLIEngine.

cache

  • Type:
type cache = boolean;
  • Default: true

The cache is enabled by default to decrease execution time.

cacheLocation

  • Type:
type cacheLocation = string;
  • Default: node_modules/.cache/eslint-webpack-plugin/.eslintcache

Specify the path to the cache location. Can be a file or a directory.

configType

  • Type:
type configType = "flat" | "eslintrc";
  • Default: flat

Specify the type of configuration to use with ESLint.

  • eslintrc is the classic configuration format available in most ESLint versions.
  • flat is the new format introduced in ESLint 8.21.0.

The new configuration format is explained in its own documentation.

context

  • Type:
type context = string;
  • Default: compiler.context

Base directory for linting.

eslintPath

  • Type:
type eslintPath = string;
  • Default: eslint

Path to eslint instance that will be used for linting.

If the eslintPath is a folder like a official ESlint, or specify a formatter option, now you don't have to install eslint.

extensions

  • Type:
type extensions = string | string[];
  • Default: 'js'

Specify file extensions that should be checked.

exclude

  • Type:
type exclude = string | string[];
  • Default: 'node_modules'

Specify the files/directories to exclude. Must be relative to options.context.

resourceQueryExclude

  • Type:
type resourceQueryExclude = RegExp | RegExp[];
  • Default: []

Specify the resource query to exclude.

files

  • Type:
type files = string | string[];
  • Default: null

Specify directories, files, or globs. Must be relative to options.context. Directories are traversed recursively looking for files matching options.extensions. File and glob patterns ignore options.extensions.

fix

  • Type:
type fix = boolean;
  • Default: false

Will enable ESLint autofix feature.

Be careful: this option will modify source files.

formatter

  • Type:
type formatter =
  | string
  | ((
      results: import("eslint").ESLint.LintResult[],
      data?: import("eslint").ESLint.LintResultData | undefined,
    ) => string);
  • Default: 'stylish'

Accepts a function that receives an array of ESLint messages (object) as its argument and must return a string as output.

You can use official ESlint formatters.

lintDirtyModulesOnly

  • Type:
type lintDirtyModulesOnly = boolean;
  • Default: false

Lint only changed files, skipping initial lint on build start.

threads

  • Type:
type threads = boolean | number;
  • Default: false

Will run lint tasks across a thread pool. The pool size is automatic unless you specify a number.

Errors and Warning

By default the plugin will auto adjust error reporting depending on eslint errors/warnings counts.

You can still force this behavior by using emitError or emitWarning options:

emitError

  • Type:
type emitError = boolean;
  • Default: true

The errors found will always be emitted, to disable set to false.

emitWarning

  • Type:
type emitWarning = boolean;
  • Default: true

The warnings found will always be emitted, to disable set to false.

failOnError

  • Type:
type failOnError = boolean;
  • Default: true

Will cause the module build to fail if any errors are found, to disable set to false.

failOnWarning

  • Type:
type failOnWarning = boolean;
  • Default: false

Will cause the module build to fail if any warnings are found, if set to true.

quiet

  • Type:
type quiet = boolean;
  • Default: false

Will process and report errors only and ignore warnings, if set to true.

outputReport

  • Type:
type outputReport =
  | boolean
  | {
      filePath?: string | undefined;
      formatter?:
        | (
            | string
            | ((
                results: import("eslint").ESLint.LintResult[],
                data?: import("eslint").ESLint.LintResultData | undefined,
              ) => string)
          )
        | undefined;
    };
  • Default: false

Write ESLint results to a file, for example a checkstyle xml file for use for reporting on Jenkins CI.

  • filePath: Path to output report file (relative to output.path or absolute).
  • formatter: You can pass in a different formatter for the output file. if none is passed in the default/configured formatter will be used.

Changelog

Changelog

Contributing

We welcome all contributions!

If you're new here, please take a moment to review our contributing guidelines.

CONTRIBUTING

License

MIT

EvalSourceMapDevToolPlugin

This plugin enables more fine grained control of source map generation. It is also enabled automatically by certain settings of the devtool configuration option.

new webpack.EvalSourceMapDevToolPlugin(options);

Options

The following options are supported:

  • test (string|RegExp|array): Include source maps for modules based on their extension (defaults to .js and .css).

  • include (string|RegExp|array): Include source maps for module paths that match the given value.

  • exclude (string|RegExp|array): Exclude modules that match the given value from source map generation.

  • append (string|function): Appends the given value to the original asset. Usually the #sourceMappingURL comment. [url] is replaced with a URL to the source map file.

    Starting from version 5.84.0, webpack allows the append option to be a function that accepts path data and an asset info object as arguments, and returns a string.

    (pathData: PathData, assetInfo?: AssetInfo) => string;
  • moduleFilenameTemplate (string): See output.devtoolModuleFilenameTemplate.

  • module (boolean): Indicates whether loaders should generate source maps (defaults to true).

  • columns (boolean): Indicates whether column mappings should be used (defaults to true).

  • protocol (string): Allows user to override default protocol (webpack-internal://)

Examples

The following examples demonstrate some common use cases for this plugin.

Basic Use Case

You can use the following code to replace the configuration option devtool: eval-source-map with an equivalent custom plugin configuration:

module.exports = {
  // ...
  devtool: false,
  plugins: [new webpack.EvalSourceMapDevToolPlugin({})],
};

Exclude Vendor Maps

The following code would exclude source maps for any modules in the vendor.js bundle:

new webpack.EvalSourceMapDevToolPlugin({
  exclude: ['vendor.js'],
});

HashedModuleIdsPlugin

This plugin will cause hashes to be based on the relative path of the module, generating a four character string as the module id. Suggested for use in production.

new webpack.ids.HashedModuleIdsPlugin({
  // Options...
});

Options

This plugin supports the following options:

  • context: The context directory (absolute path) for creating names.
  • hashFunction: The hashing algorithm to use, defaults to 'md4'. All functions from Node.JS' crypto.createHash are supported.
  • hashDigest: The encoding to use when generating the hash, defaults to 'base64'. All encodings from Node.JS' hash.digest are supported.
  • hashDigestLength: The prefix length of the hash digest to use, defaults to 4. Note that some generated ids might be longer than specified here, to avoid module id collisions.

Usage

Here's an example of how this plugin might be used:

new webpack.ids.HashedModuleIdsPlugin({
  context: __dirname,
  hashFunction: 'sha256',
  hashDigest: 'hex',
  hashDigestLength: 20,
});

HotModuleReplacementPlugin

Enables Hot Module Replacement, otherwise known as HMR.

Basic Usage

Enabling HMR is straightforward and in most cases no options are necessary.

new webpack.HotModuleReplacementPlugin({
  // Options...
});

HtmlWebpackPlugin

The HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader.

Installation

npm install --save-dev html-webpack-plugin

Basic Usage

The plugin will generate an HTML5 file for you that includes all your webpack bundles in the body using script tags. Add the plugin to your webpack configuration as follows:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'index_bundle.js',
  },
  plugins: [new HtmlWebpackPlugin()],
};

This will generate a file dist/index.html containing the following:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>webpack App</title>
  </head>
  <body>
    <script src="index_bundle.js"></script>
  </body>
</html>

If you have multiple webpack entry points, they will all be included with <script> tags in the generated HTML.

If you have any CSS assets in webpack's output (for example, CSS extracted with the MiniCssExtractPlugin) then these will be included with <link> tags in the <head> element of generated HTML.

Configuration

For all configuration options, please see the plugin documentation.

Third party addons

The plugin supports addons. For a list see the documentation.

IgnorePlugin

IgnorePlugin prevents the generation of modules for import or require calls matching the regular expressions or filter functions.

Using regular expressions

  • resourceRegExp: A RegExp to test the resource against.
  • contextRegExp: (optional) A RegExp to test the context (directory) against.
new webpack.IgnorePlugin({ resourceRegExp, contextRegExp });

Using filter functions

  • checkResource (resource, context) A Filter function that receives resource and context as arguments, must return boolean.
new webpack.IgnorePlugin({
  checkResource(resource) {
    // do something with resource
    return true | false;
  },
});

Example of ignoring Moment Locales

As of moment 2.18, all locales are bundled together with the core library (see this GitHub issue).

The resourceRegExp parameter passed to IgnorePlugin is not tested against the resolved file names or absolute module names being imported or required, but rather against the string passed to require or import within the source code where the import is taking place. For example, if you're trying to exclude node_modules/moment/locale/*.js, this won't work:

-new webpack.IgnorePlugin({ resourceRegExp: /moment\/locale\// });

Rather, because moment imports with this code:

require('./locale/' + name);

...your first regexp must match that './locale/' string. The second contextRegExp parameter is then used to select specific directories from where the import took place. The following will cause those locale files to be ignored:

new webpack.IgnorePlugin({
  resourceRegExp: /^\.\/locale$/,
  contextRegExp: /moment$/,
});

...which means "any require statement matching './locale' from any directories ending with 'moment' will be ignored.

InstallWebpackPlugin

npm deps test coverage chat

Speed up development by automatically installing & saving dependencies with Webpack.

It is inefficient to Ctrl-C your build script & server just to install a dependency you didn't know you needed until now.

Instead, use require or import how you normally would and installation will happen automatically to install & save missing dependencies while you work!

$ npm install --save-dev install-webpack-plugin

Usage

In your webpack.config.js:

plugins: [
  new InstallPlugin()
],

This is equivalent to:

plugins: [
  new InstallPlugin({
    dependencies: {
      peer: true,
    },
    packageManager: {
      type: this.getDefaultPackageManager(),
      options: {
        dev: false,
        quiet: false,
      },
    },
    prompt: true,
  });
],

Options

dependencies

Type: Object

Dependencies related options.

peer

Type: Boolean

Default: true

Install missing peer dependencies.

plugins: [
  new InstallPlugin({
    dependencies: {
      peer: true,
    }
  }),
],

packageManager

Type: 'npm' | 'yarn' | 'pnpm' | Object | Function

Package manager to use for installing dependencies.

plugins: [
  new InstallPlugin({
      packageManager: 'yarn'
    },
  }),
],

You can provide a Function to the packageManager to make it dynamic:

plugins: [
  new InstallPlugin({
    packageManager: function(module, path) {
      return [
        "babel-preset-react-hmre",
        "webpack-dev-middleware",
        "webpack-hot-middleware",
      ].indexOf(module) !== -1;
    },
  }),
],

type

Type: 'npm' | 'yarn' | 'pnpm'

Name of package manager to use for installing dependencies.

options

Type: Object

Package manager related options.

arguments

Type: Array

Provide custom arguments to use with package manager.

plugins: [
  new InstallPlugin({
      packageManager: {
        type: 'npm',
        options: {
          arguments: ['--ignore-scripts']
        }
      }
    },
  }),
],

dev

Type: Boolean

Default: false

Install as development dependencies.

plugins: [
  new InstallPlugin({
      packageManager: {
        type: 'npm',
        options: {
          dev: true,
        }
      }
    },
  }),
],

quiet

Type: Boolean

Default: false

Reduce the amount of console logging.

plugins: [
  new InstallPlugin({
      packageManager: {
        type: 'npm',
        options: {
          quiet: true,
        }
      }
    },
  }),
],

prompt

Type: Boolean

Default: true

Show a prompt to confirm installation.

plugins: [
  new InstallPlugin({
      prompt: true,
    },
  }),
],

Demo

install-webpack-plugin demo

Features

  • Works with webpack ^v5.0.0.
  • Auto-installs .babelrc plugins & presets.
  • Supports both ES5 & ES6 Modules. (e.g. require, import)
  • Supports Namespaced packages. (e.g. @cycle/dom)
  • Supports Dot-delimited packages. (e.g. lodash.capitalize)
  • Supports CSS imports. (e.g. @import "~bootstrap")
  • Supports webpack loaders. (e.g. babel-loader, file-loader, etc.)
  • Supports inline webpack loaders. (e.g. require("bundle?lazy!./App")
  • Auto-installs missing peerDependencies. (e.g. @cycle/core will automatically install rx@*)
  • Supports webpack's resolve.alias & resolve.root configuration. (e.g. require("react") can alias to react-lite)

Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

CONTRIBUTING

Internal webpack plugins

This is a list of plugins which are used by webpack internally.

Categories of internal plugins:

environment

Plugins affecting the environment of the compiler.

NodeEnvironmentPlugin

webpack.node.NodeEnvironmentPlugin()

Applies Node.js style filesystem to the compiler.

compiler

Plugins affecting the compiler

MemoryCachePlugin

MemoryCachePlugin()

Adds a cache to the compiler, where modules are cached in memory.

ProgressPlugin

ProgressPlugin(handler)

Hook into the compiler to extract progress information. The handler must have the signature function(percentage, message). Percentage is called with a value between 0 and 1, where 0 indicates the start and 1 the end.

RecordIdsPlugin

RecordIdsPlugin()

Saves and restores module and chunk ids from records.

entry

Plugins, which add entry chunks to the compilation.

EntryPlugin

EntryPlugin(context, entry, options)

Adds an entry chunk on compilation. The chunk is named options.name and contains only one module (plus dependencies). The module is resolved from entry in context (absolute path).

PrefetchPlugin

PrefetchPlugin(context, request)

Prefetches request and dependencies to enable a more parallel compilation. It doesn't create any chunk. The module is resolved from request in context (absolute path).

output

JsonpTemplatePlugin

JsonpTemplatePlugin(options)

Chunks are wrapped into JSONP-calls. A loading algorithm is included in entry chunks. It loads chunks by adding a <script> tag.

options are the output options.

options.jsonpFunction is the JSONP function.

options.publicPath is used as path for loading the chunks.

options.chunkFilename is the filename under that chunks are expected.

NodeTemplatePlugin

node/NodeTemplatePlugin(options)

Chunks are wrapped into Node.js modules exporting the bundled modules. The entry chunks loads chunks by requiring them.

options are the output options.

options.chunkFilename is the filename under that chunks are expected.

LibraryTemplatePlugin

LibraryTemplatePlugin(name, target)

The entries chunks are decorated to form a library name of type type.

WebWorkerTemplatePlugin

webworker/WebWorkerTemplatePlugin(options)

Chunks are loaded by importScripts. Else it's similar to JsonpTemplatePlugin.

options are the output options.

EvalDevToolModulePlugin

Decorates the module template by wrapping each module in a eval annotated with // @sourceURL.

SourceMapDevToolPlugin

SourceMapDevToolPlugin(sourceMapFilename, sourceMappingURLComment, moduleFilenameTemplate, fallbackModuleFilenameTemplate)

Decorates the templates by generating a SourceMap for each chunk.

sourceMapFilename the filename template of the SourceMap. [hash], [name], [id], [file] and [filebase] are replaced. If this argument is missing, the SourceMap will be inlined as DataUrl.

HotModuleReplacementPlugin

HotModuleReplacementPlugin(options)

Add support for hot module replacement. Decorates the templates to add runtime code. Adds module.hot API.

options.hotUpdateChunkFilename the filename for hot update chunks.

options.hotUpdateMainFilename the filename for the hot update manifest.

options.hotUpdateFunction JSON function name for the hot update.

source

Plugins affecting the source code of modules.

APIPlugin

Make webpack_public_path, webpack_require, webpack_modules and webpack_chunk_load accessible. Ensures that require.valueOf and require.onError are not processed by other plugins.

CompatibilityPlugin

Currently useless. Ensures compatibility with other module loaders.

ConstPlugin

Tries to evaluate expressions in if (...) statements and ternaries to replace them with true/false for further possible dead branch elimination using hooks fired by the parser.

There are multiple optimizations in production mode regarding dead branches:

  • The ones performed by Terser
  • The ones performed by webpack

Webpack will try to evaluate conditional statements. If it succeeds then the dead branch is removed. Webpack can't do constant folding unless the compiler knows it. For example:

import { calculateTax } from './tax';

const FOO = 1;
if (FOO === 0) {
  // dead branch
  calculateTax();
}

In the above example, webpack is unable to prune the branch, but Terser does. However, if FOO is defined using DefinePlugin, webpack will succeed.

It is important to mention that import { calculateTax } from './tax'; will also get pruned because calculateTax() call was in the dead branch and got eliminated.

ProvidePlugin

ProvidePlugin(name, request)

If name is used in a module it is filled by a module loaded by require(<request>).

NodeStuffPlugin

NodeStuffPlugin(options, context)

Provide stuff that is normally available in Node.js modules.

It also ensures that module is filled with some Node.js stuff if you use it.

RequireJsStuffPlugin

Provide stuff that is normally available in require.js.

require[js].config is removed. require.version is 0.0.0. requirejs.onError is mapped to require.onError.

NodeSourcePlugin

node/NodeSourcePlugin(options)

This module adds stuff from Node.js that is not available in non Node.js environments.

It adds polyfills for process, console, Buffer and global if used. It also binds the built in Node.js replacement modules.

NodeTargetPlugin

node/NodeTargetPlugin()

The plugins should be used if you run the bundle in a Node.js environment.

If ensures that native modules are loaded correctly even if bundled.

AMDPlugin

dependencies/AMDPlugin(options)

Provides AMD-style define and require to modules. Also bind require.amd, define.amd and webpack_amd_options## to the options passed as parameter.

CommonJsPlugin

dependencies/CommonJsPlugin

Provides CommonJs-style require to modules.

RequireContextPlugin

dependencies/RequireContextPlugin(modulesDirectories, extensions)

Provides require.context. The parameter modulesDirectories and extensions are used to find alternative requests for files. It's useful to provide the same arrays as you provide to the resolver.

RequireEnsurePlugin

dependencies/RequireEnsurePlugin()

Provides require.ensure.

RequireIncludePlugin

dependencies/RequireIncludePlugin()

Provides require.include.

DefinePlugin

DefinePlugin(definitions)

Define constants for identifier.

definitions is an object.

optimize

Note that all plugins under webpack.optimize namespace should only be used when mode set to 'none'. Otherwise you might get into trouble where plugins are applied twice.

LimitChunkCountPlugin

optimize/LimitChunkCountPlugin(options)

Merge chunks limit chunk count is lower than options.maxChunks.

The overhead for each chunks is provided by options.chunkOverhead or defaults to 10000. Entry chunks sizes are multiplied by options.entryChunkMultiplicator (or 10).

Chunks that reduce the total size the most are merged first. If multiple combinations are equal the minimal merged size wins.

MergeDuplicateChunksPlugin

optimize/MergeDuplicateChunksPlugin()

Chunks with the same modules are merged.

RemoveEmptyChunksPlugin

optimize/RemoveEmptyChunksPlugin()

Modules that are included in every parent chunk are removed from the chunk.

MinChunkSizePlugin

optimize/MinChunkSizePlugin(minChunkSize)

Merges chunks until each chunk has the minimum size of minChunkSize.

ModuleConcatenationPlugin

See the ModuleConcatenationPlugin page for details.

FlagIncludedChunksPlugin

optimize/FlagIncludedChunksPlugin()

Adds chunk ids of chunks which are included in the chunk. This eliminates unnecessary chunk loads.

RealContentHashPlugin

optimize/RealContentHashPlugin()

When optimization.realContentHash option is enabled, webpack will apply RealContentHashPlugin to compiler internally.

Hook

RealContentHashPlugin provides a updateHash 5.8.0+ hook for customizing hash updating:

const webpack = require('webpack');
const RealContentHashPlugin = webpack.optimize.RealContentHashPlugin;
// ...
compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
  const hooks = RealContentHashPlugin.getCompilationHooks(compilation);
  hooks.updateHash.tap('MyPlugin', (content, oldHash) => {
    // you can calculate the hash here as you wish
  });
});

LimitChunkCountPlugin

While writing your code, you may have already added many code split points to load stuff on demand. After compiling you might notice that some chunks are too small - creating larger HTTP overhead. LimitChunkCountPlugin can post-process your chunks by merging them.

new webpack.optimize.LimitChunkCountPlugin({
  // Options...
});

Options

The following options are supported:

maxChunks

number

Limit the maximum number of chunks using a value greater than or equal to 1. Using 1 will prevent any additional chunks from being added as the entry/main chunk is also included in the count.

webpack.config.js

const webpack = require('webpack');
module.exports = {
  // ...
  plugins: [
    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 5,
    }),
  ],
};

minChunkSize

Keeping chunk size above the specified limit is no longer a feature of this plugin. Use MinChunkSizePlugin instead.

Usage via CLI

This plugin and it's options can also be invoked via the CLI:

webpack --optimize-max-chunks 15

MinChunkSizePlugin

Keep chunk size above the specified limit by merging chunks that are smaller than the minChunkSize.

new webpack.optimize.MinChunkSizePlugin({
  minChunkSize: 10000, // Minimum number of characters
});

Usage via CLI

This plugin and it's options can also be invoked via the CLI:

webpack --optimize-min-chunk-size 10000

Plugins

Webpack has a rich plugin interface. Most of the features within webpack itself use this plugin interface. This makes webpack flexible.

NameDescription
BannerPluginAdd a banner to the top of each generated chunk
ChunksWebpackPluginCreate HTML files with entrypoints and chunks relations to serve your bundles
CommonsChunkPluginExtract common modules shared between chunks
CompressionWebpackPluginPrepare compressed versions of assets to serve them with Content-Encoding
ContextReplacementPluginOverride the inferred context of a require expression
CopyWebpackPluginCopies individual files or entire directories to the build directory
DefinePluginAllow global constants configured at compile time
DllPluginSplit bundles in order to drastically improve build time
EnvironmentPluginShorthand for using the DefinePlugin on process.env keys
EslintWebpackPluginA ESLint plugin for webpack
HotModuleReplacementPluginEnable Hot Module Replacement (HMR)
HtmlWebpackPluginEasily create HTML files to serve your bundles
IgnorePluginExclude certain modules from bundles
LimitChunkCountPluginSet min/max limits for chunking to better control chunking
MinChunkSizePluginKeep chunk size above the specified limit
MiniCssExtractPlugincreates a CSS file per JS file which requires CSS
NoEmitOnErrorsPluginSkip the emitting phase when there are compilation errors
NormalModuleReplacementPluginReplace resource(s) that matches a regexp
NpmInstallWebpackPluginAuto-install missing dependencies during development
ProgressPluginReport compilation progress
ProvidePluginUse modules without having to use import/require
SourceMapDevToolPluginEnables a more fine grained control of source maps
EvalSourceMapDevToolPluginEnables a more fine grained control of eval source maps
SvgChunkWebpackPluginGenerate SVG sprites optimized by SVGO based on your entry point dependencies
TerserPluginUses Terser to minify the JS in your project

For more third-party plugins, see the list from awesome-webpack.

ModuleConcatenationPlugin

In the past, one of webpack’s trade-offs when bundling was that each module in your bundle would be wrapped in individual function closures. These wrapper functions made it slower for your JavaScript to execute in the browser. In comparison, tools like Closure Compiler and RollupJS ‘hoist’ or concatenate the scope of all your modules into one closure and allow for your code to have a faster execution time in the browser.

This plugin will enable the same concatenation behavior in webpack. By default this plugin is already enabled in production mode and disabled otherwise. If you need to override the production mode optimization, set the optimization.concatenateModules option to false. To enable concatenation behavior in other modes, you can add ModuleConcatenationPlugin manually or use the optimization.concatenateModules option:

new webpack.optimize.ModuleConcatenationPlugin();

This concatenation behavior is called “scope hoisting.”

Scope hoisting is specifically a feature made possible by ECMAScript Module syntax. Because of this webpack may fallback to normal bundling based on what kind of modules you are using, and other conditions.

Optimization Bailouts

As the article explains, webpack attempts to achieve partial scope hoisting. It will merge modules into a single scope but cannot do so in every case. If webpack cannot merge a module, the two alternatives are Prevent and Root. Prevent means the module must be in its own scope. Root means a new module group will be created. The following conditions determine the outcome:

ConditionOutcome
Non ES6 ModulePrevent
Imported By Non ImportRoot
Imported From Other ChunkRoot
Imported By Multiple Other Module GroupsRoot
Imported With import()Root
Affected By ProvidePlugin Or Using modulePrevent
HMR AcceptedRoot
Using eval()Prevent
In Multiple ChunksPrevent
export * from "cjs-module"Prevent

Module Grouping Algorithm

The following pseudo JavaScript explains the algorithm:

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

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) => {
    return check && tryToAdd(nextGroup, dependent);
  }, true);
  if (!result) {
    return false;
  }
  module.dependencies.forEach((dependency) => {
    tryToAdd(group, dependency);
  });
  group.merge(nextGroup);
  return true;
}

Debugging Optimization Bailouts

When using the webpack CLI, the --stats-optimization-bailout flag will display bailout reasons. When using the webpack config, add the following to the stats object:

module.exports = {
  //...
  stats: {
    // Display bailout reasons
    optimizationBailout: true,
  },
};

ModuleFederationPlugin

The ModuleFederationPlugin allows a build to provide or consume modules with other independent builds at runtime.

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // options' typings in typescript
      runtime: string | false,
    }),
  ],
};

Options

runtime

Create a new runtime chunk with the specified name.

webpack.config.js

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      runtime: 'my-runtime-name',
    }),
  ],
};

Sharing libraries

With the shared key in the configuration you can define libraries that are shared between your federated modules. The package name is the same as the one found in the dependencies section of your package.json. However, by default webpack will only share the root level of a library.

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds date-fns as shared module
      shared: ['date-fns'],
    }),
  ],
};

So in your application you could do something like

import { format } from 'date-fns';

format(new Date(2014, 1, 11), 'MM/dd/yyyy');

and webpack will automatically share date-fns between all your federated modules that define date-fns as a shared library. However, if you want to access something that is not located at the root level of the package, for example date-fns/locale/en-GB/index.js, you need to append / to the package name in your shared configuration:

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds date-fns as shared module
      // all files of the package will be shared
      shared: ['date-fns/'],
    }),
  ],
};

The / syntax allows you to access all files of a package. However, it should be used only where necessary, because it has an impact on performance especially in development mode.

Specify package versions

There are three ways to specify the versions of shared libraries.

Array syntax

This syntax allows you to share libraries with package name only. This approach is good for prototyping, but it will not allow you to scale to large production environment given that libraries like react and react-dom will require additional requirements.

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds lodash as shared module
      // version is inferred from package.json
      // there is no version check for the required version
      // so it will always use the higher version found
      shared: ['lodash'],
    }),
  ],
};
Object syntax

This syntax provides you more control over each shared library in which you can define package name as the key and version (semver) as the value.

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        // adds lodash as shared module
        // version is inferred from package.json
        // it will use the highest lodash version that is >= 4.17 and < 5
        lodash: '^4.17.0',
      },
    }),
  ],
};
Object syntax with sharing hints

This syntax allows you to provide additional hints to each shared package where you define the package name as the key, and the value as an object containing hints to modify sharing behavior.

const deps = require('./package.json').dependencies;

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        // adds react as shared module
        react: {
          requiredVersion: deps.react,
          singleton: true,
        },
      },
    }),
  ],
};

Sharing hints

eager

boolean

This hint will allow webpack to include the provided and fallback module directly instead of fetching the library via an asynchronous request. In other words, this allows to use this shared module in the initial chunk. Also, be careful that all provided and fallback modules will always be downloaded when this hint is enabled.

import

false | string

The provided module that should be placed in the shared scope. This provided module also acts as fallback module if no shared module is found in the shared scope or version isn't valid. (The value for this hint defaults to the property name.)

packageName

string

The package name that is used to determine required version from description file. This is only needed when the package name can't be automatically determined from request.

requiredVersion

false string

This field specifies the required version of the package. It accepts semantic versioning, such as "^1.2.3". Additionally, it retrieves the version if it's provided as a URL, for instance: "git+ssh://git@github.com:foo/bar.git#v1.0.0".

shareKey

string

The requested shared module is looked up under this key from the shared scope.

shareScope

string

The name of the shared scope.

singleton

boolean

This hint only allows a single version of the shared module in the shared scope (disabled by default). Some libraries use a global internal state (e.g. react, react-dom). Thus, it is critical to have only one instance of the library running at a time.

In cases where there are multiple versions of the same dependency in the shared scope, the highest semantic version is used.

strictVersion

boolean

This hint allows webpack to reject the shared module if version is not valid (defaults to true when local fallback module is available and shared module is not a singleton, otherwise false, it has no effect if there is no required version specified). Throws a runtime error if the required version is not found.

version

false | string

The version of the provided module. It allows webpack to replace lower matching versions, but not higher.

By default, webpack uses the version from the package.json file of the dependency.

Additional examples

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds vue as shared module
      // version is inferred from package.json
      // it will always use the shared version, but print a warning when the shared vue is < 2.6.5 or >= 3
      shared: {
        vue: {
          requiredVersion: '^2.6.5',
          singleton: true,
        },
      },
    }),
  ],
};
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds vue as shared module
      // there is no local version provided
      // it will emit a warning if the shared vue is < 2.6.5 or >= 3
      shared: {
        vue: {
          import: false,
          requiredVersion: '^2.6.5',
        },
      },
    }),
  ],
};
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds vue as shared module
      // there is no local version provided
      // it will throw an error when the shared vue is < 2.6.5 or >= 3
      shared: {
        vue: {
          import: false,
          requiredVersion: '^2.6.5',
          strictVersion: true,
        },
      },
    }),
  ],
};
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        'my-vue': {
          // can be referenced by import "my-vue"
          import: 'vue', // the "vue" package will be used as a provided and fallback module
          shareKey: 'shared-vue', // under this name the shared module will be placed in the share scope
          shareScope: 'default', // share scope with this name will be used
          singleton: true, // only a single version of the shared module is allowed
          strictVersion: true, // don't use shared version when version isn't valid. Singleton or modules without fallback will throw, otherwise fallback is used
          version: '1.2.3', // the version of the shared module
          requiredVersion: '^1.0.0', // the required version of the shared module
        },
      },
    }),
  ],
};

NoEmitOnErrorsPlugin

The NoEmitOnErrorsPlugin allows you to avoid emitting assets when there are any errors. Enabled by default, you can disable using optimization.emitOnErrors

webpack.config.js

module.exports = {
  plugins: [new webpack.NoEmitOnErrorsPlugin()],
};

NormalModuleReplacementPlugin

The NormalModuleReplacementPlugin allows you to replace resources that match resourceRegExp with newResource. If newResource is relative, it is resolved relative to the previous resource. If newResource is a function, it is expected to overwrite the request attribute of the supplied resource.

This can be useful for allowing different behaviour between builds.

new webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource);

Note that the resourceRegExp is tested against the request you write in your code, not the resolved resource. For instance, './sum' will be used to test instead of './sum.js' when you have code import sum from './sum'.

Also please note that when using Windows, you have to accomodate for the different folder separator symbol. E.g. /src\/environments\/environment\.ts/ won't work on Windows, you have to use /src[\\/]environments[\\/]environment\.ts/, instead.

Basic Example

Replace a specific module when building for a development environment.

Say you have a configuration file some/path/config.development.module.js and a special version for production in some/path/config.production.module.js

Add the following plugin when building for production:

new webpack.NormalModuleReplacementPlugin(
  /some\/path\/config\.development\.js/,
  './config.production.js'
);

Advanced Example

Conditional build depending on an specified environment.

Say you want a configuration with specific values for different build targets.

module.exports = function (env) {
  var appTarget = env.APP_TARGET || 'VERSION_A';
  return {
    plugins: [
      new webpack.NormalModuleReplacementPlugin(/-APP_TARGET$/, function (
        resource
      ) {
        resource.request = resource.request.replace(
          /-APP_TARGET/,
          `-${appTarget}`
        );

        if (resource.createData) {
          resource.createData.request = resource.request;
        }
      }),
    ],
  };
};

Create the two configuration files:

app/config-VERSION_A.js

export default {
  title: 'I am version A',
};

app/config-VERSION_B.js

export default {
  title: 'I am version B',
};

Then import that configuration using the keyword you're looking for in the regexp:

import config from 'app/config-APP_TARGET';
console.log(config.title);

And now you get the right configuration imported depending on which target you're building for:

npx webpack --env APP_TARGET=VERSION_A
=> 'I am version A'

npx webpack --env APP_TARGET=VERSION_B
=> 'I am version B'

PrefetchPlugin

Prefetch normal module requests, causing them to be resolved and built before the first import or require of that module occurs. Using this plugin can boost performance. Try to profile the build first to determine clever prefetching points.

new webpack.PrefetchPlugin([context], request);

Options

  • context: An absolute path to a directory
  • request: A request string for a normal module

ProfilingPlugin

Generate Chrome profile file which includes timings of plugins execution. Outputs events.json file by default. It is possible to provide custom file path using outputPath option.

Note : ProfilingPlugin accepts only absolute paths.

Options

  • outputPath: An absolute path to a custom output file (json)

Usage: default

new webpack.debug.ProfilingPlugin();

Usage: custom outputPath

new webpack.debug.ProfilingPlugin({
  outputPath: path.join(__dirname, 'profiling/profileEvents.json'),
});

In order to view the profile file:

  1. Run webpack with ProfilingPlugin.
  2. Go to Chrome, open DevTools, and go to the Performance tab (formerly Timeline).
  3. Drag and drop generated file (events.json by default) into the profiler.

It will then display timeline stats and calls per plugin!

ProgressPlugin

The ProgressPlugin provides a way to customize how progress is reported during a compilation.

Usage

Create an instance of ProgressPlugin and provide one of the allowed params, besides, there's a static method createDefaultHandler which can be used to customize the default handler.

Providing function

Provide a handler function which will be called when hooks report progress. handler function arguments:

  • percentage: a number between 0 and 1 indicating the completion percentage of the compilation
  • message: a short description of the currently-executing hook
  • ...args: zero or more additional strings describing the current progress
const handler = (percentage, message, ...args) => {
  // e.g. Output each progress message directly to the console:
  console.info(percentage, message, ...args);
};

new webpack.ProgressPlugin(handler);

Providing object

When providing an object to the ProgressPlugin, following properties are supported:

  • activeModules (boolean = false): Shows active modules count and one active module in progress message.
  • entries (boolean = true): Shows entries count in progress message.
  • handler (See Providing function)
  • modules (boolean = true): Shows modules count in progress message.
  • modulesCount (number = 5000): A minimum modules count to start with. Takes effect when modules property is enabled.
  • profile (boolean = false): Tells ProgressPlugin to collect profile data for progress steps.
  • dependencies (boolean = true): Shows the count of dependencies in progress message.
  • dependenciesCount (number = 10000): A minimum dependencies count to start with. Takes effect when dependencies property is enabled.
  • percentBy (string = null: 'entries' | 'dependencies' | 'modules' | null): Tells ProgressPlugin how to calculate progress percentage.
new webpack.ProgressPlugin({
  activeModules: false,
  entries: true,
  handler(percentage, message, ...args) {
    // custom logic
  },
  modules: true,
  modulesCount: 5000,
  profile: false,
  dependencies: true,
  dependenciesCount: 10000,
  percentBy: null,
});

webpack.ProgressPlugin.createDefaultHandler

If the default handler of ProgressPlugin does not meet your requirements, you can customize it using the static ProgressPlugin.createDefaultHandler method.

static createDefaultHandler: (
  profile: undefined | null | boolean,
  logger: WebpackLogger
) => (percentage: number, msg: string, ...args: string[]) => void;

Percentage calculation

By default, progress percentage is calculated based on built modules count and total modules count: built / total

The total modules count is unknown in advance and changes during the build. This may cause inaccurate progress percentage.

To solve this problem ProgressPlugin caches the last known total modules count and reuses this value on the next build. The first build will warm the cache but the following builds will use and update this value.

We recommend using percentBy: 'entries' setting for projects with multiple configured entry points. Percentage calculation will become more accurate because the amount of entry points is known in advance.

Supported Hooks

The following hooks report progress information to ProgressPlugin.

Compiler

  • compilation
  • emit*
  • afterEmit*
  • done

Compilation

  • buildModule
  • failedModule
  • succeedModule
  • finishModules*
  • seal*
  • optimizeDependenciesBasic*
  • optimizeDependencies*
  • optimizeDependenciesAdvanced*
  • afterOptimizeDependencies*
  • optimize*
  • optimizeModulesBasic*
  • optimizeModules*
  • optimizeModulesAdvanced*
  • afterOptimizeModules*
  • optimizeChunksBasic*
  • optimizeChunks*
  • optimizeChunksAdvanced*
  • afterOptimizeChunks*
  • optimizeTree*
  • afterOptimizeTree*
  • optimizeChunkModulesBasic*
  • optimizeChunkModules*
  • optimizeChunkModulesAdvanced*
  • afterOptimizeChunkModules*
  • reviveModules*
  • optimizeModuleOrder*
  • advancedOptimizeModuleOrder*
  • beforeModuleIds*
  • moduleIds*
  • optimizeModuleIds*
  • afterOptimizeModuleIds*
  • reviveChunks*
  • optimizeChunkOrder*
  • beforeChunkIds*
  • optimizeChunkIds*
  • afterOptimizeChunkIds*
  • recordModules*
  • recordChunks*
  • beforeHash*
  • afterHash*
  • recordHash*
  • beforeModuleAssets*
  • beforeChunkAssets*
  • additionalChunkAssets*
  • record*
  • additionalAssets*
  • optimizeChunkAssets*
  • afterOptimizeChunkAssets*
  • optimizeAssets*
  • afterOptimizeAssets*
  • afterSeal*

Source

ProvidePlugin

Automatically load modules instead of having to import or require them everywhere.

new webpack.ProvidePlugin({
  identifier: 'module1',
  // ...
});

or

new webpack.ProvidePlugin({
  identifier: ['module1', 'property1'],
  // ...
});

By default, module resolution path is current folder (./**) and node_modules.

It is also possible to specify full path:

const path = require('path');

new webpack.ProvidePlugin({
  identifier: path.resolve(path.join(__dirname, 'src/module1')),
  // ...
});

Whenever the identifier is encountered as free variable in a module, the module is loaded automatically and the identifier is filled with the exports of the loaded module (or property in order to support named exports).

For importing the default export of an ES2015 module, you have to specify the default property of module.

Usage: jQuery

To automatically load jquery we can point both variables it exposes to the corresponding node module:

new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery',
});

Then in any of our source code:

// in a module
$('#item'); // <= works
jQuery('#item'); // <= also works
// $ is automatically set to the exports of module "jquery"

Usage: jQuery with Angular 1

Angular looks for window.jQuery in order to determine whether jQuery is present, see the source code.

new webpack.ProvidePlugin({
  'window.jQuery': 'jquery',
});

Usage: Lodash Map

new webpack.ProvidePlugin({
  _map: ['lodash', 'map'],
});

Usage: Vue.js

new webpack.ProvidePlugin({
  Vue: ['vue/dist/vue.esm.js', 'default'],
});

SourceMapDevToolPlugin

This plugin enables more fine grained control of source map generation. It is also enabled automatically by certain settings of the devtool configuration option.

new webpack.SourceMapDevToolPlugin(options);

Options

The following options are supported:

  • test (string RegExp [string, RegExp]): Include source maps for modules based on their extension (defaults to .js, .mjs, and .css).

  • include (string RegExp [string, RegExp]): Include source maps for module paths that match the given value.

  • exclude (string RegExp [string, RegExp]): Exclude modules that match the given value from source map generation.

  • filename (string): Defines the output filename of the SourceMap (will be inlined if no value is provided).

  • append (string function false): Appends the given value to the original asset. Usually the #sourceMappingURL comment. [url] is replaced with a URL to the source map file. Since webpack v4.36.0, path parameters are supported: [chunk], [filename] and [contenthash]. Setting append to false disables the appending.

    Starting from version 5.84.0, webpack allows the append option to be a function that accepts path data and an asset info object as arguments, and returns a string.

    (pathData: PathData, assetInfo?: AssetInfo) => string;
  • moduleFilenameTemplate (string): See output.devtoolModuleFilenameTemplate.

  • fallbackModuleFilenameTemplate (string): See link above.

  • namespace (string): See output.devtoolNamespace.

  • module = true (boolean): Indicates whether loaders should generate source maps.

  • columns = true (boolean): Indicates whether column mappings should be used.

  • noSources = false (boolean): Prevents the source file content from being included in the source map.

  • publicPath (string): Emits absolute URLs with public path prefix, e.g. https://example.com/project/.

  • fileContext (string): Makes the [file] argument relative to this directory.

  • sourceRoot (string): Provide a custom value for the sourceRoot property in the SourceMap.

  • debugIds (boolean): If true, unique ids will be emitted in source and sourcemaps which streamlines identifying sourcemaps across different builds. See the TC39 sourcemap debug ID proposal for more details.

The fileContext option is useful when you want to store source maps in an upper level directory to avoid ../../ appearing in the absolute [url].

Examples

The following examples demonstrate some common use cases for this plugin.

Basic Use Case

You can use the following code to replace the configuration option devtool: inline-source-map with an equivalent custom plugin configuration:

module.exports = {
  // ...
  devtool: false,
  plugins: [new webpack.SourceMapDevToolPlugin({})],
};

Exclude Vendor Maps

The following code would exclude source maps for any modules in the vendor.js bundle:

new webpack.SourceMapDevToolPlugin({
  filename: '[file].map[query]',
  exclude: ['vendor.js'],
});

Host Source Maps Externally

Set a URL for source maps. Useful for hosting them on a host that requires authorization.

new webpack.SourceMapDevToolPlugin({
  append: '\n//# sourceMappingURL=https://example.com/sourcemap/[url]',
  filename: '[file].map[query]',
});

And for cases when source maps are stored in the upper level directory:

project
|- dist
  |- public
    |- bundle-[hash].js
  |- sourcemaps
    |- bundle-[hash].js.map

With the following config:

new webpack.SourceMapDevToolPlugin({
  filename: 'sourcemaps/[file].map',
  publicPath: 'https://example.com/project/',
  fileContext: 'public',
});

Will produce the following URL:

https://example.com/project/sourcemaps/bundle-[hash].js.map

SplitChunksPlugin

Originally, chunks (and modules imported inside them) were connected by a parent-child relationship in the internal webpack graph. The CommonsChunkPlugin was used to avoid duplicated dependencies across them, but further optimizations were not possible.

Since webpack v4, the CommonsChunkPlugin was removed in favor of optimization.splitChunks.

Defaults

Out of the box SplitChunksPlugin should work well for most users.

By default it only affects on-demand chunks, because changing initial chunks would affect the script tags the HTML file should include to run the project.

Webpack will automatically split chunks based on these conditions:

  • New chunk can be shared OR modules are from the node_modules folder
  • New chunk would be bigger than 20kb (before min+gz)
  • Maximum number of parallel requests when loading chunks on demand would be lower or equal to 30
  • Maximum number of parallel requests at initial page load would be lower or equal to 30

When trying to fulfill the last two conditions, bigger chunks are preferred.

Configuration

Webpack provides a set of options for developers that want more control over this functionality.

optimization.splitChunks

This configuration object represents the default behavior of the SplitChunksPlugin.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

splitChunks.automaticNameDelimiter

string = '~'

By default webpack will generate names using origin and name of the chunk (e.g. vendors~main.js). This option lets you specify the delimiter to use for the generated names.

splitChunks.chunks

string = 'async' function (chunk) RegExp

This indicates which chunks will be selected for optimization. When a string is provided, valid values are all, async, and initial. Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.

Note that it is applied to the fallback cache group as well (splitChunks.fallbackCacheGroup.chunks).

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      // include all types of chunks
      chunks: 'all',
    },
  },
};

Alternatively, you may provide a function for more control. The return value will indicate whether to include each chunk.

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks(chunk) {
        // exclude `my-excluded-chunk`
        return chunk.name !== 'my-excluded-chunk';
      },
    },
  },
};

If you are using webpack version 5.86.0 or later, you can also pass a regular expression:

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: /foo/,
    },
  },
};

splitChunks.maxAsyncRequests

number = 30

Maximum number of parallel requests when on-demand loading.

splitChunks.maxInitialRequests

number = 30

Maximum number of parallel requests at an entry point.

splitChunks.defaultSizeTypes

[string] = ['javascript', 'unknown']

Sets the size types which are used when a number is used for sizes.

splitChunks.minChunks

number = 1

The minimum times must a module be shared among chunks before splitting.

splitChunks.hidePathInfo

boolean

Prevents exposing path info when creating names for parts splitted by maxSize.

splitChunks.minSize

number = 20000 { [index: string]: number }

Minimum size, in bytes, for a chunk to be generated.

splitChunks.minSizeReduction

number { [index: string]: number }

Minimum size reduction to the main chunk (bundle), in bytes, needed for a chunk to be generated. Meaning if splitting into a chunk does not reduce the size of the main chunk (bundle) by the given amount of bytes, it won't be split, even if it meets the splitChunks.minSize value.

splitChunks.enforceSizeThreshold

splitChunks.cacheGroups.{cacheGroup}.enforceSizeThreshold

number = 50000

Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored.

splitChunks.minRemainingSize

splitChunks.cacheGroups.{cacheGroup}.minRemainingSize

number = 0

splitChunks.minRemainingSize option was introduced in webpack 5 to avoid zero sized modules by ensuring that the minimum size of the chunk which remains after splitting is above a limit. Defaults to 0 in 'development' mode. For other cases splitChunks.minRemainingSize defaults to the value of splitChunks.minSize so it doesn't need to be specified manually except for the rare cases where deep control is required.

splitChunks.layer

splitChunks.cacheGroups.{cacheGroup}.layer

RegExp string function

Assign modules to a cache group by module layer.

splitChunks.maxSize

number = 0

Using maxSize (either globally optimization.splitChunks.maxSize per cache group optimization.splitChunks.cacheGroups[x].maxSize or for the fallback cache group optimization.splitChunks.fallbackCacheGroup.maxSize) tells webpack to try to split chunks bigger than maxSize bytes into smaller parts. Parts will be at least minSize (next to maxSize) in size. The algorithm is deterministic and changes to the modules will only have local effects. So that it is usable when using long term caching and doesn't require records. maxSize is only a hint and could be violated when modules are bigger than maxSize or splitting would violate minSize.

When the chunk has a name already, each part will get a new name derived from that name. Depending on the value of optimization.splitChunks.hidePathInfo it will add a key derived from the first module name or a hash of it.

maxSize option is intended to be used with HTTP/2 and long term caching. It increases the request count for better caching. It could also be used to decrease the file size for faster rebuilding.

splitChunks.maxAsyncSize

number

Like maxSize, maxAsyncSize can be applied globally (splitChunks.maxAsyncSize), to cacheGroups (splitChunks.cacheGroups.{cacheGroup}.maxAsyncSize), or to the fallback cache group (splitChunks.fallbackCacheGroup.maxAsyncSize).

The difference between maxAsyncSize and maxSize is that maxAsyncSize will only affect on-demand loading chunks.

splitChunks.maxInitialSize

number

Like maxSize, maxInitialSize can be applied globally (splitChunks.maxInitialSize), to cacheGroups (splitChunks.cacheGroups.{cacheGroup}.maxInitialSize), or to the fallback cache group (splitChunks.fallbackCacheGroup.maxInitialSize).

The difference between maxInitialSize and maxSize is that maxInitialSize will only affect initial load chunks.

splitChunks.name

boolean = false function (module, chunks, cacheGroupKey) => string string

Also available for each cacheGroup: splitChunks.cacheGroups.{cacheGroup}.name.

The name of the split chunk. Providing false will keep the same name of the chunks so it doesn't change names unnecessarily. It is the recommended value for production builds.

Providing a string or a function allows you to use a custom name. Specifying either a string or a function that always returns the same string will merge all common modules and vendors into a single chunk. This might lead to bigger initial downloads and slow down page loads.

If you choose to specify a function, you may find the chunk.name property (where chunk is an element of the chunks array) particularly useful in choosing a name for your chunk.

If the splitChunks.name matches an entry point name, the entry-point chunk & the cache group will be combined into a single chunk.

main.js

import _ from 'lodash';

console.log(_.join(['Hello', 'webpack'], ' '));

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          // cacheGroupKey here is `commons` as the key of the cacheGroup
          name(module, chunks, cacheGroupKey) {
            const moduleFileName = module
              .identifier()
              .split('/')
              .reduceRight((item) => item);
            const allChunksNames = chunks.map((item) => item.name).join('~');
            return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
          },
          chunks: 'all',
        },
      },
    },
  },
};

Running webpack with following splitChunks configuration would also output a chunk of the group common with next name: commons-main-lodash.js.e7519d2bb8777058fa27.js (hash given as an example of real world output).

splitChunks.usedExports

splitChunks.cacheGroups{cacheGroup}.usedExports

boolean = true

Figure out which exports are used by modules to mangle export names, omit unused exports and generate more efficient code. When it is true: analyse used exports for each runtime, when it is "global": analyse exports globally for all runtimes combined).

splitChunks.cacheGroups

Cache groups can inherit and/or override any options from splitChunks.*; but test, priority and reuseExistingChunk can only be configured on cache group level. To disable any of the default cache groups, set them to false.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        default: false,
      },
    },
  },
};

splitChunks.cacheGroups.{cacheGroup}.priority

number = -20

A module can belong to multiple cache groups. The optimization will prefer the cache group with a higher priority. The default groups have a negative priority to allow custom groups to take higher priority (default value is 0 for custom groups).

splitChunks.cacheGroups.{cacheGroup}.reuseExistingChunk

boolean = true

If the current chunk contains modules already split out from the main bundle, it will be reused instead of a new one being generated. This can affect the resulting file name of the chunk.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          reuseExistingChunk: true,
        },
      },
    },
  },
};

splitChunks.cacheGroups.{cacheGroup}.type

function RegExp string

Allows to assign modules to a cache group by module type.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        json: {
          type: 'json',
        },
      },
    },
  },
};

splitChunks.cacheGroups.test

splitChunks.cacheGroups.{cacheGroup}.test

function (module, { chunkGraph, moduleGraph }) => boolean RegExp string

Controls which modules are selected by this cache group. Omitting it selects all modules. It can match the absolute module resource path or chunk names. When a chunk name is matched, all modules in the chunk are selected.

Providing a function to{cacheGroup}.test:

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        svgGroup: {
          test(module) {
            // `module.resource` contains the absolute path of the file on disk.
            // Note the usage of `path.sep` instead of / or \, for cross-platform compatibility.
            const path = require('path');
            return (
              module.resource &&
              module.resource.endsWith('.svg') &&
              module.resource.includes(`${path.sep}cacheable_svgs${path.sep}`)
            );
          },
        },
        byModuleTypeGroup: {
          test(module) {
            return module.type === 'javascript/auto';
          },
        },
      },
    },
  },
};

In order to see what information is available in module and chunks objects, you can put debugger; statement in the callback. Then run your webpack build in debug mode to inspect the parameters in Chromium DevTools.

Providing a RegExp to {cacheGroup}.test:

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          // Note the usage of `[\\/]` as a path separator for cross-platform compatibility.
          test: /[\\/]node_modules[\\/]|vendor[\\/]analytics_provider|vendor[\\/]other_lib/,
        },
      },
    },
  },
};

splitChunks.cacheGroups.{cacheGroup}.filename

string function (pathData, assetInfo) => string

Allows to override the filename when and only when it's an initial chunk. All placeholders available in output.filename are also available here.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          filename: '[name].bundle.js',
        },
      },
    },
  },
};

And as a function:

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          filename: (pathData) => {
            // Use pathData object for generating filename string based on your requirements
            return `${pathData.chunk.name}-bundle.js`;
          },
        },
      },
    },
  },
};

It is possible to create a folder structure by providing path prefixing the filename: 'js/vendor/bundle.js'.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          filename: 'js/[name]/bundle.js',
        },
      },
    },
  },
};

splitChunks.cacheGroups.{cacheGroup}.enforce

boolean = false

Tells webpack to ignore splitChunks.minSize, splitChunks.minChunks, splitChunks.maxAsyncRequests and splitChunks.maxInitialRequests options and always create chunks for this cache group.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          enforce: true,
        },
      },
    },
  },
};

splitChunks.cacheGroups.{cacheGroup}.idHint

string

Sets the hint for chunk id. It will be added to chunk's filename.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          idHint: 'vendors',
        },
      },
    },
  },
};

Examples

Defaults: Example 1

// index.js

import('./a'); // dynamic import
// a.js
import 'react';

//...

Result: A separate chunk would be created containing react. At the import call this chunk is loaded in parallel to the original chunk containing ./a.

Why:

  • Condition 1: The chunk contains modules from node_modules
  • Condition 2: react is bigger than 30kb
  • Condition 3: Number of parallel requests at the import call is 2
  • Condition 4: Doesn't affect request at initial page load

What's the reasoning behind this? react probably won't change as often as your application code. By moving it into a separate chunk this chunk can be cached separately from your app code (assuming you are using chunkhash, records, Cache-Control or other long term cache approach).

Defaults: Example 2

// entry.js

// dynamic imports
import('./a');
import('./b');
// a.js
import './helpers'; // helpers is 40kb in size

//...
// b.js
import './helpers';
import './more-helpers'; // more-helpers is also 40kb in size

//...

Result: A separate chunk would be created containing ./helpers and all dependencies of it. At the import calls this chunk is loaded in parallel to the original chunks.

Why:

  • Condition 1: The chunk is shared between both import calls
  • Condition 2: helpers is bigger than 30kb
  • Condition 3: Number of parallel requests at the import calls is 2
  • Condition 4: Doesn't affect request at initial page load

Putting the content of helpers into each chunk will result into its code being downloaded twice. By using a separate chunk this will only happen once. We pay the cost of an additional request, which could be considered a tradeoff. That's why there is a minimum size of 30kb.

Split Chunks: Example 1

Create a commons chunk, which includes all code shared between entry points.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          name: 'commons',
          chunks: 'initial',
          minChunks: 2,
        },
      },
    },
  },
};

Split Chunks: Example 2

Create a vendors chunk, which includes all code from node_modules in the whole application.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
      },
    },
  },
};

Split Chunks: Example 3

Create a custom vendor chunk, which contains certain node_modules packages matched by RegExp.

webpack.config.js

module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
          name: 'vendor',
          chunks: 'all',
        },
      },
    },
  },
};

StylelintWebpackPlugin

npm node tests coverage discussion size

This version of stylelint-webpack-plugin only works with webpack 5. For webpack 4, see the 2.x branch.

This plugin uses stylelint, which helps you avoid errors and enforce conventions in your styles.

Getting Started

To begin, you'll need to install stylelint-webpack-plugin:

npm install stylelint-webpack-plugin --save-dev

or

yarn add -D stylelint-webpack-plugin

or

pnpm add -D stylelint-webpack-plugin

[!NOTE]

You also need to install stylelint >= 13 from npm, if you haven't already:

npm install stylelint --save-dev

or

yarn add -D stylelint

or

pnpm add -D stylelint

[!NOTE]

If you are using Stylelint 13 rather than 14+, you might also need to install @types/stylelint as a dev dependency if you encounter Stylelint-related type errors.

Then add the plugin to your webpack configuration. For example:

const StylelintPlugin = require("stylelint-webpack-plugin");

module.exports = {
  // ...
  plugins: [new StylelintPlugin(options)],
  // ...
};

Options

See stylelint's options for the complete list of available options . These options are passed directly to stylelint.

cache

  • Type:
type cache = boolean;
  • Default: true

The cache is enabled by default to decrease execution time.

cacheLocation

  • Type:
type cacheLocation = string;
  • Default: node_modules/.cache/stylelint-webpack-plugin/.stylelintcache

Specify the path to the cache location. This can be a file or a directory.

configFile

  • Type:
type context = string;
  • Default: undefined

Specify the config file location to be used by stylelint.

Note:

By default this is handled by stylelint.

context

  • Type:
type context = string;
  • Default: compiler.context

A string indicating the root of your files.

exclude

  • Type:
type exclude = string | string[];
  • Default: ['node_modules', compiler.options.output.path]

Specify the files and/or directories to exclude. Must be relative to options.context.

extensions

  • Type:
type extensions = string | string[];
  • Default: ['css', 'scss', 'sass']

Specify the extensions that should be checked.

files

  • Type:
type files = string | string[];
  • Default: null

Specify directories, files, or globs. Must be relative to options.context. Directories are traversed recursively, looking for files matching options.extensions. File and glob patterns ignore options.extensions.

fix

  • Type:
type fix = boolean;
  • Default: false

If true, stylelint will fix as many errors as possible. The fixes are made to the actual source files. All unfixed errors will be reported. See Autofixing errors docs.

formatter

  • Type:
type formatter =
  | string
  | ((results: import("stylelint").LintResult[]) => string);
  • Default: 'string'

Specify the formatter you would like to use to format your results. See the formatter option.

lintDirtyModulesOnly

  • Type:
type lintDirtyModulesOnly = boolean;
  • Default: false

Lint only changed files; skip linting on start.

stylelintPath

  • Type:
type stylelintPath = string;
  • Default: stylelint

Path to stylelint instance that will be used for linting.

threads

  • Type:
type threads = boolean | number;
  • Default: false

Set to true for an auto-selected pool size based on number of CPUs. Set to a number greater than 1 to set an explicit pool size.

Set to false, 1, or less to disable and run only in main process.

Errors and Warning

By default, the plugin will automatically adjust error reporting depending on the number of Stylelint errors/warnings.

You can still force this behavior by using the emitError or emitWarning options:

emitError

  • Type:
type emitError = boolean;
  • Default: true

The errors found will always be emitted. To disable, set to false.

emitWarning

  • Type:
type emitWarning = boolean;
  • Default: true

The warnings found will always be emitted. To disable, set to false.

failOnError

  • Type:
type failOnError = boolean;
  • Default: true

Will cause the module build to fail if there are any errors. To disable, set to false.

failOnWarning

  • Type:
type failOnWarning = boolean;
  • Default: false

Will cause the module build to fail if there are any warnings, when set to true.

quiet

  • Type:
type quiet = boolean;
  • Default: false

Will process and report errors only, and ignore warnings, when set to true.

outputReport

  • Type:
type outputReport =
  | boolean
  | {
      filePath?: string | undefined;
      formatter?:
        | (string | ((results: import("stylelint").LintResult[]) => string))
        | undefined;
    };
  • Default: false

Writes the output of the errors to a file - for example, a json file for use for reporting.

The filePath is relative to the webpack config: output.path.

You can pass in a different formatter for the output file. If none is passed in the default/configured formatter will be used.

const outputReport = {
  filePath: "path/to/file",
  formatter: "json",
};

Changelog

Changelog

Contributing

We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.

CONTRIBUTING

License

MIT

SvgChunkWebpackPlugin

GitHub Workflow Status (branch) Coverage Status Npm downloads

The svg-chunk-webpack-plugin creates optimized SVG sprites, according to Webpack's entrypoints. Each sprite contains only the SVG dependencies listed on its entrypoints to improved code splitting, even on SVG files.

The plugin includes the popular SVGO package to generates clean and optimized SVG sprites.

Code splitting is the key to deliver files without any content that is unused by the pages. It already exists for CSS, Javascript and now for SVG files with this plugin.

When to use this plugin

On multiple page application, each pages must includes only its necessary dependencies. In other words, it must include only the SVG files imported by its entrypoint and all its dependencies.

With reusable components, SVGs are often duplicated on all the project. Now, you can create a global SVG library and every Javascript files can easily import any SVG from this library. Entrypoint dependencies are automatically updated, thanks to the Webpack compilation.

When you work with SVGs exported by design softwares, like Sketch or Illustrator, their source code is never optimized and often contains comments, CSS classes which can create conflicts between them. The plugin automatically cleans all SVGs before creating the sprite.

Zero config

The plugin works without configuration with already the optimized settings. For advanced usage, see the section using configuration.

Installation

The plugin is available as a package with the name of svg-chunk-webpack-plugin on npm and Github.

npm install svg-chunk-webpack-plugin --save-dev
yarn add svg-chunk-webpack-plugin --dev

[!WARNING] Plugin svg-chunk-webpack-plugin@5 is ESM only. [!NOTE] Minimum supported Node.js version is 16.20.0 and Webpack >=5.10.3.

Example

The project includes a minimalist example in the ./example directory. Run the npm run build:example command to execute the Webpack example and see the plugin's implementation in action.

Basic usage

The plugin will generate one SVG sprite for each entrypoints. Sprites are built in the output path directory with all the other assets. Each sprite filename is composed with its entrypoint name (in the example below, that would be home.svg).

First, let's add the loader and the plugin to the Webpack configuration.

[!WARNING] The loader and the plugin need to works together.

webpack.config.js

import SvgChunkWebpackPlugin from 'svg-chunk-webpack-plugin';

export default {
  module: {
    rules: [
      {
        test: /\.svg$/,
        use: [
          {
            loader: SvgChunkWebpackPlugin.loader
          }
        ]
      }
    ]
  },
  plugins: [new SvgChunkWebpackPlugin()]
};

[!NOTE] For more flexibility and better performance, inline SVG files are better. Fewer HTTP requests, CSS properties to change the style, no flickering during the page load.

Then, include the sprite in the wanted pages (we use Twig in the following example).

home.html.twig

{{ include 'home.svg' }}

Finally, use the SVG with the <use> tag, like the following example. Replace <svg_name> by the SVG name (without the extension).

home.html.twig

<svg>
  <use href="#<svg_name>"></use>
</svg>

Using a configuration

The loader and the plugin accepts configuration to override the default behavior.

Loader

The loader configuration allow to personalize the SVGO configuration. SVGO optimization is executed during the loader process to optimize build performance.

configFile

Type:

type configFile = string | boolean;

Default: path.resolve(opts.root, 'svgo.config.js')

Tells the loader whether to load the custom SVGO configuration. Custom configuration can be disabled with configFile: false.

webpack.config.js

export default {
  module: {
    rules: [
      {
        test: /\.svg$/,
        loader: SvgChunkWebpackPlugin.loader,
        options: {
          configFile: './path/svgo.config.js'
        }
      }
    ]
  }
};

SVGO custom configuration

SVGO have a default preset to optimize SVG files. See how to configure svgo for details.

svgo.config.js

export default {
  multipass: true,
  plugins: [
    {
      name: 'preset-default',
      params: {
        overrides: {
          inlineStyles: {
            onlyMatchedOnce: false
          },
          removeViewBox: false
        }
      }
    },
    {
      name: 'convertStyleToAttrs'
    }
  ]
};

Plugin

The plugin configuration allow to personalize sprite settings.

filename

Type:

type filename = string;

Default: '[name].svg'

Tells the plugin whether to personalize the default sprite filename. The placeholder [name] is automatically replaced by entrypoints names.

webpack.config.js

export default {
  plugins: [
    new SvgChunkWebpackPlugin({
      filename: '[name].svg'
    })
  ]
};

[!NOTE] The filename parameter is compatible with Webpack caching placeholders, see the section caching.

svgstoreConfig

Type:

type svgstoreConfig = object;

Default: { cleanDefs: false, cleanSymbols: false, inline: true }

SVG sprites are built using the svgstore package. Update the parameters according to your needs from the options list available on the svgstore documentation.

webpack.config.js

export default {
  plugins: [
    new SvgChunkWebpackPlugin({
      svgstoreConfig: {
        svgAttrs: {
          'aria-hidden': true,
          style: 'position: absolute; width: 0; height: 0; overflow: hidden;'
        }
      }
    })
  ]
};

[!NOTE] To avoid LinearGradient conflicts, avoid the display: none property which breaks SVG definitions.

generateSpritesManifest

Type:

type generateSpritesManifest = boolean;

Default: false

Tells the plugin whether to generate the sprites-manifest.json. The JSON file contains the list of all SVG included by entrypoints.

webpack.config.js

export default {
  plugins: [
    new SvgChunkWebpackPlugin({
      generateSpritesManifest: true
    })
  ]
};

generateSpritesPreview

Type:

type generateSpritesPreview = boolean;

Default: false

Tells the plugin whether to generate the sprites-preview.html. The HTML preview contains a display list of all SVG included by entrypoints with the SVG overviews and the names. See the sprites preview of the example.

webpack.config.js

export default {
  plugins: [
    new SvgChunkWebpackPlugin({
      generateSpritesPreview: true
    })
  ]
};

Caching

With webpack caching, several placeholders are available depending on your needs. With SVG inlined in the page, this option is not useful.

[!NOTE] The [contenthash] placeholder is the best option because it depends on the sprite content. Cache placeholders are expensive in build performance, use it only in production mode.

[contenthash]

The [contenthash] placeholder will add a unique hash based on the content of the sprite. When the sprite's content changes, the hash will change as well.

webpack.config.js

export default {
  plugins: [
    new SvgChunkWebpackPlugin({
      filename: '[name].[contenthash].svg'
    })
  ]
};

[fullhash]

The [fullhash] placeholder will add a unique hash generated for every build. When the compilation build is updated, the hash will change as well.

webpack.config.js

export default {
  plugins: [
    new SvgChunkWebpackPlugin({
      filename: '[name].[fullhash].svg'
    })
  ]
};

License

svg-chunk-webpack-plugin is licensed under the MIT License.

Created with ♥ by @yoriiis.

VirtualUrlPlugin

Allow creating virtual modules of any type, such as .ts, .json, .css, etc. default is .js.

5.100.0+
const webpack = require('webpack');

new webpack.experiments.schemes.VirtualUrlPlugin({
  myModule: `export const msg = "from virtual module"`,
});

src/app.js

import { msg } from 'virtual:myModule';

console.log(msg);

Basic Example

Create a virtual module that generates build information

const webpack = require('webpack')

new webpack.experiments.schemes.VirtualUrlPlugin({
  buildInfo: {
    source: () {
      return `export const buildTime = ${+new Date()}`
    },
    version: true
  }
});

src/app.js

import { buildTime } from 'virtual:buildInfo';

console.log('App version: ', buildTime);

Use custom schema

const webpack = require('webpack');

new webpack.experiments.schemes.VirtualUrlPlugin(
  {
    myModule: `export const msg = "from virtual module"`,
  },
  'v'
);

src/app.js

import { msg } from 'v:myModule';

console.log(msg);

Advanced Example

Create multiple virtual modules of different types

const webpack = require('webpack');

new webpack.experiments.schemes.VirtualUrlPlugin({
  myCssModule: {
    type: '.css',
    source: 'body{background-color: powderblue;}',
  },
  myJsonModule: {
    type: '.json',
    source: `{"name": "virtual-url-plugin"}`,
  },
});

src/app.js

import json from 'virtual:myJsonModule';
import 'virtual:myCssModule';

Virtualize the routing file

const webpack = require('webpack');
const path = require('path');
const watchDir = path.join(__dirname, './src/routes');

new webpack.experiments.schemes.VirtualUrlPlugin({
  routes: {
    source(loaderContext) {
      // Use addContextDependency to monitor the addition or removal of subdirectories in watchDir to trigger the rebuilding of virtual modules.
      loaderContext.addContextDependency(watchDir);

      const files = fs.readdirSync(watchDir);
      return `
        export const routes = {
          ${files.map((key) => `${key.split('.')[0]}: () => import('./src/routes/${key}')`).join(',\n')}
        }
      `;
    },
  },
});

src/app.js

import { routes } from 'virtual:routes';

Options

  • module.type (string): Content type of the virtual module.
  • module.source (string | ((loaderContext: import('webpack').LoaderContext<T>) => Promise<string> | string)): Factory function for generating the content of virtual module.

  • module.version(boolean | string | () => string): When a invalidate is triggered, the source function is called again if the value of the version is different from the previous one. If set to true it will always trigger.

  • schema (string): Customizable virtual module schema, default is virtual.

WatchIgnorePlugin

Ignore the specified files, i.e. those matching the provided paths or regular expressions, while in watch mode.

new webpack.WatchIgnorePlugin({ paths });

Options

  • paths (Array<string | RegExp>): A list of RegExps or absolute paths to directories or files that should be ignored.

1 Contributor

webpack