前言
来吧,又遇到新问题了。
最近项目搞得差不多了,开始尝试打包Node后台程序。
问题
pkg用起来各种问题,不知道为什么pkg明明引用了babel却还是不能自动转换es6语法,导致编译出来的程序运行起来报错。
明明项目的package.json 里面已经声明了type:“module”,但依旧很鬼畜。
解决
好吧,我们自动手动搞一个babel编译过程。
1.首先在项目里面装个babel
npm install babel-cli --save-dev
2.然后根目录下创建个.babelrc文件
{
"presets": [
"@babel/preset-env"
]
}
3.修改package.json
{
...
"type": "module",
"bin": "dist/es5/index.js",
"pkg": {
"options": [
"experimental-modules"
],
"scripts": "dist/es5/**/*.js",
"targets": [
"node16-win-x64"
],
"outputPath": "dist"
},
"scripts": {
...
"build": "babel src -d dist/es5 && pkg ."
...
},
...
}
解释下,上面这些参数都是干啥的:
键 | 备注 |
---|---|
type | 告诉NodeJS我们的JS使用ES6的是语法。 |
bin | pkg要打包程序的入口文件 |
pkg | pkg的一堆参数配置 |
pkg->options | pkg要打包程序的入口文件 |
pkg->scripts | 一些动态引用无法被pkg捕捉到,我们需要告诉pkg这些东西也要一并打包出去。比如import(‘aaa.js’)这样的语法。 |
pkg->targets | 要构建的目标平台,有许多,比如node16-linux-arm64,请自行搜索 |
scripts->build | 这里是我们写的自动构建命令行,让babel完事儿后自动pkg |
所以以上就实现了pkg构建es6项目。
但事情还没有结束,我们还需要对fork做处理。
因为pkg构建出来的程序,干净到只有一个exe可执行文件,所以我们不能使用以往的fork(‘123.js’)这种形式来启动另一个进程,这样会报出找不到123.js这样的错误。
我们应该思考重复调用自身,通过不同的命令行参数来执行不同的任务。就像Chrome那样,开个网页有好多进程…
我们创建一个src目录,随后在搞两个测试文件index.js和child.js
//index.js
import cprocess from "child_process";
import child from "./child.js";
if (process.env.a == null) {
console.log("LOL!!", process.argv0, process.argv[1]);
cprocess.fork(process.argv[1], {
env: { a: "aaa" },
});
} else {
child();
}
//child.js
export default function () {
console.log("IM CHILD!!");
}
我们一起分析一下上述代码:
在index.js中,import child from “./child.js” 这样的语句是能够被pkg捕捉到的,child.js将会被一起打包进发布程序。
我们通过fork的option参数,设置了被frok进程的env
当程序启动时会检查env是否存在我们设置的a,如果没有则判定为主进程,如果有则为辅进程。
通过这种机制,我们再去处理每个进程该干的事。
案例工程可以戳这里下载