114 lines
3.0 KiB
JavaScript
114 lines
3.0 KiB
JavaScript
|
|
/**
|
|||
|
|
* 将 JavaScript 编译成字节码
|
|||
|
|
* 使用 bytenode 将 JS 编译成 .jsc 文件,增加破解难度
|
|||
|
|
*/
|
|||
|
|
const bytenode = require('bytenode')
|
|||
|
|
const fs = require('fs')
|
|||
|
|
const path = require('path')
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 编译单个文件为字节码
|
|||
|
|
*/
|
|||
|
|
function compileFile(inputPath, outputPath) {
|
|||
|
|
try {
|
|||
|
|
console.log(`编译字节码: ${inputPath} -> ${outputPath}`)
|
|||
|
|
|
|||
|
|
// 确保输出目录存在
|
|||
|
|
const outputDir = path.dirname(outputPath)
|
|||
|
|
if (!fs.existsSync(outputDir)) {
|
|||
|
|
fs.mkdirSync(outputDir, { recursive: true })
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 编译为字节码
|
|||
|
|
bytenode.compileFile(inputPath, outputPath)
|
|||
|
|
|
|||
|
|
console.log(`✅ 编译完成: ${outputPath}`)
|
|||
|
|
return true
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(`❌ 编译失败: ${inputPath}`, error.message)
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 递归编译目录中的所有 JS 文件
|
|||
|
|
*/
|
|||
|
|
function compileDirectory(inputDir, outputDir) {
|
|||
|
|
if (!fs.existsSync(inputDir)) {
|
|||
|
|
console.error(`❌ 输入目录不存在: ${inputDir}`)
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const files = fs.readdirSync(inputDir)
|
|||
|
|
let successCount = 0
|
|||
|
|
let failCount = 0
|
|||
|
|
|
|||
|
|
files.forEach(file => {
|
|||
|
|
const inputPath = path.join(inputDir, file)
|
|||
|
|
const stat = fs.statSync(inputPath)
|
|||
|
|
|
|||
|
|
if (stat.isDirectory()) {
|
|||
|
|
// 递归处理子目录
|
|||
|
|
const subOutputDir = path.join(outputDir, file)
|
|||
|
|
if (compileDirectory(inputPath, subOutputDir)) {
|
|||
|
|
successCount++
|
|||
|
|
} else {
|
|||
|
|
failCount++
|
|||
|
|
}
|
|||
|
|
} else if (file.endsWith('.js') && !file.endsWith('.min.js')) {
|
|||
|
|
// 编译 .js 文件为 .jsc
|
|||
|
|
const outputPath = path.join(outputDir, file.replace('.js', '.jsc'))
|
|||
|
|
if (compileFile(inputPath, outputPath)) {
|
|||
|
|
successCount++
|
|||
|
|
} else {
|
|||
|
|
failCount++
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 复制非 JS 文件
|
|||
|
|
const outputPath = path.join(outputDir, file)
|
|||
|
|
const outputPathDir = path.dirname(outputPath)
|
|||
|
|
if (!fs.existsSync(outputPathDir)) {
|
|||
|
|
fs.mkdirSync(outputPathDir, { recursive: true })
|
|||
|
|
}
|
|||
|
|
fs.copyFileSync(inputPath, outputPath)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
console.log(`\n编译统计: 成功 ${successCount} 个文件, 失败 ${failCount} 个文件`)
|
|||
|
|
return failCount === 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 主函数
|
|||
|
|
function main() {
|
|||
|
|
const args = process.argv.slice(2)
|
|||
|
|
|
|||
|
|
if (args.length < 2) {
|
|||
|
|
console.log('用法: node compile-to-bytecode.js <输入目录> <输出目录>')
|
|||
|
|
console.log('示例: node compile-to-bytecode.js dist dist-bytecode')
|
|||
|
|
process.exit(1)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const inputDir = path.resolve(args[0])
|
|||
|
|
const outputDir = path.resolve(args[1])
|
|||
|
|
|
|||
|
|
console.log('开始编译为字节码...')
|
|||
|
|
console.log(`输入目录: ${inputDir}`)
|
|||
|
|
console.log(`输出目录: ${outputDir}\n`)
|
|||
|
|
|
|||
|
|
if (compileDirectory(inputDir, outputDir)) {
|
|||
|
|
console.log('\n✅ 所有文件编译完成!')
|
|||
|
|
console.log('注意: 字节码文件需要 bytenode 运行时才能执行')
|
|||
|
|
process.exit(0)
|
|||
|
|
} else {
|
|||
|
|
console.log('\n❌ 编译过程中有错误')
|
|||
|
|
process.exit(1)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (require.main === module) {
|
|||
|
|
main()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { compileFile, compileDirectory }
|
|||
|
|
|