CopyWebpackPlugin

免責事項 CopyWebpackPluginはコミュニティメンバーによって管理されているサードパーティパッケージであり、webpackと同じサポート、セキュリティポリシー、またはライセンスを持っていない可能性があり、webpackによって管理されていません。

npm node tests cover discussion size

既存の個々のファイルまたはディレクトリ全体をビルドディレクトリにコピーします。

はじめに

まず、copy-webpack-pluginをインストールする必要があります。

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

または

yarn add -D copy-webpack-plugin

または

pnpm add -D copy-webpack-plugin

次に、プラグインをwebpack構成に追加します。例:

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 は、ビルドプロセスで生成されたファイルをコピーするように設計されていません。むしろ、ビルドプロセスの一環として、ソースツリーにすでに存在するファイルをコピーするためのものです。

注意

開発中に 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" },
        "path/to/source", // absolute or relative, files/directories/globs - see below for examples
      ],
      options: {
        concurrency: 100,
      },
    }),
  ],
};

Patterns

from

type from = string;

デフォルト: undefined

ファイルのコピー元となるグロブまたはパス。グロブは fast-glob パターン構文を受け入れます。グロブは string のみ可能です。

警告

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 で定義する場合は、Windows パスセグメント (\\) を使用できます。

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

ただし、glob 式では常にフォワードスラッシュを使用する必要があります。fast-glob マニュアルを参照してください。

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

context は、from が何であるか (globfile、または dir) によって動作が異なります。詳しくは を参照してください。

to

type to =
  | string
  | ((pathData: { context: string; absoluteFilename?: string }) => string);

デフォルト: compiler.options.output

string

出力パス。

警告

to (例:path\to\dest)オプションでは、\\ を直接使用しないでください。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]",
        },
      ],
    }),
  ],
};
function

書き込みパスを変更できます。

警告

to (例:path\to\newFile)オプションでは、\\ を直接返さないでください。UNIX では、バックスラッシュはパスコンポーネント内の有効な文字であり、セパレータではありません。Windows では、フォワードスラッシュとバックスラッシュはどちらもセパレータです。代わりに / または path メソッドを使用してください。

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 context = string;

デフォルト: options.context|compiler.options.context

from に (1) 前置され、(2) 結果のパスの先頭から削除されるパス。

警告

context (例:path\to\context)オプションでは、\\ を直接使用しないでください。UNIX では、バックスラッシュはパスコンポーネント内の有効な文字であり、セパレータではありません。Windows では、フォワードスラッシュとバックスラッシュはどちらもセパレータです。代わりに / または path メソッドを使用してください。

webpack.config.js

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

context は絶対パスまたは相対パスにできます。相対パスの場合、compiler.options.context に基づいて絶対パスに変換されます。

context は、from に glob が含まれている場合にのみ明示的に設定する必要があります。それ以外の場合、contextfrom がファイルかディレクトリかに基づいて自動的に設定されます。

from がファイルの場合、context はそのディレクトリです。結果のパスはファイル名のみになります。

from がディレクトリの場合、contextfrom と等しくなります。結果のパスは、ディレクトリの内容(ネストされた内容を含む)の、そのディレクトリからの相対パスになります。

context の使用例は、 で説明されています。

globOptions

type globOptions = import("globby").Options;

デフォルト: undefined

プラグインが使用する glob パターンマッチングライブラリを設定できます。サポートされているオプションのリストを参照してください 選択からファイルを除外するには、globOptions.ignore オプションを使用する必要があります。

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "public/**/*",
          globOptions: {
            dot: true,
            gitignore: true,
            ignore: ["**/file.*", "**/ignored-directory/**"],
          },
        },
      ],
    }),
  ],
};

filter

type filter = (filepath: string) => boolean;

デフォルト: undefined

注意

パスでファイルを無視するには、globOptions.ignore オプションを使用してください。

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 toType = "dir" | "file" | "template";

デフォルト: undefined

to オプションがディレクトリ、ファイル、テンプレートのどれであるかを決定します。path/to/dir-with.ext のように、to が何であるかを判断するのが難しい場合があります。ディレクトリにファイルをコピーする場合は、dir オプションを使用する必要があります。type は自動的に判別しようとするため、このオプションはほとんどの場合必要ありません。

