翻译一下,方便自己后续查阅,翻译时插件版本:7.0.0,少部分通过自己的理解翻译,非全文直译。
CopyWebpackPlugin插件作用:拷贝单独一个文件或者一整个目录到编译结果目录
安装 copy-webpack-plugin
:
$ npm install copy-webpack-plugin --save-dev
添加到 webpack 配置文件
. 例如:
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "source", to: "dest" },
{ from: "other", to: "public" },
],
}),
],
};
注意:
webpack-copy-plugin 不是用于拷贝编译过程中生成的文件 ; 它是用于拷贝已经存在的文件。
如果你想 webpack-dev-server
在开发期间将文件写到output目录, 你可以配置 writeToDisk
或者用 write-file-webpack-plugin插件
.
你可以在 Asset Objects.获取到原始文件名
插件的签名:
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 | 全局或者我们要复制的文件的路径 |
to | {String|Function} | compiler.options.output | 输出路径 |
context | {String} | options.context || compiler.options.context | 确定如何解析from 路径的路径. |
globOptions | {Object} | undefined | 传递给模式匹配库的Options参数,包含 ignore 配置选项 . |
filter | {Function} | undefined | 允许过滤复制的资源 |
toType | {String} | undefined | 确定to选项是什么 - 目录, 文件或者模板 |
force | {Boolean} | false | 覆盖compilation.assets中 已经存在的文件 (一般是其他插件或者loader添加的). |
transform | {Object} | undefined | 允许修改文件内容. 开启 transform 缓存. 你可以使用{ transform: {cache: { key: 'my-cache-key' }} } 使缓存失效 |
noErrorOnMissing | {Boolean} | false | 在找不到文件的时候不生成错误信息. |
info | {Object|Function} | undefined | 允许添加资源信息 |
from
Type: String
Default: undefined
Glob 或者 我们要复制文件的路径. Globs 接受 fast-glob pattern-syntax. Glob 只能是一个字符串.
注意:不要直接在from
选项中使用 \\
,如果它是一个 glob
(如:path\to\file.ext
) 选项,因为在 UNIX 反斜杠在路径中是一个有效字符,例如, 它不是一个分割符. 在windows, 正斜杠和反斜杠都是分隔符. 请使用 /
.
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"
),
],
}),
],
};
windows
如果你定义 from
为绝对路径,你可以使用 windows 路径分隔符 (\\
)
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "file.txt"),
},
],
}),
],
};
glob
表达式中,你必须使用正斜杠 看 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"
),
},
],
}),
],
};
根据from(glob
, file
or dir
).不同, context
有不同的表现 更多 例子(examples
)
to
Type: String|Function
Default: compiler.options.output
String
输出路径
注意:不要直接在from
选项中使用 \\
,如果它是一个 glob
(如:path\to\file.ext
) 选项,因为在 UNIX 反斜杠在路径中是一个有效字符,例如, 它不是一个分割符. 在windows, 正斜杠和反斜杠都是分隔符. 请使用 /
.
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]",
},
],
}),
],
};
函数
运行修改输出路径
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
一个用于确定如何解析from路径的路径
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/*.txt",
to: "dest/",
context: "app/",
},
],
}),
],
};
context
可以使绝对路径或者是相对路径. 如果 context
是相对路径, 它会根据 compiler.options.context
被转化成绝对路径
此外, context
标明如何解析搜索结果. 它更多的用于此场景
context
选项用于确定从from找到的资源会被拷贝到目标文件
如果 from
是一个文件, context
相当于文件所在目录. 输出结果只包含文件名.
如果from
是一个目录, 输出结果会是所找到文件context后面的部分.
如果from
是一个 glob, 无论context设置什么
, 输出结果会以from设置的结构为准
(这几句看不懂的话,往下面找,有相关的例子,结合着看就好懂了)
更多例子 examples
globOptions
Type: Object
Default: undefined
glob 库的配置选项. 查看支持的选项 ,要排除某些文件,你可以使用 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
ℹ️ 通过path忽略文件,使用 [
globOptions.ignore
]((#globoptions) 选项.
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
确定to选项是什么
- 目录, 文件或者模板 有时候很难确定to是什么, 例如 path/to/dir-with.ext
. 如果你想要复制目录里的文件,你需要使用 dir
. 我们会尽可能自动的确定类型,你一般用不到这个选项.
Name | Type | Default | Description |
---|---|---|---|
'dir' | {String} | undefined | 如果 to 没有扩展名或者 '/'结尾 |
'file' | {String} | undefined | 如果to 不是一个目录或者模板 |
'template' | {String} | undefined | 如果 to 包含一个 模板模式 |
'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].[hash].[ext]",
toType: "template",
},
],
}),
],
};
force
Type: Boolean
Default: false
重写已经在 compilation.assets
中的文件(一般是其他插件或loader添加的).
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/**/*",
to: "dest/",
force: true,
},
],
}),
],
};
transform
Type: Function|Object
Default: undefined
允许修改文件内容.
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 | 允许修改文件内容 |
cache | {Boolean|Object} | false | 开启transform缓存 . 你可以使用 transform: { cache: { key: 'my-cache-key' } } 使缓存失效 |
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
开启/关闭和配置缓存. 默认缓存目录: node_modules/.cache/copy-webpack-plugin
.
Boolean
开启/关闭 transform
缓存.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/*.png",
to: "dest/",
transform: {
transformer(content, path) {
return optimize(content);
},
cache: true,
},
},
],
}),
],
};
Object
开启transform
缓存并设置缓存缓存目录和缓存根据那个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",
},
},
},
},
],
}),
],
};
你可以通过函数设置失效 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: (defaultCacheKeys, absoluteFrom) => {
const keys = getCustomCacheInvalidationKeysSync();
return {
...defaultCacheKeys,
keys,
};
},
},
},
},
],
}),
],
};
Async 函数:
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,
};
},
},
},
},
],
}),
],
};
noErrorOnMissing
Type: Boolean
Default: false
找不到文件的时候,不触发错误;
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "missing-file.txt"),
noErrorOnMissing: true,
},
],
}),
],
};
info
Type: Object|Function<Object>
Default: undefined
允许添加资源信息.
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 | 限制对fs的同时请求数 |
concurrency
限制对fs的同时请求数
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [...patterns],
options: { concurrency: 50 },
}),
],
};
不同类型的 from
(glob
, file
或 dir
).
以下面的文件结构作为例子:
src/directory-nested/deep-nested/deepnested-file.txt
src/directory-nested/nested-file.txt
From 是一个 Glob
所有你在from中指定的,都会包含在结果中:
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/directory-nested/**/*",
},
],
}),
],
};
结果:
src/directory-nested/deep-nested/deepnested-file.txt,
src/directory-nested/nested-file.txt
如果你只想要src/directory-nested/
, 你需要设置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"),
},
],
}),
],
};
结果:
deep-nested/deepnested-file.txt,
nested-file.txt
From 是一个目录
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "src", "directory-nested"),
},
],
}),
],
};
结果:
deep-nested/deepnested-file.txt,
nested-file.txt
这等同于下面的设置.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "**/*",
context: path.resolve(__dirname, "src", "directory-nested"),
},
],
}),
],
};
结果:
deep-nested/deepnested-file.txt,
nested-file.txt
From 是一个文件
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(
__dirname,
"src",
"directory-nested",
"nested-file.txt"
),
},
],
}),
],
};
结果:
nested-file.txt
这等同于下面设置
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "nested-file.txt",
context: path.resolve(__dirname, "src", "directory-nested"),
},
],
}),
],
};
结果:
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/**",
],
},
},
],
}),
],
};
展平复制
删除所有目录,只复制文件名
⚠️ 如果有相同的文件名,结果是不确定的
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/**/*",
to: "[name].[ext]",
},
],
}),
],
};
结果:
file-1.txt
file-2.txt
nested-file.txt
复制到新目录
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
// 当复制以点开头的文件时, 必须制定toType配置项
// toType: "file",
to({ context, absoluteFilename }) {
return `newdirectory/${path.relative(context, absoluteFilename)}`;
},
from: "directory",
},
],
}),
],
};
结果:
"newdirectory/file-1.txt",
"newdirectory/nestedfile.txt",
"newdirectory/nested/deep-nested/deepnested.txt",
"newdirectory/nested/nestedfile.txt",