使用pkg打包你的前端应用为exe可执行文件

5,180 阅读4分钟

1. 需求场景

前端的你正在进行一个前端项目,此时产品过来说:客户现在急着想看下现在做的如何,能不能让客户先看下,做了多少看多少。此时的你心里头是一万只xx马在奔腾,由于项目部署、内外网络等各种问题,还不能部署在线上,急中生智的你想到了**pkg**,成功化解了此危机。

2. 什么是pkg?

pkg.png
pkg.png

Single-Command Node.js binary complier

  1. pkg是一个Node.js的单命令二进制编译器。

pkg was created for use within containers and is not intended for use in serverless environments

  1. pkg是为在容器内使用而创建的,不在无服务器环境中使用。

This command line interface enables you to package your Node.js project into an executable that can be run even on devices without Node.js installed.

  1. 通过命令行界面,将Node.js项目打包为可执行文件,即使在未安装Node.js的设备上也可以运行该可执行文件

如标题所言,pkg可以快速的将你的应用打包成一个exe可执行文件,然后发给别人,别人不需要处理一系列环境等问题,只需要运行这个exe文件,即可预览你的应用了。

3. 如何使用pkg?

1. 安装

npm i pkg -D

2. 先打包你的应用

react或者vue应用请执行yarn run build打包命令,获得打包结果

3. 使用express或者koa创建服务

这里移koa为例

  1. 安装koa
npm i koa koa-static -D
  1. 在项目根目录创建services.js文件 folder.jpg
const { exec } = require("child_process");
const Koa = require("koa");
const koaStatic = require("koa-static");
const app = new Koa();

// build为打包后的目录
app.use(koaStatic("./build"));

app.on("error"function (err) {
  console.log("logging error ", err.message);
  console.log(err);
});

app.listen(4000() => {
  const url = `http://localhost:4000`;
  console.log(`server start successfully, on: ${url}`);
  console.log("process.platform: ", process.platform);

  // auto open browser
  switch (process.platform) {
    //mac
    case "darwin":
      exec(`open ${url}`);
    case "win32":
      exec(`start ${url}`);
    default:
      exec(`open ${url}`);
  }
});
  1. 启动koa服务

在项目根目录运行,成功后即可在浏览器里看到刚才打包后的页面

node services.js

4. 打包pkg

  1. 修改根目录package.json
{
+   "bin": "./services.js",
+   "pkg": {
+     "scripts": [],
+     "assets": [
+       "./build/**/*"
+     ]
+   },
  "scripts": {
    "start": "react-scripts start",
-   "build": "react-scripts build"
+   "build": "react-scripts build",
+   "build:pkg": "pkg . -t win --out-path=dist/ --debug"
  },
}
  • 添加bin命令,为pkg打包入口文件,这里我们写services.js
  • 添加pkg命令,为pkg打包配置项,scripts为要打包进去的js文件,可以添加多个,assets为静态资源,也可以添加多个
  • scripts命令中添加build:pkg,为pkg打包执行命令
  1. 执行pkg打包命令
npm run build:pkg

这时候可能由于网络的原因,执行打包会超时报错,因为要下载外网资源,你懂得

> pkg@4.4.9
> Fetching base Node.js binaries to PKG_CACHE_PATH
  fetched-v10.21.0-win-x64     [===                    ] 16%
> Error! connect ETIMEDOUT 13.229.188.59:443
> Asset not found by direct link:
  {"tag":"v2.6","name":"uploaded-v2.6-node-v10.21.0-win-x64"}

这时候我们可以手动下载,选择自己电脑对应的版本进行下载。

然后把下载的文件复制到C:\Users\Administrator\.pkg-cache\v2.6这个文件目录下,记得同时修改文件名称,我这里下载的是uploaded-v2.6-node-v10.21.0-win-x64,那么将它重名为fetched-v10.21.0-win-x64

然后重新执行打包命令,即可成功打包。

  1. 运行打包后的exe可执行文件 双击执行这个文件,我们发现服务是成功启动了,但是浏览器上的页面是空白的,只显示Not Found,因为我们还有最关键的一步没做,是因为路径问题导致的,需要修改services.js文件:
// build为打包后的目录
- app.use(koaStatic("./build"));
+ app.use(koaStatic(path.resolve(__dirname, "./build")));

修改完之后我们重新执行打包,运行exe文件,即可看到页面正常打开

  1. 动态修改配置文件 如何将项目的配置文件,不打包进exe文件中,在外面灵活的修改呢?这里我们已服务启动的端口为例
  • 在dist目录下新建conf.js文件:
const requestConf = {
  url: 'localhost',
  port: 8080
}

module.exports = requestConf;
  • 修改services.js文件:

process.cwd()表示当前运行所在目录,其它具体见Snapshot filesystem

+ const requestConf = require(path.join(process.cwd(), 'conf.js'));
...
- app.listen(4000, () => {
-  const url = `http://localhost:4000`;
+ app.listen(requestConf.port, () => {
+  const url = `http://${requestConf.url}:${requestConf.port}`;
...
  • 然后执行打包命令,这样我们就可以在外面动态的修改,然后执行文件

5. 参考资料

  1. pkg
  2. Pkg —— 打包node为可执行文件(.exe)工具
  3. node打包可执行文件工具——Pkg使用心得