2 lines
48 KiB
JSON
2 lines
48 KiB
JSON
{"host":"blog.risingstack.com","thumbnail":"https://cdn.rawgit.com/feross/standard/master/badge.svg","url":"https://blog.risingstack.com/how-to-become-a-better-node-js-developer-in-2016/","html":"<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n<title>How to Become a Better Node.js Developer in 2016</title>\n<meta name=\"description\" content=\"Tips and best practices for development, how to operate Node.js infrastructures, how to do your day-to-day development and other useful advice.\">\n<meta name=\"HandheldFriendly\" content=\"True\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta name=\"google-site-verification\" content=\"1VZwYFsfiVb7eRGn7Hx4CQN2PHLUmbYZnlJOXrBaCPA\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/assets/favicons/android-chrome-192x192.png?v=43cd619e27\">\n<link rel=\"manifest\" href=\"/assets/favicons/manifest.json?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"57x57\" href=\"/assets/favicons/apple-touch-icon-57x57.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"60x60\" href=\"/assets/favicons/apple-touch-icon-60x60.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"/assets/favicons/apple-touch-icon-72x72.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"/assets/favicons/apple-touch-icon-76x76.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"114x114\" href=\"/assets/favicons/apple-touch-icon-114x114.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"/assets/favicons/apple-touch-icon-120x120.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"144x144\" href=\"/assets/favicons/apple-touch-icon-144x144.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"/assets/favicons/apple-touch-icon-152x152.png?v=43cd619e27\">\n<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/assets/favicons/apple-touch-icon-180x180.png?v=43cd619e27\">\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">\n<meta name=\"apple-mobile-web-app-title\" content=\"RisingStackBlog\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"228x228\" href=\"/assets/favicons/coast-228x228.png?v=43cd619e27\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/assets/favicons/favicon-16x16.png?v=43cd619e27\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/assets/favicons/favicon-32x32.png?v=43cd619e27\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"96x96\" href=\"/assets/favicons/favicon-96x96.png?v=43cd619e27\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"230x230\" href=\"/assets/favicons/favicon-230x230.png?v=43cd619e27\">\n<link rel=\"shortcut icon\" href=\"/assets/favicons/favicon.ico?v=43cd619e27\">\n<link rel=\"yandex-tableau-widget\" href=\"/assets/favicons/yandex-browser-manifest.json?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 1)\" href=\"/assets/favicons/apple-touch-startup-image-320x460.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)\" href=\"/assets/favicons/apple-touch-startup-image-640x920.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)\" href=\"/assets/favicons/apple-touch-startup-image-640x1096.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)\" href=\"/assets/favicons/apple-touch-startup-image-750x1294.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 414px) and (device-height: 736px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 3)\" href=\"/assets/favicons/apple-touch-startup-image-1182x2208.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 414px) and (device-height: 736px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 3)\" href=\"/assets/favicons/apple-touch-startup-image-1242x2148.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 1)\" href=\"/assets/favicons/apple-touch-startup-image-748x1024.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 1)\" href=\"/assets/favicons/apple-touch-startup-image-768x1004.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)\" href=\"/assets/favicons/apple-touch-startup-image-1496x2048.png?v=43cd619e27\">\n<link rel=\"apple-touch-startup-image\" media=\"(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)\" href=\"/assets/favicons/apple-touch-startup-image-1536x2008.png?v=43cd619e27\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/css/screen.css?v=43cd619e27\">\n<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:400,700\" rel=\"stylesheet\" type=\"text/css\">\n<link rel=\"canonical\" href=\"http://blog.risingstack.com/how-to-become-a-better-node-js-developer-in-2016/\">\n<meta name=\"referrer\" content=\"origin\">\n<meta property=\"og:site_name\" content=\"RisingStack Engineering\">\n<meta property=\"og:type\" content=\"article\">\n<meta property=\"og:title\" content=\"How to Become a Better Node.js Developer in 2016\">\n<meta property=\"og:description\" content=\"Tips and best practices for development, how to operate Node.js infrastructures, how to do your day-to-day development and other useful advice.\">\n<meta property=\"og:url\" content=\"http://blog.risingstack.com/how-to-become-a-better-node-js-developer-in-2016/\">\n<meta property=\"article:published_time\" content=\"2015-12-29T07:46:00.000Z\">\n<meta property=\"article:modified_time\" content=\"2016-01-05T10:34:32.928Z\">\n<meta property=\"article:tag\" content=\"nodejs\">\n<meta property=\"article:tag\" content=\"best practices\">\n<meta name=\"twitter:card\" content=\"summary\">\n<meta name=\"twitter:title\" content=\"How to Become a Better Node.js Developer in 2016\">\n<meta name=\"twitter:description\" content=\"Tips and best practices for development, how to operate Node.js infrastructures, how to do your day-to-day development and other useful advice.\">\n<meta name=\"twitter:url\" content=\"http://blog.risingstack.com/how-to-become-a-better-node-js-developer-in-2016/\">\n<script type=\"application/ld+json\">\n{\n \"@context\": \"http://schema.org\",\n \"@type\": \"Article\",\n \"publisher\": \"RisingStack Engineering\",\n \"author\": {\n \"@type\": \"Person\",\n \"name\": \"Gergely Nemeth\",\n \"image\": \"//www.gravatar.com/avatar/302ec98934a517eec6c10b05e64d82c1?s=250&d=mm&r=x\",\n \"url\": \"http://blog.risingstack.com/author/gergely/\",\n \"description\": \"Node.js and microservices, organizer of @Oneshotbudapest @nodebp @jsconfbp\"\n },\n \"headline\": \"How to Become a Better Node.js Developer in 2016\",\n \"url\": \"http://blog.risingstack.com/how-to-become-a-better-node-js-developer-in-2016/\",\n \"datePublished\": \"2015-12-29T07:46:00.000Z\",\n \"dateModified\": \"2016-01-05T10:34:32.928Z\",\n \"keywords\": \"nodejs, best practices\",\n \"description\": \"Tips and best practices for development, how to operate Node.js infrastructures, how to do your day-to-day development and other useful advice.\"\n}\n </script>\n<meta name=\"generator\" content=\"Ghost 0.7\">\n<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RisingStack Engineering\" href=\"http://blog.risingstack.com/rss/\">\n<script src=\"https://cdn.optimizely.com/js/5395330186.js\"></script>\n \n<script src=\"https://js.tito.io/v1\" async></script>\n \n<script type=\"text/javascript\">\n\tvar $mcGoal = {'settings':{'uuid':'510d6f81b948a39e0d9c32ec3','dc':'us9'}};\n\t(function() {\n\t\t var sp = document.createElement('script'); sp.type = 'text/javascript'; sp.async = true; sp.defer = true;\n\t\tsp.src = ('https:' == document.location.protocol ? 'https://s3.amazonaws.com/downloads.mailchimp.com' : 'http://downloads.mailchimp.com') + '/js/goal.min.js';\n\t\tvar s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(sp, s);\n\t})(); \n</script>\n<link href=\"//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css\" rel=\"stylesheet\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/css/prism.css?v=43cd619e27\">\n \n<style type=\"text/css\">#mc_embed_signup{clear:left;}</style>\n</head>\n<body class=\"post-template tag-nodejs-2 tag-best-practices\">\n \n<noscript><iframe src=\"//www.googletagmanager.com/ns.html?id=GTM-KV8B2T\" height=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"></iframe></noscript>\n<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\nnew Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\nj=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\n'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\n})(window,document,'script','dataLayer','GTM-KV8B2T');</script>\n \n<div id=\"sidebar\">\n<div id=\"sidebar-content\" class=\"inner\">\n<a class=\"blog-logo\" href=\"https://risingstack.com\"><img src=\"https://risingstack-blog.s3.amazonaws.com/2016/Mar/risingstack_logo-1457001742686.png\" alt=\"RisingStack logo\"></a>\n<h2 class=\"blog-title\"><a href=\"http://blog.risingstack.com\">RisingStack Engineering</a></h2>\n<h3 class=\"blog-description\">Engineering blog for all-the-things JavaScript/DevOps/IoT\n</h3>\n<form id=\"search\">\n<input id=\"search-field\" placeholder=\"Search\">\n<div id=\"search-results\"></div>\n</form>\n<div id=\"sidebar-links\">\n<ul id=\"subscription-links\">\n<li><a target=\"_blank\" href=\"http://blog.risingstack.com/rss/\"><i class=\"fa fa-rss\"></i> Subscribe via RSS</a></li>\n \n</ul>\n<ul id=\"sidebar-internal\">\n \n</ul>\n<ul id=\"sidebar-external\">\n<li class=\"external-link\"><a href=\"https://blog.risingstack.com/articles/\"><i class=\"fa fa-list-ul\"></i> Best Articles</a></li>\n<li class=\"external-link\"><a target=\"_blank\" href=\"https://risingstack.com\"><i class=\"fa fa-globe\"></i> RisingStack Website</a></li>\n<li class=\"external-link\"><a target=\"_blank\" href=\"http://trace.risingstack.com/?utm_source=rsblog&utm_medium=sidebar&utm_campaign=tracebeta\"><i class=\"fa fa-bullseye\"></i> Microservice Monitoring</a><a class=\"new\"> New!</a></li>\n<li class=\"external-link\"><a target=\"_blank\" href=\"https://github.com/risingstack\"><i class=\"fa fa-github\"></i> GitHub</a></li>\n<li class=\"external-link\"><a target=\"_blank\" href=\"https://twitter.com/risingstack\"><i class=\"fa fa-twitter\"></i> Twitter</a></li>\n<li class=\"external-link\"><a target=\"_blank\" href=\"https://risingstack.com/?utm_source=rsblog&utm_medium=sidebar&utm_campaign=consulting#contact\"><i class=\"fa fa-envelope\"></i> Contact</a></li>\n<div id=\"mc_embed_signup\">\n<form action=\"//risingstack.us9.list-manage.com/subscribe/post?u=510d6f81b948a39e0d9c32ec3&id=02a6a69990\" method=\"post\" id=\"mc-embedded-subscribe-form\" name=\"mc-embedded-subscribe-form\" class=\"validate\" target=\"_blank\" novalidate=\"\">\n<label for=\"mce-EMAIL\">Subscribe to the RisingStack Engineering newsletter</label>\n<input type=\"email\" value=\"\" name=\"EMAIL\" class=\"email\" id=\"mce-EMAIL\" placeholder=\"email address\" required>\n \n<div style=\"position: absolute; left: -5000px;\"><input type=\"text\" name=\"b_510d6f81b948a39e0d9c32ec3_02a6a69990\" tabindex=\"-1\" value=\"\"></div>\n<div class=\"clear\"><input type=\"submit\" value=\"Subscribe\" name=\"subscribe\" id=\"mc-embedded-subscribe\" class=\"button\"></div>\n</form>\n</div>\n</ul>\n</div>\n<footer class=\"site-footer\">\n<section class=\"copyright\">© 2016 <a href=\"/cdn-cgi/l/email-protection#741d1a121b34061d071d1a13070015171f5a171b19\">RisingStack Inc.</a> • All rights reserved.\n| <a href=\"http://blog.risingstack.com/privacy-policy\">Privacy Policy</a></section>\n<section class=\"poweredby\">Proudly published with <a class=\"icon-ghost\" href=\"https://ghost.org\">Ghost</a></section>\n<section class=\"theme-credits\"><a href=\"https://github.com/dlecina/StayPuft\">StayPuft theme</a> by David Lecina</section>\n</footer>\n</div>\n</div>\n<main>\n<div class=\"main-inner\">\n<section id=\"results\"></section>\n<article class=\"post tag-nodejs-2 tag-best-practices\">\n\n<section class=\"post-content\">\n<p>These tips and best practices are not just for development - but how to operate Node.js infrastructures, how you should do your day-to-day development and other useful pieces of advice.</p>\n<h3 id=\"usees2015\">Use ES2015</h3>\n<p>During the summer of 2015 the <a href=\"http://www.ecma-international.org/ecma-262/6.0/index.html\">final draft of ES2015</a> <em>(formerly ES6)</em> was published. With this a number of new language features were added to the JavaScript language, including:</p>\n<ul>\n<li>arrow functions,</li>\n<li>template strings,</li>\n<li>rest operator, argument spreading,</li>\n<li>generators,</li>\n<li>promises,</li>\n<li>maps, sets,</li>\n<li>symbols,</li>\n</ul>\n<p>and a lot more. For a comprehensive list of new features check out <a href=\"https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond\">ES6 and Beyond</a> by <a href=\"https://twitter.com/getify\">Kyle Simpson</a>. <strong>Most of them are added to Node.js v4.</strong></p>\n<p>On the client side, you can already use all of them with the help of <a href=\"https://babeljs.io/\">Babel</a>, a JavaScript compiler. Still, <strong>on the server side we prefer to use only the features that are added to the latest stable version</strong>, without compiling the source to save us from all the potential headaches.</p>\n<p>For more information on ES6 in Node.js, visit the official site: <a href=\"https://nodejs.org/en/docs/es6/\">https://nodejs.org/en/docs/es6/</a>.</p>\n<h3 id=\"callbackconventionwithpromisesupport\">Callback convention - with Promise support</h3>\n<p>For the last years, we encouraged you to expose an error-first callback interface for your modules. With the <strong>generators functions</strong> already being available and with the upcoming <strong>async functions</strong> your modules <em>(the ones published to NPM)</em> should expose an <strong>error-first callback interface with Promise support</strong>.</p>\n<p><em>Why? To provide backward compatibility a callback interface has to be provided, and for future compatibility you will need the Promise support as well.</em></p>\n<p>For a demonstration of how to do it, take a look at the script below. In this example the <code>readPackage</code> function reads the <code>package.json</code> file and returns its' content by providing both a Promise and a callback interface.</p>\n\n<h3 id=\"asyncpatterns\">Async patterns</h3>\n<p>For a long time in Node.js, you had two choices to manage asynchronous flows: callbacks and streams. For callbacks you could use libraries like <a href=\"https://www.npmjs.com/package/async\">async</a> and for streams <a href=\"https://www.npmjs.com/package/through\">through</a>, <a href=\"https://www.npmjs.com/package/bl\">bl</a> or <a href=\"http://highlandjs.org/\">highland</a>.</p>\n<p>With the introduction of <em>Promises</em>, <em>generators</em> and the <em>async functions</em> it is changing.</p>\n<blockquote>\n<p><em>For a more detailed history of asynchronous JavaScript check out <a href=\"https://blog.risingstack.com/asynchronous-javascript/\">The Evolution of Asynchronous JavaScript</a></em></p>\n</blockquote>\n<h3 id=\"errorhandling\">Error handling</h3>\n<p>Error handling is a crucial part of the application to get right: knowing when to crash, or simply just log the error and continue/retry can be hard.</p>\n<p>To make it easier, we have to distinguish between <strong>programmer errors</strong> and <strong>operational errors</strong>. </p>\n<p>Programmer errors are basically bugs so you should crash the process immediately as you won't know in what state your application is. </p>\n<p>On the other hand, operational errors are problems with the system itself or a remote service, like request timeout or running out of memory. Based on the nature of the error you can try to solve with retrying, or if a file is missing you may have to create it first.</p>\n<h4 id=\"errorhandlingincallbacks\">Error handling in callbacks</h4>\n<p>If an error occurs during an async operation, the error object will be passed as the first argument of the async function. <strong>You always have to check it and handle it.</strong></p>\n<p>The code snippet in the <em>Callback convention</em> section above contains an example.</p>\n<h4 id=\"errorhandlinginpromises\">Error handling in Promises</h4>\n<p>What's going to happen in the following snippet?</p>\n\n<ol>\n<li>It will throw an exception in line 3 </li>\n<li>The catch will handle it, and print it out to the stdout: <code>[Error: ops]</code> </li>\n<li>The execution continues and in line 9 a new error will be thrown </li>\n<li>Nothing else</li>\n</ol>\n<p>And really nothing else - the last error thrown will be a silent one. <strong>Pay extra attention to always add a catch as the last member of the promise chain.</strong> It will save you a lot of headaches. So it should look like this:</p>\n\n<p>And now the output will be:</p>\n<pre><code>[Error: ops]\n[Error: ups]\n</code></pre>\n<h3 id=\"usejavascriptstandardstyle\">Use JavaScript Standard Style</h3>\n<p>In the past years, we had JSLint then JSHint, JSCS, ESLint - all excellent tools trying to automate as much code checking as possible.</p>\n<p>Recently, when it comes to code style we use the <a href=\"https://github.com/feross/standard\">JavaScript Standard Style</a> by <a href=\"https://github.com/feross\">feross</a>.</p>\n<p><a href=\"https://github.com/feross/standard\"><img src=\"http://image.silvrtree.co.uk/900,fit/https://cdn.rawgit.com/feross/standard/master/badge.svg\" alt=\"js-standard-style\" title=\"\"></a></p>\n<p>The reason is simple: no configuration needed, just drop it in the project. Some rules that are incorporated <em>(taken from the readme)</em>:</p>\n<ul>\n<li><strong>2 spaces</strong> – for indentation</li>\n<li><strong>Single quotes for strings</strong> – except to avoid escaping</li>\n<li><strong>No unused variables</strong></li>\n<li><strong>No semicolons</strong></li>\n<li><strong>Never start a line with <code>(</code> or <code>[</code></strong>\n<ul><li>This is the <strong>only</strong> gotcha with omitting semicolons</li></ul></li>\n<li><strong>Space after keywords</strong> <code>if (condition) { ... }</code></li>\n<li><strong>Space after function name</strong> <code>function name (arg) { ... }</code></li>\n<li>Always use <code>===</code> instead of <code>==</code> – but <code>obj == null</code> is allowed to check <code>null || undefined</code>.</li>\n<li>Always handle the node.js <code>err</code> function parameter</li>\n<li>Always prefix browser globals with <code>window</code> – except <code>document</code> and <code>navigator</code> are okay\n<ul><li>Prevents accidental use of poorly-named browser globals like <code>open</code>, <code>length</code>,\n<code>event</code>, and <code>name</code>.</li></ul></li>\n</ul>\n<p>Also, if your editor of choice supports ESLint only, there is an ESLint ruleset as well for the Standard Style, the <a href=\"https://github.com/xjamundx/eslint-plugin-standard\">eslint-plugin-standard</a>. With this plugin installed your <code>.eslintrc</code> will something like this:</p>\n<pre><code class=\"language-javascript\">{\n "plugins": [\n "standard"\n ],\n}\n</code></pre>\n<h3 id=\"thetwelvefactorapplication\">The Twelve-Factor Application</h3>\n<p>The Twelve-Factor application manifesto describes best practices on how web applications should be written.</p>\n<ol>\n<li><a target=\"_blank\" href=\"http://12factor.net/codebase\">One codebase tracked in revision control, many deploys</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/dependencies\">Explicitly declare and isolate dependencies</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/config\">Store config in the environment</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/backing-services\">Treat backing services as attached resources</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/build-release-run\">Strictly separate build and run stages</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/processes\">Execute the app as one or more stateless processes</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/port-binding\">Export services via port binding</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/concurrency\">Scale out via the process model</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/disposability\">Maximize robustness with fast startup and graceful shutdown</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/dev-prod-parity\">Keep development, staging, and production as similar as possible</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/logs\">Treat logs as event streams</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/admin-processes\">Run admin/management tasks as one-off processes</a></li>\n</ol>\n<h3 id=\"startingnewprojects\">Starting new projects</h3>\n<p>Always start a new project with <code>npm init</code>. This will generate a basic <code>package.json</code> for your project.</p>\n<p>If you want to skip the initial questions and go with the defaults, just run <code>npm init --yes</code>.</p>\n<h3 id=\"monitoringyourapplications\">Monitoring your applications</h3>\n<p>Getting notified as soon as something wrong happened or is going to happen in your system can save your business.</p>\n<p>To monitor your applications, you can use open-source software as well as SaaS products.</p>\n<p>For open-source, you can take a look at <a href=\"http://www.zabbix.com/\">Zabbix</a>, <a href=\"https://collectd.org/\">Collectd</a>, <a href=\"https://www.elastic.co/products/elasticsearch\">ElasticSearch</a> or <a href=\"https://www.elastic.co/products/logstash\">Logstash</a>. </p>\n<p>If you do not want to host them, you can try <a href=\"http://trace.risingstack.com/?utm_source=how-to-become-a-better-node-js-developer-in-2016&utm_medium=rsblog&utm_campaign=tracebeta\">Trace</a>, our Node.js and microservice monitoring solution.</p>\n<p><a href=\"http://trace.risingstack.com/?utm_source=how-to-become-a-better-node-js-developer-in-2016&utm_medium=rsblog&utm_campaign=tracebeta\" target=\"_blank\"> <br>\n<img src=\"http://image.silvrtree.co.uk/900,fit/https://risingstack-blog.s3.amazonaws.com/2015/Dec/trace_transaction-1451512486757.png\" alt=\"Trace - Node.js and microservice monitoring\" style=\"width:35em;display: block;margin-left: auto;margin-right: auto;\">\n</a></p>\n<h3 id=\"useabuildsystem\">Use a build system</h3>\n<p><strong>Automate everything you can.</strong> There is nothing more annoying and wasteful activity for a developer than to do grunt work.</p>\n<p>Nowadays the tooling around JavaScript evolved a lot - Grunt, Gulp, and Webpack, just to name a few.</p>\n<p>At RisingStack, most of the new projects use Webpack to aid in front-end development and gulp for other kinds of automated tasks. At first, Webpack can take more time to understand - for newcomers I highly recommend to check out the <a href=\"http://christianalfoni.github.io/react-webpack-cookbook/\">Webpack Cookbooks</a>.</p>\n<h3 id=\"usethelatestltsnodejsversion\">Use the latest LTS Node.js version</h3>\n<p>To get both stability and new features we recommend to use the latest <strong>LTS</strong> <em>(long-term support)</em> version of Node.js - they are the ones with even release numbers. Of course, feel free to experiment with newer versions, called the <strong>Stable</strong> release line with the odd release numbers.</p>\n<p>If you are working on different projects with different Node.js version requirements then start using the Node Version Manager - <a href=\"https://github.com/creationix/nvm\">nvm</a> today.</p>\n<p>For more information on Node.js releases check out the official website: <a href=\"https://nodejs.org/en/blog/community/node-v5/\">https://nodejs.org/en/blog/community/node-v5/</a>.</p>\n<h3 id=\"updatedependenciesonaweeklybasis\">Update dependencies on a weekly basis</h3>\n<p>Make it a habit to update dependencies on a weekly basis. For this, you can use <code>npm outdated</code> or the <a href=\"https://www.npmjs.com/package/npm-check-updates\">ncu</a> package.</p>\n<h3 id=\"picktherightdatabase\">Pick the right database</h3>\n<p>When talking about Node.js and databases the first technology that usually comes up is MongoDB. While there is nothing wrong with it, don't just jump into using it. Ask yourself and your team questions before doing so. To give some idea:</p>\n<ul>\n<li>Do you have structured data?</li>\n<li>Do you have to handle transactions?</li>\n<li>How long should you store the data?</li>\n</ul>\n<p>You may only need Redis, or if you have structured data then you could go for PostgreSQL. If you start developing with SQL in Node.js, check out <a href=\"http://knexjs.org\">knex</a>.</p>\n<h3 id=\"usesemanticversioning\">Use Semantic Versioning</h3>\n<blockquote>\n<p>Semantic Versioning is a formal convention for specifying compatibility using a three-part version number: major version; minor version; and patch. </p>\n</blockquote>\n<p>Major versions are bumped if an API change is not backward-compatible. Minor versions are bumped when new features are added, but the API change is backward compatible. Patch versions are bumped when only bug fixes happened.</p>\n<p>Luckily, you can automate the release of your JavaScript modules with <a href=\"https://github.com/semantic-release/semantic-release\">semantic-release</a>.</p>\n<h3 id=\"keepup\">Keep up</h3>\n<p>It can be challenging to keep up with the latest news and developments in the JavaScript and Node.js world. To make it easier make sure to subscribe to the following media:</p>\n<ul>\n<li><a href=\"http://nodeweekly.com/\">Node.js Weekly Newsletter</a></li>\n<li><a href=\"https://microserviceweekly.com\">Microservice Weekly Newsletter</a></li>\n<li><a href=\"https://changelog.com/\">Changelog Weekly</a> - for Open-Source news</li>\n</ul>\n<h3 id=\"learnmore\">Learn more</h3>\n<blockquote>\n<p>Want to learn more about how you could implement Node.js at your company? Drop us a message at <a href=\"http://risingstack.com/\">RisingStack.com</a>!</p>\n</blockquote>\n</section>\n\n<a href=\"https://trace.risingstack.com/?utm_source=risingstack&utm_medium=blog&utm_content=How to Become a Better Node.js Developer in 2016&utm_campaign=tracebeta\" target=\"_blank\">\n<img src=\"http://image.silvrtree.co.uk/900,fit/https://risingstack-blog.s3.amazonaws.com/2016/Apr/trace_node_js_monitoring_banner-1460471311258.png\" alt=\"Trace - Node.js and microservice monitoring\" style=\"width: 100%; margin: 0px;\">\n</a>\n<div id=\"mc_embed_signup\">\n<form action=\"//risingstack.us9.list-manage.com/subscribe/post?u=510d6f81b948a39e0d9c32ec3&id=02a6a69990\" method=\"post\" id=\"mc-embedded-subscribe-form\" name=\"mc-embedded-subscribe-form\" class=\"validate\" target=\"_blank\" novalidate=\"\">\n<label for=\"mce-EMAIL\">Get early access to our posts</label>\n<input type=\"email\" value=\"\" name=\"EMAIL\" class=\"email\" id=\"mce-EMAIL\" placeholder=\"email address\" required>\n \n<div style=\"position: absolute; left: -5000px;\"><input type=\"text\" name=\"b_510d6f81b948a39e0d9c32ec3_02a6a69990\" tabindex=\"-1\" value=\"\"></div>\n<div class=\"clear\"><input type=\"submit\" value=\"Subscribe\" name=\"subscribe\" id=\"mc-embedded-subscribe\" class=\"button\"></div>\n</form>\n</div>\n\n</article>\n</div>\n</main>\n<script>\n console.log(\"______ _ _ _____ _ _ \\n| ___ \\\\(_) (_) / ___|| | | | \\n| |_/ / _ ___ _ _ __ __ _ \\\\ `--. | |_ __ _ ___ | | __\\n| / | |/ __|| || '_ \\\\ / _` | `--. \\\\| __| / _` | / __|| |/ /\\n| |\\\\ \\\\ | |\\\\__ \\\\| || | | || (_| |/\\\\__/ /| |_ | (_| || (__ | < \\n\\\\_| \\\\_||_||___/|_||_| |_| \\\\__, |\\\\____/ \\\\__| \\\\__,_| \\\\___||_|\\\\_\\\\\\n __/ | \\n |___/ \\n\");\n console.log(\"You like to look under the hood? Why not join us? https://risingstack.workable.com\")\n</script>\n<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>\n<script src=\"//cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js\"></script>\n<script src=\"//cdn.jsdelivr.net/autocomplete.js/0.16.0/autocomplete.jquery.js\"></script>\n<script type=\"text/javascript\" src=\"/assets/js/jquery.fitvids.js?v=43cd619e27\"></script>\n<script type=\"text/javascript\" src=\"/assets/js/index.js?v=43cd619e27\"></script>\n<script type=\"text/javascript\" src=\"/assets/js/prism-loader.js?v=43cd619e27\"></script>\n<script type=\"text/javascript\" src=\"/assets/js/prism.js?v=43cd619e27\"></script>\n<script src=\"/assets/js/jquery.ghostHunter.min.js?v=43cd619e27\"></script>\n<script type=\"text/html\" id=\"search_result_item\">\n <a href=\"<%=url%>\"><%=title%>\n <p class=\"description\">\n <%=description%>\n </p>\n </a>\n </script>\n<script>\n (function(){\n var cache = {};\n\n this.tmpl = function tmpl(str, data){\n // Figure out if we're getting a template, or if we need to\n // load the template - and be sure to cache the result.\n var fn = !/\\W/.test(str) ?\n cache[str] = cache[str] ||\n tmpl(document.getElementById(str).innerHTML) :\n\n // Generate a reusable function that will serve as a template\n // generator (and which will be cached).\n new Function(\"obj\",\n \"var p=[],print=function(){p.push.apply(p,arguments);};\" +\n\n // Introduce the data as local variables using with(){}\n \"with(obj){p.push('\" +\n\n // Convert the template into pure JavaScript\n str\n .replace(/[\\r\\t\\n]/g, \" \")\n .split(\"<%\").join(\"\\t\")\n .replace(/((^|%>)[^\\t]*)'/g, \"$1\\r\")\n .replace(/\\t=(.*?)%>/g, \"',$1,'\")\n .split(\"\\t\").join(\"');\")\n .split(\"%>\").join(\"p.push('\")\n .split(\"\\r\").join(\"\\\\'\")\n + \"');}return p.join('');\");\n\n // Provide some basic currying to the user\n return data ? fn( data ) : fn;\n };\n })();\n $(document).ready(function() {\n // Replace the following values by your ApplicationID and ApiKey.\n var client = algoliasearch('715XFIUYHQ', '7c9256de26d70006b079ef535ec963ce');\n // Replace the following value by the name of the index you want to query.\n var index = client.initIndex('blog');\n\n $('#search-field').autocomplete({\n dropdownMenuContainer: '#search-results'\n }, {\n source: $.fn.autocomplete.sources.hits(index, {\n hitsPerPage: 5\n }),\n displayKey: 'title',\n templates: {\n suggestion: function(hit) {\n return tmpl('search_result_item', hit);\n },\n empty: function () {\n return 'No results'\n }\n }\n });\n });\n </script>\n<script type=\"text/javascript\">/* <![CDATA[ */(function(d,s,a,i,j,r,l,m,t){try{l=d.getElementsByTagName('a');t=d.createElement('textarea');for(i=0;l.length-i;i++){try{a=l[i].href;s=a.indexOf('/cdn-cgi/l/email-protection');m=a.length;if(a&&s>-1&&m>28){j=28+s;s='';if(j<m){r='0x'+a.substr(j,2)|0;for(j+=2;j<m&&a.charAt(j)!='X';j+=2)s+='%'+('0'+('0x'+a.substr(j,2)^r).toString(16)).slice(-2);j++;s=decodeURIComponent(s)+a.substr(j,m-j)}t.innerHTML=s.replace(/</g,'<').replace(/>/g,'>');l[i].href='mailto:'+t.value}}catch(e){}}}catch(e){}})(document);/* ]]> */</script></body>\n</html>\n","reduced":"<section class=\"post-content\">\n<p>These tips and best practices are not just for development - but how to operate Node.js infrastructures, how you should do your day-to-day development and other useful pieces of advice.</p>\n<h3 id=\"usees2015\">Use ES2015</h3>\n<p>During the summer of 2015 the <a href=\"http://www.ecma-international.org/ecma-262/6.0/index.html\">final draft of ES2015</a> <em>(formerly ES6)</em> was published. With this a number of new language features were added to the JavaScript language, including:</p>\n<ul>\n<li>arrow functions,</li>\n<li>template strings,</li>\n<li>rest operator, argument spreading,</li>\n<li>generators,</li>\n<li>promises,</li>\n<li>maps, sets,</li>\n<li>symbols,</li>\n</ul>\n<p>and a lot more. For a comprehensive list of new features check out <a href=\"https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond\">ES6 and Beyond</a> by <a href=\"https://twitter.com/getify\">Kyle Simpson</a>. <strong>Most of them are added to Node.js v4.</strong></p>\n<p>On the client side, you can already use all of them with the help of <a href=\"https://babeljs.io/\">Babel</a>, a JavaScript compiler. Still, <strong>on the server side we prefer to use only the features that are added to the latest stable version</strong>, without compiling the source to save us from all the potential headaches.</p>\n<p>For more information on ES6 in Node.js, visit the official site: <a href=\"https://nodejs.org/en/docs/es6/\">https://nodejs.org/en/docs/es6/</a>.</p>\n<h3 id=\"callbackconventionwithpromisesupport\">Callback convention - with Promise support</h3>\n<p>For the last years, we encouraged you to expose an error-first callback interface for your modules. With the <strong>generators functions</strong> already being available and with the upcoming <strong>async functions</strong> your modules <em>(the ones published to NPM)</em> should expose an <strong>error-first callback interface with Promise support</strong>.</p>\n<p><em>Why? To provide backward compatibility a callback interface has to be provided, and for future compatibility you will need the Promise support as well.</em></p>\n<p>For a demonstration of how to do it, take a look at the script below. In this example the <code>readPackage</code> function reads the <code>package.json</code> file and returns its' content by providing both a Promise and a callback interface.</p>\n\n<h3 id=\"asyncpatterns\">Async patterns</h3>\n<p>For a long time in Node.js, you had two choices to manage asynchronous flows: callbacks and streams. For callbacks you could use libraries like <a href=\"https://www.npmjs.com/package/async\">async</a> and for streams <a href=\"https://www.npmjs.com/package/through\">through</a>, <a href=\"https://www.npmjs.com/package/bl\">bl</a> or <a href=\"http://highlandjs.org/\">highland</a>.</p>\n<p>With the introduction of <em>Promises</em>, <em>generators</em> and the <em>async functions</em> it is changing.</p>\n<blockquote>\n<p><em>For a more detailed history of asynchronous JavaScript check out <a href=\"https://blog.risingstack.com/asynchronous-javascript/\">The Evolution of Asynchronous JavaScript</a></em></p>\n</blockquote>\n<h3 id=\"errorhandling\">Error handling</h3>\n<p>Error handling is a crucial part of the application to get right: knowing when to crash, or simply just log the error and continue/retry can be hard.</p>\n<p>To make it easier, we have to distinguish between <strong>programmer errors</strong> and <strong>operational errors</strong>. </p>\n<p>Programmer errors are basically bugs so you should crash the process immediately as you won't know in what state your application is. </p>\n<p>On the other hand, operational errors are problems with the system itself or a remote service, like request timeout or running out of memory. Based on the nature of the error you can try to solve with retrying, or if a file is missing you may have to create it first.</p>\n<h4 id=\"errorhandlingincallbacks\">Error handling in callbacks</h4>\n<p>If an error occurs during an async operation, the error object will be passed as the first argument of the async function. <strong>You always have to check it and handle it.</strong></p>\n<p>The code snippet in the <em>Callback convention</em> section above contains an example.</p>\n<h4 id=\"errorhandlinginpromises\">Error handling in Promises</h4>\n<p>What's going to happen in the following snippet?</p>\n\n<ol>\n<li>It will throw an exception in line 3 </li>\n<li>The catch will handle it, and print it out to the stdout: <code>[Error: ops]</code> </li>\n<li>The execution continues and in line 9 a new error will be thrown </li>\n<li>Nothing else</li>\n</ol>\n<p>And really nothing else - the last error thrown will be a silent one. <strong>Pay extra attention to always add a catch as the last member of the promise chain.</strong> It will save you a lot of headaches. So it should look like this:</p>\n\n<p>And now the output will be:</p>\n<pre><code>[Error: ops]\n[Error: ups]\n</code></pre>\n<h3 id=\"usejavascriptstandardstyle\">Use JavaScript Standard Style</h3>\n<p>In the past years, we had JSLint then JSHint, JSCS, ESLint - all excellent tools trying to automate as much code checking as possible.</p>\n<p>Recently, when it comes to code style we use the <a href=\"https://github.com/feross/standard\">JavaScript Standard Style</a> by <a href=\"https://github.com/feross\">feross</a>.</p>\n<p><a href=\"https://github.com/feross/standard\"><img src=\"http://image.silvrtree.co.uk/900,fit/https://cdn.rawgit.com/feross/standard/master/badge.svg\" alt=\"js-standard-style\" title=\"\"></a></p>\n<p>The reason is simple: no configuration needed, just drop it in the project. Some rules that are incorporated <em>(taken from the readme)</em>:</p>\n<ul>\n<li><strong>2 spaces</strong> – for indentation</li>\n<li><strong>Single quotes for strings</strong> – except to avoid escaping</li>\n<li><strong>No unused variables</strong></li>\n<li><strong>No semicolons</strong></li>\n<li><strong>Never start a line with <code>(</code> or <code>[</code></strong>\n<ul><li>This is the <strong>only</strong> gotcha with omitting semicolons</li></ul></li>\n<li><strong>Space after keywords</strong> <code>if (condition) { ... }</code></li>\n<li><strong>Space after function name</strong> <code>function name (arg) { ... }</code></li>\n<li>Always use <code>===</code> instead of <code>==</code> – but <code>obj == null</code> is allowed to check <code>null || undefined</code>.</li>\n<li>Always handle the node.js <code>err</code> function parameter</li>\n<li>Always prefix browser globals with <code>window</code> – except <code>document</code> and <code>navigator</code> are okay\n<ul><li>Prevents accidental use of poorly-named browser globals like <code>open</code>, <code>length</code>,\n<code>event</code>, and <code>name</code>.</li></ul></li>\n</ul>\n<p>Also, if your editor of choice supports ESLint only, there is an ESLint ruleset as well for the Standard Style, the <a href=\"https://github.com/xjamundx/eslint-plugin-standard\">eslint-plugin-standard</a>. With this plugin installed your <code>.eslintrc</code> will something like this:</p>\n<pre><code class=\"language-javascript\">{\n "plugins": [\n "standard"\n ],\n}\n</code></pre>\n<h3 id=\"thetwelvefactorapplication\">The Twelve-Factor Application</h3>\n<p>The Twelve-Factor application manifesto describes best practices on how web applications should be written.</p>\n<ol>\n<li><a target=\"_blank\" href=\"http://12factor.net/codebase\">One codebase tracked in revision control, many deploys</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/dependencies\">Explicitly declare and isolate dependencies</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/config\">Store config in the environment</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/backing-services\">Treat backing services as attached resources</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/build-release-run\">Strictly separate build and run stages</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/processes\">Execute the app as one or more stateless processes</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/port-binding\">Export services via port binding</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/concurrency\">Scale out via the process model</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/disposability\">Maximize robustness with fast startup and graceful shutdown</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/dev-prod-parity\">Keep development, staging, and production as similar as possible</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/logs\">Treat logs as event streams</a> </li>\n<li><a target=\"_blank\" href=\"http://12factor.net/admin-processes\">Run admin/management tasks as one-off processes</a></li>\n</ol>\n<h3 id=\"startingnewprojects\">Starting new projects</h3>\n<p>Always start a new project with <code>npm init</code>. This will generate a basic <code>package.json</code> for your project.</p>\n<p>If you want to skip the initial questions and go with the defaults, just run <code>npm init --yes</code>.</p>\n<h3 id=\"monitoringyourapplications\">Monitoring your applications</h3>\n<p>Getting notified as soon as something wrong happened or is going to happen in your system can save your business.</p>\n<p>To monitor your applications, you can use open-source software as well as SaaS products.</p>\n<p>For open-source, you can take a look at <a href=\"http://www.zabbix.com/\">Zabbix</a>, <a href=\"https://collectd.org/\">Collectd</a>, <a href=\"https://www.elastic.co/products/elasticsearch\">ElasticSearch</a> or <a href=\"https://www.elastic.co/products/logstash\">Logstash</a>. </p>\n<p>If you do not want to host them, you can try <a href=\"http://trace.risingstack.com/?utm_source=how-to-become-a-better-node-js-developer-in-2016&utm_medium=rsblog&utm_campaign=tracebeta\">Trace</a>, our Node.js and microservice monitoring solution.</p>\n<p><a href=\"http://trace.risingstack.com/?utm_source=how-to-become-a-better-node-js-developer-in-2016&utm_medium=rsblog&utm_campaign=tracebeta\" target=\"_blank\"> <br>\n<img src=\"http://image.silvrtree.co.uk/900,fit/https://risingstack-blog.s3.amazonaws.com/2015/Dec/trace_transaction-1451512486757.png\" alt=\"Trace - Node.js and microservice monitoring\" style=\"width:35em;display: block;margin-left: auto;margin-right: auto;\">\n</a></p>\n<h3 id=\"useabuildsystem\">Use a build system</h3>\n<p><strong>Automate everything you can.</strong> There is nothing more annoying and wasteful activity for a developer than to do grunt work.</p>\n<p>Nowadays the tooling around JavaScript evolved a lot - Grunt, Gulp, and Webpack, just to name a few.</p>\n<p>At RisingStack, most of the new projects use Webpack to aid in front-end development and gulp for other kinds of automated tasks. At first, Webpack can take more time to understand - for newcomers I highly recommend to check out the <a href=\"http://christianalfoni.github.io/react-webpack-cookbook/\">Webpack Cookbooks</a>.</p>\n<h3 id=\"usethelatestltsnodejsversion\">Use the latest LTS Node.js version</h3>\n<p>To get both stability and new features we recommend to use the latest <strong>LTS</strong> <em>(long-term support)</em> version of Node.js - they are the ones with even release numbers. Of course, feel free to experiment with newer versions, called the <strong>Stable</strong> release line with the odd release numbers.</p>\n<p>If you are working on different projects with different Node.js version requirements then start using the Node Version Manager - <a href=\"https://github.com/creationix/nvm\">nvm</a> today.</p>\n<p>For more information on Node.js releases check out the official website: <a href=\"https://nodejs.org/en/blog/community/node-v5/\">https://nodejs.org/en/blog/community/node-v5/</a>.</p>\n<h3 id=\"updatedependenciesonaweeklybasis\">Update dependencies on a weekly basis</h3>\n<p>Make it a habit to update dependencies on a weekly basis. For this, you can use <code>npm outdated</code> or the <a href=\"https://www.npmjs.com/package/npm-check-updates\">ncu</a> package.</p>\n<h3 id=\"picktherightdatabase\">Pick the right database</h3>\n<p>When talking about Node.js and databases the first technology that usually comes up is MongoDB. While there is nothing wrong with it, don't just jump into using it. Ask yourself and your team questions before doing so. To give some idea:</p>\n<ul>\n<li>Do you have structured data?</li>\n<li>Do you have to handle transactions?</li>\n<li>How long should you store the data?</li>\n</ul>\n<p>You may only need Redis, or if you have structured data then you could go for PostgreSQL. If you start developing with SQL in Node.js, check out <a href=\"http://knexjs.org\">knex</a>.</p>\n<h3 id=\"usesemanticversioning\">Use Semantic Versioning</h3>\n<blockquote>\n<p>Semantic Versioning is a formal convention for specifying compatibility using a three-part version number: major version; minor version; and patch. </p>\n</blockquote>\n<p>Major versions are bumped if an API change is not backward-compatible. Minor versions are bumped when new features are added, but the API change is backward compatible. Patch versions are bumped when only bug fixes happened.</p>\n<p>Luckily, you can automate the release of your JavaScript modules with <a href=\"https://github.com/semantic-release/semantic-release\">semantic-release</a>.</p>\n<h3 id=\"keepup\">Keep up</h3>\n<p>It can be challenging to keep up with the latest news and developments in the JavaScript and Node.js world. To make it easier make sure to subscribe to the following media:</p>\n<ul>\n<li><a href=\"http://nodeweekly.com/\">Node.js Weekly Newsletter</a></li>\n<li><a href=\"https://microserviceweekly.com\">Microservice Weekly Newsletter</a></li>\n<li><a href=\"https://changelog.com/\">Changelog Weekly</a> - for Open-Source news</li>\n</ul>\n<h3 id=\"learnmore\">Learn more</h3>\n<blockquote>\n<p>Want to learn more about how you could implement Node.js at your company? Drop us a message at <a href=\"http://risingstack.com/\">RisingStack.com</a>!</p>\n</blockquote>\n</section>\n\n<a href=\"https://trace.risingstack.com/?utm_source=risingstack&utm_medium=blog&utm_content=How to Become a Better Node.js Developer in 2016&utm_campaign=tracebeta\" target=\"_blank\">\n<img src=\"http://image.silvrtree.co.uk/900,fit/https://risingstack-blog.s3.amazonaws.com/2016/Apr/trace_node_js_monitoring_banner-1460471311258.png\" alt=\"Trace - Node.js and microservice monitoring\" style=\"width: 100%; margin: 0px;\">\n</a>\n<div id=\"mc_embed_signup\">\n<form action=\"//risingstack.us9.list-manage.com/subscribe/post?u=510d6f81b948a39e0d9c32ec3&id=02a6a69990\" method=\"post\" id=\"mc-embedded-subscribe-form\" name=\"mc-embedded-subscribe-form\" class=\"validate\" target=\"_blank\" novalidate=\"\">\n<label for=\"mce-EMAIL\">Get early access to our posts</label>\n<input type=\"email\" value=\"\" name=\"EMAIL\" class=\"email\" id=\"mce-EMAIL\" placeholder=\"email address\" required>\n \n<div style=\"position: absolute; left: -5000px;\"><input type=\"text\" name=\"b_510d6f81b948a39e0d9c32ec3_02a6a69990\" tabindex=\"-1\" value=\"\"></div>\n<div class=\"clear\"><input type=\"submit\" value=\"Subscribe\" name=\"subscribe\" id=\"mc-embedded-subscribe\" class=\"button\"></div>\n</form>\n</div>","nib":"These tips and best practices are not just for development - but how to operate Node.js infrastructures, how you should do your day-to-day development and other useful pieces of advice. Use ES2015 During the summer of 2015 the final draft of ES2015 (formerly ES6) was published. With this a number of","title":"How to Become a Better Node.js Developer in 2016"}
|