copy-webpack-plugin v 6.0.3

将已经存在的单个文件或整个目录复制到构建目录。

开始

先安装

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

接下来将其加入您的 webpack 配置当中。举例:

webpack.config.js

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

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        { from: 'source', to: 'dest' },
        { from: 'other', to: 'public' },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12

WARNING

webpack-copy-plugin并不是用来复制构建过程中所生成的文件的;相反,它是复制源码树中已经存在的文件,作为构建过程的一部分而存在。

WARNING

如果你希望webpack-dev-server在开发过程中将文件写入输出目录,可以使用writeToDisk配置项或是write-file-webpack-plugin强制进行。

配置项

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,
      },
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

pattern

名称 类型 默认 描述
from String undefined 通配符或我们拷贝文件的路径
to String compiler.options.output 输出路径
context String options.context 或 compiler.options.context 这一项决定了如何解释上面from路径
globOptions Object undefined 通配符模式的配置项,可设置 ignore
toType String undefined 这一项定义了上面to的配置项 - 目录、文件或模板
force Boolean false 覆盖已经存在于compilation.assets中的文件。(通常由其他插件和加载器添加)
flattern Boolean false 移除所有的目录引用,仅复制文件名。
transform Function undefined 允许修改文件内容。
cacheTransform Boolean/String/Object false 启用transfrom缓存。您可以使用{ cache: { key: 'my-cache-key' } }来使缓存无效。
transformPath Function undefined 允许修改写入路径
noErrorOnMissing Boolean false 丢失文件时不产生错误

from

  • 类型:String
  • 默认:Undefined

通配符或我们拷贝文件的路径。通配符支持快速通配模式语法,只能为字符串。

如果是通配符的话(如 path\to\file.ext),不要在 from 配置项中直接使用 \\。因为在 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: '**/*',
        },
        // 如果绝对路径是“通配符”,我们将反斜杠替换为正斜杠,因为在“通配符”中只能使用正斜杠。
        path.posix.join(
          path.resolve(__dirname, 'src').replace(/\\/g, '/'),
          '*.txt'
        ),
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

对于 windows 系统

如果在 Windows 中将 from 定义为绝对文件路径或绝对文件夹路径,则可以使用 Windows 路径段\\

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, 'file.txt'),
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11

但是您应该始终在通配符表达式中使用正斜杠,请参阅快速通配符手册

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          // 如果绝对路径是“通配符”,我们将反斜杠替换为正斜杠,因为在“通配符”中只能使用正斜杠。
          from: path.posix.join(
            path.resolve(__dirname, 'fixtures').replace(/\\/g, '/'),
            '*.txt'
          ),
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

context根据from的类型(通配符、文件或目录)采取不同行为。更多示例

to

类型:String 默认:compiler.options.output

输出的路径。

如果是通配符的话(如 path\to\dest),不要在 to 配置项中直接使用 \\。因为在 UNIX 中,反斜杠是路径组件的有效字符,而不是分隔符。在 Windows 中,正斜杠和反斜杠都是分隔符。请用 /path方法代替。

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]',
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

context

类型:String 默认:options.context|compiler.options.context

这一项决定了如何解释上面from路径

如果是通配符的话(如 path\to\context),不要在 context 配置项中直接使用 \\。因为在 UNIX 中,反斜杠是路径组件的有效字符,而不是分隔符。在 Windows 中,正斜杠和反斜杠都是分隔符。请用 /path方法代替。

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: 'src/*.txt',
          to: 'dest/',
          context: 'app/',
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13

context配置项可以传入绝对或相对路径。如果context是相对路径,那么就会被转换为基于compiler.options.context的绝对路径。

此外,context表示如何解释搜索结果。进一步讲,它就是干这个的。

若要确定从哪里的资源架构拷贝到目标文件夹,请使用context配置项。

如果from配置为一个文件,那么context就是该文件所在的目录。因此,结果只会是文件名。

如果from配置为一个目录,那么contextfrom相同也是这个目录。在这种情况下,结果则是相对于指定目录找到的文件夹和文件的层次结构。

如果from配置为通配符,那么就会无视context配置项,结果也将是from中指定的结构。

更多示例

globOptions

类型:对象 默认:undefined

允许配置插件使用的通配模式匹配库。请参阅所支持配置项项的列表以从选择中排除文件,您应该使用globOptions.ignore配置项

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                from: 'public/**/*',
                globOptions: {
                        dot: true,
                        gitignore: true,
                        ignore: ['**/file.*', '**/ignored-directory/**'],
                    },
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

toType

类型:String 默认:undefined

决定to配置项是什么 —— 目录、文件或模板。有些时候很难说什么是to,举个例子:path/to/dir-with.ext。如果你想复制目录中的文件,您需要使用dir。我们尝试着自动识别type,所以您可能不需要它。

