11 ms·
Mistakes Node.js Developers Make
- nailer 12y agoRad list - I'm going to use your 1.2 automatic browser restarts via SSE trick! Re: 1.1 automatic server restarts (for crashes etc) there's no need for forever / supervisord / nodemon on current Linux: make a .service file for your app and it will automatically restart if it crashes, on all major distros. [Unit] Description=My app [Service] ExecStart=/var/www/myapp/app.js Restart=always User=nobody Group=nobody Environment=PATH=/usr/bin:/usr/local/bin Environment=NODE_ENV=production [Install] WantedBy=multi-user.target From: http://medium.com/@mikemaccana/how-i-deploy-node-apps-on-linux-2014-edition-309d606219ca http://medium.com/@mikemaccana/how-i-deploy-node-apps-on-lin...
- silverwind 12y agoI'd add something like After=network.target in the [Unit] section, or you could be in for a bad surprise after a reboot, when your service tries to start before network comes up. Also, I doubt that systemd is available on 'all major' distros.
- nailer 12y agoCheers will do. Re major, Red Hat, Ubuntu, Debian and SuSE current stable releases all have systemd. That said AWS Linux doesn't have it.
- babby 12y agoOr better yet, use PM2 instead of forever. As someone who has spent years with forever, I was ultimately happy to drop it into the trash after discovering PM2. https://github.com/Unitech/pm2 https://github.com/Unitech/pm2 It's significantly more advanced. Create a "process.json" file in your project directory (As you would a nodemon.json), like so: { "name" : "someApp" , "script" : "./index.js" , "node_args" : "--harmony" , "log_file" : true , "merge_logs" : true , "exec_mode" : "fork_mode" , "ignoreWatch" : [ "\\.(css|styl|log)$" , "static/.*" , "views/.*" ] } This will show logs intertwined just like forever, merge logs from seperate forked processes and you can even throw in watch rules like nodemon. pm2 start process.json Then to make all of your processes always restart do this: pm2 save pm2 startup centos Replacing centos with your distro. Couldn't be easier. There are a lot of other features I don't use (such as deployment, which I suspect will be significant for some big websites), but definitely consider dropping forever/supervisord and even nodemon in favor of PM2. They merge pull requests quickly it seems, too. The only issue I've had is that for some reason using the "watch" functionality on a lot of files causes massive CPU overload, or at least it did, it may be fixed by now. If you're going to use the watch functionality (to reload stuff like nodemon), consider whitelisting and not blacklisting files.
- ixtli 12y agoanother mistake javascript developers make: using %s when it's unnecessary. by way of example, the author says: console.log('delay is %s', chalk.green(delay)); where as it's much clearer to say console.log('delay is', chalk.green(delay)); This works in node as of at least v0.10.33 and chrome, but probably most modern browsers.
- nailer 12y agoIf anyone else is wondering: https://www.npmjs.com/package/chalk https://www.npmjs.com/package/chalk
- jbnicolai 12y agoOf which the next version is nearly coming out! (see: https://github.com/sindresorhus/chalk/issues/44 https://github.com/sindresorhus/chalk/issues/44 ). Shameless plug (co-author here), but if you have any questions about it: feel free to ask.
- olalonde 12y agoI personally prefer console.log('delay is ' + chalk.green(delay))); as it is more consistent with non console.log expressions. For example, just with copy/paste I could replace the above with: var msg = 'delay is ' + chalk.green(delay); console.log(msg); But it's really just a matter of preference as long as only one convention is used throughout the same codebase.
- thirsteh 12y agoMistakes Node.js Developers Make, or a critique of Node.js?
- tg3 12y agoconsidering every mistake in the list had an accompanying "right way", I don't think it was a critique of Node.js. Some of these might rightly be called "Mistakes Web Developers Make".
- thirsteh 12y agoMost of the callback spaghetti and event loop blocking stuff is just a critique of Node.js, not developer ability. Most other languages don't have these problems.
- jonny_eh 12y agoIt's a trade off. Other languages don't have this problem but they are missing the benefit of an all async ecosystem.
- thirsteh 12y agoIt's not a benefit. Most other modern languages are also async, they just don't force the programmer to think about it. Go, for example, is just as "async" when it comes to efficiency as Node.js (more so, actually, since it can use more than one CPU core.) The whole notion that node.js (or Python's Twisted) makes everything more efficient by putting you in an event loop is just a cop-out for not having something more intuitive like blocking semantics with an evented I/O scheduler.
- nostrademons 12y agoI wouldn't say "most" - it's basically just Go, Erlang/Elixir, and Haskell that offer blocking semantics with an eventloop under the hood. If you work in Java, the "easy" way is to use threads, and you have to think about it if you want non-blocking IO. If you work in C++, there is no "easy" way, and you have to think about it if you want non-blocking IO. If you work in PHP, Perl, Python, Ruby, or Javascript, they are single-threaded by default but give you basic UNIX concurrency/IO primitives to work with.
- jdp23 12y agoI'm seeing an Application Error -- An error occurred in the application and your page could not be served. Please try again in a few moments. How meta.
- gnarbarian 12y agoI also found irony in this post: http://i.imgur.com/GAvWVnN.png http://i.imgur.com/GAvWVnN.png
- _RPM 12y agoWhile this is a great list, it is subjective, and shouldn't be taken literally. There is no "right way" to do things.
- LukeB_UK 12y agoThere's no "right way", but there are best practices as with any language.
- LewisJEllis 12y agoI agree with you in part; there are at least a few entries in the list which would be better described as "pitfalls" than as "mistakes". But "subjective" does not describe every entry in the list; there's absolutely no reason not to lint, test, and profile a production application.
- pikachu_is_cool 12y agoI was half expecting it to say "choosing to use Node.js" with absolutely nothing else.
- jjangsangy 12y agoI was also expecting this. Im glad I didn't though, that type of post doesn't deserve any attention.
- MichaelGG 12y agoWhat's up with node people packaging every function into a module? How can anyone think that a clean build needing to pull in a dozen thousand files and taking twenty minutes is a good thing? Why have a, say, sha1 module instead of a general crypto one? I've seen at least one module that wasn't more than ten lines of actual code. It's packaging JSON and "tests" were far bigger. It was something trivial that should be in a stdlib.
- sehr 12y agoI don't need the rest of the stuff in the crypto module
- mattdesl 12y agoThere are a lot of reasons to break modules into really tiny pieces, even if they are only a dozen lines or less. Some benefits: - a terse and frozen API (like "domready" and "xtend") does not end up with the scope creep and bitrot that monolithic frameworks and "standard libraries" tend to carry - it encourages diversity rather than "this is the one true way" - it generally leads to less fragmentation overall (and tighter and more robust apps) - each piece can be versioned, tested and bug-tracked independently - once you get used to it and start finding modules you like, it can be incredibly easy to prototype and rapidly iterate with existing solutions. My 100+ modules are in a similar domain (graphics) and my efficiency for prototyping has improved because of them. - it is better for reusability. If you have an algorithm that depends on jQuery or another monolithic framework for just a single function, it is hard to reuse. (ie version issues, bundle size) It took me a while to come around, but npm has really given me a better appreciation for small modules. :)
- STRML 12y agoJust to add to your list, small modules are incredibly useful for browserify/webpack apps. For example, if I just want to md5 some strings and do a `require('crypto')`, I've just pulled about 100 KB of code into my app. Instead, I can find some simple md5 lib (in this case I used one called "js-md5"), and get the same functionality in about 3KB. It seems a lot of Node projects have gone the small module direction. Given that npm is a package manager that (mostly) works correctly - which is so much harder than it sounds - we can actually use small modules in our app to little detriment. Yeah, an npm install might take a little bit longer than you'd like, although it's really not that slow. The duplication of modules isn't really an issue in server-side apps, and in webpack apps you can dedupe code pretty easily with webpack.optimize.DedupePlugin + gzipping, so it's not an issue there either.
- hacknat 12y agoThese were great ideas, but blocking the event loop could have been discussed more. Great suggestions on how to profile, but some examples of how to write code that doesn't block could have been given (for example, spawning a child process to do a continuous set of discrete tasks). Additionally, node's limits should be discussed. If a specifically intense compute task requires a lot of input and will also generate a lot of output (depending on how frequently this task occurs), that's where node starts to really get clobbered and the solution may be very difficult.
- alessioalex 12y agoThanks for the suggestions. Indeed I could have elaborated more on the subject, but I was afraid the article would be longer that needed. I'll keep these in mind for a future one though.
- nnq 12y ago> Since Node.js runs on a single thread, everything that will block the event loop will block everything. That means that if you have a web server with a thousand connected clients and you happen to block the event loop, every client will just...wait. Read more at https://www.airpair.com/node.js/posts/top-10-mistakes-node-developers-make#z8vI87iR0ts5wKuc.99 https://www.airpair.com/node.js/posts/top-10-mistakes-node-d... This kind of thing would be big enough for me to just recommend to most average developers to just stick with PHP or whatever they are using now. At least the one-thread/process-per-request shared-nothing architecture successfully mitigates the effects of unavoidable developer stupidity (or of "code you've pushed to production without review after more than a couple beers" if you want to put it more 1st person...). Simply because: 1. bad code will inevitably be written, 2. bad code will inevitably end up, among other things, blocking the event loop, and 3. the application will need to keep working speedly, form the user's perspective, despite having bad code sprinkled in it. Isn't there any "automagic" way to prevent this from happening with node? ...something like, if a request takes more than XXX ms, than at least start handling new requests in new threads?
- davidw 12y ago> block the event loop This is one of the problems Erlang solves: its internal scheduler keeps things running even if some code ends up in an infinite loop or otherwise misbehaves.
- Havvy 12y agoInfinite loops aren't necessarily a form of misbehavior in Erlang. It is how you keep Erlang processes up after all - just spawn a function that calls itself at the end. Though the vast majority of those have a receive statement so that they're not always running.
- davidw 12y agoClearly I was not talking about the normal kind of "infinite loop", but the "malicious" sort.
- 12y ago
- deleted 12y ago[deleted]
- deleted 12y ago[deleted]
- GeneralError 12y agoWhy is this post on the front page, what's so special about it? Read the TOC: 1 Not using development tools 2 Blocking the event loop 3 Executing a call back multiple times 4 The Christmas tree of callbacks (Callback light) 5 Creating big monolithic applications 6 Poor logging 7 No tests 8 Not using static analysis tools 9 Zero monitoring or profiling 10 Debugging with console.log The author talks about trivial or something that has already been written few times. It would be interesting to see if a post with the title "Top 10 Mistakes C # Developers Make" and comparable content would get just drop the same attention and encouragement. Maybe if it was written by Jon Skeet...
- wildpeaks 12y agoBrowserSync (http://www.browsersync.io http://www.browsersync.io) would be more useful than Livereload because it also reloads CSS without refreshing the page and synchronizes navigation if the page is open on several devices / browsers.
- STRML 12y agoTry webpack-hot-loader, you can not only hot reload CSS, but you can hot reload some JS, most notably React components! It's really a treat when you see it work, and it's just one more way to tighten up your dev loop.
- funthree 12y agorconsole provides syslog bindings as a drop-in replacement for node's built in console module along with other useful output (revised console) If you want to forward your logs somewhere remote you can set that up in your syslog config https://github.com/tblobaum/rconsole https://github.com/tblobaum/rconsole
- nawitus 12y ago>Automating restarts / Automatic browser refresh I don't think this is very beneficial when your project's complexity grows enough to require a non-trivial build. It's nice to have for simple projects, of course. > Using control flow modules (such as async) In my experience the async module creates verbose and ugly looking code. In almost all cases promises are a better solution. Of course, even promises are pretty ugly as it's a "hack" to solve a problem at the language level. ES7 proposal includes async/await, maybe that'll finally solve this problem. >Not using static analysis tools I'd also recommend checking out TypeScript and tslint for complex Node.js applications.
- esailija 12y ago`async/await` is only for sequencing, it's not gonna replace anything other than `.then` chains. If you have such chains to the extent that you think `async/await` will solve your problems, you should think very hard if every item in the chain is truly depending on the previous item in the chain because you are currently losing a lot of performance to that otherwise. I have often seen examples using generators and `async await` that needlessly turn fast concurrent promise code into slower sequential code.
- nawitus 12y agoYou can sequence multiple async operations with promises quite easily by using Q.all (of course this depends on the promise library you're using). Even if async/await will only replace .then chains, that already fixes most of the issues. Most async code actually consists of .then chains (or just a single async function call). Anyway, I agree with your point. Developers need to understand how to use async/await correctly. I wonder if async/await could be implemented for grouping multiple async operations together..
- deleted 12y ago[deleted]
- icantthinkofone 12y agoI often see the complaint that you need a tool to restart node after making changes. And here it is as the first one of ten top mistakes which makes me think reading the article might be one of ten mistakes one would make today. If doing 'Ctrl-C, node file.js' is too debilitating .....