项目地址:https://github.com/helson-lin/pkg_sqlite
在ffandown
项目内,由于项目使用了sqlite3
,在跨平台打包的时候,除了本机外其他平台打包之后运行缺少node_sqlite3.node
依赖。
为了解决问题,百度了很久,能够实现的方案就三种。
- 分别在不同平台打包,这个是最直接的方法。
- 将
node_sqlite3.node
文件放在可执行文件同级目录下,运行的时候binding
会自动找到。 - 在每一次构建之后,手动将
node_sqlite3.node
依赖移动到node_modules/sqlite3/building/Release/
, 该方案支持github actions
自动打包。
方案3如何实现github actions自动打包
准备好各个平台的node_sqlite3.node文件
这里演示没有配置所有的node文件,其他平台自行配置
文件可以从TryGhost-GIthub下载
编写脚本打包之前替换node_sqlite3.node文件
脚本如下,主要思路就是,在每个平台打包之前,现将对应平台的文件移动到node_modules/sqlite3/building/Release/
下面。
如果直接使用改脚本,请确保package下面文件的名称和我的保持一致。
📢 需要注意,这个脚本运行之前有一些前提的条件
- package.json配置好pkg配置项, 包括targets和assets
- 所有的node文件放在同级的package目录下
- 脚本文件放在根目录下面的
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const { execSync} = require('child_process')
// 源文件路径(根据你的项目结构调整)
let isDebug = false;
let releaseName;
const argv = process.argv.slice(2)
// 支持debug参数
if (argv && argv[0] === '--debug') isDebug = true
// package为我的项目根目录下面文件夹存放node文件
const sourcePath = path.join(__dirname, "package/");
// 目标路径
const targetPath = path.join(__dirname, "node_modules/sqlite3/build/Release/");
const moveNodeSqlite = (targetPlatform) => {
// 根据目标平台选择正确的文件,这里只写了几个平台可以自行补充
let targetFile;
const name = targetPlatform.split('-').slice(1).join('-')
switch (name) {
case "linux-x64":
targetFile = "linux_x64_node_sqlite3.node";
break;
case "linux-arm64":
targetFile = "linux_arm64_node_sqlite3.node";
break;
case "macos-arm64":
targetFile = "macos_arm64_node_sqlite3.node";
break;
case "macos-arm64":
targetFile = "macos_x64_node_sqlite3.node";
break;
default:
console.error(`\n ❗️ Unsupported target platform:${targetPlatform} \n`);
}
if (targetFile) {
// 复制文件
fs.copyFileSync(
path.join(sourcePath, targetFile),
path.join(targetPath, "node_sqlite3.node")
);
console.log(
`\n ✅ Copied ${path.join(sourcePath, targetFile)} to ${path.join(
targetPath,
"node_sqlite3.node"
)}\n`
);
}
};
const pkgRelease = (targetPlatform) => {
moveNodeSqlite(targetPlatform);
// 执行打包命令
// --output指定输出的目录地址,和文件的名称
execSync(`pkg . -t ${targetPlatform} --output ./dist/${releaseName}-${targetPlatform}${targetPlatform.indexOf('windows') !== -1 ? '.exe' : ''}` + (isDebug ? ' --debug' : ''), { stdio: 'inherit' })
};
const start = () => {
try {
const dataString = fs.readFileSync(path.join(__dirname, 'package.json'), 'utf-8')
const data = JSON.parse(dataString)
const platforms = data.pkg.targets
releaseName = data.name
for (let item of platforms) {
pkgRelease(item)
}
} catch (e) {
console.error('❗️ read package.json failed', e)
}
}
start()
package.json配置
这里只粘贴了pkg配置部分、
scripts
配置项为需要打包的js文件
assets
配置项必不可少,少了node文件不会被打包到可执行文件内
targets
配置项填写需要构建的平台,这里被脚本引用了,少了脚本会出现问题。
{
"name": "docker_sync",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": "index.js",
"scripts": {
"build": "node build.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/helson-lin/docker_sync_template.git"
},
"keywords": ["demo"],
"author": "helsonlin",
"license": "ISC",
"pkg": {
"scripts": [
"index.js",
"db.js"
],
"assets": [
"/node_modules/sqlite3/build/**/*"
],
"targets": [
"node14-macos-arm64",
"node14-macos-x64",
"node14-windows-x64",
"node14-linux-x64",
"node14-linux-arm64",
"node14-alpine-x64",
"node14-alpine-arm64"
],
"outputPath": "dist"
},
"bugs": {
"url": "https://github.com/helson-lin/docker_sync_template/issues"
},
"homepage": "https://github.com/helson-lin/docker_sync_template#readme",
"devDependencies": {
"body-parser": "^1.20.2",
"express": "^4.18.2",
"pkg": "^5.8.1",
"sqlite3": "^5.1.6"
}
}
Github actions配置
该配置文件不做过多解释
name: Build and push Docker image
on:
push:
branches: [ main ]
tags:
- 'v*.*.*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Npm Install
run: npm install --registry=https://registry.npmmirror.com
- name: Build Release
run: npm run build
- name: release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: "dist/**"
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}