Monday, July 22, 2024
HomeJavaScriptThe way to create a module-based Node.js executable

The way to create a module-based Node.js executable

Lots of my tasks embrace Node.js scripts to carry out setup or teardown steps. And whereas I might run all of them with the node binary (node create-thumbnails.js), I favor to take away the file extension and make the scripts executables (./create-thumbnails). This strategy saves characters, and makes me really feel like a hacker!

My steps to create an executable are:

  • Take away the .js file extension (mv create-thumbnails.js create-thumbnails).
  • Make the file executable (chmod 744 create-thumbnails).
  • Add a shebang (#!/usr/bin/env node) to sign that the executing shell ought to use the node binary.

Et voilà, you simply created a Node.js executable!

This strategy has served me nicely for CommonJS-based scripts utilizing the require operate. But it surely’s 2022, and I deliberate to undertake ECMAScript modules in Node.js executables. Sadly, it isn’t that straightforward.

However what’s the issue?

The Node.js binary is lacking a flag to specify module recordsdata

There are 3 ways to allow ECMAScript modules in Node.js:

  1. use the .mjs file extension
  2. have a surrounding package deal.json with a "kind": "module" subject
  3. name node with the --input-type=module flag

My executables ought to work and not using a file extension, which guidelines out the primary possibility. I additionally do not need to declare all recordsdata as module recordsdata or add a package deal.json, so the kind subject is out, too.

The --input-type flag seems to be promising at first, but it surely solely works for strings you pipe into the Node binary your self.

echo "import { mkdir } from 'node:fs/guarantees';" | node --input-type=module

Why’s there no flag to allow modules when operating a file?

I spent the final quarter-hour studying Node.js points and discussions concerning the matter, and I nonetheless cannot reply this query. If you wish to learn extra, this is a really lengthy GitHub dialogue on why such a flag is not out there but.

Knock your self out, the dialogue takes many turns, and people have sturdy opinions!

A “hacky” resolution to run module-based JavaScript executables

There are a number of methods to make ECMAScript module-based executables work. All of them include barely completely different spins however use the identical trick.

Axel recommends the next for UNIX environments.


import * as os from 'node:os';

const {username} = os.userInfo();
console.log(`Hey ${username}!`);

This snippet is wild! In brief, it does the next:

  • the cat command reads the present file (the executable itself)
  • the file content material is then piped into node with the --input-type flag
  • all the unique parameters are handed over to node, too ($@)
  • the node name’s exit code is caught and propagated to the executable

This instruction makes the file learn and pipe itself into the node binary as a result of there is no flag to allow modules. Wow! 🤯

As mentioned, this publish is just for my reference. Listed here are extra sources if you wish to study extra about different approaches or make it work on Home windows.



Please enter your comment!
Please enter your name here

Most Popular

Recent Comments