1. 需求场景
前端的你正在进行一个前端项目,此时产品过来说:客户现在急着想看下现在做的如何,能不能让客户先看下,做了多少看多少。此时的你心里头是一万只xx马在奔腾,由于项目部署、内外网络等各种问题,还不能部署在线上,急中生智的你想到了**pkg**,成功化解了此危机。
2. 什么是pkg?
Single-Command Node.js binary complier
- pkg是一个Node.js的单命令二进制编译器。
pkg was created for use within containers and is not intended for use in serverless environments
- 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.
- 通过命令行界面,将Node.js项目打包为可执行文件,即使在未安装Node.js的设备上也可以运行该可执行文件。
如标题所言,pkg可以快速的将你的应用打包成一个exe可执行文件,然后发给别人,别人不需要处理一系列环境等问题,只需要运行这个exe文件,即可预览你的应用了。
3. 如何使用pkg?
1. 安装
npm i pkg -D
2. 先打包你的应用
react或者vue应用请执行yarn run build
打包命令,获得打包结果
3. 使用express或者koa创建服务
这里移koa为例
- 安装koa
npm i koa koa-static -D
- 在项目根目录创建
services.js
文件
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}`);
}
});
- 启动koa服务
在项目根目录运行,成功后即可在浏览器里看到刚才打包后的页面
node services.js
4. 打包pkg
- 修改根目录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打包执行命令
- 执行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
。
然后重新执行打包命令,即可成功打包。
- 运行打包后的exe可执行文件
双击执行这个文件,我们发现服务是成功启动了,但是浏览器上的页面是空白的,只显示
Not Found
,因为我们还有最关键的一步没做,是因为路径问题导致的,需要修改services.js
文件:
// build为打包后的目录
- app.use(koaStatic("./build"));
+ app.use(koaStatic(path.resolve(__dirname, "./build")));
修改完之后我们重新执行打包,运行exe文件,即可看到页面正常打开
- 动态修改配置文件 如何将项目的配置文件,不打包进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}`;
...
- 然后执行打包命令,这样我们就可以在外面动态的修改,然后执行文件