如何从一个Node.js应用程序创建可执行文件?

173

我有一个Node.js应用程序,它需要通过以下命令运行:

node.exe app.js inputArg

是否有办法将其打包成独立的 .exe 文件呢?这样我就可以像这样运行:

App.exe inputArg

我也可以通过使用批处理文件来模拟这个过程,例如:

App.bat inputArg

但这需要在同一文件夹中安装所有依赖项和 Node.js,这并不理想。


1
可能是重复问题:https://dev59.com/uW025IYBdhLWcg3wOzE9 - Mike Christensen
3
这似乎是重复的问题集锦,包含以下链接:https://dev59.com/uW025IYBdhLWcg3wOzE9,https://dev59.com/d1vUa4cB1Zd3GeqPvqUK,https://dev59.com/Xmsz5IYBdhLWcg3wADMm,https://dev59.com/n2oy5IYBdhLWcg3wEJ9n,https://dev59.com/S2HVa4cB1Zd3GeqPoJWp,https://dev59.com/ZWYr5IYBdhLWcg3wytLe。 - Mogsdad
这里有一份不错的工具列表:https://dev59.com/dWw15IYBdhLWcg3wFH3f#12486874 - GrGr
2
我认为任何在这里添加答案的人都应该考虑是否已经完成。这个问题正在变成一堆链接,指向各种质量/活动不同的开源产品。 - Liam
@Liam 一个关于SO的好描述 :) - john k
21个回答

80
我使用的解决方案是Roger Wang的node-webkit
这是一种打包nodejs应用程序并分发它们的绝佳方式,甚至还提供了将整个应用程序“捆绑”为单个可执行文件的选项。它支持Windows、Mac和Linux。 这里有一些关于部署node-webkit应用程序各种选项的文档,但简而言之,您需要执行以下操作:
  1. 将所有文件与package.json压缩在一起
  2. 将扩展名从.zip更改为.nw
  3. 复制/b nw.exe+app.nw app.exe
只是额外说明一下——我已经使用这个方法发布了几个生产环境的应用程序,并且效果非常好。同一个应用可以在Windows、Mac、Linux和Web上运行。
更新:该项目名称已更改为'nw.js',正确位置在nw.js

2
刚试了一下,效果很棒!而且这个工具得到了英特尔的支持。 - Timo Huovinen
这应该是截至今天最准确和最新的答案。此外,还可以参考此处的node-webkit备忘清单:https://gist.github.com/LeCoupa/80eca2716a2b13c37cce其中包含其他非常有用的内容,比如如何编译JS(或者至少压缩成字节码,具体取决于你对“编译”这个词使用多么守旧)。 - Erik Reppen
我喜欢这个答案,但是它仍然不能创建一个独立的exe文件。根据Intelnw.js在Github上的页面,你仍然需要在同一个文件夹中至少有另外两个文件:nw.pak和icudt.dll。如何创建一个独立的exe文件? - Jeff Baker
@JeffBaker 如果你在Github的文档中往下看一点,你会看到这个链接:https://github.com/nwjs/nw.js/wiki/How-to-package-and-distribute-your-apps#an-alternative-way-to-make-an-executable-file-in-windows 如果你不想要包含额外的文件,你可以按照此链接所示的方法进行操作。 - Clayton Gulick
@Clayton,Nw.js也被chrome.com推荐。https://developer.chrome.com/apps/migration#native - Pacerier
4
不确定这是否仍然是2019年的良好方法。听起来它会捆绑大型的WebKit库,这对于HTML GUI应用程序来说很好,但对于控制台应用程序来说是不必要的。 - Simon East

47

有几种免费和商业化的替代品可供选择,我没有使用过其中任何一个,但理论上它们应该可以工作:

大多数工具都需要您将批处理文件保留为主要可执行文件,然后捆绑node.exe和您的脚本。

取决于您的脚本,您还可以选择将它移植到JSDB,它支持一种通过简单附加资源创建可执行文件的简便方法

第三种准解决方案是将node保留在类似C:\ utils的位置,并将此文件夹添加到PATH环境变量中。然后,您可以在该目录中创建运行node和首选脚本的.bat文件 - 我以这种方式在Windows上运行coffeescript的coffee。此设置可以使用批处理文件、vb脚本或安装程序自动化。


3
我尝试了“高级”批处理转EXE转换器,它非常好用。你可以将依赖项打包到EXE文件中。感谢您的帮助。 - Aishwar
1
@Aishwar,但是你不能捆绑node_modules文件夹,所以你无法在其中执行任何高级操作... - Clint
如果你将node_modules压缩成zip/rar格式,在应用程序运行时解压到临时目录中,会怎样呢?但是,如果你有很多模块的话,速度可能会变慢。 - Jarrod Mosen

44

对于那些偶然发现这个问题的人,现在有两个项目可以将你的Node项目生成exe文件, PkgElectron.atom.io,它们略有不同:

