| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent fa0da51 commit 579c4c2
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ | |||
| 18 | 18 | <br/> | |
| 19 | 19 | ||
| 20 | 20 | # Welcome! 3 Things You Ought To Know First: | |
| 21 | - **1. When you read here, you in fact read dozens of the best Node.JS articles -** this is a summary and curation of the top-ranked content on Node JS best practices | ||
| 21 | + **1. When you read here, you in fact read dozens of the best Node.js articles -** this is a summary and curation of the top-ranked content on Node.js best practices | ||
| 22 | 22 | ||
| 23 | 23 | **2. It is the largest compilation, and it is growing every week -** currently, more than 50 best practices, style guides, and architectural tips are presented. New issues and PR are created every day to keep this live book updated. We'd love to see you contributing here, whether fixing some code mistake or suggesting brilliant new ideas. See our [milestones here](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open) | |
| 24 | 24 | ||
@@ -99,7 +99,7 @@ | |||
| 99 | 99 | ||
| 100 | 100 | **TL;DR:** Handling async errors in callback style is probably the fastest way to hell (a.k.a the pyramid of doom). The best gift you can give to your code is using a reputable promise library or async-await instead which enables a much more compact and familiar code syntax like try-catch | |
| 101 | 101 | ||
| 102 | - **Otherwise:** Node.JS callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns | ||
| 102 | + **Otherwise:** Node.js callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns | ||
| 103 | 103 | ||
| 104 | 104 | 🔗 [**Read More: avoiding callbacks**](/sections/errorhandling/asyncerrorhandling.md) | |
| 105 | 105 | ||
@@ -227,11 +227,11 @@ | |||
| 227 | 227 | ||
| 228 | 228 | <br/><br/> | |
| 229 | 229 | ||
| 230 | - ## ![✔] 3.2 Node JS Specific Plugins | ||
| 230 | + ## ![✔] 3.2 Node.js Specific Plugins | ||
| 231 | 231 | ||
| 232 | 232 | **TL;DR:** On top of ESLint standard rules that cover vanilla JS only, add Node-specific plugins like [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) and [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security) | |
| 233 | 233 | ||
| 234 | - **Otherwise:** Many faulty Node.JS code patterns might escape under the radar. For example, developers might require(variableAsPath) files with a variable given as path which allows attackers to execute any JS script. Node.JS linters can detect such patterns and complain early | ||
| 234 | + **Otherwise:** Many faulty Node.js code patterns might escape under the radar. For example, developers might require(variableAsPath) files with a variable given as path which allows attackers to execute any JS script. Node.js linters can detect such patterns and complain early | ||
| 235 | 235 | ||
| 236 | 236 | <br/><br/> | |
| 237 | 237 | ||
@@ -269,7 +269,7 @@ | |||
| 269 | 269 | ||
| 270 | 270 | ## ![✔] 3.5 Name Your Functions | |
| 271 | 271 | ||
| 272 | - **TL;DR:** Name all functions, including closures and callbacks. Avoid anonymous functions. This is especially useful when profiling a node app. Naming all functions will allow you to easily understand what you're looking at when checking a memory snapshot. | ||
| 272 | + **TL;DR:** Name all functions, including closures and callbacks. Avoid anonymous functions. This is especially useful when profiling a Node.js application. Naming all functions will allow you to easily understand what you're looking at when checking a memory snapshot. | ||
| 273 | 273 | ||
| 274 | 274 | **Otherwise:** Debugging production issues using a core dump (memory snapshot) might become challenging as you notice significant memory consumption from anonymous functions. | |
| 275 | 275 | ||
@@ -316,7 +316,7 @@ | |||
| 316 | 316 | ||
| 317 | 317 | **TL;DR:** Require modules at the beginning of each file, before and outside of any functions. This simple best practice will not only help you easily and quickly tell the dependencies of a file right at the top, but also avoids a couple of potential problems. | |
| 318 | 318 | ||
| 319 | - **Otherwise:** Requires are run synchronously by NodeJS. If they are called from within a function, it may block other requests from being handled at a more critical time. Also, if a required module or any of its own dependencies throw an error and crash the server, it is best to find out about it as soon as possible, which might not be the case if that module is required from within a function. | ||
| 319 | + **Otherwise:** Requires are run synchronously by Node.js. If they are called from within a function, it may block other requests from being handled at a more critical time. Also, if a required module or any of its own dependencies throw an error and crash the server, it is best to find out about it as soon as possible, which might not be the case if that module is required from within a function. | ||
| 320 | 320 | ||
| 321 | 321 | <br/><br/> | |
| 322 | 322 | ||
@@ -370,7 +370,7 @@ All statements above will return false if used with `===` | |||
| 370 | 370 | ||
| 371 | 371 | ## ![✔] 3.11 Use Async Await, avoid callbacks | |
| 372 | 372 | ||
| 373 | - **TL;DR:** Node 8 LTS now has full support for Async-await. This is a new way of dealing with asynchronous code which supersedes callbacks and promises. Async-await is non-blocking, and it makes asynchronous code look synchronous. The best gift you can give to your code is using async-await which provides a much more compact and familiar code syntax like try-catch. | ||
| 373 | + **TL;DR:** Node.js 8 LTS now has full support for Async-await. This is a new way of dealing with asynchronous code which supersedes callbacks and promises. Async-await is non-blocking, and it makes asynchronous code look synchronous. The best gift you can give to your code is using async-await which provides a much more compact and familiar code syntax like try-catch. | ||
| 374 | 374 | ||
| 375 | 375 | **Otherwise:** Handling async errors in callback style is probably the fastest way to hell - this style forces to check errors all over, deal with akward code nesting and make it difficult to reason about the code flow. | |
| 376 | 376 | ||
@@ -406,7 +406,7 @@ All statements above will return false if used with `===` | |||
| 406 | 406 | ||
| 407 | 407 | **TL;DR:** ESLint is the de-facto standard for checking code style, not only to identify nitty-gritty spacing issues but also to detect serious code anti-patterns like developers throwing errors without classification. On top of ESLint standard rules that cover vanilla JS only, add Node-specific plugins like [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) and [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security) | |
| 408 | 408 | ||
| 409 | - **Otherwise:** Many faulty Node.JS code patterns might escape under the radar. For example, developers might require(variableAsPath) files with a variable given as path which allows attackers to execute any JS script. Node.JS linters can detect such patterns and complain early | ||
| 409 | + **Otherwise:** Many faulty Node.js code patterns might escape under the radar. For example, developers might require(variableAsPath) files with a variable given as path which allows attackers to execute any JS script. Node.js linters can detect such patterns and complain early | ||
| 410 | 410 | ||
| 411 | 411 | ||
| 412 | 412 | <br/><br/> | |
@@ -492,7 +492,7 @@ All statements above will return false if used with `===` | |||
| 492 | 492 | ||
| 493 | 493 | ## ![✔] 5.3. Delegate anything possible (e.g. gzip, SSL) to a reverse proxy | |
| 494 | 494 | ||
| 495 | - **TL;DR:** Node is awfully bad at doing CPU intensive tasks like gzipping, SSL termination, etc. Instead, use a ‘real’ middleware services like nginx, HAproxy or cloud vendor services | ||
| 495 | + **TL;DR:** Node.js is awfully bad at doing CPU intensive tasks like gzipping, SSL termination, etc. Instead, use a ‘real’ middleware services like nginx, HAproxy or cloud vendor services | ||
| 496 | 496 | ||
| 497 | 497 | **Otherwise:** Your poor single thread will keep busy doing networking tasks instead of dealing with your application core and performance will degrade accordingly | |
| 498 | 498 | ||
@@ -526,9 +526,9 @@ All statements above will return false if used with `===` | |||
| 526 | 526 | ||
| 527 | 527 | ## ![✔] 5.6. Utilize all CPU cores | |
| 528 | 528 | ||
| 529 | - **TL;DR:** At its basic form, a Node app runs on a single CPU core while all other are left idling. It’s your duty to replicate the Node process and utilize all CPUs – For small-medium apps you may use Node Cluster or PM2. For a larger app consider replicating the process using some Docker cluster (e.g. K8S, ECS) or deployment scripts that are based on Linux init system (e.g. systemd) | ||
| 529 | + **TL;DR:** At its basic form, a Node.js application runs on a single CPU core while all other are left idling. It’s your duty to replicate the Node process and utilize all CPUs – For small-medium apps you may use Node.js Cluster or PM2. For a larger app consider replicating the process using some Docker cluster (e.g. K8S, ECS) or deployment scripts that are based on Linux init system (e.g. systemd) | ||
| 530 | 530 | ||
| 531 | - **Otherwise:** Your app will likely utilize only 25% of its available resources(!) or even less. Note that a typical server has 4 CPU cores or more, naive deployment of Node.JS utilizes only 1 (even using PaaS services like AWS beanstalk!) | ||
| 531 | + **Otherwise:** Your app will likely utilize only 25% of its available resources(!) or even less. Note that a typical server has 4 CPU cores or more, naive deployment of Node.js utilizes only 1 (even using PaaS services like AWS beanstalk!) | ||
| 532 | 532 | ||
| 533 | 533 | ||
| 534 | 534 | 🔗 [**Read More: Utilize all CPU cores**](/sections/production/utilizecpu.md) | |
@@ -584,12 +584,12 @@ All statements above will return false if used with `===` | |||
| 584 | 584 | ||
| 585 | 585 | ## ![✔] 5.11. Get your frontend assets out of Node | |
| 586 | 586 | ||
| 587 | - **TL;DR:** Serve frontend content using dedicated middleware (nginx, S3, CDN) because Node performance really gets hurt when dealing with many static files due to its single threaded model | ||
| 587 | + **TL;DR:** Serve frontend content using dedicated middleware (nginx, S3, CDN) because Node.js' performance really gets hurt when dealing with many static files due to its single threaded model | ||
| 588 | 588 | ||
| 589 | - **Otherwise:** Your single Node thread will be busy streaming hundreds of html/images/angular/react files instead of allocating all its resources for the task it was born for – serving dynamic content | ||
| 589 | + **Otherwise:** Your single Node.js thread will be busy streaming hundreds of html/images/angular/react files instead of allocating all its resources for the task it was born for – serving dynamic content | ||
| 590 | 590 | ||
| 591 | 591 | ||
| 592 | - 🔗 [**Read More: Get your frontend assets out of Node**](/sections/production/frontendout.md) | ||
| 592 | + 🔗 [**Read More: Get your frontend assets out of Node.js**](/sections/production/frontendout.md) | ||
| 593 | 593 | ||
| 594 | 594 | <br/><br/> | |
| 595 | 595 | ||
@@ -621,7 +621,7 @@ All statements above will return false if used with `===` | |||
| 621 | 621 | ||
| 622 | 622 | ## ![✔] 5.14. Assign ‘TransactionId’ to each log statement | |
| 623 | 623 | ||
| 624 | - **TL;DR:** Assign the same identifier, transaction-id: {some value}, to each log entry within a single request. Then when inspecting errors in logs, easily conclude what happened before and after. Unfortunately, this is not easy to achieve in Node due its async nature, see code examples inside | ||
| 624 | + **TL;DR:** Assign the same identifier, transaction-id: {some value}, to each log entry within a single request. Then when inspecting errors in logs, easily conclude what happened before and after. Unfortunately, this is not easy to achieve in Node.js due its async nature, see code examples inside | ||
| 625 | 625 | ||
| 626 | 626 | **Otherwise:** Looking at a production error log without the context – what happened before – makes it much harder and slower to reason about the issue | |
| 627 | 627 | ||
@@ -784,11 +784,11 @@ Developers in the project may not follow consistent code security practices, lea | |||
| 784 | 784 | <br/><br/> | |
| 785 | 785 | ||
| 786 | 786 | ||
| 787 | - ## ![✔] 6.13. Run Node as non-root user | ||
| 787 | + ## ![✔] 6.13. Run Node.js as non-root user | ||
| 788 | 788 | ||
| 789 | - **TL;DR:** In Docker environment, Nodejs runs as a root user by default with unlimited permission set. Create a noon-root user during image creation and run the container with the flag "-u username" | ||
| 789 | + **TL;DR:** In a Docker environment, Node.js runs as a root user with unlimited permissions by default. Create a non-root user during image creation and run the container with the flag "-u username" | ||
| 790 | 790 | ||
| 791 | - **Otherwise:** An attacker who manage to run a script on the server gets unlimited power over the local machine (e.g. change iptable and re-route traffic to his server) | ||
| 791 | + **Otherwise:** An attacker who manages to run a script on the server gets unlimited power over the local machine (e.g. change iptable and re-route traffic to his server) | ||
| 792 | 792 | ||
| 793 | 793 | ||
| 794 | 794 | 🔗 [**Read More:**](/sections/security/non-root-user.md) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,9 +1,9 @@ | |||
| 1 | - # Run Node as Noon-Root User | ||
| 1 | + # Run Node.js as Non-Root User | ||
| 2 | 2 | ||
| 3 | 3 | ### One Paragraph Explainer | |
| 4 | - According to the 'Principle of least privilege' a user/process must be able to access only the information and resources that are necessary. Granting root access to an attacker opens a whole new world of malicious ideas like routing traffic to other servers. In practice, most Node apps don't need a root access and don't run with such privilege. However, there are two common scenario that might push to root usage: (1) to gain access to privilege port (e.g. port 80) Nodejs must run as root (2) Docker containers by default run as root(!). It's recommended for Node webserver to listen to non-privilege ports and rely on a reverse-proxy like nginx redirect from port 80. When building a docker image, highly secured apps should run the container with an alternate non-root user. Most docker clusters (e.g. Swarm, Kubernetes) allow setting the security context declaratively | ||
| 4 | + According to the 'Principle of least privilege' a user/process must be able to access only the necessary information and resources. Granting root access to an attacker opens a whole new world of malicious ideas like routing traffic to other servers. In practice, most Node.js apps don't need root access and don't run with such privileges. However, there are two common scenarios that might push to root usage: (1) to gain access to privilege port (e.g. port 80) Node.js must run as root (2) Docker containers by default run as root(!). It's recommended for Node.js webservers to listen on non-privilege ports and rely on a reverse-proxy like nginx to redirect incoming traffic from port 80 to your Node.js application. When building a Docker image, highly secured apps should run the container with an alternate non-root user. Most Docker clusters (e.g. Swarm, Kubernetes) allow setting the security context declaratively | ||
| 5 | 5 | ||
| 6 | - ### Code example - Building a Docker image as noon-root | ||
| 6 | + ### Code example - Building a Docker image as non-root | ||
| 7 | 7 | ```javascript | |
| 8 | 8 | FROM node:some-version-here | |
| 9 | 9 | COPY package.json . | |
| Back | FazBrowse Home | New Git URL |
0 commit comments