Midwayjs部署环境-pkg可执行文件
介绍
大家都知道 Node 是以源码方式进行启动 node xxx.js
就可以运行。
我们运行 Node.js 开发的后端服务是需要安装环境后还需要安装相关依赖才能运行,部署目录就能直接看到源代码,这样会有源码泄露的风险。
为了更好的保护知识产权,将 Node.js 打包为一个单独的可执行文件,部署时直接拷贝执行即可,不需要安装node运行环境。Midwayjs 二进制文件部署
安装依赖
## 将所有的项目代码以组件的形式导出用于生成入口
npm i @midwayjs/bundle-helper --save-dev
## 用于构建二进制文件
npm i pkg --save-dev
pkg配置说明
首先需要对 pkg 进行配置,主要内容在 package.json
的 bin
和 pkg
字段下。
main
程序默认的启动运行入口文件bin
二进制文件启动入口文件pkg.scripts
构建启动使用的使用的所有 js 文件,使用 glob 的语法pkg.asserts
代码内部固定使用的模块引用文件pkg.targets
构建的平台产物,是下列选项的组合(nodeRange-platform-arch):- nodeRange node10, node12, node14, node16 or latest
- platform alpine, linux, linuxstatic, win, macos
- arch x64, arm64, armv7
pkg.outputPath
构建产物的输出地址
package.json 添加pkg配置
// package.json
{
"name": "mask_api_midwayjs",
// ...
"devDependencies": {
// ...
"@midwayjs/bundle-helper": "^1.2.1",
"pkg": "^5.8.1",
},
"scripts": {
// ...
"bundle": "bundle && npm run build",
"pkg": "bundle && pkg . --compress Brotli"
},
"main": "./bootstrap.js", // 程序部署PM2启动运行入口
"bin": "./bootstrap-bin.js", // pkg打包方式入口
"pkg": {
"scripts": "dist/**/*.js", // 需要打包的js脚本
"assets": [ // 模块引用缺失的文件
"./dist/assets/ip2region.xdb",
"./node_modules/bull/**/*"
],
"targets": [ // 需要在对应平台上构建避免缺失平台依赖
"node18-win-x64"
],
"outputPath": "./bin"
}
// ...
}
使用 --compress Brotli
对文件进行压缩,可选Brotli或GZip。
补充文件
mask_api_midwayjs
├── bin
├ ├── assets 目录-静态文件目录
├ ├── config.json 文件-传入覆盖的配置
├ └── 可执行文件 文件-可执行文件
├ └── package.json 文件-项目包信息
├── ...
├── bootstrap-bin.js 文件-pkg打包方式入口
├── bootstrap.js 文件-程序部署PM2启动运行入口
└── package.json 文件-程序依赖及启动命令信息
bin
作为pkg打包输出目录,其中是部署时必要的文件,需要与可执行文件同级放置。
assets 是给程序内部读取的静态资源文件,通过fs文件操作方式读取,修改后不需要重新启动才会生效。将构建生成的 dist
目录下的 assets
内非模块引用的文件放入,可解决读取内部文件失败问题。
config.json 是标准JSON格式内容,不含注释说明。文件放置与可执行文件同级,配置内容会合并到当前服务环境运行配置中,修改后需要重新启动才能生效。
package.json 可以直接复制使用项目根路径下的 package.json
文件,解决 MidwayInformationService 无法获取包信息的问题。文件修改后需要重新启动才能生效。
bootstrap-bin.js 需要在项目根路径下创建该文件,配置给pkg作为启动入口。
// bootstrap-bin.js
const { Bootstrap } = require('@midwayjs/bootstrap');
const fs = require('fs');
const path = require('path');
// 指定读取配置文件
const configPath = path.resolve(process.cwd(), 'config.json');
// 配置文件JSON格式内容
let jsonConfig = undefined;
// 检查文件是否存在
if (fs.existsSync(configPath)) {
try {
const jsonData = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
if (jsonData) {
jsonConfig = jsonData;
}
} catch (err) {
console.error(`读取配置文件 config.json 格式错误:${err.message}`);
}
}
Bootstrap.configure({
// 项目代码目录,指向可执行文件的目录
baseDir: process.cwd(),
// 引用的是编译后的入口
imports: require('./dist/index'),
// 禁用依赖注入的目录扫描
moduleDetector: false,
// 全局传入的配置,直接以对象形式合并到当前的配置中
globalConfig: jsonConfig,
}).run();
构建
npm install # 安装项目所需依赖
npm run bundle # 生成编译模块入口文件
npm run pkg # 构建平台产物
跨平台构建会存在缺失依赖的情况,所以推荐部署平台上安装依赖进行构建。
Linux中命令行输入 arch
查看系统架构。 x86_64
就选 x64
。
可以在虚拟机中构建同系统架构的二进制产物,然后将 bin
目录后拿去部署。
运行可执行程序时有提示缺失模块依赖的情况可以在 pkg.asserts
中进行补充。
下载构建的平台产物包
当遇到下载失败或下载慢的时候建议去Github仓库里下载,之后放到指定路径在继续构建操作。
Github仓库 github.com/vercel/pkg-…
$> npm run pkg
> mask_api_midwayjs@0.0.1 pkg
> bundle && pkg .
> pkg@5.8.1
> Fetching base Node.js binaries to PKG_CACHE_PATH
fetched-v18.5.0-win-x64 [ ] 0%
> Not found in remote cache:
{"tag":"v3.4","name":"node-v18.5.0-win-x64"}
第一步:根据打包时给出的文件信息确认版本
根据提示应该去找对应的tag版本,上Github仓库 github.com/vercel/pkg-… 在 Assets 展开找到对应的 node-v18.5.0-win-x64
下载。
也可以根据下载文件名称上Github仓库找到对应的版本,要和 tag
一致的,不然会校验不通过。
第二步:替换下载文件
PKG_CACHE_PATH 目录,默认是 ~/.pkg-cache
- Linux平台对应
/home/{当前用户}/.pkg-cache/{tag}
- Window平台对应
C:\Users\{当前用户}\.pkg-cache\{tag}
将下载好的文件 node-v18.5.0-win-x64
修改文件名称 fetched-v18.5.0-win-x64
放入指定位置。
第三步:执行构建命令
如果提示 Binary hash does NOT match. Re-fetching...
说明你下载错版本校验不通过,建议检查对应的tag
。
如遇到无法解决的问题,可以在下方进行留言,会在第一时间进行解答。