1. Pkg会将您的项目编译为本机代码,同时包含资源和NodeJS安装(系统不需要安装NodeJS来运行可执行文件)。您的源代码将不会被包括在内。生成的可执行文件仅适用于Windows(.exe)。现在支持所有平台。商业产品现在需要许可证。完全开源。 2. 虽然Electron.atom.io不会压缩和生成可执行文件,但它可以用于分发NodeJS应用程序,因为它们提供了一种distribute applications的方式。优点是electron是多平台的(Windows,macOS,Linux),缺点是您的源代码将会被包括在内,即使他们提供了一种将您的应用程序分发到asar存档中的方法。它不是绝对安全的,但仍然比您的源代码明文更好。

3
请更新:EncloseJS现在支持Linux和OS X。 - 000000000000000000000
修改了评论!@000000000000000000000 - sokie
EncloseJS是一个不错的选择。我现在就要尝试它!感谢您提供答案!+1 :) - tftd
我无法安装EncloseJS。它显示Err代码ELIFECYCLE,但没有任何有用的错误消息。 - Elmue
2
EncloseJS不再维护。其继承者似乎是zeit/pkg(https://www.npmjs.com/package/pkg)。 - Lucas Gonze
asar 只是一个存档文件。请参阅https://dev59.com/n1kT5IYBdhLWcg3wfvin#38524534。 - Chayim Friedman

39

我知道的最好工具是 NodeJS 工具: vercel/pkg

它非常容易使用(比如 Nexe 简单得多),你只需全局安装: npm install -g pkg

来创建适用于 macOS、Linux 和 Windows 的可执行文件:

pkg exampleApp.js

我有一些复杂的代码,使用了 NodeJS socket 服务器,我尝试了不同的应用程序,除了 zeit/pkg 都无法正确创建它。


我试图将Appium安装压缩到一个Exe文件中,但是zeit/pkg彻底失败了。从磁盘上的310MB中得到了一个仅有18MB的小型Exe文件,显然完全无法工作。 - Elmue
2
仓库名称现已更新为vercel/pkg - ikhvjs

29

默认情况下,Windows将.js文件与Windows Script Host相关联,这是微软独立的JS运行时引擎。如果您在命令提示符处键入script.js(或在资源管理器中双击一个.js文件),则会由wscript.exe执行脚本。

这可能是使用全局设置解决本地问题, 但您也可以.js文件与node.exe关联,这样在命令提示符处键入script.js或双击/拖动项目到脚本上都将使用Node启动它们。

当然,如果(像我一样)您将.js文件与编辑器相关联,以便双击打开您喜欢的文本编辑器,则此建议不会有太大作用。您还可以添加右键菜单项“使用Node执行”到.js文件,尽管这种选择不能解决您的命令行需求。


最简单的解决方案可能是使用批处理文件 - 您不必在脚本所在的文件夹中拥有Node的副本。只需绝对引用Node可执行文件即可:

"C:\Program Files (x86)\nodejs\node.exe" app.js %*

另一种选择是使用这个非常简单的C#应用程序,它将使用自己的文件名+.js作为要运行的脚本,并传递任何命令行参数来启动Node。

class Program
{
    static void Main(string[] args)
    {
        var info = System.Diagnostics.Process.GetCurrentProcess();
        var proc = new System.Diagnostics.ProcessStartInfo(@"C:\Program Files (x86)\nodejs\node.exe", "\"" + info.ProcessName + ".js\" " + String.Join(" ", args));
        proc.UseShellExecute = false;
        System.Diagnostics.Process.Start(proc);
    }
}

所以,如果你将生成的EXE命名为"app.exe",你可以键入app arg1 ...,Node将使用命令行"app.js" arg1 ...启动。请注意,C#引导程序应用程序将立即退出,使Node负责控制台窗口。
由于这可能是相对广泛的兴趣,我已经将其放在GitHub上,包括编译的exe文件,如果与陌生人一起乘坐面包车是你的事情的话。

正如你所提到的,这并不是以理想的方式解决我的问题。但是因为有趣的阅读材料,我还是给你点赞(+1)。 - Aishwar
@Aishwar,我已经添加了一个简单的应用程序,可以为您启动Node。请查看编辑。 - josh3736
@josh3736,你的exe文件是否仍需要在同一文件夹中有node.exe? - Ricardo Tomasi
@RicardoTomasi,不是的。它假设Node已安装在系统的Program Files目录中(即安装程序放置它的位置)。 - josh3736
@josh3736 这是一个有趣的解决方案。我喜欢你所做的事情,希望我能再次点赞 :)。但这仍然不是理想的,因为它需要用户安装并将node.js添加到标准路径中。 - Aishwar

15

自从这个问题被解决后,又推出了另一个解决方案。

https://github.com/appjs/appjs

