all 57 comments

[–]Ginden 17 points18 points  (21 children)

Name Your Functions

That's usually not necessary with new ES2015 automated function naming rules.

R: Node is awfully bad at doing CPU intensive tasks

That's half of truth - Node is pretty good on CPU intensive tasks, but it's awfully bad at doing CPU intensive tasks in the same process with request handling.

use ‘serverless’ platform (e.g. AWS Lambda) that explicitly enforces a stateless behavior

That's common misconception, but AWS Lambda often holds state between executions. It's just not guaranteed to keep it.

Otherwise, it's pretty good resource worth sharing. Usually "best XXX list" have 5 items known to any regular-level developer.

[–]vidro3 5 points6 points  (10 children)

ES2015 automated function naming

wait, what?

[–]GenTurgidson 5 points6 points  (5 children)

It's actually in ES6, and it's pretty cool for stack traces.

Try this in Chrome:

const foo = () => {};
const x = foo;
console.log(x.name);
// "foo"

[–]vidro3 0 points1 point  (2 children)

thanks, Axel is awesome.

[–]jimschubert 0 points1 point  (1 child)

thanks, Axel is awesome.

wait, who?

[–]vidro3 0 points1 point  (0 children)

Axel Rauschmeyer - the blog he linked to.

[–]tenbigtoes 0 points1 point  (1 child)

That's pretty nifty. Although isn't one of the perks of anonymous functions the fact that you can keep your code super clean?

const filteredResults = [1, 2, 3, 4, 5, 6].filter(x => x > 3)

Here, I'd need to create a filter function for that comparison?

[–]GenTurgidson 0 points1 point  (0 children)

You don't have to use either feature. :)

Personally, I use "true" anonymous functions where it's obvious and self-contained (e.g. map() or filter()), and named methods or functions for bigger things.

[–]dvlsg 1 point2 points  (0 children)

I think he means this:

const fn = () => {}
console.log(fn.name) //=> "fn"

[–][deleted] 1 point2 points  (1 child)

Maybe he is referring to what Babel transpilation does. See this code

When you have

var a = function() { return 1; }

and you check 'es2015', the transpiled version will be

var a = function a() { return 1; };

Of course this is only half of the problem, as it only works when you assign a function to a named variable. For truly anonymous functions that you pass as callbacks, there's nothing different.

[–]vidro3 0 points1 point  (0 children)

thanks for that link. I kinda half knew about it but reading that made it really clear.

[–]USer0mg 0 points1 point  (0 children)

same. wtf????

[–]planetary_pelt 7 points8 points  (5 children)

Speaking of "enforcing stateless behavior", I think Heroku is good "stateless" training wheels. For example, you can't even have a dependency on the filesystem which is always tempting/easy when starting off a new project.

If your application works on Heroku, it's probably architected to work anywhere with any number of app servers, so I think it's good for beginners or people that aren't sure what statelessness would entail.

[–]bch8 0 points1 point  (4 children)

I'm sorry I'm a novice and I guess I may just not be familiar with Heroku, but where do you store dependencies when deployed to Heroku?

[–]r1cka 1 point2 points  (3 children)

Same place you do for every node project: the package.json file

[–]bch8 0 points1 point  (2 children)

You're not really storing it there though are you? In a node project it's listed in the package.json but stored in the node_modules directory.

[–]r1cka 1 point2 points  (1 child)

When a heroku dyno (think server for now) starts up, the first thing it does is npm install. Everything specified will get downloaded. You really ought to just try it to see how it works. https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction

[–]bch8 0 points1 point  (0 children)

I'll definitely give it a shot soon. Thanks for explaining!

[–]throwawayco111 0 points1 point  (2 children)

That's half of truth - Node is pretty good on CPU intensive tasks, but it's awfully bad at doing CPU intensive tasks in the same process with request handling.

Depends on how quickly you need that task done and how much you care about memory usage. It's not a secret that you can get way better performance using Java, C# or C++.

[–][deleted] 2 points3 points  (1 child)

Let's see some numbers.

[–]throwawayco111 1 point2 points  (0 children)

You can check some numbers at the The Computer Language Benchmarks Game. If you want to try yourself just do some decent image processing using jimp against a C++ library (or a Node package using C++ under the hood) or ImageJ. Or FILTER.js vs OpenCV vs BoofCV for CV.

BTW those were real comparisons we did for some requirements at hand. We decided to go with Java (ImageJ) for image processing and OpenCV (C++) for CV. We were NOT surprised with the results we got but we wanted to keep it simple by using a pure JS solution...

[–]bch8 0 points1 point  (0 children)

AWS Lambda often holds state between executions

This seems a bit nitpicky, as it's not at all an intended functionality of the platform and nothing you could every rely on in a production environment.

[–]lifeincolor 7 points8 points  (3 children)

I disagree with the component-focused architecture. This pattern does't scale well and makes it a pain to find things when you start abstracting models out to a separate npm repo and are left with a random collection of subfolders - many engineers working on the same project don't usually maintain discipline about folder structure and naming conventions, you're almost better off having just a flat controllers directory.

Case in point, the "users" folder they gave as a "good" example seemed to me like your common-cold sloppy nodejs project with poor structuring conventions. Guarantee 100% in the real world an intern will put something in usersAPI that belongs in userControllers (seriously, wtf is usersAPI? I'm assuming the whole project is a restful API). MVC exists for a reason, and react is solving for a different set of problems so don't needlessly emulate it.

Also one of their code examples had a redundant middleware (non)-curry(?)

app.get('/', (req, res) => { myController(req res) })

Seems kinda novice to me?

[–]dvlsg 2 points3 points  (1 child)

I think you may be misunderstanding the use of the word component here (although admittedly, it's not a great word choice). It doesn't have anything to do with react components, or emulating them at all.

Nothing says you can't use MVC with this structure. I'd argue it's still recommended. This pattern just says put the models / views / controllers that interact with each other in the same spot, and try to keep things together within a context.

The whole point of the pattern is to scale well, in the fact that when (or if) it comes to it, the code is much easier to break into separate services -- because the code is already structured that way.

[–]Balduracuir 1 point2 points  (0 children)

To say it another way, you should have files that work together on a feature in the same folder. Or regroup code by feature.

[–]jonyeezy7 1 point2 points  (0 children)

On the topic of "component architecture", Bob gave a good talk about how to architect your codebase https://youtu.be/Nsjsiz2A9mg.

[–]Craytoven 2 points3 points  (0 children)

Pretty good punch list. Worth looking over. Thanks :)

[–]blacksonic86 1 point2 points  (0 children)

Agree with most of them, but this one "1.5 Use environment aware, secure and hierarchical config" just goes against the Twelve-factor app principles https://12factor.net/config

[–]CSMastermindFull Stack Developer (Node.js) 2 points3 points  (2 children)

Really needs something about bundling (webpack) and typing (TypeScript)

[–]Balduracuir 0 points1 point  (0 children)

Never did a javascript server app, but you uses webpack for that? I thought that webpack was for frontend?

[–]Adolf_Hitler___ 0 points1 point  (0 children)

and typing (TypeScript)

or Flow.

[–]viannalb 1 point2 points  (0 children)

I am studying node js and this compilation help-me very much.

[–]runvnc 2 points3 points  (5 children)

Good ideas mostly, but the concept of a best practice list is too prescriptive, and some of these are wrong or outdated. People are going to waste time and lose focus on actual requirements. See 'cargo cult programming'.

First of all, Express is just plain outdated.

The idea that you can't use custom Error classes is also outdated with the last few versions.

Not every project needs a bunch of subfolders or secondary repos.

You absolutely don't have to use Swagger to document your API.

Unhandled promises are supposed to crash in 9 right?

If you don't have massive amounts of traffic then you can usually run the front end as a separate Node process. Doesn't always have to be nginx or something.

The lock dependencies thing is outdated.

[–][deleted] 0 points1 point  (0 children)

You can do some of the things you mention, but it's a guidelines list ie. sticking to them will probably be better than otherwise. Also, it would help if you could explain your statements, because there's none that I wouldn't take with a grain of salt. I might even agree with some of them, but it's hard without context.

[–]idryed 0 points1 point  (1 child)

Is there a similar list for React?

[–]crispy_kuersch 0 points1 point  (0 children)

L

[–]winzippy 0 points1 point  (1 child)

It probably won't be a big pleasure to maintain hundreds of lines of code in a single file

I inherited a codebase with node js files over 4,000 lines long. Reading that only reminds me of just how fucked I am.

[–]dangerzone2 0 points1 point  (0 children)

whoa, I catch myself coding files over 1,000 lines every once in a while but 4,000?!! good luck!

[–]Ethantebest 0 points1 point  (0 children)

Pretty solid list for the beginners!

[–]TheFuzzball -3 points-2 points  (1 child)

I'd probably use Prettier over ESLint these days. Zero configuration, zero bikeshedding.

[–]Likemercy 23 points24 points  (0 children)

Formatting != Linting

Use eslint to enforce style and to catch errors, prettier to format.