Hacker News new | ask | show | jobs
by rawnlq 3149 days ago
Rather than changing express's syntax, I would much rather have a better express boilerplate generator with an opinionated stack with good documentation/justification.

I recently started learning express/node and wasted weeks googling for blog posts for each dependency to figure out how to configure them. I guess this is somewhat valuable for end-to-end understanding but not for productivity.

There are a bunch dependencies I am now kind of decided on (not for technical reasons, but because they are clear popularity contest winners) and figured out how use:

    body-parser
    compression
    serve-favicon
    express-session
    csurf
    helmet
    cors
    dotenv
    moment
    selfsigned
    chalk
    debug
But still a bunch that I haven't gotten to googling and still need to decide on what to choose:

    logging (morgan vs winston)
    validation (express-validator, joi)
    auth (passport jwt, local, social)
    session storage (redis vs keeping it in database?)
    database (mongo/mongoose vs pg/knex/bookshelf/sequelize, graphql)
    storage (s3 vs gcs)
    ajax requests (request vs axios)
    mail (mailgun, sendgrid, mailchimp)
    error handlers
    rate limiting
    geo ip
I would be so happy if someone took away my power to choose and just forced me to use something that will "just work".
18 comments

Totally a tangent but, don’t use moment.js! It inherits some of the parsing and other quirks from the awfulness that is the JS Date object, the mutability almost certainly will lead to being bit by a couple of bugs before you actually internalize it, and the time zone support is kind of tacked on as an afterthought.

I highly recommend js-joda, particularly if you’ll ever be computing/showing things to your users in different time zones. It actually treats dates and times rigorously, and has an api that makes it clear what kinds of operations make sense to do on a zoned vs local datetime and makes things like converting between timezones vs transposing them explicit and simple.

I haven't tried it, but https://date-fns.org/ looks nice. For example, immutable API and just uses native Date objects.
Yeah it looks nicely simple & modular, but it probably works best in Node.js since your servers can all be in UTC.

In general I see the appeal of using a small shim around a standard library thing rather than re-implementing something totally new, but JS Date is bad enough that you're better off staying away altogether. It's just hard to use correctly since there's no "timezone unaware" object available and it always assumes the local timezone, so users' browsers in different timezones treat them differently. Lots of seemingly simple things (e.g. a time + timezone input picker) are easy to mess up because you end up accidentally implicitly converting things to the local time.

