@@ -10,15 +10,17 @@ This feature allows the distribution of a Node.js application conveniently to a
1010system that does not have Node.js installed.
1111
1212Node.js supports the creation of [ single executable applications] [ ] by allowing
13- the injection of a JavaScript file into the ` node ` binary. During start up, the
14- program checks if anything has been injected. If the script is found, it
15- executes its contents. Otherwise Node.js operates as it normally does.
13+ the injection of a blob prepared by Node.js, which can contain a bundled script,
14+ into the ` node ` binary. During start up, the program checks if anything has been
15+ injected. If the blob is found, it executes the script in the blob. Otherwise
16+ Node.js operates as it normally does.
1617
17- The single executable application feature only supports running a single
18- embedded [ CommonJS] [ ] file .
18+ The single executable application feature currently only supports running a
19+ single embedded script using the [ CommonJS] [ ] module system .
1920
20- A bundled JavaScript file can be turned into a single executable application
21- with any tool which can inject resources into the ` node ` binary.
21+ Users can create a single executable application from their bundled script
22+ with the ` node ` binary itself and any tool which can inject resources into the
23+ binary.
2224
2325Here are the steps for creating a single executable application using one such
2426tool, [ postject] [ ] :
@@ -28,12 +30,23 @@ tool, [postject][]:
2830 $ echo 'console.log(`Hello, ${process.argv[2]}!`);' > hello.js
2931 ```
3032
31- 2 . Create a copy of the ` node ` executable and name it according to your needs:
33+ 2 . Create a configuration file building a blob that can be injected into the
34+ single executable application:
35+ ``` console
36+ $ echo '{ "main": "hello.js", "output": "sea-prep.blob" }' > sea-config.json
37+ ```
38+
39+ 3 . Generate the blob to be injected:
40+ ``` console
41+ $ node --experimental-sea-config sea-config.json
42+ ```
43+
44+ 4 . Create a copy of the ` node ` executable and name it according to your needs:
3245 ``` console
3346 $ cp $(command -v node) hello
3447 ```
3548
36- 3 . Remove the signature of the binary:
49+ 5 . Remove the signature of the binary:
3750
3851 * On macOS:
3952
@@ -50,35 +63,35 @@ tool, [postject][]:
5063 $ signtool remove /s hello
5164 ```
5265
53- 4 . Inject the JavaScript file into the copied binary by running ` postject ` with
66+ 6 . Inject the blob into the copied binary by running ` postject ` with
5467 the following options:
5568
5669 * ` hello ` - The name of the copy of the ` node ` executable created in step 2.
57- * ` NODE_JS_CODE ` - The name of the resource / note / section in the binary
58- where the contents of the JavaScript file will be stored.
59- * ` hello.js ` - The name of the JavaScript file created in step 1.
60- * ` --sentinel-fuse NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2 ` - The
70+ * ` NODE_SEA_BLOB ` - The name of the resource / note / section in the binary
71+ where the contents of the blob will be stored.
72+ * ` hello.js ` - The name of the blob created in step 1.
73+ * ` --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 ` - The
6174 [ fuse] [ ] used by the Node.js project to detect if a file has been injected.
62- * ` --macho-segment-name NODE_JS ` (only needed on macOS) - The name of the
63- segment in the binary where the contents of the JavaScript file will be
75+ * ` --macho-segment-name NODE_SEA ` (only needed on macOS) - The name of the
76+ segment in the binary where the contents of the blob will be
6477 stored.
6578
6679 To summarize, here is the required command for each platform:
6780
6881 * On systems other than macOS:
6982 ``` console
70- $ npx postject hello NODE_JS_CODE hello.js \
71- --sentinel-fuse NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2
83+ $ npx postject hello NODE_SEA_BLOB hello.js \
84+ --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
7285 ```
7386
7487 * On macOS:
7588 ```console
76- $ npx postject hello NODE_JS_CODE hello.js \
77- --sentinel-fuse NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2 \
78- --macho-segment-name NODE_JS
89+ $ npx postject hello NODE_SEA_BLOB hello.js \
90+ --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 \
91+ --macho-segment-name NODE_SEA
7992 ```
8093
81- 5 . Sign the binary:
94+ 7 . Sign the binary:
8295
8396 * On macOS:
8497
@@ -95,12 +108,33 @@ tool, [postject][]:
95108 $ signtool sign /fd SHA256 hello
96109 ```
97110
98- 6 . Run the binary:
111+ 8 . Run the binary:
99112 ``` console
100113 $ ./hello world
101114 Hello, world!
102115 ```
103116
117+ ## Generating single executable preparation blobs
118+
119+ Single executable preparation blobs that are injected into the application can
120+ be generated using the ` --experimental-sea-config ` flag of the Node.js binary
121+ that will be used to build the single executable. It takes a path to a
122+ configuration file in JSON format. If the path passed to it isn't absolute,
123+ Node.js will use the path relative to the current working directory.
124+
125+ The configuration currently reads the following top-level fields:
126+
127+ ``` json
128+ {
129+ "main" : " /path/to/bundled/script.js" ,
130+ "output" : " /path/to/write/the/generated/blob.blob"
131+ }
132+ ```
133+
134+ If the paths are not absolute, Node.js will use the path relative to the
135+ current working directory. The version of the Node.js binary used to produce
136+ the blob must be the same as the one to which the blob will be injected.
137+
104138## Notes
105139
106140### ` require(id) ` in the injected module is not file based
@@ -135,15 +169,16 @@ of [`process.execPath`][].
135169### Single executable application creation process
136170
137171A tool aiming to create a single executable Node.js application must
138- inject the contents of a JavaScript file into:
172+ inject the contents of the blob prepared with ` --experimental-sea-config" `
173+ into:
139174
140- * a resource named ` NODE_JS_CODE ` if the ` node ` binary is a [ PE] [ ] file
141- * a section named ` NODE_JS_CODE ` in the ` NODE_JS ` segment if the ` node ` binary
175+ * a resource named ` NODE_SEA_BLOB ` if the ` node ` binary is a [ PE] [ ] file
176+ * a section named ` NODE_SEA_BLOB ` in the ` NODE_SEA ` segment if the ` node ` binary
142177 is a [ Mach-O] [ ] file
143- * a note named ` NODE_JS_CODE ` if the ` node ` binary is an [ ELF] [ ] file
178+ * a note named ` NODE_SEA_BLOB ` if the ` node ` binary is an [ ELF] [ ] file
144179
145180Search the binary for the
146- ` NODE_JS_FUSE_fce680ab2cc467b6e072b8b5df1996b2 :0` [ fuse] [ ] string and flip the
181+ ` NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 :0` [ fuse] [ ] string and flip the
147182last character to ` 1 ` to indicate that a resource has been injected.
148183
149184### Platform support
0 commit comments