在撰写本文时,这是将node.js应用程序打包为可执行文件的终极解决方案,它通过编译成可执行文件的精简版chromium包来实现。

编辑: AppJS已不再更新,但它本身建议使用名为deskshell的分支。

https://github.com/sihorton/appjs-deskshell/


2
似乎是一个损坏的链接。 - starbeamrainbowlabs
2
该项目已不再活跃。请参考Clayton Gulick提到的node-webkit作为替代方案。 - Andrew Camilleri 'Kukks'
Appjs本身建议使用一个活跃的分支,叫做deskshell https://github.com/sihorton/appjs-deskshell/。 - bitfed

14

13

这里有很多好的答案,但并不都像 JXcore 这样简单明了。

在 Windows 上安装 JXcore 后,您只需要运行以下命令:

jx package app.js "myAppName" -native

这将生成一个.exe文件,您可以分发并且无需任何外部依赖即可执行(甚至不需要系统上的JXcore或Node.js)。
这里是有关该功能的文档:http://jxcore.com/packaging-code-protection/#cat-74 编辑2018年 该项目现已停止,但仍在此处托管:https://github.com/jxcore/jxcore-release(感谢@Elmue)。

2
谢谢老兄。我能否在Windows中制作Linux可执行文件? - Sasivarnan
2
据我所知,不,你不能这样做。我认为JXCore会从操作系统中获取一些文件来生成可执行文件,而它并不会打包这些文件,所以如果你想创建一个Linux可执行文件,你将必须在Linux上运行这个命令。 - Nepoxx
3
JXcore停止了开发。 http://www.nubisa.com/nubisa-halting-active-development-on-jxcore-platform/ - user619271
2
这里的所有链接都已失效。这个链接有效:https://github.com/jxcore/jxcore-release - Elmue

10

我使用了以下技术:

  1. @vercel/ncc(确保将所有必要的依赖项捆绑到单个文件中)
  2. pkg(用于制作exe文件)

让我们执行以下步骤:

  1. npm i -g @vercel/ncc

  2. ncc build app.ts -o dist (我的入口文件是app.ts,输出在dist文件夹中,请确保您在包含package.json和app.ts文件的文件夹中运行,运行上述命令后,您可能会在dist文件夹中看到index.js文件)

  3. npm install -g pkg (安装pkg)

  4. pkg index.js (请确保您在上面的dist文件夹中运行命令)


9
尝试使用disclose: https://github.com/pmq20/disclose disclose实际上是将您的Node.js项目和Node.js解释器制作成一个自解压exe文件,具有以下特点:
  1. 无GUI,纯CLI。
  2. 无运行时依赖项。
  3. 支持Windows和Unix。
  4. 第一次运行速度较慢(提取到缓存目录),然后永久快速运行。
尝试使用node-compiler: https://github.com/pmq20/node-compiler 我创建了一个名为node-compiler的新项目,将您的Node.js项目编译为一个单独的可执行文件。
它比disclose更好,因为它不会在第一次运行时运行缓慢,因为您的源代码与Node.js解释器一起编译,就像标准的Node.js库一样。
此外,它在运行时透明地将文件和目录请求重定向到内存而不是文件系统。因此,运行已编译的产品不需要源代码。
如何工作:https://speakerdeck.com/pmq20/node-dot-js-compiler-compiling-your-node-dot-js-application-into-a-single-executable 与类似项目的比较:
  • pkg (https://github.com/zeit/pkg):Pkg通过动态地黑掉fs.* API来访问包内文件,而Node.js编译器则不会这样做,它通过libsquash在更深层次上工作。Pkg使用JSON存储包内文件,而Node.js编译器则使用更复杂和广泛使用的SquashFS作为数据结构。

  • EncloseJS (http://enclosejs.com/):EncloseJS仅支持五个fs.* API来访问包内文件,而Node.js编译器支持所有fs.* API。EncloseJS是专有许可证并且需要付费使用,而Node.js编译器是MIT许可证,用户可以自由使用和修改。

  • Nexe (https://github.com/nexe/nexe):Nexe由于使用browserify,不支持动态require,而Node.js编译器支持各种类型的require,包括require.resolve。

  • asar (https://github.com/electron/asar):Asar使用JSON存储文件信息,而Node.js编译器使用SquashFS。Asar将代码归档和可执行文件分开,而Node.js编译器将所有JavaScript源代码与Node.js虚拟机链接在一起,并生成单个可执行文件作为最终产品。

  • AppImage (http://appimage.org/):AppImage仅支持具有支持SquashFS的内核的Linux,而Node.js编译器支持Linux、macOS和Windows三个平台,同时不需要内核的任何特殊功能要求。


@StéphaneLaurent 请查看node-compiler,它绝对支持使用命令行参数与exe一起使用。 - Minqi Pan
最新提交于2017年8月30日(2年前)。已停用?! - Thach Lockevn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接