Skip to navigation Skip to main content

Passthrough File Copy

On this page

如果我们需要把非 Eleventy 模板之类的文件复制到输出目录中的话,可以使用被称为直接复制文件(Passthrough File Copy)的功能。

Configuration API Method

Use a configuration API method to specify files or directories for Eleventy to copy to the output folder.

eleventy.config.js
export default function (eleventyConfig) {
	// Output directory: _site

	// Copy `img/` to `_site/img/`
	eleventyConfig.addPassthroughCopy("img");

	// Copy `css/fonts/` to `_site/css/fonts/`
	// Keeps the same directory structure.
	eleventyConfig.addPassthroughCopy("css/fonts");

	// Copy any .jpg file to `_site`, via Glob pattern
	// Keeps the same directory structure.
	eleventyConfig.addPassthroughCopy("**/*.jpg");
};
module.exports = function (eleventyConfig) {
	// Output directory: _site

	// Copy `img/` to `_site/img/`
	eleventyConfig.addPassthroughCopy("img");

	// Copy `css/fonts/` to `_site/css/fonts/`
	// Keeps the same directory structure.
	eleventyConfig.addPassthroughCopy("css/fonts");

	// Copy any .jpg file to `_site`, via Glob pattern
	// Keeps the same directory structure.
	eleventyConfig.addPassthroughCopy("**/*.jpg");
};
直接复制文件(Passthrough File Copy)功能所复制的内容是相对于项目更目录的,而 不是 你为 Eleventy 所设置的输入目录(即配置文件中的 input 配置项)。

如果不需要保持原始的目录结构的话,可以 改变输出目录

input 目录是被如何处理的

如上所示,直接复制文件(passthrough file copy)所复制的文件路径是相对于项目的根目录(而不是所设置的输入目录)而言的。因此,如果直接复制文件(passthrough file copy)所复制的路径位于输入目录内的话,则输入目录将被剥离。

例如:

  • input directory is src
  • output directory is _site.

如果我们使用直接复制文件(passthrough file copy)功能复制 src/img 的话,它将被复制到 _site/img

eleventy.config.js
export default function (eleventyConfig) {
	// Input directory: src
	// Output directory: _site

	// The following copies to `_site/img`
	eleventyConfig.addPassthroughCopy("src/img");
};
module.exports = function (eleventyConfig) {
	// Input directory: src
	// Output directory: _site

	// The following copies to `_site/img`
	eleventyConfig.addPassthroughCopy("src/img");
};

使用 Glob 模式匹配

在本例中,我们将所有 jpg 图片文件复制到输出目录中,并保持各自原始的目录结构。如果不想保持原始目录结构的话,可以 修改输出目录。

注意,此方法比不使用 glob 模式匹配的方法慢,因为它需要搜索整个目录结构并逐个复制文件。

eleventy.config.js
export default function (eleventyConfig) {
	// Find and copy any `jpg` files, maintaining directory structure.
	eleventyConfig.addPassthroughCopy("**/*.jpg");
};
module.exports = function (eleventyConfig) {
	// Find and copy any `jpg` files, maintaining directory structure.
	eleventyConfig.addPassthroughCopy("**/*.jpg");
};

补上输出目录 _site 之后的完整路径如下:

  • img/avatar.jpg will copy to _site/img/avatar.jpg
  • subdir/img/avatar.jpg will copy to _site/subdir/img/avatar.jpg

Copy a file alongside a Template Added in v3.1.0

Use the HTML Relative Passthrough Copy Mode to copy files referenced in any template syntax that outputs to .html. Issue #3573

eleventy.config.js
export default function(eleventyConfig) {
	// Relative to the project root directory
	eleventyConfig.addPassthroughCopy("content/**/*.mp4", {
		mode: "html-relative"
	});
}
module.exports = function(eleventyConfig) {
	// Relative to the project root directory
	eleventyConfig.addPassthroughCopy("content/**/*.mp4", {
		mode: "html-relative"
	});
}
Full options list
eleventy.config.js
export default async function(eleventyConfig) {
	// glob or Array of globs to match for copy
	eleventyConfig.addPassthroughCopy("**/*.png", {
		mode: "html-relative",
		paths: [], // additional fallback directories to look for source files
		failOnError: true, // throw an error when a path matches (via `match`) but not found on file system
		copyOptions: { dot: false }, // `recursive-copy` copy options
	});
}
module.exports = async function(eleventyConfig) {
	// glob or Array of globs to match for copy
	eleventyConfig.addPassthroughCopy("**/*.png", {
		mode: "html-relative",
		paths: [], // additional fallback directories to look for source files
		failOnError: true, // throw an error when a path matches (via `match`) but not found on file system
		copyOptions: { dot: false }, // `recursive-copy` copy options
	});
}

Any references that match this glob in a[href], video[src], audio[src], source, img[src], [srcset] and a whole bunch more (via posthtml-urls) will colocate the file alongside your template (reusing any permalink values correctly). If a passthrough copy file is not found to be referenced in an HTML output file, it will not be copied to the output directory.

As a few example paths, with an output directory of _site:

  • <video src="video.mp4"> on template.njk will copy to _site/template/video.mp4 alongside _site/template/index.html.
  • <video src="assets/video.mp4"> on dir/template.njk will copy to _site/dir/template/assets/video.mp4 alongside _site/dir/template/index.html
