41 lines
2.0 KiB
TypeScript
41 lines
2.0 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { execFileSync } from "node:child_process";
|
|
import type { Plugin, ResolvedConfig } from "vite";
|
|
|
|
export function syncPublicAssets(publicDir: string, outputDir: string): number {
|
|
const source = fs.realpathSync(publicDir);
|
|
const output = path.resolve(outputDir);
|
|
if (source === output || source.startsWith(`${output}${path.sep}`) || output.startsWith(`${source}${path.sep}`))
|
|
throw new Error("Public and build output directories must be disjoint");
|
|
const started = performance.now();
|
|
fs.mkdirSync(output, { recursive: true });
|
|
if (fs.lstatSync(output).isSymbolicLink()) throw new Error("Build output must not be a symlink");
|
|
const actualOutput = fs.realpathSync(output);
|
|
if (actualOutput === source || source.startsWith(`${actualOutput}${path.sep}`) || actualOutput.startsWith(`${source}${path.sep}`))
|
|
throw new Error("Public and build output directories must be disjoint");
|
|
const publicNames = new Set(fs.readdirSync(source));
|
|
// Remove the previous bundle while keeping unchanged public assets for rsync.
|
|
for (const name of fs.readdirSync(output)) {
|
|
const destination = path.join(output, name);
|
|
if (!publicNames.has(name) || fs.lstatSync(destination).isSymbolicLink())
|
|
fs.rmSync(destination, { recursive: true, force: true });
|
|
}
|
|
execFileSync("rsync", ["-a", "--modify-window=-1", "--delete", `${source}${path.sep}`, `${output}${path.sep}`], { stdio: "pipe" });
|
|
return (performance.now() - started) / 1000;
|
|
}
|
|
|
|
export function fastPublicAssets(): Plugin {
|
|
let config: ResolvedConfig;
|
|
return {
|
|
name: "freecad-fast-public-assets",
|
|
apply: "build",
|
|
config() { return { build: { copyPublicDir: false, emptyOutDir: false } }; },
|
|
configResolved(value) { config = value; },
|
|
buildStart() {
|
|
const seconds = syncPublicAssets(config.publicDir, path.resolve(config.root, config.build.outDir));
|
|
config.logger.info(`Public assets synchronized incrementally in ${seconds.toFixed(3)}s`);
|
|
},
|
|
};
|
|
}
|