简介
在NodeJS项目中,一般情况下构建成品是放在dist
文件夹下的一堆JS和TS文件,这样子有以下这些缺点:
- 不方便打包部署到服务端。
- 有时会因为一些依赖配置问题导致无法在服务器环境中顺利启动。
- 源码未加密,项目源代码有被窃取的风险。
而使用ncc
即可解决上述这些问题,因此本文记录一下如何将NodeJS项目利用ncc
打包成单文件。
安装@vercel/ncc
NCC有什么用?
NCC可以将 Node.js 模块及其所有依赖项编译成单个文件。
有了它,你将可以:
- 在NPM上发布最小依赖包
- 只将相关程序代码发送到无服务器环境
- 省去了调整依赖配置的时间
- 更快的启动时间和更少的IO开销
- 加密源代码,防止项目代码被窃取
NCC的目标:
- 零依赖
- 内置TypeScript
- 支持所有的NodeJS设计模式和NPM模块
首先根据你项目中所使用到的包管理工具,安装@vercel/ncc
依赖包。
npm i @vercel/ncc
# yarn
yarn add @vercel/ncc
# pnpm
pnpm add @vercel/ncc
项目构建
安装完依赖后,先执行构建操作:
这里以pnpm
为例
# 清理dist目录
pnpm rimraf dist
# 构建dist中的main.js到build目录下
pnpm ncc build dist/main.js -m -t -o dist/bundle/
构建成功后可以在dist/bundle/
目录中看到一个index.js
,使用node
命令即可直接运行它。
例如:node dist/bundle/index.js
这样就和单jar
包差不多了,哪里有node
环境哪里就能运行它,非常方便和可靠。
进阶配置
在package.json
中配置打包脚本
每次手动输入一组命令比较麻烦,我们可以将这组命令写入到package.json
中。
在scripts
中添加这一行:
"bundle": "rimraf dist && pnpm build && pnpm ncc build dist/main.js -m -t -o dist/bundle/",
然后我们运行pnpm bundle
命令即可一键构建了。
将项目进一步打包成全平台可执行文件
通过NCC将项目打包成单个JS文件确实不错,打包出来的JS文件将可以在任何装有NodeJS的环境中运行。
现在这玩意唯一的缺点就是需要依赖服务端的NodeJS环境了,能不能让这玩意不依赖服务端的Node环境,直接打包成全平台二进制可执行文件呢?
还真有,vercel
的PKG可以满足这个需求。
它的原理就是将JS文件和整个Node环境一起打包进去(electron直呼内行),就好比你想运行个环境无关的Jar包,那么你可以将整个JRE塞进去。
这么做的缺点就是打出来的包大了点,比如我有一个项目,通过NCC打包出来的index.js
单文件只占3MB,而使用PKG打包出来的linux
可执行文件达到了50MB,不过无伤大雅,服务器也不缺这50MB的磁盘空间,在服务端没有配置Node环境的时候还是很有意义的。
下面就简单记录一下如何利用PKG将NodeJS项目打包成全平台可执行文件。
安装PKG
# 利用NPM全局安装PKG
npm i -g pkg
# 也可以使用别的包管理工具仅在当前项目安装PKG
# 例如pnpm
pnpm add pkg
打包
看了眼文档中的操作示例,可以发现最简单的打包命令如下
pkg index.js
这个index.js
可以是上面使用NCC构建出来的单文件,如果你按我的文章操作,构建后应该在dist/bundle/
目录中。
因此,在终端中进入该目录后,只需运行上面那行命令,即可构建出三个平台的可执行二进制文件了,实测都能正常运行。
此时package.json
中的构建脚本可以改成下面这样:
"bundle": "rimraf dist && pnpm build && pnpm ncc build dist/main.js -m -t -o dist/bundle/&&cd dist/bundle/&&pkg index.js",
更多细节请查看项目文档:https://github.com/vercel/pkg
参考项目:
- https://github1s.com/mx-space/core/blob/HEAD/package.json
- https://github1s.com/tansincosy/CertificationCenter/
- https://github.com/haixiangyan/nest-todo
参考文章: