使用pkg打包node应用
flytam Lv4

node相比其它C艹等语言的好处是直接装好node环境后node xxx.js就可以运行了,非常方便。但是这样的话别人就能直接看到源代码,而且每次部署都需要node环境,并且安装相关的依赖。

此时pkg这个库就能解决介个问题。最近因为项目需求方需要,搞了下这方面的需求。

正确的姿势。例如项目的入口文件是app.js

1、项目根目录下安装pkg

1
npm i -D pkg

2、打包配置

参考pkg文档。pkg可以在任意系统上打包全平台的可执行文件。例如我的需求是需要打包win64位系统node8环境的包。只需要package.json的scripts下配置。.的话是去读取bin的入口文件。

1
"pkgwin": "pkg . -t node8-win-x64 -o app",

bin路径

1
"bin": "./app.js"

需要注意的是pkg只会分析require的文件并打包在一起,如果是动态拼接的路径就不会打包进去。

例如我的项目下有的是开启子进程的代码

1
const trackWorker = child_process.fork(`${__dirname}/workers/trackChild.js`);

此时,需要告诉pkg需要手动打包的文件

1
2
3
"pkg": {
"scripts": "workers/**/*.js"
},

这样就大功告成了

4、实现自定义配置文件

数据库等其它的配置我们肯定需要暴露出来的,毕竟打包出来就只有一个二进制文件。配置就需要特殊处理下。预期是打包出来最终运行的时候是

  • 目录
    • app.exe
    • config.json

我们只需要改config.json的配置就行了。也很简单,就是读取配置的时候去读取json文件就行(文档也让我们尽量用json而不是js,因为node的模块加载制止我们的config.js代码会被执行,别人会读取到源码)

1
2
3
4
5
6
7
8
9
10
const fs = require("fs");
const path = require("path");

const configPath = path.join(process.execPath, "../","./config.json");
let isConfigExist = fs.existsSync(configPath);

let jsonConfig = null
if (isConfigExist) {
jsonConfig = JSON.parse(fs.readFileSync(configPath, "utf8"));
}

5、部署

pm2也是可以直接部署可执行文件,不过使用这种部署的话就只能使用fork模式 ,而不能使用cluster模式。

简单的说,pm2的cluster模式只能执行node。以node的cluster为基础,多进程。
fork模式,单实例。不止node

最后附上package.json和pm2的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"name": "webapi",
"scripts": {
"start": "nodemon ./app.js",
"pm2": "pm2 start pm2.json",
"pkgmac": "pkg . -t node8-macos-x64 -o app",
"pkgwin": "pkg . -t node8-win-x64 -o app",
"pkg": "pkg . -t node10-win-x64 -o app"
},
"bin": "./app.js",
"pkg": {
"scripts": "workers/**/*.js"
},
"dependencies": {
...
},
"devDependencies": {
"nodemon": "^1.11.0",
"pkg": "^4.3.5"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"apps": [
{
"name": "webAPI",
"script": "app",
"cwd": "./",
"error_file": "./logs/app-err.log",
"out_file": "./logs/app-out.log",
"log_date_format": "YYYY-MM-DD HH:mm Z",
"max_memory_restart": "300M"
}
]
}

可能遇到问题:

第一次打包的时候,会遇到下包很慢很可能超时的问题。如下:

image

https://github.com/zeit/pkg-fetch/releases下载对应的包,然后
~/.pkh-cache/2.5/目录下,改名为fetched-v8.11.3-macos-x64(参考运行时下的包名字改)即可。参考https://github.com/zeit/pkg/issues/419

  • Post title:使用pkg打包node应用
  • Post author:flytam
  • Create time:2018-12-23 21:56:06
  • Post link:https://blog.flytam.vip/使用pkg打包node应用.html
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.