名称 类型 默认值 描述
'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',
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13

'file'

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                    from: 'path/to/file.txt',
                    to: 'file/without/extension',
                    toType: 'file',
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13

'template'

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                from: 'src/',
                to: 'dest/[name].[hash].[ext]',
                toType: 'template',
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13

force

类型:Boolean 默认:false

覆盖已经存在于compilation.assets中的文件。(通常由其他插件和加载器添加)。

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                    from: 'src/**/*',
                    to: 'dest/',
                    force: true,
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13

flattern

类型:Boolean 默认:false

移除所有的目录引用,仅复制文件名。

WARNING

⚠️如果拥有相同名字的文件,那么结果是不确定的。

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                    from: 'src/**/*',
                    to: 'dest/',
                    flatten: true,
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13

transform

类型:Function 默认:undefined

允许修改文件内容。

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                    from: 'src/*.png',
                    to: 'dest/', 
                    // content 参数是一个 Buffer 对象,可以使用 content.toString() 转换为字符串。
                    // absoluteFrom 参数是字符串,表示拷贝文件的绝对路径
                    transform(content, absoluteFrom) {
                        return optimize(content);
                    },
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                    from: 'src/*.png',
                    to: 'dest/',
                    transform(content, path) {
                        return Promise.resolve(optimize(content));
                    },
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

cacheTransform

类型:Boolean|String|Object 默认:false

启用/弃用并配置配置缓存。默认的路径是缓存目录:node_modules/.cache/copy-webpack-plugin

Boolean

启用/弃用transform缓存。

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                    from: 'src/*.png',
                    to: 'dest/',
                    transform(content, path) {
                        return optimize(content);
                    },
                    cacheTransform: true,
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Object

启用transform缓存并设置缓存目录和失效键。

webpack.config.js

module.exports = {
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                from: 'src/*.png',
                to: 'dest/',
                transform(content, path) {
                    return optimize(content);
                },
                cacheTransform: {
                    directory: path.resolve(__dirname, 'cache-directory'),
                    keys: {
                        // 可能是有用的基于外部值的无效缓存
                        // 举例:您可以基于`process.version - { node: process.version }`来使缓存无效
                        key: 'value',
                        },
                    },
                },
            ],
        }),
    ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

您可以使用函数来设置无效键。

webpack.config.js

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

异步函数。

webpack.config.js

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

              return {
                ...defaultCacheKeys,
                keys,
              };
            },
          },
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

transformPath

类型:Function 默认:undefined

允许修改写入路径。

如果是通配符的话(如 path\to\newFile),不要在 transformPath 配置项中直接使用 \\。因为在 UNIX 中,反斜杠是路径组件的有效字符,而不是分隔符。在 Windows 中,正斜杠和反斜杠都是分隔符。请用 /path方法代替。

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: 'src/*.png',
          to: 'dest/',
          transformPath(targetPath, absolutePath) {
            return 'newPath';
          },
        },
      ],
    }),
  ],
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: 'src/*.png',
          to: 'dest/',
          transformPath(targetPath, absolutePath) {
            return Promise.resolve('newPath');
          },
        },
      ],
    }),
  ],
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

noErrorOnMissing

类型:Boolean 默认:false

在丢失文件时不会产生错误。

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

1
2
3
4
5
6
7
8
9
10
11
12
13

options

名称 类型 默认值 描述
concurrency Number 100 fs模块并发请求的数量限制。

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [...patterns],
      options: { concurrency: 50 },
    }),
  ],
};
1
2
3
4
5
6
7
8

示例

from的不同变体(globfiledir)。

以下面的文件结构为例:

src/directory-nested/deep-nested/deepnested-file.txt
src/directory-nested/nested-file.txt
1
2

fromGlob(通配符)

那么您在from配置的应当是:

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: 'src/directory-nested/**/*',
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11

结果:

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

如果您希望结果仅仅是src/directory-nested/,那么from中应当只设置通配符(glob)。应当将发生搜索行为的文件夹移到context中。

webpack.config.js

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

1
2
3
4
5
6
7
8
9
10
11
12
13

结果:

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

from目录(dir)

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, 'src', 'directory-nested'),
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11

结果:

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

从技术上讲,带有预定义上下文的**/*等同于指定目录。

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: '**/*',
          context: path.resolve(__dirname, 'src', 'directory-nested'),
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12

结果:

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

from文件.

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(
            __dirname,
            'src',
            'directory-nested',
            'nested-file.txt'
          ),
        },
      ],
    }),
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

结果:

nested-file.txt
1

忽略文件的写法

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/**',
            ],
          },
        },
      ],
    }),
  ],
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23