將已存在的個別檔案或整個目錄複製到建置目錄。
首先,您需要安裝 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,
},
}),
],
};
模式
從
類型
type from = string;
預設值:未定義
Glob 或路徑,用於複製檔案。Glob 接受 fast-glob 模式語法。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
如果您在 Windows
中將 from
定義為絕對檔案路徑或絕對資料夾路徑,則可以使用 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
的內容(glob
、file
或 dir
)而有所不同。更多 範例
到
類型
type to =
| string
| ((pathData: { context: string; absoluteFilename?: string }) => string);
預設值:compiler.options.output
字串
輸出路徑。
警告
請勿在
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
一個路徑,將(1)加到 from
之前,並(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
轉換為一個絕對路徑。
只有當 from
包含一個 glob 時,才應該明確設定 context
。否則,context
會根據 from
是檔案或目錄自動設定
如果 from
是檔案,則 context
是它的目錄。結果路徑將僅為檔名。
如果 from
是目錄,則 context
等於 from
。結果路徑將是目錄內容(包括巢狀內容)相對於目錄的路徑。
context
的用法說明請參閱這些 範例
。
globOptions
類型
type globOptions = import("globby").Options;
預設值:未定義
允許設定外掛程式所使用的 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;
預設值:未定義
注意
若要依路徑忽略檔案,請使用
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";
預設值:未定義
決定 to
選項是什麼 - 目錄、檔案或範本。有時很難說 to
是什麼,例如 path/to/dir-with.ext
。如果您想複製目錄中的檔案,您需要使用 dir
選項。我們會嘗試自動判斷 type
,因此您很可能不需要這個選項。
名稱 | 類型 | 預設值 | 說明 |
---|---|---|---|
'dir' | 字串 | 未定義 | 如果 to 沒有副檔名或以 '/' 結尾 |
'file' | 字串 | 未定義 | 如果 to 不是目錄也不是範本 |
'template' | 字串 | 未定義 | 如果 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].[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);
預設值:未定義
允許修改檔案內容。
function
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/*.png",
to: "dest/",
// The `content` argument is a [`Buffer`](https://node.dev.org.tw/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
名稱 | 預設值 | 說明 |
---|---|---|
轉換器 | 未定義 | 允許修改檔案內容。 |
快取 | false | 啟用 transform 快取。您可以使用 transform: { cache: { key: 'my-cache-key' } } 來使快取失效。 |
transformer
類型
type transformer = (input: string, absoluteFilename: string) => string;
預設值:未定義
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/*.png",
to: "dest/",
// The `content` argument is a [`Buffer`](https://node.dev.org.tw/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;
預設值:未定義
允許您修改多個檔案的內容,並將結果儲存到一個檔案。
注意
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.dev.org.tw/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>);
預設值:未定義
允許新增資產資訊。
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 concurrency = number;
預設值:100
限制同時對 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
中指定的任何內容都將包含在結果中
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
中只會保留 glob 模式 **/*
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
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "src", "directory-nested"),
},
],
}),
],
};
結果
deep-nested/deepnested-file.txt,
nested-file.txt
技術上來說,這是 **/*
,預先定義的 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
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(
__dirname,
"src",
"directory-nested",
"nested-file.txt",
),
},
],
}),
],
};
結果
nested-file.txt
技術上來說,這是一個檔名,預先定義的 context 等於 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",
如果你需要將 *.js
檔案「原樣」複製到目的地,而不需要使用 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
和 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",
},
],
}),
],
};
如果你尚未閱讀我們的貢獻指南,請花點時間閱讀。