文章目录
1. 前言
该功能目前还是实验性的
NodeJS 程序运行时需要 node 环境, 某些情况下该操作非常多余,比如开发一个工具脚本给非开发人员用,你还要他装个 NodeJS 吗,显然有点麻烦。 在此之前可以使用 pkg 构建二进制程序,或者带着node的一键包… 今天逛 B乎偶然看到对 NodeV20 的一些新特性描述回答链接,看到个打包可执行程序!简单记录一下。
本文以 Windows 环境为例,其实主要区别就是命令部分有些差异吧,其它步骤都是类似的
文章代码已上传至 single-executable-applications-demo,main 分支是单文件的,multi-build 分支是多文件的
目前我感知到的一个缺点上面截图已经说明了,就是起步 60M!!一个 hello world 也要 60M !!在网络传输方面确实挺吃亏…
不过他这个 nodejs 20 本身25M是不对的啊,压缩包 20M 左右是对的,解压完 node 就是 60 多M(我下的 20.2.0,跟 20.0.0 应该差不多)
2. 环境要求
- NodeJS >= 20
3. 程序编写
这里就直接引用官方的案例了
hello.js :
console.log(`Hello, ${process.argv[2]}!`);
4. 可执行程序构建
关键步骤就四步 创建配置文件 -> 生成二进制 -> 复制一份 node -> 注入二进制
4.1. 创建配置文件
sea-config.json :
{
"main": "hello.js",
"output": "sea-prep.blob"
}
4.2. 生成二进制文件
node --experimental-sea-config sea-config.json
出现这种即为成功
4.3. 创建 Node 的副本
不用命令手动拷贝一份也行哈
PowerShell:
cp (Get-Command node).Source hello.exe
CMD:
for /F "tokens=*" %n IN ('where.exe node') DO @(copy "%n" hello.exe)
4.4. 删除二进制文件签名
只需在 macOS 和 Windows 执行该操作,其中 Windows 也是非强制的
如果不删除签名,后续注入的时候就会有警告
signtool remove /s hello.exe
4.5. 将二进制文件注入到复制的node中
npx postject hello.exe NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
出现这种就是成功了
没有删除签名的话此时就会多个警告(好像也仅此而已了…
需要注意的是,同一个 node 不能多次注入,如果需要重新注入的话可以加上 --overwrite 参数
4.6 程序签名
仅 macOS 和 Windows 需要,其中 Windows 也是非强制的
signtool sign /fd SHA256 hello.exe
4.7 运行
5. 多文件构建
该特性全名为 Single executable applications,英文水平很差,直觉翻译就是 单个可执行程序?起初还有点疑惑,一般就是一个啊怎么还声明一下,难不成意思是只能包含一个JS文件?试了下带外部代码引用的,果然,运行直接找不到XXX… …
处理这个问题只需使用 esbuild、rollup 等打包工具,将文件打包为一个,然后再进行构建即可。
如果是 esbuild 的话记得加 bundle 标识,将依赖文件也打包进去。有兴趣可以看下使用 esbuild 的示例 single-executable-applications-demo/tree/multi-build
6. Linux 和 macOS 补充
没有 🍎设备,这里直接CV下官方文档的
6.1 创建Node的副本
Linux 和 macOS一致
cp $(command -v node) hello
6.2 删除签名
macOS
codesign --remove-signature hello
6.3 注入二进制
Linux
npx postject hello NODE_SEA_BLOB sea-prep.blob \
--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
macOS
npx postject hello NODE_SEA_BLOB sea-prep.blob \
--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 \
--macho-segment-name NODE_SEA
6.4 签名
macOS
$ codesign --sign - hello
7. FAQ
Q:没有 signtool
- 我的文件夹 C:\Program Files (x86)\Windows Kits\10\App Certification Kit 下面有 signtool,直接配个 path 环境变量就好了
- 参考该链接 how-to-install-signtool-exe-for-windows-10
Q: 签名出现:SignTool Error: No certificates were found that met all the given criteria.
这我也不知道什么情况啊,反正结果是不影响使用的,后续知道了再补充,有知道的大佬可以告知一下!!!