(redirected from Homepage)

Strona domowa

Witam na mojej prywatnej stronie internetowej!

[If this is all Polish to you, click here: English]

Uwaga: z oczywistych powodów nie mogę zagwarantować swojej nieomylności, choć staram się o zgodność tego, co piszę, z Prawdą. Jest również oczywiste, że nie gwarantuję takiej zgodności w przypadku komentarzy. Umieszczenie linku do strony spoza niniejszego serwisu nie musi oznaczać, że podzielam poglądy autora tej strony, a jedynie, że uważam ją za wartościową z takich czy innych powodów.

Marcin ‘mbork’ Borkowski

2026-02-09 Node modules working as command-line scripts revisited

Over five years ago I wrote a short post about writing JavaScript scripts which also work as CJS modules. I wrote that I didn’t know how to perform a similar trick with ESM modules, and that it might even be impossible. Well, I was wrong. I found a solution in the book Shell scripting with Node.js by Axel Rauschmayer. He proposes the following solution in the chapter about file system paths and file URLs:

import {fileURLToPath} from 'node:url';

const modulePath = fileURLToPath(import.meta.url);
if (process.argv[1] === modulePath) {
    main();
}

(well actually, his solution is a bit more complex, but this is the gist of it – head to his book for more details).

I started using it and it worked great… until it didn’t. It turned out that I was able to trick this code by symlinking to my script and calling the symlink instead. After a bit of poking around, I arrived at this code:

import {fileURLToPath} from 'node:url';
import {realpath} from 'node:fs/promises';

const modulePath = await realpath(fileURLToPath(import.meta.url));
if (await realpath(process.argv[1]) === modulePath) {
        main();
}

Note that it uses top-level await, which Node.js has been supporting for some time now.

From now on, I can both call my ESM script directly (even as a symlink) or import it in other code (for example, unit tests).

That’s it for today, thanks for reading!

CategoryEnglish, CategoryBlog, CategoryJavaScript

Comments on this page

More...