andy-stack_vaultkeeper-ai/esbuild.config.mjs
Andrew Beal df5d62d981 refactor: improve message height calculation and update dependencies
- Calculate height for consecutive assistant messages instead of just last message
- Track message role in ChatArea for proper height calculation
- Update MultiAgentIntegration test to use ChatMode enum
- Update officeparser browser bundle path and shim for v6
2026-04-19 23:53:14 +01:00

200 lines
No EOL
6.4 KiB
JavaScript

import esbuild from "esbuild";
import process from "process";
import builtins from "builtin-modules";
import { copyFileSync, mkdirSync, existsSync, readdirSync, statSync, readFileSync, writeFileSync, unlinkSync, watch as fsWatch } from "fs";
import { join } from "path";
import esbuildSvelte from "esbuild-svelte";
import { sveltePreprocess } from "svelte-preprocess";
const banner =
`/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
`;
const prod = (process.argv[2] === "production");
// Clean up build artifacts that aren"t needed (main.css, main.js, font files)
const CLEANUP_BUILD_ARTIFACTS = true; // Set to false if you need to debug these files
// Function to copy directory recursively
function copyDir(src, dest) {
if (!existsSync(dest)) {
mkdirSync(dest, { recursive: true });
}
const files = readdirSync(src);
for (const file of files) {
const srcPath = join(src, file);
const destPath = join(dest, file);
if (statSync(srcPath).isDirectory()) {
copyDir(srcPath, destPath);
} else {
copyFileSync(srcPath, destPath);
console.log(`📁 Copied: ${srcPath}${destPath}`);
}
}
}
// Plugin to merge CSS files into styles.css and cleanup build artifacts
const cssMergerPlugin = {
name: "css-merger",
setup(build) {
build.onEnd(() => {
// esbuild outputs CSS as main.css (based on outfile: main.js)
const generatedCss = "main.css";
const customCssDir = "Styles";
const outputCss = "styles.css";
let mergedCss = "";
// Read generated CSS from dependencies if it exists
if (existsSync(generatedCss)) {
mergedCss += readFileSync(generatedCss, "utf-8");
mergedCss += "\n\n/* Custom Styles */\n\n";
}
// Append custom CSS files from styles directory
if (existsSync(customCssDir)) {
const cssFiles = readdirSync(customCssDir)
.filter(file => file.endsWith(".css"))
.sort();
for (const cssFile of cssFiles) {
const cssPath = join(customCssDir, cssFile);
mergedCss += readFileSync(cssPath, "utf-8");
mergedCss += "\n\n";
console.log(`📦 Merged: ${cssPath}`);
}
}
// Write merged CSS to styles.css
writeFileSync(outputCss, mergedCss);
console.log(`✅ Generated: ${outputCss}`);
// Clean up build artifacts if enabled
if (CLEANUP_BUILD_ARTIFACTS) {
// Remove main.css (intermediate CSS file)
if (existsSync(generatedCss)) {
unlinkSync(generatedCss);
console.log(`🗑️ Removed: ${generatedCss}`);
}
// Remove KaTeX font files
let anyRemoved = false;
const fontExtensions = [".woff", ".woff2", ".ttf"];
const files = readdirSync(".");
for (const file of files) {
const ext = file.substring(file.lastIndexOf("."));
if (fontExtensions.includes(ext)) {
unlinkSync(file);
anyRemoved = true;
}
}
if (anyRemoved) {
console.log("🗑️ Removed KaTeX Font Files");
}
}
});
}
};
// officeparser's browser bundle is an IIFE (var officeParser = (()=> { ... })()) that doesn't
// set module.exports, so esbuild can't resolve its exports. This plugin intercepts the resolve
// and appends a CJS export line so imports work correctly.
//
// The browser bundle contains dynamic require() patterns (from its own esbuild bundling) that
// our esbuild would otherwise resolve against the `external` list, emitting require("fs") etc.
// in the final output. On Obsidian mobile there is no "fs" module, so we must neutralise those
// internal requires by replacing the dynamic-require shim with a stub that always throws, and
// stripping eval("require")("stream") calls. This keeps the bundle self-contained.
const officeParserPlugin = {
name: "officeparser-cjs-shim",
setup(build) {
build.onResolve({ filter: /^officeparser$/ }, () => ({
path: join(process.cwd(), 'node_modules', 'officeparser', 'dist', 'officeparser.browser.iife.js'),
namespace: 'officeparser-shim',
}));
build.onLoad({ filter: /.*/, namespace: 'officeparser-shim' }, async (args) => {
let contents = readFileSync(args.path, 'utf-8');
// Replace the dynamic require shim so esbuild doesn't see real require() calls.
// The variable name changed from Au (v5) to Vm (v6).
contents = contents.replace(
/var Vm=\(r=>typeof require<"u"\?require:typeof Proxy<"u"\?new Proxy\(r,\{get:\(t,e\)=>\(typeof require<"u"\?require:t\)\[e\]\}\):r\)\(function\(r\)\{if\(typeof require<"u"\)return require\.apply\(this,arguments\);throw Error\('Dynamic require of "'\+r\+'" is not supported'\)\}\)/,
'var Vm=(function(r){throw Error(\'Dynamic require of "\'+r+\'" is not supported\')})'
);
return {
contents: contents + '\nmodule.exports = officeParser;\n',
loader: 'js',
};
});
},
};
const buildOptions = {
plugins: [
officeParserPlugin,
esbuildSvelte({
compilerOptions: { css: "injected" },
preprocess: sveltePreprocess(),
}),
cssMergerPlugin,
],
banner: {
js: banner,
},
entryPoints: ["main.ts"],
bundle: true,
define: {
"process.env.NODE_ENV": JSON.stringify(prod ? "production" : "development"),
},
external: [
"obsidian",
"electron",
"@codemirror/autocomplete",
"@codemirror/collab",
"@codemirror/commands",
"@codemirror/language",
"@codemirror/lint",
"@codemirror/search",
"@codemirror/state",
"@codemirror/view",
"@lezer/common",
"@lezer/highlight",
"@lezer/lr",
...builtins],
format: "cjs",
target: "es2018",
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
outfile: "main.js",
minify: prod,
loader: {
".css": "css",
".ttf": "file",
".woff": "file",
".woff2": "file",
},
};
if (prod) {
await esbuild.build(buildOptions);
console.log("✅ Production build complete!");
} else {
const ctx = await esbuild.context(buildOptions);
await ctx.watch();
// Watch Styles directory for CSS changes
if (existsSync("Styles")) {
fsWatch("Styles", { recursive: true }, (_eventType, filename) => {
if (filename && filename.endsWith(".css")) {
console.log(`🔄 CSS file changed: ${filename} - Rebuilding...`);
ctx.rebuild();
}
});
}
}