embersparks_obsidian-github.../esbuild.config.mjs
2026-06-02 17:47:16 +08:00

206 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import esbuild from "esbuild";
import process from "process";
import fs from "fs"; // Added for file system operations
import path from "path"; // Added for path manipulation
import { builtinModules } from "node:module";
function loadLocalEnvFile(envPath = ".env") {
if (!fs.existsSync(envPath)) return;
const envContent = fs.readFileSync(envPath, "utf8");
for (const line of envContent.split(/\r?\n/)) {
const trimmedLine = line.trim();
if (!trimmedLine || trimmedLine.startsWith("#")) continue;
const separatorIndex = trimmedLine.indexOf("=");
if (separatorIndex === -1) continue;
const key = trimmedLine.slice(0, separatorIndex).trim();
let value = trimmedLine.slice(separatorIndex + 1).trim();
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
value = value.slice(1, -1);
}
if (key && process.env[key] === undefined) {
process.env[key] = value;
}
}
}
loadLocalEnvFile();
// 设置正确的字符编码处理
process.stdout.setEncoding('utf8');
process.stderr.setEncoding('utf8');
// 修复Windows中文路径显示问题的函数
function fixChinesePathDisplay(pathStr) {
try {
// 直接使用Buffer进行编码转换
if (typeof pathStr === 'string') {
// 尝试多种编码修复方案
let fixedPath = pathStr;
// 方案1已知的乱码字符替换
const replacements = {
'鐨<>': '的',
'榛<>': '黑',
'鏇<>': '曜',
'鐭<>': '石',
'鐢<>': '用',
'鎴<>': '户'
};
for (const [wrong, correct] of Object.entries(replacements)) {
fixedPath = fixedPath.replace(new RegExp(wrong, 'g'), correct);
}
// 方案2如果还有乱码尝试编码转换
if (fixedPath.match(/[\u4e00-\u9fff]/g) && fixedPath.includes('鐨<>')) {
try {
// 尝试从GBK转UTF-8
const buffer = Buffer.from(pathStr, 'binary');
fixedPath = buffer.toString('utf8');
} catch (e) {
// 如果转换失败,保持原样
}
}
return fixedPath;
}
return pathStr;
} catch (error) {
console.warn('Path encoding fix failed:', error);
return pathStr;
}
}
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");
const nodeBuiltins = Array.from(new Set(builtinModules.flatMap(moduleName => {
return moduleName.startsWith("node:") ? [moduleName, moduleName.slice(5)] : [moduleName, `node:${moduleName}`];
})));
// esbuild plugin to handle copying files after build with backup
const copyPlugin = {
name: 'copy-to-obsidian',
setup: (build) => {
build.onEnd(result => {
if (result.errors.length > 0) {
console.error("Build failed with errors, skipping copy.");
return;
}
const obsidianPluginDir = process.env.OBSIDIAN_PLUGIN_DIR;
if (!obsidianPluginDir) {
console.warn("OBSIDIAN_PLUGIN_DIR environment variable not set. Plugin will not be automatically copied to Obsidian vault.");
return;
}
const pluginId = "github-stars-manager"; // Must match the 'id' in manifest.json
const targetDir = path.join(obsidianPluginDir, pluginId);
const backupDir = path.join(targetDir, "backup");
// Ensure target directory exists
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
// Ensure backup directory exists
if (!fs.existsSync(backupDir)) {
fs.mkdirSync(backupDir, { recursive: true });
}
// Function to backup and copy file
const backupAndCopy = (sourceFile, targetFile, fileName) => {
try {
// Create backup if target file exists
if (fs.existsSync(targetFile)) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const backupFile = path.join(backupDir, `${fileName}.${timestamp}.backup`);
fs.copyFileSync(targetFile, backupFile);
// 修复中文路径显示
const displayBackupPath = fixChinesePathDisplay(backupFile);
console.log(`Backed up ${fileName} to ${displayBackupPath}`);
}
// Copy new file
fs.copyFileSync(sourceFile, targetFile);
// 修复中文路径显示
const displayTargetDir = fixChinesePathDisplay(targetDir);
console.log(`Copied ${fileName} to ${displayTargetDir}`);
} catch (err) {
console.error(`Error copying ${fileName}:`, err);
}
};
// Copy main.js with backup
backupAndCopy("main.js", path.join(targetDir, "main.js"), "main.js");
// Copy styles.css with backup if it exists
if (fs.existsSync("styles.css")) {
backupAndCopy("styles.css", path.join(targetDir, "styles.css"), "styles.css");
}
// Copy themes.css with backup if it exists
if (fs.existsSync("themes.css")) {
backupAndCopy("themes.css", path.join(targetDir, "themes.css"), "themes.css");
}
// Copy manifest.json with backup
backupAndCopy("manifest.json", path.join(targetDir, "manifest.json"), "manifest.json");
// 修复中文路径显示
const displayTargetDir = fixChinesePathDisplay(targetDir);
const displayBackupDir = fixChinesePathDisplay(backupDir);
console.log(`\n✅ Plugin files deployed to: ${displayTargetDir}`);
console.log(`📦 Backups stored in: ${displayBackupDir}`);
});
},
};
const context = await esbuild.context({
banner: {
js: banner,
},
entryPoints: ["src/main.ts"], // Corrected entry point
bundle: true,
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",
...nodeBuiltins],
format: "cjs",
target: "es2018",
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
outfile: "main.js",
minify: prod,
plugins: [copyPlugin]
});
if (prod) {
await context.rebuild();
process.exit(0);
} else {
await context.watch();
}