Security News
Cloudflare Adds Security.txt Setup Wizard
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
copy-webpack-plugin
Advanced tools
The copy-webpack-plugin is a webpack plugin that allows you to copy files and directories from one location to another within your build process. It is commonly used to copy static assets such as images, fonts, and HTML files to the output directory defined in your webpack configuration.
Copying individual files or entire directories
This feature allows you to copy individual files or entire directories from a specified source to a destination within your output directory. The 'from' field specifies the relative or absolute path to the source file or directory, and the 'to' field specifies the relative path to the destination within the output directory.
new CopyPlugin({ patterns: [{ from: 'source', to: 'dest' }] })
Ignoring files
This feature allows you to exclude specific files or patterns from being copied. In the provided code sample, all JavaScript files are ignored and will not be copied to the destination.
new CopyPlugin({ patterns: [{ from: 'source', to: 'dest', globOptions: { ignore: ['**/*.js'] } }] })
Adding context to file paths
This feature allows you to specify a context for the file paths. The 'context' option sets a base path for the 'from' property. In the code sample, the actual path that will be copied is 'app/source'.
new CopyPlugin({ patterns: [{ from: 'source', to: 'dest', context: 'app' }] })
Transforming file content
This feature allows you to modify the content of files before they are copied. The 'transform' function receives the content of the file and its path, and it should return the new content. This can be used to minify files, add banners, or perform other transformations.
new CopyPlugin({ patterns: [{ from: 'source', to: 'dest', transform: (content, path) => { return modifyContent(content); } }] })
The file-loader resolves import/require() on a file into a url and emits the file into the output directory. It is similar to copy-webpack-plugin in that it helps manage static assets, but it is more focused on handling assets within the module system.
The html-webpack-plugin simplifies the creation of HTML files to serve your webpack bundles. It can copy HTML files and automatically inject script tags for bundle files. It differs from copy-webpack-plugin by focusing on HTML files and their dependencies.
The assets-webpack-plugin generates a JSON file with the assets produced by webpack. It is similar to copy-webpack-plugin in that it deals with the output of assets, but it does not copy files; instead, it provides a manifest of the generated assets.
Copies individual files or entire directories, which already exist, to the build directory.
To begin, you'll need to install copy-webpack-plugin
:
npm install copy-webpack-plugin --save-dev
Then add the plugin to your webpack
config. 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" },
],
}),
],
};
ℹ️
copy-webpack-plugin
is not 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.
ℹ️ If you want
webpack-dev-server
to write files to the output directory during development, you can force it with thewriteToDisk
option or thewrite-file-webpack-plugin
.
ℹ️ You can get the original source filename from Asset Objects.
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,
},
}),
],
};
Name | Type | Default | Description |
---|---|---|---|
from | {String} | undefined | Glob or path from where we сopy 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 сopy files.
Globs accept fast-glob pattern-syntax.
Glob can only be a string
.
⚠️ Don't use directly
\\
infrom
option if it is aglob
(i.epath\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
Output path.
⚠️ Don't use directly
\\
into
(i.epath\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/
orpath
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]",
},
],
}),
],
};
Allows to modify the writing path.
⚠️ Don't return directly
\\
into
(i.epath\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/
orpath
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
\\
incontext
(i.epath\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/
orpath
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: [
// Сopied second and will overwrite "dir_2/file.txt"
{
from: "dir_1/file.txt",
to: "newfile.txt",
force: true,
priority: 10,
},
// Сopied 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 }),
},
],
}),
],
};
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 },
}),
],
};
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
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
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
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
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/**",
],
},
},
],
}),
],
};
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
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",
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",
},
],
}),
],
};
Please take a moment to read our contributing guidelines if you haven't yet done so.
FAQs
Copy files && directories with webpack
The npm package copy-webpack-plugin receives a total of 4,888,721 weekly downloads. As such, copy-webpack-plugin popularity was classified as popular.
We found that copy-webpack-plugin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.
Security News
ENISA’s 2024 report highlights the EU’s top cybersecurity threats, including rising DDoS attacks, ransomware, supply chain vulnerabilities, and weaponized AI.