Node.js v18.16.0 文档


目录

单个可执行应用程序#

稳定性: 1 - 实验: 此功能正在设计中并将更改。

源代码: lib/internal/main/single_executable_application.js

此功能允许将 Node.js 应用程序方便地分发到未安装 Node.js 的系统。

Node.js 通过允许将 JavaScript 文件注入 node 二进制文件来支持 单个可执行应用程序 的创建。 在启动过程中,程序会检查是否注入了任何东西。 如果找到脚本,它将执行其内容。 否则 Node.js 会像往常一样运行。

单个可执行应用程序功能仅支持运行单个嵌入式 CommonJS 文件。

可以使用任何可以将资源注入 node 二进制文件的工具将捆绑的 JavaScript 文件转换为单个可执行应用程序。

以下是使用此类工具 postject 创建单个可执行应用程序的步骤:

  1. 创建一个 JavaScript 文件:

    $ echo 'console.log(`Hello, ${process.argv[2]}!`);' > hello.js 
  2. 创建 node 可执行文件的副本并根据需要命名:

    $ cp $(command -v node) hello 
  3. 通过使用以下选项运行 postject,将 JavaScript 文件注入到复制的二进制文件中:

    • hello - 在步骤 2 中创建的 node 可执行文件副本的名称。
    • NODE_JS_CODE - 二进制文件中将存储 JavaScript 文件内容的资源/注释/部分的名称。
    • hello.js - 在步骤 1 中创建的 JavaScript 文件的名称。
    • --sentinel-fuse NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2 - Node.js 项目用来检测文件是否被注入的 fuse
    • --macho-segment-name NODE_JS(仅在 macOS 上需要)- 将存储 JavaScript 文件内容的二进制文件中的段的名称。

    总而言之,这是每个平台所需的命令:

    • 在 macOS 以外的系统上:

      $ npx postject hello NODE_JS_CODE hello.js \
          --sentinel-fuse NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2 
    • 在 macOS 上:

      $ npx postject hello NODE_JS_CODE hello.js \
          --sentinel-fuse NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2 \
          --macho-segment-name NODE_JS 
  4. 运行二进制文件:

    $ ./hello world
    Hello, world! 

注意事项#

注入模块中的 require(id) 不是基于文件的#

注入模块中的 require() 与未注入模块可用的 require() 不同。 除 require.main 外,它也不具有非注入 require() 所具有的任何属性。 它只能用于加载内置模块。 尝试加载只能在文件系统中找到的模块将引发错误。

用户可以将他们的应用程序捆绑到一个独立的 JavaScript 文件中以注入可执行文件,而不是依赖于基于 require() 的文件。 这也确保了更具确定性的依赖图。

但是,如果仍然需要基于 require() 的文件,也可以实现:

const { createRequire } = require('node:module');
require = createRequire(__filename); 

注入模块中的 __filenamemodule.filename#

注入模块中的 __filenamemodule.filename 的值等于 process.execPath

注入模块中的 __dirname#

注入模块中__dirname的值等于process.execPath的目录名。

单个可执行应用程序创建过程#

旨在创建单个可执行 Node.js 应用程序的工具必须将 JavaScript 文件的内容注入到:

  • 如果 node 二进制文件是 PE 文件,则名为 NODE_JS_CODE 的资源
  • 如果 node 二进制文件是 Mach-O 文件,则 NODE_JS 段中名为 NODE_JS_CODE 的部分
  • 如果 node 二进制文件是 ELF 文件,则名为 NODE_JS_CODE 的注释

在二进制文件中搜索 NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2:0 fuse 字符串并将最后一个字符翻转为 1 以指示已注入资源。

平台支持#

仅在以下平台上的 CI 上定期测试单一可执行支持:

  • Windows
  • 苹果系统
  • Linux(仅限 AMD64)

这是由于缺乏更好的工具来生成可用于在其他平台上测试此功能的单一可执行文件。

欢迎对其他资源注入工具/工作流程提出建议。 请在 https://github.com/nodejs/single-executable/discussions 开始讨论以帮助我们记录它们。