diff --git a/.gitignore b/.gitignore
index af90acd87..0a6b52467 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,17 +1,17 @@
-*.log
-.idea
-.vscode
-.idea/**/*
-.vscode/**/*
-.nyc_output
-mochawesome-report
-.DS_Store
-npm-debug.log.*
-node_modules
-node_modules/**/*
-.eslintcache
-cert
-logs/*
-desktop.ini
-package-lock.json
+*.log
+.idea
+.vscode
+.idea/**/*
+.vscode/**/*
+.nyc_output
+mochawesome-report
+.DS_Store
+npm-debug.log.*
+node_modules
+node_modules/**/*
+.eslintcache
+cert
+logs/*
+desktop.ini
+package-lock.json
.history
\ No newline at end of file
diff --git a/.operations/operations-manual.md b/.operations/operations-manual.md
new file mode 100644
index 000000000..435bb24f9
--- /dev/null
+++ b/.operations/operations-manual.md
@@ -0,0 +1,66 @@
+# Operations Manual - Organizing and Maximizing Our Work
+Building a community and knowledge by efficiently handling issues
+
+## Handling issues and PR
+
+
+In a nutshell, every issue and PR should get tagged by one of our core team and routed to the person who specializes in the related topic. This person then, will warmly welcome and kick the discussion shortly (hopefully within 48 hours). The goal of each issue/pr is to learn, improve and join the opener to our forces.
+
+We count on our core team to visit almost everyday and route inquiries - this way the workflow is not depend upon any specific person rather on our entire team.
+
+Any new content should conform to our writing guidelines
+
+## Monthly maintenance
+
+
+On every month a maintainer on call will open an issue for maintenance work and record within all the actions to perform by the end of the month (e.g. assign flower to a contributor). On the end of the corresponding month, the maintainer will run the following checklist
+
+Maintainer on call: @someone
+
+**Updates**
+
+- [x] Update top badges with best practices item count, last update date and Node.js version
+- [ ] Ensure all translations are aligned with the English version
+- [x] Update 'thank you' stars & flowers
+- [x] Notify and thanks the contributors of the month
+
+**Flowers**
+- @someone2
+- @someone1
+
+**Stars**
+- @someone1
+
+**Core Team**
+
+| Month | Maintainer on call |
+|---------|--------------------|
+| 10/2018 | Sagir |
+| 11/2018 | Bruno |
+| 12/2018 | Yoni |
+| 01/2019 | Kyle |
+| 02/2019 | Sagir |
+| 03/2019 | Bruno |
+| 04/2019 | Yoni |
+| 05/2019 | Kyle |
+| 06/2019 | Sagir |
+| 07/2019 | Bruno |
+| 09/2019 | Yoni |
+
+
+
+
+## Routing by areas of expertise
+
+| Topic | Examples | Assignee |
+|--------------------------|-----------------------------------------------------|------------------------------------|
+| Code standards and fixes | Code typos, code standards, examples refinements | Bruno |
+| Translations | Adding new language, merging language PRs | Monthly rotation October - Yoni |
+| General Writing quality | Typos, text clarift | Bruno |
+| Javascript runtime | JS runtime, syntax correctness | Sagir |
+| Devops | Monitoring, hardening a production site, deployment | Kyle |
+| Architetecture | Project structure, microservices | Yoni |
+| Testing | CI, linting, testing | Yoni |
+| Performance | Efficient code, inspecting processes on fire | Sagir |
+| Security | Security packages, secured code | Kyle |
+| General inquires | Ideas, requests to contribute, etc | Monthly rotation October - Bruno |
\ No newline at end of file
diff --git a/writing-guidelines.chinese.md b/.operations/writing-guidelines.chinese.md
similarity index 98%
rename from writing-guidelines.chinese.md
rename to .operations/writing-guidelines.chinese.md
index f6fc3c9b2..8d52d3549 100644
--- a/writing-guidelines.chinese.md
+++ b/.operations/writing-guidelines.chinese.md
@@ -1,31 +1,31 @@
-# 我们的内容写作声明
-如何提高访问者的阅读和学习体验
-
-## 1. 越简单越好
-
-
-我们的使命, 我们管理内容是为了使阅读和吸收知识更容易。因此, 我们专注于将复杂和无趣的话题转化为一个简化的清单, 用缩短和不那么精确的细节来交易超载信息, 避免 ‘易燃’ 和有争议的话题, 摆脱主观想法, 赞成普遍接受做法
-
-
-
-## 2. 以证据为基础并且可靠
-
-
-我们的读者应该有很大的信心, 他们浏览的内容是可靠的。我们通过包括引用、数据和本主题可用的其他资源等证据来实现这一点。实际上, 努力包括可靠来源的引用, 显示基准, 相关的设计模式或任何科学措施, 以证明您的主张
-
-
-## 3. MECE (Mutually Exclusive and Collectively Exhaustive)
-除了大量编辑和可靠的内容, 通过它略读也应该提供全面覆盖的主题。不应排除重要的子主题
-
-## 4. 一致的格式
-内容是使用固定模板显示的。任何将来的内容都必须符合同一模板。如果希望添加新项目符号, 请从现有项目符号复制项目符号格式, 并将其扩展以满足您的需要。有关其他信息, 请查看[模版](https://github.com/i0natan/nodebestpractices/blob/master/sections/template.md)
-
-## 5. 关于Node.js
-每个建议都应直接与Node.js相关, 而不是一般软件开发。当我们建议在Node.js中实现通用模式/规则时, 内容应该集中在Node的实现上。例如, 当我们建议将所有请求的输入为了安全原因进行处理时, 应使用Node行话 - '使用中间件来处理请求输入'
-
-## 6. 仅限主要的vendor
-有时, 包括可以解决某些挑战和问题 (如 npm 软件包、开源工具甚至商业产品) 的供应商名称是很有用的。为了避免极长的列表或推荐信誉不好和不稳定的项目, 我们提出了以下规则:
-
-- 只有排名前3的vendor应该被推荐 – 对于一个给定的相关关键词,如果某个vendor出现在搜索引擎结果中排名前3(谷歌或GitHub通过人气排序),那么它可以包含在我们的推荐里
-- 如果它是一个npm包,它必须平均一天下载至少750次
-- 如果它是一个开源项目,它必须在过去的6个月里至少更新一次
+# 我们的内容写作声明
+如何提高访问者的阅读和学习体验
+
+## 1. 越简单越好
+
+
+我们的使命, 我们管理内容是为了使阅读和吸收知识更容易。因此, 我们专注于将复杂和无趣的话题转化为一个简化的清单, 用缩短和不那么精确的细节来交易超载信息, 避免 ‘易燃’ 和有争议的话题, 摆脱主观想法, 赞成普遍接受做法
+
+
+
+## 2. 以证据为基础并且可靠
+
+
+我们的读者应该有很大的信心, 他们浏览的内容是可靠的。我们通过包括引用、数据和本主题可用的其他资源等证据来实现这一点。实际上, 努力包括可靠来源的引用, 显示基准, 相关的设计模式或任何科学措施, 以证明您的主张
+
+
+## 3. MECE (Mutually Exclusive and Collectively Exhaustive)
+除了大量编辑和可靠的内容, 通过它略读也应该提供全面覆盖的主题。不应排除重要的子主题
+
+## 4. 一致的格式
+内容是使用固定模板显示的。任何将来的内容都必须符合同一模板。如果希望添加新项目符号, 请从现有项目符号复制项目符号格式, 并将其扩展以满足您的需要。有关其他信息, 请查看[模版](https://github.com/i0natan/nodebestpractices/blob/master/sections/template.md)
+
+## 5. 关于Node.js
+每个建议都应直接与Node.js相关, 而不是一般软件开发。当我们建议在Node.js中实现通用模式/规则时, 内容应该集中在Node的实现上。例如, 当我们建议将所有请求的输入为了安全原因进行处理时, 应使用Node行话 - '使用中间件来处理请求输入'
+
+## 6. 仅限主要的vendor
+有时, 包括可以解决某些挑战和问题 (如 npm 软件包、开源工具甚至商业产品) 的供应商名称是很有用的。为了避免极长的列表或推荐信誉不好和不稳定的项目, 我们提出了以下规则:
+
+- 只有排名前3的vendor应该被推荐 – 对于一个给定的相关关键词,如果某个vendor出现在搜索引擎结果中排名前3(谷歌或GitHub通过人气排序),那么它可以包含在我们的推荐里
+- 如果它是一个npm包,它必须平均一天下载至少750次
+- 如果它是一个开源项目,它必须在过去的6个月里至少更新一次
diff --git a/writing-guidelines.md b/.operations/writing-guidelines.md
similarity index 98%
rename from writing-guidelines.md
rename to .operations/writing-guidelines.md
index c5f50e0b2..c57db2fd0 100644
--- a/writing-guidelines.md
+++ b/.operations/writing-guidelines.md
@@ -1,31 +1,31 @@
-# Our content writing manifest
-How we enhance the reading and learning experience for our visitors
-
-## 1. Simple is better than better
-
-
-Making it easy to read and absorb knowledge is our mission, we curate content. As such we focus on transforming complex and exhausting topics into a simplified list, trade overloaded information with shortened and less-accurate details, avoid ‘flammable’ and controversial topics and escape subjective ideas in favor of generally accepted practices
-
-
-
-## 2. Be evidence-based and reliable
-
-
-Our readers should have great confidence that the content they skim through is reliable. We achieve this by including evidence like references, data and other resources available to this topic. Practically, strive to include quotes from reliable sources, show benchmarks, related design patterns or any scientific measure to prove your claims
-
-
-## 3. MECE (Mutually Exclusive and Collectively Exhaustive)
-Apart from the content being greatly edited and reliable, skimming through it should also provide full coverage of the topic. No important sub-topic should be left out
-
-## 4. Consistent formatting
-The content is presented using fixed templates. Any future content must conform to the same template. If you wish to add new bullets copy a bullet format from an existing bullet and extend it to your needs. For additional information please view [this template](https://github.com/i0natan/nodebestpractices/blob/master/sections/template.md)
-
-## 5. It's About Node.js
-Each advice should be related directly to Node.js and not to software development in general. When we advise to implement generic pattern/rule in Node.js, the content should focus on the Node implementation. For example, when we advise to sanitize all requests input for security reasons, Node-lingo should be used - ‘Use middleware to sanitize request input’
-
-## 6. Leading vendors only
-Sometimes it's useful to include names of vendors that can address certain challenges and problems like npm packages, open source tools or even commercial products. To avoid overwhelmingly long lists or recommending non-reputable and unstable projects, we came up with the following rules:
-
-- Only the top 3 vendors should be recommended – a vendor that appears in the top 3 results of a search engine (Google or GitHub sorted by popularity) for a given relevant keyword can be included in our recommendation
-- If it’s a npm package it must also be downloaded at least 750 times a day on average
-- If it’s an open-source project, it must have been updated at least once in the last 6 months
+# Our content writing manifest
+How we enhance the reading and learning experience for our visitors
+
+## 1. Simple is better than better
+
+
+Making it easy to read and absorb knowledge is our mission, we curate content. As such we focus on transforming complex and exhausting topics into a simplified list, trade overloaded information with shortened and less-accurate details, avoid ‘flammable’ and controversial topics and escape subjective ideas in favor of generally accepted practices
+
+
+
+## 2. Be evidence-based and reliable
+
+
+Our readers should have great confidence that the content they skim through is reliable. We achieve this by including evidence like references, data and other resources available to this topic. Practically, strive to include quotes from reliable sources, show benchmarks, related design patterns or any scientific measure to prove your claims
+
+
+## 3. MECE (Mutually Exclusive and Collectively Exhaustive)
+Apart from the content being greatly edited and reliable, skimming through it should also provide full coverage of the topic. No important sub-topic should be left out
+
+## 4. Consistent formatting
+The content is presented using fixed templates. Any future content must conform to the same template. If you wish to add new bullets copy a bullet format from an existing bullet and extend it to your needs. For additional information please view [this template](https://github.com/i0natan/nodebestpractices/blob/master/sections/template.md)
+
+## 5. It's About Node.js
+Each advice should be related directly to Node.js and not to software development in general. When we advise to implement generic pattern/rule in Node.js, the content should focus on the Node implementation. For example, when we advise to sanitize all requests input for security reasons, Node-lingo should be used - ‘Use middleware to sanitize request input’
+
+## 6. Leading vendors only
+Sometimes it's useful to include names of vendors that can address certain challenges and problems like npm packages, open source tools or even commercial products. To avoid overwhelmingly long lists or recommending non-reputable and unstable projects, we came up with the following rules:
+
+- Only the top 3 vendors should be recommended – a vendor that appears in the top 3 results of a search engine (Google or GitHub sorted by popularity) for a given relevant keyword can be included in our recommendation
+- If it’s a npm package it must also be downloaded at least 750 times a day on average
+- If it’s an open-source project, it must have been updated at least once in the last 6 months
diff --git a/LICENSE b/LICENSE
index 0f40703c5..5b3c078d3 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,173 +1,173 @@
-## creative commons
-
-# Attribution-ShareAlike 4.0 International
-
-Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
-
-### Using Creative Commons Public Licenses
-
-Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
-
-* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
-
-* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
-
-## Creative Commons Attribution-ShareAlike 4.0 International Public License
-
-By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
-
-### Section 1 – Definitions.
-
-a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
-
-b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
-
-c. __BY-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License.
-
-d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
-
-e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
-
-f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
-
-g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike.
-
-h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
-
-i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
-
-j. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
-
-k. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
-
-l. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
-
-m. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
-
-### Section 2 – Scope.
-
-a. ___License grant.___
-
- 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
-
- A. reproduce and Share the Licensed Material, in whole or in part; and
-
- B. produce, reproduce, and Share Adapted Material.
-
- 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
-
- 3. __Term.__ The term of this Public License is specified in Section 6(a).
-
- 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
-
- 5. __Downstream recipients.__
-
- A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
-
- B. __Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply.
-
- C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
-
- 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
-
-b. ___Other rights.___
-
- 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
-
- 2. Patent and trademark rights are not licensed under this Public License.
-
- 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
-
-### Section 3 – License Conditions.
-
-Your exercise of the Licensed Rights is expressly made subject to the following conditions.
-
-a. ___Attribution.___
-
- 1. If You Share the Licensed Material (including in modified form), You must:
-
- A. retain the following if it is supplied by the Licensor with the Licensed Material:
-
- i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
-
- ii. a copyright notice;
-
- iii. a notice that refers to this Public License;
-
- iv. a notice that refers to the disclaimer of warranties;
-
- v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
-
- B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
-
- C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
-
- 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
-
- 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
-
-b. ___ShareAlike.___
-
-In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
-
-1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License.
-
-2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
-
-3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
-
-### Section 4 – Sui Generis Database Rights.
-
-Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
-
-a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
-
-b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
-
-c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
-
-For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
-
-### Section 5 – Disclaimer of Warranties and Limitation of Liability.
-
-a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__
-
-b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
-
-c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
-
-### Section 6 – Term and Termination.
-
-a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
-
-b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
-
- 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
-
- 2. upon express reinstatement by the Licensor.
-
- For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
-
-c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
-
-d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
-
-### Section 7 – Other Terms and Conditions.
-
-a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
-
-b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.t stated herein are separate from and independent of the terms and conditions of this Public License.
-
-### Section 8 – Interpretation.
-
-a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
-
-b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
-
-c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
-
-d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
-
-> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
->
-> Creative Commons may be contacted at creativecommons.org
+## creative commons
+
+# Attribution-ShareAlike 4.0 International
+
+Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
+
+### Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
+
+* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
+
+* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
+
+## Creative Commons Attribution-ShareAlike 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
+
+### Section 1 – Definitions.
+
+a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
+
+b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
+
+c. __BY-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License.
+
+d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+
+e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
+
+f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
+
+g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike.
+
+h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
+
+i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
+
+j. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
+
+k. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
+
+l. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
+
+m. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
+
+### Section 2 – Scope.
+
+a. ___License grant.___
+
+ 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
+
+ A. reproduce and Share the Licensed Material, in whole or in part; and
+
+ B. produce, reproduce, and Share Adapted Material.
+
+ 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
+
+ 3. __Term.__ The term of this Public License is specified in Section 6(a).
+
+ 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
+
+ 5. __Downstream recipients.__
+
+ A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
+
+ B. __Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply.
+
+ C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
+
+ 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
+
+b. ___Other rights.___
+
+ 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this Public License.
+
+ 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
+
+### Section 3 – License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the following conditions.
+
+a. ___Attribution.___
+
+ 1. If You Share the Licensed Material (including in modified form), You must:
+
+ A. retain the following if it is supplied by the Licensor with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
+
+ B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
+
+ C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
+
+ 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
+
+b. ___ShareAlike.___
+
+In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
+
+1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License.
+
+2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
+
+3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
+
+### Section 4 – Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
+
+a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
+
+b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
+
+c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
+
+### Section 5 – Disclaimer of Warranties and Limitation of Liability.
+
+a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__
+
+b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
+
+c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+
+### Section 6 – Term and Termination.
+
+a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
+
+b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+
+c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
+
+d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+
+### Section 7 – Other Terms and Conditions.
+
+a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
+
+b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.t stated herein are separate from and independent of the terms and conditions of this Public License.
+
+### Section 8 – Interpretation.
+
+a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
+
+b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
+
+c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
+
+d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
+
+> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
+>
+> Creative Commons may be contacted at creativecommons.org
diff --git a/README.chinese.md b/README.chinese.md
index 1afded088..2c8e6fede 100644
--- a/README.chinese.md
+++ b/README.chinese.md
@@ -1,752 +1,752 @@
-[✔]: assets/images/checkbox-small-blue.png
-
-# Node.js 最佳实践
-
-
-
-
-
-
-
-
-
-
-
- [![nodepractices](/assets/images/twitter-s.png)](https://twitter.com/nodepractices/) **Follow us on Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
-
-
-# 欢迎! 首先您应该知道的三件事情:
-**1. 当您读到这里,实际上您读了很多关于Node.js的优秀文章 -** 这是对Node.js最佳实践中排名最高的内容的总结和分享
-
-**2. 这里是最大的汇集,且每周都在增长 -** 当前,超过50个最佳实现,样式指南,架构建议已经呈现。每天都有新的issue和PR被创建,以使这本在线书籍不断更新。我们很乐于见到您能在这里做出贡献,不管是修复一些代码的错误,或是提出绝妙的新想法。请查看我们的[milestones](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open)
-
-**3. 大部分的条目包含额外的信息 -** 大部分的最佳实践条目的旁边,您将发现 **🔗Read More** 链接,它将呈现给您示例代码,博客引用和更多信息
-
-
-
-## 目录
-1. [项目结构实践 (5) ](#1-project-structure-practices)
-2. [异常处理实践 (11) ](#2-error-handling-practices)
-3. [编码规范实践 (12) ](#3-code-style-practices)
-4. [测试和总体质量实践 (8) ](#4-testing-and-overall-quality-practices)
-5. [进入生产实践 (16) ](#5-going-to-production-practices)
-6. Security Practices ([coming soon](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
-7. Performance Practices ([coming soon](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
-
-
-
-1. 项目结构实践
-
-## ![✔] 1.1 组件式构建你的解决方案
-
- **TL;DR:** 大型项目的最坏的隐患就是维护一个庞大的,含有几百个依赖的代码库 - 当开发人员准备整合新的需求的时候,这样一个庞然大物势必减缓了开发效率。反之,把您的代码拆分成组件,每一个组件有它自己的文件夹和代码库,并且确保每一个组件小而简单。查看正确的项目结构的例子请访问下面的 ‘更多’ 链接。
-
-**否则:** 当编写新需求的开发人员逐步意识到他所做改变的影响,并担心会破坏其他的依赖模块 - 部署会变得更慢,风险更大。当所有业务逻辑没有被分开,这也会被认为很难扩展
-
-🔗 [**更多: 组件结构**](/sections/projectstructre/breakintcomponents.chinese.md)
-
-
-
-## ![✔] 1.2 分层设计组件,保持Express在特定的区域
-
-**TL;DR:** 每一个组件都应该包含'层级' - 一个专注的用于接入网络,逻辑,数据的概念。这样不仅获得一个清晰的分离考量,而且使仿真和测试系统变得异常容易。尽管这是一个普通的模式,但接口开发者易于混淆层级关系,比如把网络层的对象(Express req, res)传给业务逻辑和数据层 - 这会令您的应用彼此依赖,并且只能通过Express使用。
-
-**否则:** 对于混淆了网络层和其它层的应用,将不易于测试,执行CRON的任务,其它非-Express的调用者无法使用
-
-🔗 [**更多: 应用分层**](/sections/projectstructre/createlayers.chinese.md)
-
-
-
-## ![✔] 1.3 封装公共模块成为NPM的包
-
-**TL;DR:** 由大量代码构成的一个大型应用中,贯彻全局的,比如日志,加密和其它类似的公共组件,应该进行封装,并暴露成一个私有的NPM包。这将使其在更多的代码库和项目中被使用变成了可能。
-
-**否则:** 您将不得不重造部署和依赖的轮子
-
-🔗 [**更多: 通过需求构建**](/sections/projectstructre/wraputilities.chinese.md)
-
-
-
-## ![✔] 1.4 分离 Express 'app' and 'server'
-
-**TL;DR:** 避免定义整个[Express](https://expressjs.com/)应用在一个单独的大文件里, 这是一个不好的习惯 - 分离您的 'Express' 定义至少在两个文件中: API声明(app.js) 和 网络相关(WWW)。对于更好的结构,是把你的API声明放在组件中。
-
-**否则:** 您的API将只能通过HTTP的调用进行测试(慢,并且很难产生测试覆盖报告)。维护一个有着上百行代码的文件也不是一个令人开心的事情。
-
-🔗 [**更多: 分离 Express 'app' and 'server'**](/sections/projectstructre/separateexpress.chinese.md)
-
-
-
-## ![✔] 1.5 使用易于设置环境变量,安全和分级的配置
-
-
-**TL;DR:** 一个完美无瑕的配置安装应该确保 (a) 元素可以从文件中,也可以从环境变量中读取 (b) 密码排除在提交的代码之外 (c) 为了易于检索,配置是分级的。仅有几个包可以满足这样的条件,比如[rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) 和 [config](https://www.npmjs.com/package/config)。
-
-**否则:** 不能满足任意的配置要求将会使开发,运维团队,或者两者,易于陷入泥潭。
-
-🔗 [**更多: 配置最佳实践**](/sections/projectstructre/configguide.chinese.md)
-
-
-
-⬆ 返回顶部
-
-2. 错误处理最佳实践
-
-## ![✔] 2.1 使用 Async-Await 和 promises 用于异步错误处理
-
-**TL;DR:** 使用回调的方式处理异步错误可能是导致灾难的最快的方式(a.k.a the pyramid of doom)。对您的代码来说,最好的礼物就是使用规范的promise库或async-await来替代,这会使其像try-catch一样更加简洁,具有熟悉的代码结构。
-
-**否则:** Node.js回调特性, function(err, response), 是导致不可维护代码的一个必然的方式。究其原因,是由于混合了随意的错误处理代码,臃肿的内嵌,蹩脚的代码模式。
-
-🔗 [**更多: 避免回调**](/sections/errorhandling/asyncerrorhandling.chinese.md)
-
-
-
-## ![✔] 2.2 仅使用内建的错误对象
-
-**TL;DR:** 很多人抛出异常使用字符串类型或一些自定义类型 - 这会导致错误处理逻辑和模块间的调用复杂化。是否您reject一个promise,抛出异常或发出(emit)错误 - 使用内建的错误对象将会增加设计一致性,并防止信息的丢失。
-
-
-**否则:** 调用某些模块,将不确定哪种错误类型会返回 - 这将会使恰当的错误处理更加困难。更坏的情况是,使用特定的类型描述错误,会导致重要的错误信息缺失,比如stack trace!
-
-🔗 [**更多: 使用内建错误对象**](/sections/errorhandling/useonlythebuiltinerror.chinese.md)
-
-
-
-## ![✔] 2.3 区分运行错误和程序设计错误
-
-**TL;DR:** 运行错误(例如, API接受到一个无效的输入)指的是一些已知场景下的错误,这类错误的影响已经完全被理解,并能被考虑周全的处理掉。同时,程序设计错误(例如,尝试读取未定义的变量)指的是未知的编码问题,影响到应用得当的重启。
-
-**否则:** 当一个错误产生的时候,您总是得重启应用,但为什么要让 ~5000 个在线用户不能访问,仅仅是因为一个细微的,可以预测的,运行时错误?相反的方案,也不完美 – 当未知的问题(程序问题)产生的时候,使应用依旧可以访问,可能导致不可预测行为。区分两者会使处理更有技巧,并在给定的上下文下给出一个平衡的对策。
-
-🔗 [**更多: 运行错误和程序设计错误**](/sections/errorhandling/operationalvsprogrammererror.chinese.md)
-
-
-
-## ![✔] 2.4 集中处理错误,不要在Express中间件中处理错误
-
-**TL;DR:** 错误处理逻辑,比如给管理员发送邮件,日志应该封装在一个特定的,集中的对象当中,这样当错误产生的时候,所有的终端(例如 Express中间件,cron任务,单元测试)都可以调用。
-
-**否则:** 错误处理的逻辑不放在一起将会导致代码重复和非常可能不恰当的错误处理。
-
-🔗 [**更多: 集中处理错误**](/sections/errorhandling/centralizedhandling.chinese.md)
-
-
-
-## ![✔] 2.5 对API错误使用Swagger文档化
-
-**TL;DR:** 让你的API调用者知道哪种错误会返回,这样他们就能完全的处理这些错误,而不至于系统崩溃。Swagger,REST API的文档框架,通常处理这类问题。
-
-**否则:** 任何API的客户端可能决定崩溃并重启,仅仅因为它收到一个不能处理的错误。注意:API的调用者可能是你(在微服务环境中非常典型)。
-
-
-🔗 [**更多: 使用Swagger记录错误**](/sections/errorhandling/documentingusingswagger.chinese.md)
-
-
-
-## ![✔] 2.6 当一个特殊的情况产生,停掉服务是得体的
-
-**TL;DR:** 当一个不确定错误产生(一个开发错误,最佳实践条款#3) - 这就意味着对应用运转健全的不确定。一个普通的实践将是建议仔细地重启进程,并使用一些‘启动器’工具,比如Forever和PM2。
-
-**否则:** 当一个未知的异常被抛出,意味着某些对象包含错误的状态(例如某个全局事件发生器由于某些内在的错误,不在产生事件),未来的请求可能失败或者行为异常。
-
-🔗 [**更多: 停掉服务**](/sections/errorhandling/shuttingtheprocess.chinese.md)
-
-
-
-
-
-## ![✔] 2.7 使用一个成熟的日志工具提高错误的可见性
-
-**TL;DR:** 一系列成熟的日志工具,比如Winston,Bunyan和Log4J,会加速错误的发现和理解。忘记console.log吧。
-
-**否则:** 浏览console的log,和不通过查询工具或者一个好的日志查看器,手动浏览繁琐的文本文件,会使你忙于工作到很晚。
-
-🔗 [**更多: 使用好用的日志工具**](/sections/errorhandling/usematurelogger.chinese.md)
-
-
-
-
-
-## ![✔] 2.8 使用你最喜欢的测试框架测试错误流
-
-**TL;DR:** 无论专业的自动化测试或者简单的手动开发测试 - 确保您的代码不仅满足正常的场景,而且处理并且返回正确的错误。测试框架,比如Mocha & Chai可以非常容易的处理这些问题(在"Gist popup"中查看代码实例) 。
-
-**否则:** 没有测试,不管自动还是手动,您不可能依赖代码去返回正确的错误。而没有可以理解的错误,那将毫无错误处理可言。
-
-
-🔗 [**更多: 测试错误流向**](/sections/errorhandling/testingerrorflows.chinese.md)
-
-
-
-## ![✔] 2.9 使用APM产品发现错误和宕机时间
-
-**TL;DR:** 监控和性能产品 (别名 APM) 先前一步的检测您的代码库和API,这样他们能自动的,像使用魔法一样的强调错误,宕机和您忽略的性能慢的部分。
-
-**否则:** 您花了很多的力气在测量API的性能和错误,但可能您从来没有意识到真实场景下您最慢的代码块和他们对UX的影响。
-
-
-🔗 [**更多: 使用APM产品**](/sections/errorhandling/apmproducts.chinese.md)
-
-
-
-
-## ![✔] 2.10 捕获未处理的promise rejections
-
-**TL;DR:** 任何在promise中被抛出的异常将被收回和遗弃,除非开发者没有忘记去明确的处理。即使您的代码调用的是process.uncaughtException!解决这个问题可以注册到事件process.unhandledRejection。
-
-**否则:** 您的错误将被回收,无踪迹可循。没有什么可以需要考虑。
-
-
-🔗 [**更多: 捕获未处理的promise rejection**](/sections/errorhandling/catchunhandledpromiserejection.chinese.md)
-
-
-
-## ![✔] 2.11 快速查错,验证参数使用一个专门的库Fail fast, validate arguments using a dedicated library
-
-**TL;DR:** 这应该是您的Express最佳实践中的一部分 – assert API输入避免难以理解的漏洞,这类漏洞以后会非常难以追踪。而验证代码通常是一件乏味的事情,除非使用一些非常炫酷的帮助库比如Joi。
-
-**否则:** 考虑这种情况 – 您的功能期望一个数字参数 “Discount” ,然而调用者忘记传值,之后在您的代码中检查是否 Discount!=0 (允许的折扣值大于零),这样它将允许用户使用一个折扣。OMG,多么不爽的一个漏洞。你能明白吗?
-
-🔗 [**更多: 快速查错**](/sections/errorhandling/failfast.chinese.md)
-
-
-
-⬆ 返回顶部
-
-3. 编码风格实践
-
-## ![✔] 3.1 使用ESLint
-
-**TL;DR:** [ESLint](https://eslint.org)是检查可能的代码错误和修复代码样式的事实上的标准,不仅可以识别实际的间距问题, 而且还可以检测严重的反模式代码, 如开发人员在不分类的情况下抛出错误。尽管ESlint可以自动修复代码样式,但其他的工具比如[prettier](https://www.npmjs.com/package/prettier)和[beautify](https://www.npmjs.com/package/js-beautify)在格式化修复上功能强大,可以和Eslint结合起来使用。
-
-**否则:** 开发人员将必须关注单调乏味的间距和线宽问题, 并且时间可能会浪费在过多考虑项目的代码样式。
-
-
-
-## ![✔] 3.2 Node.js特定的插件
-
-**TL;DR:** 除了仅仅涉及 vanilla JS 的 ESLint 标准规则,添加 Node 相关的插件,比如[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)
-
-**否则:** 许多错误的Node.js代码模式可能在检测下逃生。例如,开发人员可能需要某些文件,把一个变量作为路径名 (variableAsPath) ,这会导致攻击者可以执行任何JS脚本。Node.JS linters可以检测这类模式,并及早预警。
-
-
-
-## ![✔] 3.3 在同一行开始一个代码块的大括号
-
-**TL;DR:** 代码块的第一个大括号应该和声明的起始保持在同一行中。
-
-### 代码示例
-```javascript
- // 建议
- function someFunction() {
- // 代码块
- }
-
- // 避免
- function someFunction
- {
- // 代码块
- }
-```
-
-**否则:** 不遵守这项最佳实践可能导致意外的结果,在Stackoverflow的帖子中可以查看到,如下:
-
-🔗 [**更多:** "Why does a results vary based on curly brace placement?" (Stackoverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
-
-
-
-## ![✔] 3.4 不要忘记分号
-
-**TL;DR:** 即使没有获得一致的认同,但在每一个表达式后面放置分号还是值得推荐的。这将使您的代码, 对于其他阅读代码的开发者来说,可读性,明确性更强。
-
-**否则:** 在前面的章节里面已经提到,如果表达式的末尾没有添加分号,JavaScript的解释器会在自动添加一个,这可能会导致一些意想不到的结果。
-
-
-
-## ![✔] 3.5 命名您的方法
-
-**TL;DR:** 命名所有的方法,包含闭包和回调, 避免匿名方法。当剖析一个node应用的时候,这是特别有用的。命名所有的方法将会使您非常容易的理解内存快照中您正在查看的内容。
-
-**否则:** 使用一个核心dump(内存快照)调试线上问题,会是一项非常挑战的事项,因为你注意到的严重内存泄漏问题极有可能产生于匿名的方法。
-
-
-
-## ![✔] 3.6 变量、常量、函数和类的命名约定
-
-**TL;DR:** 当命名变量和方法的时候,使用 ***lowerCamelCase*** ,当命名类的时候,使用 ***UpperCamelCase*** (首字母大写),对于常量,则 ***UPPERCASE*** 。这将帮助您轻松地区分普通变量/函数和需要实例化的类。使用描述性名称,但使它们尽量简短。
-
-**否则:** JavaScript是世界上唯一一门不需要实例化,就可以直接调用构造函数("Class")的编码语言。因此,类和函数的构造函数由采用UpperCamelCase开始区分。
-
-### 代码示例 ###
-```javascript
- // 使用UpperCamelCase命名类名
- class SomeClassExample () {
-
- // 常量使用const关键字,并使用lowerCamelCase命名
- const config = {
- key: 'value'
- };
-
- // 变量和方法使用lowerCamelCase命名
- let someVariableExample = 'value';
- function doSomething() {
-
- }
-
- }
-```
-
-
-
-## ![✔] 3.7 使用const优于let,废弃var
-
-**TL;DR:** 使用`const`意味着一旦一个变量被分配,它不能被重新分配。使用const将帮助您免于使用相同的变量用于不同的用途,并使你的代码更清晰。如果一个变量需要被重新分配,以在一个循环为例,使用`let`声明它。let的另一个重要方面是,使用let声明的变量只在定义它的块作用域中可用。 `var`是函数作用域,不是块级作用域,既然您有const和let让您随意使用,那么[不应该在ES6中使用var](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70)。
-
-**否则:** 当经常更改变量时,调试变得更麻烦了。
-
-🔗 [**更多: JavaScript ES6+: var, let, or const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
-
-
-
-## ![✔] 3.8 先require, 而不是在方法内部
-
-**TL;DR:** 在每个文件的起始位置,在任何函数的前面和外部require模块。这种简单的最佳实践,不仅能帮助您轻松快速地在文件顶部辨别出依赖关系,而且避免了一些潜在的问题。
-
-**否则:** 在Node.js中,require 是同步运行的。如果从函数中调用它们,它可能会阻塞其他请求,在更关键的时间得到处理。另外,如果所require的模块或它自己的任何依赖项抛出错误并使服务器崩溃,最好尽快查明它,如果该模块在函数中require的,则可能不是这样的情况。
-
-
-
-## ![✔] 3.9 在文件夹上 require ,而不是直接在文件上
-
-**TL;DR:** 当在一个文件夹中开发库/模块,放置一个文件index.js暴露模块的
-内部,这样每个消费者都会通过它。这将作为您模块的一个接口,并使未来的变化简单而不违反规则。
-
-**否则:** 更改文件内部结构或签名可能会破坏与客户端的接口。
-
-### 代码示例
-```javascript
- // 建议
- module.exports.SMSProvider = require('./SMSProvider');
- module.exports.SMSNumberResolver = require('./SMSNumberResolver');
-
- // 避免
- module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
- module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
-```
-
-
-
-
-## ![✔] 3.10 使用 `===` 操作符
-
-**TL;DR:** 对比弱等于 `==`,优先使用严格的全等于 `===` 。`==`将在它们转换为普通类型后比较两个变量。在 `===` 中没有类型转换,并且两个变量必须是相同的类型。
-
-**否则:** 与 `==` 操作符比较,不相等的变量可能会返回true。
-
-### 代码示例
-```javascript
-'' == '0' // false
-0 == '' // true
-0 == '0' // true
-
-false == 'false' // false
-false == '0' // true
-
-false == undefined // false
-false == null // false
-null == undefined // true
-
-' \t\r\n ' == 0 // true
-```
-如果使用`===`, 上面所有语句都将返回 false。
-
-
-
-## ![✔] 3.11 使用 Async Await, 避免回调
-
-**TL;DR:** Node 8 LTS现已全面支持异步等待。这是一种新的方式处理异步请求,取代回调和promise。Async-await是非阻塞的,它使异步代码看起来像是同步的。您可以给你的代码的最好的礼物是用async-await提供了一个更紧凑的,熟悉的,类似try catch的代码语法。
-
-**否则:** 使用回调的方式处理异步错误可能是陷入困境最快的方式 - 这种方式必须面对不停地检测错误,处理别扭的代码内嵌,难以推理编码流。
-
-🔗[**更多:** async await 1.0 引导](https://github.com/yortus/asyncawait)
-
-
-
-## ![✔] 3.12 使用 (=>) 箭头函数
-
-**TL;DR:** 尽管使用 async-await 和避免方法作为参数是被推荐的, 但当处理那些接受promise和回调的老的API的时候 - 箭头函数使代码结构更加紧凑,并保持了根方法上的语义上下文 (例如 'this')。
-
-**否则:** 更长的代码(在ES5方法中)更易于产生缺陷,并读起来很是笨重。
-
-🔗 [**更多: 这是拥抱箭头函数的时刻**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
-
-
-
-
-⬆ 返回顶部
-
-
-4. 测试和总体的质量实践
-
-## ![✔] 4.1 至少,编写API(组件)测试
-
-**TL;DR:** 大多数项目只是因为时间表太短而没有进行任何自动化测试,或者测试项目失控而正被遗弃。因此,优先从API测试开始,这是最简单的编写和提供比单元测试更多覆盖率的事情(你甚至可能不需要编码而进行API测试,像[Postman](https://www.getpostman.com/)。之后,如果您有更多的资源和时间,继续使用高级测试类型,如单元测试、DB测试、性能测试等。
-
-**否则:** 您可能需要花很长时间编写单元测试,才发现只有20%的系统覆盖率。
-
-
-
-## ![✔] 4.2 使用一个linter检测代码问题
-
-**TL;DR:** 使用代码linter检查基本质量并及早检测反模式。在任何测试之前运行它, 并将其添加为预提交的git钩子, 以最小化审查和更正任何问题所需的时间。也可在[Section 3](https://github.com/i0natan/nodebestpractices#3-code-style-practices)中查阅编码样式实践
-
-**否则:** 您可能让一些反模式和易受攻击的代码传递到您的生产环境中。
-
-
-
-
-## ![✔] 4.3 仔细挑选您的持续集成(CI)平台
-
-**TL;DR:** 您的持续集成平台(cicd)将集成各种质量工具(如测试、lint),所以它应该是一个充满活力的生态系统,包含各种插件。[jenkins](https://jenkins.io/)曾经是许多项目的默认选项,因为它有最大的社区,同时也是一个非常强大的平台,这样的代价是要求一个陡峭的学习曲线。如今,使用SaaS工具,比如[CircleCI](https://circleci.com)及其他,安装一套CI解决方案,相对是一件容易的事情。这些工具允许构建灵活的CI管道,而无需管理整个基础设施。最终,这是一个鲁棒性和速度之间的权衡 - 仔细选择您支持的方案。
-
-**否则:** 一旦您需要一些高级定制,选择一些细分市场供应商可能会让您停滞不前。另一方面,伴随着jenkins,可能会在基础设施设置上浪费宝贵的时间。
-
-🔗 [**更多: 挑选 CI 平台**](/sections/testingandquality/citools.chinese.md)
-
-
-
-## ![✔] 4.4 经常检查易受攻击的依赖
-
-**TL;DR:** 即使是那些最有名的依赖模块,比如Express,也有已知的漏洞。使用社区和商业工具,比如 🔗 [nsp](https://github.com/nodesecurity/nsp) ,集成在您的CI平台上,在每一次构建的时候都会被调用,这样可以很容易地解决漏洞问题。
-
-**否则:** 在没有专用工具的情况下,使代码清除漏洞,需要不断地跟踪有关新威胁的在线出版物,相当繁琐。
-
-
-
-## ![✔] 4.5 测试标签化
-
-**TL;DR:** 不同的测试必须运行在不同的情景:quick smoke,IO-less,当开发者保存或提交一个文件,测试应该启动;完整的端到端的测试通常运行在一个新的pull request被提交之后,等等。这可以通过对测试用例设置标签,比如关键字像#cold #api #sanity,来完成。这样您可以对您的测试集进行grep,调用需要的子集。例如,这就是您通过[Mocha](https://mochajs.org/)仅仅调用sanity测试集所需要做的:mocha --grep 'sanity'。
-
-**否则:** 运行所有的测试,包括执行数据库查询的几十个测试,任何时候开发者进行小的改动都可能很慢,这使得开发者不愿意运行测试。
-
-
-
-## ![✔] 4.6 检查测试覆盖率,它有助于识别错误的测试模式
-
-**TL;DR:** 代码覆盖工具比如[Istanbul/NYC ](https://github.com/gotwarlost/istanbul),很好用有3个原因:它是免费的(获得这份报告不需要任何开销),它有助于确定测试覆盖率降低的部分,以及最后但非最不重要的是它指出了测试中的不匹配:通过查看颜色标记的代码覆盖报告您可以注意到,例如,从来不会被测到的代码片段像catch语句(即测试只是调用正确的路径,而不调用应用程序发生错误时的行为)。如果覆盖率低于某个阈值,则将其设置为失败的构建。
-
-**否则:** 当你的大部分代码没有被测试覆盖时,就不会有任何自动化的度量指标告诉你了。
-
-
-
-
-
-## ![✔] 4.7 检查过期的依赖包
-
-**TL;DR:** 使用您的首选工具 (例如 “npm outdated” or [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) 来检测已安装的过期依赖包, 将此检查注入您的 CI 管道, 甚至在严重的情况下使构建失败。例如, 当一个已安装的依赖包滞后5个补丁时 (例如:本地版本是1.3.1 的, 存储库版本是1.3.8 的), 或者它被其作者标记为已弃用, 可能会出现严重的情况 - 停掉这次构建并防止部署此版本。
-
-**否则:** 您的生产环境将运行已被其作者明确标记为有风险的依赖包
-
-
-
-## ![✔] 4.8 对于e2e testing,使用docker-compose
-
-**TL;DR:** 端对端(e2e)测试包含现场数据,由于它依赖于很多重型服务如数据库,习惯被认为是CI过程中最薄弱的环节。Docker-compose通过制定类似生产的环境,并使用一个简单的文本文件和简单的命令,轻松化解了这个问题。它为了e2e测试,允许制作所有相关服务,数据库和隔离网络。最后但并非最不重要的一点是,它可以保持一个无状态环境,该环境在每个测试套件之前被调用,然后立即消失。
-
-
-**否则:** 没有docker-compose,团队必须维护一个测试数据库在每一个测试环境上,包含开发机器,保持所有数据同步,这样测试结果不会因环境不同而不同。
-
-
-
-
-⬆ 返回顶部
-
-5. 上线实践
-
-## ![✔] 5.1. 监控!
-
-**TL;DR:** 监控是一种在顾客之前发现问题的游戏 – 显然这应该被赋予前所未有的重要性。考虑从定义你必须遵循的基本度量标准开始(我的建议在里面),到检查附加的花哨特性并选择解决所有问题的解决方案。市场已经淹没其中。点击下面的 ‘The Gist’ ,了解解决方案的概述。
-
-**否则:** 错误 === 失望的客户. 非常简单.
-
-
-🔗 [**更多: 监控!**](/sections/production/monitoring.chinese.md)
-
-
-
-## ![✔] 5.2. 使用智能日志增加透明度
-
-**TL;DR:** 日志可以是调试语句的一个不能说话的仓库,或者表述应用运行过程的一个漂亮仪表板的驱动。从第1天计划您的日志平台:如何收集、存储和分析日志,以确保所需信息(例如,错误率、通过服务和服务器等完成整个事务)都能被提取出来。
-
-**否则:** 您最终像是面对一个黑盒,不知道发生了什么事情,然后你开始重新写日志语句添加额外的信息。
-
-
-🔗 [**更多: 使用智能日志增加透明度**](/sections/production/smartlogging.chinese.md)
-
-
-
-## ![✔] 5.3. 委托一切可能的(例如:gzip,SSL)给反向代理
-
-**TL;DR:** Node处理CPU密集型任务,如gzipping,SSL termination等,表现糟糕。相反,使用一个 ‘真正’ 的中间件服务像Nginx,HAProxy或者云供应商的服务。
-
-**否则:** 可怜的单线程Node将不幸地忙于处理网络任务,而不是处理应用程序核心,性能会相应降低。
-
-
-🔗 [**更多: 委托一切可能的(例如:gzip,SSL)给反向代理**](/sections/production/delegatetoproxy.chinese.md)
-
-
-
-## ![✔] 5.4. 锁住依赖
-
-**TL;DR:** 您的代码必须在所有的环境中是相同的,但是令人惊讶的是,NPM默认情况下会让依赖在不同环境下发生偏移 – 当在不同的环境中安装包的时候,它试图拿包的最新版本。克服这种问题可以利用NPM配置文件, .npmrc,告诉每个环境保存准确的(不是最新的)包的版本。另外,对于更精细的控制,使用NPM “shrinkwrap”。*更新:作为NPM5,依赖默认锁定。新的包管理工具,Yarn,也默认锁定。
-
-**否则:** QA测试通过的代码和批准的版本,在生产中表现不一致。更糟糕的是,同一生产集群中的不同服务器可能运行不同的代码。
-
-
-🔗 [**更多: 锁住依赖**](/sections/production/lockdependencies.chinese.md)
-
-
-
-## ![✔] 5.5. 使用正确的工具保护进程正常运行
-
-**TL;DR:** 进程必须继续运行,并在失败时重新启动。对于简单的情况下,“重启”工具如PM2可能足够,但在今天的“Dockerized”世界 – 集群管理工具也值得考虑
-
-**否则:** 运行几十个实例没有明确的战略和太多的工具(集群管理,docker,PM2)可能导致一个DevOps混乱
-
-
-🔗 [**更多: 使用正确的工具保护进程正常运行**](/sections/production/guardprocess.chinese.md)
-
-
-
-
-## ![✔] 5.6. 利用CPU多核
-
-**TL;DR:** 在基本形式上,node应用程序运行在单个CPU核心上,而其他都处于空闲状态。复制node进程和利用多核,这是您的职责 – 对于中小应用,您可以使用Node Cluster和PM2. 对于一个大的应用,可以考虑使用一些Docker cluster(例如k8s,ECS)复制进程或基于Linux init system(例如systemd)的部署脚本
-
-**否则:** 您的应用可能只是使用了其可用资源中的25% (!),甚至更少。注意,一台典型的服务器有4个或更多的CPU,默认的Node.js部署仅仅用了一个CPU(甚至使用PaaS服务,比如AWS beanstalk,也一样)。
-
-
-🔗 [**更多: 利用所有的CPU**](/sections/production/utilizecpu.chinese.md)
-
-
-
-## ![✔] 5.7. 创建一个“维护端点”
-
-**TL;DR:** 在一个安全的API中暴露一组系统相关的信息,比如内存使用情况和REPL等等。尽管这里强烈建议依赖标准和作战测试工具,但一些有价值的信息和操作更容易使用代码完成。
-
-**否则:** 您会发现,您正在执行许多“诊断部署” – 将代码发送到生产中,仅仅只为了诊断目的提取一些信息。
-
-
-🔗 [**更多: 创建一个 '维护端点'**](/sections/production/createmaintenanceendpoint.chinese.md)
-
-
-
-## ![✔] 5.8. 使用APM产品发现错误和宕机时间
-
-**TL;DR:** 监控和性能的产品(即APM)先前一步地评估代码库和API,自动的超过传统的监测,并测量在服务和层级上的整体用户体验。例如,一些APM产品可以突显导致最终用户负载过慢的事务,同时指出根本原因。
-
-**否则:** 你可能会花大力气测量API性能和停机时间,也许你永远不会知道,真实场景下哪个是你最慢的代码部分,这些怎么影响用户体验。
-
-
-🔗 [**更多: 使用APM产品发现错误和宕机时间**](/sections/production/apmproducts.chinese.md)
-
-
-
-
-
-## ![✔] 5.9. 使您的代码保持生产环境就绪
-
-**TL;DR:** 在意识中抱着最终上线的想法进行编码,从第1天开始计划上线。这听起来有点模糊,所以我编写了一些与生产维护密切相关的开发技巧(点击下面的要点)
-
-**否则:** 一个世界冠军级别的IT/运维人员也不能拯救一个编码低劣的系统。
-
-
-🔗 [**更多: 使您的代码保持生产环境就绪**](/sections/production/productoncode.chinese.md)
-
-
-
-## ![✔] 5.10. 测量和保护内存使用
-
-**TL;DR:** Node.js和内存有引起争论的联系:V8引擎对内存的使用有稍微的限制(1.4GB),在node的代码里面有内存泄漏的很多途径 – 因此监视node的进程内存是必须的。在小应用程序中,你可以使用shell命令周期性地测量内存,但在中等规模的应用程序中,考虑把内存监控建成一个健壮的监控系统。
-
-**否则:** 您的内存可能一天泄漏一百兆,就像曾发生在沃尔玛的一样。
-
-
-🔗 [**更多: 测量和保护内存使用**](/sections/production/measurememory.chinese.md)
-
-
-
-
-## ![✔] 5.11. Node外管理您的前端资源
-
-**TL;DR:** 使用专门的中间件(nginx,S3,CDN)服务前端内容,这是因为在处理大量静态文件的时候,由于node的单线程模型,它的性能很受影响。
-
-**否则:** 您的单个node线程将忙于传输成百上千的html/图片/angular/react文件,而不是分配其所有的资源为了其擅长的任务 – 服务动态内容
-
-
-🔗 [**更多: Node外管理您的前端资源**](/sections/production/frontendout.chinese.md)
-
-
-
-
-## ![✔] 5.12. 保持无状态,几乎每天都要停下服务器
-
-**TL;DR:** 在外部数据存储上,存储任意类型数据(例如用户会话,缓存,上传文件)。考虑间隔地停掉您的服务器或者使用 ‘serverless’ 平台(例如 AWS Lambda),这是一个明确的强化无状态的行为。
-
-**否则:** 某个服务器上的故障将导致应用程序宕机,而不仅仅是停用故障机器。此外,由于依赖特定服务器,伸缩弹性会变得更具挑战性。
-
-
-🔗 [**更多: 保持无状态,几乎每天都要停下服务器**](/sections/production/bestateless.chinese.md)
-
-
-
-
-
-## ![✔] 5.13. 使用自动检测漏洞的工具
-
-**TL;DR:** 即使是最有信誉的依赖项,比如Express,会有使系统处于危险境地的已知漏洞(随着时间推移)。通过使用社区的或者商业工具,不时的检查漏洞和警告(本地或者Github上),这类问题很容易被抑制,有些问题甚至可以立即修补。
-
-**否则:** 否则: 在没有专用工具的情况下,使代码清除漏洞,需要不断地跟踪有关新威胁的在线出版物。相当繁琐。
-
-
-🔗 [**更多: 使用自动检测漏洞的工具**](/sections/production/detectvulnerabilities.chinese.md)
-
-
-
-
-## ![✔] 5.14. 在每一个log语句中指明 ‘TransactionId’
-
-**TL;DR:** 在每一个请求的每一条log入口,指明同一个标识符,transaction-id: {某些值}。然后在检查日志中的错误时,很容易总结出前后发生的事情。不幸的是,由于Node异步的天性自然,这是不容易办到的,看下代码里面的例子
-
-**否则:** 在没有上下文的情况下查看生产错误日志,这会使问题变得更加困难和缓慢去解决。
-
-
-🔗 [**更多: 在每一个log语句中指明 ‘TransactionId’**](/sections/production/assigntransactionid.chinese.md)
-
-
-
-
-## ![✔] 5.15. 设置NODE_ENV=production
-
-**TL;DR:** 设置环境变量NODE_ENV为‘production’ 或者 ‘development’,这是一个是否激活上线优化的标志 - 很多NPM的包通过它来判断当前的环境,据此优化生产环境代码。
-
-**否则:** 遗漏这个简单的属性可能大幅减弱性能。例如,在使用Express作为服务端渲染页面的时候,如果未设置NODE_ENV,性能将会减慢大概三分之一!
-
-
-🔗 [**更多: 设置NODE_ENV=production**](/sections/production/setnodeenv.chinese.md)
-
-
-
-
-
-## ![✔] 5.16. 设计自动化、原子化和零停机时间部署
-
-**TL;DR:** 研究表明,执行许多部署的团队降低了严重上线问题的可能性。不需要危险的手动步骤和服务停机时间的快速和自动化部署大大改善了部署过程。你应该达到使用Docker结合CI工具,使他们成为简化部署的行业标准。
-
-**否则:** 长时间部署 -> 线上宕机 & 和人相关的错误 -> 团队部署时不自信 -> 更少的部署和需求
-
-
-
-⬆ 返回顶部
-
-# `Security Practices`
-
-## Our contributors are working on this section. Would you like to join?
-
-
-# `Performance Practices`
-
-## Our contributors are working on this section. Would you like to join?
-
-
-
-
-# Milestones
-To maintain this guide and keep it up to date, we are constantly updating and improving the guidelines and best practices with the help of the community. You can follow our [milestones](https://github.com/i0natan/nodebestpractices/milestones) and join the working groups if you want to contribute to this project.
-
-
-
-# Contributors
-## `Yoni Goldberg`
-Independent Node.js consultant who works with customers at USA, Europe and Israel on building large-scale scalable Node applications. Many of the best practices above were first published on his blog post at [http://www.goldbergyoni.com](http://www.goldbergyoni.com). Reach Yoni at @goldbergyoni or me@goldbergyoni.com
-
-## `Ido Richter`
-👨💻 Software engineer, 🌐 web developer, 🤖 emojis enthusiast.
-
-## `Refael Ackermann` [@refack](https://github.com/refack) <refack@gmail.com> (he/him)
-Node.js Core Collaborator, been noding since 0.4, and have noded in multiple production sites. Founded `node4good` home of [`lodash-contrib`](https://github.com/node4good/lodash-contrib), [`formage`](https://github.com/node4good/formage), and [`asynctrace`](https://github.com/node4good/asynctrace).
-`refack` on freenode, Twitter, GitHub, GMail, and many other platforms. DMs are open, happy to help.
-
-## `Bruno Scheufler`
-💻 full-stack web developer and Node.js enthusiast.
-
-## `Kyle Martin` [@js-kyle](https://github.com/js-kyle)
-Full Stack Developer based in New Zealand, interested in architecting and building Node.js applications to perform at global scale. Keen contributor to open source software, including Node.js Core.
-
-
-
-
-# Thank You Notes
-
-This repository is being kept up to date thanks to the help from the community. We appreciate any contribution, from a single word fix to a new best practice. Below is a list of everyone who contributed to this project. A :sunflower: marks a successful pull request and a :star: marks an approved new best practice.
-
-### Flowers
-
-🌻 [Kevin Rambaud](https://github.com/kevinrambaud),
-🌻 [Michael Fine](https://github.com/mfine15),
-🌻 [Shreya Dahal](https://github.com/squgeim),
-🌻 [ChangJoo Park](https://github.com/ChangJoo-Park),
-🌻 [Matheus Cruz Rocha](https://github.com/matheusrocha89),
-🌻 [Yog Mehta](https://github.com/BitYog),
-🌻 [Kudakwashe Paradzayi](https://github.com/kudapara),
-🌻 [t1st3](https://github.com/t1st3),
-🌻 [mulijordan1976](https://github.com/mulijordan1976),
-🌻 [Matan Kushner](https://github.com/matchai),
-🌻 [Fabio Hiroki](https://github.com/fabiothiroki),
-🌻 [James Sumners](https://github.com/jsumners),
-🌻 [Chandan Rai](https://github.com/crowchirp),
-🌻 [Dan Gamble](https://github.com/dan-gamble),
-🌻 [PJ Trainor](https://github.com/trainorpj),
-🌻 [Remek Ambroziak](https://github.com/reod),
-🌻 [Yoni Jah](https://github.com/yonjah),
-🌻 [Misha Khokhlov](https://github.com/hazolsky),
-🌻 [Evgeny Orekhov](https://github.com/EvgenyOrekhov),
-🌻 [Gediminas Petrikas](https://github.com/gediminasml),
-🌻 [Isaac Halvorson](https://github.com/hisaac),
-🌻 [Vedran Karačić](https://github.com/vkaracic),
-🌻 [lallenlowe](https://github.com/lallenlowe),
-🌻 [Nathan Wells](https://github.com/nwwells),
-🌻 [Paulo Vítor S Reis](https://github.com/paulovitin),
-🌻 [syzer](https://github.com/syzer),
-🌻 [David Sancho](https://github.com/davesnx),
-🌻 [Robert Manolea](https://github.com/pupix),
-🌻 [Xavier Ho](https://github.com/spaxe),
-🌻 [Aaron Arney](https://github.com/ocularrhythm),
-🌻 [Jan Charles Maghirang Adona](https://github.com/septa97),
-🌻 [Allen Fang](https://github.com/AllenFang),
-🌻 [Leonardo Villela](https://github.com/leonardovillela),
-🌻 [Michal Zalecki](https://github.com/MichalZalecki)
-🌻 [Chris Nicola](https://github.com/chrisnicola),
-🌻 [Alejandro Corredor](https://github.com/aecorredor),
-🌻 [Ye Min Htut](https://github.com/ymhtut),
-🌻 [cwar](https://github.com/cwar),
-🌻 [Yuwei](https://github.com/keyfoxth),
-🌻 [Utkarsh Bhatt](https://github.com/utkarshbhatt12),
-🌻 [Duarte Mendes](https://github.com/duartemendes),
-🌻 [Sagir Khan](https://github.com/sagirk),
-🌻 [Jason Kim](https://github.com/serv),
-🌻 [Mitja O.](https://github.com/Max101),
-🌻 [Sandro Miguel Marques](https://github.com/SandroMiguel),
-🌻 [Gabe Kuslansky](https://github.com/GabeKuslansky),
-🌻 [Ron Gross](https://github.com/ripper234),
-🌻 [Valeri Karpov](https://github.com/vkarpov15)
-
-### Stars
-
-⭐ [Kyle Martin](https://github.com/js-kyle)
-⭐ [Keith Holliday](https://github.com/TheHollidayInn)
-
+[✔]: assets/images/checkbox-small-blue.png
+
+# Node.js 最佳实践
+
+
+
+
+
+
+
+
+
+
+
+ [![nodepractices](/assets/images/twitter-s.png)](https://twitter.com/nodepractices/) **Follow us on Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+# 欢迎! 首先您应该知道的三件事情:
+**1. 当您读到这里,实际上您读了很多关于Node.js的优秀文章 -** 这是对Node.js最佳实践中排名最高的内容的总结和分享
+
+**2. 这里是最大的汇集,且每周都在增长 -** 当前,超过50个最佳实现,样式指南,架构建议已经呈现。每天都有新的issue和PR被创建,以使这本在线书籍不断更新。我们很乐于见到您能在这里做出贡献,不管是修复一些代码的错误,或是提出绝妙的新想法。请查看我们的[milestones](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open)
+
+**3. 大部分的条目包含额外的信息 -** 大部分的最佳实践条目的旁边,您将发现 **🔗Read More** 链接,它将呈现给您示例代码,博客引用和更多信息
+
+
+
+## 目录
+1. [项目结构实践 (5) ](#1-project-structure-practices)
+2. [异常处理实践 (11) ](#2-error-handling-practices)
+3. [编码规范实践 (12) ](#3-code-style-practices)
+4. [测试和总体质量实践 (8) ](#4-testing-and-overall-quality-practices)
+5. [进入生产实践 (16) ](#5-going-to-production-practices)
+6. Security Practices ([coming soon](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
+7. Performance Practices ([coming soon](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
+
+
+
+1. 项目结构实践
+
+## ![✔] 1.1 组件式构建你的解决方案
+
+ **TL;DR:** 大型项目的最坏的隐患就是维护一个庞大的,含有几百个依赖的代码库 - 当开发人员准备整合新的需求的时候,这样一个庞然大物势必减缓了开发效率。反之,把您的代码拆分成组件,每一个组件有它自己的文件夹和代码库,并且确保每一个组件小而简单。查看正确的项目结构的例子请访问下面的 ‘更多’ 链接。
+
+**否则:** 当编写新需求的开发人员逐步意识到他所做改变的影响,并担心会破坏其他的依赖模块 - 部署会变得更慢,风险更大。当所有业务逻辑没有被分开,这也会被认为很难扩展
+
+🔗 [**更多: 组件结构**](/sections/projectstructre/breakintcomponents.chinese.md)
+
+
+
+## ![✔] 1.2 分层设计组件,保持Express在特定的区域
+
+**TL;DR:** 每一个组件都应该包含'层级' - 一个专注的用于接入网络,逻辑,数据的概念。这样不仅获得一个清晰的分离考量,而且使仿真和测试系统变得异常容易。尽管这是一个普通的模式,但接口开发者易于混淆层级关系,比如把网络层的对象(Express req, res)传给业务逻辑和数据层 - 这会令您的应用彼此依赖,并且只能通过Express使用。
+
+**否则:** 对于混淆了网络层和其它层的应用,将不易于测试,执行CRON的任务,其它非-Express的调用者无法使用
+
+🔗 [**更多: 应用分层**](/sections/projectstructre/createlayers.chinese.md)
+
+
+
+## ![✔] 1.3 封装公共模块成为NPM的包
+
+**TL;DR:** 由大量代码构成的一个大型应用中,贯彻全局的,比如日志,加密和其它类似的公共组件,应该进行封装,并暴露成一个私有的NPM包。这将使其在更多的代码库和项目中被使用变成了可能。
+
+**否则:** 您将不得不重造部署和依赖的轮子
+
+🔗 [**更多: 通过需求构建**](/sections/projectstructre/wraputilities.chinese.md)
+
+
+
+## ![✔] 1.4 分离 Express 'app' and 'server'
+
+**TL;DR:** 避免定义整个[Express](https://expressjs.com/)应用在一个单独的大文件里, 这是一个不好的习惯 - 分离您的 'Express' 定义至少在两个文件中: API声明(app.js) 和 网络相关(WWW)。对于更好的结构,是把你的API声明放在组件中。
+
+**否则:** 您的API将只能通过HTTP的调用进行测试(慢,并且很难产生测试覆盖报告)。维护一个有着上百行代码的文件也不是一个令人开心的事情。
+
+🔗 [**更多: 分离 Express 'app' and 'server'**](/sections/projectstructre/separateexpress.chinese.md)
+
+
+
+## ![✔] 1.5 使用易于设置环境变量,安全和分级的配置
+
+
+**TL;DR:** 一个完美无瑕的配置安装应该确保 (a) 元素可以从文件中,也可以从环境变量中读取 (b) 密码排除在提交的代码之外 (c) 为了易于检索,配置是分级的。仅有几个包可以满足这样的条件,比如[rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) 和 [config](https://www.npmjs.com/package/config)。
+
+**否则:** 不能满足任意的配置要求将会使开发,运维团队,或者两者,易于陷入泥潭。
+
+🔗 [**更多: 配置最佳实践**](/sections/projectstructre/configguide.chinese.md)
+
+
+
+⬆ 返回顶部
+
+2. 错误处理最佳实践
+
+## ![✔] 2.1 使用 Async-Await 和 promises 用于异步错误处理
+
+**TL;DR:** 使用回调的方式处理异步错误可能是导致灾难的最快的方式(a.k.a the pyramid of doom)。对您的代码来说,最好的礼物就是使用规范的promise库或async-await来替代,这会使其像try-catch一样更加简洁,具有熟悉的代码结构。
+
+**否则:** Node.js回调特性, function(err, response), 是导致不可维护代码的一个必然的方式。究其原因,是由于混合了随意的错误处理代码,臃肿的内嵌,蹩脚的代码模式。
+
+🔗 [**更多: 避免回调**](/sections/errorhandling/asyncerrorhandling.chinese.md)
+
+
+
+## ![✔] 2.2 仅使用内建的错误对象
+
+**TL;DR:** 很多人抛出异常使用字符串类型或一些自定义类型 - 这会导致错误处理逻辑和模块间的调用复杂化。是否您reject一个promise,抛出异常或发出(emit)错误 - 使用内建的错误对象将会增加设计一致性,并防止信息的丢失。
+
+
+**否则:** 调用某些模块,将不确定哪种错误类型会返回 - 这将会使恰当的错误处理更加困难。更坏的情况是,使用特定的类型描述错误,会导致重要的错误信息缺失,比如stack trace!
+
+🔗 [**更多: 使用内建错误对象**](/sections/errorhandling/useonlythebuiltinerror.chinese.md)
+
+
+
+## ![✔] 2.3 区分运行错误和程序设计错误
+
+**TL;DR:** 运行错误(例如, API接受到一个无效的输入)指的是一些已知场景下的错误,这类错误的影响已经完全被理解,并能被考虑周全的处理掉。同时,程序设计错误(例如,尝试读取未定义的变量)指的是未知的编码问题,影响到应用得当的重启。
+
+**否则:** 当一个错误产生的时候,您总是得重启应用,但为什么要让 ~5000 个在线用户不能访问,仅仅是因为一个细微的,可以预测的,运行时错误?相反的方案,也不完美 – 当未知的问题(程序问题)产生的时候,使应用依旧可以访问,可能导致不可预测行为。区分两者会使处理更有技巧,并在给定的上下文下给出一个平衡的对策。
+
+🔗 [**更多: 运行错误和程序设计错误**](/sections/errorhandling/operationalvsprogrammererror.chinese.md)
+
+
+
+## ![✔] 2.4 集中处理错误,不要在Express中间件中处理错误
+
+**TL;DR:** 错误处理逻辑,比如给管理员发送邮件,日志应该封装在一个特定的,集中的对象当中,这样当错误产生的时候,所有的终端(例如 Express中间件,cron任务,单元测试)都可以调用。
+
+**否则:** 错误处理的逻辑不放在一起将会导致代码重复和非常可能不恰当的错误处理。
+
+🔗 [**更多: 集中处理错误**](/sections/errorhandling/centralizedhandling.chinese.md)
+
+
+
+## ![✔] 2.5 对API错误使用Swagger文档化
+
+**TL;DR:** 让你的API调用者知道哪种错误会返回,这样他们就能完全的处理这些错误,而不至于系统崩溃。Swagger,REST API的文档框架,通常处理这类问题。
+
+**否则:** 任何API的客户端可能决定崩溃并重启,仅仅因为它收到一个不能处理的错误。注意:API的调用者可能是你(在微服务环境中非常典型)。
+
+
+🔗 [**更多: 使用Swagger记录错误**](/sections/errorhandling/documentingusingswagger.chinese.md)
+
+
+
+## ![✔] 2.6 当一个特殊的情况产生,停掉服务是得体的
+
+**TL;DR:** 当一个不确定错误产生(一个开发错误,最佳实践条款#3) - 这就意味着对应用运转健全的不确定。一个普通的实践将是建议仔细地重启进程,并使用一些‘启动器’工具,比如Forever和PM2。
+
+**否则:** 当一个未知的异常被抛出,意味着某些对象包含错误的状态(例如某个全局事件发生器由于某些内在的错误,不在产生事件),未来的请求可能失败或者行为异常。
+
+🔗 [**更多: 停掉服务**](/sections/errorhandling/shuttingtheprocess.chinese.md)
+
+
+
+
+
+## ![✔] 2.7 使用一个成熟的日志工具提高错误的可见性
+
+**TL;DR:** 一系列成熟的日志工具,比如Winston,Bunyan和Log4J,会加速错误的发现和理解。忘记console.log吧。
+
+**否则:** 浏览console的log,和不通过查询工具或者一个好的日志查看器,手动浏览繁琐的文本文件,会使你忙于工作到很晚。
+
+🔗 [**更多: 使用好用的日志工具**](/sections/errorhandling/usematurelogger.chinese.md)
+
+
+
+
+
+## ![✔] 2.8 使用你最喜欢的测试框架测试错误流
+
+**TL;DR:** 无论专业的自动化测试或者简单的手动开发测试 - 确保您的代码不仅满足正常的场景,而且处理并且返回正确的错误。测试框架,比如Mocha & Chai可以非常容易的处理这些问题(在"Gist popup"中查看代码实例) 。
+
+**否则:** 没有测试,不管自动还是手动,您不可能依赖代码去返回正确的错误。而没有可以理解的错误,那将毫无错误处理可言。
+
+
+🔗 [**更多: 测试错误流向**](/sections/errorhandling/testingerrorflows.chinese.md)
+
+
+
+## ![✔] 2.9 使用APM产品发现错误和宕机时间
+
+**TL;DR:** 监控和性能产品 (别名 APM) 先前一步的检测您的代码库和API,这样他们能自动的,像使用魔法一样的强调错误,宕机和您忽略的性能慢的部分。
+
+**否则:** 您花了很多的力气在测量API的性能和错误,但可能您从来没有意识到真实场景下您最慢的代码块和他们对UX的影响。
+
+
+🔗 [**更多: 使用APM产品**](/sections/errorhandling/apmproducts.chinese.md)
+
+
+
+
+## ![✔] 2.10 捕获未处理的promise rejections
+
+**TL;DR:** 任何在promise中被抛出的异常将被收回和遗弃,除非开发者没有忘记去明确的处理。即使您的代码调用的是process.uncaughtException!解决这个问题可以注册到事件process.unhandledRejection。
+
+**否则:** 您的错误将被回收,无踪迹可循。没有什么可以需要考虑。
+
+
+🔗 [**更多: 捕获未处理的promise rejection**](/sections/errorhandling/catchunhandledpromiserejection.chinese.md)
+
+
+
+## ![✔] 2.11 快速查错,验证参数使用一个专门的库Fail fast, validate arguments using a dedicated library
+
+**TL;DR:** 这应该是您的Express最佳实践中的一部分 – assert API输入避免难以理解的漏洞,这类漏洞以后会非常难以追踪。而验证代码通常是一件乏味的事情,除非使用一些非常炫酷的帮助库比如Joi。
+
+**否则:** 考虑这种情况 – 您的功能期望一个数字参数 “Discount” ,然而调用者忘记传值,之后在您的代码中检查是否 Discount!=0 (允许的折扣值大于零),这样它将允许用户使用一个折扣。OMG,多么不爽的一个漏洞。你能明白吗?
+
+🔗 [**更多: 快速查错**](/sections/errorhandling/failfast.chinese.md)
+
+
+
+⬆ 返回顶部
+
+3. 编码风格实践
+
+## ![✔] 3.1 使用ESLint
+
+**TL;DR:** [ESLint](https://eslint.org)是检查可能的代码错误和修复代码样式的事实上的标准,不仅可以识别实际的间距问题, 而且还可以检测严重的反模式代码, 如开发人员在不分类的情况下抛出错误。尽管ESlint可以自动修复代码样式,但其他的工具比如[prettier](https://www.npmjs.com/package/prettier)和[beautify](https://www.npmjs.com/package/js-beautify)在格式化修复上功能强大,可以和Eslint结合起来使用。
+
+**否则:** 开发人员将必须关注单调乏味的间距和线宽问题, 并且时间可能会浪费在过多考虑项目的代码样式。
+
+
+
+## ![✔] 3.2 Node.js特定的插件
+
+**TL;DR:** 除了仅仅涉及 vanilla JS 的 ESLint 标准规则,添加 Node 相关的插件,比如[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)
+
+**否则:** 许多错误的Node.js代码模式可能在检测下逃生。例如,开发人员可能需要某些文件,把一个变量作为路径名 (variableAsPath) ,这会导致攻击者可以执行任何JS脚本。Node.JS linters可以检测这类模式,并及早预警。
+
+
+
+## ![✔] 3.3 在同一行开始一个代码块的大括号
+
+**TL;DR:** 代码块的第一个大括号应该和声明的起始保持在同一行中。
+
+### 代码示例
+```javascript
+ // 建议
+ function someFunction() {
+ // 代码块
+ }
+
+ // 避免
+ function someFunction
+ {
+ // 代码块
+ }
+```
+
+**否则:** 不遵守这项最佳实践可能导致意外的结果,在Stackoverflow的帖子中可以查看到,如下:
+
+🔗 [**更多:** "Why does a results vary based on curly brace placement?" (Stackoverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
+
+
+
+## ![✔] 3.4 不要忘记分号
+
+**TL;DR:** 即使没有获得一致的认同,但在每一个表达式后面放置分号还是值得推荐的。这将使您的代码, 对于其他阅读代码的开发者来说,可读性,明确性更强。
+
+**否则:** 在前面的章节里面已经提到,如果表达式的末尾没有添加分号,JavaScript的解释器会在自动添加一个,这可能会导致一些意想不到的结果。
+
+
+
+## ![✔] 3.5 命名您的方法
+
+**TL;DR:** 命名所有的方法,包含闭包和回调, 避免匿名方法。当剖析一个node应用的时候,这是特别有用的。命名所有的方法将会使您非常容易的理解内存快照中您正在查看的内容。
+
+**否则:** 使用一个核心dump(内存快照)调试线上问题,会是一项非常挑战的事项,因为你注意到的严重内存泄漏问题极有可能产生于匿名的方法。
+
+
+
+## ![✔] 3.6 变量、常量、函数和类的命名约定
+
+**TL;DR:** 当命名变量和方法的时候,使用 ***lowerCamelCase*** ,当命名类的时候,使用 ***UpperCamelCase*** (首字母大写),对于常量,则 ***UPPERCASE*** 。这将帮助您轻松地区分普通变量/函数和需要实例化的类。使用描述性名称,但使它们尽量简短。
+
+**否则:** JavaScript是世界上唯一一门不需要实例化,就可以直接调用构造函数("Class")的编码语言。因此,类和函数的构造函数由采用UpperCamelCase开始区分。
+
+### 代码示例 ###
+```javascript
+ // 使用UpperCamelCase命名类名
+ class SomeClassExample () {
+
+ // 常量使用const关键字,并使用lowerCamelCase命名
+ const config = {
+ key: 'value'
+ };
+
+ // 变量和方法使用lowerCamelCase命名
+ let someVariableExample = 'value';
+ function doSomething() {
+
+ }
+
+ }
+```
+
+
+
+## ![✔] 3.7 使用const优于let,废弃var
+
+**TL;DR:** 使用`const`意味着一旦一个变量被分配,它不能被重新分配。使用const将帮助您免于使用相同的变量用于不同的用途,并使你的代码更清晰。如果一个变量需要被重新分配,以在一个循环为例,使用`let`声明它。let的另一个重要方面是,使用let声明的变量只在定义它的块作用域中可用。 `var`是函数作用域,不是块级作用域,既然您有const和let让您随意使用,那么[不应该在ES6中使用var](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70)。
+
+**否则:** 当经常更改变量时,调试变得更麻烦了。
+
+🔗 [**更多: JavaScript ES6+: var, let, or const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 先require, 而不是在方法内部
+
+**TL;DR:** 在每个文件的起始位置,在任何函数的前面和外部require模块。这种简单的最佳实践,不仅能帮助您轻松快速地在文件顶部辨别出依赖关系,而且避免了一些潜在的问题。
+
+**否则:** 在Node.js中,require 是同步运行的。如果从函数中调用它们,它可能会阻塞其他请求,在更关键的时间得到处理。另外,如果所require的模块或它自己的任何依赖项抛出错误并使服务器崩溃,最好尽快查明它,如果该模块在函数中require的,则可能不是这样的情况。
+
+
+
+## ![✔] 3.9 在文件夹上 require ,而不是直接在文件上
+
+**TL;DR:** 当在一个文件夹中开发库/模块,放置一个文件index.js暴露模块的
+内部,这样每个消费者都会通过它。这将作为您模块的一个接口,并使未来的变化简单而不违反规则。
+
+**否则:** 更改文件内部结构或签名可能会破坏与客户端的接口。
+
+### 代码示例
+```javascript
+ // 建议
+ module.exports.SMSProvider = require('./SMSProvider');
+ module.exports.SMSNumberResolver = require('./SMSNumberResolver');
+
+ // 避免
+ module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
+ module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
+```
+
+
+
+
+## ![✔] 3.10 使用 `===` 操作符
+
+**TL;DR:** 对比弱等于 `==`,优先使用严格的全等于 `===` 。`==`将在它们转换为普通类型后比较两个变量。在 `===` 中没有类型转换,并且两个变量必须是相同的类型。
+
+**否则:** 与 `==` 操作符比较,不相等的变量可能会返回true。
+
+### 代码示例
+```javascript
+'' == '0' // false
+0 == '' // true
+0 == '0' // true
+
+false == 'false' // false
+false == '0' // true
+
+false == undefined // false
+false == null // false
+null == undefined // true
+
+' \t\r\n ' == 0 // true
+```
+如果使用`===`, 上面所有语句都将返回 false。
+
+
+
+## ![✔] 3.11 使用 Async Await, 避免回调
+
+**TL;DR:** Node 8 LTS现已全面支持异步等待。这是一种新的方式处理异步请求,取代回调和promise。Async-await是非阻塞的,它使异步代码看起来像是同步的。您可以给你的代码的最好的礼物是用async-await提供了一个更紧凑的,熟悉的,类似try catch的代码语法。
+
+**否则:** 使用回调的方式处理异步错误可能是陷入困境最快的方式 - 这种方式必须面对不停地检测错误,处理别扭的代码内嵌,难以推理编码流。
+
+🔗[**更多:** async await 1.0 引导](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 使用 (=>) 箭头函数
+
+**TL;DR:** 尽管使用 async-await 和避免方法作为参数是被推荐的, 但当处理那些接受promise和回调的老的API的时候 - 箭头函数使代码结构更加紧凑,并保持了根方法上的语义上下文 (例如 'this')。
+
+**否则:** 更长的代码(在ES5方法中)更易于产生缺陷,并读起来很是笨重。
+
+🔗 [**更多: 这是拥抱箭头函数的时刻**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
+
+
+
+
+⬆ 返回顶部
+
+
+4. 测试和总体的质量实践
+
+## ![✔] 4.1 至少,编写API(组件)测试
+
+**TL;DR:** 大多数项目只是因为时间表太短而没有进行任何自动化测试,或者测试项目失控而正被遗弃。因此,优先从API测试开始,这是最简单的编写和提供比单元测试更多覆盖率的事情(你甚至可能不需要编码而进行API测试,像[Postman](https://www.getpostman.com/)。之后,如果您有更多的资源和时间,继续使用高级测试类型,如单元测试、DB测试、性能测试等。
+
+**否则:** 您可能需要花很长时间编写单元测试,才发现只有20%的系统覆盖率。
+
+
+
+## ![✔] 4.2 使用一个linter检测代码问题
+
+**TL;DR:** 使用代码linter检查基本质量并及早检测反模式。在任何测试之前运行它, 并将其添加为预提交的git钩子, 以最小化审查和更正任何问题所需的时间。也可在[Section 3](https://github.com/i0natan/nodebestpractices#3-code-style-practices)中查阅编码样式实践
+
+**否则:** 您可能让一些反模式和易受攻击的代码传递到您的生产环境中。
+
+
+
+
+## ![✔] 4.3 仔细挑选您的持续集成(CI)平台
+
+**TL;DR:** 您的持续集成平台(cicd)将集成各种质量工具(如测试、lint),所以它应该是一个充满活力的生态系统,包含各种插件。[jenkins](https://jenkins.io/)曾经是许多项目的默认选项,因为它有最大的社区,同时也是一个非常强大的平台,这样的代价是要求一个陡峭的学习曲线。如今,使用SaaS工具,比如[CircleCI](https://circleci.com)及其他,安装一套CI解决方案,相对是一件容易的事情。这些工具允许构建灵活的CI管道,而无需管理整个基础设施。最终,这是一个鲁棒性和速度之间的权衡 - 仔细选择您支持的方案。
+
+**否则:** 一旦您需要一些高级定制,选择一些细分市场供应商可能会让您停滞不前。另一方面,伴随着jenkins,可能会在基础设施设置上浪费宝贵的时间。
+
+🔗 [**更多: 挑选 CI 平台**](/sections/testingandquality/citools.chinese.md)
+
+
+
+## ![✔] 4.4 经常检查易受攻击的依赖
+
+**TL;DR:** 即使是那些最有名的依赖模块,比如Express,也有已知的漏洞。使用社区和商业工具,比如 🔗 [nsp](https://github.com/nodesecurity/nsp) ,集成在您的CI平台上,在每一次构建的时候都会被调用,这样可以很容易地解决漏洞问题。
+
+**否则:** 在没有专用工具的情况下,使代码清除漏洞,需要不断地跟踪有关新威胁的在线出版物,相当繁琐。
+
+
+
+## ![✔] 4.5 测试标签化
+
+**TL;DR:** 不同的测试必须运行在不同的情景:quick smoke,IO-less,当开发者保存或提交一个文件,测试应该启动;完整的端到端的测试通常运行在一个新的pull request被提交之后,等等。这可以通过对测试用例设置标签,比如关键字像#cold #api #sanity,来完成。这样您可以对您的测试集进行grep,调用需要的子集。例如,这就是您通过[Mocha](https://mochajs.org/)仅仅调用sanity测试集所需要做的:mocha --grep 'sanity'。
+
+**否则:** 运行所有的测试,包括执行数据库查询的几十个测试,任何时候开发者进行小的改动都可能很慢,这使得开发者不愿意运行测试。
+
+
+
+## ![✔] 4.6 检查测试覆盖率,它有助于识别错误的测试模式
+
+**TL;DR:** 代码覆盖工具比如[Istanbul/NYC ](https://github.com/gotwarlost/istanbul),很好用有3个原因:它是免费的(获得这份报告不需要任何开销),它有助于确定测试覆盖率降低的部分,以及最后但非最不重要的是它指出了测试中的不匹配:通过查看颜色标记的代码覆盖报告您可以注意到,例如,从来不会被测到的代码片段像catch语句(即测试只是调用正确的路径,而不调用应用程序发生错误时的行为)。如果覆盖率低于某个阈值,则将其设置为失败的构建。
+
+**否则:** 当你的大部分代码没有被测试覆盖时,就不会有任何自动化的度量指标告诉你了。
+
+
+
+
+
+## ![✔] 4.7 检查过期的依赖包
+
+**TL;DR:** 使用您的首选工具 (例如 “npm outdated” or [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) 来检测已安装的过期依赖包, 将此检查注入您的 CI 管道, 甚至在严重的情况下使构建失败。例如, 当一个已安装的依赖包滞后5个补丁时 (例如:本地版本是1.3.1 的, 存储库版本是1.3.8 的), 或者它被其作者标记为已弃用, 可能会出现严重的情况 - 停掉这次构建并防止部署此版本。
+
+**否则:** 您的生产环境将运行已被其作者明确标记为有风险的依赖包
+
+
+
+## ![✔] 4.8 对于e2e testing,使用docker-compose
+
+**TL;DR:** 端对端(e2e)测试包含现场数据,由于它依赖于很多重型服务如数据库,习惯被认为是CI过程中最薄弱的环节。Docker-compose通过制定类似生产的环境,并使用一个简单的文本文件和简单的命令,轻松化解了这个问题。它为了e2e测试,允许制作所有相关服务,数据库和隔离网络。最后但并非最不重要的一点是,它可以保持一个无状态环境,该环境在每个测试套件之前被调用,然后立即消失。
+
+
+**否则:** 没有docker-compose,团队必须维护一个测试数据库在每一个测试环境上,包含开发机器,保持所有数据同步,这样测试结果不会因环境不同而不同。
+
+
+
+
+⬆ 返回顶部
+
+5. 上线实践
+
+## ![✔] 5.1. 监控!
+
+**TL;DR:** 监控是一种在顾客之前发现问题的游戏 – 显然这应该被赋予前所未有的重要性。考虑从定义你必须遵循的基本度量标准开始(我的建议在里面),到检查附加的花哨特性并选择解决所有问题的解决方案。市场已经淹没其中。点击下面的 ‘The Gist’ ,了解解决方案的概述。
+
+**否则:** 错误 === 失望的客户. 非常简单.
+
+
+🔗 [**更多: 监控!**](/sections/production/monitoring.chinese.md)
+
+
+
+## ![✔] 5.2. 使用智能日志增加透明度
+
+**TL;DR:** 日志可以是调试语句的一个不能说话的仓库,或者表述应用运行过程的一个漂亮仪表板的驱动。从第1天计划您的日志平台:如何收集、存储和分析日志,以确保所需信息(例如,错误率、通过服务和服务器等完成整个事务)都能被提取出来。
+
+**否则:** 您最终像是面对一个黑盒,不知道发生了什么事情,然后你开始重新写日志语句添加额外的信息。
+
+
+🔗 [**更多: 使用智能日志增加透明度**](/sections/production/smartlogging.chinese.md)
+
+
+
+## ![✔] 5.3. 委托一切可能的(例如:gzip,SSL)给反向代理
+
+**TL;DR:** Node处理CPU密集型任务,如gzipping,SSL termination等,表现糟糕。相反,使用一个 ‘真正’ 的中间件服务像Nginx,HAProxy或者云供应商的服务。
+
+**否则:** 可怜的单线程Node将不幸地忙于处理网络任务,而不是处理应用程序核心,性能会相应降低。
+
+
+🔗 [**更多: 委托一切可能的(例如:gzip,SSL)给反向代理**](/sections/production/delegatetoproxy.chinese.md)
+
+
+
+## ![✔] 5.4. 锁住依赖
+
+**TL;DR:** 您的代码必须在所有的环境中是相同的,但是令人惊讶的是,NPM默认情况下会让依赖在不同环境下发生偏移 – 当在不同的环境中安装包的时候,它试图拿包的最新版本。克服这种问题可以利用NPM配置文件, .npmrc,告诉每个环境保存准确的(不是最新的)包的版本。另外,对于更精细的控制,使用NPM “shrinkwrap”。*更新:作为NPM5,依赖默认锁定。新的包管理工具,Yarn,也默认锁定。
+
+**否则:** QA测试通过的代码和批准的版本,在生产中表现不一致。更糟糕的是,同一生产集群中的不同服务器可能运行不同的代码。
+
+
+🔗 [**更多: 锁住依赖**](/sections/production/lockdependencies.chinese.md)
+
+
+
+## ![✔] 5.5. 使用正确的工具保护进程正常运行
+
+**TL;DR:** 进程必须继续运行,并在失败时重新启动。对于简单的情况下,“重启”工具如PM2可能足够,但在今天的“Dockerized”世界 – 集群管理工具也值得考虑
+
+**否则:** 运行几十个实例没有明确的战略和太多的工具(集群管理,docker,PM2)可能导致一个DevOps混乱
+
+
+🔗 [**更多: 使用正确的工具保护进程正常运行**](/sections/production/guardprocess.chinese.md)
+
+
+
+
+## ![✔] 5.6. 利用CPU多核
+
+**TL;DR:** 在基本形式上,node应用程序运行在单个CPU核心上,而其他都处于空闲状态。复制node进程和利用多核,这是您的职责 – 对于中小应用,您可以使用Node Cluster和PM2. 对于一个大的应用,可以考虑使用一些Docker cluster(例如k8s,ECS)复制进程或基于Linux init system(例如systemd)的部署脚本
+
+**否则:** 您的应用可能只是使用了其可用资源中的25% (!),甚至更少。注意,一台典型的服务器有4个或更多的CPU,默认的Node.js部署仅仅用了一个CPU(甚至使用PaaS服务,比如AWS beanstalk,也一样)。
+
+
+🔗 [**更多: 利用所有的CPU**](/sections/production/utilizecpu.chinese.md)
+
+
+
+## ![✔] 5.7. 创建一个“维护端点”
+
+**TL;DR:** 在一个安全的API中暴露一组系统相关的信息,比如内存使用情况和REPL等等。尽管这里强烈建议依赖标准和作战测试工具,但一些有价值的信息和操作更容易使用代码完成。
+
+**否则:** 您会发现,您正在执行许多“诊断部署” – 将代码发送到生产中,仅仅只为了诊断目的提取一些信息。
+
+
+🔗 [**更多: 创建一个 '维护端点'**](/sections/production/createmaintenanceendpoint.chinese.md)
+
+
+
+## ![✔] 5.8. 使用APM产品发现错误和宕机时间
+
+**TL;DR:** 监控和性能的产品(即APM)先前一步地评估代码库和API,自动的超过传统的监测,并测量在服务和层级上的整体用户体验。例如,一些APM产品可以突显导致最终用户负载过慢的事务,同时指出根本原因。
+
+**否则:** 你可能会花大力气测量API性能和停机时间,也许你永远不会知道,真实场景下哪个是你最慢的代码部分,这些怎么影响用户体验。
+
+
+🔗 [**更多: 使用APM产品发现错误和宕机时间**](/sections/production/apmproducts.chinese.md)
+
+
+
+
+
+## ![✔] 5.9. 使您的代码保持生产环境就绪
+
+**TL;DR:** 在意识中抱着最终上线的想法进行编码,从第1天开始计划上线。这听起来有点模糊,所以我编写了一些与生产维护密切相关的开发技巧(点击下面的要点)
+
+**否则:** 一个世界冠军级别的IT/运维人员也不能拯救一个编码低劣的系统。
+
+
+🔗 [**更多: 使您的代码保持生产环境就绪**](/sections/production/productoncode.chinese.md)
+
+
+
+## ![✔] 5.10. 测量和保护内存使用
+
+**TL;DR:** Node.js和内存有引起争论的联系:V8引擎对内存的使用有稍微的限制(1.4GB),在node的代码里面有内存泄漏的很多途径 – 因此监视node的进程内存是必须的。在小应用程序中,你可以使用shell命令周期性地测量内存,但在中等规模的应用程序中,考虑把内存监控建成一个健壮的监控系统。
+
+**否则:** 您的内存可能一天泄漏一百兆,就像曾发生在沃尔玛的一样。
+
+
+🔗 [**更多: 测量和保护内存使用**](/sections/production/measurememory.chinese.md)
+
+
+
+
+## ![✔] 5.11. Node外管理您的前端资源
+
+**TL;DR:** 使用专门的中间件(nginx,S3,CDN)服务前端内容,这是因为在处理大量静态文件的时候,由于node的单线程模型,它的性能很受影响。
+
+**否则:** 您的单个node线程将忙于传输成百上千的html/图片/angular/react文件,而不是分配其所有的资源为了其擅长的任务 – 服务动态内容
+
+
+🔗 [**更多: Node外管理您的前端资源**](/sections/production/frontendout.chinese.md)
+
+
+
+
+## ![✔] 5.12. 保持无状态,几乎每天都要停下服务器
+
+**TL;DR:** 在外部数据存储上,存储任意类型数据(例如用户会话,缓存,上传文件)。考虑间隔地停掉您的服务器或者使用 ‘serverless’ 平台(例如 AWS Lambda),这是一个明确的强化无状态的行为。
+
+**否则:** 某个服务器上的故障将导致应用程序宕机,而不仅仅是停用故障机器。此外,由于依赖特定服务器,伸缩弹性会变得更具挑战性。
+
+
+🔗 [**更多: 保持无状态,几乎每天都要停下服务器**](/sections/production/bestateless.chinese.md)
+
+
+
+
+
+## ![✔] 5.13. 使用自动检测漏洞的工具
+
+**TL;DR:** 即使是最有信誉的依赖项,比如Express,会有使系统处于危险境地的已知漏洞(随着时间推移)。通过使用社区的或者商业工具,不时的检查漏洞和警告(本地或者Github上),这类问题很容易被抑制,有些问题甚至可以立即修补。
+
+**否则:** 否则: 在没有专用工具的情况下,使代码清除漏洞,需要不断地跟踪有关新威胁的在线出版物。相当繁琐。
+
+
+🔗 [**更多: 使用自动检测漏洞的工具**](/sections/production/detectvulnerabilities.chinese.md)
+
+
+
+
+## ![✔] 5.14. 在每一个log语句中指明 ‘TransactionId’
+
+**TL;DR:** 在每一个请求的每一条log入口,指明同一个标识符,transaction-id: {某些值}。然后在检查日志中的错误时,很容易总结出前后发生的事情。不幸的是,由于Node异步的天性自然,这是不容易办到的,看下代码里面的例子
+
+**否则:** 在没有上下文的情况下查看生产错误日志,这会使问题变得更加困难和缓慢去解决。
+
+
+🔗 [**更多: 在每一个log语句中指明 ‘TransactionId’**](/sections/production/assigntransactionid.chinese.md)
+
+
+
+
+## ![✔] 5.15. 设置NODE_ENV=production
+
+**TL;DR:** 设置环境变量NODE_ENV为‘production’ 或者 ‘development’,这是一个是否激活上线优化的标志 - 很多NPM的包通过它来判断当前的环境,据此优化生产环境代码。
+
+**否则:** 遗漏这个简单的属性可能大幅减弱性能。例如,在使用Express作为服务端渲染页面的时候,如果未设置NODE_ENV,性能将会减慢大概三分之一!
+
+
+🔗 [**更多: 设置NODE_ENV=production**](/sections/production/setnodeenv.chinese.md)
+
+
+
+
+
+## ![✔] 5.16. 设计自动化、原子化和零停机时间部署
+
+**TL;DR:** 研究表明,执行许多部署的团队降低了严重上线问题的可能性。不需要危险的手动步骤和服务停机时间的快速和自动化部署大大改善了部署过程。你应该达到使用Docker结合CI工具,使他们成为简化部署的行业标准。
+
+**否则:** 长时间部署 -> 线上宕机 & 和人相关的错误 -> 团队部署时不自信 -> 更少的部署和需求
+
+
+
+⬆ 返回顶部
+
+# `Security Practices`
+
+## Our contributors are working on this section. Would you like to join?
+
+
+# `Performance Practices`
+
+## Our contributors are working on this section. Would you like to join?
+
+
+
+
+# Milestones
+To maintain this guide and keep it up to date, we are constantly updating and improving the guidelines and best practices with the help of the community. You can follow our [milestones](https://github.com/i0natan/nodebestpractices/milestones) and join the working groups if you want to contribute to this project.
+
+
+
+# Contributors
+## `Yoni Goldberg`
+Independent Node.js consultant who works with customers at USA, Europe and Israel on building large-scale scalable Node applications. Many of the best practices above were first published on his blog post at [http://www.goldbergyoni.com](http://www.goldbergyoni.com). Reach Yoni at @goldbergyoni or me@goldbergyoni.com
+
+## `Ido Richter`
+👨💻 Software engineer, 🌐 web developer, 🤖 emojis enthusiast.
+
+## `Refael Ackermann` [@refack](https://github.com/refack) <refack@gmail.com> (he/him)
+Node.js Core Collaborator, been noding since 0.4, and have noded in multiple production sites. Founded `node4good` home of [`lodash-contrib`](https://github.com/node4good/lodash-contrib), [`formage`](https://github.com/node4good/formage), and [`asynctrace`](https://github.com/node4good/asynctrace).
+`refack` on freenode, Twitter, GitHub, GMail, and many other platforms. DMs are open, happy to help.
+
+## `Bruno Scheufler`
+💻 full-stack web developer and Node.js enthusiast.
+
+## `Kyle Martin` [@js-kyle](https://github.com/js-kyle)
+Full Stack Developer based in New Zealand, interested in architecting and building Node.js applications to perform at global scale. Keen contributor to open source software, including Node.js Core.
+
+
+
+
+# Thank You Notes
+
+This repository is being kept up to date thanks to the help from the community. We appreciate any contribution, from a single word fix to a new best practice. Below is a list of everyone who contributed to this project. A :sunflower: marks a successful pull request and a :star: marks an approved new best practice.
+
+### Flowers
+
+🌻 [Kevin Rambaud](https://github.com/kevinrambaud),
+🌻 [Michael Fine](https://github.com/mfine15),
+🌻 [Shreya Dahal](https://github.com/squgeim),
+🌻 [ChangJoo Park](https://github.com/ChangJoo-Park),
+🌻 [Matheus Cruz Rocha](https://github.com/matheusrocha89),
+🌻 [Yog Mehta](https://github.com/BitYog),
+🌻 [Kudakwashe Paradzayi](https://github.com/kudapara),
+🌻 [t1st3](https://github.com/t1st3),
+🌻 [mulijordan1976](https://github.com/mulijordan1976),
+🌻 [Matan Kushner](https://github.com/matchai),
+🌻 [Fabio Hiroki](https://github.com/fabiothiroki),
+🌻 [James Sumners](https://github.com/jsumners),
+🌻 [Chandan Rai](https://github.com/crowchirp),
+🌻 [Dan Gamble](https://github.com/dan-gamble),
+🌻 [PJ Trainor](https://github.com/trainorpj),
+🌻 [Remek Ambroziak](https://github.com/reod),
+🌻 [Yoni Jah](https://github.com/yonjah),
+🌻 [Misha Khokhlov](https://github.com/hazolsky),
+🌻 [Evgeny Orekhov](https://github.com/EvgenyOrekhov),
+🌻 [Gediminas Petrikas](https://github.com/gediminasml),
+🌻 [Isaac Halvorson](https://github.com/hisaac),
+🌻 [Vedran Karačić](https://github.com/vkaracic),
+🌻 [lallenlowe](https://github.com/lallenlowe),
+🌻 [Nathan Wells](https://github.com/nwwells),
+🌻 [Paulo Vítor S Reis](https://github.com/paulovitin),
+🌻 [syzer](https://github.com/syzer),
+🌻 [David Sancho](https://github.com/davesnx),
+🌻 [Robert Manolea](https://github.com/pupix),
+🌻 [Xavier Ho](https://github.com/spaxe),
+🌻 [Aaron Arney](https://github.com/ocularrhythm),
+🌻 [Jan Charles Maghirang Adona](https://github.com/septa97),
+🌻 [Allen Fang](https://github.com/AllenFang),
+🌻 [Leonardo Villela](https://github.com/leonardovillela),
+🌻 [Michal Zalecki](https://github.com/MichalZalecki)
+🌻 [Chris Nicola](https://github.com/chrisnicola),
+🌻 [Alejandro Corredor](https://github.com/aecorredor),
+🌻 [Ye Min Htut](https://github.com/ymhtut),
+🌻 [cwar](https://github.com/cwar),
+🌻 [Yuwei](https://github.com/keyfoxth),
+🌻 [Utkarsh Bhatt](https://github.com/utkarshbhatt12),
+🌻 [Duarte Mendes](https://github.com/duartemendes),
+🌻 [Sagir Khan](https://github.com/sagirk),
+🌻 [Jason Kim](https://github.com/serv),
+🌻 [Mitja O.](https://github.com/Max101),
+🌻 [Sandro Miguel Marques](https://github.com/SandroMiguel),
+🌻 [Gabe Kuslansky](https://github.com/GabeKuslansky),
+🌻 [Ron Gross](https://github.com/ripper234),
+🌻 [Valeri Karpov](https://github.com/vkarpov15)
+
+### Stars
+
+⭐ [Kyle Martin](https://github.com/js-kyle)
+⭐ [Keith Holliday](https://github.com/TheHollidayInn)
+
\ No newline at end of file
diff --git a/README.korean.md b/README.korean.md
index dc25a923e..3147d6dd2 100644
--- a/README.korean.md
+++ b/README.korean.md
@@ -1,749 +1,749 @@
-[✔]: assets/images/checkbox-small-blue.png
-
-# Node.js 모범 사례
-
-
-
-
-
-
-
-
-
-
-
-[![nodepractices](/assets/images/twitter-s.png)](https://twitter.com/nodepractices/) **트위터에서 팔로우 하세요!** [**@nodepractices**](https://twitter.com/nodepractices/)
-
-
-
-다른 언어로 읽기: [![CN](/assets/flags/CN.png)**CN**](/README.chinese.md) [(![ES](/assets/flags/ES.png)**ES**, ![FR](/assets/flags/FR.png)**FR**, ![HE](/assets/flags/HE.png)**HE**, ![KR](/assets/flags/KR.png)**KR**, ![RU](/assets/flags/RU.png)**RU**, ![TR](/assets/flags/TR.png)**TR** 는 작업중입니다!)](#translations)
-
-
-
-# 안녕하세요! 먼저 알아야 할 3가지가 있습니다:
-
-**1. 이 문서를 읽는 것은, 사실상 수십 개의 베스트 Node.js 문서를 읽는 것입니다. -** 이 문서는 Node.js 의 가장 인기 있는 모범사례(Best Practice)들을 모은 요약집 및 큐레이션입니다.
-
-**2. 가장 큰 모음집이며, 매주 성장하고 있습니다. -** 현재, 50개 이상의 모범사례들과, 스타일 가이드, 아키텍처적인 팁들이 제공되고 있습니다. 이 문서의 업데이트를 위해 새로운 이슈들과 PR들이 매일 만들어지고 있습니다. 우리는 이 문서의 잘못된 코드를 고치거나 새로운 아이디어들을 제안하는 것을 매우 환영합니다. [마일스톤 보러가기](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open)
-
-**3. 항목 대부분은 추가적인 정보가 있습니다 -** 항목 옆쪽에 존재하는 **🔗자세히 보기** 링크에서 코드 예제, 참조 블로그 또는 기타 정보들을 확인 할 수 있습니다.
-
-
-
-## 목차
-
-1. [프로젝트 구조 설계 (5)](#1-프로젝트-구조-설계)
-2. [에러 처리 방법 (11)](#2-에러-처리-방법)
-3. [코드 스타일 (12) ](#3-코드-스타일)
-4. [테스트 및 전체 품질 관리 (8) ](#4-테스트-및-전체-품질-관리)
-5. [운영 환경으로 전환하기 (16) ](#5-운영-환경으로-전환하기)
-6. 보안 ([예정](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
-7. 성능 ([예정](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
-
-
-
-# `1. 프로젝트 구조 설계`
-
-## ![✔] 1.1 컴포넌트 기반으로 설계하라
-
-**핵심요약:** 큰 프로젝트에서 빠지기 쉬운 최악의 함정은 많은 수백개의 의존성을 가진 커다란 소스코드를 유지보수하는 것이다. 그렇게 하나로 통째로 짜여진 코드는 개발자가 새로운 기능들을 협업하는 속도를 느려지게 한다. 그 대신에 당신의 코드를 컴포넌트로 나누고, 각각의 컴포넌트가 자신의 폴더 혹은 할당된 코드베이스를 가지게 하고 컴포넌트의 각 단위가 작고 간단하게 유지되도록 하라. 아래의 '자세히 보기'를 눌러 올바른 프로젝트 구조의 예시를 확인하라.
-
-**그렇게 하지 않을 경우:** 새로운 기능을 작성하는 개발자가 변경사항이 미치는 영향을 깨닫기위해 몸부림치거나 의존하고 있는 다른 컴포넌트를 망칠까봐 두려워 할때 배포는 느려지고 더 위험해진다. 비지니스 단위가 나눠져 있지 않으면 확장(scale-out)하기도 쉽지 않다.
-
-🔗 [**자세히 보기: 컴포넌트로 구조화하기**](/sections/projectstructre/breakintcomponents.korean.md)
-
-
-
-## ![✔] 1.2 컴포넌트를 계층화(layer)하고, Express를 그 경계 안에 둬라.
-
-**핵심요약:** 각각의 컴포넌트는 웹, 로직, 데이터 접근 코드을 위한 객체인 '계층'을 포함해야 한다. 이것은 우려를 깨끗하게 분리할 뿐만 아니라 모의 객체를 만들거나(mocking) 테스트하기가 굉장히 쉽게 만든다. 이것이 굉장히 일반적인 패턴임에도, API 개발자는 웹 계층의 객체 (Express req, res)를 비지니스 로직과 데이터 계층으로 보내서 계층을 뒤섞어버리는 경향이 있다. 그렇게 하는것은 당신의 어플리케이션에 의존성을 만들고 Express에서만 접근 가능하도록 만든다.
-
-**그렇게 하지 않을 경우:** 웹 객체를 다른 계층과 뒤섞은 앱은 테스트 코드, CRON 작업이나 Express가 아닌 다른 곳에서 접근이 불가능하게 한다.
-
-🔗 [**자세히 보기: 앱을 계층화하기**](/sections/projectstructre/createlayers.korean.md)
-
-
-
-## ![✔] 1.3 유틸리티들을 NPM 패키지로 감싸라(wrap)
-
-**핵심요약:** 커다란 코드 기반으로 구성되어있는 커다란 앱에서는 로깅, 암호화 같은 횡단 관심사(cross-cutting-concern)가 존재하는 유틸의 경우 당신 자신의 코드로 감싸져야하며 개인 NPM package로 노출이 되어야한다. 이것은 여러 코드 기반과 프로젝트들 사이에서 그것들을 공유가 가능하도록 해준다.
-
-**그렇게 하지 않을 경우:** 당신 자신만의 배포 및 의존성 바퀴(wheel)를 새로 발명해야 할 것이다.
-
-🔗 [**자세히 보기: 기능으로 구조화 하기**](/sections/projectstructre/wraputilities.korean.md)
-
-
-
-## ![✔] 1.4 Express의 app과 server를 분리하라
-
-**핵심요약:** 'Express' 정의를 적어도 API 선언(app.js)과 네트워크 부분(WWW)의 두 개 파일로 나눠서 전체 [Express](https://expressjs.com/)앱을 하나의 큰 파일에 정의하는 불쾌한 습관을 피해라. 더 좋은 구조는 API 선언을 컴포넌트에 위치시키는 것이다.
-
-**그렇게 하지 않을 경우:** API는 HTTP 요청으로만 테스트가 가능 할것이다(커버리지 보고서를 생성하기가 더 느려지고 훨씬 힘들어진다). 수백줄의 코드를 하나의 파일에서 관리하는 것이 크게 즐겁지는 않을 것이다.
-
-🔗 [**자세히 보기: Express를 'app'과 'server'로 분리하기**](/sections/projectstructre/separateexpress.korean.md)
-
-
-
-## ![✔] 1.5 환경을 인식하는, 보안적인, 계층적인 설정을 사용하라
-
-**핵심요약:** 완벽하고 결점이 없는 구성 설정은 (a) 파일과 환경 변수에서 키 값을 읽을 수 있어야하고 (b) 보안 값들은 커밋된 코드 바깥에서 관리되어야하고 (c) 설정은 좀 더 쉽게 찾을 수 있도록 계층적으로 관리해야 한다. [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config)와 같이 이러한 요구사항을 동작하게 해주는 몇가지 패키지가 존재한다.
-
-**그렇게 하지 않을 경우:** 위의 구성 요구사항 중 어느 것도 만족시키지 못한다면 개발팀 혹은 데브옵스팀을 늪으로 몰아갈 수 있다. 아마도 두 팀 모두일 것이다.
-
-🔗 [**자세히 보기: 구성 모범 사례**](/sections/projectstructre/configguide.korean.md)
-
-
-
-⬆ 목차로 돌아가기
-
-# `2. 에러 처리 방법`
-
-## ![✔] 2.1 비동기 에러 처리시에는 async-await 혹은 promise를 사용하라
-
-**핵심요약:** 비동기 에러를 콜백 스타일로 처리하는 것은 지옥으로 가는 급행열차일 것이다(운명의 피라미드로 잘 알려진). 당신이 코드에 줄 수 있는 가장 큰 선물은 평판이 좋은 promise 라이브러리를 사용하거나 훨신 작고 친숙한 코드 문법인 try-catch를 사용하게 해주는 async-await를 사용하는 것이다.
-
-**그렇게 하지 않을 경우:** Node.js 콜백 스타일인 function(err, response)는 에러 처리와 일반 코드의 혼합, 코드의 과도한 중첩, 이상한 코딩 패턴 때문에 유지보수가 불가능한 코드로가는 확실한 길이다.
-
-🔗 [**자세히 보기: 콜백 피하기**](/sections/errorhandling/asyncerrorhandling.korean.md)
-
-
-
-## ![✔] 2.2 내장된 Error 객체만 사용하라
-
-**핵심요약:** 많은 사람들이 문자열이나 사용자가 임의로 정의한 타입으로 에러를 던진다(throw). 이것은 에러처리 로직과 모듈 사이의 상호운영성을 복잡하게 한다. 당신이 promise를 거부(reject)하든, 예외를 던지든, 에러를 냈건 내장된 Error 객체를 이용하는 것은 균일성을 향상하고 정보의 손실을 방지하게 만들것이다.
-
-**그렇게 하지 않을 경우:** 일부 컴포넌트를 호출할때 어떤 에러의 타입이 반환될지 불확실해져서 적절한 에러처리가 매우 어려워 질것이다. 더 나쁜 것은, 사용자가 정의한 타입으로 에러를 나타내는 것은 스택 정보(stack trace)와 같은 중요한 에러 정보를 손실할 가능성이 있다는 것이다!
-
-🔗 [**자세히 보기: 내장된 Error 객체 사용하기**](/sections/errorhandling/useonlythebuiltinerror.korean.md)
-
-
-
-## ![✔] 2.3 동작상의 에러와 프로그래머 에러를 구분하라
-
-**핵심요약:** API에서 잘못된 입력을 받는 것과 같은 동작상의 에러는 에러의 영향을 완전히 이해할수 있고 신중하게 처리 할수있는 알려진 경우를 의미한다. 반면에 정의되지 않은 변수를 읽는 것과 같은 프로그래머 에러는 어플리케이션을 우아하게 다시 시작하도록 만드는 알수 없는 코드 에러를 의미한다.
-
-**그렇게 하지 않을 경우:** 당신은 에러가 날때마다 어플리케이션을 다시 시작할수도 있다. 하지만 왜 사소하고 예측가능한 동작상의 오류때문에 5000명의 온라인 사용자를 다운시키는 것인가? 나머지 상황 또한 이상적이지 않다. 알수없는 이슈(프로그래머 에러)가 났는데 어플리케이션을 그대로 두는 것은 예측이 불가능한 동작을 일으킬 수 있다. 두 가지를 구별하는 것은 현명한 행동과 주어진 상황에 따른 균형잡힌 접근을 가능하게 한다.
-
-🔗 [**자세히 보기: 동작상의 에러와 프로그래머 에러**](/sections/errorhandling/operationalvsprogrammererror.korean.md)
-
-
-
-## ![✔] 2.4 에러를 Express 미들웨어로 처리하지 말고 중앙집중적으로 처리하라
-
-**핵심요약:** 관리자에게 메일을 보내거나 로깅을 하는 것과 같은 에러 처리는 에러가 발생할 때 모든 엔드포인트(예를 들어 Express 미들웨어, cron 작업, 단위 테스트 등)가 호출하는 에러전용 중앙집중 객체로 캡슐화 되어야한다.
-
-**그렇게 하지 않을 경우:** 한 곳에서 에러를 처리하지 않는 것은 코드 중복과 부적절한 에러처리로 이어진다.
-
-🔗 [**자세히 보기: 중앙집중적으로 에러 처리하기**](/sections/errorhandling/centralizedhandling.korean.md)
-
-
-
-## ![✔] 2.5 Swagger를 이용해 API 에러를 문서화하라
-
-**핵심요약:** API를 호출한 사람들이 어떤 에러가 반환 될수 있는지 알게하여 충돌없이 신중하게 처리 할 수 있도록하라. 이것은 보통 Swagger와 같은 API 문서화 프레임워크를 통해 이루어진다.
-
-**그렇게 하지 않을 경우:** API 클라이언트는 알수 없는 에러로 인해 충돌 후에 재시작을 결정할수도 있을 것이다. 참고: 당신의 API를 호출한 사람이 당신 자신 일수도 있다.(마이크로서비스 환경에서는 아주 일반적임).
-
-🔗 [**자세히 보기: Swagger에서 에러 문서화하기**](/sections/errorhandling/documentingusingswagger.korean.md)
-
-
-
-## ![✔] 2.6 이상한 것이 들어왔을때 프로세스를 정상적으로 중단하라
-
-**핵심요약:** 알수 없는 에러(프로그래머 에러, 모범사례 #3번 참조)가 발생하면 어플리케이션의 건강상태에 대한 불확실성이 있다. 일반적인 방법은 Forever와 PM2 같은 '재시작' 도구로 프로세스를 다시 시작하는 것이다.
-
-**그렇게 하지 않을 경우:** 익숙치 않은 예외가 발생하면 일부 객체가 오류 상태(예를 들어 전역적으로 사용되지만 내부 오류로 인해 이벤트를 더이상 발생시키지 않는 Event Emitter)일 수 있으며 향후의 모든 요청이 실패하거나 미친것처럼(crazily) 동작할 수 있다.
-
-🔗 [**자세히 보기: 프로세스 중단하기**](/sections/errorhandling/shuttingtheprocess.korean.md)
-
-
-
-## ![✔] 2.7 에러 확인을 용이하게 해주는 로거를 사용하라
-
-**핵심요약:** Winston, Bunyan 혹은 Log4J와 같은 발전된 로깅 도구의 집합은 에러를 찾는 것과 이해하는 것의 속도를 높여준다. 그러니 console.log를 잊어버려라.
-
-**그렇게 하지 않을 경우:** 로그 검색 도구나 괜찮은 로그 뷰어 없이 console.log 혹은 지저분한 텍스트 파일을 대충 읽는 것은 야근을 부를 수 있다.
-
-🔗 [**자세히 보기: 발전된 로거를 사용하기**](/sections/errorhandling/usematurelogger.korean.md)
-
-
-
-## ![✔] 2.8 당신이 선호하는 테스트 프레임워크로 에러 흐름을 테스트하라
-
-**핵심요약:** 전문 자동화 QA든 일반 수동 개발자 테스트든 당신의 코드가 긍정적인 상황에서 잘 동작할 뿐만 아니라 올바른 에러를 처리하고 반환하는지 확실히 하라. Mocha & Chai와 같은 테스트 프레임워크는 이것을 쉽게 처리 할수 있다("Gist popup"안의 코드 예제를 확인하라).
-
-**그렇게 하지 않을 경우:** 자동이든 수동이든 테스트가 없다면 당신은 당신의 코드가 올바른 에러를 반환하는지 믿지 못할 것이다. 의미가 있는 에러가 없다면 에러 처리는 없는 것이다.
-
-🔗 [**자세히 보기: 에러 흐름 테스트하기**](/sections/errorhandling/testingerrorflows.korean.md)
-
-
-
-## ![✔] 2.9 APM 제품을 사용하여 에러와 다운타임을 확인하라
-
-**핵심요약:** APM이라고 불리는 모니터링 및 성능 제품은 미리 알아서 코드베이스와 API를 측정하고 자동적으로 당신이 놓친 에러, 충돌, 느린부분을 강조 표시해준다.
-
-**그렇게 하지 않을 경우:** API의 성능과 다운타임을 측정하기위해 많은 노력을 들여야 할지도 모른다. 아마 당신은 실제 상황에서 어떤 코드 부분이 가장 느린지, 그것이 UX에 어떻게 영향을 미칠지 절대 알수없을 것이다.
-
-🔗 [**자세히 보기: APM 제품 사용하기**](/sections/errorhandling/apmproducts.korean.md)
-
-
-
-## ![✔] 2.10 처리되지 않은 promise 거부(unhandled promise rejection)를 잡아라
-
-**핵심요약:** promise안에서 발생한 예외는 개발자가 명시적으로 처리하는 것을 잊게되면 삼켜지고 버려지게 된다. 당신의 코드가 process.uncaughtException 이벤트를 구독하고 있다고해도 말이다! 이것을 극복하기위해 process.unhandledRejection 이벤트를 등록하라.
-
-**그렇게 하지 않을 경우:** 당신의 에러는 삼켜지고 어떤 흔적도 남기지 않을 것이다. 걱정할 것이 없긴 하다.
-
-🔗 [**자세히 보기: 처리되지 않은 promise 거부 잡기**](/sections/errorhandling/catchunhandledpromiserejection.korean.md)
-
-
-
-## ![✔] 2.11 전용 라이브러리를 이용해 인자값이 유효한지 검사하여 빠르게 실패하라(fail fast)
-
-**핵심요약:** 나중에 처리하기가 더 힘들어지는 지저분한 버그를 피하기 위해 Assert API입력은 당신의 Express 모범사례가 되어야 한다. 당신이 Joi와 같은 유용한 헬퍼 라이브러리를 사용하지 않는 이상 유효성 검사 코드는 일반적으로 지루하다.
-
-**그렇게 하지 않을 경우:** 이런 상황을 생각해보자. 당신의 함수가 "Discount"라는 숫자를 받아야하는데 요청하는 사람이 넘겨주는 것을 깜빡했다. 그 후에 당신의 코드는 Discount!=0인지 아닌지 체크한다(사실 허용된 Discount의 값은 0보다 커야 한다). 그러면 사용자가 할인을 받게될 것이다. 보이는가? 엄청나게 지저분한 버그이다.
-
-🔗 [**자세히 보기: 빠르게 실패하기**](/sections/errorhandling/failfast.korean.md)
-
-
-
-⬆ 목차로 돌아가기
-
-# `3. 코드 스타일`
-
-## ![✔] 3.1 ESLint를 사용하라
-
-**핵심요약:** [ESLint](https://eslint.org)는 발생 가능한 코드 에러를 체크하고 껄끄러운 간격(spacing)문제를 식별하는 것부터 프로그래머가 분별없이 에러를 던지는 것과 같은 코드의 심각한 안티 패턴을 감지하여 코드 스타일을 바꾸는 것에 대한 사실상의 표준이다. ESLint도 자동으로 코드스타일을 고칠 수 있지만 [prettier](https://www.npmjs.com/package/prettier)와 [beautify](https://www.npmjs.com/package/js-beautify)같은 수정 부분의 포맷을 맞춰주는 강력한 툴이 있고 ESLint와 함께 작동된다.
-
-**그렇게 하지 않을 경우:** 프로그래머가 쓸데없는 간격과 한줄의 길이(line-width) 문제에 대해서 집중해야하고 프로젝트의 코드스타일에 대해 과도하게 생각하느라 시간을 낭비해야할 수도 있다.
-
-
-
-## ![✔] 3.2 Node.js에 특화된 플러그인들
-
-**핵심요약:** vanlla JS만 지원하는 ESLinst의 표준 규칙 위에 [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha), [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security)와 같은 Node에 특화된 플러그인을 같이 사용하라.
-
-**그렇게 하지 않을 경우:** 많은 결함이 있는 Node.js 코드 패턴들이 레이더에서 벗어날 수 있다. 예를 들어 프로그래머는 변수로된 파일경로를 이용해 `require(파일경로변수)`로 파일을 가져올수 있다. 이것은 공격자들이 어떤 JS script도 실행시킬 수 있게 한다. Node.js linter는 그러한 패턴을 감지하고 미리 알려준다.
-
-
-
-## ![✔] 3.3 코드 블록의 중괄호를 같은 줄에서 시작하라
-
-**핵심요약:** 블록에서 중괄호를 여는 부분은 코드를 여는 문장과 같은 줄에 있어야 한다.
-
-### 코드 예제
-
-```javascript
-// Do
-function someFunction() {
- // code block
-}
-
-// Avoid
-function someFunction()
-{
- // code block
-}
-```
-
-**그렇게 하지 않을 경우:** 이 모범사례를 적용하지 않는 것은 아래의 Stackoverflow 스레드에서 보는 바와 같이 예기치못한 결과로 이어질 수 있다.
-
-🔗 [**자세히 보기:** "왜 결과가 중괄호의 위치에 따라 달라지는 거죠?" (Stackoverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
-
-
-
-## ![✔] 3.4 세미콜론을 잊지 마라
-
-**핵심요약:** 만장일치로 동의하지는 않겠지만 각 문장의 끝에 세미콜론을 붙이는 것은 여전히 권장사항이다. 이것은 당신의 코드를 읽는 다른 프로그래머가 좀더 잘 읽게하고 명확하게 할것이다.
-
-**그렇게 하지 않을 경우:** 이전 섹션에서 본것처럼 자바스크립트의 인터프리터는 세미콜론이 없으면 의도되지 않은 결과를 야기할수 있기에 자동으로 문장의 끝에 세미콜론을 붙인다.
-
-
-
-## ![✔] 3.5 함수에 이름을 붙여라
-
-**핵심요약:** 클로저와 콜백을 포함한 모든 함수에 이름을 붙여라. 익명함수를 피해라. 이것은 노드 앱을 프로파일링 할때 특히 유용하다. 모든 함수를 명명하는 것은 당신이 메모리 스냅샷을 확인할때 당신이 보고있는 것이 무엇인지 쉽게 이해 할수있도록 해준다.
-
-**그렇게 하지 않을 경우:**
-당신이 익명함수에서 메모리 소비가 많다는 것을 확인 했을 때 코어 덤프(메모리 스냅샷)을 이용해 프로덕션 문제를 디버깅하는 것이 어려울 수도 있습니다.
-
-
-
-## ![✔] 3.6 변수, 상수, 함수, 클래스의 명명 규칙(naming convention)
-
-**핵심요약:** 상수와 변수 함수를 명명할때는 **_lowerCamelCase_** 를 사용하고 클래스를 명명 할때는 **_UpperCamelCase_**(첫 글자 대문자)를 사용하라. 이것은 일반 변수/함수와 인스턴스로 만들어야 하는 클래스를 구분하는데 도움을 것이다. 설명이 포함된 이름을 사용하되 이름을 짧게 유지하도록 해라.
-
-**그렇게 하지 않을 경우:** 자바스크립트는 먼저 인스턴스로 만들지 않고 직접 생성자("Class")를 호출할 수 있는 세계 유일의 언어이다. 그러므로 클래스와 함수생성자는 UpperCamelCase를 통해 구분된다.
-
-### 코드예제
-
-```javascript
-// 클래스명은 UpperCamelCase 사용
-class SomeClassExample {}
-
-// 상수명은 const 키워드와 lowerCamelCase 사용
-const config = {
- key: 'value'
-};
-
-// 변수와 함수 이름은 lowerCamelCase 사용
-let someVariableExample = 'value';
-function doSomething() {}
-```
-
-
-
-## ![✔] 3.7 let보다는 const를 사용하라. var는 갖다버려라
-
-**핵심요약:** `const`를 사용한다는 것은 변수에 한번 값이 할당되면 다시 할당할 수 없다는 것을 의미한다. `const`를 선호하는 것은 같은 변수를 다른 용도로 사용하는 것을 방지하고 당신의 코드를 더 깔끔하게 만드는데 도움을 준다. for루프처럼 변수가 재할당 되어야 할 필요가 있으면 `let`을 사용하여 선언하라. `let`의 또 다른 중요한 부분은 선언된 변수를 사용하는 것이 변수가 정의된 블록범위(block scope) 안에서만 가능하다는 것이다. `var`는 블록범위가 아니라 함수범위(function scope)이며 이제 대신할 수 있는 const와 let이 있으므로 [ES6에서는 사용하면 안된다](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70).
-
-**그렇게 하지 않을 경우:** 자주 변경되는 변수를 따라가려면 디버깅이 훨씬 더 번거로워 진다.
-
-🔗 [**자세히 보기: JavaScript ES6+: var 혹은 let 혹은 const?**](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
-
-
-
-## ![✔] 3.8 require는 맨 처음에 오게하고 함수 안에서의 사용은 피하라
-
-**핵심요약:** 모듈을 각 파일의 시작이나 모든 함수의 앞부분 혹은 밖에서 require하라. 이 간단한 모범사례는 파일의 의존성을 맨 위에서 쉽고 빠르게 구분 할수 있게 해줄 뿐만 아니라 여러 잠재적인 문제를 피하게 해준다.
-
-**그렇게 하지 않을 경우:** require는 Node.js에서 동기로 실행된다. 함수 안에서 호출되면 다른 요청들을 더 중요한 시간에 처리되지 못하도록 막을 수 있다. 또한 require된 모듈이나 그것의 의존 모듈이 에러를 뱉거나 서버를 다운시키면, 함수 안에서 그 모듈이 require된 것이 아닌지 가능한 아주 빠르게 찾아야 할 것이다.
-
-
-
-## ![✔] 3.9 require는 파일에 직접하지말고 폴더에 하라
-
-**핵심요약:** 폴더에서 모듈과 라이브러리를 개발할 때 모든 소비자가 그것을 거치도록 모듈의 내부를 노출하는 index.js 파일을 둬라. 이것은 모듈의 '인터페이스'역할을 하며 계약을 위반하지 않으면서 미래의 변경사항에 대해 유연하게 대처하도록 해준다.
-
-**그렇게 하지 않을 경우:** 파일 내부의 구조 혹은 서명을 변경하면 클라이언트와의 인터페이스가 손상될 수 있다.
-
-### 코드 예제
-
-```javascript
-// 이렇게 하라
-module.exports.SMSProvider = require('./SMSProvider');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver');
-
-// 피하라
-module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
-```
-
-
-
-## ![✔] 3.10 `===` 연산자를 사용하라
-
-**핵심요약:** 약하고 추상적인 같음연산자 `==` 보다 엄격한 항등연산자 `===`를 선호한다. `==`는 두 변수를 공용 타입으로 변환한 후에 비교한다. `===`에는 타입 변환이 없고 두 변수가 같으려면 타입도 같아야 한다.
-
-**그렇게 하지 않을 경우:** `==`으로 비교하는 경우 같지 않은 변수가 true로 반환 될 수있다.
-
-### 코드 예제
-
-```javascript
-'' == '0' // false
-0 == '' // true
-0 == '0' // true
-
-false == 'false' // false
-false == '0' // true
-
-false == undefined // false
-false == null // false
-null == undefined // true
-
-' \t\r\n ' == 0 // true
-```
-
-위의 모든 문장은 `===`를 사용했다면 false를 반환 했을것이다.
-
-
-
-## ![✔] 3.11 async-await을 사용하고 콜백을 피하라
-
-**핵심요약:** Node 8의 LTS 버전은 현재 async-await을 완전히 지원한다. 이것은 콜백과 promise를 대체하여 비동기 코드를 다루는 새로운 방법이다. async-await은 비차단적(non-blocking)이고 비동기 코드를 동기 코드처럼 보이게 만든다. 당신의 코드에게 줄수 있는 최고의 선물은 try-catch와 같은 더 작고 친숙한 코드 구문을 제공하는 async-await을 사용하는 것이다.
-
-**그렇게 하지 않을 경우:** 콜백 스타일로 비동기 에러를 처리하는 것은 아마도 지옥으로 가는 가장 빠른 방법일것이다. 이런 스타일은 에러를 전부 확인하게 하고 어색한 코드 중첩을 다루게하며 코드 흐름을 추론하기 어렵게 만든다.
-
-🔗[**자세히 보기: async-await 1.0 가이드**](https://github.com/yortus/asyncawait)
-
-
-
-## ![✔] 3.12 두꺼운(=>) 화살표 함수를 사용하라
-
-**핵심요약:** async-await을 사용하고 함수 인자를 사용하는 것을 피하는 것이 권장되지만 promise와 콜백을 받는 예전 API를 다룰 때는 화살표 함수가 코드 구조를 더 작게해주고 루트 함수의 어휘적 맥락(lexical context)을 유지시켜 준다. (예를 들어 'this')
-
-**그렇게 하지 않을 경우:** 더 긴 코드(ES5의 function)은 버그에 더 취약하고 읽기가 번거롭다.
-
-🔗 [**Read mode: 화살표 함수를 받아들일 시간이다**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
-
-
-
-⬆ 목차로 돌아가기
-
-# `4. 테스트 및 전체 품질 관리`
-
-## ![✔] 4.1 At the very least, write API (component) testing
-
-**핵심요약:** Most projects just don't have any automated testing due to short timetables or often the 'testing project' run out of control and being abandoned. For that reason, prioritize and start with API testing which is the easiest to write and provide more coverage than unit testing (you may even craft API tests without code using tools like [Postman](https://www.getpostman.com/). Afterward, should you have more resources and time, continue with advanced test types like unit testing, DB testing, performance testing, etc
-
-**그렇게 하지 않을 경우:** You may spend long days on writing unit tests to find out that you got only 20% system coverage
-
-
-
-## ![✔] 4.2 Detect code issues with a linter
-
-**핵심요약:** Use a code linter to check basic quality and detect anti-patterns early. Run it before any test and add it as a pre-commit git-hook to minimize the time needed to review and correct any issue. Also check [Section 3](https://github.com/i0natan/nodebestpractices#3-code-style-practices) on Code Style Practices
-
-**그렇게 하지 않을 경우:** You may let pass some anti-pattern and possible vulnerable code to your production environment.
-
-
-
-## ![✔] 4.3 Carefully choose your CI platform (Jenkins vs CircleCI vs Travis vs Rest of the world)
-
-**핵심요약:** Your continuous integration platform (CICD) will host all the quality tools (e.g test, lint) so it should come with a vibrant ecosystem of plugins. [Jenkins](https://jenkins.io/) used to be the default for many projects as it has the biggest community along with a very powerful platform at the price of complex setup that demands a steep learning curve. Nowadays, it became much easier to set up a CI solution using SaaS tools like [CircleCI](https://circleci.com) and others. These tools allow crafting a flexible CI pipeline without the burden of managing the whole infrastructure. Eventually, it's a trade-off between robustness and speed - choose your side carefully
-
-**그렇게 하지 않을 경우:** Choosing some niche vendor might get you blocked once you need some advanced customization. On the other hand, going with Jenkins might burn precious time on infrastructure setup
-
-🔗 [**자세히 보기: Choosing CI platform**](/sections/testingandquality/citools.korean.md)
-
-
-
-## ![✔] 4.4 Constantly inspect for vulnerable dependencies
-
-**핵심요약:** Even the most reputable dependencies such as Express have known vulnerabilities. This can get easily tamed using community and commercial tools such as 🔗 [nsp](https://github.com/nodesecurity/nsp) that can be invoked from your CI on every build
-
-**그렇게 하지 않을 경우:** Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
-
-
-
-## ![✔] 4.5 Tag your tests
-
-**핵심요약:** Different tests must run on different scenarios: quick smoke, IO-less, tests should run when a developer saves or commits a file, full end-to-end tests usually run when a new pull request is submitted, etc. This can be achieved by tagging tests with keywords like #cold #api #sanity so you can grep with your testing harness and invoke the desired subset. For example, this is how you would invoke only the sanity test group with [Mocha](https://mochajs.org/): mocha --grep 'sanity'
-
-**그렇게 하지 않을 경우:** Running all the tests, including tests that perform dozens of DB queries, any time a developer makes a small change can be extremely slow and keeps developers away from running tests
-
-
-
-## ![✔] 4.6 Check your test coverage, it helps to identify wrong test patterns
-
-**핵심요약:** Code coverage tools like [Istanbul/NYC ](https://github.com/gotwarlost/istanbul)are great for 3 reasons: it comes for free (no effort is required to benefit this reports), it helps to identify a decrease in testing coverage, and last but not least it highlights testing mismatches: by looking at colored code coverage reports you may notice, for example, code areas that are never tested like catch clauses (meaning that tests only invoke the happy paths and not how the app behaves on errors). Set it to fail builds if the coverage falls under a certain threshold
-
-**그렇게 하지 않을 경우:** There won't be any automated metric telling you when a large portion of your code is not covered by testing
-
-
-
-## ![✔] 4.7 Inspect for outdated packages
-
-**핵심요약:** Use your preferred tool (e.g. 'npm outdated' or [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) to detect installed packages which are outdated, inject this check into your CI pipeline and even make a build fail in a severe scenario. For example, a severe scenario might be when an installed package is 5 patch commits behind (e.g. local version is 1.3.1 and repository version is 1.3.8) or it is tagged as deprecated by its author - kill the build and prevent deploying this version
-
-**그렇게 하지 않을 경우:** Your production will run packages that have been explicitly tagged by their author as risky
-
-
-
-## ![✔] 4.8 Use docker-compose for e2e testing
-
-**핵심요약:** End to end (e2e) testing which includes live data used to be the weakest link of the CI process as it depends on multiple heavy services like DB. Docker-compose turns this problem into a breeze by crafting production-like environment using a simple text file and easy commands. It allows crafting all the dependent services, DB and isolated network for e2e testing. Last but not least, it can keep a stateless environment that is invoked before each test suite and dies right after
-
-**그렇게 하지 않을 경우:** Without docker-compose teams must maintain a testing DB for each testing environment including developers machines, keep all those DBs in sync so test results won't vary across environments
-
-
-
-⬆ 목차로 돌아가기
-
-# `5. 운영 환경으로 전환하기`
-
-## ![✔] 5.1. Monitoring!
-
-**핵심요약:** Monitoring is a game of finding out issues before customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my suggestions inside), then go over additional fancy features and choose the solution that ticks all boxes. Click ‘The Gist’ below for an overview of the solutions
-
-**그렇게 하지 않을 경우:** Failure === disappointed customers. Simple
-
-🔗 [**자세히 보기: Monitoring!**](/sections/production/monitoring.korean.md)
-
-
-
-## ![✔] 5.2. Increase transparency using smart logging
-
-**핵심요약:** Logs can be a dumb warehouse of debug statements or the enabler of a beautiful dashboard that tells the story of your app. Plan your logging platform from day 1: how logs are collected, stored and analyzed to ensure that the desired information (e.g. error rate, following an entire transaction through services and servers, etc) can really be extracted
-
-**그렇게 하지 않을 경우:** You end-up with a black box that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**자세히 보기: Increase transparency using smart logging**](/sections/production/smartlogging.korean.md)
-
-
-
-## ![✔] 5.3. Delegate anything possible (e.g. gzip, SSL) to a reverse proxy
-
-**핵심요약:** Node is awfully bad at doing CPU intensive tasks like gzipping, SSL termination, etc. You should use ‘real’ middleware services like nginx, HAproxy or cloud vendor services instead
-
-**그렇게 하지 않을 경우:** Your poor single thread will stay busy doing infrastructural tasks instead of dealing with your application core and performance will degrade accordingly
-
-🔗 [**자세히 보기: Delegate anything possible (e.g. gzip, SSL) to a reverse proxy**](/sections/production/delegatetoproxy.korean.md)
-
-
-
-## ![✔] 5.4. Lock dependencies
-
-**핵심요약:** Your code must be identical across all environments, but amazingly NPM lets dependencies drift across environments by default – when you install packages at various environments it tries to fetch packages’ latest patch version. Overcome this by using NPM config files, .npmrc, that tell each environment to save the exact (not the latest) version of each package. Alternatively, for finer grain control use NPM” shrinkwrap”. \*Update: as of NPM5, dependencies are locked by default. The new package manager in town, Yarn, also got us covered by default
-
-**그렇게 하지 않을 경우:** QA will thoroughly test the code and approve a version that will behave differently at production. Even worse, different servers at the same production cluster might run different code
-
-🔗 [**자세히 보기: Lock dependencies**](/sections/production/lockdependencies.korean.md)
-
-
-
-## ![✔] 5.5. Guard process uptime using the right tool
-
-**핵심요약:** The process must go on and get restarted upon failures. For simple scenarios, ‘restarter’ tools like PM2 might be enough but in today ‘dockerized’ world – a cluster management tools should be considered as well
-
-**그렇게 하지 않을 경우:** Running dozens of instances without a clear strategy and too many tools together (cluster management, docker, PM2) might lead to a DevOps chaos
-
-🔗 [**자세히 보기: Guard process uptime using the right tool**](/sections/production/guardprocess.korean.md)
-
-
-
-## ![✔] 5.6. Utilize all CPU cores
-
-**핵심요약:** 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)
-
-**그렇게 하지 않을 경우:** 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!)
-
-🔗 [**자세히 보기: Utilize all CPU cores**](/sections/production/utilizecpu.korean.md)
-
-
-
-## ![✔] 5.7. Create a ‘maintenance endpoint’
-
-**핵심요약:** Expose a set of system-related information, like memory usage and REPL, etc in a secured API. Although it’s highly recommended to rely on standard and battle-tests tools, some valuable information and operations are easier done using code
-
-**그렇게 하지 않을 경우:** You’ll find that you’re performing many “diagnostic deploys” – shipping code to production only to extract some information for diagnostic purposes
-
-🔗 [**자세히 보기: Create a ‘maintenance endpoint’**](/sections/production/createmaintenanceendpoint.korean.md)
-
-
-
-## ![✔] 5.8. Discover errors and downtime using APM products
-
-**핵심요약:** Monitoring and performance products (a.k.a APM) proactively gauge codebase and API so they can auto-magically go beyond traditional monitoring and measure the overall user-experience across services and tiers. For example, some APM products can highlight a transaction that loads too slow on the end-users side while suggesting the root cause
-
-**그렇게 하지 않을 경우:** You might spend great effort on measuring API performance and downtimes, probably you’ll never be aware which is your slowest code parts under real-world scenario and how these affects the UX
-
-🔗 [**자세히 보기: Discover errors and downtime using APM products**](/sections/production/apmproducts.korean.md)
-
-
-
-## ![✔] 5.9. Make your code production-ready
-
-**핵심요약:** Code with the end in mind, plan for production from day 1. This sounds a bit vague so I’ve compiled a few development tips that are closely related to production maintenance (click Gist below)
-
-**그렇게 하지 않을 경우:** A world champion IT/DevOps guy won’t save a system that is badly written
-
-🔗 [**자세히 보기: Make your code production-ready**](/sections/production/productoncode.korean.md)
-
-
-
-## ![✔] 5.10. Measure and guard the memory usage
-
-**핵심요약:** Node.js has controversial relationships with memory: the v8 engine has soft limits on memory usage (1.4GB) and there are known paths to leaks memory in Node’s code – thus watching Node’s process memory is a must. In small apps, you may gauge memory periodically using shell commands but in medium-large app consider baking your memory watch into a robust monitoring system
-
-**그렇게 하지 않을 경우:** Your process memory might leak a hundred megabytes a day like how it happened at [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)
-
-🔗 [**자세히 보기: Measure and guard the memory usage**](/sections/production/measurememory.korean.md)
-
-
-
-## ![✔] 5.11. Get your frontend assets out of Node
-
-**핵심요약:** 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
-
-**그렇게 하지 않을 경우:** 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
-
-🔗 [**자세히 보기: Get your frontend assets out of Node**](/sections/production/frontendout.korean.md)
-
-
-
-## ![✔] 5.12. Be stateless, kill your Servers almost every day
-
-**핵심요약:** Store any type of data (e.g. users session, cache, uploaded files) within external data stores. Consider ‘killing’ your servers periodically or use ‘serverless’ platform (e.g. AWS Lambda) that explicitly enforces a stateless behavior
-
-**그렇게 하지 않을 경우:** Failure at a given server will result in application downtime instead of just killing a faulty machine. Moreover, scaling-out elasticity will get more challenging due to the reliance on a specific server
-
-🔗 [**자세히 보기: Be stateless, kill your Servers almost every day**](/sections/production/bestateless.korean.md)
-
-
-
-## ![✔] 5.13. Use tools that automatically detect vulnerabilities
-
-**핵심요약:** Even the most reputable dependencies such as Express have known vulnerabilities (from time to time) that can put a system at risk. This can get easily tamed using community and commercial tools that constantly check for vulnerabilities and warn (locally or at GitHub), some can even patch them immediately
-
-**그렇게 하지 않을 경우:** 그렇게 하지 않을 경우: Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
-
-🔗 [**자세히 보기: Use tools that automatically detect vulnerabilities**](/sections/production/detectvulnerabilities.korean.md)
-
-
-
-## ![✔] 5.14. Assign ‘TransactionId’ to each log statement
-
-**핵심요약:** 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 to its async nature, see code examples inside
-
-**그렇게 하지 않을 경우:** Looking at a production error log without the context – what happened before – makes it much harder and slower to reason about the issue
-
-🔗 [**자세히 보기: Assign ‘TransactionId’ to each log statement**](/sections/production/assigntransactionid.korean.md)
-
-
-
-## ![✔] 5.15. Set NODE_ENV=production
-
-**핵심요약:** Set the environment variable NODE_ENV to ‘production’ or ‘development’ to flag whether production optimizations should get activated – many NPM packages determining the current environment and optimize their code for production
-
-**그렇게 하지 않을 경우:** Omitting this simple property might greatly degrade performance. For example, when using Express for server-side rendering omitting `NODE_ENV` makes the slower by a factor of three!
-
-🔗 [**자세히 보기: Set NODE_ENV=production**](/sections/production/setnodeenv.korean.md)
-
-
-
-## ![✔] 5.16. Design automated, atomic and zero-downtime deployments
-
-**TL;DR:** Researches show that teams who perform many deployments – lowers the probability of severe production issues. Fast and automated deployments that don’t require risky manual steps and service downtime significantly improves the deployment process. You should probably achieve that using Docker combined with CI tools as they became the industry standard for streamlined deployment
-
-**그렇게 하지 않을 경우:** Long deployments -> production down time & human-related error -> team unconfident and in making deployment -> less deployments and features
-
-
-
-## ![✔] 5.17. Use an LTS release of Node.js
-
-**TL;DR:** Ensure you are using an LTS version of Node.js to receive critical bug fixes, security updates and performance improvements
-
-**그렇게 하지 않을 경우:** Newly discovered bugs or vulnerabilities could be used to exploit an application running in production, and your application may become unsupported by various modules and harder to maintain
-
-🔗 [**자세히 보기: Use an LTS release of Node.js**](/sections/production/LTSrelease.korean.md)
-
-
-
-⬆ 목차로 돌아가기
-
-# `보안`
-
-## 컨트리뷰터들이 현재 작업중 입니다. 함께 하시겠습니까?
-
-
-
-# `성능`
-
-## 컨트리뷰터들이 현재 작업중 입니다. 함께 하시겠습니까?
-
-
-
-# 마일스톤
-
-이 가이드를 관리하고 최신 버전을 유지하기 위해, 우리는 지속해서 가이드라인과 모범 사례들을 커뮤니티의 도움으로 업데이트하고 개선해 나가고 있습니다. 만약 이 프로젝트에 기여를 하고 싶으시면 [마일스톤](https://github.com/i0natan/nodebestpractices/milestones) 을 보고 참여하십시오.
-
-
-
-## 번역
-
-모든 번역은 커뮤니티에 의해 기여되고 있습니다. 이미 완성된 번역이나, 진행중, 새로운 번역에 대한 도움은 언제나 환영합니다!
-
-### 번역 작업 완료
-
-* ![CN](/assets/flags/CN.png) [Chinese](README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
-
-### 번역 작업중
-
-* ![FR](/assets/flags/FR.png) [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/129))
-* ![HE](/assets/flags/HE.png) Hebrew ([Discussion](https://github.com/i0natan/nodebestpractices/issues/156))
-* ![KR](/assets/flags/KR.png) [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/94))
-* ![RU](/assets/flags/RU.png) [Russian](https://github.com/i0natan/nodebestpractices/blob/russian-translation/README.russian.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/105))
-* ![ES](/assets/flags/ES.png) [Spanish](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/95))
-* ![TR](/assets/flags/TR.png) Turkish ([Discussion](https://github.com/i0natan/nodebestpractices/issues/139))
-
-
-
-# Contributors
-
-## `Yoni Goldberg`
-
-Independent Node.js consultant who works with customers in USA, Europe, and Israel on building large-scale scalable Node applications. Many of the best practices above were first published in his blog post at [http://www.goldbergyoni.com](http://www.goldbergyoni.com). Reach Yoni at @goldbergyoni or me@goldbergyoni.com
-
-## `Ido Richter`
-
-👨💻 Software engineer, 🌐 web developer, 🤖 emojis enthusiast
-
-## `Refael Ackermann` [@refack](https://github.com/refack) <refack@gmail.com> (he/him)
-
-Node.js Core Collaborator, been noding since 0.4, and have noded in multiple production sites. Founded `node4good` home of [`lodash-contrib`](https://github.com/node4good/lodash-contrib), [`formage`](https://github.com/node4good/formage), and [`asynctrace`](https://github.com/node4good/asynctrace).
-`refack` on freenode, Twitter, GitHub, GMail, and many other platforms. DMs are open, happy to help
-
-## `Bruno Scheufler`
-
-💻 full-stack web developer and Node.js enthusiast
-
-## `Kyle Martin` [@js-kyle](https://github.com/js-kyle)
-Full Stack Developer based in New Zealand, interested in architecting and building Node.js applications to perform at global scale. Keen contributor to open source software, including Node.js Core.
-
-
-
-# Thank You Notes
-
-This repository is being kept up to date thanks to the help from the community. We appreciate any contribution, from a single word fix to a new best practice. Below is a list of everyone who contributed to this project. A 🌻 marks a successful pull request and a ⭐ marks an approved new best practice
-
-### Flowers
-
-🌻 [Kevin Rambaud](https://github.com/kevinrambaud),
-🌻 [Michael Fine](https://github.com/mfine15),
-🌻 [Shreya Dahal](https://github.com/squgeim),
-🌻 [ChangJoo Park](https://github.com/ChangJoo-Park),
-🌻 [Matheus Cruz Rocha](https://github.com/matheusrocha89),
-🌻 [Yog Mehta](https://github.com/BitYog),
-🌻 [Kudakwashe Paradzayi](https://github.com/kudapara),
-🌻 [t1st3](https://github.com/t1st3),
-🌻 [mulijordan1976](https://github.com/mulijordan1976),
-🌻 [Matan Kushner](https://github.com/matchai),
-🌻 [Fabio Hiroki](https://github.com/fabiothiroki),
-🌻 [James Sumners](https://github.com/jsumners),
-🌻 [Chandan Rai](https://github.com/crowchirp),
-🌻 [Dan Gamble](https://github.com/dan-gamble),
-🌻 [PJ Trainor](https://github.com/trainorpj),
-🌻 [Remek Ambroziak](https://github.com/reod),
-🌻 [Yoni Jah](https://github.com/yonjah),
-🌻 [Misha Khokhlov](https://github.com/hazolsky),
-🌻 [Evgeny Orekhov](https://github.com/EvgenyOrekhov),
-🌻 [Gediminas Petrikas](https://github.com/gediminasml),
-🌻 [Isaac Halvorson](https://github.com/hisaac),
-🌻 [Vedran Karačić](https://github.com/vkaracic),
-🌻 [lallenlowe](https://github.com/lallenlowe),
-🌻 [Nathan Wells](https://github.com/nwwells),
-🌻 [Paulo Vítor S Reis](https://github.com/paulovitin),
-🌻 [syzer](https://github.com/syzer),
-🌻 [David Sancho](https://github.com/davesnx),
-🌻 [Robert Manolea](https://github.com/pupix),
-🌻 [Xavier Ho](https://github.com/spaxe),
-🌻 [Aaron Arney](https://github.com/ocularrhythm),
-🌻 [Jan Charles Maghirang Adona](https://github.com/septa97),
-🌻 [Allen Fang](https://github.com/AllenFang),
-🌻 [Leonardo Villela](https://github.com/leonardovillela),
-🌻 [Michal Zalecki](https://github.com/MichalZalecki)
-🌻 [Chris Nicola](https://github.com/chrisnicola),
-🌻 [Alejandro Corredor](https://github.com/aecorredor),
-🌻 [Ye Min Htut](https://github.com/ymhtut),
-🌻 [cwar](https://github.com/cwar),
-🌻 [Yuwei](https://github.com/keyfoxth),
-🌻 [Utkarsh Bhatt](https://github.com/utkarshbhatt12),
-🌻 [Duarte Mendes](https://github.com/duartemendes),
-🌻 [Sagir Khan](https://github.com/sagirk),
-🌻 [Jason Kim](https://github.com/serv),
-🌻 [Mitja O.](https://github.com/Max101),
-🌻 [Sandro Miguel Marques](https://github.com/SandroMiguel),
-🌻 [Gabe Kuslansky](https://github.com/GabeKuslansky),
-🌻 [Ron Gross](https://github.com/ripper234),
-🌻 [Valeri Karpov](https://github.com/vkarpov15)
-
-
-### Stars
-
-⭐ [Kyle Martin](https://github.com/js-kyle)
-
-
+[✔]: assets/images/checkbox-small-blue.png
+
+# Node.js 모범 사례
+
+
+
+
+
+
+
+
+
+
+
+[![nodepractices](/assets/images/twitter-s.png)](https://twitter.com/nodepractices/) **트위터에서 팔로우 하세요!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+
+다른 언어로 읽기: [![CN](/assets/flags/CN.png)**CN**](/README.chinese.md) [(![ES](/assets/flags/ES.png)**ES**, ![FR](/assets/flags/FR.png)**FR**, ![HE](/assets/flags/HE.png)**HE**, ![KR](/assets/flags/KR.png)**KR**, ![RU](/assets/flags/RU.png)**RU**, ![TR](/assets/flags/TR.png)**TR** 는 작업중입니다!)](#translations)
+
+
+
+# 안녕하세요! 먼저 알아야 할 3가지가 있습니다:
+
+**1. 이 문서를 읽는 것은, 사실상 수십 개의 베스트 Node.js 문서를 읽는 것입니다. -** 이 문서는 Node.js 의 가장 인기 있는 모범사례(Best Practice)들을 모은 요약집 및 큐레이션입니다.
+
+**2. 가장 큰 모음집이며, 매주 성장하고 있습니다. -** 현재, 50개 이상의 모범사례들과, 스타일 가이드, 아키텍처적인 팁들이 제공되고 있습니다. 이 문서의 업데이트를 위해 새로운 이슈들과 PR들이 매일 만들어지고 있습니다. 우리는 이 문서의 잘못된 코드를 고치거나 새로운 아이디어들을 제안하는 것을 매우 환영합니다. [마일스톤 보러가기](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open)
+
+**3. 항목 대부분은 추가적인 정보가 있습니다 -** 항목 옆쪽에 존재하는 **🔗자세히 보기** 링크에서 코드 예제, 참조 블로그 또는 기타 정보들을 확인 할 수 있습니다.
+
+
+
+## 목차
+
+1. [프로젝트 구조 설계 (5)](#1-프로젝트-구조-설계)
+2. [에러 처리 방법 (11)](#2-에러-처리-방법)
+3. [코드 스타일 (12) ](#3-코드-스타일)
+4. [테스트 및 전체 품질 관리 (8) ](#4-테스트-및-전체-품질-관리)
+5. [운영 환경으로 전환하기 (16) ](#5-운영-환경으로-전환하기)
+6. 보안 ([예정](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
+7. 성능 ([예정](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
+
+
+
+# `1. 프로젝트 구조 설계`
+
+## ![✔] 1.1 컴포넌트 기반으로 설계하라
+
+**핵심요약:** 큰 프로젝트에서 빠지기 쉬운 최악의 함정은 많은 수백개의 의존성을 가진 커다란 소스코드를 유지보수하는 것이다. 그렇게 하나로 통째로 짜여진 코드는 개발자가 새로운 기능들을 협업하는 속도를 느려지게 한다. 그 대신에 당신의 코드를 컴포넌트로 나누고, 각각의 컴포넌트가 자신의 폴더 혹은 할당된 코드베이스를 가지게 하고 컴포넌트의 각 단위가 작고 간단하게 유지되도록 하라. 아래의 '자세히 보기'를 눌러 올바른 프로젝트 구조의 예시를 확인하라.
+
+**그렇게 하지 않을 경우:** 새로운 기능을 작성하는 개발자가 변경사항이 미치는 영향을 깨닫기위해 몸부림치거나 의존하고 있는 다른 컴포넌트를 망칠까봐 두려워 할때 배포는 느려지고 더 위험해진다. 비지니스 단위가 나눠져 있지 않으면 확장(scale-out)하기도 쉽지 않다.
+
+🔗 [**자세히 보기: 컴포넌트로 구조화하기**](/sections/projectstructre/breakintcomponents.korean.md)
+
+
+
+## ![✔] 1.2 컴포넌트를 계층화(layer)하고, Express를 그 경계 안에 둬라.
+
+**핵심요약:** 각각의 컴포넌트는 웹, 로직, 데이터 접근 코드을 위한 객체인 '계층'을 포함해야 한다. 이것은 우려를 깨끗하게 분리할 뿐만 아니라 모의 객체를 만들거나(mocking) 테스트하기가 굉장히 쉽게 만든다. 이것이 굉장히 일반적인 패턴임에도, API 개발자는 웹 계층의 객체 (Express req, res)를 비지니스 로직과 데이터 계층으로 보내서 계층을 뒤섞어버리는 경향이 있다. 그렇게 하는것은 당신의 어플리케이션에 의존성을 만들고 Express에서만 접근 가능하도록 만든다.
+
+**그렇게 하지 않을 경우:** 웹 객체를 다른 계층과 뒤섞은 앱은 테스트 코드, CRON 작업이나 Express가 아닌 다른 곳에서 접근이 불가능하게 한다.
+
+🔗 [**자세히 보기: 앱을 계층화하기**](/sections/projectstructre/createlayers.korean.md)
+
+
+
+## ![✔] 1.3 유틸리티들을 NPM 패키지로 감싸라(wrap)
+
+**핵심요약:** 커다란 코드 기반으로 구성되어있는 커다란 앱에서는 로깅, 암호화 같은 횡단 관심사(cross-cutting-concern)가 존재하는 유틸의 경우 당신 자신의 코드로 감싸져야하며 개인 NPM package로 노출이 되어야한다. 이것은 여러 코드 기반과 프로젝트들 사이에서 그것들을 공유가 가능하도록 해준다.
+
+**그렇게 하지 않을 경우:** 당신 자신만의 배포 및 의존성 바퀴(wheel)를 새로 발명해야 할 것이다.
+
+🔗 [**자세히 보기: 기능으로 구조화 하기**](/sections/projectstructre/wraputilities.korean.md)
+
+
+
+## ![✔] 1.4 Express의 app과 server를 분리하라
+
+**핵심요약:** 'Express' 정의를 적어도 API 선언(app.js)과 네트워크 부분(WWW)의 두 개 파일로 나눠서 전체 [Express](https://expressjs.com/)앱을 하나의 큰 파일에 정의하는 불쾌한 습관을 피해라. 더 좋은 구조는 API 선언을 컴포넌트에 위치시키는 것이다.
+
+**그렇게 하지 않을 경우:** API는 HTTP 요청으로만 테스트가 가능 할것이다(커버리지 보고서를 생성하기가 더 느려지고 훨씬 힘들어진다). 수백줄의 코드를 하나의 파일에서 관리하는 것이 크게 즐겁지는 않을 것이다.
+
+🔗 [**자세히 보기: Express를 'app'과 'server'로 분리하기**](/sections/projectstructre/separateexpress.korean.md)
+
+
+
+## ![✔] 1.5 환경을 인식하는, 보안적인, 계층적인 설정을 사용하라
+
+**핵심요약:** 완벽하고 결점이 없는 구성 설정은 (a) 파일과 환경 변수에서 키 값을 읽을 수 있어야하고 (b) 보안 값들은 커밋된 코드 바깥에서 관리되어야하고 (c) 설정은 좀 더 쉽게 찾을 수 있도록 계층적으로 관리해야 한다. [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config)와 같이 이러한 요구사항을 동작하게 해주는 몇가지 패키지가 존재한다.
+
+**그렇게 하지 않을 경우:** 위의 구성 요구사항 중 어느 것도 만족시키지 못한다면 개발팀 혹은 데브옵스팀을 늪으로 몰아갈 수 있다. 아마도 두 팀 모두일 것이다.
+
+🔗 [**자세히 보기: 구성 모범 사례**](/sections/projectstructre/configguide.korean.md)
+
+
+
+⬆ 목차로 돌아가기
+
+# `2. 에러 처리 방법`
+
+## ![✔] 2.1 비동기 에러 처리시에는 async-await 혹은 promise를 사용하라
+
+**핵심요약:** 비동기 에러를 콜백 스타일로 처리하는 것은 지옥으로 가는 급행열차일 것이다(운명의 피라미드로 잘 알려진). 당신이 코드에 줄 수 있는 가장 큰 선물은 평판이 좋은 promise 라이브러리를 사용하거나 훨신 작고 친숙한 코드 문법인 try-catch를 사용하게 해주는 async-await를 사용하는 것이다.
+
+**그렇게 하지 않을 경우:** Node.js 콜백 스타일인 function(err, response)는 에러 처리와 일반 코드의 혼합, 코드의 과도한 중첩, 이상한 코딩 패턴 때문에 유지보수가 불가능한 코드로가는 확실한 길이다.
+
+🔗 [**자세히 보기: 콜백 피하기**](/sections/errorhandling/asyncerrorhandling.korean.md)
+
+
+
+## ![✔] 2.2 내장된 Error 객체만 사용하라
+
+**핵심요약:** 많은 사람들이 문자열이나 사용자가 임의로 정의한 타입으로 에러를 던진다(throw). 이것은 에러처리 로직과 모듈 사이의 상호운영성을 복잡하게 한다. 당신이 promise를 거부(reject)하든, 예외를 던지든, 에러를 냈건 내장된 Error 객체를 이용하는 것은 균일성을 향상하고 정보의 손실을 방지하게 만들것이다.
+
+**그렇게 하지 않을 경우:** 일부 컴포넌트를 호출할때 어떤 에러의 타입이 반환될지 불확실해져서 적절한 에러처리가 매우 어려워 질것이다. 더 나쁜 것은, 사용자가 정의한 타입으로 에러를 나타내는 것은 스택 정보(stack trace)와 같은 중요한 에러 정보를 손실할 가능성이 있다는 것이다!
+
+🔗 [**자세히 보기: 내장된 Error 객체 사용하기**](/sections/errorhandling/useonlythebuiltinerror.korean.md)
+
+
+
+## ![✔] 2.3 동작상의 에러와 프로그래머 에러를 구분하라
+
+**핵심요약:** API에서 잘못된 입력을 받는 것과 같은 동작상의 에러는 에러의 영향을 완전히 이해할수 있고 신중하게 처리 할수있는 알려진 경우를 의미한다. 반면에 정의되지 않은 변수를 읽는 것과 같은 프로그래머 에러는 어플리케이션을 우아하게 다시 시작하도록 만드는 알수 없는 코드 에러를 의미한다.
+
+**그렇게 하지 않을 경우:** 당신은 에러가 날때마다 어플리케이션을 다시 시작할수도 있다. 하지만 왜 사소하고 예측가능한 동작상의 오류때문에 5000명의 온라인 사용자를 다운시키는 것인가? 나머지 상황 또한 이상적이지 않다. 알수없는 이슈(프로그래머 에러)가 났는데 어플리케이션을 그대로 두는 것은 예측이 불가능한 동작을 일으킬 수 있다. 두 가지를 구별하는 것은 현명한 행동과 주어진 상황에 따른 균형잡힌 접근을 가능하게 한다.
+
+🔗 [**자세히 보기: 동작상의 에러와 프로그래머 에러**](/sections/errorhandling/operationalvsprogrammererror.korean.md)
+
+
+
+## ![✔] 2.4 에러를 Express 미들웨어로 처리하지 말고 중앙집중적으로 처리하라
+
+**핵심요약:** 관리자에게 메일을 보내거나 로깅을 하는 것과 같은 에러 처리는 에러가 발생할 때 모든 엔드포인트(예를 들어 Express 미들웨어, cron 작업, 단위 테스트 등)가 호출하는 에러전용 중앙집중 객체로 캡슐화 되어야한다.
+
+**그렇게 하지 않을 경우:** 한 곳에서 에러를 처리하지 않는 것은 코드 중복과 부적절한 에러처리로 이어진다.
+
+🔗 [**자세히 보기: 중앙집중적으로 에러 처리하기**](/sections/errorhandling/centralizedhandling.korean.md)
+
+
+
+## ![✔] 2.5 Swagger를 이용해 API 에러를 문서화하라
+
+**핵심요약:** API를 호출한 사람들이 어떤 에러가 반환 될수 있는지 알게하여 충돌없이 신중하게 처리 할 수 있도록하라. 이것은 보통 Swagger와 같은 API 문서화 프레임워크를 통해 이루어진다.
+
+**그렇게 하지 않을 경우:** API 클라이언트는 알수 없는 에러로 인해 충돌 후에 재시작을 결정할수도 있을 것이다. 참고: 당신의 API를 호출한 사람이 당신 자신 일수도 있다.(마이크로서비스 환경에서는 아주 일반적임).
+
+🔗 [**자세히 보기: Swagger에서 에러 문서화하기**](/sections/errorhandling/documentingusingswagger.korean.md)
+
+
+
+## ![✔] 2.6 이상한 것이 들어왔을때 프로세스를 정상적으로 중단하라
+
+**핵심요약:** 알수 없는 에러(프로그래머 에러, 모범사례 #3번 참조)가 발생하면 어플리케이션의 건강상태에 대한 불확실성이 있다. 일반적인 방법은 Forever와 PM2 같은 '재시작' 도구로 프로세스를 다시 시작하는 것이다.
+
+**그렇게 하지 않을 경우:** 익숙치 않은 예외가 발생하면 일부 객체가 오류 상태(예를 들어 전역적으로 사용되지만 내부 오류로 인해 이벤트를 더이상 발생시키지 않는 Event Emitter)일 수 있으며 향후의 모든 요청이 실패하거나 미친것처럼(crazily) 동작할 수 있다.
+
+🔗 [**자세히 보기: 프로세스 중단하기**](/sections/errorhandling/shuttingtheprocess.korean.md)
+
+
+
+## ![✔] 2.7 에러 확인을 용이하게 해주는 로거를 사용하라
+
+**핵심요약:** Winston, Bunyan 혹은 Log4J와 같은 발전된 로깅 도구의 집합은 에러를 찾는 것과 이해하는 것의 속도를 높여준다. 그러니 console.log를 잊어버려라.
+
+**그렇게 하지 않을 경우:** 로그 검색 도구나 괜찮은 로그 뷰어 없이 console.log 혹은 지저분한 텍스트 파일을 대충 읽는 것은 야근을 부를 수 있다.
+
+🔗 [**자세히 보기: 발전된 로거를 사용하기**](/sections/errorhandling/usematurelogger.korean.md)
+
+
+
+## ![✔] 2.8 당신이 선호하는 테스트 프레임워크로 에러 흐름을 테스트하라
+
+**핵심요약:** 전문 자동화 QA든 일반 수동 개발자 테스트든 당신의 코드가 긍정적인 상황에서 잘 동작할 뿐만 아니라 올바른 에러를 처리하고 반환하는지 확실히 하라. Mocha & Chai와 같은 테스트 프레임워크는 이것을 쉽게 처리 할수 있다("Gist popup"안의 코드 예제를 확인하라).
+
+**그렇게 하지 않을 경우:** 자동이든 수동이든 테스트가 없다면 당신은 당신의 코드가 올바른 에러를 반환하는지 믿지 못할 것이다. 의미가 있는 에러가 없다면 에러 처리는 없는 것이다.
+
+🔗 [**자세히 보기: 에러 흐름 테스트하기**](/sections/errorhandling/testingerrorflows.korean.md)
+
+
+
+## ![✔] 2.9 APM 제품을 사용하여 에러와 다운타임을 확인하라
+
+**핵심요약:** APM이라고 불리는 모니터링 및 성능 제품은 미리 알아서 코드베이스와 API를 측정하고 자동적으로 당신이 놓친 에러, 충돌, 느린부분을 강조 표시해준다.
+
+**그렇게 하지 않을 경우:** API의 성능과 다운타임을 측정하기위해 많은 노력을 들여야 할지도 모른다. 아마 당신은 실제 상황에서 어떤 코드 부분이 가장 느린지, 그것이 UX에 어떻게 영향을 미칠지 절대 알수없을 것이다.
+
+🔗 [**자세히 보기: APM 제품 사용하기**](/sections/errorhandling/apmproducts.korean.md)
+
+
+
+## ![✔] 2.10 처리되지 않은 promise 거부(unhandled promise rejection)를 잡아라
+
+**핵심요약:** promise안에서 발생한 예외는 개발자가 명시적으로 처리하는 것을 잊게되면 삼켜지고 버려지게 된다. 당신의 코드가 process.uncaughtException 이벤트를 구독하고 있다고해도 말이다! 이것을 극복하기위해 process.unhandledRejection 이벤트를 등록하라.
+
+**그렇게 하지 않을 경우:** 당신의 에러는 삼켜지고 어떤 흔적도 남기지 않을 것이다. 걱정할 것이 없긴 하다.
+
+🔗 [**자세히 보기: 처리되지 않은 promise 거부 잡기**](/sections/errorhandling/catchunhandledpromiserejection.korean.md)
+
+
+
+## ![✔] 2.11 전용 라이브러리를 이용해 인자값이 유효한지 검사하여 빠르게 실패하라(fail fast)
+
+**핵심요약:** 나중에 처리하기가 더 힘들어지는 지저분한 버그를 피하기 위해 Assert API입력은 당신의 Express 모범사례가 되어야 한다. 당신이 Joi와 같은 유용한 헬퍼 라이브러리를 사용하지 않는 이상 유효성 검사 코드는 일반적으로 지루하다.
+
+**그렇게 하지 않을 경우:** 이런 상황을 생각해보자. 당신의 함수가 "Discount"라는 숫자를 받아야하는데 요청하는 사람이 넘겨주는 것을 깜빡했다. 그 후에 당신의 코드는 Discount!=0인지 아닌지 체크한다(사실 허용된 Discount의 값은 0보다 커야 한다). 그러면 사용자가 할인을 받게될 것이다. 보이는가? 엄청나게 지저분한 버그이다.
+
+🔗 [**자세히 보기: 빠르게 실패하기**](/sections/errorhandling/failfast.korean.md)
+
+
+
+⬆ 목차로 돌아가기
+
+# `3. 코드 스타일`
+
+## ![✔] 3.1 ESLint를 사용하라
+
+**핵심요약:** [ESLint](https://eslint.org)는 발생 가능한 코드 에러를 체크하고 껄끄러운 간격(spacing)문제를 식별하는 것부터 프로그래머가 분별없이 에러를 던지는 것과 같은 코드의 심각한 안티 패턴을 감지하여 코드 스타일을 바꾸는 것에 대한 사실상의 표준이다. ESLint도 자동으로 코드스타일을 고칠 수 있지만 [prettier](https://www.npmjs.com/package/prettier)와 [beautify](https://www.npmjs.com/package/js-beautify)같은 수정 부분의 포맷을 맞춰주는 강력한 툴이 있고 ESLint와 함께 작동된다.
+
+**그렇게 하지 않을 경우:** 프로그래머가 쓸데없는 간격과 한줄의 길이(line-width) 문제에 대해서 집중해야하고 프로젝트의 코드스타일에 대해 과도하게 생각하느라 시간을 낭비해야할 수도 있다.
+
+
+
+## ![✔] 3.2 Node.js에 특화된 플러그인들
+
+**핵심요약:** vanlla JS만 지원하는 ESLinst의 표준 규칙 위에 [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha), [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security)와 같은 Node에 특화된 플러그인을 같이 사용하라.
+
+**그렇게 하지 않을 경우:** 많은 결함이 있는 Node.js 코드 패턴들이 레이더에서 벗어날 수 있다. 예를 들어 프로그래머는 변수로된 파일경로를 이용해 `require(파일경로변수)`로 파일을 가져올수 있다. 이것은 공격자들이 어떤 JS script도 실행시킬 수 있게 한다. Node.js linter는 그러한 패턴을 감지하고 미리 알려준다.
+
+
+
+## ![✔] 3.3 코드 블록의 중괄호를 같은 줄에서 시작하라
+
+**핵심요약:** 블록에서 중괄호를 여는 부분은 코드를 여는 문장과 같은 줄에 있어야 한다.
+
+### 코드 예제
+
+```javascript
+// Do
+function someFunction() {
+ // code block
+}
+
+// Avoid
+function someFunction()
+{
+ // code block
+}
+```
+
+**그렇게 하지 않을 경우:** 이 모범사례를 적용하지 않는 것은 아래의 Stackoverflow 스레드에서 보는 바와 같이 예기치못한 결과로 이어질 수 있다.
+
+🔗 [**자세히 보기:** "왜 결과가 중괄호의 위치에 따라 달라지는 거죠?" (Stackoverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
+
+
+
+## ![✔] 3.4 세미콜론을 잊지 마라
+
+**핵심요약:** 만장일치로 동의하지는 않겠지만 각 문장의 끝에 세미콜론을 붙이는 것은 여전히 권장사항이다. 이것은 당신의 코드를 읽는 다른 프로그래머가 좀더 잘 읽게하고 명확하게 할것이다.
+
+**그렇게 하지 않을 경우:** 이전 섹션에서 본것처럼 자바스크립트의 인터프리터는 세미콜론이 없으면 의도되지 않은 결과를 야기할수 있기에 자동으로 문장의 끝에 세미콜론을 붙인다.
+
+
+
+## ![✔] 3.5 함수에 이름을 붙여라
+
+**핵심요약:** 클로저와 콜백을 포함한 모든 함수에 이름을 붙여라. 익명함수를 피해라. 이것은 노드 앱을 프로파일링 할때 특히 유용하다. 모든 함수를 명명하는 것은 당신이 메모리 스냅샷을 확인할때 당신이 보고있는 것이 무엇인지 쉽게 이해 할수있도록 해준다.
+
+**그렇게 하지 않을 경우:**
+당신이 익명함수에서 메모리 소비가 많다는 것을 확인 했을 때 코어 덤프(메모리 스냅샷)을 이용해 프로덕션 문제를 디버깅하는 것이 어려울 수도 있습니다.
+
+
+
+## ![✔] 3.6 변수, 상수, 함수, 클래스의 명명 규칙(naming convention)
+
+**핵심요약:** 상수와 변수 함수를 명명할때는 **_lowerCamelCase_** 를 사용하고 클래스를 명명 할때는 **_UpperCamelCase_**(첫 글자 대문자)를 사용하라. 이것은 일반 변수/함수와 인스턴스로 만들어야 하는 클래스를 구분하는데 도움을 것이다. 설명이 포함된 이름을 사용하되 이름을 짧게 유지하도록 해라.
+
+**그렇게 하지 않을 경우:** 자바스크립트는 먼저 인스턴스로 만들지 않고 직접 생성자("Class")를 호출할 수 있는 세계 유일의 언어이다. 그러므로 클래스와 함수생성자는 UpperCamelCase를 통해 구분된다.
+
+### 코드예제
+
+```javascript
+// 클래스명은 UpperCamelCase 사용
+class SomeClassExample {}
+
+// 상수명은 const 키워드와 lowerCamelCase 사용
+const config = {
+ key: 'value'
+};
+
+// 변수와 함수 이름은 lowerCamelCase 사용
+let someVariableExample = 'value';
+function doSomething() {}
+```
+
+
+
+## ![✔] 3.7 let보다는 const를 사용하라. var는 갖다버려라
+
+**핵심요약:** `const`를 사용한다는 것은 변수에 한번 값이 할당되면 다시 할당할 수 없다는 것을 의미한다. `const`를 선호하는 것은 같은 변수를 다른 용도로 사용하는 것을 방지하고 당신의 코드를 더 깔끔하게 만드는데 도움을 준다. for루프처럼 변수가 재할당 되어야 할 필요가 있으면 `let`을 사용하여 선언하라. `let`의 또 다른 중요한 부분은 선언된 변수를 사용하는 것이 변수가 정의된 블록범위(block scope) 안에서만 가능하다는 것이다. `var`는 블록범위가 아니라 함수범위(function scope)이며 이제 대신할 수 있는 const와 let이 있으므로 [ES6에서는 사용하면 안된다](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70).
+
+**그렇게 하지 않을 경우:** 자주 변경되는 변수를 따라가려면 디버깅이 훨씬 더 번거로워 진다.
+
+🔗 [**자세히 보기: JavaScript ES6+: var 혹은 let 혹은 const?**](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 require는 맨 처음에 오게하고 함수 안에서의 사용은 피하라
+
+**핵심요약:** 모듈을 각 파일의 시작이나 모든 함수의 앞부분 혹은 밖에서 require하라. 이 간단한 모범사례는 파일의 의존성을 맨 위에서 쉽고 빠르게 구분 할수 있게 해줄 뿐만 아니라 여러 잠재적인 문제를 피하게 해준다.
+
+**그렇게 하지 않을 경우:** require는 Node.js에서 동기로 실행된다. 함수 안에서 호출되면 다른 요청들을 더 중요한 시간에 처리되지 못하도록 막을 수 있다. 또한 require된 모듈이나 그것의 의존 모듈이 에러를 뱉거나 서버를 다운시키면, 함수 안에서 그 모듈이 require된 것이 아닌지 가능한 아주 빠르게 찾아야 할 것이다.
+
+
+
+## ![✔] 3.9 require는 파일에 직접하지말고 폴더에 하라
+
+**핵심요약:** 폴더에서 모듈과 라이브러리를 개발할 때 모든 소비자가 그것을 거치도록 모듈의 내부를 노출하는 index.js 파일을 둬라. 이것은 모듈의 '인터페이스'역할을 하며 계약을 위반하지 않으면서 미래의 변경사항에 대해 유연하게 대처하도록 해준다.
+
+**그렇게 하지 않을 경우:** 파일 내부의 구조 혹은 서명을 변경하면 클라이언트와의 인터페이스가 손상될 수 있다.
+
+### 코드 예제
+
+```javascript
+// 이렇게 하라
+module.exports.SMSProvider = require('./SMSProvider');
+module.exports.SMSNumberResolver = require('./SMSNumberResolver');
+
+// 피하라
+module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
+module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
+```
+
+
+
+## ![✔] 3.10 `===` 연산자를 사용하라
+
+**핵심요약:** 약하고 추상적인 같음연산자 `==` 보다 엄격한 항등연산자 `===`를 선호한다. `==`는 두 변수를 공용 타입으로 변환한 후에 비교한다. `===`에는 타입 변환이 없고 두 변수가 같으려면 타입도 같아야 한다.
+
+**그렇게 하지 않을 경우:** `==`으로 비교하는 경우 같지 않은 변수가 true로 반환 될 수있다.
+
+### 코드 예제
+
+```javascript
+'' == '0' // false
+0 == '' // true
+0 == '0' // true
+
+false == 'false' // false
+false == '0' // true
+
+false == undefined // false
+false == null // false
+null == undefined // true
+
+' \t\r\n ' == 0 // true
+```
+
+위의 모든 문장은 `===`를 사용했다면 false를 반환 했을것이다.
+
+
+
+## ![✔] 3.11 async-await을 사용하고 콜백을 피하라
+
+**핵심요약:** Node 8의 LTS 버전은 현재 async-await을 완전히 지원한다. 이것은 콜백과 promise를 대체하여 비동기 코드를 다루는 새로운 방법이다. async-await은 비차단적(non-blocking)이고 비동기 코드를 동기 코드처럼 보이게 만든다. 당신의 코드에게 줄수 있는 최고의 선물은 try-catch와 같은 더 작고 친숙한 코드 구문을 제공하는 async-await을 사용하는 것이다.
+
+**그렇게 하지 않을 경우:** 콜백 스타일로 비동기 에러를 처리하는 것은 아마도 지옥으로 가는 가장 빠른 방법일것이다. 이런 스타일은 에러를 전부 확인하게 하고 어색한 코드 중첩을 다루게하며 코드 흐름을 추론하기 어렵게 만든다.
+
+🔗[**자세히 보기: async-await 1.0 가이드**](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 두꺼운(=>) 화살표 함수를 사용하라
+
+**핵심요약:** async-await을 사용하고 함수 인자를 사용하는 것을 피하는 것이 권장되지만 promise와 콜백을 받는 예전 API를 다룰 때는 화살표 함수가 코드 구조를 더 작게해주고 루트 함수의 어휘적 맥락(lexical context)을 유지시켜 준다. (예를 들어 'this')
+
+**그렇게 하지 않을 경우:** 더 긴 코드(ES5의 function)은 버그에 더 취약하고 읽기가 번거롭다.
+
+🔗 [**Read mode: 화살표 함수를 받아들일 시간이다**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
+
+
+
+⬆ 목차로 돌아가기
+
+# `4. 테스트 및 전체 품질 관리`
+
+## ![✔] 4.1 At the very least, write API (component) testing
+
+**핵심요약:** Most projects just don't have any automated testing due to short timetables or often the 'testing project' run out of control and being abandoned. For that reason, prioritize and start with API testing which is the easiest to write and provide more coverage than unit testing (you may even craft API tests without code using tools like [Postman](https://www.getpostman.com/). Afterward, should you have more resources and time, continue with advanced test types like unit testing, DB testing, performance testing, etc
+
+**그렇게 하지 않을 경우:** You may spend long days on writing unit tests to find out that you got only 20% system coverage
+
+
+
+## ![✔] 4.2 Detect code issues with a linter
+
+**핵심요약:** Use a code linter to check basic quality and detect anti-patterns early. Run it before any test and add it as a pre-commit git-hook to minimize the time needed to review and correct any issue. Also check [Section 3](https://github.com/i0natan/nodebestpractices#3-code-style-practices) on Code Style Practices
+
+**그렇게 하지 않을 경우:** You may let pass some anti-pattern and possible vulnerable code to your production environment.
+
+
+
+## ![✔] 4.3 Carefully choose your CI platform (Jenkins vs CircleCI vs Travis vs Rest of the world)
+
+**핵심요약:** Your continuous integration platform (CICD) will host all the quality tools (e.g test, lint) so it should come with a vibrant ecosystem of plugins. [Jenkins](https://jenkins.io/) used to be the default for many projects as it has the biggest community along with a very powerful platform at the price of complex setup that demands a steep learning curve. Nowadays, it became much easier to set up a CI solution using SaaS tools like [CircleCI](https://circleci.com) and others. These tools allow crafting a flexible CI pipeline without the burden of managing the whole infrastructure. Eventually, it's a trade-off between robustness and speed - choose your side carefully
+
+**그렇게 하지 않을 경우:** Choosing some niche vendor might get you blocked once you need some advanced customization. On the other hand, going with Jenkins might burn precious time on infrastructure setup
+
+🔗 [**자세히 보기: Choosing CI platform**](/sections/testingandquality/citools.korean.md)
+
+
+
+## ![✔] 4.4 Constantly inspect for vulnerable dependencies
+
+**핵심요약:** Even the most reputable dependencies such as Express have known vulnerabilities. This can get easily tamed using community and commercial tools such as 🔗 [nsp](https://github.com/nodesecurity/nsp) that can be invoked from your CI on every build
+
+**그렇게 하지 않을 경우:** Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
+
+
+
+## ![✔] 4.5 Tag your tests
+
+**핵심요약:** Different tests must run on different scenarios: quick smoke, IO-less, tests should run when a developer saves or commits a file, full end-to-end tests usually run when a new pull request is submitted, etc. This can be achieved by tagging tests with keywords like #cold #api #sanity so you can grep with your testing harness and invoke the desired subset. For example, this is how you would invoke only the sanity test group with [Mocha](https://mochajs.org/): mocha --grep 'sanity'
+
+**그렇게 하지 않을 경우:** Running all the tests, including tests that perform dozens of DB queries, any time a developer makes a small change can be extremely slow and keeps developers away from running tests
+
+
+
+## ![✔] 4.6 Check your test coverage, it helps to identify wrong test patterns
+
+**핵심요약:** Code coverage tools like [Istanbul/NYC ](https://github.com/gotwarlost/istanbul)are great for 3 reasons: it comes for free (no effort is required to benefit this reports), it helps to identify a decrease in testing coverage, and last but not least it highlights testing mismatches: by looking at colored code coverage reports you may notice, for example, code areas that are never tested like catch clauses (meaning that tests only invoke the happy paths and not how the app behaves on errors). Set it to fail builds if the coverage falls under a certain threshold
+
+**그렇게 하지 않을 경우:** There won't be any automated metric telling you when a large portion of your code is not covered by testing
+
+
+
+## ![✔] 4.7 Inspect for outdated packages
+
+**핵심요약:** Use your preferred tool (e.g. 'npm outdated' or [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) to detect installed packages which are outdated, inject this check into your CI pipeline and even make a build fail in a severe scenario. For example, a severe scenario might be when an installed package is 5 patch commits behind (e.g. local version is 1.3.1 and repository version is 1.3.8) or it is tagged as deprecated by its author - kill the build and prevent deploying this version
+
+**그렇게 하지 않을 경우:** Your production will run packages that have been explicitly tagged by their author as risky
+
+
+
+## ![✔] 4.8 Use docker-compose for e2e testing
+
+**핵심요약:** End to end (e2e) testing which includes live data used to be the weakest link of the CI process as it depends on multiple heavy services like DB. Docker-compose turns this problem into a breeze by crafting production-like environment using a simple text file and easy commands. It allows crafting all the dependent services, DB and isolated network for e2e testing. Last but not least, it can keep a stateless environment that is invoked before each test suite and dies right after
+
+**그렇게 하지 않을 경우:** Without docker-compose teams must maintain a testing DB for each testing environment including developers machines, keep all those DBs in sync so test results won't vary across environments
+
+
+
+⬆ 목차로 돌아가기
+
+# `5. 운영 환경으로 전환하기`
+
+## ![✔] 5.1. Monitoring!
+
+**핵심요약:** Monitoring is a game of finding out issues before customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my suggestions inside), then go over additional fancy features and choose the solution that ticks all boxes. Click ‘The Gist’ below for an overview of the solutions
+
+**그렇게 하지 않을 경우:** Failure === disappointed customers. Simple
+
+🔗 [**자세히 보기: Monitoring!**](/sections/production/monitoring.korean.md)
+
+
+
+## ![✔] 5.2. Increase transparency using smart logging
+
+**핵심요약:** Logs can be a dumb warehouse of debug statements or the enabler of a beautiful dashboard that tells the story of your app. Plan your logging platform from day 1: how logs are collected, stored and analyzed to ensure that the desired information (e.g. error rate, following an entire transaction through services and servers, etc) can really be extracted
+
+**그렇게 하지 않을 경우:** You end-up with a black box that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**자세히 보기: Increase transparency using smart logging**](/sections/production/smartlogging.korean.md)
+
+
+
+## ![✔] 5.3. Delegate anything possible (e.g. gzip, SSL) to a reverse proxy
+
+**핵심요약:** Node is awfully bad at doing CPU intensive tasks like gzipping, SSL termination, etc. You should use ‘real’ middleware services like nginx, HAproxy or cloud vendor services instead
+
+**그렇게 하지 않을 경우:** Your poor single thread will stay busy doing infrastructural tasks instead of dealing with your application core and performance will degrade accordingly
+
+🔗 [**자세히 보기: Delegate anything possible (e.g. gzip, SSL) to a reverse proxy**](/sections/production/delegatetoproxy.korean.md)
+
+
+
+## ![✔] 5.4. Lock dependencies
+
+**핵심요약:** Your code must be identical across all environments, but amazingly NPM lets dependencies drift across environments by default – when you install packages at various environments it tries to fetch packages’ latest patch version. Overcome this by using NPM config files, .npmrc, that tell each environment to save the exact (not the latest) version of each package. Alternatively, for finer grain control use NPM” shrinkwrap”. \*Update: as of NPM5, dependencies are locked by default. The new package manager in town, Yarn, also got us covered by default
+
+**그렇게 하지 않을 경우:** QA will thoroughly test the code and approve a version that will behave differently at production. Even worse, different servers at the same production cluster might run different code
+
+🔗 [**자세히 보기: Lock dependencies**](/sections/production/lockdependencies.korean.md)
+
+
+
+## ![✔] 5.5. Guard process uptime using the right tool
+
+**핵심요약:** The process must go on and get restarted upon failures. For simple scenarios, ‘restarter’ tools like PM2 might be enough but in today ‘dockerized’ world – a cluster management tools should be considered as well
+
+**그렇게 하지 않을 경우:** Running dozens of instances without a clear strategy and too many tools together (cluster management, docker, PM2) might lead to a DevOps chaos
+
+🔗 [**자세히 보기: Guard process uptime using the right tool**](/sections/production/guardprocess.korean.md)
+
+
+
+## ![✔] 5.6. Utilize all CPU cores
+
+**핵심요약:** 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)
+
+**그렇게 하지 않을 경우:** 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!)
+
+🔗 [**자세히 보기: Utilize all CPU cores**](/sections/production/utilizecpu.korean.md)
+
+
+
+## ![✔] 5.7. Create a ‘maintenance endpoint’
+
+**핵심요약:** Expose a set of system-related information, like memory usage and REPL, etc in a secured API. Although it’s highly recommended to rely on standard and battle-tests tools, some valuable information and operations are easier done using code
+
+**그렇게 하지 않을 경우:** You’ll find that you’re performing many “diagnostic deploys” – shipping code to production only to extract some information for diagnostic purposes
+
+🔗 [**자세히 보기: Create a ‘maintenance endpoint’**](/sections/production/createmaintenanceendpoint.korean.md)
+
+
+
+## ![✔] 5.8. Discover errors and downtime using APM products
+
+**핵심요약:** Monitoring and performance products (a.k.a APM) proactively gauge codebase and API so they can auto-magically go beyond traditional monitoring and measure the overall user-experience across services and tiers. For example, some APM products can highlight a transaction that loads too slow on the end-users side while suggesting the root cause
+
+**그렇게 하지 않을 경우:** You might spend great effort on measuring API performance and downtimes, probably you’ll never be aware which is your slowest code parts under real-world scenario and how these affects the UX
+
+🔗 [**자세히 보기: Discover errors and downtime using APM products**](/sections/production/apmproducts.korean.md)
+
+
+
+## ![✔] 5.9. Make your code production-ready
+
+**핵심요약:** Code with the end in mind, plan for production from day 1. This sounds a bit vague so I’ve compiled a few development tips that are closely related to production maintenance (click Gist below)
+
+**그렇게 하지 않을 경우:** A world champion IT/DevOps guy won’t save a system that is badly written
+
+🔗 [**자세히 보기: Make your code production-ready**](/sections/production/productoncode.korean.md)
+
+
+
+## ![✔] 5.10. Measure and guard the memory usage
+
+**핵심요약:** Node.js has controversial relationships with memory: the v8 engine has soft limits on memory usage (1.4GB) and there are known paths to leaks memory in Node’s code – thus watching Node’s process memory is a must. In small apps, you may gauge memory periodically using shell commands but in medium-large app consider baking your memory watch into a robust monitoring system
+
+**그렇게 하지 않을 경우:** Your process memory might leak a hundred megabytes a day like how it happened at [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)
+
+🔗 [**자세히 보기: Measure and guard the memory usage**](/sections/production/measurememory.korean.md)
+
+
+
+## ![✔] 5.11. Get your frontend assets out of Node
+
+**핵심요약:** 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
+
+**그렇게 하지 않을 경우:** 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
+
+🔗 [**자세히 보기: Get your frontend assets out of Node**](/sections/production/frontendout.korean.md)
+
+
+
+## ![✔] 5.12. Be stateless, kill your Servers almost every day
+
+**핵심요약:** Store any type of data (e.g. users session, cache, uploaded files) within external data stores. Consider ‘killing’ your servers periodically or use ‘serverless’ platform (e.g. AWS Lambda) that explicitly enforces a stateless behavior
+
+**그렇게 하지 않을 경우:** Failure at a given server will result in application downtime instead of just killing a faulty machine. Moreover, scaling-out elasticity will get more challenging due to the reliance on a specific server
+
+🔗 [**자세히 보기: Be stateless, kill your Servers almost every day**](/sections/production/bestateless.korean.md)
+
+
+
+## ![✔] 5.13. Use tools that automatically detect vulnerabilities
+
+**핵심요약:** Even the most reputable dependencies such as Express have known vulnerabilities (from time to time) that can put a system at risk. This can get easily tamed using community and commercial tools that constantly check for vulnerabilities and warn (locally or at GitHub), some can even patch them immediately
+
+**그렇게 하지 않을 경우:** 그렇게 하지 않을 경우: Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
+
+🔗 [**자세히 보기: Use tools that automatically detect vulnerabilities**](/sections/production/detectvulnerabilities.korean.md)
+
+
+
+## ![✔] 5.14. Assign ‘TransactionId’ to each log statement
+
+**핵심요약:** 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 to its async nature, see code examples inside
+
+**그렇게 하지 않을 경우:** Looking at a production error log without the context – what happened before – makes it much harder and slower to reason about the issue
+
+🔗 [**자세히 보기: Assign ‘TransactionId’ to each log statement**](/sections/production/assigntransactionid.korean.md)
+
+
+
+## ![✔] 5.15. Set NODE_ENV=production
+
+**핵심요약:** Set the environment variable NODE_ENV to ‘production’ or ‘development’ to flag whether production optimizations should get activated – many NPM packages determining the current environment and optimize their code for production
+
+**그렇게 하지 않을 경우:** Omitting this simple property might greatly degrade performance. For example, when using Express for server-side rendering omitting `NODE_ENV` makes the slower by a factor of three!
+
+🔗 [**자세히 보기: Set NODE_ENV=production**](/sections/production/setnodeenv.korean.md)
+
+
+
+## ![✔] 5.16. Design automated, atomic and zero-downtime deployments
+
+**TL;DR:** Researches show that teams who perform many deployments – lowers the probability of severe production issues. Fast and automated deployments that don’t require risky manual steps and service downtime significantly improves the deployment process. You should probably achieve that using Docker combined with CI tools as they became the industry standard for streamlined deployment
+
+**그렇게 하지 않을 경우:** Long deployments -> production down time & human-related error -> team unconfident and in making deployment -> less deployments and features
+
+
+
+## ![✔] 5.17. Use an LTS release of Node.js
+
+**TL;DR:** Ensure you are using an LTS version of Node.js to receive critical bug fixes, security updates and performance improvements
+
+**그렇게 하지 않을 경우:** Newly discovered bugs or vulnerabilities could be used to exploit an application running in production, and your application may become unsupported by various modules and harder to maintain
+
+🔗 [**자세히 보기: Use an LTS release of Node.js**](/sections/production/LTSrelease.korean.md)
+
+
+
+⬆ 목차로 돌아가기
+
+# `보안`
+
+## 컨트리뷰터들이 현재 작업중 입니다. 함께 하시겠습니까?
+
+
+
+# `성능`
+
+## 컨트리뷰터들이 현재 작업중 입니다. 함께 하시겠습니까?
+
+
+
+# 마일스톤
+
+이 가이드를 관리하고 최신 버전을 유지하기 위해, 우리는 지속해서 가이드라인과 모범 사례들을 커뮤니티의 도움으로 업데이트하고 개선해 나가고 있습니다. 만약 이 프로젝트에 기여를 하고 싶으시면 [마일스톤](https://github.com/i0natan/nodebestpractices/milestones) 을 보고 참여하십시오.
+
+
+
+## 번역
+
+모든 번역은 커뮤니티에 의해 기여되고 있습니다. 이미 완성된 번역이나, 진행중, 새로운 번역에 대한 도움은 언제나 환영합니다!
+
+### 번역 작업 완료
+
+* ![CN](/assets/flags/CN.png) [Chinese](README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
+
+### 번역 작업중
+
+* ![FR](/assets/flags/FR.png) [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/129))
+* ![HE](/assets/flags/HE.png) Hebrew ([Discussion](https://github.com/i0natan/nodebestpractices/issues/156))
+* ![KR](/assets/flags/KR.png) [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/94))
+* ![RU](/assets/flags/RU.png) [Russian](https://github.com/i0natan/nodebestpractices/blob/russian-translation/README.russian.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/105))
+* ![ES](/assets/flags/ES.png) [Spanish](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/95))
+* ![TR](/assets/flags/TR.png) Turkish ([Discussion](https://github.com/i0natan/nodebestpractices/issues/139))
+
+
+
+# Contributors
+
+## `Yoni Goldberg`
+
+Independent Node.js consultant who works with customers in USA, Europe, and Israel on building large-scale scalable Node applications. Many of the best practices above were first published in his blog post at [http://www.goldbergyoni.com](http://www.goldbergyoni.com). Reach Yoni at @goldbergyoni or me@goldbergyoni.com
+
+## `Ido Richter`
+
+👨💻 Software engineer, 🌐 web developer, 🤖 emojis enthusiast
+
+## `Refael Ackermann` [@refack](https://github.com/refack) <refack@gmail.com> (he/him)
+
+Node.js Core Collaborator, been noding since 0.4, and have noded in multiple production sites. Founded `node4good` home of [`lodash-contrib`](https://github.com/node4good/lodash-contrib), [`formage`](https://github.com/node4good/formage), and [`asynctrace`](https://github.com/node4good/asynctrace).
+`refack` on freenode, Twitter, GitHub, GMail, and many other platforms. DMs are open, happy to help
+
+## `Bruno Scheufler`
+
+💻 full-stack web developer and Node.js enthusiast
+
+## `Kyle Martin` [@js-kyle](https://github.com/js-kyle)
+Full Stack Developer based in New Zealand, interested in architecting and building Node.js applications to perform at global scale. Keen contributor to open source software, including Node.js Core.
+
+
+
+# Thank You Notes
+
+This repository is being kept up to date thanks to the help from the community. We appreciate any contribution, from a single word fix to a new best practice. Below is a list of everyone who contributed to this project. A 🌻 marks a successful pull request and a ⭐ marks an approved new best practice
+
+### Flowers
+
+🌻 [Kevin Rambaud](https://github.com/kevinrambaud),
+🌻 [Michael Fine](https://github.com/mfine15),
+🌻 [Shreya Dahal](https://github.com/squgeim),
+🌻 [ChangJoo Park](https://github.com/ChangJoo-Park),
+🌻 [Matheus Cruz Rocha](https://github.com/matheusrocha89),
+🌻 [Yog Mehta](https://github.com/BitYog),
+🌻 [Kudakwashe Paradzayi](https://github.com/kudapara),
+🌻 [t1st3](https://github.com/t1st3),
+🌻 [mulijordan1976](https://github.com/mulijordan1976),
+🌻 [Matan Kushner](https://github.com/matchai),
+🌻 [Fabio Hiroki](https://github.com/fabiothiroki),
+🌻 [James Sumners](https://github.com/jsumners),
+🌻 [Chandan Rai](https://github.com/crowchirp),
+🌻 [Dan Gamble](https://github.com/dan-gamble),
+🌻 [PJ Trainor](https://github.com/trainorpj),
+🌻 [Remek Ambroziak](https://github.com/reod),
+🌻 [Yoni Jah](https://github.com/yonjah),
+🌻 [Misha Khokhlov](https://github.com/hazolsky),
+🌻 [Evgeny Orekhov](https://github.com/EvgenyOrekhov),
+🌻 [Gediminas Petrikas](https://github.com/gediminasml),
+🌻 [Isaac Halvorson](https://github.com/hisaac),
+🌻 [Vedran Karačić](https://github.com/vkaracic),
+🌻 [lallenlowe](https://github.com/lallenlowe),
+🌻 [Nathan Wells](https://github.com/nwwells),
+🌻 [Paulo Vítor S Reis](https://github.com/paulovitin),
+🌻 [syzer](https://github.com/syzer),
+🌻 [David Sancho](https://github.com/davesnx),
+🌻 [Robert Manolea](https://github.com/pupix),
+🌻 [Xavier Ho](https://github.com/spaxe),
+🌻 [Aaron Arney](https://github.com/ocularrhythm),
+🌻 [Jan Charles Maghirang Adona](https://github.com/septa97),
+🌻 [Allen Fang](https://github.com/AllenFang),
+🌻 [Leonardo Villela](https://github.com/leonardovillela),
+🌻 [Michal Zalecki](https://github.com/MichalZalecki)
+🌻 [Chris Nicola](https://github.com/chrisnicola),
+🌻 [Alejandro Corredor](https://github.com/aecorredor),
+🌻 [Ye Min Htut](https://github.com/ymhtut),
+🌻 [cwar](https://github.com/cwar),
+🌻 [Yuwei](https://github.com/keyfoxth),
+🌻 [Utkarsh Bhatt](https://github.com/utkarshbhatt12),
+🌻 [Duarte Mendes](https://github.com/duartemendes),
+🌻 [Sagir Khan](https://github.com/sagirk),
+🌻 [Jason Kim](https://github.com/serv),
+🌻 [Mitja O.](https://github.com/Max101),
+🌻 [Sandro Miguel Marques](https://github.com/SandroMiguel),
+🌻 [Gabe Kuslansky](https://github.com/GabeKuslansky),
+🌻 [Ron Gross](https://github.com/ripper234),
+🌻 [Valeri Karpov](https://github.com/vkarpov15)
+
+
+### Stars
+
+⭐ [Kyle Martin](https://github.com/js-kyle)
+
+
diff --git a/README.md b/README.md
index 33c3fb5c5..37a57f2de 100644
--- a/README.md
+++ b/README.md
@@ -1,1064 +1,1064 @@
-[✔]: assets/images/checkbox-small-blue.png
-
-# Node.js Best Practices
-
-
-
-
-
-
-
-
-
-
-
-[![nodepractices](/assets/images/twitter-s.png)](https://twitter.com/nodepractices/) **Follow us on Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
-
-
-
-Read in a different language: [![CN](/assets/flags/CN.png)**CN**](/README.chinese.md) [(![ES](/assets/flags/ES.png)**ES**, ![FR](/assets/flags/FR.png)**FR**, ![HE](/assets/flags/HE.png)**HE**, ![KR](/assets/flags/KR.png)**KR**, ![RU](/assets/flags/RU.png)**RU** and ![TR](/assets/flags/TR.png)**TR** in progress!)](#translations)
-
-
-
-# Welcome! 3 Things You Ought To Know First:
-
-**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
-
-**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)
-
-**3. Most bullets have additional info -** nearby most best practice bullets you'll find **🔗Read More** link that will present you with code examples, quotes from selected blogs and more info
-
-
-
-## Table of Contents
-
-1. [Project structure Practices (5)](#1-project-structure-practices)
-2. [Error Handling Practices (11) ](#2-error-handling-practices)
-3. [Code Style Practices (12) ](#3-code-style-practices)
-4. [Testing And Overall Quality Practices (8) ](#4-testing-and-overall-quality-practices)
-5. [Going To Production Practices (17) ](#5-going-to-production-practices)
-6. :star: New: [Security Practices (23)](#6-security-best-practices)
-7. Performance Practices ([coming soon](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
-
-
-
-# `1. Project Structure Practices`
-
-## ![✔] 1.1 Structure your solution by components
-
-**TL;DR:** The worst large applications pitfall is maintaining a huge code base with hundreds of dependencies - such a monolith slows down developers as they try to incorporate new features. Instead, partition your code into components, each gets its own folder or a dedicated codebase, and ensure that each unit is kept small and simple. Visit 'Read More' below to see examples of correct project structure
-
-**Otherwise:** When developers who code new features struggle to realize the impact of their change and fear to break other dependant components - deployments become slower and more risky. It's also considered harder to scale-out when all the business units are not separated
-
-🔗 [**Read More: structure by components**](/sections/projectstructre/breakintcomponents.md)
-
-
-
-## ![✔] 1.2 Layer your components, keep Express within its boundaries
-
-**TL;DR:** Each component should contain 'layers' - a dedicated object for the web, logic and data access code. This not only draws a clean separation of concerns but also significantly eases mocking and testing the system. Though this is a very common pattern, API developers tend to mix layers by passing the web layer objects (Express req, res) to business logic and data layers - this makes your application dependant on and accessible by Express only
-
-**Otherwise:** App that mixes web objects with other layers can not be accessed by testing code, CRON jobs and other non-Express callers
-
-🔗 [**Read More: layer your app**](/sections/projectstructre/createlayers.md)
-
-
-
-## ![✔] 1.3 Wrap common utilities as npm packages
-
-**TL;DR:** In a large app that constitutes a large code base, cross-cutting-concern utilities like logger, encryption and alike, should be wrapped by your own code and exposed as private npm packages. This allows sharing them among multiple code bases and projects
-
-**Otherwise:** You'll have to invent your own deployment and dependency wheel
-
-🔗 [**Read More: Structure by feature**](/sections/projectstructre/wraputilities.md)
-
-
-
-## ![✔] 1.4 Separate Express 'app' and 'server'
-
-**TL;DR:** Avoid the nasty habit of defining the entire [Express](https://expressjs.com/) app in a single huge file - separate your 'Express' definition to at least two files: the API declaration (app.js) and the networking concerns (WWW). For even better structure, locate your API declaration within components
-
-**Otherwise:** Your API will be accessible for testing via HTTP calls only (slower and much harder to generate coverage reports). It probably won't be a big pleasure to maintain hundreds of lines of code in a single file
-
-🔗 [**Read More: separate Express 'app' and 'server'**](/sections/projectstructre/separateexpress.md)
-
-
-
-## ![✔] 1.5 Use environment aware, secure and hierarchical config
-
-**TL;DR:** A perfect and flawless configuration setup should ensure (a) keys can be read from file AND from environment variable (b) secrets are kept outside committed code (c) config is hierarchical for easier findability. There are a few packages that can help tick most of those boxes like [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) and [config](https://www.npmjs.com/package/config)
-
-**Otherwise:** Failing to satisfy any of the config requirements will simply bog down the development or devops team. Probably both
-
-🔗 [**Read More: configuration best practices**](/sections/projectstructre/configguide.md)
-
-
-
-⬆ Return to top
-
-# `2. Error Handling Practices`
-
-## ![✔] 2.1 Use Async-Await or promises for async error handling
-
-**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
-
-**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
-
-🔗 [**Read More: avoiding callbacks**](/sections/errorhandling/asyncerrorhandling.md)
-
-
-
-## ![✔] 2.2 Use only the built-in Error object
-
-**TL;DR:** Many throws errors as a string or as some custom type – this complicates the error handling logic and the interoperability between modules. Whether you reject a promise, throw an exception or an emit error – using only the built-in Error object will increase uniformity and prevent loss of information
-
-**Otherwise:** When invoking some component, being uncertain which type of errors come in return – it makes proper error handling much harder. Even worse, using custom types to describe errors might lead to loss of critical error information like the stack trace!
-
-🔗 [**Read More: using the built-in error object**](/sections/errorhandling/useonlythebuiltinerror.md)
-
-
-
-## ![✔] 2.3 Distinguish operational vs programmer errors
-
-**TL;DR:** Operational errors (e.g. API received an invalid input) refer to known cases where the error impact is fully understood and can be handled thoughtfully. On the other hand, programmer error (e.g. trying to read undefined variable) refers to unknown code failures that dictate to gracefully restart the application
-
-**Otherwise:** You may always restart the application when an error appears, but why let ~5000 online users down because of a minor, predicted, operational error? the opposite is also not ideal – keeping the application up when an unknown issue (programmer error) occurred might lead to an unpredicted behavior. Differentiating the two allows acting tactfully and applying a balanced approach based on the given context
-
-🔗 [**Read More: operational vs programmer error**](/sections/errorhandling/operationalvsprogrammererror.md)
-
-
-
-## ![✔] 2.4 Handle errors centrally, not within an Express middleware
-
-**TL;DR:** Error handling logic such as mail to admin and logging should be encapsulated in a dedicated and centralized object that all endpoints (e.g. Express middleware, cron jobs, unit-testing) call when an error comes in
-
-**Otherwise:** Not handling errors within a single place will lead to code duplication and probably to improperly handled errors
-
-🔗 [**Read More: handling errors in a centralized place**](/sections/errorhandling/centralizedhandling.md)
-
-
-
-## ![✔] 2.5 Document API errors using Swagger
-
-**TL;DR:** Let your API callers know which errors might come in return so they can handle these thoughtfully without crashing. This is usually done with REST API documentation frameworks like Swagger
-
-**Otherwise:** An API client might decide to crash and restart only because he received back an error he couldn’t understand. Note: the caller of your API might be you (very typical in a microservice environment)
-
-🔗 [**Read More: documenting errors in Swagger**](/sections/errorhandling/documentingusingswagger.md)
-
-
-
-## ![✔] 2.6 Shut the process gracefully when a stranger comes to town
-
-**TL;DR:** When an unknown error occurs (a developer error, see best practice number #3)- there is uncertainty about the application healthiness. A common practice suggests restarting the process carefully using a ‘restarter’ tool like Forever and PM2
-
-**Otherwise:** When an unfamiliar exception is caught, some object might be in a faulty state (e.g an event emitter which is used globally and not firing events anymore due to some internal failure) and all future requests might fail or behave crazily
-
-🔗 [**Read More: shutting the process**](/sections/errorhandling/shuttingtheprocess.md)
-
-
-
-## ![✔] 2.7 Use a mature logger to increase error visibility
-
-**TL;DR:** A set of mature logging tools like Winston, Bunyan or Log4J, will speed-up error discovery and understanding. So forget about console.log
-
-**Otherwise:** Skimming through console.logs or manually through messy text file without querying tools or a decent log viewer might keep you busy at work until late
-
-🔗 [**Read More: using a mature logger**](/sections/errorhandling/usematurelogger.md)
-
-
-
-## ![✔] 2.8 Test error flows using your favorite test framework
-
-**TL;DR:** Whether professional automated QA or plain manual developer testing – Ensure that your code not only satisfies positive scenario but also handle and return the right errors. Testing frameworks like Mocha & Chai can handle this easily (see code examples within the "Gist popup")
-
-**Otherwise:** Without testing, whether automatically or manually, you can’t rely on our code to return the right errors. Without meaningful errors – there’s no error handling
-
-🔗 [**Read More: testing error flows**](/sections/errorhandling/testingerrorflows.md)
-
-
-
-## ![✔] 2.9 Discover errors and downtime using APM products
-
-**TL;DR:** Monitoring and performance products (a.k.a APM) proactively gauge your codebase or API so they can automagically highlight errors, crashes and slow parts that you were missing
-
-**Otherwise:** You might spend great effort on measuring API performance and downtimes, probably you’ll never be aware which are your slowest code parts under real-world scenario and how these affect the UX
-
-🔗 [**Read More: using APM products**](/sections/errorhandling/apmproducts.md)
-
-
-
-## ![✔] 2.10 Catch unhandled promise rejections
-
-**TL;DR:** Any exception thrown within a promise will get swallowed and discarded unless a developer didn’t forget to explicitly handle. Even if your code is subscribed to process.uncaughtException! Overcome this by registering to the event process.unhandledRejection
-
-**Otherwise:** Your errors will get swallowed and leave no trace. Nothing to worry about
-
-🔗 [**Read More: catching unhandled promise rejection**](/sections/errorhandling/catchunhandledpromiserejection.md)
-
-
-
-## ![✔] 2.11 Fail fast, validate arguments using a dedicated library
-
-**TL;DR:** This should be part of your Express best practices – Assert API input to avoid nasty bugs that are much harder to track later. The validation code is usually tedious unless you are using a very cool helper library like Joi
-
-**Otherwise:** Consider this – your function expects a numeric argument “Discount” which the caller forgets to pass, later on, your code checks if Discount!=0 (amount of allowed discount is greater than zero), then it will allow the user to enjoy a discount. OMG, what a nasty bug. Can you see it?
-
-🔗 [**Read More: failing fast**](/sections/errorhandling/failfast.md)
-
-
-
-⬆ Return to top
-
-# `3. Code Style Practices`
-
-## ![✔] 3.1 Use ESLint
-
-**TL;DR:** [ESLint](https://eslint.org) is the de-facto standard for checking possible code errors and fixing code style, not only to identify nitty-gritty spacing issues but also to detect serious code anti-patterns like developers throwing errors without classification. Though ESLint can automatically fix code styles, other tools like [prettier](https://www.npmjs.com/package/prettier) and [beautify](https://www.npmjs.com/package/js-beautify) are more powerful in formatting the fix and work in conjunction with ESLint
-
-**Otherwise:** Developers will focus on tedious spacing and line-width concerns and time might be wasted overthinking about the project's code style
-
-
-
-## ![✔] 3.2 Node.js Specific Plugins
-
-**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)
-
-**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
-
-
-
-## ![✔] 3.3 Start a Codeblock's Curly Braces on the Same Line
-
-**TL;DR:** The opening curly braces of a code block should be in the same line of the opening statement
-
-### Code Example
-
-```javascript
-// Do
-function someFunction() {
- // code block
-}
-
-// Avoid
-function someFunction()
-{
- // code block
-}
-```
-
-**Otherwise:** Deferring from this best practice might lead to unexpected results, as seen in the StackOverflow thread below:
-
-🔗 [**Read more:** "Why does a results vary based on curly brace placement?" (Stackoverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
-
-
-
-## ![✔] 3.4 Don't Forget the Semicolon
-
-**TL;DR:** While not unanimously agreed upon, it is still recommended to put a semicolon at the end of each statement. This will make your code more readable and explicit to other developers who read it
-
-**Otherwise:** As seen in the previous section, JavaScript's interpreter automatically adds a semicolon at the end of a statement if there isn't one which might lead to some undesired results
-
-
-
-## ![✔] 3.5 Name Your Functions
-
-**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
-
-**Otherwise:** Debugging production issues using a core dump (memory snapshot) might become challenging as you notice significant memory consumption from anonymous functions
-
-
-
-## ![✔] 3.6 Naming conventions for variables, constants, functions and classes
-
-**TL;DR:** Use **_lowerCamelCase_** when naming constants, variables and functions and **_UpperCamelCase_** (capital first letter as well) when naming classes. This will help you to easily distinguish between plain variables/functions, and classes that require instantiation. Use descriptive names, but try to keep them short
-
-**Otherwise:** Javascript is the only language in the world which allows invoking a constructor ("Class") directly without instantiating it first. Consequently, Classes and function-constructors are differentiated by starting with UpperCamelCase
-
-### Code Example
-
-```javascript
-// for class name we use UpperCamelCase
-class SomeClassExample {}
-
-// for const names we use the const keyword and lowerCamelCase
-const config = {
- key: 'value'
-};
-
-// for variables and functions names we use lowerCamelCase
-let someVariableExample = 'value';
-function doSomething() {}
-```
-
-
-
-## ![✔] 3.7 Prefer const over let. Ditch the var
-
-**TL;DR:** Using `const` means that once a variable is assigned, it cannot be reassigned. Preferring const will help you to not be tempted to use the same variable for different uses, and make your code clearer. If a variable needs to be reassigned, in a for loop, for example, use `let` to declare it. Another important aspect of `let` is that a variable declared using it is only available in the block scope in which it was defined. `var` is function scoped, not block scoped, and [shouldn't be used in ES6](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70) now that you have const and let at your disposal
-
-**Otherwise:** Debugging becomes way more cumbersome when following a variable that frequently changes
-
-🔗 [**Read more: JavaScript ES6+: var, let, or const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
-
-
-
-## ![✔] 3.8 Requires come first, and not inside functions
-
-**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
-
-**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
-
-
-
-## ![✔] 3.9 Do Require on the folders, not directly on the files
-
-**TL;DR:** When developing a module/library in a folder, place an index.js file that exposes the module's
-internals so every consumer will pass through it. This serves as an 'interface' to your module and eases
-future changes without breaking the contract
-
-**Otherwise:** Changing the internal structure of files or the signature may break the interface with
-clients
-
-### Code example
-
-```javascript
-// Do
-module.exports.SMSProvider = require('./SMSProvider');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver');
-
-// Avoid
-module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
-```
-
-
-
-## ![✔] 3.10 Use the `===` operator
-
-**TL;DR:** Prefer the strict equality operator `===` over the weaker abstract equality operator `==`. `==` will compare two variables after converting them to a common type. There is no type conversion in `===`, and both variables must be of the same type to be equal
-
-**Otherwise:** Unequal variables might return true when compared with the `==` operator
-
-### Code example
-
-```javascript
-'' == '0' // false
-0 == '' // true
-0 == '0' // true
-
-false == 'false' // false
-false == '0' // true
-
-false == undefined // false
-false == null // false
-null == undefined // true
-
-' \t\r\n ' == 0 // true
-```
-
-All statements above will return false if used with `===`
-
-
-
-## ![✔] 3.11 Use Async Await, avoid callbacks
-
-**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
-
-**Otherwise:** Handling async errors in callback style is probably the fastest way to hell - this style forces to check errors all over, deal with awkward code nesting and make it difficult to reason about the code flow
-
-🔗[**Read more:** Guide to async await 1.0](https://github.com/yortus/asyncawait)
-
-
-
-## ![✔] 3.12 Use Fat (=>) Arrow Functions
-
-**TL;DR:** Though it's recommended to use async-await and avoid function parameters when dealing with older API that accept promises or callbacks - arrow functions make the code structure more compact and keep the lexical context of the root function (i.e. 'this')
-
-**Otherwise:** Longer code (in ES5 functions) is more prone to bugs and cumbersome to read
-
-🔗 [**Read mode: It’s Time to Embrace Arrow Functions**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
-
-
-
-⬆ Return to top
-
-# `4. Testing And Overall Quality Practices`
-
-## ![✔] 4.1 At the very least, write API (component) testing
-
-**TL;DR:** Most projects just don't have any automated testing due to short timetables or often the 'testing project' run out of control and being abandoned. For that reason, prioritize and start with API testing which is the easiest to write and provide more coverage than unit testing (you may even craft API tests without code using tools like [Postman](https://www.getpostman.com/). Afterward, should you have more resources and time, continue with advanced test types like unit testing, DB testing, performance testing, etc
-
-**Otherwise:** You may spend long days on writing unit tests to find out that you got only 20% system coverage
-
-
-
-## ![✔] 4.2 Detect code issues with a linter
-
-**TL;DR:** Use a code linter to check basic quality and detect anti-patterns early. Run it before any test and add it as a pre-commit git-hook to minimize the time needed to review and correct any issue. Also check [Section 3](https://github.com/i0natan/nodebestpractices#3-code-style-practices) on Code Style Practices
-
-**Otherwise:** You may let pass some anti-pattern and possible vulnerable code to your production environment.
-
-
-
-## ![✔] 4.3 Carefully choose your CI platform (Jenkins vs CircleCI vs Travis vs Rest of the world)
-
-**TL;DR:** Your continuous integration platform (CICD) will host all the quality tools (e.g test, lint) so it should come with a vibrant ecosystem of plugins. [Jenkins](https://jenkins.io/) used to be the default for many projects as it has the biggest community along with a very powerful platform at the price of complex setup that demands a steep learning curve. Nowadays, it became much easier to set up a CI solution using SaaS tools like [CircleCI](https://circleci.com) and others. These tools allow crafting a flexible CI pipeline without the burden of managing the whole infrastructure. Eventually, it's a trade-off between robustness and speed - choose your side carefully
-
-**Otherwise:** Choosing some niche vendor might get you blocked once you need some advanced customization. On the other hand, going with Jenkins might burn precious time on infrastructure setup
-
-🔗 [**Read More: Choosing CI platform**](/sections/testingandquality/citools.md)
-
-
-
-## ![✔] 4.4 Constantly inspect for vulnerable dependencies
-
-**TL;DR:** Even the most reputable dependencies such as Express have known vulnerabilities. This can get easily tamed using community and commercial tools such as 🔗 [nsp](https://github.com/nodesecurity/nsp) that can be invoked from your CI on every build
-
-**Otherwise:** Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
-
-
-
-## ![✔] 4.5 Tag your tests
-
-**TL;DR:** Different tests must run on different scenarios: quick smoke, IO-less, tests should run when a developer saves or commits a file, full end-to-end tests usually run when a new pull request is submitted, etc. This can be achieved by tagging tests with keywords like #cold #api #sanity so you can grep with your testing harness and invoke the desired subset. For example, this is how you would invoke only the sanity test group with [Mocha](https://mochajs.org/): mocha --grep 'sanity'
-
-**Otherwise:** Running all the tests, including tests that perform dozens of DB queries, any time a developer makes a small change can be extremely slow and keeps developers away from running tests
-
-
-
-## ![✔] 4.6 Check your test coverage, it helps to identify wrong test patterns
-
-**TL;DR:** Code coverage tools like [Istanbul/NYC ](https://github.com/gotwarlost/istanbul)are great for 3 reasons: it comes for free (no effort is required to benefit this reports), it helps to identify a decrease in testing coverage, and last but not least it highlights testing mismatches: by looking at colored code coverage reports you may notice, for example, code areas that are never tested like catch clauses (meaning that tests only invoke the happy paths and not how the app behaves on errors). Set it to fail builds if the coverage falls under a certain threshold
-
-**Otherwise:** There won't be any automated metric telling you when a large portion of your code is not covered by testing
-
-
-
-## ![✔] 4.7 Inspect for outdated packages
-
-**TL;DR:** Use your preferred tool (e.g. 'npm outdated' or [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) to detect installed packages which are outdated, inject this check into your CI pipeline and even make a build fail in a severe scenario. For example, a severe scenario might be when an installed package is 5 patch commits behind (e.g. local version is 1.3.1 and repository version is 1.3.8) or it is tagged as deprecated by its author - kill the build and prevent deploying this version
-
-**Otherwise:** Your production will run packages that have been explicitly tagged by their author as risky
-
-
-
-## ![✔] 4.8 Use docker-compose for e2e testing
-
-**TL;DR:** End to end (e2e) testing which includes live data used to be the weakest link of the CI process as it depends on multiple heavy services like DB. Docker-compose turns this problem into a breeze by crafting production-like environment using a simple text file and easy commands. It allows crafting all the dependent services, DB and isolated network for e2e testing. Last but not least, it can keep a stateless environment that is invoked before each test suite and dies right after
-
-**Otherwise:** Without docker-compose teams must maintain a testing DB for each testing environment including developers machines, keep all those DBs in sync so test results won't vary across environments
-
-
-
-## ![✔] 4.9 Refactor regularly using static analysis tools
-
-**TL;DR:** Using static analysis tools helps by giving objective ways to improve code quality and keep your code maintainable. You can add static analysis tools to your CI build to fail when it finds code smells. Its main selling points over plain linting are the ability to inspect quality in the context of multiple files (e.g. detect duplications), perform advanced analysis (e.g. code complexity) and follow the history and progress of code issues. Two examples of tools you can use are [Sonarqube](https://www.sonarqube.org/) (2,600+ [stars](https://github.com/SonarSource/sonarqube)) and [Code Climate](https://codeclimate.com/) (1,500+ [stars](https://github.com/codeclimate/codeclimate)).
-
-**Otherwise:** With poor code quality, bugs and performance will always be an issue that no shiny new library or state of the art features can fix.
-
-🔗 [**Read More: Refactoring!**](/sections/testingandquality/refactoring.md)
-
-
-
-
-⬆ Return to top
-
-# `5. Going To Production Practices`
-
-## ![✔] 5.1. Monitoring!
-
-**TL;DR:** Monitoring is a game of finding out issues before customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my suggestions inside), then go over additional fancy features and choose the solution that ticks all boxes. Click ‘The Gist’ below for an overview of the solutions
-
-**Otherwise:** Failure === disappointed customers. Simple
-
-🔗 [**Read More: Monitoring!**](/sections/production/monitoring.md)
-
-
-
-## ![✔] 5.2. Increase transparency using smart logging
-
-**TL;DR:** Logs can be a dumb warehouse of debug statements or the enabler of a beautiful dashboard that tells the story of your app. Plan your logging platform from day 1: how logs are collected, stored and analyzed to ensure that the desired information (e.g. error rate, following an entire transaction through services and servers, etc) can really be extracted
-
-**Otherwise:** You end-up with a black box that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**Read More: Increase transparency using smart logging**](/sections/production/smartlogging.md)
-
-
-
-## ![✔] 5.3. Delegate anything possible (e.g. gzip, SSL) to a reverse proxy
-
-**TL;DR:** Node is awfully bad at doing CPU intensive tasks like gzipping, SSL termination, etc. You should use ‘real’ middleware services like nginx, HAproxy or cloud vendor services instead
-
-**Otherwise:** Your poor single thread will stay busy doing infrastructural tasks instead of dealing with your application core and performance will degrade accordingly
-
-🔗 [**Read More: Delegate anything possible (e.g. gzip, SSL) to a reverse proxy**](/sections/production/delegatetoproxy.md)
-
-
-
-## ![✔] 5.4. Lock dependencies
-
-**TL;DR:** Your code must be identical across all environments, but amazingly npm lets dependencies drift across environments by default – when you install packages at various environments it tries to fetch packages’ latest patch version. Overcome this by using npm config files, .npmrc, that tell each environment to save the exact (not the latest) version of each package. Alternatively, for finer grain control use npm” shrinkwrap”. \*Update: as of NPM5, dependencies are locked by default. The new package manager in town, Yarn, also got us covered by default
-
-**Otherwise:** QA will thoroughly test the code and approve a version that will behave differently at production. Even worse, different servers at the same production cluster might run different code
-
-🔗 [**Read More: Lock dependencies**](/sections/production/lockdependencies.md)
-
-
-
-## ![✔] 5.5. Guard process uptime using the right tool
-
-**TL;DR:** The process must go on and get restarted upon failures. For simple scenarios, ‘restarter’ tools like PM2 might be enough but in today ‘dockerized’ world – a cluster management tools should be considered as well
-
-**Otherwise:** Running dozens of instances without a clear strategy and too many tools together (cluster management, docker, PM2) might lead to a DevOps chaos
-
-🔗 [**Read More: Guard process uptime using the right tool**](/sections/production/guardprocess.md)
-
-
-
-## ![✔] 5.6. Utilize all CPU cores
-
-**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)
-
-**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!)
-
-🔗 [**Read More: Utilize all CPU cores**](/sections/production/utilizecpu.md)
-
-
-
-## ![✔] 5.7. Create a ‘maintenance endpoint’
-
-**TL;DR:** Expose a set of system-related information, like memory usage and REPL, etc in a secured API. Although it’s highly recommended to rely on standard and battle-tests tools, some valuable information and operations are easier done using code
-
-**Otherwise:** You’ll find that you’re performing many “diagnostic deploys” – shipping code to production only to extract some information for diagnostic purposes
-
-🔗 [**Read More: Create a ‘maintenance endpoint’**](/sections/production/createmaintenanceendpoint.md)
-
-
-
-## ![✔] 5.8. Discover errors and downtime using APM products
-
-**TL;DR:** Monitoring and performance products (a.k.a APM) proactively gauge codebase and API so they can auto-magically go beyond traditional monitoring and measure the overall user-experience across services and tiers. For example, some APM products can highlight a transaction that loads too slow on the end-users side while suggesting the root cause
-
-**Otherwise:** You might spend great effort on measuring API performance and downtimes, probably you’ll never be aware which is your slowest code parts under real-world scenario and how these affects the UX
-
-🔗 [**Read More: Discover errors and downtime using APM products**](/sections/production/apmproducts.md)
-
-
-
-## ![✔] 5.9. Make your code production-ready
-
-**TL;DR:** Code with the end in mind, plan for production from day 1. This sounds a bit vague so I’ve compiled a few development tips that are closely related to production maintenance (click Gist below)
-
-**Otherwise:** A world champion IT/DevOps guy won’t save a system that is badly written
-
-🔗 [**Read More: Make your code production-ready**](/sections/production/productoncode.md)
-
-
-
-## ![✔] 5.10. Measure and guard the memory usage
-
-**TL;DR:** Node.js has controversial relationships with memory: the v8 engine has soft limits on memory usage (1.4GB) and there are known paths to leaks memory in Node’s code – thus watching Node’s process memory is a must. In small apps, you may gauge memory periodically using shell commands but in medium-large app consider baking your memory watch into a robust monitoring system
-
-**Otherwise:** Your process memory might leak a hundred megabytes a day like how it happened at [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)
-
-🔗 [**Read More: Measure and guard the memory usage**](/sections/production/measurememory.md)
-
-
-
-## ![✔] 5.11. Get your frontend assets out of Node
-
-**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
-
-**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
-
-🔗 [**Read More: Get your frontend assets out of Node**](/sections/production/frontendout.md)
-
-
-
-## ![✔] 5.12. Be stateless, kill your Servers almost every day
-
-**TL;DR:** Store any type of data (e.g. users session, cache, uploaded files) within external data stores. Consider ‘killing’ your servers periodically or use ‘serverless’ platform (e.g. AWS Lambda) that explicitly enforces a stateless behavior
-
-**Otherwise:** Failure at a given server will result in application downtime instead of just killing a faulty machine. Moreover, scaling-out elasticity will get more challenging due to the reliance on a specific server
-
-🔗 [**Read More: Be stateless, kill your Servers almost every day**](/sections/production/bestateless.md)
-
-
-
-## ![✔] 5.13. Use tools that automatically detect vulnerabilities
-
-**TL;DR:** Even the most reputable dependencies such as Express have known vulnerabilities (from time to time) that can put a system at risk. This can get easily tamed using community and commercial tools that constantly check for vulnerabilities and warn (locally or at GitHub), some can even patch them immediately
-
-**Otherwise:** Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
-
-🔗 [**Read More: Use tools that automatically detect vulnerabilities**](/sections/production/detectvulnerabilities.md)
-
-
-
-## ![✔] 5.14. Assign ‘TransactionId’ to each log statement
-
-**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 to its async nature, see code examples inside
-
-**Otherwise:** Looking at a production error log without the context – what happened before – makes it much harder and slower to reason about the issue
-
-🔗 [**Read More: Assign ‘TransactionId’ to each log statement**](/sections/production/assigntransactionid.md)
-
-
-
-## ![✔] 5.15. Set NODE_ENV=production
-
-**TL;DR:** Set the environment variable NODE_ENV to ‘production’ or ‘development’ to flag whether production optimizations should get activated – many npm packages determining the current environment and optimize their code for production
-
-**Otherwise:** Omitting this simple property might greatly degrade performance. For example, when using Express for server-side rendering omitting `NODE_ENV` makes the slower by a factor of three!
-
-🔗 [**Read More: Set NODE_ENV=production**](/sections/production/setnodeenv.md)
-
-
-
-## ![✔] 5.16. Design automated, atomic and zero-downtime deployments
-
-**TL;DR:** Researches show that teams who perform many deployments – lowers the probability of severe production issues. Fast and automated deployments that don’t require risky manual steps and service downtime significantly improves the deployment process. You should probably achieve that using Docker combined with CI tools as they became the industry standard for streamlined deployment
-
-**Otherwise:** Long deployments -> production down time & human-related error -> team unconfident and in making deployment -> less deployments and features
-
-
-
-## ![✔] 5.17. Use an LTS release of Node.js
-
-**TL;DR:** Ensure you are using an LTS version of Node.js to receive critical bug fixes, security updates and performance improvements
-
-**Otherwise:** Newly discovered bugs or vulnerabilities could be used to exploit an application running in production, and your application may become unsupported by various modules and harder to maintain
-
-🔗 [**Read More: Use an LTS release of Node.js**](/sections/production/LTSrelease.md)
-
-
-
-⬆ Return to top
-
-# `6. Security Best Practices`
-
-
-
-
-
-## ![✔] 6.1. Embrace linter security rules
-
-
-
-**TL;DR:** Make use of security-related linter plugins such as [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security) to catch security vulnerabilities and issues as early as possible , at best while they're being coded. This can help catching security weaknesses like using eval, invoking a child process or importing a module with a string literal (e.g. user input). Click 'Read more' below to see code examples that will get caught by a security linter
-
-**Otherwise:** What could have been a straightforward security weakness during development becomes a major issue in production. Also, the project may not follow consistent code security practices, leading to vulnerabilities being introduced, or sensitive secrets committed into remote repositories
-
-
-🔗 [**Read More: Lint rules**](sections/security/lintrules.md)
-
-
-
-## ![✔] 6.2. Limit concurrent requests using a middleware
-
-
-
-**TL;DR:** DOS attacks are very popular and relatively easy to conduct. Implement rate limiting using an external service such as cloud load balancers, cloud firewalls, nginx, or (for smaller and less critical apps) a rate limiting middleware (e.g. [express-rate-limit](https://www.npmjs.com/package/express-rate-limit))
-
-**Otherwise:** An application could be subject to an attack resulting in a denial of service where real users receive a degraded or unavailable service.
-
-🔗 [**Read More: Implement rate limiting**](sections/security/limitrequests.md)
-
-
-
-## ![✔] 6.3 Extract secrets from config files or use packages to encrypt them
-
-
-
-
-**TL;DR:** Never store plain-text secrets in configuration files or source code. Instead, make use of secret-management systems like Vault products, Kubernetes/Docker Secrets, or using environment variables. As a last result, secrets stored in source control must be encrypted and managed (rolling keys, expiring, auditing, etc). Make use of pre-commit/push hooks to prevent committing secrets accidentally
-
-**Otherwise:** Source control, even for private repositories, can mistakenly be made public, at which point all secrets are exposed. Access to source control for an external party will inadvertently provide access to related systems (databases, apis, services, etc).
-
-
-🔗 [**Read More: Secret management**](sections/security/secretmanagement.md)
-
-
-
-
-## ![✔] 6.4. Prevent query injection vulnerabilities with ORM/ODM libraries
-
-
-
-**TL;DR:** To prevent SQL/NoSQL injection and other malicious attacks, always make use of an ORM/ODM or a database library that escapes data or supports named or indexed parameterized queries, and takes care of validating user input for expected types. Never just use JavaScript template strings or string concatenation to inject values into queries as this opens your application to a wide spectrum of vulnerabilities. All the reputable Node.js data access libraries (e.g. [Sequelize](https://github.com/sequelize/sequelize), [Knex](https://github.com/tgriesser/knex), [mongoose](https://github.com/Automattic/mongoose)) have built-in protection agains injection attacks
-
-**Otherwise:** Unvalidated or unsanitized user input could lead to operator injection when working with MongoDB for NoSQL, and not using a proper sanitization system or ORM will easily allow SQL injection attacks, creating a giant vulnerability.
-
-🔗 [**Read More: Query injection prevention using ORM/ODM libraries**](/sections/security/ormodmusage.md)
-
-
-
-
-## ![✔] 6.5. Collection of generic security best practices
-
-**TL;DR:** These is a collection of security advice that are not related directly to Node.js - the Node implementation is not much different than any other language. Click read more to skim through.
-
-
-🔗 [**Read More: Common security best practices**](/sections/security/commonsecuritybestpractices.md)
-
-
-
-## ![✔] 6.6. Adjust the HTTP response headers for enhanced security
-
-
-
-**TL;DR:** Your application should be using secure headers to prevent attackers from using common attacks like cross-site scripting (XSS), clickjacking and other malicious attacks. These can be configured easily using modules like [helmet](https://www.npmjs.com/package/helmet).
-
-**Otherwise:** Attackers could perform direct attacks on your application's users, leading huge security vulnerabilities
-
-
-🔗 [**Read More: Using secure headers in your application**](/sections/security/secureheaders.md)
-
-
-
-## ![✔] 6.7. Constantly and automatically inspect for vulnerable dependencies
-
-
-
-**TL;DR:** With the npm ecosystem it is common to have many dependencies for a project. Dependencies should always be kept in check as new vulnerabilities are found. Use tools like [npm audit](https://docs.npmjs.com/cli/audit) or [snyk](https://snyk.io/) to track, monitor and patch vulnerable dependencies. Integrate these tools with your CI setup so you catch a vulnerable dependency before it makes it to production.
-
-**Otherwise:** An attacker could detect your web framework and attack all its known vulnerabilities.
-
-🔗 [**Read More: Dependency security**](/sections/security/dependencysecurity.md)
-
-
-
-
-## ![✔] 6.8. Avoid using the Node.js crypto library for handling passwords, use Bcrypt
-
-
-
-
-**TL;DR:** Passwords or secrets (API keys) should be stored using a secure hash + salt function like `bcrypt`, that should be a preferred choice over its JavaScript implementation due to performance and security reasons.
-
-**Otherwise:** Passwords or secrets that are persisted without using a secure function are vulnerable to brute forcing and dictionary attacks that will lead to their disclosure eventually.
-
-🔗 [**Read More: Use Bcrypt**](/sections/security/bcryptpasswords.md)
-
-
-
-## ![✔] 6.9. Escape HTML, JS and CSS output
-
-
-
-**TL;DR:** Untrusted data that is sent down to the browser might get executed instead of just being displayed, this is commonly being referred as a cross-site-scripting (XSS) attack. Mitigate this by using dedicated libraries that explicitly mark the data as pure content that should never get executed (i.e. encoding, escaping)
-
-**Otherwise:** An attacker might store a malicious JavaScript code in your DB which will then be sent as-is to the poor clients
-
-🔗 [**Read More: Escape output**](/sections/security/escape-output.md)
-
-
-
-## ![✔] 6.10. Validate incoming JSON schemas
-
-
-
-**TL;DR:** Validate the incoming requests' body payload and ensure it qualifies the expectations, fail fast if it doesn't. To avoid tedious validation coding within each route you may use lightweight JSON-based validation schemas such as [jsonschema](https://www.npmjs.com/package/jsonschema) or [joi](https://www.npmjs.com/package/joi)
-
-**Otherwise:** Your generosity and permissive approach greatly increases the attack surface and encourages the attacker to try out many inputs until they find some combination to crash the application
-
-🔗 [**Read More: Validate incoming JSON schemas**](/sections/security/validation.md)
-
-
-
-
-## ![✔] 6.11. Support blacklisting JWTs
-
-
-
-**TL;DR:** When using JSON Web Tokens (for example, with [Passport.js](https://github.com/jaredhanson/passport)), by default there's no mechanism to revoke access from issued tokens. Once you discover some malicious user activity, there's no way to stop them from accessing the system as long as they hold a valid token. Mitigate this by implementing a blacklist of untrusted tokens that are validated on each request.
-
-**Otherwise:** Expired, or misplaced tokens could be used maliciously by a third party to access an application and impersonate the owner of the token.
-
-
-🔗 [**Read More: Blacklist JSON Web Tokens**](/sections/security/expirejwt.md)
-
-
-
-
-## ![✔] 6.12. Limit the allowed login requests of each user
-
-
-
-**TL;DR:** A brute force protection middleware such as [express-brute](https://www.npmjs.com/package/express-brute) should be used inside an express application to prevent brute force/dictionary attacks on sensitive routes such as /admin or /login based on request properties such as the user name, or other identifiers such as body parameters
-
-**Otherwise:** An attacker can issue unlimited automated password attempts to gain access to privileged accounts on an application
-
-🔗 [**Read More: Login rate limiting**](/sections/security/login-rate-limit.md)
-
-
-
-
-## ![✔] 6.13. Run Node.js as non-root user
-
-
-
-**TL;DR:** There is a common scenario where Node.js runs as a root user with unlimited permissions. For example, this is the default behaviour in Docker containers. It's recommended to create a non-root user and either bake it into the Docker image (examples given below) or run the process on this users' behalf by invoking the container with the flag "-u username"
-
-**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)
-
-
-🔗 [**Read More: Run Node.js as non-root user**](/sections/security/non-root-user.md)
-
-
-
-
-## ![✔] 6.14. Limit payload size using a reverse-proxy or a middleware
-
-
-
-**TL;DR:** The bigger the body payload is, the harder your single thread works in processing it. This is an opportunity for attackers to bring servers to their knees without tremendous amount of requests (DOS/DDOS attacks). Mitigate this limiting the body size of incoming requests on the edge (e.g. firewall, ELB) or by configuring [express body parser](https://github.com/expressjs/body-parser) to accept only small-size payloads
-
-**Otherwise:** Your application will have to deal with large requests, unable to process the other important work it has to accomplish, leading to performance implications and vulnerability towards DOS attacks
-
-
-🔗 [**Read More: Limit payload size**](/sections/security/requestpayloadsizelimit.md)
-
-
-
-
-## ![✔] 6.15. Avoid JavaScript eval statements
-
-
-
-
-**TL;DR:** `eval` is evil as it allows executing a custom JavaScript code during run time. This is not just a performance concern but also an important security concern due to malicious JavaScript code that may be sourced from user input. Another language feature that should be avoided is `new Function` constructor. `setTimeout` and `setInterval` should never be passed dynamic JavaScript code either.
-
-**Otherwise:** Malicious JavaScript code finds a way into a text passed into `eval` or other real-time evaluating JavaScript language functions, and will gain complete access to JavaScript permissions on the page. This vulnerability is often manifested as an XSS attack.
-
-
-🔗 [**Read More: Avoid JavaScript eval statements**](/sections/security/avoideval.md)
-
-
-
-
-## ![✔] 6.16. Prevent evil RegEx from overloading your single thread execution
-
-
-
-**TL;DR:** Regular Expressions, while being handy, pose a real threat to JavaScript applications at large, and the Node.js platform in particular. A user input for text to match might require an outstanding amount of CPU cycles to process. RegEx processing might be inefficient to an extent that a single request that validates 10 words can block the entire event loop for 6 seconds and set the CPU on 🔥. For that reason, prefer third-party validation packages like [validator.js](https://github.com/chriso/validator.js) instead of writing your own Regex patterns, or make use of [safe-regex](https://github.com/substack/safe-regex) to detect vulnerable regex patterns
-
-**Otherwise:** Poorly written regexes could be susceptible to Regular Expression DoS attacks that will block the event loop completely. For example, the popular `moment` package was found vulnerable with malicious RegEx usage in November of 2017
-
-🔗 [**Read More: Prevent malicious RegEx**](/sections/security/regex.md)
-
-
-
-## ![✔] 6.17. Avoid module loading using a variable
-
-
-
-
-**TL;DR:** Avoid requiring/importing another file with a path that was given as parameter due to the concern that it could have originated from user input. This rule can be extended for accessing files in general (i.e. `fs.readFile()`) or other sensitive resource access with dynamic variables originating from user input. [Eslint-plugin-security](https://www.npmjs.com/package/eslint-plugin-security) linter can catch such patterns and warn early enough
-
-**Otherwise:** Malicious user input could find its way to a parameter that is used to require tampered files, for example a previously uploaded file on the filesystem, or access already existing system files.
-
-
-🔗 [**Read More: Safe module loading**](/sections/security/safemoduleloading.md)
-
-
-
-## ![✔] 6.18. Run unsafe code in a sandbox
-
-
-
-**TL;DR:** When tasked to run external code that is given at run-time (e.g. plugin), use any sort of 'sandbox' execution environment that isolates and guards the main code against the plugin. This can be achieved using a dedicated process (e.g. cluster.fork()), serverless environment or dedicated npm packages that acting as a sandbox
-
-**Otherwise:** A plugin can attack through an endless variety of options like infinite loops, memory overloading, and access to sensitive process environment variables
-
-
-🔗 [**Read More: Run unsafe code in a sandbox**](/sections/security/sandbox.md)
-
-
-
-
-## ![✔] 6.19. Take extra care when working with child processes
-
-
-
-**TL;DR:** Avoid using child processes when possible and validate and sanitize input to mitigate shell injection attacks if you still have to. Prefer using `child_process.execFile` which by definition will only execute a single command with a set of attributes and will not allow shell parameter expansion.
-
-**Otherwise:** Naive use of child processes could result in remote command execution or shell injection attacks due to malicious user input passed to an unsanitized system command.
-
-🔗 [**Read More: Be cautious when working with child processes**](/sections/security/childprocesses.md)
-
-
-
-
-## ![✔] 6.20. Hide error details from clients
-
-
-
-**TL;DR:** An integrated express error handler hides the error details by default. However, great are the chances that you implement your own error handling logic with custom Error objects (considered by many as a best practice). If you do so, ensure not to return the entire Error object to the client, which might contain some sensitive application details
-
-**Otherwise:** Sensitive application details such as server file paths, third party modules in use, and other internal workflows of the application which could be exploited by an attacker, could be leaked from information found in a stack trace
-
-🔗 [**Read More: Hide error details from client**](/sections/security/hideerrors.md)
-
-
-
-## ![✔] 6.21. Configure 2FA for npm or Yarn
-
-
-
-**TL;DR:** Any step in the development chain should be protected with MFA (multi-factor authentication), npm/Yarn are a sweet opportunity for attackers who can get their hands on some developer's password. Using developer credentials, attackers can inject malicious code into libraries that are widely installed across projects and services. Maybe even across the web if published in public. Enabling 2-factor-authentication in npm leaves almost zero chances for attackers to alter your package code.
-
-**Otherwise:** [Have you heard about the eslint developer who's password was hijacked?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
-
-
-
-
-## ![✔] 6.22. Modify session middleware settings
-
-
-
-**TL;DR:** Each web framework and technology has its known weaknesses - telling an attacker which web framework we use is a great help for them. Using the default settings for session middlewares can expose your app to module- and framework-specific hijacking attacks in a similar way to the `X-Powered-By` header. Try hiding anything that identifies and reveals your tech stack (E.g. Node.js, express)
-
-**Otherwise:** Cookies could be sent over insecure connections, and an attacker might use session identification to identify the underlying framework of the web application, as well as module-specific vulnerabilities
-
-🔗 [**Read More: Cookie and session security**](/sections/security/sessions.md)
-
-
-
-## ![✔] 6.23. Avoid DOS attacks by explicitly setting when a process should crash
-
-
-
-**TL;DR:** The Node process will crash when errors are not handled. Many best practices even recommend to exit even though an error was caught and got handled. Express, for example, will crash on any asynchronous error - unless you wrap routes with a catch clause. This opens a very sweet attack spot for attackers who recognize what input makes the process crash and repeatedly send the same request. There's no instant remedy for this but a few techniques can mitigate the pain: Alert with critical severity anytime a process crashes due to an unhandled error, validate the input and avoid crashing the process due to invalid user input, wrap all routes with a catch and consider not to crash when an error originated within a request (as opposed to what happens globally)
-
-**Otherwise:** This is just an educated guess: given many Node.js applications, if we try passing an empty JSON body to all POST requests - a handful of applications will crash. At that point, we can just repeat sending the same request to take down the applications with ease
-
-
-
-
-⬆ Return to top
-
-# `API Practices`
-
-## Our contributors are working on this section. Would you like to join?
-
-
-# `Performance Practices`
-
-## Our contributors are working on this section. Would you like to join?
-
-
-
-# Milestones
-
-To maintain this guide and keep it up to date, we are constantly updating and improving the guidelines and best practices with the help of the community. You can follow our [milestones](https://github.com/i0natan/nodebestpractices/milestones) and join the working groups if you want to contribute to this project
-
-
-
-## Translations
-
-All translations are contributed by the community. We will be happy to get any help with either completed, ongoing or new translations!
-
-### Completed translations
-
-* ![CN](/assets/flags/CN.png) [Chinese](README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
-
-### Translations in progress
-
-* ![FR](/assets/flags/FR.png) [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/129))
-* ![HE](/assets/flags/HE.png) Hebrew ([Discussion](https://github.com/i0natan/nodebestpractices/issues/156))
-* ![KR](/assets/flags/KR.png) [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/94))
-* ![RU](/assets/flags/RU.png) [Russian](https://github.com/i0natan/nodebestpractices/blob/russian-translation/README.russian.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/105))
-* ![ES](/assets/flags/ES.png) [Spanish](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/95))
-* ![TR](/assets/flags/TR.png) Turkish ([Discussion](https://github.com/i0natan/nodebestpractices/issues/139))
-
-
-
-# Contributors
-
-## `Yoni Goldberg`
-
-Independent Node.js consultant who works with customers in USA, Europe, and Israel on building large-scale scalable Node applications. Many of the best practices above were first published in his blog post at [goldbergyoni.com](https://goldbergyoni.com). Reach Yoni at @goldbergyoni or me@goldbergyoni.com
-
-## `Ido Richter`
-
-👨💻 Software engineer, 🌐 web developer, 🤖 emojis enthusiast
-
-## `Refael Ackermann` [@refack](https://github.com/refack) <refack@gmail.com> (he/him)
-
-Node.js Core Collaborator, been noding since 0.4, and have noded in multiple production sites. Founded `node4good` home of [`lodash-contrib`](https://github.com/node4good/lodash-contrib), [`formage`](https://github.com/node4good/formage), and [`asynctrace`](https://github.com/node4good/asynctrace).
-`refack` on freenode, Twitter, GitHub, GMail, and many other platforms. DMs are open, happy to help
-
-## `Bruno Scheufler`
-
-💻 full-stack web developer and Node.js enthusiast
-
-## `Kyle Martin` [@js-kyle](https://github.com/js-kyle)
-Full Stack Developer based in New Zealand, interested in architecting and building Node.js applications to perform at global scale. Keen contributor to open source software, including Node.js Core.
-
-
-
-# Thank You Notes
-
-This repository is being kept up to date thanks to the help from the community. We appreciate any contribution, from a single word fix to a new best practice. Below is a list of everyone who contributed to this project. A 🌻 marks a successful pull request and a ⭐ marks an approved new best practice
-
-### Flowers
-
-🌻 [Kevin Rambaud](https://github.com/kevinrambaud),
-🌻 [Michael Fine](https://github.com/mfine15),
-🌻 [Shreya Dahal](https://github.com/squgeim),
-🌻 [ChangJoo Park](https://github.com/ChangJoo-Park),
-🌻 [Matheus Cruz Rocha](https://github.com/matheusrocha89),
-🌻 [Yog Mehta](https://github.com/BitYog),
-🌻 [Kudakwashe Paradzayi](https://github.com/kudapara),
-🌻 [t1st3](https://github.com/t1st3),
-🌻 [mulijordan1976](https://github.com/mulijordan1976),
-🌻 [Matan Kushner](https://github.com/matchai),
-🌻 [Fabio Hiroki](https://github.com/fabiothiroki),
-🌻 [James Sumners](https://github.com/jsumners),
-🌻 [Chandan Rai](https://github.com/crowchirp),
-🌻 [Dan Gamble](https://github.com/dan-gamble),
-🌻 [PJ Trainor](https://github.com/trainorpj),
-🌻 [Remek Ambroziak](https://github.com/reod),
-🌻 [Yoni Jah](https://github.com/yonjah),
-🌻 [Misha Khokhlov](https://github.com/hazolsky),
-🌻 [Evgeny Orekhov](https://github.com/EvgenyOrekhov),
-🌻 [Gediminas Petrikas](https://github.com/gediminasml),
-🌻 [Isaac Halvorson](https://github.com/hisaac),
-🌻 [Vedran Karačić](https://github.com/vkaracic),
-🌻 [lallenlowe](https://github.com/lallenlowe),
-🌻 [Nathan Wells](https://github.com/nwwells),
-🌻 [Paulo Vítor S Reis](https://github.com/paulovitin),
-🌻 [syzer](https://github.com/syzer),
-🌻 [David Sancho](https://github.com/davesnx),
-🌻 [Robert Manolea](https://github.com/pupix),
-🌻 [Xavier Ho](https://github.com/spaxe),
-🌻 [Aaron Arney](https://github.com/ocularrhythm),
-🌻 [Jan Charles Maghirang Adona](https://github.com/septa97),
-🌻 [Allen Fang](https://github.com/AllenFang),
-🌻 [Leonardo Villela](https://github.com/leonardovillela),
-🌻 [Michal Zalecki](https://github.com/MichalZalecki)
-🌻 [Chris Nicola](https://github.com/chrisnicola),
-🌻 [Alejandro Corredor](https://github.com/aecorredor),
-🌻 [Ye Min Htut](https://github.com/ymhtut),
-🌻 [cwar](https://github.com/cwar),
-🌻 [Yuwei](https://github.com/keyfoxth),
-🌻 [Utkarsh Bhatt](https://github.com/utkarshbhatt12),
-🌻 [Duarte Mendes](https://github.com/duartemendes),
-🌻 [Sagir Khan](https://github.com/sagirk),
-🌻 [Jason Kim](https://github.com/serv),
-🌻 [Mitja O.](https://github.com/Max101),
-🌻 [Sandro Miguel Marques](https://github.com/SandroMiguel),
-🌻 [Gabe Kuslansky](https://github.com/GabeKuslansky),
-🌻 [Ron Gross](https://github.com/ripper234),
-🌻 [Valeri Karpov](https://github.com/vkarpov15)
-
-### Stars
-
-⭐ [Kyle Martin](https://github.com/js-kyle)
-⭐ [Keith Holliday](https://github.com/TheHollidayInn)
-
-
+[✔]: assets/images/checkbox-small-blue.png
+
+# Node.js Best Practices
+
+
+
+
+
+
+
+
+
+
+
+[![nodepractices](/assets/images/twitter-s.png)](https://twitter.com/nodepractices/) **Follow us on Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+
+Read in a different language: [![CN](/assets/flags/CN.png)**CN**](/README.chinese.md) [(![ES](/assets/flags/ES.png)**ES**, ![FR](/assets/flags/FR.png)**FR**, ![HE](/assets/flags/HE.png)**HE**, ![KR](/assets/flags/KR.png)**KR**, ![RU](/assets/flags/RU.png)**RU** and ![TR](/assets/flags/TR.png)**TR** in progress!)](#translations)
+
+
+
+# Welcome! 3 Things You Ought To Know First:
+
+**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
+
+**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)
+
+**3. Most bullets have additional info -** nearby most best practice bullets you'll find **🔗Read More** link that will present you with code examples, quotes from selected blogs and more info
+
+
+
+## Table of Contents
+
+1. [Project structure Practices (5)](#1-project-structure-practices)
+2. [Error Handling Practices (11) ](#2-error-handling-practices)
+3. [Code Style Practices (12) ](#3-code-style-practices)
+4. [Testing And Overall Quality Practices (8) ](#4-testing-and-overall-quality-practices)
+5. [Going To Production Practices (17) ](#5-going-to-production-practices)
+6. :star: New: [Security Practices (23)](#6-security-best-practices)
+7. Performance Practices ([coming soon](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open))
+
+
+
+# `1. Project Structure Practices`
+
+## ![✔] 1.1 Structure your solution by components
+
+**TL;DR:** The worst large applications pitfall is maintaining a huge code base with hundreds of dependencies - such a monolith slows down developers as they try to incorporate new features. Instead, partition your code into components, each gets its own folder or a dedicated codebase, and ensure that each unit is kept small and simple. Visit 'Read More' below to see examples of correct project structure
+
+**Otherwise:** When developers who code new features struggle to realize the impact of their change and fear to break other dependant components - deployments become slower and more risky. It's also considered harder to scale-out when all the business units are not separated
+
+🔗 [**Read More: structure by components**](/sections/projectstructre/breakintcomponents.md)
+
+
+
+## ![✔] 1.2 Layer your components, keep Express within its boundaries
+
+**TL;DR:** Each component should contain 'layers' - a dedicated object for the web, logic and data access code. This not only draws a clean separation of concerns but also significantly eases mocking and testing the system. Though this is a very common pattern, API developers tend to mix layers by passing the web layer objects (Express req, res) to business logic and data layers - this makes your application dependant on and accessible by Express only
+
+**Otherwise:** App that mixes web objects with other layers can not be accessed by testing code, CRON jobs and other non-Express callers
+
+🔗 [**Read More: layer your app**](/sections/projectstructre/createlayers.md)
+
+
+
+## ![✔] 1.3 Wrap common utilities as npm packages
+
+**TL;DR:** In a large app that constitutes a large code base, cross-cutting-concern utilities like logger, encryption and alike, should be wrapped by your own code and exposed as private npm packages. This allows sharing them among multiple code bases and projects
+
+**Otherwise:** You'll have to invent your own deployment and dependency wheel
+
+🔗 [**Read More: Structure by feature**](/sections/projectstructre/wraputilities.md)
+
+
+
+## ![✔] 1.4 Separate Express 'app' and 'server'
+
+**TL;DR:** Avoid the nasty habit of defining the entire [Express](https://expressjs.com/) app in a single huge file - separate your 'Express' definition to at least two files: the API declaration (app.js) and the networking concerns (WWW). For even better structure, locate your API declaration within components
+
+**Otherwise:** Your API will be accessible for testing via HTTP calls only (slower and much harder to generate coverage reports). It probably won't be a big pleasure to maintain hundreds of lines of code in a single file
+
+🔗 [**Read More: separate Express 'app' and 'server'**](/sections/projectstructre/separateexpress.md)
+
+
+
+## ![✔] 1.5 Use environment aware, secure and hierarchical config
+
+**TL;DR:** A perfect and flawless configuration setup should ensure (a) keys can be read from file AND from environment variable (b) secrets are kept outside committed code (c) config is hierarchical for easier findability. There are a few packages that can help tick most of those boxes like [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) and [config](https://www.npmjs.com/package/config)
+
+**Otherwise:** Failing to satisfy any of the config requirements will simply bog down the development or devops team. Probably both
+
+🔗 [**Read More: configuration best practices**](/sections/projectstructre/configguide.md)
+
+
+
+⬆ Return to top
+
+# `2. Error Handling Practices`
+
+## ![✔] 2.1 Use Async-Await or promises for async error handling
+
+**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
+
+**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
+
+🔗 [**Read More: avoiding callbacks**](/sections/errorhandling/asyncerrorhandling.md)
+
+
+
+## ![✔] 2.2 Use only the built-in Error object
+
+**TL;DR:** Many throws errors as a string or as some custom type – this complicates the error handling logic and the interoperability between modules. Whether you reject a promise, throw an exception or an emit error – using only the built-in Error object will increase uniformity and prevent loss of information
+
+**Otherwise:** When invoking some component, being uncertain which type of errors come in return – it makes proper error handling much harder. Even worse, using custom types to describe errors might lead to loss of critical error information like the stack trace!
+
+🔗 [**Read More: using the built-in error object**](/sections/errorhandling/useonlythebuiltinerror.md)
+
+
+
+## ![✔] 2.3 Distinguish operational vs programmer errors
+
+**TL;DR:** Operational errors (e.g. API received an invalid input) refer to known cases where the error impact is fully understood and can be handled thoughtfully. On the other hand, programmer error (e.g. trying to read undefined variable) refers to unknown code failures that dictate to gracefully restart the application
+
+**Otherwise:** You may always restart the application when an error appears, but why let ~5000 online users down because of a minor, predicted, operational error? the opposite is also not ideal – keeping the application up when an unknown issue (programmer error) occurred might lead to an unpredicted behavior. Differentiating the two allows acting tactfully and applying a balanced approach based on the given context
+
+🔗 [**Read More: operational vs programmer error**](/sections/errorhandling/operationalvsprogrammererror.md)
+
+
+
+## ![✔] 2.4 Handle errors centrally, not within an Express middleware
+
+**TL;DR:** Error handling logic such as mail to admin and logging should be encapsulated in a dedicated and centralized object that all endpoints (e.g. Express middleware, cron jobs, unit-testing) call when an error comes in
+
+**Otherwise:** Not handling errors within a single place will lead to code duplication and probably to improperly handled errors
+
+🔗 [**Read More: handling errors in a centralized place**](/sections/errorhandling/centralizedhandling.md)
+
+
+
+## ![✔] 2.5 Document API errors using Swagger
+
+**TL;DR:** Let your API callers know which errors might come in return so they can handle these thoughtfully without crashing. This is usually done with REST API documentation frameworks like Swagger
+
+**Otherwise:** An API client might decide to crash and restart only because he received back an error he couldn’t understand. Note: the caller of your API might be you (very typical in a microservice environment)
+
+🔗 [**Read More: documenting errors in Swagger**](/sections/errorhandling/documentingusingswagger.md)
+
+
+
+## ![✔] 2.6 Shut the process gracefully when a stranger comes to town
+
+**TL;DR:** When an unknown error occurs (a developer error, see best practice number #3)- there is uncertainty about the application healthiness. A common practice suggests restarting the process carefully using a ‘restarter’ tool like Forever and PM2
+
+**Otherwise:** When an unfamiliar exception is caught, some object might be in a faulty state (e.g an event emitter which is used globally and not firing events anymore due to some internal failure) and all future requests might fail or behave crazily
+
+🔗 [**Read More: shutting the process**](/sections/errorhandling/shuttingtheprocess.md)
+
+
+
+## ![✔] 2.7 Use a mature logger to increase error visibility
+
+**TL;DR:** A set of mature logging tools like Winston, Bunyan or Log4J, will speed-up error discovery and understanding. So forget about console.log
+
+**Otherwise:** Skimming through console.logs or manually through messy text file without querying tools or a decent log viewer might keep you busy at work until late
+
+🔗 [**Read More: using a mature logger**](/sections/errorhandling/usematurelogger.md)
+
+
+
+## ![✔] 2.8 Test error flows using your favorite test framework
+
+**TL;DR:** Whether professional automated QA or plain manual developer testing – Ensure that your code not only satisfies positive scenario but also handle and return the right errors. Testing frameworks like Mocha & Chai can handle this easily (see code examples within the "Gist popup")
+
+**Otherwise:** Without testing, whether automatically or manually, you can’t rely on our code to return the right errors. Without meaningful errors – there’s no error handling
+
+🔗 [**Read More: testing error flows**](/sections/errorhandling/testingerrorflows.md)
+
+
+
+## ![✔] 2.9 Discover errors and downtime using APM products
+
+**TL;DR:** Monitoring and performance products (a.k.a APM) proactively gauge your codebase or API so they can automagically highlight errors, crashes and slow parts that you were missing
+
+**Otherwise:** You might spend great effort on measuring API performance and downtimes, probably you’ll never be aware which are your slowest code parts under real-world scenario and how these affect the UX
+
+🔗 [**Read More: using APM products**](/sections/errorhandling/apmproducts.md)
+
+
+
+## ![✔] 2.10 Catch unhandled promise rejections
+
+**TL;DR:** Any exception thrown within a promise will get swallowed and discarded unless a developer didn’t forget to explicitly handle. Even if your code is subscribed to process.uncaughtException! Overcome this by registering to the event process.unhandledRejection
+
+**Otherwise:** Your errors will get swallowed and leave no trace. Nothing to worry about
+
+🔗 [**Read More: catching unhandled promise rejection**](/sections/errorhandling/catchunhandledpromiserejection.md)
+
+
+
+## ![✔] 2.11 Fail fast, validate arguments using a dedicated library
+
+**TL;DR:** This should be part of your Express best practices – Assert API input to avoid nasty bugs that are much harder to track later. The validation code is usually tedious unless you are using a very cool helper library like Joi
+
+**Otherwise:** Consider this – your function expects a numeric argument “Discount” which the caller forgets to pass, later on, your code checks if Discount!=0 (amount of allowed discount is greater than zero), then it will allow the user to enjoy a discount. OMG, what a nasty bug. Can you see it?
+
+🔗 [**Read More: failing fast**](/sections/errorhandling/failfast.md)
+
+
+
+⬆ Return to top
+
+# `3. Code Style Practices`
+
+## ![✔] 3.1 Use ESLint
+
+**TL;DR:** [ESLint](https://eslint.org) is the de-facto standard for checking possible code errors and fixing code style, not only to identify nitty-gritty spacing issues but also to detect serious code anti-patterns like developers throwing errors without classification. Though ESLint can automatically fix code styles, other tools like [prettier](https://www.npmjs.com/package/prettier) and [beautify](https://www.npmjs.com/package/js-beautify) are more powerful in formatting the fix and work in conjunction with ESLint
+
+**Otherwise:** Developers will focus on tedious spacing and line-width concerns and time might be wasted overthinking about the project's code style
+
+
+
+## ![✔] 3.2 Node.js Specific Plugins
+
+**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)
+
+**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
+
+
+
+## ![✔] 3.3 Start a Codeblock's Curly Braces on the Same Line
+
+**TL;DR:** The opening curly braces of a code block should be in the same line of the opening statement
+
+### Code Example
+
+```javascript
+// Do
+function someFunction() {
+ // code block
+}
+
+// Avoid
+function someFunction()
+{
+ // code block
+}
+```
+
+**Otherwise:** Deferring from this best practice might lead to unexpected results, as seen in the StackOverflow thread below:
+
+🔗 [**Read more:** "Why does a results vary based on curly brace placement?" (Stackoverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
+
+
+
+## ![✔] 3.4 Don't Forget the Semicolon
+
+**TL;DR:** While not unanimously agreed upon, it is still recommended to put a semicolon at the end of each statement. This will make your code more readable and explicit to other developers who read it
+
+**Otherwise:** As seen in the previous section, JavaScript's interpreter automatically adds a semicolon at the end of a statement if there isn't one which might lead to some undesired results
+
+
+
+## ![✔] 3.5 Name Your Functions
+
+**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
+
+**Otherwise:** Debugging production issues using a core dump (memory snapshot) might become challenging as you notice significant memory consumption from anonymous functions
+
+
+
+## ![✔] 3.6 Naming conventions for variables, constants, functions and classes
+
+**TL;DR:** Use **_lowerCamelCase_** when naming constants, variables and functions and **_UpperCamelCase_** (capital first letter as well) when naming classes. This will help you to easily distinguish between plain variables/functions, and classes that require instantiation. Use descriptive names, but try to keep them short
+
+**Otherwise:** Javascript is the only language in the world which allows invoking a constructor ("Class") directly without instantiating it first. Consequently, Classes and function-constructors are differentiated by starting with UpperCamelCase
+
+### Code Example
+
+```javascript
+// for class name we use UpperCamelCase
+class SomeClassExample {}
+
+// for const names we use the const keyword and lowerCamelCase
+const config = {
+ key: 'value'
+};
+
+// for variables and functions names we use lowerCamelCase
+let someVariableExample = 'value';
+function doSomething() {}
+```
+
+
+
+## ![✔] 3.7 Prefer const over let. Ditch the var
+
+**TL;DR:** Using `const` means that once a variable is assigned, it cannot be reassigned. Preferring const will help you to not be tempted to use the same variable for different uses, and make your code clearer. If a variable needs to be reassigned, in a for loop, for example, use `let` to declare it. Another important aspect of `let` is that a variable declared using it is only available in the block scope in which it was defined. `var` is function scoped, not block scoped, and [shouldn't be used in ES6](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70) now that you have const and let at your disposal
+
+**Otherwise:** Debugging becomes way more cumbersome when following a variable that frequently changes
+
+🔗 [**Read more: JavaScript ES6+: var, let, or const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 Requires come first, and not inside functions
+
+**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
+
+**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
+
+
+
+## ![✔] 3.9 Do Require on the folders, not directly on the files
+
+**TL;DR:** When developing a module/library in a folder, place an index.js file that exposes the module's
+internals so every consumer will pass through it. This serves as an 'interface' to your module and eases
+future changes without breaking the contract
+
+**Otherwise:** Changing the internal structure of files or the signature may break the interface with
+clients
+
+### Code example
+
+```javascript
+// Do
+module.exports.SMSProvider = require('./SMSProvider');
+module.exports.SMSNumberResolver = require('./SMSNumberResolver');
+
+// Avoid
+module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
+module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
+```
+
+
+
+## ![✔] 3.10 Use the `===` operator
+
+**TL;DR:** Prefer the strict equality operator `===` over the weaker abstract equality operator `==`. `==` will compare two variables after converting them to a common type. There is no type conversion in `===`, and both variables must be of the same type to be equal
+
+**Otherwise:** Unequal variables might return true when compared with the `==` operator
+
+### Code example
+
+```javascript
+'' == '0' // false
+0 == '' // true
+0 == '0' // true
+
+false == 'false' // false
+false == '0' // true
+
+false == undefined // false
+false == null // false
+null == undefined // true
+
+' \t\r\n ' == 0 // true
+```
+
+All statements above will return false if used with `===`
+
+
+
+## ![✔] 3.11 Use Async Await, avoid callbacks
+
+**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
+
+**Otherwise:** Handling async errors in callback style is probably the fastest way to hell - this style forces to check errors all over, deal with awkward code nesting and make it difficult to reason about the code flow
+
+🔗[**Read more:** Guide to async await 1.0](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 Use Fat (=>) Arrow Functions
+
+**TL;DR:** Though it's recommended to use async-await and avoid function parameters when dealing with older API that accept promises or callbacks - arrow functions make the code structure more compact and keep the lexical context of the root function (i.e. 'this')
+
+**Otherwise:** Longer code (in ES5 functions) is more prone to bugs and cumbersome to read
+
+🔗 [**Read mode: It’s Time to Embrace Arrow Functions**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
+
+
+
+⬆ Return to top
+
+# `4. Testing And Overall Quality Practices`
+
+## ![✔] 4.1 At the very least, write API (component) testing
+
+**TL;DR:** Most projects just don't have any automated testing due to short timetables or often the 'testing project' run out of control and being abandoned. For that reason, prioritize and start with API testing which is the easiest to write and provide more coverage than unit testing (you may even craft API tests without code using tools like [Postman](https://www.getpostman.com/). Afterward, should you have more resources and time, continue with advanced test types like unit testing, DB testing, performance testing, etc
+
+**Otherwise:** You may spend long days on writing unit tests to find out that you got only 20% system coverage
+
+
+
+## ![✔] 4.2 Detect code issues with a linter
+
+**TL;DR:** Use a code linter to check basic quality and detect anti-patterns early. Run it before any test and add it as a pre-commit git-hook to minimize the time needed to review and correct any issue. Also check [Section 3](https://github.com/i0natan/nodebestpractices#3-code-style-practices) on Code Style Practices
+
+**Otherwise:** You may let pass some anti-pattern and possible vulnerable code to your production environment.
+
+
+
+## ![✔] 4.3 Carefully choose your CI platform (Jenkins vs CircleCI vs Travis vs Rest of the world)
+
+**TL;DR:** Your continuous integration platform (CICD) will host all the quality tools (e.g test, lint) so it should come with a vibrant ecosystem of plugins. [Jenkins](https://jenkins.io/) used to be the default for many projects as it has the biggest community along with a very powerful platform at the price of complex setup that demands a steep learning curve. Nowadays, it became much easier to set up a CI solution using SaaS tools like [CircleCI](https://circleci.com) and others. These tools allow crafting a flexible CI pipeline without the burden of managing the whole infrastructure. Eventually, it's a trade-off between robustness and speed - choose your side carefully
+
+**Otherwise:** Choosing some niche vendor might get you blocked once you need some advanced customization. On the other hand, going with Jenkins might burn precious time on infrastructure setup
+
+🔗 [**Read More: Choosing CI platform**](/sections/testingandquality/citools.md)
+
+
+
+## ![✔] 4.4 Constantly inspect for vulnerable dependencies
+
+**TL;DR:** Even the most reputable dependencies such as Express have known vulnerabilities. This can get easily tamed using community and commercial tools such as 🔗 [nsp](https://github.com/nodesecurity/nsp) that can be invoked from your CI on every build
+
+**Otherwise:** Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
+
+
+
+## ![✔] 4.5 Tag your tests
+
+**TL;DR:** Different tests must run on different scenarios: quick smoke, IO-less, tests should run when a developer saves or commits a file, full end-to-end tests usually run when a new pull request is submitted, etc. This can be achieved by tagging tests with keywords like #cold #api #sanity so you can grep with your testing harness and invoke the desired subset. For example, this is how you would invoke only the sanity test group with [Mocha](https://mochajs.org/): mocha --grep 'sanity'
+
+**Otherwise:** Running all the tests, including tests that perform dozens of DB queries, any time a developer makes a small change can be extremely slow and keeps developers away from running tests
+
+
+
+## ![✔] 4.6 Check your test coverage, it helps to identify wrong test patterns
+
+**TL;DR:** Code coverage tools like [Istanbul/NYC ](https://github.com/gotwarlost/istanbul)are great for 3 reasons: it comes for free (no effort is required to benefit this reports), it helps to identify a decrease in testing coverage, and last but not least it highlights testing mismatches: by looking at colored code coverage reports you may notice, for example, code areas that are never tested like catch clauses (meaning that tests only invoke the happy paths and not how the app behaves on errors). Set it to fail builds if the coverage falls under a certain threshold
+
+**Otherwise:** There won't be any automated metric telling you when a large portion of your code is not covered by testing
+
+
+
+## ![✔] 4.7 Inspect for outdated packages
+
+**TL;DR:** Use your preferred tool (e.g. 'npm outdated' or [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) to detect installed packages which are outdated, inject this check into your CI pipeline and even make a build fail in a severe scenario. For example, a severe scenario might be when an installed package is 5 patch commits behind (e.g. local version is 1.3.1 and repository version is 1.3.8) or it is tagged as deprecated by its author - kill the build and prevent deploying this version
+
+**Otherwise:** Your production will run packages that have been explicitly tagged by their author as risky
+
+
+
+## ![✔] 4.8 Use docker-compose for e2e testing
+
+**TL;DR:** End to end (e2e) testing which includes live data used to be the weakest link of the CI process as it depends on multiple heavy services like DB. Docker-compose turns this problem into a breeze by crafting production-like environment using a simple text file and easy commands. It allows crafting all the dependent services, DB and isolated network for e2e testing. Last but not least, it can keep a stateless environment that is invoked before each test suite and dies right after
+
+**Otherwise:** Without docker-compose teams must maintain a testing DB for each testing environment including developers machines, keep all those DBs in sync so test results won't vary across environments
+
+
+
+## ![✔] 4.9 Refactor regularly using static analysis tools
+
+**TL;DR:** Using static analysis tools helps by giving objective ways to improve code quality and keep your code maintainable. You can add static analysis tools to your CI build to fail when it finds code smells. Its main selling points over plain linting are the ability to inspect quality in the context of multiple files (e.g. detect duplications), perform advanced analysis (e.g. code complexity) and follow the history and progress of code issues. Two examples of tools you can use are [Sonarqube](https://www.sonarqube.org/) (2,600+ [stars](https://github.com/SonarSource/sonarqube)) and [Code Climate](https://codeclimate.com/) (1,500+ [stars](https://github.com/codeclimate/codeclimate)).
+
+**Otherwise:** With poor code quality, bugs and performance will always be an issue that no shiny new library or state of the art features can fix.
+
+🔗 [**Read More: Refactoring!**](/sections/testingandquality/refactoring.md)
+
+
+
+
+⬆ Return to top
+
+# `5. Going To Production Practices`
+
+## ![✔] 5.1. Monitoring!
+
+**TL;DR:** Monitoring is a game of finding out issues before customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my suggestions inside), then go over additional fancy features and choose the solution that ticks all boxes. Click ‘The Gist’ below for an overview of the solutions
+
+**Otherwise:** Failure === disappointed customers. Simple
+
+🔗 [**Read More: Monitoring!**](/sections/production/monitoring.md)
+
+
+
+## ![✔] 5.2. Increase transparency using smart logging
+
+**TL;DR:** Logs can be a dumb warehouse of debug statements or the enabler of a beautiful dashboard that tells the story of your app. Plan your logging platform from day 1: how logs are collected, stored and analyzed to ensure that the desired information (e.g. error rate, following an entire transaction through services and servers, etc) can really be extracted
+
+**Otherwise:** You end-up with a black box that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**Read More: Increase transparency using smart logging**](/sections/production/smartlogging.md)
+
+
+
+## ![✔] 5.3. Delegate anything possible (e.g. gzip, SSL) to a reverse proxy
+
+**TL;DR:** Node is awfully bad at doing CPU intensive tasks like gzipping, SSL termination, etc. You should use ‘real’ middleware services like nginx, HAproxy or cloud vendor services instead
+
+**Otherwise:** Your poor single thread will stay busy doing infrastructural tasks instead of dealing with your application core and performance will degrade accordingly
+
+🔗 [**Read More: Delegate anything possible (e.g. gzip, SSL) to a reverse proxy**](/sections/production/delegatetoproxy.md)
+
+
+
+## ![✔] 5.4. Lock dependencies
+
+**TL;DR:** Your code must be identical across all environments, but amazingly npm lets dependencies drift across environments by default – when you install packages at various environments it tries to fetch packages’ latest patch version. Overcome this by using npm config files, .npmrc, that tell each environment to save the exact (not the latest) version of each package. Alternatively, for finer grain control use npm” shrinkwrap”. \*Update: as of NPM5, dependencies are locked by default. The new package manager in town, Yarn, also got us covered by default
+
+**Otherwise:** QA will thoroughly test the code and approve a version that will behave differently at production. Even worse, different servers at the same production cluster might run different code
+
+🔗 [**Read More: Lock dependencies**](/sections/production/lockdependencies.md)
+
+
+
+## ![✔] 5.5. Guard process uptime using the right tool
+
+**TL;DR:** The process must go on and get restarted upon failures. For simple scenarios, ‘restarter’ tools like PM2 might be enough but in today ‘dockerized’ world – a cluster management tools should be considered as well
+
+**Otherwise:** Running dozens of instances without a clear strategy and too many tools together (cluster management, docker, PM2) might lead to a DevOps chaos
+
+🔗 [**Read More: Guard process uptime using the right tool**](/sections/production/guardprocess.md)
+
+
+
+## ![✔] 5.6. Utilize all CPU cores
+
+**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)
+
+**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!)
+
+🔗 [**Read More: Utilize all CPU cores**](/sections/production/utilizecpu.md)
+
+
+
+## ![✔] 5.7. Create a ‘maintenance endpoint’
+
+**TL;DR:** Expose a set of system-related information, like memory usage and REPL, etc in a secured API. Although it’s highly recommended to rely on standard and battle-tests tools, some valuable information and operations are easier done using code
+
+**Otherwise:** You’ll find that you’re performing many “diagnostic deploys” – shipping code to production only to extract some information for diagnostic purposes
+
+🔗 [**Read More: Create a ‘maintenance endpoint’**](/sections/production/createmaintenanceendpoint.md)
+
+
+
+## ![✔] 5.8. Discover errors and downtime using APM products
+
+**TL;DR:** Monitoring and performance products (a.k.a APM) proactively gauge codebase and API so they can auto-magically go beyond traditional monitoring and measure the overall user-experience across services and tiers. For example, some APM products can highlight a transaction that loads too slow on the end-users side while suggesting the root cause
+
+**Otherwise:** You might spend great effort on measuring API performance and downtimes, probably you’ll never be aware which is your slowest code parts under real-world scenario and how these affects the UX
+
+🔗 [**Read More: Discover errors and downtime using APM products**](/sections/production/apmproducts.md)
+
+
+
+## ![✔] 5.9. Make your code production-ready
+
+**TL;DR:** Code with the end in mind, plan for production from day 1. This sounds a bit vague so I’ve compiled a few development tips that are closely related to production maintenance (click Gist below)
+
+**Otherwise:** A world champion IT/DevOps guy won’t save a system that is badly written
+
+🔗 [**Read More: Make your code production-ready**](/sections/production/productoncode.md)
+
+
+
+## ![✔] 5.10. Measure and guard the memory usage
+
+**TL;DR:** Node.js has controversial relationships with memory: the v8 engine has soft limits on memory usage (1.4GB) and there are known paths to leaks memory in Node’s code – thus watching Node’s process memory is a must. In small apps, you may gauge memory periodically using shell commands but in medium-large app consider baking your memory watch into a robust monitoring system
+
+**Otherwise:** Your process memory might leak a hundred megabytes a day like how it happened at [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)
+
+🔗 [**Read More: Measure and guard the memory usage**](/sections/production/measurememory.md)
+
+
+
+## ![✔] 5.11. Get your frontend assets out of Node
+
+**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
+
+**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
+
+🔗 [**Read More: Get your frontend assets out of Node**](/sections/production/frontendout.md)
+
+
+
+## ![✔] 5.12. Be stateless, kill your Servers almost every day
+
+**TL;DR:** Store any type of data (e.g. users session, cache, uploaded files) within external data stores. Consider ‘killing’ your servers periodically or use ‘serverless’ platform (e.g. AWS Lambda) that explicitly enforces a stateless behavior
+
+**Otherwise:** Failure at a given server will result in application downtime instead of just killing a faulty machine. Moreover, scaling-out elasticity will get more challenging due to the reliance on a specific server
+
+🔗 [**Read More: Be stateless, kill your Servers almost every day**](/sections/production/bestateless.md)
+
+
+
+## ![✔] 5.13. Use tools that automatically detect vulnerabilities
+
+**TL;DR:** Even the most reputable dependencies such as Express have known vulnerabilities (from time to time) that can put a system at risk. This can get easily tamed using community and commercial tools that constantly check for vulnerabilities and warn (locally or at GitHub), some can even patch them immediately
+
+**Otherwise:** Keeping your code clean from vulnerabilities without dedicated tools will require to constantly follow online publications about new threats. Quite tedious
+
+🔗 [**Read More: Use tools that automatically detect vulnerabilities**](/sections/production/detectvulnerabilities.md)
+
+
+
+## ![✔] 5.14. Assign ‘TransactionId’ to each log statement
+
+**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 to its async nature, see code examples inside
+
+**Otherwise:** Looking at a production error log without the context – what happened before – makes it much harder and slower to reason about the issue
+
+🔗 [**Read More: Assign ‘TransactionId’ to each log statement**](/sections/production/assigntransactionid.md)
+
+
+
+## ![✔] 5.15. Set NODE_ENV=production
+
+**TL;DR:** Set the environment variable NODE_ENV to ‘production’ or ‘development’ to flag whether production optimizations should get activated – many npm packages determining the current environment and optimize their code for production
+
+**Otherwise:** Omitting this simple property might greatly degrade performance. For example, when using Express for server-side rendering omitting `NODE_ENV` makes the slower by a factor of three!
+
+🔗 [**Read More: Set NODE_ENV=production**](/sections/production/setnodeenv.md)
+
+
+
+## ![✔] 5.16. Design automated, atomic and zero-downtime deployments
+
+**TL;DR:** Researches show that teams who perform many deployments – lowers the probability of severe production issues. Fast and automated deployments that don’t require risky manual steps and service downtime significantly improves the deployment process. You should probably achieve that using Docker combined with CI tools as they became the industry standard for streamlined deployment
+
+**Otherwise:** Long deployments -> production down time & human-related error -> team unconfident and in making deployment -> less deployments and features
+
+
+
+## ![✔] 5.17. Use an LTS release of Node.js
+
+**TL;DR:** Ensure you are using an LTS version of Node.js to receive critical bug fixes, security updates and performance improvements
+
+**Otherwise:** Newly discovered bugs or vulnerabilities could be used to exploit an application running in production, and your application may become unsupported by various modules and harder to maintain
+
+🔗 [**Read More: Use an LTS release of Node.js**](/sections/production/LTSrelease.md)
+
+
+
+⬆ Return to top
+
+# `6. Security Best Practices`
+
+
+
+
+
+## ![✔] 6.1. Embrace linter security rules
+
+
+
+**TL;DR:** Make use of security-related linter plugins such as [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security) to catch security vulnerabilities and issues as early as possible , at best while they're being coded. This can help catching security weaknesses like using eval, invoking a child process or importing a module with a string literal (e.g. user input). Click 'Read more' below to see code examples that will get caught by a security linter
+
+**Otherwise:** What could have been a straightforward security weakness during development becomes a major issue in production. Also, the project may not follow consistent code security practices, leading to vulnerabilities being introduced, or sensitive secrets committed into remote repositories
+
+
+🔗 [**Read More: Lint rules**](sections/security/lintrules.md)
+
+
+
+## ![✔] 6.2. Limit concurrent requests using a middleware
+
+
+
+**TL;DR:** DOS attacks are very popular and relatively easy to conduct. Implement rate limiting using an external service such as cloud load balancers, cloud firewalls, nginx, or (for smaller and less critical apps) a rate limiting middleware (e.g. [express-rate-limit](https://www.npmjs.com/package/express-rate-limit))
+
+**Otherwise:** An application could be subject to an attack resulting in a denial of service where real users receive a degraded or unavailable service.
+
+🔗 [**Read More: Implement rate limiting**](sections/security/limitrequests.md)
+
+
+
+## ![✔] 6.3 Extract secrets from config files or use packages to encrypt them
+
+
+
+
+**TL;DR:** Never store plain-text secrets in configuration files or source code. Instead, make use of secret-management systems like Vault products, Kubernetes/Docker Secrets, or using environment variables. As a last result, secrets stored in source control must be encrypted and managed (rolling keys, expiring, auditing, etc). Make use of pre-commit/push hooks to prevent committing secrets accidentally
+
+**Otherwise:** Source control, even for private repositories, can mistakenly be made public, at which point all secrets are exposed. Access to source control for an external party will inadvertently provide access to related systems (databases, apis, services, etc).
+
+
+🔗 [**Read More: Secret management**](sections/security/secretmanagement.md)
+
+
+
+
+## ![✔] 6.4. Prevent query injection vulnerabilities with ORM/ODM libraries
+
+
+
+**TL;DR:** To prevent SQL/NoSQL injection and other malicious attacks, always make use of an ORM/ODM or a database library that escapes data or supports named or indexed parameterized queries, and takes care of validating user input for expected types. Never just use JavaScript template strings or string concatenation to inject values into queries as this opens your application to a wide spectrum of vulnerabilities. All the reputable Node.js data access libraries (e.g. [Sequelize](https://github.com/sequelize/sequelize), [Knex](https://github.com/tgriesser/knex), [mongoose](https://github.com/Automattic/mongoose)) have built-in protection agains injection attacks
+
+**Otherwise:** Unvalidated or unsanitized user input could lead to operator injection when working with MongoDB for NoSQL, and not using a proper sanitization system or ORM will easily allow SQL injection attacks, creating a giant vulnerability.
+
+🔗 [**Read More: Query injection prevention using ORM/ODM libraries**](/sections/security/ormodmusage.md)
+
+
+
+
+## ![✔] 6.5. Collection of generic security best practices
+
+**TL;DR:** These is a collection of security advice that are not related directly to Node.js - the Node implementation is not much different than any other language. Click read more to skim through.
+
+
+🔗 [**Read More: Common security best practices**](/sections/security/commonsecuritybestpractices.md)
+
+
+
+## ![✔] 6.6. Adjust the HTTP response headers for enhanced security
+
+
+
+**TL;DR:** Your application should be using secure headers to prevent attackers from using common attacks like cross-site scripting (XSS), clickjacking and other malicious attacks. These can be configured easily using modules like [helmet](https://www.npmjs.com/package/helmet).
+
+**Otherwise:** Attackers could perform direct attacks on your application's users, leading huge security vulnerabilities
+
+
+🔗 [**Read More: Using secure headers in your application**](/sections/security/secureheaders.md)
+
+
+
+## ![✔] 6.7. Constantly and automatically inspect for vulnerable dependencies
+
+
+
+**TL;DR:** With the npm ecosystem it is common to have many dependencies for a project. Dependencies should always be kept in check as new vulnerabilities are found. Use tools like [npm audit](https://docs.npmjs.com/cli/audit) or [snyk](https://snyk.io/) to track, monitor and patch vulnerable dependencies. Integrate these tools with your CI setup so you catch a vulnerable dependency before it makes it to production.
+
+**Otherwise:** An attacker could detect your web framework and attack all its known vulnerabilities.
+
+🔗 [**Read More: Dependency security**](/sections/security/dependencysecurity.md)
+
+
+
+
+## ![✔] 6.8. Avoid using the Node.js crypto library for handling passwords, use Bcrypt
+
+
+
+
+**TL;DR:** Passwords or secrets (API keys) should be stored using a secure hash + salt function like `bcrypt`, that should be a preferred choice over its JavaScript implementation due to performance and security reasons.
+
+**Otherwise:** Passwords or secrets that are persisted without using a secure function are vulnerable to brute forcing and dictionary attacks that will lead to their disclosure eventually.
+
+🔗 [**Read More: Use Bcrypt**](/sections/security/bcryptpasswords.md)
+
+
+
+## ![✔] 6.9. Escape HTML, JS and CSS output
+
+
+
+**TL;DR:** Untrusted data that is sent down to the browser might get executed instead of just being displayed, this is commonly being referred as a cross-site-scripting (XSS) attack. Mitigate this by using dedicated libraries that explicitly mark the data as pure content that should never get executed (i.e. encoding, escaping)
+
+**Otherwise:** An attacker might store a malicious JavaScript code in your DB which will then be sent as-is to the poor clients
+
+🔗 [**Read More: Escape output**](/sections/security/escape-output.md)
+
+
+
+## ![✔] 6.10. Validate incoming JSON schemas
+
+
+
+**TL;DR:** Validate the incoming requests' body payload and ensure it qualifies the expectations, fail fast if it doesn't. To avoid tedious validation coding within each route you may use lightweight JSON-based validation schemas such as [jsonschema](https://www.npmjs.com/package/jsonschema) or [joi](https://www.npmjs.com/package/joi)
+
+**Otherwise:** Your generosity and permissive approach greatly increases the attack surface and encourages the attacker to try out many inputs until they find some combination to crash the application
+
+🔗 [**Read More: Validate incoming JSON schemas**](/sections/security/validation.md)
+
+
+
+
+## ![✔] 6.11. Support blacklisting JWTs
+
+
+
+**TL;DR:** When using JSON Web Tokens (for example, with [Passport.js](https://github.com/jaredhanson/passport)), by default there's no mechanism to revoke access from issued tokens. Once you discover some malicious user activity, there's no way to stop them from accessing the system as long as they hold a valid token. Mitigate this by implementing a blacklist of untrusted tokens that are validated on each request.
+
+**Otherwise:** Expired, or misplaced tokens could be used maliciously by a third party to access an application and impersonate the owner of the token.
+
+
+🔗 [**Read More: Blacklist JSON Web Tokens**](/sections/security/expirejwt.md)
+
+
+
+
+## ![✔] 6.12. Limit the allowed login requests of each user
+
+
+
+**TL;DR:** A brute force protection middleware such as [express-brute](https://www.npmjs.com/package/express-brute) should be used inside an express application to prevent brute force/dictionary attacks on sensitive routes such as /admin or /login based on request properties such as the user name, or other identifiers such as body parameters
+
+**Otherwise:** An attacker can issue unlimited automated password attempts to gain access to privileged accounts on an application
+
+🔗 [**Read More: Login rate limiting**](/sections/security/login-rate-limit.md)
+
+
+
+
+## ![✔] 6.13. Run Node.js as non-root user
+
+
+
+**TL;DR:** There is a common scenario where Node.js runs as a root user with unlimited permissions. For example, this is the default behaviour in Docker containers. It's recommended to create a non-root user and either bake it into the Docker image (examples given below) or run the process on this users' behalf by invoking the container with the flag "-u username"
+
+**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)
+
+
+🔗 [**Read More: Run Node.js as non-root user**](/sections/security/non-root-user.md)
+
+
+
+
+## ![✔] 6.14. Limit payload size using a reverse-proxy or a middleware
+
+
+
+**TL;DR:** The bigger the body payload is, the harder your single thread works in processing it. This is an opportunity for attackers to bring servers to their knees without tremendous amount of requests (DOS/DDOS attacks). Mitigate this limiting the body size of incoming requests on the edge (e.g. firewall, ELB) or by configuring [express body parser](https://github.com/expressjs/body-parser) to accept only small-size payloads
+
+**Otherwise:** Your application will have to deal with large requests, unable to process the other important work it has to accomplish, leading to performance implications and vulnerability towards DOS attacks
+
+
+🔗 [**Read More: Limit payload size**](/sections/security/requestpayloadsizelimit.md)
+
+
+
+
+## ![✔] 6.15. Avoid JavaScript eval statements
+
+
+
+
+**TL;DR:** `eval` is evil as it allows executing a custom JavaScript code during run time. This is not just a performance concern but also an important security concern due to malicious JavaScript code that may be sourced from user input. Another language feature that should be avoided is `new Function` constructor. `setTimeout` and `setInterval` should never be passed dynamic JavaScript code either.
+
+**Otherwise:** Malicious JavaScript code finds a way into a text passed into `eval` or other real-time evaluating JavaScript language functions, and will gain complete access to JavaScript permissions on the page. This vulnerability is often manifested as an XSS attack.
+
+
+🔗 [**Read More: Avoid JavaScript eval statements**](/sections/security/avoideval.md)
+
+
+
+
+## ![✔] 6.16. Prevent evil RegEx from overloading your single thread execution
+
+
+
+**TL;DR:** Regular Expressions, while being handy, pose a real threat to JavaScript applications at large, and the Node.js platform in particular. A user input for text to match might require an outstanding amount of CPU cycles to process. RegEx processing might be inefficient to an extent that a single request that validates 10 words can block the entire event loop for 6 seconds and set the CPU on 🔥. For that reason, prefer third-party validation packages like [validator.js](https://github.com/chriso/validator.js) instead of writing your own Regex patterns, or make use of [safe-regex](https://github.com/substack/safe-regex) to detect vulnerable regex patterns
+
+**Otherwise:** Poorly written regexes could be susceptible to Regular Expression DoS attacks that will block the event loop completely. For example, the popular `moment` package was found vulnerable with malicious RegEx usage in November of 2017
+
+🔗 [**Read More: Prevent malicious RegEx**](/sections/security/regex.md)
+
+
+
+## ![✔] 6.17. Avoid module loading using a variable
+
+
+
+
+**TL;DR:** Avoid requiring/importing another file with a path that was given as parameter due to the concern that it could have originated from user input. This rule can be extended for accessing files in general (i.e. `fs.readFile()`) or other sensitive resource access with dynamic variables originating from user input. [Eslint-plugin-security](https://www.npmjs.com/package/eslint-plugin-security) linter can catch such patterns and warn early enough
+
+**Otherwise:** Malicious user input could find its way to a parameter that is used to require tampered files, for example a previously uploaded file on the filesystem, or access already existing system files.
+
+
+🔗 [**Read More: Safe module loading**](/sections/security/safemoduleloading.md)
+
+
+
+## ![✔] 6.18. Run unsafe code in a sandbox
+
+
+
+**TL;DR:** When tasked to run external code that is given at run-time (e.g. plugin), use any sort of 'sandbox' execution environment that isolates and guards the main code against the plugin. This can be achieved using a dedicated process (e.g. cluster.fork()), serverless environment or dedicated npm packages that acting as a sandbox
+
+**Otherwise:** A plugin can attack through an endless variety of options like infinite loops, memory overloading, and access to sensitive process environment variables
+
+
+🔗 [**Read More: Run unsafe code in a sandbox**](/sections/security/sandbox.md)
+
+
+
+
+## ![✔] 6.19. Take extra care when working with child processes
+
+
+
+**TL;DR:** Avoid using child processes when possible and validate and sanitize input to mitigate shell injection attacks if you still have to. Prefer using `child_process.execFile` which by definition will only execute a single command with a set of attributes and will not allow shell parameter expansion.
+
+**Otherwise:** Naive use of child processes could result in remote command execution or shell injection attacks due to malicious user input passed to an unsanitized system command.
+
+🔗 [**Read More: Be cautious when working with child processes**](/sections/security/childprocesses.md)
+
+
+
+
+## ![✔] 6.20. Hide error details from clients
+
+
+
+**TL;DR:** An integrated express error handler hides the error details by default. However, great are the chances that you implement your own error handling logic with custom Error objects (considered by many as a best practice). If you do so, ensure not to return the entire Error object to the client, which might contain some sensitive application details
+
+**Otherwise:** Sensitive application details such as server file paths, third party modules in use, and other internal workflows of the application which could be exploited by an attacker, could be leaked from information found in a stack trace
+
+🔗 [**Read More: Hide error details from client**](/sections/security/hideerrors.md)
+
+
+
+## ![✔] 6.21. Configure 2FA for npm or Yarn
+
+
+
+**TL;DR:** Any step in the development chain should be protected with MFA (multi-factor authentication), npm/Yarn are a sweet opportunity for attackers who can get their hands on some developer's password. Using developer credentials, attackers can inject malicious code into libraries that are widely installed across projects and services. Maybe even across the web if published in public. Enabling 2-factor-authentication in npm leaves almost zero chances for attackers to alter your package code.
+
+**Otherwise:** [Have you heard about the eslint developer who's password was hijacked?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
+
+
+
+
+## ![✔] 6.22. Modify session middleware settings
+
+
+
+**TL;DR:** Each web framework and technology has its known weaknesses - telling an attacker which web framework we use is a great help for them. Using the default settings for session middlewares can expose your app to module- and framework-specific hijacking attacks in a similar way to the `X-Powered-By` header. Try hiding anything that identifies and reveals your tech stack (E.g. Node.js, express)
+
+**Otherwise:** Cookies could be sent over insecure connections, and an attacker might use session identification to identify the underlying framework of the web application, as well as module-specific vulnerabilities
+
+🔗 [**Read More: Cookie and session security**](/sections/security/sessions.md)
+
+
+
+## ![✔] 6.23. Avoid DOS attacks by explicitly setting when a process should crash
+
+
+
+**TL;DR:** The Node process will crash when errors are not handled. Many best practices even recommend to exit even though an error was caught and got handled. Express, for example, will crash on any asynchronous error - unless you wrap routes with a catch clause. This opens a very sweet attack spot for attackers who recognize what input makes the process crash and repeatedly send the same request. There's no instant remedy for this but a few techniques can mitigate the pain: Alert with critical severity anytime a process crashes due to an unhandled error, validate the input and avoid crashing the process due to invalid user input, wrap all routes with a catch and consider not to crash when an error originated within a request (as opposed to what happens globally)
+
+**Otherwise:** This is just an educated guess: given many Node.js applications, if we try passing an empty JSON body to all POST requests - a handful of applications will crash. At that point, we can just repeat sending the same request to take down the applications with ease
+
+
+
+
+⬆ Return to top
+
+# `API Practices`
+
+## Our contributors are working on this section. Would you like to join?
+
+
+# `Performance Practices`
+
+## Our contributors are working on this section. Would you like to join?
+
+
+
+# Milestones
+
+To maintain this guide and keep it up to date, we are constantly updating and improving the guidelines and best practices with the help of the community. You can follow our [milestones](https://github.com/i0natan/nodebestpractices/milestones) and join the working groups if you want to contribute to this project
+
+
+
+## Translations
+
+All translations are contributed by the community. We will be happy to get any help with either completed, ongoing or new translations!
+
+### Completed translations
+
+* ![CN](/assets/flags/CN.png) [Chinese](README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
+
+### Translations in progress
+
+* ![FR](/assets/flags/FR.png) [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/129))
+* ![HE](/assets/flags/HE.png) Hebrew ([Discussion](https://github.com/i0natan/nodebestpractices/issues/156))
+* ![KR](/assets/flags/KR.png) [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/94))
+* ![RU](/assets/flags/RU.png) [Russian](https://github.com/i0natan/nodebestpractices/blob/russian-translation/README.russian.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/105))
+* ![ES](/assets/flags/ES.png) [Spanish](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/95))
+* ![TR](/assets/flags/TR.png) Turkish ([Discussion](https://github.com/i0natan/nodebestpractices/issues/139))
+
+
+
+# Contributors
+
+## `Yoni Goldberg`
+
+Independent Node.js consultant who works with customers in USA, Europe, and Israel on building large-scale scalable Node applications. Many of the best practices above were first published in his blog post at [goldbergyoni.com](https://goldbergyoni.com). Reach Yoni at @goldbergyoni or me@goldbergyoni.com
+
+## `Ido Richter`
+
+👨💻 Software engineer, 🌐 web developer, 🤖 emojis enthusiast
+
+## `Refael Ackermann` [@refack](https://github.com/refack) <refack@gmail.com> (he/him)
+
+Node.js Core Collaborator, been noding since 0.4, and have noded in multiple production sites. Founded `node4good` home of [`lodash-contrib`](https://github.com/node4good/lodash-contrib), [`formage`](https://github.com/node4good/formage), and [`asynctrace`](https://github.com/node4good/asynctrace).
+`refack` on freenode, Twitter, GitHub, GMail, and many other platforms. DMs are open, happy to help
+
+## `Bruno Scheufler`
+
+💻 full-stack web developer and Node.js enthusiast
+
+## `Kyle Martin` [@js-kyle](https://github.com/js-kyle)
+Full Stack Developer based in New Zealand, interested in architecting and building Node.js applications to perform at global scale. Keen contributor to open source software, including Node.js Core.
+
+
+
+# Thank You Notes
+
+This repository is being kept up to date thanks to the help from the community. We appreciate any contribution, from a single word fix to a new best practice. Below is a list of everyone who contributed to this project. A 🌻 marks a successful pull request and a ⭐ marks an approved new best practice
+
+### Flowers
+
+🌻 [Kevin Rambaud](https://github.com/kevinrambaud),
+🌻 [Michael Fine](https://github.com/mfine15),
+🌻 [Shreya Dahal](https://github.com/squgeim),
+🌻 [ChangJoo Park](https://github.com/ChangJoo-Park),
+🌻 [Matheus Cruz Rocha](https://github.com/matheusrocha89),
+🌻 [Yog Mehta](https://github.com/BitYog),
+🌻 [Kudakwashe Paradzayi](https://github.com/kudapara),
+🌻 [t1st3](https://github.com/t1st3),
+🌻 [mulijordan1976](https://github.com/mulijordan1976),
+🌻 [Matan Kushner](https://github.com/matchai),
+🌻 [Fabio Hiroki](https://github.com/fabiothiroki),
+🌻 [James Sumners](https://github.com/jsumners),
+🌻 [Chandan Rai](https://github.com/crowchirp),
+🌻 [Dan Gamble](https://github.com/dan-gamble),
+🌻 [PJ Trainor](https://github.com/trainorpj),
+🌻 [Remek Ambroziak](https://github.com/reod),
+🌻 [Yoni Jah](https://github.com/yonjah),
+🌻 [Misha Khokhlov](https://github.com/hazolsky),
+🌻 [Evgeny Orekhov](https://github.com/EvgenyOrekhov),
+🌻 [Gediminas Petrikas](https://github.com/gediminasml),
+🌻 [Isaac Halvorson](https://github.com/hisaac),
+🌻 [Vedran Karačić](https://github.com/vkaracic),
+🌻 [lallenlowe](https://github.com/lallenlowe),
+🌻 [Nathan Wells](https://github.com/nwwells),
+🌻 [Paulo Vítor S Reis](https://github.com/paulovitin),
+🌻 [syzer](https://github.com/syzer),
+🌻 [David Sancho](https://github.com/davesnx),
+🌻 [Robert Manolea](https://github.com/pupix),
+🌻 [Xavier Ho](https://github.com/spaxe),
+🌻 [Aaron Arney](https://github.com/ocularrhythm),
+🌻 [Jan Charles Maghirang Adona](https://github.com/septa97),
+🌻 [Allen Fang](https://github.com/AllenFang),
+🌻 [Leonardo Villela](https://github.com/leonardovillela),
+🌻 [Michal Zalecki](https://github.com/MichalZalecki)
+🌻 [Chris Nicola](https://github.com/chrisnicola),
+🌻 [Alejandro Corredor](https://github.com/aecorredor),
+🌻 [Ye Min Htut](https://github.com/ymhtut),
+🌻 [cwar](https://github.com/cwar),
+🌻 [Yuwei](https://github.com/keyfoxth),
+🌻 [Utkarsh Bhatt](https://github.com/utkarshbhatt12),
+🌻 [Duarte Mendes](https://github.com/duartemendes),
+🌻 [Sagir Khan](https://github.com/sagirk),
+🌻 [Jason Kim](https://github.com/serv),
+🌻 [Mitja O.](https://github.com/Max101),
+🌻 [Sandro Miguel Marques](https://github.com/SandroMiguel),
+🌻 [Gabe Kuslansky](https://github.com/GabeKuslansky),
+🌻 [Ron Gross](https://github.com/ripper234),
+🌻 [Valeri Karpov](https://github.com/vkarpov15)
+
+### Stars
+
+⭐ [Kyle Martin](https://github.com/js-kyle)
+⭐ [Keith Holliday](https://github.com/TheHollidayInn)
+
+
diff --git a/assets/images/placeholdet.txt b/assets/images/placeholdet.txt
index 01a59b011..20e3f456a 100644
--- a/assets/images/placeholdet.txt
+++ b/assets/images/placeholdet.txt
@@ -1 +1 @@
-lorem ipsum
+lorem ipsum
diff --git a/sections/codestylepractices/eslint_prettier.chinese.md b/sections/codestylepractices/eslint_prettier.chinese.md
index c8f32b8f5..ffaa4dad3 100644
--- a/sections/codestylepractices/eslint_prettier.chinese.md
+++ b/sections/codestylepractices/eslint_prettier.chinese.md
@@ -1,26 +1,26 @@
-# 使用 ESLint 和 Prettier
-
-
-### 比较 ESLint 和 Prettier
-
-如果你使用ESLint格式化代码,它只是给你一个警告,比如这一行太宽(取决于你的`最大长度`设置)。Prettier会自动为你格式化。
-
-```javascript
-foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne(), noWayYouGottaBeKiddingMe());
-```
-
-```javascript
-foo(
- reallyLongArg(),
- omgSoManyParameters(),
- IShouldRefactorThis(),
- isThereSeriouslyAnotherOne(),
- noWayYouGottaBeKiddingMe()
-);
-```
-
-Source: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
-
-### Integrating ESLint and Prettier
-
-ESLint和Prettier在代码格式化功能上有重叠, 但它可以很容易通过其他的包来解决,比如 [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier), and [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)。 有关他们的差异的更多信息,您可以查看链接 [here](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint).
+# 使用 ESLint 和 Prettier
+
+
+### 比较 ESLint 和 Prettier
+
+如果你使用ESLint格式化代码,它只是给你一个警告,比如这一行太宽(取决于你的`最大长度`设置)。Prettier会自动为你格式化。
+
+```javascript
+foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne(), noWayYouGottaBeKiddingMe());
+```
+
+```javascript
+foo(
+ reallyLongArg(),
+ omgSoManyParameters(),
+ IShouldRefactorThis(),
+ isThereSeriouslyAnotherOne(),
+ noWayYouGottaBeKiddingMe()
+);
+```
+
+Source: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
+
+### Integrating ESLint and Prettier
+
+ESLint和Prettier在代码格式化功能上有重叠, 但它可以很容易通过其他的包来解决,比如 [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier), and [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)。 有关他们的差异的更多信息,您可以查看链接 [here](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint).
diff --git a/sections/codestylepractices/eslint_prettier.md b/sections/codestylepractices/eslint_prettier.md
index 698857dbc..8d52a1dbd 100644
--- a/sections/codestylepractices/eslint_prettier.md
+++ b/sections/codestylepractices/eslint_prettier.md
@@ -1,26 +1,26 @@
-# Using ESLint and Prettier
-
-
-### Comparing ESLint and Prettier
-
-If you format this code using ESLint, it will just give you a warning that it's too wide (depends on your `max-len` setting). Prettier will automatically format it for you.
-
-```javascript
-foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne(), noWayYouGottaBeKiddingMe());
-```
-
-```javascript
-foo(
- reallyLongArg(),
- omgSoManyParameters(),
- IShouldRefactorThis(),
- isThereSeriouslyAnotherOne(),
- noWayYouGottaBeKiddingMe()
-);
-```
-
-Source: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
-
-### Integrating ESLint and Prettier
-
-ESLint and Prettier overlap in the code formatting feature but can be easily combined by using other packages like [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier), and [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier). For more information about their differences, you can view the link [here](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint).
+# Using ESLint and Prettier
+
+
+### Comparing ESLint and Prettier
+
+If you format this code using ESLint, it will just give you a warning that it's too wide (depends on your `max-len` setting). Prettier will automatically format it for you.
+
+```javascript
+foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne(), noWayYouGottaBeKiddingMe());
+```
+
+```javascript
+foo(
+ reallyLongArg(),
+ omgSoManyParameters(),
+ IShouldRefactorThis(),
+ isThereSeriouslyAnotherOne(),
+ noWayYouGottaBeKiddingMe()
+);
+```
+
+Source: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
+
+### Integrating ESLint and Prettier
+
+ESLint and Prettier overlap in the code formatting feature but can be easily combined by using other packages like [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier), and [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier). For more information about their differences, you can view the link [here](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint).
diff --git a/sections/drafts/readme-general-toc-1.md b/sections/drafts/readme-general-toc-1.md
index 461803c27..463cedaed 100644
--- a/sections/drafts/readme-general-toc-1.md
+++ b/sections/drafts/readme-general-toc-1.md
@@ -1,86 +1,86 @@
-
-
-
-
-
-
-
-
-
-
-# Welcome to Node.js Best Practices
-
-Welcome to the biggest compilation of Node.js best practices. The content below was gathered from all top ranked books and posts and is updated constantly - when you read here rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
-
-## Table of Contents
-
-* [Project Setup Practices (18)](#project-setup-practices)
-* [Code Style Practices (11)](#code-style-practices)
-* [Error Handling Practices (14)](#error-handling-practices)
-* [Going To Production Practices (21)](#going-to-production-practices)
-* [Testing Practices (9)](#deployment-practices)
-* [Security Practices (8)](#security-practices)
-
-
-
-# `Project Setup Practices`
-
-## ✔ 1. Structure your solution by feature ('microservices')
-
-**TL&DR:** The worst large applications pitfal is a huge code base with hundreds of dependencies that slow down they developers as they try to incorporate new features. Partioning into small units ensures that each unit is kept simple and easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
-
-**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-## ✔ 2. Layer your app, keep Express within its boundaries
-
-**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
-
-**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-## ✔ 3. Configure ESLint with node-specific plugins
-
-**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
-
-**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-
-# `Code Style Practices`
-
-
-
-
-# `Error Handling Practices`
-
-⬆ Return to top
-
-## ✔ Use async-await for async error handling
-
-* **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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
-
-* **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
-
-🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
-
-
-
-# `Going To Production Practices`
-
-
-
-# `Deployment Practices`
-
-
-
-# `Security Practices`
+
+
+
+
+
+
+
+
+
+
+# Welcome to Node.js Best Practices
+
+Welcome to the biggest compilation of Node.js best practices. The content below was gathered from all top ranked books and posts and is updated constantly - when you read here rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
+
+## Table of Contents
+
+* [Project Setup Practices (18)](#project-setup-practices)
+* [Code Style Practices (11)](#code-style-practices)
+* [Error Handling Practices (14)](#error-handling-practices)
+* [Going To Production Practices (21)](#going-to-production-practices)
+* [Testing Practices (9)](#deployment-practices)
+* [Security Practices (8)](#security-practices)
+
+
+
+# `Project Setup Practices`
+
+## ✔ 1. Structure your solution by feature ('microservices')
+
+**TL&DR:** The worst large applications pitfal is a huge code base with hundreds of dependencies that slow down they developers as they try to incorporate new features. Partioning into small units ensures that each unit is kept simple and easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
+
+**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+## ✔ 2. Layer your app, keep Express within its boundaries
+
+**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
+
+**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+## ✔ 3. Configure ESLint with node-specific plugins
+
+**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
+
+**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+
+# `Code Style Practices`
+
+
+
+
+# `Error Handling Practices`
+
+⬆ Return to top
+
+## ✔ Use async-await for async error handling
+
+* **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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
+
+* **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
+
+🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
+
+
+
+# `Going To Production Practices`
+
+
+
+# `Deployment Practices`
+
+
+
+# `Security Practices`
diff --git a/sections/drafts/readme-general-toc-2.md b/sections/drafts/readme-general-toc-2.md
index c5d920f27..fe3c5af07 100644
--- a/sections/drafts/readme-general-toc-2.md
+++ b/sections/drafts/readme-general-toc-2.md
@@ -1,78 +1,78 @@
-# Node.js Best Practices
-
-
-
-![Node.js Best Practices](assets/images/banner-1.png)
-
-# Welcome to Node.js Best Practices
-
-Welcome to the biggest compilation of Node.js best practices. The content below was gathered from all top ranked books and posts and is updated constantly - when you read here rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
-
-## Table of Contents
-* [Project Setup Practices (18)](#project-setup-practices)
-* [Code Style Practices (11) ](#code-style-practices)
-* [Error Handling Practices (14) ](#error-handling-practices)
-* [Going To Production Practices (21) ](#going-to-production-practices)
-* [Testing Practices (9) ](#deployment-practices)
-* [Security Practices (8) ](#security-practices)
-
-
-# `Project Setup Practices`
-
-## ✔ 1. Structure your solution by feature ('microservices')
-
-**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
-
-**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-## ✔ 2. Layer your app, keep Express within its boundaries
-
-**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
-
-**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-## ✔ 3. Configure ESLint with node-specific plugins
-
-**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
-
-**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-# `Code Style Practices`
-
-
-
-# `Error Handling Practices`
-⬆ Return to top
-
-## ✔ Use async-await for async error handling
-
-**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
-
-**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
-
-🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
-
-
-
-
-# `Going To Production Practices`
-
-
-
-# `Deployment Practices`
-
-
-
-# `Security Practices`
-
+# Node.js Best Practices
+
+
+
+![Node.js Best Practices](assets/images/banner-1.png)
+
+# Welcome to Node.js Best Practices
+
+Welcome to the biggest compilation of Node.js best practices. The content below was gathered from all top ranked books and posts and is updated constantly - when you read here rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
+
+## Table of Contents
+* [Project Setup Practices (18)](#project-setup-practices)
+* [Code Style Practices (11) ](#code-style-practices)
+* [Error Handling Practices (14) ](#error-handling-practices)
+* [Going To Production Practices (21) ](#going-to-production-practices)
+* [Testing Practices (9) ](#deployment-practices)
+* [Security Practices (8) ](#security-practices)
+
+
+# `Project Setup Practices`
+
+## ✔ 1. Structure your solution by feature ('microservices')
+
+**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
+
+**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+## ✔ 2. Layer your app, keep Express within its boundaries
+
+**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
+
+**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+## ✔ 3. Configure ESLint with node-specific plugins
+
+**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
+
+**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+# `Code Style Practices`
+
+
+
+# `Error Handling Practices`
+⬆ Return to top
+
+## ✔ Use async-await for async error handling
+
+**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
+
+**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
+
+🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
+
+
+
+
+# `Going To Production Practices`
+
+
+
+# `Deployment Practices`
+
+
+
+# `Security Practices`
+
diff --git a/sections/drafts/readme-general-toc-3.md b/sections/drafts/readme-general-toc-3.md
index 19d791314..6bb3f9c60 100644
--- a/sections/drafts/readme-general-toc-3.md
+++ b/sections/drafts/readme-general-toc-3.md
@@ -1,82 +1,82 @@
-
-
-
-
-
-
-
-
-
-
-# Welcome to Node.js Best Practices
-
-Welcome to the biggest compilation of Node.js best practices, based on our check it's also the largest collection on any programming language (more than 53 items). The content below was gathered from all top ranked books and posts and is updated constantly - if you read here you can rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
-
-## Table of Contents
-* [Project Setup Practices (18)](#project-setup-practices)
-* [Code Style Practices (11) ](#code-style-practices)
-* [Error Handling Practices (14) ](#error-handling-practices)
-* [Going To Production Practices (21) ](#going-to-production-practices)
-* [Testing Practices (9) ](#deployment-practices)
-* [Security Practices (8) ](#security-practices)
-
-
-# `Project Setup Practices`
-
-## ✔ 1. Structure your solution by feature ('microservices')
-
-**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
-
-**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
-
-
-
-## ✔ 2. Layer your app, keep Express within its boundaries
-
-**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
-
-**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-
-## ✔ 3. Configure ESLint with node-specific plugins
-
-**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
-
-**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-# `Code Style Practices`
-
-
-
-# `Error Handling Practices`
-⬆ Return to top
-
-## ✔ Use async-await for async error handling
-
-**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
-
-**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
-
-🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
-
-
-
-
-# `Going To Production Practices`
-
-
-
-# `Deployment Practices`
-
-
-
-# `Security Practices`
-
+
+
+
+
+
+
+
+
+
+
+# Welcome to Node.js Best Practices
+
+Welcome to the biggest compilation of Node.js best practices, based on our check it's also the largest collection on any programming language (more than 53 items). The content below was gathered from all top ranked books and posts and is updated constantly - if you read here you can rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
+
+## Table of Contents
+* [Project Setup Practices (18)](#project-setup-practices)
+* [Code Style Practices (11) ](#code-style-practices)
+* [Error Handling Practices (14) ](#error-handling-practices)
+* [Going To Production Practices (21) ](#going-to-production-practices)
+* [Testing Practices (9) ](#deployment-practices)
+* [Security Practices (8) ](#security-practices)
+
+
+# `Project Setup Practices`
+
+## ✔ 1. Structure your solution by feature ('microservices')
+
+**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
+
+**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
+
+
+
+## ✔ 2. Layer your app, keep Express within its boundaries
+
+**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
+
+**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+
+## ✔ 3. Configure ESLint with node-specific plugins
+
+**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
+
+**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+# `Code Style Practices`
+
+
+
+# `Error Handling Practices`
+⬆ Return to top
+
+## ✔ Use async-await for async error handling
+
+**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
+
+**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
+
+🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
+
+
+
+
+# `Going To Production Practices`
+
+
+
+# `Deployment Practices`
+
+
+
+# `Security Practices`
+
diff --git a/sections/drafts/readme-general-toc-4.md b/sections/drafts/readme-general-toc-4.md
index 7a122dc75..19f42ea1c 100644
--- a/sections/drafts/readme-general-toc-4.md
+++ b/sections/drafts/readme-general-toc-4.md
@@ -1,115 +1,115 @@
-
-
-
-
-
-
-
-
-
-
-# Welcome to Node.js Best Practices
-
-Welcome to the biggest compilation of Node.js best practices, based on our check it's also the largest collection on any programming language (more than 53 items). The content below was gathered from all top ranked books and posts and is updated constantly - if you read here you can rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
-
-## Table of Contents
-* [Project Setup Practices (18)](#project-setup-practices)
-* [Code Style Practices (11) ](#code-style-practices)
-* [Error Handling Practices (14) ](#error-handling-practices)
-* [Going To Production Practices (21) ](#going-to-production-practices)
-* [Testing Practices (9) ](#deployment-practices)
-* [Security Practices (8) ](#security-practices)
-
-
-# `Project Setup Practices`
-
-## ![](assets/images/checkbox-sm.png) 1. Structure your solution by feature ('microservices')
-
-**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
-
-**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-## ![](assets/images/checkbox-sm.png) 2. Layer your app, keep Express within its boundaries
-
-**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
-
-**Otherwise:** Application can be accesses by Express only and require to create complex testing mocks
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-## ![](assets/images/checkbox-sm.png) 3. Configure ESLint with node-specific plugins
-
-**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
-
-**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-
-
-## Additional 15 bullets will appear here
-
-
-# `Code Style Practices`
-
-## ![](assets/images/checkbox-sm.png) 1. Use async-await
-
-**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
-
-**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-
-## ![](assets/images/checkbox-sm.png) 2. Break into small classes or objects
-
-**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
-
-**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
-
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
-
-
-# `Error Handling Practices`
-⬆ Return to top
-
-## Use async-await for async error handling
-
-**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
-
-**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
-
-🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
-
-
-
-## Use async-await for async error handling
-
-**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
-
-**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
-
-🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
-
-
-
-
-# `Going To Production Practices`
-
-
-
-# `Deployment Practices`
-
-
-
-# `Security Practices`
-
+
+
+
+
+
+
+
+
+
+
+# Welcome to Node.js Best Practices
+
+Welcome to the biggest compilation of Node.js best practices, based on our check it's also the largest collection on any programming language (more than 53 items). The content below was gathered from all top ranked books and posts and is updated constantly - if you read here you can rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
+
+## Table of Contents
+* [Project Setup Practices (18)](#project-setup-practices)
+* [Code Style Practices (11) ](#code-style-practices)
+* [Error Handling Practices (14) ](#error-handling-practices)
+* [Going To Production Practices (21) ](#going-to-production-practices)
+* [Testing Practices (9) ](#deployment-practices)
+* [Security Practices (8) ](#security-practices)
+
+
+# `Project Setup Practices`
+
+## ![](assets/images/checkbox-sm.png) 1. Structure your solution by feature ('microservices')
+
+**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
+
+**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+## ![](assets/images/checkbox-sm.png) 2. Layer your app, keep Express within its boundaries
+
+**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
+
+**Otherwise:** Application can be accesses by Express only and require to create complex testing mocks
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+## ![](assets/images/checkbox-sm.png) 3. Configure ESLint with node-specific plugins
+
+**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
+
+**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+
+
+## Additional 15 bullets will appear here
+
+
+# `Code Style Practices`
+
+## ![](assets/images/checkbox-sm.png) 1. Use async-await
+
+**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
+
+**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+
+## ![](assets/images/checkbox-sm.png) 2. Break into small classes or objects
+
+**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
+
+**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
+
+🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+
+
+# `Error Handling Practices`
+⬆ Return to top
+
+## Use async-await for async error handling
+
+**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
+
+**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
+
+🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
+
+
+
+## Use async-await for async error handling
+
+**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 instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
+
+**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
+
+🔗 [**Use async-await for async error handling**](/sections/errorhandling/asyncawait.md)
+
+
+
+
+# `Going To Production Practices`
+
+
+
+# `Deployment Practices`
+
+
+
+# `Security Practices`
+
diff --git a/sections/errorhandling/apmproducts.chinese.md b/sections/errorhandling/apmproducts.chinese.md
index 50441b732..eed5aecc3 100644
--- a/sections/errorhandling/apmproducts.chinese.md
+++ b/sections/errorhandling/apmproducts.chinese.md
@@ -1,27 +1,27 @@
-# 使用 APM 产品发现错误和宕机时间
-
-
-### 一段解释
-
-异常 != 错误。传统的错误处理假定存在异常,但应用程序错误可能以代码路径慢,API停机,缺少计算资源等形式出现。因为APM产品允许使用最小的设置来先前一步地检测各种各样 "深埋" 的问题,这是运用它们方便的地方。APM产品的常见功能包括: 当HTTP API返回错误时报警, 在API响应时间低于某个阈值时能被检测, 觉察到‘code smells’,监视服务器资源,包含IT度量的操作型智能仪表板以及其他许多有用的功能。大多数供应商提供免费方案。
-
-### 关于 APM 的维基百科
-
-在信息技术和系统管理领域, 应用程序性能管理(APM)是对软件应用程序的性能和可用性的监视和管理。APM努力检测和诊断复杂的应用程序性能问题, 以维护预期的服务级别。APM是"将IT度量标准转换为业务含义"
-
-### 了解 APM 市场
-
-APM 产品由3个主要部分构成:
-
-1. 网站或API监控 – 通过HTTP请求不断监视正常运行时间和性能的外部服务。可以在几分钟内安装。以下是少数选定的竞争者: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), 和[New Relic](https://newrelic.com/application-monitoring);
-
-2. 代码检测 – 这类产品需要在应用程序中嵌入代理, 以实现如检测运行缓慢的代码、异常统计、性能监视等功能。以下是少数选定的竞争者: New Relic, App Dynamics;
-
-3. 操作型智能仪表板 – 这些产品系列侧重于为ops团队提供度量和管理内容, 帮助他们轻松地保持应用程序性能维持在最佳状态。这通常涉及聚合多个信息源 (应用程序日志、DB日志、服务器日志等) 和前期仪表板设计工作。以下是少数选定的竞争者: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/);
-
-
- ### 示例: UpTimeRobot.Com – 网站监控仪表板
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/uptimerobot.jpg "Website monitoring dashboard")
-
- ### 示例: AppDynamics.Com – 与代码检测结合的端到端监视
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/app-dynamics-dashboard.png "end to end monitoring combined with code instrumentation")
+# 使用 APM 产品发现错误和宕机时间
+
+
+### 一段解释
+
+异常 != 错误。传统的错误处理假定存在异常,但应用程序错误可能以代码路径慢,API停机,缺少计算资源等形式出现。因为APM产品允许使用最小的设置来先前一步地检测各种各样 "深埋" 的问题,这是运用它们方便的地方。APM产品的常见功能包括: 当HTTP API返回错误时报警, 在API响应时间低于某个阈值时能被检测, 觉察到‘code smells’,监视服务器资源,包含IT度量的操作型智能仪表板以及其他许多有用的功能。大多数供应商提供免费方案。
+
+### 关于 APM 的维基百科
+
+在信息技术和系统管理领域, 应用程序性能管理(APM)是对软件应用程序的性能和可用性的监视和管理。APM努力检测和诊断复杂的应用程序性能问题, 以维护预期的服务级别。APM是"将IT度量标准转换为业务含义"
+
+### 了解 APM 市场
+
+APM 产品由3个主要部分构成:
+
+1. 网站或API监控 – 通过HTTP请求不断监视正常运行时间和性能的外部服务。可以在几分钟内安装。以下是少数选定的竞争者: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), 和[New Relic](https://newrelic.com/application-monitoring);
+
+2. 代码检测 – 这类产品需要在应用程序中嵌入代理, 以实现如检测运行缓慢的代码、异常统计、性能监视等功能。以下是少数选定的竞争者: New Relic, App Dynamics;
+
+3. 操作型智能仪表板 – 这些产品系列侧重于为ops团队提供度量和管理内容, 帮助他们轻松地保持应用程序性能维持在最佳状态。这通常涉及聚合多个信息源 (应用程序日志、DB日志、服务器日志等) 和前期仪表板设计工作。以下是少数选定的竞争者: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/);
+
+
+ ### 示例: UpTimeRobot.Com – 网站监控仪表板
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/uptimerobot.jpg "Website monitoring dashboard")
+
+ ### 示例: AppDynamics.Com – 与代码检测结合的端到端监视
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/app-dynamics-dashboard.png "end to end monitoring combined with code instrumentation")
diff --git a/sections/errorhandling/apmproducts.md b/sections/errorhandling/apmproducts.md
index ffb1fd7c1..5a6f773a8 100644
--- a/sections/errorhandling/apmproducts.md
+++ b/sections/errorhandling/apmproducts.md
@@ -1,29 +1,29 @@
-# Discover errors and downtime using APM products
-
-
-### One Paragraph Explainer
-
-Exception != Error. Traditional error handling assumes the existence of Exception but application errors might come in the form of slow code paths, API downtime, lack of computational resources and more. This is where APM products come in handy as they allow to detect a wide variety of ‘burried’ issues proactively with a minimal setup. Among the common features of APM products are for example alerting when the HTTP API returns errors, detect when the API response time drops below some threshold, detection of ‘code smells’, features to monitor server resources, operational intelligence dashboard with IT metrics and many other useful features. Most vendors offer a free plan.
-
-### Wikipedia about APM
-
-In the fields of information technology and systems management, Application Performance Management (APM) is the monitoring and management of performance and availability of software applications. APM strives to detect and diagnose complex application performance problems to maintain an expected level of service. APM is “the translation of IT metrics into business meaning ([i.e.] value)
-Major products and segments
-
-### Understanding the APM marketplace
-
-APM products constitute 3 major segments:
-
-1. Website or API monitoring – external services that constantly monitor uptime and performance via HTTP requests. Can be set up in few minutes. Following are few selected contenders: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), and [New Relic](https://newrelic.com/application-monitoring)
-
-2. Code instrumentation – product family which requires embedding an agent within the application to use features like slow code detection, exception statistics, performance monitoring and many more. Following are few selected contenders: New Relic, App Dynamics
-
-3. Operational intelligence dashboard – this line of products is focused on facilitating the ops team with metrics and curated content that helps to easily stay on top of application performance. This usually involves aggregating multiple sources of information (application logs, DB logs, servers log, etc) and upfront dashboard design work. Following are few selected contenders: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/)
-
-
-
- ### Example: UpTimeRobot.Com – Website monitoring dashboard
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/uptimerobot.jpg "Website monitoring dashboard")
-
- ### Example: AppDynamics.Com – end to end monitoring combined with code instrumentation
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/app-dynamics-dashboard.png "end to end monitoring combined with code instrumentation")
+# Discover errors and downtime using APM products
+
+
+### One Paragraph Explainer
+
+Exception != Error. Traditional error handling assumes the existence of Exception but application errors might come in the form of slow code paths, API downtime, lack of computational resources and more. This is where APM products come in handy as they allow to detect a wide variety of ‘burried’ issues proactively with a minimal setup. Among the common features of APM products are for example alerting when the HTTP API returns errors, detect when the API response time drops below some threshold, detection of ‘code smells’, features to monitor server resources, operational intelligence dashboard with IT metrics and many other useful features. Most vendors offer a free plan.
+
+### Wikipedia about APM
+
+In the fields of information technology and systems management, Application Performance Management (APM) is the monitoring and management of performance and availability of software applications. APM strives to detect and diagnose complex application performance problems to maintain an expected level of service. APM is “the translation of IT metrics into business meaning ([i.e.] value)
+Major products and segments
+
+### Understanding the APM marketplace
+
+APM products constitute 3 major segments:
+
+1. Website or API monitoring – external services that constantly monitor uptime and performance via HTTP requests. Can be set up in few minutes. Following are few selected contenders: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), and [New Relic](https://newrelic.com/application-monitoring)
+
+2. Code instrumentation – product family which requires embedding an agent within the application to use features like slow code detection, exception statistics, performance monitoring and many more. Following are few selected contenders: New Relic, App Dynamics
+
+3. Operational intelligence dashboard – this line of products is focused on facilitating the ops team with metrics and curated content that helps to easily stay on top of application performance. This usually involves aggregating multiple sources of information (application logs, DB logs, servers log, etc) and upfront dashboard design work. Following are few selected contenders: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/)
+
+
+
+ ### Example: UpTimeRobot.Com – Website monitoring dashboard
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/uptimerobot.jpg "Website monitoring dashboard")
+
+ ### Example: AppDynamics.Com – end to end monitoring combined with code instrumentation
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/app-dynamics-dashboard.png "end to end monitoring combined with code instrumentation")
diff --git a/sections/errorhandling/asyncerrorhandling.chinese.md b/sections/errorhandling/asyncerrorhandling.chinese.md
index f168a4500..ef2f12e51 100644
--- a/sections/errorhandling/asyncerrorhandling.chinese.md
+++ b/sections/errorhandling/asyncerrorhandling.chinese.md
@@ -1,56 +1,56 @@
-# 对于异步的错误处理,请使用Async-Await或者promise
-
-
-### 一段解释
-
-由于回调对于大多数的程序员来说不熟悉,被迫随处检测错误,让人不快的代码内嵌和难以理解的代码流程,它没有形成一定规模。promise的库,比如BlueBird,async,和Q封装了一种标准的代码风格, 它通过使用return和throw来控制程序流程。具体来说,它们支持最受欢迎的try-catch错误处理风格,这使得主流程代码从在每一个方法中处理错误的方式中解放出来。
-
-
-### 代码示例 – 使用promise捕获错误
-
-
-```javascript
-doWork()
- .then(doWork)
- .then(doOtherWork)
- .then((result) => doWork)
- .catch((error) => {throw error;})
- .then(verify);
-```
-
-### 代码示例 反模式 – 回调方式的错误处理
-
-```javascript
-getData(someParameter, function(err, result){
- if(err != null)
- //做一些事情类似于调用给定的回调函数并传递错误
- getMoreData(a, function(err, result){
- if(err != null)
- //做一些事情类似于调用给定的回调函数并传递错误
- getMoreData(b, function(c){
- getMoreData(d, function(e){
- if(err != null)
- //你有什么想法?
- });
-});
-```
-
-### 博客引用: "我们使用promise有一个问题"
- 摘自博客pouchdb.com
-
- > ……实际上, 回调会做一些更险恶的事情: 他们剥夺了我们的stack, 这是我们通常在编程语言中想当然的事情。编写没有堆栈的代码很像驾驶一辆没有刹车踏板的汽车: 你没有意识到你有多么需要它, 直到你伸手去找它, 而它不在那里。promise的全部目的是让我们回到我们在异步时丢失的语言基础: return,throw和stack。但你必须知道如何正确使用promise, 以便利用他们。
-
-### 博客引用: "promise方法更加紧凑"
- 摘自博客gosquared.com
-
- > ………promise的方法更紧凑, 更清晰, 写起来更快速。如果在任何ops中发生错误或异常,则由单个.catch()处理程序处理。有这个单一的地方来处理所有的错误意味着你不需要为每个阶段的工作写错误检查。
-
-### 博客引用: "原生ES6支持promise,可以和generator一起使用"
- 摘自博客StrongLoop
-
- > ….回调有一个糟糕的错误处理的报道。promise更好。将express内置的错误处理与promise结合起来, 大大降低了uncaught exception的几率。原生ES6支持promise, 通过编译器babel,它可以与generator,ES7提议的技术(比如async/await)一起使用。
-
-### 博客引用: "所有那些您所习惯的常规的流量控制结构, 完全被打破"
- 摘自博客Benno’s
-
- > ……关于基于异步、回调编程的最好的事情之一是, 基本上所有那些您习惯的常规流量控制结构, 完全被打破。然而, 我发现最易打破的是处理异常。Javascript提供了一个相当熟悉的try...catch结构来处理异常。异常的问题是, 它们提供了在一个调用堆栈上 short-cutting错误的很好的方法, 但最终由于不同堆栈上发生的错误导致完全无用…
+# 对于异步的错误处理,请使用Async-Await或者promise
+
+
+### 一段解释
+
+由于回调对于大多数的程序员来说不熟悉,被迫随处检测错误,让人不快的代码内嵌和难以理解的代码流程,它没有形成一定规模。promise的库,比如BlueBird,async,和Q封装了一种标准的代码风格, 它通过使用return和throw来控制程序流程。具体来说,它们支持最受欢迎的try-catch错误处理风格,这使得主流程代码从在每一个方法中处理错误的方式中解放出来。
+
+
+### 代码示例 – 使用promise捕获错误
+
+
+```javascript
+doWork()
+ .then(doWork)
+ .then(doOtherWork)
+ .then((result) => doWork)
+ .catch((error) => {throw error;})
+ .then(verify);
+```
+
+### 代码示例 反模式 – 回调方式的错误处理
+
+```javascript
+getData(someParameter, function(err, result){
+ if(err != null)
+ //做一些事情类似于调用给定的回调函数并传递错误
+ getMoreData(a, function(err, result){
+ if(err != null)
+ //做一些事情类似于调用给定的回调函数并传递错误
+ getMoreData(b, function(c){
+ getMoreData(d, function(e){
+ if(err != null)
+ //你有什么想法?
+ });
+});
+```
+
+### 博客引用: "我们使用promise有一个问题"
+ 摘自博客pouchdb.com
+
+ > ……实际上, 回调会做一些更险恶的事情: 他们剥夺了我们的stack, 这是我们通常在编程语言中想当然的事情。编写没有堆栈的代码很像驾驶一辆没有刹车踏板的汽车: 你没有意识到你有多么需要它, 直到你伸手去找它, 而它不在那里。promise的全部目的是让我们回到我们在异步时丢失的语言基础: return,throw和stack。但你必须知道如何正确使用promise, 以便利用他们。
+
+### 博客引用: "promise方法更加紧凑"
+ 摘自博客gosquared.com
+
+ > ………promise的方法更紧凑, 更清晰, 写起来更快速。如果在任何ops中发生错误或异常,则由单个.catch()处理程序处理。有这个单一的地方来处理所有的错误意味着你不需要为每个阶段的工作写错误检查。
+
+### 博客引用: "原生ES6支持promise,可以和generator一起使用"
+ 摘自博客StrongLoop
+
+ > ….回调有一个糟糕的错误处理的报道。promise更好。将express内置的错误处理与promise结合起来, 大大降低了uncaught exception的几率。原生ES6支持promise, 通过编译器babel,它可以与generator,ES7提议的技术(比如async/await)一起使用。
+
+### 博客引用: "所有那些您所习惯的常规的流量控制结构, 完全被打破"
+ 摘自博客Benno’s
+
+ > ……关于基于异步、回调编程的最好的事情之一是, 基本上所有那些您习惯的常规流量控制结构, 完全被打破。然而, 我发现最易打破的是处理异常。Javascript提供了一个相当熟悉的try...catch结构来处理异常。异常的问题是, 它们提供了在一个调用堆栈上 short-cutting错误的很好的方法, 但最终由于不同堆栈上发生的错误导致完全无用…
diff --git a/sections/errorhandling/asyncerrorhandling.md b/sections/errorhandling/asyncerrorhandling.md
index 06ca39532..4c428bba5 100644
--- a/sections/errorhandling/asyncerrorhandling.md
+++ b/sections/errorhandling/asyncerrorhandling.md
@@ -1,62 +1,62 @@
-# Use Async-Await or promises for async error handling
-
-### One Paragraph Explainer
-
-Callbacks don’t scale well since most programmers are not familiar with them. They force to check errors all over, deal with nasty code nesting and make it difficult to reason about the code flow. Promise libraries like BlueBird, async, and Q pack a standard code style using RETURN and THROW to control the program flow. Specifically, they support the favorite try-catch error handling style which allows freeing the main code path from dealing with errors in every function
-
-### Code Example – using promises to catch errors
-
-```javascript
-doWork()
- .then(doWork)
- .then(doOtherWork)
- .then((result) => doWork)
- .catch((error) => {throw error;})
- .then(verify);
-```
-
-### Anti pattern code example – callback style error handling
-
-```javascript
-getData(someParameter, function(err, result) {
- if(err !== null) {
- // do something like calling the given callback function and pass the error
- getMoreData(a, function(err, result) {
- if(err !== null) {
- // do something like calling the given callback function and pass the error
- getMoreData(b, function(c) {
- getMoreData(d, function(e) {
- if(err !== null ) {
- // you get the idea?
- }
- })
- });
- }
- });
- }
-});
-```
-
-### Blog Quote: "We have a problem with promises"
-
- From the blog pouchdb.com
-
- > ……And in fact, callbacks do something even more sinister: they deprive us of the stack, which is something we usually take for granted in programming languages. Writing code without a stack is a lot like driving a car without a brake pedal: you don’t realize how badly you need it until you reach for it and it’s not there. The whole point of promises is to give us back the language fundamentals we lost when we went async: return, throw, and the stack. But you have to know how to use promises correctly in order to take advantage of them.
-
-### Blog Quote: "The promises method is much more compact"
-
- From the blog gosquared.com
-
- > ………The promises method is much more compact, clearer and quicker to write. If an error or exception occurs within any of the ops it is handled by the single .catch() handler. Having this single place to handle all errors means you don’t need to write error checking for each stage of the work.
-
-### Blog Quote: "Promises are native ES6, can be used with generators"
-
- From the blog StrongLoop
-
- > ….Callbacks have a lousy error-handling story. Promises are better. Marry the built-in error handling in Express with promises and significantly lower the chances of an uncaught exception. Promises are native ES6, can be used with generators, and ES7 proposals like async/await through compilers like Babel
-
-### Blog Quote: "All those regular flow control constructs you are used to are completely broken"
-
-From the blog Benno’s
-
- > ……One of the best things about asynchronous, callback-based programming is that basically all those regular flow control constructs you are used to are completely broken. However, the one I find most broken is the handling of exceptions. Javascript provides a fairly familiar try…catch construct for dealing with exceptions. The problem with exceptions is that they provide a great way of short-cutting errors up a call stack, but end up being completely useless of the error happens on a different stack…
+# Use Async-Await or promises for async error handling
+
+### One Paragraph Explainer
+
+Callbacks don’t scale well since most programmers are not familiar with them. They force to check errors all over, deal with nasty code nesting and make it difficult to reason about the code flow. Promise libraries like BlueBird, async, and Q pack a standard code style using RETURN and THROW to control the program flow. Specifically, they support the favorite try-catch error handling style which allows freeing the main code path from dealing with errors in every function
+
+### Code Example – using promises to catch errors
+
+```javascript
+doWork()
+ .then(doWork)
+ .then(doOtherWork)
+ .then((result) => doWork)
+ .catch((error) => {throw error;})
+ .then(verify);
+```
+
+### Anti pattern code example – callback style error handling
+
+```javascript
+getData(someParameter, function(err, result) {
+ if(err !== null) {
+ // do something like calling the given callback function and pass the error
+ getMoreData(a, function(err, result) {
+ if(err !== null) {
+ // do something like calling the given callback function and pass the error
+ getMoreData(b, function(c) {
+ getMoreData(d, function(e) {
+ if(err !== null ) {
+ // you get the idea?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
+### Blog Quote: "We have a problem with promises"
+
+ From the blog pouchdb.com
+
+ > ……And in fact, callbacks do something even more sinister: they deprive us of the stack, which is something we usually take for granted in programming languages. Writing code without a stack is a lot like driving a car without a brake pedal: you don’t realize how badly you need it until you reach for it and it’s not there. The whole point of promises is to give us back the language fundamentals we lost when we went async: return, throw, and the stack. But you have to know how to use promises correctly in order to take advantage of them.
+
+### Blog Quote: "The promises method is much more compact"
+
+ From the blog gosquared.com
+
+ > ………The promises method is much more compact, clearer and quicker to write. If an error or exception occurs within any of the ops it is handled by the single .catch() handler. Having this single place to handle all errors means you don’t need to write error checking for each stage of the work.
+
+### Blog Quote: "Promises are native ES6, can be used with generators"
+
+ From the blog StrongLoop
+
+ > ….Callbacks have a lousy error-handling story. Promises are better. Marry the built-in error handling in Express with promises and significantly lower the chances of an uncaught exception. Promises are native ES6, can be used with generators, and ES7 proposals like async/await through compilers like Babel
+
+### Blog Quote: "All those regular flow control constructs you are used to are completely broken"
+
+From the blog Benno’s
+
+ > ……One of the best things about asynchronous, callback-based programming is that basically all those regular flow control constructs you are used to are completely broken. However, the one I find most broken is the handling of exceptions. Javascript provides a fairly familiar try…catch construct for dealing with exceptions. The problem with exceptions is that they provide a great way of short-cutting errors up a call stack, but end up being completely useless of the error happens on a different stack…
diff --git a/sections/errorhandling/catchunhandledpromiserejection.chinese.md b/sections/errorhandling/catchunhandledpromiserejection.chinese.md
index 830d4bbd0..81c69ba35 100644
--- a/sections/errorhandling/catchunhandledpromiserejection.chinese.md
+++ b/sections/errorhandling/catchunhandledpromiserejection.chinese.md
@@ -1,58 +1,58 @@
-# 捕获未处理的promise rejections
-
-
-
-### 一段解释
-
-通常,大部分的现代node.js/express应用代码运行在promise里 – 或者是在.then里处理,一个回调函数中,或者在一个catch块中。令人惊讶的是,除非开发者记得添加.catch语句,在这些地方抛出的错误都不会被uncaughtException事件处理程序来处理,然后消失掉。当未处理的rejection出现,node最近的版本增加了一个警告消息,尽管当事情出错的时候这可能有助于发现问题,但这显然不是一个适当的错误处理方法。简单明了的解决方案是永远不要忘记在每个promise链式调用中添加.catch语句,并重定向到一个集中的错误处理程序。然而,只在开发人员的规程上构建错误处理策略是有些脆弱的。因此,使用一个优雅的回调并订阅到process.on('unhandledrejection',callback)是高度推荐的 – 这将确保任何promise错误,如果不是本地处理,将在这处理。
-
-
-
-### 代码示例: 这些错误将不会得到任何错误处理程序捕获(除unhandledrejection)
-
-```javascript
-DAL.getUserById(1).then((johnSnow) =>
-{
- //this error will just vanish
- if(johnSnow.isAlive == false)
- throw new Error('ahhhh');
-});
-
-```
-
-### 代码示例: 捕获 unresolved 和 rejected 的 promise
-
-```javascript
-process.on('unhandledRejection', (reason, p) => {
- //我刚刚捕获了一个未处理的promise rejection, 因为我们已经有了对于未处理错误的后备的处理机制(见下面), 直接抛出,让它来处理
- throw reason;
-});
-process.on('uncaughtException', (error) => {
- //我刚收到一个从未被处理的错误,现在处理它,并决定是否需要重启应用
- errorManagement.handler.handleError(error);
- if (!errorManagement.handler.isTrustedError(error))
- process.exit(1);
-});
-
-```
-
-### 博客引用: "如果你犯了错误,在某个时候你就会犯错误。"
- 摘自 James Nelson 的博客
-
- > 让我们测试一下您的理解。下列哪一项是您期望错误将会打印到控制台的?
-
-```javascript
-Promise.resolve(‘promised value’).then(() => {
- throw new Error(‘error’);
-});
-
-Promise.reject(‘error value’).catch(() => {
- throw new Error(‘error’);
-});
-
-new Promise((resolve, reject) => {
- throw new Error(‘error’);
-});
-```
-
-> 我不知道您的情况,但我的回答是我希望它们所有都能打印出一个错误。然而,现实是许多现代JavaScript环境不会为其中任何一个打印错误。做为人的问题是,如果你犯了错误,在某个时候你就会犯错误。记住这一点,很显然,我们应该设计这样一种方式,使错误尽可能少创造伤害,这意味着默认地处理错误,而不是丢弃错误。
+# 捕获未处理的promise rejections
+
+
+
+### 一段解释
+
+通常,大部分的现代node.js/express应用代码运行在promise里 – 或者是在.then里处理,一个回调函数中,或者在一个catch块中。令人惊讶的是,除非开发者记得添加.catch语句,在这些地方抛出的错误都不会被uncaughtException事件处理程序来处理,然后消失掉。当未处理的rejection出现,node最近的版本增加了一个警告消息,尽管当事情出错的时候这可能有助于发现问题,但这显然不是一个适当的错误处理方法。简单明了的解决方案是永远不要忘记在每个promise链式调用中添加.catch语句,并重定向到一个集中的错误处理程序。然而,只在开发人员的规程上构建错误处理策略是有些脆弱的。因此,使用一个优雅的回调并订阅到process.on('unhandledrejection',callback)是高度推荐的 – 这将确保任何promise错误,如果不是本地处理,将在这处理。
+
+
+
+### 代码示例: 这些错误将不会得到任何错误处理程序捕获(除unhandledrejection)
+
+```javascript
+DAL.getUserById(1).then((johnSnow) =>
+{
+ //this error will just vanish
+ if(johnSnow.isAlive == false)
+ throw new Error('ahhhh');
+});
+
+```
+
+### 代码示例: 捕获 unresolved 和 rejected 的 promise
+
+```javascript
+process.on('unhandledRejection', (reason, p) => {
+ //我刚刚捕获了一个未处理的promise rejection, 因为我们已经有了对于未处理错误的后备的处理机制(见下面), 直接抛出,让它来处理
+ throw reason;
+});
+process.on('uncaughtException', (error) => {
+ //我刚收到一个从未被处理的错误,现在处理它,并决定是否需要重启应用
+ errorManagement.handler.handleError(error);
+ if (!errorManagement.handler.isTrustedError(error))
+ process.exit(1);
+});
+
+```
+
+### 博客引用: "如果你犯了错误,在某个时候你就会犯错误。"
+ 摘自 James Nelson 的博客
+
+ > 让我们测试一下您的理解。下列哪一项是您期望错误将会打印到控制台的?
+
+```javascript
+Promise.resolve(‘promised value’).then(() => {
+ throw new Error(‘error’);
+});
+
+Promise.reject(‘error value’).catch(() => {
+ throw new Error(‘error’);
+});
+
+new Promise((resolve, reject) => {
+ throw new Error(‘error’);
+});
+```
+
+> 我不知道您的情况,但我的回答是我希望它们所有都能打印出一个错误。然而,现实是许多现代JavaScript环境不会为其中任何一个打印错误。做为人的问题是,如果你犯了错误,在某个时候你就会犯错误。记住这一点,很显然,我们应该设计这样一种方式,使错误尽可能少创造伤害,这意味着默认地处理错误,而不是丢弃错误。
diff --git a/sections/errorhandling/catchunhandledpromiserejection.md b/sections/errorhandling/catchunhandledpromiserejection.md
index e71f79cc3..b2e890d0a 100644
--- a/sections/errorhandling/catchunhandledpromiserejection.md
+++ b/sections/errorhandling/catchunhandledpromiserejection.md
@@ -1,62 +1,62 @@
-# Catch unhandled promise rejections
-
-
-
-### One Paragraph Explainer
-
-Typically, most of modern Node.js/Express application code runs within promises – whether within the .then handler, a function callback or in a catch block. Surprisingly, unless a developer remembered to add a .catch clause, errors thrown at these places are not handled by the uncaughtException event-handler and disappear. Recent versions of Node added a warning message when an unhandled rejection pops, though this might help to notice when things go wrong but it's obviously not a proper error handling method. The straightforward solution is to never forget adding .catch clauses within each promise chain call and redirect to a centralized error handler. However, building your error handling strategy only on developer’s discipline is somewhat fragile. Consequently, it’s highly recommended using a graceful fallback and subscribe to `process.on(‘unhandledRejection’, callback)` – this will ensure that any promise error, if not handled locally, will get its treatment.
-
-
-
-### Code example: these errors will not get caught by any error handler (except unhandledRejection)
-
-```javascript
-DAL.getUserById(1).then((johnSnow) => {
- // this error will just vanish
- if(johnSnow.isAlive == false)
- throw new Error('ahhhh');
-});
-
-```
-
-
-
-### Code example: Catching unresolved and rejected promises
-
-```javascript
-process.on('unhandledRejection', (reason, p) => {
- // I just caught an unhandled promise rejection, since we already have fallback handler for unhandled errors (see below), let throw and let him handle that
- throw reason;
-});
-process.on('uncaughtException', (error) => {
- // I just received an error that was never handled, time to handle it and then decide whether a restart is needed
- errorManagement.handler.handleError(error);
- if (!errorManagement.handler.isTrustedError(error))
- process.exit(1);
-});
-
-```
-
-
-
-### Blog Quote: "If you can make a mistake, at some point you will"
-
- From the blog James Nelson
-
- > Let’s test your understanding. Which of the following would you expect to print an error to the console?
-
-```javascript
-Promise.resolve(‘promised value’).then(() => {
- throw new Error(‘error’);
-});
-
-Promise.reject(‘error value’).catch(() => {
- throw new Error(‘error’);
-});
-
-new Promise((resolve, reject) => {
- throw new Error(‘error’);
-});
-```
-
-> I don’t know about you, but my answer is that I’d expect all of them to print an error. However, the reality is that a number of modern JavaScript environments won’t print errors for any of them.The problem with being human is that if you can make a mistake, at some point you will. Keeping this in mind, it seems obvious that we should design things in such a way that mistakes hurt as little as possible, and that means handling errors by default, not discarding them.
+# Catch unhandled promise rejections
+
+
+
+### One Paragraph Explainer
+
+Typically, most of modern Node.js/Express application code runs within promises – whether within the .then handler, a function callback or in a catch block. Surprisingly, unless a developer remembered to add a .catch clause, errors thrown at these places are not handled by the uncaughtException event-handler and disappear. Recent versions of Node added a warning message when an unhandled rejection pops, though this might help to notice when things go wrong but it's obviously not a proper error handling method. The straightforward solution is to never forget adding .catch clauses within each promise chain call and redirect to a centralized error handler. However, building your error handling strategy only on developer’s discipline is somewhat fragile. Consequently, it’s highly recommended using a graceful fallback and subscribe to `process.on(‘unhandledRejection’, callback)` – this will ensure that any promise error, if not handled locally, will get its treatment.
+
+
+
+### Code example: these errors will not get caught by any error handler (except unhandledRejection)
+
+```javascript
+DAL.getUserById(1).then((johnSnow) => {
+ // this error will just vanish
+ if(johnSnow.isAlive == false)
+ throw new Error('ahhhh');
+});
+
+```
+
+
+
+### Code example: Catching unresolved and rejected promises
+
+```javascript
+process.on('unhandledRejection', (reason, p) => {
+ // I just caught an unhandled promise rejection, since we already have fallback handler for unhandled errors (see below), let throw and let him handle that
+ throw reason;
+});
+process.on('uncaughtException', (error) => {
+ // I just received an error that was never handled, time to handle it and then decide whether a restart is needed
+ errorManagement.handler.handleError(error);
+ if (!errorManagement.handler.isTrustedError(error))
+ process.exit(1);
+});
+
+```
+
+
+
+### Blog Quote: "If you can make a mistake, at some point you will"
+
+ From the blog James Nelson
+
+ > Let’s test your understanding. Which of the following would you expect to print an error to the console?
+
+```javascript
+Promise.resolve(‘promised value’).then(() => {
+ throw new Error(‘error’);
+});
+
+Promise.reject(‘error value’).catch(() => {
+ throw new Error(‘error’);
+});
+
+new Promise((resolve, reject) => {
+ throw new Error(‘error’);
+});
+```
+
+> I don’t know about you, but my answer is that I’d expect all of them to print an error. However, the reality is that a number of modern JavaScript environments won’t print errors for any of them.The problem with being human is that if you can make a mistake, at some point you will. Keeping this in mind, it seems obvious that we should design things in such a way that mistakes hurt as little as possible, and that means handling errors by default, not discarding them.
diff --git a/sections/errorhandling/centralizedhandling.chinese.md b/sections/errorhandling/centralizedhandling.chinese.md
index 1f7d4214d..976c5d891 100644
--- a/sections/errorhandling/centralizedhandling.chinese.md
+++ b/sections/errorhandling/centralizedhandling.chinese.md
@@ -1,83 +1,83 @@
-# 集中处理错误,通过但不是在中间件里处理错误
-
-
-### 一段解释
-
-如果没有一个专用的错误处理对象,那么由于操作不当,在雷达下重要错误被隐藏的可能性就会更大。错误处理对象负责使错误可见,例如通过写入一个格式化良好的logger,通过电子邮件将事件发送到某个监控产品或管理员。一个典型的错误处理流程可能是:一些模块抛出一个错误 -> API路由器捕获错误 -> 它传播错误给负责捕获错误的中间件(如Express,KOA)-> 集中式错误处理程序被调用 -> 中间件正在被告之这个错误是否是一个不可信的错误(不是操作型错误),这样可以优雅的重新启动应用程序。注意,在Express中间件中处理错误是一种常见但又错误的做法,这样做不会覆盖在非Web接口中抛出的错误。
-
-
-
-### 代码示例 – 一个典型错误流
-
-```javascript
-//DAL层, 在这里我们不处理错误
-DB.addDocument(newCustomer, (error, result) => {
- if (error)
- throw new Error("Great error explanation comes here", other useful parameters)
-});
-
-//API路由代码, 我们同时捕获异步和同步错误,并转到中间件
-try {
- customerService.addNew(req.body).then(function (result) {
- res.status(200).json(result);
- }).catch((error) => {
- next(error)
- });
-}
-catch (error) {
- next(error);
-}
-
-//错误处理中间件,我们委托集中式错误处理程序处理错误
-app.use(function (err, req, res, next) {
- errorHandler.handleError(err).then((isOperationalError) => {
- if (!isOperationalError)
- next(err);
- });
-});
-
-```
-
-### 代码示例 – 在一个专门的对象里面处理错误
-
-```javascript
-module.exports.handler = new errorHandler();
-
-function errorHandler(){
- this.handleError = function (error) {
- return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
- }
-
-```
-
-### 代码示例 – 反模式:在中间件内处理错误
-
-```javascript
-//中间件直接处理错误,那谁将处理Cron任务和测试错误呢?
-app.use(function (err, req, res, next) {
- logger.logError(err);
- if(err.severity == errors.high)
- mailer.sendMail(configuration.adminMail, "Critical error occured", err);
- if(!err.isOperational)
- next(err);
-});
-
-```
-
-### 博客引用: "有时较低的级别不能做任何有用的事情, 除非将错误传播给他们的调用者"
- 摘自博客 Joyent, 对应关键字 “Node.JS error handling” 排名第一
-
- > …您可能会在stack的多个级别上处理相同的错误。这发生在当较低级别不能执行任何有用的操作,除了将错误传播给它们的调用方, 从而将错误传播到其调用方, 等等。通常, 只有top-level调用方知道适当的响应是什么, 无论是重试操作、向用户报告错误还是其他事情。但这并不意味着您应该尝试将所有错误报告给单个top-level回调, 因为该回调本身无法知道错误发生在什么上下文中…
-
-
-### 博客引用: "单独处理每个错误将导致大量的重复"
- 摘自博客 JS Recipes, 对应关键字 “Node.JS error handling” 排名17
-
- > ……仅仅在Hackathon启动api.js控制器中, 有超过79处重复的错误对象。单独处理每个错误将导致大量的代码重复。您可以做的下一个最好的事情是将所有错误处理逻辑委派给一个express中间件…
-
-
-### 博客引用: "HTTP错误不会在数据库代码中出现"
- 摘自博客 Daily JS, 对应关键字 “Node.JS error handling” 排名14
-
- > ……您应该在error对象中设置有用的属性, 但使用此类属性时应保持一致。而且, 不要越过流: HTTP错误不会在数据库代码中出现。或者对于浏览器开发人员来说, Ajax 错误在与服务器交互的代码中有一席之地, 而不是处理Mustache模板的代码…
-
+# 集中处理错误,通过但不是在中间件里处理错误
+
+
+### 一段解释
+
+如果没有一个专用的错误处理对象,那么由于操作不当,在雷达下重要错误被隐藏的可能性就会更大。错误处理对象负责使错误可见,例如通过写入一个格式化良好的logger,通过电子邮件将事件发送到某个监控产品或管理员。一个典型的错误处理流程可能是:一些模块抛出一个错误 -> API路由器捕获错误 -> 它传播错误给负责捕获错误的中间件(如Express,KOA)-> 集中式错误处理程序被调用 -> 中间件正在被告之这个错误是否是一个不可信的错误(不是操作型错误),这样可以优雅的重新启动应用程序。注意,在Express中间件中处理错误是一种常见但又错误的做法,这样做不会覆盖在非Web接口中抛出的错误。
+
+
+
+### 代码示例 – 一个典型错误流
+
+```javascript
+//DAL层, 在这里我们不处理错误
+DB.addDocument(newCustomer, (error, result) => {
+ if (error)
+ throw new Error("Great error explanation comes here", other useful parameters)
+});
+
+//API路由代码, 我们同时捕获异步和同步错误,并转到中间件
+try {
+ customerService.addNew(req.body).then(function (result) {
+ res.status(200).json(result);
+ }).catch((error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+//错误处理中间件,我们委托集中式错误处理程序处理错误
+app.use(function (err, req, res, next) {
+ errorHandler.handleError(err).then((isOperationalError) => {
+ if (!isOperationalError)
+ next(err);
+ });
+});
+
+```
+
+### 代码示例 – 在一个专门的对象里面处理错误
+
+```javascript
+module.exports.handler = new errorHandler();
+
+function errorHandler(){
+ this.handleError = function (error) {
+ return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
+ }
+
+```
+
+### 代码示例 – 反模式:在中间件内处理错误
+
+```javascript
+//中间件直接处理错误,那谁将处理Cron任务和测试错误呢?
+app.use(function (err, req, res, next) {
+ logger.logError(err);
+ if(err.severity == errors.high)
+ mailer.sendMail(configuration.adminMail, "Critical error occured", err);
+ if(!err.isOperational)
+ next(err);
+});
+
+```
+
+### 博客引用: "有时较低的级别不能做任何有用的事情, 除非将错误传播给他们的调用者"
+ 摘自博客 Joyent, 对应关键字 “Node.JS error handling” 排名第一
+
+ > …您可能会在stack的多个级别上处理相同的错误。这发生在当较低级别不能执行任何有用的操作,除了将错误传播给它们的调用方, 从而将错误传播到其调用方, 等等。通常, 只有top-level调用方知道适当的响应是什么, 无论是重试操作、向用户报告错误还是其他事情。但这并不意味着您应该尝试将所有错误报告给单个top-level回调, 因为该回调本身无法知道错误发生在什么上下文中…
+
+
+### 博客引用: "单独处理每个错误将导致大量的重复"
+ 摘自博客 JS Recipes, 对应关键字 “Node.JS error handling” 排名17
+
+ > ……仅仅在Hackathon启动api.js控制器中, 有超过79处重复的错误对象。单独处理每个错误将导致大量的代码重复。您可以做的下一个最好的事情是将所有错误处理逻辑委派给一个express中间件…
+
+
+### 博客引用: "HTTP错误不会在数据库代码中出现"
+ 摘自博客 Daily JS, 对应关键字 “Node.JS error handling” 排名14
+
+ > ……您应该在error对象中设置有用的属性, 但使用此类属性时应保持一致。而且, 不要越过流: HTTP错误不会在数据库代码中出现。或者对于浏览器开发人员来说, Ajax 错误在与服务器交互的代码中有一席之地, 而不是处理Mustache模板的代码…
+
diff --git a/sections/errorhandling/centralizedhandling.md b/sections/errorhandling/centralizedhandling.md
index 373ad6619..e5157d3e3 100644
--- a/sections/errorhandling/centralizedhandling.md
+++ b/sections/errorhandling/centralizedhandling.md
@@ -1,82 +1,82 @@
-# Handle errors centrally. Not within middlewares
-
-### One Paragraph Explainer
-
-Without one dedicated object for error handling, greater are the chances of important errors hiding under the radar due to improper handling. The error handler object is responsible for making the error visible, for example by writing to a well-formatted logger, sending events to some monitoring product like [Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/), or [Raygun](https://raygun.com/). Most web frameworks, like [Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers), provide an error handling middleware mechanism. A typical error handling flow might be: Some module throws an error -> API router catches the error -> it propagates the error to the middleware (e.g. Express, KOA) who is responsible for catching errors -> a centralized error handler is called -> the middleware is being told whether this error is an untrusted error (not operational) so it can restart the app gracefully. Note that it’s a common, yet wrong, practice to handle errors within Express middleware – doing so will not cover errors that are thrown in non-web interfaces.
-
-### Code Example – a typical error flow
-
-```javascript
-// DAL layer, we don't handle errors here
-DB.addDocument(newCustomer, (error, result) => {
- if (error)
- throw new Error("Great error explanation comes here", other useful parameters)
-});
-
-// API route code, we catch both sync and async errors and forward to the middleware
-try {
- customerService.addNew(req.body).then((result) => {
- res.status(200).json(result);
- }).catch((error) => {
- next(error)
- });
-}
-catch (error) {
- next(error);
-}
-
-// Error handling middleware, we delegate the handling to the centralized error handler
-app.use(async (err, req, res, next) => {
- const isOperationalError = await errorHandler.handleError(err);
- if (!isOperationalError)
- next(err);
-});
-
-```
-
-### Code example – handling errors within a dedicated object
-
-```javascript
-module.exports.handler = new errorHandler();
-
-function errorHandler(){
- this.handleError = async function (error) {
- await logger.logError(err);
- await sendMailToAdminIfCritical;
- await saveInOpsQueueIfCritical;
- await determineIfOperationalError;
- }
-}
-```
-
-### Code Example – Anti Pattern: handling errors within the middleware
-
-```javascript
-// middleware handling the error directly, who will handle Cron jobs and testing errors?
-app.use((err, req, res, next) => {
- logger.logError(err);
- if(err.severity == errors.high)
- mailer.sendMail(configuration.adminMail, "Critical error occured", err);
- if(!err.isOperational)
- next(err);
-});
-
-```
-
-### Blog Quote: "Sometimes lower levels can’t do anything useful except propagate the error to their caller"
-
- From the blog Joyent, ranked 1 for the keywords “Node.js error handling”
-
- > …You may end up handling the same error at several levels of the stack. This happens when lower levels can’t do anything useful except propagate the error to their caller, which propagates the error to its caller, and so on. Often, only the top-level caller knows what the appropriate response is, whether that’s to retry the operation, report an error to the user, or something else. But that doesn’t mean you should try to report all errors to a single top-level callback, because that callback itself can’t know in what context the error occurred…
-
-### Blog Quote: "Handling each err individually would result in tremendous duplication"
-
- From the blog JS Recipes ranked 17 for the keywords “Node.js error handling”
-
- > ……In Hackathon Starter api.js controller alone, there are over 79 occurrences of error objects. Handling each err individually would result in a tremendous amount of code duplication. The next best thing you can do is to delegate all error handling logic to an Express middleware…
-
-### Blog Quote: "HTTP errors have no place in your database code"
-
- From the blog Daily JS ranked 14 for the keywords “Node.js error handling”
-
- > ……You should set useful properties in error objects, but use such properties consistently. And, don’t cross the streams: HTTP errors have no place in your database code. Or for browser developers, Ajax errors have a place in the code that talks to the server, but not code that processes Mustache templates…
+# Handle errors centrally. Not within middlewares
+
+### One Paragraph Explainer
+
+Without one dedicated object for error handling, greater are the chances of important errors hiding under the radar due to improper handling. The error handler object is responsible for making the error visible, for example by writing to a well-formatted logger, sending events to some monitoring product like [Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/), or [Raygun](https://raygun.com/). Most web frameworks, like [Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers), provide an error handling middleware mechanism. A typical error handling flow might be: Some module throws an error -> API router catches the error -> it propagates the error to the middleware (e.g. Express, KOA) who is responsible for catching errors -> a centralized error handler is called -> the middleware is being told whether this error is an untrusted error (not operational) so it can restart the app gracefully. Note that it’s a common, yet wrong, practice to handle errors within Express middleware – doing so will not cover errors that are thrown in non-web interfaces.
+
+### Code Example – a typical error flow
+
+```javascript
+// DAL layer, we don't handle errors here
+DB.addDocument(newCustomer, (error, result) => {
+ if (error)
+ throw new Error("Great error explanation comes here", other useful parameters)
+});
+
+// API route code, we catch both sync and async errors and forward to the middleware
+try {
+ customerService.addNew(req.body).then((result) => {
+ res.status(200).json(result);
+ }).catch((error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+// Error handling middleware, we delegate the handling to the centralized error handler
+app.use(async (err, req, res, next) => {
+ const isOperationalError = await errorHandler.handleError(err);
+ if (!isOperationalError)
+ next(err);
+});
+
+```
+
+### Code example – handling errors within a dedicated object
+
+```javascript
+module.exports.handler = new errorHandler();
+
+function errorHandler(){
+ this.handleError = async function (error) {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical;
+ await saveInOpsQueueIfCritical;
+ await determineIfOperationalError;
+ }
+}
+```
+
+### Code Example – Anti Pattern: handling errors within the middleware
+
+```javascript
+// middleware handling the error directly, who will handle Cron jobs and testing errors?
+app.use((err, req, res, next) => {
+ logger.logError(err);
+ if(err.severity == errors.high)
+ mailer.sendMail(configuration.adminMail, "Critical error occured", err);
+ if(!err.isOperational)
+ next(err);
+});
+
+```
+
+### Blog Quote: "Sometimes lower levels can’t do anything useful except propagate the error to their caller"
+
+ From the blog Joyent, ranked 1 for the keywords “Node.js error handling”
+
+ > …You may end up handling the same error at several levels of the stack. This happens when lower levels can’t do anything useful except propagate the error to their caller, which propagates the error to its caller, and so on. Often, only the top-level caller knows what the appropriate response is, whether that’s to retry the operation, report an error to the user, or something else. But that doesn’t mean you should try to report all errors to a single top-level callback, because that callback itself can’t know in what context the error occurred…
+
+### Blog Quote: "Handling each err individually would result in tremendous duplication"
+
+ From the blog JS Recipes ranked 17 for the keywords “Node.js error handling”
+
+ > ……In Hackathon Starter api.js controller alone, there are over 79 occurrences of error objects. Handling each err individually would result in a tremendous amount of code duplication. The next best thing you can do is to delegate all error handling logic to an Express middleware…
+
+### Blog Quote: "HTTP errors have no place in your database code"
+
+ From the blog Daily JS ranked 14 for the keywords “Node.js error handling”
+
+ > ……You should set useful properties in error objects, but use such properties consistently. And, don’t cross the streams: HTTP errors have no place in your database code. Or for browser developers, Ajax errors have a place in the code that talks to the server, but not code that processes Mustache templates…
diff --git a/sections/errorhandling/documentingusingswagger.chinese.md b/sections/errorhandling/documentingusingswagger.chinese.md
index 57db0bcf5..e7f5addfa 100644
--- a/sections/errorhandling/documentingusingswagger.chinese.md
+++ b/sections/errorhandling/documentingusingswagger.chinese.md
@@ -1,16 +1,16 @@
-# 使用Swagger对API错误文档化
-
-
-### 一段解释
-
-REST API使用HTTP代码返回结果, API用户不仅绝对需要了解API schema, 而且还要注意潜在错误 – 调用方可能会捕获错误并巧妙地处理它。例如, 您的api文档可能提前指出, 当客户名称已经存在时, HTTP状态409将返回 (假设api注册新用户), 因此调用方可以相应地呈现给定情况下的最佳UX。Swagger是一个标准, 它定义了 API 文档的schema, 提供了一个生态系统的工具, 允许在线轻松创建文档, 请参阅下面的打印屏幕。
-
-### 博客引用: "您必须告诉您的调用者什么错误可能发生"
- 摘自博客 Joyent, 对于关键字 “Node.JS logging” , 排名第一
-
- > 我们已经讨论了如何处理错误, 但是在编写新函数时, 如何将错误传递给调用您的函数的代码?
-...如果你不知道会发生什么错误或者不知道他们的意思, 那么你的程序就不可能是正确的, 除非是偶然的。所以, 如果你正在写一个新的函数, 你必须告诉你的调用者什么错误可以发生, 它们的意思是什么…
-
-
- ### 有用的工具: Swagger 在线文档创建工具
+# 使用Swagger对API错误文档化
+
+
+### 一段解释
+
+REST API使用HTTP代码返回结果, API用户不仅绝对需要了解API schema, 而且还要注意潜在错误 – 调用方可能会捕获错误并巧妙地处理它。例如, 您的api文档可能提前指出, 当客户名称已经存在时, HTTP状态409将返回 (假设api注册新用户), 因此调用方可以相应地呈现给定情况下的最佳UX。Swagger是一个标准, 它定义了 API 文档的schema, 提供了一个生态系统的工具, 允许在线轻松创建文档, 请参阅下面的打印屏幕。
+
+### 博客引用: "您必须告诉您的调用者什么错误可能发生"
+ 摘自博客 Joyent, 对于关键字 “Node.JS logging” , 排名第一
+
+ > 我们已经讨论了如何处理错误, 但是在编写新函数时, 如何将错误传递给调用您的函数的代码?
+...如果你不知道会发生什么错误或者不知道他们的意思, 那么你的程序就不可能是正确的, 除非是偶然的。所以, 如果你正在写一个新的函数, 你必须告诉你的调用者什么错误可以发生, 它们的意思是什么…
+
+
+ ### 有用的工具: Swagger 在线文档创建工具
![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/swaggerDoc.png "API error handling")
\ No newline at end of file
diff --git a/sections/errorhandling/documentingusingswagger.md b/sections/errorhandling/documentingusingswagger.md
index e2f7a496c..d5da04aba 100644
--- a/sections/errorhandling/documentingusingswagger.md
+++ b/sections/errorhandling/documentingusingswagger.md
@@ -1,15 +1,15 @@
-# Document API errors using Swagger
-
-### One Paragraph Explainer
-
-REST APIs return results using HTTP status codes, it’s absolutely required for the API user to be aware not only about the API schema but also about potential errors – the caller may then catch an error and tactfully handle it. For example, your API documentation might state in advance that HTTP status 409 is returned when the customer name already exists (assuming the API register new users) so the caller can correspondingly render the best UX for the given situation. Swagger is a standard that defines the schema of API documentation offering an eco-system of tools that allow creating documentation easily online, see print screens below
-
-### Blog Quote: "You have to tell your callers what errors can happen"
-
-From the blog Joyent, ranked 1 for the keywords “Node.js logging”
-
- > We’ve talked about how to handle errors, but when you’re writing a new function, how do you deliver errors to the code that called your function? …If you don’t know what errors can happen or don’t know what they mean, then your program cannot be correct except by accident. So if you’re writing a new function, you have to tell your callers what errors can happen and what they mean…
-
-### Useful Tool: Swagger Online Documentation Creator
-
-![Swagger API Scheme](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/swaggerDoc.png "API error handling")
+# Document API errors using Swagger
+
+### One Paragraph Explainer
+
+REST APIs return results using HTTP status codes, it’s absolutely required for the API user to be aware not only about the API schema but also about potential errors – the caller may then catch an error and tactfully handle it. For example, your API documentation might state in advance that HTTP status 409 is returned when the customer name already exists (assuming the API register new users) so the caller can correspondingly render the best UX for the given situation. Swagger is a standard that defines the schema of API documentation offering an eco-system of tools that allow creating documentation easily online, see print screens below
+
+### Blog Quote: "You have to tell your callers what errors can happen"
+
+From the blog Joyent, ranked 1 for the keywords “Node.js logging”
+
+ > We’ve talked about how to handle errors, but when you’re writing a new function, how do you deliver errors to the code that called your function? …If you don’t know what errors can happen or don’t know what they mean, then your program cannot be correct except by accident. So if you’re writing a new function, you have to tell your callers what errors can happen and what they mean…
+
+### Useful Tool: Swagger Online Documentation Creator
+
+![Swagger API Scheme](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/swaggerDoc.png "API error handling")
diff --git a/sections/errorhandling/failfast.chinese.md b/sections/errorhandling/failfast.chinese.md
index 5055d1ad5..9ba76c841 100644
--- a/sections/errorhandling/failfast.chinese.md
+++ b/sections/errorhandling/failfast.chinese.md
@@ -1,50 +1,50 @@
-# 快速报错,使用专用库验证参数
-
-
-### 一段解释
-
-我们都知道如何检查参数和快速报错对于避免隐藏的错误很重要(见下面的反模式代码示例)。如果没有,请阅读显式编程和防御性编程。在现实中,由于对其编码是件恼人的事情(比如考虑验证分层的JSON对象,它包含像email和日期这样的字段),我们倾向于避免做这样的事情 – 像Joi这样的库和验证器轻而易举的处理这个乏味的任务。
-
-### 维基百科: 防御性编程
-
-防御性编程是一种改进软件和源代码的方法, 在以下方面: 一般质量 – 减少软件 bug 和问题的数量。使源代码可理解 – 源代码应该是可读的和可理解的, 以便在代码审核中得到批准。尽管会有意外输入或用户操作, 但使软件的行为具有可预知的方式。
-
-
-
-### 代码示例: 使用‘Joi’验证复杂的JSON输入
-
-```javascript
-var memberSchema = Joi.object().keys({
- password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
- birthyear: Joi.number().integer().min(1900).max(2013),
- email: Joi.string().email()
-});
-
-function addNewMember(newMember)
-{
- //assertions come first
- Joi.assert(newMember, memberSchema); //throws if validation fails
- //other logic here
-}
-
-```
-
-### 反模式: 没有验证会产生令人讨厌的错误
-
-```javascript
-//假如折扣为正,重定向用户去打印他的折扣优惠劵
-function redirectToPrintDiscount(httpResponse, member, discount)
-{
- if(discount != 0)
- httpResponse.redirect(`/discountPrintView/${member.id}`);
-}
-
-redirectToPrintDiscount(httpResponse, someMember);
-//忘记传递参数discount, 为什么用户被重定向到折扣页面?
-
-```
-
-### 博客引用: "您应该立即抛出这些错误"
- 摘自博客: Joyent
-
+# 快速报错,使用专用库验证参数
+
+
+### 一段解释
+
+我们都知道如何检查参数和快速报错对于避免隐藏的错误很重要(见下面的反模式代码示例)。如果没有,请阅读显式编程和防御性编程。在现实中,由于对其编码是件恼人的事情(比如考虑验证分层的JSON对象,它包含像email和日期这样的字段),我们倾向于避免做这样的事情 – 像Joi这样的库和验证器轻而易举的处理这个乏味的任务。
+
+### 维基百科: 防御性编程
+
+防御性编程是一种改进软件和源代码的方法, 在以下方面: 一般质量 – 减少软件 bug 和问题的数量。使源代码可理解 – 源代码应该是可读的和可理解的, 以便在代码审核中得到批准。尽管会有意外输入或用户操作, 但使软件的行为具有可预知的方式。
+
+
+
+### 代码示例: 使用‘Joi’验证复杂的JSON输入
+
+```javascript
+var memberSchema = Joi.object().keys({
+ password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
+ birthyear: Joi.number().integer().min(1900).max(2013),
+ email: Joi.string().email()
+});
+
+function addNewMember(newMember)
+{
+ //assertions come first
+ Joi.assert(newMember, memberSchema); //throws if validation fails
+ //other logic here
+}
+
+```
+
+### 反模式: 没有验证会产生令人讨厌的错误
+
+```javascript
+//假如折扣为正,重定向用户去打印他的折扣优惠劵
+function redirectToPrintDiscount(httpResponse, member, discount)
+{
+ if(discount != 0)
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+}
+
+redirectToPrintDiscount(httpResponse, someMember);
+//忘记传递参数discount, 为什么用户被重定向到折扣页面?
+
+```
+
+### 博客引用: "您应该立即抛出这些错误"
+ 摘自博客: Joyent
+
> 一个退化情况是有人调用一个异步函数但没有传递一个回调方法。你应该立即抛出这些错误, 因为程序有了错误, 最好的调试它的时机包括,获得至少一个stack trace, 和理想情况下,核心文件里错误的点。为此, 我们建议在函数开始时验证所有参数的类型。
\ No newline at end of file
diff --git a/sections/errorhandling/failfast.md b/sections/errorhandling/failfast.md
index 8d56ebe76..90ddbbb13 100644
--- a/sections/errorhandling/failfast.md
+++ b/sections/errorhandling/failfast.md
@@ -1,48 +1,48 @@
-# Fail fast, validate arguments using a dedicated library
-
-### One Paragraph Explainer
-
-We all know how checking arguments and failing fast is important to avoid hidden bugs (see anti-pattern code example below). If not, read about explicit programming and defensive programming. In reality, we tend to avoid it due to the annoyance of coding it (e.g. think of validating hierarchical JSON object with fields like email and dates) – libraries like Joi and Validator turn this tedious task into a breeze.
-
-### Wikipedia: Defensive Programming
-
-Defensive programming is an approach to improve software and source code, in terms of General quality – reducing the number of software bugs and problems. Making the source code comprehensible – the source code should be readable and understandable so it is approved in a code audit. Making the software behave in a predictable manner despite unexpected inputs or user actions.
-
-### Code example: validating complex JSON input using ‘Joi’
-
-```javascript
-var memberSchema = Joi.object().keys({
- password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
- birthyear: Joi.number().integer().min(1900).max(2013),
- email: Joi.string().email()
-});
-
-function addNewMember(newMember)
-{
- // assertions come first
- Joi.assert(newMember, memberSchema); //throws if validation fails
- // other logic here
-}
-
-```
-
-### Anti-pattern: no validation yields nasty bugs
-
-```javascript
-// if the discount is positive let's then redirect the user to pring his discount coupons
-function redirectToPrintDiscount(httpResponse, member, discount)
-{
- if(discount != 0)
- httpResponse.redirect(`/discountPrintView/${member.id}`);
-}
-
-redirectToPrintDiscount(httpResponse, someMember);
-// forgot to pass the parameter discount, why the heck was the user redirected to the discount screen?
-
-```
-
-### Blog Quote: "You should throw these errors immediately"
-
- From the blog: Joyent
-
- > A degenerate case is where someone calls an asynchronous function but doesn’t pass a callback. You should throw these errors immediately since the program is broken and the best chance of debugging it involves getting at least a stack trace and ideally a core file at the point of the error. To do this, we recommend validating the types of all arguments at the start of the function.
+# Fail fast, validate arguments using a dedicated library
+
+### One Paragraph Explainer
+
+We all know how checking arguments and failing fast is important to avoid hidden bugs (see anti-pattern code example below). If not, read about explicit programming and defensive programming. In reality, we tend to avoid it due to the annoyance of coding it (e.g. think of validating hierarchical JSON object with fields like email and dates) – libraries like Joi and Validator turn this tedious task into a breeze.
+
+### Wikipedia: Defensive Programming
+
+Defensive programming is an approach to improve software and source code, in terms of General quality – reducing the number of software bugs and problems. Making the source code comprehensible – the source code should be readable and understandable so it is approved in a code audit. Making the software behave in a predictable manner despite unexpected inputs or user actions.
+
+### Code example: validating complex JSON input using ‘Joi’
+
+```javascript
+var memberSchema = Joi.object().keys({
+ password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
+ birthyear: Joi.number().integer().min(1900).max(2013),
+ email: Joi.string().email()
+});
+
+function addNewMember(newMember)
+{
+ // assertions come first
+ Joi.assert(newMember, memberSchema); //throws if validation fails
+ // other logic here
+}
+
+```
+
+### Anti-pattern: no validation yields nasty bugs
+
+```javascript
+// if the discount is positive let's then redirect the user to pring his discount coupons
+function redirectToPrintDiscount(httpResponse, member, discount)
+{
+ if(discount != 0)
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+}
+
+redirectToPrintDiscount(httpResponse, someMember);
+// forgot to pass the parameter discount, why the heck was the user redirected to the discount screen?
+
+```
+
+### Blog Quote: "You should throw these errors immediately"
+
+ From the blog: Joyent
+
+ > A degenerate case is where someone calls an asynchronous function but doesn’t pass a callback. You should throw these errors immediately since the program is broken and the best chance of debugging it involves getting at least a stack trace and ideally a core file at the point of the error. To do this, we recommend validating the types of all arguments at the start of the function.
diff --git a/sections/errorhandling/monitoring.chinese.md b/sections/errorhandling/monitoring.chinese.md
index 724dc913e..479a86b76 100644
--- a/sections/errorhandling/monitoring.chinese.md
+++ b/sections/errorhandling/monitoring.chinese.md
@@ -1,18 +1,18 @@
-# 监控
-
-
-### 一段解释
-
-> 在最基本的层面上,监控意味着您可以很*容易地识别出在生产环境中发生了什么不好的事情,例如,通过电子邮件或Slack通知。挑战在于选择合适的工具集来满足您的需求而不会破坏您的防护。我建议,从确定核心的指标集开始,这些指标必须被监控以确保一个健康的状态 – CPU,服务器的RAM,node进程RAM(小于1.4GB),在最后一分钟的错误量,进程重新启动的数量,平均响应时间。然后浏览一些你可能喜欢的高级功能并添加到你的愿望清单中。一些豪华的监控功能的例子:数据库分析,跨服务的测量(即测量业务交易),前端整合,暴露原始数据给自定义的BI clients,Slack通知及其他。
-
-实现高级功能需要冗长的设置或购买商业产品如datadog,NewRelic和相似产品。不幸的是,即使是基本的实现也不像在公园散步那么简单,因为一些度量指标是硬件相关的(CPU),而其他的则在node进程内(内部错误),因此所有直接了当的工具都需要一些额外的设置。例如,云供应商监控解决方案(如AWS CloudWatch,谷歌Stackdriver)将立即告诉你关于硬件度量,但对内部应用程序的行为却无可奉告。在另一端,基于日志的解决方案如Elasticsearch默认情况下缺少hardware view。解决方案是用缺少的指标来增加您的选择,例如,一个流行的选择是将应用程序日志发送到Elastic stack,并配置一些额外的代理(如Beat)来共享与硬件相关的信息以获得完整的画面。
-
-### 博客引用: "我们对于promise有一个问题"
- 摘自博客 pouchdb.com, 对于关键字“node promises”,排名11
-
- > … 我们建议您为所有服务监视这些信号:
-错误率:因为错误是面向用户的,并且会立即影响您的客户。
-响应时间:因为延迟直接影响您的客户和业务。
-吞吐量:流量有助于您了解错误率增加和延迟的上下文。
-饱和度:它告诉您的服务负载多少。如果CPU使用率是90%,你的系统能处理更多的流量吗?
-…
+# 监控
+
+
+### 一段解释
+
+> 在最基本的层面上,监控意味着您可以很*容易地识别出在生产环境中发生了什么不好的事情,例如,通过电子邮件或Slack通知。挑战在于选择合适的工具集来满足您的需求而不会破坏您的防护。我建议,从确定核心的指标集开始,这些指标必须被监控以确保一个健康的状态 – CPU,服务器的RAM,node进程RAM(小于1.4GB),在最后一分钟的错误量,进程重新启动的数量,平均响应时间。然后浏览一些你可能喜欢的高级功能并添加到你的愿望清单中。一些豪华的监控功能的例子:数据库分析,跨服务的测量(即测量业务交易),前端整合,暴露原始数据给自定义的BI clients,Slack通知及其他。
+
+实现高级功能需要冗长的设置或购买商业产品如datadog,NewRelic和相似产品。不幸的是,即使是基本的实现也不像在公园散步那么简单,因为一些度量指标是硬件相关的(CPU),而其他的则在node进程内(内部错误),因此所有直接了当的工具都需要一些额外的设置。例如,云供应商监控解决方案(如AWS CloudWatch,谷歌Stackdriver)将立即告诉你关于硬件度量,但对内部应用程序的行为却无可奉告。在另一端,基于日志的解决方案如Elasticsearch默认情况下缺少hardware view。解决方案是用缺少的指标来增加您的选择,例如,一个流行的选择是将应用程序日志发送到Elastic stack,并配置一些额外的代理(如Beat)来共享与硬件相关的信息以获得完整的画面。
+
+### 博客引用: "我们对于promise有一个问题"
+ 摘自博客 pouchdb.com, 对于关键字“node promises”,排名11
+
+ > … 我们建议您为所有服务监视这些信号:
+错误率:因为错误是面向用户的,并且会立即影响您的客户。
+响应时间:因为延迟直接影响您的客户和业务。
+吞吐量:流量有助于您了解错误率增加和延迟的上下文。
+饱和度:它告诉您的服务负载多少。如果CPU使用率是90%,你的系统能处理更多的流量吗?
+…
diff --git a/sections/errorhandling/monitoring.md b/sections/errorhandling/monitoring.md
index 81b71721d..57213a831 100644
--- a/sections/errorhandling/monitoring.md
+++ b/sections/errorhandling/monitoring.md
@@ -1,17 +1,17 @@
-# Monitoring
-
-### One Paragraph Explainer
-
-> At the very basic level, monitoring means you can *easily identify when bad things happen at production. For example, by getting notified by email or Slack. The challenge is to choose the right set of tools that will satisfy your requirements without breaking your bank. May I suggest, start with defining the core set of metrics that must be watched to ensure a healthy state – CPU, server RAM, Node process RAM (less than 1.4GB), the number of errors in the last minute, number of process restarts, average response time. Then go over some advanced features you might fancy and add to your wish list. Some examples of a luxury monitoring feature: DB profiling, cross-service measuring (i.e. measure business transaction), front-end integration, expose raw data to custom BI clients, Slack notifications and many others.
-
-Achieving the advanced features demands lengthy setup or buying a commercial product such as Datadog, newrelic and alike. Unfortunately, achieving even the basics is not a walk in the park as some metrics are hardware-related (CPU) and others live within the node process (internal errors) thus all the straightforward tools require some additional setup. For example, cloud vendor monitoring solutions (e.g. AWS CloudWatch, Google StackDriver) will tell you immediately about the hardware metric but nothing about the internal app behavior. On the other end, Log-based solutions such as ElasticSearch lack by default the hardware view. The solution is to augment your choice with missing metrics, for example, a popular choice is sending application logs to Elastic stack and configure some additional agent (e.g. Beat) to share hardware-related information to get the full picture.
-
-### Blog Quote: "We have a problem with promises"
-
- From the blog, pouchdb.com ranked 11 for the keywords “Node Promises”
-
- > … We recommend you to watch these signals for all of your services: Error Rate: Because errors are user facing and immediately affect your customers.
-Response time: Because the latency directly affects your customers and business.
-Throughput: The traffic helps you to understand the context of increased error rates and the latency too.
-Saturation: It tells how “full” your service is. If the CPU usage is 90%, can your system handle more traffic?
-…
+# Monitoring
+
+### One Paragraph Explainer
+
+> At the very basic level, monitoring means you can *easily identify when bad things happen at production. For example, by getting notified by email or Slack. The challenge is to choose the right set of tools that will satisfy your requirements without breaking your bank. May I suggest, start with defining the core set of metrics that must be watched to ensure a healthy state – CPU, server RAM, Node process RAM (less than 1.4GB), the number of errors in the last minute, number of process restarts, average response time. Then go over some advanced features you might fancy and add to your wish list. Some examples of a luxury monitoring feature: DB profiling, cross-service measuring (i.e. measure business transaction), front-end integration, expose raw data to custom BI clients, Slack notifications and many others.
+
+Achieving the advanced features demands lengthy setup or buying a commercial product such as Datadog, newrelic and alike. Unfortunately, achieving even the basics is not a walk in the park as some metrics are hardware-related (CPU) and others live within the node process (internal errors) thus all the straightforward tools require some additional setup. For example, cloud vendor monitoring solutions (e.g. AWS CloudWatch, Google StackDriver) will tell you immediately about the hardware metric but nothing about the internal app behavior. On the other end, Log-based solutions such as ElasticSearch lack by default the hardware view. The solution is to augment your choice with missing metrics, for example, a popular choice is sending application logs to Elastic stack and configure some additional agent (e.g. Beat) to share hardware-related information to get the full picture.
+
+### Blog Quote: "We have a problem with promises"
+
+ From the blog, pouchdb.com ranked 11 for the keywords “Node Promises”
+
+ > … We recommend you to watch these signals for all of your services: Error Rate: Because errors are user facing and immediately affect your customers.
+Response time: Because the latency directly affects your customers and business.
+Throughput: The traffic helps you to understand the context of increased error rates and the latency too.
+Saturation: It tells how “full” your service is. If the CPU usage is 90%, can your system handle more traffic?
+…
diff --git a/sections/errorhandling/operationalvsprogrammererror.chinese.md b/sections/errorhandling/operationalvsprogrammererror.chinese.md
index a68f94151..c8c070e49 100644
--- a/sections/errorhandling/operationalvsprogrammererror.chinese.md
+++ b/sections/errorhandling/operationalvsprogrammererror.chinese.md
@@ -1,51 +1,51 @@
-# 区分操作型错误和程序型错误
-
-### 一段解释
-
-区分以下两种错误类型将最大限度地减少应用程序停机时间并帮助避免出现荒唐的错误: 操作型错误指的是您了解发生了什么情况及其影响的情形 – 例如, 由于连接问题而导致对某些 HTTP 服务的查询失败问题。另一方面, 程序型错误指的是您不知道原因, 有时是错误不知道来自何处的情况 – 可能是一些代码试图读取未定义的值或 DB 连接池内存泄漏。操作型错误相对容易处理 – 通常记录错误就足够了。当程序型错误出现,事情变得难以应付, 应用程序可能处于不一致状态, 你可以做的,没有什么比优雅的重新启动更好了。
-
-
-
-### 代码示例 – 将错误标记为可操作 (受信任)
-
-```javascript
-//将错误标记为可操作
-var myError = new Error("How can I add new product when no value provided?");
-myError.isOperational = true;
-
-//或者, 如果您使用的是一些集中式错误工厂 (请参见项目符号中的示例"仅使用内置错误对象")
-function appError(commonType, description, isOperational) {
- Error.call(this);
- Error.captureStackTrace(this);
- this.commonType = commonType;
- this.description = description;
- this.isOperational = isOperational;
-};
-
-throw new appError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
-
-```
-
-### 博客引用: "程序型错误是程序中的 bug"
- 摘自博客 Joyent, 对于关键字“Node.JS error handling”排名第一
-
- > …从程序型错误中恢复的最好方法是立即崩溃。您应该使用restarter运行程序, 以便在发生崩溃时自动重新启动程序。在一个使用了restarter的地方, 在面对一个瞬态程序型错误, 崩溃是最快的方式来恢复可靠的服务…
-
- ### 博客引用: "不伴随着创建一些未定义的脆性状态,没有安全的方式可以离开"
- 摘自Node.JS官方文档
-
- > …在 JavaScript 中, throw的工作性质, 几乎没有任何方法可以安全地"在你离开的地方重新捡起",没有泄漏引用, 或者创建一些其他形式的未定义的脆性状态,。对引发的错误进行响应的最安全方法是关闭进程。当然, 在普通的 web 服务器中, 您可能会打开许多连接, 并且由于其他人触发了错误而突然关闭这些连接是不合理的。更好的方法是向触发错误的请求发送错误响应, 同时让其他人在正常时间内完成, 并停止侦听该工作人员中的新请求。
-
-
- ### 博客引用: "否则,您置您应用的状态于风险之中"
- 摘自博客 debugable.com, 对于关键字“Node.JS uncaught exception”排名第3
-
- > …所以, 除非你真的知道你在做什么, 否则你应该在收到一个"uncaughtException"异常事件之后, 对你的服务进行一次优雅的重新启动。否则, 您应用的状态, 或和第三方库的状态变得不一致, 都被置于风险之中,导致各种荒唐的错误…
-
- ### 博客引用: "对于错误处理,有三种学院派想法"
- 摘自博客: JS Recipes
-
- > …对于错误处理,主要有三种学院派想法:
-1. 让应用崩溃并重启.
-2. 处理所有可能的错误,从不崩溃.
-3. 两者之间的折中方案
+# 区分操作型错误和程序型错误
+
+### 一段解释
+
+区分以下两种错误类型将最大限度地减少应用程序停机时间并帮助避免出现荒唐的错误: 操作型错误指的是您了解发生了什么情况及其影响的情形 – 例如, 由于连接问题而导致对某些 HTTP 服务的查询失败问题。另一方面, 程序型错误指的是您不知道原因, 有时是错误不知道来自何处的情况 – 可能是一些代码试图读取未定义的值或 DB 连接池内存泄漏。操作型错误相对容易处理 – 通常记录错误就足够了。当程序型错误出现,事情变得难以应付, 应用程序可能处于不一致状态, 你可以做的,没有什么比优雅的重新启动更好了。
+
+
+
+### 代码示例 – 将错误标记为可操作 (受信任)
+
+```javascript
+//将错误标记为可操作
+var myError = new Error("How can I add new product when no value provided?");
+myError.isOperational = true;
+
+//或者, 如果您使用的是一些集中式错误工厂 (请参见项目符号中的示例"仅使用内置错误对象")
+function appError(commonType, description, isOperational) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.commonType = commonType;
+ this.description = description;
+ this.isOperational = isOperational;
+};
+
+throw new appError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
+
+```
+
+### 博客引用: "程序型错误是程序中的 bug"
+ 摘自博客 Joyent, 对于关键字“Node.JS error handling”排名第一
+
+ > …从程序型错误中恢复的最好方法是立即崩溃。您应该使用restarter运行程序, 以便在发生崩溃时自动重新启动程序。在一个使用了restarter的地方, 在面对一个瞬态程序型错误, 崩溃是最快的方式来恢复可靠的服务…
+
+ ### 博客引用: "不伴随着创建一些未定义的脆性状态,没有安全的方式可以离开"
+ 摘自Node.JS官方文档
+
+ > …在 JavaScript 中, throw的工作性质, 几乎没有任何方法可以安全地"在你离开的地方重新捡起",没有泄漏引用, 或者创建一些其他形式的未定义的脆性状态,。对引发的错误进行响应的最安全方法是关闭进程。当然, 在普通的 web 服务器中, 您可能会打开许多连接, 并且由于其他人触发了错误而突然关闭这些连接是不合理的。更好的方法是向触发错误的请求发送错误响应, 同时让其他人在正常时间内完成, 并停止侦听该工作人员中的新请求。
+
+
+ ### 博客引用: "否则,您置您应用的状态于风险之中"
+ 摘自博客 debugable.com, 对于关键字“Node.JS uncaught exception”排名第3
+
+ > …所以, 除非你真的知道你在做什么, 否则你应该在收到一个"uncaughtException"异常事件之后, 对你的服务进行一次优雅的重新启动。否则, 您应用的状态, 或和第三方库的状态变得不一致, 都被置于风险之中,导致各种荒唐的错误…
+
+ ### 博客引用: "对于错误处理,有三种学院派想法"
+ 摘自博客: JS Recipes
+
+ > …对于错误处理,主要有三种学院派想法:
+1. 让应用崩溃并重启.
+2. 处理所有可能的错误,从不崩溃.
+3. 两者之间的折中方案
diff --git a/sections/errorhandling/operationalvsprogrammererror.md b/sections/errorhandling/operationalvsprogrammererror.md
index d0750e7e9..ebcc6d640 100644
--- a/sections/errorhandling/operationalvsprogrammererror.md
+++ b/sections/errorhandling/operationalvsprogrammererror.md
@@ -1,52 +1,52 @@
-# Distinguish operational vs programmer errors
-
-### One Paragraph Explainer
-
-Distinguishing the following two error types will minimize your app downtime and helps avoid crazy bugs: Operational errors refer to situations where you understand what happened and the impact of it – for example, a query to some HTTP service failed due to connection problem. On the other hand, programmer errors refer to cases where you have no idea why and sometimes where an error came from – it might be some code that tried to read an undefined value or DB connection pool that leaks memory. Operational errors are relatively easy to handle – usually logging the error is enough. Things become hairy when a programmer error pops up, the application might be in an inconsistent state and there’s nothing better you can do than to restart gracefully
-
-### Code Example – marking an error as operational (trusted)
-
-```javascript
-// marking an error object as operational
-var myError = new Error("How can I add new product when no value provided?");
-myError.isOperational = true;
-
-// or if you're using some centralized error factory (see other examples at the bullet "Use only the built-in Error object")
-function appError(commonType, description, isOperational) {
- Error.call(this);
- Error.captureStackTrace(this);
- this.commonType = commonType;
- this.description = description;
- this.isOperational = isOperational;
-};
-
-throw new appError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
-
-```
-
-### Blog Quote: "Programmer errors are bugs in the program"
-
-From the blog, Joyent ranked 1 for the keywords “Node.js error handling”
-
- > …The best way to recover from programmer errors is to crash immediately. You should run your programs using a restarter that will automatically restart the program in the event of a crash. With a restarter in place, crashing is the fastest way to restore reliable service in the face of a transient programmer error…
-
-### Blog Quote: "No safe way to leave without creating some undefined brittle state"
-
-From Node.js official documentation
-
- > …By the very nature of how throw works in JavaScript, there is almost never any way to safely “pick up where you left off”, without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error while letting the others finish in their normal time, and stop listening for new requests in that worker.
-
-### Blog Quote: "Otherwise you risk the state of your application"
-
-From the blog, debugable.com ranked 3 for the keywords “Node.js uncaught exception”
-
- > …So, unless you really know what you are doing, you should perform a graceful restart of your service after receiving an “uncaughtException” exception event. Otherwise, you risk the state of your application, or that of 3rd party libraries to become inconsistent, leading to all kinds of crazy bugs…
-
-### Blog Quote: "Blog Quote: There are three schools of thoughts on error handling"
-
-From the blog: JS Recipes
-
-> …There are primarily three schools of thoughts on error handling:
-1. Let the application crash and restart it.
-2. Handle all possible errors and never crash.
-3. A balanced approach between the two
+# Distinguish operational vs programmer errors
+
+### One Paragraph Explainer
+
+Distinguishing the following two error types will minimize your app downtime and helps avoid crazy bugs: Operational errors refer to situations where you understand what happened and the impact of it – for example, a query to some HTTP service failed due to connection problem. On the other hand, programmer errors refer to cases where you have no idea why and sometimes where an error came from – it might be some code that tried to read an undefined value or DB connection pool that leaks memory. Operational errors are relatively easy to handle – usually logging the error is enough. Things become hairy when a programmer error pops up, the application might be in an inconsistent state and there’s nothing better you can do than to restart gracefully
+
+### Code Example – marking an error as operational (trusted)
+
+```javascript
+// marking an error object as operational
+var myError = new Error("How can I add new product when no value provided?");
+myError.isOperational = true;
+
+// or if you're using some centralized error factory (see other examples at the bullet "Use only the built-in Error object")
+function appError(commonType, description, isOperational) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.commonType = commonType;
+ this.description = description;
+ this.isOperational = isOperational;
+};
+
+throw new appError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
+
+```
+
+### Blog Quote: "Programmer errors are bugs in the program"
+
+From the blog, Joyent ranked 1 for the keywords “Node.js error handling”
+
+ > …The best way to recover from programmer errors is to crash immediately. You should run your programs using a restarter that will automatically restart the program in the event of a crash. With a restarter in place, crashing is the fastest way to restore reliable service in the face of a transient programmer error…
+
+### Blog Quote: "No safe way to leave without creating some undefined brittle state"
+
+From Node.js official documentation
+
+ > …By the very nature of how throw works in JavaScript, there is almost never any way to safely “pick up where you left off”, without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error while letting the others finish in their normal time, and stop listening for new requests in that worker.
+
+### Blog Quote: "Otherwise you risk the state of your application"
+
+From the blog, debugable.com ranked 3 for the keywords “Node.js uncaught exception”
+
+ > …So, unless you really know what you are doing, you should perform a graceful restart of your service after receiving an “uncaughtException” exception event. Otherwise, you risk the state of your application, or that of 3rd party libraries to become inconsistent, leading to all kinds of crazy bugs…
+
+### Blog Quote: "Blog Quote: There are three schools of thoughts on error handling"
+
+From the blog: JS Recipes
+
+> …There are primarily three schools of thoughts on error handling:
+1. Let the application crash and restart it.
+2. Handle all possible errors and never crash.
+3. A balanced approach between the two
diff --git a/sections/errorhandling/shuttingtheprocess.chinese.md b/sections/errorhandling/shuttingtheprocess.chinese.md
index 5de0faaba..b7f6d04b7 100644
--- a/sections/errorhandling/shuttingtheprocess.chinese.md
+++ b/sections/errorhandling/shuttingtheprocess.chinese.md
@@ -1,54 +1,54 @@
-# 特殊情况产生时,优雅地退出服务
-
-
-### 一段解释
-
-在您的代码的某个地方,当一个错误抛出的时候,错误处理对象负责决定如何进行时 – 如果错误是可信的(即操作型错误,在最佳实践#3了解进一步的解释),写入日志文件可能是足够的。如果错误不熟悉,事情就变得棘手了 – 这意味着某些组件可能处于故障状态,所有将来的请求都可能失败。例如,假设一个单例(singleton)的,有状态的令牌发行者服务抛出异常并失去它的状态 — 从现在起,它可能会出现意外行为并导致所有请求失败。在这种情况下,杀进程,使用“重启”的工具(像Forever,PM2,等等)重新开始。
-
-
-
-### 代码实例: 决定是否退出
-
-```javascript
-//收到未捕获的异常时,决定是否要崩溃
-//如果开发人员标记已知的操作型错误使用:error.isOperational=true, 查看最佳实践 #3
-process.on('uncaughtException', function(error) {
- errorManagement.handler.handleError(error);
- if(!errorManagement.handler.isTrustedError(error))
- process.exit(1)
-});
-
-
-//封装错误处理相关逻辑在集中的错误处理中
-function errorHandler(){
- this.handleError = function (error) {
- return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
- }
-
- this.isTrustedError = function(error)
- {
- return error.isOperational;
- }
-
-```
-
-
-### 博客引用: "最好的方式是立即崩溃"
-摘自 博客:Joyent
-
- > …从程序型错误中恢复过来的最好方法是立即崩溃。你应该使用一个重启助手来运行您的程序,它会在崩溃的情况下自动启动程序。当使用重启助手,崩溃是面对临时性的程序型错误时,恢复可靠的服务的最快的方法…
-
-
-### 博客引用: "错误处理有三种流派"
-摘自 博客:JS Recipes
-
- > …错误处理主要有三种流派:
-1. 让应用崩溃,并重启。
-2. 处理所有的错误,从不崩溃。
-3. 介于两者之间。
-
-
-### 博客引用: "不伴随着创建一些易碎的状态,是没有保险的方式退出"
-摘自 Node.JS 官方文档
-
+# 特殊情况产生时,优雅地退出服务
+
+
+### 一段解释
+
+在您的代码的某个地方,当一个错误抛出的时候,错误处理对象负责决定如何进行时 – 如果错误是可信的(即操作型错误,在最佳实践#3了解进一步的解释),写入日志文件可能是足够的。如果错误不熟悉,事情就变得棘手了 – 这意味着某些组件可能处于故障状态,所有将来的请求都可能失败。例如,假设一个单例(singleton)的,有状态的令牌发行者服务抛出异常并失去它的状态 — 从现在起,它可能会出现意外行为并导致所有请求失败。在这种情况下,杀进程,使用“重启”的工具(像Forever,PM2,等等)重新开始。
+
+
+
+### 代码实例: 决定是否退出
+
+```javascript
+//收到未捕获的异常时,决定是否要崩溃
+//如果开发人员标记已知的操作型错误使用:error.isOperational=true, 查看最佳实践 #3
+process.on('uncaughtException', function(error) {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+
+//封装错误处理相关逻辑在集中的错误处理中
+function errorHandler(){
+ this.handleError = function (error) {
+ return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
+ }
+
+ this.isTrustedError = function(error)
+ {
+ return error.isOperational;
+ }
+
+```
+
+
+### 博客引用: "最好的方式是立即崩溃"
+摘自 博客:Joyent
+
+ > …从程序型错误中恢复过来的最好方法是立即崩溃。你应该使用一个重启助手来运行您的程序,它会在崩溃的情况下自动启动程序。当使用重启助手,崩溃是面对临时性的程序型错误时,恢复可靠的服务的最快的方法…
+
+
+### 博客引用: "错误处理有三种流派"
+摘自 博客:JS Recipes
+
+ > …错误处理主要有三种流派:
+1. 让应用崩溃,并重启。
+2. 处理所有的错误,从不崩溃。
+3. 介于两者之间。
+
+
+### 博客引用: "不伴随着创建一些易碎的状态,是没有保险的方式退出"
+摘自 Node.JS 官方文档
+
> …就throw工作在JavaScript的本质而言,几乎没有任何方法可以安全地“在您丢下的地方捡起”,而不会泄漏引用,或者创建其他类型的未定义的易碎性状态。对抛出的错误作出响应的最安全的方法是关闭进程。当然,在一个普通的Web服务器中,可能有很多连接打开了,因为其他人触发了一个错误,所以突然关闭这些连接是不合理的。更好的方法是将错误响应发送给触发错误的请求,同时让其他人在正常时间内完成,并停止侦听该工作者的新请求。
\ No newline at end of file
diff --git a/sections/errorhandling/shuttingtheprocess.md b/sections/errorhandling/shuttingtheprocess.md
index 1065d3cf3..03cd9b12b 100644
--- a/sections/errorhandling/shuttingtheprocess.md
+++ b/sections/errorhandling/shuttingtheprocess.md
@@ -1,51 +1,51 @@
-# Exit the process gracefully when a stranger comes to town
-
-### One Paragraph Explainer
-
-Somewhere within your code, an error handler object is responsible for deciding how to proceed when an error is thrown – if the error is trusted (i.e. operational error, see further explanation within best practice #3) then writing to log file might be enough. Things get hairy if the error is not familiar – this means that some component might be in a faulty state and all future requests are subject to failure. For example, assuming a singleton, stateful token issuer service that threw an exception and lost its state – from now it might behave unexpectedly and cause all requests to fail. Under this scenario, kill the process and use a ‘Restarter tool’ (like Forever, PM2, etc) to start over with a clean slate.
-
-### Code example: deciding whether to crash
-
-```javascript
-// Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
-process.on('uncaughtException', function(error) {
- errorManagement.handler.handleError(error);
- if(!errorManagement.handler.isTrustedError(error))
- process.exit(1)
-});
-
-// centralized error handler encapsulates error-handling related logic
-function errorHandler() {
- this.handleError = function (error) {
- return logger.logError(err)
- .then(sendMailToAdminIfCritical)
- .then(saveInOpsQueueIfCritical)
- .then(determineIfOperationalError);
- }
-
- this.isTrustedError = function (error) {
- return error.isOperational;
- }
-}
-```
-
-### Blog Quote: "The best way is to crash"
-
-From the blog Joyent
-
-> …The best way to recover from programmer errors is to crash immediately. You should run your programs using a restarter that will automatically restart the program in the event of a crash. With a restarter in place, crashing is the fastest way to restore reliable service in the face of a transient programmer error…
-
-### Blog Quote: "There are three schools of thoughts on error handling"
-
-From the blog: JS Recipes
-
-> …There are primarily three schools of thoughts on error handling:
-1. Let the application crash and restart it.
-2. Handle all possible errors and never crash.
-3. A balanced approach between the two
-
-### Blog Quote: "No safe way to leave without creating some undefined brittle state"
-
-From Node.js official documentation
-
-> …By the very nature of how throw works in JavaScript, there is almost never any way to safely “pick up where you left off”, without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error while letting the others finish in their normal time, and stop listening for new requests in that worker.
+# Exit the process gracefully when a stranger comes to town
+
+### One Paragraph Explainer
+
+Somewhere within your code, an error handler object is responsible for deciding how to proceed when an error is thrown – if the error is trusted (i.e. operational error, see further explanation within best practice #3) then writing to log file might be enough. Things get hairy if the error is not familiar – this means that some component might be in a faulty state and all future requests are subject to failure. For example, assuming a singleton, stateful token issuer service that threw an exception and lost its state – from now it might behave unexpectedly and cause all requests to fail. Under this scenario, kill the process and use a ‘Restarter tool’ (like Forever, PM2, etc) to start over with a clean slate.
+
+### Code example: deciding whether to crash
+
+```javascript
+// Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
+process.on('uncaughtException', function(error) {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+// centralized error handler encapsulates error-handling related logic
+function errorHandler() {
+ this.handleError = function (error) {
+ return logger.logError(err)
+ .then(sendMailToAdminIfCritical)
+ .then(saveInOpsQueueIfCritical)
+ .then(determineIfOperationalError);
+ }
+
+ this.isTrustedError = function (error) {
+ return error.isOperational;
+ }
+}
+```
+
+### Blog Quote: "The best way is to crash"
+
+From the blog Joyent
+
+> …The best way to recover from programmer errors is to crash immediately. You should run your programs using a restarter that will automatically restart the program in the event of a crash. With a restarter in place, crashing is the fastest way to restore reliable service in the face of a transient programmer error…
+
+### Blog Quote: "There are three schools of thoughts on error handling"
+
+From the blog: JS Recipes
+
+> …There are primarily three schools of thoughts on error handling:
+1. Let the application crash and restart it.
+2. Handle all possible errors and never crash.
+3. A balanced approach between the two
+
+### Blog Quote: "No safe way to leave without creating some undefined brittle state"
+
+From Node.js official documentation
+
+> …By the very nature of how throw works in JavaScript, there is almost never any way to safely “pick up where you left off”, without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error while letting the others finish in their normal time, and stop listening for new requests in that worker.
diff --git a/sections/errorhandling/testingerrorflows.chinese.md b/sections/errorhandling/testingerrorflows.chinese.md
index eadd073e3..aba39f70d 100644
--- a/sections/errorhandling/testingerrorflows.chinese.md
+++ b/sections/errorhandling/testingerrorflows.chinese.md
@@ -1,37 +1,37 @@
-# 使用您喜欢的测试框架测试错误流
-
-
-### 一段解释
-
-测试‘正确’路径并不比测试失败更好。良好的测试代码覆盖率要求测试异常路径。否则,异常确实被处理正确是不可信的。每个单元测试框架,如[Mocha](https://mochajs.org/) & [Chai](http://chaijs.com/),都支持异常测试(请看下面的代码示例)。如果您觉得测试每个内部函数和异常都很乏味,那么您可以只测试REST API HTTP错误。
-
-
-
-### 代码示例: 使用 Mocha & Chai 确保正确的异常被抛出
-
-```javascript
-describe("Facebook chat", () => {
- it("Notifies on new chat message", () => {
- var chatService = new chatService();
- chatService.participants = getDisconnectedParticipants();
- expect(chatService.sendMessage.bind({message: "Hi"})).to.throw(ConnectionError);
- });
-});
-
-```
-
-### 代码示例: 确保 API 返回正确的 HTTP 错误码
-
-```javascript
-it("Creates new Facebook group", function (done) {
- var invalidGroupInfo = {};
- httpRequest({method: 'POST', uri: "facebook.com/api/groups", resolveWithFullResponse: true, body: invalidGroupInfo, json: true
- }).then((response) => {
- //oh no if we reached here than no exception was thrown
- }).catch(function (response) {
- expect(400).to.equal(response.statusCode);
- done();
- });
- });
-
+# 使用您喜欢的测试框架测试错误流
+
+
+### 一段解释
+
+测试‘正确’路径并不比测试失败更好。良好的测试代码覆盖率要求测试异常路径。否则,异常确实被处理正确是不可信的。每个单元测试框架,如[Mocha](https://mochajs.org/) & [Chai](http://chaijs.com/),都支持异常测试(请看下面的代码示例)。如果您觉得测试每个内部函数和异常都很乏味,那么您可以只测试REST API HTTP错误。
+
+
+
+### 代码示例: 使用 Mocha & Chai 确保正确的异常被抛出
+
+```javascript
+describe("Facebook chat", () => {
+ it("Notifies on new chat message", () => {
+ var chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({message: "Hi"})).to.throw(ConnectionError);
+ });
+});
+
+```
+
+### 代码示例: 确保 API 返回正确的 HTTP 错误码
+
+```javascript
+it("Creates new Facebook group", function (done) {
+ var invalidGroupInfo = {};
+ httpRequest({method: 'POST', uri: "facebook.com/api/groups", resolveWithFullResponse: true, body: invalidGroupInfo, json: true
+ }).then((response) => {
+ //oh no if we reached here than no exception was thrown
+ }).catch(function (response) {
+ expect(400).to.equal(response.statusCode);
+ done();
+ });
+ });
+
```
\ No newline at end of file
diff --git a/sections/errorhandling/testingerrorflows.md b/sections/errorhandling/testingerrorflows.md
index 3e2d3f887..86ac61e7d 100644
--- a/sections/errorhandling/testingerrorflows.md
+++ b/sections/errorhandling/testingerrorflows.md
@@ -1,38 +1,38 @@
-# Test error flows using your favorite test framework
-
-### One Paragraph Explainer
-
-Testing ‘happy’ paths is no better than testing failures. Good testing code coverage demands to test exceptional paths. Otherwise, there is no trust that exceptions are indeed handled correctly. Every unit testing framework, like [Mocha](https://mochajs.org/) & [Chai](http://chaijs.com/), supports exception testing (code examples below). If you find it tedious to test every inner function and exception you may settle with testing only REST API HTTP errors.
-
-### Code example: ensuring the right exception is thrown using Mocha & Chai
-
-```javascript
-describe("Facebook chat", () => {
- it("Notifies on new chat message", () => {
- var chatService = new chatService();
- chatService.participants = getDisconnectedParticipants();
- expect(chatService.sendMessage.bind({ message: "Hi" })).to.throw(ConnectionError);
- });
-});
-
-```
-
-### Code example: ensuring API returns the right HTTP error code
-
-```javascript
-it("Creates new Facebook group", function (done) {
- var invalidGroupInfo = {};
- httpRequest({
- method: 'POST',
- uri: "facebook.com/api/groups",
- resolveWithFullResponse: true,
- body: invalidGroupInfo,
- json: true
- }).then((response) => {
- // if we were to execute the code in this block, no error was thrown in the operation above
- }).catch(function (response) {
- expect(400).to.equal(response.statusCode);
- done();
- });
-});
-```
+# Test error flows using your favorite test framework
+
+### One Paragraph Explainer
+
+Testing ‘happy’ paths is no better than testing failures. Good testing code coverage demands to test exceptional paths. Otherwise, there is no trust that exceptions are indeed handled correctly. Every unit testing framework, like [Mocha](https://mochajs.org/) & [Chai](http://chaijs.com/), supports exception testing (code examples below). If you find it tedious to test every inner function and exception you may settle with testing only REST API HTTP errors.
+
+### Code example: ensuring the right exception is thrown using Mocha & Chai
+
+```javascript
+describe("Facebook chat", () => {
+ it("Notifies on new chat message", () => {
+ var chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: "Hi" })).to.throw(ConnectionError);
+ });
+});
+
+```
+
+### Code example: ensuring API returns the right HTTP error code
+
+```javascript
+it("Creates new Facebook group", function (done) {
+ var invalidGroupInfo = {};
+ httpRequest({
+ method: 'POST',
+ uri: "facebook.com/api/groups",
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ }).then((response) => {
+ // if we were to execute the code in this block, no error was thrown in the operation above
+ }).catch(function (response) {
+ expect(400).to.equal(response.statusCode);
+ done();
+ });
+});
+```
diff --git a/sections/errorhandling/usematurelogger.chinese.md b/sections/errorhandling/usematurelogger.chinese.md
index 1dd751119..210037a7f 100644
--- a/sections/errorhandling/usematurelogger.chinese.md
+++ b/sections/errorhandling/usematurelogger.chinese.md
@@ -1,54 +1,54 @@
-# 使用成熟的logger提高错误可见性
-
-### 一段解释
-
-我们都特别喜欢(loovve)console.log,但显而易见地,对于严肃的项目, 有信誉和持久的Logger是必需的,比如[Winston][winston], [Bunyan][bunyan] (非常流行) or [Pino][pino](专注于性能的新库)。一套实践和工具将有助于更快速地解释错误 – (1)使用不同的级别(debug, info, error)频繁地log;(2)在记录日志时, 以 JSON 对象的方式提供上下文信息, 请参见下面的示例;(3)使用日志查询API(在大多数logger中内置)或日志查看程序软件监视和筛选日志;(4)使用操作智能工具(如 Splunk)为操作团队公开和管理日志语句。
-
-[winston]: https://www.npmjs.com/package/winston
-[bunyan]: https://www.npmjs.com/package/bunyan
-[pino]: https://www.npmjs.com/package/pino
-
-### 代码示例 – 使用Winston Logger
-
-```javascript
-//您的集中式logger对象
-var logger = new winston.Logger({
- level: 'info',
- transports: [
- new (winston.transports.Console)(),
- new (winston.transports.File)({ filename: 'somefile.log' })
- ]
-});
-
-//在某个地方使用logger的自定义代码
-logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
-
-```
-
-### 代码示例 – 查询日志文件夹 (搜索条目)
-
-```javascript
-var options = {
- from: new Date - 24 * 60 * 60 * 1000,
- until: new Date,
- limit: 10,
- start: 0,
- order: 'desc',
- fields: ['message']
- };
-
-
- // 查找在今天和昨天之间记录的项目
- winston.query(options, function (err, results) {
- //对于结果的回调处理
- });
-
-```
-
-### 博客引用: "Logger要求"
- 摘自博客 Strong Loop
-
- > 让我们确定一些要求 (对于logger):
-1. 为每条日志添加时间戳。这条很好自我解释-你应该能够告知每个日志条目发生在什么时候。
-2. 日志格式应易于被人类和机器理解。
-3. 允许多个可配置的目标流。例如, 您可能正在将trace log写入到一个文件中, 但遇到错误时, 请写入同一文件, 然后写入到错误日志文件,并同时发送电子邮件…
+# 使用成熟的logger提高错误可见性
+
+### 一段解释
+
+我们都特别喜欢(loovve)console.log,但显而易见地,对于严肃的项目, 有信誉和持久的Logger是必需的,比如[Winston][winston], [Bunyan][bunyan] (非常流行) or [Pino][pino](专注于性能的新库)。一套实践和工具将有助于更快速地解释错误 – (1)使用不同的级别(debug, info, error)频繁地log;(2)在记录日志时, 以 JSON 对象的方式提供上下文信息, 请参见下面的示例;(3)使用日志查询API(在大多数logger中内置)或日志查看程序软件监视和筛选日志;(4)使用操作智能工具(如 Splunk)为操作团队公开和管理日志语句。
+
+[winston]: https://www.npmjs.com/package/winston
+[bunyan]: https://www.npmjs.com/package/bunyan
+[pino]: https://www.npmjs.com/package/pino
+
+### 代码示例 – 使用Winston Logger
+
+```javascript
+//您的集中式logger对象
+var logger = new winston.Logger({
+ level: 'info',
+ transports: [
+ new (winston.transports.Console)(),
+ new (winston.transports.File)({ filename: 'somefile.log' })
+ ]
+});
+
+//在某个地方使用logger的自定义代码
+logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
+
+```
+
+### 代码示例 – 查询日志文件夹 (搜索条目)
+
+```javascript
+var options = {
+ from: new Date - 24 * 60 * 60 * 1000,
+ until: new Date,
+ limit: 10,
+ start: 0,
+ order: 'desc',
+ fields: ['message']
+ };
+
+
+ // 查找在今天和昨天之间记录的项目
+ winston.query(options, function (err, results) {
+ //对于结果的回调处理
+ });
+
+```
+
+### 博客引用: "Logger要求"
+ 摘自博客 Strong Loop
+
+ > 让我们确定一些要求 (对于logger):
+1. 为每条日志添加时间戳。这条很好自我解释-你应该能够告知每个日志条目发生在什么时候。
+2. 日志格式应易于被人类和机器理解。
+3. 允许多个可配置的目标流。例如, 您可能正在将trace log写入到一个文件中, 但遇到错误时, 请写入同一文件, 然后写入到错误日志文件,并同时发送电子邮件…
diff --git a/sections/errorhandling/usematurelogger.md b/sections/errorhandling/usematurelogger.md
index d735bda93..3247967d9 100644
--- a/sections/errorhandling/usematurelogger.md
+++ b/sections/errorhandling/usematurelogger.md
@@ -1,55 +1,55 @@
-# Use a mature logger to increase errors visibility
-
-### One Paragraph Explainer
-
-We all love console.log but obviously, a reputable and persistent logger like [Winston][winston], [Bunyan][bunyan] (highly popular) or [Pino][pino] (the new kid in town which is focused on performance) is mandatory for serious projects. A set of practices and tools will help to reason about errors much quicker – (1) log frequently using different levels (debug, info, error), (2) when logging, provide contextual information as JSON objects, see example below. (3) watch and filter logs using a log querying API (built-in in most loggers) or a log viewer software
-(4) Expose and curate log statement for the operation team using operational intelligence tools like Splunk
-
-[winston]: https://www.npmjs.com/package/winston
-[bunyan]: https://www.npmjs.com/package/bunyan
-[pino]: https://www.npmjs.com/package/pino
-
-### Code Example – Winston Logger in action
-
-```javascript
-// your centralized logger object
-var logger = new winston.Logger({
- level: 'info',
- transports: [
- new (winston.transports.Console)(),
- new (winston.transports.File)({ filename: 'somefile.log' })
- ]
-});
-
-// custom code somewhere using the logger
-logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
-
-```
-
-### Code Example – Querying the log folder (searching for entries)
-
-```javascript
-var options = {
- from: new Date - 24 * 60 * 60 * 1000,
- until: new Date,
- limit: 10,
- start: 0,
- order: 'desc',
- fields: ['message']
-};
-
-
-// Find items logged between today and yesterday.
-winston.query(options, function (err, results) {
- // execute callback with results
-});
-```
-
-### Blog Quote: "Logger Requirements"
-
- From the blog Strong Loop
-
-> Lets identify a few requirements (for a logger):
-1. Timestamp each log line. This one is pretty self-explanatory – you should be able to tell when each log entry occurred.
-2. Logging format should be easily digestible by humans as well as machines.
-3. Allows for multiple configurable destination streams. For example, you might be writing trace logs to one file but when an error is encountered, write to the same file, then into error file and send an email at the same time…
+# Use a mature logger to increase errors visibility
+
+### One Paragraph Explainer
+
+We all love console.log but obviously, a reputable and persistent logger like [Winston][winston], [Bunyan][bunyan] (highly popular) or [Pino][pino] (the new kid in town which is focused on performance) is mandatory for serious projects. A set of practices and tools will help to reason about errors much quicker – (1) log frequently using different levels (debug, info, error), (2) when logging, provide contextual information as JSON objects, see example below. (3) watch and filter logs using a log querying API (built-in in most loggers) or a log viewer software
+(4) Expose and curate log statement for the operation team using operational intelligence tools like Splunk
+
+[winston]: https://www.npmjs.com/package/winston
+[bunyan]: https://www.npmjs.com/package/bunyan
+[pino]: https://www.npmjs.com/package/pino
+
+### Code Example – Winston Logger in action
+
+```javascript
+// your centralized logger object
+var logger = new winston.Logger({
+ level: 'info',
+ transports: [
+ new (winston.transports.Console)(),
+ new (winston.transports.File)({ filename: 'somefile.log' })
+ ]
+});
+
+// custom code somewhere using the logger
+logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
+
+```
+
+### Code Example – Querying the log folder (searching for entries)
+
+```javascript
+var options = {
+ from: new Date - 24 * 60 * 60 * 1000,
+ until: new Date,
+ limit: 10,
+ start: 0,
+ order: 'desc',
+ fields: ['message']
+};
+
+
+// Find items logged between today and yesterday.
+winston.query(options, function (err, results) {
+ // execute callback with results
+});
+```
+
+### Blog Quote: "Logger Requirements"
+
+ From the blog Strong Loop
+
+> Lets identify a few requirements (for a logger):
+1. Timestamp each log line. This one is pretty self-explanatory – you should be able to tell when each log entry occurred.
+2. Logging format should be easily digestible by humans as well as machines.
+3. Allows for multiple configurable destination streams. For example, you might be writing trace logs to one file but when an error is encountered, write to the same file, then into error file and send an email at the same time…
diff --git a/sections/errorhandling/useonlythebuiltinerror.chinese.md b/sections/errorhandling/useonlythebuiltinerror.chinese.md
index 6473ff196..a7de3cb40 100644
--- a/sections/errorhandling/useonlythebuiltinerror.chinese.md
+++ b/sections/errorhandling/useonlythebuiltinerror.chinese.md
@@ -1,78 +1,78 @@
-# 仅使用内建的错误对象
-
-
-### 一段解释
-
-js天生的宽容性及其多变的代码流选项(例如 EventEmitter, Callbacks, Promises等等)迫使开发人员怎么去引发错误时有多的不一致 – 有些人使用字符串,有些人使用自定义的类型。使用Node.js的内置错误对象有助于在你的代码和第三方库之间保持一致性,它还保留了重要信息,比如StackTrace。当引发异常时,这通常是一个好的习惯去使用附加的上下文属性(如错误名称和相关的HTTP错误代码)填充异常。要实现这种一致性和实践,请考虑使用附加属性扩展错误对象,见下面的代码示例。
-
-博客引用:“I don’t see the value in having lots of different types”
-
-摘自博客Ben Nadel, 对于关键字“Node.JS错误对象”,排名第五
-
-…就我个人而言,我不认为有很多不同类型的错误对象的价值 – JavaScript作为一种语言,似乎不符合基于构造函数的错误捕获。因此,区分对象属性似乎比在构造函数类型上区分要容易得多…
-
-
-
-### 代码示例 – 正确处理它
-
-```javascript
-//从典型函数抛出错误, 无论是同步还是异步
- if(!productToAdd)
- throw new Error("How can I add new product when no value provided?");
-
-//从EventEmitter抛出错误
-const myEmitter = new MyEmitter();
-myEmitter.emit('error', new Error('whoops!'));
-
-//从promise抛出错误
- return new promise(function (resolve, reject) {
- Return DAL.getProduct(productToAdd.id).then((existingProduct) => {
- if(existingProduct != null)
- reject(new Error("Why fooling us and trying to add an existing product?"));
-
-```
-
-### 代码示例 – 反模式
-
-```javascript
-//抛出字符串错误缺少任何stack trace信息和其他重要属性
-if(!productToAdd)
- throw ("How can I add new product when no value provided?");
-
-```
-
-### 代码示例 – 更好处理它
-
-```javascript
-//从node错误派生的集中错误对象
-function appError(name, httpCode, description, isOperational) {
- Error.call(this);
- Error.captureStackTrace(this);
- this.name = name;
- //...在这赋值其它属性
-};
-
-appError.prototype.__proto__ = Error.prototype;
-
-module.exports.appError = appError;
-
-//客户端抛出一个错误
-if(user == null)
- throw new appError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "further explanation", true)
-```
-
-
-### 博客引用: "字符串不是错误"
- 摘自博客 devthought.com, 对于关键字 “Node.JS error object” 排名第6
-
- > …传递字符串而不是错误导致模块间协作性降低。它打破了和API的约定,可能是执行instanceof Error这样的检查,或想了解更多关于错误的信息。正如我们将看到的,错误对象在现代JavaScript引擎中拥有非常有趣的属性,同时保留传递给构造函数的消息…
-
-### 博客引用: "从Error对象继承不会增加太多的值"
- 摘自博客 machadogj
-
- > …我对Error类的一个问题是不太容易扩展。当然, 您可以继承该类并创建自己的Error类, 如HttpError、DbError等。然而, 这需要时间, 并且不会增加太多的价值, 除非你是在做一些关于类型的事情。有时, 您只想添加一条消息, 并保留内部错误, 有时您可能希望使用参数扩展该错误, 等等…
-
- ### 博客引用: "所有由node.js引发的 JavaScript 和系统错误继承自Error对象"
- 摘自 Node.JS 官方文档
-
- > …所有由node.js引发的JavaScript和系统错误继承自,或是JavaScript标准错误类的实例, 这保证至少提供了该类的可用属性。一个通用的JavaScript错误对象, 它不表示错误为什么发生的任何特定环境。错误对象捕获一个"stack trace", 详细说明了错误被实例化时在代码中的点, 并可能提供错误的文本描述。由node.js生成的所有错误, 包括所有的系统和JavaScript错误, 都将是Error类的实例, 或继承自Error类…
+# 仅使用内建的错误对象
+
+
+### 一段解释
+
+js天生的宽容性及其多变的代码流选项(例如 EventEmitter, Callbacks, Promises等等)迫使开发人员怎么去引发错误时有多的不一致 – 有些人使用字符串,有些人使用自定义的类型。使用Node.js的内置错误对象有助于在你的代码和第三方库之间保持一致性,它还保留了重要信息,比如StackTrace。当引发异常时,这通常是一个好的习惯去使用附加的上下文属性(如错误名称和相关的HTTP错误代码)填充异常。要实现这种一致性和实践,请考虑使用附加属性扩展错误对象,见下面的代码示例。
+
+博客引用:“I don’t see the value in having lots of different types”
+
+摘自博客Ben Nadel, 对于关键字“Node.JS错误对象”,排名第五
+
+…就我个人而言,我不认为有很多不同类型的错误对象的价值 – JavaScript作为一种语言,似乎不符合基于构造函数的错误捕获。因此,区分对象属性似乎比在构造函数类型上区分要容易得多…
+
+
+
+### 代码示例 – 正确处理它
+
+```javascript
+//从典型函数抛出错误, 无论是同步还是异步
+ if(!productToAdd)
+ throw new Error("How can I add new product when no value provided?");
+
+//从EventEmitter抛出错误
+const myEmitter = new MyEmitter();
+myEmitter.emit('error', new Error('whoops!'));
+
+//从promise抛出错误
+ return new promise(function (resolve, reject) {
+ Return DAL.getProduct(productToAdd.id).then((existingProduct) => {
+ if(existingProduct != null)
+ reject(new Error("Why fooling us and trying to add an existing product?"));
+
+```
+
+### 代码示例 – 反模式
+
+```javascript
+//抛出字符串错误缺少任何stack trace信息和其他重要属性
+if(!productToAdd)
+ throw ("How can I add new product when no value provided?");
+
+```
+
+### 代码示例 – 更好处理它
+
+```javascript
+//从node错误派生的集中错误对象
+function appError(name, httpCode, description, isOperational) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.name = name;
+ //...在这赋值其它属性
+};
+
+appError.prototype.__proto__ = Error.prototype;
+
+module.exports.appError = appError;
+
+//客户端抛出一个错误
+if(user == null)
+ throw new appError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "further explanation", true)
+```
+
+
+### 博客引用: "字符串不是错误"
+ 摘自博客 devthought.com, 对于关键字 “Node.JS error object” 排名第6
+
+ > …传递字符串而不是错误导致模块间协作性降低。它打破了和API的约定,可能是执行instanceof Error这样的检查,或想了解更多关于错误的信息。正如我们将看到的,错误对象在现代JavaScript引擎中拥有非常有趣的属性,同时保留传递给构造函数的消息…
+
+### 博客引用: "从Error对象继承不会增加太多的值"
+ 摘自博客 machadogj
+
+ > …我对Error类的一个问题是不太容易扩展。当然, 您可以继承该类并创建自己的Error类, 如HttpError、DbError等。然而, 这需要时间, 并且不会增加太多的价值, 除非你是在做一些关于类型的事情。有时, 您只想添加一条消息, 并保留内部错误, 有时您可能希望使用参数扩展该错误, 等等…
+
+ ### 博客引用: "所有由node.js引发的 JavaScript 和系统错误继承自Error对象"
+ 摘自 Node.JS 官方文档
+
+ > …所有由node.js引发的JavaScript和系统错误继承自,或是JavaScript标准错误类的实例, 这保证至少提供了该类的可用属性。一个通用的JavaScript错误对象, 它不表示错误为什么发生的任何特定环境。错误对象捕获一个"stack trace", 详细说明了错误被实例化时在代码中的点, 并可能提供错误的文本描述。由node.js生成的所有错误, 包括所有的系统和JavaScript错误, 都将是Error类的实例, 或继承自Error类…
diff --git a/sections/errorhandling/useonlythebuiltinerror.md b/sections/errorhandling/useonlythebuiltinerror.md
index 794ceb6bd..300f41588 100644
--- a/sections/errorhandling/useonlythebuiltinerror.md
+++ b/sections/errorhandling/useonlythebuiltinerror.md
@@ -1,78 +1,78 @@
-# Use only the built-in Error object
-
-### One Paragraph Explainer
-
-The permissive nature of JS along with its variety code-flow options (e.g. EventEmitter, Callbacks, Promises, etc) pushes to great variance in how developers raise errors – some use strings, other define their own custom types. Using Node.js built-in Error object helps to keep uniformity within your code and with 3rd party libraries, it also preserves significant information like the StackTrace. When raising the exception, it’s usually a good practice to fill it with additional contextual properties like the error name and the associated HTTP error code. To achieve this uniformity and practices, consider extending the Error object with additional properties, see code example below
-
-### Code Example – doing it right
-
-```javascript
-// throwing an Error from typical function, whether sync or async
-if(!productToAdd)
- throw new Error("How can I add new product when no value provided?");
-
-// 'throwing' an Error from EventEmitter
-const myEmitter = new MyEmitter();
-myEmitter.emit('error', new Error('whoops!'));
-
-// 'throwing' an Error from a Promise
-return new Promise(function (resolve, reject) {
- return DAL.getProduct(productToAdd.id).then((existingProduct) => {
- if(existingProduct != null)
- reject(new Error("Why fooling us and trying to add an existing product?"));
- });
-});
-```
-
-### Code example – Anti Pattern
-
-```javascript
-// throwing a string lacks any stack trace information and other important data properties
-if(!productToAdd)
- throw ("How can I add new product when no value provided?");
-```
-
-### Code example – doing it even better
-
-```javascript
-// centralized error object that derives from Node’s Error
-function AppError(name, httpCode, description, isOperational) {
- Error.call(this);
- Error.captureStackTrace(this);
- this.name = name;
- //...other properties assigned here
-};
-
-AppError.prototype.__proto__ = Error.prototype;
-
-module.exports.AppError = AppError;
-
-// client throwing an exception
-if(user == null)
- throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "further explanation", true)
-```
-
-### Blog Quote: "I don’t see the value in having lots of different types"
-
-From the blog, Ben Nadel ranked 5 for the keywords “Node.js error object”
-
->…”Personally, I don’t see the value in having lots of different types of error objects – JavaScript, as a language, doesn’t seem to cater to Constructor-based error-catching. As such, differentiating on an object property seems far easier than differentiating on a Constructor type…
-
-### Blog Quote: "A string is not an error"
-
-From the blog, devthought.com ranked 6 for the keywords “Node.js error object”
-
-> …passing a string instead of an error results in reduced interoperability between modules. It breaks contracts with APIs that might be performing `instanceof` Error checks, or that want to know more about the error. Error objects, as we’ll see, have very interesting properties in modern JavaScript engines besides holding the message passed to the constructor…
-Blog Quote: “All JavaScript and System errors raised by Node.js inherit from Error”
-
-### Blog Quote: "Inheriting from Error doesn’t add too much value"
-
-From the blog machadogj
-
-> …One problem that I have with the Error class is that is not so simple to extend. Of course, you can inherit the class and create your own Error classes like HttpError, DbError, etc. However, that takes time and doesn’t add too much value unless you are doing something with types. Sometimes, you just want to add a message and keep the inner error, and sometimes you might want to extend the error with parameters, and such…
-
-### Blog Quote: "All JavaScript and System errors raised by Node.js inherit from Error"
-
-From Node.js official documentation
-
-> …All JavaScript and System errors raised by Node.js inherit from, or are instances of, the standard JavaScript Error class and are guaranteed to provide at least the properties available on that class. A generic JavaScript Error object that does not denote any specific circumstance of why the error occurred. Error objects capture a “stack trace” detailing the point in the code at which the Error was instantiated, and may provide a text description of the error.All errors generated by Node.js, including all System and JavaScript errors, will either be instances of or inherit from, the Error class…
+# Use only the built-in Error object
+
+### One Paragraph Explainer
+
+The permissive nature of JS along with its variety code-flow options (e.g. EventEmitter, Callbacks, Promises, etc) pushes to great variance in how developers raise errors – some use strings, other define their own custom types. Using Node.js built-in Error object helps to keep uniformity within your code and with 3rd party libraries, it also preserves significant information like the StackTrace. When raising the exception, it’s usually a good practice to fill it with additional contextual properties like the error name and the associated HTTP error code. To achieve this uniformity and practices, consider extending the Error object with additional properties, see code example below
+
+### Code Example – doing it right
+
+```javascript
+// throwing an Error from typical function, whether sync or async
+if(!productToAdd)
+ throw new Error("How can I add new product when no value provided?");
+
+// 'throwing' an Error from EventEmitter
+const myEmitter = new MyEmitter();
+myEmitter.emit('error', new Error('whoops!'));
+
+// 'throwing' an Error from a Promise
+return new Promise(function (resolve, reject) {
+ return DAL.getProduct(productToAdd.id).then((existingProduct) => {
+ if(existingProduct != null)
+ reject(new Error("Why fooling us and trying to add an existing product?"));
+ });
+});
+```
+
+### Code example – Anti Pattern
+
+```javascript
+// throwing a string lacks any stack trace information and other important data properties
+if(!productToAdd)
+ throw ("How can I add new product when no value provided?");
+```
+
+### Code example – doing it even better
+
+```javascript
+// centralized error object that derives from Node’s Error
+function AppError(name, httpCode, description, isOperational) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.name = name;
+ //...other properties assigned here
+};
+
+AppError.prototype.__proto__ = Error.prototype;
+
+module.exports.AppError = AppError;
+
+// client throwing an exception
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "further explanation", true)
+```
+
+### Blog Quote: "I don’t see the value in having lots of different types"
+
+From the blog, Ben Nadel ranked 5 for the keywords “Node.js error object”
+
+>…”Personally, I don’t see the value in having lots of different types of error objects – JavaScript, as a language, doesn’t seem to cater to Constructor-based error-catching. As such, differentiating on an object property seems far easier than differentiating on a Constructor type…
+
+### Blog Quote: "A string is not an error"
+
+From the blog, devthought.com ranked 6 for the keywords “Node.js error object”
+
+> …passing a string instead of an error results in reduced interoperability between modules. It breaks contracts with APIs that might be performing `instanceof` Error checks, or that want to know more about the error. Error objects, as we’ll see, have very interesting properties in modern JavaScript engines besides holding the message passed to the constructor…
+Blog Quote: “All JavaScript and System errors raised by Node.js inherit from Error”
+
+### Blog Quote: "Inheriting from Error doesn’t add too much value"
+
+From the blog machadogj
+
+> …One problem that I have with the Error class is that is not so simple to extend. Of course, you can inherit the class and create your own Error classes like HttpError, DbError, etc. However, that takes time and doesn’t add too much value unless you are doing something with types. Sometimes, you just want to add a message and keep the inner error, and sometimes you might want to extend the error with parameters, and such…
+
+### Blog Quote: "All JavaScript and System errors raised by Node.js inherit from Error"
+
+From Node.js official documentation
+
+> …All JavaScript and System errors raised by Node.js inherit from, or are instances of, the standard JavaScript Error class and are guaranteed to provide at least the properties available on that class. A generic JavaScript Error object that does not denote any specific circumstance of why the error occurred. Error objects capture a “stack trace” detailing the point in the code at which the Error was instantiated, and may provide a text description of the error.All errors generated by Node.js, including all System and JavaScript errors, will either be instances of or inherit from, the Error class…
diff --git a/sections/production/LTSrelease.md b/sections/production/LTSrelease.md
index 1a3e0808a..de2194066 100644
--- a/sections/production/LTSrelease.md
+++ b/sections/production/LTSrelease.md
@@ -1,20 +1,20 @@
-# Use an LTS release of Node.js in production
-
-### One Paragraph Explainer
-
-Ensure you are using an LTS(Long Term Support) version of Node.js in production to receive critical bug fixes, security updates and performance improvements.
-
-LTS versions of Node.js are supported for at least 18 months and are indicated by even version numbers (e.g. 4, 6, 8). They're best for production since the LTS release line is focussed on stability and security, whereas the 'Current' release line has a shorter lifespan and more frequent updates to the code. Changes to LTS versions are limited to bug fixes for stability, security updates, possible npm updates, documentation updates and certain performance improvements that can be demonstrated to not break existing applications.
-
-
-
-### Read on
-
-🔗 [Node.js release definitions](https://nodejs.org/en/about/releases/)
-
-🔗 [Node.js release schedule](https://github.com/nodejs/Release)
-
-🔗 [Essential Steps: Long Term Support for Node.js by Rod Vagg](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
-> ...the schedule of incremental releases within each of these will be driven by the availability of bug fixes, security fixes, and other small but important changes. The focus will be on stability, but stability also includes minimizing the number of known bugs and staying on top of security concerns as they arise.
-
-
+# Use an LTS release of Node.js in production
+
+### One Paragraph Explainer
+
+Ensure you are using an LTS(Long Term Support) version of Node.js in production to receive critical bug fixes, security updates and performance improvements.
+
+LTS versions of Node.js are supported for at least 18 months and are indicated by even version numbers (e.g. 4, 6, 8). They're best for production since the LTS release line is focussed on stability and security, whereas the 'Current' release line has a shorter lifespan and more frequent updates to the code. Changes to LTS versions are limited to bug fixes for stability, security updates, possible npm updates, documentation updates and certain performance improvements that can be demonstrated to not break existing applications.
+
+
+
+### Read on
+
+🔗 [Node.js release definitions](https://nodejs.org/en/about/releases/)
+
+🔗 [Node.js release schedule](https://github.com/nodejs/Release)
+
+🔗 [Essential Steps: Long Term Support for Node.js by Rod Vagg](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
+> ...the schedule of incremental releases within each of these will be driven by the availability of bug fixes, security fixes, and other small but important changes. The focus will be on stability, but stability also includes minimizing the number of known bugs and staying on top of security concerns as they arise.
+
+
diff --git a/sections/production/apmproducts.chinese.md b/sections/production/apmproducts.chinese.md
index ebe06b011..4430b6312 100644
--- a/sections/production/apmproducts.chinese.md
+++ b/sections/production/apmproducts.chinese.md
@@ -1,26 +1,26 @@
-# 使用 APM 产品确保用户体验
-
-
-
-
-### 一段解释
-
-APM(应用程序性能监视)指的是一个产品系列, 目的是从端到端,也从客户的角度监控应用程序的性能。虽然传统的监控解决方案侧重于异常和独立的技术指标 (例如错误跟踪、检测慢速服务器端点等), 在现实世界中, 我们的应用程序可能会在没有任何代码异常的情况下让用户使用起来感到失望, 例如, 如果某些中间件服务执行得非常慢。APM 产品从端到端检测用户体验, 例如, 给定一个包含前端 UI 和多个分布式服务的系统 – 一些 APM 产品可以告诉您, 一个跨过多个层的事务的速度有多快。它可以判断用户体验是否可靠, 并指出问题所在。这种诱人的产品通常有一个相对较高的价格标签, 因此, 对于需要超越一般的监测的,大规模的和复杂的产品, 它们是值得推荐的。
-
-
-
-
-### APM 示例 – 一种可视化跨服务应用性能的商业产品
-![APM example](/assets/images/apm1.png "APM example")
-
-
-
-### APM 示例 – 一种强调用户体验评分的商业产品
-
-![APM example](/assets/images/apm2.png "APM example")
-
-
-
-### APM 示例 – 一种突出显示慢速代码路径的商业产品
-
-![APM example](/assets/images/apm3.png "APM example")
+# 使用 APM 产品确保用户体验
+
+
+
+
+### 一段解释
+
+APM(应用程序性能监视)指的是一个产品系列, 目的是从端到端,也从客户的角度监控应用程序的性能。虽然传统的监控解决方案侧重于异常和独立的技术指标 (例如错误跟踪、检测慢速服务器端点等), 在现实世界中, 我们的应用程序可能会在没有任何代码异常的情况下让用户使用起来感到失望, 例如, 如果某些中间件服务执行得非常慢。APM 产品从端到端检测用户体验, 例如, 给定一个包含前端 UI 和多个分布式服务的系统 – 一些 APM 产品可以告诉您, 一个跨过多个层的事务的速度有多快。它可以判断用户体验是否可靠, 并指出问题所在。这种诱人的产品通常有一个相对较高的价格标签, 因此, 对于需要超越一般的监测的,大规模的和复杂的产品, 它们是值得推荐的。
+
+
+
+
+### APM 示例 – 一种可视化跨服务应用性能的商业产品
+![APM example](/assets/images/apm1.png "APM example")
+
+
+
+### APM 示例 – 一种强调用户体验评分的商业产品
+
+![APM example](/assets/images/apm2.png "APM example")
+
+
+
+### APM 示例 – 一种突出显示慢速代码路径的商业产品
+
+![APM example](/assets/images/apm3.png "APM example")
diff --git a/sections/production/apmproducts.md b/sections/production/apmproducts.md
index 71c51794c..bd7e5754b 100644
--- a/sections/production/apmproducts.md
+++ b/sections/production/apmproducts.md
@@ -1,25 +1,25 @@
-# Sure user experience with APM products
-
-
-
-### One Paragraph Explainer
-
-APM (application performance monitoring) refers to a family of products that aims to monitor application performance from end to end, also from the customer perspective. While traditional monitoring solutions focus on Exceptions and standalone technical metrics (e.g. error tracking, slow server endpoints, etc), in the real world our app might create disappointed users without any code exceptions, for example, if some middleware service performed real slow. APM products measure the user experience from end to end, for example, given a system that encompasses frontend UI and multiple distributed services – some APM products can tell how fast a transaction that spans multiple tiers last. It can tell whether the user experience is solid and point to the problem. This attractive offering comes with a relatively high price tag hence it’s recommended for large-scale and complex products that require going beyond straightforward monitoring.
-
-
-
-### APM example – a commercial product that visualizes cross-service app performance
-
-![APM example](/assets/images/apm1.png "APM example")
-
-
-
-### APM example – a commercial product that emphasizes the user experience score
-
-![APM example](/assets/images/apm2.png "APM example")
-
-
-
-### APM example – a commercial product that highlights slow code paths
-
-![APM example](/assets/images/apm3.png "APM example")
+# Sure user experience with APM products
+
+
+
+### One Paragraph Explainer
+
+APM (application performance monitoring) refers to a family of products that aims to monitor application performance from end to end, also from the customer perspective. While traditional monitoring solutions focus on Exceptions and standalone technical metrics (e.g. error tracking, slow server endpoints, etc), in the real world our app might create disappointed users without any code exceptions, for example, if some middleware service performed real slow. APM products measure the user experience from end to end, for example, given a system that encompasses frontend UI and multiple distributed services – some APM products can tell how fast a transaction that spans multiple tiers last. It can tell whether the user experience is solid and point to the problem. This attractive offering comes with a relatively high price tag hence it’s recommended for large-scale and complex products that require going beyond straightforward monitoring.
+
+
+
+### APM example – a commercial product that visualizes cross-service app performance
+
+![APM example](/assets/images/apm1.png "APM example")
+
+
+
+### APM example – a commercial product that emphasizes the user experience score
+
+![APM example](/assets/images/apm2.png "APM example")
+
+
+
+### APM example – a commercial product that highlights slow code paths
+
+![APM example](/assets/images/apm3.png "APM example")
diff --git a/sections/production/assigntransactionid.chinese.md b/sections/production/assigntransactionid.chinese.md
index 2d3c8ff64..0b66dbd74 100644
--- a/sections/production/assigntransactionid.chinese.md
+++ b/sections/production/assigntransactionid.chinese.md
@@ -1,40 +1,40 @@
-# 在每一个log语句指定‘TransactionId’
-
-
-
-
-### 一段解释
-
-一个典型的日志是来自所有组件和请求的条目的仓库。当检测到一些可疑行或错误时,为了与其他属于同一特定流程的行(如用户“约翰”试图购买某物)相匹配,就会变得难以应付。特别在微服务环境下,当一个请求/交易可能跨越多个计算机,这变得更加重要和具有挑战性。解决这个问题,可以通过指定一个唯一的事务标识符给从相同的请求过来的所有条目,这样当检测到一行,可以复制这个id,并搜索包含这个transaction id的每一行。但是,在node中实现这个不是那么直截了当的,这是由于它的单线程被用来服务所有的请求 – 考虑使用一个库,它可以在请求层对数据进行分组 – 在下一张幻灯片查看示例代码。当调用其它微服务,使用HTTP头“x-transaction-id”传递transaction id去保持相同的上下文。
-
-
-
-
-### 代码示例: 典型的nginx配置
-
-```javascript
-//当接收到一个新的要求,开始一个新的隔离的上下文和设置一个事务transaction id。下面的例子是使用NPM库continuation-local-storage去隔离请求
-
-const { createNamespace } = require('continuation-local-storage');
-var session = createNamespace('my session');
-
-router.get('/:id', (req, res, next) => {
- session.set('transactionId', 'some unique GUID');
- someService.getById(req.params.id);
- logger.info('Starting now to get something by Id');
-});
-
-//现在, 任何其他服务或组件都可以访问上下文、每个请求、数据
-class someService {
- getById(id) {
- logger.info(“Starting now to get something by Id”);
- //其它逻辑
- }
-}
-
-//Logger现在可以将事务 id 追加到每个条目, 以便同一请求中的项将具有相同的值
-class logger{
- info (message)
- {console.log(`${message} ${session.get('transactionId')}`);}
-}
-```
+# 在每一个log语句指定‘TransactionId’
+
+
+
+
+### 一段解释
+
+一个典型的日志是来自所有组件和请求的条目的仓库。当检测到一些可疑行或错误时,为了与其他属于同一特定流程的行(如用户“约翰”试图购买某物)相匹配,就会变得难以应付。特别在微服务环境下,当一个请求/交易可能跨越多个计算机,这变得更加重要和具有挑战性。解决这个问题,可以通过指定一个唯一的事务标识符给从相同的请求过来的所有条目,这样当检测到一行,可以复制这个id,并搜索包含这个transaction id的每一行。但是,在node中实现这个不是那么直截了当的,这是由于它的单线程被用来服务所有的请求 – 考虑使用一个库,它可以在请求层对数据进行分组 – 在下一张幻灯片查看示例代码。当调用其它微服务,使用HTTP头“x-transaction-id”传递transaction id去保持相同的上下文。
+
+
+
+
+### 代码示例: 典型的nginx配置
+
+```javascript
+//当接收到一个新的要求,开始一个新的隔离的上下文和设置一个事务transaction id。下面的例子是使用NPM库continuation-local-storage去隔离请求
+
+const { createNamespace } = require('continuation-local-storage');
+var session = createNamespace('my session');
+
+router.get('/:id', (req, res, next) => {
+ session.set('transactionId', 'some unique GUID');
+ someService.getById(req.params.id);
+ logger.info('Starting now to get something by Id');
+});
+
+//现在, 任何其他服务或组件都可以访问上下文、每个请求、数据
+class someService {
+ getById(id) {
+ logger.info(“Starting now to get something by Id”);
+ //其它逻辑
+ }
+}
+
+//Logger现在可以将事务 id 追加到每个条目, 以便同一请求中的项将具有相同的值
+class logger{
+ info (message)
+ {console.log(`${message} ${session.get('transactionId')}`);}
+}
+```
diff --git a/sections/production/assigntransactionid.md b/sections/production/assigntransactionid.md
index 4d18c30b9..9b127d1b0 100644
--- a/sections/production/assigntransactionid.md
+++ b/sections/production/assigntransactionid.md
@@ -1,38 +1,38 @@
-# Assign ‘TransactionId’ to each log statement
-
-
-
-### One Paragraph Explainer
-
-A typical log is a warehouse of entries from all components and requests. Upon detection of some suspicious line or error, it becomes hairy to match other lines that belong to the same specific flow (e.g. the user “John” tried to buy something). This becomes even more critical and challenging in a microservice environment when a request/transaction might span across multiple computers. Address this by assigning a unique transaction identifier value to all the entries from the same request so when detecting one line one can copy the id and search for every line that has similar transaction Id. However, achieving this In Node is not straightforward as a single thread is used to serve all requests –consider using a library that that can group data on the request level – see code example on the next slide. When calling other microservice, pass the transaction Id using an HTTP header like “x-transaction-id” to keep the same context.
-
-
-
-### Code example: typical Express configuration
-
-```javascript
-// when receiving a new request, start a new isolated context and set a transaction Id. The following example is using the npm library continuation-local-storage to isolate requests
-
-const { createNamespace } = require('continuation-local-storage');
-var session = createNamespace('my session');
-
-router.get('/:id', (req, res, next) => {
- session.set('transactionId', 'some unique GUID');
- someService.getById(req.params.id);
- logger.info('Starting now to get something by Id');
-});
-
-// Now any other service or components can have access to the contextual, per-request, data
-class someService {
- getById(id) {
- logger.info(“Starting to get something by Id”);
- // other logic comes here
- }
-}
-
-// The logger can now append the transaction-id to each entry so that entries from the same request will have the same value
-class logger {
- info (message)
- {console.log(`${message} ${session.get('transactionId')}`);}
-}
-```
+# Assign ‘TransactionId’ to each log statement
+
+
+
+### One Paragraph Explainer
+
+A typical log is a warehouse of entries from all components and requests. Upon detection of some suspicious line or error, it becomes hairy to match other lines that belong to the same specific flow (e.g. the user “John” tried to buy something). This becomes even more critical and challenging in a microservice environment when a request/transaction might span across multiple computers. Address this by assigning a unique transaction identifier value to all the entries from the same request so when detecting one line one can copy the id and search for every line that has similar transaction Id. However, achieving this In Node is not straightforward as a single thread is used to serve all requests –consider using a library that that can group data on the request level – see code example on the next slide. When calling other microservice, pass the transaction Id using an HTTP header like “x-transaction-id” to keep the same context.
+
+
+
+### Code example: typical Express configuration
+
+```javascript
+// when receiving a new request, start a new isolated context and set a transaction Id. The following example is using the npm library continuation-local-storage to isolate requests
+
+const { createNamespace } = require('continuation-local-storage');
+var session = createNamespace('my session');
+
+router.get('/:id', (req, res, next) => {
+ session.set('transactionId', 'some unique GUID');
+ someService.getById(req.params.id);
+ logger.info('Starting now to get something by Id');
+});
+
+// Now any other service or components can have access to the contextual, per-request, data
+class someService {
+ getById(id) {
+ logger.info(“Starting to get something by Id”);
+ // other logic comes here
+ }
+}
+
+// The logger can now append the transaction-id to each entry so that entries from the same request will have the same value
+class logger {
+ info (message)
+ {console.log(`${message} ${session.get('transactionId')}`);}
+}
+```
diff --git a/sections/production/bestateless.chinese.md b/sections/production/bestateless.chinese.md
index 045a4ad46..7ca43d208 100644
--- a/sections/production/bestateless.chinese.md
+++ b/sections/production/bestateless.chinese.md
@@ -1,42 +1,42 @@
-# 保存无状态,几乎每天停掉服务器
-
-
-
-
-### 一段解释
-
-你曾经有没有遇到一类严重的线上问题,比如一个服务器丢失了一些配置或数据?这可能是由于对于不属于部署部分的本地资源的一些不必要的依赖。许多成功的产品对待服务器就像凤凰鸟–它周期性地死亡和重生不带来任何损伤。换句话说,服务器只是一个硬件,执行你的代码一段时间后,可以更换。
-这个方法:
-- 允许动态添加和删除服务器,无任何负面影响;
-- 简化了维护,因为它使我们不必费精力对每个服务器状态进行评估。
-
-
-
-
-### 代码示例: 反模式
-
-```javascript
-//典型错误1: 保存上传文件在本地服务器上
-var multer = require('multer') // 处理multipart上传的express中间件
-var upload = multer({ dest: 'uploads/' })
-
-app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {})
-
-//典型错误2: 在本地文件或者内存中,保存授权会话(密码)
-var FileStore = require('session-file-store')(session);
-app.use(session({
- store: new FileStore(options),
- secret: 'keyboard cat'
-}));
-
-//典型错误3: 在全局对象中保存信息
-Global.someCacheLike.result = {somedata}
-```
-
-
-
-### 其他博客作者说什么
-摘自博客 [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
-> ...某天,我有了启动一个对操作的认证服务的幻想。认证评估将由我和一位同事出现在企业数据中心,并通过一个棒球棒,一个电锯和一把水枪设置关键生产服务器。评估将基于操作团队需要多长时间才能重新运行所有应用程序。这可能是一个愚蠢的幻想,但有一个真正的智慧在这里。而你应该放弃棒球棒,去定期的几乎烧毁你的服务器,这是一个好的做法。服务器应该像凤凰,经常从灰烬中升起...
-
-
+# 保存无状态,几乎每天停掉服务器
+
+
+
+
+### 一段解释
+
+你曾经有没有遇到一类严重的线上问题,比如一个服务器丢失了一些配置或数据?这可能是由于对于不属于部署部分的本地资源的一些不必要的依赖。许多成功的产品对待服务器就像凤凰鸟–它周期性地死亡和重生不带来任何损伤。换句话说,服务器只是一个硬件,执行你的代码一段时间后,可以更换。
+这个方法:
+- 允许动态添加和删除服务器,无任何负面影响;
+- 简化了维护,因为它使我们不必费精力对每个服务器状态进行评估。
+
+
+
+
+### 代码示例: 反模式
+
+```javascript
+//典型错误1: 保存上传文件在本地服务器上
+var multer = require('multer') // 处理multipart上传的express中间件
+var upload = multer({ dest: 'uploads/' })
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {})
+
+//典型错误2: 在本地文件或者内存中,保存授权会话(密码)
+var FileStore = require('session-file-store')(session);
+app.use(session({
+ store: new FileStore(options),
+ secret: 'keyboard cat'
+}));
+
+//典型错误3: 在全局对象中保存信息
+Global.someCacheLike.result = {somedata}
+```
+
+
+
+### 其他博客作者说什么
+摘自博客 [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
+> ...某天,我有了启动一个对操作的认证服务的幻想。认证评估将由我和一位同事出现在企业数据中心,并通过一个棒球棒,一个电锯和一把水枪设置关键生产服务器。评估将基于操作团队需要多长时间才能重新运行所有应用程序。这可能是一个愚蠢的幻想,但有一个真正的智慧在这里。而你应该放弃棒球棒,去定期的几乎烧毁你的服务器,这是一个好的做法。服务器应该像凤凰,经常从灰烬中升起...
+
+
diff --git a/sections/production/bestateless.md b/sections/production/bestateless.md
index cea84dec9..e50d9c032 100644
--- a/sections/production/bestateless.md
+++ b/sections/production/bestateless.md
@@ -1,42 +1,42 @@
-# Be stateless, kill your Servers almost every day
-
-
-
-### One Paragraph Explainer
-
-Have you ever encountered a severe production issue where one server was missing some piece of configuration or data? That is probably due to some unnecessary dependency on some local asset that is not part of the deployment. Many successful products treat servers like a phoenix bird – it dies and is reborn periodically without any damage. In other words, a server is just a piece of hardware that executes your code for some time and is replaced after that.
-This approach
-
-- allows scaling by adding and removing servers dynamically without any side-effects.
-- simplifies the maintenance as it frees our mind from evaluating each server state.
-
-
-
-### Code example: anti-patterns
-
-```javascript
-// Typical mistake 1: saving uploaded files locally on a server
-var multer = require('multer'); // express middleware for handling multipart uploads
-var upload = multer({ dest: 'uploads/' });
-
-app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {});
-
-// Typical mistake 2: storing authentication sessions (passport) in a local file or memory
-var FileStore = require('session-file-store')(session);
-app.use(session({
- store: new FileStore(options),
- secret: 'keyboard cat'
-}));
-
-// Typical mistake 3: storing information on the global object
-Global.someCacheLike.result = { somedata };
-```
-
-
-
-### What Other Bloggers Say
-
-From the blog [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
-> ...One day I had this fantasy of starting a certification service for operations. The certification assessment would consist of a colleague and I turning up at the corporate data center and setting about critical production servers with a baseball bat, a chainsaw, and a water pistol. The assessment would be based on how long it would take for the operations team to get all the applications up and running again. This may be a daft fantasy, but there’s a nugget of wisdom here. While you should forego the baseball bats, it is a good idea to virtually burn down your servers at regular intervals. A server should be like a phoenix, regularly rising from the ashes...
-
-
+# Be stateless, kill your Servers almost every day
+
+
+
+### One Paragraph Explainer
+
+Have you ever encountered a severe production issue where one server was missing some piece of configuration or data? That is probably due to some unnecessary dependency on some local asset that is not part of the deployment. Many successful products treat servers like a phoenix bird – it dies and is reborn periodically without any damage. In other words, a server is just a piece of hardware that executes your code for some time and is replaced after that.
+This approach
+
+- allows scaling by adding and removing servers dynamically without any side-effects.
+- simplifies the maintenance as it frees our mind from evaluating each server state.
+
+
+
+### Code example: anti-patterns
+
+```javascript
+// Typical mistake 1: saving uploaded files locally on a server
+var multer = require('multer'); // express middleware for handling multipart uploads
+var upload = multer({ dest: 'uploads/' });
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {});
+
+// Typical mistake 2: storing authentication sessions (passport) in a local file or memory
+var FileStore = require('session-file-store')(session);
+app.use(session({
+ store: new FileStore(options),
+ secret: 'keyboard cat'
+}));
+
+// Typical mistake 3: storing information on the global object
+Global.someCacheLike.result = { somedata };
+```
+
+
+
+### What Other Bloggers Say
+
+From the blog [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
+> ...One day I had this fantasy of starting a certification service for operations. The certification assessment would consist of a colleague and I turning up at the corporate data center and setting about critical production servers with a baseball bat, a chainsaw, and a water pistol. The assessment would be based on how long it would take for the operations team to get all the applications up and running again. This may be a daft fantasy, but there’s a nugget of wisdom here. While you should forego the baseball bats, it is a good idea to virtually burn down your servers at regular intervals. A server should be like a phoenix, regularly rising from the ashes...
+
+
diff --git a/sections/production/createmaintenanceendpoint.chinese.md b/sections/production/createmaintenanceendpoint.chinese.md
index c5fe4077c..90f7f84a8 100644
--- a/sections/production/createmaintenanceendpoint.chinese.md
+++ b/sections/production/createmaintenanceendpoint.chinese.md
@@ -1,37 +1,37 @@
-# 创建维护端点
-
-
-
-
-### 一段解释
-
-维护端点是一个简单的安全的HTTP API, 它是应用程序代码的一部分, 它的用途是让ops/生产团队用来监视和公开维护功能。例如, 它可以返回进程的head dump (内存快照), 报告是否存在内存泄漏, 甚至允许直接执行 REPL 命令。在常规的 devops 工具 (监视产品、日志等) 无法收集特定类型的信息或您选择不购买/安装此类工具时, 需要使用此端点。黄金法则是使用专业的和外部的工具来监控和维护生产环境, 它们通常更加健壮和准确的。这就意味着, 一般的工具可能无法提取特定于node或应用程序的信息 – 例如, 如果您希望在 GC 完成一个周期时生成内存快照 – 很少有 npm 库会很乐意为您执行这个, 但流行的监控工具很可能会错过这个功能。
-
-
-
-
-### 代码示例: 使用代码生产head dump
-
-```javascript
-var heapdump = require('heapdump');
-
-router.get('/ops/headump', (req, res, next) => {
- logger.info(`About to generate headump`);
- heapdump.writeSnapshot(function (err, filename) {
- console.log('headump file is ready to be sent to the caller', filename);
- fs.readFile(filename, "utf-8", function (err, data) {
- res.end(data);
- });
- });
-});
-```
-
-
-
-### 推荐资源
-
-[Getting your Node.js app production ready (Slides)](http://naugtur.pl/pres3/node2prod)
-
-▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
-
-![Getting your Node.js app production ready](/assets/images/createmaintenanceendpoint1.png "Getting your Node.js app production ready")
+# 创建维护端点
+
+
+
+
+### 一段解释
+
+维护端点是一个简单的安全的HTTP API, 它是应用程序代码的一部分, 它的用途是让ops/生产团队用来监视和公开维护功能。例如, 它可以返回进程的head dump (内存快照), 报告是否存在内存泄漏, 甚至允许直接执行 REPL 命令。在常规的 devops 工具 (监视产品、日志等) 无法收集特定类型的信息或您选择不购买/安装此类工具时, 需要使用此端点。黄金法则是使用专业的和外部的工具来监控和维护生产环境, 它们通常更加健壮和准确的。这就意味着, 一般的工具可能无法提取特定于node或应用程序的信息 – 例如, 如果您希望在 GC 完成一个周期时生成内存快照 – 很少有 npm 库会很乐意为您执行这个, 但流行的监控工具很可能会错过这个功能。
+
+
+
+
+### 代码示例: 使用代码生产head dump
+
+```javascript
+var heapdump = require('heapdump');
+
+router.get('/ops/headump', (req, res, next) => {
+ logger.info(`About to generate headump`);
+ heapdump.writeSnapshot(function (err, filename) {
+ console.log('headump file is ready to be sent to the caller', filename);
+ fs.readFile(filename, "utf-8", function (err, data) {
+ res.end(data);
+ });
+ });
+});
+```
+
+
+
+### 推荐资源
+
+[Getting your Node.js app production ready (Slides)](http://naugtur.pl/pres3/node2prod)
+
+▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
+
+![Getting your Node.js app production ready](/assets/images/createmaintenanceendpoint1.png "Getting your Node.js app production ready")
diff --git a/sections/production/createmaintenanceendpoint.md b/sections/production/createmaintenanceendpoint.md
index 710e5effc..405ad5bc0 100644
--- a/sections/production/createmaintenanceendpoint.md
+++ b/sections/production/createmaintenanceendpoint.md
@@ -1,45 +1,45 @@
-# Create a maintenance endpoint
-
-
-
-### One Paragraph Explainer
-
-A maintenance endpoint is a highly secure HTTP API that is part of the app code and its purpose is to be used by the ops/production team to monitor and expose maintenance functionality. For example, it can return a heap dump (memory snapshot) of the process, report whether there are some memory leaks and even allow to execute REPL commands directly. This endpoint is needed where the conventional DevOps tools (monitoring products, logs, etc) fail to gather some specific type of information or you choose not to buy/install such tools. The golden rule is using professional and external tools for monitoring and maintaining the production, these are usually more robust and accurate. That said, there are likely to be cases where the generic tools will fail to extract information that is specific to Node or to your app – for example, should you wish to generate a memory snapshot at the moment GC completed a cycle – few npm libraries will be glad to perform this for you but popular monitoring tools will likely miss this functionality. It is important to keep this endpoint private and accessibly only by admins because it can become a target of a DDOS attack.
-
-
-
-### Code example: generating a heap dump via code
-
-```javascript
-const heapdump = require('heapdump');
-
-// Check if request is authorized
-function isAuthorized(req) {
- // ...
-}
-
-router.get('/ops/heapdump', (req, res, next) => {
- if (!isAuthorized(req)) {
- return res.status(403).send('You are not authorized!');
- }
-
- logger.info('About to generate heapdump');
-
- heapdump.writeSnapshot((err, filename) => {
- console.log('heapdump file is ready to be sent to the caller', filename);
- fs.readFile(filename, "utf-8", (err, data) => {
- res.end(data);
- });
- });
-});
-```
-
-
-
-### Recommended Resources
-
-[Getting your Node.js app production ready (Slides)](http://naugtur.pl/pres3/node2prod)
-
-▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
-
-![Getting your Node.js app production ready](/assets/images/createmaintenanceendpoint1.png "Getting your Node.js app production ready")
+# Create a maintenance endpoint
+
+
+
+### One Paragraph Explainer
+
+A maintenance endpoint is a highly secure HTTP API that is part of the app code and its purpose is to be used by the ops/production team to monitor and expose maintenance functionality. For example, it can return a heap dump (memory snapshot) of the process, report whether there are some memory leaks and even allow to execute REPL commands directly. This endpoint is needed where the conventional DevOps tools (monitoring products, logs, etc) fail to gather some specific type of information or you choose not to buy/install such tools. The golden rule is using professional and external tools for monitoring and maintaining the production, these are usually more robust and accurate. That said, there are likely to be cases where the generic tools will fail to extract information that is specific to Node or to your app – for example, should you wish to generate a memory snapshot at the moment GC completed a cycle – few npm libraries will be glad to perform this for you but popular monitoring tools will likely miss this functionality. It is important to keep this endpoint private and accessibly only by admins because it can become a target of a DDOS attack.
+
+
+
+### Code example: generating a heap dump via code
+
+```javascript
+const heapdump = require('heapdump');
+
+// Check if request is authorized
+function isAuthorized(req) {
+ // ...
+}
+
+router.get('/ops/heapdump', (req, res, next) => {
+ if (!isAuthorized(req)) {
+ return res.status(403).send('You are not authorized!');
+ }
+
+ logger.info('About to generate heapdump');
+
+ heapdump.writeSnapshot((err, filename) => {
+ console.log('heapdump file is ready to be sent to the caller', filename);
+ fs.readFile(filename, "utf-8", (err, data) => {
+ res.end(data);
+ });
+ });
+});
+```
+
+
+
+### Recommended Resources
+
+[Getting your Node.js app production ready (Slides)](http://naugtur.pl/pres3/node2prod)
+
+▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
+
+![Getting your Node.js app production ready](/assets/images/createmaintenanceendpoint1.png "Getting your Node.js app production ready")
diff --git a/sections/production/delegatetoproxy.chinese.md b/sections/production/delegatetoproxy.chinese.md
index 7c3c210d5..e5c0f8d60 100644
--- a/sections/production/delegatetoproxy.chinese.md
+++ b/sections/production/delegatetoproxy.chinese.md
@@ -1,54 +1,54 @@
-# 委托任何可能的 (例如静态内容, gzip) 到反向代理
-
-
-
-
-### 一段解释
-
-这是非常诱人的 —— 去过度使用(cargo-cult)Express和使用其丰富的中间件提供网络相关的任务, 如服务静态文件, gzip 编码, throttling requests, SSL termination等。由于它的单线程模型将使 CPU 长时间处于忙碌状态 (请记住, node的执行模型针对短任务或异步 IO 相关任务进行了优化), 因此这是一个性能消耗。一个更好的方法是使用一个专注于处理网络任务的工具 – 最流行的是 nginx 和 HAproxy, 也被最大的云供应商使用, 以减轻在node.js进程上的面临的负载。
-
-
-
-
-### 代码示例 – 使用 nginx 压缩服务器响应
-
-```
-# 配置 gzip 压缩
-gzip on;
-gzip_comp_level 6;
-gzip_vary on;
-
-# 配置 upstream
-upstream myApplication {
- server 127.0.0.1:3000;
- server 127.0.0.1:3001;
- keepalive 64;
-}
-
-#定义 web server
-server {
- # configure server with ssl and error pages
- listen 80;
- listen 443 ssl;
- ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
- error_page 502 /errors/502.html;
-
- # handling static content
- location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
- root /usr/local/silly_face_society/node/public;
- access_log off;
- expires max;
-}
-```
-
-
-
-### 其他博客作者说什么
-
-* 摘自博客 [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
-> …很容易落入这个陷阱 – 你看到一个包比如Express,并认为 "真棒!让我们开始吧" – 你编写了代码, 你实现了一个应用程序, 做你想要的。这很好, 老实说, 你赢得了很多的战斗。但是, 如果您将应用程序上传到服务器并让它侦听 HTTP 端口, 您将会输掉这场战争, 因为您忘记了一个非常关键的事情: node不是 web 服务器。**一旦任何流量开始访问你的应用程序, 你会发现事情开始出错: 连接被丢弃, 资源停止服务, 或在最坏的情况下, 你的服务器崩溃。你正在做的是试图让node处理所有复杂的事情, 而这些事情让一个已验证过了的 web 服务器来处理,再好也不会过。为什么要重新造轮子?It**
-> **这只是为了一个请求, 为了一个图像, 并铭记在脑海中, 您的应用程序可以用于重要的东西, 如读取数据库或处理复杂的逻辑; 为了方便起见, 你为什么要削弱你的应用?**
-
-
-* 摘自博客 [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
-> 虽然 express.js 通过一些connect中间件处理静态文件, 但你不应该使用它。**Nginx 可以更好地处理静态文件, 并可以防止请求动态内容堵塞我们的node进程**…
+# 委托任何可能的 (例如静态内容, gzip) 到反向代理
+
+
+
+
+### 一段解释
+
+这是非常诱人的 —— 去过度使用(cargo-cult)Express和使用其丰富的中间件提供网络相关的任务, 如服务静态文件, gzip 编码, throttling requests, SSL termination等。由于它的单线程模型将使 CPU 长时间处于忙碌状态 (请记住, node的执行模型针对短任务或异步 IO 相关任务进行了优化), 因此这是一个性能消耗。一个更好的方法是使用一个专注于处理网络任务的工具 – 最流行的是 nginx 和 HAproxy, 也被最大的云供应商使用, 以减轻在node.js进程上的面临的负载。
+
+
+
+
+### 代码示例 – 使用 nginx 压缩服务器响应
+
+```
+# 配置 gzip 压缩
+gzip on;
+gzip_comp_level 6;
+gzip_vary on;
+
+# 配置 upstream
+upstream myApplication {
+ server 127.0.0.1:3000;
+ server 127.0.0.1:3001;
+ keepalive 64;
+}
+
+#定义 web server
+server {
+ # configure server with ssl and error pages
+ listen 80;
+ listen 443 ssl;
+ ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
+ error_page 502 /errors/502.html;
+
+ # handling static content
+ location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
+ root /usr/local/silly_face_society/node/public;
+ access_log off;
+ expires max;
+}
+```
+
+
+
+### 其他博客作者说什么
+
+* 摘自博客 [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
+> …很容易落入这个陷阱 – 你看到一个包比如Express,并认为 "真棒!让我们开始吧" – 你编写了代码, 你实现了一个应用程序, 做你想要的。这很好, 老实说, 你赢得了很多的战斗。但是, 如果您将应用程序上传到服务器并让它侦听 HTTP 端口, 您将会输掉这场战争, 因为您忘记了一个非常关键的事情: node不是 web 服务器。**一旦任何流量开始访问你的应用程序, 你会发现事情开始出错: 连接被丢弃, 资源停止服务, 或在最坏的情况下, 你的服务器崩溃。你正在做的是试图让node处理所有复杂的事情, 而这些事情让一个已验证过了的 web 服务器来处理,再好也不会过。为什么要重新造轮子?It**
+> **这只是为了一个请求, 为了一个图像, 并铭记在脑海中, 您的应用程序可以用于重要的东西, 如读取数据库或处理复杂的逻辑; 为了方便起见, 你为什么要削弱你的应用?**
+
+
+* 摘自博客 [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+> 虽然 express.js 通过一些connect中间件处理静态文件, 但你不应该使用它。**Nginx 可以更好地处理静态文件, 并可以防止请求动态内容堵塞我们的node进程**…
diff --git a/sections/production/delegatetoproxy.md b/sections/production/delegatetoproxy.md
index c7ed98d78..9c31d7e59 100644
--- a/sections/production/delegatetoproxy.md
+++ b/sections/production/delegatetoproxy.md
@@ -1,51 +1,51 @@
-# Delegate anything possible (e.g. static content, gzip) to a reverse proxy
-
-
-
-### One Paragraph Explainer
-
-It’s very tempting to cargo-cult Express and use its rich middleware offering for networking related tasks like serving static files, gzip encoding, throttling requests, SSL termination, etc. This is a performance kill due to its single threaded model which will keep the CPU busy for long periods (Remember, Node’s execution model is optimized for short tasks or async IO related tasks). A better approach is to use a tool that expertise in networking tasks – the most popular are nginx and HAproxy which are also used by the biggest cloud vendors to lighten the incoming load on node.js processes.
-
-
-
-### Nginx Config Example – Using nginx to compress server responses
-
-```nginx
-# configure gzip compression
-gzip on;
-gzip_comp_level 6;
-gzip_vary on;
-
-# configure upstream
-upstream myApplication {
- server 127.0.0.1:3000;
- server 127.0.0.1:3001;
- keepalive 64;
-}
-
-#defining web server
-server {
- # configure server with ssl and error pages
- listen 80;
- listen 443 ssl;
- ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
- error_page 502 /errors/502.html;
-
- # handling static content
- location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
- root /usr/local/silly_face_society/node/public;
- access_log off;
- expires max;
-}
-```
-
-
-
-### What Other Bloggers Say
-
-* From the blog [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
-> …It’s very easy to fall into this trap – You see a package like Express and think “Awesome! Let’s get started” – you code away and you’ve got an application that does what you want. This is excellent and, to be honest, you’ve won a lot of the battle. However, you will lose the war if you upload your app to a server and have it listen on your HTTP port because you’ve forgotten a very crucial thing: Node is not a web server. **As soon as any volume of traffic starts to hit your application, you’ll notice that things start to go wrong: connections are dropped, assets stop being served or, at the very worst, your server crashes. What you’re doing is attempting to have Node deal with all of the complicated things that a proven web server does really well. Why reinvent the wheel?**
-> **This is just for one request, for one image and bearing in mind this is the memory that your application could be used for important stuff like reading a database or handling complicated logic; why would you cripple your application for the sake of convenience?**
-
-* From the blog [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
-> Although express.js has built-in static file handling through some connect middleware, you should never use it. **Nginx can do a much better job of handling static files and can prevent requests for non-dynamic content from clogging our node processes**…
+# Delegate anything possible (e.g. static content, gzip) to a reverse proxy
+
+
+
+### One Paragraph Explainer
+
+It’s very tempting to cargo-cult Express and use its rich middleware offering for networking related tasks like serving static files, gzip encoding, throttling requests, SSL termination, etc. This is a performance kill due to its single threaded model which will keep the CPU busy for long periods (Remember, Node’s execution model is optimized for short tasks or async IO related tasks). A better approach is to use a tool that expertise in networking tasks – the most popular are nginx and HAproxy which are also used by the biggest cloud vendors to lighten the incoming load on node.js processes.
+
+
+
+### Nginx Config Example – Using nginx to compress server responses
+
+```nginx
+# configure gzip compression
+gzip on;
+gzip_comp_level 6;
+gzip_vary on;
+
+# configure upstream
+upstream myApplication {
+ server 127.0.0.1:3000;
+ server 127.0.0.1:3001;
+ keepalive 64;
+}
+
+#defining web server
+server {
+ # configure server with ssl and error pages
+ listen 80;
+ listen 443 ssl;
+ ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
+ error_page 502 /errors/502.html;
+
+ # handling static content
+ location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
+ root /usr/local/silly_face_society/node/public;
+ access_log off;
+ expires max;
+}
+```
+
+
+
+### What Other Bloggers Say
+
+* From the blog [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
+> …It’s very easy to fall into this trap – You see a package like Express and think “Awesome! Let’s get started” – you code away and you’ve got an application that does what you want. This is excellent and, to be honest, you’ve won a lot of the battle. However, you will lose the war if you upload your app to a server and have it listen on your HTTP port because you’ve forgotten a very crucial thing: Node is not a web server. **As soon as any volume of traffic starts to hit your application, you’ll notice that things start to go wrong: connections are dropped, assets stop being served or, at the very worst, your server crashes. What you’re doing is attempting to have Node deal with all of the complicated things that a proven web server does really well. Why reinvent the wheel?**
+> **This is just for one request, for one image and bearing in mind this is the memory that your application could be used for important stuff like reading a database or handling complicated logic; why would you cripple your application for the sake of convenience?**
+
+* From the blog [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+> Although express.js has built-in static file handling through some connect middleware, you should never use it. **Nginx can do a much better job of handling static files and can prevent requests for non-dynamic content from clogging our node processes**…
diff --git a/sections/production/detectvulnerabilities.chinese.md b/sections/production/detectvulnerabilities.chinese.md
index 2a3628072..1692915b5 100644
--- a/sections/production/detectvulnerabilities.chinese.md
+++ b/sections/production/detectvulnerabilities.chinese.md
@@ -1,17 +1,17 @@
-# 使用工具自动检测有漏洞的依赖项
-
-
-
-### 一段解释
-
-现代node应用有数十个, 有时是数以百计的依赖。如果您使用的任何依赖项存在已知的安全漏洞, 您的应用也很容易受到攻击。
-下列工具自动检查依赖项中的已知安全漏洞:
-[nsp](https://www.npmjs.com/package/nsp) - Node 安全工程
-[snyk](https://snyk.io/) - 持续查找和修复依赖中的漏洞
-
-
-
-### 其他博主说什么
-摘自博客 [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) :
-
-> ...被用来管理您应用的依赖是强大且方便的。但是, 您使用的依赖包可能存在严重的安全漏洞, 也会影响您的应用。您的应用的安全性仅仅与您的依赖组件中的 "最薄弱的一环" 一样严重。幸运的是, 您可以使用两种有用的工具来确保您使用的第三方库: ** 和 requireSafe。这两种工具在很大程度上都是一样的, 所以使用两种方法都可能过于夸张, 但 "安全比抱歉" 更安全...
+# 使用工具自动检测有漏洞的依赖项
+
+
+
+### 一段解释
+
+现代node应用有数十个, 有时是数以百计的依赖。如果您使用的任何依赖项存在已知的安全漏洞, 您的应用也很容易受到攻击。
+下列工具自动检查依赖项中的已知安全漏洞:
+[nsp](https://www.npmjs.com/package/nsp) - Node 安全工程
+[snyk](https://snyk.io/) - 持续查找和修复依赖中的漏洞
+
+
+
+### 其他博主说什么
+摘自博客 [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) :
+
+> ...被用来管理您应用的依赖是强大且方便的。但是, 您使用的依赖包可能存在严重的安全漏洞, 也会影响您的应用。您的应用的安全性仅仅与您的依赖组件中的 "最薄弱的一环" 一样严重。幸运的是, 您可以使用两种有用的工具来确保您使用的第三方库: ** 和 requireSafe。这两种工具在很大程度上都是一样的, 所以使用两种方法都可能过于夸张, 但 "安全比抱歉" 更安全...
diff --git a/sections/production/detectvulnerabilities.md b/sections/production/detectvulnerabilities.md
index 2a0c0fb5d..db3c6273f 100644
--- a/sections/production/detectvulnerabilities.md
+++ b/sections/production/detectvulnerabilities.md
@@ -1,20 +1,20 @@
-# Use tools that automatically detect vulnerable dependencies
-
-
-
-### One Paragraph Explainer
-
-Modern Node applications have tens and sometimes hundreds of dependencies. If any of the dependencies
-you use has a known security vulnerability your app is vulnerable as well.
-The following tools automatically check for known security vulnerabilities in your dependencies:
-
-- [npm audit](https://docs.npmjs.com/cli/audit) - npm audit
-- [snyk](https://snyk.io/) - Continuously find & fix vulnerabilities in your dependencies
-
-
-
-### What Other Bloggers Say
-
-From the [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) blog:
-
-> ...Using to manage your application’s dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the “weakest link” in your dependencies. Fortunately, there are two helpful tools you can use to ensure the third-party packages you use: and requireSafe. These two tools do largely the same thing, so using both might be overkill, but “better safe than sorry” are words to live by when it comes to security...
+# Use tools that automatically detect vulnerable dependencies
+
+
+
+### One Paragraph Explainer
+
+Modern Node applications have tens and sometimes hundreds of dependencies. If any of the dependencies
+you use has a known security vulnerability your app is vulnerable as well.
+The following tools automatically check for known security vulnerabilities in your dependencies:
+
+- [npm audit](https://docs.npmjs.com/cli/audit) - npm audit
+- [snyk](https://snyk.io/) - Continuously find & fix vulnerabilities in your dependencies
+
+
+
+### What Other Bloggers Say
+
+From the [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) blog:
+
+> ...Using to manage your application’s dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the “weakest link” in your dependencies. Fortunately, there are two helpful tools you can use to ensure the third-party packages you use: and requireSafe. These two tools do largely the same thing, so using both might be overkill, but “better safe than sorry” are words to live by when it comes to security...
diff --git a/sections/production/frontendout.chinese.md b/sections/production/frontendout.chinese.md
index f904829c9..c2e97f3e8 100644
--- a/sections/production/frontendout.chinese.md
+++ b/sections/production/frontendout.chinese.md
@@ -1,44 +1,44 @@
-# 在node外处理您的前端资产
-
-
-
-
-### 一段解释
-
-在一个经典的 web 应用中,后端返回前端资源/图片给浏览器, 在node的世界,一个非常常见的方法是使用 Express 静态中间件, 以数据流的形式把静态文件返回到客户端。但是, node并不是一个典型的 web应用, 因为它使用单个线程,对于同时服务多个文件,未经过任何优化。相反, 考虑使用反向代理、云存储或 CDN (例如Nginx, AWS S3, Azure Blob 存储等), 对于这项任务, 它们做了很多优化,并获得更好的吞吐量。例如, 像 nginx 这样的专业中间件在文件系统和网卡之间的直接挂钩, 并使用多线程方法来减少多个请求之间的干预。
-
-您的最佳解决方案可能是以下形式之一:
-1. 反向代理 – 您的静态文件将位于您的node应用的旁边, 只有对静态文件文件夹的请求才会由位于您的node应用前面的代理 (如 nginx) 提供服务。使用这种方法, 您的node应用负责部署静态文件, 而不是为它们提供服务。你的前端的同事会喜欢这种方法, 因为它可以防止 cross-origin-requests 的前端请求。
-2. 云存储 – 您的静态文件将不会是您的node应用内容的一部分, 他们将被上传到服务, 如 AWS S3, Azure BlobStorage, 或其他类似的服务, 这些服务为这个任务而生。使用这种方法, 您的node应用即不负责部署静态文件, 也不为它们服务, 因此, 在node和前端资源之间完全解耦, 这是由不同的团队处理。
-
-
-
-
-### 代码示例: 对于静态文件,典型的nginx配置
-
-```
-# configure gzip compression
-gzip on;
-keepalive 64;
-
-# defining web server
-server {
-listen 80;
-listen 443 ssl;
-
-# handle static content
-location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
-root /usr/local/silly_face_society/node/public;
-access_log off;
-expires max;
-}
-```
-
-
-
-### 其它博主说了什么
-摘自博客 [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
-
->…开发模式下, 您可以使用 [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) 服务静态文件. 但是不要在生产中这样做, 因为这个函数为了每个文件请求,必须从文件系统中读取, 因此它会遇到很大的延迟, 并影响应用程序的整体性能。请注意, res.sendFile() 没有用系统调用 sendFile 实现, 这将使它更高效。相反, 使用serve-static中间件 (或类似的东西), 在express应用中服务文件,这是优化了的。更佳的选择是使用反向代理来服务静态文件; 有关详细信息, 请参阅使用反向代理…
-
-
+# 在node外处理您的前端资产
+
+
+
+
+### 一段解释
+
+在一个经典的 web 应用中,后端返回前端资源/图片给浏览器, 在node的世界,一个非常常见的方法是使用 Express 静态中间件, 以数据流的形式把静态文件返回到客户端。但是, node并不是一个典型的 web应用, 因为它使用单个线程,对于同时服务多个文件,未经过任何优化。相反, 考虑使用反向代理、云存储或 CDN (例如Nginx, AWS S3, Azure Blob 存储等), 对于这项任务, 它们做了很多优化,并获得更好的吞吐量。例如, 像 nginx 这样的专业中间件在文件系统和网卡之间的直接挂钩, 并使用多线程方法来减少多个请求之间的干预。
+
+您的最佳解决方案可能是以下形式之一:
+1. 反向代理 – 您的静态文件将位于您的node应用的旁边, 只有对静态文件文件夹的请求才会由位于您的node应用前面的代理 (如 nginx) 提供服务。使用这种方法, 您的node应用负责部署静态文件, 而不是为它们提供服务。你的前端的同事会喜欢这种方法, 因为它可以防止 cross-origin-requests 的前端请求。
+2. 云存储 – 您的静态文件将不会是您的node应用内容的一部分, 他们将被上传到服务, 如 AWS S3, Azure BlobStorage, 或其他类似的服务, 这些服务为这个任务而生。使用这种方法, 您的node应用即不负责部署静态文件, 也不为它们服务, 因此, 在node和前端资源之间完全解耦, 这是由不同的团队处理。
+
+
+
+
+### 代码示例: 对于静态文件,典型的nginx配置
+
+```
+# configure gzip compression
+gzip on;
+keepalive 64;
+
+# defining web server
+server {
+listen 80;
+listen 443 ssl;
+
+# handle static content
+location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
+root /usr/local/silly_face_society/node/public;
+access_log off;
+expires max;
+}
+```
+
+
+
+### 其它博主说了什么
+摘自博客 [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
+
+>…开发模式下, 您可以使用 [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) 服务静态文件. 但是不要在生产中这样做, 因为这个函数为了每个文件请求,必须从文件系统中读取, 因此它会遇到很大的延迟, 并影响应用程序的整体性能。请注意, res.sendFile() 没有用系统调用 sendFile 实现, 这将使它更高效。相反, 使用serve-static中间件 (或类似的东西), 在express应用中服务文件,这是优化了的。更佳的选择是使用反向代理来服务静态文件; 有关详细信息, 请参阅使用反向代理…
+
+
diff --git a/sections/production/frontendout.md b/sections/production/frontendout.md
index 180bee4b2..148bd344d 100644
--- a/sections/production/frontendout.md
+++ b/sections/production/frontendout.md
@@ -1,45 +1,45 @@
-# Get your frontend assets out of Node
-
-
-
-### One Paragraph Explainer
-
-In a classic web app the backend serves the frontend/graphics to the browser, a very common approach in the Node’s world is to use Express static middleware for streamlining static files to the client. BUT – Node is not a typical webapp as it utilizes a single thread that is not optimized to serve many files at once. Instead, consider using a reverse proxy (e.g. nginx, HAProxy), cloud storage or CDN (e.g. AWS S3, Azure Blob Storage, etc) that utilizes many optimizations for this task and gain much better throughput. For example, specialized middleware like nginx embodies direct hooks between the file system and the network card and uses a multi-threaded approach to minimize intervention among multiple requests.
-
-Your optimal solution might wear one of the following forms:
-
-1. Using a reverse proxy – your static files will be located right next to your Node application, only requests to the static files folder will be served by a proxy that sits in front of your Node app such as nginx. Using this approach, your Node app is responsible deploying the static files but not to serve them. Your frontend’s colleague will love this approach as it prevents cross-origin-requests from the frontend.
-
-2. Cloud storage – your static files will NOT be part of your Node app content, they will be uploaded to services like AWS S3, Azure BlobStorage, or other similar services that were born for this mission. Using this approach, your Node app is not responsible deploying the static files neither to serve them, hence a complete decoupling is drawn between Node and the Frontend which is anyway handled by different teams.
-
-
-
-### Configuration example: typical nginx configuration for serving static files
-
-```nginx
-# configure gzip compression
-gzip on;
-keepalive 64;
-
-# defining web server
-server {
-listen 80;
-listen 443 ssl;
-
-# handle static content
-location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
-root /usr/local/silly_face_society/node/public;
-access_log off;
-expires max;
-}
-```
-
-
-
-### What Other Bloggers Say
-
-From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
-
->…In development, you can use [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) to serve static files. But don’t do this in production, because this function has to read from the file system for every file request, so it will encounter significant latency and affect the overall performance of the app. Note that res.sendFile() is not implemented with the sendfile system call, which would make it far more efficient. Instead, use serve-static middleware (or something equivalent), that is optimized for serving files for Express apps. An even better option is to use a reverse proxy to serve static files; see Use a reverse proxy for more information…
-
-
+# Get your frontend assets out of Node
+
+
+
+### One Paragraph Explainer
+
+In a classic web app the backend serves the frontend/graphics to the browser, a very common approach in the Node’s world is to use Express static middleware for streamlining static files to the client. BUT – Node is not a typical webapp as it utilizes a single thread that is not optimized to serve many files at once. Instead, consider using a reverse proxy (e.g. nginx, HAProxy), cloud storage or CDN (e.g. AWS S3, Azure Blob Storage, etc) that utilizes many optimizations for this task and gain much better throughput. For example, specialized middleware like nginx embodies direct hooks between the file system and the network card and uses a multi-threaded approach to minimize intervention among multiple requests.
+
+Your optimal solution might wear one of the following forms:
+
+1. Using a reverse proxy – your static files will be located right next to your Node application, only requests to the static files folder will be served by a proxy that sits in front of your Node app such as nginx. Using this approach, your Node app is responsible deploying the static files but not to serve them. Your frontend’s colleague will love this approach as it prevents cross-origin-requests from the frontend.
+
+2. Cloud storage – your static files will NOT be part of your Node app content, they will be uploaded to services like AWS S3, Azure BlobStorage, or other similar services that were born for this mission. Using this approach, your Node app is not responsible deploying the static files neither to serve them, hence a complete decoupling is drawn between Node and the Frontend which is anyway handled by different teams.
+
+
+
+### Configuration example: typical nginx configuration for serving static files
+
+```nginx
+# configure gzip compression
+gzip on;
+keepalive 64;
+
+# defining web server
+server {
+listen 80;
+listen 443 ssl;
+
+# handle static content
+location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
+root /usr/local/silly_face_society/node/public;
+access_log off;
+expires max;
+}
+```
+
+
+
+### What Other Bloggers Say
+
+From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
+
+>…In development, you can use [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) to serve static files. But don’t do this in production, because this function has to read from the file system for every file request, so it will encounter significant latency and affect the overall performance of the app. Note that res.sendFile() is not implemented with the sendfile system call, which would make it far more efficient. Instead, use serve-static middleware (or something equivalent), that is optimized for serving files for Express apps. An even better option is to use a reverse proxy to serve static files; see Use a reverse proxy for more information…
+
+
diff --git a/sections/production/guardprocess.chinese.md b/sections/production/guardprocess.chinese.md
index 52ec578a9..861be1015 100644
--- a/sections/production/guardprocess.chinese.md
+++ b/sections/production/guardprocess.chinese.md
@@ -1,19 +1,19 @@
-# 保护和重启你的失败进程(用正确的工具)
-
-
-
-
-### 一段解释
-
-在基本级别,必须保护Node进程并在出现故障时重新启动。简单地说, 对于那些小应用和不使用容器的应用 – 像这样的工具 [PM2](https://www.npmjs.com/package/pm2-docker) 是完美的,因为它们带来简单性,重启能力以及与Node的丰富集成。其他具有强大Linux技能的人可能会使用systemd并将Node作为服务运行。对于使用Docker或任何容器技术的应用程序来说,事情会变得更加有趣,因为集群管理和协调工具(比如[AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html ),[Kubernetes](https://kubernetes.io/)等)会完成部署,监视和保持容器健康的功能。拥有所有丰富的集群管理功能(包括容器重启),为什么还要与其他工具(如PM2)混为一谈?这里并没有可靠的答案。将PM2保留在容器(主要是其容器特定版本[pm2-docker](https://www.npmjs.com/package/pm2-docker))中作为第一个守护层是有充分的理由的 - 在主机容器要求正常重启时,重新启动更快,并提供特定于node的功能比如向代码发送信号。其他选择可能会避免不必要的层。总而言之,没有一个解决方案适合所有人,但了解这些选择是最重要的。
-
-
-
-
-### 其它博主说了什么
-
-* 来自[Express 生成最佳实践](https://expressjs.com/en/advanced/best-practice-performance.html):
-> ... 在开发中,您只需从命令行使用node.js或类似的东西启动您的应用程序。**但是在生产中这样做是一种灾难。 如果应用程序崩溃,它将掉线**,直到您重新启动它。要确保应用程序在崩溃时重新启动,请使用进程管理器。流程管理器是便于部署的应用程序的“容器”,提供高可用性,并使您能够在运行时管理应用程序。
-
-* 摘自 the Medium blog post [了解节点集群](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
-> ...了解Docker-Land中的NodeJS集群“Docker容器”是流线型的轻量级虚拟环境,旨在将流程简化为最低限度。管理和协调自己资源的流程不再有价值。**相反,像Kubernetes,Mesos和Cattle这样的管理层已经普及了这些资源应该在整个基础设施范围进行管理的概念**。CPU和内存资源由“调度器”分配,网络资源由堆栈提供的负载均衡器管理。
+# 保护和重启你的失败进程(用正确的工具)
+
+
+
+
+### 一段解释
+
+在基本级别,必须保护Node进程并在出现故障时重新启动。简单地说, 对于那些小应用和不使用容器的应用 – 像这样的工具 [PM2](https://www.npmjs.com/package/pm2-docker) 是完美的,因为它们带来简单性,重启能力以及与Node的丰富集成。其他具有强大Linux技能的人可能会使用systemd并将Node作为服务运行。对于使用Docker或任何容器技术的应用程序来说,事情会变得更加有趣,因为集群管理和协调工具(比如[AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html ),[Kubernetes](https://kubernetes.io/)等)会完成部署,监视和保持容器健康的功能。拥有所有丰富的集群管理功能(包括容器重启),为什么还要与其他工具(如PM2)混为一谈?这里并没有可靠的答案。将PM2保留在容器(主要是其容器特定版本[pm2-docker](https://www.npmjs.com/package/pm2-docker))中作为第一个守护层是有充分的理由的 - 在主机容器要求正常重启时,重新启动更快,并提供特定于node的功能比如向代码发送信号。其他选择可能会避免不必要的层。总而言之,没有一个解决方案适合所有人,但了解这些选择是最重要的。
+
+
+
+
+### 其它博主说了什么
+
+* 来自[Express 生成最佳实践](https://expressjs.com/en/advanced/best-practice-performance.html):
+> ... 在开发中,您只需从命令行使用node.js或类似的东西启动您的应用程序。**但是在生产中这样做是一种灾难。 如果应用程序崩溃,它将掉线**,直到您重新启动它。要确保应用程序在崩溃时重新启动,请使用进程管理器。流程管理器是便于部署的应用程序的“容器”,提供高可用性,并使您能够在运行时管理应用程序。
+
+* 摘自 the Medium blog post [了解节点集群](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
+> ...了解Docker-Land中的NodeJS集群“Docker容器”是流线型的轻量级虚拟环境,旨在将流程简化为最低限度。管理和协调自己资源的流程不再有价值。**相反,像Kubernetes,Mesos和Cattle这样的管理层已经普及了这些资源应该在整个基础设施范围进行管理的概念**。CPU和内存资源由“调度器”分配,网络资源由堆栈提供的负载均衡器管理。
diff --git a/sections/production/guardprocess.md b/sections/production/guardprocess.md
index ee76974bf..719e85a73 100644
--- a/sections/production/guardprocess.md
+++ b/sections/production/guardprocess.md
@@ -1,17 +1,17 @@
-# Guard and restart your process upon failure (using the right tool)
-
-
-
-### One Paragraph Explainer
-
-At the base level, Node processes must be guarded and restarted upon failures. Simply put, for small apps and those who don’t use containers – tools like [PM2](https://www.npmjs.com/package/pm2-docker) are perfect as they bring simplicity, restarting capabilities and also rich integration with Node. Others with strong Linux skills might use systemd and run Node as a service. Things get more interesting for apps that use Docker or any container technology since those are usually accompanied by cluster management and orchestration tools (e.g. [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/), etc) that deploy, monitor and heal containers. Having all those rich cluster management features including container restart, why mess up with other tools like PM2? There’s no bulletproof answer. There are good reasons to keep PM2 within containers (mostly its containers specific version [pm2-docker](https://www.npmjs.com/package/pm2-docker)) as the first guarding tier – it’s much faster to restart a process and provide Node-specific features like flagging to the code when the hosting container asks to gracefully restart. Other might choose to avoid unnecessary layers. To conclude this write-up, no solution suits them all and getting to know the options is the important thing
-
-
-
-### What Other Bloggers Say
-
-* From the [Express Production Best Practices](https://expressjs.com/en/advanced/best-practice-performance.html):
-> ... In development, you started your app simply from the command line with node server.js or something similar. **But doing this in production is a recipe for disaster. If the app crashes, it will be offline** until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a “container” for applications that facilitate deployment, provides high availability, and enables you to manage the application at runtime.
-
-* From the Medium blog post [Understanding Node Clustering](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
-> ... Understanding Node.js Clustering in Docker-Land “Docker containers are streamlined, lightweight virtual environments, designed to simplify processes to their bare minimum. Processes that manage and coordinate their own resources are no longer as valuable. **Instead, management stacks like Kubernetes, Mesos, and Cattle have popularized the concept that these resources should be managed infrastructure-wide**. CPU and memory resources are allocated by “schedulers”, and network resources are managed by stack-provided load balancers.
+# Guard and restart your process upon failure (using the right tool)
+
+
+
+### One Paragraph Explainer
+
+At the base level, Node processes must be guarded and restarted upon failures. Simply put, for small apps and those who don’t use containers – tools like [PM2](https://www.npmjs.com/package/pm2-docker) are perfect as they bring simplicity, restarting capabilities and also rich integration with Node. Others with strong Linux skills might use systemd and run Node as a service. Things get more interesting for apps that use Docker or any container technology since those are usually accompanied by cluster management and orchestration tools (e.g. [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/), etc) that deploy, monitor and heal containers. Having all those rich cluster management features including container restart, why mess up with other tools like PM2? There’s no bulletproof answer. There are good reasons to keep PM2 within containers (mostly its containers specific version [pm2-docker](https://www.npmjs.com/package/pm2-docker)) as the first guarding tier – it’s much faster to restart a process and provide Node-specific features like flagging to the code when the hosting container asks to gracefully restart. Other might choose to avoid unnecessary layers. To conclude this write-up, no solution suits them all and getting to know the options is the important thing
+
+
+
+### What Other Bloggers Say
+
+* From the [Express Production Best Practices](https://expressjs.com/en/advanced/best-practice-performance.html):
+> ... In development, you started your app simply from the command line with node server.js or something similar. **But doing this in production is a recipe for disaster. If the app crashes, it will be offline** until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a “container” for applications that facilitate deployment, provides high availability, and enables you to manage the application at runtime.
+
+* From the Medium blog post [Understanding Node Clustering](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
+> ... Understanding Node.js Clustering in Docker-Land “Docker containers are streamlined, lightweight virtual environments, designed to simplify processes to their bare minimum. Processes that manage and coordinate their own resources are no longer as valuable. **Instead, management stacks like Kubernetes, Mesos, and Cattle have popularized the concept that these resources should be managed infrastructure-wide**. CPU and memory resources are allocated by “schedulers”, and network resources are managed by stack-provided load balancers.
diff --git a/sections/production/lockdependencies.chinese.md b/sections/production/lockdependencies.chinese.md
index 34436e74e..e8a3e107e 100644
--- a/sections/production/lockdependencies.chinese.md
+++ b/sections/production/lockdependencies.chinese.md
@@ -1,73 +1,73 @@
-# 锁定依赖版本
-
-
-
-
-### 一段解释
-
-
-
-您的代码依赖于许多外部包,假设它“需要”和使用momentjs-2.1.4,默认情况下,当布署到生产中时,npm可能会获得momentjs 2.1.5,但不幸的是,这将带来一些新的bug。使用npm配置文件和设置 ```–save-exact=true``` 指示npm去完成安装,以便下次运行 ```npm install```(在生产或在Docker容器中,您计划将其用于测试)时,将获取相同的依赖版本。另一种可选择受欢迎的方法是使用一个shrinkwrap文件(很容易使用npm生成)指出应该安装哪些包和版本,这样就不需要环境来获取新版本了。
-
-* **更新:** 在npm5中,使用.shrinkwrap依赖项会被自动锁定。Yarn,一个新兴的包管理器,默认情况下也会锁定依赖项。
-
-
-
-
-### 代码示例: .npmrc文件指示npm使用精确的版本
-
-```
-// 在项目目录上保存这个为.npmrc 文件
-save-exact:true
-```
-
-
-
-### 代码示例: shirnkwrap.json文件获取准确的依赖关系树
-
-```javascript
-{
- "name": "A",
- "dependencies": {
- "B": {
- "version": "0.0.1",
- "dependencies": {
- "C": {
- "version": "0.1.0"
- }
- }
- }
- }
-}
-```
-
-
-
-### 代码示例: npm5依赖锁文件 - package.json
-
-```javascript
-{
- "name": "package-name",
- "version": "1.0.0",
- "lockfileVersion": 1,
- "dependencies": {
- "cacache": {
- "version": "9.2.6",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
- "integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
- },
- "duplexify": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
- "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
- "dependencies": {
- "end-of-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
- "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
- }
- }
- }
- }
-}
-```
+# 锁定依赖版本
+
+
+
+
+### 一段解释
+
+
+
+您的代码依赖于许多外部包,假设它“需要”和使用momentjs-2.1.4,默认情况下,当布署到生产中时,npm可能会获得momentjs 2.1.5,但不幸的是,这将带来一些新的bug。使用npm配置文件和设置 ```–save-exact=true``` 指示npm去完成安装,以便下次运行 ```npm install```(在生产或在Docker容器中,您计划将其用于测试)时,将获取相同的依赖版本。另一种可选择受欢迎的方法是使用一个shrinkwrap文件(很容易使用npm生成)指出应该安装哪些包和版本,这样就不需要环境来获取新版本了。
+
+* **更新:** 在npm5中,使用.shrinkwrap依赖项会被自动锁定。Yarn,一个新兴的包管理器,默认情况下也会锁定依赖项。
+
+
+
+
+### 代码示例: .npmrc文件指示npm使用精确的版本
+
+```
+// 在项目目录上保存这个为.npmrc 文件
+save-exact:true
+```
+
+
+
+### 代码示例: shirnkwrap.json文件获取准确的依赖关系树
+
+```javascript
+{
+ "name": "A",
+ "dependencies": {
+ "B": {
+ "version": "0.0.1",
+ "dependencies": {
+ "C": {
+ "version": "0.1.0"
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+### 代码示例: npm5依赖锁文件 - package.json
+
+```javascript
+{
+ "name": "package-name",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "dependencies": {
+ "cacache": {
+ "version": "9.2.6",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
+ "integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
+ },
+ "duplexify": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
+ "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
+ "dependencies": {
+ "end-of-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
+ "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
+ }
+ }
+ }
+ }
+}
+```
diff --git a/sections/production/lockdependencies.md b/sections/production/lockdependencies.md
index fd0430d85..4bacd048a 100644
--- a/sections/production/lockdependencies.md
+++ b/sections/production/lockdependencies.md
@@ -1,69 +1,69 @@
-# Lock dependencies
-
-
-
-### One Paragraph Explainer
-
-Your code depends on many external packages, let’s say it ‘requires’ and use momentjs-2.1.4, then by default when you deploy to production npm might fetch momentjs 2.1.5 which unfortunately brings some new bugs to the table. Using npm config files and the argument ```–save-exact=true``` instructs npm to refer to the *exact* same version that was installed so the next time you run ```npm install``` (in production or within a Docker container you plan to ship forward for testing) the same dependent version will be fetched. An alternative and popular approach is using a `.shrinkwrap` file (easily generated using npm) that states exactly which packages and versions should be installed so no environment can get tempted to fetch newer versions than expected.
-
-* **Update:** as of npm 5, dependencies are locked automatically using .shrinkwrap. Yarn, an emerging package manager, also locks down dependencies by default.
-
-
-
-### Code example: .npmrc file that instructs npm to use exact versions
-
-```npmrc
-// save this as .npmrc file on the project directory
-save-exact:true
-```
-
-
-
-### Code example: shrinkwrap.json file that distills the exact dependency tree
-
-```json
-{
- "name": "A",
- "dependencies": {
- "B": {
- "version": "0.0.1",
- "dependencies": {
- "C": {
- "version": "0.1.0"
- }
- }
- }
- }
-}
-```
-
-
-
-### Code example: npm 5 dependencies lock file – package.json
-
-```json
-{
- "name": "package-name",
- "version": "1.0.0",
- "lockfileVersion": 1,
- "dependencies": {
- "cacache": {
- "version": "9.2.6",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
- "integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
- },
- "duplexify": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
- "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
- "dependencies": {
- "end-of-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
- "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
- }
- }
- }
- }
-}
-```
+# Lock dependencies
+
+
+
+### One Paragraph Explainer
+
+Your code depends on many external packages, let’s say it ‘requires’ and use momentjs-2.1.4, then by default when you deploy to production npm might fetch momentjs 2.1.5 which unfortunately brings some new bugs to the table. Using npm config files and the argument ```–save-exact=true``` instructs npm to refer to the *exact* same version that was installed so the next time you run ```npm install``` (in production or within a Docker container you plan to ship forward for testing) the same dependent version will be fetched. An alternative and popular approach is using a `.shrinkwrap` file (easily generated using npm) that states exactly which packages and versions should be installed so no environment can get tempted to fetch newer versions than expected.
+
+* **Update:** as of npm 5, dependencies are locked automatically using .shrinkwrap. Yarn, an emerging package manager, also locks down dependencies by default.
+
+
+
+### Code example: .npmrc file that instructs npm to use exact versions
+
+```npmrc
+// save this as .npmrc file on the project directory
+save-exact:true
+```
+
+
+
+### Code example: shrinkwrap.json file that distills the exact dependency tree
+
+```json
+{
+ "name": "A",
+ "dependencies": {
+ "B": {
+ "version": "0.0.1",
+ "dependencies": {
+ "C": {
+ "version": "0.1.0"
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+### Code example: npm 5 dependencies lock file – package.json
+
+```json
+{
+ "name": "package-name",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "dependencies": {
+ "cacache": {
+ "version": "9.2.6",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
+ "integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
+ },
+ "duplexify": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
+ "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
+ "dependencies": {
+ "end-of-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
+ "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
+ }
+ }
+ }
+ }
+}
+```
diff --git a/sections/production/measurememory.chinese.md b/sections/production/measurememory.chinese.md
index 9bab948b6..97cdd9c1f 100644
--- a/sections/production/measurememory.chinese.md
+++ b/sections/production/measurememory.chinese.md
@@ -1,24 +1,24 @@
-# 测量和防范内存使用情况
-
-
-
-
-### 一段解释
-
-在一个完美的开发过程中, Web开发人员不应该处理内存泄漏问题。 实际上,内存问题是一个必须了解的Node已知的问题。首先,内存使用必须不断监视.在开发和小型生产站点上,您可以使用Linux命令或NPM工具和库(如node-inspector和memwatch)来手动测量。 这个人工操作的主要缺点是它们需要一个人进行积极的监控 - 对于正规的生产站点来说,使用鲁棒性监控工具是非常重要的,例如(AWS CloudWatch,DataDog或任何类似的主动系统),当泄漏发生时提醒。 防止泄漏的开发指南也很少:避免将数据存储在全局级别,使用动态大小的流数据,使用let和const限制变量范围。
-
-
-
-### 其他博客说了什么
-
-* 摘自博客 [Dyntrace](http://apmblog.dynatrace.com/):
-> ... ”正如我们所了解到的,在Node.js 中,JavaScript被V8编译为机器码。由此产生的机器码数据结构与原始表达没有多大关系,只能由V8管理. 这意味着我们不能主动分配或释放JavaScript中的内存. V8 使用了一个众所周知的垃圾收集机制来解决这个问题.”
-
-* 摘自博客 [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
-> ... “虽然这个例子导致了明显的结果,但这个过程总是一样的:用一些时间和相当数量的内存分配创建heap dumps,比较dumps,以找出正在增长的内存泄露。”
-
-* 摘自博客 [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
-> ... “故障, 在内存较少的系统上运行时必须限制内存,Node.js会尝试使用大约1.5GB的内存。这是预期的行为,垃圾收集是一个代价很高的操作。
-解决方案是为Node.js进程添加一个额外的参数:
-node –max_old_space_size=400 server.js –production ”
+# 测量和防范内存使用情况
+
+
+
+
+### 一段解释
+
+在一个完美的开发过程中, Web开发人员不应该处理内存泄漏问题。 实际上,内存问题是一个必须了解的Node已知的问题。首先,内存使用必须不断监视.在开发和小型生产站点上,您可以使用Linux命令或NPM工具和库(如node-inspector和memwatch)来手动测量。 这个人工操作的主要缺点是它们需要一个人进行积极的监控 - 对于正规的生产站点来说,使用鲁棒性监控工具是非常重要的,例如(AWS CloudWatch,DataDog或任何类似的主动系统),当泄漏发生时提醒。 防止泄漏的开发指南也很少:避免将数据存储在全局级别,使用动态大小的流数据,使用let和const限制变量范围。
+
+
+
+### 其他博客说了什么
+
+* 摘自博客 [Dyntrace](http://apmblog.dynatrace.com/):
+> ... ”正如我们所了解到的,在Node.js 中,JavaScript被V8编译为机器码。由此产生的机器码数据结构与原始表达没有多大关系,只能由V8管理. 这意味着我们不能主动分配或释放JavaScript中的内存. V8 使用了一个众所周知的垃圾收集机制来解决这个问题.”
+
+* 摘自博客 [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+> ... “虽然这个例子导致了明显的结果,但这个过程总是一样的:用一些时间和相当数量的内存分配创建heap dumps,比较dumps,以找出正在增长的内存泄露。”
+
+* 摘自博客 [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+> ... “故障, 在内存较少的系统上运行时必须限制内存,Node.js会尝试使用大约1.5GB的内存。这是预期的行为,垃圾收集是一个代价很高的操作。
+解决方案是为Node.js进程添加一个额外的参数:
+node –max_old_space_size=400 server.js –production ”
“为什么垃圾收集代价很高? V8 JavaScript 使用了 stop-the-world (STW)的垃圾回收机制。 事实上,这意味着程序在进行垃圾回收时停止执行。”
\ No newline at end of file
diff --git a/sections/production/measurememory.md b/sections/production/measurememory.md
index 19c700755..3b5b31d21 100644
--- a/sections/production/measurememory.md
+++ b/sections/production/measurememory.md
@@ -1,25 +1,25 @@
-# Measure and guard the memory usage
-
-
-
-### One Paragraph Explainer
-
-In a perfect world, a web developer shouldn’t deal with memory leaks. In reality, memory issues are a known Node’s gotcha one must be aware of. Above all, memory usage must be monitored constantly. In the development and small production sites, you may gauge manually using Linux commands or npm tools and libraries like node-inspector and memwatch. The main drawback of this manual activities is that they require a human being actively monitoring – for serious production sites, it’s absolutely vital to use robust monitoring tools e.g. (AWS CloudWatch, DataDog or any similar proactive system) that alerts when a leak happens. There are also few development guidelines to prevent leaks: avoid storing data on the global level, use streams for data with dynamic size, limit variables scope using let and const.
-
-
-
-### What Other Bloggers Say
-
-* From the blog [Dyntrace](http://apmblog.dynatrace.com/):
-> ... ”As we already learned, in Node.js JavaScript is compiled to native code by V8. The resulting native data structures don’t have much to do with their original representation and are solely managed by V8. This means that we cannot actively allocate or deallocate memory in JavaScript. V8 uses a well-known mechanism called garbage collection to address this problem.”
-
-* From the blog [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
-> ... “Although this example leads to obvious results the process is always the same:
-Create heap dumps with some time and a fair amount of memory allocation in between
-Compare a few dumps to find out what’s growing”
-
-* From the blog [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
-> ... “fault, Node.js will try to use about 1.5GBs of memory, which has to be capped when running on systems with less memory. This is the expected behavior as garbage collection is a very costly operation.
-The solution for it was adding an extra parameter to the Node.js process:
-node –max_old_space_size=400 server.js –production ”
-“Why is garbage collection expensive? The V8 JavaScript engine employs a stop-the-world garbage collector mechanism. In practice, it means that the program stops execution while garbage collection is in progress.”
+# Measure and guard the memory usage
+
+
+
+### One Paragraph Explainer
+
+In a perfect world, a web developer shouldn’t deal with memory leaks. In reality, memory issues are a known Node’s gotcha one must be aware of. Above all, memory usage must be monitored constantly. In the development and small production sites, you may gauge manually using Linux commands or npm tools and libraries like node-inspector and memwatch. The main drawback of this manual activities is that they require a human being actively monitoring – for serious production sites, it’s absolutely vital to use robust monitoring tools e.g. (AWS CloudWatch, DataDog or any similar proactive system) that alerts when a leak happens. There are also few development guidelines to prevent leaks: avoid storing data on the global level, use streams for data with dynamic size, limit variables scope using let and const.
+
+
+
+### What Other Bloggers Say
+
+* From the blog [Dyntrace](http://apmblog.dynatrace.com/):
+> ... ”As we already learned, in Node.js JavaScript is compiled to native code by V8. The resulting native data structures don’t have much to do with their original representation and are solely managed by V8. This means that we cannot actively allocate or deallocate memory in JavaScript. V8 uses a well-known mechanism called garbage collection to address this problem.”
+
+* From the blog [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+> ... “Although this example leads to obvious results the process is always the same:
+Create heap dumps with some time and a fair amount of memory allocation in between
+Compare a few dumps to find out what’s growing”
+
+* From the blog [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+> ... “fault, Node.js will try to use about 1.5GBs of memory, which has to be capped when running on systems with less memory. This is the expected behavior as garbage collection is a very costly operation.
+The solution for it was adding an extra parameter to the Node.js process:
+node –max_old_space_size=400 server.js –production ”
+“Why is garbage collection expensive? The V8 JavaScript engine employs a stop-the-world garbage collector mechanism. In practice, it means that the program stops execution while garbage collection is in progress.”
diff --git a/sections/production/monitoring.chinese.md b/sections/production/monitoring.chinese.md
index ac23b193f..23aaa6c09 100644
--- a/sections/production/monitoring.chinese.md
+++ b/sections/production/monitoring.chinese.md
@@ -1,39 +1,39 @@
-
-# 监控!
-
-
-
-### 一段解释
-
-基本来说,当在生产环境中发生意外时,监控意味着你能够很*容易*识别它们。比如,通过电子邮件或Slack获得通知。挑战在于选择既能满足你的需求又不会破坏防护的合适的工具集。我建议, 首先定义一组核心的度量标准, 这些指标必须被监视, 以确保健康状态 – CPU, 服务器RAM, Node进程RAM(小于1.4GB),最后一分钟的错误数量,进程重启次数,平均响应时间。然后去看看你可能喜欢的一些高级功能,并添加到你的愿望清单。一些高级监控功能的例子:DB分析,跨服务测量(即测量业务事务),前端集成,将原始数据展示给自定义BI客户端,Slack 通知等等。
-
-要实现高级功能需要冗长的设置或购买诸如Datadog,Newrelic之类的商业产品。不幸的是,实现基本功能也并不容易,因为一些测量标准是与硬件相关的(CPU),而其它则在node进程内(内部错误),因此所有简单的工具都需要一些额外的设置。例如,云供应商监控解决方案(例如[AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/))能立即告诉您硬件度量标准,但不涉及内部应用程序行为。另一方面,基于日志的解决方案(如ElasticSearch)默认缺少硬件视图。解决方案是通过缺少的指标来增加您的选择,例如,一个流行的选择是将应用程序日志发送到[Elastic stack](https://www.elastic.co/products)并配置一些额外的代理(例如[Beat](https://www.elastic.co/products))来共享硬件相关信息以获得完整的展现。
-
-
-
-### 监控示例:AWS cloudwatch默认仪表板。很难提取应用内指标
-
-![AWS cloudwatch default dashboard. Hard to extract in-app metrics](/assets/images/monitoring1.png)
-
-
-
-### 监控示例:StackDriver默认仪表板。很难提取应用内指标
-
-![StackDriver default dashboard. Hard to extract in-app metrics](/assets/images/monitoring2.jpg)
-
-
-
-### 监控示例:Grafana作为可视化原始数据的UI层
-
-
-![Grafana as the UI layer that visualizes raw data](/assets/images/monitoring3.png)
-
-
-### 其他博主说了什么
- 摘自博客 [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
-
-> ...我们建议您为所有服务监听这些信号:
-> 错误率:因为错误是用户面对的,并立即会影响您的客户。
-> 响应时间:因为延迟会直接影响您的客户和业务。
-> 吞吐量:流量可帮助您了解增加的错误率和延迟的上下文。
-> 饱和度:饱和度告诉你你的服务有多“满”。如果CPU使用率是90%,您的系统可以处理更多的流量吗?...
+
+# 监控!
+
+
+
+### 一段解释
+
+基本来说,当在生产环境中发生意外时,监控意味着你能够很*容易*识别它们。比如,通过电子邮件或Slack获得通知。挑战在于选择既能满足你的需求又不会破坏防护的合适的工具集。我建议, 首先定义一组核心的度量标准, 这些指标必须被监视, 以确保健康状态 – CPU, 服务器RAM, Node进程RAM(小于1.4GB),最后一分钟的错误数量,进程重启次数,平均响应时间。然后去看看你可能喜欢的一些高级功能,并添加到你的愿望清单。一些高级监控功能的例子:DB分析,跨服务测量(即测量业务事务),前端集成,将原始数据展示给自定义BI客户端,Slack 通知等等。
+
+要实现高级功能需要冗长的设置或购买诸如Datadog,Newrelic之类的商业产品。不幸的是,实现基本功能也并不容易,因为一些测量标准是与硬件相关的(CPU),而其它则在node进程内(内部错误),因此所有简单的工具都需要一些额外的设置。例如,云供应商监控解决方案(例如[AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/))能立即告诉您硬件度量标准,但不涉及内部应用程序行为。另一方面,基于日志的解决方案(如ElasticSearch)默认缺少硬件视图。解决方案是通过缺少的指标来增加您的选择,例如,一个流行的选择是将应用程序日志发送到[Elastic stack](https://www.elastic.co/products)并配置一些额外的代理(例如[Beat](https://www.elastic.co/products))来共享硬件相关信息以获得完整的展现。
+
+
+
+### 监控示例:AWS cloudwatch默认仪表板。很难提取应用内指标
+
+![AWS cloudwatch default dashboard. Hard to extract in-app metrics](/assets/images/monitoring1.png)
+
+
+
+### 监控示例:StackDriver默认仪表板。很难提取应用内指标
+
+![StackDriver default dashboard. Hard to extract in-app metrics](/assets/images/monitoring2.jpg)
+
+
+
+### 监控示例:Grafana作为可视化原始数据的UI层
+
+
+![Grafana as the UI layer that visualizes raw data](/assets/images/monitoring3.png)
+
+
+### 其他博主说了什么
+ 摘自博客 [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
+
+> ...我们建议您为所有服务监听这些信号:
+> 错误率:因为错误是用户面对的,并立即会影响您的客户。
+> 响应时间:因为延迟会直接影响您的客户和业务。
+> 吞吐量:流量可帮助您了解增加的错误率和延迟的上下文。
+> 饱和度:饱和度告诉你你的服务有多“满”。如果CPU使用率是90%,您的系统可以处理更多的流量吗?...
diff --git a/sections/production/monitoring.md b/sections/production/monitoring.md
index 68f42cbd9..75b0f753e 100644
--- a/sections/production/monitoring.md
+++ b/sections/production/monitoring.md
@@ -1,39 +1,39 @@
-# Monitoring!
-
-
-
-### One Paragraph Explainer
-
-At the very basic level, monitoring means you can *easily* identify when bad things happen at production. For example, by getting notified by email or Slack. The challenge is to choose the right set of tools that will satisfy your requirements without breaking your bank. May I suggest, start with defining the core set of metrics that must be watched to ensure a healthy state – CPU, server RAM, Node process RAM (less than 1.4GB), the number of errors in the last minute, number of process restarts, average response time. Then go over some advanced features you might fancy and add to your wish list. Some examples of a luxury monitoring feature: DB profiling, cross-service measuring (i.e. measure business transaction), front-end integration, expose raw data to custom BI clients, Slack notifications and many others.
-
-Achieving the advanced features demands lengthy setup or buying a commercial product such as Datadog, NewRelic and alike. Unfortunately, achieving even the basics is not a walk in the park as some metrics are hardware-related (CPU) and others live within the node process (internal errors) thus all the straightforward tools require some additional setup. For example, cloud vendor monitoring solutions (e.g. [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) will tell you immediately about the hardware metrics but not about the internal app behavior. On the other end, Log-based solutions such as ElasticSearch lack the hardware view by default. The solution is to augment your choice with missing metrics, for example, a popular choice is sending application logs to [Elastic stack](https://www.elastic.co/products) and configure some additional agent (e.g. [Beat](https://www.elastic.co/products)) to share hardware-related information to get the full picture.
-
-
-
-### Monitoring example: AWS cloudwatch default dashboard. Hard to extract in-app metrics
-
-![AWS cloudwatch default dashboard. Hard to extract in-app metrics](/assets/images/monitoring1.png)
-
-
-
-### Monitoring example: StackDriver default dashboard. Hard to extract in-app metrics
-
-![StackDriver default dashboard. Hard to extract in-app metrics](/assets/images/monitoring2.jpg)
-
-
-
-### Monitoring example: Grafana as the UI layer that visualizes raw data
-
-![Grafana as the UI layer that visualizes raw data](/assets/images/monitoring3.png)
-
-
-
-### What Other Bloggers Say
-
-From the blog [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
-
-> …We recommend you to watch these signals for all of your services:
-> Error Rate: Because errors are user facing and immediately affect your customers.
-> Response time: Because the latency directly affects your customers and business.
-> Throughput: The traffic helps you to understand the context of increased error rates and the latency too.
-> Saturation: It tells how “full” your service is. If the CPU usage is 90%, can your system handle more traffic? …
+# Monitoring!
+
+
+
+### One Paragraph Explainer
+
+At the very basic level, monitoring means you can *easily* identify when bad things happen at production. For example, by getting notified by email or Slack. The challenge is to choose the right set of tools that will satisfy your requirements without breaking your bank. May I suggest, start with defining the core set of metrics that must be watched to ensure a healthy state – CPU, server RAM, Node process RAM (less than 1.4GB), the number of errors in the last minute, number of process restarts, average response time. Then go over some advanced features you might fancy and add to your wish list. Some examples of a luxury monitoring feature: DB profiling, cross-service measuring (i.e. measure business transaction), front-end integration, expose raw data to custom BI clients, Slack notifications and many others.
+
+Achieving the advanced features demands lengthy setup or buying a commercial product such as Datadog, NewRelic and alike. Unfortunately, achieving even the basics is not a walk in the park as some metrics are hardware-related (CPU) and others live within the node process (internal errors) thus all the straightforward tools require some additional setup. For example, cloud vendor monitoring solutions (e.g. [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) will tell you immediately about the hardware metrics but not about the internal app behavior. On the other end, Log-based solutions such as ElasticSearch lack the hardware view by default. The solution is to augment your choice with missing metrics, for example, a popular choice is sending application logs to [Elastic stack](https://www.elastic.co/products) and configure some additional agent (e.g. [Beat](https://www.elastic.co/products)) to share hardware-related information to get the full picture.
+
+
+
+### Monitoring example: AWS cloudwatch default dashboard. Hard to extract in-app metrics
+
+![AWS cloudwatch default dashboard. Hard to extract in-app metrics](/assets/images/monitoring1.png)
+
+
+
+### Monitoring example: StackDriver default dashboard. Hard to extract in-app metrics
+
+![StackDriver default dashboard. Hard to extract in-app metrics](/assets/images/monitoring2.jpg)
+
+
+
+### Monitoring example: Grafana as the UI layer that visualizes raw data
+
+![Grafana as the UI layer that visualizes raw data](/assets/images/monitoring3.png)
+
+
+
+### What Other Bloggers Say
+
+From the blog [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
+
+> …We recommend you to watch these signals for all of your services:
+> Error Rate: Because errors are user facing and immediately affect your customers.
+> Response time: Because the latency directly affects your customers and business.
+> Throughput: The traffic helps you to understand the context of increased error rates and the latency too.
+> Saturation: It tells how “full” your service is. If the CPU usage is 90%, can your system handle more traffic? …
diff --git a/sections/production/productoncode.chinese.md b/sections/production/productoncode.chinese.md
index c5b97d24b..dfde2e820 100644
--- a/sections/production/productoncode.chinese.md
+++ b/sections/production/productoncode.chinese.md
@@ -1,17 +1,17 @@
-# 代码生产环境的准备
-
-
-
-
-### 一段解释
-
-以下是一个开发技巧的列表,它极大地影响了产品的维护和稳定性:
-
-* 十二因素指南 — 熟悉[12因素](https://12factor.net/)指南
-* 无状态 — 在一个特定的web服务器上不保存本地数据(请参阅相关条目 - “Be Stateless”)
-* 高速缓存 — 大量使用缓存,但不会因为缓存不匹配而产生错误
-* 测试内存 — 测量内存的使用和泄漏,是作为开发流程的一部分,诸如“memwatch”之类的工具可以极大地促进这一任务
-* 命名函数 — 将匿名函数(例如,内联callbabk)的使用最小化,因为一个典型的内存分析器为每个方法名提供内存使用情况
-* 使用CI工具 — 在发送到生产前使用CI工具检测故障。例如,使用ESLint来检测引用错误和未定义的变量。使用–trace-sync-io来识别用了同步api的代码(而不是异步版本)
-* 明确的日志 — 包括在每个日志语句中希望用json格式记录上下文信息,以便于日志聚合工具,如Elastic可以在这些属性上搜索(请参阅相关条目 – “Increase visibility using smart logs”)。此外,还包括标识每个请求的事务id,并允许将描述相同事务的行关联起来(请参阅 — “Include Transaction-ID”)
+# 代码生产环境的准备
+
+
+
+
+### 一段解释
+
+以下是一个开发技巧的列表,它极大地影响了产品的维护和稳定性:
+
+* 十二因素指南 — 熟悉[12因素](https://12factor.net/)指南
+* 无状态 — 在一个特定的web服务器上不保存本地数据(请参阅相关条目 - “Be Stateless”)
+* 高速缓存 — 大量使用缓存,但不会因为缓存不匹配而产生错误
+* 测试内存 — 测量内存的使用和泄漏,是作为开发流程的一部分,诸如“memwatch”之类的工具可以极大地促进这一任务
+* 命名函数 — 将匿名函数(例如,内联callbabk)的使用最小化,因为一个典型的内存分析器为每个方法名提供内存使用情况
+* 使用CI工具 — 在发送到生产前使用CI工具检测故障。例如,使用ESLint来检测引用错误和未定义的变量。使用–trace-sync-io来识别用了同步api的代码(而不是异步版本)
+* 明确的日志 — 包括在每个日志语句中希望用json格式记录上下文信息,以便于日志聚合工具,如Elastic可以在这些属性上搜索(请参阅相关条目 – “Increase visibility using smart logs”)。此外,还包括标识每个请求的事务id,并允许将描述相同事务的行关联起来(请参阅 — “Include Transaction-ID”)
* 错误管理 — 错误处理是Node.js生产站点的致命弱点 – 许多Node进程由于小错误而崩溃,然而其他Node进程则会在错误的状态下存活,而不是崩溃。设置你的错误处理策略绝对是至关重要的, 在这里阅读我的(错误处理的最佳实践)(http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
\ No newline at end of file
diff --git a/sections/production/productoncode.md b/sections/production/productoncode.md
index 4871ad396..a86047312 100644
--- a/sections/production/productoncode.md
+++ b/sections/production/productoncode.md
@@ -1,16 +1,16 @@
-# Make your code production-ready
-
-
-
-### One Paragraph Explainer
-
-Following is a list of development tips that greatly affect the production maintenance and stability:
-
-* The twelve-factor guide – Get familiar with the [Twelve factors](https://12factor.net/) guide
-* Be stateless – Save no data locally on a specific web server (see separate bullet – ‘Be Stateless’)
-* Cache – Utilize cache heavily, yet never fail because of cache mismatch
-* Test memory – gauge memory usage and leaks as part your development flow, tools such as ‘memwatch’ can greatly facilitate this task
-* Name functions – Minimize the usage of anonymous functions (i.e. inline callback) as a typical memory profiler will provide memory usage per method name
-* Use CI tools – Use CI tool to detect failures before sending to production. For example, use ESLint to detect reference errors and undefined variables. Use –trace-sync-io to identify code that uses synchronous APIs (instead of the async version)
-* Log wisely – Include in each log statement contextual information, hopefully in JSON format so log aggregators tools such as Elastic can search upon those properties (see separate bullet – ‘Increase visibility using smart logs’). Also, include transaction-id that identifies each request and allows to correlate lines that describe the same transaction (see separate bullet – ‘Include Transaction-ID’)
-* Error management – Error handling is the Achilles’ heel of Node.js production sites – many Node processes are crashing because of minor errors while others hang on alive in a faulty state instead of crashing. Setting your error handling strategy is absolutely critical, read here my [error handling best practices](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
+# Make your code production-ready
+
+
+
+### One Paragraph Explainer
+
+Following is a list of development tips that greatly affect the production maintenance and stability:
+
+* The twelve-factor guide – Get familiar with the [Twelve factors](https://12factor.net/) guide
+* Be stateless – Save no data locally on a specific web server (see separate bullet – ‘Be Stateless’)
+* Cache – Utilize cache heavily, yet never fail because of cache mismatch
+* Test memory – gauge memory usage and leaks as part your development flow, tools such as ‘memwatch’ can greatly facilitate this task
+* Name functions – Minimize the usage of anonymous functions (i.e. inline callback) as a typical memory profiler will provide memory usage per method name
+* Use CI tools – Use CI tool to detect failures before sending to production. For example, use ESLint to detect reference errors and undefined variables. Use –trace-sync-io to identify code that uses synchronous APIs (instead of the async version)
+* Log wisely – Include in each log statement contextual information, hopefully in JSON format so log aggregators tools such as Elastic can search upon those properties (see separate bullet – ‘Increase visibility using smart logs’). Also, include transaction-id that identifies each request and allows to correlate lines that describe the same transaction (see separate bullet – ‘Include Transaction-ID’)
+* Error management – Error handling is the Achilles’ heel of Node.js production sites – many Node processes are crashing because of minor errors while others hang on alive in a faulty state instead of crashing. Setting your error handling strategy is absolutely critical, read here my [error handling best practices](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
diff --git a/sections/production/setnodeenv.chinese.md b/sections/production/setnodeenv.chinese.md
index a89061df5..0b9251f5b 100644
--- a/sections/production/setnodeenv.chinese.md
+++ b/sections/production/setnodeenv.chinese.md
@@ -1,37 +1,37 @@
-# 配置环境变量 NODE_ENV = production
-
-
-
-
-### 一段解释
-
-进程的环境变量是一组键值对,可用于任何运行程序,通常用于配置。虽然可以使用其他任何变量,但Node鼓励使用一个名为NODE_ENV的变量来标记我们是否正在开发。这一决定允许组件在开发过程中能提供更好的诊断,例如禁用缓存或发出冗长的日志语句。任何现代部署工具 — Chef、Puppet、CloudFormation等 — 在部署时都支持设置环境变量。
-
-
-
-
-### 代码实例:配置和读取NODE_ENV环境变量
-
-```javascript
-//在启动node进程前,在bash中设置环境变量
-$ NODE_ENV=development
-$ node
-
-//使用代码读取环境变量
-If(process.env.NODE_ENV === “production”)
- useCaching = true;
-```
-
-
-
-
-### 其他博主说了什么
-摘自这篇博客[dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
-> ...在node.js中有一个约定, 它使用名为NODE_ENV的变量来设置当前工作模式。我们看到它实际上是读取NODE_ENV,如果它没有设置,则默认为“development”。我们清楚的看到,通过设置NODE_ENV为production,node.js可以处理请求的数量可以提高大约三分之二,而CPU的使用率会略有下降。 *让我强调一下:设置NODE_ENV为production可以让你的应用程序快3倍!*
-
-
-![NODE_ENV=production](/assets/images/setnodeenv1.png "NODE_ENV=production")
-
-
-
-
+# 配置环境变量 NODE_ENV = production
+
+
+
+
+### 一段解释
+
+进程的环境变量是一组键值对,可用于任何运行程序,通常用于配置。虽然可以使用其他任何变量,但Node鼓励使用一个名为NODE_ENV的变量来标记我们是否正在开发。这一决定允许组件在开发过程中能提供更好的诊断,例如禁用缓存或发出冗长的日志语句。任何现代部署工具 — Chef、Puppet、CloudFormation等 — 在部署时都支持设置环境变量。
+
+
+
+
+### 代码实例:配置和读取NODE_ENV环境变量
+
+```javascript
+//在启动node进程前,在bash中设置环境变量
+$ NODE_ENV=development
+$ node
+
+//使用代码读取环境变量
+If(process.env.NODE_ENV === “production”)
+ useCaching = true;
+```
+
+
+
+
+### 其他博主说了什么
+摘自这篇博客[dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
+> ...在node.js中有一个约定, 它使用名为NODE_ENV的变量来设置当前工作模式。我们看到它实际上是读取NODE_ENV,如果它没有设置,则默认为“development”。我们清楚的看到,通过设置NODE_ENV为production,node.js可以处理请求的数量可以提高大约三分之二,而CPU的使用率会略有下降。 *让我强调一下:设置NODE_ENV为production可以让你的应用程序快3倍!*
+
+
+![NODE_ENV=production](/assets/images/setnodeenv1.png "NODE_ENV=production")
+
+
+
+
diff --git a/sections/production/setnodeenv.md b/sections/production/setnodeenv.md
index 6fdff71f7..31bd6d017 100644
--- a/sections/production/setnodeenv.md
+++ b/sections/production/setnodeenv.md
@@ -1,32 +1,32 @@
-# Set NODE_ENV = production
-
-
-
-### One Paragraph Explainer
-
-Process environment variables is a set of key-value pairs made available to any running program, usually for configuration purposes. Though any variables can be used, Node encourages the convention of using a variable called NODE_ENV to flag whether we’re in production right now. This determination allows components to provide better diagnostics during development, for example by disabling caching or emitting verbose log statements. Any modern deployment tool – Chef, Puppet, CloudFormation, others – support setting environment variables during deployment
-
-
-
-### Code example: Setting and reading the NODE_ENV environment variable
-
-```javascript
-// Setting environment variables in bash before starting the node process
-$ NODE_ENV=development
-$ node
-
-// Reading the environment variable using code
-if (process.env.NODE_ENV === “production”)
- useCaching = true;
-```
-
-
-
-### What Other Bloggers Say
-
-From the blog [dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
-> ...In Node.js there is a convention to use a variable called NODE_ENV to set the current mode. We see that it, in fact, reads NODE_ENV and defaults to ‘development’ if it isn’t set. We clearly see that by setting NODE_ENV to production the number of requests Node.js can handle jumps by around two-thirds while the CPU usage even drops slightly. *Let me emphasize this: Setting NODE_ENV to production makes your application 3 times faster!*
-
-![NODE_ENV=production](/assets/images/setnodeenv1.png "NODE_ENV=production")
-
-
+# Set NODE_ENV = production
+
+
+
+### One Paragraph Explainer
+
+Process environment variables is a set of key-value pairs made available to any running program, usually for configuration purposes. Though any variables can be used, Node encourages the convention of using a variable called NODE_ENV to flag whether we’re in production right now. This determination allows components to provide better diagnostics during development, for example by disabling caching or emitting verbose log statements. Any modern deployment tool – Chef, Puppet, CloudFormation, others – support setting environment variables during deployment
+
+
+
+### Code example: Setting and reading the NODE_ENV environment variable
+
+```javascript
+// Setting environment variables in bash before starting the node process
+$ NODE_ENV=development
+$ node
+
+// Reading the environment variable using code
+if (process.env.NODE_ENV === “production”)
+ useCaching = true;
+```
+
+
+
+### What Other Bloggers Say
+
+From the blog [dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
+> ...In Node.js there is a convention to use a variable called NODE_ENV to set the current mode. We see that it, in fact, reads NODE_ENV and defaults to ‘development’ if it isn’t set. We clearly see that by setting NODE_ENV to production the number of requests Node.js can handle jumps by around two-thirds while the CPU usage even drops slightly. *Let me emphasize this: Setting NODE_ENV to production makes your application 3 times faster!*
+
+![NODE_ENV=production](/assets/images/setnodeenv1.png "NODE_ENV=production")
+
+
diff --git a/sections/production/smartlogging.chinese.md b/sections/production/smartlogging.chinese.md
index 2b51ca8dc..c1412f6d7 100644
--- a/sections/production/smartlogging.chinese.md
+++ b/sections/production/smartlogging.chinese.md
@@ -1,40 +1,40 @@
-# 使用智能日志使你的应用程序变得清晰
-
-
-
-
-### 一段解释
-
-无论如何,您要打印日志,显然需要一些可以在其中跟踪错误和核心指标的接口来包装生产环境信息(例如,每小时发生了多少错误,最慢的API节点是哪一个)为什么不在健壮的日志框架中进行一些适度的尝试呢? 要实现这一目标,需要在三个步骤上做出深思熟虑的决定:
-
-**1. 智能日志** – 在最基本的情况下,您需要使用像[Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan)这样有信誉的日志库,在每个事务开始和结束时输出有意义的信息。还可以考虑将日志语句格式化为JSON,并提供所有上下文属性(如用户id、操作类型等)。这样运维团队就可以在这些字段上操作。在每个日志行中包含一个唯一的transaction ID,更多的信息查阅条款 “Write transaction-id to log”。最后要考虑的一点还包括一个代理,它记录系统资源,如内存和CPU,比如Elastic Beat。
-
-**2. 智能聚合** – 一旦您在服务器文件系统中有了全面的信息,就应该定期将这些信息推送到一个可以聚合、处理和可视化数据的系统中。例如,Elastic stack是一种流行的、自由的选择,它提供所有组件去聚合和产生可视化数据。许多商业产品提供了类似的功能,只是它们大大减少了安装时间,不需要主机托管。
-
-**3. 智能可视化** – 现在的信息是聚合和可搜索的, 一个可以满足仅仅方便地搜索日志的能力, 可以走得更远, 没有编码或花费太多的努力。我们现在可以显示一些重要的操作指标, 如错误率、平均一天CPU使用, 在过去一小时内有多少新用户选择, 以及任何其他有助于管理和改进我们应用程序的指标。
-
-
-
-
-### 可视化示例: Kibana(Elastic stack的一部分)促进了对日志内容的高级搜索
-![Kibana facilitates advanced searching on log content](/assets/images/smartlogging1.png "Kibana facilitates advanced searching on log content")
-
-
-
-### 可视化示例: Kibana(Elastic stack的一部分)基于日志来可视化数据
-![Kibana visualizes data based on logs](/assets/images/smartlogging2.jpg "Kibana visualizes data based on logs")
-
-
-
-### 博客应用: Logger的需求
-摘自博客 [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
-
-> 让我们识别一些需求(对于一个日志记录器来说):
-> 1. 每条日志对应一个时间戳。这个很好解释 – 您应该能够判断每个日志条目出现的时间。
-> 2. 日志格式应该很容易被人和机器消化理解。
-> 3. 允许多个可配置的目标流。例如,您可能在一个文件中写入trace日志,但是当遇到错误时,将其写入相同的文件,然后写入错误日志文件并同时发送电子邮件...
-
-
-
-
-
+# 使用智能日志使你的应用程序变得清晰
+
+
+
+
+### 一段解释
+
+无论如何,您要打印日志,显然需要一些可以在其中跟踪错误和核心指标的接口来包装生产环境信息(例如,每小时发生了多少错误,最慢的API节点是哪一个)为什么不在健壮的日志框架中进行一些适度的尝试呢? 要实现这一目标,需要在三个步骤上做出深思熟虑的决定:
+
+**1. 智能日志** – 在最基本的情况下,您需要使用像[Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan)这样有信誉的日志库,在每个事务开始和结束时输出有意义的信息。还可以考虑将日志语句格式化为JSON,并提供所有上下文属性(如用户id、操作类型等)。这样运维团队就可以在这些字段上操作。在每个日志行中包含一个唯一的transaction ID,更多的信息查阅条款 “Write transaction-id to log”。最后要考虑的一点还包括一个代理,它记录系统资源,如内存和CPU,比如Elastic Beat。
+
+**2. 智能聚合** – 一旦您在服务器文件系统中有了全面的信息,就应该定期将这些信息推送到一个可以聚合、处理和可视化数据的系统中。例如,Elastic stack是一种流行的、自由的选择,它提供所有组件去聚合和产生可视化数据。许多商业产品提供了类似的功能,只是它们大大减少了安装时间,不需要主机托管。
+
+**3. 智能可视化** – 现在的信息是聚合和可搜索的, 一个可以满足仅仅方便地搜索日志的能力, 可以走得更远, 没有编码或花费太多的努力。我们现在可以显示一些重要的操作指标, 如错误率、平均一天CPU使用, 在过去一小时内有多少新用户选择, 以及任何其他有助于管理和改进我们应用程序的指标。
+
+
+
+
+### 可视化示例: Kibana(Elastic stack的一部分)促进了对日志内容的高级搜索
+![Kibana facilitates advanced searching on log content](/assets/images/smartlogging1.png "Kibana facilitates advanced searching on log content")
+
+
+
+### 可视化示例: Kibana(Elastic stack的一部分)基于日志来可视化数据
+![Kibana visualizes data based on logs](/assets/images/smartlogging2.jpg "Kibana visualizes data based on logs")
+
+
+
+### 博客应用: Logger的需求
+摘自博客 [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
+
+> 让我们识别一些需求(对于一个日志记录器来说):
+> 1. 每条日志对应一个时间戳。这个很好解释 – 您应该能够判断每个日志条目出现的时间。
+> 2. 日志格式应该很容易被人和机器消化理解。
+> 3. 允许多个可配置的目标流。例如,您可能在一个文件中写入trace日志,但是当遇到错误时,将其写入相同的文件,然后写入错误日志文件并同时发送电子邮件...
+
+
+
+
+
diff --git a/sections/production/smartlogging.md b/sections/production/smartlogging.md
index 5aab52d1f..bcb7bc4af 100644
--- a/sections/production/smartlogging.md
+++ b/sections/production/smartlogging.md
@@ -1,40 +1,40 @@
-# Make your app transparent using smart logs
-
-
-
-### One Paragraph Explainer
-
-Since you print out log statements anyway and you're obviously in a need of some interface that wraps up production information where you can trace errors and core metrics (e.g. how many errors happen every hour and which is your slowest API end-point) why not invest some moderate effort in a robust logging framework that will tick all boxes? Achieving that requires a thoughtful decision on three steps:
-
-**1. smart logging** – at the bare minimum you need to use a reputable logging library like [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) and write meaningful information at each transaction start and end. Consider to also format log statements as JSON and provide all the contextual properties (e.g. user id, operation type, etc) so that the operations team can act on those fields. Include also a unique transaction ID at each log line, for more information refer to the bullet below “Write transaction-id to log”. One last point to consider is also including an agent that logs the system resource like memory and CPU like Elastic Beat.
-
-**2. smart aggregation** – once you have comprehensive information on your servers file system, it’s time to periodically push these to a system that aggregates, facilities and visualizes this data. The Elastic stack, for example, is a popular and free choice that offers all the components to aggregate and visualize data. Many commercial products provide similar functionality only they greatly cut down the setup time and require no hosting.
-
-**3. smart visualization** – now the information is aggregated and searchable, one can be satisfied only with the power of easily searching the logs but this can go much further without coding or spending much effort. We can now show important operational metrics like error rate, average CPU throughout the day, how many new users opted-in in the last hour and any other metric that helps to govern and improve our app
-
-
-
-### Visualization Example: Kibana (part of the Elastic stack) facilitates advanced searching on log content
-
-![Kibana facilitates advanced searching on log content](/assets/images/smartlogging1.png "Kibana facilitates advanced searching on log content")
-
-
-
-### Visualization Example: Kibana (part of the Elastic stack) visualizes data based on logs
-
-![Kibana visualizes data based on logs](/assets/images/smartlogging2.jpg "Kibana visualizes data based on logs")
-
-
-
-### Blog Quote: Logger Requirements
-
-From the blog [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
-
-> Lets identify a few requirements (for a logger):
-> 1. Timestamp each log line. This one is pretty self-explanatory – you should be able to tell when each log entry occurred.
-> 2. Logging format should be easily digestible by humans as well as machines.
-> 3. Allows for multiple configurable destination streams. For example, you might be writing trace logs to one file but when an error is encountered, write to the same file, then into error file and send an email at the same time…
-
-
-
-
+# Make your app transparent using smart logs
+
+
+
+### One Paragraph Explainer
+
+Since you print out log statements anyway and you're obviously in a need of some interface that wraps up production information where you can trace errors and core metrics (e.g. how many errors happen every hour and which is your slowest API end-point) why not invest some moderate effort in a robust logging framework that will tick all boxes? Achieving that requires a thoughtful decision on three steps:
+
+**1. smart logging** – at the bare minimum you need to use a reputable logging library like [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) and write meaningful information at each transaction start and end. Consider to also format log statements as JSON and provide all the contextual properties (e.g. user id, operation type, etc) so that the operations team can act on those fields. Include also a unique transaction ID at each log line, for more information refer to the bullet below “Write transaction-id to log”. One last point to consider is also including an agent that logs the system resource like memory and CPU like Elastic Beat.
+
+**2. smart aggregation** – once you have comprehensive information on your servers file system, it’s time to periodically push these to a system that aggregates, facilities and visualizes this data. The Elastic stack, for example, is a popular and free choice that offers all the components to aggregate and visualize data. Many commercial products provide similar functionality only they greatly cut down the setup time and require no hosting.
+
+**3. smart visualization** – now the information is aggregated and searchable, one can be satisfied only with the power of easily searching the logs but this can go much further without coding or spending much effort. We can now show important operational metrics like error rate, average CPU throughout the day, how many new users opted-in in the last hour and any other metric that helps to govern and improve our app
+
+
+
+### Visualization Example: Kibana (part of the Elastic stack) facilitates advanced searching on log content
+
+![Kibana facilitates advanced searching on log content](/assets/images/smartlogging1.png "Kibana facilitates advanced searching on log content")
+
+
+
+### Visualization Example: Kibana (part of the Elastic stack) visualizes data based on logs
+
+![Kibana visualizes data based on logs](/assets/images/smartlogging2.jpg "Kibana visualizes data based on logs")
+
+
+
+### Blog Quote: Logger Requirements
+
+From the blog [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
+
+> Lets identify a few requirements (for a logger):
+> 1. Timestamp each log line. This one is pretty self-explanatory – you should be able to tell when each log entry occurred.
+> 2. Logging format should be easily digestible by humans as well as machines.
+> 3. Allows for multiple configurable destination streams. For example, you might be writing trace logs to one file but when an error is encountered, write to the same file, then into error file and send an email at the same time…
+
+
+
+
diff --git a/sections/production/utilizecpu.chinese.md b/sections/production/utilizecpu.chinese.md
index 8fb0072a1..027a459af 100644
--- a/sections/production/utilizecpu.chinese.md
+++ b/sections/production/utilizecpu.chinese.md
@@ -1,28 +1,28 @@
-# 利用所有的CPU内核
-
-
-
-
-### 一段解释
-
-这应该不会让人感到意外, 在其基本形式上,Node运行在单进程,单线程,单个CPU上。购买了一个强大的包含4个或8个CPU的硬件,只使用一个听起来是不可思议的,对吗?适合中型应用最快的解决方案是使用Node的Cluster模块,它在10行代码中为每个逻辑核心和路由请求产生一个进程,进程之间以round-robin的形式存在。更好的是使用PM2,它通过一个简单的接口和一个很酷的监视UI来给cluster模块裹上糖衣。虽然这个解决方案对传统应用程序很有效,但它可能无法满足需要顶级性能和健壮的devops流的应用。对于那些高级的用例,考虑使用自定义部署脚本复制NODE进程,并使用像nginx
-这样的专门的工具进行负载均衡,或者使用像AWS ECS或Kubernetees这样的容器引擎,这些工具具有部署和复制进程的高级特性。
-
-
-
-
-### 比较:使用Node的clustre vs nginx做负载均衡
-
-![Balancing using Node’s cluster vs nginx](/assets/images/utilizecpucores1.png "Balancing using Node’s cluster vs nginx")
-
-
-
-### 其他博主说什么
-* 摘自[Node.JS documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
-> ... 理论上第二种方法, Node clusters,应该是性能最佳的。然而, 在实践中, 由于操作系统调度程序的反复无常, 分布往往非常不平衡。观察负载, 所有连接中,超过70%在两个进程中处理, 而总共有八个进程...
-
-* 摘自博客[StrongLoop](From the blog StrongLoop):
-> ...通过Node的cluster模块实现集群化。这使一个主进程能够产生工作进程,并在工作进程间分配进入的连接。然而,与其直接使用这个模块,更好的选择是使用其中的许多工具之一, 它为您自动处理它; 例如,node-pm或cluster-service...
-
-* 摘自the Medium post[node.js进程负载平衡性能:比较cluster moudlle、iptables和Nginx](https://medium.com/@fermads/node-js-process-load-balancing- iptabls -and- Nginx -6746aaf38272)
+# 利用所有的CPU内核
+
+
+
+
+### 一段解释
+
+这应该不会让人感到意外, 在其基本形式上,Node运行在单进程,单线程,单个CPU上。购买了一个强大的包含4个或8个CPU的硬件,只使用一个听起来是不可思议的,对吗?适合中型应用最快的解决方案是使用Node的Cluster模块,它在10行代码中为每个逻辑核心和路由请求产生一个进程,进程之间以round-robin的形式存在。更好的是使用PM2,它通过一个简单的接口和一个很酷的监视UI来给cluster模块裹上糖衣。虽然这个解决方案对传统应用程序很有效,但它可能无法满足需要顶级性能和健壮的devops流的应用。对于那些高级的用例,考虑使用自定义部署脚本复制NODE进程,并使用像nginx
+这样的专门的工具进行负载均衡,或者使用像AWS ECS或Kubernetees这样的容器引擎,这些工具具有部署和复制进程的高级特性。
+
+
+
+
+### 比较:使用Node的clustre vs nginx做负载均衡
+
+![Balancing using Node’s cluster vs nginx](/assets/images/utilizecpucores1.png "Balancing using Node’s cluster vs nginx")
+
+
+
+### 其他博主说什么
+* 摘自[Node.JS documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
+> ... 理论上第二种方法, Node clusters,应该是性能最佳的。然而, 在实践中, 由于操作系统调度程序的反复无常, 分布往往非常不平衡。观察负载, 所有连接中,超过70%在两个进程中处理, 而总共有八个进程...
+
+* 摘自博客[StrongLoop](From the blog StrongLoop):
+> ...通过Node的cluster模块实现集群化。这使一个主进程能够产生工作进程,并在工作进程间分配进入的连接。然而,与其直接使用这个模块,更好的选择是使用其中的许多工具之一, 它为您自动处理它; 例如,node-pm或cluster-service...
+
+* 摘自the Medium post[node.js进程负载平衡性能:比较cluster moudlle、iptables和Nginx](https://medium.com/@fermads/node-js-process-load-balancing- iptabls -and- Nginx -6746aaf38272)
> ... Node cluster易于实施和配置,不依赖于其他软件就可以在Node的领域内进行。请记住,你的主进程将会工作几乎和你的工作进程一样多,比较于其他的解决方案,少一点请求率...
\ No newline at end of file
diff --git a/sections/production/utilizecpu.md b/sections/production/utilizecpu.md
index c99a081b0..301a0fc78 100644
--- a/sections/production/utilizecpu.md
+++ b/sections/production/utilizecpu.md
@@ -1,26 +1,26 @@
-# Utilize all CPU cores
-
-
-
-### One Paragraph Explainer
-
-It might not come as a surprise that in its basic form, Node runs over a single thread=single process=single CPU. Paying for beefy hardware with 4 or 8 CPU and utilizing only one sounds crazy, right? The quickest solution which fits medium sized apps is using Node’s Cluster module which in 10 lines of code spawns a process for each logical core and route requests between the processes in a round-robin style. Even better, use PM2 which sugarcoats the clustering module with a simple interface and cool monitoring UI. While this solution works well for traditional applications, it might fall short for applications that require top-notch performance and robust DevOps flow. For those advanced use cases, consider replicating the NODE process using custom deployment script and balancing using a specialized tool such as nginx or use a container engine such as AWS ECS or Kubernetees that have advanced features for deployment and replication of processes.
-
-
-
-### Comparison: Balancing using Node’s cluster vs nginx
-
-![Balancing using Node’s cluster vs nginx](/assets/images/utilizecpucores1.png "Balancing using Node’s cluster vs nginx")
-
-
-
-### What Other Bloggers Say
-
-* From the [Node.js documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
-> ... The second approach, Node clusters, should, in theory, give the best performance. In practice, however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight ...
-
-* From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
-> ... Clustering is made possible with Node’s cluster module. This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it’s far better to use one of the many tools out there that do it for you automatically; for example node-pm or cluster-service ...
-
-* From the Medium post [Node.js process load balance performance: comparing cluster module, iptables, and Nginx](https://medium.com/@fermads/node-js-process-load-balancing-comparing-cluster-iptables-and-nginx-6746aaf38272)
-> ... Node cluster is simple to implement and configure, things are kept inside Node’s realm without depending on other software. Just remember your master process will work almost as much as your worker processes and with a little less request rate than the other solutions ...
+# Utilize all CPU cores
+
+
+
+### One Paragraph Explainer
+
+It might not come as a surprise that in its basic form, Node runs over a single thread=single process=single CPU. Paying for beefy hardware with 4 or 8 CPU and utilizing only one sounds crazy, right? The quickest solution which fits medium sized apps is using Node’s Cluster module which in 10 lines of code spawns a process for each logical core and route requests between the processes in a round-robin style. Even better, use PM2 which sugarcoats the clustering module with a simple interface and cool monitoring UI. While this solution works well for traditional applications, it might fall short for applications that require top-notch performance and robust DevOps flow. For those advanced use cases, consider replicating the NODE process using custom deployment script and balancing using a specialized tool such as nginx or use a container engine such as AWS ECS or Kubernetees that have advanced features for deployment and replication of processes.
+
+
+
+### Comparison: Balancing using Node’s cluster vs nginx
+
+![Balancing using Node’s cluster vs nginx](/assets/images/utilizecpucores1.png "Balancing using Node’s cluster vs nginx")
+
+
+
+### What Other Bloggers Say
+
+* From the [Node.js documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
+> ... The second approach, Node clusters, should, in theory, give the best performance. In practice, however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight ...
+
+* From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
+> ... Clustering is made possible with Node’s cluster module. This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it’s far better to use one of the many tools out there that do it for you automatically; for example node-pm or cluster-service ...
+
+* From the Medium post [Node.js process load balance performance: comparing cluster module, iptables, and Nginx](https://medium.com/@fermads/node-js-process-load-balancing-comparing-cluster-iptables-and-nginx-6746aaf38272)
+> ... Node cluster is simple to implement and configure, things are kept inside Node’s realm without depending on other software. Just remember your master process will work almost as much as your worker processes and with a little less request rate than the other solutions ...
diff --git a/sections/projectstructre/breakintcomponents.korean.md b/sections/projectstructre/breakintcomponents.korean.md
index 1da60edcc..6dedadfe1 100644
--- a/sections/projectstructre/breakintcomponents.korean.md
+++ b/sections/projectstructre/breakintcomponents.korean.md
@@ -1,36 +1,36 @@
-# 组件式构建你的解决方案
-
-
-
-
-### 一段解释
-
-对于中等规模的应用程序及以上,一个代码库是非常糟糕的 - 一个包含很多依赖的大型软件很难理解,往往导致代码混乱。即使是那些擅长解决负责问题和 "模块化" 的聪明架构师 - 在设计上花费了很大的脑力, 每一个变化都需要仔细评估对其他依赖对象的影响。最终的解决方案是开发小型软件:将整个堆栈划分为独立的组件,这些组件不与其他组件共享文件,每个组件由很少的文件构成(例如API、服务、数据访问、测试等),因此很容易理解它。有些人可能称之为 "microservices" 架构 - 重要的是要理解 microservices 不是一个你必须遵循的规范,而是一套原则。您可以将许多原则引入到成熟的 microservices 体系结构中, 或者只采用少数几个。只要您保持软件的复杂性低, 两者都是好的。最起码应该做的是在组件之间创建一个基本边界, 为每个业务组件在项目根目录中分配一个文件夹, 并使其自包含-其他组件只能通过其公共接口或 API 使用其功能。这是保持您的组件简单的基础,在未来, 一旦您的应用程序增长,避免依赖性地狱,为全面的 microservices 架构铺平了道路.
-
-
-
-
-### 博客引用: "伸缩需要对整个应用程序进行伸缩设计"
- 摘自博客 MartinFowler.com
-
- > 单个应用程序可以成功, 但越来越多的人对它们感到失望 - 尤其是随着更多的应用程序被部署到云中。更改周期被捆绑在一起 - 对应用程序的一小部分进行更改, 需要重建和部署整个整体。随着时间的推移, 通常很难保持一个良好的模块化结构, 这使得更改哪怕只会影响该模块中的一个模块变得更加困难。伸缩设计需要扩展整个应用程序, 而不是它的部分,这往往需要更多资源。
-
-
-
- ### 博客引用: "那么, 你的应用程序的架构声明了什么?"
- 摘自博客 [uncle-bob](https://8thlight.com/blog/uncle-bob/2011/09/30/Screaming-Architecture.html)
-
-> ...如果你正在寻找一个图书馆的建筑架构, 你可能会看到一个盛大的入口, 一个 check-in-out 的文员, 阅读区, 小会议室, 画廊, 画廊后面容纳了装载所有图书馆书籍的书架。建筑会声明: 图书馆.
-那么, 应用程序的体系架构会声明什么呢? 当您查看顶级目录结构和最高级别包中的源文件时; 他们声明: 医疗保健系统, 或会计系统, 或库存管理系统? 或者他们声明: Rails, 或Spring/Hibernate, 或 ASP?.
-
-
-
-
- ### 推荐: 通过独立组件构建解决方案
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
-
-
-
-
-### 避免: 按技术角色对文件进行分组
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
+# 组件式构建你的解决方案
+
+
+
+
+### 一段解释
+
+对于中等规模的应用程序及以上,一个代码库是非常糟糕的 - 一个包含很多依赖的大型软件很难理解,往往导致代码混乱。即使是那些擅长解决负责问题和 "模块化" 的聪明架构师 - 在设计上花费了很大的脑力, 每一个变化都需要仔细评估对其他依赖对象的影响。最终的解决方案是开发小型软件:将整个堆栈划分为独立的组件,这些组件不与其他组件共享文件,每个组件由很少的文件构成(例如API、服务、数据访问、测试等),因此很容易理解它。有些人可能称之为 "microservices" 架构 - 重要的是要理解 microservices 不是一个你必须遵循的规范,而是一套原则。您可以将许多原则引入到成熟的 microservices 体系结构中, 或者只采用少数几个。只要您保持软件的复杂性低, 两者都是好的。最起码应该做的是在组件之间创建一个基本边界, 为每个业务组件在项目根目录中分配一个文件夹, 并使其自包含-其他组件只能通过其公共接口或 API 使用其功能。这是保持您的组件简单的基础,在未来, 一旦您的应用程序增长,避免依赖性地狱,为全面的 microservices 架构铺平了道路.
+
+
+
+
+### 博客引用: "伸缩需要对整个应用程序进行伸缩设计"
+ 摘自博客 MartinFowler.com
+
+ > 单个应用程序可以成功, 但越来越多的人对它们感到失望 - 尤其是随着更多的应用程序被部署到云中。更改周期被捆绑在一起 - 对应用程序的一小部分进行更改, 需要重建和部署整个整体。随着时间的推移, 通常很难保持一个良好的模块化结构, 这使得更改哪怕只会影响该模块中的一个模块变得更加困难。伸缩设计需要扩展整个应用程序, 而不是它的部分,这往往需要更多资源。
+
+
+
+ ### 博客引用: "那么, 你的应用程序的架构声明了什么?"
+ 摘自博客 [uncle-bob](https://8thlight.com/blog/uncle-bob/2011/09/30/Screaming-Architecture.html)
+
+> ...如果你正在寻找一个图书馆的建筑架构, 你可能会看到一个盛大的入口, 一个 check-in-out 的文员, 阅读区, 小会议室, 画廊, 画廊后面容纳了装载所有图书馆书籍的书架。建筑会声明: 图书馆.
+那么, 应用程序的体系架构会声明什么呢? 当您查看顶级目录结构和最高级别包中的源文件时; 他们声明: 医疗保健系统, 或会计系统, 或库存管理系统? 或者他们声明: Rails, 或Spring/Hibernate, 或 ASP?.
+
+
+
+
+ ### 推荐: 通过独立组件构建解决方案
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
+
+
+
+
+### 避免: 按技术角色对文件进行分组
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
diff --git a/sections/projectstructre/breakintcomponents.md b/sections/projectstructre/breakintcomponents.md
index c28a0f10f..4b1c0b36d 100644
--- a/sections/projectstructre/breakintcomponents.md
+++ b/sections/projectstructre/breakintcomponents.md
@@ -1,37 +1,37 @@
-# Structure your solution by components
-
-
-
-### One Paragraph Explainer
-
-For medium sized apps and above, monoliths are really bad - having one big software with many dependencies is just hard to reason about and often leads to spaghetti code. Even smart architects — those who are skilled enough to tame the beast and 'modularize' it — spend great mental effort on design, and each change requires carefully evaluating the impact on other dependent objects. The ultimate solution is to develop small software: divide the whole stack into self-contained components that don't share files with others, each constitutes very few files (e.g. API, service, data access, test, etc.) so that it's very easy to reason about it. Some may call this 'microservices' architecture — it's important to understand that microservices are not a spec which you must follow, but rather a set of principles. You may adopt many principles into a full-blown microservices architecture or adopt only a few. Both are good as long as you keep the software complexity low. The very least you should do is create basic borders between components, assign a folder in your project root for each business component and make it self-contained - other components are allowed to consume its functionality only through its public interface or API. This is the foundation for keeping your components simple, avoid dependency hell and pave the way to full-blown microservices in the future once your app grows.
-
-
-
-### Blog Quote: "Scaling requires scaling of the entire application"
-
- From the blog MartinFowler.com
-
-> Monolithic applications can be successful, but increasingly people are feeling frustrations with them - especially as more applications are being deployed to the cloud. Change cycles are tied together - a change made to a small part of the application requires the entire monolith to be rebuilt and deployed. Over time it's often hard to keep a good modular structure, making it harder to keep changes that ought to only affect one module within that module. Scaling requires scaling of the entire application rather than parts of it that require greater resource.
-
-
-
-### Blog Quote: "So what does the architecture of your application scream?"
-
- From the blog [uncle-bob](https://8thlight.com/blog/uncle-bob/2011/09/30/Screaming-Architecture.html)
-
-> ...if you were looking at the architecture of a library, you’d likely see a grand entrance, an area for check-in-out clerks, reading areas, small conference rooms, and gallery after gallery capable of holding bookshelves for all the books in the library. That architecture would scream: Library.
-
-So what does the architecture of your application scream? When you look at the top level directory structure, and the source files in the highest level package; do they scream: Health Care System, or Accounting System, or Inventory Management System? Or do they scream: Rails, or Spring/Hibernate, or ASP?.
-
-
-
-### Good: Structure your solution by self-contained components
-
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
-
-
-
-### Bad: Group your files by technical role
-
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
+# Structure your solution by components
+
+
+
+### One Paragraph Explainer
+
+For medium sized apps and above, monoliths are really bad - having one big software with many dependencies is just hard to reason about and often leads to spaghetti code. Even smart architects — those who are skilled enough to tame the beast and 'modularize' it — spend great mental effort on design, and each change requires carefully evaluating the impact on other dependent objects. The ultimate solution is to develop small software: divide the whole stack into self-contained components that don't share files with others, each constitutes very few files (e.g. API, service, data access, test, etc.) so that it's very easy to reason about it. Some may call this 'microservices' architecture — it's important to understand that microservices are not a spec which you must follow, but rather a set of principles. You may adopt many principles into a full-blown microservices architecture or adopt only a few. Both are good as long as you keep the software complexity low. The very least you should do is create basic borders between components, assign a folder in your project root for each business component and make it self-contained - other components are allowed to consume its functionality only through its public interface or API. This is the foundation for keeping your components simple, avoid dependency hell and pave the way to full-blown microservices in the future once your app grows.
+
+
+
+### Blog Quote: "Scaling requires scaling of the entire application"
+
+ From the blog MartinFowler.com
+
+> Monolithic applications can be successful, but increasingly people are feeling frustrations with them - especially as more applications are being deployed to the cloud. Change cycles are tied together - a change made to a small part of the application requires the entire monolith to be rebuilt and deployed. Over time it's often hard to keep a good modular structure, making it harder to keep changes that ought to only affect one module within that module. Scaling requires scaling of the entire application rather than parts of it that require greater resource.
+
+
+
+### Blog Quote: "So what does the architecture of your application scream?"
+
+ From the blog [uncle-bob](https://8thlight.com/blog/uncle-bob/2011/09/30/Screaming-Architecture.html)
+
+> ...if you were looking at the architecture of a library, you’d likely see a grand entrance, an area for check-in-out clerks, reading areas, small conference rooms, and gallery after gallery capable of holding bookshelves for all the books in the library. That architecture would scream: Library.
+
+So what does the architecture of your application scream? When you look at the top level directory structure, and the source files in the highest level package; do they scream: Health Care System, or Accounting System, or Inventory Management System? Or do they scream: Rails, or Spring/Hibernate, or ASP?.
+
+
+
+### Good: Structure your solution by self-contained components
+
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
+
+
+
+### Bad: Group your files by technical role
+
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
diff --git a/sections/projectstructre/configguide.chinese.md b/sections/projectstructre/configguide.chinese.md
index 90bddc18c..2efeb2ba1 100644
--- a/sections/projectstructre/configguide.chinese.md
+++ b/sections/projectstructre/configguide.chinese.md
@@ -1,34 +1,34 @@
-# 使用环境感知,安全,分层的配置
-
-
-
-
-### 一段解释
-
-当我们处理配置参数时,常常会很慢并且很烦躁:(1)当需要注入100个keys(而不是只在配置文件中提交它们)时,使用进程环境变量设置所有的keys变得非常繁琐,但是当处理只有devops管理权限的文件时,不改变代码行为就不不会变。一个可靠的配置解决方案必须结合配置文件和进程变量覆盖。(2)枚举一个普通JSON的所有keys时,当目录变得非常庞杂的时候,查找修改条目困难。几乎没有配置库允许将配置存储在多个文件中,运行时将所有文件联合起来。分成几个部分的分层JSON文件能够克服这个问题。请参照下面示例。(3)不推荐存储像密码数据这样的敏感信息,但是又没有快速便捷的方法解决这个难题。一些配置库允许文件加密,其他库在Git提交时加密目录,或者不存储这些目录的真实值,在通过环境变量部署期间枚举真实值。(4)一些高级配置场景需要通过命令行(vargs)注入配置值,或者像Redis一样通过集中缓存同步配置信息,所以不同的服务器不会保存不同的数据。
-
-一些配置库可以免费提供这些功能的大部分功能,请查看NPM库([nconf](https://www.npmjs.com/package/nconf) 和 [config](https://www.npmjs.com/package/config))这些库可以满足这些要求中的许多要求。
-
-
-
-### 代码示例 – 分层配置有助于查找条目和维护庞大的配置文件
-
-```javascript
-{
- // Customer module configs
- "Customer": {
- "dbConfig": {
- "host": "localhost",
- "port": 5984,
- "dbName": "customers"
- },
- "credit": {
- "initialLimit": 100,
- // Set low for development
- "initialDays": 1
- }
- }
-}
-```
-
-
+# 使用环境感知,安全,分层的配置
+
+
+
+
+### 一段解释
+
+当我们处理配置参数时,常常会很慢并且很烦躁:(1)当需要注入100个keys(而不是只在配置文件中提交它们)时,使用进程环境变量设置所有的keys变得非常繁琐,但是当处理只有devops管理权限的文件时,不改变代码行为就不不会变。一个可靠的配置解决方案必须结合配置文件和进程变量覆盖。(2)枚举一个普通JSON的所有keys时,当目录变得非常庞杂的时候,查找修改条目困难。几乎没有配置库允许将配置存储在多个文件中,运行时将所有文件联合起来。分成几个部分的分层JSON文件能够克服这个问题。请参照下面示例。(3)不推荐存储像密码数据这样的敏感信息,但是又没有快速便捷的方法解决这个难题。一些配置库允许文件加密,其他库在Git提交时加密目录,或者不存储这些目录的真实值,在通过环境变量部署期间枚举真实值。(4)一些高级配置场景需要通过命令行(vargs)注入配置值,或者像Redis一样通过集中缓存同步配置信息,所以不同的服务器不会保存不同的数据。
+
+一些配置库可以免费提供这些功能的大部分功能,请查看NPM库([nconf](https://www.npmjs.com/package/nconf) 和 [config](https://www.npmjs.com/package/config))这些库可以满足这些要求中的许多要求。
+
+
+
+### 代码示例 – 分层配置有助于查找条目和维护庞大的配置文件
+
+```javascript
+{
+ // Customer module configs
+ "Customer": {
+ "dbConfig": {
+ "host": "localhost",
+ "port": 5984,
+ "dbName": "customers"
+ },
+ "credit": {
+ "initialLimit": 100,
+ // Set low for development
+ "initialDays": 1
+ }
+ }
+}
+```
+
+
diff --git a/sections/projectstructre/configguide.md b/sections/projectstructre/configguide.md
index c78f3a7dc..89fa8cb36 100644
--- a/sections/projectstructre/configguide.md
+++ b/sections/projectstructre/configguide.md
@@ -1,41 +1,41 @@
-# Use environment aware, secure and hierarchical config
-
-
-
-### One Paragraph Explainer
-
-When dealing with configuration data, many things can just annoy and slow down:
-
-1. setting all the keys using process environment variables becomes very tedious when in need to inject 100 keys (instead of just committing those in a config file), however when dealing with files only the DevOps admins cannot alter the behavior without changing the code. A reliable config solution must combine both configuration files + overrides from the process variables
-
-2. when specifying all keys in a flat JSON, it becomes frustrating to find and modify entries when the list grows bigger. A hierarchical JSON file that is grouped into sections can overcome this issue + few config libraries allow to store the configuration in multiple files and take care to union all at runtime. See example below
-
-3. storing sensitive information like DB password is obviously not recommended but no quick and handy solution exists for this challenge. Some configuration libraries allow to encrypt files, others encrypt those entries during GIT commits or simply don't store real values for those entries and specify the actual value during deployment via environment variables.
-
-4. some advanced configuration scenarios demand to inject configuration values via command line (vargs) or sync configuration info via a centralized cache like Redis so multiple servers will use the same configuration data.
-
-Some configuration libraries can provide most of these features for free, have a look at npm libraries like [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) and [config](https://www.npmjs.com/package/config) which tick many of these requirements.
-
-
-
-### Code Example – hierarchical config helps to find entries and maintain huge config files
-
-```json
-{
- // Customer module configs
- "Customer": {
- "dbConfig": {
- "host": "localhost",
- "port": 5984,
- "dbName": "customers"
- },
- "credit": {
- "initialLimit": 100,
- // Set low for development
- "initialDays": 1
- }
- }
-}
-```
-
-
+# Use environment aware, secure and hierarchical config
+
+
+
+### One Paragraph Explainer
+
+When dealing with configuration data, many things can just annoy and slow down:
+
+1. setting all the keys using process environment variables becomes very tedious when in need to inject 100 keys (instead of just committing those in a config file), however when dealing with files only the DevOps admins cannot alter the behavior without changing the code. A reliable config solution must combine both configuration files + overrides from the process variables
+
+2. when specifying all keys in a flat JSON, it becomes frustrating to find and modify entries when the list grows bigger. A hierarchical JSON file that is grouped into sections can overcome this issue + few config libraries allow to store the configuration in multiple files and take care to union all at runtime. See example below
+
+3. storing sensitive information like DB password is obviously not recommended but no quick and handy solution exists for this challenge. Some configuration libraries allow to encrypt files, others encrypt those entries during GIT commits or simply don't store real values for those entries and specify the actual value during deployment via environment variables.
+
+4. some advanced configuration scenarios demand to inject configuration values via command line (vargs) or sync configuration info via a centralized cache like Redis so multiple servers will use the same configuration data.
+
+Some configuration libraries can provide most of these features for free, have a look at npm libraries like [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) and [config](https://www.npmjs.com/package/config) which tick many of these requirements.
+
+
+
+### Code Example – hierarchical config helps to find entries and maintain huge config files
+
+```json
+{
+ // Customer module configs
+ "Customer": {
+ "dbConfig": {
+ "host": "localhost",
+ "port": 5984,
+ "dbName": "customers"
+ },
+ "credit": {
+ "initialLimit": 100,
+ // Set low for development
+ "initialDays": 1
+ }
+ }
+}
+```
+
+
diff --git a/sections/projectstructre/createlayers.chinese.md b/sections/projectstructre/createlayers.chinese.md
index efa7db1b6..6a0866330 100644
--- a/sections/projectstructre/createlayers.chinese.md
+++ b/sections/projectstructre/createlayers.chinese.md
@@ -1,11 +1,11 @@
-# 应用程序分层,保持Express在其边界内
-
-
-
- ### 将组件代码分成web, services, DAL层
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Separate component code into layers")
-
-
-
-### 1分钟说明:混合层的缺点
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/keepexpressinweb.gif "The downside of mixing layers")
+# 应用程序分层,保持Express在其边界内
+
+
+
+ ### 将组件代码分成web, services, DAL层
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Separate component code into layers")
+
+
+
+### 1分钟说明:混合层的缺点
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/keepexpressinweb.gif "The downside of mixing layers")
diff --git a/sections/projectstructre/createlayers.md b/sections/projectstructre/createlayers.md
index cdadfd85d..029924a57 100644
--- a/sections/projectstructre/createlayers.md
+++ b/sections/projectstructre/createlayers.md
@@ -1,13 +1,13 @@
-# Layer your app, keep Express within its boundaries
-
-
-
- ### Separate component code into layers: web, services, and DAL
-
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Separate component code into layers")
-
-
-
-### 1 min explainer: The downside of mixing layers
-
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/keepexpressinweb.gif "The downside of mixing layers")
+# Layer your app, keep Express within its boundaries
+
+
+
+ ### Separate component code into layers: web, services, and DAL
+
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Separate component code into layers")
+
+
+
+### 1 min explainer: The downside of mixing layers
+
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/keepexpressinweb.gif "The downside of mixing layers")
diff --git a/sections/projectstructre/separateexpress.chinese.md b/sections/projectstructre/separateexpress.chinese.md
index 8b8a2d703..37af9cf1b 100644
--- a/sections/projectstructre/separateexpress.chinese.md
+++ b/sections/projectstructre/separateexpress.chinese.md
@@ -1,63 +1,63 @@
-# Express的 '应用' 和 '服务' 分离
-
-
-
-
-### 一段解释
-
-最新的Express生成器有一个值得保留的伟大实践--API声明与网络相关配置(端口、协议等)是分开的。这样就可以在不执行网络调用的情况下对API进行在线测试,它所带来的好处是:快速执行测试操作和获取代码覆盖率。它还允许在灵活多样的网络条件下部署相同的API。额外好处:更好的关注点分离和更清晰的代码结构。
-
-
-
-### 代码示例:API声明应该在 app.js 文件里面
-
-```javascript
-var app = express();
-app.use(bodyParser.json());
-app.use("/api/events", events.API);
-app.use("/api/forms", forms);
-
-```
-
-
-
-### 代码示例: 服务器网络声明,应该在 /bin/www 文件里面
-
-```javascript
-var app = require('../app');
-var http = require('http');
-
-/**
- * Get port from environment and store in Express.
- */
-
-var port = normalizePort(process.env.PORT || '3000');
-app.set('port', port);
-
-/**
- * Create HTTP server.
- */
-
-var server = http.createServer(app);
-
-```
-
-
-### 示例代码: 使用超快的流行的测试包在线测试你的代码
-
-```javascript
-const app = express();
-
-app.get('/user', function(req, res) {
- res.status(200).json({ name: 'tobi' });
-});
-
-request(app)
- .get('/user')
- .expect('Content-Type', /json/)
- .expect('Content-Length', '15')
- .expect(200)
- .end(function(err, res) {
- if (err) throw err;
- });
-````
+# Express的 '应用' 和 '服务' 分离
+
+
+
+
+### 一段解释
+
+最新的Express生成器有一个值得保留的伟大实践--API声明与网络相关配置(端口、协议等)是分开的。这样就可以在不执行网络调用的情况下对API进行在线测试,它所带来的好处是:快速执行测试操作和获取代码覆盖率。它还允许在灵活多样的网络条件下部署相同的API。额外好处:更好的关注点分离和更清晰的代码结构。
+
+
+
+### 代码示例:API声明应该在 app.js 文件里面
+
+```javascript
+var app = express();
+app.use(bodyParser.json());
+app.use("/api/events", events.API);
+app.use("/api/forms", forms);
+
+```
+
+
+
+### 代码示例: 服务器网络声明,应该在 /bin/www 文件里面
+
+```javascript
+var app = require('../app');
+var http = require('http');
+
+/**
+ * Get port from environment and store in Express.
+ */
+
+var port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+
+var server = http.createServer(app);
+
+```
+
+
+### 示例代码: 使用超快的流行的测试包在线测试你的代码
+
+```javascript
+const app = express();
+
+app.get('/user', function(req, res) {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end(function(err, res) {
+ if (err) throw err;
+ });
+````
diff --git a/sections/projectstructre/separateexpress.md b/sections/projectstructre/separateexpress.md
index c60ea4b57..c0f88679f 100644
--- a/sections/projectstructre/separateexpress.md
+++ b/sections/projectstructre/separateexpress.md
@@ -1,59 +1,59 @@
-# Separate Express 'app' and 'server'
-
-
-
-### One Paragraph Explainer
-
-The latest Express generator comes with a great practice that is worth to keep - the API declaration is separated from the network related configuration (port, protocol, etc). This allows testing the API in-process, without performing network calls, with all the benefits that it brings to the table: fast testing execution and getting coverage metrics of the code. It also allows deploying the same API under flexible and different network conditions. Bonus: better separation of concerns and cleaner code
-
-
-
-### Code example: API declaration, should reside in app.js
-
-```javascript
-var app = express();
-app.use(bodyParser.json());
-app.use("/api/events", events.API);
-app.use("/api/forms", forms);
-```
-
-
-
-### Code example: Server network declaration, should reside in /bin/www
-
-```javascript
-var app = require('../app');
-var http = require('http');
-
-/**
- * Get port from environment and store in Express.
- */
-
-var port = normalizePort(process.env.PORT || '3000');
-app.set('port', port);
-
-/**
- * Create HTTP server.
- */
-
-var server = http.createServer(app);
-```
-
-### Example: test your API in-process using supertest (popular testing package)
-
-```javascript
-const app = express();
-
-app.get('/user', function(req, res) {
- res.status(200).json({ name: 'tobi' });
-});
-
-request(app)
- .get('/user')
- .expect('Content-Type', /json/)
- .expect('Content-Length', '15')
- .expect(200)
- .end(function(err, res) {
- if (err) throw err;
- });
-````
+# Separate Express 'app' and 'server'
+
+
+
+### One Paragraph Explainer
+
+The latest Express generator comes with a great practice that is worth to keep - the API declaration is separated from the network related configuration (port, protocol, etc). This allows testing the API in-process, without performing network calls, with all the benefits that it brings to the table: fast testing execution and getting coverage metrics of the code. It also allows deploying the same API under flexible and different network conditions. Bonus: better separation of concerns and cleaner code
+
+
+
+### Code example: API declaration, should reside in app.js
+
+```javascript
+var app = express();
+app.use(bodyParser.json());
+app.use("/api/events", events.API);
+app.use("/api/forms", forms);
+```
+
+
+
+### Code example: Server network declaration, should reside in /bin/www
+
+```javascript
+var app = require('../app');
+var http = require('http');
+
+/**
+ * Get port from environment and store in Express.
+ */
+
+var port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+
+var server = http.createServer(app);
+```
+
+### Example: test your API in-process using supertest (popular testing package)
+
+```javascript
+const app = express();
+
+app.get('/user', function(req, res) {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end(function(err, res) {
+ if (err) throw err;
+ });
+````
diff --git a/sections/projectstructre/thincomponents.chinese.md b/sections/projectstructre/thincomponents.chinese.md
index 65a0cf3be..d55704b02 100644
--- a/sections/projectstructre/thincomponents.chinese.md
+++ b/sections/projectstructre/thincomponents.chinese.md
@@ -1,26 +1,26 @@
-# 用组件来构造你的解决方案
-
-
-
-
-### 一段解释
-
-对于中型应用以上来说,按部就班的写在一起真是太糟糕了-当一个有很多依赖的大型的软件会导致我们理解起来非常困难并且导致我们的代码杂乱不堪。甚至像那些能够熟练地驯服野兽的聪明的设计师一样,他们在设计上花费大量的精力用来"模块化"代码,每一次改动都需要仔细的评估对于其他依赖对象的影响。构建小型项目的最终方法是:将整体的项目分享一个个不与其他组件共享文件的独立组件,每个组件由很少的文件组成(例如API、服务、数据访问、测试等),所以这是比较容易理解的。一些被称为"microservices"的架构,去理解"microservices"不是你必须遵守的规范而是一套原则是非常重要的。你可以将许多原则应用到一个成熟的微服务体系结构中,或者只采用少数几个原则。只要你把软件的复杂性保持在低水平,两者都是好的。您至少应该做的是在组件之间创建一个基本的边界,在项目根中为每个业务组件分配一个文件夹,并让它自己做到其他组件只允许通过它的公共接口或API来实现它的功能。这是让你的组件保持简单的基础,避免依赖关系,在你的应用程序成长后,为将来成熟的微服务铺平道路。
-
-
-
-
-### 引用博客: "扩展需要整个应用的扩展"
- 摘自博客 MartinFowler.com
-
- > 单片应用程序可以成功,但是越来越多的人对它们感到失望——特别是当越来越多的应用程序被部署到云上时。变更周期是绑定在一起的——对应用程序的一小部分进行了更改,需要重新构建和部署整个庞然大物。随着时间的推移,保持良好的模块结构通常很难,这使得更改只会影响自己内部的模块变得更加困难。扩展需要扩展整个应用程序,而不是需要更大的资源的部分。
-
-
-
- ### 推荐: 通过自包含的组件来构造解决方案
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
-
-
-
-### 避免: 通过技术角色对文件进行分组
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
+# 用组件来构造你的解决方案
+
+
+
+
+### 一段解释
+
+对于中型应用以上来说,按部就班的写在一起真是太糟糕了-当一个有很多依赖的大型的软件会导致我们理解起来非常困难并且导致我们的代码杂乱不堪。甚至像那些能够熟练地驯服野兽的聪明的设计师一样,他们在设计上花费大量的精力用来"模块化"代码,每一次改动都需要仔细的评估对于其他依赖对象的影响。构建小型项目的最终方法是:将整体的项目分享一个个不与其他组件共享文件的独立组件,每个组件由很少的文件组成(例如API、服务、数据访问、测试等),所以这是比较容易理解的。一些被称为"microservices"的架构,去理解"microservices"不是你必须遵守的规范而是一套原则是非常重要的。你可以将许多原则应用到一个成熟的微服务体系结构中,或者只采用少数几个原则。只要你把软件的复杂性保持在低水平,两者都是好的。您至少应该做的是在组件之间创建一个基本的边界,在项目根中为每个业务组件分配一个文件夹,并让它自己做到其他组件只允许通过它的公共接口或API来实现它的功能。这是让你的组件保持简单的基础,避免依赖关系,在你的应用程序成长后,为将来成熟的微服务铺平道路。
+
+
+
+
+### 引用博客: "扩展需要整个应用的扩展"
+ 摘自博客 MartinFowler.com
+
+ > 单片应用程序可以成功,但是越来越多的人对它们感到失望——特别是当越来越多的应用程序被部署到云上时。变更周期是绑定在一起的——对应用程序的一小部分进行了更改,需要重新构建和部署整个庞然大物。随着时间的推移,保持良好的模块结构通常很难,这使得更改只会影响自己内部的模块变得更加困难。扩展需要扩展整个应用程序,而不是需要更大的资源的部分。
+
+
+
+ ### 推荐: 通过自包含的组件来构造解决方案
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
+
+
+
+### 避免: 通过技术角色对文件进行分组
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
diff --git a/sections/projectstructre/thincomponents.md b/sections/projectstructre/thincomponents.md
index 750d31386..b248637b4 100644
--- a/sections/projectstructre/thincomponents.md
+++ b/sections/projectstructre/thincomponents.md
@@ -1,27 +1,27 @@
-# Structure your solution by components
-
-
-
-### One Paragraph Explainer
-
-For medium sized apps and above, monoliths are really bad - one big software with many dependencies is just hard to reason about and often leads to code spaghetti. Even those smart architects who are skilled to tame the beast and 'modularize' it - spend great mental effort on design and each change requires to carefully evaluate the impact on other dependent objects. The ultimate solution is to develop small software: divide the whole stack into self-contained components that don't share files with others, each constitutes very few files (e.g. API, service, data access, test, etc) so that it's very easy to reason about it. Some may call this 'microservices' architecture - it's important to understand that microservices are not a spec which you must follow rather a set of principles. You may adopt many principles into a full-blown microservices architecture or adopt only a few. Both are good as long as you keep the software complexity low. The very least you should do is create basic borders between components, assign a folder in your project root for each business component and make it self-contained - other components are allowed to consume its functionality only through its public interface or API. This is the foundation for keeping your components simple, avoid dependencies hell and pave the way to full-blown microservices in the future once your app grows
-
-
-
-### Blog Quote: "Scaling requires scaling of the entire application"
-
- From the blog MartinFowler.com
-
- > Monolithic applications can be successful, but increasingly people are feeling frustrations with them - especially as more applications are being deployed to the cloud. Change cycles are tied together - a change made to a small part of the application requires the entire monolith to be rebuilt and deployed. Over time it's often hard to keep a good modular structure, making it harder to keep changes that ought to only affect one module within that module. Scaling requires scaling of the entire application rather than parts of it that require greater resource.
-
-
-
-### Good: Structure your solution by self-contained components
-
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
-
-
-
-### Bad: Group your files by technical role
-
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
+# Structure your solution by components
+
+
+
+### One Paragraph Explainer
+
+For medium sized apps and above, monoliths are really bad - one big software with many dependencies is just hard to reason about and often leads to code spaghetti. Even those smart architects who are skilled to tame the beast and 'modularize' it - spend great mental effort on design and each change requires to carefully evaluate the impact on other dependent objects. The ultimate solution is to develop small software: divide the whole stack into self-contained components that don't share files with others, each constitutes very few files (e.g. API, service, data access, test, etc) so that it's very easy to reason about it. Some may call this 'microservices' architecture - it's important to understand that microservices are not a spec which you must follow rather a set of principles. You may adopt many principles into a full-blown microservices architecture or adopt only a few. Both are good as long as you keep the software complexity low. The very least you should do is create basic borders between components, assign a folder in your project root for each business component and make it self-contained - other components are allowed to consume its functionality only through its public interface or API. This is the foundation for keeping your components simple, avoid dependencies hell and pave the way to full-blown microservices in the future once your app grows
+
+
+
+### Blog Quote: "Scaling requires scaling of the entire application"
+
+ From the blog MartinFowler.com
+
+ > Monolithic applications can be successful, but increasingly people are feeling frustrations with them - especially as more applications are being deployed to the cloud. Change cycles are tied together - a change made to a small part of the application requires the entire monolith to be rebuilt and deployed. Over time it's often hard to keep a good modular structure, making it harder to keep changes that ought to only affect one module within that module. Scaling requires scaling of the entire application rather than parts of it that require greater resource.
+
+
+
+### Good: Structure your solution by self-contained components
+
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebycomponents.PNG "Structuring solution by components")
+
+
+
+### Bad: Group your files by technical role
+
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/structurebyroles.PNG "Structuring solution by technical roles")
diff --git a/sections/projectstructre/wraputilities.chinese.md b/sections/projectstructre/wraputilities.chinese.md
index cd6e86f46..1d3f14457 100644
--- a/sections/projectstructre/wraputilities.chinese.md
+++ b/sections/projectstructre/wraputilities.chinese.md
@@ -1,14 +1,14 @@
-# 将公用实用工具封装成 npm 包
-
-
-
-
-### 一段解释
-一旦你开始在不同的服务器上增加不同的组件并使用不同的服务器,这些服务器会消耗类似的工具,那么你应该开始管理依赖关系 - 你如何保留实用工具代码的一个副本,并让多个使用组件者使用和部署? 好吧,有一个这样的框架,它被称为npm ...首先用自己的代码包装第三方实用工具包,以便将来可以轻松替换,并发布自己的代码作为私人npm包。 现在,您所有的代码库都可以导入该代码并受益于免费的依赖管理框架。 您可以发布npm包供您自己的私人使用,而无需公开分享 [私人模块](https://docs.npmjs.com/private-modules/intro), [私人注册表](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) or [本地 npm 包](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
-
-
-
-
-
- ### 在环境和组件中共享你自己的公用实用工具
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/Privatenpm.png "构建解决方案的组件")
+# 将公用实用工具封装成 npm 包
+
+
+
+
+### 一段解释
+一旦你开始在不同的服务器上增加不同的组件并使用不同的服务器,这些服务器会消耗类似的工具,那么你应该开始管理依赖关系 - 你如何保留实用工具代码的一个副本,并让多个使用组件者使用和部署? 好吧,有一个这样的框架,它被称为npm ...首先用自己的代码包装第三方实用工具包,以便将来可以轻松替换,并发布自己的代码作为私人npm包。 现在,您所有的代码库都可以导入该代码并受益于免费的依赖管理框架。 您可以发布npm包供您自己的私人使用,而无需公开分享 [私人模块](https://docs.npmjs.com/private-modules/intro), [私人注册表](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) or [本地 npm 包](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
+
+
+
+
+
+ ### 在环境和组件中共享你自己的公用实用工具
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/Privatenpm.png "构建解决方案的组件")
diff --git a/sections/projectstructre/wraputilities.md b/sections/projectstructre/wraputilities.md
index 23cca38ca..4b52ff6db 100644
--- a/sections/projectstructre/wraputilities.md
+++ b/sections/projectstructre/wraputilities.md
@@ -1,13 +1,13 @@
-# Wrap common utilities as npm packages
-
-
-
-### One Paragraph Explainer
-
-Once you start growing and have different components on different servers which consumes similar utilities, you should start managing the dependencies - how can you keep 1 copy of your utility code and let multiple consumer components use and deploy it? well, there is a tool for that, it's called npm... Start by wrapping 3rd party utility packages with your own code to make it easily replaceable in the future and publish your own code as private npm package. Now, all your code base can import that code and benefit free dependency management tool. It's possible to publish npm packages for your own private use without sharing it publicly using [private modules](https://docs.npmjs.com/private-modules/intro), [private registry](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) or [local npm packages](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
-
-
-
-### Sharing your own common utilities across environments and components
-
-![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/Privatenpm.png "Structuring solution by components")
+# Wrap common utilities as npm packages
+
+
+
+### One Paragraph Explainer
+
+Once you start growing and have different components on different servers which consumes similar utilities, you should start managing the dependencies - how can you keep 1 copy of your utility code and let multiple consumer components use and deploy it? well, there is a tool for that, it's called npm... Start by wrapping 3rd party utility packages with your own code to make it easily replaceable in the future and publish your own code as private npm package. Now, all your code base can import that code and benefit free dependency management tool. It's possible to publish npm packages for your own private use without sharing it publicly using [private modules](https://docs.npmjs.com/private-modules/intro), [private registry](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) or [local npm packages](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
+
+
+
+### Sharing your own common utilities across environments and components
+
+![alt text](https://github.com/i0natan/nodebestpractices/blob/master/assets/images/Privatenpm.png "Structuring solution by components")
diff --git a/sections/security/avoideval.md b/sections/security/avoideval.md
index fe3342099..e034216f5 100644
--- a/sections/security/avoideval.md
+++ b/sections/security/avoideval.md
@@ -1,23 +1,23 @@
-# Avoid JS eval statements
-
-### One Paragraph Explainer
-
-`eval()`, `setTimeout()` and `setInterval()` are global functions, often used in Node.js, which accept a string parameter representing a JavaScript expression, statement, or sequence of statements. The security concern of using these functions is the possibility that untrusted user input might find its way into code execution leading to server compromise, as evaluating user code essentially allows an attacker to perform any actions that you can. It is suggested to refactor code to not rely on the usage of these functions where user input could be passed to the function and executed.
-
-### Code example
-
-```javascript
-// example of malicious code which an attacker was able to input
-userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
-
-// malicious code executed
-eval(userInput);
-```
-
-### What other bloggers say
-
-From the Essential Node.js Security book by [Liran Tal](https://leanpub.com/nodejssecurity):
-> The eval() function is perhaps of the most frowned upon JavaScript pieces from a security
-perspective. It parses a JavaScript string as text, and executes it as if it were a JavaScript code.
-Mixing that with untrusted user input that might find it’s way to eval() is a recipe for disaster that
+# Avoid JS eval statements
+
+### One Paragraph Explainer
+
+`eval()`, `setTimeout()` and `setInterval()` are global functions, often used in Node.js, which accept a string parameter representing a JavaScript expression, statement, or sequence of statements. The security concern of using these functions is the possibility that untrusted user input might find its way into code execution leading to server compromise, as evaluating user code essentially allows an attacker to perform any actions that you can. It is suggested to refactor code to not rely on the usage of these functions where user input could be passed to the function and executed.
+
+### Code example
+
+```javascript
+// example of malicious code which an attacker was able to input
+userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
+
+// malicious code executed
+eval(userInput);
+```
+
+### What other bloggers say
+
+From the Essential Node.js Security book by [Liran Tal](https://leanpub.com/nodejssecurity):
+> The eval() function is perhaps of the most frowned upon JavaScript pieces from a security
+perspective. It parses a JavaScript string as text, and executes it as if it were a JavaScript code.
+Mixing that with untrusted user input that might find it’s way to eval() is a recipe for disaster that
can end up with server compromise.
\ No newline at end of file
diff --git a/sections/security/bcryptpasswords.md b/sections/security/bcryptpasswords.md
index d21ba388a..4c8fb25b9 100644
--- a/sections/security/bcryptpasswords.md
+++ b/sections/security/bcryptpasswords.md
@@ -1,30 +1,30 @@
-# Avoid using the Node.js Crypto library for passwords, use Bcrypt
-
-### One Paragraph Explainer
-
-When storing user passwords, using an adaptive hashing algorithm such as bcrypt, offered by the [bcrypt npm module](https://www.npmjs.com/package/bcrypt) is recommended as opposed to using the native Node.js crypto module. `Math.random()` should also never be used as part of any password or token generation due to it's predictability.
-
-The `bcrypt` module or similar should be used as opposed to the JavaScript implementation, as when using `bcrypt`, a number of 'rounds' can be specified in order to provide a secure hash. This sets the work factor or the number of 'rounds' the data is processed for, and more hashing rounds leads to more secure hash (although this at the cost of CPU time). The introduction of hashing rounds means that the brute force factor is significantly reduced, as password crackers are slowed down increasing the time required to generate one attempt.
-
-### Code example
-
-```javascript
-// asynchronously generate a secure password using 10 hashing rounds
-bcrypt.hash('myPassword', 10, function(err, hash) {
- // Store secure hash in user record
-});
-
-// compare a provided password input with saved hash
-bcrypt.compare('somePassword', hash, function(err, match) {
- if(match) {
- // Passwords match
- } else {
- // Passwords don't match
- }
-});
-```
-
-### What other bloggers say
-
-From the blog by [Max McCarty](https://dzone.com/articles/nodejs-and-password-storage-with-bcrypt):
-> ... it’s not just using the right hashing algorithm. I’ve talked extensively about how the right tool also includes the necessary ingredient of “time” as part of the password hashing algorithm and what it means for the attacker who’s trying to crack passwords through brute-force.
+# Avoid using the Node.js Crypto library for passwords, use Bcrypt
+
+### One Paragraph Explainer
+
+When storing user passwords, using an adaptive hashing algorithm such as bcrypt, offered by the [bcrypt npm module](https://www.npmjs.com/package/bcrypt) is recommended as opposed to using the native Node.js crypto module. `Math.random()` should also never be used as part of any password or token generation due to it's predictability.
+
+The `bcrypt` module or similar should be used as opposed to the JavaScript implementation, as when using `bcrypt`, a number of 'rounds' can be specified in order to provide a secure hash. This sets the work factor or the number of 'rounds' the data is processed for, and more hashing rounds leads to more secure hash (although this at the cost of CPU time). The introduction of hashing rounds means that the brute force factor is significantly reduced, as password crackers are slowed down increasing the time required to generate one attempt.
+
+### Code example
+
+```javascript
+// asynchronously generate a secure password using 10 hashing rounds
+bcrypt.hash('myPassword', 10, function(err, hash) {
+ // Store secure hash in user record
+});
+
+// compare a provided password input with saved hash
+bcrypt.compare('somePassword', hash, function(err, match) {
+ if(match) {
+ // Passwords match
+ } else {
+ // Passwords don't match
+ }
+});
+```
+
+### What other bloggers say
+
+From the blog by [Max McCarty](https://dzone.com/articles/nodejs-and-password-storage-with-bcrypt):
+> ... it’s not just using the right hashing algorithm. I’ve talked extensively about how the right tool also includes the necessary ingredient of “time” as part of the password hashing algorithm and what it means for the attacker who’s trying to crack passwords through brute-force.
diff --git a/sections/security/childprocesses.md b/sections/security/childprocesses.md
index 16fddc7d0..75bfccbb8 100644
--- a/sections/security/childprocesses.md
+++ b/sections/security/childprocesses.md
@@ -1,31 +1,31 @@
-# Be cautious when working with child processes
-
-### One Paragraph Explainer
-
-As great as child processes are, they should be used with caution. Passing in user input must be sanitized, if not avoided at all.
-The dangers of unsanitized input executing system-level logic are unlimited, reaching from remote code execution to the exposure of
-sensitive system data and even data loss. A check list of preparations could look like this
-
-- avoid user input in every case, otherwise validate and sanitize it
-- limit the privileges of the parent and child processes using user/group identities
-- run your process inside of an isolated environment to prevent unwanted side-effects if the other preparations fail
-
-### Code example: Dangers of unsanitized child process executions
-
-```javascript
-const { exec } = require('child_process');
-
-...
-
-// as an example, take a script that takes two arguments, one of them is unsanitized user input
-exec('"/path/to/test file/someScript.sh" --someOption ' + input);
-
-// -> imagine what could happen if the user simply enters something like '&& rm -rf --no-preserve-root /'
-// you'd be in for an unwanted surprise
-```
-
-### Additional resources
-
-From the Node.js child process [documentation](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback):
-
-> Never pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.
+# Be cautious when working with child processes
+
+### One Paragraph Explainer
+
+As great as child processes are, they should be used with caution. Passing in user input must be sanitized, if not avoided at all.
+The dangers of unsanitized input executing system-level logic are unlimited, reaching from remote code execution to the exposure of
+sensitive system data and even data loss. A check list of preparations could look like this
+
+- avoid user input in every case, otherwise validate and sanitize it
+- limit the privileges of the parent and child processes using user/group identities
+- run your process inside of an isolated environment to prevent unwanted side-effects if the other preparations fail
+
+### Code example: Dangers of unsanitized child process executions
+
+```javascript
+const { exec } = require('child_process');
+
+...
+
+// as an example, take a script that takes two arguments, one of them is unsanitized user input
+exec('"/path/to/test file/someScript.sh" --someOption ' + input);
+
+// -> imagine what could happen if the user simply enters something like '&& rm -rf --no-preserve-root /'
+// you'd be in for an unwanted surprise
+```
+
+### Additional resources
+
+From the Node.js child process [documentation](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback):
+
+> Never pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.
diff --git a/sections/security/commonsecuritybestpractices.md b/sections/security/commonsecuritybestpractices.md
index fb9f6a274..08d472a4d 100644
--- a/sections/security/commonsecuritybestpractices.md
+++ b/sections/security/commonsecuritybestpractices.md
@@ -1,96 +1,96 @@
-[✔]: ../../assets/images/checkbox-small-blue.png
-
-# Common Node.js security best practices
-
-The common security guidelines section contains best practices that are standardized in many frameworks and conventions, running an application with ssl/tls for example should be a common guideline and convention followed in every setup to achieve great security benefits.
-
-## ![✔] Use SSL/TLS to encrypt the client-server connection
-
-**TL;DR:** In the times of [free SSL/TLS certificates](https://letsencrypt.org/) and easy configuration of those, you do no longer have to weigh advantages and disadvantages of using a secure server because the advantages such as security, support of modern technology and trust clearly outweigh the disadvantages like minimal overhead compared to pure http.
-
-**Otherwise:** Attackers could perform man-in-the-middle attacks, spy on your users' behaviour and perform even more malicious actions when the connection is unencrypted
-
-🔗 [**Read More: Running a secure Node.js server**](secureserver.md)
-
-
-
-## ![✔] Comparing secret values and hashes securely
-
-**TL;DR:** When comparing secret values or hashes like HMAC digests, you should use the [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) function Node provides out of the box since Node.js v6.6.0. This method compares two given objects and keeps comparing even if data does not match. The default equality comparison methods would simply return after a character mismatch, allowing timing attacks based on the operation length.
-
-**Otherwise:** Using default equality comparison operators you might expose critical information based on the time taken to compare two objects
-
-
-
-## ![✔] Generating random strings using Node.js
-
-**TL;DR:** Using a custom-built function generating pseudo-random strings for tokens and other security-sensitive use cases might actually not be as random as you think, rendering your application vulnerable to cryptographic attacks. When you have to generate secure random strings, use the [`crypto.RandomBytes(size, [callback])`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_randombytes_size_callback) function using available entropy provided by the system.
-
-**Otherwise:** When generating pseudo-random strings without cryptographically secure methods, attackers might predict and reproduce the generated results, rendering your application insecure
-
-
-
-Going on, below we've listed some important bits of advice from the OWASP project.
-
-## ![✔] OWASP A2: Broken Authentication
-
-- Require MFA/2FA for important services and accounts
-- Rotate passwords and access keys frequently, including SSH keys
-- Apply strong password policies, both for ops and in-application user management ([🔗 OWASP password recommendation](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
-- Do not ship or deploy your application with any default credentials, particularly for admin users or external services you depend on
-- Use only standard authentication methods like OAuth, OpenID, etc. - **avoid** basic authentication
-- Auth rate limiting: Disallow more than _X_ login attempts (including password recovery, etc.) in a period of _Y_
-- On login failure, don't let the user know whether the username or password verification failed, just return a common auth error
-- Consider using a centralized user management system to avoid managing multiple account per employee (e.g. GitHub, AWS, Jenkins, etc) and to benefit from a battle-tested user management system
-
-## ![✔] OWASP A5: Broken access control
-
-- Respect the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) - every component and DevOps person should only have access to the necessary information and resources
-- **Never** work with the console/root (full-privilege) account except for account management
-- Run all instances/containers on behalf of a role/service account
-- Assign permissions to groups and not to users. This should make permission management easier and more transparent for most cases
-
-## ![✔] OWASP A6: Security Misconfiguration
-
-- Access to production environment internals is done through the internal network only, use SSH or other ways, but _never_ expose internal services
-- Restrict internal network access - explicitly set which resource can access other resources (e.g. network policy or subnets)
-- If using cookies, configure it to "secured" mode where it's being sent over SSL only
-- If using cookies, configure it for "same site" only so only requests from same domain will get back the designated cookies
-- If using cookies, prefer "http only" configuration that prevent browser side JavaScript code from accessing the cookies
-- Protect each VPC with strict and restrictive access rules
-- Prioritize threats using any standard security threat modeling like STRIDE or DREAD
-- Protect against DDoS attacks using HTTP(S) and TCP load balancers
-- Perform periodic penetration tests by specialized agencies
-
-## ![✔] OWASP A3: Sensitive Data Exposure
-
-- Only accept SSL/TLS connections, enforce Strict-Transport-Security using headers
-- Separate the network into segments (i.e. subnets) and ensure each node has the least necessary networking access permissions
-- Group all services/instances that need no internet access and explictly disallow any outgoing connection (a.k.a private subnet)
-- Store all secrets in a vault products like AWS KMS, HashiCorp Vault or Google Cloud KMS
-- Lock down sensitive instance metadata using metadata
-- Encrypt data in transit when it leaves a physical boundary
-- Don't include secrets in log statements
-- Avoid showing plain passwords in the frontend, take necessary measures in the backend and never store sensitive information in plaintext
-
-## ![✔] OWASP A9: Using Components With Known Security Vulneraibilities
-
-- Scan docker images for known vulnerabilities (using Docker's and other vendors offer scanning services)
-- Enable automatic instance (machine) patching and upgrades to avoid running old OS versions that lack security patches
-- Provide the user with both 'id', 'access' and 'refresh' token so the access token is short-lived and renewed with the refresh token
-- Log and audit each API call to cloud and management services (e.g who deleted the S3 bucket?) using services like AWS CloudTrail
-- Run the security checker of your cloud provider (e.g. AWS security trust advisor)
-
-## ![✔] OWASP A10: Insufficient Logging & Monitoring
-
-- Alert on remarkable or suspicious auditing events like user login, new user creation, permission change, etc
-
-- Alert on irregular amount of login failures (or equivelant actions like forgot password)
-
-- Include the time and username that initiated the update in each DB record
-
-## ![✔] OWASP A7: Cross-Site-Scripting (XSS)
-
-- Instruct the browser to load resources from the same domain only, using the Content-Security-Policy http header
-
-
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# Common Node.js security best practices
+
+The common security guidelines section contains best practices that are standardized in many frameworks and conventions, running an application with ssl/tls for example should be a common guideline and convention followed in every setup to achieve great security benefits.
+
+## ![✔] Use SSL/TLS to encrypt the client-server connection
+
+**TL;DR:** In the times of [free SSL/TLS certificates](https://letsencrypt.org/) and easy configuration of those, you do no longer have to weigh advantages and disadvantages of using a secure server because the advantages such as security, support of modern technology and trust clearly outweigh the disadvantages like minimal overhead compared to pure http.
+
+**Otherwise:** Attackers could perform man-in-the-middle attacks, spy on your users' behaviour and perform even more malicious actions when the connection is unencrypted
+
+🔗 [**Read More: Running a secure Node.js server**](secureserver.md)
+
+
+
+## ![✔] Comparing secret values and hashes securely
+
+**TL;DR:** When comparing secret values or hashes like HMAC digests, you should use the [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) function Node provides out of the box since Node.js v6.6.0. This method compares two given objects and keeps comparing even if data does not match. The default equality comparison methods would simply return after a character mismatch, allowing timing attacks based on the operation length.
+
+**Otherwise:** Using default equality comparison operators you might expose critical information based on the time taken to compare two objects
+
+
+
+## ![✔] Generating random strings using Node.js
+
+**TL;DR:** Using a custom-built function generating pseudo-random strings for tokens and other security-sensitive use cases might actually not be as random as you think, rendering your application vulnerable to cryptographic attacks. When you have to generate secure random strings, use the [`crypto.RandomBytes(size, [callback])`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_randombytes_size_callback) function using available entropy provided by the system.
+
+**Otherwise:** When generating pseudo-random strings without cryptographically secure methods, attackers might predict and reproduce the generated results, rendering your application insecure
+
+
+
+Going on, below we've listed some important bits of advice from the OWASP project.
+
+## ![✔] OWASP A2: Broken Authentication
+
+- Require MFA/2FA for important services and accounts
+- Rotate passwords and access keys frequently, including SSH keys
+- Apply strong password policies, both for ops and in-application user management ([🔗 OWASP password recommendation](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
+- Do not ship or deploy your application with any default credentials, particularly for admin users or external services you depend on
+- Use only standard authentication methods like OAuth, OpenID, etc. - **avoid** basic authentication
+- Auth rate limiting: Disallow more than _X_ login attempts (including password recovery, etc.) in a period of _Y_
+- On login failure, don't let the user know whether the username or password verification failed, just return a common auth error
+- Consider using a centralized user management system to avoid managing multiple account per employee (e.g. GitHub, AWS, Jenkins, etc) and to benefit from a battle-tested user management system
+
+## ![✔] OWASP A5: Broken access control
+
+- Respect the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) - every component and DevOps person should only have access to the necessary information and resources
+- **Never** work with the console/root (full-privilege) account except for account management
+- Run all instances/containers on behalf of a role/service account
+- Assign permissions to groups and not to users. This should make permission management easier and more transparent for most cases
+
+## ![✔] OWASP A6: Security Misconfiguration
+
+- Access to production environment internals is done through the internal network only, use SSH or other ways, but _never_ expose internal services
+- Restrict internal network access - explicitly set which resource can access other resources (e.g. network policy or subnets)
+- If using cookies, configure it to "secured" mode where it's being sent over SSL only
+- If using cookies, configure it for "same site" only so only requests from same domain will get back the designated cookies
+- If using cookies, prefer "http only" configuration that prevent browser side JavaScript code from accessing the cookies
+- Protect each VPC with strict and restrictive access rules
+- Prioritize threats using any standard security threat modeling like STRIDE or DREAD
+- Protect against DDoS attacks using HTTP(S) and TCP load balancers
+- Perform periodic penetration tests by specialized agencies
+
+## ![✔] OWASP A3: Sensitive Data Exposure
+
+- Only accept SSL/TLS connections, enforce Strict-Transport-Security using headers
+- Separate the network into segments (i.e. subnets) and ensure each node has the least necessary networking access permissions
+- Group all services/instances that need no internet access and explictly disallow any outgoing connection (a.k.a private subnet)
+- Store all secrets in a vault products like AWS KMS, HashiCorp Vault or Google Cloud KMS
+- Lock down sensitive instance metadata using metadata
+- Encrypt data in transit when it leaves a physical boundary
+- Don't include secrets in log statements
+- Avoid showing plain passwords in the frontend, take necessary measures in the backend and never store sensitive information in plaintext
+
+## ![✔] OWASP A9: Using Components With Known Security Vulneraibilities
+
+- Scan docker images for known vulnerabilities (using Docker's and other vendors offer scanning services)
+- Enable automatic instance (machine) patching and upgrades to avoid running old OS versions that lack security patches
+- Provide the user with both 'id', 'access' and 'refresh' token so the access token is short-lived and renewed with the refresh token
+- Log and audit each API call to cloud and management services (e.g who deleted the S3 bucket?) using services like AWS CloudTrail
+- Run the security checker of your cloud provider (e.g. AWS security trust advisor)
+
+## ![✔] OWASP A10: Insufficient Logging & Monitoring
+
+- Alert on remarkable or suspicious auditing events like user login, new user creation, permission change, etc
+
+- Alert on irregular amount of login failures (or equivelant actions like forgot password)
+
+- Include the time and username that initiated the update in each DB record
+
+## ![✔] OWASP A7: Cross-Site-Scripting (XSS)
+
+- Instruct the browser to load resources from the same domain only, using the Content-Security-Policy http header
+
+
diff --git a/sections/security/dependencysecurity.md b/sections/security/dependencysecurity.md
index 4b5cedf8d..2f737e00e 100644
--- a/sections/security/dependencysecurity.md
+++ b/sections/security/dependencysecurity.md
@@ -1,53 +1,53 @@
-# Constantly and automatically inspect for vulnerable dependencies
-
-### One Paragraph Explainer
-
-The majority of Node.js applications rely heavily on a large number of third party modules from npm or Yarn, both popular package registries, due to ease and speed of development. However, the downside to this benefit is the security risks of including unknown vulnerabilities into your application, which is a risk recognised by it's place in the OWASP top critical web application security risks list.
-
-There is a number of tools available to help identify third-party packages in Node.js applications which have been identified as vulnerable by the community to mitigate the risk of introducing them into your project. These can be used periodically from CLI tools or included as part of your application's build process.
-
-### Table of Contents
-
-- [NPM audit](#npm-audit)
-- [Snyk](#snyk)
-- [Greenkeeper](#greenkeeper)
-
-### NPM Audit
-
-`npm audit` is a new cli tool introduced with NPM@6.
-
-Running `npm audit` will produce a report of security vulnerabilities with the affected package name, vulnerability severity and description, path, and other information, and, if available, commands to apply patches to resolve vulnerabilities.
-
-![npm audit example](/assets/images/npm-audit.png)
-
-🔗 [Read on: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
-
-### Snyk
-
-Snyk offers a feature-rich CLI, as well as GitHub integration. Snyk goes further with this and in addition to notifying vulnerabilities, also automatically creates new pull requests fixing vulnerabilities as patches are released for known vulnerabilties.
-
-Snyk's feature rich website also allows for ad-hoc assessment of dependencies when provided with a GitHub repository or npm module url. You can also search for npm packages which have vulnerabilties directly.
-
-An example of the output of the Synk GitHub integration automatically created pull request:
-![synk GitHub example](/assets/images/snyk.png)
-
-🔗 [Read on: Snyk website](https://snyk.io/)
-
-🔗 [Read on: Synk online tool to check npm packages and GitHub modules](https://snyk.io/test)
-
-### Greenkeeper
-
-Greenkeeper is a service which offers real-time dependency updates, which keeps an application more secure by always using the most update to date and patched dependency versions.
-
-Greenkeeper watches the npm dependencies specified in a repository's `package.json` file, and automatically creates a working branch with each dependency update. The repository CI suite is then run to reveal any breaking changes for the updated dependency version in the application. If CI fails due the dependency update, a clear and consise issue is created in the repository to be actioned outlining the current and updated package versions, along with information and commit history of the updated version.
-
-An example of the output of the Greenkeeper GitHub integration automatically created pull request:
-
-![synk github example](/assets/images/greenkeeper.png)
-🔗 [Read on: Greenkeeper website](https://greenkeeper.io/)
-
-### Additional resources
-
-🔗 [Rising Stack Blog: Node.js dependency risks](https://blog.risingstack.com/controlling-node-js-security-risk-npm-dependencies/)
-
-🔗 [NodeSource Blog: Improving npm security](https://nodesource.com/blog/how-to-reduce-risk-and-improve-security-around-npm)
+# Constantly and automatically inspect for vulnerable dependencies
+
+### One Paragraph Explainer
+
+The majority of Node.js applications rely heavily on a large number of third party modules from npm or Yarn, both popular package registries, due to ease and speed of development. However, the downside to this benefit is the security risks of including unknown vulnerabilities into your application, which is a risk recognised by it's place in the OWASP top critical web application security risks list.
+
+There is a number of tools available to help identify third-party packages in Node.js applications which have been identified as vulnerable by the community to mitigate the risk of introducing them into your project. These can be used periodically from CLI tools or included as part of your application's build process.
+
+### Table of Contents
+
+- [NPM audit](#npm-audit)
+- [Snyk](#snyk)
+- [Greenkeeper](#greenkeeper)
+
+### NPM Audit
+
+`npm audit` is a new cli tool introduced with NPM@6.
+
+Running `npm audit` will produce a report of security vulnerabilities with the affected package name, vulnerability severity and description, path, and other information, and, if available, commands to apply patches to resolve vulnerabilities.
+
+![npm audit example](/assets/images/npm-audit.png)
+
+🔗 [Read on: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
+
+### Snyk
+
+Snyk offers a feature-rich CLI, as well as GitHub integration. Snyk goes further with this and in addition to notifying vulnerabilities, also automatically creates new pull requests fixing vulnerabilities as patches are released for known vulnerabilties.
+
+Snyk's feature rich website also allows for ad-hoc assessment of dependencies when provided with a GitHub repository or npm module url. You can also search for npm packages which have vulnerabilties directly.
+
+An example of the output of the Synk GitHub integration automatically created pull request:
+![synk GitHub example](/assets/images/snyk.png)
+
+🔗 [Read on: Snyk website](https://snyk.io/)
+
+🔗 [Read on: Synk online tool to check npm packages and GitHub modules](https://snyk.io/test)
+
+### Greenkeeper
+
+Greenkeeper is a service which offers real-time dependency updates, which keeps an application more secure by always using the most update to date and patched dependency versions.
+
+Greenkeeper watches the npm dependencies specified in a repository's `package.json` file, and automatically creates a working branch with each dependency update. The repository CI suite is then run to reveal any breaking changes for the updated dependency version in the application. If CI fails due the dependency update, a clear and consise issue is created in the repository to be actioned outlining the current and updated package versions, along with information and commit history of the updated version.
+
+An example of the output of the Greenkeeper GitHub integration automatically created pull request:
+
+![synk github example](/assets/images/greenkeeper.png)
+🔗 [Read on: Greenkeeper website](https://greenkeeper.io/)
+
+### Additional resources
+
+🔗 [Rising Stack Blog: Node.js dependency risks](https://blog.risingstack.com/controlling-node-js-security-risk-npm-dependencies/)
+
+🔗 [NodeSource Blog: Improving npm security](https://nodesource.com/blog/how-to-reduce-risk-and-improve-security-around-npm)
diff --git a/sections/security/escape-output.md b/sections/security/escape-output.md
index baa65ec53..1f28acb45 100644
--- a/sections/security/escape-output.md
+++ b/sections/security/escape-output.md
@@ -1,62 +1,62 @@
-# Escape Output
-
-### One Paragraph Explainer
-
-HTML and other web languages mix content with executable code - a single HTML paragraph might contain a visual representation of data along with JavaScript execution instructions. When rendering HTML or returning data from API, what we believe is a pure content might actually embody JavaScript code that will get interpreted and executed by the browser. This happens, for example, when we render content that was inserted by an attacker to a database - for example ``. This can be mitigated by instructing the browser to treat any chunk of untrusted data as content only and never interpret it - this technique is called escaping. Many npm libraries and HTML templating engines provide escaping capabilities (example: [escape-html](https://github.com/component/escape-html), [node-esapi](https://github.com/ESAPI/node-esapi)). Not only HTML content should be escaped but also CSS and JavaScript
-
-
-### Code example - Don't put untrusted data into your HTML
-
-```javascript
- directly in a script
-
- inside an HTML comment
-
- in an attribute name
-
- in a tag name
-
- directly in CSS
-
-```
-
-### Code example - Malicious content that might be injected into a DB
-
-```javascript
-
- A pseudo comment to the a post
-
-
-
-```
-
-
-
-### Blog Quote: "When we don’t want the characters to be interpreted"
-
-From the Blog [benramsey.com](https://benramsey.com/articles/escape-output/)
-> Data may leave your application in the form of HTML sent to a Web browser, SQL sent to a database, XML sent to an RSS reader, WML sent to a wireless device, etc. The possibilities are limitless. Each of these has its own set of special characters that are interpreted differently than the rest of the plain text received. Sometimes we want to send these special characters so that they are interpreted (HTML tags sent to a Web browser, for example), while other times (in the case of input from users or some other source), we don’t want the characters to be interpreted, so we need to escape them.
-
-> Escaping is also sometimes referred to as encoding. In short, it is the process of representing data in a way that it will not be executed or interpreted. For example, HTML will render the following text in a Web browser as bold-faced text because the tags have special meaning:
-This is bold text.
-But, suppose I want to render the tags in the browser and avoid their interpretation. Then, I need to escape the angle brackets, which have special meaning in HTML. The following illustrates the escaped HTML:
-
-<strong>This is bold text.</strong>
-
-
-
-
-### Blog Quote: "OWASP recommends using a security-focused encoding library"
-
-From the blog OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
-> "Writing these encoders is not tremendously difficult, but there are quite a few hidden pitfalls. For example, you might be tempted to use some of the escaping shortcuts like \" in JavaScript. However, these values are dangerous and may be misinterpreted by the nested parsers in the browser. You might also forget to escape the escape character, which attackers can use to neutralize your attempts to be safe. **OWASP recommends using a security-focused encoding library to make sure these rules are properly implemented**."
-
-
-
-
-### Blog Quote: "You MUST use the escape syntax for the part of the HTML"
-
-From the blog OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
+# Escape Output
+
+### One Paragraph Explainer
+
+HTML and other web languages mix content with executable code - a single HTML paragraph might contain a visual representation of data along with JavaScript execution instructions. When rendering HTML or returning data from API, what we believe is a pure content might actually embody JavaScript code that will get interpreted and executed by the browser. This happens, for example, when we render content that was inserted by an attacker to a database - for example ``. This can be mitigated by instructing the browser to treat any chunk of untrusted data as content only and never interpret it - this technique is called escaping. Many npm libraries and HTML templating engines provide escaping capabilities (example: [escape-html](https://github.com/component/escape-html), [node-esapi](https://github.com/ESAPI/node-esapi)). Not only HTML content should be escaped but also CSS and JavaScript
+
+
+### Code example - Don't put untrusted data into your HTML
+
+```javascript
+ directly in a script
+
+ inside an HTML comment
+
+ in an attribute name
+
+ in a tag name
+
+ directly in CSS
+
+```
+
+### Code example - Malicious content that might be injected into a DB
+
+```javascript
+
+ A pseudo comment to the a post
+
+
+
+```
+
+
+
+### Blog Quote: "When we don’t want the characters to be interpreted"
+
+From the Blog [benramsey.com](https://benramsey.com/articles/escape-output/)
+> Data may leave your application in the form of HTML sent to a Web browser, SQL sent to a database, XML sent to an RSS reader, WML sent to a wireless device, etc. The possibilities are limitless. Each of these has its own set of special characters that are interpreted differently than the rest of the plain text received. Sometimes we want to send these special characters so that they are interpreted (HTML tags sent to a Web browser, for example), while other times (in the case of input from users or some other source), we don’t want the characters to be interpreted, so we need to escape them.
+
+> Escaping is also sometimes referred to as encoding. In short, it is the process of representing data in a way that it will not be executed or interpreted. For example, HTML will render the following text in a Web browser as bold-faced text because the tags have special meaning:
+This is bold text.
+But, suppose I want to render the tags in the browser and avoid their interpretation. Then, I need to escape the angle brackets, which have special meaning in HTML. The following illustrates the escaped HTML:
+
+<strong>This is bold text.</strong>
+
+
+
+
+### Blog Quote: "OWASP recommends using a security-focused encoding library"
+
+From the blog OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
+> "Writing these encoders is not tremendously difficult, but there are quite a few hidden pitfalls. For example, you might be tempted to use some of the escaping shortcuts like \" in JavaScript. However, these values are dangerous and may be misinterpreted by the nested parsers in the browser. You might also forget to escape the escape character, which attackers can use to neutralize your attempts to be safe. **OWASP recommends using a security-focused encoding library to make sure these rules are properly implemented**."
+
+
+
+
+### Blog Quote: "You MUST use the escape syntax for the part of the HTML"
+
+From the blog OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
> "But HTML entity encoding doesn't work if you're putting untrusted data inside a