# @11ty/recursive-copy 中文文档

规范地址：https://npmcn.com/package/%4011ty/recursive-copy/

版本：5\.2\.0
npm 元数据更新时间：2026-11-02T23:33:33.951Z
中文译文更新时间：2026-11-05T17:18:39.354Z
软件包许可：ISC

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%4011ty/recursive-copy
原文对照：https://npmcn.com/package/%4011ty/recursive-copy/?lang=original
项目主页：https://github.com/11ty/recursive-copy
源码仓库：https://github.com/11ty/recursive-copy

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：27.6 kB，7 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：2 个
- 首次发布：2024-07-11T15:57:34.252Z
- 最新版本发布：2026-11-02T23:33:33.600Z
- 近 30 天下载量：684678（2026-10-04 至 2026-11-02，npm 官方下载统计）
- 已发布版本数：12（近 12 个月 7 个）

## 中文简介

一个叉子 `recursive-copy`: 简单而灵活的文件副本工具

## 安装

```sh
npm install @11ty/recursive-copy
```

也可以使用：`pnpm add @11ty/recursive-copy`、`yarn add @11ty/recursive-copy`、`bun add @11ty/recursive-copy`

## README

# `@11ty/recursive-copy`

临时叉子 [`timkendrick/recursive-copy`](https://github.com/timkendrick/recursive-copy) 满足 [https://github.com/11ty/eleventy/issues/3299 互联网档案馆的存檔,存档日期2013-12-02](https://github.com/11ty/eleventy/issues/3299) 慢慢的十一点 [移动以使用节点本地 API `fs.cp`](https://github.com/11ty/eleventy/issues/3360)。 。 。 .

-   v5.x 需要节点 20+
-   v4.x 需要节点 18+
-   v3.x需要节点0.10+
-   v2.x需要节点0.10+

> 简单而灵活的文件副本工具

## 特征

-   连续复制整个目录等级
-   通过传递过滤函数、正则表达式或 glob 选择哪些文件被复制
-   动态重命名文件,包括更改输出路径
-   使用流转换文件内容
-   选择是否覆盖已存在文件
-   选择是否复制系统文件
-   过滤出 [垃圾](https://www.npmjs.com/package/junk) 默认文件
-   为处理的每个文件发送开始、完成和出错事件
-   基于承诺的可选界面

## 实例

#### 节点风格的回调接口

```javascript
var copy = require('@11ty/recursive-copy');

copy('src', 'dest', function(error, results) {
    if (error) {
        console.error('Copy failed: ' + error);
    } else {
        console.info('Copied ' + results.length + ' files');
    }
});
```

#### 承诺接口

```javascript
var copy = require('@11ty/recursive-copy');

copy('src', 'dest')
    .then(function(results) {
        console.info('Copied ' + results.length + ' files');
    })
    .catch(function(error) {
        console.error('Copy failed: ' + error);
    });
```

#### ES2015+ 使用量

```javascript
import copy from '@11ty/recursive-copy';

try {
    const results = await copy('src', 'dest');
    console.info('Copied ' + results.length + ' files');
} catch (error) {
    console.error('Copy failed: ' + error);
}
```

#### 高级选项

```javascript
var copy = require('@11ty/recursive-copy');

var path = require('path');
var through = require('through2');

var options = {
    overwrite: true,
    expand: true,
    dot: true,
    junk: true,
    filter: [
        '**/*',
        '!.htpasswd'
    ],
    rename: function(filePath) {
        return filePath + '.orig';
    },
    transform: function(src, dest, stats) {
        if (path.extname(src) !== '.txt') { return null; }
        return through(function(chunk, enc, done)  {
            var output = chunk.toString().toUpperCase();
            done(null, output);
        });
    }
};

copy('src', 'dest', options)
    .on(copy.events.COPY_FILE_START, function(copyOperation) {
        console.info('Copying file ' + copyOperation.src + '...');
    })
    .on(copy.events.COPY_FILE_COMPLETE, function(copyOperation) {
        console.info('Copied to ' + copyOperation.dest);
    })
    .on(copy.events.ERROR, function(error, copyOperation) {
        console.error('Unable to copy ' + copyOperation.dest);
    })
    .then(function(results) {
        console.info(results.length + ' file(s) copied');
    })
    .catch(function(error) {
        return console.error('Copy failed: ' + error);
    });
```

## 使用量

### `copy(src, dest, [options], [callback])`

递归复制文件和文件夹 `src` 改为 `dest`

#### 参数 :

| 名称 | 类型 | 需求 | 默认 | 说明 |
| --- | --- | --- | --- | --- |
| `src` | `string` | 对 | 不详 | 源文件/文件夹路径 |
| `dest` | `string` | 对 | 不详 | 目标文件/文件夹路径 |
| `options.overwrite` | `boolean` | 没有 | `false` | 是否覆盖目标文件 |
| `options.expand` | `boolean` | 没有 | `false` | 是否扩展符号链接 |
| `options.dot` | `boolean` | 没有 | `false` | 是否先复制文件 `.` |
| `options.junk` | `boolean` | 没有 | `false` | 是否复制 OS 垃圾文件( 例如 ) . `.DS_Store`, (中文(简体) ), `Thumbs.db`(中文(简体) ) |
| `options.filter` | `function`, (中文(简体) ), `RegExp`, (中文(简体) ), `string`, (中文(简体) ), `array` | 没有 | `null` | 过滤函数 /正则表达式 / glob 决定要复制的文件( 使用) [最大切换](https://www.npmjs.com/package/maximatch)(中文(简体) ) |
| `options.rename` | `function` | 没有 | `null` | 将源路径映射到目的路径的函数 |
| `options.transform` | `function` | 没有 | `null` | 返回用于修改文件内容的变换流的函数 |
| `options.results` | `boolean` | 没有 | `true` | 是否返回一系列复制结果 |
| `options.concurrency` | `number` | 没有 | `255` | 最大同时复制操作次数 |
| `options.debug` | `boolean` | 没有 | `false` | 是否日志调试信息 |
| `options.streams` | `boolean` | 没有 | `false` | 是否用流来复制文件内容 [`fs.copyFile`](https://nodejs.org/api/fs.html#fspromisescopyfilesrc-dest-mode) (之前的行为) |
| `callback` | `function` | 没有 | `null` | 召回, 在成功/ 失败时引用 |

#### 回返情况:

`Promise<Array>` 承诺, 以一系列复制结果实现 :

```json
[
    {
        "src": "/path/to/src",
        "dest": "/path/to/dest",
        "stats": <Stats>
    },
    {
        "src": "/path/to/src/file.txt",
        "dest": "/path/to/dest/file.txt",
        "stats": <Stats>
    },
    {
        "src": "/path/to/src/subfolder",
        "dest": "/path/to/dest/subfolder",
        "stats": <Stats>
    },
    {
        "src": "/path/to/src/subfolder/nested.txt",
        "dest": "/path/to/dest/subfolder/nested.txt",
        "stats": <Stats>
    }
]
```

### `copy.shouldCopy(filePath, [options])`

返回是否为 `dot` 财务报告和审定财务报表 `junk` 选项保存一个文件,对照其基准名检查(`filter` (不应用).

```javascript
copy.shouldCopy('src/.DS_Store', { dot: true }); // false
copy.shouldCopy('src/.htaccess', { dot: true }); // true
```

## 活动

返回的值 `copy` 函数执行 `EventEmitter` 界面,并释放以下事件:

| 活动 | 处理器签名 |
| --- | --- |
| `copy.events.ERROR` | `function(error, ErrorInfo)` |
| `copy.events.COMPLETE` | `function(Array<CopyOperation>)` |
| `copy.events.CREATE_DIRECTORY_START` | `function(CopyOperation)` |
| `copy.events.CREATE_DIRECTORY_ERROR` | `function(error, CopyOperation)` |
| `copy.events.CREATE_DIRECTORY_COMPLETE` | `function(CopyOperation)` |
| `copy.events.CREATE_SYMLINK_START` | `function(CopyOperation)` |
| `copy.events.CREATE_SYMLINK_ERROR` | `function(error, CopyOperation)` |
| `copy.events.CREATE_SYMLINK_COMPLETE` | `function(CopyOperation)` |
| `copy.events.COPY_FILE_START` | `function(CopyOperation)` |
| `copy.events.COPY_FILE_ERROR` | `function(error, CopyOperation)` |
| `copy.events.COPY_FILE_COMPLETE` | `function(CopyOperation)` |

...如果处理器签名中提到的类型如下:

### `ErrorInfo`

| 财产 | 类型 | 说明 |
| --- | --- | --- |
| `src` | `string` | 无法复制的文件/文件夹/ symlink 的来源路径 |
| `dest` | `string` | 无法复制的文件/文件夹/同义链接的目标路径 |

### `CopyOperation`

| 财产 | 类型 | 说明 |
| --- | --- | --- |
| `src` | `string` | 相关文件/文件夹/同义链接的源路径 |
| `dest` | `string` | 相关文件/文件夹/同义链接的目标路径 |
| `stats` | `fs.Stats` | 相关文件/文件夹/同义链接的Stats |

## 常见问题

### @11ty/recursive-copy 是什么？

一个叉子 recursive-copy: 简单而灵活的文件副本工具

### 如何安装 @11ty/recursive-copy？

在项目目录运行 npm install @11ty/recursive-copy，或使用 pnpm add / yarn add / bun add。

### @11ty/recursive-copy 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @11ty/recursive-copy 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @11ty/recursive-copy 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @11ty/recursive-copy 可以商用吗？

@11ty/recursive-copy 使用 ISC 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @11ty/recursive-copy 的下载量有多少？

根据 npm 官方下载统计，@11ty/recursive-copy 在 2026/10/04 – 2026/11/02 这 30 天内被下载 684,678 次，日均约 22,823 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @11ty/recursive-copy 还在维护吗？

最新版本 5\.2\.0 发布于 2026/11/03（3 天前）；至今共发布 12 个版本，其中过去 12 个月发布了 7 个；首次发布于 2024/07/11。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

