2fa20da94d
- Main: license service, IPC, router; закрытие окон; yauzl закрытие zip (EMFILE), zipRead тест - Editor: стабильный projectState без мигания, логотип и меню, строки UI, LayoutShell overlay - Control: ластик для всех типов эффектов, затухание/нарастание музыки при смене сцены - Сборка: vite, build/dev scripts, obfuscate-main и build-env скрипты с тестами; package.json Made-with: Cursor
90 lines
2.5 KiB
JavaScript
90 lines
2.5 KiB
JavaScript
import { execFileSync } from 'node:child_process';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
import { build } from 'esbuild';
|
|
|
|
import { resolveIsProduction, resolveObfuscateMain } from './build-env.mjs';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
const root = path.resolve(__dirname, '..');
|
|
|
|
const isProd = resolveIsProduction();
|
|
const obfuscateMain = resolveObfuscateMain();
|
|
|
|
/** Старые .map от dev-сборок не должны попадать в pack. */
|
|
function removeStaleNodeBundleMaps() {
|
|
for (const p of [
|
|
path.join(root, 'dist/main/index.cjs.map'),
|
|
path.join(root, 'dist/preload/index.cjs.map'),
|
|
]) {
|
|
if (fs.existsSync(p)) fs.unlinkSync(p);
|
|
}
|
|
}
|
|
|
|
function runViteBuild() {
|
|
const cmd = isProd ? 'npx vite build' : 'npx vite build --mode development';
|
|
execFileSync(cmd, {
|
|
cwd: root,
|
|
stdio: 'inherit',
|
|
shell: true,
|
|
env: {
|
|
...process.env,
|
|
NODE_ENV: isProd ? 'production' : 'development',
|
|
},
|
|
});
|
|
}
|
|
|
|
async function buildNodeTargets() {
|
|
if (isProd) removeStaleNodeBundleMaps();
|
|
|
|
const nodeEnvLiteral = JSON.stringify(isProd ? 'production' : 'development');
|
|
const common = {
|
|
platform: 'node',
|
|
target: 'node22',
|
|
format: 'cjs',
|
|
bundle: true,
|
|
minify: isProd,
|
|
sourcemap: !isProd,
|
|
external: ['electron'],
|
|
define: { 'process.env.NODE_ENV': nodeEnvLiteral },
|
|
drop: isProd ? ['console', 'debugger'] : [],
|
|
};
|
|
|
|
const mainOut = path.join(root, 'dist/main/index.cjs');
|
|
|
|
await build({
|
|
...common,
|
|
entryPoints: [path.join(root, 'app/main/index.ts')],
|
|
outfile: mainOut,
|
|
});
|
|
|
|
if (isProd && obfuscateMain) {
|
|
const { obfuscateMainBundleFile } = await import('./obfuscate-main.mjs');
|
|
obfuscateMainBundleFile(mainOut);
|
|
}
|
|
|
|
await build({
|
|
...common,
|
|
entryPoints: [path.join(root, 'app/preload/index.ts')],
|
|
outfile: path.join(root, 'dist/preload/index.cjs'),
|
|
});
|
|
}
|
|
|
|
await buildNodeTargets();
|
|
execFileSync('node', [path.join(root, 'scripts', 'gen-window-icon.mjs')], {
|
|
cwd: root,
|
|
stdio: 'inherit',
|
|
});
|
|
runViteBuild();
|
|
|
|
// Тот же PNG, что electron-builder кладёт в .exe/.app — в рантайме для окна/дока (паритет с Windows).
|
|
const packIcon = path.join(root, 'build', 'icon.png');
|
|
const distPackIcon = path.join(root, 'dist', 'renderer', 'app-pack-icon.png');
|
|
if (fs.existsSync(packIcon)) {
|
|
fs.copyFileSync(packIcon, distPackIcon);
|
|
console.log('copied pack icon to', distPackIcon);
|
|
}
|