| src | ||
| tests | ||
| .c8rc.json | ||
| .dockerignore | ||
| .env.example | ||
| .eslintrc.json | ||
| .gitignore | ||
| Dockerfile | ||
| jsconfig.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
Todo App
A Todo app made in the style of TodoMVC
[[TOC]]
Description
I realised all the projects I have on Gitlab are test or learning projects, this means they are either unfinished or full of odd ideas. Which may not present my skills in a good light. This Todo is my A game, no crazy ideas, just web standards, well known patterns, and packages.
The main points of interest for this project are:
- Progressive enhancement, will still work without JS or CSS
- Content Negotiation, same endpoints can serve HTML or JSON
- HATEOAS using hal+json
Installation and running
Docker
- Clone this repository
- run
docker build -t todo - run
docker run -e REPOSITORY="file" -p 3000:3000 todo(see environment variables below to configure container)
Node
- Clone this repository
- run
npm ci - create a
.envfile as detailed below - run
npm run devornode ./src/index.js
Environment variables
See example .env.example.
| Variable | Values | Description |
|---|---|---|
| REPOSITORY | "file"/memory" ("memory") | Where should to todos be stored |
| PORT | number (3000) | Which port should the server use |
| COOKIE_SECRET | string ("secret") | Secret used to encrypt the cookies |
Usage
Visit the website, new todos can be added, set as completed, deleted, filtered, and updated.
Try also visiting the site with css disabled, and/or with javascript disabled the site will remain functional.
Currently the server creates a cookie with an ID, the server stores any todos created using this ID. If the user clears their cookies their todos will be inaccessible.
Leasons Learnt / Future Changes
JSX express view engine
I chose this because I like the JSX format, and was hoping it would provide type safety, however this was not the case.
I would re-do this without using an express view engine and instead call the
react renderToString/prerenderToNodeStream/renderToPipeableStream from
the routes instead. Maybe with some additional handling and caching around it.