build.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. const fs = require('fs');
  2. const path = require('path');
  3. const { exec } = require('child_process');
  4. const { minify } = require('terser');
  5. // 源目录和目标目录
  6. const sourceDir = path.join(__dirname, 'dist', 'ts');
  7. const jsSourceDir = path.join(__dirname, 'src', 'js');
  8. const targetDir = path.join(__dirname, 'dist', 'compressed');
  9. const tsSourceDir = path.join(__dirname, 'src', 'ts');
  10. // 确保目标目录存在
  11. if (!fs.existsSync(targetDir)) {
  12. fs.mkdirSync(targetDir, { recursive: true });
  13. }
  14. // 递归获取所有JS文件
  15. function getAllJsFiles(dir, fileList = []) {
  16. console.log(`正在扫描目录: ${dir}`);
  17. if (!fs.existsSync(dir)) {
  18. console.log(`目录不存在: ${dir}`);
  19. return fileList;
  20. }
  21. const files = fs.readdirSync(dir);
  22. console.log(`发现文件: ${files.length}个`);
  23. files.forEach(file => {
  24. const filePath = path.join(dir, file);
  25. const stat = fs.statSync(filePath);
  26. if (stat.isDirectory()) {
  27. getAllJsFiles(filePath, fileList);
  28. } else if (file.endsWith('.js') && !file.endsWith('.compressed.js')) {
  29. console.log(`添加文件: ${filePath}`);
  30. fileList.push(filePath);
  31. }
  32. });
  33. return fileList;
  34. }
  35. // 获取所有需要处理的JS文件
  36. function getJsFilesToProcess() {
  37. console.log('开始获取需要处理的文件...');
  38. console.log(`jsSourceDir: ${jsSourceDir}`);
  39. if (shouldCompileTs) {
  40. console.log('处理所有文件模式');
  41. // 获取编译后的TypeScript文件
  42. const tsCompiledFiles = getAllJsFiles(sourceDir);
  43. console.log(`找到 ${tsCompiledFiles.length} 个TS编译文件`);
  44. // 获取js目录下的所有JS文件
  45. const pureJsFiles = getAllJsFiles(jsSourceDir);
  46. console.log(`找到 ${pureJsFiles.length} 个纯JS文件`);
  47. return [...tsCompiledFiles, ...pureJsFiles];
  48. } else {
  49. console.log('仅处理JS文件模式');
  50. // 只处理js目录下的文件
  51. const jsFiles = getAllJsFiles(jsSourceDir);
  52. console.log(`找到 ${jsFiles.length} 个JS文件`);
  53. return jsFiles;
  54. }
  55. }
  56. // 处理每个文件
  57. async function processFiles() {
  58. console.log('开始处理文件...');
  59. const jsFiles = getJsFilesToProcess();
  60. console.log(`总共找到 ${jsFiles.length} 个文件需要处理`);
  61. for (const file of jsFiles) {
  62. // 确定文件来源(ts编译或js目录)
  63. const isFromTs = file.includes(path.sep + 'dist' + path.sep + 'ts' + path.sep);
  64. const baseSourceDir = isFromTs ? sourceDir : jsSourceDir;
  65. const relativePath = path.relative(baseSourceDir, file);
  66. const targetPath = path.join(targetDir, relativePath);
  67. // 确保目标文件夹存在
  68. const targetDirPath = path.dirname(targetPath);
  69. if (!fs.existsSync(targetDirPath)) {
  70. fs.mkdirSync(targetDirPath, { recursive: true });
  71. }
  72. console.log(`处理文件: ${relativePath}`);
  73. try {
  74. // 读取源文件
  75. const code = fs.readFileSync(file, 'utf8');
  76. // 混淆选项
  77. const options = {
  78. compress: {
  79. drop_console: true, // 删除console.*调用
  80. drop_debugger: true, // 删除debugger语句
  81. dead_code: true, // 删除无法访问的代码
  82. unused: true, // 删除未使用的变量和函数
  83. join_vars: true // 合并连续变量声明
  84. },
  85. output: {
  86. comments: false, // 删除所有注释
  87. beautify: false, // 不美化输出
  88. indent_level: 0, // 不缩进
  89. ascii_only: true // 仅使用ASCII字符
  90. }
  91. };
  92. // 执行混淆
  93. const result = await minify(code, options);
  94. // 写入目标文件
  95. fs.writeFileSync(targetPath, result.code, 'utf8');
  96. console.log(`成功处理: ${relativePath} -> ${path.basename(targetPath)}`);
  97. } catch (error) {
  98. console.error(`处理 ${relativePath} 时出错:`, error);
  99. }
  100. }
  101. console.log('所有文件处理完成!');
  102. }
  103. // 根据命令行参数决定执行流程
  104. const args = process.argv.slice(2);
  105. const shouldCompileTs = !args.includes('--js-only');
  106. if (shouldCompileTs) {
  107. // 执行 TypeScript 编译和混淆
  108. console.log('开始 TypeScript 编译...');
  109. exec('npx tsc --project tsconfig.json --skipLibCheck', (error, stdout, stderr) => {
  110. if (error) {
  111. console.error(`编译错误: ${error.message}`);
  112. console.error(`错误详情: ${stdout}`);
  113. return;
  114. }
  115. if (stderr) {
  116. console.error(`编译警告: ${stderr}`);
  117. }
  118. console.log('TypeScript 编译完成!');
  119. processFiles();
  120. });
  121. } else {
  122. // 只执行 JavaScript 混淆
  123. console.log('跳过 TypeScript 编译,只处理 JavaScript 文件...');
  124. processFiles();
  125. }