async function build(options) {
	options.out = options.out || 'dist';

	// @todo remove this hack once registry.js is instantiable
	setCwd(options.cwd);

	options = await normalizeOptions(options, 'build');

	// Clears out the output folder without deleting it -- useful
	// when mounted with Docker and the like
	await Promise.all((await fs.readdir(options.out)).map(item => rm(path.join(options.out, item), { recursive: true })));

	const bundleOutput = await bundleProd(options);

	const stats = bundleStats(bundleOutput, path.relative(options.cwd, options.out));
	process.stdout.write(kl.bold(`\nWrote ${stats.totalText} to disk:`) + stats.assetsText + '\n');

	if (!options.prerender) return;

	try {
		const { routes } = await prerender(options);
		const routeMap = routes.reduce((s, r) => {
			s += `\n  ${r.url}`;
			if (r._discoveredBy) s += kl.dim(` [from ${r._discoveredBy.url}]`);
			return s;
		}, '');

		process.stdout.write(
			kl.bold(`Prerendered ${routes.length} page${routes.length == 1 ? '' : 's'}:`) + routeMap + '\n'
		);
	} catch (err) {
		err.hint = 'The following error was thrown during prerendering:';
		throw err;
	}
}
@param {Parameters<bundleProd>[0] & { prerender?: boolean }} options