名前デフォルト説明
'dir'stringundefinedto に拡張子がない場合、または '/' で終わる場合
'file'stringundefinedto がディレクトリではなく、テンプレートでもない場合
'template'stringundefinedtoテンプレートパターンが含まれている場合
'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 force = boolean;

デフォルト: false

compilation.assets にすでに存在するファイル (通常は他のプラグイン/ローダーによって追加されたファイル) を上書きします。

webpack.config.js

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

priority

type priority = number;

デフォルト: 0

同じ宛先名を持つファイルのコピーの優先度を指定できます。優先度の高いパターンのファイルは後でコピーされます。ファイルを上書きするには、force オプションを有効にする必要があります。

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 transform =
  | {
      transformer: (input: string, absoluteFilename: string) => string | Buffer;
      cache?: boolean | TransformerCacheObject | undefined;
    }
  | ((input: string, absoluteFilename: string) => string | Buffer);

デフォルト: undefined

ファイルの内容を変更できます。

function

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          // The `content` argument is a [`Buffer`](https://node.dokyumento.jp/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
名前デフォルト説明
transformerundefinedファイルの内容を変更できます。
cachefalsetransform のキャッシュを有効にします。キャッシュを無効にするには、transform: { cache: { key: 'my-cache-key' } } を使用できます。
transformer

type transformer = (input: string, absoluteFilename: string) => string;

デフォルト: undefined

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          // The `content` argument is a [`Buffer`](https://node.dokyumento.jp/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 cache =
  | boolean
  | {
      keys: {
        [key: string]: any;
      };
    }
  | {
      keys: (
        defaultCacheKeys: {
          [key: string]: any;
        },
        absoluteFilename: string,
      ) => Promise<{
        [key: string]: any;
      }>;
    }
  | undefined;

デフォルト: 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 のキャッシュを有効にし、無効化キーを設定します。

webpack.config.js

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "src/*.png",
          to: "dest/",
          transform: {
            transformer(content, path) {
              return optimize(content);
            },
            cache: {
              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",
              },
            },
          },
        },
      ],
    }),
  ],
};

関数を使用して無効化キーを設定できます。

シンプルな関数

webpack.config.js

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

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

非同期関数

webpack.config.js

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

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

transformAll

type transformAll = (
  data: {
    data: Buffer;
    sourceFilename: string;
    absoluteFilename: string;
  }[],
) => any;

デフォルト: undefined

複数のファイルの内容を変更して、結果を1つのファイルに保存できます。

注意

to オプションは指定する必要があり、ファイルを参照する必要があります。[contenthash] および [fullhash] テンプレート文字列のみを使用できます。

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://node.dokyumento.jp/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 noErrorOnMissing = boolean;

デフォルト: false

ファイルが見つからない場合にエラーを生成しません。

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

info

type info =
  | Record<string, any>
  | ((item: {
      absoluteFilename: string;
      sourceFilename: string;
      filename: string;
      toType: ToType;
    }) => Record<string, any>);

デフォルト: 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 }),
        },
      ],
    }),
  ],
};

オプション

concurrency

type

type concurrency = number;

デフォルト: 100

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/ で開始したくない場合は、src/directory-nested/context に移動し、グロブパターン **/* だけが from に残るようにする必要があります

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 が Dir の場合

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 が File の場合
module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(
            __dirname,
            "src",
            "directory-nested",
            "nested-file.txt",
          ),
        },
      ],
    }),
  ],
};

結果

nested-file.txt

技術的には、これは path.dirname(pathToFile) と等しい事前定義されたコンテキストを持つファイル名です。

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: [
        {
          // 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",
        },
      ],
    }),
  ],
};

結果

"newdirectory/file-1.txt",
"newdirectory/nestedfile.txt",
"newdirectory/nested/deep-nested/deepnested.txt",
"newdirectory/nested/nestedfile.txt",

JavaScript ファイルをミニマイザーに通すのをスキップする

Terser を使用して評価および最小化せずに、*.js ファイルをそのまま宛先にコピーする必要がある場合に便利です。

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 および monorepos

yarn workspaces または monorepos を使用する場合、パッケージのホイスト方法により、node_modules からの相対コピーパスが壊れる可能性があります。これを回避するには、require.resolve を使用して、ファイルのコピー元を明示的に指定する必要があります。

webpack.config.js

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

貢献

まだお読みでない場合は、貢献ガイドラインを読む時間を取ってください。

CONTRIBUTING

ライセンス

MIT