excalidraw/scripts/buildPackage.mjs
2025-04-13 17:46:38 -06:00

164 lines
No EOL
4.6 KiB
JavaScript

import { build } from "esbuild";
import { sassPlugin } from "esbuild-sass-plugin";
import { fileURLToPath } from "url";
import path from "path";
import fs from "fs";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const parseEnvVariables = (filePath) => {
try {
const envContent = fs.readFileSync(filePath, "utf8");
const envVars = {};
envContent.split("\n").forEach((line) => {
const [key, value] = line.split("=");
if (key && value) envVars[key.trim()] = value.trim();
});
return envVars;
} catch {
return {};
}
};
const ENV_VARS = {
development: {
...parseEnvVariables(path.join(__dirname, "../.env.development")),
DEV: true,
},
production: {
...parseEnvVariables(path.join(__dirname, "../.env.production")),
PROD: true,
},
};
const getConfig = (outdir) => ({
outdir,
bundle: true,
splitting: true,
format: "esm",
target: "es2020",
plugins: [
sassPlugin({
loadPaths: [
path.resolve(__dirname, "../node_modules"),
path.resolve(__dirname, "../node_modules/open-color"),
path.resolve(__dirname, "../packages/excalidraw/css"),
path.resolve(__dirname, "../packages/excalidraw/src"),
path.resolve(__dirname, "../packages/excalidraw/components"),
],
precompile: (source, pathname) => {
// Skip precompile for open-color and css files to avoid loops
if (
pathname.includes("node_modules/open-color") ||
pathname.includes("css/variables.module.scss") ||
pathname.includes("css/styles.scss") ||
pathname.includes("css/theme.scss")
) {
return source;
}
if (pathname.endsWith(".scss")) {
return `
@use '../css/variables.module.scss' as vars;
@use '../css/styles.scss' as styles;
${source}
`;
}
return source;
},
type: "css",
sourceMap: false,
logger: {
warn: () => {},
error: (msg) => {
console.error("Sass compilation error:", msg);
throw new Error(msg);
},
},
}),
],
assetNames: "[dir]/[name]",
chunkNames: "[dir]/[name]-[hash]",
alias: {
"@excalidraw/common": path.resolve(__dirname, "../packages/common/src"),
"@excalidraw/element": path.resolve(__dirname, "../packages/element/src"),
"@excalidraw/excalidraw": path.resolve(__dirname, "../packages/excalidraw"),
"@excalidraw/math": path.resolve(__dirname, "../packages/math/src"),
"@excalidraw/utils": path.resolve(__dirname, "../packages/utils/src"),
},
loader: { ".woff2": "file" },
});
async function buildDev(config) {
console.log("Starting dev build to", config.outdir);
try {
await build({
...config,
sourcemap: true,
define: { "import.meta.env": JSON.stringify(ENV_VARS.development) },
});
console.log("Dev build completed successfully");
} catch (err) {
console.error("Dev build failed:", err);
throw err;
}
}
async function buildProd(config) {
console.log("Starting prod build to", config.outdir);
try {
await build({
...config,
minify: true,
define: { "import.meta.env": JSON.stringify(ENV_VARS.production) },
});
console.log("Prod build completed successfully");
} catch (err) {
console.error("Prod build failed:", err);
throw err;
}
}
const createESMRawBuild = async () => {
console.log("Creating ESM raw build...");
const prodDir = path.resolve(__dirname, "../packages/excalidraw/dist/prod");
const devDir = path.resolve(__dirname, "../packages/excalidraw/dist/dev");
if (!fs.existsSync(prodDir)) {
fs.mkdirSync(prodDir, { recursive: true });
}
if (!fs.existsSync(devDir)) {
fs.mkdirSync(devDir, { recursive: true });
}
const chunksConfig = {
entryPoints: [
path.resolve(__dirname, "../packages/excalidraw/index.tsx"),
...fs
.readdirSync(path.resolve(__dirname, "../packages/excalidraw"), { recursive: true })
.filter((file) => file.endsWith(".chunk.ts"))
.map((file) => path.resolve(__dirname, "../packages/excalidraw", file)),
],
entryNames: "[name]",
};
await buildDev({
...getConfig(path.resolve(__dirname, "../packages/excalidraw/dist/dev")),
...chunksConfig,
});
await buildProd({
...getConfig(path.resolve(__dirname, "../packages/excalidraw/dist/prod")),
...chunksConfig,
});
console.log("ESM raw build finished");
};
(async () => {
console.log("Build script started");
try {
await createESMRawBuild();
console.log("Build script completed successfully");
} catch (err) {
console.error("Build script failed:", err);
process.exit(1);
}
})();