Files
FreeCADWasmDev/web/tools/fast-public-assets.ts
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

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`);
},
};
}