I've always been of the opinion that timestamps should be stored UTC datetime or unix timestamp on the server side and then displayed to the proper locale by the client's device. Is this not a good method?
It is not good enough. All the major browsers that I tried do not properly handle the timezone offset, as I discovered a few days ago (I put a more complete answer about this in a stackoverflow answer, but I don't know if putting the link would count as self-promotion so I will leave it out)

In short, the ES5 specs [1] say that

    The implementation of ECMAScript should not try to determine whether the 
    exact time was subject to daylight saving time, but just whether daylight 
    saving time would have been in effect if the current daylight saving time 
    algorithm had been used at the time. This avoids complications such as 
    taking into account the years that the locale observed daylight saving time year round.
This means that if your country handled daylight saving differently in the past, converting the timestamp to string may give you a wrong answer (this would be the case of a number of european countries during WWII).

The spec has been improved starting with ES6 [2], but to my knowledge no browser has fixed the issue:

    An implementation dependent algorithm using best available information on 
    time zones to determine the local daylight saving time adjustment 
    DaylightSavingTA(t), measured in milliseconds. An implementation of 
    ECMAScript is expected to make its best effort to determine the local 
    daylight saving time adjustment.

    NOTE It is recommended that implementations use the 
    time zone information of the IANA Time Zone Database 
    http://www.iana.org/time-zones/.
A solution is to use a JS library that has its own timezone database.

[1] http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.8 [2] http://www.ecma-international.org/ecma-262/6.0/#sec-daylight...

It's good enough (and correct) to store unix timestamps. For displaying the date - your comment applies...

Unix timestamp refers unambiguously to single point in time. Interpretation of this point in time in different timezones is complicated but it's outside of it.

I agree that storing unix timestamps is a good approach.

My issue was with "then displayed to the proper locale by the client's device." I mean, by itself it is ok, but in the case of a web client one cannot unfortunately just use the Date object and convert the timestamp to a human readable string.

There are some cases where you not only care about the exact time (unix timestamps are fine for this) but also the timezone in which it was specified. I work on an app where users specify "people in california should see this at 3pm PDT" and get confused when they reload the page and it has been switched to "6pm EDT".

As an aside, moment-timezone it a godsend for dealing with timezone discrepancies. I would pay money for it.

Thank you for this comment. I've been suffering for JS Date quirks for a long time, and haven't found a solution that alleviates the issues I've been having. Looks like js-joda is exactly what I need.

Link for the lazy: https://github.com/js-joda/js-joda

For some reason reading the API docs of js-joda gives me flashbacks to Java programming. Maybe it's all the "public static" stuff. Maybe it's that I can't immediately see how to do something useful. Some examples would be nice.
I'm guessing the name is a reference to Joda-Time which is a DateTime library for Java.

Maybe you'd seen the name somewhere and your subconscious had reminded you, haha

Yeah probably that too
Fecha is antother light alternative

https://github.com/taylorhakes/fecha

    rate-limiting -> nginx || iptables
Never ask PHP/Node/Ruby/Python to do low-level network routing. Your throwing megabytes of memory at a simple connection decision. If you need advanced logic for rate-limiting (not just access counting) then using nginx + memcached/redis as the marker. Have your app mark the ip in memcached/redis so nginx knows not to bother Node/PHP/Ruby/Python next time.
What you propose is only a performance optimization at the expense of operational complexity. Like caching.

"Never" doesn't make sense.

I guess you could simply rate-limit your login/signup if your not worried about a DoS and just want to keep people from brute-forcing a password.

On the other hand, it's not simply "a performance optimization" as there is no way for node to handle a DDoS without crazy amounts of hardware relative to what iptables|nginx can handle.

You're the one talking about DoS.

Notice how "rate-limiting" is a much more generic concept.

For example, Hacker News rate-limits the amount of posts you can make in a window of time. That's not because they think you're trying to DoS them.

This is optimization, might as well go all out and call it caching. "never" won't even apply.
Couldn't agree with you more. Have been involved in a few projects this year where a bunch of freelancers who had never worked together were thrown together to get something up and running quickly. The results were slightly horrifying precisely because everyone had their own tooling and way of doing things. Opinionated boilerplate would have solved so many problems for us upfront.
> I would be so happy if someone took away my power to choose and just forced me to use something that will "just work".

You are looking for django/ruby on rails.

No, he and others used to more complete (for lack of a better term) frameworks are looking for the Django/Rails equivalent in Node.js. I got my first taste of Node.js development a few months ago (https://engineering.edx.org/serverless-984cee7797e1) and found it confusing that so much of what I take for granted in Django is kinda all over the place in Node.js. The one that stood out to me was internationalization (i18n). In Django, I mark my strings, run a couple commands to extract/compile translations, and I'm pretty much done. The most popular options for Node.js involved writing a crawler for my site. It makes no sense me that folks are writing crawlers when the static text is on the disk, marked up, waiting to be parsed.

The diversity of the Node.js ecosystem is great because there is clear change and innovation. It's bad, however, because some of that innovation is simply taking things done by other frameworks and poorly implementing them in libraries or other frameworks. The lack of general consensus potentially hurts adoption by those of us who work with Django/Rails and perpetuates the myth of the JS world changing every hour/day/week.

I think you're guilty of the trope that everything should be ported to Node/Javascript.

More likely is that the people who want the features of Django/Rails just use Django/Rails, so there's no goldrush to recreate them in Node nor a monolithic community around the attempts so far.

The Node ecosystem is like the Clojure ecosystem: all-inclusive frameworks just aren't as popular as library composition.

It could just as easily be said that you are guilty of assuming all Node developers want a million tiny modules and all of the decision making overhead that goes with it.

Express is a nice small framework and is good for some things. Sometimes though you really want a monolith. If you are a Node developer there isn’t a clear choice for this.

I actually enjoy Sails, but I can see some decisions they’ve made that probably aren’t attractive to new developers (such as still using Grunt by default).

Waterline is nice as an ORM on the surface, but you run into walls as your queries become significantly complex.

Nope. I want well-defined best practices that make it easy for me to focus on the real engineering challenges rather than boilerplate. The issue I have is that there are numerous, sometimes conflicting, methods of solving the same problems that, in the Django/Rails worlds have one generally-accepted solution. As I mentioned earlier, there are numerous methods of solving i18n and it isn't clear which is "the best." A framework is a potential solution to this problem. Simply getting folks to all align on supporting a few libraries is also a solution. The challenge, of course, is that my "best" isn't the same as your "best," thus we end up with conflicting solutions.
Actually it sounds like OP is looking for something in NodeJS.

I'm also interested in a NodeJS version of something like that even though express is very straightforward once you've worked out all the modules you need.

Or Laravel
https://feathersjs.com/, https://github.com/zeit/next.js/, and https://github.com/jedireza/aqua/ handle more of this for you without turning into the black-box Meteor.js.
I much prefer frameworks like Adonis (https://dev.adonisjs.com/docs/4.0/installation) - it feels a lot easier to just strip out what I don't need from an MVC framework, than to end up rebuilding 90% of the same functionality from a bare-bones Express / Koa application.
I'm working on something like that in my spare time for myself. I have a bunch of websites and it was quite annoying to have to update the same thing over and over again if there was a bug with one of my middleware so I just extracted out into it's own project. It uses Koa under the hood, but all it essentially does is bring in the most popular Koa middleware and mesh them all together.

https://github.com/konstructorjs/konstructor It is still in it's very early stages. Thoughts welcome!

Good list to ponder trade off Node js Express packages , all in one place !!!!!

> But still a bunch that I haven't gotten to googling and still need to decide on what to choose:

    logging (morgan vs winston)

    validation (express-validator, joi)

    auth (passport jwt, local, social)

    session storage (redis vs keeping it in database?)

    database (mongo/mongoose vs 
pg/knex/bookshelf/sequelize, graphql)

    storage (s3 vs gcs)

    ajax requests (request vs axios)

    mail (mailgun, sendgrid, mailchimp)

    error handlers

    rate limiting

    geo ip
For those who don't have too too much time to spend comparing stacks, looking at download trends is sometimes a decent heuristic for weeding out which you might not want to throw into a production system yet. Shameless plug for a site I made to help visualize that

logging - morgan vs winston - popularities seem similar, although winston has a bit of a lead: https://npmcharts.com/compare/morgan,winston

validation - express-validator vs joi - joi no question: https://npmcharts.com/compare/express-validator,joi

SQL ORMs - sequelize and knex were neck and neck for a while, but sequelize seems to have pulled ahead in the last couple months. bookshelf is way behind. https://npmcharts.com/compare/knex,bookshelf,sequelize

Totally agree with you. I miss the opinionated nature of Rails when I work in the JS world.
I think it's always just going to be a different-strokes thing.

For example, I left the Rails world hungering for tiny, composable solutions like Clojure's Ring and Node's Koa.

I ended up preferring to just see glue code in my git diffs. For me and the small teams I work on, there's a lot of productivity to be gained when you can just look at the code and understand what's going on.

You end up with bespoke glue code per application, but the glue is generally simple so I didn't reap much reward from using a framework that tries to hide it at all cost.

You might like Ember. Very opinionated. Yehuda Katz is one of the creators and core team leader.
> I would be so happy if someone took away my power to choose and just forced me to use something that will "just work".

That's basically what Google did on the front end with Angular for people who had the exact same problem with React. Maybe we'll see something like this happen on Backend Javascript, I mean there is Sails, but it doesn't "just work" as well as Angular does on the frontend.

Isn't that what Meteor did (for the backend), or am I not understanding the problem here?
Well if you want this and you’ve ever considered using TypeScript for a JS project, you could try C# + ASP.NET Core. IMO it’s probably the best web stack out there. Opinionated, but allows you to stray from those opinions fairly easily. Secure by default. Great support and stability.
If you already have a database, I recommend storing the session in the database. I personally use connect-pg-simple when using Postgres. In other words, I wouldn't add another major dependency like Redis just for session storage.
Changing the syntax is really useful to avoid Callback Hell by leveraging async/await: http://callbackhell.com/
Yeah, I have a similar feeling.

At this point I have a repo that I keep somewhat up to date and then fork the repo for any new projects.

Every time I start a new express app I feel like I'm working at the 'wrong level of abstraction' to put it in Dan Abramov's words about the React ecosystem. I end up writing the same boilerplate over and over.

The only solution I have is a bare bones repo that I keep up to date myself. Not a great solution, but it's a solution.

Isn't Sails just that: https://sailsjs.com/
Yes but not with the "just work" part
A lot has changed in v1
what's the part that "just" does not work?

I am starting a new project soon and I played with Sails. I really liked it, except I struggled with the user authentication part.

Also worried that the momentum of the project seems to have slowed down a bit, Mike does a lot but seems a bit lonely... Or?

The problem with Sails is that unlike Rails or Django, it's not very popular. This not only means a lot less documentation and help for you but also help for the maintainer (financial or code-wise). This means a slow rate of development, bug fixes, and updates.

I do agree with another poster in that if you want a opinionated just works stack, use Ruby or Python.

You're looking for Adonisjs.
maybe time to make a "node on rails"!
https://sailsjs.com still going strong last time I checked.
Please no.
Why not? Figuring out DB access, session storage, i18n, etc. is not core to my business. Why not abstract that into a framework, and let engineers focus on solving their business needs?
Most of the things you mention are already solved in several useful and applicable to different situations methods in JS anyhow.

Mega-frameworks are, in my experience, one of the biggest sources of encouraging Bad Practices just because their the favorite idiom of the developers.

Rails is infamous for this.

Node (and JavaScript) already has a big enough problem encouraging good code practices that a Rails framework would do untold damage.

The closest it has now is Express (obviously not the same) and that’s already pretty bad for doing what I mention (vastly superseded by Koa and Hapi anyhow).

These things create a very dangerously myopic gravity.

The micro module route Node, JS , and npm uses is - I feel - much much more flexible and beneficial long term.

It's a double edge sword. With so much freedom, there is a high chance an inexperienced dev can wreck your project before it even begins.
That's true even with the large framework though. Rails does very little to protect against that and can make many things worse.
Bingo! I've seen things go wrong with Backbone. The lack of opinion is great if you have an experienced developer starting the project and defining the filesystem layout and overall architecture. We, unfortunately, did not have that for our marketing site. I actively avoid working on our marketing site for this very reason.
Software development should be about thinking, creating, solving problems, and yet a large percentage is grunt work that barely requires more than monkey intelligence.

In some ways we benefit. Sometimes its harder to replace us not just because of skill, but because of countless layers of byzantine and mundane information we’ve memorized about a system. It just not cost effective to stuff all of that crap into someone else’s brain if you don’t have to.

However whenever there is a way to reduce the cruft to productivity ratio, the power is staggering. That’s your “10x” developer right there, someone who gets to actually think a higher percentage of the time.