mirror of
https://github.com/logseq/logseq.git
synced 2026-05-13 23:42:19 +00:00
173 lines
4.7 KiB
JavaScript
173 lines
4.7 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import { promises as fs } from "node:fs";
|
|
import { builtinModules } from "node:module";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { build } from "vite";
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
const repoRoot = path.resolve(__dirname, "..");
|
|
const distDir = path.join(repoRoot, "dist");
|
|
const shadowEntry = path.join(repoRoot, "static", "db-worker-node.js");
|
|
const bundleEntry = path.join(distDir, "db-worker-node.js");
|
|
const manifestPath = path.join(distDir, "db-worker-node-assets.json");
|
|
const legacyNccOutDir = path.join(distDir, ".db-worker-node-ncc");
|
|
const builtinModuleSet = new Set([
|
|
...builtinModules,
|
|
...builtinModules.map((moduleName) => `node:${moduleName}`),
|
|
]);
|
|
const externalModuleSet = new Set([
|
|
"keytar",
|
|
"ws",
|
|
]);
|
|
|
|
async function exists(targetPath) {
|
|
try {
|
|
await fs.access(targetPath);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function listFilesRecursive(baseDir, dir = baseDir) {
|
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
const files = [];
|
|
for (const entry of entries) {
|
|
const absolute = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
files.push(...(await listFilesRecursive(baseDir, absolute)));
|
|
} else if (entry.isFile()) {
|
|
files.push(path.relative(baseDir, absolute));
|
|
}
|
|
}
|
|
return files.sort();
|
|
}
|
|
|
|
async function removeIfExists(targetPath) {
|
|
if (await exists(targetPath)) {
|
|
await fs.rm(targetPath, { recursive: true, force: true });
|
|
}
|
|
}
|
|
|
|
async function cleanupPreviousBundle() {
|
|
// Remove the legacy ncc output directory if it still exists from older builds.
|
|
await removeIfExists(legacyNccOutDir);
|
|
await removeIfExists(bundleEntry);
|
|
|
|
if (await exists(manifestPath)) {
|
|
let manifest;
|
|
try {
|
|
manifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
|
} catch (error) {
|
|
throw new Error(`failed to read ${manifestPath}: ${error.message}`);
|
|
}
|
|
|
|
const assets = Array.isArray(manifest.assets) ? manifest.assets : [];
|
|
for (const relativePath of assets) {
|
|
if (typeof relativePath !== "string" || relativePath.length === 0) {
|
|
continue;
|
|
}
|
|
const assetPath = path.join(distDir, relativePath);
|
|
await removeIfExists(assetPath);
|
|
}
|
|
}
|
|
|
|
await removeIfExists(manifestPath);
|
|
}
|
|
|
|
async function main() {
|
|
if (!(await exists(shadowEntry))) {
|
|
throw new Error(`missing shadow entry: ${shadowEntry}`);
|
|
}
|
|
|
|
await cleanupPreviousBundle();
|
|
await fs.mkdir(distDir, { recursive: true });
|
|
const filesBefore = await listFilesRecursive(distDir);
|
|
|
|
await build({
|
|
configFile: false,
|
|
logLevel: "error",
|
|
build: {
|
|
codeSplitting: false,
|
|
minify: "terser",
|
|
target: "node22",
|
|
sourcemap: false,
|
|
write: true,
|
|
emptyOutDir: false,
|
|
outDir: distDir,
|
|
lib: {
|
|
entry: shadowEntry,
|
|
formats: ["cjs"],
|
|
fileName: () => "db-worker-node.js",
|
|
},
|
|
rollupOptions: {
|
|
external: (id) =>
|
|
id.endsWith(".node") ||
|
|
id.startsWith("node:") ||
|
|
builtinModuleSet.has(id) ||
|
|
externalModuleSet.has(id),
|
|
output: {
|
|
format: "cjs",
|
|
exports: "auto",
|
|
entryFileNames: "db-worker-node.js",
|
|
chunkFileNames: "db-worker-node.js",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!(await exists(bundleEntry))) {
|
|
throw new Error(`vite bundle missing output file: ${bundleEntry}`);
|
|
}
|
|
|
|
const bundleContents = await fs.readFile(bundleEntry, "utf8");
|
|
if (bundleContents.includes("node_modules/.pnpm/keytar")) {
|
|
throw new Error(
|
|
"vite bundle contains a pnpm keytar native path; keytar must stay external"
|
|
);
|
|
}
|
|
if (bundleContents.includes("ws does not work in the browser")) {
|
|
throw new Error(
|
|
"vite bundle contains the ws browser stub; ws must stay external"
|
|
);
|
|
}
|
|
|
|
let filesAfter = await listFilesRecursive(distDir);
|
|
if (filesAfter.includes("index.html") && !filesBefore.includes("index.html")) {
|
|
await removeIfExists(path.join(distDir, "index.html"));
|
|
filesAfter = await listFilesRecursive(distDir);
|
|
}
|
|
|
|
const extraJsFiles = filesAfter.filter(
|
|
(relativePath) =>
|
|
relativePath.endsWith(".js") &&
|
|
relativePath !== "db-worker-node.js" &&
|
|
!filesBefore.includes(relativePath)
|
|
);
|
|
if (extraJsFiles.length > 0) {
|
|
throw new Error(
|
|
`vite bundle produced unexpected JS outputs: ${extraJsFiles.join(", ")}`
|
|
);
|
|
}
|
|
|
|
await fs.writeFile(
|
|
manifestPath,
|
|
`${JSON.stringify(
|
|
{
|
|
assets: [],
|
|
},
|
|
null,
|
|
2
|
|
)}\n`,
|
|
"utf8"
|
|
);
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(`[db-worker-node-bundle] ${error.message}`);
|
|
process.exit(1);
|
|
});
|