Building a Static Site Generator with Node.js and Jekyll

Static site generators have become increasingly popular in recent years, as they offer a more efficient way to build and deploy websites. By generating static HTML pages instead of relying on dynamic server-side processing, static site generators can be much faster and more secure than traditional CMS systems. In this article, we will explore how to build a static site generator using Node.js and Jekyll.

What is a Static Site Generator?

A static site generator is a tool that takes content written in various formats (such as Markdown or HTML) and generates a set of static HTML pages that can be served to visitors by a web server. Unlike dynamic websites, which require server-side processing for each page request, static sites can be served quickly and efficiently by simply serving the pre-built HTML files.

One popular static site generator is Jekyll, which is written in Ruby and has been used to build thousands of websites. However, if you prefer to work with Node.js, you can build your own static site generator that mimics Jekyll’s functionality.

Building a Static Site Generator with Node.js

To build our static site generator, we will need to use Node.js and a few other libraries. Here’s an overview of the tools we will be using:

  • Node.js: A JavaScript runtime that allows us to run JavaScript on the server.
  • Markdown: A lightweight markup language that we will use to write content.
  • Gray-Matter: A library that allows us to parse front matter (metadata) from our Markdown files.
  • EJS: A template language that we will use to create HTML templates.
  • File System: A Node.js module that provides file system-related functionality.
  1. Setting up the Project

The first step is to create a new Node.js project using npm. Open a terminal window and run the following command:

csharp
npm init -y

This will create a new package.json file in your project directory.

Next, we need to install the necessary dependencies. Run the following command to install the required libraries:

npm install markdown gray-matter ejs fs-extra

These libraries will allow us to parse Markdown files, extract metadata, render templates, and manipulate files in the file system.

  1. Parsing Markdown Files

Once we have set up our project, we can begin parsing our Markdown files. In this example, we will create a simple blog using Markdown files as our content source.

Create a new directory called src and create a new file called index.md inside it. Add the following content to the file:

yaml
---
title: My First Blog Post
date: 2023-03-27
---

# Welcome to my blog

This is my first blog post. Thanks for reading!

This file includes front matter (metadata) in YAML format, followed by the blog post content in Markdown format.

To parse this file and extract the metadata, we will use the gray-matter library. Create a new file called parseMarkdown.js and add the following code:

javascript
const fs = require('fs');
const matter = require('gray-matter');

function parseMarkdown(file) {
  const data = fs.readFileSync(file, 'utf8');
  const { data: frontMatter, content } = matter(data);
  return {
    ...frontMatter,
    content,
  };
}

module.exports = parseMarkdown;

This code reads the contents of a Markdown file and uses gray-matter to extract the front matter and content. It then returns an object that includes the front matter properties as well as the content.

  1. Rendering Templates

Now that we can parse our Markdown files, we need to create HTML templates to render our content. We will use the ejs template language to create our templates.

Create a new file called template.ejs in a new directory called templates. Add the following code to the file:

php
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title><%= title %></title>
  </head>
  <body>
    <h1><%= title %></h1>
    <p><%= date %></p>
    <div><%= content %></div>
  </body>
</html>

This template includes placeholders that will be replaced with the values extracted from the Markdown front matter. The <%= %> syntax is used to insert values into the HTML.

To render the template with our Markdown content, create a new file called renderTemplate.js and add the following code:

javascript
const fs = require('fs-extra');
const ejs = require('ejs');

async function renderTemplate(markdownData, templatePath) {
  const template = await fs.readFile(templatePath, 'utf8');
  const html = ejs.render(template, markdownData);
  return html;
}

module.exports = renderTemplate;

This code reads the contents of a template file and uses ejs to render the HTML with the Markdown content. It then returns the HTML as a string.

  1. Building the Site

With our Markdown parsing and template rendering functions in place, we can now build the static site. Create a new file called build.js and add the following code:

javascript
const fs = require('fs-extra');
const parseMarkdown = require('./parseMarkdown');
const renderTemplate = require('./renderTemplate');

async function build() {
  const templatePath = './templates/template.ejs';
  const outputDir = './dist';
  const files = await fs.readdir('./src');

  await fs.emptyDir(outputDir);

  for (const file of files) {
    if (file.endsWith('.md')) {
      const markdownData = parseMarkdown(`./src/${file}`);
      const html = await renderTemplate(markdownData, templatePath);
      const outputPath = `${outputDir}/${file.replace('.md', '.html')}`;
      await fs.outputFile(outputPath, html);
    }
  }

  console.log('Site built successfully!');
}

build();

This code reads all Markdown files in the src directory, parses them with parseMarkdown, and renders them with the renderTemplate function. The resulting HTML is then written to the dist directory with a .html extension.

To run the build script, open a terminal window and run the following command:

node build.js

This will build the static site and output the generated HTML files to the dist directory.

Conclusion

In this article, we have explored how to build a static site generator using Node.js and Jekyll. By using Node.js, we were able to create a custom static site generator that mimics Jekyll’s functionality. We parsed Markdown files, extracted metadata, rendered templates, and wrote the resulting HTML files to the file system. With this basic understanding of static site generators, you can further customize the generator to fit your specific needs and preferences.

0368826868