Sliced Backend
At this point index.js contains everything: the LiteNode instance, the marked config, and both routes. That's fine for a small demo. It becomes a problem when you have ten routes and several shared utilities.
The fix is straightforward: move each responsibility into its own file and import it where needed.
Extract the Marked setup
Move the marked configuration into functions/markedParseAndHighlight.js (you may have already done this in the previous section). Export the configured instance:
// functions/markedParseAndHighlight.js
export const markedParseAndHighlight = new Marked(/* ... */)
Create an initialize module
Create functions/initialize.js to hold the shared app and marked instances:
import { LiteNode } from "litenode"
import { markedParseAndHighlight } from "./markedParseAndHighlight.js"
const app = new LiteNode()
const marked = markedParseAndHighlight
export { app, marked }
Every route file will import from here instead of creating its own instance.
Extract routes
Create a routes/ directory and add one file per route.
routes/entryRoute.js
import { app, marked } from "../functions/initialize.js"
export const entryRoute = () => {
app.get("/", (req, res) => {
const parsed = app.parseMarkdownFile("index.md")
const html_content = marked.parse(parsed.content)
const { title, description } = parsed.frontmatter
res.render("layouts/index.html", {
title,
description,
html_content,
entryRoute: true,
})
})
}
routes/tutorialRoute.js
import { app, marked } from "../functions/initialize.js"
export const tutorialRoute = () => {
app.get("/tutorial/:href", async (req, res) => {
const pages = await app.parseMarkdownFileS("markdown")
const current = pages.find((file) => file.frontmatter.href === req.params.href)
if (!current) return res.redirect("/404", 302)
const { title, description } = current.frontmatter
const html_content = marked.parse(current.content)
res.render("layouts/index.html", {
title,
description,
html_content,
tutorialRoute: true,
})
})
}
Slim down index.js
index.js becomes a thin entry point that wires things together:
import { app } from "./functions/initialize.js"
import { entryRoute } from "./routes/entryRoute.js"
import { tutorialRoute } from "./routes/tutorialRoute.js"
app.notFound((req, res) => {
res.status(404).render("layouts/index.html", {
title: "Page Not Found",
description: "The server cannot find the requested resource.",
notFoundRoute: true,
})
})
entryRoute()
tutorialRoute()
app.startServer()
The resulting structure
litenode-markdown-app/
├── index.js
├── functions/
│ ├── initialize.js
│ └── markedParseAndHighlight.js
├── routes/
│ ├── entryRoute.js
│ └── tutorialRoute.js
└── views/
├── index.md
├── layouts/
│ └── index.html
├── components/
└── markdown/
Restart the server and verify everything still works. The behavior hasn't changed — only the organization has.
When you need a new route, add one file to routes/. When you need a new utility, add one file to functions/. index.js stays short and readable no matter how large the app grows.
