diff --git a/src/generators/web/generate.mjs b/src/generators/web/generate.mjs index 7ec803ef..e5b19fb8 100644 --- a/src/generators/web/generate.mjs +++ b/src/generators/web/generate.mjs @@ -3,6 +3,7 @@ import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; +import { copyStaticAssets } from './utils/copying.mjs'; import { processJSXEntries } from './utils/processing.mjs'; import getConfig from '../../utils/configuration/index.mjs'; import { writeFile } from '../../utils/file.mjs'; @@ -39,6 +40,8 @@ export async function generate(input) { } await writeFile(join(config.output, 'styles.css'), css, 'utf-8'); + + await copyStaticAssets(config); } return results.map(({ html }) => ({ html: html.toString(), css })); diff --git a/src/generators/web/utils/copying.mjs b/src/generators/web/utils/copying.mjs new file mode 100644 index 00000000..e90cb7c9 --- /dev/null +++ b/src/generators/web/utils/copying.mjs @@ -0,0 +1,46 @@ +import { constants } from 'node:fs'; +import { stat, cp, mkdir, copyFile } from 'node:fs/promises'; +import { join, basename, dirname } from 'node:path'; + +import logger from '../../../logger/index.mjs'; + +/** + * Copies static directories/files defined in `pathsToCopy` to the output directory. + * @param {import('../types').Configuration} config + */ +export async function copyStaticAssets(config) { + if (Array.isArray(config.pathsToCopy)) { + for (const item of config.pathsToCopy) { + if (!item) { + continue; + } + + const copyTasks = + typeof item === 'string' + ? [{ src: item, dest: join(config.output, basename(item)) }] + : Object.entries(item).map(([src, dest]) => ({ + src, + dest: join(config.output, dest.replace(/^[/\\]+/, '')), + })); + + for (const { src, dest } of copyTasks) { + try { + const fileStats = await stat(src); + + if (fileStats.isDirectory()) { + await cp(src, dest, { recursive: true, force: true }); + } else { + await mkdir(dirname(dest), { recursive: true }); + await copyFile(src, dest, constants.COPYFILE_FICLONE); + } + } catch (err) { + if (err.code !== 'ENOENT') { + logger.error( + `[web-generator] Failed to copy asset from ${src} to ${dest}: ${err.message}` + ); + } + } + } + } + } +} diff --git a/src/utils/configuration/index.mjs b/src/utils/configuration/index.mjs index 8323fe8d..b20a634a 100644 --- a/src/utils/configuration/index.mjs +++ b/src/utils/configuration/index.mjs @@ -32,6 +32,7 @@ export const getDefaultConfig = lazy(() => repository: 'nodejs/node', ref: 'HEAD', }), + pathsToCopy: ['assets', 'public', 'static'], }, // The number of wasm memory instances is severely limited on