electron-vite 是一个新型 Electron 开发构建工具,旨在为 Electron 提供更快、更精简的开发体验。
源代码保护
背景
无法保护 Electron 源代码,是很多开发者提及最多的问题之一。我们都知道 Electron 使用 javascript 来构建桌面应用程序,这使得黑客很容易对我们的应用程序进行进行解包、修改逻辑破解商业化限制、重新打包,再重新分发破解版。
解决方案
要想真正解决问题,除了把所有商业化逻辑做到服务端,我们还需要对代码进行加固,避免解包、篡改、二次打包、二次分发。
主流方案:
-
Uglify / Obfuscator:通过对 JS 代码进行丑化和混淆,尽可能降低其可读性。
-
Native 加密:通过 XOR 或 AES 对构建产物进行加密,封装到 Node Addon 中,并在运行时由 JS 解密。
-
ASAR 加密:将 Electron ASAR 文件进行加密,并修改 Electron 源代码,在读取 ASAR 文件之前对其解密后再运行。
-
V8 字节码: 通过 Node 标准库里的
vm
模块,可以从 script 对象中生成其缓存数据(参考)。该缓存数据可以理解为 v8 的字节码,该方案通过分发字节码的形式来达到源代码保护的目的。
方案比较:
目前,使用 v8 字节码的解决方案似乎是最好的解决方案。
如何实现
什么是 V8 字节码
我们可以理解,V8 字节码是 V8 引擎在解析和编译 JavaScript 后产物的序列化形式,它通常用于浏览器内的性能优化。所以如果我们通过 V8 字节码运行代码,不仅能够起到代码保护作用,还对性能有一定的提升。
具体实现
electron-vite 受 bytenode 启发,具体实现:
-
实现一个插件
bytecodePlugin
来解析构建产物,并确定是否编译为字节码。 -
启动 Electron 进程将构建产物编译成
.jsc
文件,并确保生成的字节码可以在 Electron 的 Node 环境中运行。 -
自动生成字节码 Loader(加载器),让 Electron 能正常加载字节码模块。
-
支持开发者自由决定编译哪些块。
此外,electron-vite 还解决了一些 bytenode
无法解决的问题:
- 修复了异步箭头函数可能导致 Electron 应用程序崩溃的问题。
如何使用
开启字节码插件保护源代码
启用 bytecodePlugin
插件:
`import { defineConfig, bytecodePlugin } from 'electron-vite'
export default defineConfig({
main: {
plugins: [bytecodePlugin()]
},
preload: {
plugins: [bytecodePlugin()]
},
renderer: {
// ...
}
})`
是不是非常简单呢?
自定义保护
例如,只要保护 src/main/foo.ts
:
├──src
│ ├──main
│ │ ├──index.ts
│ │ ├──foo.ts
│ │ └──...
└──...
可以像下面一样修改配置文件:
`import { defineConfig, bytecodePlugin } from 'electron-vite'
export default defineConfig({
main: {
plugins: [bytecodePlugin({ chunkAlias: 'foo' })],
build: {
rollupOptions: {
output: {
manualChunks(id): string | void {
if (id.includes('foo')) {
return 'foo'
}
}
}
}
}
},
preload: {
// ...
},
renderer: {
// ...
}
})`
常见疑问
对代码组织和编写的影响?
目前发现字节码方案对代码的唯一影响,是 Function.prototype.toString()
方法无法正常使用,原因是源代码并不跟随字节码分发,因此取不到函数的源代码。
对程序性能是否有影响?
对代码执行性能没有影响,略有提升。
对程序体积的影响?
对于只有几百 KB 的 Bundle 来说,字节码体积会有比较明显的膨胀,但是对于 2M+ 的 Bundle 来说,字节码体积没有太大的区别。
代码保护强度如何?
目前来说,还没有现成的工具能够对 v8 字节码进行反编译,因此该方案还是还是比较可靠且安全的。
更多功能
electron-vite 还有很多好用功能:
-
预配置:针对 Electron 预先配置,不用担心配置问题。
-
热替换 HMR:渲染器支持模块热替换(HMR)。
-
热重载:主进程和预加载脚本支持热重载。
-
IDE调试:非常容易在 IDE 中调试,例如 vscode 或 webstorm。
-
开箱即用:开箱即用支持 Typescript、Vue、React、Svelte 和 SolidJS 等