使用使用pkg打包打包Node.js应用的方法步骤应用的方法步骤
Node.js应用不需要经过编译过程,可以直接把源代码拷贝到部署机上执行,确实比C++、Java这类编译型应用部署方便。然
而,Node.js应用执行需要有运行环境,意味着你需要先在部署机器上安装Node.js。虽说没有麻烦到哪里去,但毕竟多了一个
步骤,特别是对于离线环境下的部署机,麻烦程度还要上升一级。假设你用Node.js写一些小的桌面级工具软件,部署到客户
机上还要先安装Node.js,有点“大炮打蚊子”的感觉。更严重的是,如果部署机器上游多个Node.js应用,而且这些应用要依赖
于不同的Node.js版本,那就更难部署了。
理想的情况是将Node.js打包为一个单独的可执行文件,部署的时候直接拷贝过去就行了。除了部署方便外,因为不需要再拷
贝源代码了,还有利于保护知识产权。
将Node.js打包为可执行文件的工具有pkg、nexe、node-packer、enclose等,从打包速度、使用便捷程度、功能完整性来
说,pkg是最优秀的。这篇文章就来讲一讲半年来我使用pkg打包Node.js应用的一些经验。
pkg的打包原理简单来说,就是将js代码以及相关的资源文件打包到可执行文件中,然后劫持fs里面的一些函数,使它能够读
到可执行文件中的代码和资源文件。例如,原来的require(‘./a.js’)会被劫持到一个虚拟目录require(‘/snapshot/a.js’)。
安装安装
pkg既可以全局安装也可以局部安装,推荐采用局部安装:
npm install pkg --save-dev
用法用法
pkg使用比较简单,执行下pkg -h就可以基本了解用法,基本语法是:
pkg [options] <input>
<input>可以通过三种方式指定:可以通过三种方式指定:
1.一个脚本文件,例如pkg index.js;
2.package.json,例如pkg package.json,这时会使用package.json中的bin字段作为入口文件;
3.一个目录,例如pkg .,这时会寻找指定目录下的package.json文件,然后在找bin字段作为入口文件。
[options]中可以指定打包的参数:中可以指定打包的参数:
1.-t指定打包的目标平台和Node版本,如-t node6-win-x64,node6-linux-x64,node6-macos-x64可以同时打包3个平台的可执行
程序;
2.-o指定输出可执行文件的名称,但如果用-t指定了多个目标,那么就要用–out-path指定输出的目录;
3.-c指定一个JSON配置文件,用来指定需要额外打包脚本和资源文件,通常使用package.json配置。
使用pkg的最佳实践是:在package.json中的pkg字段中指定打包参数,使用npm scripts来执行打包过程,例如:
{
...
"bin": "./bin/www",
"scripts": {
"pkg": "pkg . --out-path=dist/"
},
"pkg": {
"scripts": [...] "assets": [...],
"targets": [...] },
...
}
scripts和assets用来配置未打包进可执行文件的脚本和资源文件,文件路径可以使用glob通配符。这里就浮现出一个问题:为
什么有的脚本和资源文件打包不进去呢?
要回答这个问题,就涉及到pkg打包文件的机制。按照pkg文档的说法,pkg只会自动地打包相对于__dirname、__filename的
文件,例如path.join(__dirname, ‘../path/to/asset’)。至于require(),因为require本身就是相对于__dirname的,所以能够自动
打包。假设文件中有以下代码:
require('./build/' + cmd + '.js')
path.join(__dirname, 'views/' + viewName)
这些路径都不是常量,pkg没办法帮你自动识别要打包哪个文件,所以文件就丢失了,所以这时候就使用scripts和assets来告
诉pkg,这些文件要打包进去。那么我们怎么知道哪些文件没有被打包呢?难倒要一行行地去翻源代码吗?其实很简单,只需
要把打包好的文件运行下,报错信息一般就会告诉你缺失哪些文件,并且pkg在打包过程中也会提示一些它不能自动打包的文
评论5
最新资源