NODE打包交付第三方使用之PKG

背景:这我来本公司的第一个任务,中间踩了很多坑。万幸的是最终解决了!我们所采用的技术栈是midway.js(node的框架,可以用koa、egg、express代替)+so+pkg。

so:作为现阶段可逆难度比较大的技术手段,采用so来做加密的案例有很多,这个就不过多的赘述了,动C++的做起来很方便,也可以用dll,用法大体类似。

pkg:作为JS的打包工具,会把环境和依赖都打包进一个可执行文件,随便复制到相应的地方就可以用了!

1、so的node使用,直接上代码

1
2
3
4
5
6
ini复制代码const [data, key] = base64.decode(deCryptoKey).split(',');
const libm = ffi.Library(path.join(process.cwd(), this.soPwd), {
TKS: ['string', [GoString, GoString, GoString]],});
// 获取soConfigconst
secStr = libm.TKS( newGoString('sec_code'), newGoString(data), newGoString(key));
let soConfig = JSON.parse(secStr);

2、PKG打包配置——package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
go复制代码package.json

"pkg": {"scripts": ["./dist/**/*.js", "./bootstrap.js" ],
"assets": [
"./node_modules/ref-napi/**/*",
"./node_modules/ffi-napi/**/*",
"./node_modules/ref-struct-napi/**/*",
"./node_modules/node-gyp-build/**/*",
"./node_modules/grpc/**/*"
],
"targets": ["node12-linux-x64"]},
"scripts": {
"pkg-macos": "pkg . -t node12-macos-x64 --out-path=",
"pkg-linux": "pkg . -t node12-linux-x64 --out-path=",
},

3、PKG打包配置——dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bash复制代码FROM nikolaik/python-nodejs:python3.8-nodejs12
ENV NODE_ENV=local ENV MIDWAY_LOGGER_DISABLE_COLORS=true
WORKDIR /root

COPY . .
RUN npm i midway-bin \
&& npm i \
&& npm run build \
&& npm rebuild \
&& npm run pkg-linux \
&& ls |grep -v -E "^so|artery"|xargs -i rm -rf {} \
&& cd so \
&& ls |grep -v *${NODE_ENV}.so|xargs -i rm -rf {}
EXPOSE 7001

["/root/artery"]

4、PKG打包配置——bootstrap.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ini复制代码// 加载所有js文件-解决路由丢失问题
const getFiles = function (dir, list = []) {
const arr = fs.readdirSync(dir);
while (arr.length) {
const item = arr.pop();
const fullpath = path.join(dir, item);
const stats = fs.statSync(fullpath);
if (!stats.isDirectory()) {
if (/.js$/.test(fullpath)) list.push(require(fullpath));
} else {
getFiles(fullpath, list);
}
}
return list;
};
Bootstrap.before(async (container) => {
// 读取远程配置
web = createKoaweb(container.getConfigService().getConfiguration());
}).configure({
baseDir: path.join(__dirname, '/dist'),
preloadModules: getFiles(path.join(__dirname, '/dist')),
}).load(() => {
return web;
}).run();

总结遇到的坑

1、python问题

换源、npm rebuild

2、项目启动问题

Node启动换为直接运行

3、npm build 丢失二进制文件问题

dockerfil复制进去

4、无效的内存地址或 nil 指针取消引用

so包不对

5、路由找不到

与作者沟通加了preloadModules方法

6、native complate have not……

将依赖放进打包目录assets下

7、V8报错

降低node版本

8、数据库dao无法加载

执行目录有问题,解决方案用:join(__dirname, ‘../‘, it)))

后续优化

1、因为我们用了SO,所以导致打出来的docker镜像比较大,后续可以采用二次打包,打出来要缩小十倍左右!

2、或者把SO做成服务,用SDK调用(我们的方案)

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%