613b5bafd9d4d924dbfc2df7d9bdc19e097f50cd92d067d822c06ee8aeb28dc2742842f346ed14410053a8ac0e8a375da468646ff232eead96353fde7a75ec 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * This feature allows the distribution of a Node.js application conveniently to a
  3. * system that does not have Node.js installed.
  4. *
  5. * Node.js supports the creation of [single executable applications](https://github.com/nodejs/single-executable) by allowing
  6. * the injection of a blob prepared by Node.js, which can contain a bundled script,
  7. * into the `node` binary. During start up, the program checks if anything has been
  8. * injected. If the blob is found, it executes the script in the blob. Otherwise
  9. * Node.js operates as it normally does.
  10. *
  11. * The single executable application feature currently only supports running a
  12. * single embedded script using the `CommonJS` module system.
  13. *
  14. * Users can create a single executable application from their bundled script
  15. * with the `node` binary itself and any tool which can inject resources into the
  16. * binary.
  17. *
  18. * Here are the steps for creating a single executable application using one such
  19. * tool, [postject](https://github.com/nodejs/postject):
  20. *
  21. * 1. Create a JavaScript file:
  22. * ```bash
  23. * echo 'console.log(`Hello, ${process.argv[2]}!`);' > hello.js
  24. * ```
  25. * 2. Create a configuration file building a blob that can be injected into the
  26. * single executable application (see `Generating single executable preparation blobs` for details):
  27. * ```bash
  28. * echo '{ "main": "hello.js", "output": "sea-prep.blob" }' > sea-config.json
  29. * ```
  30. * 3. Generate the blob to be injected:
  31. * ```bash
  32. * node --experimental-sea-config sea-config.json
  33. * ```
  34. * 4. Create a copy of the `node` executable and name it according to your needs:
  35. * * On systems other than Windows:
  36. * ```bash
  37. * cp $(command -v node) hello
  38. * ```
  39. * * On Windows:
  40. * ```text
  41. * node -e "require('fs').copyFileSync(process.execPath, 'hello.exe')"
  42. * ```
  43. * The `.exe` extension is necessary.
  44. * 5. Remove the signature of the binary (macOS and Windows only):
  45. * * On macOS:
  46. * ```bash
  47. * codesign --remove-signature hello
  48. * ```
  49. * * On Windows (optional):
  50. * [signtool](https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool) can be used from the installed [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/).
  51. * If this step is
  52. * skipped, ignore any signature-related warning from postject.
  53. * ```powershell
  54. * signtool remove /s hello.exe
  55. * ```
  56. * 6. Inject the blob into the copied binary by running `postject` with
  57. * the following options:
  58. * * `hello` / `hello.exe` \- The name of the copy of the `node` executable
  59. * created in step 4.
  60. * * `NODE_SEA_BLOB` \- The name of the resource / note / section in the binary
  61. * where the contents of the blob will be stored.
  62. * * `sea-prep.blob` \- The name of the blob created in step 1.
  63. * * `--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2` \- The [fuse](https://www.electronjs.org/docs/latest/tutorial/fuses) used by the Node.js project to detect if a file has been
  64. * injected.
  65. * * `--macho-segment-name NODE_SEA` (only needed on macOS) - The name of the
  66. * segment in the binary where the contents of the blob will be
  67. * stored.
  68. * To summarize, here is the required command for each platform:
  69. * * On Linux:
  70. * ```bash
  71. * npx postject hello NODE_SEA_BLOB sea-prep.blob \
  72. * --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
  73. * ```
  74. * * On Windows - PowerShell:
  75. * ```powershell
  76. * npx postject hello.exe NODE_SEA_BLOB sea-prep.blob `
  77. * --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
  78. * ```
  79. * * On Windows - Command Prompt:
  80. * ```text
  81. * npx postject hello.exe NODE_SEA_BLOB sea-prep.blob ^
  82. * --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
  83. * ```
  84. * * On macOS:
  85. * ```bash
  86. * npx postject hello NODE_SEA_BLOB sea-prep.blob \
  87. * --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 \
  88. * --macho-segment-name NODE_SEA
  89. * ```
  90. * 7. Sign the binary (macOS and Windows only):
  91. * * On macOS:
  92. * ```bash
  93. * codesign --sign - hello
  94. * ```
  95. * * On Windows (optional):
  96. * A certificate needs to be present for this to work. However, the unsigned
  97. * binary would still be runnable.
  98. * ```powershell
  99. * signtool sign /fd SHA256 hello.exe
  100. * ```
  101. * 8. Run the binary:
  102. * * On systems other than Windows
  103. * ```console
  104. * $ ./hello world
  105. * Hello, world!
  106. * ```
  107. * * On Windows
  108. * ```console
  109. * $ .\hello.exe world
  110. * Hello, world!
  111. * ```
  112. * @since v19.7.0, v18.16.0
  113. * @experimental
  114. * @see [source](https://github.com/nodejs/node/blob/v24.x/src/node_sea.cc)
  115. */
  116. declare module "node:sea" {
  117. type AssetKey = string;
  118. /**
  119. * @since v20.12.0
  120. * @return Whether this script is running inside a single-executable application.
  121. */
  122. function isSea(): boolean;
  123. /**
  124. * This method can be used to retrieve the assets configured to be bundled into the
  125. * single-executable application at build time.
  126. * An error is thrown when no matching asset can be found.
  127. * @since v20.12.0
  128. */
  129. function getAsset(key: AssetKey): ArrayBuffer;
  130. function getAsset(key: AssetKey, encoding: string): string;
  131. /**
  132. * Similar to `sea.getAsset()`, but returns the result in a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
  133. * An error is thrown when no matching asset can be found.
  134. * @since v20.12.0
  135. */
  136. function getAssetAsBlob(key: AssetKey, options?: {
  137. type: string;
  138. }): Blob;
  139. /**
  140. * This method can be used to retrieve the assets configured to be bundled into the
  141. * single-executable application at build time.
  142. * An error is thrown when no matching asset can be found.
  143. *
  144. * Unlike `sea.getRawAsset()` or `sea.getAssetAsBlob()`, this method does not
  145. * return a copy. Instead, it returns the raw asset bundled inside the executable.
  146. *
  147. * For now, users should avoid writing to the returned array buffer. If the
  148. * injected section is not marked as writable or not aligned properly,
  149. * writes to the returned array buffer is likely to result in a crash.
  150. * @since v20.12.0
  151. */
  152. function getRawAsset(key: AssetKey): ArrayBuffer;
  153. }