angular打包(三):pkg
希望打包成1个web服务,运行exe,启动 angular,供浏览器显示。
问题分析:
其实angular编译后,都是静态文件了。只需要打包express,让express可以以exe的形式运行就可以了。
pkg的坑很多,写下来。
1 打包配置
这部分最坑。官网说的也不太清楚,绕了很多弯路。
我的最终做法如下:
1 在ng工程下单独建1个文件夹 命名为pkg(随便)
2 在pkg里建立package.json:
{ "name": "frontend", "bin": "server.js", "dependencies": { "express": "4.17.1" }, "pkg": { "assets": ["../dist/**/*"] } }
说明:
1 只需要打包express作为静态文件服务器。
用于伺服ng build 之后的dist文件夹即可,而不是把整个ng工程都打包。
因为ng是前端,只是在开发过程中用npm/node 进行包管理,而不是用node写的后端服务。
——一开始没想清这个,也确实发现pkg的问题:无法正确打包normalize.css 库, 然后才发现,我其实根本不需要打包这个。
2 dist文件夹全部当做assets处理。
即默认的ng编译出的文件位置。ng已经对文件进行了编译(--aot)。
3 建立server.js
const express = require('express'); const app = express(); const path = require('path'); const path_dist = path.join(path.resolve(__dirname, '..'), 'dist') app.use(express.static(path_dist)); app.get('/*', (req, res) => { res.sendFile(path.join(path_dist, 'index.html')); }); var server = app.listen(4000, function () { var host = server.address().address var port = server.address().port console.log(`server start successfully on http://${host}:${port}`) })
说明:
1 静态文件指向外层dist文件夹
2 express 路由 写成/*, 保证直接访问任意host:port/XX/YY 这样的url时,都能正确处理。
express 只负责把任意路由都指向 index.html就够了,
ng居然后面能自动正确处理路由。
这一点还是很智能,很省心的。
2 用pkg打包
win+R cmd, cd到包含server.js和package.json的路径下 执行
pkg server.js -t win-x64 --config package.json
坑点1:必须显式指定 --config ,否则只会孤零零打包server.js一个文件。
启动服务后,如果是简单hello world会正确,但是ng工程 浏览器会提示
cannot GET /
因为根没用package.json,所以dist根本就没打包进来
坑点2:打包时,会首先下载一个pkg专用的node 二进制文件, 40M左右,发布的打包exe就是基于这个的。不同平台,不同node版本不同。好像只支持node长期版,比如10 12这样的。
但是国内网不好,下载很慢,甚至总是中断。
可以根据提示去 这里下载对应版本 https://github.com/vercel/pkg-fetch/releases
尝试每天不同时段下载试试,反正不下载好这个,是根本无从打包的。
下载位置:
C:\Users\用户名\.pkg-cache
v2.6 文件夹 是 pkg@4.4.0 用的 比如给windos 和 node12用的 就是 fetched-v12.2.0-win-x64
v3.2 fetched-v14.18.3-win-x64
一旦下载好后:可以保存起来,复制到别的机器上,避免再次下载。
—— 最终打包成功后exe的体积约等于 下载的40M二进制文件 + dist文件夹的体积。
------------------------后记-----------------------------
用pkg打包坑点太多。 搜索了不少文章,但是误导,含混居多。包括官方文档,也不是太清楚。所以我就不列出引用了。
但是最终打包出来还是很小巧可人的。
总是打包失败的时候,我一度想直接用py的flask+ cxfreeze打包算了。那样必然体积大些。
现在这样很好。又学会1招。