Achive of Hiso of the Day runs on Node.js now
I haven't drawn any Hisos for very long. There is simply no justification of porting the backend PHP code to Node.js. Thus I set out porting.
First I read a tutorial on how to set up Node with MySQL and ran the code there. I didn't plan to learn knex, but it turned out to be profitable.
Timezone issue
Then I ported all the backend code that talked to MySQL to Node. All went well until I used the real database in test. There was a timezone issue. knex or Node produced Date object for date columns in the table. I used the date part and discarded the time part. Due to knex cleverly putting in a timezone, my dates were shifted by one day. One needs to make the connection to MySQL with timezone UTC. Googling showed that this could be resolved by putting in the property timezone: '+0:00'
in the knexfile.js
.
Express app
I set up some routing in express
and liked it more than my clumsy ?item=stuff
way during the PHP days. I didn't learn how to do in-app routing then and relied on nginx
. Thus I changed the way how the app received query strings.
Frontend
I was blown away by how ugly my frontend javascript looked with all of its unsuccessful abstractions. I set about simplifying the code. Then I updated jQuery to the latest version and removed the dead-looking jQuery-mobile. I was forced to write my own swipe detection code, but it turned out to be easy and I gained more control over using the black box of jQuery-mobile. I could have done away with jQuery as well, but I kept it in for the future???
Now that the grid
layout is supported by major browsers, I adopted it just as how I decided to use flex
when it was a fancy new thing. I think grid
is very nice to space items. Thus I changed a large portion of CSS files. I disliked tweaking CSS.
Handlebars
In addition to the ahotd
app page, I had the index and about pages. They shared a footer which up to this point had been manually pasted in once change was made. I looked into template engines for express
and settled on Handlebars because pug
would totally annihilate my work on the html. In addition my Ghost blog uses Handlebars and I have had some experiences with it from making my custom casper theme. 😎 Using a template engine would reveal more possibilities for my app. Someday I may want to send a page with certain values filled out server-side rather than making ajax request to fetch the value and update. The end result was that I had a footer partial that got inserted on every page and that I used Handlebars to insert values in the Atom feed.
Minification
I decided to minify my html/css/js. I used the HTML-minifier. Somehow it does not work on pure js files. It can minify html and pure css files. I set up gulp
tasks to minify my handlebars and css files with it. One can ask it to ignore {{...}}
in handlebars and <?...?>
in the XML file which is my feed. I set up uglify-es
separately to minify js files. uglify
does not work with ES6 syntax???
I also use gulp
to copy files around so that the end result is a nice build
directory without extraneous files and with everything minified.
Later I noticed that Chrome complained about the feed being an invalid XML file. The reason was that HTML-minifier removed closing slashes for singleton elements like <link/>
. I added the option to not removing closing slashes... The change was not reflected until I restarted the express app. I suspect that it was due to the cache of Handlebars. Did it consider my remote server production environment? I forgot to check if I had set proper environment variables.
Deployment
First I just copied the build
directory to remote server. I set up a systemd
service to run the express app. I didn't want to introduce more dependencies like pm2
etc. Then I put in a conf file for nginx
asking it to reverse-proxy the express app. Everything looked good. (Well, a lot of debugging went in.)
Then I set up a git
repository on the remote server. I would push the source and the post-receive
hook would install needed node modules, build the thing, copy the built thing to the web directory and run a knex migration to update database. This is the moment when I realised that knex was a nice addition. If anything happens I can rollback database change provided I properly provide the down
directory. Now this work flow is analogous to how Ghost updates itself.
Email function
There is a feedback form on my site, but apparently nobody has used it because nobody visits this site. It is just so easy to have emails landing into spam folders despite setting up spf and dkim. I just want to maintain a website! The next time I migrate to a new server, I will not try setting up an email server. How about anybody wanting to contact me join Discord?
Domain name
I haven't pointed the tujion domain name to this app yet...
BTW Cloudflare declared that it would be domain name registrar. I am not sure how this works. I probably shouldn't have paid GoDaddy for 5 years. However the moment I decided to pay I was so exacerbated that I just wanted the site to keep staying up for 5 years without any intervention from me.