Why I made an Express template engine
I reached a development crisis with Lingomio because I couldn’t find a good way to host it.
Trying to host Lingomio (for free)
I want some kind of Netlify for Node.js; git push
as the deployment model. I’m aware that GitHub Actions and the like can be made to do this kind of bidding if you have a backend to push to. Also freeware such as Coolify is available but you need a VPS. I should add that I’m a cheapskate and as this thing is not going to wash its face for a few years if ever, I want the hosting to be free or nearly free 🙂 this rules out even a $5 DigitalOcean droplet.
I looked at:
- OVH “Power” hosting, which was a labs beta of theirs I discovered by accident. It was completely free to set up as many instances as you wanted! But it was stuck on Node < 14 and the deployments didn’t work so well. It was a thin layer on top of Phusion Passenger but tbh it looks like an innovation that someone had a few years ago that never got any traction. Shortly after I decided it wasn’t going to work, they announced the shutdown of the platform anyway, so that’s for the best, I suppose.
- Azure Web Apps. I get a decent free usage limit on Azure because of work. I know this platform pretty well but I’ve never tried deploying Node.js to it before and I was not having fun.
- Glitch. Those who know me or have read more than a few posts here will know that I love Glitch. They have been stuck on older Node.js versions for a while. They now have 16.x but I was struggling to get
express-nunjucks
to work under that environment. Glitch is free (with usage limits and sites that go to sleep), but I also get premium for free because I was nice to the community for a long time.
While I was working between these options, it occurred to me that Node 14/16 application hosting seems more plentiful than cutting edge. My must-have in JS is ESM support, and Node had that since 12.0.0, and since 14.0.0 it’s not marked “experimental”.
So I started cutting out the problematic express-nunjucks
. The funny thing is that pretty much the only feature I want from a template engine is insert {route}.htm into the <content /> area of layout.htm
. I couldn’t easily search up something that did that, and decided to make a templating engine for Express.
Getting ChatGPT to write me an Express template engine
I’d seen the express docs on developing a template engine and that looked pretty easy. But as this was a boilerplate-ish activity in an unfamiliar package, it seemed like a good time to try out ChatGPT for coding.
Our abridged conversation:
- SG: Hey, please make me an express template engine that will allow a master view to load child content in place of the static string
<content />
- GPT: Sure, here is your
simpleViewEngine.js
(in CommonJS style), yourapp.js
, amaster.simple
view and an overview of how it hangs together.
- GPT: Sure, here is your
- SG: I try it and realise I didn’t describe the requirements clearly enough
- SG: Ok, please rewrite it in ESM syntax and make this functional change: the
views/main.htm
should always be used as the base template, into which the imported content offilePath
should be inserted. For example, whenindex
is specified, thenindex.htm
should be inserted into the content slot ofmain.htm
.- GPT: Certainly! Here’s some code. (It does a good job)
- SG: Change the name of simpleViewEngine to
sste
for “Ste’s Simple Template Engine”. Rewrite it to useexport const
and arrow functions instead offunction
declarations and export default.- GPT: (Does it exactly right)
I went on to get it to describe caching patterns in popular template engines, and then chose one for it to implement for me.
For kicks, I also got it to rewrite it as a Fastify plugin in case I ever move to Fastify.
On the whole - very impressed. It was like working with a subservient mid level developer who works 700x faster than a real person. It was a good lesson in describing requirements clearly.
I haven’t published this as an npm package; I’m just consuming it as a local sste.js
file.
Putting sste into sg-login
sg-login is my personal “next-gen” project template for hacking together multi-user projects in Node.js.
Before I make any changes into the fundamentals of Lingomio, they will go through sg-login first, which is the prototype.
I replaced express-nunjucks with sste, and there’s the tasty git commit to prove it.
Then I realised I’d used quite a lot of other nunjucks features in the FormData kind of demos.
I needed a way to get Express model data into the frontend.
My first and only idea was to have a second placeholder variable which would be replaced at render time with the JSON of the data model.
A little bit of hacking later (this time I was on a train with no Wifi and did my own dirty work… no Gipity) and sste could replace the _STE_DATA
token with the JSON model.
This works as well as I could hope, and it isn’t tied to any specific JS framework.
Despite originally wanting sg-login to be vanilla JS only, I decided to throw petite-vue at it to replace what I was doing with nunjucks conditionals with v-if
. The petite vue setup is simply:
<script>
PetiteVue
.createApp({
data: _STE_DATA
})
.mount();
</script>
…and this gives me access to do stuff like:
<p v-if="data.user" class=" white f6 pl1">
Hi
</p>
…which I think is just fine.
Note that data
isn’t a standard required thing in petite-vue; I’m using it here to isolate backend data from vue members which are explicitly part of the frontend implementation. See my petite-vue post for more.
Check out sg-login
After this effort I could host sg-login on Glitch - hooray!
Two things that need to go into my setup guide:
- You have to set a
SESSION_SECRET
in.env
; - You have to run
npm run migrations
in terminal to do first time setup of the database.
You can view the fruits of this labour in source code and in an actual running instance of sg-login on Glitch 🎉
Also there’s a lightweight demo of sste itself at https://sg-sste.glitch.me/
Now I’m a little less blocked with development… hoping to put up a version of Lingomio in 2024 😂 we’ll see!