46 lines
1.4 KiB
JavaScript
46 lines
1.4 KiB
JavaScript
import * as esbuild from 'esbuild';
|
|
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
|
|
export const outdir = 'dist/assets';
|
|
|
|
export function buildOptions({ dev = false } = {}) {
|
|
return {
|
|
entryPoints: [
|
|
{ in: 'client/js/main.js', out: 'app' },
|
|
{ in: 'client/css/main.css', out: 'app' },
|
|
],
|
|
outdir,
|
|
bundle: true,
|
|
format: 'esm',
|
|
minify: !dev,
|
|
sourcemap: dev ? 'linked' : false,
|
|
metafile: true,
|
|
entryNames: '[name]-[hash]',
|
|
assetNames: '[name]-[hash]',
|
|
loader: { '.woff2': 'file', '.woff': 'file' },
|
|
// Old enough that esbuild lowers CSS nesting for Safari 15/16
|
|
target: ['chrome109', 'firefox115', 'safari15.4'],
|
|
logLevel: 'info',
|
|
};
|
|
}
|
|
|
|
// Maps "app.js" -> "/assets/app-HASH.js" so templates don't need to know the hash.
|
|
export async function writeManifest(metafile) {
|
|
const manifest = {};
|
|
for (const [file, output] of Object.entries(metafile.outputs)) {
|
|
if (!output.entryPoint) continue;
|
|
const base = path.basename(file);
|
|
const key = base.replace(/-[A-Z0-9]{8}(\.\w+)$/, '$1');
|
|
manifest[key] = '/assets/' + base;
|
|
}
|
|
await writeFile('dist/manifest.json', JSON.stringify(manifest, null, 2));
|
|
}
|
|
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
await rm('dist', { recursive: true, force: true });
|
|
await mkdir(outdir, { recursive: true });
|
|
const result = await esbuild.build(buildOptions());
|
|
await writeManifest(result.metafile);
|
|
}
|