将您的 Node 应用程序捆绑为适用于 Windows、Linux 和 OsX 的单个可执行文件,运行 express 示例时出现 index.html 未包含在包错误中

2025-05-25

将您的 Node 应用程序捆绑为适用于 Windows、Linux 和 OsX 的单个可执行文件

运行 express 示例时出现 index.html 未包含在包错误中

很多人问我一个问题:如何将 Node 应用编译成单个可执行文件。我感到很惊讶,因为这其实很简单。

询问的理由

  • 保护源代码不被更改或复制——您无法在简单的文本编辑器中打开可执行文件。
  • 隐藏 API 凭证- 与保护源代码相同。
  • 无需 Node 或 NPM 即可运送到系统- 无需 NPM 安装依赖项,将所有内容捆绑在一个可执行文件中。
  • 规定 Node 版本- 强制使用某个版本的 Node 来保证功能支持。
  • 防止商业应用程序被无效——这不再像注释掉、替换或删除许可证验证功能那么简单。
  • 提升性能- 这不是一个合理的理由。打包后的可执行文件性能并没有提升,而且由于它包含完整的 Node,所以比 13kb 的 JavaScript 代码要大得多(22MB)。
  • 向朋友炫耀——我们有时都会这样做。
  • 广泛学习- 对事物底层工作原理感兴趣的人。我最喜欢的原因。
  • 看看我能做到的证据——嗯,就是这个。

市面上有一些工具可以做类似的事情。在本文中,我将重点介绍pkg,因为它是免费的(开源的),并且根据我的经验,它是迄今为止最令人愉快的工具。

包装

PKG 是一个命令行工具,可以简化应用的构建过程。运行npm i pkg -g即可全局安装。您也可以通过编程方式使用它,但我们稍后会详细介绍。

示例 Node 应用程序“prettyprint.exe”

我们将创建一个 Node 应用,用于打开一个 .json 输入文件,添加缩进(制表符、空格),并在控制台中打印出更美观、更易读的 JSON 格式。我将详细描述整个过程,并创建一个包含这些文件的 git 仓库。

NPM 初始化/package.json

使用package.json创建新 Node 应用程序的简单方法是在空目录中运行npm init 。

{
  "name": "prettyprint",
  "version": "0.0.1",
  "description": "Pretty print a JSON file.",
  "main": "main.js",
  "author": "anybody",
  "license": "MIT"
}
Enter fullscreen mode Exit fullscreen mode

导出函数的模块

为了绝对简单起见,我们假设main.js包含一个如下所示的函数:

/* You might want to check first if the file exists and stuff but this is an example. */
const fs = require('fs')
module.exports = function(filePath) {
    let data = fs.readFileSync(filePath).toString() /* open the file as string */
    let object = JSON.parse(data) /* parse the string to object */
    return JSON.stringify(object, false, 3) /* use 3 spaces of indentation */
}
Enter fullscreen mode Exit fullscreen mode

是的,@joelnet。我们都知道你喜欢这样写。谢谢你。

module.exports = filePath => JSON.stringify(JSON.parse(require('fs').readFileSync(filePath).toString()), false, 3)
Enter fullscreen mode Exit fullscreen mode

创建一个bin.js文件。

const prettyprint = require('.') /* the current working directory so that means main.js because of package.json */
let theFile = process.argv[2] /* what the user enters as first argument */

console.log(
    prettyprint(theFile)
)
Enter fullscreen mode Exit fullscreen mode

是的,@joelnet。可以像这样更短:

console.log(require('.')(process.argv[2]))
Enter fullscreen mode Exit fullscreen mode

一个虚拟 JSON 文件,用于测试一切是否正常

或者使用您自己的 JSON 文件。

{"user":{"name":"jochem","email":"jochemstoel@gmail.com"}}
Enter fullscreen mode Exit fullscreen mode

测试您是否复制/粘贴正确

如果您运行node bin.js file.json,您将会看到以下内容:

{
   "user": {
      "name": "jochem",
      "email": "jochemstoel@gmail.com"
   }
}
Enter fullscreen mode Exit fullscreen mode

向 package.json 添加一个属性

只需将值为“bin.js”的属性“bin”添加到包 json 中,如下所示:

{
  "name": "prettyprint",
  "version": "0.0.1",
  "description": "Pretty print a JSON file.",
  "main": "main.js",
  "bin": "bin.js", 
  "author": "anybody",
  "license": "MIT"
}
Enter fullscreen mode Exit fullscreen mode

运行 pkg

从你的应用目录运行pkg .来构建可执行文件。
如果不指定目标平台,它将同时针对 Windows、Linux 和 OSX 三个平台进行构建。

pkg .
> pkg@4.3.4
> Targets not specified. Assuming:
  node10-linux-x64, node10-macos-x64, node10-win-x64
Enter fullscreen mode Exit fullscreen mode

完毕!

瞧。将创建 3 个新文件。

prettyprint-win.exe
prettyprint-linux
prettyprint-macos
Enter fullscreen mode Exit fullscreen mode

要查看应用程序的运行情况,请运行prettyprint-win.exe file.json。在 Linux 上,请将二进制文件修改为 a+x使其可执行,然后运行​​./prettyprint-linux file.json。MacOS 系统暂不支持。

额外的

相关的东西我没法挤进任何地方。

为当前平台和版本构建的简单方法

从你的应用程序文件夹运行pkg -t host .-t表示目标平台,host表示你的系统。.表示当前目录。
当然,你也可以运行pkg --help获取完整的参数列表。

在 package.json 中,“main”和“bin”不需要不同

尽管您通常希望将它们分开,但mainbin可以具有相同的值,并且不一定需要是两个单独的文件。

依赖项需要位于 package.json 中

如果您在创建应用程序后使用 NPM 安装,它将自动将依赖项添加到 package.json。

原生模块和资产

要在可执行文件中包括资产文件/目录和/或构建依赖于本机 Node 模块的节点应用程序,请阅读文档

...

本教程中我们所做的一切都不是绝对必要的。你不需要包含“bin”属性的整个 package.json 文件。这只是一些常见的练习,有助于你学习。你也可以只构建一个 JavaScript 文件。

PKG API

在这个例子中,我使用 PKG API 来构建单个 JavaScript 文件,而不需要整个工作目录或 package.json

/* js2exe.js */
const { exec } = require('pkg')
exec([ process.argv[2], '--target', 'host', '--output', 'app.exe' ]).then(function() {
    console.log('Done!')
}).catch(function(error) {
    console.error(error)
})
Enter fullscreen mode Exit fullscreen mode

是的,@joelnet。可以像这样更短:

require('pkg').exec([ process.argv[2], '--target', 'host', '--output', 'app.exe' ]).then(console.log).catch(console.error)
Enter fullscreen mode Exit fullscreen mode
跑步
node js2exe.js "file.js"
Enter fullscreen mode Exit fullscreen mode
制作你自己的独立编译器可执行文件

你甚至可以让它自行构建,最终生成一个可以自行构建并独立构建任何其他 JavaScript 的可执行文件。一个独立的编译器。

node js2exe.js js2exe.js
Enter fullscreen mode Exit fullscreen mode

现在,您可以将输出可执行文件app.exe用作不再需要 Node 或 NPM 的独立编译器。

app.exe myfile.js
Enter fullscreen mode Exit fullscreen mode
文章来源:https://dev.to/jochemstoel/bundle-your-node-app-to-a-single-executable-for-windows-linux-and-osx-2c89
PREV
DevOps路线图
NEXT
2021 年前端开发