Migrating from Gatsby to custom Node.js script

Two years ago I created a small site to track what movies and shows I watch. I did it with Gatbsy because well, it was a new thing for me and I wanted to experiment with Jamstack.

The idea is to create a new Markdown file for each movie or tv episode watched. A TV show season has 10 episodes, then I have 10 files. Using GraphQL I would query the files and show those on the site. Neat!

Using GitHub Actions, of course, I would simply build the Gatbsy site and send it to GitHub Pages. No issues. Life was good.

The site never needed much update. It was working fine. Until I noticed it wasn't that fast, it was taking a while to build, around 2 minutes on GH Actions. The naive version of me thought: "oh; i'll try to upgrade the NPM dependencies see if the newer versions speed things up" 🤭

🤦‍♂️ Dependency hell

You might have experienced this. The pain of trying to upgrade an old build system, the deprecated packages, the incompatibilities of the old versions with the newer and more secure versions of Node and NPM.

It was painful. Nothing worked anymore. Gatsby would no longer compile of course. Upgrading to breaking change versions was bound to break stuff. I did try to fix but I eventually gave up.

I'm just fed up with this nonsense. Having dozens of packages in your package.json is a recipe for headache if you're not constantly upgrading it, checking the changelogs, etc. For work projects it's fine, but for a side project with 0 maintenance... no good.

🤔 What's the alternative?

Custom Node script with just 1 dependency. It feels good, I just feel clean! 🥰

That's right. The only thing I really needed for this site is a way to convert Markdown files into HTML. Well, there's just a package to do that. A single one, your package.json will never look better.

Have a look at markdown-it/markdown-it if you're interested.

const MarkdownIt = require('markdown-it');

const md = new MarkdownIt();

const result = md.render('# markdown-it rulezz!');Code language: JavaScript (javascript)

🤓 Yeah, yeah... but how?

Using what Node already gives you functions to read folders, to read files and to write files. What else do you need?

Sure, you won't have all the featues Gatbsy gives you out of the box, that's obvious. But I don't really needed them for this site anyway. This is a very boiled down version but has all the essentials:

  • Read a folder to get all the files in it.
  • Read each of the files inside a folder.
  • Process the Markdown into HTML.
  • Save a new HTML file with the processed content.
const movies = await fs.promises.readdir(`my/folder`);

movies.forEach((movie) => {
  const movieContent = fs.readFileSync(`source/folder/${movie}/index.md`, { encoding: 'utf8', flag: 'r' });

  const md = new MarkdownIt();
  const html = md.render(movieContent);
  fs.writeFileSync(`new-file-html`, html);
});Code language: JavaScript (javascript)

The final main.js is surely a little bit more complex but that's because I wanted to add the extra features. Have a look here.

Final thoughts

Running through close to 6.000 (thousand!) Markdown files and creating the new HTML takes on GitHub actions takes about 20 seconds 😮 The whole build is 45 seconds 🏎

Am I going to be in dependency hell in the future?

Very doubtful. There just 2 things I need to take care of, the main dependency and the Node.js version which has very long LTS versions. I should be fine for a couple of years.

I'm very happy with the result. Not only to learn more about file handling in Node.js but to speed things up. Taking less build time and resources is just a win-win for me, the data-center running the build, and the environment 💜



Leave a Reply

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