Transform Markdown into JavaScript with a Vite Plugin

  • javascript
  • markdown
  • plugin development
  • typescript
  • vite
Jul 27, 2024
Unlock the power of Vite plugins to seamlessly convert markdown files into dynamic JavaScript modules, enhancing your web development workflow.

Introduction

Imagine harnessing the simplicity of Markdown and the dynamism of JavaScript all within your Vite-powered projects. In this guide, we’ll embark on a journey to create a Vite plugin that transforms Markdown files into HTML strings, seamlessly integrating them into your JavaScript modules. Whether you’re a developer looking to streamline your workflow or a content creator aiming to blend prose with code, this tutorial has you covered.

If you’re new to plugin creation, don’t worry. Start with this Create Your Own Vite Plugin tutorial to build a solid foundation.

Install Dependencies

First things first: let’s equip our project with the tools we need. We’ll use marked to convert Markdown into HTML.

npm install marked

The transform Hook Unveiled

Vite’s plugin system is a playground for innovation. At the heart of our plugin lies the transform hook, a powerful feature borrowed from Rollup. This hook enables Vite to process files that aren’t pure JavaScript by compiling them into modules during the build phase. Think of it as a translator that turns Markdown into something your JavaScript can understand and utilize.

We’ll follow the Vite documentation example to craft our markdown plugin. Let’s name it markdown-html and integrate it into our vite.config.ts.

// vite.config.ts
import { parse } from "marked";
import { defineConfig } from "vite";

export default defineConfig({
    plugins: [
        {
            name: "markdown-html",
            async transform(code, id) {
                if (/\.md$/.test(id)) {
                    // Convert Markdown to HTML
                    const html = await parse(code);

                    return {
                        // Export the HTML and original Markdown as modules
                        code: `
                            export const html = ${JSON.stringify(html)};
                            export const md = ${JSON.stringify(code)};
                        `,
                        map: null,
                    };
                }
            },
        },
    ],
});

Typing with TypeScript

To make TypeScript aware of our new Markdown modules, we need to declare them properly. Add a declaration file within src/types/md.d.ts:

// src/types/md.d.ts
declare module "*.md" {
    export const html: string;
    export const md: string;
}

This tells TypeScript that whenever you import a .md file, it will have html and md string exports.

Testing the Plugin

Let’s put our plugin to the test. Create a sample Markdown file:

<!-- src/md/post.md -->

# Welcome to Vite

Harnessing the power of Markdown with seamless JavaScript integration.

- Easy to write
- Simple to convert
- Flexible to use

Now, import and utilize it in your main.ts:

// src/main.ts
import { html } from "./md/post.md";

document.body.insertAdjacentHTML("afterbegin", html);

Run your development server:

npm run dev

Navigate to your app, and you should see the rendered Markdown content on the page!

Build Time Magic

Remember, this transformation happens at build time. When you run npm run build, Vite processes your Markdown files, embedding the generated HTML directly into your bundled JavaScript. Inspecting the dist/assets/index...js file will reveal your inlined HTML, proving the plugin works its magic.

Conclusion

By leveraging Rollup’s transform hook within a Vite plugin, we’ve unlocked a seamless way to integrate Markdown into JavaScript modules. This approach not only enhances your development workflow but also opens doors to creative content presentation. Dive deeper into Vite’s plugin ecosystem and explore endless possibilities for your projects.

Thanks for joining this adventure!