Node.js 项目打包为 exe 可执行文件
如果你想要把你写的 Node 脚本发给别人使用,你可能需要指导对方下载安装 Node.js 运行环境,毕竟大多数电脑上都不会安装有 Node.js。把 Node 脚本打包为 exe 后,可以直接在没有安装 Node.js 的电脑或服务器上运行,不需要再安装 Node.js。
我这里的 Node 打包 exe 是不带 GUI 界面的命令行程序,如果需要使用界面操作只能启动一个 HTTP 服务,使用浏览器里的 HTML 和 JS 来操作。
如果你想要使用 JavaScript 开发带 GUI 界面的程序,可以使用 Electron。
Node 脚本需要有 Node.js 运行环境才能运行,把 Node 项目打包为 exe 就是把 Node.js 运行环境打包到项目中。因为程序中包含了 Node 运行环境,所以一个没有 node_modules
模块的 console.log
单文件,打包为 exe 后,文件体积也在 30M 以上。
安装
我这里使用的打包工具是 pkg,,它可以把 Node.js 项目打包为 Windows、Linux、Mac 的可执行程序。
pkg 打包的时候需要到 Node.js 的服务器(nodejs.org)下载对应版本的 Node.js,为了能顺利打包,你可能需要有一个稳定的国际互联网连接。
下面使用 npm 全局安装 pkg:
npm install pkg -g
安装完成后可以输入:
pkg -h
或输入:
pkg -v
如果能显示使用说明和版本信息就说明安装成功。
打包
创建一个 index.js
文件,随便写几行代码:
console.log('我的博客 https://www.misterma.com');
setTimeout(() => {
console.log('完成');
}, 5000);
如果你在资源管理器里直接运行打包的 exe 文件的话,代码执行完成后命令行会直接关闭,也就是说你只能看到命令行闪一下。如果要让程序不自动关闭可以使用定时器或 readline
接收输入。
我使用的是全局安装,打包前需要先进入项目目录,输入 pkg 文件名.js
,例如:
pkg index.js
打包完成后默认会在项目目录生成三个文件,其中 win.exe
结尾的就是 Windows 的程序,其它两个是 Linux 和 Mac 的。
如果你的程序中包含第三方的 Node 模块,使用 require
引入后 pkg 也能在 node_modules
查找打包,下面是一个包含 Express 的项目:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send(`<h1>Hello</h1>`);
});
app.listen('7777', () => {
console.log('浏览器访问 http://localhost:7777');
});
打包后运行程序,在浏览器中也能访问 HTTP 服务。
配置文件
pkg 支持很多自定义打包配置,package.json
可以作为 pkg 的配置文件,下面是一些配置说明:
入口文件和输出位置
你可以直接在 package.json
中设置 pkg 的入口文件和输出位置:
{
"name": "express-test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"pkg": {
"outputPath": "dist"
},
"bin": "index.js"
}
上面主要看 pkg
和 bin
,bin
设置的 index.js
就是 pkg 的入口文件。pkg
就是 pkg 相关的配置,outputPath
就是设置 pkg 打包完成后的存放位置。
使用了配置文件后,打包也需要使用:
pkg .
静态文件
pkg 默认只会打包 require
引入的模块,如果你的项目中还包含 HTML、CSS、图片之类的静态文件的话,pkg 是不会打包的。
下面配置 pkg 打包 public
目录里的文件:
{
"pkg": {
"assets": ["public/**/*"],
"outputPath": "dist"
},
"bin": "index.js"
}
assets
就是静态文件打包配置,数组里的 public/**/*
就是打包 public
目录的所有文件,静态文件可以配置多个目录。
pkg 会把所有的静态文件都打包到一个 exe 程序里,运行的时候才会释放文件,程序关闭后释放的文件也会被销毁。
目标平台配置
目标平台配置可以配置集成的 Node 版本、操作系统、架构,下面是一组简单的配置:
{
"pkg": {
"assets": ["public/**/*"],
"outputPath": "dist",
"targets": ["node14-win-x64", "node14-win-arm64"]
},
"bin": "index.js"
}
上面的 pkg
里的 targets
是目标平台和版本配置,targets
的配置项包含三个参数,参数之间用 -
连接,下面是用到的参数说明:
node14
:Node.js 的版本,支持 node8、10、12、14、16、latest
(最新版本)win
:操作系统平台,支持alpine
、linux
、win
、macos
、linuxstatic
、freebsd
x64
:架构,支持x64
、arm64
、armv6
、armv7
文件路径处理
pkg 打包的程序就像 Electron 一样,执行的时候 JS 脚本才会被释放。pkg 的 Windows 程序执行的时候会释放到 C:\snapshot\项目目录
,程序关闭后,释放的 JS 也会被销毁。
对于打包到 exe 程序里的静态文件来说,你可以使用 __dirname
当前脚本目录来查找文件,但是如果你要查找 exe 程序的所在位置就不能使用 __dirname
。
要获取当前的 exe 程序位置可以使用 process.cwd()
,要获取 exe 程序目录下的其它文件可以使用 path.join(process.cwd(), '文件名')
。
压缩
在打包的时候加入 --compress Brotli
或 --compress GZip
选项可以减小文件体积,使用方式如下:
pkg . --compress
或者:
pkg index.js --compress
使用压缩后,程序的启动时间可能会稍微增加。
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/936/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。