// 设置输出编码为 UTF-8(修复 Windows 中文乱码问题) if (process.platform === 'win32') { process.stdout.setDefaultEncoding('utf8'); process.stderr.setDefaultEncoding('utf8'); // 设置环境变量确保中文正确显示 if (!process.env.CHCP) { process.env.CHCP = '65001'; } } // 确保在 Electron 环境中运行 if (!process.versions.electron) { console.error('❌ 错误:此脚本必须在 Electron 环境中运行!'); console.error('请使用以下方式运行:'); console.error(' Windows: encrypt-electron-win.bat'); console.error(' Linux/Mac: ./encrypt-electron.sh'); console.error(' 或: npm run encrypt:win / npm run encrypt:linux'); process.exit(1); } const bytenode = require('bytenode'); const fs = require('fs'); const path = require('path'); // 获取项目根目录(脚本在 scripts/encrypt 目录下,需要向上两级) const projectRoot = path.resolve(__dirname, '../..'); // 读取模块映射配置(从 lib 目录读取) const moduleMapPath = path.join(projectRoot, 'lib', 'module-map.json'); let moduleMap = {}; if (fs.existsSync(moduleMapPath)) { try { moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8')); console.log('✅ 已加载模块映射配置\n'); } catch (error) { console.warn(`⚠️ 读取模块映射配置失败: ${error.message},使用默认文件名\n`); } } // 文件映射函数:根据配置返回加密后的文件名(跨平台兼容) function getEncryptedFileName(originalPath) { // 使用 path 模块处理路径,确保跨平台兼容 const normalizedPath = originalPath.replace(/\\/g, '/'); // 统一使用正斜杠 const parts = normalizedPath.split('/'); const fileName = parts[parts.length - 1].replace('.js', ''); const dirName = parts[parts.length - 2]; // 检查是否有映射配置 if (moduleMap.mappings) { if (dirName === 'design1' && moduleMap.mappings.design1 && moduleMap.mappings.design1[fileName]) { return moduleMap.mappings.design1[fileName] + '.jsc'; } if (dirName === 'design2' && moduleMap.mappings.design2 && moduleMap.mappings.design2[fileName]) { return moduleMap.mappings.design2[fileName] + '.jsc'; } if (dirName === 'lib' && moduleMap.mappings.main && moduleMap.mappings.main[fileName]) { return moduleMap.mappings.main[fileName] + '.jsc'; } } // 默认:原文件名 + 'c' return fileName + '.jsc'; } const filesToEncrypt = [ 'lib/index.js', 'lib/design1.js', 'lib/design2.js', 'lib/design1/core.js', 'lib/design1/output.js', 'lib/design1/ui.js', 'lib/design2/core.js', 'lib/design2/output.js', 'lib/design2/ui.js' ]; // 先删除所有旧的 .jsc 文件(包括映射后的文件名) console.log('正在删除旧的 .jsc 文件...'); let deletedCount = 0; filesToEncrypt.forEach(filePath => { // 删除默认名称的 .jsc 文件(跨平台兼容) const fullPath = path.join(projectRoot, filePath); const defaultJscPath = fullPath + 'c'; if (fs.existsSync(defaultJscPath)) { try { fs.unlinkSync(defaultJscPath); deletedCount++; } catch (error) { console.error(`⚠️ 删除失败: ${defaultJscPath} - ${error.message}`); } } // 删除映射后的 .jsc 文件(跨平台兼容) const dir = path.dirname(fullPath); const encryptedFileName = getEncryptedFileName(filePath); const mappedJscPath = path.join(dir, encryptedFileName); // 使用 path.resolve 进行规范化比较,确保跨平台兼容 const normalizedDefault = path.resolve(defaultJscPath); const normalizedMapped = path.resolve(mappedJscPath); if (fs.existsSync(mappedJscPath) && normalizedMapped !== normalizedDefault) { try { fs.unlinkSync(mappedJscPath); deletedCount++; } catch (error) { console.error(`⚠️ 删除失败: ${mappedJscPath} - ${error.message}`); } } }); console.log(`已删除 ${deletedCount} 个旧的 .jsc 文件\n`); // 开始编译 let successCount = 0, failCount = 0; filesToEncrypt.forEach(filePath => { try { const fullPath = path.join(projectRoot, filePath); if (!fs.existsSync(fullPath)) { console.error(`❌ 文件不存在: ${filePath}`); failCount++; return; } // 编译文件(bytenode 会生成默认的 .jsc 文件) bytenode.compileFile({ filename: fullPath }); // 检查默认的 .jsc 文件是否生成 const defaultJscPath = fullPath + 'c'; if (!fs.existsSync(defaultJscPath)) { console.error(`❌ 编译失败: ${filePath}`); failCount++; return; } // 如果配置了映射,重命名文件(跨平台兼容) const dir = path.dirname(fullPath); const encryptedFileName = getEncryptedFileName(filePath); const mappedJscPath = path.join(dir, encryptedFileName); // 使用 path.resolve 进行规范化比较,确保跨平台兼容 const normalizedDefault = path.resolve(defaultJscPath); const normalizedMapped = path.resolve(mappedJscPath); if (normalizedMapped !== normalizedDefault) { // 重命名文件 fs.renameSync(defaultJscPath, mappedJscPath); console.log(`✅ ${filePath} → ${encryptedFileName}`); } else { console.log(`✅ ${filePath} → ${path.basename(defaultJscPath)}`); } successCount++; } catch (error) { console.error(`❌ 编译失败: ${filePath} - ${error.message}`); failCount++; } }); console.log(`\n编译完成!成功: ${successCount}, 失败: ${failCount}`); process.exit(failCount > 0 ? 1 : 0);