This is the DOC Trailhead web application!
Interested in contributing? See the contributions guidelines.
To get started developing, run npm i
to install the dependencies.
Then, you can run the server with npm run dev
and visit it by navigating your browser to localhost:8080
.
Development commands:
npm i
- install dependenciesnpm t
- run tests (requires SQLite installation)npm run dev
- run in development modenpm start
- run in production mode (requires.env
file)npm run lint
- run the linternpm run format
- run the linter in--fix
mode (might alter the code)
Database commands
npm run set-admin
- if using the prebuilt database, this will log the user in as an adminnpm run set-leader
- if using the prebuilt database, this will log the user in as trip leader
Trailhead is a NodeJS application. It uses SQLite as a datastore, Express to define routes, Nunjucks to build HTML views, and HTMX to add interactivity to the webpage.
You can read more about SQLite in the appendix section below, but the main thing to know about it is that its datastore is a single file, not a separate process. That means the NodeJS application does all the database "stuff", not a separate application. This has two big implications for the application:
- It can be run and tested without any other install besides
npm run i
. This substantially improves development speed and simplicity. - Since database requests do not have to make a network hop, it basically removes the performance penalty for executing multiple small SQL queries (sometimes called the "n+1 problem"). This lets you write more intelligible SQL commands, mixed with a little bit of JS. In practice, I use a bunch of small queries and a few medium-sized ones.
This application does not really have a distinction between frontend and backend. The views are written in an HTML templating language called Nunjucks. When the user requests a webpage, the HTML that they receive is built by the templating language at runtime. The frontend as such is entirely stateless; whatever the user is "allowed" to do in the application is built into the HTML that is returned from each route.
If you want to be fancy, this is a concept called Hypertext As The Engine of Application State
(HATEOAS). If you don't want to be fancy, think of this way: the
route responds with some HTML that contains links or buttons relevant to the user that requested it.
If the user is allowed to see a trip to hike Cardigan, the HTML will have an
<a href=/trips/2>Cardigan Hike!</a>
element in it. If they're allowed to signup, it might have a
<button type=submit>Signup!</button>
element. In this way the stateless hypertext (HTML) is
defining what the user is allowed to do, and Nunjucks make it easy(ish) to mix and match bits of
HTML.
Trailhead is deployed on a DigitalOcean droplet and served behind an NGINX proxy. Trailhead is currently running on Node 22.
To upgrade it to the latest stable version (22 at the time of this writing, but it won't be forever) using the n module:
- Log in as a sudo-capable user and run
sudo n stable
- Log in as
node
- Check the new node version is the one you expect with
node --version
cd ~/doc-trailhead
and runnpm rebuild
(otherwise it will crash on startup)cd ~
andpm2 restart trailhead
I'll admit I've had a couple fits and starts testing Trailhead and never quite come up with a solution I liked. The problem isn't that Trailhead couldn't be tested with Playwright or the like; it's that I'd really like for the tests to be as easy to start and run as the application is. So far I haven't put together a suite that does that (while still testing something useful).
Here are some useful resources that might help you understand the tech stack better, if you're not familiar with parts of it:
- How To Set Up a Node.js Application for Production on Ubuntu 16.04 (this is basically the deployment setup)
- Consider SQLite
- How Did REST Come To Mean The Opposite Of Rest?