Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?

Compile a single executable from your Node app with Node.js 20 and ESBuild

Node.js 20 was launched very lately. Together with a number of different options, now you can compile your Node.js challenge right into a single executable that may be run in environments with out Node.js put in. It’s vital to notice that that is nonetheless experimental and might not be appropriate to be used in manufacturing.

Node.js has directions on methods to arrange these single executables: https://nodejs.org/api/single-executable-applications.html

Sadly, when compiling the executable, you’ll not compile dependencies into your executable. To unravel this downside, we are going to leverage a JavaScript bundler to bundle our dependencies into one file earlier than compiling it into our single executable.

Conditions:

Please be aware: Whereas TypeScript is used on this article, it isn’t mandatory.

First, we want a challenge that we’ll construct into our executable.

We’ll first outline our server.

server.ts

import specific from "specific";
import https from "https";
import fs from "fs";
import path from "path";

export const app = specific();

//Initialize Request Information Kind
app.use(specific.json({ restrict: "10mb" }));

app.get("/", (req, res) => res.ship("Howdy World!!"));

const port = 3000;
app.hear(port, () => {
    console.log(`Server is reside on ${port}`);
});

Enter fullscreen mode

Exit fullscreen mode

We outline our bundle.json subsequent:

bundle.json

{
  "identify": "node-executable-example",
  "model": "1.0.0",
  "description": "",
  "essential": "index.js",
  "scripts": {
    "construct": "esbuild server.ts --bundle --platform=node --outfile=server-out.js",
    "take a look at": "echo "Error: no take a look at specified" && exit 1"
  },
  "creator": "",
  "license": "ISC",
  "dependencies": {
    "esbuild": "0.17.17",
    "specific": "^4.18.2"
  },
  "devDependencies": {
    "@sorts/specific": "^4.17.17",
    "@sorts/node": "^18.15.7",
    "typescript": "^5.0.2"
  }
}
Enter fullscreen mode

Exit fullscreen mode

Please be aware the construct script. Esbuild will take our .ts file and bundle it with our dependencies right into a single .js file server-out.js. You possibly can truly run this file as soon as it’s created utilizing node server-out.js to verify if the bundling was completed accurately.

We then outline our tsconfig.json

tsconfig.json

{
  "compilerOptions": {
    "goal": "es2022",
    "lib": ["es2022"],
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}
Enter fullscreen mode

Exit fullscreen mode

We now outline our sea-config.json file.

It is a configuration file constructing a blob that may be injected into the one executable utility (see Producing single executable preparation blobs for particulars)

sea-config.json

{
  "essential": "server-out.js",
  "output": "sea-prep.blob"
}
Enter fullscreen mode

Exit fullscreen mode

Now that we’ve every part we want, we will start placing collectively our single executable.

Start by putting in all of the dependencies we’ll want by operating this command:

npm set up
Enter fullscreen mode

Exit fullscreen mode

As soon as npm set up is accomplished, we run the command:

npm run construct
Enter fullscreen mode

Exit fullscreen mode

This may create our server-out.js which shall be our bundled file we are going to make into an executable.

Observe: Should you somewhat, you’ll be able to observe the directions from the Node.js information ranging from step 3 as the next steps shall be precisely the identical, positioned right here: https://nodejs.org/api/single-executable-applications.html

Generate the blob to be injected:

node --experimental-sea-config sea-config.json 
Enter fullscreen mode

Exit fullscreen mode

Create a replica of the node executable and identify it in response to your wants:

cp $(command -v node) server
Enter fullscreen mode

Exit fullscreen mode

Observe: If you’re on a Linux Distro (similar to Ubuntu), you’ll be able to skip the following steps and transfer straight to operating the binary.

Take away the signature of the binary:

On macOS:

codesign --remove-signature server
Enter fullscreen mode

Exit fullscreen mode

On Home windows (optionally available):
signtool can be utilized from the put in Home windows SDK. If this step is skipped, ignore any signature-related warning from postject.

signtool take away /s server
Enter fullscreen mode

Exit fullscreen mode

Inject the blob into the copied binary by operating postject with the next choices:

  • server – The identify of the copy of the node executable created in step 2.
  • NODE_SEA_BLOB – The identify of the useful resource / be aware / part within the binary the place the contents of the blob shall be saved.
    sea-prep.blob – The identify of the blob created in step 1.
  • --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 – The fuse utilized by the Node.js challenge to detect if a file has been injected.
  • --macho-segment-name NODE_SEA (solely wanted on macOS) – The identify of the phase within the binary the place the contents of the blob shall be saved.

To summarize, right here is the required command for every platform:

On programs aside from macOS:

npx postject server NODE_SEA_BLOB sea-prep.blob 
    --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 
Enter fullscreen mode

Exit fullscreen mode

On macOS:

npx postject server NODE_SEA_BLOB sea-prep.blob 
    --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 
    --macho-segment-name NODE_SEA 
Enter fullscreen mode

Exit fullscreen mode

Signal the binary:

On macOS:

codesign --sign - server 
Enter fullscreen mode

Exit fullscreen mode

On Home windows (optionally available):
A certificates must be current for this to work. Nonetheless, the unsigned binary would nonetheless be runnable.

signtool signal /fd SHA256 server 
Enter fullscreen mode

Exit fullscreen mode

Run the binary:

./server
Enter fullscreen mode

Exit fullscreen mode

It’s best to now have a operating Node server related in the event you simply ran node server-out.js

Should you wished to see a accomplished instance, go right here: https://github.com/chadstewart/ts-node-executable-article-example

  • Should you discovered this text attention-grabbing, please be at liberty to coronary heart this text!
  • Should you’re interested by studying extra about Entrance-Finish Engineering, observe me right here on style-tricks.com and Twitter
  • Should you’re on the lookout for jobs, I’d extremely advocate testing @TechIsHiring on Twitter, LinkedIn or TechIsHiring’s web site https://www.TechIsHiring.com/ for posted jobs and different sources!
  • Need to take a look at a curated listing of jobs, job seekers and sources from TechIsHiring? Try TechIsHiring’s Newsletter



Add a Comment

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?