npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

copy-advanced-webpack-plugin

v1.0.0

Published

Copy files && directories which are already exists or generated with webpack

Downloads

7

Readme

npm node deps tests cover

size

copy-advanced-webpack-plugin

Copies individual files or entire directories, which already exist or generated from the build process, to the build directory.

Getting Started

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

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

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

webpack.config.js

const CopyAdvancedPlugin = require("copy-advanced-webpack-plugin");

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

ℹ️ copy-advanced-webpack-plugin is mainly designed to copy files generated from the build process; rather, it is to copy files that already exist in the source tree, as part of the build process.

ℹ️ copy-advanced-webpack-plugin is based on copy-webpack-plugin. So, all user guidelines are similar between two plugin.

Options

| Name | Type | Description | | :-------------------------: | :-----------------------: | :--------------------------------------- | | patterns | {Array<String\|Object>} | Specify file related patterns for plugin | | options | {Object} | Specify options for plugin |

The plugin's signature:

webpack.config.js

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

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

Patterns

| Name | Type | Default | Description | | :-------------------------------------: | :------------------: | :---------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------- | | from | {String} | undefined | Glob or path from where we copy files. | | to | {String\|Function} | compiler.options.output | Output path. | | context | {String} | options.context \|\| compiler.options.context | A path that determines how to interpret the from path. | | globOptions | {Object} | undefined | Options passed to the glob pattern matching library including ignore option. | | filter | {Function} | undefined | Allows to filter copied assets. | | toType | {String} | undefined | Determinate what is to option - directory, file or template. | | force | {Boolean} | false | Overwrites files already in compilation.assets (usually added by other plugins/loaders). | | priority | {Number} | 0 | Allows you to specify the copy priority. | | transform | {Object} | undefined | Allows to modify the file contents. Enable transform caching. You can use { transform: {cache: { key: 'my-cache-key' }} } to invalidate the cache. | | transformAll | {Function} | undefined | Allows you to modify the contents of multiple files and save the result to one file. | | noErrorOnMissing | {Boolean} | false | Doesn't generate an error on missing file(s). | | info | {Object\|Function} | undefined | Allows to add assets info. |

from

Type: String Default: undefined

Glob or path from where we copy files. Globs accept fast-glob pattern-syntax. Glob can only be a string.

⚠️ Don't use directly \\ in from option if it is a glob (i.e path\to\file.ext) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use /.

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").replace(/\\/g, "/"),
          "*.txt"
        ),
      ],
    }),
  ],
};
For windows

If you define from as absolute file path or absolute folder path on Windows, you can use windows path segment (\\)

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

But you should always use forward-slashes in glob expressions See fast-glob manual.

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").replace(/\\/g, "/"),
            "*.txt"
          ),
        },
      ],
    }),
  ],
};

The context behaves differently depending on what the from is (glob, file or dir). More examples

to

Type: String|Function Default: compiler.options.output

String

Output path.

⚠️ Don't use directly \\ in to (i.e path\to\dest) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use / or path methods.

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.

⚠️ Don't return directly \\ in to (i.e path\to\newFile) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use / or path methods.

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: String Default: options.context|compiler.options.context

A path that determines how to interpret the from path.

⚠️ Don't use directly \\ in context (i.e path\to\context) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use / or path methods.

webpack.config.js

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

The context option can be an absolute or relative path. If context is a relative, then it is converted to absolute based to compiler.options.context

Also, context indicates how to interpret the search results. Further, he is considered in this role.

To determine the structure from which the found resources will be copied to the destination folder, the context option is used.

If from is a file, then context is equal to the directory in which this file is located. Accordingly, the result will be only the file name.

If from is a directory, then context is the same as from and is equal to the directory itself. In this case, the result will be a hierarchical structure of the found folders and files relative to the specified directory.

If from is a glob, then regardless of the context option, the result will be the structure specified in the from option

More examples

globOptions

Type: Object Default: undefined

Allows to configute the glob pattern matching library used by the plugin. See the list of supported options To exclude files from the selection, you should use 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: Function Default: undefined

ℹ️ To ignore files by path please use the globOptions.ignore option.

webpack.config.js

const fs = require("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: String Default: undefined

Determinate what is to option - 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 need use dir option. We try to automatically determine the type so you most likely do not need this option.

| Name | Type | Default | Description | | :---------------------------: | :--------: | :---------: | :--------------------------------------------------------------------------------------------------- | | 'dir' | {String} | undefined | If to has no extension or ends on '/' | | 'file' | {String} | undefined | If to is not a directory and is not a template | | 'template' | {String} | undefined | If 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: Boolean Default: false

Overwrites files already in compilation.assets (usually added by other plugins/loaders).

webpack.config.js

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

priority

Type: 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 overwrite files, the force option must be enabled.

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: Function|Object Default: undefined

Allows to modify the file contents.

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

| Name | Type | Default | Description | | :-------------------------------: | :-----------------: | :---------: | :--------------------------------------------------------------------------------------------------------------- | | transformer | {Function} | undefined | Allows to modify the file contents. | | cache | {Boolean\|Object} | false | Enable transform caching. You can use transform: { cache: { key: 'my-cache-key' } } to invalidate the cache. |

transformer

Type: Function 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: Boolean|Object Default: false

webpack.config.js

Enable/disable and configure caching. Default path to cache directory: 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 cache directory and invalidation keys.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          transform: {
            transformer(content, path) {
              return optimize(content);
            },
            cache: {
              directory: path.resolve(__dirname, "cache-directory"),
              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: {
              directory: path.resolve(__dirname, "cache-directory"),
              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: {
              directory: path.resolve(__dirname, "cache-directory"),
              keys: async (defaultCacheKeys, absoluteFrom) => {
                const keys = await getCustomCacheInvalidationKeysAsync();

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

transformAll

Type: Function Default: undefined

Allows you to modify the contents of multiple files and save the result to one file.

ℹ️ The to option must be specified and point to a file. It is allowed to use only [contenthash] and [fullhash] template strings.

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/**/*.txt",
          to: "dest/file.txt",
          // The `assets` argument is an assets array for 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: Boolean Default: false

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

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

info

Type: Object|Function<Object> 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 minimization
          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

| Name | Type | Default | Description | | :---------------------------: | :--------: | :-----: | :----------------------------------------------- | | concurrency | {Number} | 100 | Limits the number of simultaneous requests to fs |

concurrency

limits the number of simultaneous requests to fs

webpack.config.js

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

Examples

Different variants from (glob, file or dir).

Take for example 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 want only content src/directory-nested/, you should only indicate glob in from. The path to the folder in which the search should take place, should be moved to context.

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 **/* with a predefined context equal 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 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").replace(/\\/g, "/"),
            "**/*"
          ),
          globOptions: {
            ignore: [
              // Ignore all `txt` files
              "**/*.txt",
              // Ignore all files in all subdirectories
              "**/subdir/**",
            ],
          },
        },
      ],
    }),
  ],
};

Flatten copy

Removes all directory references and only copies file names.

⚠️ 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, should explicitly specify where to copy the files from using require.resolve.

webpack.config.js

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

Related Plugin

Copy Webpack Plugin

Thanks to

All copy-webpack-plugin contributors

Contributing

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

CONTRIBUTING

License

MIT