copy-webpack-plugin文档翻译

汪晨
2023-12-01

翻译一下,方便自己后续查阅,翻译时插件版本: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.获取到原始文件名

Options

插件的签名:

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

NameTypeDefaultDescription
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(globfile 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 . 我们会尽可能自动的确定类型,你一般用不到这个选项.

NameTypeDefaultDescription
'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

NameTypeDefaultDescription
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 }),
        },
      ],
    }),
  ],
};

Options

NameTypeDefaultDescription
concurrency{Number}100限制对fs的同时请求数

concurrency

限制对fs的同时请求数

webpack.config.js

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

例子

不同类型的 from (globfile 或 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",

 

 

 

 

 

 

 

 

 

 

 类似资料: