pkg打包

最近项目要改版,最大的变动就是更换组件库,同时转发 server 也由 Python 转为了 Node。因为前端对 Js 更加熟悉,转发 server 用 Node 对前端或者新加入的新人来说都更加友好些。

既然是个 Node 应用,自然想到了使用 pkg 将其打包进行部署。于是没接触过 pkg 的我开始研究如何将 Node 应用使用 pkg 进行打包。

pkg 简介

首先简单介绍下 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 项目的,最终 Node 项目会被打包成可执行文件,这个可执行文件甚至可以在你不安装 Node 环境的情况下运行。并且,打包时可以指定打包平台,让可执行文件可以在像 linux、mac、windows等多个平台运行。

安装

首先需要安装下 pkg,可以本地和全局安装,一般进行下本地安装就足够了。安装命令很简单:

1
2
npm install pkg    // 本地安装
npm install pkg -g // 全局安装

配置

配置可以分为两种类型,一种是直接打包 Node 入口文件的方式,另一种是通过在 package.json 中添加配置字段进行配置。
关于各个配置项不再多加赘述,可以直接在官网看到。下面贴出我们项目的目录结构,并以我们项目为例介绍下两种打包方式。


image.png

  1. 通过打包 Node 入口文件方式直接进行打包
    只需要在 package.json 的 “scripts” 字段添加或者如果全局安装了的话直接运行下面命令:
1
pkg ./server/app.js -t node10-macos-x64 -o /a/b/文件名
这样就算配置完成了,但是这种配置有个问题就是无法将前端 webpack 打包出的相关文件自动打包进可执行文       件中,必须通过提供打包好的文件夹如 dist 文件夹。
  1. 通过配置 package.json 方式进行打包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"scripts": {
"start": "npm run dev",
"dev": "node build/dev-server",
"dev-server": "NODE_ENV=development node server/app.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.jsx src test",
"test": "jest",
"pkg": "pkg . --target=node10-linux-x64 --out-path=pkg",
"pkg-mac": "pkg . --target=node10-macos-x64 --out-path=pkg",
"pkg-win": "pkg . --target=node10-win-x64 --out-path=pkg"
},
"pkg": {
"assets": [
"server/views/**/*.pug",
"dist/static/css/**/*.css",
"dist/static/images/**/*"
],
"scripts": [
"dist/static/js/**/*.js"
]
},

这种方式在配置时考虑的问题会更多一些,但是配置好了使用起来特别方便。你可以配置任何你想打包进去的内容,而且生成的可执行文件可以在任何目录双击打开(第一种方式直接双击执行会出问题,默认执行目录会变为当前 user 目录)
配置时需要注意 dependencies 里的依赖包会被打包进可执行文件中

代码

除了写配置文件,Node 路径相关的代码也需要做些调整,使用 path.join(__dirname, ‘xxx’) 这种的路径资源打包的时候会被检测到,直接使用绝对路径或者动态 require 的不会被检测到,所以可以根据这样的原则来写代码决定是否要讲文件打包进可执行文件。

关于 package.json

建议将 Node 相关的依赖单独放到一个 package.json 中,可以分两个文件夹 client 和 server,每个文件夹下有各自的 package.json, 因为在实践中发现 dependencies 的依赖会打包进可执行文件, devDependencies 也会部分打包进可执行文件,所以如果前后端依赖放到一个 package.json 会增大最后可执行文件的体积。具体哪些依赖被加入了可执行文件可以在使用 pkg 命令时添加 –debug 来查看。