Replace node-static with serve-static for ESP32 Sawppy Development
One of the optional middleware modules maintained by the Expressjs team is express.static
, which can handle serving static assets like HTML, CSS, and images. It was used in code examples for Codecademy's Learn Express course, and I made a mental note to investigate further after class. I thought it might help me with a problem I already had on hand, and it did!
When I started writing code for a micro Sawppy rover running on an ESP32, I wanted to be able to iterate on client-side code without having to reflash an ESP32. So as an educational test run of Node.js, I wrote a JavaScript counterpart to the code I wrote (in C/C++) for running on ESP32. While they are two different codebases, I intended for the HTTP interface to be identical and indistinguishable by the HTML/CSS/JavaScript client code I wrote. Most of this server-side work was focused around websocket, but I also needed to serve some static files. I looked on nodejs.org and found "How to serve static files" in their knowledge base. That page gave an example using the node-static
module, which I copied for my project.
Things were fine for a while, but then I started getting messages from the Github Dependabot nagging me to fix a critical security flaw in my repository due to its use of a library called minimist
. It was an indirect dependency I picked up by using node-static
, so I figured it'll be fixed after I pick up an update to node-static
. But that update never came. As of this writing, the node-static
package on NPM hadn't been updated for four years. I see updates made on the GitHub repository, but for whatever reason NPM hasn't picked that up and thus its registry remains outdated.
The good news is that my code isn't deployed on an internet-facing server. This Node.js server is only for local development of my ESP32 Sawppy client-side browser code, which vastly minimizes the window of vulnerability. But still, I don't like running known vulnerable code, even if it is only accessible from my own computer and only while I'm working on ESP32 Sawppy code. I want to get this fixed somehow.
After I got nginx set up as a local web server, I thought maybe I could switch to using nginx to serve these static files too. But there's a hitch: a websocket connection starts as a HTTP request for an upgrade to websocket. So the HTTP server must interoperate with the websocket server for a smooth handover. It's possible to set this up with nginx, but the instructions to do so is above my current nginx skill level. To keep this simple I need to stay within Node.js.
Which brought me back to Express and its express.static
file server. I thought maybe I could fire up an Express app, use just this express.static
middleware, and almost nothing else of Express. It's overkill but it's not stupid if it works. I just had to figure out how it would handover to my websocket code. Reading Express documentation for express.static
, I saw it was built on top of a NPM module called serve-static
, and was delighted to learn it can be used independent of Express! Their README included an example: Serve files with vanilla node.js http server and this was exactly what I needed. By using the same Node.js http module, my websocket upgrade handover code will work in exactly the same way. At the end, switching from node-static
to serve-static
was nearly a direct replacement requiring minimal code edit. And after removing node-static
from my package.json, GitHub dependabot was happy and closed out my security issue. I will be free from nagging messages, at least until the next security concern. That might be serious if I had deployed to be internet accessible, but the odds of that just dropped.