NodeJS学习使用过的童鞋们都知道,可以利用V8来解析运行javascript程序, 我们在写一个server(一般都是使用NodeJS建立http/https server), 如果是云平台,都会直接把js代码上传上去,因为云平台的账户都是自己的,那么客户端的用户是看不见server的code的,那么我们一般的应用server呢?比如你需要把程序安装在客户那边的时候,你的javascript code需要保密吧?同时为了运行javascript代码,我们需要安装node, 而node程序有很多版本,怎么跟其它软件统一版本呢?最好是既不能暴露源代码,有能不要安装其他的程序比如node, 那么pkg就是其中的一个选择,它将所有的js code编译成二进制, 并且直接把node的code打包进去,形成一个exe, 直接双击运行,不需要安装node,那么客户机器上安装的Node版本就跟咱们的server无关了。
在使用pkg进行编译的时候,使用起来简单,但是编译的时候有一些注意的地方:
1. 如果有native addon的话,pkg不支持将addon (.node文件)打包进exe, 所以如果自己写的.node文件或者引用的module里面有.node文件,需要打包完之后将.node文件放到跟exe一个目录里面。
2. 检查资源的时候,pkg在打包的时候,要对目录进行判断,比如require(路径)或者path.join(路径)。但是对于一些特殊引用例如:
require('./build/' + cmd + '.js')path.join(__dirname, 'views/' + viewName)
在例子中,cmd和viewName都是参数,也就是在pkg打包的时候,并不知道真是的文件名字,pkg就没法把文件或者资源打包,这种情况下就可以在package.json的配置里面增加assets的配置
"pkg": {"scripts": "build/**/*.js","assets": "views/**/*"}
其中assets的文件就会对应路径一起打包进去。如果是多个目录那就可以是数组,如下:
"assets": [ "assets/**/*", "images/**/*" ]
下面是对package.json里面的'pkg'的说明:
Scripts
scripts
is a glob or list of globs. Files specified asscripts
will be compiled usingv8::ScriptCompiler
and placed into executable without sources. They must conform to the JS standards of those Node.js versions you target (see Targets), i.e. be already transpiled.
指定的files将会编译到exe里面,但是这个js文件必须要符合目标版本的标准,比如你要编译成node的12版本,windows下的应用程序,那么你用的js语法必须被这个版本的node支持
Assets
assets
is a glob or list of globs. Files specified asassets
will be packaged into executable as raw content without modifications. Javascript files may also be specified asassets
. Their sources will not be stripped as it improves execution performance of the files and simplifies debugging.
assets里面指定的文件,将会原封不动的打包进去,即使是javascript file 作为assets
3. 如果我们的application 有配置文件,需要在安装的时候配置怎么办呢?那可以不打包配置文件,例如我们经常用的config模块,config模块如果不指定配置文件,需要在project目录下创建config目录,在文件夹下创建default.json文件,在里面做一些配置,在安装完application之后,可以修改这些配置,如果打包进exe,那就没法修改了,这种情况下,不要把该文件default.json放到配置的assets里面,只是将该文件以及对应的目录放到跟exe同一个目录下就行,比如:本例中将打包的demo.exe和config文件夹在同一个文件夹里面。
当然对于config模块是因为内部读配置文件的时候,用到了
Path.join( process.cwd(), 'config')
这就涉及到在打包前和打包后,目录的对比了,这就是snapshot文件系统,打包后的所有的文件都有个/snapshot(如果目标文件是windows的exe就是c:/snapshot)的前缀文件夹,比如打包的时候用
pkg /path/app.js
那么打包后,__filename就是/snapshot/path/app.js,__dirname就是/snapshot/path,下面是列的表格。
所以通过上面可以看出,如果你想将配置文件放到外面,那么在读取配置文件的时候,要使用path.join(process.cwd(), 配置文件相对路径),因为通过上面的表格可以看出来process.cwd()是exe所在的目录。
注意: 因为native addon 是跟编译的时候node版本是有关系的,那么我们在用pkg进行打包的时候,target要对应。
4. 如果你是用typescript编写的程序,那么在进行打包之前,需要用tsc进行compile到javascript,然后再打包。
下面是一个简单的例子:
a. 在package.json里面增加配置:
"bin": "dist/app.js","pkg": {"scripts": "dist/**/*.js","assets": ["package.json"]},
b. 安装pkg, npm install -g pkg
c. 在package.json的所在文件夹里运行 pkg . -t node12-win
这样就package.json所在的文件夹就会出现一个exe,名字是通过package.json里面的'name'来设置的。
pkg路径
如果觉得《使用pkg编译打包nodejs程序成执行文件》对你有帮助,请点赞、收藏,并留下你的观点哦!