HTML Relative Copy Mode restrictions
  • dot files are filtered out by default (override by changing the copyOptions.dot: false default, consult the Full options list above)
  • Referenced files must be inside the project’s root directory.
  • Absolute paths are ignored.

更改输出目录

除了传入字符串类型的参数,还支持对象作为参数,结构如下:{ "input": "target" }

eleventy.config.js
export default function (eleventyConfig) {
	// Input directory: src
	// Output directory: _site

	// Copy `img/` to `_site/subfolder/img`
	eleventyConfig.addPassthroughCopy({ img: "subfolder/img" });

	// Copy `src/img/` to `_site/subfolder/img`
	eleventyConfig.addPassthroughCopy({ "src/img": "subfolder/img" });

	// Copy `random-folder/img/` to `_site/subfolder/img`
	eleventyConfig.addPassthroughCopy({ "random-folder/img": "subfolder/img" });
};
module.exports = function (eleventyConfig) {
	// Input directory: src
	// Output directory: _site

	// Copy `img/` to `_site/subfolder/img`
	eleventyConfig.addPassthroughCopy({ img: "subfolder/img" });

	// Copy `src/img/` to `_site/subfolder/img`
	eleventyConfig.addPassthroughCopy({ "src/img": "subfolder/img" });

	// Copy `random-folder/img/` to `_site/subfolder/img`
	eleventyConfig.addPassthroughCopy({ "random-folder/img": "subfolder/img" });
};

使用 Glob 模式匹配并指定输出目录

注意,此方式比采用非 Glob 模式匹配的方式慢,因为 Eleventy 需要搜索整个目录结构并复制文件。

eleventy.config.js
export default function (eleventyConfig) {
	// Output directory: _site

	// Find and copy any `jpg` files in any folder to _site/img
	// Does not keep the same directory structure.
	eleventyConfig.addPassthroughCopy({ "**/*.jpg": "img" });
};
module.exports = function (eleventyConfig) {
	// Output directory: _site

	// Find and copy any `jpg` files in any folder to _site/img
	// Does not keep the same directory structure.
	eleventyConfig.addPassthroughCopy({ "**/*.jpg": "img" });
};

补上输出目录 _site 之后的完整路径如下:

  • img/avatar.jpg would copy to _site/img/avatar.jpg
  • subdir/img/avatar.jpg would copy to _site/img/avatar.jpg

Emulate Passthrough Copy During --serve Added in v2.0.0

The Eleventy Dev Server includes a great build-performance feature that will emulate passthrough file copy.

Practically speaking, this means that (during --serve only!) files are referenced directly and will not be copied to your output folder. Changes to passthrough file copies will not trigger an Eleventy build but will live reload appropriately in the dev server.

You can enable this behavior in your project using this configuration API method:

eleventy.config.js
export default function (eleventyConfig) {
	// the default is "copy"
	eleventyConfig.setServerPassthroughCopyBehavior("passthrough");
};
module.exports = function (eleventyConfig) {
	// the default is "copy"
	eleventyConfig.setServerPassthroughCopyBehavior("passthrough");
};

This behavior will revert to "copy" in your project automatically if:

  1. If you are running Eleventy without --serve (a standard build or via --watch)
  2. You change from the default development server: Eleventy Dev Server (e.g. swap back to Browsersync)
For 2.0 canary users, note that this behavior spent a fair bit of time as the default and required opt-out from 2.0.0-canary.12 through 2.0.0-canary.30. It was changed to opt-in in 2.0.0-canary.31.

Passthrough by File Extension

Eleventy, by default, searches for any file in the input directory with a file extension listed in your templateFormats configuration. That means if you’ve listed njk in your templateFormats, we’ll look for any Nunjucks templates (files with the .njk file extension).

If a file format is not recognized by Eleventy as a template file extension, Eleventy will ignore the file. You can modify this behavior by adding supported template formats:

eleventy.config.js
export default function (eleventyConfig) {
	eleventyConfig.setTemplateFormats([
		"md",
		"css", // `css` is not a registered template syntax file extension
	]);
};
module.exports = function (eleventyConfig) {
	eleventyConfig.setTemplateFormats([
		"md",
		"css", // `css` is not a registered template syntax file extension
	]);
};

In the above code sample css is not currently a recognized Eleventy template, but Eleventy will search for any *.css files inside of the input directory and copy them to output (maintaining the same directory structure).

You might use this for images by adding "jpg", "png", or even "webp".

Note that this method is typically slower than the addPassthroughCopy configuration API method above, especially if your project is large and has lots of files.

Advanced Options Added in v2.0.0

Additionally, you can pass additional configuration options to the recursive-copy package. This unlocks the use passthrough file copy with symlinks, transforming or renaming copied files. Here are just a few examples:

eleventy.config.js
export default function (eleventyConfig) {
	eleventyConfig.addPassthroughCopy("img", {
		expand: true, // expand symbolic links
	});

	eleventyConfig.addPassthroughCopy({ img: "subfolder/img" }, {
		debug: true, // log debug information
	});
};
module.exports = function (eleventyConfig) {
	eleventyConfig.addPassthroughCopy("img", {
		expand: true, // expand symbolic links
	});

	eleventyConfig.addPassthroughCopy({ img: "subfolder/img" }, {
		debug: true, // log debug information
	});
};

Review the full list of options on the recursive-copy GitHub repository.


Other pages in Eleventy Projects