diff --git a/.all-contributorsrc b/.all-contributorsrc
index 5f679a4cb..8a9cc8163 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -1,9 +1,19 @@
{
"files": [
- "CONTRIBUTORS.md"
+ "README.basque.md",
+ "README.brazilian-portuguese.md",
+ "README.chinese.md",
+ "README.french.md",
+ "README.indonesian.md",
+ "README.japanese.md",
+ "README.korean.md",
+ "README.md",
+ "README.polish.md",
+ "README.russian.md"
],
"imageSize": 100,
"contributorsPerLine": 7,
+ "contributorTemplate": "\">\" width=\"<%= options.imageSize %>px;\" alt=\"<%= contributor.name %>\"style=\"max-width:<%= options.imageSize %>px;min-width:<%= options.imageSize %>px;\" /> <%= contributor.name %> <%= contributions %>",
"badgeTemplate": "[](#contributors)",
"contributors": [
{
@@ -806,10 +816,946 @@
"contributions": [
"content"
]
+ },
+ {
+ "login": "collierrgbsitisfise",
+ "name": "Vadim Nicolaev",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/13496126?v=4",
+ "profile": "https://github.com/collierrgbsitisfise",
+ "contributions": [
+ "content",
+ "translation"
+ ]
+ },
+ {
+ "login": "germangamboa95",
+ "name": "German Gamboa Gonzalez",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/28633849?v=4",
+ "profile": "https://github.com/germangamboa95",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "AbdelrahmanHafez",
+ "name": "Hafez",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/19984935?v=4",
+ "profile": "https://github.com/AbdelrahmanHafez",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "chandiran-dmc",
+ "name": "Chandiran",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/42678579?v=4",
+ "profile": "http://linkedin.com/in/chandiran-dmc",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "VinayaSathyanarayana",
+ "name": "VinayaSathyanarayana",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/16976677?v=4",
+ "profile": "https://github.com/VinayaSathyanarayana",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "kiwikern",
+ "name": "Kim Kern",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/2671139?v=4",
+ "profile": "https://www.kimkern.de",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "kennethfreitas",
+ "name": "Kenneth Freitas",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/55669043?v=4",
+ "profile": "https://kennethfreitas.github.io/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "songe",
+ "name": "songe",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/1531561?v=4",
+ "profile": "https://github.com/songe",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "Ksedline",
+ "name": "Kirill Shekhovtsov",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/30693707?v=4",
+ "profile": "http://ksed.dev",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "SerzN1",
+ "name": "Serge",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/2534649?v=4",
+ "profile": "https://github.com/SerzN1",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "keyrwinz",
+ "name": "keyrwinz",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/21241761?v=4",
+ "profile": "https://github.com/keyrwinz",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "nDmitry",
+ "name": "Dmitry Nikitenko",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/2134568?v=4",
+ "profile": "https://github.com/nDmitry",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "bushuai",
+ "name": "bushuai",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/1875256?v=4",
+ "profile": "https://bushuai.cc",
+ "contributions": [
+ "review",
+ "content"
+ ]
+ },
+ {
+ "login": "benjamingr",
+ "name": "Benjamin Gruenbaum",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/1315533?v=4",
+ "profile": "https://stackoverflow.com/users/1348195/benjamin-gruenbaum",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "byeze",
+ "name": "Ezequiel",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/7424138?v=4",
+ "profile": "https://github.com/byeze",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "juaoose",
+ "name": "Juan José Rodríguez",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/994594?v=4",
+ "profile": "https://github.com/juaoose",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "OrBin",
+ "name": "Or Bin",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/6897234?v=4",
+ "profile": "https://github.com/OrBin",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "andreoav",
+ "name": "Andreo Vieira",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/508827?v=4",
+ "profile": "https://twitter.com/andreoav07",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "mikicho",
+ "name": "Michael Solomon",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/11459632?v=4",
+ "profile": "https://github.com/mikicho",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "jimmycallin",
+ "name": "Jimmy Callin",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/2225828?v=4",
+ "profile": "https://github.com/jimmycallin",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "w01fS",
+ "name": "Siddharth",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/26025955?v=4",
+ "profile": "https://www.linkedin.com/in/siddharthofficial/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "ryan3E0",
+ "name": "Ryan Smith",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/1578766?v=4",
+ "profile": "https://ryansmith.tech/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "bttger",
+ "name": "Tom Boettger",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/49961674?v=4",
+ "profile": "https://de.linkedin.com/in/tom-boettger",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "jormaechea",
+ "name": "Joaquín Ormaechea",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/5612500?v=4",
+ "profile": "https://github.com/jormaechea",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "dfrzuz",
+ "name": "dfrzuz",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/71859096?v=4",
+ "profile": "https://github.com/dfrzuz",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "victor-homyakov",
+ "name": "Victor Homyakov",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/121449?v=4",
+ "profile": "https://github.com/victor-homyakov",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "josh-hemphill",
+ "name": "Josh",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/46608115?v=4",
+ "profile": "http://joshuahemphill.com",
+ "contributions": [
+ "content",
+ "security"
+ ]
+ },
+ {
+ "login": "alec-francis",
+ "name": "Alec Francis",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/32949882?v=4",
+ "profile": "https://github.com/alec-francis",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "arjun6610",
+ "name": "arjun6610",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/61268891?v=4",
+ "profile": "https://github.com/arjun6610",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "jan-osch",
+ "name": "Jan Osch",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/11651780?v=4",
+ "profile": "https://github.com/jan-osch",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "thiagotrs",
+ "name": "Thiago Rotondo Sampaio",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/32005779?v=4",
+ "profile": "https://github.com/thiagotrs",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "Alexsey",
+ "name": "Alexsey",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/6392013?v=4",
+ "profile": "https://github.com/Alexsey",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "13luismb",
+ "name": "Luis A. Acurero",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/32210483?v=4",
+ "profile": "https://github.com/13luismb",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "lromano97",
+ "name": "Lucas Romano",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/22394847?v=4",
+ "profile": "https://lromano97.github.io/",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "denisecase",
+ "name": "Denise Case",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/13016516?v=4",
+ "profile": "https://github.com/denisecase",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "elektronik2k5",
+ "name": "Nick Ribal",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/1078554?v=4",
+ "profile": "http://stackoverflow.com/story/elektronik",
+ "contributions": [
+ "content",
+ "review"
+ ]
+ },
+ {
+ "login": "0xflotus",
+ "name": "0xflotus",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/26602940?v=4",
+ "profile": "https://github.com/0xflotus",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "dijonkitchen",
+ "name": "Jonathan Chen",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/11434205?v=4",
+ "profile": "https://www.dijonkitchen.org/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "dilansri",
+ "name": "Dilan Srilal",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/5089728?v=4",
+ "profile": "https://github.com/dilansri",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "vladthelittleone",
+ "name": "vladthelittleone",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/4215285?v=4",
+ "profile": "https://vectree.ru",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "nosvalds",
+ "name": "Nik Osvalds",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/60047271?v=4",
+ "profile": "https://www.nikolaso.com",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "kdaniel21",
+ "name": "Daniel Kiss",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/39854385?v=4",
+ "profile": "https://github.com/kdaniel21",
+ "contributions": [
+ "doc"
+ ]
+ },
+ {
+ "login": "forresst",
+ "name": "Forresst",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/163352?v=4",
+ "profile": "https://twitter.com/forresst17",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "svenheden",
+ "name": "Jonathan Svenheden",
+ "avatar_url": "https://avatars1.githubusercontent.com/u/76098?v=4",
+ "profile": "https://github.com/svenheden",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "AustrisC",
+ "name": "AustrisC",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/12381652?v=4",
+ "profile": "https://github.com/AustrisC",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "cisco0808",
+ "name": "kyeongtae kim",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/60251188?v=4",
+ "profile": "https://github.com/cisco0808",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "6gx7iycn53ioq2e8apk1j1ypwov4giui",
+ "name": "007",
+ "avatar_url": "https://avatars.githubusercontent.com/u/65741741?v=4",
+ "profile": "https://keybase.io/651z9pz968v2accj",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "anediaz",
+ "name": "Ane Diaz de Tuesta",
+ "avatar_url": "https://avatars.githubusercontent.com/u/17216937?v=4",
+ "profile": "http://www.anediaz.com",
+ "contributions": [
+ "translation",
+ "content"
+ ]
+ },
+ {
+ "login": "YukiOta",
+ "name": "YukiOta",
+ "avatar_url": "https://avatars.githubusercontent.com/u/23182489?v=4",
+ "profile": "http://yukioh.net",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "Fdawgs",
+ "name": "Frazer Smith",
+ "avatar_url": "https://avatars.githubusercontent.com/u/43814140?v=4",
+ "profile": "https://www.yeovilhospital.co.uk/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "rluvaton",
+ "name": "Raz Luvaton",
+ "avatar_url": "https://avatars.githubusercontent.com/u/16746759?v=4",
+ "profile": "https://github.com/rluvaton",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "YA21",
+ "name": "Yuta Azumi",
+ "avatar_url": "https://avatars.githubusercontent.com/u/37298463?v=4",
+ "profile": "https://github.com/YA21",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "andrewjbarbour",
+ "name": "andrewjbarbour",
+ "avatar_url": "https://avatars.githubusercontent.com/u/77080074?v=4",
+ "profile": "https://github.com/andrewjbarbour",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "MasujimaRyohei",
+ "name": "mr",
+ "avatar_url": "https://avatars.githubusercontent.com/u/17163541?v=4",
+ "profile": "https://MasujimaRyohei.jp",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "kubanac95",
+ "name": "Aleksandar",
+ "avatar_url": "https://avatars.githubusercontent.com/u/16191931?v=4",
+ "profile": "https://github.com/kubanac95",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "SuspiciousLookingOwl",
+ "name": "Owl",
+ "avatar_url": "https://avatars.githubusercontent.com/u/32597776?v=4",
+ "profile": "http://vincentjonathan.com",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "yedidyas",
+ "name": "Yedidya Schwartz",
+ "avatar_url": "https://avatars.githubusercontent.com/u/36074789?v=4",
+ "profile": "https://github.com/yedidyas",
+ "contributions": [
+ "content",
+ "example"
+ ]
+ },
+ {
+ "login": "ariel-diaz",
+ "name": "ari",
+ "avatar_url": "https://avatars.githubusercontent.com/u/20423540?v=4",
+ "profile": "https://github.com/ariel-diaz",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "Vispercept",
+ "name": "Thomas König",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7080389?v=4",
+ "profile": "http://www.koenigthomas.de/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "coocos",
+ "name": "Kalle Lämsä",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1397804?v=4",
+ "profile": "https://github.com/coocos",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "ZhyMC",
+ "name": "Wyatt",
+ "avatar_url": "https://avatars.githubusercontent.com/u/10328430?v=4",
+ "profile": "http://math.cat",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "tkhadir",
+ "name": "KHADIR Tayeb",
+ "avatar_url": "https://avatars.githubusercontent.com/u/45130488?v=4",
+ "profile": "http://libkhadir.fr",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "shankarregmi",
+ "name": "Shankar Regmi",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7703345?v=4",
+ "profile": "https://github.com/shankarregmi",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "codebyshubham",
+ "name": "Shubham",
+ "avatar_url": "https://avatars.githubusercontent.com/u/10389723?v=4",
+ "profile": "https://github.com/codebyshubham",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "lucalves",
+ "name": "Lucas Alves",
+ "avatar_url": "https://avatars.githubusercontent.com/u/17712401?v=4",
+ "profile": "http://lucalves.me/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "benjaminudoh10",
+ "name": "Benjamin",
+ "avatar_url": "https://avatars.githubusercontent.com/u/9018331?v=4",
+ "profile": "https://github.com/benjaminudoh10",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "yjoer",
+ "name": "Yeoh Joer",
+ "avatar_url": "https://avatars.githubusercontent.com/u/47742486?v=4",
+ "profile": "https://www.yjoer.com",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "Miigon",
+ "name": "Miigon",
+ "avatar_url": "https://avatars.githubusercontent.com/u/16161991?v=4",
+ "profile": "https://blog.miigon.net",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "Egregor2011",
+ "name": "Rostislav Bogorad",
+ "avatar_url": "https://avatars.githubusercontent.com/u/3630318?v=4",
+ "profile": "http://brainstorage.me/Egregor2011",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "Flouse",
+ "name": "Flouse",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1297478?v=4",
+ "profile": "https://github.com/Flouse",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "taranttini",
+ "name": "Tarantini Pereira",
+ "avatar_url": "https://avatars.githubusercontent.com/u/6922125?v=4",
+ "profile": "http://taranttini.com",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "kzmat",
+ "name": "Kazuki Matsuo",
+ "avatar_url": "https://avatars.githubusercontent.com/u/34614358?v=4",
+ "profile": "https://github.com/kzmat",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "burkybang",
+ "name": "Adam Smith",
+ "avatar_url": "https://avatars.githubusercontent.com/u/927886?v=4",
+ "profile": "https://github.com/burkybang",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "k906506",
+ "name": "Dohyeon Ko",
+ "avatar_url": "https://avatars.githubusercontent.com/u/33795856?v=4",
+ "profile": "https://codekodo.tistory.com",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "vlad99902",
+ "name": "Vladislav Legkov",
+ "avatar_url": "https://avatars.githubusercontent.com/u/67615003?v=4",
+ "profile": "https://github.com/vlad99902",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "kerolloz",
+ "name": "Kerollos Magdy",
+ "avatar_url": "https://avatars.githubusercontent.com/u/36763164?v=4",
+ "profile": "http://kerolloz.github.io",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "erezLieberman",
+ "name": "Erez Lieberman",
+ "avatar_url": "https://avatars.githubusercontent.com/u/3277260?v=4",
+ "profile": "https://www.linkedin.com/in/erez-lieberman-b90b7219/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "breno404",
+ "name": "Breno Macedo",
+ "avatar_url": "https://avatars.githubusercontent.com/u/48841329?v=4",
+ "profile": "https://www.linkedin.com/in/breno-macedo-ernani-de-s%C3%A1-110223158/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "JFernando122",
+ "name": "Fernando Flores",
+ "avatar_url": "https://avatars.githubusercontent.com/u/40414805?v=4",
+ "profile": "https://github.com/JFernando122",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "rafaelconcept",
+ "name": "Rafael Brito",
+ "avatar_url": "https://avatars.githubusercontent.com/u/43880669?v=4",
+ "profile": "https://www.linkedin.com/in/rafaelconcept/",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "emiperalta",
+ "name": "Emiliano Peralta",
+ "avatar_url": "https://avatars.githubusercontent.com/u/63617637?v=4",
+ "profile": "https://emiliano-peralta-portfolio.vercel.app/",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "lannex",
+ "name": "Shin, SJ",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7369541?v=4",
+ "profile": "https://lannex.github.io",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "e-e-e",
+ "name": "Benjamin Forster",
+ "avatar_url": "https://avatars.githubusercontent.com/u/12589522?v=4",
+ "profile": "http://www.benjaminforster.com",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "DanieleFedeli",
+ "name": "Daniele Fedeli",
+ "avatar_url": "https://avatars.githubusercontent.com/u/37077048?v=4",
+ "profile": "https://github.com/DanieleFedeli",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "djob195",
+ "name": "djob195",
+ "avatar_url": "https://avatars.githubusercontent.com/u/17146669?v=4",
+ "profile": "https://github.com/djob195",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "antspk",
+ "name": "antspk",
+ "avatar_url": "https://avatars.githubusercontent.com/u/78955792?v=4",
+ "profile": "https://github.com/antspk",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "jjy821",
+ "name": "정진영",
+ "avatar_url": "https://avatars.githubusercontent.com/u/88075341?v=4",
+ "profile": "https://jjy0821.tistory.com/",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "kkk-cashwalk",
+ "name": "kkk-cashwalk",
+ "avatar_url": "https://avatars.githubusercontent.com/u/91455122?v=4",
+ "profile": "https://github.com/kkk-cashwalk",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "apainintheneck",
+ "name": "apainintheneck",
+ "avatar_url": "https://avatars.githubusercontent.com/u/42982186?v=4",
+ "profile": "https://github.com/apainintheneck",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "koyanyaroo",
+ "name": "Fajar Budhi Iswanda",
+ "avatar_url": "https://avatars.githubusercontent.com/u/9715368?v=4",
+ "profile": "https://github.com/koyanyaroo",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "jutiger",
+ "name": "이주호",
+ "avatar_url": "https://avatars.githubusercontent.com/u/97490806?v=4",
+ "profile": "https://github.com/jutiger",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "MisterSingh",
+ "name": "Singh",
+ "avatar_url": "https://avatars.githubusercontent.com/u/44462019?v=4",
+ "profile": "https://github.com/MisterSingh",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "Alex-Dumitru",
+ "name": "Alex Dumitru",
+ "avatar_url": "https://avatars.githubusercontent.com/u/43738450?v=4",
+ "profile": "https://github.com/Alex-Dumitru",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "lykhatskyi",
+ "name": "Anton Lykhatskyi",
+ "avatar_url": "https://avatars.githubusercontent.com/u/18104686?v=4",
+ "profile": "https://github.com/lykhatskyi",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "EverythingAvailable",
+ "name": "sangwonlee",
+ "avatar_url": "https://avatars.githubusercontent.com/u/81002379?v=4",
+ "profile": "https://github.com/EverythingAvailable",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "euberdeveloper",
+ "name": "Eugenio Berretta",
+ "avatar_url": "https://avatars.githubusercontent.com/u/33126163?v=4",
+ "profile": "https://github.com/euberdeveloper",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "soranakk",
+ "name": "soranakk",
+ "avatar_url": "https://avatars.githubusercontent.com/u/3930307?v=4",
+ "profile": "https://github.com/soranakk",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "backend-joonyoung",
+ "name": "고준영",
+ "avatar_url": "https://avatars.githubusercontent.com/u/94430145?v=4",
+ "profile": "https://github.com/backend-joonyoung",
+ "contributions": [
+ "content",
+ "code"
+ ]
+ },
+ {
+ "login": "GuilhermePortella",
+ "name": "Guilherme Portella ",
+ "avatar_url": "https://avatars.githubusercontent.com/u/59876059?v=4",
+ "profile": "https://github.com/GuilhermePortella",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "Esser50K",
+ "name": "André Esser",
+ "avatar_url": "https://avatars.githubusercontent.com/u/18497570?v=4",
+ "profile": "https://www.youtube.com/channel/UCBxzOQd2v9wWfiMDrf_RQ7A",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "ShiChenCong",
+ "name": "Scc",
+ "avatar_url": "https://avatars.githubusercontent.com/u/22486446?v=4",
+ "profile": "https://github.com/ShiChenCong",
+ "contributions": [
+ "translation"
+ ]
+ },
+ {
+ "login": "mauroaccornero",
+ "name": "Mauro Accornero",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1875822?v=4",
+ "profile": "https://www.mauroaccornero.it",
+ "contributions": [
+ "content"
+ ]
+ },
+ {
+ "login": "no-yan",
+ "name": "no-yan",
+ "avatar_url": "https://avatars.githubusercontent.com/u/63000297?v=4",
+ "profile": "https://github.com/no-yan",
+ "contributions": [
+ "content"
+ ]
}
],
"projectName": "nodebestpractices",
"projectOwner": "goldbergyoni",
"repoType": "github",
- "repoHost": "https://github.com"
+ "repoHost": "https://github.com",
+ "skipCi": true,
+ "commitConvention": "angular"
}
diff --git a/.github/workflows/automerge-prs.yml b/.github/workflows/automerge-prs.yml
new file mode 100644
index 000000000..3f8333e46
--- /dev/null
+++ b/.github/workflows/automerge-prs.yml
@@ -0,0 +1,33 @@
+name: automerge
+on:
+ pull_request:
+ types:
+ - labeled
+ - unlabeled
+ - synchronize
+ - opened
+ - edited
+ - ready_for_review
+ - reopened
+ - unlocked
+ pull_request_review:
+ types:
+ - submitted
+ check_suite:
+ types:
+ - completed
+ status: {}
+jobs:
+ automerge:
+ runs-on: ubuntu-20.04
+ steps:
+ - name: automerge
+ uses: "pascalgn/automerge-action@v0.15.5"
+ env:
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+ MERGE_LABELS: "auto-merge,!work in progress"
+ MERGE_REMOVE_LABELS: "auto-merge"
+ MERGE_FORKS: "false"
+ MERGE_RETRIES: "6"
+ MERGE_RETRY_SLEEP: "10000"
+ MERGE_DELETE_BRANCH: "true"
diff --git a/.github/workflows/lint-and-generate-html-from-markdown.yml b/.github/workflows/lint-and-generate-html-from-markdown.yml
new file mode 100644
index 000000000..9c62c5b4b
--- /dev/null
+++ b/.github/workflows/lint-and-generate-html-from-markdown.yml
@@ -0,0 +1,30 @@
+name: Lint & Generate HTML from Markdown
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+defaults:
+ run:
+ shell: bash
+ working-directory: .operations
+
+jobs:
+ lint:
+ name: Lint
+ runs-on: ubuntu-20.04
+ env:
+ NODE_ENV: test
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Setup Node.js environment
+ uses: actions/setup-node@v3
+ with:
+ node-version: "18"
+
+ - run: npm install
+ - run: npm run lint
diff --git a/.github/workflows/update-date-in-last-update-badge.yml b/.github/workflows/update-date-in-last-update-badge.yml
new file mode 100644
index 000000000..c440307be
--- /dev/null
+++ b/.github/workflows/update-date-in-last-update-badge.yml
@@ -0,0 +1,39 @@
+name: Update date in last update badge
+on:
+ push:
+ branches:
+ - master
+
+jobs:
+ run:
+ name: Update the date in last update badge to today
+ runs-on: ubuntu-20.04
+
+ # Limit this action to only run on the main repo and not on forks
+ if: github.repository_owner == 'goldbergyoni'
+
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v3
+
+ - name: Update last update badge
+ run: |
+ # Make file runnable
+ chmod +x "${GITHUB_WORKSPACE}/.github/workflows/update-last-update-badge.sh"
+ # Run script
+ "${GITHUB_WORKSPACE}/.github/workflows/update-last-update-badge.sh" "${GITHUB_WORKSPACE}/README.md"
+
+ - name: Commit & Create Pull Request
+ uses: peter-evans/create-pull-request@v4
+ with:
+ commit-message: update the last update badge to today [skip ci]
+ author: Update Last Update Badge Action <${{ github.actor }}@users.noreply.github.com>
+ branch: update-last-update-badge
+ delete-branch: true
+ title: 'Update last update badge to today [skip ci]'
+ labels: |
+ update-last-update-badge
+ auto-merge
+
+ # Force empty body as the action have default body
+ body: ''
diff --git a/.github/workflows/update-last-update-badge.sh b/.github/workflows/update-last-update-badge.sh
new file mode 100755
index 000000000..4765439a8
--- /dev/null
+++ b/.github/workflows/update-last-update-badge.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+set -e
+
+INPUT_FILE=$1
+
+url_encode() {
+ # url_encode
+ local length="${#1}"
+ for (( i = 0; i < length; i++ )); do
+ local c="${1:i:1}"
+ case $c in
+ [a-zA-Z0-9.~_-]) printf "$c" ;;
+ *) printf '%%%02X' "'$c" ;;
+ esac
+ done
+}
+
+is_there_last_update_badge() {
+ local input_file=$1
+ local updated_badge_regex=$2
+
+ if grep -q "$updated_badge_regex" "$input_file"; then return 0
+ else return 1
+ fi
+}
+
+is_last_update_badge_date_is_today() {
+ local input_file=$1
+ local updated_badge=$2
+
+ if grep -q "$updated_badge" "$input_file"; then return 0
+ else return 1
+ fi
+}
+
+
+# We use already encoded string emoji because I'm on Windows and the calendar emoji failed to render
+CALENDAR_EMOJI_ENCODED='%F0%9F%93%85'
+
+# Date format example: March 03, 2021
+CURRENT_DATE=`date +"%B %d, %Y"`
+
+# We explicitly matching the img.shields.io/badge because when we change the provider of the badge the input will be changed too
+LAST_UPDATE_BADGE_REGEX='"
+
+
+if ! is_there_last_update_badge "$INPUT_FILE" "$LAST_UPDATE_BADGE_REGEX"; then
+ # Print with red foreground
+ echo -e "\033[31mError: Can't find Last update badge\033[m"
+ exit 1
+fi
+
+if is_last_update_badge_date_is_today "$INPUT_FILE" "$UPDATED_LAST_UPDATE_BADGE"; then
+ echo "No need to update the $INPUT_FILE, the last update badge already pointing to today"
+ exit 0
+fi
+
+sed -i "s@$LAST_UPDATE_BADGE_REGEX@$UPDATED_LAST_UPDATE_BADGE@" "$INPUT_FILE"
diff --git a/.operations/.common-answers.md b/.operations/.common-answers.md
deleted file mode 100644
index 9484e951d..000000000
--- a/.operations/.common-answers.md
+++ /dev/null
@@ -1,15 +0,0 @@
-**Welcoming new translators**
-
-@name - Welcome aboard 🎆
-
-Having an Egyptian translation could be awesome
-
-Let's go for this? Few basic guideliness:
-1. Work on your own fork - fork, create a branch, translate & collaborate with other translators, then PR finally
-2. Focus on translation, not content editing - the focus is on translation, should anyone want to modify the content or the graphics - let's PR first in English and then translate to other languages. Also the format of the text should remain intact (same design)
-3. Duplicate the readme and the inner pages - the content should be translated over a page duplication. Readme.MD became Readme.{translated-language}.MD (e.g. readme.french.md), all other files should be duplicated similarly. So the number of English & translated pages should be the same
-4. Collaborate - once you do the basic setup (branch, duplicate pages), we can announce the work on a new language and get others involved and help you in translation (if you wish)
-5. We're here to help - let us know whether we can do anything to support you. We can Tweet about this work, put homepage banner or anything else
-
-
-____________________
diff --git a/.operations/.env.example b/.operations/.env.example
deleted file mode 100644
index 77e1c98da..000000000
--- a/.operations/.env.example
+++ /dev/null
@@ -1 +0,0 @@
-GITHUB_TOKEN=REPLACEME
\ No newline at end of file
diff --git a/.operations/CONTRIBUTING.md b/.operations/CONTRIBUTING.md
index b3d18c97c..2e9f76905 100644
--- a/.operations/CONTRIBUTING.md
+++ b/.operations/CONTRIBUTING.md
@@ -1,25 +1,61 @@
-## Contribution model
+# Contribution guidelines
-### Steering committee 🏆
+## Lovely & friendly atmosphere
-Members of the steering committee work together to provide guidance and future direction to the project. Each committee member has a particular expertise which they share their knowledge on, and work to lead further improvements to the project in that area. The steering committee members are responsible for approving new best practices, and ensuring current best practices remain relevant.
+Our code of conduct is 5 words long: we are all friends here
-### Collaborators 👍
+We recognize that being professional and kind are the same thing and strive to maximize our professionalism
-Collaborators are members who are contributing to the repository on a regular basis, through suggesting new best practices, triaging issues, reviewing pull requests and more. Along with the steering committee, each collaborator leads a project tracked under our Github projects.
+## Handling issues and PRs
-The role is in place to help the steering committee ensure that the content provided is of a high standard, up-to-date with the industry, and available in many languages. Members who frequently participate in these activities will be invited to become a collaborator, based on the quality of their contributions.
+
+In a nutshell, every issue is an opprtunity to gain new knowledge and attract new contributor. Therefore we aim for vast response and welcoming words 💚
+
+When merging a new PR, add the contributor to our credits list using the all-contributors bot. Just include this text as a PR comment:
+
+`@all-contributors please add @username for content`
+
+The specific PR/issue resolustion depends on its kind:
+
+**A. New best practice or fundamental changes to existing content -** In that case, involve at least 1 other members to solicit enough feedback for this change. Start by greeting the contributor, ensure the formalities are fine, ensure it conforms to our [writing guidelines](./writing-guidelines.md), ensure enough information was provided and then get at least 1 more collaborators and allow at least a week for comments
+
+**B. Plain text change (e.g. Grammar correctness) -** When super-simple wording edits are proposed (i.e. not new content rather language correctness), one can just greet, approve and merge immediately
+
+**C. Translations to a new (not existing) language -** When offered to add new language, greet the person and paste our [translation guidelines](./common-answers.md)
+
+**D. Edits to existing translations -** If the change can be inferred by the reviewer (e.g., a change of a symbol, number or just date update) then feel free to merge alone. If familiarity with the language is needed, tag the original translator and ask for feedback. The translators name can be found in the home page under "Translations"
+
+**D. Dicussions and ideas -** When a technical discussion or just general conversation is brought into a new issue, apply your own judgements whether to tag other collaborators
-The steering committee periodically reviews the collaborator list to identify inactive collaborators. Inactive collaborators can choose to either continue in or step down from their role, in which case they are acknowledged as a past collaborator. They may later request that the steering committee restore them to active status.
-### Other contributions ✨
+## Assets to be aware of
-This project follows the [All Contributors Specification](https://allcontributors.org/), which means we recognize all types of contributions, whether they are new suggested best practices/ideas, translations, or new content.
+- Our content writing guidelines [can be found here](./writing-guidelines.md)
+- Common questions and answers to issues/PRs [can be found here](./common-answers.md)
-If you have contributed to the project in some way and aren't listed, please add an entry for yourself by using the @all-contributors-bot in a Pull Request or issue. Examples:
+## Precommit
-`@all-contributors-bot please add @js-kyle for code`
+Before pushing, verify your Markdown passes [the linter](https://www.npmjs.com/package/markdownlint-cli) :
-`@all-contributors-bot please add @brunoscheufler for content`
+```bash
+npm run lint
+```
+For example fix basic errors :
-Contribution types are listed [here](https://allcontributors.org/docs/en/emoji-key).
+```bash
+npm run lint --fix
+```
+
+## Contribution model
+
+### Steering committee 🏆
+
+Members of the steering committee work together to provide guidance and future direction to the project. Each committee member has a particular expertise which they share their knowledge on, and work to lead further improvements to the project in that area. The steering committee members are responsible for approving new best practices, and ensuring current best practices remain relevant.
+
+### Collaborators 👍
+
+Collaborators are members who are contributing to the repository on a regular basis, through suggesting new best practices, triaging issues, reviewing pull requests and more. Along with the steering committee, each collaborator leads a project tracked under our Github projects.
+
+The role is in place to help the steering committee ensure that the content provided is of high standard, up-to-date with the industry, and available in many languages. Members who frequently participate in these activities will be invited to become a collaborator, based on the quality of their contributions.
+
+The steering committee periodically reviews the collaborator list to identify inactive collaborators. Inactive collaborators can choose to either continue in or step down from their role, in which case they are acknowledged as a past collaborator. They may later request that the steering committee restore them to active status.
diff --git a/.operations/common-answers.md b/.operations/common-answers.md
new file mode 100644
index 000000000..5cfa72f77
--- /dev/null
+++ b/.operations/common-answers.md
@@ -0,0 +1,17 @@
+**Welcoming new translators**
+
+@name - Welcome aboard, it's great to have you here! 🎆
+
+Having A Slovak translation could be awesome! At the end, we can Tweet about this, put in our news section, include your name at the top of the translated language and also at the main home page contributors list.
+
+Let's go for this? Few basic guideliness:
+
+- Work on your own fork - Fork this repo, create a branch for yourself, translate & collaborate with other translators, then finally when ready create a PR.
+
+- Focus on translation, not content editing - The focus is on translation, should you want to modify the content or the graphics - let's PR first in English and then translate to other languages. Also the format of the text should remain intact (same design).
+
+- Duplicate the readme and the inner pages - The content should be translated over a page duplication. readme.md became readme.{translated-language}.md (e.g. readme.french.md), all other files should be duplicated similarly. So the number of English & translated pages should be the same. You may see examples in currently translated languages.
+
+Collaborate - once you do the basic setup (branch, duplicate pages), we can announce the work on a new language and get others involved and help you in translation (if you wish).
+
+We're here to help - let us know whether we can do anything to support you. We can Tweet about this work, put homepage banner or anything else.
diff --git a/.operations/gen-html.js b/.operations/gen-html.js
deleted file mode 100644
index 6a4abd10b..000000000
--- a/.operations/gen-html.js
+++ /dev/null
@@ -1,226 +0,0 @@
-const path = require('path');
-const cheerio = require('cheerio');
-const showdown = require('showdown');
-const Repository = require('github-api/dist/components/Repository');
-const { readdir, readFile, writeFile } = require('graceful-fs');
-
-const imagemin = require('imagemin');
-const imageminJpegtran = require('imagemin-jpegtran');
-const imageminPngquant = require('imagemin-pngquant');
-
-const converter = new showdown.Converter();
-
-const templateFilePath = './.operations/res/template.html';
-
-const imageminOpts = {
- plugins: [
- imageminJpegtran(),
- imageminPngquant({ quality: '65-80' })
- ]
-};
-
-console.info(`Working in [${process.cwd()}]`);
-
-const { GITHUB_TOKEN, TRAVIS_BRANCH, TRAVIS, TRAVIS_REPO_SLUG } = process.env;
-const isCI = !!TRAVIS;
-
-readDirPromise('./')
- .then(async (fileNames) => {
- const indexFileNames = fileNames.filter(fn => fn.includes('README.') && fn.includes('.md'));
-
- for (let fileName of indexFileNames) {
- const startTime = new Date();
- console.info(`Beginning Generate Document [${fileName}] at [${startTime.toISOString()}]`);
- try {
- const templateHTML = await readFilePromise(templateFilePath);
- const processedTemplateHTML = await inlineResources(templateHTML);
- const outputHTML = await processMDFile(fileName, processedTemplateHTML);
- console.info(`Completed Generation in [${(Date.now() - startTime) / 1000}s]`);
-
- const outFileName = path.parse(fileName).name + '.html';
- const outFilePath = path.join('.operations', 'out', outFileName);
- console.info(`Writing output to [${outFilePath}]`);
- await writeFilePromise(outFilePath, outputHTML);
-
- if (isCI && TRAVIS_BRANCH === 'master') {
- const repo = new Repository(TRAVIS_REPO_SLUG, {
- token: GITHUB_TOKEN
- });
-
- console.info(`Committing HTML file to branch [gh-pages]`);
- await repo.writeFile('gh-pages', outFileName, outputHTML, ':loudspeaker: :robot: Automatically updating built HTML file', {});
- }
- } catch (err) {
- console.error(`Failed to generate from [${fileName}] in [${(Date.now() - startTime) / 1000}s]`, err);
- process.exit(1);
- }
- }
- })
- .then(() => {
- console.log(`🎉 Finished gen-html 🎉`);
- })
-
-
-
-async function processMDFile(filePath = '/', templateHTML = null) {
- let mdSrc;
- try {
- mdSrc = await readFilePromise(filePath);
- } catch (err) {
- console.warn(`Failed to read file [${filePath}], does it exist?`);
- return '';
- }
- const generatedHTML = converter.makeHtml(mdSrc);
- let nexHTML = generatedHTML;
- if (templateHTML) {
- const $ = cheerio.load(templateHTML);
- $('.content').html(generatedHTML);
- nexHTML = $.html();
- }
-
- const fileDir = path.parse(filePath).dir.replace(process.cwd(), '/') || '/';
-
- console.log(`Processing file [${filePath}]`);
- const outHtml = await (
- inlineLocalReferences(nexHTML, fileDir)
- .then((html) => fixMdReferences(html))
- .then((html) => fixHashAs(html))
- .then((html) => inlineAssets(html, fileDir))
- );
-
- return outHtml;
-}
-
-const internalRefRegExp = /^((?!http)(?!#)(?!\/\/).)*$/; // Doesn't start with 'http', '//', or '#'
-async function inlineLocalReferences(html, filePath = '/') {
- const $ = cheerio.load(html);
- const as = $('a');
- const internalAs = as.toArray().filter((a) => internalRefRegExp.test(a.attribs.href) && !a.attribs.href.includes('README'));
-
- const processedInternalRefs = await Promise.all(
- internalAs.map((a) => processMDFile(path.resolve(filePath, a.attribs.href)))
- );
-
- processedInternalRefs.forEach((processedHTML, index) => {
- const originalA = $(internalAs[index]);
-
- const contentId = originalA.text().replace(/[^A-Za-z0-9]/g, '_');
- $('.references').append([
- $(''),
- $('
')
- .addClass('reference-section')
- .attr('id', contentId)
- .html(processedHTML)
- ]);
-
- originalA.attr('href', `#${contentId}`);
- });
-
- return $.html();
-}
-
-async function fixMdReferences(html) { // Primarily for links to translations
- const $ = cheerio.load(html);
- const as = $('a');
- const mdReferences = as.toArray().filter((a) => internalRefRegExp.test(a.attribs.href) && a.attribs.href.includes('.md'));
-
- mdReferences
- .forEach((a) => {
- const $a = $(a);
- const href = $a.attr('href')
- const newHref = href.replace('.md', '.html');
- $a.attr('href', './' + newHref);
- })
-
- return $.html();
-}
-
-async function inlineAssets(html, filePath = '/') {
- const $ = cheerio.load(html);
- const imgs = $('img');
- const internalImgs = imgs.toArray().filter((img) => internalRefRegExp.test(img.attribs.src));
-
- for (let img of internalImgs) {
- const ext = path.parse(img.attribs.src).ext.slice(1); // parse().ext includes '.'
- const imgPath = path.resolve('/', filePath, img.attribs.src);
- const imgBuffer = await readFilePromise(imgPath, null);
- const compressedImgBuffer = await imagemin.buffer(imgBuffer, imageminOpts);
- const base64 = compressedImgBuffer.toString('base64');
- const mediaUri = `data:image/${ext};base64,${base64}`;
- const originalImg = $(img);
- originalImg.attr('src', mediaUri);
- }
-
- return $.html();
-}
-
-async function fixHashAs(html) {
- const $ = cheerio.load(html);
- const as = $('a');
-
- const hashAs = as.toArray().filter((a) => a.attribs.href[0] === '#');
- hashAs.forEach(a => {
- $(a).attr('href', a.attribs.href.replace(/-/g, ''));
- });
-
- return $.html()
-}
-
-
-
-async function inlineResources(html, filePath = '/') {
- const $ = cheerio.load(html);
- const scripts = $('script[src]');
- const links = $('link[href]');
-
- const internalScripts = scripts.toArray().filter((script) => internalRefRegExp.test(script.attribs.src));
- const internalLinks = links.toArray().filter((link) => internalRefRegExp.test(link.attribs.href));
-
- for (let scriptEl of internalScripts) {
- const scriptPath = path.resolve('/', filePath, scriptEl.attribs.src);
- const scriptBuffer = await readFilePromise(scriptPath, null);
- const base64 = scriptBuffer.toString('base64');
- const mediaUri = `data:text/javascript;base64,${base64}`;
- $(scriptEl).attr('src', mediaUri);
- }
-
- for (let linkEl of internalLinks) {
- const linkPath = path.resolve('/', filePath, linkEl.attribs.href);
- const linkBuffer = await readFilePromise(linkPath, null);
- const base64 = linkBuffer.toString('base64');
- const mediaUri = `data:text/css;base64,${base64}`;
- $(linkEl).attr('href', mediaUri);
- }
-
- return $.html();
-}
-
-
-
-
-function readFilePromise(filePath, encoding = 'utf8') {
- return new Promise((resolve, reject) => {
- readFile(path.resolve(process.cwd(), './' + filePath), encoding, (err, content) => {
- if (err) reject(err);
- else resolve(content);
- });
- });
-}
-
-function writeFilePromise(filePath, encoding = 'utf8') {
- return new Promise((resolve, reject) => {
- writeFile(path.resolve(process.cwd(), './' + filePath), encoding, (err, content) => {
- if (err) reject(err);
- else resolve(content);
- });
- });
-}
-
-function readDirPromise(dirPath) {
- return new Promise((resolve, reject) => {
- readdir(path.resolve(process.cwd(), dirPath), (err, files) => {
- if (err) reject(err);
- else resolve(files);
- });
- });
-}
\ No newline at end of file
diff --git a/.operations/operations-manual.md b/.operations/operations-manual.md
index 65daf19f9..1c7595099 100644
--- a/.operations/operations-manual.md
+++ b/.operations/operations-manual.md
@@ -1,19 +1,19 @@
# Operations Manual - Organizing and Maximizing Our Work
-Building a community and knowledge by efficiently handling issues
+Building knowledge and a community by efficiently handling issues
-## Handling issues and PR
+## Handling issues and PRs
-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 new thing that might improve our repo and try joining the opener to our forces.
+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 the contributor and then kick off the discussion (hopefully within 48 hours). The goal of each issue/PR is to learn new thing that might improve our repo and try to include the contributor in our army.
There is no specific person on call who assigns inquiries rather we count on our core team to visit almost everyday and assign issues/PR - 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](https://github.com/i0natan/nodebestpractices/blob/master/.operations/writing-guidelines.md)
+Any new content should conform to our [writing guidelines](./writing-guidelines.md)
## Monthly maintenance
-Each 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
+Each month, a maintainer on call will open an issue for a maintenance work checklist and write down all the actions to perform by the end of the month (e.g. assign flower to a contributor). At the end of the month, that maintainer will perform the tasks on the checklist.
---
@@ -41,17 +41,13 @@ Each month, a maintainer on call will open an issue for maintenance work and rec
| Month | Maintainer on call |
|---------|--------------------|
| 10/2019 | Yoni |
-| 11/2019 | Bruno |
-| 12/2019 | Kyle |
-| 01/2020 | Yoni |
-| 02/2020 | Bruno |
-| 03/2020 | Kyle |
+| 12/2019 | Bruno |
+| 02/2020 | Kyle |
| 04/2020 | Yoni |
-| 05/2020 | Bruno |
-| 06/2020 | Kyle |
-| 07/2020 | Yoni |
-| 09/2020 | Bruno |
-
+| 06/2020 | Bruno |
+| 08/2020 | Kyle |
+| 10/2020 | Yoni |
+| 12/2020 | Bruno |
@@ -59,8 +55,8 @@ Each month, a maintainer on call will open an issue for maintenance work and rec
| 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 |
+| 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 clarify | Bruno |
| Javascript runtime | JS runtime, syntax correctness | Sagir |
| Devops | Monitoring, hardening a production site, deployment | Kyle |
@@ -84,9 +80,11 @@ Each month, a maintainer on call will open an issue for maintenance work and rec
| French | Yoni |
| Russian | Yoni |
| Korean | Yoni |
-| Spanish | Kyle |
+| Spanish | Kevyn |
| Chinese | Yoni |
| Korean | Kyle |
| Egyptian | Yoni |
| Ukrainian | Bruno |
+| Polish | Kevyn |
+| Thai | Kevyn |
diff --git a/.operations/out/.gitignore b/.operations/out/.gitignore
deleted file mode 100644
index d6b7ef32c..000000000
--- a/.operations/out/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/.operations/package.json b/.operations/package.json
deleted file mode 100644
index 8da9d7a58..000000000
--- a/.operations/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "nodebestpractices",
- "version": "1.0.0",
- "description": "[✔]: assets/images/checkbox-small-blue.png",
- "main": "gen-html.js",
- "scripts": {
- "build": "cd .. && node .operations/gen-html.js",
- "test": "echo \"Error: no test specified\" && exit 1",
- "lint": "./node_modules/.bin/markdownlint ../README.md"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/i0natan/nodebestpractices.git"
- },
- "author": "",
- "license": "ISC",
- "bugs": {
- "url": "https://github.com/i0natan/nodebestpractices/issues"
- },
- "homepage": "https://github.com/i0natan/nodebestpractices#readme",
- "dependencies": {
- "cheerio": "^1.0.0-rc.2",
- "github-api": "^3.0.0",
- "graceful-fs": "^4.1.15",
- "imagemin": "^6.0.0",
- "imagemin-jpegtran": "^6.0.0",
- "imagemin-pngquant": "^6.0.0",
- "markdownlint-cli": "^0.18.0",
- "showdown": "^1.9.0"
- }
-}
diff --git a/.operations/res/github.css b/.operations/res/github.css
deleted file mode 100644
index 791932b87..000000000
--- a/.operations/res/github.css
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-
-github.com style (c) Vasily Polovnyov
-
-*/
-
-.hljs {
- display: block;
- overflow-x: auto;
- padding: 0.5em;
- color: #333;
- background: #f8f8f8;
-}
-
-.hljs-comment,
-.hljs-quote {
- color: #998;
- font-style: italic;
-}
-
-.hljs-keyword,
-.hljs-selector-tag,
-.hljs-subst {
- color: #333;
- font-weight: bold;
-}
-
-.hljs-number,
-.hljs-literal,
-.hljs-variable,
-.hljs-template-variable,
-.hljs-tag .hljs-attr {
- color: #008080;
-}
-
-.hljs-string,
-.hljs-doctag {
- color: #d14;
-}
-
-.hljs-title,
-.hljs-section,
-.hljs-selector-id {
- color: #900;
- font-weight: bold;
-}
-
-.hljs-subst {
- font-weight: normal;
-}
-
-.hljs-type,
-.hljs-class .hljs-title {
- color: #458;
- font-weight: bold;
-}
-
-.hljs-tag,
-.hljs-name,
-.hljs-attribute {
- color: #000080;
- font-weight: normal;
-}
-
-.hljs-regexp,
-.hljs-link {
- color: #009926;
-}
-
-.hljs-symbol,
-.hljs-bullet {
- color: #990073;
-}
-
-.hljs-built_in,
-.hljs-builtin-name {
- color: #0086b3;
-}
-
-.hljs-meta {
- color: #999;
- font-weight: bold;
-}
-
-.hljs-deletion {
- background: #fdd;
-}
-
-.hljs-addition {
- background: #dfd;
-}
-
-.hljs-emphasis {
- font-style: italic;
-}
-
-.hljs-strong {
- font-weight: bold;
-}
diff --git a/.operations/res/highlight.pack.js b/.operations/res/highlight.pack.js
deleted file mode 100644
index b64bd7d80..000000000
--- a/.operations/res/highlight.pack.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! highlight.js v9.13.1 | BSD3 License | git.io/hljslicense */
-!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=M.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function c(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function u(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function c(e){l+=""+t(e)+">"}function u(e){("start"===e.event?o:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function l(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):B(a.k).forEach(function(e){c(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.endSameAsBegin&&(a.e=a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return s("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var u=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=u.length?t(u.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e){return new RegExp(e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")}function c(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t].endSameAsBegin&&(n.c[t].eR=o(n.c[t].bR.exec(e)[0])),n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function s(e,n){return!a&&r(n.iR,e)}function p(e,n){var t=R.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function d(e,n,t,r){var a=r?"":j.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=p(E,r),e?(M+=e[1],a+=d(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function b(){var e="string"==typeof E.sL;if(e&&!L[E.sL])return n(k);var t=e?f(E.sL,k,!0,B[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(B[E.sL]=t.top),d(t.language,t.value,!1,!0)}function v(){y+=null!=E.sL?b():h(),k=""}function m(e){y+=e.cN?d(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function N(e,n){if(k+=e,null==n)return v(),0;var t=c(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),v(),t.rB||t.eB||(k=n)),m(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),v(),a.eE&&(k=n));do E.cN&&(y+=I),E.skip||E.sL||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),m(r.starts,"")),a.rE?0:n.length}if(s(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var R=w(e);if(!R)throw new Error('Unknown language: "'+e+'"');l(R);var x,E=i||R,B={},y="";for(x=E;x!==R;x=x.parent)x.cN&&(y=d(x.cN,"",!0)+y);var k="",M=0;try{for(var C,A,S=0;;){if(E.t.lastIndex=S,C=E.t.exec(t),!C)break;A=N(t.substring(S,C.index),C[0]),S=C.index+A}for(N(t.substr(S)),x=E;x.parent;x=x.parent)x.cN&&(y+=I);return{r:M,value:y,language:e,top:E}}catch(O){if(O.message&&-1!==O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function g(e,t){t=t||j.languages||B(L);var r={r:0,value:n(e)},a=r;return t.filter(w).filter(x).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return j.tabReplace||j.useBR?e.replace(C,function(e,n){return j.useBR&&"\n"===e?" ":j.tabReplace?n.replace(/\t/g,j.tabReplace):""}):e}function d(e,n,t){var r=n?y[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n,t,r,o,s,l=i(e);a(l)||(j.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/ /g,"\n")):n=e,s=n.textContent,r=l?f(l,s,!0):g(s),t=c(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=u(t,c(o),s)),r.value=p(r.value),e.innerHTML=r.value,e.className=d(e.className,l,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){j=o(j,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,h)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=L[n]=t(e);r.aliases&&r.aliases.forEach(function(e){y[e]=n})}function R(){return B(L)}function w(e){return e=(e||"").toLowerCase(),L[e]||L[y[e]]}function x(e){var n=w(e);return n&&!n.disableAutodetect}var E=[],B=Object.keys,L={},y={},k=/^(no-?highlight|plain|text)$/i,M=/\blang(?:uage)?-([\w-]+)\b/i,C=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,I="",j={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=h,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.autoDetection=x,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/,r:0,c:[{cN:"attr",b:e,r:0},{b:/=\s*/,r:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b:/,e:/(\/\w+|\w+\/)>/,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});
\ No newline at end of file
diff --git a/.operations/res/normalize.css b/.operations/res/normalize.css
deleted file mode 100644
index 81c6f31ea..000000000
--- a/.operations/res/normalize.css
+++ /dev/null
@@ -1,427 +0,0 @@
-/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- * user zoom.
- */
-
-html {
- font-family: sans-serif; /* 1 */
- -ms-text-size-adjust: 100%; /* 2 */
- -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
- margin: 0;
-}
-
-/* HTML5 display definitions
- ========================================================================== */
-
-/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-menu,
-nav,
-section,
-summary {
- display: block;
-}
-
-/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
- */
-
-audio,
-canvas,
-progress,
-video {
- display: inline-block; /* 1 */
- vertical-align: baseline; /* 2 */
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
- display: none;
-}
-
-/* Links
- ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
- background-color: transparent;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
- outline: 0;
-}
-
-/* Text-level semantics
- ========================================================================== */
-
-/**
- * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
- */
-
-abbr[title] {
- border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
- */
-
-b,
-strong {
- font-weight: bold;
-}
-
-/**
- * Address styling not present in Safari and Chrome.
- */
-
-dfn {
- font-style: italic;
-}
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
- */
-
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
- background: #ff0;
- color: #000;
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
- font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-/* Embedded content
- ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9/10.
- */
-
-img {
- border: 0;
-}
-
-/**
- * Correct overflow not hidden in IE 9/10/11.
- */
-
-svg:not(:root) {
- overflow: hidden;
-}
-
-/* Grouping content
- ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari.
- */
-
-figure {
- margin: 1em 40px;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- */
-
-hr {
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- height: 0;
-}
-
-/**
- * Contain overflow in all browsers.
- */
-
-pre {
- overflow: auto;
-}
-
-/**
- * Address odd `em`-unit font size rendering in all browsers.
- */
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, monospace;
- font-size: 1em;
-}
-
-/* Forms
- ========================================================================== */
-
-/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
- */
-
-/**
- * 1. Correct color not being inherited.
- * Known issue: affects color of disabled elements.
- * 2. Correct font properties not being inherited.
- * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
- */
-
-button,
-input,
-optgroup,
-select,
-textarea {
- color: inherit; /* 1 */
- font: inherit; /* 2 */
- margin: 0; /* 3 */
-}
-
-/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
- */
-
-button {
- overflow: visible;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
- */
-
-button,
-select {
- text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- * `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
- cursor: default;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-input {
- line-height: normal;
-}
-
-/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
- */
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
- height: auto;
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
- * (include `-moz` to future-proof).
- */
-
-input[type="search"] {
- -webkit-appearance: textfield; /* 1 */
- -moz-box-sizing: content-box;
- -webkit-box-sizing: content-box; /* 2 */
- box-sizing: content-box;
-}
-
-/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9/10/11.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * Remove default vertical scrollbar in IE 8/9/10/11.
- */
-
-textarea {
- overflow: auto;
-}
-
-/**
- * Don't inherit the `font-weight` (applied by a rule above).
- * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
- */
-
-optgroup {
- font-weight: bold;
-}
-
-/* Tables
- ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-td,
-th {
- padding: 0;
-}
\ No newline at end of file
diff --git a/.operations/res/skeleton.css b/.operations/res/skeleton.css
deleted file mode 100644
index f28bf6c59..000000000
--- a/.operations/res/skeleton.css
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
-* Skeleton V2.0.4
-* Copyright 2014, Dave Gamache
-* www.getskeleton.com
-* Free to use under the MIT license.
-* http://www.opensource.org/licenses/mit-license.php
-* 12/29/2014
-*/
-
-
-/* Table of contents
-––––––––––––––––––––––––––––––––––––––––––––––––––
-- Grid
-- Base Styles
-- Typography
-- Links
-- Buttons
-- Forms
-- Lists
-- Code
-- Tables
-- Spacing
-- Utilities
-- Clearing
-- Media Queries
-*/
-
-
-/* Grid
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.container {
- position: relative;
- width: 100%;
- max-width: 960px;
- margin: 0 auto;
- padding: 0 20px;
- box-sizing: border-box; }
-.column,
-.columns {
- width: 100%;
- float: left;
- box-sizing: border-box; }
-
-/* For devices larger than 400px */
-@media (min-width: 400px) {
- .container {
- width: 85%;
- padding: 0; }
-}
-
-/* For devices larger than 550px */
-@media (min-width: 550px) {
- .container {
- width: 80%; }
- .column,
- .columns {
- margin-left: 4%; }
- .column:first-child,
- .columns:first-child {
- margin-left: 0; }
-
- .one.column,
- .one.columns { width: 4.66666666667%; }
- .two.columns { width: 13.3333333333%; }
- .three.columns { width: 22%; }
- .four.columns { width: 30.6666666667%; }
- .five.columns { width: 39.3333333333%; }
- .six.columns { width: 48%; }
- .seven.columns { width: 56.6666666667%; }
- .eight.columns { width: 65.3333333333%; }
- .nine.columns { width: 74.0%; }
- .ten.columns { width: 82.6666666667%; }
- .eleven.columns { width: 91.3333333333%; }
- .twelve.columns { width: 100%; margin-left: 0; }
-
- .one-third.column { width: 30.6666666667%; }
- .two-thirds.column { width: 65.3333333333%; }
-
- .one-half.column { width: 48%; }
-
- /* Offsets */
- .offset-by-one.column,
- .offset-by-one.columns { margin-left: 8.66666666667%; }
- .offset-by-two.column,
- .offset-by-two.columns { margin-left: 17.3333333333%; }
- .offset-by-three.column,
- .offset-by-three.columns { margin-left: 26%; }
- .offset-by-four.column,
- .offset-by-four.columns { margin-left: 34.6666666667%; }
- .offset-by-five.column,
- .offset-by-five.columns { margin-left: 43.3333333333%; }
- .offset-by-six.column,
- .offset-by-six.columns { margin-left: 52%; }
- .offset-by-seven.column,
- .offset-by-seven.columns { margin-left: 60.6666666667%; }
- .offset-by-eight.column,
- .offset-by-eight.columns { margin-left: 69.3333333333%; }
- .offset-by-nine.column,
- .offset-by-nine.columns { margin-left: 78.0%; }
- .offset-by-ten.column,
- .offset-by-ten.columns { margin-left: 86.6666666667%; }
- .offset-by-eleven.column,
- .offset-by-eleven.columns { margin-left: 95.3333333333%; }
-
- .offset-by-one-third.column,
- .offset-by-one-third.columns { margin-left: 34.6666666667%; }
- .offset-by-two-thirds.column,
- .offset-by-two-thirds.columns { margin-left: 69.3333333333%; }
-
- .offset-by-one-half.column,
- .offset-by-one-half.columns { margin-left: 52%; }
-
-}
-
-
-/* Base Styles
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/* NOTE
-html is set to 62.5% so that all the REM measurements throughout Skeleton
-are based on 10px sizing. So basically 1.5rem = 15px :) */
-html {
- font-size: 62.5%; }
-body {
- font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
- line-height: 1.6;
- font-weight: 400;
- font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: #222; }
-
-
-/* Typography
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-h1, h2, h3, h4, h5, h6 {
- margin-top: 0;
- margin-bottom: 2rem;
- font-weight: 300; }
-h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;}
-h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }
-h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; }
-h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }
-h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; }
-h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; }
-
-/* Larger than phablet */
-@media (min-width: 550px) {
- h1 { font-size: 5.0rem; }
- h2 { font-size: 4.2rem; }
- h3 { font-size: 3.6rem; }
- h4 { font-size: 3.0rem; }
- h5 { font-size: 2.4rem; }
- h6 { font-size: 1.5rem; }
-}
-
-p {
- margin-top: 0; }
-
-
-/* Links
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-a {
- color: #1EAEDB; }
-a:hover {
- color: #0FA0CE; }
-
-
-/* Buttons
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.button,
-button,
-input[type="submit"],
-input[type="reset"],
-input[type="button"] {
- display: inline-block;
- height: 38px;
- padding: 0 30px;
- color: #555;
- text-align: center;
- font-size: 11px;
- font-weight: 600;
- line-height: 38px;
- letter-spacing: .1rem;
- text-transform: uppercase;
- text-decoration: none;
- white-space: nowrap;
- background-color: transparent;
- border-radius: 4px;
- border: 1px solid #bbb;
- cursor: pointer;
- box-sizing: border-box; }
-.button:hover,
-button:hover,
-input[type="submit"]:hover,
-input[type="reset"]:hover,
-input[type="button"]:hover,
-.button:focus,
-button:focus,
-input[type="submit"]:focus,
-input[type="reset"]:focus,
-input[type="button"]:focus {
- color: #333;
- border-color: #888;
- outline: 0; }
-.button.button-primary,
-button.button-primary,
-input[type="submit"].button-primary,
-input[type="reset"].button-primary,
-input[type="button"].button-primary {
- color: #FFF;
- background-color: #33C3F0;
- border-color: #33C3F0; }
-.button.button-primary:hover,
-button.button-primary:hover,
-input[type="submit"].button-primary:hover,
-input[type="reset"].button-primary:hover,
-input[type="button"].button-primary:hover,
-.button.button-primary:focus,
-button.button-primary:focus,
-input[type="submit"].button-primary:focus,
-input[type="reset"].button-primary:focus,
-input[type="button"].button-primary:focus {
- color: #FFF;
- background-color: #1EAEDB;
- border-color: #1EAEDB; }
-
-
-/* Forms
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea,
-select {
- height: 38px;
- padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
- background-color: #fff;
- border: 1px solid #D1D1D1;
- border-radius: 4px;
- box-shadow: none;
- box-sizing: border-box; }
-/* Removes awkward default styles on some inputs for iOS */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea {
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none; }
-textarea {
- min-height: 65px;
- padding-top: 6px;
- padding-bottom: 6px; }
-input[type="email"]:focus,
-input[type="number"]:focus,
-input[type="search"]:focus,
-input[type="text"]:focus,
-input[type="tel"]:focus,
-input[type="url"]:focus,
-input[type="password"]:focus,
-textarea:focus,
-select:focus {
- border: 1px solid #33C3F0;
- outline: 0; }
-label,
-legend {
- display: block;
- margin-bottom: .5rem;
- font-weight: 600; }
-fieldset {
- padding: 0;
- border-width: 0; }
-input[type="checkbox"],
-input[type="radio"] {
- display: inline; }
-label > .label-body {
- display: inline-block;
- margin-left: .5rem;
- font-weight: normal; }
-
-
-/* Lists
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-ul {
- list-style: circle inside; }
-ol {
- list-style: decimal inside; }
-ol, ul {
- padding-left: 0;
- margin-top: 0; }
-ul ul,
-ul ol,
-ol ol,
-ol ul {
- margin: 1.5rem 0 1.5rem 3rem;
- font-size: 90%; }
-li {
- margin-bottom: 1rem; }
-
-
-/* Code
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-code {
- padding: .2rem .5rem;
- margin: 0 .2rem;
- font-size: 90%;
- white-space: nowrap;
- background: #F1F1F1;
- border: 1px solid #E1E1E1;
- border-radius: 4px; }
-pre > code {
- display: block;
- padding: 1rem 1.5rem;
- white-space: pre; }
-
-
-/* Tables
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-th,
-td {
- padding: 12px 15px;
- text-align: left;
- border-bottom: 1px solid #E1E1E1; }
-th:first-child,
-td:first-child {
- padding-left: 0; }
-th:last-child,
-td:last-child {
- padding-right: 0; }
-
-
-/* Spacing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-button,
-.button {
- margin-bottom: 1rem; }
-input,
-textarea,
-select,
-fieldset {
- margin-bottom: 1.5rem; }
-pre,
-blockquote,
-dl,
-figure,
-table,
-p,
-ul,
-ol,
-form {
- margin-bottom: 2.5rem; }
-
-
-/* Utilities
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.u-full-width {
- width: 100%;
- box-sizing: border-box; }
-.u-max-full-width {
- max-width: 100%;
- box-sizing: border-box; }
-.u-pull-right {
- float: right; }
-.u-pull-left {
- float: left; }
-
-
-/* Misc
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-hr {
- margin-top: 3rem;
- margin-bottom: 3.5rem;
- border-width: 0;
- border-top: 1px solid #E1E1E1; }
-
-
-/* Clearing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-
-/* Self Clearing Goodness */
-.container:after,
-.row:after,
-.u-cf {
- content: "";
- display: table;
- clear: both; }
-
-
-/* Media Queries
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/*
-Note: The best way to structure the use of media queries is to create the queries
-near the relevant code. For example, if you wanted to change the styles for buttons
-on small devices, paste the mobile query code up in the buttons section and style it
-there.
-*/
-
-
-/* Larger than mobile */
-@media (min-width: 400px) {}
-
-/* Larger than phablet (also point when grid becomes active) */
-@media (min-width: 550px) {}
-
-/* Larger than tablet */
-@media (min-width: 750px) {}
-
-/* Larger than desktop */
-@media (min-width: 1000px) {}
-
-/* Larger than Desktop HD */
-@media (min-width: 1200px) {}
diff --git a/.operations/res/template.html b/.operations/res/template.html
deleted file mode 100644
index 735d4f393..000000000
--- a/.operations/res/template.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
- Node Best Practices
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.operations/writing-guidelines.basque.md b/.operations/writing-guidelines.basque.md
new file mode 100644
index 000000000..f82b21180
--- /dev/null
+++ b/.operations/writing-guidelines.basque.md
@@ -0,0 +1,31 @@
+# Gure agiriko edukia hobeto idazteko
+
+Nola hobetu gure bisitarien irakurtzeko eta ikasteko esperientzia
+
+## 1. Sinplea ezin hobea da
+
+Gure helburua da irakurketa eta ezagutzaren xurgaketa erraztea: edukia zaintzen dugu. Horrenbestez, saiatzen gara gai konplexu eta nekagarriak zerrenda erraztu bihurtzen, informazio astuna zati txikiagoetan eta zehaztasun gutxiagokoetan eratzen dugu, gai eztabaidagarri eta 'sukoiak' ekiditen ditugu, ideia subjektiboak saihestuz eta orokorrean onartutako jarraibideak erabiliz
+
+## 2. Oinarritu egitate frogatu eta fidagarrietan
+
+Gure irakurleek konfidantza handia izan behar dute irakurtzen duten informazioa fidagarria dela. Hori lortzeko, erreferentziak, datuak eta gaiarekin zerikusirik duten bestelako ebidentziak erabiltzen ditugu. Praktikan, gure baieztapenak frogatzeko, ahalegintzen gara iturburu fidagarrietako aipuak aurkezten eta konparaketak, erlazionatutako diseinu ereduak edo neurketa zientifikoak azaltzen
+
+## 3. EEKS (Elkarrekiko Esklusiboa eta Kolektiboki Sakona)
+
+Edukia ondo editatua eta fidagarria izateaz gain, haren irakurketak gaiaz bere osoan jabetzea bermatu behar du. Ez da azpigai garrantzitsurik baztertu behar
+
+## 4. Formatu koherentea
+
+Edukia txantiloi finkoak erabiliz dago aurkeztua, eta etorkizuneko beste edozein edukik txantiloi bera errespetatu behar du. Eduki berriak gehitu nahi izanez gero, kopiatu buleta formatua iada existitzen den bulet batetik eta moldatu zure beharretara. Informazio gehiago nahi izanez gero begiratu [txantiloi hau](../sections/template.basque.md)
+
+## 5. Node.jsri buruz ari gara
+
+Aholku bakoitzak zuzenean Node.jsrekin erlazionatuta egon behar du, eta ez orokorrean software garapenarekin. Node.jsren eredu/arau generikoak ezartzea aholkatzen dugunean, edukiak Noderen ezarpenean ardaztuta egon behar du. Adibidez, eskaera sarrera guztiak onbideratzea aholkatzen dugunean, segurtasun arrazoiengatik, Node-lingo erabili behar da, ‘erabili middlewarea eskaera sarrera onbideratzeko‘. Gai batek Node.jsren ezarpenik ez badauka (esaterako Python & Jaban bezala), gehitu edukiontzi generiko batean, begiratu 6.5 gaia adibidetzat
+
+## 6. Hornitzaile nagusiak soilik
+
+Batzuetan, npm paketeak, open source tresnak edota produktu komertzialak bezalako zenbait erronka eta arazo abordatzen dituzten hornitzaileen izenak gehitzea erabilgarria da. Gainezka egiten duten zerrenda luzeak edota ospetsuak eta egonkorrak ez diren proiektuak ekiditeko, hurrengo arauak proposatzen ditugu:
+
+- Soilik 3 hornitzaile ezagunenak gomendatu behar dira: hitz gako batentzat bilaketa motore bateko (Google edo Github ospearen arabera ordenatua) lehenengo 3 emaitzetan agertzen den hornitzaile bat aipatu genezake gure gomendioetan
+- npm pakete bat bada, batez beste egunean, gutxienez, 750 aldiz deskargatua izan behar da
+- Kode irekiko proiektu bat bada, azken 6 hilabeteetan gutxienez behin eguneratua izan behar da
diff --git a/.operations/writing-guidelines.chinese.md b/.operations/writing-guidelines.chinese.md
index 8d52d3549..97629cc69 100644
--- a/.operations/writing-guidelines.chinese.md
+++ b/.operations/writing-guidelines.chinese.md
@@ -1,31 +1,31 @@
-# 我们的内容写作声明
-如何提高访问者的阅读和学习体验
+# 我们创作内容的准则
-## 1. 越简单越好
+提高访问者的阅读和学习体验
-
-我们的使命, 我们管理内容是为了使阅读和吸收知识更容易。因此, 我们专注于将复杂和无趣的话题转化为一个简化的清单, 用缩短和不那么精确的细节来交易超载信息, 避免 ‘易燃’ 和有争议的话题, 摆脱主观想法, 赞成普遍接受做法
+## 1. 越简单越好
-
+我们的使命,是使知识更易于理解与吸收。因此,我们专注于将复杂和无趣的话题转化为一个简化的清单,用简短但细节相对不精确的列表,去避免超负荷的信息量。同时避免涉及”易爆炸“和有争议的话题。摆脱主观观点,赞成普遍接受的实践。
-## 2. 以证据为基础并且可靠
+## 2. 基于证据且可靠
-
-我们的读者应该有很大的信心, 他们浏览的内容是可靠的。我们通过包括引用、数据和本主题可用的其他资源等证据来实现这一点。实际上, 努力包括可靠来源的引用, 显示基准, 相关的设计模式或任何科学措施, 以证明您的主张
+我们应使得我们的内容能让读者充分信任其可靠性。为实现这一点,我们加入引用、数据和与主题相关的其他资源。实践上,通过努力包括来自可靠来源的引用话语,展示基准测试结果、相关的设计模式,或采用任何其他的科学手段以证明您的主张。
+## 3. MECE(不重不漏)
-## 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行话 - '使用中间件来处理请求输入'
+内容是使用固定模板显示的。任何新的内容都必须遵守这一模板。如果希望添加新项目符号,请从现有项目符号复制项目符号格式,并将其扩展以满足您的需要。有关其他信息,请查看[模版](../sections/template.md)
+
+## 5. Node.js 相关
+
+每个建议都应直接与 Node.js 相关,而不能仅仅是一般的软件开发。当我们建议在 Node.js 中实现通用的模式/规则时,内容应该集中在 Node 的实现上。例如,当我们建议将所有请求的输入为了安全原因进行处理时,应使用 Node 行话——‘使用中间件来处理请求输入’,如果一个条目在 Node.js 中没有具体特别的实现(e.g. 在 Python 或 Java 中看起来一样)——则将其包含在一个通用的容器条目,例子请查看条目 6.5。
+
+## 6. 仅限主要的厂商
-## 6. 仅限主要的vendor
-有时, 包括可以解决某些挑战和问题 (如 npm 软件包、开源工具甚至商业产品) 的供应商名称是很有用的。为了避免极长的列表或推荐信誉不好和不稳定的项目, 我们提出了以下规则:
+有时, 为解决某些问题和挑战,可以包含一些软件 (如 npm 软件包、开源工具甚至商业产品) 的厂商名。为了避免极长的列表,或推荐信誉不好或不稳定的项目,我们提出了以下规则:
-- 只有排名前3的vendor应该被推荐 – 对于一个给定的相关关键词,如果某个vendor出现在搜索引擎结果中排名前3(谷歌或GitHub通过人气排序),那么它可以包含在我们的推荐里
-- 如果它是一个npm包,它必须平均一天下载至少750次
-- 如果它是一个开源项目,它必须在过去的6个月里至少更新一次
+- 只有排名前 3 的厂商应该被推荐 – 对于一个给定的相关关键词,如果某个厂商出现在搜索引擎结果中排名前3(谷歌或 GitHub 通过人气排序),那么它可以包含在我们的推荐里。
+- 如果它是一个 npm 包,平均日下载量应至少 750 次。
+- 如果它是一个开源项目,在过去的 6 个月里必须至少更新过一次。
diff --git a/.operations/writing-guidelines.french.md b/.operations/writing-guidelines.french.md
new file mode 100644
index 000000000..2e46f05e2
--- /dev/null
+++ b/.operations/writing-guidelines.french.md
@@ -0,0 +1,31 @@
+# Notre manifeste de rédaction de contenu
+
+Comment nous améliorons l'expérience de lecture et l'apprentissage pour nos visiteurs.
+
+## 1. La simplicité vaut mieux que la perfection
+
+Faciliter la lecture et l'absorption des connaissances est notre mission, nous en organisons son contenu. En tant que tels, nous nous concentrons sur la transformation des sujets complexes et difficiles en une liste simplifiée, nous traitons les informations trop volumineuses avec du contenu plus courts et moins précis, nous évitons les sujets ‘qui mettent de l'huile sur le feu’ ou controversés et nous évitons les idées subjectives au profit de pratiques généralement acceptées.
+
+## 2. Se baser sur des faits probants et fiables
+
+Nos lecteurs doivent être persuadés que le contenu qu'ils parcourent est fiable. Pour ce faire, nous incluons des données probantes comme des références, des données et d'autres ressources disponibles à ce sujet. Dans la pratique, nous essayons d'inclure des citations provenant de sources fiables, de montrer des benchmarks, des modèles de conception connexes ou toute autre mesure scientifique pour prouver les affirmations.
+
+## 3. MECE (Mutuellement Exclusif Collectivement Exhaustif)
+
+En plus d'être d'une grande fiabilité et d'une grande qualité rédactionnelle, le fait de parcourir le contenu devrait également permettre de couvrir l'ensemble du sujet. Aucun sous-thème important ne doit être laissé de côté.
+
+## 4. Formatage cohérent
+
+Le contenu est présenté à l'aide de modèles prédéfinis. Tout contenu futur doit être conforme au même modèle. Si vous souhaitez ajouter de nouveaux points, copiez le format d'un point existant et complétez-le selon vos besoins. Pour plus d'informations, veuillez consulter [ce modèle](../sections/template.md).
+
+## 5. C'est à propos de Node.js
+
+Chaque conseil doit être directement lié à Node.js et non au développement de logiciels en général. Lorsque nous conseillons d'implémenter un modèle/une règle générique dans Node.js, le contenu doit se concentrer sur l'implémentation dans Node. Par exemple, lorsque nous conseillons de nettoyer toutes les requêtes saisies pour des raisons de sécurité, il convient d'utiliser Node-lingo - ‘Utiliser un middleware pour nettoyer les requêtes saisies’. Si un élément n'a pas d'implémentation spécifique dans Node.js (par exemple, il est identique dans Python & Java) - incluez-le dans un élément de conteneur générique, voir l'article 6.5 par exemple.
+
+## 6. Uniquement les fournisseurs majeurs
+
+Il est parfois utile d'inclure des noms de fournisseurs qui peuvent répondre à certains défis et problèmes comme les paquets npm, les outils open source ou même les produits commerciaux. Afin d'éviter des listes trop longues ou de recommander des projets peu fiables et instables, nous avons élaboré les règles suivantes :
+
+- Seuls les 3 premiers fournisseurs devraient être recommandés - un fournisseur qui apparaît dans les 3 premiers résultats d'un moteur de recherche (Google ou GitHub triés par popularité) pour un mot clé pertinent donné peut être inclus dans notre recommandation.
+- S'il s'agit d'un paquet npm, il doit également être téléchargé au moins 750 fois par jour en moyenne.
+- S'il s'agit d'un projet open-source, il doit avoir été mis à jour au moins une fois au cours des 6 derniers mois.
diff --git a/.operations/writing-guidelines.indonesia.md b/.operations/writing-guidelines.indonesia.md
new file mode 100644
index 000000000..d33359121
--- /dev/null
+++ b/.operations/writing-guidelines.indonesia.md
@@ -0,0 +1,31 @@
+# Manifes penulisan konten kami
+
+Bagaimana kami meningkatkan pengalaman membaca dan belajar bagi pengunjung kami.
+
+## 1. Sederhana lebih baik daripada lebih baik
+
+Memudahkan membaca dan menyerap pengetahuan adalah misi kami, kami mengurasi konten. Karena itu, kami fokus pada mengubah topik yang kompleks dan melelahkan menjadi daftar yang disederhanakan, memperdagangkan informasi yang kelebihan beban dengan detail yang dipersingkat dan kurang akurat, menghindari topik yang 'mudah terbakar' dan kontroversial, serta menghindari ide subjektif yang mendukung praktik yang diterima secara umum.
+
+## 2. Berbasis bukti dan dapat diandalkan
+
+Pembaca kami harus yakin bahwa konten yang mereka baca dapat diandalkan. Kami mencapai ini dengan memasukkan bukti seperti referensi, data, dan sumber daya lain yang tersedia untuk topik ini. Secara praktis, upayakan untuk memasukkan kutipan dari sumber yang dapat dipercaya, menunjukkan tolok ukur, pola desain terkait, atau ukuran ilmiah apa pun untuk membuktikan klaim Anda.
+
+## 3. MECE (Saling Eksklusif dan Secara Kolektif)
+
+Selain konten yang sangat diedit dan dapat diandalkan, membaca sekilas konten juga harus memberikan cakupan topik yang lengkap. Tidak ada sub-topik penting yang harus ditinggalkan.
+
+## 4. Pemformatan yang konsisten
+
+Konten disajikan menggunakan templat tetap. Setiap konten di masa mendatang harus sesuai dengan template yang sama. Jika Anda ingin menambahkan poin baru, salin format poin dari poin yang ada dan kembangkan sesuai kebutuhan Anda. Untuk informasi tambahan, silakan lihat [template ini] (/sections/template.md).
+
+## 5. Ini Tentang Node.js
+
+Setiap saran harus terkait langsung dengan Node.js dan tidak dengan pengembangan perangkat lunak secara umum. Saat kami menyarankan untuk menerapkan pola / aturan umum di Node.js, konten harus fokus pada implementasi Node. Misalnya, ketika kami menyarankan untuk membersihkan semua input permintaan untuk alasan keamanan, Node-lingo harus digunakan - ‘Gunakan middleware untuk membersihkan input permintaan’. Jika sebuah item tidak memiliki implementasi khusus di Node.js (misalnya, item tersebut terlihat sama di Python & Jaba) - sertakan di dalam item container umum, lihat item 6.5 misalnya.
+
+## 6. Hanya vendor terkemuka
+
+Terkadang berguna untuk memasukkan nama vendor yang dapat mengatasi tantangan dan masalah tertentu seperti paket npm, alat open source atau bahkan produk komersial. Untuk menghindari daftar yang sangat panjang atau merekomendasikan proyek yang tidak bereputasi baik dan tidak stabil, kami membuat aturan berikut:
+
+- Hanya 3 vendor teratas yang disarankan - vendor yang muncul di 3 hasil teratas dari mesin pencari (Google atau GitHub diurutkan berdasarkan popularitas) untuk kata kunci relevan tertentu dapat dimasukkan dalam rekomendasi kami.
+- Jika ini adalah paket npm, itu juga harus diunduh setidaknya rata-rata 750 kali sehari.
+- Jika ini adalah proyek sumber terbuka, itu harus diperbarui setidaknya sekali dalam 6 bulan terakhir.
diff --git a/.operations/writing-guidelines.japanese.md b/.operations/writing-guidelines.japanese.md
new file mode 100644
index 000000000..23cfc416a
--- /dev/null
+++ b/.operations/writing-guidelines.japanese.md
@@ -0,0 +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](../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’. If an item has no specific implementation in Node.js (e.g. it looks the same in Python & Jaba) - include it within a generic container item, see item 6.5 for example.
+
+## 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/.operations/writing-guidelines.md b/.operations/writing-guidelines.md
index c0e6d6ea8..3b5163a35 100644
--- a/.operations/writing-guidelines.md
+++ b/.operations/writing-guidelines.md
@@ -16,11 +16,11 @@ Apart from the content being greatly edited and reliable, skimming through it sh
## 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).
+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](../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’. If an item has no specific implementation in Node.js (e.g. it looks the same in Python & Jaba) - include it within a generic container item, see item 6.5 for example.
+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’. If an item has no specific implementation in Node.js (e.g. it looks the same in Python & Java) - include it within a generic container item, see item 6.5 for example.
## 6. Leading vendors only
diff --git a/.operations/writing-guidelines.polish.md b/.operations/writing-guidelines.polish.md
new file mode 100644
index 000000000..e7ad37f4b
--- /dev/null
+++ b/.operations/writing-guidelines.polish.md
@@ -0,0 +1,31 @@
+# Nasz manifest pisania treści
+
+Jak zwiększamy komfort czytania i uczenia się dla naszych gości.
+
+## 1. Proste jest lepsze
+
+Naszą misją jest ułatwianie czytania i przyswajania wiedzy. Dlatego koncentrujemy się na przekształcaniu skomplikowanych i wyczerpujących tematów w uproszczoną listę, handlujemy przeciążonymi informacjami ze skróconymi i mniej dokładnymi szczegółami, unikamy „łatwopalnych” i kontrowersyjnych tematów i unikamy subiektywnych pomysłów na rzecz ogólnie przyjętych praktyk.
+
+## 2. Bądź wiarygodny i niezawodny
+
+Nasi czytelnicy powinni mieć wielką pewność, że przeglądane przez nich treści są wiarygodne. Osiągamy to poprzez włączenie dowodów, takich jak referencje, dane i inne zasoby dostępne na ten temat. Praktycznie staraj się zamieszczać cytaty z wiarygodnych źródeł, wykazywać wzorce, powiązane wzorce projektowe lub wszelkie środki naukowe, aby udowodnić swoje twierdzenia.
+
+## 3. MECE (Mutually Exclusive and Collectively Exhaustive)
+
+Oprócz tego, że treść jest znacznie edytowana i niezawodna, przeglądanie w niej powinno również zapewniać pełne omówienie tematu. Nie można pominąć żadnego ważnego tematu.
+
+## 4. Spójne formatowanie
+
+Treść jest prezentowana przy użyciu stałych szablonów. Wszelkie przyszłe treści muszą być zgodne z tym samym szablonem. Jeśli chcesz dodać nowe punktory, skopiuj format punktora z istniejącego i rozszerz go do swoich potrzeb. Aby uzyskać dodatkowe informacje, zobacz [ten szablon](../sections/template.md).
+
+## 5. To na temat Node.js
+
+Każda rada powinna dotyczyć bezpośrednio Node.js, a nie ogólnie oprogramowania. Kiedy radzimy zaimplementować ogólny wzorzec / regułę w Node.js, treść powinna koncentrować się na implementacji Node. Na przykład, gdy ze względów bezpieczeństwa zalecamy oczyszczenie danych wejściowych, należy użyć Node-lingo - „Użyj oprogramowania pośredniego do oczyszczenia danych wejściowych”. Jeśli element nie ma określonej implementacji w Node.js (np. wygląda tak samo w Python i Jaba) - dołącz go do ogólnego elementu kontenera, patrz na przykład pozycja 6.5.
+
+## 6. Tylko wiodący dostawcy
+
+Czasami przydatne jest podanie nazw dostawców, którzy mogą rozwiązać niektóre wyzwania i problemy, takie jak pakiety npm, narzędzia open source, a nawet produkty komercyjne. Aby uniknąć przytłaczających długich list lub rekomendować projekty nierenomowane i niestabilne, opracowaliśmy następujące zasady:
+
+- Polecamy tylko 3 najlepszych dostawców - dostawcę, który pojawia się w 3 najlepszych wynikach wyszukiwania (Google lub GitHub posortowane według popularności) dla danego odpowiedniego słowa kluczowego, możemy uwzględnić w naszej rekomendacji.
+- Jeśli jest to pakiet npm, musi być pobierany średnio co najmniej 750 razy dziennie.
+- Jeśli jest to projekt typu open source, musi zostać zaktualizowany przynajmniej raz w ciągu ostatnich 6 miesięcy.
diff --git a/.operations/writing-guidelines.russian.md b/.operations/writing-guidelines.russian.md
index c1bff4332..8f42baff9 100644
--- a/.operations/writing-guidelines.russian.md
+++ b/.operations/writing-guidelines.russian.md
@@ -16,7 +16,7 @@
## 4. Согласованное форматирование
-Контент представлен с использованием фиксированных шаблонов. Любое будущее содержание должно соответствовать тому же шаблону. Если вы хотите добавить новые маркеры, скопируйте формат маркера из существующего маркера и расширьте его для своих нужд. Для получения дополнительной информации, пожалуйста, просмотрите [этот шаблон](https://github.com/i0natan/nodebestpractices/blob/master/sections/template.md).
+Контент представлен с использованием фиксированных шаблонов. Любое будущее содержание должно соответствовать тому же шаблону. Если вы хотите добавить новые маркеры, скопируйте формат маркера из существующего маркера и расширьте его для своих нужд. Для получения дополнительной информации, пожалуйста, просмотрите [этот шаблон](../sections/template.md).
## 5. Это про Node.js
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 624468fbd..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-language: node_js
-node_js: 8
-script:
- - cd .operations
- - npm i
- - export PR=https://api.github.com/repos/$TRAVIS_REPO_SLUG/pulls/$TRAVIS_PULL_REQUEST
- - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo `curl -s $PR | jq -r .head.ref`; fi)
- - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH"
- - npm run lint
- - npm run build
\ No newline at end of file
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
deleted file mode 100644
index 9445d5553..000000000
--- a/CONTRIBUTORS.md
+++ /dev/null
@@ -1,128 +0,0 @@
-## Contributing
-If you've ever wanted to contribute to open source, now is your chance! See the [contributing docs](.operations/CONTRIBUTING.md) for more information.
-
-## Contributors ✨
-
-Thanks goes to these wonderful people who have contributed to this repository!
-
-
-
-
-
-
diff --git a/README.basque.md b/README.basque.md
new file mode 100644
index 000000000..eefa504a1
--- /dev/null
+++ b/README.basque.md
@@ -0,0 +1,1635 @@
+[✔]: assets/images/checkbox-small-blue.png
+
+# Node.js-ren praktika onak
+
+
+
+
+
+
+
+
+
+
+
+
+
+[](https://twitter.com/nodepractices/) **Hemen ere bagaude!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+
+Irakurri beste hizkuntza batzuetan: [**EN**](./README.md), [**CN**](./README.chinese.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**PL**](./README.polish.md),[**JA**](./README.japanese.md) [(**ES**, **FR**, **HE**, **KR** eta **TR** aribidean!)](#itzulpenak)
+
+
+
+###### Gure [Zuzendaritza Batzordeak ](#zuzendaritza-batzordea) eta [laguntzaileek](#Languntzaileak) eraiki eta mantentzen dute webgune hau
+
+# Azken praktika onak eta albisteak
+
+- ** Euskarazko itzulpena!:** wow gure euskal irakurleek ere gida hau bere ama-hizkuntzan irakur dezakete! [Ane Diaz de Tuesta](https://github.com/anediaz) eta Joxefe Diaz de Tuestaren eskutik
+
+- **🇯🇵 Japonierazko itzulpena:** hemendik aurrera japonieraz erabili daiteke gure gida, [YukiOta](https://github.com/YukiOta) eta [Yuta Azumi](https://github.com/YA21) gure laguntzaile ikaragarriei esker
+
+- **🎊 60.000 izar!**: Gure biltegiak 60.100 garatzaileren aitortza eta konfiantza jaso ditu. Hitzik gabe gaude
+
+
+
+# Ongi etorri! Hasi aurretik jakin beharreko 3 gauza
+
+**1. Hemen dozenaka artikulu dauzkazu, onenetarikoak Node.jsri buruz egindakoetan:** alegia, bilduma honek Node.jsren praktika onak jasotzen ditu, edukien arabera sailkatuta
+
+**2. Dagoen bildumarik handiena da, eta astetik astera handiagoa da:** une honetan 80tik gora praktika, estilo eskuliburu eta arkitektura aholku dauzkagu bilduta. Gustura asko jasoko genituzke zure ekarpenak bilduma hau eguneratuta edukitzeko, bai kode akatsak konponduz, bai itzulpenak eginez, bai ideia berriak proposatuz egin ditzakezunak: izan zaitez Node.jsren praktika onen liburuko partaide. Ikusi gure [idazketa jarraibideak](./.operations/writing-guidelines.basque.md)
+
+**3. Jarraibide gehienek informazio gehigarria dute.** Jarraibideko puntu bakoitzaren ondoan **🔗Informazio gehiago** esteka aurkituko duzu, jarraibidea osatzen duena kode adibideekin, blogetako aipu hautatuekin eta informazio osagarri gehiagorekin
+
+
+
+# `1. Proiektuaren egitura`
+
+## ![✔] 1.1 Antolatu zure proiektua atal eta osagai txikiagotan
+
+**TL;PL:** aplikazio handien oztoporik handiena kode base erraldoi bat mantendu beharra da, ehundaka lotura eta menpekotasun dituena. Horrelako lan monolitikoek programatzaileen lana motelarazten dute, funtzionalitate berriak gehitzen saiatzen dira eta. Hori gerta ez dadin, zatitu zure kodea osagai txikiagotan, bakoitza bere datuekin karpeta banatan, eta bermatu osagai bakoitza laburra eta sinplea izatea. Bisitatu hemen behean dagoen “Informazio gehiago” esteka, proiektu egoki baten egitura zuzenaren adibideak ikusteko
+
+**Bestela:** funtzionalitate berriak programatzean, garatzaileek zailtasun handiak izaten dituzte aldaketa horien eragina atzemateko, eta beldur izaten dira funtzionalitateon menpeko osagaiak hautsiko ote dituzten. Ondorioz, inplementazioak motelagoak eta arriskutsuagoak izaten dira. Oro har, zailagoa izaten da aplikazio baten kodea luzatzea negozio unitateak banatuta ez daudenean
+
+🔗 [**Informazio gehiago: antolatu zure proiektua osagai txikiagotan**](./sections/projectstructre/breakintcomponents.basque.md)
+
+
+
+## ![✔] 1.2 Antolatu zure aplikazioa geruzatan eta mantendu webaren geruza bere esparruaren barruan
+
+**TL;PL:** osagai bakoitzak «geruzak» izan beharko lituzke: hau da, berariaz weberako egindako objektu bat; beste bat, logikarako; eta beste bat, datuen sarbidearen koderako. Horrek, zati bakoitzaren funtzioak ondo bereizteko aukera eskaintzeaz gainera, sistema errazago simulatu eta testatzea ahalbidetzen du. Modelo hau oso ohikoa bada ere, APIen garatzaileek joera izaten dute geruzak nahasteko, webeko objektu espezifikoa (Express req, res) logika operatiboaren eta datuen geruzetara pasatuz, eta, ondorioz bai aplikazioa bai sarbidea Expressen menpeko bihurtzen dira
+
+**Bestela:** aplikazio batean webeko objektuak beste geruzekin nahastuta badaude, ezingo da bertara sartu testak, CRON atazak eta Express middleware-ak baino erabiliz
+
+🔗 [**Informazio gehiago: antolatu zure aplikazioa geruzatan**](./sections/projectstructre/createlayers.basque.md)
+
+
+
+## ![✔] 1.3 Kokatu baliabide komunak npm paketetan
+
+**TL;PL:** datu base askok osatzen duten aplikazio handi bat prestatzen dugunean, geruza guztietan lan egiten duten zeharkako tresna bakoitzak –erregistragailuak, zifragailuak eta beste– bere kodearen barruan egon behar du, npm pakete pribatu moduan, tresna horiek hainbat proiektutan partekatu ahal izatea ahalbidetzen duena
+
+**Bestela:** zuk zeuk asmatu beharko duzu zeure inplementazioa eta menpekotasun gurpila
+
+🔗 [**Informazio gehiago: antolatu funtzioen arabera**](./sections/projectstructre/wraputilities.basque.md)
+
+
+
+## ![✔] 1.4 Banandu Express 'aplikazioa' eta 'zerbitzaria'
+
+**TL;PL:** ekidin [Express](https://expressjs.com/) aplikazioa artxibo handi batean oso-osorik definitzeko ohitura desegokia. Banandu Express aplikazioaren definizioa bi artxibotan gutxienez: batetik, APIaren definizioa (app.js); eta, bestetik, sarearen ezaugarriak (WWW). Are gehiago, egitura egokiagoa izan dadin, jarri APIaren definizioa osagaiekin batera
+
+**Bestela:** probak egiteko, HTTP deien bidez baino ezingo da zure APIra sartu. Sarbide hori motelagoa da eta asko zailtzen du estaldura txostenak egitea. Gainera, ziur aski, ez da bat ere atsegina izango ehundaka lerro dituen kodea mantentzea
+
+🔗 [**Informazio gehiago: banandu Express 'aplikazioa' eta 'zerbitzaria'**](./sections/projectstructre/separateexpress.basque.md)
+
+
+
+## ![✔] 1.5 Erabili ingurunea errespetatzen duen konfigurazio seguru eta hierarkiko bat
+
+**TL;PL:** akatsik gabeko konfigurazio perfektu batek bermatu behar du (a) giltzak fitxategietatik eta inguruneko aldagaietatik irakurri ahal izatea, (b) sekretuak iturri kodetik kanpo gordeta egotea, eta, (c), bilaketak errazte aldera, konfigurazioa hierarkikoa izatea. Hori dena lortzeko badira paketeak, hala nola, [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) eta [convict](https://www.npmjs.com/package/convict)
+
+**Bestela:** konfiguazioa egitean baldintza horietarikoren bat betetzen ez baduzu, lana moteldu egingo da, bai garapen taldearena, bai devops taldearena
+
+🔗 [**Informazio gehiago: konfigurazio praktika onak**](./sections/projectstructre/configguide.basque.md)
+
+
+
+# `2. Erroreen kudeaketa`
+
+## ![✔] 2.1 Erabili Async-Await edo errore asinkronoak kudeatzeko promesak
+
+**TL;PL:** errore asinkronoak callback erabiliz kudeatzen badituzu, infernurako biderik azkarrena hartuko duzu edo galbiderako piramidean sartuko zara. Zure kodeari opari on bat egin nahi badiozu, erabili agintzen liburutegi ezagun bat edo async-await, try-catch erakoa adibidez kode sintaxis askoz trinkoago eta ohikoago bat eskaintzen duena
+
+**Bestela:** Node.jsren callback teknika (“err, response” prozedura) erabiltzen baduzu, kode ez jasangarriak sortuko dituzu, batera suertatuko baitira kode arrunta duten erroreen kudeaketa, habiaratze sarriegiak eta kodetze eredu ez erosoak
+
+🔗 [**Informazio gehiago: ekidin callback prozedurak**](./sections/errorhandling/asyncerrorhandling.basque.md)
+
+
+
+## ![✔] 2.2 Erabili soilik “Errorea” objektu kapsulatua
+
+**TL;PL:** maiz, erroreak kate gisa edo modu pertsonalizatuan agertzen dira, erroreak kudeatzeko logika zaildu eta moduluen arteko elkarreragingarritasuna oztopatzen duena. Agintza bat baztertu zein salbuespen bat ezarri edo errore ohar bat argitaratzen duzunean, soilik “Errorea” objektu kapsulatua –edo “Errore txertatua“ objektua zabaltzen duen objektua– erabiliz lortuko duzu bermatzea bateratasuna handitu eta informazioa ez galtzea
+
+**Bestela:** osagairen bati deitzean erroreak zein motatakoak diren jakin gabe, askoz zailagoa da eurak kontrolatzea. Are okerrago, erroreak deskribatzeko modu pertsonalizatuak erabiltzeak errore kritikoen informazioa galtzea ekar dezake, pilaren aztarna, besteak beste
+
+🔗 [**Informazio gehiago: erabili soilik “Errorea” objektu kapsulatua**](./sections/errorhandling/useonlythebuiltinerror.basque.md)
+
+
+
+## ![✔] 2.3 Bereizi eragiketa erroreak eta programatze erroreak
+
+**TL; PL:** eragiketa erroreek (adibidez, APIak balio gabeko sarrera jasotzea) agerian jartzen dituzten arazoak ezagunak izaten dira, eta, haien eragina guztiz ulertu eta kontuz kudeatzeko modukoak izaten dira. Bestetik, programatze erroreak (adibidez, zehaztu gabeko aldagaia irakurtzen saiatzea) aplikazioa berrabiarazteko agindua ematen duten kode hutsegite ezezagunak izaten dira
+
+**Bestela:** beti berrabiaraz dezakezu aplikazioa errore bat agertzen denean. Baina zergatik utzi 5.000 erabiltzaile offline iragarri daitekeen errore funtzional txiki batengatik? Kontrakoa ere ez da egokia: arazo ezezagun bat gertatzen denean -programatze errore bat, esaterako- aplikazioa martxan mantentzeak ezusteko jokaerak eragin ditzake. Biak bereizteak aukera ematen du kontuz jokatzeko eta ikuspegi orekatu bat aplikatzeko testuinguruan oinarrituz
+
+🔗 [**Informazio gehiago: eragiketa erroreak vs programatze erroreak**](./sections/errorhandling/operationalvsprogrammererror.basque.md)
+
+
+
+## ![✔] 2.4 Kudeatu erroreak gune bakar batean, Express middleware erabili partez
+
+**TL;PL:** erroreak kudeatzeko logika -hala nola, haien erregistroa eramatea eta administratzaileari mezuak bidaltzea- objektu dedikatu zentralizatu batean kapsulatu behar da, erroreren bat gertatzen denean helmuga guztiek (adibidez, Express middlewarea, cron atazak, atalkako egiaztatzeak) hara deitu dezaten
+
+**Bestela:** erroreak toki bakarrean ez kudeatzeak kodea bikoiztea eragiten du eta, ziur aski, erroreak gaizki kudeatzea ere bai
+
+🔗 [**Informazio gehiago: kudeatu erroreak gune bakar batean**](./sections/errorhandling/centralizedhandling.basque.md)
+
+
+
+## ![✔] 2.5 Dokumentatu aplikazioaren erroreak Swagger edo GraphQL-ren laguntzarekin
+
+**TL;PL:** jakinaren gainean jarri aplikazioaren deitzaileak erroreak berriro gerta daitezkeela, errore horiek behar bezala konpondu ahal izateko hutsik egin gabe. RESTful aplikazioetan Swagger bezalako dokumentazio esparruak erabiltzen dira. GraphQL erabiltzen baduzu, zeure eskema eta azalpenak erabil ditzakezu
+
+**Bestela:** aplikazio baten bezeroak erabaki dezake aplikazioa itxi eta berrabiaraztea, ulertzen ez duen errore baten abisua jaso duelako soil-soilik. Oharra: zu zeu izan zaitezke zure aplikaziotik deitzen duena (oso ohikoa mikrozerbitzu inguruneetan)
+
+🔗 [**Informazio gehiago: dokumentatu aplikazioaren erroreak Swagger edo GraphQLren laguntzarekin**](./sections/errorhandling/documentingusingswagger.basque.md)
+
+
+
+## ![✔] 2.6 Irten prozesutik elegantziarekin kanpoko norbait iristen denean hirira
+
+**TL;PL:** errore ezezagun bat gertatzen denean (programazio errore bat, ikusi 2.3 praktika ona), zalantza izaten da era egokian lanean ote dabilen aplikazioa. Kasu horietan, oso ohikoa izaten da prozesuak kudeatzeko tresna bat erabiltzea [Forever](https://www.npmjs.com/package/forever), [PM2](http://pm2.keymetrics.io/) edo antzekoren bat– prozesua berriro hasteko
+
+**Bestela:** ezagutzen ez duzun zerbait gertatzen denean, izan daiteke objekturen batzuk egoera txarrean daudelako (esaterako, globalki erabiltzen den gertaera igorle bat, barneko erroreren batengatik ondo ez dabilena) eta gerta daiteke aurrerantzean abisuek huts egitea edo modu ero samarrean funtzionatzea
+
+🔗 [**Informazio gehiago: gelditu prozesua**](./sections/errorhandling/shuttingtheprocess.basque.md)
+
+
+
+## ![✔] 2.7 Erabili erregistratze tresna helduak erroreen ikusgaitasuna handitzeko
+
+**TL;PL:** erregistratze tresna helduen sortak erabiltzen badituzu –[Pino](https://github.com/pinojs/pino) edo [Log4js](https://www.npmjs.com/package/log4js), adibidez–, erroreak lehenago atzeman eta ulertuko dituzu. Beraz, utzi alde batera console.log
+
+**Bestela:** console.log-ak arakatu behar badituzu edo testua desordenatua duen artxibo batean erroreak eskuz, kontsulta tresnarik gabe edo erregistratze bisore ganorazkorik gabe bilatu behar badituzu, ordu asko emango dituzu lanean gaueko ordu txikiak arte
+
+🔗 [**Informazio gehiago: erabili erregistratze tresna helduak**](./sections/errorhandling/usematurelogger.basque.md)
+
+
+
+## ![✔] 2.8 Testeatu erroreen fluxua zure test framework gustukoena erabiliz
+
+**TL;PL:** kalitate profesionaleko kontrol tresna automatizatu bat izan zein programatzaileentzako eskuzko test soil bat izan, bermatu zure kodeak ez duela egoera positiboetan bakarrik lan egiten, baizik eta errore zuzenak ere kudeatu eta birbidaltzen dituela. Mocha eta Chai bezalako unitate test frameworkek erraz egin dezakete lan hori (ikusi “Gist leiho”ko kode adibideak)
+
+**Bestela:** automatikoki zein eskuz probarik egin gabe ezin duzu konfiantzarik izan zure kodeak benetako erroreak atzemango dituen. Errore adierazgarririk gabe ez dago erroreak kudeatzerik
+
+🔗 [**Informazio gehiago: testeatu erroreen fluxua**](./sections/errorhandling/testingerrorflows.basque.md)
+
+
+
+## ![✔] 2.9 Aurkitu erroreak eta jardunik gabeko uneak APM produktuak erabiliz
+
+**TL;PL:** monitorizazio eta errendimendu produktuek (APM, ingelesezko siglen arabera) modu proaktiboan ebaluatzen dute zure kode basea edo aplikazioa automatikoki aurkitu ahal izan ditzaten erroreak, blokeoak eta atzeman ezin dituzun eraginkortasun txikiko atalak
+
+**Bestela:** denbora asko pasa zenezake zure aplikazioaren errendimendua eta jardunik gabeko uneak neurtzen, eta, hala ere, ez zenuke aurkituko zeintzuk diren zure kodearen zatirik motelenak egoera errealetan eta ez zenuke inoiz jakingo nola eragiten dioten erabiltzailearen lanari
+
+🔗 [**Informazio gehiago: APM produktuen erabilera**](./sections/errorhandling/apmproducts.basque.md)
+
+
+
+## ![✔] 2.10 Atzeman kudeatu gabeko agintzen arbuioak
+
+**TL;PL:** agintza baten barruan dauden salbuespenak xurgatuak eta baztertuak izango dira programatzaileak modu esplizituan kudeatzen ez baditu, haren kodea `process.uncaughtException`-ari atxikia egonda ere. Ekidin hori `process.unhandledRejection` erabiliz
+
+**Bestela:** zure erroreak xurgatuak izango dira eta ez da haien arrastorik geratuko. Ez duzu zertaz kezkatu
+
+🔗 [**Informazio gehiago: atzeman kudeatu gabeko aginduen arbuioak**](./sections/errorhandling/catchunhandledpromiserejection.basque.md)
+
+
+
+## ![✔] 2.11 Huts egin azkar, balidatu argudioak liburutegi dedikatu baten laguntzarekin
+
+**TL;PL:** Express erabiltzen duzunean, zure praktika onetako bat izan beharko litzateke aplikazioaren sarbidea kontrolatzea, ustegabeko erroreak ekiditeko, aurrerago erroreak atzematea askoz zailagoa izaten da eta. Balidazio kodea gogaikarria izan ohi da, [ajv](https://www.npmjs.com/package/ajv) eta [Joi](https://www.npmjs.com/package/joi) bezalako laguntza liburutegi moderno bat erabili ezean
+
+**Bestela:** pentsatu zure funtzioa agintza numeriko baten zain dagoela, adibidez «deskontua», eskatzaileak bidaltzea ahaztu duena; geroago, haren kodeak baieztatzen du « deskontua! = 0 (baimendutako deskontua zero baino handiagoa da)», eta horrek ahalmena ematen dio erabiltzaileari deskontua izateko. Ene, nolako errore arriskutsua! Konturatzen zara?
+
+🔗 [**Informazio gehiago: huts eragin azkar**](./sections/errorhandling/failfast.basque.md)
+
+
+
+## ![✔] 2.12 Agintzen zain egon beti itzuli aurretik, pilak arrastorik uztea saihesteko
+
+**TL; PL:** beti egin `return await` promesa bat itzultzean, pila osoaren jarraipena egin ahal izateko. Funtzio batek promesa bat itzultzen badu, funtzio hori `async`, hau da, asinkronotzat jo behar da, eta esplizituki `await`, itxaron agintza, itzuli aurretik
+
+**Bestela:** itxaron gabe agintza itzultzen duen funtzioa ez da pilaren arrastoan agertuko. Galdutako fotograma horiek akatsa eragingo duen fluxua ulertzea zailduko lukete, batez ere portaera anormalaren zergatia falta den funtzioaren barruan baldin badago
+
+🔗 [**Informazio gehiago: agintzak itzultzea**](./sections/errorhandling/returningpromises.basque.md)
+
+
+
+# `3. Kode estiloa`
+
+## ![✔] 3.1 Erabili ESLint
+
+**TL;PL:** [ESLint](https://eslint.org) da gerta daitezkeen kode erroreak egiaztatzeko eta kodearen estiloa zuzentzeko estandarra. Ez da soilik erabiltzen tarteen arazoak identifikatzeko, baizik eta kodearen antipatroi kritikoak atzemateko ere, hala nola garatzaileen errore ez-sailkatuak. ESLint kode estiloak automatikoki zuzentzeko gai bada ere, badira beste tresna batzuk eraginkorragoak direnak zuzenketak egiten –esaterako, [prettier](https://www.npmjs.com/package/prettier) eta [beautify](https://www.npmjs.com/package/js-beautify)– eta, gainera, ESLintekin batera egiten dute lan
+
+**Bestela:** garatzaileek arreta jarriko dute hain gogaikarriak diren arazo batzuk konpontzen –kodearen tarteak eta lerroaren luzera–, eta denbora gehiegi gal dezakete proiektuaren kode estiloa aztertzen
+
+🔗 [**Informazio gehiago: erabili ESLint eta Prettier**](./sections/codestylepractices/eslint_prettier.basque.md)
+
+
+
+## ![✔] 3.2 Node.jsrentzako plugin espezifikoak
+
+**TL;PL:** ESLintek Vanilla JavaScript babesteko dituen arau estandarretatik aparte, komeni da Node.jsren osagai espeziko batzuk erabiltzea, hala nola [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) eta [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security)
+
+**Bestela:** Node.jsren arau akastun batzuek radarraren kontrolari ihes egin ahal diote. Esaterako, garatzaileek sarbide moduan aldagai jakin baten beharra izan dezakete (require(variableCommeChemin)), edozein JS script erabiltzeko aukera ematen diena erasotzaileei. Node.jsren linterrek patroi horiek atzeman ditzakete eta garaiz jo alarma
+
+
+
+## ![✔] 3.3 Jarri kode multzo baten giltzak lerro bakarrean
+
+**TL;PL:** kode bloke baten hasierako parentesiak irekiera instrukzioaren lerroan egon behar du
+
+### Kode adibidea
+
+```javascript
+// Egin
+function edozeinFuntzio() {
+ // kode blokea
+}
+
+// Baztertu
+function edozeinFuntzio()
+{
+ // kode blokea
+}
+```
+
+**Bestela:** praktika on hau ez erabiltzeak ustekabeko emaitzak eragin ditzake, behean dagoen StackOverflow-en eztabaida harian ikus daitekeen bezala:
+
+🔗 [**Informazio gehiago:** “Zergatik aldatzen dira emaitzak giltzen kokapenaren arabera?” (StackOverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
+
+
+
+## ![✔] 3.4 Bereizi instrukzioak modu egokian
+
+Ez dio axola instrukzioak bereizteko puntu eta koma erabiltzen duzun edo ez, ohiko lerro jauzi okerrak edo koma txertatze automatikoak ezagutzeak lagundu egingo dizu ohiko errore sintaktikoak ez egiten
+
+**TL;PL:** erabili ESLint bereizketetan izaten diren erroreez jabetzeko. [Prettier](https://prettier.io/) edo [Standardjs](https://standardjs.com/) erabiliz automatikoki konpon ditzakezu arazo horiek
+
+**Bestela:** aurreko atalean esan bezala, JavaScripteko interpreteak automatikoki “puntu eta koma” gehitzen du instrukzio baten amaieran “puntu eta koma”rik ez badago edo instrukzioa behar den tokian ez dela amaitu eta horrek okerreko emaitzak eragin ditzakeela pentsatzen badu. Ustekabeko errore gehienak ekiditeko, esleipenak erabil ditzakezu eta, horrela, berehala deitutako funtzio adierazpenak erabiltzea saihestuko duzu
+
+### Kode Adibidea
+
+```javascript
+// Egin
+function eginZerbait() {
+ // ...
+}
+
+eginZerbait()
+
+// Egin
+
+const items = [1, 2, 3]
+items.forEach(console.log)
+
+// Baztertu — salbuespen bat jaurtitzen du
+const m = new Map()
+const a = [1,2,3]
+[...m.values()].forEach(console.log)
+> [...m.values()].forEach(console.log)
+> ^^^
+> SyntaxError: Unexpected token ...
+
+// egin zerbait — salbuespen bat jaurtitzen du
+const count = 2 // 2() burutzen saiatzen da, baina 2() ez da funtzio bat
+(function egin zerbait() {
+ // egin zerbait paregabea
+}())
+// jarri puntu eta koma berehala deitutako funtzioa baino lehen, const definizioaren ostean, funtzio anonimoak bueltatutako balioa aldagarri batean gorde edo baztertu IIFE guztiak
+```
+
+🔗 [**Informazio gehiago:** "Semi ESLint araua"](https://eslint.org/docs/rules/semi)
+🔗 [**Informazio gehiago:** "Ez dago ustekabeko ESLint arau lerroaniztunik"](https://eslint.org/docs/rules/no-unexpected-multiline)
+
+
+
+## ![✔] 3.5 Izendatu funtzio guztiak
+
+**TL;PL:** izendatu funtzio guztiak, itxierak eta deiak. Saihestu funtzio anonimoak. Hau bereziki erabilgarria da node aplikazio bat profilatzerakoan. Funtzio guztiak izendatzeak memoria argazkia egiaztatzean aukera emango dizu zer bilatzen ari zaren ulertzen
+
+**Bestela:** zaila izan liteke ekoizpen arazoak araztea memoria erregistroak erabiliz (memoria argazkia), funtzio anonimoetako memoria kontsumoa handia denean
+
+
+
+## ![✔] 3.6 Erabili izen deskriptiboak aldagaiak, konstanteak, funtzioak eta klaseak izendatzeko
+
+**TL;PL:** Erabili **_lowerCamelCase_** konstanteak, aldagaiak eta funtzioak izendatzean eta **_UpperCamelCase_** (maiuskulazko lehen letra ere) klaseak izendatzean. Horrek lagunduko dizu aldagai/funtzio arruntak eta instantziazioa behar duten klaseak erraz bereizten. Erabili izen deskriptiboak, baina saiatu laburrak izan daitezen
+
+**Bestela:** Javascript munduko hizkuntza bakarra da eraikitzailea ("Klasea") zuzenean deitzea ahalbidetzen duena aurretik eskatu/instantziatu gabe. Horrenbestez, klaseak eta funtzio eraikitzaileak bereizten dira UpperCamelCase-tik hasita
+
+### 3.6 Kode eredua
+
+```javascript
+// funtzioa izendatzeko UpperCamelCase erabiltzen dugu
+class KlaseBatenAdibidea {}
+
+// konstanteak izendatzeko const hitz gakoa eta lowerCamelCase erabiltzen ditugu
+const config = {
+ key: "balioa",
+};
+
+// aldagaiak eta funtzioak izendatzeko lowerCamelCase erabiltzen dugu
+let aldagaiBatenAdibidea = "balioa";
+function eginZerbait() {}
+```
+
+
+
+## ![✔] 3.7 Aukeratu const, let ordez. Ez erabili var
+
+**TL;PL:** `const` erabiltzeak esan nahi du behin aldagai bat esleituta ezin dela berriro esleitu. Beraz, erabilera desberdinetarako aldagai bakarra erabiltzeko joera baztertzen lagunduko dizu `const` erabiltzeak, bai eta kodea garbitzen ere. Aldagai bat behin baino gehiagotan esleitu behar baduzu –for begizta batean, adibidez– erabili `let`, garbiagoa da eta. Leten beste alderdi garrantzitsu bat da definitu duzun blokearen eremuan bakarrik eskura dezakezula deklaratutako aldagia. `var` funtzioen eremukoa da, ez blokearena, eta [ez da ES6n erabili behar](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70), `const` eta `let` erabiltzeko aukera duzu eta
+
+**Bestela:** arazketa askoz ere astunagoa da, maiz aldatzen den aldagai baten jarraipena egitean
+
+🔗 [**Informazio gehiago: JavaScript ES6 +: var, let, edo const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 Erabili moduluak lehenengo, barne funtzioen partez
+
+**TL;PL:** moduluak fitxategi bakoitzaren hasieran erabili behar dira, edozein funtzioren aurretik eta kanpo. Praktika on eta sinple honek lagunduko dizu fitxategiaren menpekotasunak erraz eta azkar atzematen haren eskuineko goi aldean, baita arazo posible batzuk ekiditen ere
+
+**Bestela:** Node.jsk aldi berean exekutatzen ditu require-ak. Funtzio batek dei egiten badie, egoera kritikoago batean dauden beste eskaera batzuk blokea daitezke. Gainera, deitutako moduluetako batek edo haren menpeko ataza batek errore bat izanez gero, komeni da lehenbailehen haren berri jakitea, eta agian ezingo da hori egin, modulu horri funtzio batek deitzen badio
+
+
+
+## ![✔] 3.9 Inportatu moduluak karpetaka eta ez artxiboak zuzenean
+
+**TL;PL:** modulua/liburutegia karpeta batean garatzean, sartu index.js fitxategia, moduluaren barruko osagarriak agerian jarri eta erabiltzaile guztiek bertara joko dute eta. Hori eginez gero, moduluaren 'interfaze' gisa lan egiten du, eta geroago egin beharreko aldaketak errazten ditu kontratua hautsi gabe
+
+**Bestela:** fitxategien barne egitura edo sinadura aldatzeak erabiltzaileen interfazea apur dezake
+
+### 3.9 Kodea adibidea
+
+```javascript
+// Egin
+module.exports.SMSProvider = require("./SMSProvider");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver");
+
+// Baztertu
+module.exports.SMSProvider = require("./SMSProvider/SMSProvider.js");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver/SMSNumberResolver.js");
+```
+
+
+
+## ![✔] 3.10 Erabili `===` eragilea
+
+**TL;PL:** hobetsi berdintasunaren eragile zorrotza `===` berdintasun abstraktuaren eragile ahulagoa baino `==`. `==` eragileak bi aldagai alderatuko ditu, behin aldagai arrunt bihurtu ondoren. `===` eragileak ez du aldagai motaren bihurketarik egiten, eta bi aldagaiek mota berekoak izan behar dute berdinak izateko
+
+**Bestela:** `==` eragileak, berdinak ez diren aldagaiak alderatuz gero, berdinak direlako mezua helaraz dezake
+
+### 3.10 Kode adibidea
+
+```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
+```
+
+Aurreko azalpen guztiak faltsuak izango lirateke `===` eragilea erabili izan balitz
+
+
+
+## ![✔] 3.11 Erabili Async Await, ekidin callbackak
+
+**TL;PL:** Node 8 LTS erabat bateragarria da orain Async-awaitekin, eta, horrela kode asinkronikoa kudeatzeko aukera ematen du, callbackik eta agintzarik erabili gabe. Async-awaitek ez du blokeorik eragiten, eta kode asinkronikoak sinkroniko bihurtzen ditu. Zure kodeari egin ahal diozun oparirik onena async-await erabiltzea da, eskaintzen duen kode sintaxia askoz ere trinkoagoa eta ezagunagoa da eta
+
+**Bestela:** gaizki pasatu eta infernura joateko biderik azkarrena hartu nahi baduzu, erabili callbackak errore asinkronoak kudeatzeko, seguruenik, infernura joateko biderik azkarrena aukeratuko duzu. Estilo honek gune guztietako erroreak egiaztatzera behartzen du, eta, gainera, kode habiaratze beti deserosoaren kudeaketa eta kode fluxua ulertzea zailtzen du
+
+🔗[**Informazio gehiago:** async-await 1.0ren gida](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 Erabili gezi funtzioak (=>)
+
+**TL;PL:** agintzak eta callbackak onartzen dituzten API zaharrekin async-await erabiltzea eta funtzio parametroak ekiditea gomendarria bada ere, gezi funtzioek kodearen egitura trinkotu egiten dute eta erro funtzioaren testuinguru lexikoa bermatu (hau da, `this`)
+
+**Bestela:** (ES5 funtzioetan) kode luzeek erroreak izateko joera handiagoa dute, eta, gainera, irakurtzeko astunak dira
+
+🔗 [**Informazio gehiago: gezi funtzioak erabiltzeko garaia da**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
+
+
+
+# `4. Probak eta kalitate orokorra`
+
+## ![✔] 4.1 Idatzi APIaren probak (osagaia), gutxienez
+
+**TL;PL:** proiektu gehienei ez zaie proba automatikorik egiten denbora gutxian egiten direlako edo, maiz, 'proba proiektua' kontroletik kanpo geratu eta bertan behera uzten delako. Hori dela eta, lehentasuna eman API probei eta hasi beraiek egiten; izan ere, hori da idazteko erarik errazena eta, gainera, proba unitarioek baino estaldura handiagoa eskaintzen dute; are gehiago, API probak sor ditzakezu, [Postman](https://www.getpostman.com/) bezalako tresnak erabiliz. Ondoren, baliabide eta denbora gehiago edukiz gero, jarraitu proba aurreratuak egiten, hala nola proba unitarioak, datu baseen probak, errendimendu probak, etab.
+
+**Bestela:** luzaroan aritu zintezke proba unitarioak idazten, azkenean soilik %20ko estaldura lortu duzula jakiteko
+
+
+
+## ![✔] 4.2 Erabili 3 zati proba izen bakoitzean
+
+**TL;PL:** proba adierazgarria izan behar da eskakizunen mailan, barne kodearekin lan egiten ohituta ez dauden QAko ingeniariek eta garatzaileek berez eta erraz uler dezaten. Probaren izenean adierazi zer ari den probatzen (probapean dagoen unitatea), zer egoeratan eta zer emaitza espero den
+
+**Bestela:** inplementazio batek huts egin du, “Gehitu produktua“ izeneko proba batek huts egin du. Esaten dizu horrek zehazki zer dabilen gaizki?
+
+🔗 [**Informazio gehiago: erabili 3 zati proba izen bakoitzean**](./sections/testingandquality/3-parts-in-name.basque.md)
+
+
+
+## ![✔] 4.3 Egitura probak AAA ereduaren arabera
+
+**TL;PL:** egituratu zure probak ondo bereizitako 3 ataletan: antolatu, aritu eta baieztatu (AAA). Lehenengo atalean probaren konfigurazioa egin behar da; ondoren proba egikaritu behar da; eta, azkenik, baieztapen fasea dator. Egitura horri jarraitzeak bermatzen du irakurleak garuneko PUZik ez gastatzea proba plana ulertzen
+
+**Bestela:** kode nagusia ulertzen egunero orduak eta orduak pasatzeaz gainera, orain zure garuna trebatzen pasatzen duzu bestela eguneko zatirik lasaiena izan behar zuena (probak)
+
+🔗 [**Informazio gehiago: egitura probak AAA ereduaren arabera**](./sections/testingandquality/aaa.basque.md)
+
+
+
+## ![✔] 4.4 Antzeman kodeko arazoak linter bat erabiliz
+
+**TL;PL:** erabili kode linterra oinarrizko kalitatea egiaztatzeko eta antiereduak garaiz atzemateko. Exekutatu edozein proba baino lehen eta gehitu aurre-commit-a git kako moduan, edozein arazo berrikusteko eta zuzentzeko behar den denbora minimizatu ahal izateko. Era berean, egiaztatu [3. atala](#3-kode-estiloa), kodearen estilo praktikei dagokienez
+
+**Bestela:** kode antiereduren bat zuzendu gabe utz dezakezu, zure ekoizpen ingurunean ahula izan litekeena
+
+
+
+## ![✔] 4.5 Saihestu datu globalak, gehitu datu pertsonalizatuak proba bakoitzean
+
+**TL;PL:** probak akopla daitezen ekiditeko eta proben fluxuari buruz erraz arrazoitzeko, proba bakoitzak bere datu baseko lerroen multzoan lan egin beharko luke. Proba batek datu baseko datu batzuk ba ote diren jakin nahi duenean edo haien beharra duen bakoitzean, berariaz erantsi behar dira datu horiek eta eragotzi beste erregistroren bat mutatzea
+
+**Bestela:** probek huts egin dutela eta, inplementazioa bertan behera utzi beharra izan duzula pentsatu. Egoera horretan, lan taldeak denbora asko pasatuko du porrotaren zergatiak aztertzen, azkenean, ondorio tamalgarri honetara iristeko: sistema ondo dabil; probek, ordea, elkarri eragiten diote eta egitura hausten dute
+
+🔗 [**Informazio gehiago: saihestu datu globalak**](./sections/testingandquality/avoid-global-test-fixture.basque.md)
+
+
+
+## ![✔] 4.6 Etengabe ikuskatu menpekotasun ahulak
+
+**TL;PL:** Express bezalako menpekotasun ospetsuenek ere ahultasun ezagunak dituzte, erraz gaindi daitezkeenak tresna komunitarioak eta komertzialak erabiliz, esaterako 🔗 [npm auditoria](https://docs.npmjs.com/cli/audit) eta 🔗 [snyk.io](https://snyk.io), zure CItik dei ditzakezunak konpilazio bakoitzean
+
+**Bestela:** zure kodeak ahultasunik ez izatea lortzeko tresna dedikaturik erabili gabe, etengabe begiratu beharko duzu mehatxu berriei buruz onlinen zer argitaratzen den eta haren jarraipena egin
+
+
+
+## ![✔] 4.7 Etiketatu zure probak
+
+**TL;PL:** egin beharreko probak desberdinak dira eszenatokiaren arabera; ke lasterrak, input-output gabekoak, garatzaileek artxibo bat gorde edo commit egiten dutenean erabiltzen diren testak, hasieratik amaierarainoko test erabatekoak presio eskaera berri bat bidaltzen denean egikaritzen direnak, etab. Hori lor daiteke #cold #api #sanity bezalako gako hitzak erabiliz probak etiketatzean, aukera izan dezazun zure proba tresnak erabiltzeko eta behar duzun azpimultzoari deitzeko. Adibidez, honela deitu ahal izango zenioke zentzutasun proba multzoari [Mocha](https://mochajs.org/) erabiliz: mocha --grep 'sanity'
+
+**Bestela:** garatzaile batek aldaketa txiki bat egiten duen bakoitzean oso motela izan daiteke proba guztiak exekutatzea, datu baseak kontsultatzen dituzten probak barne. Horrelako kasuetan, garatzaileei etsigarria gertatuko zaie probak egitea
+
+
+
+## ![✔] 4.8 Egiaztatu zure proben estaldura, proba eredu okerrak identifikatzen laguntzen du eta
+
+**TL;PL:** [Istanbul](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc) bezalako estaldura tresnak oso aproposak dira 3 arrazoirengatik: dohainik dira, hau da, ez da lanik egin behar txostenak lortzeko; proben estaldura gutxitu den identifikatzen laguntzen dute; eta, azkenik, baina ez garrantzi txikiagokoa, proben desdoikuntzak agerian jartzen dituzte. Koloretako kode estalduraren txostenak aztertzean, baliteke harrapaketa kapsula moduan sekula testatzen ez diren kode arloak ikustea, adibidez. Horrek esan nahi du probek bide arrakastatsuak besterik ez dituztela atzematen eta ez aplikazioak nola jokatzen duen erroreak gertatzen direnean. Konfiguratu zure probak estaldura maila batetik behera jaisten denean erroreak eragiteko
+
+**Bestela:** ez da inolako neurgailu automatizaturik egongo zure kodearen zati handi bat proben estalduratik kanpo dagoela esango dizuna
+
+
+
+## ![✔] 4.9 Ikuskatu pakete zaharkituak
+
+**TL;PL:** erabili zure tresnarik gogokoena (adibidez, 'npm outdated' edo [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) zaharkituta dauden paketeak atzemateko, ezarri kontrol hau zure IEren bideetan eta, are gehiago, eragin konpilazio batek huts egitea ingurune kritikoetan. Adibidez, agertoki kritikoa izan daiteke instalatutako pakete batek 5 adabaki baieztatuak dituenean (adibidez, bertsio lokala 1.3.1 da eta biltegi bertsioa 1.3.8) edo haren egileak zaharkitu etiketa jarri dionean. Kasu horretan, ezabatu konpilazioa eta ekidin bertsio hori erabiltzea
+
+**Bestela:** modu esplizituan arriskutsutzat etiketatuta dauden paketeak egikarituko ditu zure produkzioak
+
+
+
+## ![✔] 4.10 Erabili production bezalako inguruneak e2e probetarako
+
+**TL;PL:** zuzeneko datuak erabiltzen dituen hasieratik amaierarainoko proba (e2e) lehen IEren prozesuko katebegirik ahulena izaten zen, datu baseak bezalako zerbitzu astun askoren menpean dago eta. Erabili zure ekoizpen errealetik ahalik eta hurbilen dagoen ingurunea
+
+**Bestela:** docker-compose erabili ezean, taldeek ingurune bakoitzeko proben datu baseak mantendu behar izaten dituzte, garatzaileen makinak barne. Mantendu beti datu base horiek sinkronizatuta, proben emaitzak alda ez daitezen ingurune batetik bestera
+
+
+
+## ![✔] 4.11 Eguneratu probak aldizka analisi estatikoko tresnak erabiliz
+
+**TL;PL:** analisi estatikoko tresnak erabiltzeak lagundu egiten dizu kodearen kalitatea hobetzeko modu objektiboak lortzen eta zure kodea jasangarri izaten. Analisirako tresna estatikoak gehitu ahal dizkiozu zure IE konpilazioari, huts egingo duen susmoa duzuenean. Estaldurari dagokionean, bere aldeko puntu nagusiak dira kalitatea ikuskatzeko gaitasuna dutela fitxategi anitzen testuinguruan (adibidez, bikoizketak atzematea), azterketa aurreratuak egitea (adibidez, kodearen konplexutasuna hautematea), eta kode arazoen historiaren eta aurrerapenaren jarraipena egitea. Horretarako, bi tresna hauek erabil ditzakezu: [Sonarqube](https://www.sonarqube.org/) (2.600+ [izar](https://github.com/SonarSource/sonarqube)) eta [Code Climate](https://codeclimate.com/) (1.500+ [izar](https://github.com/codeclimate/codeclimate))
+
+**Bestela:** kodearen kalitatea txarra denean, erroreek eta errendimenduak beti emango dituzte arazoak, azken belaunaldiko ezaugarriak dituen liburutegi berri distiratsu batek ere konpontzerik izango ez dituenak
+
+🔗 [**Informazio gehiago: berregituratu!**](./sections/testingandquality/refactoring.basque.md)
+
+
+
+## ![✔] 4.12 Aukeratu arretaz zure IE plataforma (Jenkins vs CircleCI vs Travis vs gainerako mundua)
+
+**TL;PL:** zure integrazio jarraituaren plataformak (CICD) kalitateko tresna guztiak (adib. testak, lintak) ostatatu behar ditu, eta, beraz, indartsua izan beharko du bere pluginen ekosistemak. Aspaldian [Jenkins](https://jenkins.io/) proiektu askoren balio lehenetsia izan ohi zen, komunitaterik handiena eta oso plataforma indartsua baititu, ordainetan konfigurazio konplexu samarra eta ikaste kurba pikoa baditu ere. Gaur egun, askoz errazagoa da IE irtenbide bat sortzea [CircleCI](https://circleci.com) eta haren antzeko SaaS tresnak erabiliz. Tresna horiek IE hodi malgu bat sortzea ahalbidetzen dute azpiegitura osoa kudeatzeko zama hartu beharra izan gabe. Azken batean, sendotasuna eta abiaduraren arteko oreka lortzea da kontua. Egin zure aukera arretaz
+
+**Bestela:** hornitzaile espezializatu bat aukeratzeak blokeatu zaitzake, pertsonalizazio aurreratu bat behar duzunean. Bestalde, Jenkins erabiltzeak denbora asko eska dezake azpiegitura konfiguratzean
+
+🔗 [**Informazio gehiago: aukeratu IE plataforma**](./sections/testingandquality/citools.basque.md)
+
+
+
+## ![✔] 4.13 Probatu zure middlewareak eurak bakarrik
+
+**TL;PL:** middlewareak eskaera askori erantzuten dion logika sendo bat duenean, merezi du middlewarea probatzea bera bakarrik, web esparru osoa aktibatu gabe. Hori erraz lor daiteke {req, res, next} objektuak atzemanez eta behatuz
+
+**Bestela:** middleware Expressean === errorea izanez gero, errorea gertatuko zaizu eskaera guztietan edo gehienetan
+
+🔗 [**Informazio gehiago: probatu zure middlewareak eurak bakarrik**](./sections/testingandquality/test-middlewares.basque.md)
+
+
+
+# `5. Ekoizpena`
+
+## ![✔] 5.1. Monitorizazioa
+
+**TL;PL:** bezeroek baino lehenago arazoak aurkitzeko joku bat da monitorizazioa. Jakina, garrantzi handia eman behar zaio. Merkatua eskaintzez gainezka dago, eta, beraz, komeni zaizu zehazten hastea zeintzuk diren hartu behar dituzun oinarrizko neurriak (hemen dituzu nire iradokizunak); ondoren, pentsatu zer neurri osagarri ezarri behar dituzun; eta, azkenik, aukeratu hipotesi guztiak kontuan hartzen dituen soluzioa. Egin klik soluzioen ikuspegi orokorra izateko
+
+**Bestela:** hutsegitea === bezero zapuztuak
+
+🔗 [**Informazio gehiago: monitorizazioa!**](./sections/production/monitoring.basque.md)
+
+
+
+## ![✔] 5.2. Gardentasuna handitu erregistratze plataforma adimendunak erabiliz
+
+**TL;PL:** erregistroak arazketa adierazpen hutsalen biltegia izan daitezke edo zure aplikazioaren historia kontatzen duen aginte mahai praktikoa. Planifikatu zure erregistratze plataforma lehenengo egunetik: hau da, nola bildu, gorde eta aztertuko dituzun erregistroak, nahi duzun informazioa benetan eskura daitekeela bermatzeko (adibidez, zein den errore tasa, zerbitzu eta zerbitzarien bidez transakzio oso bat egin ondoren, eta abar)
+
+**Bestela:** kutxa beltz batekin amaituko duzu, eta zaila izango zaizu han jasotako ezarpenen zergatia aurkitzea. Azkenean, erregistro adierazpen guztiak idazten hasiko zara informazio osagarria gehitzeko
+
+🔗 [**Informazio gehiago: gardentasuna handitu erregistratze plataforma adimendunak erabiliz**](./sections/production/smartlogging.basque.md)
+
+
+
+## ![✔] 5.3. Delegatu ahal den guztia alderantzizko proxy batean (adibidez, gzip, SSL)
+
+**TL;PL:** Node izugarri txarra da PUZen zeregin intentsiboak egiten, esate baterako, gzipping, SSL termination. Haien partez benetako middleware zerbitzuak erabili behar dituzu –hala nola nginx eta Haproxy–
+edo hornitzaileen lainoko zerbitzuak
+
+**Bestela:** zure hari bakarra lanpetuta egongo da azpiegitura lanak egiten, zure aplikazioaren guneari kasu egin beharrean, eta, ondorioz, haren errendimenduak behera egingo du
+
+🔗 [**Informazio gehiago: delegatu ahal den guztia alderantzizko proxy batean (adibidez, gzip, SSL)**](./sections/production/delegatetoproxy.basque.md)
+
+
+
+## ![✔] 5.4. Blokeatu menpekotasunak
+
+**TL;PL:** zure kodeak berdin-berdina izan behar du ingurune guztietan, baina harrigarria bada ere npm lehenetsita dago menpekotasunei ingurune batetik bestera pasatzen uzteko. Instalatzen dituzunean paketeak hainbat ingurunetan, paketeen azken bertsioa eskuratzen saiatzen da. Hori saihesteko, erabili npm edo .npmrc konfigurazio artxiboak, ingurune bakoitzean dagokion paketearen zein bertsio zehatz (eta ez derrigorrez berriena) komeni zaizun adieraziko dizu eta. Bestela, kontrola fintze aldera, erabili `npm shrinkwrap`. \*Eguneratzea: NPM5 bertsiotik aurrera, menpekotasunak defektuz blokeatzeko konfiguratuta dator. Yarn pakete kudeatzaile berria ere lehenetsita dago horrela lan egiteko
+
+**Bestela:** QAk kodea xeheki probatuko du eta onartuko duen bertsioak desberdin jokatuko du produkzioan. Are okerrago, produkzio talde bereko zerbitzarien kodeak desberdinak izan litezke
+
+🔗 [**Informazio gehiago: blokeatu menpekotasunak**](./sections/production/lockdependencies.basque.md)
+
+
+
+## ![✔] 5.5. Babestu prozesuaren erabilgarritasuna tresna egokiak erabiliz
+
+**TL;PL:** prozesuak huts eginez gero, aurrera egin eta berrabiarazi beharra dago. Egoera arruntetan, nahikoak izan daitezke PM2 bezalako prozesuak kudeatzeko tresnak, baina gaur egungo mundu ”docker”-izatuan, taldeak kudeatzeko tresnak ere kontuan hartu behar dira
+
+**Bestela:** estrategia argirik gabe dozenaka eskaera exekutatzeak DevOpsa nahaste-borrastera eraman dezake, hartarako aldi berean tresna gehiegi (talde kudeaketa, dockerra, PM2) erabiliz gero
+
+🔗 [**Informazio gehiago: babestu prozesuaren erabilgarritasuna tresna egokiak erabiliz**](./sections/production/guardprocess.basque.md)
+
+
+
+## ![✔] 5.6. Erabili PUZeko nukleo guztiak
+
+**TL;PL:** Noderen oinarrizko bertsioa PUZeko nukleo bakar batean exekutatzen da, eta beste nukleo guztiak geldi geratzen dira. Beharrezkoa da Noderen prozesua erreplikatzea PUZ guztiak erabiliz: aplikazio txiki eta ertainekin, Node Cluster edo PM2 erabil dezakezu; aplikazio handi samarrekin, berriz, saiatu erabiltzen Docker tankerako talderen bat (adibidez, K8S, ECS) edo Linux hasieratze sisteman oinarritutako garatze idazkerak (adibidez, systemd)
+
+**Bestela:** seguruenik, zure aplikazioak erabilgarri dituen baliabideen %25a besterik ez du erabiltzen (!), edo gutxiago, agian. Kontuan izan ohiko zerbitzariek gutxienez lau nukleo dituztela PUZen, eta Node.jsren garatzaile soilak bat bakarra erabiltzen duela (AWS beanstalk bezalako PaaS zerbitzuekin lan egiten duenean ere)
+
+🔗 [**Informazio gehiago: erabili PUZeko nukleo guztiak**](./sections/production/utilizecpu.basque.md)
+
+
+
+## ![✔] 5.7. Sortu ‘mantentze lanen amaiera puntua‘
+
+**TL;PL:** API seguru batean, jarri agerian sistemarekin lotutako informazio multzo bat, hala nola, memoriaren erabilera eta REPL, etab. Nahiz eta gomendagarria den proba estandarretan eta tresna arruntetan oinarritzea, zenbait informazio eta eragiketa baliotsu errazago egiten dira kodea erabiliz
+
+**Bestela:** konturatuko zara “diagnostiko-inplementazio“ asko egiten ari zarela, eta kodea produkziora bidaltzen duzula soilik informazioa lortzeko diagnostikoa egite aldera
+
+🔗 [**Informazio gehiago: sortu ‘mantentze lanen amaiera puntua‘**](./sections/production/createmaintenanceendpoint.basque.md)
+
+
+
+## ![✔] 5.8. Aurkitu erroreak eta geldialdiak APM produktuak erabiliz
+
+**TL;PL:** aplikazioen jarraipen eta errendimendu produktuek (APM deritzona) modu proaktiboan neurtzen dituzte kode basea eta APIa, modu automatikoan ohiko jarraipenetik haratago joateko eta erabiltzaileen esperientzia arrunta zerbitzu eta maila guztietan neurtzeko. Adibidez, APM produktu batzuek agerian jarri dezakete azken erabiltzaileen aldean motelegi kargatzen dela transakzio bat, sakoneko arrazoia iradokitzen duten bitartean
+
+**Bestela:** APIaren errendimendua eta geldialdiak neurtzeko ahalegin handia egin zenezake, eta, ziurrenik, ez zinateke jabetuko zein diren zure kodearen atalik motelenak mundu errealeko eszenatokian eta nola eragiten dioten zure erabiltzaile esperientziari
+
+🔗 [**Informazio gehiago: aurkitu erroreak eta geldialdiak APM produktuak erabiliz**](./sections/production/apmproducts.basque.md)
+
+
+
+## ![✔] 5.9. Prestatu zure kodea ekoizpenerako
+
+**TL;PL:** programatu helburua kontuan izanik; planifikatu produkzioa lehenengo egunetik hasita. Horrek lausoa eta zehazgabea ematen duenez, produkzioaren mantentzeari estu-estu lotuta dauden garatze aholku batzuk bildu ditut (egin klik hemen behean dagoen Gist estekan)
+
+**Bestela:** IT / DevOps arloko munduko txapeldun batek ere ez du salbatuko gaizki idatzita dagoen sistema
+
+🔗 [**Informazio gehiago: prestatu zure kodea ekoizpenerako**](./sections/production/productioncode.basque.md)
+
+
+
+## ![✔] 5.10. Neurtu eta babestu memoriaren erabilera
+
+**TL;PL:** Node.jsk harreman gatazkatsuak ditu memoriarekin: v8 motorrak muga leunak dauzka memoria erabiltzean (1,4 GB) eta ezaguna da zein bidetatik galtzen duen Noderen kodeak memoria. Beraz, ezinbestekoa da Noderen prozesu memoriari erreparatzea. Aplikazio txikietan memoria aldizka neur dezakezu geruza komandoak erabiliz; baina aplikazio ertainetan eta handietan aztertu beharko zenuke ez ote zaizun komeni zure memoria erlojua kontrol sistema sendo baten erara erabiltzea
+
+**Bestela:** zure memoria prozesuak 100 bat megabyte gal dezake egunean, [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)-i gertatu zitzaion bezala
+
+🔗 [**Informazio gehiago: neurtu eta babestu memoriaren erabilera**](./sections/production/measurememory.basque.md)
+
+
+
+## ![✔] 5.11. Atera zure frontend modulu aktiboak Nodetik
+
+**TL;PL:** prestatu frontend edukia middleware dedikatu bat erabiliz (adibidez, nginx, S3, CDN), zeren Noderen errendimenduak behera egiten baitu artxibo estatiko askorekin lan egiten duenean, bera azpiprozesu bakarrekoa da eta
+
+**Bestela:** Node eduki dinamikoa eskaintzeko sortu zen arren, haren hari bakarra lanpetuta egongo da html / images / angular / react erako ehunka fitxategi bidaltzen, bera egiteko sortua izan zen zereginei esleitu barik bere baliabide guztiak
+
+🔗 [**Informazio gehiago: atera zure frontend/interfazeko modulu aktiboak Nodetik**](./sections/production/frontendout.basque.md)
+
+
+
+## ![✔] 5.12. Izan aberrigabea, hil zerbitzariak ia egunero
+
+**TL;PL:** gorde edozein datu mota (adibidez, erabiltzaile saioak, cacheak, kargatutako fitxategiak) kanpoko datu biltegietan; eta aztertu ez ote zenituzkeen zure zerbitzari guztiak aldian behin “hil” beharko edo “zerbitzaririk gabe”ko plataformaren bat erabili (adibidez, AWS Lambda), berariaz aberrigabe (stateless) jokaera duena
+
+**Bestela:** zerbitzari jakin batek huts eginez gero, makina akastun bat hil beharrean, aplikazioen geldialdia eragingo du. Gainera, gero eta zailagoa izango da mailaketaren elastikotasuna, zerbitzari jakin baten menpeko izanda
+
+🔗 [**Informazio gehiago: izan aberrigabea, hil zerbitzariak ia egunero**](./sections/production/bestateless.basque.md)
+
+
+
+## ![✔] 5.13. Erabili menpekotasunak automatikoki atzematen dituzten tresnak
+
+**TL;PL:** menpekotasun ezagunenek ere –Express, adibidez– badituzte (noizean behin) ahulezia ezagunak, sistema arriskuan jar ditzaketenak. Horrek konponbide erraza du, ordea, tresna komunitario eta komertzialak erabiliz gero, ahuleziak etengabe kontrolatu eta haien berri ematen dute eta (bertan edo GitHub-en)
+
+**Bestela:** zure kodea ahulezia eta zaurgarritasunetatik garbi mantentzeko tresna dedikaturik gabe, jarraipen estua egin beharko diezu mehatxu berriei buruz linean egiten diren argitalpenei, bide batez esanda, aspergarri samarra izaten dena
+
+🔗 [**Informazio gehiago: erabili menpekotasunak automatikoki atzematen dituzten tresnak**](./sections/production/detectvulnerabilities.basque.md)
+
+
+
+## ![✔] 5.14. Esleitu transakzio identifikazio bana adierazpen erregistro bakoitzari
+
+**TL;PL:** esleitu identifikatzaile bera –transakzio-: {balioren bat}– erregistro sarrera bakoitzari eskaera bakar baten barruan. Ondoren, erregistroetako erroreak ikuskatzean, erraz konturatuko zara zer gertatu zen aurretik eta ondoren. Zoritxarrez, hori ez da erraz lortzen Noden, haren izaera asinkronoa da eta. Ikusi kodearen adibideak beheko estekan
+
+**Bestela:** produkzioko erroreen erregistroa testuingururik gabe ikustean – aurretik gertatu zena, alegia –, askoz zailagoa eta motelagoa da arazoa aztertzea
+
+🔗 [**Informazio gehiago: esleitu transakzio identifikazio bana adierazpen erregistro bakoitzari**](./sections/production/assigntransactionid.basque.md)
+
+
+
+## ![✔] 5.15. Ezarri NODE_ENV = produkzioa
+
+**TL;PL:** ezarri NODE_ENV ingurune aldagaia ‘produkzioa‘ edo ‘garapena‘ ataletan produkzioaren optimizazioak aktibatu beharra dagoen adierazteko; npm pakete askok uneko ingurunea zehazten dute eta haren kodea optimizatzen dute ekoizpenerako
+
+**Bestela:** ezaugarri soil hori gabe errendimendua asko jaits liteke. Adibidez, Express erabiltzean zerbitzarira bideratzeko `NODE_ENV` gabe, errendimendua heren bat moteltzen da
+
+🔗 [**Informazio gehiago: Ezarri NODE_ENV = produkzioa**](./sections/production/setnodeenv.basque.md)
+
+
+
+## ![✔] 5.16. Diseinatu inplementazio automatizatuak, atomikoak eta geldialdi gabekoak
+
+**TL;PL:** ikerketek frogatu dute inplementazio ugari egiten dituzten taldeek ekoizpen arazo kritikoak izateko probabilitatea txikiagotzen dutela. Eskuz egin beharreko urrats arriskutsurik eta zerbitzuen geldialdirik ez duten inplementazio azkar eta automatizatuek nabarmen hobetzen dute inplementazio prozesua. Baliteke hori bera lortzea Docker eta IE tresnak, biak batera, erabiliz, inplementazio sinplifikatuari dagokionez industriaren estandarra bihurtu dira eta
+
+**Bestela:** inplementazio luzeak -> produkzioaren geldialdia eta gizakiak eragindako erroreak -> inplementazioan konfiantzarik ez duen taldea -> inplementazio eta funtzio gutxiago egitea
+
+
+
+## ![✔] 5.17. Erabili Node.jsren LTS bertsio berria
+
+**TL;PL:** ziurtatu Node.jsren LTS bertsioa erabiltzen ari zarela errore kritikoen zuzenketak, segurtasun eguneratzeak eta errendimenduaren hobekuntzak jasotzeko
+
+**Bestela:** aurkitu berri diren erroreak edo ahuleziak erabil litezke produkzioan exekutatzen den aplikazio bat ustiatzeko eta baliteke zure aplikazioa ez izatea bateragarria hainbat modulurekin eta zailagoa gertatzea hura mantentzea
+
+🔗 [**Informazio gehiago: Erabili NTS.jsren LTS bertsioa**](./sections/production/LTSrelease.basque.md)
+
+
+
+## ![✔] 5.18. Ez bideratu erregistrorik aplikazioaren barruan
+
+**TL;PL:** garatzaileek ez dituzte erregistroen helmugak aplikazio kodearen barruan kodetu behar, aplikazioa exekutatzen den inguruneak berak definitu beharko ditu eta. Garatzaileek `stdout`-ean idatzi behar dituzte erregistroak erregistratze tresna bat erabiliz, eta gero exekuzio inguruneak (edukiontzia, zerbitzaria eta abar) bideratuko du `stdout` korrontea helmuga egokira (hau da, Splunk, Graylog, ElasticSearch eta abar)
+
+**Bestela:** aplikazioen kudeaketaren erregistroak bideratzea === zaila da eskalatzen, erregistroen galera dakar, eskasa izaten da kezken bereizketa
+
+🔗 [**Informazio gehiago: erregistroen bideraketa**](./sections/production/logrouting.basque.md)
+
+
+
+## ![✔] 5.19. Instalatu zure paketeak `npm ci` erabiliz
+
+**TL;PL:** ziurtatu ekoizpen kodeak erabiltzen duela probak egiteko erabili dituzun paketeen bertsio berdina. Exekutatu `npm ci` zure package.json eta package-lock.json paketen menpekotasunen instalazio garbia egiteko
+
+**Bestela:** QAk kodea sakonki probatuko du eta produkzioan modu desberdinean jokatuko duen bertsioa onartuko du. Are okerrago, produkzio talde bateko hainbat zerbitzarik kode desberdinak exekuta ditzake
+
+🔗 [**Informazio gehiago: erabili npm ci**](./sections/production/installpackageswithnpmci.basque.md)
+
+
+
+## ![✔] 6.1. Erabili linter segurtasun arauak
+
+
+
+**TL;PL:** erabili segurtasunarekin lotutako linter pluginak, [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security) bezalako segurtasun ahuleziak eta arazoak lehenbailehen atzemateko, ahal bada kodetzen ari diren bitartean. Horrek segurtasun ahuleziak atzematen lagun dezake, hala nola eval erabiltzea, bigarren mailako prozesu bat deitzea edo modulu bat inportatzea kate literal batekin (adibidez, erabiltzailearen sarrera). Egin klik 'Informazio gehiago' atalean segurtasun liner batek atzematen dituen kode adibideak ikusteko
+
+**Bestela:** garapenean zehar segurtasun ahulezia zuzena izan zitekeena produkzioaren arazo nagusia bihurtzen da. Gainera, baliteke proiektuak kodeen segurtasun praktika koherenterik ez jarraitzea, ahuleziak sartzea edo urruneko biltegietan sartutako sekretu konfidentzialak sortzea
+
+🔗 [**Informazio gehiago: lint arauak**](./sections/security/lintrules.basque.md)
+
+
+
+## ![✔] 6.2. Mugatu aldi baterako eskaerak middlewareak erabiliz
+
+
+
+**TL;PL:** DOS erasoak oso ezagunak dira, eta nahiko erraz eragin daitezke. Ezarri abiadura muga kanpoko zerbitzu bat erabiliz, hala nola hodeiko karga orekatzaileak, hodeiko suebakiak, nginx, [abiadura-mugatzaile-malgua](https://www.npmjs.com/package/rate-limiter-flexible) (rate-limiter-flexible) edo (aplikazio txikiagoak eta ez hain kritikoetarako) abiadura mugatzeko middleware bat (adibidez, [express-rate-limit](https://www.npmjs.com/package/express-rate-limit), express abiadura mugatzailea)
+
+**Bestela:** aplikazio batek erasoak jasan ahal ditu, haren erabiltzaileei ukatzen bazaie jaso beharko luketen zerbitzua, aplikazioa egoera txarrean dagoelako edo eskuragarri ez dagoelako
+
+🔗 [**Informazio gehiago: ezarri abiadura muga**](./sections/security/limitrequests.basque.md)
+
+
+
+## ![✔] 6.3 Kendu sekretuak konfigurazio fitxategietatik edo erabili paketeak enkriptatzeko
+
+
+
+**TL;PL:** ez gorde inoiz testu arrunteko sekreturik konfigurazio fitxategietan edo iturburu kodean. Horren ordez, erabili sekretuak kudeatzeko sistemak, hala nola Vault produktuak, Kubernetes / Docker Secrets edo ingurune aldagaiak. Azken baliabide gisa, iturburuko kontrolean gordetako sekretuak enkriptatu eta kudeatu egin behar dira (gako birakariak, iraungitzeak, ikuskaritza, etab.). Erabili aurre-commit/push kakoak, ustekabean sekreturik gordetzea saihesteko
+
+**Bestela:** iturburu kodearen kontrola publiko egin daiteke akats baten ondorioz, biltegi pribatuetan ere, eta orduan sekretu guztiak agerian geratzen dira. Kanpoko norbaitek iturburuko kontrolaren sarbidea ezagutzeak nahi gabe eragingo du erlazionatutako sistemetarako sarbideak ere ezagutzea (datu baseak, APIak, zerbitzuak, etab.)
+
+🔗 [**Informazio gehiago: kudeaketa sekretua**](./sections/security/secretmanagement.basque.md)
+
+
+
+## ![✔] 6.4. Saihestu kontsultak injektatzeko ahultasunak ORM / ODM liburutegiekin
+
+
+
+**TL;PL:** SQL / NoSQL injekzioa eta beste eraso maltzur batzuk ekiditeko, erabili beti ORM / ODM edo datuetatik ihes egiten duen datu baseen liburutegia, edo kontsulta parametro izendatuak edo indexatuak onartzen dituena eta espero diren erabiltzaileen sarrera balioztatzen duena. Inoiz ez erabili JavaScript txantiloien kateak edo katearen kateatzea balioak kontsultetan txertatzeko, horrek zure aplikazioa ahultasunen espektro zabalera irekitzen baitu. Node.js entzute handiko datuen liburutegi guztiek injekzio erasoen aurkako babesa dute (adibidez, [Sequelize](https://github.com/sequelize/sequelize), [Knex](https://github.com/tgriesser/knex), [mongoose](https://github.com/Automattic/mongoose))
+
+**Bestela:** balidatu gabeko edo baimendu gabeko erabiltzaileen sarrerak operadorearen injekzioa ekar dezake NoSQLrako MongoDB-rekin lan egitean, eta saneamendu sistema edo ORM egokia ez erabiltzeak SQL injekzio erasoak ahalbidetuko ditu, ahultasun erraldoia sortuz
+
+🔗 [**Informazio gehiago: kontsulten injekzioaren prebentzioa ORM / ODM liburutegiak erabiliz**](./sections/security/ormodmusage.basque.md)
+
+
+
+## ![✔] 6.5. Segurtasuneko praktika onen bilduma
+
+**TL;PL:** Node.jsrekin zuzenean loturarik ez duen segurtasuneko aholku bilduma bat da: Noderen inplementazioa ez da hain desberdina beste edozein hizkuntzaren inplementazioaren aldean. Egin klik “Informazio gehiago” botoian sakontzeko
+
+🔗 [**Informazio gehiago: ohiko segurtasun praktika onak**](./sections/security/commonsecuritybestpractices.basque.md)
+
+
+
+## ![✔] 6.6. Doitu HTTP erantzunen izenburuak segurtasun hobea lortzeko
+
+
+
+**TL;PL:** zure aplikazioak izenburu seguruak erabili beharko lituzke erasotzaileek gune arteko scriptak (XSS), clickjacking-a eta beste eraso maltzur arruntak egitea saihesteko. Horiek erraz konfigura daitezke [helmet](https://www.npmjs.com/package/helmet) bezalako moduluak erabiliz
+
+**Bestela:** erasotzaileek zure aplikazioaren erabiltzaileen aurkako eraso zuzenak egin ditzakete, segurtasun ahultasun handiak sortuz
+
+🔗 [**Informazio gehiago: erabili izenburu seguruak zure aplikazioan**](./sections/security/secureheaders.basque.md)
+
+
+
+## ![✔] 6.7. Etengabe eta automatikoki ikuskatu ba ote dagoen erasotzen errazak diren menpekotasunak
+
+
+
+**TL;PL:** npm ekosistemarekin ohikoa da proiektu batek menpekotasun ugari izatea. Menpekotasunak beti kontrolatuta egon behar dira ahultasun berriak aurkitzen diren heinean. Erabili [npm audit](https://docs.npmjs.com/cli/audit) edo [snyk](https://snyk.io/) bezalako tresnak, erasotzen errazak diren menpekotasunen jarraipena egiteko, kontrolatzeko eta adabakiak jartzeko. Tresna horiek zure IE konfigurazioarekin integratu, erasotzen errazak diren menpekotasunenak atzemateko ekoizpenera iritsi aurretik
+
+**Bestela:** erasotzaile batek zure web esparrua detektatu eta ageriko ahultasun guztiei eraso ahal die
+
+🔗 [**Informazio gehiago: menpekotasunen segurtasuna**](./sections/security/dependencysecurity.basque.md)
+
+
+
+## ![✔] 6.8. Babestu erabiltzaileen pasahitzak / sekretuak BCrypt edo Script erabiliz
+
+
+
+**TL;PL:** pasahitzak eta sekretuak (adibidez API giltzak) gorde behar dira hash + gatz funtzio seguru bat erabiliz, esaterako, `bcrypt`edo `scrypt`; eta kasurik okerrenean, `pbkdf2`
+
+**Bestela:** funtzio segururik erabili gabe gordetzen diren pasahitzak eta sekretuak bortxaz erasotuak izan daitezke edo hiztegi erasoak jasan ditzakete. Azkenean agerian gera daitezke, bai eta agian zabaldu ere
+
+🔗 [**Informazio gehiago: erabiltzaileen pasahitzak**](./sections/security/userpasswords.basque.md)
+
+
+
+## ![✔] 6.9. Ekidin HTML, JS eta CSS irteerak
+
+
+
+**TL;PL:** arakatzailera bidaltzen diren datu ez fidagarriak bistaratu beharrean exekutatu egin daitezke, normalean cross-site-scripting (XSS) erasoa deritzona. Arindu hori datuak inoiz exekutatu behar ez diren eduki huts gisa (hau da, kodetu, ihes)esplizituki markatzen dituzten liburutegi espezializatuak erabiliz
+
+**Bestela:** erasotzaile batek JavaScript kodeketa kaltegarria gorde dezake zure DBn, gero bezero gizajoei dagoen moduan bidaliko zaiena
+
+🔗 [**Informazio gehiago: ihes irteera**](./sections/security/escape-output.basque.md)
+
+
+
+## ![✔] 6.10. Balidatu sarrerako JSON eskemak
+
+
+
+**TL;PL:** balidatu sarrerako eskaeren gorputzeko zama erabilgarria eta ziurtatu zure itxaropenak betetzen dituela; eta, haiek bete ezean, huts eragin. Ibilbide bakoitzaren balioztatze kodetze neketsua saihesteko JSONen oinarritutako balioztatze eskema arinak erabil ditzakezu, hala nola [jsonschema](https://www.npmjs.com/package/jsonschema) edo [joi](https://www.npmjs.com/package/joi)
+
+**Bestela:** zure eskuzabaltasunak eta ikuspegi permisiboak asko handitzen dute erasoaren tamainua, eta erasotzailea sarrera asko probatzera bultzatzen du, aplikazioa kraskatzeko konbinazio bat aurkitu arte
+
+🔗 [**Informazio gehiago: balidatu sarrerako JSON eskemak**](./sections/security/validation.basque.md)
+
+
+
+## ![✔] 6.11. Onartu JWTen zerrenda beltzak
+
+
+
+**TL;PL:** JSON web fitxak erabiltzean (adibidez, [Passport.js](https://github.com/jaredhanson/passport))-rekin), lehenespenez ez dago igorritako fitxen sarbidea ezeztatzeko mekanismorik. Erabiltzaileen jarduera maltzurren bat aurkitu ondoren, ez dago modurik sistemara sartzea eragozteko, baliozko fitxaren bat duten bitartean. Konpondu hori eskaera bakoitzean balioztatuko diren fitxa ezfidagarrien zerrenda beltza erabiliz
+
+**Bestela:** edozeinek erabil litzake iraungitako edo gaizki kokatutako fitxak, maltzurki aplikazio batera sartzeko eta fitxaren jabea ordezkatzeko
+
+🔗 [**Informazio gehiago: JSON web fitxen zerrenda beltzak**](./sections/security/expirejwt.basque.md)
+
+
+
+## ![✔] 6.12. Aurrea hartu baimenaren aurkako eraso basatiei
+
+
+
+**TL;PL:** oso teknika sinple eta eraginkorra da baimen saiakerak mugatzea bi metrika erabiliz:
+
+1. Lehenengoa, erabiltzaile beraren ID / izen eta IP helbide bakarrak jarraian huts egin duen saiakera kopurua
+2. Bigarrena, IP helbide batek denbora tarte luze batean huts egin duen saiakera kopurua. Adibidez, blokeatu IP helbide bat, egun batean 100 saiakera huts egiten baditu
+
+**Bestela:** erasotzaile batek pasahitz automatizatuen saiakera mugagabeak egin ditzake aplikazio bateko kontu pribilegiatuetara sartzeko
+
+🔗 [**Informazio gehiago: mugatu saioa hasteko abiadura**](./sections/security/login-rate-limit.basque.md)
+
+
+
+## ![✔] 6.13. Exekutatu Node.js erabiltzaile ez-erro gisa
+
+
+
+**TL;PL:** eszenatoki arrunt batean Node.js baimen mugagabeak dituen erro erabiltzaile gisa exekutatzen da. Hori da, adibidez, Docker edukiontzietako portaera lehenetsia. Gomendagarria da erro ez den erabiltzaile bat sortzea eta Docker irudian sartzea (behean azaltzen dira adibideak) edo prozesua erabiltzaile horren izenean abiaraztea "-u username" marka duen edukiontzia deituz
+
+**Bestela:** zerbitzarian script bat exekutatzea lortzen duten erasotzaileek botere mugagabea lortzen dute makina lokalaren gainean (adibidez, iptable aldatu eta trafikoa beren zerbitzarira bideratzea)
+
+🔗 [**Informazio gehiago: exekutatu Node.js erabiltzaile ez-erro gisa**](./sections/security/non-root-user.basque.md)
+
+
+
+## ![✔] 6.14. Mugatu kargaren tamaina alderantzizko proxy edo middlewareak erabiliz
+
+
+
+**TL;PL:** zenbat eta gorputzaren karga handiagoa izan, orduan eta zailagoa da zure hari bakarra lan egitea hura prozesatzean. Hori da erasotzaileek zerbitzariak belauniko jartzeko aukera ona eskaera kopuru izugarririk egin gabe (DOS / DDOS erasoak). Murriztu arriskua ertzean jasotako eskaeren gorputzaren tamaina mugatuz (adibidez, suebakia, ELB) edo [express body parser](https://github.com/expressjs/body-parser) konfiguratuz tamaina txikiko kargak bakarrik onartzeko
+
+**Bestela:** zure aplikazioak eskaera handiei aurre egin beharko die, eta ezingo du prozesatu egin behar duen beste lan garrantzitsua, ondorioz errendimendua gutxituz eta DOS erasoekiko ahulduz
+
+🔗 [**Informazio gehiago: mugatu kargaren tamaina**](./sections/security/requestpayloadsizelimit.basque.md)
+
+
+
+## ![✔] 6.15. Saihestu JavaScripten eval adierazpenak
+
+
+
+**TL;PL:** `eval` arriskutsua da, exekutatzeko garaian JavaScript kode pertsonalizatua exekutatzea baimentzen baitu. Hori ez da errendimendu arazo bat bakarrik, baizik eta segurtasun arazo garrantzitsua, erabiltzaileen sarreratik JavaScript kode gaiztoa lor daiteke eta. Halaber, `new Function constructor` ere saihestu beharra dago; eta, azkenik, `setTimeout` eta `setInterval`, ez dira inoiz pasatu behar, ezta JavaScript kode dinamikoa ere
+
+**Bestela:** Javascript kode gaiztoak bidea aurkitzen du `eval` testura edo JavaScript hizkuntzak denbora errealean ebaluatzeko dituen funtzioetara sartzeko, eta sarbide osoa lortuko du JavaScripten orrialdeko baimenetara. Ahultasun hori XSS eraso gisa agertzen da askotan
+
+🔗 [**Informazio gehiago: saihestu JavaScript eval adierazpenak**](./sections/security/avoideval.basque.md)
+
+
+
+## ![✔] 6.16. Saihestu RegEx gaiztoak zure exekuzio hari bakarra gainkargatzea
+
+
+
+**TL;PL:** adierazpen erregularrak, oso erabilgarriak izan arren, benetako mehatxua dira JavaScript aplikazioentzat, oro har, eta Node.js plataformarentzat, bereziki. Erabiltzaile baten sarrera prozesatzeko testuarekin bat etor dadin, gerta liteke PUZeko ziklo kopuru handia behar izatea. RegExen prozesamenduaren eraginkortasuna hain txikia izan daiteke, ezen 10 hitz balioztatzen dituen eskaera bakar batek blokea baitezake gertaeren begizta osoa 6 segundoz, eta PUZa su hartzeko moduan jarri 🔥. Hori dela eta, erasotzen errazak diren ohiko adierazpen ahulen txantiloiak atzemateko erabili hirugarrenen balidazio paketeak -esaterako, [validator.js](https://github.com/chriso/validator.js)-, zuk zeure Regex ereduak idatzi edo [safe-regex](https://github.com/substack/safe-regex) erabili gabe
+
+**Bestela:** gaizki idatzitako ohiko adierazpenek Regular Expression DoSen erasoak jasan ditzakete, gertaeren begizta erabat blokeatuko dutenak. Adibidez, 2017ko azaroan, RegExen erabilera gaiztoak agerian jarri zuen `moment` pakete ezagunaren ahultasuna
+
+🔗 [**Informazio gehiago: saihestu RegEx gaiztoa erabiltzea**](./sections/security/regex.basque.md)
+
+
+
+## ![✔] 6.17. Saihestu moduluak kargatzea aldagai bat erabiliz
+
+
+
+**TL;PL:** bide bat erabiltzailea sartu ondoren sortua ote den kezka baduzu eta horregatik parametro gisa ezarri baduzu, saihestu bide hori erabiltzea beste fitxategi bat deitzeko / inportatzeko. Arau hori, oro har, edozein fitxategitara sartzeko erabil daiteke (hau da, `fs.readFile()`) edo erabiltzailea sartu ondoren sortutako aldagai dinamikoak dituen beste baliabide konfidentzialetara sartzeko. [Eslint-plugin-security](https://www.npmjs.com/package/eslint-plugin-security) linterrek eredu horiek atzeman eta nahikoa goiz ohartaraz dezake
+
+**Bestela:** erabiltzaile gaiztoen sarrerak manipulatutako fitxategiak deitzeko erabiltzen den parametro batera jo dezake, adibidez, aurretik fitxategi sisteman kargatutako fitxategietara edo lehendik sisteman bazeuden fitxategietara sartzeko
+
+🔗 [**Informazio gehiago: moduluaren karga segurua**](./sections/security/safemoduleloading.basque.md)
+
+
+
+## ![✔] 6.18. Exekutatu kode ez segurua sandbox batean
+
+
+
+**TL;PL:** exekuzio garaian ematen den kanpoko kodea exekutatu behar duzunean (adibidez, plugina), erabili kode nagusia isolatu eta pluginetik babesten duen 'sandbox' tankerako edozein exekuzio ingurune mota. Hori lor daiteke prozesu dedikatu baten bidez (adibidez, `cluster.fork()`), zerbitzaririk gabeko ingurune bat erabiliz edo sandbox bat balitz bezala jokatzen duten npm pakete dedikatuak erabiliz
+
+**Bestela:** plugin batek bide ugari erabil ditzake erasotzeko, hala nola begizta infinituak erabiliz, memoria gainkargatuz eta prozesu ingurune eraso errazen aldagaiak eskuratuz
+
+🔗 [**Informazio gehiago: exekutatu kode ez segurua sandbox batean**](./sections/security/sandbox.basque.md)
+
+
+
+## ![✔] 6.19. Kontu handia izan bigarren mailako prozesuekin lan egitean
+
+
+
+**TL;PL:** ahal dela, saihestu bigarren mailako prozesuak, eta, hala behar izanez gero, balioztatu eta garbitu sarrera, shell injekzioko erasoak arintzeko. Hobetsi `child_process.execFile` fitxategia, definizioz komando bakarra exekutatuko duena atributu multzo batekin eta shell parametroen hedapena onartuko ez duena
+
+**Bestela:** bigarren mailako prozesuak ganorarik gabe erabiltzeak urruneko komandoen exekuzioa edo shell injekzioko erasoak eragin ditzake, desinfektatu gabeko sistema komando batera erabiltzaile gaiztoren bat sartu dela eta
+
+🔗 [**Informazio gehiago: kontuz ibili bigarren mailako prozesuekin lan egitean**](./sections/security/childprocesses.basque.md)
+
+
+
+## ![✔] 6.20. Ezkutatu bezeroari erroreen xehetasunak
+
+
+
+**TL;PL:** errore integratuen kudeatzaile lasterrek lehenespenez ezkutatzen dituzte erroreen xehetasunak. Haatik, aukera handia dago inplementa dezan errore pertsonalizatuak dituzten objektuak kudeatzeko berak daukan logika (batzuen ustez praktika ona dena). Hala eginez gero, ziurtatu bezeroari errorearen objektu osoa ez itzultzea, horrek aplikazioen datu sentikorrak izan litzake eta
+
+**Bestela:** aplikazioaren xehetasun sentikorrak —hala nola, zerbitzariko fitxategien bideak, erabiltzen ari diren hirugarrenen moduluak eta erasotzaile batek balia ditzakeen aplikazioaren barneko beste lan fluxuak— atera daitezke pila aztarna batean aurkitutako informazioetatik
+
+🔗 [**Informazio gehiago: ezkutatu bezeroari erroreen xehetasunak**](./sections/security/hideerrors.basque.md)
+
+
+
+## ![✔] 6.21. Konfiguratu 2FA npm edo Yarn-entzat
+
+
+
+**TL;PL:** garapen katearen edozein urrats MFArekin (faktore anitzeko autentifikazioarekin) babestu behar da. Iza ere, npm / Yarn aukera paregabea da garatzaile batzuen pasahitza eskuratu nahi duten erasotzaileentzat. Garatzaileen egiaztagiriak erabiliz, erasotzaileek kode gaiztoa txerta dezakete proiektu eta zerbitzuetan instalatuta dauden liburutegietan, eta, agian, sarean bertan ere, jendaurrean argitarauta badago. npm-n autentifikazioa 2 faktore bidez egin beharra ezartzeak ia zero aukera uzten die erasotzaileei zure pakete kodea aldatzeko
+
+**Bestela:** [ba al duzu pasahitza bahitu zuten eslint garatzailearen berri?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
+
+
+
+## ![✔] 6.22. Aldatu saioko middlewarearen ezarpenak
+
+
+
+**TL;PL:** web esparru eta teknologia bakoitzak bere ahulguneak ditu: erasotzaileei esatea zein web esparru erabiltzen dugun laguntza handia da haientzat. Saioaren middlewareen ezarpen lehenetsiak erabiltzeak eragin dezake zure moduluko eta esparruko berariazko bahiketa erasoak izatea zure aplikazioak, `X-Powered-By` izenburukoaren antzekoak. Saiatu ezkutatzen zure pila teknologkoa identifikatzen eta agerian uzten duen edozein gauza (adibidez, Node.js, express)
+
+**Bestela:** cookieak segurtasunik gabeko konexioen bidez bidal litezke, eta erasotzaile batek saioaren identifikazioa erabil lezake web aplikazioaren barruko esparrua eta moduluen berariazko ahultasunak ere identifikatzeko
+
+🔗 [**Informazio gehiago: cookieak eta saioaren segurtasuna**](./sections/security/sessions.basque.md)
+
+
+
+## ![✔] 6.23. Saihestu DOS erasoak prozesuak noiz huts egin behar duen berariaz ezarriz
+
+
+
+**TL;PL:** Node prozesuak huts egingo du akatsak kudeatzen ez direnean. Praktika onetako askok irtetea gomendatzen dute, akats bat atzeman eta kudeatuta badago ere. Expressek, adibidez, huts egiten du errore asinkronoren bat izanez gero –blokeatze klausula batekin ibilbideak biltzen ez badituzu behintzat. Horrek oso eraso bide aproposa irekitzen die erasotzaileei, zer informaziok eragiten duen prozesuaren blokeoa jakinda, behin eta berriz eskaera bera bidaltzen baitute prozesua blokeatzea lortu arte. Horretarako ez dago berehalako erremediorik, baina teknika batzuek mina arindu dezakete: abisatu zorroztasun kritikoarekin, kontrolatu gabeko errore baten ondorioz prozesuak huts egiten duen bakoitzean, balioztatu sarrera eta saihestu prozesua blokeatuta gelditzea erabiltzailearen sarrera baliogabea delako, bildu ibilbide guztiak cacth batekin eta kontuan hartu prozesuak ez duela huts egin behar eskaera batean errore bat sortzen denean (oro har, gertatzen denaren kontra)
+
+**Bestela:** hau uste oneko suposizio soil bat besterik ez da. Node.js aplikazio asko edukiz gero, JSON gorputz huts bat POST eskaera guztietara pasatzen saiatzen bagara, zenbait aplikazio blokeatu egingo dira. Une horretan, eskaera bera berbidal dezakegu, aplikazioak erraz ezabatzeko
+
+
+
+## ![✔] 6.24. Saihestu birbideratze ez seguruak
+
+
+
+**TL;PL:** erabiltzaileen sarrerak balioztatzen ez dituzten birbideratzeek ahalbidetzen dute erasotzaileek phishing iruzurrak abiatzea, erabiltzaileen egiaztagiriak lapurtzea eta beste ekintza kaltegarri batzuk burutzea
+
+**Bestela:** erasotzailea ohartzen bada erabiltzaileek emandako kanpo sarrerarik ez dela balioztatzen, ahultasun hori balia dezake foroetan, sare sozialetan eta beste toki publiko batzuetan hartarako bereziki sortutako estekak argitaratzean, erabiltzaileek bertan klik egin dezaten
+
+🔗 [**Informazio gehiago: saihestu birbideratze ez seguruak**](./sections/security/saferedirects.basque.md)
+
+
+
+## ![✔] 6.25. Saihestu sekretuak npm erregistroan argitaratzea
+
+
+
+**TL;PL:** neurriak hartu behar dira npm erregistro publikoetan sekretuak nahi gabe argitaratzeko arriskua ekiditeko. Erabil daiteke `.npmignore` fitxategi bat karpeta edo fitxategi espezikoak zerrenda beltz batean jartzeko eta `files` matrizea `package.json` artxiboarekin erabil daiteke zerrenda zuri moduan lan egin dezan
+
+**Bestela:** arriskua dago norbaitek zure proiektuaren API giltzak, pasahitzak edo beste sekretu batzuk aurkitu eta erasoak egiten saiatzeko, eta horrek galera ekonomikoak, nortasun arazoak eta bestelako arriskuak sor ditzake
+
+🔗 [**Informazio gehiago: saihestu sekretuak argitaratzea**](./sections/security/avoid_publishing_secrets.basque.md)
+
+
+# `7. Zirriborroa: errendimendua`
+
+## Gure laguntzaileak lanean ari dira atal honetan. [Parte hartu nahi zenuke?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
+
+
+
+## ![✔] 7.1. Ez blokeatu gertaeren begizta
+
+**TL;PL:** saihestu PUZen zeregin intentsiboak, gertaeren begizta blokeatuko baitute. Izan ere, gertaera horietako gehienak azpiprozesu bakarrekoak dira, eta deskargatuak izango baitira azpiprozesu dedikatu batean, prozesu batean edo teknologia desberdinetan, dauden testuinguruaren arabera
+
+**Bestela:** gertaeren begizta blokeatuta dagoenez, Node.jsk ezin izango du beste eskaera bat kudeatu eta, ondorioz, atzerapena eragin diezaieke erabiltzaileei. **3000 erabiltzaile erantzunaren zain daude, edukia zerbitzatzeko prest dago, baina eskaera bakar batek emaitzak berriro bidaltzea galarazten dio zerbitzariari**
+
+🔗 [**Informazio gehiago: ez blokeatu gertaeraren begizta**](./sections/performance/block-loop.basque.md)
+
+
+
+## ![✔] 7.2. Hobetsi jatorrizko JS metodoak Lodash bezalako erabiltzaileen baliabideak baino
+
+**TL;PL:** askotan zorrotzagoa da `lodash` eta `underscore` bezalako baliabide liburutegiak erabiltzea jatorrizko metodoak baino, beharrezkoak ez diren menpekotasunak eragin eta abiadura moteltzen baitu. Gogoan izan, V8 motor berria ES estandar berriekin batera, bertako metodoak hobetu egin zirela, eta gaur egun baliabide liburutegiak % 50 inguru eraginkorragoak direla liburutegi publikoak baino
+
+**Bestela:** errendimendu txikiagoko proiektuak mantendu beharko zenituzke, non **dagoeneko** eskura zenuena erabili beharko baitzenuke edo, fitxategi batzu gehiagoren truke, beste zenbait lerro landu
+
+🔗 [**Informazio gehiago: erabiltzaileen jatorrizko baliabideak**](./sections/performance/nativeoverutil.basque.md)
+
+
+
+# `8. Docker, praktika onak`
+
+🏅 Mila esker [Bret Fisher](https://github.com/BretFisher)-i, ondorengo praktika hauetako asko ikasi baikenituen berarengandik
+
+
+
+## ![✔] 8.1 Erabili etapa anitzeko konpilazioak Docker irudi sinpleagoak eta seguruagoak lortzeko
+
+**TL;PL:** erabili etapa anitzeko konpilazioak beharrezko produkzio objektuak soilik kopiatzeko. Konpilazio menpekotasun eta fitxategi asko ez dira beharrezkoak zure aplikazioa exekutatzeko. Etapa anitzeko konpilazioak erabiliz gero, baliabide horiek konpilazioan zehar erabil daitezke, denboraren exekuzio inguruneak beharrezko baliabideak besterik ez duen bitartean. Etapa anitzeko konpilazioak oso modu erraza dira gehiegizko pisua kendu eta segurtasun mehatxuak saihesteko
+
+**Bestela:** irudi handiagoek denbora gehiago beharko dute konpilatzeko eta zabaltzeko. Eraikitzeko soilik diren tresnek ahultasunak eduki ditzakete eta eraikitze faserako soilik gordetako sekretuak filtratu daitezke
+
+### Etapa anitzeko eraikuntzetarako Dockerfile fitxategiaren adibidea
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY . .
+RUN npm ci && npm run build
+
+
+FROM node:slim-14.4.0
+
+USER node
+EXPOSE 8080
+
+COPY --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/package-lock.json ./
+RUN npm ci --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+🔗 [**Informazio gehiago: erabili etapa anitzeko konpilazioak**](./sections/docker/multi_stage_builds.basque.md)
+
+
+
+## ![✔] 8.2. Abiarazi edukiontzia node komandoa erabiliz, saihestu npm
+
+**TL;PL:** erabili `CMD ['node','server.js']` aplikazioa abiarazteko, saihestu OS seinaleak kodera pasatzen ez dituzten npm scriptak erabiltzea. Horrek arazoak izatea ekiditen du bigarren mailako prozesuetan, seinaleak kudeatzean, itxiera seguruetan eta prozesu zonbietan
+
+**Bestela:** seinalerik pasatzen ez denean, zure kodeak ez du inoiz izango itzalaldien berri, eta, hori gabe, ez da behar bezala itxiko, unean uneko eskaerak eta / edo datuak galduz
+
+[**Informazio gehiago: abiarazi edukiontzia 'node' komandoa erabiliz, saihestu npm abiatzea**](./sections/docker/bootstrap-using-node.basque.md)
+
+
+
+## ![✔] 8.3. Utzi Dockeren egikaritze denborari erreplikatu eta jardueraren iraupena kudeatzen
+
+**TL;PL:** Dockerren exekuzio denboraren orkestratzailea erabiltzen duzunean (adibidez, Kubernetes), deitu Node.js prozesua zuzenean, prozesua errepikatzen duten bitarteko prozesuen kudeatzailerik edo koderik pertsonalizatu gabe (adibidez, PM2, Cluster modulua). Exekuzio denboraren plataformak datu kopuru eta ikusgarritasun handiena dauzka kokapenari buruzko erabakiak hartzeko: badaki zenbat prozesu behar diren, nola antolatu prozesuok eta zer egin huts eginez gero
+
+**Bestela:** edukiontziak huts egiten jarraituko du baliabide faltagatik, eta prozesuen kudeatzaileak behin eta berriro berrabiaraziko du, gelditu gabe. Kubernetes horretaz jabetuko balitz, beste toki zabal batera lekualda lezake
+
+🔗 [**Informazio gehiago: utzi Dockeren exekuzio denborari erreplikatu eta jardueraren iraupena kudeatzen**](./sections/docker/restart-and-replicate-processes.basque.md)
+
+
+
+## ![✔] 8.4. Erabili .dockerignore sekretuak filtratzea ekiditeko
+
+**TL;DR**: erabili `.dockerignore` fitxategia, fitxategi sekretu arruntak eta garapeneko objektuak iragazten ditu eta. Horrela, sekretuak irudira ez sartzea lor dezakezu. Eta onura gehigarri bat izango duzu: eraikitzeko denbora nabarmen murriztuko da. Gainera, ziurtatu fitxategi guztiak ez direla behin eta berriro kopiatzen eta berariaz aukeratu zer kopiatu behar den Dockerren
+
+**Bestela**: irudira sarbidea duen edonorekin partekatuko dira `.env`, `.aws` eta `.npmrc` bezalako fitxategi sekretu pertsonal arruntak (adibidez, Docker biltegia)
+
+🔗 [**Informazio gehiago: erabili .dockerignore**](./sections/docker/docker-ignore.basque.md)
+
+
+
+## ![✔] 8.5. Garbitu menpekotasunak ekoizpenaren aurretik
+
+**TL;PL:** nahiz eta dev-menpekotasunak (dev-dependencies) batzuetan eraikuntza eta probako bizitza zikloan zehar beharrezkoak izan, azkenean ekoizpenera bidaltzen den irudiak ahalik eta txikiena izan behar du eta ez du garapeneko menpekotasunik eduki behar. Hori eginez gero, beharrezko kodea soilik bidaliko dela eta balizko erasoen kopurua (hau da, erasoaren azalera) minimizatuko dela bermatzen da, eta, hori lor daiteke menpekotasun guztiak lehenik instalatuz eta azkenean `npm ci --production` exekutatuz, beti ere etapa anitzeko eraikuntza erabiltzen denean (ikusi buleta dedikatua)
+
+**Bestela:** npm segurtasun arau hauste ezagun asko garapen paketeen barruan aurkitu izan dira (adibidez, [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes))
+
+🔗 Informazio gehiago: [ezabatu garapen menpekotasunak](./sections/docker/install-for-production.basque.md)
+
+
+
+## ![✔] 8.6. Itzali arazorik gabe eta dotore
+
+**TL;PL:** kudeatu prozesuaren SIGTERM gertaera eta garbitu lehendik dauden konexio eta baliabide guztiak. Hori etengabeko eskaerei erantzutean egin behar da. Dockerized exekutatzen den bitartean edukiontziak ixtea ez da arraroa, baizik eta ohiko lanaren zati gisa maiz gertatzen den zerbait. Hori lortzeko ondo pentsatutako kodea prestatu beharra dago hainbat elementu koordinatuz: karga orekatzailea, mantentze konexioak, HTTP zerbitzaria eta beste baliabide batzuk
+
+**Bestela:** berehala hiltzeak etsita dauden milaka erabiltzaileri ez erantzutea ekarriko du
+
+🔗 [**Informazio gehiago: itzalaldi dotorea**](./sections/docker/graceful-shutdown.basque.md)
+
+
+
+## ![✔] 8.7. Ezarri memoria mugak Docker eta v8 erabiliz
+
+**TL;PL:** konfiguratu beti memoria muga bai Docker bai JavaScript exekuzio adierazgailak erabiliz. Dockerren muga beharrezkoa da edukiontzien kokapena erabakitzeko; --v8ren bandera max-old-space beharrezkoa da GC garaiz abiarazteko eta memoria erabiltzea saihesteko. Praktikan, ezarri v8rren espazio memoria zaharra edukiontziaren muga baino apur bat txikiagoa izan dadin
+
+**Bestela:** Dockerren definizioa beharrezkoa da eskalatutako erabakiak burutzeko eta beste herritarrak gosez hiltzea ekiditeko. V8rren mugak zehaztu gabe ere, edukiontziaren baliabideak erabiliko ditu. Argibide espliziturik gabe, baliabideen %50-60a erabiltzean huts egiten du
+
+🔗 [**Informazio gehiago: ezarri memoria mugak Docker erabiliz soilik**](./sections/docker/memory-limit.basque.md)
+
+
+
+## ![✔] 8.8. Baliatu cachea konpilazio denbora murrizteko
+
+**TL;PL:** Dockerren irudi osoa cache-tik berreraikitzea ia berehalakoa izan daiteke, zuzen eginez gero. Eguneratu ez diren argibideek Dockerfile fitxategiaren goialdean egon behar dute, eta etengabe aldatzen ari direnek (aplikazioaren kodea, esate baterako) beheko aldean egon behar dute
+
+**Bestela:** Docker eraikitzeak oso luze jo dezake eta baliabide asko kontsumituko ditu, nahiz eta aldaketa txikiak egin
+
+🔗 [**Informazio gehiago: baliatu cachea konpilazio denborak murrizteko**](./sections/docker/use-cache-for-shorter-build-time.basque.md)
+
+
+
+## ![✔] 8.9. Erabili irudiaren erreferentzia esplizitua, saihestu "azken" (`latest`) etiketa
+
+**TL;PL:** zehaztu irudi laburpen esplizitu bat edo etiketa baten bertsioa, inoiz ez aipatu `latest`. Garatzaileek sarritan uste izaten dute, `latest` adieraziz gero, biltegiko azken irudia eskuratuko dutela, baina ez da horrela. Laburpena erabiltzeak zerbitzuaren instantzia guztiek kode bera exekutatuko dutela bermatzen du
+
+Gainera, irudi etiketa bat aipatzen bada, oinarrizko irudia aldatu egin daiteke, ez baitago irudi etiketekin fidatzerik instalazio determinista bat egiteko orduan. Horren ordez, instalazioa determinista izanez gero, SHA256 laburpena erabil daiteke irudi zehatza erreferentziatzeko
+
+**Bestela:** oinarrizko irudi baten bertsio berri bat erabiliz gero, aldaketa handiak gerta litezke produkzioan, horrek aplikazioaren nahigabeko portaera sortuz
+
+🔗 [**Informazio gehiago: ulertu irudi etiketak eta erabili "azken" (`latest`) etiketa kontu handiz**](./sections/docker/image-tags.basque.md)
+
+
+
+## ![✔] 8.10. Hobetsi Docker oinarrizko irudi txikiagoak
+
+**TL;PL:** irudi handiek ahultasun gehiago izateko arriskua handitu eta baliabideen kontsumoa areagotzen dute. Docker irudi arinagoak erabiltzeak, Slim eta Alpine Linux aldaerak adibidez, arazo hori arindu egiten du
+
+**Bestela:** batetik, denbora gehiago beharko da irudiak eraiki, txertatu eta ateratzeko; bestetik, erabiltzaile maltzurrek eraso bektore ezezagunak erabil ditzakete; eta, azkenik, baliabide gehiago beharko dira
+
+🔗 [**Informazio gehiago: hobetsi irudi txikiagoak**](./sections/docker/smaller_base_images.basque.md)
+
+
+
+## ![✔] 8.11. Garbitu eraikitze faseko sekretuak, saihestu sekretuak argudioetan
+
+**TL;PL:** saihestu Dockerren konpilazio inguruneko sekretuak agerian geratzea. Docker irudi bat IE bezalako ingurune anitzetan eta ekoizpena bezain garbituta ez dauden erregistroetan partekatzen da normalean. Adibide tipikoa npm giltza (tokena) da, normalean dockerfile fitxategi batera pasatzen dena argumentu gisa. Giltza hori irudiaren barruan geratzen da denbora luzez beharrezkoa izateari utzi ondoren ere, eta erasotzaileari npm erregistro pribatura sartzeko aukera ematen dio. Hori ekidin daiteke sekretua `.npmrc` bezalako fitxategi batean kopiatuz, eta, ondoren, sekretu hori kenduz etapa anitzeko eraikuntza bat erabiliz (kontuz, eraikitze historia ere ezabatu beharko litzateke) edo bat ere aztarnarik uzten dituen Docker build-kit funtzio sekretua erabiliz
+
+**Bestela:** IE eta docker erregistroan sartzeko aukera duten guztiek erakundearen sekretu preziatuak ere eskuratzeko aukera izango dute onura gehigarri gisa
+
+🔗 [**Informazio gehiago: garbitu eraikitze faseko sekretuak**](./sections/docker/avoid-build-time-secrets.basque.md)
+
+
+
+## ![✔] 8.12. Eskaneatu ahultasun geruza anitzeko irudiak
+
+**TL;PL:** kode menpekotasunen ahultasunak egiaztatzeaz gain, eskaneatu ekoizpenera bidalitako azken irudia ere. Dockerren irudien eskanerrek kodeen menpekotasunak egiaztatzen dituzte, baina baita sistema eragilearen binarioak ere. E2E segurtasun eskaneatze horrek eremu handiago bat hartzen du eta egiaztatzen du inongo erabiltzaile maltzurrak ez duela maltzurkeriatik egin eraikitze aldian zerbait injektatuz. Ondorioz, hau exekutatzea gomendatzen da hedapenaren aurreko azken urrats gisa. Mordoska bat eskaner doako eta komertzial dago CI / CD pluginak ere eskaintzen dituztenak
+
+**Bestela:** baliteke zure kodeak ahultasunik ez izatea. Hala ere, baliteke oraindik ere hackeatua izatea, aplikazioek normalean erabiltzen dituzten sistema eragilearen mailako binarioen bertsioak ahultasunak dituelako (adibidez, OpenSSL, TarBall)
+
+🔗 [**Informazio gehiago: Docker praktika arruntak**](./sections/docker/scan-images.basque.md)
+
+
+
+## ![✔] 8.13 Garbitu NODE_MODULE cachea
+
+**TL;PL:** menpekotasunak edukiontzi batean instalatu ondoren, kendu bertako cachea. Ez du inolako zentzurik etorkizuneko instalazio azkarragoetarako menpekotasunak bikoizteak, ez baita beste instalaziorik egingo: Dockeren irudiak aldaezinak dira. Kode lerro bakarra erabiliz dozenaka MB aurrezten dira (normalean, irudiaren tamainaren % 10-50)
+
+**Bestela:** ekoizpenera bidaliko den irudiak % 30 gehiago pisatuko du, inoiz erabiliko ez diren fitxategiak direla eta
+
+🔗 [**Informazio gehiago: garbitu NODE_MODULE cachea**](./sections/docker/clean-cache.basque.md)
+
+
+
+## ![✔] 8.14. Dockeren praktika generikoak
+
+**TL;PL:** hemen duzu Node.jsrekin zuzenean loturarik ez duen Docker aholkuen bilduma. Ez dago alderik Noderen eta beste edozein lengoaiaren inplementazioen artean. Egin klik “Informazio gehiago” botoian
+
+🔗 [**Informazio gehiago: Dockeren praktika generikoak**](./sections/docker/generic-tips.basque.md)
+
+
+
+## ![✔] 8.15. Garbitu zure Dockerfile fitxategia Linterra erabiliz
+
+**TL;PL:** Linterra erabiliz zure Dockerfile fitxategia garbitzea urrats garrantzitsua da haren barruan praktika onak errespetatzen ez dituzten arazoak identifikatzeko. Docker garbitzaile (linter) espezializatu bat erabiliz errendimendu eta segurtasun hobekuntzak erraz atzematen dira, alferrikako ordu ugari aurreztea edo produkzio kodean segurtasun arazoak murriztea lortuz
+
+**Bestela:** okerrez, Dockerfile fitxategiaren sortzaileak nagusi (root) bat utzi zuen produkzio erabiltzaile moduan, eta jatorri ezezaguneko biltegi irudi bat ere erabili zuen. Hori liner soil batekin ekidin liteke.
+
+🔗 [**Informazio gehiago: garbitu zure Dockerfile fitxategia**](./sections/docker/lint-dockerfile.basque.md)
+
+
+
+# Mugarriak
+
+Gida hau mantentzeko eta eguneratuta egoteko, jarraibideak eta praktika onak eguneratzen eta hobetzen ari gara etengabe komunitatearen laguntzarekin. Proiektu honetan lagundu nahi baduzu, jarraitu gure [mugarriak](https://github.com/goldbergyoni/nodebestpractices/milestones) jarrai sartu lantaldeetan
+
+
+
+## Itzulpenak
+
+Komunitatearen ekarpena dira hemengo itzulpen guztiak eman. Oso pozik hartuko genituzke zure itzulpenak, bai dagoeneko eginda dauden testuenak zein egiten ari garen eta egingo ditugunenak
+
+### Amaitutako itzulpenak
+
+-  [Brasilgo portugalera](./README.brazilian-portuguese.md) - [Marcelo Melo](https://github.com/marcelosdm)-ren eskutik
+-  [Txinera](./README.chinese.md) - [Matt Jin](https://github.com/mattjin)-ren eskutik
+-  [Errusiera](./README.russian.md) - [Alex Ivanov](https://github.com/contributorpw)-ren eskutik
+-  [Poloniera](./README.polish.md) - [Michal Biesiada](https://github.com/mbiesiad)-ren eskutik
+-  [Euskara](README.basque.md) - [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuestaren eskutik
+
+### Aribidean dauden itzulpenak
+
+-  [Frantsesa](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Eztabaidan](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  Hebrearra ([Eztabaidan](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Koreera](README.korean.md) - [Sangbeom Han](https://github.com/uronly14me)-ren eskutik ([Eztabaidan](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Gaztelera](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Eztabaidan](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turkiera ([Eztabaidan](https://github.com/goldbergyoni/nodebestpractices/issues/139))
+
+
+
+## Zuzendaritza Batzordea
+
+Ezagutu Zuzendaritza Batzordeko kideak, proiektuaren orientazioa eta etorkizunerako jarraibideak emateko elkarlanean dirautenak. Gainera, batzordeko kide bakoitza gure [Github projects](https://github.com/goldbergyoni/nodebestpractices/projects)-pean dagoen proiektu baten buru da
+
+
+
+[Yoni Goldberg](https://github.com/goldbergyoni)
+
+
+
+EEBB-etan, Europan eta Israelen, bezeroekin tamaina handiko Node.js aplikazioen sorkuntzan lan egiten duen Node.jsren inguruko aholkulari independentea. Gida honetako praktika on asko lehenengo aldiz [goldbergyoni.com](https://goldbergyoni.com)-en argitaratuak izan ziren. Jar zaitez Yoni-rekin kontatuan [@goldbergyoni](https://github.com/goldbergyoni)-en edo [me@goldbergyoni.com](mailto:me@goldbergyoni.com) helbidearen bidez
+
+
+
+
+
+[Bruno Scheufler](https://github.com/BrunoScheufler)
+
+
+💻 full-stack web ingeniaria, Node.js eta GraphQL zalea
+
+
+
+
+
+[Kyle Martin](https://github.com/js-kyle)
+
+
+
+Full Stack Garatzailea eta Zelanda Berrian lan egiten duen Site Reliability Ingeniaria, web aplikazioen segurtasutasunean eta egituraketan, eta tamaina handiko Node.js aplikazioen sorkuntzan interesa du
+
+
+
+
+
+[Kevyn Bruyere](https://github.com/kevynb)
+
+
+Full-stack garatzaile independentea, Ops eta automatizazioan zaletua dena
+
+
+
+### Steering Committee Emeriti
+
+
+
+[Sagir Khan](https://github.com/sagirk)
+
+
+
+
+Javascripten eta bere ekosisteman (React, Node.js, TypeScript, GraphQL, MongoDB, eta sistemako JS/JSON edozein geruzatan eragin dezakeen edozer) aditua, munduko marka ezagunenetarako produktuak sortzen ditu web plataforma erabiliaz. Node.js Fundazioko Banakako Kidea
+
+
+
+## Languntzaileak
+
+Mila esker gure laguntzaile guztiei! 🙏
+
+Gure kolaboratzaileak proiektuan maiz parte hartzen duten kideak dira, praktika onak proposatuz, gaien zerrenda ordenatuz, parte hartze eskaerak (pull request) aztertuz... Milaka pertsona Node.js aplikazioak hobeto sortzen laguntzen interesa baduzu, irakur ezazu gure [kolaboratzaile gida](./.operations/CONTRIBUTING.md) 🎉
+
+| | |
+| :---------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
+| [Ido Richter (Fundatzailea)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
+
+### Emeriti Kolaboratzailea
+
+| |
+| :-------------------------------------------------------------------------------------------------------------------------: |
+| [Refael Ackermann](https://github.com/refack) |
+
+
+
+## Parte hartu
+
+Open sourcen parte hartu nahi baduzu, hemen duzu aukera! Gehiago jakiteko, irakurri [parte hartu dokumentua](.operations/CONTRIBUTING.md)
+
+## Parte hartzaileak ✨
+
+Eskerrik asko proiektu honetan parte hartu duten pertsona zoragarriei!
+
+
+
+
+
-[](https://twitter.com/nodepractices/) **Siga-nos no Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
+[](https://twitter.com/nodepractices/) **Siga-nos no Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
-Leia em diferentes idiomas: [**CN**](/README.chinese.md), [**BR**](/README.brazilian-portuguese.md) [(**ES**, **FR**, **HE**, **KR**, **RU** e **TR** em progresso!)](#translations)
+Leia em diferentes idiomas: [**CN**](./README.chinese.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**PL**](./README.polish.md), [**JA**](./README.japanese.md), [**EU**](./README.basque.md) [(**ES**, **FR**, **HE**, **KR** and **TR** em progresso! )](#translations)
@@ -28,17 +28,19 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
- **Nova Boa Prática:** 4.4: [Evite dados fixos e sementes para teste, adicione os dados no teste](#4-práticas-de-testes-e-qualidade-geral)
-- **Nova Boa Prática:** 6.25: [Evite publicar segredos no registro do npm](/sections/security/avoid_publishing_secrets.brazilian-portuguese.md)
+- **Nova Boa Prática:** 6.25: [Evite publicar segredos no registro do npm](./sections/security/avoid_publishing_secrets.brazilian-portuguese.md)
-- **Nova tradução:**  [Português Brasileiro](/README.brazilian-portuguese.md) disponível agora, cortesia de [Marcelo Melo](https://github.com/marcelosdm)! ❤️
+- **Nova tradução:**  [Português Brasileiro](./README.brazilian-portuguese.md) disponível agora, cortesia de [Marcelo Melo](https://github.com/marcelosdm)! ❤️
+
+- **🎊 60,000 estrelas!**: Nosso repo recebeu estrela e a confiança de 60.100 desenvolvedores. Estamos sem palavras
-# Bem-vindo! 3 Coisas Que Você Precisa Saber:
+# Bem-vindo! 3 Coisas Que Você Precisa Saber
**1. Quando você lê aqui, na verdade você lê alguns dos melhores artigos de Node.js -** este é um resumo e curadoria dos mais bem ranqueados conteúdos sobre as melhores práticas do Node.js.
-**2. Esta é a maior coletânea, e está crescendo mais a cada semana -** atualmente, são apresentadas mais de 80 melhores práticas, guias de estilo e dicas de arquitetura. Novas issues e PR são criadas diariamente para manter este livro vivo atualizado. Gostaríamos muito de ver você contribuindo aqui, seja corrigindo algum erro de código ou sugerindo novas e brilhantes ideias. Veja nossas [conquistas aqui](https://github.com/i0natan/nodebestpractices/milestones?direction=asc&sort=due_date&state=open).
+**2. Esta é a maior coletânea, e está crescendo mais a cada semana -** atualmente, são apresentadas mais de 80 melhores práticas, guias de estilo e dicas de arquitetura. Novas issues e PR são criadas diariamente para manter este livro vivo atualizado. Gostaríamos muito de ver você contribuindo aqui, seja corrigindo algum erro de código ou sugerindo novas e brilhantes ideias. Veja nossas [conquistas aqui](https://github.com/goldbergyoni/nodebestpractices/milestones?direction=asc&sort=due_date&state=open).
**3. A maioria dos tópicos possuem informações adicionais -** perto dos tópicos das melhores práticas, você encontrará o link **🔗Leia Mais** que irá apresentar exemplos de códigos, citações de blogs selecionados e mais informações.
@@ -46,13 +48,13 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
## Índice
-1. [Práticas de Estrutura de Projeto (5)](#1-práticas-de-estrutura-de-projeto)
-2. [Práticas de Tratamento de Erros (11) ](#2-práticas-de-tratamento-de-erros)
-3. [Práticas de Estilo de Código (12) ](#3-práticas-de-estilo-de-código)
-4. [Práticas de Testes e Qualidade Geral (11) ](#4-práticas-de-testes-e-qualidade-geral)
-5. [Práticas de Produção (18) ](#5-boas-práticas-de-produção)
-6. [Práticas de Segurança (25)](#6-boas-práticas-em-segurança)
-7. [Práticas de Performance (1) (Em Progresso ✍️)](#7-boas-práticas-em-performance)
+1. [Práticas de Estrutura de Projeto (5)](#1-práticas-de-estrutura-de-projeto)
+2. [Práticas de Tratamento de Erros (12) ](#2-práticas-de-tratamento-de-erros)
+3. [Práticas de Estilo de Código (13) ](#3-práticas-de-estilo-de-código)
+4. [Práticas de Testes e Qualidade Geral (13) ](#4-práticas-de-testes-e-qualidade-geral)
+5. [Práticas de Produção (19) ](#5-boas-práticas-de-produção)
+6. [Práticas de Segurança (25)](#6-boas-práticas-em-segurança)
+7. [Práticas de Performance (1) (Em Progresso ✍️)](#7-boas-práticas-em-performance)
@@ -60,11 +62,11 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
## ![✔] 1.1 Estruture sua solução por componentes
-**TL;DR:** A pior armadilha das grandes aplicações é manter uma enorme base de código com centenas de dependências - tal qual as monolíticas, que diminuem a velocidade dos desenvolvedores conforme eles tentam incorporar novos recursos. Em vez disso, particione seu código em componentes, cada um com sua própria pasta ou uma base de código dedicada, e garanta cada unidade seja mantida pequena e simples. Veja o link ‘Leia Mais’ abaixo, para ver exemplos de estrutura correta de projeto.
+**TL;DR:** A pior armadilha das grandes aplicações é manter uma enorme base de código com centenas de dependências - tal qual as monolíticas, que diminuem a velocidade dos desenvolvedores conforme eles tentam incorporar novos recursos. Em vez disso, particione seu código em componentes, cada um com sua própria pasta ou uma base de código dedicada, e garanta que cada unidade seja mantida pequena e simples. Veja o link ‘Leia Mais’ abaixo, para ver exemplos de estrutura correta de projeto.
**Caso contrário:** Quando desenvolvendo novos recursos, desenvolvedores têm dificuldade para perceber o impacto de suas modificações e temem estragar outros componentes dependentes - deploys se tornam mais lentos e arriscados. Também é considerado mais difícil de escalar quando nenhuma unidade de negócio está separada.
-🔗 [**Leia mais: estruture por componentes**](/sections/projectstructre/breakintcomponents.brazilian-portuguese.md)
+🔗 [**Leia mais: estruture por componentes**](./sections/projectstructre/breakintcomponents.brazilian-portuguese.md)
@@ -74,7 +76,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Uma aplicação que misture objetos WEB com outras camadas não podem ser acessadas por códigos de teste, CRON jobs e outras chamadas não oriundas do Express.
-🔗 [**Leia Mais: seu app em camadas**](/sections/projectstructre/createlayers.brazilian-portuguese.md)
+🔗 [**Leia Mais: seu app em camadas**](./sections/projectstructre/createlayers.brazilian-portuguese.md)
@@ -84,7 +86,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Você deverá criar seu próprio ciclo de implantação e dependência.
-🔗 [**Leia Mais: estrutura por característica**](/sections/projectstructre/wraputilities.brazilian-portuguese.md)
+🔗 [**Leia Mais: estrutura por característica**](./sections/projectstructre/wraputilities.brazilian-portuguese.md)
@@ -94,17 +96,17 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Sua API será acessível apenas para testes via chamadas HTTP (mais lentos e muito mais difíceis de gerar relatórios de cobertura). Provavelmente não será um grande prazer manter centenas de linhas de código em um único arquivo.
-🔗 [**Leia Mais: separe 'app' e 'server' no Express**](/sections/projectstructre/separateexpress.brazilian-portuguese.md)
+🔗 [**Leia Mais: separe 'app' e 'server' no Express**](./sections/projectstructre/separateexpress.brazilian-portuguese.md)
## ![✔] 1.5 Use configuração consciente, segura e hierárquica do ambiente
-**TL;DR:** Uma definição de configuração perfeita e impecável deve garantir que (a) as chaves possam ser lidas a partir do arquivo E TAMBÉM da variável de ambiente (b) os segredos sejam mantidos fora do código consolidado (c) a configuração é hierárquica para facilitar a localização. Existem alguns pacotes que podem auxiliar na checagem destes tópicos, como [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) e [config](https://www.npmjs.com/package/config)
+**TL;DR:** Uma definição de configuração perfeita e impecável deve garantir que (a) as chaves possam ser lidas a partir do arquivo E TAMBÉM da variável de ambiente (b) os segredos sejam mantidos fora do código consolidado (c) a configuração é hierárquica para facilitar a localização. Existem alguns pacotes que podem auxiliar na checagem destes tópicos, como [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) e [convict](https://www.npmjs.com/package/convict)
**Caso contrário:** Deixar de satisfazer qualquer um dos requisitos de configuração simplesmente atrapalhará a equipe de desenvolvimento ou devops. Provavelmente ambas.
-🔗 [**Leia Mais: melhores práticas de configuração**](/sections/projectstructre/configguide.brazilian-portuguese.md)
+🔗 [**Leia Mais: melhores práticas de configuração**](./sections/projectstructre/configguide.brazilian-portuguese.md)
@@ -118,7 +120,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** O estilo de callback do Node.js, function(err, response), é um caminho promissor para um código insustentável devido à combinação de manipulação de erro com código casual, aninhamento excessivo e padrões de codificação inadequados.
-🔗 [**Leia Mais: evitando callbacks**](/sections/errorhandling/asyncerrorhandling.brazilian-portuguese.md)
+🔗 [**Leia Mais: evitando callbacks**](./sections/errorhandling/asyncerrorhandling.brazilian-portuguese.md)
@@ -128,7 +130,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Ao invocar algum componente, sendo incerto qual tipo de erro irá retornar - isso faz com que o tratamento de erros seja muito mais difícil. Até pior, usar tipos personalizados para descrever erros pode levar à perda de informações de erros críticos, como o stack trace!
-🔗 [**Leia Mais: usando o objeto interno de erro**](/sections/errorhandling/useonlythebuiltinerror.brazilian-portuguese.md)
+🔗 [**Leia Mais: usando o objeto interno de erro**](./sections/errorhandling/useonlythebuiltinerror.brazilian-portuguese.md)
@@ -138,7 +140,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Você pode sempre reiniciar o aplicativo quando um erro aparecer, mas por que derrubar aproximadamente 5000 usuários que estavam online por causa de um pequeno erro operacional previsto? O contrário também não é ideal - manter a aplicação rodando quando um problema desconhecido (erro de programação) ocorreu, pode levar para um comportamento não esperado. Diferenciá-los, permite agir com tato e aplicar uma abordagem equilibrada baseada no dado contexto.
-🔗 [**Leia Mais: erros operacionais vs erros de programação**](/sections/errorhandling/operationalvsprogrammererror.brazilian-portuguese.md)
+🔗 [**Leia Mais: erros operacionais vs erros de programação**](./sections/errorhandling/operationalvsprogrammererror.brazilian-portuguese.md)
@@ -148,7 +150,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Não tratar os erros em um mesmo lugar irá levar à duplicidade de código, e provavelmente, a erros tratados incorretamente.
-🔗 [**Leia Mais: tratando erros de forma centralizada**](/sections/errorhandling/centralizedhandling.brazilian-portuguese.md)
+🔗 [**Leia Mais: tratando erros de forma centralizada**](./sections/errorhandling/centralizedhandling.brazilian-portuguese.md)
@@ -158,27 +160,27 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Um cliente de uma API pode decidir travar e reiniciar, apenas pelo motivo de ter recebido de volta um erro que não conseguiu entender. Nota: o visitante de sua API pode ser você (muito comum em um ambiente de microsserviço).
-🔗 [**Leia Mais: documentando erros de API no Swagger ou GraphQL**](/sections/errorhandling/documentingusingswagger.brazilian-portuguese.md)
+🔗 [**Leia Mais: documentando erros de API no Swagger ou GraphQL**](./sections/errorhandling/documentingusingswagger.brazilian-portuguese.md)
## ![✔] 2.6 Finalize o processo quando um estranho chegar
-**TL;DR:** Quando ocorre um erro desconhecido (um erro de programação, veja a melhor prática #3) - há incerteza sobre a integridade da aplicação. Uma prática comum sugere reiniciar cuidadosamente o processo utilizando uma ferramenta de “reinicialização” como Forever e PM2.
+**TL;DR:** Quando ocorre um erro desconhecido (um erro de programação, veja a melhor prática #3) - há incerteza sobre a integridade da aplicação. Uma prática comum sugere reiniciar cuidadosamente o processo utilizando uma ferramenta de “reinicialização” como [Forever](https://www.npmjs.com/package/forever) e [PM2](http://pm2.keymetrics.io/).
**Caso contrário:** Quando uma exceção desconhecida é lançada, algum objeto pode estar com defeito (por exemplo, um emissor de evento que é usado globalmente e não dispara mais eventos devido a alguma falha interna) e todas as requisições futuras podem falhar ou se comportar loucamente.
-🔗 [**Leia Mais: finalizando o processo**](/sections/errorhandling/shuttingtheprocess.brazilian-portuguese.md)
+🔗 [**Leia Mais: finalizando o processo**](./sections/errorhandling/shuttingtheprocess.brazilian-portuguese.md)
## ![✔] 2.7 Use um agente de log maduro para aumentar a visibilidade de erros
-**TL;DR:** Um conjunto de ferramentas de registro maduras como Winston, Bunyan ou Log4j, irão acelerar a descoberta e entendimento de erros. Portanto, esqueça o console.log.
+**TL;DR:** Um conjunto de ferramentas de registro maduras como [Pino](https://www.npmjs.com/package/pino), [Winston](https://www.npmjs.com/package/winston), [Bunyan](https://www.npmjs.com/package/bunyan) ou [Log4js](https://www.npmjs.com/package/log4js), irão acelerar a descoberta e entendimento de erros. Portanto, esqueça o console.log.
**Caso contrário:** Ficar procurando através de console.logs ou manualmente em arquivos de texto confusos sem utilizar ferramentas de consulta ou um visualizador de log decente, pode mantê-lo ocupado até tarde.
-🔗 [**Leia Mais: usando um logger maduro**](/sections/errorhandling/usematurelogger.brazilian-portuguese.md)
+🔗 [**Leia Mais: usando um logger maduro**](./sections/errorhandling/usematurelogger.brazilian-portuguese.md)
@@ -188,7 +190,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Sem testes, seja automático ou manual, não podemos confiar em nosso código para retornar os erros certos. Sem erros significantes, não há tratamento de erros.
-🔗 [**Leia Mais: fluxos de testes de erros**](/sections/errorhandling/testingerrorflows.brazilian-portuguese.md)
+🔗 [**Leia Mais: fluxos de testes de erros**](./sections/errorhandling/testingerrorflows.brazilian-portuguese.md)
@@ -198,7 +200,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Você pode gastar muito esforço medindo o desempenho e os tempos de inatividade (downtime) da API. Provavelmente, você nunca saberá quais são suas partes de código mais lentas no cenário real e como elas afetam o UX.
-🔗 [**Leia Mais: usando APM**](/sections/errorhandling/apmproducts.brazilian-portuguese.md)
+🔗 [**Leia Mais: usando APM**](./sections/errorhandling/apmproducts.brazilian-portuguese.md)
@@ -208,7 +210,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Seus erros serão engolidos e não vão deixar rastros. Nada para se preocupar.
-🔗 [**Leia Mais: capturando rejeições de promises não tratadas**](/sections/errorhandling/catchunhandledpromiserejection.brazilian-portuguese.md)
+🔗 [**Leia Mais: capturando rejeições de promises não tratadas**](./sections/errorhandling/catchunhandledpromiserejection.brazilian-portuguese.md)
@@ -218,7 +220,19 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Considere isto: sua função espera receber um “Desconto” como argumento numérico que foi esquecido de passar. Mais adiante, seu código verifica se Desconto!=0 (valor do desconto permitido é maior que zero). Depois, irá permitir que o usuário desfrute de um desconto. Meu Deus, que baita bug. Entendeu?
-🔗 [**Leia Mais: falhando rápido**](/sections/errorhandling/failfast.brazilian-portuguese.md)
+🔗 [**Leia Mais: falhando rápido**](./sections/errorhandling/failfast.brazilian-portuguese.md)
+
+
+
+## ![✔] 2.12 Sempre use 'await' antes de retornar as 'promises' para evitar um rastreamento parcial da pilha de erro
+
+**TL;DR:** Sempre use `return await` quando retornar uma 'promise' para beneficiar o rastreamento completo da pilha de erro. Se um função retorna uma 'promise', essa função deve ser declarada como função `async` e explicitamente `await` na `promise` antes de devolvê-la
+
+**Caso contrário:** Uma função que retorna uma `promise` sem o `await` não aparecerá na pilha de erro.
+A ausência dessas informações provavelmente complicariam a compreensão do fluxo que leva ao erro,
+especialmente se a causa do comportamento anormal estiver dentro da função ausente
+
+🔗 [**Leia Mais: retornando promises**](./sections/errorhandling/returningpromises.md)
@@ -232,7 +246,7 @@ Leia em diferentes idiomas: [**CN**](/README.chinese.
**Caso contrário:** Desenvolvedores irão focar nas preocupações tediosas de espaçamento e largura de linha e o tempo poderá ser desperdiçado pensando sobre o estilo de código do projeto.
-🔗 [**Leia Mais: Usando ESLint e Prettier**](/sections/codestylepractices/eslint_prettier.brazilian-portuguese.md)
+🔗 [**Leia Mais: Usando ESLint e Prettier**](./sections/codestylepractices/eslint_prettier.brazilian-portuguese.md)
@@ -275,9 +289,9 @@ Não importa se você usa ponto-e-vírgula ou não para separar suas declaraçõ
**TL;DR:** Use o ESLint para obter conhecimento sobre as preocupações de separação. [Prettier](https://prettier.io/) ou [Standardjs](https://standardjs.com/) podem resolver automaticamente esses problemas.
-**Otherwise:** Como visto na seção anterior, o interpretador do JavaScript adiciona automaticamente um ponto-e-vírgula ao final de uma instrução, se não houver uma, ou considera uma instrução como não terminada onde deveria, o que pode levar a alguns resultados indesejáveis. Você pode usar atribuições e evitar o uso de expressões de função chamadas imediatas para evitar a maioria dos erros inesperados.
+**Caso contrário:** Como visto na seção anterior, o interpretador do JavaScript adiciona automaticamente um ponto-e-vírgula ao final de uma instrução, se não houver uma, ou considera uma instrução como não terminada onde deveria, o que pode levar a alguns resultados indesejáveis. Você pode usar atribuições e evitar o uso de expressões de função chamadas imediatas para evitar a maioria dos erros inesperados.
-### Exemplo de Código
+### Exemplo de código
```javascript
// Faça
@@ -327,7 +341,7 @@ const count = 2 // tenta executar 2(), mas 2 não é uma função
**Caso contrário:** O JavaScript é a única linguagem no mundo que permite invocar um construtor (“Class”) diretamente sem instanciá-lo primeiro. Consequentemente, Classes e construtores de funções são diferenciados começando com UpperCamelCase
-### Exemplo de Código
+### 3.6 Exemplo de Código
```javascript
// para classes nós usamos UpperCamelCase
@@ -335,11 +349,11 @@ class SomeClassExample {}
// para nomes de constantes nós usamos a palavra const e lowerCamelCase
const config = {
- key: 'value'
+ key: "value",
};
// para nomes de variáveis e funções nós usamos lowerCamelCase
-let someVariableExample = 'value';
+let someVariableExample = "value";
function doSomething() {}
```
@@ -370,16 +384,16 @@ function doSomething() {}
**Caso contrário:** Alterar a estrutura interna dos arquivos ou a assinatura pode quebrar a interface com clientes.
-### Exemplo de Código
+### 3.9 Exemplo de Código
```javascript
// Do
-module.exports.SMSProvider = require('./SMSProvider');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver');
+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');
+module.exports.SMSProvider = require("./SMSProvider/SMSProvider.js");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver/SMSNumberResolver.js");
```
@@ -390,21 +404,21 @@ module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolve
**Caso contrário:** Variáveis diferentes podem retornar verdadeiro quando comparadas usando o operador `==`.
-### Exemplo de Código
+### 3.10 Exemplo de Código
```javascript
-'' == '0' // false
-0 == '' // true
-0 == '0' // true
+"" == "0"; // false
+0 == ""; // true
+0 == "0"; // true
-false == 'false' // false
-false == '0' // true
+false == "false"; // false
+false == "0"; // true
-false == undefined // false
-false == null // false
-null == undefined // true
+false == undefined; // false
+false == null; // false
+null == undefined; // true
-' \t\r\n ' == 0 // true
+" \t\r\n " == 0; // true
```
Todas as declarações acima false se feitas com `===`.
@@ -449,29 +463,39 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Uma implantação falhou, um teste chamado "Adicionar produto" falhou. Isso lhe diz exatamente o que está errado?
-🔗 [**Leia Mais: Inclua 3 partes em cada nome de teste**](/sections/testingandquality/3-parts-in-name.brazilian-portuguese.md)
+🔗 [**Leia Mais: Inclua 3 partes em cada nome de teste**](./sections/testingandquality/3-parts-in-name.brazilian-portuguese.md)
+
+
+
+## ![✔] 4.3 Estutura de testes padrão AAA
+
+**TL;DR:** Estruture seus testes com 3 seções bem separadas: Arrange, Act & Assert (AAA). A primeira parte inclui a configuração do teste, depois a execução do teste unitário, e finalmente, a fase de asserção. Seguir esta estrutura garante que o leitor não gaste nenhuma CPU cerebral para entender o plano de teste
+
+**Caso contrário:** Você não somente passará várias horas do dia para entender o código principal, mas agora também gastará várias horas no que deveria ter sido uma simples parte do dia (testando) esticando seu cérebro.
+
+🔗 [**Leia Mais: Estutura de testes padrão AAA**](./sections/testingandquality/aaa.md)
-## ![✔] 4.3 Detecte problemas de código com um linter
+## ![✔] 4.4 Detecte problemas de código com um linter
-**TL;DR:** Use um code linter para checar a qualidade básica e detectar antipadrões antecipadamente. Rode-o antes de qualquer teste e adicione-o como um pre-commit git-hook para minimizar o tempo necessário para revisar e corrigir qualquer problema. Veja também [Seção 3](https://github.com/i0natan/nodebestpractices#3-code-style-practices) no Prática de Estilo de Código.
+**TL;DR:** Use um code linter para checar a qualidade básica e detectar antipadrões antecipadamente. Rode-o antes de qualquer teste e adicione-o como um pre-commit git-hook para minimizar o tempo necessário para revisar e corrigir qualquer problema. Veja também [Seção 3](https://github.com/goldbergyoni/nodebestpractices#3-code-style-practices) no Prática de Estilo de Código.
**Caso contrário:** Você pode deixar passar algum antipadrão e possível código vulnerável para seu ambiente de produção.
-## ![✔] 4.4 Evite dados fixos e sementes para teste, adicione os dados no teste
+## ![✔] 4.5 Evite dados fixos e sementes para teste, adicione os dados no teste
**TL;DR:** Para evitar o acoplamento de testes e facilitar o entendimento do fluxo do teste, cada teste deve adicionar e atuar em seu próprio conjunto de linhas de banco de dados. Sempre que um teste precisar extrair ou assumir a existência de alguns dados do banco de dados - ele deve incluir explicitamente esses dados e evitar a mutação de outros registros
**Caso contrário:** Considere um cenário em que a implementação é abortada devido a falhas nos testes. Agora, a equipe gastará um tempo precioso de investigação que termina em uma triste conclusão: o sistema funciona bem, mas os testes interferem uns nos outros e quebram a compilação
-🔗 [**Leia Mais: Evite dados fixos para teste**](/sections/testingandquality/avoid-global-test-fixture.brazilian-portuguese.md)
+🔗 [**Leia Mais: Evite dados fixos para teste**](./sections/testingandquality/avoid-global-test-fixture.brazilian-portuguese.md)
-## ![✔] 4.5 Inspencione constantemente por dependências vulneráveis
+## ![✔] 4.6 Inspencione constantemente por dependências vulneráveis
**TL;DR:** Até mesmo as dependências mais confiáveis, como o Express, têm vulnerabilidades conhecidas. Isso pode ser facilmente contornado usando ferramentas comunitárias e comerciais como 🔗 [nsp](https://github.com/nodesecurity/nsp) que pode ser invocado a partir do seu CI em cada build.
@@ -479,7 +503,7 @@ Todas as declarações acima false se feitas com `===`.
-## ![✔] 4.6 Marque seus testes
+## ![✔] 4.7 Marque seus testes
**TL;DR:** Diferentes testes devem rodar em diferentes cenários: testes de rápidos, sem IO, devem ser executados quando um desenvolvedor salva ou faz commit em um arquivo, testes completos de ponta a ponta geralmente são executados quando uma nova solicitação de request é enviada, etc. Isso pode ser conseguido através da marcação de testes com palavras-chave como #cold #api #sanity. Assim você pode invocar o subconjunto desejado. Por exemplo, é desta forma que você invocaria apenas o grupo de sanity test usando o [Mocha](https://mochajs.org/): mocha --grep 'sanity'
@@ -487,7 +511,7 @@ Todas as declarações acima false se feitas com `===`.
-## ![✔] 4.7 Verifique a cobertura de seu teste, isso te ajuda a identificar padrões incorretos de teste
+## ![✔] 4.8 Verifique a cobertura de seu teste, isso te ajuda a identificar padrões incorretos de teste
**TL;DR:** Ferramentas de cobertura de código como [Istanbul](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc), são ótimas por 3 motivos: elas são gratuitas (nenhum esforço é necessário para beneficiar esses relatórios), elas ajuda a identificar diminuição na cobertura de testes, e por último mas não menos importante, ela destacam a incompatibilidade de testes: olhando relatórios coloridos de cobertura de código, você pode notar, por exemplo, áreas de código que nunca são testadas como cláusulas catch (o que significa que os testes só invocam os caminhos felizes e não como o aplicativo se comporta em erros). Configure-o para falhas se a cobertura estiver abaixo de um certo limite.
@@ -495,7 +519,7 @@ Todas as declarações acima false se feitas com `===`.
-## ![✔] 4.8 Inspecione pacotes desatualizados
+## ![✔] 4.9 Inspecione pacotes desatualizados
**TL;DR:** Use sua ferramenta preferida (por exemplo, 'npm outdated' ou [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) para detectar pacotes instalados que estão desatualizados, injetar essa verificação em seu pipeline de CI e até mesmo fazer uma falha grave em um cenário grave. Por exemplo, um cenário grave pode ser quando um pacote instalado esteja há 5 commits atrás (por exemplo, a versão local é 1.3.1 e a versão no repositório é 1.3.8) ou está marcada como descontinuada pelo autor - mate o build e impeça a implantação desta versão.
@@ -503,7 +527,7 @@ Todas as declarações acima false se feitas com `===`.
-## ![✔] 4.9 Use docker-compose para testes e2e
+## ![✔] 4.10 Use docker-compose para testes e2e
**TL;DR:** Teste de ponta a ponta (end to end, ou e2e), que inclui dados ativos, costumava ser o elo mais fraco do processo de CI, já que depende de vários serviços pesados como o banco de dados. O docker-compose deixa isso mamão com açúcar, criando um ambiente de produção usando um arquivo de texto simples e comandos fáceis. Isto permite criar todos os serviços dependentes, banco de dados e rede isolada para teste e2e. Por último mas não menos importante, ele pode manter um ambiente sem estado que é invocado antes de cada suíte de testes e é encerrado logo após.
@@ -511,23 +535,33 @@ Todas as declarações acima false se feitas com `===`.
-## ![✔] 4.10 Refatore regularmente usando ferramentas de análise estática
+## ![✔] 4.11 Refatore regularmente usando ferramentas de análise estática
**TL;DR:** O uso de ferramentas de análise estática ajuda fornecendo maneiras objetivas de melhorar a qualidade do código e manter seu código sustentável. Você pode adicionar ferramentas de análise estática para seu build de Integração Contínua (CI) falhar quando encontre code smells. Seus principais pontos de vantagem sobre o linting são a abilidade de inspecionar a qualidade no contexto de múltiplos arquivos (por exemplo, detectar duplicidades), realizar análises avançadas (por exemplo, complexidade de código), e acompanhar histórico e progresso de problemas de código. Dois dexemplos de ferramentas que podem ser utilizadas são [Sonarqube](https://www.sonarqube.org/) (mais de 2.600 [stars](https://github.com/SonarSource/sonarqube)) e [Code Climate](https://codeclimate.com/) (mais de 1.500 [stars](https://github.com/codeclimate/codeclimate)).
**Caso contrário:** Com qualidade de código ruim, bugs e desempenho sempre serão um problema que nenhuma nova biblioteca maravilhosa ou recursos de última geração podem corrigir.
-🔗 [**Leia Mais: Refatoração!**](/sections/testingandquality/refactoring.brazilian-portuguese.md)
+🔗 [**Leia Mais: Refatoração!**](./sections/testingandquality/refactoring.brazilian-portuguese.md)
-## ![✔] 4.11 Escolha cuidadosamente sua plataforma de Integração Contínua - CI (Jenkins vs CircleCI vs Travis vs Resto do mundo)
+## ![✔] 4.12 Escolha cuidadosamente sua plataforma de Integração Contínua - CI (Jenkins vs CircleCI vs Travis vs Resto do mundo)
**TL;DR:** Sua plataforma de integração contínua (CICD) irá hospedar todas as ferramentas de qualidade (por exemplo, teste, lint), então ela deve vir com um ecosistema de plugins arrebatador. O [Jenkins](https://jenkins.io/) costumava ser o padrão de muitos projetos, pois tem a maior comunidade, juntamente com uma poderosa plataforma, ao preço de configuração complexa que exige uma curva de aprendizado íngreme. Atualmente, ficou bem mais fácil para configurar uma solução de CI usando ferramentas SaaS como [CircleCI](https://circleci.com) e outras. Essas ferramentas permitem a criação de um pipeline de CI flexível sem o peso de gerenciar toda a infraestrutura. Eventualmente, é um perde e ganha entre robustez e velocidade - escolha seu lado com cuidado!
**Caso contrário:** Escolher algum fornecedor de nicho pode fazer com que você fique engessado quando precisar de alguma personalização avançada. Por outro lado, escolher o Jenkins pode ser uma perda de tempo precioso na configuração da infraestrutura.
-🔗 [**Leia Mais: Escolhendo a plataforma de CI**](/sections/testingandquality/citools.brazilian-portuguese.md)
+🔗 [**Leia Mais: Escolhendo a plataforma de CI**](./sections/testingandquality/citools.brazilian-portuguese.md)
+
+
+
+## ![✔] 4.13 Teste seus 'middlewares' isoladamente
+
+**TL;DR:** quando um 'middleware' contém alguma lógica imensa que abrange muitas solicitações, vale a pena testá-lo isoladamente, sem ativar todo o framework. Isso pode ser facilmente alcançado por 'stubbing' e espionando os objetos {req, res, next}
+
+**Caso contrário:** Um bug no 'middleware Express' === um bug em todas ou na maioria das solicitações
+
+🔗 [**Read More: Test middlewares in isolation**](./sections/testingandquality/test-middlewares.md)
@@ -535,13 +569,13 @@ Todas as declarações acima false se feitas com `===`.
# `5. Boas Práticas de Produção`
-## ![✔] 5.1. Monitoramento!
+## ![✔] 5.1. Monitoramento
**TL;DR:** O monitoramento é um jogo de descobrir problemas antes que os clientes os encontrem - obviamente deve ser atribuída muita importância para isto. O mercado está sobrecarregado de ofertas, portanto, considere começar com a definição das métricas básicas que você deve seguir (sugestões minhas dentro), depois passe por recursos extras e escolha a solução que marca todas as caixas. Acesse o ‘Gist’ abaixo para uma visão geral das soluções.
**Caso contrário:** Falha === clientes desapontados. Simples
-🔗 [**Leia Mais: Monitoramento!**](/sections/production/monitoring.brazilian-portuguese.md)
+🔗 [**Leia Mais: Monitoramento!**](./sections/production/monitoring.brazilian-portuguese.md)
@@ -551,7 +585,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Você acaba com uma caixa preta que é difícil de raciocinar, então você começa a reescrever todas as declarações de log para adicionar informações adicionais.
-🔗 [**Leia Mais: Aumente a transparência usando smart logging**](/sections/production/smartlogging.brazilian-portuguese.md)
+🔗 [**Leia Mais: Aumente a transparência usando smart logging**](./sections/production/smartlogging.brazilian-portuguese.md)
@@ -561,7 +595,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Seu único e pobre thread permanecerá ocupado fazendo tarefas de infra-estrutura em vez de lidar com o núcleo da sua aplicação e o desempenho certamente será degradado.
-🔗 [**Leia Mais: Delegue tudo o que for possível (por exemplo, gzip, SSL) a um proxy reverso**](/sections/production/delegatetoproxy.brazilian-portuguese.md)
+🔗 [**Leia Mais: Delegue tudo o que for possível (por exemplo, gzip, SSL) a um proxy reverso**](./sections/production/delegatetoproxy.brazilian-portuguese.md)
@@ -571,7 +605,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** O QA testará completamente o código e aprovará uma versão que se comportará de maneira diferente na produção. Pior ainda, servidores diferentes no mesmo cluster de produção podem executar código diferente.
-🔗 [**Leia Mais: Bloqueio de dependências**](/sections/production/lockdependencies.brazilian-portuguese.md)
+🔗 [**Leia Mais: Bloqueio de dependências**](./sections/production/lockdependencies.brazilian-portuguese.md)
@@ -581,7 +615,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Rodar dezenas de instâncias sem uma estratégia clara e muitas ferramentas juntas (gerenciamento de cluster, docker, PM2) pode levar o DevOps ao caos.
-🔗 [**Leia Mais: Poupe tempo de atividade do processo usando a ferramenta certa**](/sections/production/guardprocess.brazilian-portuguese.md)
+🔗 [**Leia Mais: Poupe tempo de atividade do processo usando a ferramenta certa**](./sections/production/guardprocess.brazilian-portuguese.md)
@@ -591,7 +625,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Sua aplicação vai utilizar apenas 25% dos recursos disponíveis(!) ou talvez até menos. Note que um servidor típico possui 4 núcleos de processamento ou mais, o deploy ingênuo do Node.js utiliza apenas 1 (mesmo usando serviços de PaaS como AWS Beanstalk!)
-🔗 [**Leia Mais: Utilize todos os núcleos do processador**](/sections/production/utilizecpu.brazilian-portuguese.md)
+🔗 [**Leia Mais: Utilize todos os núcleos do processador**](./sections/production/utilizecpu.brazilian-portuguese.md)
@@ -601,7 +635,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Você perceberá que está realizando muitos “deploys de diagnóstico” - enviando código para produção apenas para extrair algumas informações para fins de diagnóstico.
-🔗 [**Leia Mais: Crie um ‘endpoint de manutenção’**](/sections/production/createmaintenanceendpoint.brazilian-portuguese.md)
+🔗 [**Leia Mais: Crie um ‘endpoint de manutenção’**](./sections/production/createmaintenanceendpoint.brazilian-portuguese.md)
@@ -611,7 +645,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Você pode gastar muito esforço medindo o desempenho e os tempos de inatividade da API, provavelmente você nunca saberá quais são suas partes de código mais lentas no cenário do mundo real e como elas afetam o UX.
-🔗 [**Leia Mais: Descubra erros e tempo de inatividade usando produtos APM**](/sections/production/apmproducts.brazilian-portuguese.md)
+🔗 [**Leia Mais: Descubra erros e tempo de inatividade usando produtos APM**](./sections/production/apmproducts.brazilian-portuguese.md)
@@ -621,7 +655,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Uma pessoa fera em TI/DevOps não salvará um sistema mal escrito.
-🔗 [**Leia Mais: Deixe seu código pronto para produção**](/sections/production/productioncode.brazilian-portuguese.md)
+🔗 [**Leia Mais: Deixe seu código pronto para produção**](./sections/production/productioncode.brazilian-portuguese.md)
@@ -631,7 +665,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** A memória de seus processos pode vazar cem megabytes por dia, assim como aconteceu no [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak).
-🔗 [**Leia Mais: Meça e proteja o uso de memória**](/sections/production/measurememory.brazilian-portuguese.md)
+🔗 [**Leia Mais: Meça e proteja o uso de memória**](./sections/production/measurememory.brazilian-portuguese.md)
@@ -641,7 +675,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Seu único thread do Node ficará ocupado fazendo streaming the centenas de arquivos de html/imagens/angular/react ao invés de alocar todo seu recurso para a tarefa que ele foi designado - servir conteúdo dinâmico.
-🔗 [**Leia Mais: Deixe seus recursos de frontend fora do Node**](/sections/production/frontendout.brazilian-portuguese.md)
+🔗 [**Leia Mais: Deixe seus recursos de frontend fora do Node**](./sections/production/frontendout.brazilian-portuguese.md)
@@ -651,7 +685,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Falha em um determinado servidor resultará em tempo de inatividade da aplicação, em vez de apenas matar uma máquina defeituosa. Além do mais, dimensionar a elasticidade será mais desafiador devido à dependência de um servidor específico.
-🔗 [**Leia Mais: Seja stateless, mate seus Servidores quase todos os dias**](/sections/production/bestateless.brazilian-portuguese.md)
+🔗 [**Leia Mais: Seja stateless, mate seus Servidores quase todos os dias**](./sections/production/bestateless.brazilian-portuguese.md)
@@ -661,7 +695,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Manter seu código limpo com vulnerabilidades sem ferramentas dedicadas exigirá o acompanhamento constante de publicações online sobre novas ameaças. Bem entendiante.
-🔗 [**Leia Mais: Utilize ferramentas que detectam vulnerabilidades automaticamente**](/sections/production/detectvulnerabilities.brazilian-portuguese.md)
+🔗 [**Leia Mais: Utilize ferramentas que detectam vulnerabilidades automaticamente**](./sections/production/detectvulnerabilities.brazilian-portuguese.md)
@@ -671,7 +705,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Observar um log de erros de produção sem o contexto - o que aconteceu antes - torna muito mais difícil e mais lento raciocinar sobre o problema.
-🔗 [**Leia Mais: Atribua ‘TransactionId’ para cada declaração de log**](/sections/production/assigntransactionid.brazilian-portuguese.md)
+🔗 [**Leia Mais: Atribua ‘TransactionId’ para cada declaração de log**](./sections/production/assigntransactionid.brazilian-portuguese.md)
@@ -681,7 +715,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Omitir esta simples propriedade pode degradar muito o desempenho. Por exemplo, ao utilizar o Express para renderização do lado do servidor, omitir o NODE_ENV o torna mais lento!
-🔗 [**Leia Mais: Defina NODE_ENV=production**](/sections/production/setnodeenv.brazilian-portuguese.md)
+🔗 [**Leia Mais: Defina NODE_ENV=production**](./sections/production/setnodeenv.brazilian-portuguese.md)
@@ -699,7 +733,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Bugs recentemente descobertos e vulnerabilidades podem ser usados para explorar uma aplicação em produção, e sua aplicação pode se tornar incompatível com vários módulos e mais difícil de manter.
-🔗 [**Leia Mais: Use uma versão LTS do Node.js**](/sections/production/LTSrelease.brazilian-portuguese.md)
+🔗 [**Leia Mais: Use uma versão LTS do Node.js**](./sections/production/LTSrelease.brazilian-portuguese.md)
@@ -709,7 +743,17 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Aplicações manipulando o roteamento de log === difícil de dimensionar, perda de logs, separação ruim de preocupações.
-🔗 [**Leia Mais: Roteamento de Logs**](/sections/production/logrouting.brazilian-portuguese.md)
+🔗 [**Leia Mais: Roteamento de Logs**](./sections/production/logrouting.brazilian-portuguese.md)
+
+
+
+## ![✔] 5.19. Instale seus pacotes com `npm ci`
+
+**TL;DR:** Você precisa ter certeza de que o código de produção usa a versão exata dos pacotes que você realizou os testes. Execute `npm ci` para fazer estritamente uma instalação limpa de suas dependências correspondentes do package.json e do package-lock.json. O uso desse comando é recomendado em ambientes automatizados, como pipelines de integração contínua.
+
+**Caso contrário:** o QA testará completamente o código e aprovará uma versão que se comportará de maneira diferente em produção. Pior ainda, diferentes servidores no mesmo cluster de produção podem executar códigos diferentes.
+
+🔗 [**Read More: Use npm ci**](./sections/production/installpackageswithnpmci.md)
@@ -765,7 +809,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** A entrada de usuários não validados pode levar à injeção do operador ao trabalhar com MongoDB para NoSQL e não usar um sistema próprio ou ORM irão permitir facilmente um ataque de SQL injection, criando uma grande vulnerabilidade.
-🔗 [**Leia Mais: Prevenção de query injection usando bibliotecas de ORM/ODM**](/sections/security/ormodmusage.brazilian-portuguese.md)
+🔗 [**Leia Mais: Prevenção de query injection usando bibliotecas de ORM/ODM**](./sections/security/ormodmusage.brazilian-portuguese.md)
@@ -773,7 +817,7 @@ Todas as declarações acima false se feitas com `===`.
**TL;DR:** Esta é uma coleção de conselhos de segurança que não estão relacionadas diretamente com Node.js - a implementação do Node não é muito diferente comparado a outras linguagens. Clique em “leia mais” para dar uma olhada.
-🔗 [**Leia Mais: Boas práticas comuns de segurança**](/sections/security/commonsecuritybestpractices.brazilian-portuguese.md)
+🔗 [**Leia Mais: Boas práticas comuns de segurança**](./sections/security/commonsecuritybestpractices.brazilian-portuguese.md)
@@ -785,7 +829,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Invasores podem realizar ataques diretos aos usuários de sua aplicação, levando a grandes vulnerabilidades de segurança.
-🔗 [**Leia Mais: Usando headers seguros em sua aplicação**](/sections/security/secureheaders.brazilian-portuguese.md)
+🔗 [**Leia Mais: Usando headers seguros em sua aplicação**](./sections/security/secureheaders.brazilian-portuguese.md)
@@ -797,7 +841,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Um invasor pode detectar seu framework web e atacar todas suas vulnerabilidades.
-🔗 [**Leia Mais: Segurança de dependências**](/sections/security/dependencysecurity.brazilian-portuguese.md)
+🔗 [**Leia Mais: Segurança de dependências**](./sections/security/dependencysecurity.brazilian-portuguese.md)
@@ -809,7 +853,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Senhas ou segredos que são persistidos sem o uso de uma função segura, são vulneráveis a força bruta e ataques de dicionário que levarão eventualmente à sua divulgação.
-🔗 [**Leia Mais: Use o Bcrypt**](/sections/security/bcryptpasswords.brazilian-portuguese.md)
+🔗 [**Leia Mais: Use o Bcrypt**](./sections/security/bcryptpasswords.brazilian-portuguese.md)
@@ -821,7 +865,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Um invasor pode armazenar um código JavaScript malicioso em seu banco de dados, que será enviado para os clientes.
-🔗 [**Leia Mais: Evite saídas**](/sections/security/escape-output.brazilian-portuguese.md)
+🔗 [**Leia Mais: Evite saídas**](./sections/security/escape-output.brazilian-portuguese.md)
@@ -833,7 +877,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Sua generosidade e abordagem permissiva aumentam muito a superfície de ataque e incentivam o invasor a experimentar muitas entradas até encontrar alguma combinação para travar a aplicação.
-🔗 [**Leia Mais: Valide os esquemas de entrada JSON**](/sections/security/validation.brazilian-portuguese.md)
+🔗 [**Leia Mais: Valide os esquemas de entrada JSON**](./sections/security/validation.brazilian-portuguese.md)
@@ -845,7 +889,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Tokens expirados ou extraviados, podem ser usados maliciosamente por terceiros para acessar uma aplicação e para representar o proprietário do token.
-🔗 [**Leia Mais: Blacklist de JSON Web Tokens**](/sections/security/expirejwt.brazilian-portuguese.md)
+🔗 [**Leia Mais: Blacklist de JSON Web Tokens**](./sections/security/expirejwt.brazilian-portuguese.md)
@@ -854,13 +898,13 @@ Todas as declarações acima false se feitas com `===`.
**TL;DR:** Uma técnica simples e poderosa é limitar as tentativas de autorização usando duas métricas:
-
+
1. A primeiro é o número de tentativas consecutivas com falha do mesmo ID/nome e endereço IP exclusivos do usuário.
2. A segundo é o número de tentativas malsucedidas de um endereço IP durante um longo período de tempo. Por exemplo, bloqueie um endereço IP se ele fizer 100 tentativas com falha em um dia.
**Caso contrário:** Um invasor pode emitir tentativas ilimitadas de senha automatizada para obter acesso a contas com privilégios em uma aplicação.
-🔗 [**Leia Mais: Limitando a taxa de login**](/sections/security/login-rate-limit.brazilian-portuguese.md)
+🔗 [**Leia Mais: Limitando a taxa de login**](./sections/security/login-rate-limit.brazilian-portuguese.md)
@@ -872,7 +916,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Um invasor que consiga executar um script no servidor obtém poder ilimitado sobre a máquina local (por exemplo, alterar o iptable e redirecionar o tráfego para seu servidor).
-🔗 [**Leia Mais: Rode o Node.js com um usuário não raiz**](/sections/security/non-root-user.brazilian-portuguese.md)
+🔗 [**Leia Mais: Rode o Node.js com um usuário não raiz**](./sections/security/non-root-user.brazilian-portuguese.md)
@@ -884,7 +928,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Sua aplicação terá que lidar com solicitações grandes, incapazes de processar o outro trabalho importante que ele precisa realizar, o que leva a implicações de desempenho e vulnerabilidade em relação a ataques DOS.
-🔗 [**Leia Mais: Limite o tamanho dos payloads**](/sections/security/requestpayloadsizelimit.brazilian-portuguese.md)
+🔗 [**Leia Mais: Limite o tamanho dos payloads**](./sections/security/requestpayloadsizelimit.brazilian-portuguese.md)
@@ -896,7 +940,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** o código JavaScript malicioso encontra um caminho para um texto passado para o eval ou outras funções de avaliação em tempo real da linguagem JavaScript, e terá acesso total às permissões do JavaScript na página. Essa vulnerabilidade geralmente se manifesta como um ataque XSS.
-🔗 [**Leia Mais: Evite instruções eval do JavaScript**](/sections/security/avoideval.brazilian-portuguese.md)
+🔗 [**Leia Mais: Evite instruções eval do JavaScript**](./sections/security/avoideval.brazilian-portuguese.md)
@@ -908,7 +952,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Expressões regulares mal escritas podem ser suscetíveis a ataques de Regular Expresssion DoS, que irão bloquear completamente o loop de eventos. Por exemplo, o popular pacote `moment` foi encontrado com vulnerabilidades de uso de RegEx maliciosos em novembro de 2017.
-🔗 [**Leia Mais: Evite RegEx maliciosos**](/sections/security/regex.brazilian-portuguese.md)
+🔗 [**Leia Mais: Evite RegEx maliciosos**](./sections/security/regex.brazilian-portuguese.md)
@@ -920,7 +964,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** A entrada de usuário mal-intencionada pode encontrar o caminho para um parâmetro usado para require de arquivos adulterados, por exemplo, um arquivo carregado anteriormente no sistema de arquivos ou para acessar arquivos de sistema já existentes.
-🔗 [**Leia Mais: Carregamento seguro de módulos**](/sections/security/safemoduleloading.brazilian-portuguese.md)
+🔗 [**Leia Mais: Carregamento seguro de módulos**](./sections/security/safemoduleloading.brazilian-portuguese.md)
@@ -932,7 +976,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Um plugin pode atacar através de uma infinita variedade de opções, como loops infinitos, sobrecarga de memória e acesso a variáveis sensíveis do ambiente de processo.
-🔗 [**Leia Mais: Rode códigos não seguros em uma sandbox**](/sections/security/sandbox.brazilian-portuguese.md)
+🔗 [**Leia Mais: Rode códigos não seguros em uma sandbox**](./sections/security/sandbox.brazilian-portuguese.md)
@@ -944,7 +988,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** O uso ingênuo de processos filhos pode resultar na execução de comandos remotos ou em ataques de shell injection, devido à entrada do usuário mal-intencionado passada para um comando do sistema não-autorizado.
-🔗 [**Leia Mais: Tenha cautela ao trabalhar com processos filhos**](/sections/security/childprocesses.brazilian-portuguese.md)
+🔗 [**Leia Mais: Tenha cautela ao trabalhar com processos filhos**](./sections/security/childprocesses.brazilian-portuguese.md)
@@ -956,7 +1000,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Detalhes confidenciais da aplicação como caminhos e arquivos do servidor, módulos de terceiros em uso e outros workflows internos da aplicação poderiam ser explorados e expostos por um invasor.
-🔗 [**Leia Mais: Oculte detalhes de erros dos usuários**](/sections/security/hideerrors.brazilian-portuguese.md)
+🔗 [**Leia Mais: Oculte detalhes de erros dos usuários**](./sections/security/hideerrors.brazilian-portuguese.md)
@@ -978,7 +1022,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Cookies podem ser enviados através de conexões não seguras, e um hacker pode usar a sessão do usuário para identificar o framework utilizado na aplicação, bem como vulnerabilidades específicas do módulo.
-🔗 [**Leia Mais: Segurança de cookies e sessões**](/sections/security/sessions.brazilian-portuguese.md)
+🔗 [**Leia Mais: Segurança de cookies e sessões**](./sections/security/sessions.brazilian-portuguese.md)
@@ -1000,7 +1044,7 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** Se um invasor descobrir que você não está validando informações externas fornecidas pelo usuário, ele poderá explorar essa vulnerabilidade postando links especialmente em fóruns, mídias sociais e outros locais públicos para que os usuários cliquem.
-🔗 [**Leia Mais: Impeça redirecionamentos não seguros**](/sections/security/saferedirects.brazilian-portuguese.md)
+🔗 [**Leia Mais: Impeça redirecionamentos não seguros**](./sections/security/saferedirects.brazilian-portuguese.md)
@@ -1012,14 +1056,14 @@ Todas as declarações acima false se feitas com `===`.
**Caso contrário:** As chaves, as senhas ou outros segredos da API do seu projeto estão sujeitos a abusos por qualquer pessoa que os encontre, o que pode resultar em perda financeira, falsificação de identidade e outros riscos.
-🔗 [**Leia Mais: Evite publicar segredos**](/sections/security/avoid_publishing_secrets.brazilian-portuguese.md)
+🔗 [**Leia Mais: Evite publicar segredos**](./sections/security/avoid_publishing_secrets.brazilian-portuguese.md)
# `7. Boas Práticas em Performance`
-## Nossos colaboradores estão trabalhando nesta seção. [Gostaria de participar?](https://github.com/i0natan/nodebestpractices/issues/256)
+## Nossos colaboradores estão trabalhando nesta seção. [Gostaria de participar?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
## ![✔] 7.1. Prefira métodos JS nativos ao invés de utilitários de usuário, como o Lodash
@@ -1028,13 +1072,13 @@ Tenha em mente que, com a introdução do novo motor V8 juntamente com os novos
**Caso contrário:** Você terá que manter projetos de menor desempenho onde você poderia simplesmente ter usado o que **já estava** disponível ou lidar com mais algumas linhas em troca de mais alguns arquivos.
-🔗 [**Leia Mais: Prefira métodos nativos ao invés de utilitários do usuário como Lodash**](/sections/performance/nativeoverutil.brazilian-portuguese.md)
+🔗 [**Leia Mais: Prefira métodos nativos ao invés de utilitários do usuário como Lodash**](./sections/performance/nativeoverutil.brazilian-portuguese.md)
# Feitos
-Para manter este guia e deixá-lo atualizado, estamos constantemente atualizando e aprimorando as diretrizes e as práticas recomendadas com a ajuda da comunidade. Você pode acompanhar nossos [feitos](https://github.com/i0natan/nodebestpractices/milestones) e se juntar aos grupos de trabalho, caso queira contribuir com este projeto.
+Para manter este guia e deixá-lo atualizado, estamos constantemente atualizando e aprimorando as diretrizes e as práticas recomendadas com a ajuda da comunidade. Você pode acompanhar nossos [feitos](https://github.com/goldbergyoni/nodebestpractices/milestones) e se juntar aos grupos de trabalho, caso queira contribuir com este projeto.
@@ -1044,27 +1088,28 @@ Todas as traduções são contribuições da comunidade. Nós ficaremos felizes
### Traduções concluídas
--  [Português Brasileiro](/README.brazilian-portuguese.md) - Cortesia de [Marcelo Melo](https://github.com/marcelosdm)
--  [Chinês](README.chinese.md) - Cortesia de [Matt Jin](https://github.com/mattjin)
+-  [Português Brasileiro](./README.brazilian-portuguese.md) - Cortesia de [Marcelo Melo](https://github.com/marcelosdm)
+-  [Chinês](README.chinese.md) - Cortesia de [Matt Jin](https://github.com/mattjin)
+-  [Vasco](README.basque.md) - Cortesia de [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuesta
### Traduções em andamento
--  [Francês](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussão](https://github.com/i0natan/nodebestpractices/issues/129))
--  Hebraico ([Discussão](https://github.com/i0natan/nodebestpractices/issues/156))
--  [Coreano](https://github.com/i0natan/nodebestpractices/blob/korean-translation/README.md) ([Discussão](https://github.com/i0natan/nodebestpractices/issues/94))
--  [Russo](https://github.com/i0natan/nodebestpractices/blob/russian-translation/README.russian.md) ([Discussão](https://github.com/i0natan/nodebestpractices/issues/454))
--  [Espanhol](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussão](https://github.com/i0natan/nodebestpractices/issues/95))
--  Turco ([Discussão](https://github.com/i0natan/nodebestpractices/issues/139))
+-  [Francês](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussão](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  Hebraico ([Discussão](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Coreano](https://github.com/goldbergyoni/nodebestpractices/blob/korean-translation/README.md) ([Discussão](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Russo](https://github.com/goldbergyoni/nodebestpractices/blob/russian-translation/README.russian.md) ([Discussão](https://github.com/goldbergyoni/nodebestpractices/issues/454))
+-  [Espanhol](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussão](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turco ([Discussão](https://github.com/goldbergyoni/nodebestpractices/issues/139))
## Comitê Diretivo
-Conheça os membros do comitê diretivo - as pessoas que trabalham juntas para fornecer orientação e direção futura para o projeto. Além disso, cada membro do comitê lidera um projeto rastreado em nossos [projetos do Github](https://github.com/i0natan/nodebestpractices/projects).
+Conheça os membros do comitê diretivo - as pessoas que trabalham juntas para fornecer orientação e direção futura para o projeto. Além disso, cada membro do comitê lidera um projeto rastreado em nossos [projetos do Github](https://github.com/goldbergyoni/nodebestpractices/projects).
-
+
-[Yoni Goldberg](https://github.com/i0natan)
+[Yoni Goldberg](https://github.com/goldbergyoni)
@@ -1072,7 +1117,7 @@ Consultor de Node.js independente, que trabalha com clientes nos EUA, Europa e I
-
+
[Bruno Scheufler](https://github.com/BrunoScheufler)
@@ -1081,7 +1126,7 @@ Consultor de Node.js independente, que trabalha com clientes nos EUA, Europa e I
-
+
[Kyle Martin](https://github.com/js-kyle)
@@ -1091,7 +1136,7 @@ Full Stack Developer e Engenheiro de Confiabilidade de Sites com sede na Nova Ze
-
+
[Sagir Khan](https://github.com/sagirk)
@@ -1106,22 +1151,22 @@ Especialista profundo em JavaScript e seu ecossistema - React, Node.js, MongoDB,
Obrigado a todos nossos colaboradores! 🙏
-Nossos colaboradores são membros que estão contribuindo com o repositório em base regular, sugerindo novas práticas recomendadas, triando problemas, analisando solicitações de pull e muito mais. Se você estiver interessado em nos ajudar a orientar milhares de pessoas a criar melhores aplicações Node.js, leia nossas [diretrizes de colaborador](/.operations/CONTRIBUTING.md) 🎉
+Nossos colaboradores são membros que estão contribuindo com o repositório em base regular, sugerindo novas práticas recomendadas, triando problemas, analisando solicitações de pull e muito mais. Se você estiver interessado em nos ajudar a orientar milhares de pessoas a criar melhores aplicações Node.js, leia nossas [diretrizes de colaborador](./.operations/CONTRIBUTING.md) 🎉
-| | |
-| :--: | :--: |
-| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
+| | |
+| :---------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
+| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
### Colaboradores anteriores
-| |
-| :--: |
-| [Refael Ackermann](https://github.com/refack) |
+| |
+| :-------------------------------------------------------------------------------------------------------------------------: |
+| [Refael Ackermann](https://github.com/refack) |
## Thank You Notes
-We appreciate any contribution, from a single word fix to a new best practice. View our contributors and [contributing documentation here!](CONTRIBUTORS.md)
+We appreciate any contribution, from a single word fix to a new best practice. View our contributors and [contributing documentation here!](./README.md#contributors-)
-
-# `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.
-
-
-
-# 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
-
-We appreciate any contribution, from a single word fix to a new best practice. View our contributors and [contributing documentation here!](CONTRIBUTORS.md)
-
-
+
+# 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/goldbergyoni/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
+
+We appreciate any contribution, from a single word fix to a new best practice. View our contributors and [contributing documentation here!](./README.md#contributors-)
+
+
+
+
+
+[](https://twitter.com/nodepractices/) **Suivez nous sur Twitter !** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+
+Lire dans une autre langue : [**CN**](./README.chinese.md), [**FR**](./README.french.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**PL**](./README.polish.md), [**JA**](./README.japanese.md), [**EU**](./README.basque.md) [(**ES**, **HE**, **KR** et **TR** en cours ! )](#traductions)
+
+
+
+###### Construit et entretenu par notre [comité de pilotage](#comité-de-pilotage) et nos [collaborateurs](#collaborateurs)
+
+# Dernières bonnes pratiques et nouveautés
+
+- ** Traduction française!1! :** La dernière traduction qui rejoint notre guide international est le français. Bienvenue
+
+- **🇯🇵 traduction japonaise :** Notre guide est désormais également traduit en japonais ! Avec l'aimable autorisation des extraordinaires [YukiOta](https://github.com/YukiOta) et [Yuta Azumi](https://github.com/YA21).
+
+- **🎊 60,000 stars !** : Notre dépôt a reçu la reconnaissance et la confiance de 60 100 développeurs. Nous sommes sans voix.
+
+
+
+# Bienvenue ! 3 Choses à savoir avant tout
+
+**1. Vous êtes en train de lire un regroupement des meilleurs articles sur Node.js. -** ce référentiel est un résumé et il conserve le contenu le mieux classé sur les bonnes pratiques Node.js, ainsi que du contenu écrit ici par des collaborateurs
+
+**2. Il s'agit du plus grand assemblage d'articles et il s'agrandit chaque semaine -** actuellement, plus de 80 bonnes pratiques, guides de style et astuces d'architecture sont présentées. Nous serions ravis de vous voir contribuer ici, qu'il s'agisse de corriger des erreurs de code, d'aider aux traductions ou de suggérer de nouvelles idées brillantes. Consultez nos [recommandations d'écriture](./.operations/writing-guidelines.french.md)
+
+**3. Les bonnes pratiques contiennent des informations supplémentaires -** la plupart des points ont un lien **🔗Plus d'infos** qui développe la bonne pratique avec des exemples de code, des citations venant de pages sélectionnées et plus encore.
+
+
+
+## Table des matières
+
+1. [Structure de projet (5)](#1-structure-de-projet)
+2. [Gestion des erreurs (12) ](#2-gestion-des-erreurs)
+3. [Style du code (12) ](#3-style-du-code)
+4. [Tests et pratiques générales de qualité (13) ](#4-tests-et-pratiques-générales-de-qualité)
+5. [Pratiques de mise en production (19) ](#5-pratiques-de-mise-en-production)
+6. [Sécurité (25)](#6-bonnes-pratiques-de-sécurité)
+7. [Performance (2) (Travail en cours ✍️)](#7-brouillon-bonnes-pratiques-de-performance)
+8. [Pratiques de Docker (15)](#8-bonnes-pratiques-de-docker)
+
+
+
+# `1. Structure de projet`
+
+## ![✔] 1.1 Organisez votre projet en composants
+
+**TL;PL :** Le pire obstacle des énormes applications est la maintenance d'une base de code immense contenant des centaines de dépendances - un tel monolithe ralentit les développeurs tentant d'ajouter de nouvelles fonctionnalités. Pour éviter cela, répartissez votre code en composants, chacun dans son dossier avec son code dédié, et assurez vous que chaque unité soit courte et simple. Visitez le lien « Plus d'infos » plus bas pour voir des exemples de structure de projet correcte.
+
+**Autrement :** Lorsque les développeurs qui codent de nouvelles fonctionnalités ont du mal à réaliser l'impact de leur changement et craignent de casser d'autres composants dépendants - les déploiements deviennent plus lents et plus risqués. Il est aussi considéré plus difficile d'élargir un modèle d'application quand les unités opérationnelles ne sont pas séparées.
+
+🔗 [**Plus d'infos : organisez en composants**](./sections/projectstructre/breakintcomponents.french.md)
+
+
+
+## ![✔] 1.2 Organisez vos composants en strates, gardez la couche web à l'intérieur de son périmètre
+
+**TL;PL :** Chaque composant devrait contenir des « strates » - un objet dédié pour le web, un pour la logique et un pour le code d'accès aux données. Cela permet non seulement de séparer clairement les responsabilités mais permet aussi de simuler et de tester le système de manière plus simple. Bien qu'il s'agisse d'un modèle très courant, les développeurs d'API ont tendance à mélanger les strates en passant l'objet dédié au web (Par exemple Express req, res) à la logique opérationnelle et aux strates de données - cela rend l'application dépendante et accessible seulement par les frameworks web spécifiques.
+
+**Autrement :** Les tests, les jobs CRON, les déclencheurs des files d'attente de messages et etc ne peuvent pas accéder à une application qui mélange les objets web avec les autres strates.
+
+🔗 [**Plus d'infos : organisez en strates votre app**](./sections/projectstructre/createlayers.french.md)
+
+
+
+## ![✔] 1.3 Externalisez les utilitaires communs en paquets NPM
+
+**TL;PL :** Dans une grande appli rassemblant de nombreuses lignes de codes, les utilitaires opérant sur toutes les strates comme un logger, l'encryption et autres, devraient être inclus dans le code et exposés en tant que paquets NPM privés. Cela permet leur partage au sein de plusieurs projets.
+
+**Autrement :** Vous devrez inventer votre propre roue de déploiement et de dépendance
+
+🔗 [**Plus d'infos : organisez par fonction**](./sections/projectstructre/wraputilities.french.md)
+
+
+
+## ![✔] 1.4 Séparez Express 'app' et 'server'
+
+**TL;PL :** Evitez la sale habitude de définir l'appli [Express](https://expressjs.com/) toute entière dans un seul fichier immense - séparez la définition de votre 'Express' en au moins deux fichiers : la déclaration de l'API (app.js) et les responsabilités de gestion de réseau (WWW). Pour une structure encore plus poussée, localisez la déclaration de l'API dans les composants.
+
+**Autrement :** Votre API sera seulement accessible aux tests par le biais d'appels HTTP (plus lent et plus difficile de générer des rapports de couverture). Cela ne sera pas un réel plaisir de maintenir des centaines de lignes de code dans un fichier unique.
+
+🔗 [**Plus d'infos : séparez Express 'app' et 'server'**](./sections/projectstructre/separateexpress.french.md)
+
+
+
+## ![✔] 1.5 Utilisez une configuration respectueuse de l'environnement, sécurisée et hiérarchique
+
+**TL;PL :** La mise en place d'une configuration parfaite et sans faille doit garantir que (a) les clés peuvent être lues depuis un fichier ET à partir de la variable d'environnement (b) les secrets sont conservés hors du code source (c) la configuration est hiérarchique pour une recherche plus simple. Certains paquets peuvent gérer la plupart de ces points comme [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) et [convict](https://www.npmjs.com/package/convict).
+
+**Autrement :** Ne pas se soucier de ces exigences de configuration ne fera que ralentir l'équipe de développement ou l'équipe de DevOps. Probablement les deux.
+
+🔗 [**Plus d'infos : bonnes pratiques de configuration**](./sections/projectstructre/configguide.french.md)
+
+
+
+# `2. Gestion des erreurs`
+
+## ![✔] 2.1 Utilisez Async-Await ou les promesses pour le traitement des erreurs asynchrones
+
+**TL;PL :** Gérer les erreurs asynchrone avec le style fonction de rappel est probablement le chemin le plus rapide vers l'enfer (ou la [pyramide condamnée](https://fr.wikipedia.org/wiki/Pyramide_condamn%C3%A9e)). Le meilleur cadeau que vous puissiez faire à votre code est d'utiliser une bibliothèque de promesses réputée ou async-await à la place, ceci permet une syntaxe de code beaucoup plus compacte et familière comme try-catch.
+
+**Autrement :** Le style fonction de rappel de Node.js, function(err, response), constituent une autre manière d’obtenir une solution non maintenable mêlant gestion de l’erreur avec du code ordinaire, des imbrications excessives et une conception bancale.
+
+🔗 [**Plus d'infos : évitez les fonctions de rappel**](./sections/errorhandling/asyncerrorhandling.french.md)
+
+
+
+## ![✔] 2.2 Utilisez uniquement l'objet intégré Error
+
+**TL;PL :** Beaucoup lèvent des erreurs sous forme de chaîne ou de type personnalisé - cela complique la logique de gestion des erreurs et l'interopérabilité entre les modules. Que vous rejetiez une promesse, leviez une exception ou émettiez une erreur - l'utilisation uniquement de l'objet intégré Error (ou un objet qui étend l'objet Error) augmentera l'uniformité et empêchera la perte d'informations. Il existe une règle ESLint `no-throw-literal` qui vérifie strictement cela (bien qu'elle ait quelques [limitations](https://eslint.org/docs/rules/no-throw-literal) qui peuvent être résolues en utilisant TypeScript et en définissant la règle `@typescript-eslint/no-throw-literal`).
+
+**Autrement :** Lorsque vous appelez un composant, le type d'erreurs en retour étant incertain - cela rend la gestion des erreurs beaucoup plus difficile. Pire encore, l'utilisation de types personnalisés pour décrire des erreurs peut entraîner la perte d'informations d'erreurs critiques comme la trace de la pile !
+
+🔗 [**Plus d'infos : utilisez uniquement l'objet intégré Error**](./sections/errorhandling/useonlythebuiltinerror.french.md)
+
+
+
+## ![✔] 2.3 Distinguez les erreurs opérationnelles des erreurs de programmation
+
+**TL;PL :** Les erreurs opérationnelles (par exemple, l'API a reçu une entrée non valide) se rapportent à des cas connus où l'impact de l'erreur est entièrement compris et peut être géré de manière réfléchie. D'autre part, une erreur de programmation (par exemple, essayer de lire une variable non définie) fait référence à des échecs de code inconnus qui dictent de redémarrer l'application en douceur.
+
+**Autrement :** Vous pouvez toujours redémarrer l'application lorsqu'une erreur apparaît, mais pourquoi lâcher environ 5000 utilisateurs en ligne en raison d'une erreur opérationnelle mineure prévue ? L'inverse n'est pas non plus idéal - laisser l'application en place lorsqu'un problème inconnu (erreur de programmation) s'est produit peut conduire à un comportement imprévu. Différencier les deux permet d'agir avec tact et d'appliquer une approche équilibrée en fonction du contexte donné.
+
+🔗 [**Plus d'infos : erreur opérationnelle vs erreur de programmation**](./sections/errorhandling/operationalvsprogrammererror.french.md)
+
+
+
+## ![✔] 2.4 Gérez les erreurs de manière centralisée, pas dans un middleware
+
+**TL;PL :** Les logiques de gestion des erreurs telles que le mail à l'administrateur et la journalisation doivent être encapsulées dans un objet dédié et centralisé, pour que tous les points de terminaison (par exemple, middleware Express, tâches cron, tests unitaires) l'appellent lorsqu'une erreur survient.
+
+**Autrement :** Ne pas traiter les erreurs dans un seul endroit entraînera une duplication de code et probablement des erreurs mal gérées
+
+🔗 [**Plus d'infos : gestion des erreurs dans un lieu centralisé**](./sections/errorhandling/centralizedhandling.french.md)
+
+
+
+## ![✔] 2.5 Documentez les erreurs de l'API à l'aide de Swagger ou GraphQL
+
+**TL;PL :** Faites savoir à vos appelants de l'API quelles erreurs peuvent survenir en retour afin de pouvoir les traiter de manière réfléchie sans planter. Pour les API RESTful, cela se fait généralement avec des frameworks de documentation comme Swagger. Si vous utilisez GraphQL, vous pouvez également utiliser votre schéma et vos commentaires.
+
+**Autrement :** Un client d'une API peut décider de planter et de redémarrer uniquement parce qu'il a reçu une erreur qu'il ne comprend pas. Remarque: l'appelant de votre API peut être vous (très typique dans un environnement de microservice)
+
+🔗 [**Plus d'infos : documentez les erreurs de l'API à l'aide de Swagger ou GraphQL**](./sections/errorhandling/documentingusingswagger.french.md)
+
+
+
+## ![✔] 2.6 Quittez le processus avec élégance lorsqu'un étranger arrive en ville
+
+**TL;PL :** Lorsqu'une erreur inconnue se produit (une erreur de programmation, voir la bonne pratique 2.3) - il existe une incertitude sur la bonne santé de l'application. Une pratique courante suggère de redémarrer le processus avec précaution à l'aide d'un outil de gestion des processus comme [Forever](https://www.npmjs.com/package/forever) ou [PM2](http://pm2.keymetrics.io/).
+
+**Autrement :** Lorsqu'une exception inconnue se produit, certains objets peuvent être dans un état défectueux (par exemple, un émetteur d'événements qui est utilisé globalement et qui ne déclenche plus d'événements en raison d'une défaillance interne) et toutes les demandes futures peuvent échouer ou se comporter de manière folle.
+
+🔗 [**Plus d'infos : arrêtez le processus**](./sections/errorhandling/shuttingtheprocess.french.md)
+
+
+
+## ![✔] 2.7 Utilisez un outil de journalisation mature pour augmenter la visibilité des erreurs
+
+**TL;PL :** Un ensemble d'outils de journalisation matures comme [Pino](https://github.com/pinojs/pino) ou [Log4js](http://stritti.github.io/log4js/), accélérera la découverte et la compréhension des erreurs. Alors oubliez console.log.
+
+**Autrement :** En parcourant les console.logs ou manuellement par le biais d'un fichier texte désordonné sans outils d'interrogation ou d'une visionneuse de journaux décente, vous pourriez être occupé au travail jusqu'à tard dans la nuit.
+
+🔗 [**Plus d'infos : utilisation d'un outil de journalisation mature**](./sections/errorhandling/usematurelogger.french.md)
+
+
+
+## ![✔] 2.8 Testez les flux d'erreurs en utilisant votre framework de test préféré
+
+**TL;PL :** Qu'il s'agisse d'un outil automatisée d'assurance qualité professionnelle ou de tests manuels simples pour les développeurs - Assurez-vous que votre code non seulement satisfait les scénarios positifs, mais gère et renvoie également les bonnes erreurs. Les frameworks de test comme Mocha & Chai peuvent gérer cela facilement (voir les exemples de code dans « Plus d'infos »)
+
+**Autrement :** Sans test, que ce soit automatiquement ou manuellement, vous ne pouvez pas compter sur votre code pour renvoyer les bonnes erreurs. Sans erreurs significatives - il n'y a pas de gestion des erreurs.
+
+🔗 [**Plus d'infos : test des flux d'erreurs**](./sections/errorhandling/testingerrorflows.french.md)
+
+
+
+## ![✔] 2.9 Découvrez les erreurs et les indisponibilités à l'aide des produits de gestion de la performance applicative
+
+**TL;PL :** Les produits de surveillance et de performance (alias GPA, APM en anglais : application performance management) évaluent de manière proactive votre base de code ou votre API afin qu'ils puissent mettre en évidence automatiquement les erreurs, les plantages et les parties lentes qui vous ont échappé.
+
+**Autrement :** Vous pourriez consacrer beaucoup d'efforts à mesurer les performances et les indisponibilités de l'API, vous ne saurez probablement jamais quelles sont vos parties de code les plus lentes dans le scénario du monde réel et comment celles-ci affectent l'expérience utilisateur.
+
+🔗 [**Plus d'infos : utilisation des produits GPA**](./sections/errorhandling/apmproducts.french.md)
+
+
+
+## ![✔] 2.10 Capturez les rejets de promesses non gérés
+
+**TL;PL :** Toute exception levée dans une promesse sera absorbée et écartée à moins qu'un développeur n'ait pas oublié de le traiter explicitement. Même si votre code est abonné à `process.uncaughtException` ! Surmontez cela en vous inscrivant à l'événement `process.unhandledRejection`.
+
+**Autrement :** Vos erreurs seront absorbées et ne laisseront aucune trace. Il n'y a pas de quoi s'inquiéter.
+
+🔗 [**Plus d'infos : capturez les rejets de promesses non gérés**](./sections/errorhandling/catchunhandledpromiserejection.french.md)
+
+
+
+## ![✔] 2.11 Échouez rapidement, valider les arguments à l'aide d'une bibliothèque dédiée
+
+**TL;PL :** Contrôlez les arguments de l'API pour éviter les bugs désagréables qui sont beaucoup plus difficiles à suivre plus tard. Le code de validation est généralement fastidieux, sauf si vous utilisez une bibliothèque d'aide très cool comme [ajv](https://www.npmjs.com/package/ajv) et [Joi](https://www.npmjs.com/package/joi).
+
+**Autrement :** Considérez ceci - votre fonction attend un argument numérique « Discount » que l'appelant oublie de passer, plus loin dans le code, il vérifie si Discount!= 0 (le montant de la remise autorisée est supérieur à zéro), ensuite le code permet à l'utilisateur de profiter d'un remise. OMG, quel méchant bug. Le vois-tu ?
+
+🔗 [**Plus d'infos : échec rapide**](./sections/errorhandling/failfast.french.md)
+
+
+
+## ![✔] 2.12 Attendez toujours les promesses avant de retourner afin d'éviter des traces de pile partielles
+
+**TL;PL :** Faites toujours `return await` lorsque vous retournez une promesse afin de bénéficier d'une trace de pile complète. Si une
+fonction retourne une promesse, cette fonction doit être déclarée comme fonction `async` et explicitement
+attendre (`await`) la promesse avant de la retourner.
+
+**Autrement :** La fonction qui retourne une promesse sans attendre n'apparaîtra pas dans la trace de la pile.
+De telles trames manquantes compliqueraient probablement la compréhension du flux qui conduit à l'erreur,
+surtout si la cause du comportement anormal se situe à l'intérieur de la fonction manquante
+
+🔗 [**Plus d'infos : le retour des promesses**](./sections/errorhandling/returningpromises.french.md)
+
+
+
+# `3. Style du code`
+
+## ![✔] 3.1 Utilisez ESLint
+
+**TL;PL :** [ESLint](https://eslint.org) est la norme de facto pour vérifier d'éventuelles erreurs de code et pour corriger le style du code, ce n'est pas uniquement pour identifier les problèmes d'espacement mais aussi pour détecter les antipatterns préoccupants du code comme par exemple les développeurs levant des erreurs sans classification. Bien qu'ESLint puisse corriger automatiquement les styles du code, d'autres outils comme [prettier](https://www.npmjs.com/package/prettier) et [beautify](https://www.npmjs.com/package/js-beautify) sont plus puissants dans le formatage de la correction et fonctionnent en collaboration avec ESLint.
+
+**Autrement :** Les développeurs se concentreront sur les problèmes fastidieux d'espacement et de largeur de ligne, ce qui pourrait faire perdre du temps à trop réfléchir sur le style de code du projet.
+
+🔗 [**Plus d'infos : Utilisez ESLint et Prettier**](./sections/codestylepractices/eslint_prettier.french.md)
+
+
+
+## ![✔] 3.2 Plugins spécifiques à Node.js
+
+**TL;PL :** En plus des règles standard ESLint couvrant JavaScript vanilla, ajoutez des plugins spécifiques à Node.js comme [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) et [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security).
+
+**Autrement :** De nombreux modèles de code Node.js défectueux peuvent s'échapper des radars. Par exemple, les développeurs pourrait exiger des fichiers avec une variable donnée comme un chemin d'accès (`require(variableCommeChemin)`) qui permet aux attaquants d'exécuter n'importe quel script JS. Les linters de Node.js peuvent détecter de tels modèles et se plaindre en amont.
+
+
+
+## ![✔] 3.3 Commencez les accolades d'un bloc de code sur la même ligne
+
+**TL;PL :** Les accolades ouvrantes d'un bloc de code doivent être sur la même ligne que l'instruction d'ouverture.
+
+### Code Example
+
+```javascript
+// À faire
+function someFunction() {
+ // bloc de code
+}
+
+// À éviter
+function someFunction
+{
+ // bloc de code
+}
+```
+
+**Autrement :** Le non-respect de cette bonne pratique peut conduire à des résultats inattendus, comme le montre la discussion de StackOverflow ci-dessous :
+
+🔗 [**Plus d'infos :** « Pourquoi les résultats varient-ils en fonction du placement des accolades ? » (StackOverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
+
+
+
+## ![✔] 3.4 Séparez correctement vos instructions
+
+Peu importe si vous utilisez les points-virgules ou non pour séparer vos instructions, le fait de connaître les pièges courants des sauts de ligne incorrects ou de l'insertion automatique de points-virgules, vous aidera à éliminer les erreurs syntaxiques habituelles.
+
+**TL;PL :** Utilisez ESLint pour vous sensibiliser aux problèmes de séparation. [Prettier](https://prettier.io/) ou [Standardjs](https://standardjs.com/) peuvent résoudre automatiquement ces problèmes.
+
+**Autrement :** Comme vu dans la section précédente, l'interpréteur JavaScript ajoute automatiquement un point-virgule à la fin d'une instruction s'il n'y en a pas, ou considère une instruction comme non terminée là où elle devrait, ce qui pourrait conduire à des résultats indésirables. Vous pouvez utiliser des affectations et éviter d'utiliser des expressions de fonction invoquées immédiatement pour éviter la plupart des erreurs inattendues.
+
+### Exemple de code
+
+```javascript
+// À faire
+function doThing() {
+ // ...
+}
+
+doThing()
+
+// À faire
+
+const items = [1, 2, 3]
+items.forEach(console.log)
+
+// À éviter — lève une exception
+const m = new Map()
+const a = [1,2,3]
+[...m.values()].forEach(console.log)
+> [...m.values()].forEach(console.log)
+> ^^^
+> SyntaxError: Unexpected token ...
+
+// À éviter — lève une exception
+const count = 2 // il essaie d'exécuter 2(), mais 2 n'est pas une fonction
+(function doSomething() {
+ // faire quelque chose d'incroyable
+}())
+// placez un point-virgule avant la fonction immédiatement invoquée, après la définition de const, enregistrez la valeur de retour de la fonction anonyme dans une variable ou évitez tous les IIFE
+```
+
+🔗 [**Plus d'infos :** « Règle de ESLint : points-virgules »](https://eslint.org/docs/rules/semi)
+🔗 [**Plus d'infos :** « Règle de ESLint : pas de multiligne inattendue »](https://eslint.org/docs/rules/no-unexpected-multiline)
+
+
+
+## ![✔] 3.5 Nommez vos fonctions
+
+**TL;PL :** Nommez toutes les fonctions, y compris les fermetures _(closures, NdT)_ et les fonctions de rappel. Évitez les fonctions anonymes. Cela est particulièrement utile lors du profilage d'une application de Node. Nommer toutes les fonctions vous permettra de comprendre facilement ce que vous regardez lors de la vérification d'un instantané de mémoire _(snapshot memory, NdT)_.
+
+**Autrement :** Le débogage des problèmes de production à l'aide d'un vidage de mémoire (instantané de mémoire) peut devenir difficile lorsque vous remarquez une consommation de mémoire importante de la part de fonctions anonymes.
+
+
+
+## ![✔] 3.6 Utilisez des conventions de nommage pour les variables, les constantes, les fonctions et les classes
+
+**TL;PL :** Utilisez **_LowerCamelCase_** lorsque vous nommez des constantes, des variables et des fonctions et **_UpperCamelCase_** (première lettre en majuscule également) lorsque vous nommez des classes. Cela vous aidera à distinguer facilement les simples variables/fonctions et les classes qui nécessitent une instanciation. Utilisez des noms évocateurs, mais efforcez-vous de les garder concis.
+
+**Autrement :** JavaScript est le seul langage au monde qui permet d'invoquer directement un constructeur (« Class ») sans l'instancier au préalable. Par conséquent, les classes et les fonctions-constructeurs sont différenciés en commençant par UpperCamelCase.
+
+### 3.6 Exemple de code
+
+```javascript
+// pour le nom d'une classe, nous utilisons UpperCamelCase
+class SomeClassExample {}
+
+// pour les noms de constantes, nous utilisons le mot-clé const et lowerCamelCase
+const config = {
+ key: "value",
+};
+
+// pour les noms de variables et de fonctions, nous utilisons lowerCamelCase
+let someVariableExample = "value";
+function doSomething() {}
+```
+
+
+
+## ![✔] 3.7 Préférez const à let. Laissez tomber le var
+
+**TL;PL :** L'utilisation de `const` signifie qu'une fois qu'une variable est affectée, elle ne peut pas être réaffectée. Préférer `const` vous aidera à ne pas être tenté d'utiliser la même variable pour différentes utilisations et rendra votre code plus clair. Si une variable doit être réaffectée, par exempledans une boucle for, utilisez `let` pour la déclarer. Un autre aspect important de `let` est qu'une variable déclarée l'utilisant n'est disponible que dans la portée du bloc dans laquelle elle a été définie. `var` est une portée de fonction, pas une portée de bloc, et [ne devrait pas être utilisé en ES6](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70) maintenant que vous avez `const` et `let` à votre disposition.
+
+**Autrement :** Le débogage devient beaucoup plus lourd lorsque vous suivez une variable qui change fréquemment.
+
+🔗 [**Plus d'infos : JavaScript ES6+ : var, let, ou const ?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 Utilisez en premier require pour les modules, pas dans des fonctions internes
+
+**TL;PL :** Utilisez au début de chaque fichier `require` pour les modules, avant et en dehors de toute fonction. Cette bonne pratique simple vous aidera non seulement à identifier facilement et rapidement les dépendances en haut d'un fichier, mais évite également quelques problèmes potentiels.
+
+**Autrement :** Les `require` sont exécutées de manière synchrone par Node.js. S'ils sont appelés depuis une fonction, cela peut empêcher le traitement d'autres demandes à un moment plus critique. De plus, si un module requis ou l'une de ses dépendances lance une erreur et plante le serveur, il est préférable de le découvrir le plus tôt possible, ce qui pourrait ne pas être le cas si ce module est requis depuis une fonction.
+
+
+
+## ![✔] 3.9 Exiger les modules par leurs dossiers, contrairement à l'appel direct aux fichiers
+
+**TL;PL :** Lorsque vous développez un module/bibliothèque dans un dossier, placez un fichier index.js qui expose les composants internes du module afin que chaque utilisateur puisse y accéder. Cela sert d '« interface » à votre module et facilite les modifications futures sans rompre le contrat.
+
+**Autrement :** La modification de la structure interne des fichiers ou de la signature peut rompre l'interface avec les clients.
+
+### 3.9 Exemple de code
+
+```javascript
+// À faire
+module.exports.SMSProvider = require("./SMSProvider");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver");
+
+// À éviter
+module.exports.SMSProvider = require("./SMSProvider/SMSProvider.js");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver/SMSNumberResolver.js");
+```
+
+
+
+## ![✔] 3.10 Utilisez l'opérateur `===`
+
+**TL;PL :** Préférez l'opérateur d'égalité stricte `===` à l'opérateur d'égalité abstraite plus faible `==`. `==` comparera deux variables après les avoir converties en un type commun. Il n'y a pas de conversion de type dans `===`, et les deux variables doivent être du même type pour être égales.
+
+**Autrement :** Les variables inégales peuvent renvoyer true avec l'opérateur `==`.
+
+### 3.10 Exemple de code
+
+```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
+```
+
+Toutes les déclarations ci-dessus renverront false si elles sont utilisées avec `===`
+
+
+
+## ![✔] 3.11 Utilisez Async Await, évitez les fonctions de rappel
+
+**TL;PL :** Node 8 LTS prend désormais entièrement en charge Async-wait. Il s'agit d'une nouvelle façon de gérer le code asynchrone qui remplace les fonctions de rappel et les promesses. L'attente asynchrone n'est pas bloquante et rend le code asynchrone synchrone. Le meilleur cadeau que vous puissiez faire à votre code est d'utiliser async-wait qui fournit une syntaxe de code beaucoup plus compacte et familière comme try-catch.
+
+**Autrement :** La gestion des erreurs asynchrones dans le style des fonctions de rappel est probablement le chemin le plus rapide vers l'enfer - ce style oblige de vérifier les erreurs partout, à gérer les imbrications de code gênantes et rend difficile la compréhension du flux du code.
+
+🔗[**Plus d'infos :** guide pour async-await 1.0](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 Utiliser les expressions de fonction fléchée (=>)
+
+**TL;PL :** Bien qu'il soit recommandé d'utiliser async-wait et d'éviter les paramètres de fonction lorsque vous traitez avec des API plus anciennes qui acceptent des promesses ou des rappels - les fonctions fléchées rendent la structure de code plus compacte et gardent le contexte lexical de la fonction racine (c'est-à-dire `this`).
+
+**Autrement :** Un code plus long (dans les fonctions ES5) est plus sujet aux bogues et lourd à lire.
+
+🔗 [**Plus d'infos : il est temps d'adopter les fonctions fléchées**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
+
+
+
+# `4. Tests et pratiques générales de qualité`
+
+## ![✔] 4.1 Au minimum, écrivez des tests API (pour chaque composant)
+
+**TL;PL :** La plupart des projets n'ont tout simplement pas de test automatisé en raison de délais courts ou souvent le « projet de test » est devenu incontrôlable et a été abandonné. Pour cette raison, priorisez et commencez par les tests d'API, qui est le moyen le plus simple d'écrire et qui offre plus de couverture que les tests unitaires (vous pouvez même créer des tests d'API sans code à l'aide d'outils comme [Postman](https://www.getpostman.com/)). Par la suite, si vous avez plus de ressources et de temps, continuez avec des types de tests avancés tels que les tests unitaires, les tests DB (base de données), les tests de performances, etc.
+
+**Autrement :** Vous pouvez passer de longues journées à écrire des tests unitaires pour découvrir que vous n'avez qu'une couverture système de 20%
+
+
+
+## ![✔] 4.2 Incluez 3 parties dans chaque nom de test
+
+**TL;PL :** Donnez un nom de test éloquent selon son niveau d'exigences pour qu'il soit compréhensible par les ingénieurs et développeurs de l'assurance qualité qui ne sont pas familiers avec les codes internes. Indiquez dans le nom du test ce qui est testé (élément du test), dans quelles circonstances et quel est le résultat attendu.
+
+**Autrement :** Un déploiement vient d'échouer, un test nommé « Ajoute un produit » a échoué. Cela vous indique-t-il exactement ce qui ne fonctionne pas correctement ?
+
+🔗[**Plus d'infos : incluez 3 parties dans chaque nom de test**](./sections/testingandquality/3-parts-in-name.french.md)
+
+
+
+## ![✔] 4.3 Structurez vos tests avec le format AAA
+
+**TL;PL :** Structurez vos tests avec 3 sections bien séparées : Arrange, Act & Assert (AAA). La première partie comprend la configuration du test, puis l'exécution de l'unité testée et enfin la phase d'assertion (vérification). Le respect de cette structure garantit que le lecteur n'utilise pas de le CPU de son cerveau pour comprendre le plan de test.
+
+**Autrement :** Non seulement vous passez de longues heures par jour à comprendre le code principal, mais maintenant, ce qui aurait dû être la partie la plus simple de la journée (les tests) accroche votre cerveau
+
+🔗[**Plus d'infos : structurez vos tests avec le format AAA**](./sections/testingandquality/aaa.french.md)
+
+
+
+## ![✔] 4.4 Détectez les problèmes de code avec un linter
+
+**TL;PL :** Utilisez un linter de code pour vérifier la qualité et détecter les antipatterns au plus tôt. Exécutez-le avant les tests et ajoutez-le en tant que git-hook de pré-commit pour diminuer le temps nécessaire pour examiner et corriger tout problème. Vérifiez également la [section 3](#3-style-du-code) sur les pratiques de style de code.
+
+**Autrement :** Vous pouvez laisser passer un code antipatterns et éventuellement vulnérable sur votre environnement de production.
+
+
+
+## ![✔] 4.5 Évitez les tests globaux, ajoutez des données pour chaque test
+
+**TL;PL :** Pour éviter le chevauchement de test et expliquer facilement le déroulement du test, chaque test doit ajouter et agir sur son propre ensemble d'enregistrement de la base de données. Chaque fois qu'un test a besoin de récupérer ou de présumer l'existence de certaines données de la BD - il doit explicitement ajouter ces données et éviter de modifier tout autre enregistrement.
+
+\***\*Autrement :** Considérez un scénario où le déploiement est interrompu à cause de l'échec des tests, l'équipe va maintenant passer un temps d'investigation précieux qui se terminera par une triste conclusion : le système fonctionne bien, les tests interfèrent cependant les uns avec les autres et interrompent la construction.
+
+🔗[**Plus d'infos : évitez les tests globaux, ajoutez des données pour chaque test**](./sections/testingandquality/avoid-global-test-fixture.french.md)
+
+
+
+## ![✔] 4.6 Inspectez en permanence les dépendances vulnérables
+
+**TL;PL :** Même les dépendances les plus réputées telles qu'Express ont des vulnérabilités connues. Cela peut être facilement apprivoisé à l'aide d'outils communautaires et commerciaux tels que 🔗 [npm audit](https://docs.npmjs.com/cli/audit) et 🔗 [snyk.io](https://snyk.io) qui peuvent être appelé depuis votre CI pour chaque construction.
+
+**Autrement :** Garder votre code propre contre les vulnérabilités sans outils dédiés nécessitera de suivre en permanence les publications en ligne sur les nouvelles menaces. C'est assez fastidieux.
+
+
+
+## ![✔] 4.7 Étiquetez vos tests
+
+**TL;PL :** Différents tests doivent s'exécuter selon différents scénarios : test d'intégrité, sans IO, les tests doivent s'exécuter lorsqu'un développeur enregistre ou commit un fichier, les tests complets de bout en bout s'exécutent généralement lorsqu'une nouvelle « pull request » est soumise, etc. Cela peut être réalisé en étiquetant les tests avec des mots clés comme #IO #api #integrite afin que vous puissiez utiliser votre harnais de test et invoquer le sous-ensemble souhaité. Par exemple, voici comment vous invoqueriez uniquement le groupe de test d'intégrité avec [Mocha](https://mochajs.org/) : mocha --grep 'sanity'
+
+**Autrement :** Exécutez tous les tests, y compris les tests qui effectuent des dizaines de requêtes sur la base de données, chaque fois qu'un développeur apporte un petit changement, cela peut être extrêmement lent et souvent les développeurs s'abstiennent de faire des tests.
+
+
+
+## ![✔] 4.8 Vérifiez votre couverture de test, cela aide à identifier les mauvaises conception de test
+
+**TL;PL :** Les outils de couverture de code comme [Istanbul](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc) sont parfaits pour 3 raisons : ils sont gratuits (aucun effort n'est nécessaire pour bénéficier de ces rapports), ils aident à identifier une diminution de la couverture des tests, et enfin et surtout, ils mettent en évidence les incompatibilités de test : en regardant les rapports de couverture de code en couleur, vous remarquerez peut-être, par exemple, des zones de code qui ne sont jamais testées comme les clauses catch (ce qui signifie que les tests invoquent uniquement les chemins positifs et non le comportement de l'application en cas d'erreur). Configurez-les pour faire échouer les constructions si la couverture tombe sous un certain seuil.
+
+**Autrement :** Il n'y aura aucune mesure automatisée vous indiquant quand une grande partie de votre code n'est pas couverte par les tests
+
+
+
+## ![✔] 4.9 Inspectez les paquets obsolètes
+
+**TL;PL :** Utilisez votre outil préféré (par exemple, `npm outdated` ou [npm-check-updates](https://www.npmjs.com/package/npm-check-updates)) pour détecter les paquets installés qui sont obsolètes, injectez cette vérification dans votre CI et même faites échouer une construction dans un scénario critique. Par exemple, un scénario critique peut se produire lorsqu'un paquet installé a 5 patchs de retard (par exemple, la version locale est 1.3.1 et la version du référentiel est 1.3.8) ou quand il est marqué comme obsolète par son auteur - stoppez la construction et empêchez le déploiement de cette version.
+
+**Autrement :** Votre production exécutera des paquets qui ont été explicitement étiquetés par leur auteur comme risqués.
+
+
+
+## ![✔] 4.10 Utilisez pour les tests e2e un environnement proche de la production
+
+**TL;PL :** Les tests de bout en bout (e2e) qui comprennent l'utilisation de données en direct sont les maillons les plus faibles du processus du CI car ils dépendent de plusieurs services complexes comme la base de données. Utilisez un environnement de test continue aussi proche que possible de votre production actuelle. (Un oubli pour continue ici. A en juger par la clause **Autrement**, cela devrait mentionner docker-compose)
+
+**Autrement :** Sans docker-compose, les équipes doivent maintenir une base de données de test pour chaque environnement de test, y compris les machines des développeurs, garder toutes ces bases de données synchronisées afin que les résultats des tests ne varient pas d'un environnement à l'autre.
+
+
+
+## ![✔] 4.11 Refactorisez régulièrement à l'aide d'outils d'analyse statique
+
+**TL;PL :** L'utilisation d'outils d'analyse statique vous aide en donnant des moyens concrets d'améliorer la qualité du code et permet de maintenir votre code. Vous pouvez ajouter des outils d'analyse statique à votre CI pour échouer lorsqu'il trouve du code incorrect. Ses principaux arguments de vente par rapport au contrôle ordinaire de code sont la capacité d'inspecter la qualité dans le contexte de plusieurs fichiers (par exemple, détecter les doublons), d'effectuer une analyse avancée (par exemple la complexité du code) et de suivre l'historique et la progression des problèmes de code. Deux exemples d'outils que vous pouvez utiliser sont [Sonarqube](https://www.sonarqube.org/) (+ de 2 600 [étoiles](https://github.com/SonarSource/sonarqube)) et [Code Climate](https://codeclimate.com/) (+ de 1 500 [étoiles](https://github.com/codeclimate/codeclimate)).
+
+**Autrement :** Avec une mauvaise qualité de code, les bogues et les performances seront toujours un problème qu'aucune nouvelle bibliothèque brillante ou fonctionnalité de pointe ne peut résoudre.
+
+🔗[**Plus d'infos: refactorisation !**](./sections/testingandquality/refactoring.french.md)
+
+
+
+## ![✔] 4.12 Choisissez soigneusement votre plateforme CI (Jenkins vs CircleCI vs Travis vs Rest of the world)
+
+**TL;PL :** Votre plateforme d'intégration continue (CICD) hébergera tous les outils de qualité (par exemple test, lint), elle devrait donc être accompagnée d'un écosystème dynamique de plugins. [Jenkins](https://jenkins.io/) était utilisé par défaut pour de nombreux projets car il a la plus grande communauté avec une plateforme très puissante au prix d'une configuration complexe qui nécessite une courbe d'apprentissage abrupte. De nos jours, il est devenu beaucoup plus facile de mettre en place une solution CI en utilisant des outils SaaS comme [CircleCI](https://circleci.com) et d'autres. Ces outils permettent de créer un pipeline de CI flexible sans avoir à gérer l'ensemble de l'infrastructure. Finalement, c'est un compromis entre robustesse et rapidité - choisissez votre camp avec soin.
+
+**Autrement :** Le choix d'un fournisseur de niche peut vous bloquer une fois que vous aurez besoin d'une personnalisation avancée. En revanche, faire appel à Jenkins pourrait vous faire perdre un temps précieux à la mise en place de l'infrastructure.
+
+🔗[**Plus d'infos : choisissez soigneusement votre plateforme CI**](./sections/testingandquality/citools.french.md)
+
+## ![✔] 4.13 Testez vos middlewares de manière isolée
+
+**TL;PL :** Lorsqu'un middleware contient une logique immense qui couvre de nombreuses requêtes, cela vaut la peine de le tester de manière isolée sans réveiller l'ensemble du framework du web. Cela peut être facilement réalisé en espionnant les objets {req, res, next}.
+
+**Autrement :** Un bogue dans le middleware Express === un bogue dans toutes ou la plupart des requêtes
+
+🔗 [**Plus d'infos : testez vos middlewares de manière isolée**](./sections/testingandquality/test-middlewares.french.md)
+
+
+
+# `5. Pratiques de mise en production`
+
+## ![✔] 5.1. Surveillance
+
+**TL;PL :** La surveillance est un jeu qui consiste à découvrir les problèmes avant que les clients ne les trouvent - il est évident qu'il faut accorder une importance sans précédent à cette question. Le marché est submergé d'offres, pensez donc à commencer par définir les mesures de base que vous devez suivre (mes suggestions à l'intérieur), puis passez en revue les fonctionnalités supplémentaires et choisissez la solution qui coche toutes les cases. Cliquez sur « l'essentiel » ci-dessous pour un aperçu des solutions.
+
+**Autrement :** Échec === clients déçus. C'est simple.
+
+🔗 [**Plus d'infos : surveillance !**](./sections/production/monitoring.french.md)
+
+
+
+## ![✔] 5.2. Augmentez la clarté à l'aide de la journalisation intelligente
+
+**TL;PL :** Les journaux peuvent être un stupide inventaire de relevés de débogage ou le facilitateur d'un magnifique tableau de bord qui raconte l'histoire de votre application. Prévoyez votre plateforme de journalisation dès le premier jour : comment les logs sont collectés, stockés et analysés pour s'assurer que les informations souhaitées (par exemple le taux d'erreur, le suivi d'une transaction complète via des services et des serveurs, etc.) peuvent réellement être exploitées.
+
+**Autrement :** Vous vous retrouvez avec une boîte noire qui est difficile à analyser, puis vous commencez à réécrire toutes les instructions de journalisation pour ajouter des informations supplémentaires.
+
+🔗 [**Plus d'infos : augmentez la clarté à l'aide de la journalisation intelligente**](./sections/production/smartlogging.french.md)
+
+
+
+## ![✔] 5.3. Déléguez tout ce qui est possible (par exemple gzip, SSL) à un proxy inverse
+
+**TL;PL :** Node est terriblement mauvais pour faire des tâches gourmandes en CPU comme la compression avec gzip, terminaison SSL, etc. Vous devriez utiliser à la place des services de middleware « réels » comme nginx, HAproxy ou des services de fournisseurs du cloud.
+
+**Autrement :** Votre pauvre processus restera occupé à faire des tâches d'infrastructure au lieu de s'occuper du cœur de votre application et les performances se dégraderont en conséquence.
+
+🔗 [**Plus d'infos : déléguez tout ce qui est possible (par exemple gzip, SSL) à un proxy inverse**](./sections/production/delegatetoproxy.french.md)
+
+
+
+## ![✔] 5.4. Verrouillez les dépendances
+
+**TL;PL :** Votre code doit être identique dans tous les environnements, mais étonnamment npm laisse les dépendances fluctuer entre les environnements par défaut - lorsque vous installez des paquets dans différents environnements, il essaie de récupérer la dernière version du patch des paquets. Surmontez cela en utilisant les fichiers de configuration de npm, .npmrc, qui indiquent à chaque environnement de sauvegarder la version exacte (et non la dernière) de chaque paquet. Alternativement, pour un contrôle plus fin, utilisez `npm shrinkwrap`. \*Mise à jour : à partir de NPM5, les dépendances sont verrouillées par défaut. Le nouveau gestionnaire de paquets en place, Yarn, nous a aussi fourni une couverture par défaut.
+
+**Autrement :** Le service qualité testera le code de manière approfondie et approuvera une version qui se comportera différemment en production. Pire encore, différents serveurs dans le même cluster de production peuvent exécuter un code différent.
+
+🔗 [**Plus d'infos : verrouillez les dépendances**](./sections/production/lockdependencies.french.md)
+
+
+
+## ![✔] 5.5. Protégez la disponibilité du processus avec des bons outils
+
+**TL;PL :** Le processus doit continuer et être redémarré en cas d'échec. Pour des scénarios simples, des outils de gestion de processus comme PM2 peuvent suffire, mais dans le monde « dockérizé » d'aujourd'hui, les outils de gestion de cluster doivent également être pris en compte.
+
+**Autrement :** L'exécution simultanée de dizaines d'instances sans stratégie claire et trop d'outils (gestion de cluster, docker, PM2) pourrait conduire au chaos du DevOps.
+
+🔗 [**Plus d'infos : protégez la disponibilité du processus avec des bons outils**](./sections/production/guardprocess.french.md)
+
+
+
+## ![✔] 5.6. Utilisez tous les cœurs du CPU
+
+**TL;PL :** Dans sa forme de base, une application Node fonctionne sur un seul cœur de CPU alors que tous les autres sont laissés au repos. Il est de votre devoir de répliquer le processus Node et d'utiliser tous les CPU - Pour les petites et moyennes applications, vous pouvez utiliser Node Cluster ou PM2. Pour une application plus grande, pensez à répliquer le processus à l'aide d'un cluster Docker (par exemple K8S, ECS) ou des scripts de déploiement basés sur le système d'initialisation Linux (par exemple systemd).
+
+**Autrement :** Votre application n'utilisera probablement que 25% de ses ressources disponibles (!) ou même moins. Notez qu'un serveur typique possède 4 cœurs CPU ou plus, le déploiement naïf de Node.js n'en utilise qu'un (même en utilisant des services PaaS comme AWS beanstalk !)
+
+🔗 [**Plus d'infos : utilisez tous les cœurs du CPU**](./sections/production/utilizecpu.french.md)
+
+
+
+## ![✔] 5.7. Créez un « point de terminaison de maintenance »
+
+**TL;PL :** Exposez dans une API sécurisée un ensemble d'informations liées au système, comme l'utilisation de la mémoire et le REPL, etc. Bien qu'il soit fortement recommandé de s'appuyer sur des outils standard et éprouvés au combat, certaines informations et opérations précieuses sont plus faciles à utiliser à l'aide de code.
+
+**Autrement :** Vous constaterez que vous effectuez de nombreuses « livraisons de diagnostics » - la livraison de code vers la production uniquement pour extraire des informations à des fins de diagnostic.
+
+🔗 [**Plus d'infos : créez un « point de terminaison de maintenance »**](./sections/production/createmaintenanceendpoint.french.md)
+
+
+
+## ![✔] 5.8. Découvrez les erreurs et les indisponibilités à l'aide des produits APM
+
+**TL;PL :** Les produits de surveillance et de performance des applications (a.k.a APM) mesurent de manière proactive la base de code et l'API afin qu'ils puissent aller automatiquement au-delà de la surveillance traditionnelle et mesurer l'expérience utilisateur globale à travers les services et les tiers. Par exemple, certains produits APM peuvent mettre en évidence une transaction qui se charge trop lentement du côté des utilisateurs finaux tout en suggérant la cause principale.
+
+**Autrement :** Vous pourriez consacrer beaucoup d'efforts à mesurer les performances et l'indisponibilité de l'API, vous ne saurez probablement jamais quelles sont vos parties de code les plus lentes dans le scénario du monde réel et comment celles-ci affectent l'expérience utilisateur.
+
+🔗 [**Plus d'infos : découvrez les erreurs et les indisponibilités à l'aide des produits APM**](./sections/production/apmproducts.french.md)
+
+
+
+## ![✔] 5.9. Préparez votre code pour la production
+
+**TL;PL :** Codez en pensant à la solution définitive, planifiez la production dès le premier jour. Cela semble un peu vague, j'ai donc compilé quelques conseils de développement qui sont étroitement liés à la maintenance de la production (cliquez sur l'essentiel ci-dessous)
+
+**Autrement :** Même le champion du monde Architecte/DevOps ne sauvera pas un système mal écrit.
+
+🔗 [**Plus d'infos : préparez votre code pour la production**](./sections/production/productioncode.french.md)
+
+
+
+## ![✔] 5.10. Mesurez et protégez l'utilisation de la mémoire
+
+**TL;PL :** Node.js a des relations controversées avec la mémoire : le moteur v8 a de faibles limites sur l'utilisation de la mémoire (1.4GB) et il y a des moyens connus pour faire fuir la mémoire dans le code de Node - donc surveiller la mémoire du processus de Node est une chose indispensable. Dans les petites applications, vous pouvez mesurer la mémoire périodiquement en utilisant des commandes shell mais dans les applications de taille moyenne, vous pouvez envisager de faire de votre surveillance mémoire via un système de surveillance robuste.
+
+**Autrement :** La mémoire de votre processus peut fuir une centaine de mégaoctets par jour, comme cela s'est produit chez [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)
+
+🔗 [**Plus d'infos : mesurez et protégez l'utilisation de la mémoire**](./sections/production/measurememory.french.md)
+
+
+
+## ![✔] 5.11. Retirez vos ressources frontend de Node
+
+**TL;PL :** Servez le contenu du frontend en utilisant un middleware dédié (nginx, S3, CDN) parce que les performances de Node sont vraiment diminuées lors du traitement de nombreux fichiers statiques en raison de son modèle mono-processus.
+
+**Autrement :** Votre unique processus de Node sera occupé à diffuser des centaines de fichiers html/images/angular/react au lieu d'allouer toutes ses ressources à la tâche pour laquelle il est conçu - fournir du contenu dynamique
+
+🔗 [**Plus d'infos : retirez vos ressources frontend de Node**](./sections/production/frontendout.french.md)
+
+
+
+## ![✔] 5.12. Soyez sans état, tuez vos serveurs presque tous les jours
+
+**TL;PL :** Stockez tout type de données (par exemple, sessions utilisateur, cache, fichiers téléchargés) dans des stockages de données externes. Envisagez de « tuer » vos serveurs périodiquement ou d'utiliser une plateforme « sans serveur » (par exemple AWS Lambda) qui impose explicitement un comportement sans état.
+
+**Autrement :** La défaillance d'un serveur particulier entraînera l'arrêt des applications au lieu de simplement tuer une machine défectueuse. De plus, l'élasticité de l'extensibilité sera plus difficile à obtenir en raison de la dépendance à un serveur spécifique.
+
+🔗 [**Plus d'infos : soyez sans état, tuez vos serveurs presque tous les jours**](./sections/production/bestateless.french.md)
+
+
+
+## ![✔] 5.13. Utilisez des outils qui détectent automatiquement les vulnérabilités
+
+**TL;PL :** Même les dépendances les plus réputées comme Express ont des vulnérabilités connues (de temps en temps) qui peuvent mettre un système en danger. Cela peut être facilement maîtrisé en utilisant des outils communautaires et commerciaux qui vérifient constamment les vulnérabilités et avertissent (localement ou sur GitHub), certains peuvent même les corriger immédiatement.
+
+**Autrement :** Si vous ne disposez pas d'outils dédiés pour protéger votre code contre les vulnérabilités, vous devrez suivre en permanence les publications en ligne sur les nouvelles menaces. C'est assez fastidieux.
+
+🔗 [**Plus d'infos : Utilisez des outils qui détectent automatiquement les vulnérabilités**](./sections/production/detectvulnerabilities.french.md)
+
+
+
+## ![✔] 5.14. Attribuez un id de transaction à chaque relevé du journal
+
+Également connu sous le nom de corrélation id / transit id / tracing id / request id / request context / etc.
+
+**TL;PL :** Attribuez le même identifiant, transaction-id : {une valeur}, à chaque entrée du journal à l'intérieur d'une même requête. Ensuite, lors de l'inspection des erreurs dans les journaux, il est facile de conclure ce qui s'est passé avant et après. Malheureusement, cela n'est pas facile à réaliser dans Node en raison de sa nature asynchrone, consultez les exemples de code. Jusqu'à la version 14 de Node, cela n'était pas facile à réaliser en raison de la nature asynchrone de Node, mais depuis l'arrivée de AsyncLocalStorage, cela est devenu possible et plus facile que jamais. Consultez les exemples de code fournis.
+
+**Autrement :** L'examen d'un journal d'erreurs de production sans le contexte (ce qui s'est passé auparavant) rend le travail de réflexion beaucoup plus difficile et lent.
+
+🔗 [**Plus d'infos : attribuez un ‘TransactionId’ à chaque relevé du journal**](./sections/production/assigntransactionid.french.md)
+
+
+
+## ![✔] 5.15. Définissez `NODE_ENV=production`
+
+**TL;PL :** Définissez la variable d'environnement `NODE_ENV` avec « production » ou « development » pour indiquer si les optimisations de production doivent être activées - de nombreux paquets npm déterminent l'environnement en cours et optimisent leur code pour la production.
+
+**Autrement :** L'omission de cette simple propriété pourrait fortement dégrader les performances. Par exemple, lors de l'utilisation d'Express pour le rendu côté serveur, l'omission de `NODE_ENV` le rend trois fois plus lent !
+
+🔗 [**Plus d'infos : définissez NODE_ENV=production**](./sections/production/setnodeenv.french.md)
+
+
+
+## ![✔] 5.16. Concevez des déploiements automatisés, atomiques et sans interruption de service
+
+**TL;PL :** Les études montrent que les équipes qui effectuent de nombreux déploiements réduisent la probabilité de graves problèmes en production. Les déploiements rapides et automatisés qui ne nécessitent pas d'étapes manuelles risquées ni d'interruptions de service améliorent considérablement le processus de déploiement. Vous devriez probablement y parvenir en utilisant Docker combiné à des outils de CI, car ils sont devenus la norme du secteur pour un déploiement optimisé.
+
+**Autrement :** Déploiements longs -> arrêt de la production et erreur humaine -> équipe peu confiante dans la réalisation du déploiement -> moins de déploiements et de fonctionnalités.
+
+
+
+## ![✔] 5.17. Utilisez une version LTS de Node.js
+
+**TL;PL :** Assurez-vous d'utiliser une version LTS de Node.js pour recevoir les corrections de bogues critiques, les mises à jour de sécurité et les améliorations de performance
+
+**Autrement :** Les bogues ou vulnérabilités récemment découverts pourraient être utilisés pour exploiter une application en production, et votre application pourrait devenir non supportée par divers modules et plus difficile à maintenir
+
+🔗 [**Plus d'infos : Utilisez une version LTS de Node.js**](./sections/production/LTSrelease.french.md)
+
+
+
+## ![✔] 5.18. Ne redirigez pas les journaux vers l'application
+
+**TL;PL :** Les destinations des journaux ne devraient pas être codées en dur par les développeurs dans le code de l'application, mais devraient plutôt être définies par l'environnement d'exécution dans lequel l'application s'exécute. Les développeurs doivent écrire des journaux dans `stdout` en utilisant un utilitaire de journalisation et laisser l'environnement d'exécution (conteneur, serveur, etc.) diriger le flux `stdout` vers la destination appropriée (c'est-à-dire Splunk, Graylog, ElasticSearch, etc.).
+
+**Autrement :** Acheminement des journaux de gestion des applications === difficile à dimensionner, perte de journaux, mauvaise séparation des informations.
+
+🔗 [**Plus d'infos : redirection du journal**](./sections/production/logrouting.french.md)
+
+
+
+## ![✔] 5.19. Installez vos paquets avec `npm ci`
+
+**TL;PL :** Vous devez vous assurer que le code de production utilise la version exacte des paquets avec lesquels vous l'avez testé. Exécutez `npm ci` pour faire une installation propre de vos dépendances correspondant aux fichiers package.json et package-lock.json.
+
+**Autrement :\*\*\*\*** Le service qualité testera le code de manière approfondie et approuvera une version qui se comportera différemment en production. Pire encore, différents serveurs dans le même cluster de production peuvent exécuter un code différent.
+
+🔗 [**Plus d'infos : utilisez npm ci**](./sections/production/installpackageswithnpmci.french.md)
+
+
+
+## ![✔] 6.1. Adoptez les règles de sécurité du linter
+
+
+
+**TL;PL :** Utilisez des plugins de sécurité de linter tels que [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security) pour détecter les vulnérabilités et les problèmes de sécurité le plus tôt possible, de préférence lors de leur codage. Cela peut aider à détecter des vulnérabilités de sécurité comme l'utilisation de eval, l'invocation d'un processus enfant ou l'importation d'un module avec une chaîne littérale (par exemple, une entrée utilisateur). Cliquez sur « Plus d'infos » ci-dessous pour voir des exemples de codes qui seront pris en compte par un linter de sécurité.
+
+**Autrement :** Ce qui aurait pu être une simple défaillance de sécurité pendant le développement devient un problème majeur en production. En outre, le projet peut ne pas suivre des pratiques de sécurité de code conformes, ce qui peut entraîner l'introduction de vulnérabilités ou la divulgation de secrets sensibles dans des dépôts distants.
+
+🔗 [**Plus d'infos : régles du linter**](./sections/security/lintrules.french.md)
+
+
+
+## ![✔] 6.2. Limitez les requêtes simultanées en utilisant un middleware
+
+
+
+**TL;PL :** Les attaques DOS sont très populaires et relativement faciles à mener. Mettre en œuvre la limitation de débit en utilisant un service externe tel que les équilibreurs de charge, les pare-feux, nginx, un paquet [rate-limiter-flexible](https://www.npmjs.com/package/rate-limiter-flexible), ou (pour les applications plus petites et moins critiques) un middleware de limitation de débit (par exemple, [express-rate-limit](https://www.npmjs.com/package/express-rate-limit)).
+
+**Autrement :** Une application pourrait faire l'objet d'une attaque entraînant un déni de service, de ce fait, les utilisateurs réels obtiennent un service dégradé ou indisponible.
+
+🔗 [**Plus d'infos : mettez en œuvre la limitation de débit**](./sections/security/limitrequests.french.md)
+
+
+
+## ![✔] 6.3 Retirez les secrets des fichiers de configuration ou utiliser des paquets pour les crypter
+
+
+
+**TL;PL :** Ne stockez jamais les secrets en clair dans les fichiers de configuration ou le code source. Utilisez plutôt des systèmes de gestion des secrets comme les produits Vault, Kubernetes/Docker Secrets ou des variables d'environnement. En dernier recours, les secrets stockés dans le contenu des sources doivent être cryptés et gérés (clés de roulement, expiration, audit, etc.). Utilisez des hooks de pre-commit/push pour éviter de commeittez des secrets accidentellement.
+
+**Autrement :** Le contenu des sources, même pour les dépôts privés, peut être rendu public par erreur, et tous les secrets sont alors dévoilés. L'accès au contenu des sources pour une partie externe donnera par inadvertance accès à des systèmes connexes (bases de données, apis, services, etc.).
+
+🔗 [**Plus d'infos : gestion des secrets**](./sections/security/secretmanagement.french.md)
+
+
+
+## ![✔] 6.4. Évitez les vulnérabilités d'injection de query avec les bibliothèques ORM/ODM
+
+
+
+**TL;PL :** Pour éviter l'injection SQL/NoSQL et d'autres attaques malveillantes, utilisez toujours un ORM/ODM ou une bibliothèque de base de données qui échappe les données ou prend en charge les queries paramétrées nommées ou indexées et se charge de valider les entrées de l'utilisateur pour les types attendus. N'utilisez jamais simplement des chaînes de template JavaScript ou une concaténation de chaînes pour injecter des valeurs dans les queries, car cela ouvre votre application à un large éventail de vulnérabilités. Toutes les bibliothèques d'accès aux données Node.js réputées (par exemple [Sequelize](https://github.com/sequelize/sequelize), [Knex](https://github.com/tgriesser/knex), [mongoose](https://github.com/Automattic/mongoose)) disposent d'une protection intégrée contre les attaques par injection.
+
+**Autrement :** Une entrée utilisateur non validée ou non assainie pourrait conduire à l'injection de l'opérateur lorsqu'on travaille avec MongoDB pour NoSQL, et le fait de ne pas utiliser un système d'assainissement approprié ou un ORM permettra facilement des attaques par injection SQL, créant une énorme vulnérabilité.
+
+🔗 [**Plus d'infos : Prévention de l'injection de queries à l'aide des bibliothèques ORM/ODM**](./sections/security/ormodmusage.french.md)
+
+
+
+## ![✔] 6.5. Collection des meilleures pratiques génériques en matière de sécurité
+
+**TL;PL :** Il s'agit d'une collection de conseils de sécurité qui n'est pas directement liée à Node.js, l'implémentation de Node n'est pas très différente de toute autre langage. Cliquez pour en savoir plus.
+
+🔗 [**Plus d'infos : les meilleures pratiques communes en matière de sécurité**](./sections/security/commonsecuritybestpractices.french.md)
+
+
+
+## ![✔] 6.6. Adaptez les entêtes de réponse HTTP pour une sécurité accrue
+
+
+
+**TL;PL :** Votre application doit utiliser des entêtes sécurisés pour empêcher les attaquants d'utiliser des attaques courantes comme le cross-site scripting (XSS), le clickjacking et d'autres attaques malveillantes. Celles-ci peuvent être facilement configurées à l'aide de modules tels que [helmet](https://www.npmjs.com/package/helmet).
+
+**Autrement :** Les attaquants pourraient lancer des attaques directes sur les utilisateurs de votre application, ce qui entraînerait d'énormes vulnérabilités de sécurité.
+
+🔗 [**Plus d'infos : utilisation d'entêtes sécurisés dans votre application**](./sections/security/secureheaders.french.md)
+
+
+
+## ![✔] 6.7. Inspectez constamment et automatiquement les dépendances vulnérables
+
+
+
+**TL;PL :** Avec l'écosystème npm, il est courant d'avoir de nombreuses dépendances pour un projet. Les dépendances doivent toujours être contrôlées lorsque de nouvelles vulnérabilités sont détectées. Utilisez des outils comme [npm audit](https://docs.npmjs.com/cli/audit) ou [snyk](https://snyk.io/) pour suivre, surveiller et corriger les dépendances vulnérables. Intégrez ces outils à votre configuration CI afin de détecter une dépendance vulnérable avant qu'elle ne passe en production.
+
+**Autrement :** Un attaquant pourrait détecter votre framework Web et attaquer toutes ses vulnérabilités connues.
+
+🔗 [**Plus d'infos : sécurité des dépendances**](./sections/security/dependencysecurity.french.md)
+
+
+
+## ![✔] 6.8. Protégez les mots de passe/secrets des utilisateurs à l'aide de bcrypt ou scrypt
+
+
+
+**TL;PL :** Les mots de passe ou les secrets (par exemple les clés API) doivent être stockés en utilisant une fonction de hachage sécurisée + un salt comme `bcrypt`,`scrypt`, ou dans le pire des cas `pbkdf2`.
+
+**Autrement :** Les mots de passe et les secrets qui sont stockés sans utiliser de fonction sécurisée sont vulnérables au brute-force et aux attaques de dictionnaire qui mèneront à leur divulgation.
+
+🔗 [**Plus d'infos : mots de passe utilisateur**](./sections/security/userpasswords.french.md)
+
+
+
+## ![✔] 6.9. Échappez les sorties HTML, JS et CSS
+
+
+
+**TL;PL :** Les données non approuvées qui sont envoyées au navigateur peuvent être exécutées au lieu d'être simplement affichées, ce qui est communément appelé une attaque de script intersite (XSS). Atténuez cela en utilisant des bibliothèques dédiées qui marquent explicitement les données comme du contenu pur qui ne devrait jamais être exécuté (par exemple encodage, échappement).
+
+**Autrement :** Un attaquant pourrait stocker du code JavaScript malveillant dans votre base de données qui sera ensuite envoyé tel quel aux pauvres clients.
+
+🔗 [**Plus d'infos : échappez la sortie**](./sections/security/escape-output.french.md)
+
+
+
+## ![✔] 6.10. Validez les schémas JSON entrants
+
+
+
+**TL;PL :** Validez la charge utile du corps des requêtes entrantes et assurez-vous qu'elle répond aux exigences, sinon échouez rapidement. Pour éviter un codage de validation fastidieux pour chaque route, vous pouvez utiliser des schémas de validation légers basés sur JSON tels que [jsonschema](https://www.npmjs.com/package/jsonschema) ou [joi](https://www.npmjs.com/package/joi).
+
+**Autrement :** Votre générosité et votre approche permissive augmentent considérablement la surface d'attaque et encouragent l'attaquant à essayer de nombreuses entrées jusqu'à ce qu'il trouve une combinaison pour planter l'application.
+
+🔗 [**Plus d'infos : validez les schémas JSON entrants**](./sections/security/validation.french.md)
+
+
+
+## ![✔] 6.11. Prenez en charge le blocage des JWT
+
+
+
+**TL;PL :** Lorsque vous utilisez des jetons Web JSON (par exemple, avec [Passport.js](https://github.com/jaredhanson/passport)), il n'existe par défaut aucun mécanisme permettant de révoquer l'accès aux jetons émis. Lorsque vous découvrez une activité malveillante de la part d'un utilisateur, il n'y a aucun moyen de l'empêcher d'accéder au système tant qu'il détient un jeton valide. Pour atténuer ce problème, il est possible de mettre en place une liste de blocage des jetons non fiables qui sont validés à chaque requête.
+
+**Autrement :** Les jetons expirés ou égarés pourraient être utilisés de manière malveillante par un tiers pour accéder à une application et se faire passer pour le propriétaire du jeton.
+
+🔗 [**Plus d'infos : bloquez les jetons Web JSON**](./sections/security/expirejwt.french.md)
+
+
+
+## ![✔] 6.12. Empêchez les attaques brute-force perpétrées contre les autorisations
+
+
+
+**TL;PL :** Une technique simple et puissante consiste à limiter les tentatives d'autorisation en utilisant deux mesures :
+
+1. Le premier est le nombre de tentatives infructueuses consécutives par le même ID/nom unique d'utilisateur et la même adresse IP.
+2. Le deuxième est le nombre de tentatives infructueuses à partir d'une adresse IP sur une longue période de temps. Par exemple, bloquez une adresse IP si elle fait 100 tentatives infructueuses en une journée.
+
+**Autrement :** Un attaquant peut lancer des tentatives de mot de passe automatisées illimitées pour accéder à des comptes privilégiés sur une application.
+
+🔗 [**Plus d'infos : restrictions du nombre de connexions**](./sections/security/login-rate-limit.french.md)
+
+
+
+## ![✔] 6.13. Exécutez Node.js en tant qu'utilisateur non root
+
+
+
+**TL;PL :** Il existe un scénario répandu dans lequel Node.js s'exécute en tant qu'utilisateur root avec des autorisations illimitées. Par exemple, c'est le comportement par défaut dans les conteneurs Docker. Il est recommandé de créer un utilisateur non root et de l'intégrer dans l'image du Docker (exemples donnés ci-dessous) ou d'exécuter le processus sous le nom de cet utilisateur en invoquant le conteneur avec l'indicateur « -u nom_utilisateur ».
+
+**Autrement :** Un attaquant qui réussit à exécuter un script sur le serveur obtient un pouvoir illimité sur la machine locale (par exemple, modifier iptable et réacheminer le trafic vers son serveur).
+
+🔗 [**Plus d'infos : exécutez Node.js en tant qu'utilisateur non root**](./sections/security/non-root-user.french.md)
+
+
+
+## ![✔] 6.14. Limitez la capacité des données utiles en utilisant un proxy inverse ou un middleware
+
+
+
+**TL;PL :** Plus les données utiles du corps sont grandes, plus votre processus unique travaille intensément pour les traiter. C'est l'occasion pour les attaquants de mettre les serveurs à genoux sans qu'il y ait beaucoup de requêtes (attaques DOS/DDOS). Atténuez cela en limitant la taille du corps des requêtes entrantes en périphérie (par exemple, pare-feu, ELB) ou en configurant [express body parser](https://github.com/expressjs/body-parser) pour accepter uniquement les données utiles de petite taille.
+
+**Autrement :** Votre application devra traiter des requêtes importantes, incapable de traiter les autres travaux importants qu'elle doit accomplir, ce qui aura des conséquences sur les performances et la vulnérabilité aux attaques DOS.
+Votre application devra faire face à de grosses requêtes, incapable de traiter les autres travaux importants qu'elle doit accomplir, entraînant des implications en termes de performances et une vulnérabilité face aux attaques DOS.
+🔗 [**Plus d'infos : limitez la capacité des données utiles**](./sections/security/requestpayloadsizelimit.french.md)
+
+
+
+## ![✔] 6.15. Évitez les instruction eval de JavaScript
+
+
+
+**TL;PL :** `eval` est diabolique car il permet d'exécuter du code JavaScript personnalisé pendant l'exécution. Il ne s'agit pas seulement d'un problème de performances, mais également d'un problème de sécurité important en raison du code JavaScript malveillant qui peut provenir de la saisie de l'utilisateur. Une autre fonctionnalité du langage à éviter est le constructeur `new Function`. Il ne faut pas non plus passer de code JavaScript dynamique à `setTimeout` et `setInterval`.
+
+**Autrement :** Un code JavaScript malveillant trouve un moyen d'accéder au texte passé dans `eval` ou d'autres fonctions d'évaluation en temps réel du langage JavaScript, et obtiendra un accès complet aux autorisations JavaScript sur la page. Cette vulnérabilité se manifeste souvent par une attaque XSS.
+
+🔗 [**Plus d'infos : évitez les instruction eval de JavaScript**](./sections/security/avoideval.french.md)
+
+
+
+## ![✔] 6.16. Empêchez une mauvaise RegEx de surcharger l'exécution de votre unique processus
+
+
+
+**TL;PL :** Les expressions régulières, bien qu'elles soient pratiques, constituent une réelle menace pour les applications JavaScript en général et la plateforme Node.js en particulier. La saisie d'un texte par l'utilisateur peut nécessiter un nombre exceptionnel de cycles du CPU pour être traitée. Le traitement RegEx pourrait être inefficace, à tel point qu'une seule requête qui valide 10 mots peut bloquer toute la boucle d'événement pendant 6 secondes et mettre l'unité centrale en 🔥. Pour cette raison, préférez les paquets de validation tiers comme [validator.js](https://github.com/chriso/validator.js) au lieu d'écrire vos propres modèles de regex, ou utilisez [safe-regex](https://github.com/substack/safe-regex) pour détecter les modèles de regex vulnérables.
+
+**Autrement :** Des RegEx mal écrites pourraient être susceptibles de faire l'objet d'attaques DoS par expression régulière qui bloqueraient complètement la boucle de l'événement. Par exemple, le populaire paquet "moment" a été déclaré vulnérable par une utilisation malveillante de RegEx en novembre 2017.
+
+🔗 [**Plus d'infos : empêcher une RegEx malveillante**](./sections/security/regex.french.md)
+
+
+
+## ![✔] 6.17. Évitez le chargement de modules à l'aide d'une variable
+
+
+
+**TL;PL :** Évitez de demander/importer un autre fichier dont le chemin d'accès a été donné en paramètre, car on peut craindre qu'il provienne d'une saisie de l'utilisateur. Cette règle peut être étendue pour l'accès aux fichiers en général (c'est-à-dire `fs.readFile()`) ou à d'autres ressources sensibles avec des variables dynamiques provenant d'une entrée utilisateur. Le linter [Eslint-plugin-security](https://www.npmjs.com/package/eslint-plugin-security) peut détecter de tels modèles et avertir suffisamment tôt.
+
+**Autrement :** Une entrée utilisateur malveillante pourrait trouver son chemin vers un paramètre qui est utilisé pour exiger des fichiers falsifiés, par exemple, un fichier précédemment téléchargé sur le système de fichiers, ou accéder à des fichiers système déjà existants.
+
+🔗 [**Plus d'infos : chargement sécurisé des modules**](./sections/security/safemoduleloading.french.md)
+
+
+
+## ![✔] 6.18. Exécutez un code dangereux dans un bac à sable
+
+
+
+**TL;PL :** Lorsqu'il s'agit d'exécuter du code externe donné en cours d'exécution (par exemple un plugin), utilisez un environnement d'exécution de type « bac à sable » (« sandbox ») qui isole et protège le code principal contre le plugin. Ceci peut être réalisé en utilisant un processus dédié (par exemple `cluster.fork()`), un environnement sans serveur ou des paquets npm dédiés qui agissent comme un bac à sable.
+
+**Autrement :** Un plugin peut attaquer à travers une variété infinie d'options comme les boucles infinies, la surcharge de la mémoire et l'accès aux variables sensibles de l'environnement du processus.
+
+🔗 [**Plus d'infos : exécutez un code dangereux dans un bac à sable**](./sections/security/sandbox.french.md)
+
+
+
+## ![✔] 6.19. Soyez particulièrement vigilants lorsque vous travaillez avec des processus fils
+
+
+
+**TL;PL :** Évitez d'utiliser des processus fils lorsque c'est possible et validez et assainissez les entrées pour atténuer les attaques par injection dans l'interface sytème si vous devez encore le faire. Préférez l'utilisation de `child_process.execFile` qui, par définition, n'exécutera qu'une seule commande avec un ensemble d'attributs et ne permettra pas l'expansion des paramètres de l'interface système.
+
+**Autrement :** L'utilisation naïve de processus fils pourrait entraîner l'exécution de commandes à distance ou des attaques par injection dans l'interface système en raison d'une entrée utilisateur malveillante transmise à une commande système non assainie.
+
+🔗 [**Plus d'infos : soyez prudents lorsque vous travaillez avec des processus fils**](./sections/security/childprocesses.french.md)
+
+
+
+## ![✔] 6.20. Masquez les détails des erreurs aux clients
+
+
+
+**TL;PL :** Un gestionnaire d'erreur express intégré masque les détails de l'erreur par défaut. Cependant, il y a de grandes chances que vous implémentiez votre propre logique de traitement des erreurs avec des objets d'erreur personnalisés (considérés par beaucoup comme une meilleure pratique). Si vous le faites, veillez à ne pas renvoyer l'objet Error complet au client, qui pourrait contenir certains détails sensibles de l'application.
+
+**Autrement :** Des détails sensibles de l'application pourraient être divulgués à partir d'informations trouvées dans une trace de pile, tels que les chemins d'accès aux fichiers du serveur, les modules tiers utilisés et d'autres flux de travail internes de l'application qui pourraient être exploités par un attaquant.
+
+🔗 [**Plus d'infos : masquez les détails des erreurs au client**](./sections/security/hideerrors.french.md)
+
+
+
+## ![✔] 6.21. Configurez 2FA pour npm ou Yarn
+
+
+
+**TL;PL :** Toute étape de la chaîne de développement doit être protégée par une authentification multi-facteurs (MFA). npm/Yarn sont une belle opportunité pour les attaquants qui peuvent mettre la main sur le mot de passe d'un développeur. En utilisant les identifiants des développeurs, les attaquants peuvent injecter du code malveillant dans des bibliothèques qui sont largement installées dans les projets et les services. Peut-être même sur le web s'ils sont publiés publiquement. L'activation de l'authentification à deux facteurs dans npm ne laisse pratiquement aucune chance aux attaquants de modifier le code de votre paquet.
+
+**Autrement :** [Avez-vous entendu parler du développeur d'eslint dont le mot de passe a été piraté ?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
+
+
+
+## ![✔] 6.22. Modifiez les paramètres du middleware de session
+
+
+
+**TL;PL :** Chaque framework et technologie web a ses faiblesses connues - dire à un attaquant quel framework web nous utilisons est d'une grande aide pour lui. L'utilisation des paramètres par défaut des middlewares de session peut exposer votre application à des attaques de détournement sur un module ou un framework spécifique, de la même manière que l'entête « X-Powered-By ». Essayez de cacher tout ce qui identifie et révèle votre pile technique (par exemple, Node.js, express).
+
+**Autrement :** Les cookies peuvent être envoyés via des connexions non sécurisées, et un attaquant peut utiliser l'identification de session pour identifier le framework sous-jacent de l'application web, ainsi que les vulnérabilités spécifiques aux modules.
+
+🔗 [**Plus d'infos : cookie et sécurité des sessions**](./sections/security/sessions.french.md)
+
+
+
+## ![✔] 6.23. Évitez les attaques DOS en définissant explicitement le moment où un processus doit s'interrompre
+
+
+
+**TL;PL :** Le processus de Node plante lorsque les erreurs ne sont pas gérées. De nombreuses bonnes pratiques recommandent même de quitter Node même si une erreur a été détectée et traitée. Express, par exemple, plante sur toutes les erreurs asynchrones - à moins que vous n'ayez inclus une clause catch dans les routes. Cela ouvre un point d'attaque très intéressant pour les attaquants qui reconnaissent quelle entrée fait planter le processus et envoient la même requête de manière répétée. Il n'y a pas de remède immédiat à ce problème, mais quelques techniques peuvent atténuer la menace : alertez avec une gravité critique chaque fois qu'un processus se bloque à cause d'une erreur non gérée, valider l'entrée et éviter de planter le processus à cause d'une entrée utilisateur non valide, englober toutes les routes d'une clause catch et envisager de ne pas planter lorsqu'une erreur a été commise dans une requête (par opposition à ce qui se passe globalement).
+
+**Autrement :** Ce n'est qu'une intuition : étant donné le grand nombre d'applications Node.js, si nous essayons de faire passer un corps JSON vide à toutes les requêtes POST - une poignée d'applications plantera. À ce stade, il suffit de répéter l'envoi de la même requête pour faire tomber les applications avec facilité.
+
+
+
+## ![✔] 6.24. Empêchez les redirections dangereuses
+
+
+
+**TL;PL :** Les redirections qui ne valident pas les entrées de l'utilisateur peuvent permettre aux attaquants de lancer des attaques de phishing, de voler les identifiants de l'utilisateur et d'effectuer d'autres actions malveillantes.
+
+**Autrement :** Si un attaquant découvre que vous ne validez pas les données externes fournies par l'utilisateur, il peut exploiter cette vulnérabilité en publiant des liens spécialement conçus sur des forums, des médias sociaux et d'autres lieux publics pour inciter les utilisateurs à cliquer.
+
+🔗 [**Plus d'infos : empêchez les redirections dangereuses**](./sections/security/saferedirects.french.md)
+
+
+
+## ![✔] 6.25. Évitez de publier des secrets dans le registre npm
+
+
+
+**TL;PL :** Des précautions doivent être prises pour éviter le risque de publier accidentellement des secrets dans les registres publics de npm. Un fichier `.npmignore` peut être utilisé pour ignorer des fichiers ou des dossiers spécifiques, ou le tableau `files` dans `package.json` peut agir comme une liste d'autorisation.
+
+**Autrement :** Les clés API, mots de passe ou autres secrets de votre projet sont susceptibles d'être utilisés abusivement par toute personne qui les découvre, ce qui peut entraîner des pertes financières, une usurpation d'identité et d'autres risques.
+
+🔗 [**Plus d'infos : évitez de publier des secrets**](./sections/security/avoid_publishing_secrets.french.md)
+
+
+# `7. Brouillon : Bonnes pratiques de performance`
+
+## Nos contributeurs travaillent sur cette section. [Voulez-vous nous rejoindre ?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
+
+
+
+## ![✔] 7.1. Ne bloquez pas la boucle d'événement
+
+**TL;PL :** Évitez les tâches gourmandes en CPU car elles bloqueront la boucle d'événement principalement mono-thread, il faut les décharger vers un thread dédié, un processus ou même une technologie différente en fonction du contexte.
+
+**Autrement :** Comme la boucle d'événements est bloquée, Node.js sera incapable de traiter d'autres requêtes, ce qui entraînera des retards pour les utilisateurs concurrents. **3000 utilisateurs attendent une réponse, le contenu est prêt à être servi, mais une seule requêtes bloque le serveur pour qu'il ne puisse pas renvoyer les résultats**.
+
+🔗 [**Plus d'infos : ne bloquez pas la boucle d'événement**](./sections/performance/block-loop.french.md)
+
+
+
+## ![✔] 7.2. Préférez les méthodes JS natives aux utilitaires comme Lodash
+
+**TL;PL :** Il est souvent plus pénalisant d'utiliser des bibliothèques utilitaires telles que `lodash` et `underscore` plutôt que des méthodes natives car cela conduit à des dépendances inutiles et à des performances plus lentes.
+Gardez à l'esprit qu'avec l'introduction du nouveau moteur V8 en parallèle des nouvelles normes ES, les méthodes natives ont été améliorées de telle manière qu'elles sont maintenant environ 50% plus performantes que les bibliothèques utilitaires.
+
+**Autrement :** Vous devez maintenir des projets moins performants où vous auriez pu simplement utiliser ce qui était **déjà** disponible ou traiter quelques lignes supplémentaires en échange de quelques fichiers supplémentaires.
+
+🔗 [**Plus d'infos : natif supérieur aux utilitaires**](./sections/performance/nativeoverutil.french.md)
+
+
+
+# `8. Bonnes pratiques de Docker`
+
+🏅 Un grand merci à [Bret Fisher](https://github.com/BretFisher) de qui nous avons appris plusieurs des pratiques suivantes
+
+
+
+## ![✔] 8.1 Utilisez multi-stage builds pour des images Docker plus légères et plus sûres
+
+**TL;PL :** Utilisez multi-stage builds pour copier uniquement les artefacts de production nécessaires. Un grand nombre de dépendances et de fichiers au moment de la construction ne sont pas nécessaires pour exécuter votre application. Avec multi-stage builds, ces ressources peuvent être utilisées pendant la construction tandis que l'environnement d'exécution ne contient que ce qui est nécessaire. multi-stage builds est un moyen facile de se débarrasser du surpoids et des menaces de sécurité.
+
+**Autrement :** Les images plus grandes prendront plus de temps à construire et à livrer. Les outils uniquement de construction peuvent contenir des vulnérabilités. Et des secrets destinés uniquement à la phase de construction peuvent être divulgués.
+
+### Exemple de Dockerfile pour le multi-stage builds
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY . .
+RUN npm ci && npm run build
+
+
+FROM node:slim-14.4.0
+
+USER node
+EXPOSE 8080
+
+COPY --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/package-lock.json ./
+RUN npm ci --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+🔗 [**Plus d'infos : utilisez multi-stage builds**](./sections/docker/multi_stage_builds.french.md)
+
+
+
+## ![✔] 8.2. Démarrez à l'aide de la commande `node`, évitez `npm start`
+
+**TL;PL :** Utilisez `CMD ['node','server.js']` pour démarrer votre application, évitez d'utiliser des scripts npm qui ne transmettent pas les signaux du système d'exploitation au code. Cela empêche les problèmes de processus fils, de gestion du signal, d'arrêt progressif et de processus zombies.
+
+**Autrement :** Si aucun signal n'est transmis, votre code ne sera jamais notifié des interruptions. Sans cela, il perdra sa chance de se fermer correctement, ce qui pourrait entraîner la perte de requêtes et/ou de données en cours.
+
+[**Plus d'infos : Démarrez un conteneur à l'aide de la commande node, évitez npm start**](./sections/docker/bootstrap-using-node.french.md)
+
+
+
+## ![✔] 8.3. Laissez le système d'exécution Docker s'occuper de la réplication et de la disponibilité
+
+**TL;PL :** Lorsque vous utilisez un orchestrateur d'exécution Docker (par exemple, Kubernetes), appelez le processus Node.js directement sans gestionnaires de processus intermédiaires ou code personnalisé qui réplique le processus (par exemple, PM2, module Cluster). La plateforme d'exécution possède la plus grande quantité de données et la meilleure visibilité pour prendre des décisions de placement - Elle sait mieux que quiconque combien de processus sont nécessaires, comment les répartir et quoi faire en cas de plantage.
+
+**Autrement :** Le conteneur continue de se planter par manque de ressources et sera redémarré indéfiniment par le responsable du processus. Si Kubernetes est au courant de cela, il pourrait le déplacer vers une autre instance plus importante.
+
+🔗 [**Plus d'infos : laissez l'orchestrateur Docker redémarrer et répliquer les processus**](./sections/docker/restart-and-replicate-processes.french.md)
+
+
+
+## ![✔] 8.4. Utilisez .dockerignore pour éviter les divulgations de secrets
+
+**TL;PL :** Ajoutez un fichier `.dockerignore` qui filtre les fichiers secrets courants et les artefacts de développement. Ainsi, vous pouvez éviter que des secrets ne s'infiltrent dans l'image. En prime, le temps de construction sera considérablement réduit. De plus, assurez-vous de ne pas copier tous les fichiers récursivement, choisissez plutôt explicitement ce qui doit être copié dans Docker.
+
+**Autrement :** Les fichiers secrets personnels habituels comme `.env`, `.aws` et `.npmrc` seront partagés avec toute personne ayant accès à l'image (par exemple le dépôt Docker).
+
+🔗 [**Plus d'infos : utilisez .dockerignore**](./sections/docker/docker-ignore.french.md)
+
+
+
+## ![✔] 8.5. Nettoyez les dépendances avant la production
+
+**TL;PL :** Bien que des dépendances de développement soient parfois nécessaires pendant le cycle de vie de la construction et des tests, l'image qui est envoyée à la production doit être minimale et exempte de toute dépendance de développement. Cela garantit que seul le code nécessaire est livré et que la quantité d'attaques potentielles (c'est-à-dire la surface d'attaque) soit réduite au minimum. Lorsque l'on utilise un multi-stage build (voir le point consacré à ce sujet), cela peut être réalisé en installant d'abord toutes les dépendances et en exécutant enfin `npm ci --production`.
+
+**Autrement :** De nombreuses failles célèbres de sécurité de npm ont été trouvées dans des packages de développement (par exemple [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes))
+
+🔗 Plus d'infos : [supprimez les dépendances de développement](./sections/docker/install-for-production.french.md)
+
+
+
+## ![✔] 8.6. Arrêtez intelligemment et progressivement
+
+**TL;PL :** Gérez l'événement SIGTERM du processus et nettoyez toutes les connexions et ressources existantes. Cela doit être fait tout en répondant aux requêtes en cours. Dans des environnements d'exécution Dockerisés, l'arrêt des conteneurs n'est pas un événement rare, mais plutôt une occurrence fréquente qui se produit dans le cadre du travail routinier. Pour y parvenir, il faut un code réfléchi pour orchestrer plusieurs pièces mobiles : l'équilibreur de charge, les connexions persistantes, le serveur HTTP et d'autres ressources.
+
+**Autrement :** S'éteindre immédiatement signifie ne pas répondre aux milliers d'utilisateurs qui seront déçus.
+
+🔗 [**Plus d'infos : arrêt progressif**](./sections/docker/graceful-shutdown.french.md)
+
+
+
+## ![✔] 8.7. Définissez des limites de mémoire en utilisant à la fois Docker et v8
+
+**TL;PL :** Configurez toujours une limite de mémoire en utilisant à la fois Docker et les indicateurs d'exécution JavaScript. La limite de Docker est nécessaire pour prendre une décision judicieuse de placement des conteneurs, l'indicateur max-old-space de --v8 est nécessaire pour lancer le GC à temps et éviter la sous-utilisation de la mémoire. Concrètement, il faut que cet indicateur de v8 soit juste un peu plus petit que la limite du conteneur.
+
+**Autrement :** La définition de docker est nécessaire pour prendre une décision judicieuse pour la mise à l'échelle et éviter de priver d'autres consommateurs de mémoire. Sans définir également les limites de v8, il sous-utilisera les ressources du conteneur - Sans instructions explicites, il se plantera lorsqu'il utilisera ~50-60% des ressources de ses hôtes.
+
+🔗 [**Plus d'infos : définissez des limites de mémoire en utilisant uniquement Docker**](./sections/docker/memory-limit.french.md)
+
+
+
+## ![✔] 8.8. Organisez une mise en cache efficace
+
+**TL;PL :** La reconstruction d'une image entière de docker à partir du cache peut être presque instantanée si elle est faite correctement. Les instructions qui changent peu devraient se trouver en haut de votre Dockerfile et celles qui changent constamment (comme le code de l'application) devraient se trouver en bas.
+
+**Autrement :** La construction de docker sera très longue et consommera beaucoup de ressources, même en cas de changements minimes.
+
+🔗 [**Plus d'infos : exploiter la mise en cache pour réduire les temps de construction**](./sections/docker/use-cache-for-shorter-build-time.french.md)
+
+
+
+## ![✔] 8.9. Utilisez une référence explicite de l'image, évitez le tag `latest`
+
+**TL;PL :** Précisez un condensé (_digest_) d'image explicite ou une étiquette versionnée, ne faites jamais référence à `latest`. Les développeurs sont souvent amenés à croire que la spécification du tag `latest` leur fournira l'image la plus récente dans le dépôt, mais ce n'est pas le cas. L'utilisation d'un digest garantit que chaque instance du service exécute exactement le même code.
+
+En outre, la référence à un tag d'une image signifie que l'image de base est sujette à des modifications, car on ne peut pas se fier aux tags image pour une installation déterminée. En revanche, si une installation déterminée est prévue, un digest SHA256 peut être utilisé pour faire référence à une image exacte.
+
+**Autrement :** Une nouvelle version d'une image de base pourrait être déployée en production avec des modifications importantes, provoquant un comportement non souhaité de l'application.
+
+🔗 [**Plus d'infos : Comprendre les tags d'image et utiliser le tag "latest" avec précaution**](./sections/docker/image-tags.french.md)
+
+
+
+## ![✔] 8.10. Privilégiez les plus petites images de base Docker
+
+**TL;PL :** Les images de grande taille entraînent une plus grande exposition aux vulnérabilités et une consommation accrue des ressources. L'utilisation d'images Docker plus fines, telles que les variantes Slim et Alpine de Linux, atténue ce problème.
+
+**Autrement :** Construire, pousser et tirer des images prendra plus de temps, des vecteurs d'attaque inconnus peuvent être utilisés par des acteurs malveillants et plus de ressources sont consommées.
+
+🔗 [**Plus d'infos : privilégiez les plus petites images**](./sections/docker/smaller_base_images.french.md)
+
+
+
+## ![✔] 8.11. Nettoyez les secrets de construction, évitez les secrets dans les arguments
+
+**TL;PL :** Évitez que des secrets ne s'échappent de l'environnement de construction du Docker. Une image Docker est généralement partagée dans plusieurs environnements comme les CI et un registre qui ne sont pas aussi aseptisés que la production. Un exemple typique est un jeton npm qui est généralement transmis à un fichier Docker en tant qu'argument. Ce jeton reste dans l'image longtemps après qu'on en ait eu besoin et permet à l'attaquant d'accéder indéfiniment à un registre npm privé. Cela peut être évité en copiant un fichier secret comme `.npmrc` et en le supprimant en utilisant une construction en plusieurs étapes (attention, l'historique de la construction doit également être supprimé) ou en utilisant la fonctionnalité secrète Docker build-kit qui ne laisse aucune trace.
+
+**Autrement :** Toute personne ayant accès au CI et au registre des dockers aura également accès, en prime, à certains secrets précieux de l'organisation
+
+🔗 [**Plus d'infos : nettoyez les secrets de construction**](./sections/docker/avoid-build-time-secrets.french.md)
+
+
+
+## ![✔] 8.12. Analysez les images pour détecter les multiples catégories de vulnérabilités
+
+**TL;PL :** En plus de vérifier les vulnérabilités des dépendances du code, il analyse également l'image finale qui est envoyée à la production. Les scanners d'images Docker vérifient les dépendances du code mais aussi les binaires du système d'exploitation. Ce scan de sécurité E2E couvre plus de terrain et vérifie qu'aucun mauvais gars n'a injecté de mauvaises choses pendant la construction. Par conséquent, il est recommandé de l'exécuter comme dernière étape avant le déploiement. Il existe une poignée de scanners gratuits et commerciaux qui fournissent également des plugins CI/CD.
+
+**Autrement :** Votre code pourrait être entièrement exempt de vulnérabilités. Cependant, il peut être piraté en raison de la vulnérabilité des versions binaires au niveau OS (par exemple, OpenSSL, TarBall) qui sont couramment utilisées par les applications.
+
+🔗 [**Plus d'infos : scannez l'ensemble de l'image avant la production**](./sections/docker/scan-images.french.md)
+
+
+
+## ![✔] 8.13 Nettoyez le cache NODE_MODULE
+
+**TL;PL :** Après avoir installé les dépendances dans un conteneur, il faut supprimer le cache local. Il n'est pas logique de dupliquer les dépendances pour des installations futures plus rapides puisqu'il n'y aura pas d'autres installations - Une image du Docker est immuable. Une image du Docker est immuable. En utilisant une seule ligne de code, des dizaines de Mo (généralement 10 à 50 % de la taille de l'image) sont supprimées.
+
+**Autrement :** L'image qui sera envoyée à la production pèsera 30 % de plus à cause de fichiers qui ne seront jamais utilisés.
+
+🔗 [**Plus d'infos : nettoyez le cache NODE_MODULE**](./sections/docker/clean-cache.french.md)
+
+
+
+## ![✔] 8.14. Les pratiques de Docker en général
+
+**TL;PL :** Il s'agit d'un recueil de conseils de Docker qui n'est pas directement lié à Node.js - la mise en œuvre de Node n'est pas très différente de celle de tout autre langage. Cliquez pour en savoir plus.
+
+🔗 [**Plus d'infos : les pratiques de Docker en général**](./sections/docker/generic-tips.french.md)
+
+
+
+## ![✔] 8.15. Lintez votre Dockerfile
+
+**TL;PL :** Linter votre Dockerfile est une étape importante pour identifier les problèmes de votre Dockerfile qui diffèrent des meilleures pratiques. En vérifiant les failles potentielles à l'aide d'un linter Docker spécialisé, les améliorations de performance et de sécurité peuvent être facilement identifiées, ce qui permet d'économiser d'innombrables heures de perte de temps ou des problèmes de sécurité dans le code de production.
+
+**Autrement :** Par erreur, le créateur du Dockerfile a laissé Root comme utilisateur de production, et a également utilisé une image provenant d'un dépôt de source inconnue. Cela pourrait être évité avec un simple linter.
+
+🔗 [**Plus d'infos : lintez your Dockerfile**](./sections/docker/lint-dockerfile.french.md)
+
+
+
+# Jalons
+
+Pour maintenir ce guide et le tenir à jour, nous actualisons et améliorons constamment les lignes directrices et les meilleures pratiques avec l'aide de la communauté. Vous pouvez suivre nos [jalons](https://github.com/goldbergyoni/nodebestpractices/milestones) et rejoindre les groupes de travail si vous souhaitez contribuer à ce projet
+
+
+
+## Traductions
+
+Toutes les traductions sont fournies par la communauté. Nous serons heureux de recevoir toute aide concernant les traductions terminées, en cours ou nouvelles !
+
+### Traductions terminées
+
+-  [Portugais brésilien](./README.brazilian-portuguese.md) - Avec l'aimable autorisation de [Marcelo Melo](https://github.com/marcelosdm)
+-  [Chinois](./README.chinese.md) - Avec l'aimable autorisation de [Matt Jin](https://github.com/mattjin)
+-  [Russe](./README.russian.md) - Avec l'aimable autorisation de [Alex Ivanov](https://github.com/contributorpw)
+-  [Polonais](./README.polish.md) - Avec l'aimable autorisation de [Michal Biesiada](https://github.com/mbiesiad)
+-  [Japonais](./README.japanese.md) - Avec l'aimable autorisation de [Yuki Ota](https://github.com/YukiOta), [Yuta Azumi](https://github.com/YA21)
+-  [Basque](README.basque.md) - Avec l'aimable autorisation de [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuesta
+
+### Traductions en cours
+
+-  [Français](./README.french.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  Hébreu ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Coréen](README.korean.md) - Avec l'aimable autorisation de [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Espagnol](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turque ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/139))
+
+
+
+## Comité de pilotage
+
+Rencontrez les membres du comité de pilotage - les personnes qui travaillent ensemble pour fournir des conseils et des orientations futures au projet. En outre, chaque membre du comité dirige un projet suivi dans le cadre de nos [projets GitHub](https://github.com/goldbergyoni/nodebestpractices/projects).
+
+
+
+[Yoni Goldberg](https://github.com/goldbergyoni)
+
+
+
+Consultant indépendant Node.js qui travaille avec des clients aux États-Unis, en Europe et en Israël sur la construction d'applications Node.js à grande échelle. Nombre des meilleures pratiques ci-dessus ont été publiées pour la première fois sur [goldbergyoni.com](https://goldbergyoni.com). Contactez Yoni via [@goldbergyoni](https://github.com/goldbergyoni) ou [me@goldbergyoni.com](mailto:me@goldbergyoni.com)
+
+
+
+
+
+[Bruno Scheufler](https://github.com/BrunoScheufler)
+
+
+💻 ingénieur web full-stack, passionné de Node.js & GraphQL
+
+
+
+
+
+[Kyle Martin](https://github.com/js-kyle)
+
+
+
+Développeur Full Stack et ingénieur de fiabilité de site basé en Nouvelle-Zélande, intéressé par la sécurité des applications web, et l'architecture et la construction d'applications Node.js pour fonctionner à l'échelle mondiale.
+
+
+
+
+
+[Kevyn Bruyere](https://github.com/kevynb)
+
+
+Développeur indépendant full-stack ayant un penchant pour les Ops et l'automatisation.
+
+
+
+### Comité de pilotage émérite
+
+
+
+[Sagir Khan](https://github.com/sagirk)
+
+
+
+
+Spécialiste de JavaScript et de son écosystème - React, Node.js, TypeScript, GraphQL, MongoDB, à peu près tout ce qui implique JS/JSON dans n'importe quelle couche du système - construisant des produits en utilisant la plateforme web pour les marques les plus reconnues au monde. Membre individuel de la Fondation Node.js.
+
+
+
+## Collaborateurs
+
+Merci à tous nos collaborateurs ! 🙏
+
+Nos collaborateurs sont des membres qui contribuent régulièrement au dépôt, en suggérant de nouvelles bonnes pratiques, en triant les issues, en examinant les pull request et bien d'autres choses encore. Si vous souhaitez nous aider à guider des milliers de personnes à créer de meilleures applications Node.js, veuillez lire nos [directives pour les contributeurs](./.operations/CONTRIBUTING.md) 🎉
+
+| | | | |
+| :--: | :--: | :--: | :--: |
+| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) | [Raz Luvaton](https://github.com/rluvaton) | [Josh Hemphill](https://github.com/josh-hemphill) |
+
+### Collaborateur émérite
+
+| |
+| :-------------------------------------------------------------------------------------------------------------------------: |
+| [Refael Ackermann](https://github.com/refack) |
+
+
+
+## Contribution
+
+Si vous avez toujours voulu contribuer à l'open source, voici votre chance ! Consultez les [documents de contributions](.operations/CONTRIBUTING.md) pour plus d'information.
+
+## Contributeurs ✨
+
+Merci à ces merveilleuses personnes qui ont contribué à ce dépôt !
+
+
+
+
+
+
+
+
+
+
diff --git a/README.hebrew.md b/README.hebrew.md
new file mode 100644
index 000000000..22d5ce0ba
--- /dev/null
+++ b/README.hebrew.md
@@ -0,0 +1,1927 @@
+[✔]: assets/images/checkbox-small-blue.png
+
+# שיטות עבודה מומלצות ב Node.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+[](https://twitter.com/nodepractices/) **עיקבו אחרינו בטוויטר!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+**:writing_hand: תורגם על ידי [הוד בואר](https://github.com/hodbauer)**
+
+
+לקריאה בשפות נוספות: [**סינית**](./README.chinese.md), [**צרפתית**](./README.french.md), [**פורטוגזית**](./README.brazilian-portuguese.md), [**רוסית**](./README.russian.md), [**פולנית**](./README.polish.md), [**יפנית**](./README.japanese.md), [**באסקית**](./README.basque.md) [(**ספרדית**, **עברית**, **קוריאנית** ו **טורקית** בתהליך! )](#translations)
+
+
+
+# Latest Best Practices and News
+
+- **🛰 2023 edition is released soon**: We're now writing the next edition, stay tuned?
+
+- **✨ 89,000 stars**: Blushing, surprised and proud!
+
+- **🔖 New menu and tags**: Our menu is collapsible now and includes `#tags`. New visitors can read `#strategic` items first. Returning visitors can focus on `#new` content. Seniors can filter for `#advanced` items. Courtesy of the one and only [Rubek Joshi](https://github.com/rubek-joshi)
+
+- ** French translation!1! :** The latest translation that joins our international guide is French. Bienvenue
+
+
+
+# ברוכים הבאים! שלושה דברים שכדאי לדעת לפני שגוללים מטה
+
+**1. הנכם קוראים עשרות מאמרים של שיטות העבודה המומלצות ב Node.js -** המאגר הזה הוא סיכום לא יסולא בפז של שיטות העבודה המומלצות ב Node.js , כמו כן הוא נעשה על בשיתוף פעולה.
+
+**2. זהו האוסף הגדול ביותר, והוא ממשיך לגדול כל שבוע -** נכון לרגע זה, יש למעלה מ 100 שיטות עבודה מומלצות, המלצות ארכיטקטורה והמלצות סגנון כתיבה. נושאים חדשים ובקשות חדשות (PR's) מתווספים כל יום במטרה לשמור את התוכן מעודכן. אנחנו נשמח לראותכם תורמים לפה, בין אם לתקן שגיאות קוד, עזרה בתרגום, או להציע רעיונות מבריקים חדשים. ראו את [המדריך לכתיבת הנחיות](./.operations/writing-guidelines.md).
+
+**3. שיטות העבודה כוללות מידע נוסף -** רוב הנקודות כוללות קישור **🔗לקריאה נוספת** שמרחיב על ידי דוגמאות קוד, ציטוטים מבלוגים נבחרים ומידע נוסף.
+
+
+
+# מאת יוני גולדברג
+
+### לימדו איתי: כיועץ, אני נפגש עם קבוצות מכל העולם במגוון פעולות כמו סדנאות ומעבר על קוד. 🎉 לאחרונה פרסמתי את [הקורס המתקדם לכתיבת בדיקות](https://testjavascript.com/)
+
+
+## תוכן העניינים
+
+
+
+ 1. מבנה הפרוייקט (6)
+
+
+ [1.1 בנו את הפרוייקט לפי רכיבים עסקיים `#strategic` `#updated`](#-11-structure-your-solution-by-business-components)
+ [1.2 חלוקת הרכיבים ל3 שכבות, שמירה על שכבת הווב בגבולותיה `#strategic` `#updated`](#-12-layer-your-components-with-3-tiers-keep-the-web-layer-within-its-boundaries)
+ [1.3 עטפו כלים משותפים בחבילות, שקלו את הפצתם](#-13-wrap-common-utilities-as-packages-consider-publishing)
+ [1.4 השתמשו בקונפיגורציה עם משתני סביבה באופן מודע, מאובטח והיררכי `#updated`](#-14-use-environment-aware-secure-and-hierarchical-config)
+ [1.5 שקלו את כל ההשלכות בעת בחירת מסגרת `#new`](#-15-consider-all-the-consequences-when-choosing-the-main-framework)
+ [1.6 השתמשו ב-TypeScript במידתיות ובצורה מושכלת `#new`](#-16-use-typescript-sparingly-and-thoughtfully)
+
+
+
+
+
+ 2. ניהול שגיאות (12)
+
+
+ [2.1 השתמשו ב Async-Await או הבטחות לניהול שגיאות אסינכרוניות](#-21-use-async-await-or-promises-for-async-error-handling)
+ [2.2 הרחיבו את מבנה אוביקט השגיאה המובנה Error `#strategic` `#updated`](#-22-extend-the-built-in-error-object)
+ [2.3 הבחינו בין שגיאות קטסטרופליות לבין שגיאות תפעוליות `#strategic` `#updated`](#-23-distinguish-catastrophic-errors-from-operational-errors)
+ [2.4 נהלו את השגיאות במרוכז ולא באמצעות כלי ביניים `#strategic`](#-24-handle-errors-centrally-not-within-a-middleware)
+ [2.5 תעדו את שגיאות ה-API באמצעות OpenAPI או GraphQL](#-25-document-api-errors-using-openapi-or-graphql)
+ [2.6 הורידו את התהליך בצורה מסודרת כאשר זר בא לבקר `#strategic`](#-26-exit-the-process-gracefully-when-a-stranger-comes-to-town)
+ [2.7 השתמשו ב-Logger מוכר ואמין כדי להגדיל את הקְרִיאוּת של השגיאות `#updated`](#-27-use-a-mature-logger-to-increase-errors-visibility)
+ [2.8 בידקו את תגובת המערכת לשגיאות על ידי שימוש בכלי הבדיקות האהוב עליכם `#updated`](#-28-test-error-flows-using-your-favorite-test-framework)
+ [2.9 גלו שגיאות וזמני השבתה על ידי שימוש בכלי APM](#-29-discover-errors-and-downtime-using-apm-products)
+ [2.10 תפסו מקרים לא מטופלים של דחיות של הבטחות `#updated`](#-210-catch-unhandled-promise-rejections)
+ [2.11 היכשלו מהר, ודאו את משתני הקלט באמצעות ספריה יעודית](#-211-fail-fast-validate-arguments-using-a-dedicated-library)
+ [2.12 תמיד המתינו לתשובה מההבטחות לפני שאתם מעבירים את התשובה הלאה כדי להימנע ממעקב חלקי `#new`](#-212-always-await-promises-before-returning-to-avoid-a-partial-stacktrace)
+
+
+
+
+
+ 3. תבניות קוד וסגנון עיצוב (13)
+
+
+ [3.1 השתמשו ב-ESLint `#strategic`](#-31-use-eslint)
+ [3.2 השתמשו בתוספים של Node.js שמרחיבים את ESLint `#updated`](#-32-use-nodejs-eslint-extension-plugins)
+ [3.3 התחילו בלוק של קוד עם סוגריים מסולסלים באותה השורה](#-33-start-a-codeblocks-curly-braces-on-the-same-line)
+ [3.4 הפרידו בין ההצהרות השונות בצורה תקנית](#-34-separate-your-statements-properly)
+ [3.5 תנו לפונקציה שם](#-35-name-your-functions)
+ [3.6 השתמשו במוסכמות קבועות במתן שמות למשתנים, לקבועים, לפונקציות ולמחלקות](#-36-use-naming-conventions-for-variables-constants-functions-and-classes)
+ [3.7 העדיפו const על פני let. ניטשו את var](#-37-prefer-const-over-let-ditch-the-var)
+ [3.8 טענו מודולים בתחילה, ולא בקריאה לפונקציות](#-38-require-modules-first-not-inside-functions)
+ [3.9 הגדירו כניסה מסודרת לספריה שלכם `#updated`](#-39-set-an-explicit-entry-point-to-a-modulefolder)
+ [3.10 השתמשו באופרטור `===`](#-310-use-the--operator)
+ [3.11 השתמשו ב-Async Await, המנעו מ-callbacks `#strategic`](#-311-use-async-await-avoid-callbacks)
+ [3.12 השתמשו בפונקציות חץ (=>)](#-312-use-arrow-function-expressions-)
+ [3.13 הימנעו מהשפעות צדדיות מחוץ לפונקציות `#new`](#-313-avoid-effects-outside-of-functions)
+
+
+
+
+
+ 4. בדיקות ובקרת איכות (13)
+
+
+ [4.1 לפחות, כיתבו בדיקות API לרכיבים השונים `#strategic`](#-41-at-the-very-least-write-api-component-testing)
+ [4.2 סווגו 3 חלקים במתן שם לכל בדיקה `#new`](#-42-include-3-parts-in-each-test-name)
+ [4.3 חלקו את הבדיקות לפי תבנית ה-AAA `#strategic`](#-43-structure-tests-by-the-aaa-pattern)
+ [4.4 וודאו כי גרסת ה-Node אחידה `#new`](#-44-ensure-node-version-is-unified)
+ [4.5 הימנעו מאתחול מידע גרעיני משותף, הגדירו לפי צורך של בדיקה `#strategic`](#-45-avoid-global-test-fixtures-and-seeds-add-data-per-test)
+ [4.6 תייגו את הבדיקות `#advanced`](#-46-tag-your-tests)
+ [4.7 בידקו את רמת כיסוי הבדיקות שלכם, זה יעזור לזהות דפוסי בדיקות שגויים](#-47-check-your-test-coverage-it-helps-to-identify-wrong-test-patterns)
+ [4.8 Use production-like environment for e2e testing](#-48-use-production-like-environment-for-e2e-testing)
+ [4.9 שכתבו את הקוד באופן קבוע בעזרת כלי ניתוח סטטי](#-49-refactor-regularly-using-static-analysis-tools)
+ [4.10 הדמיית תשובות של שרתי HTTP חיצוניים `#new` `#advanced`](#-410-mock-responses-of-external-http-services)
+ [4.11 בדקו את פונקציות הביניים בנפרד](#-411-test-your-middlewares-in-isolation)
+ [4.12 קבעו את הפורט בייצור, הגדירו אקראי לבדיקות `#new`](#-412-specify-a-port-in-production-randomize-in-testing)
+ [4.13 בידקו את חמשת התוצאות האפשריות `#strategic` `#new`](#-413-test-the-five-possible-outcomes)
+
+
+
+
+
+ 5. עלייה לאוויר (19)
+
+
+ [5.1. ניטור `#strategic`](#-51-monitoring)
+ [5.2. הגדילו את יכולת הצפייה בעזרת לוגים איכותיים `#strategic`](#-52-increase-the-observability-using-smart-logging)
+ [5.3. האצילו כל מה שאפשר (לדוגמה gzip, SSL) לשירות נפרד `#strategic`](#-53-delegate-anything-possible-eg-gzip-ssl-to-a-reverse-proxy)
+ [5.4. קיבוע תלויות](#-54-lock-dependencies)
+ [5.5. הבטיחו את זמינות המערכת בעזרת הכלי המתאים](#-55-guard-process-uptime-using-the-right-tool)
+ [5.6. השתמשו בכל מעבדי ה-CPU](#-56-utilize-all-cpu-cores)
+ [5.7. תיצרו ‘maintenance endpoint’](#-57-create-a-maintenance-endpoint)
+ [5.8. גלו את הלא ידוע בעזרת מוצרי APM `#advanced` `#updated`](#-58-discover-the-unknowns-using-apm-products)
+ [5.9. כתבו את הקוד מותאם להתקנה](#-59-make-your-code-production-ready)
+ [5.10. מדדו ושימרו את ניצול הזיכרון `#advanced`](#-510-measure-and-guard-the-memory-usage)
+ [5.11. Get your frontend assets out of Node](#-511-get-your-frontend-assets-out-of-node)
+ [5.12. Strive to be stateless `#strategic`](#-512-strive-to-be-stateless)
+ [5.13. Use tools that automatically detect vulnerabilities](#-513-use-tools-that-automatically-detect-vulnerabilities)
+ [5.14. Assign a transaction id to each log statement `#advanced`](#-514-assign-a-transaction-id-to-each-log-statement)
+ [5.15. Set NODE_ENV=production](#-515-set-node_envproduction)
+ [5.16. Design automated, atomic and zero-downtime deployments `#advanced`](#-516-design-automated-atomic-and-zero-downtime-deployments)
+ [5.17. Use an LTS release of Node.js](#-517-use-an-lts-release-of-nodejs)
+ [5.18. Log to stdout, avoid specifying log destination within the app](#-518-log-to-stdout-avoid-specifying-log-destination-within-the-app)
+ [5.19. Install your packages with npm ci `#new`](#-519-install-your-packages-with-npm-ci)
+
+
+
+
+
+ 6. אבטחה (27)
+
+
+ [6.1. Embrace linter security rules](#-61-embrace-linter-security-rules)
+ [6.2. Limit concurrent requests using a middleware](#-62-limit-concurrent-requests-using-a-middleware)
+ [6.3 Extract secrets from config files or use packages to encrypt them `#strategic`](#-63-extract-secrets-from-config-files-or-use-packages-to-encrypt-them)
+ [6.4. Prevent query injection vulnerabilities with ORM/ODM libraries `#strategic`](#-64-prevent-query-injection-vulnerabilities-with-ormodm-libraries)
+ [6.5. Collection of generic security best practices](#-65-collection-of-generic-security-best-practices)
+ [6.6. Adjust the HTTP response headers for enhanced security](#-66-adjust-the-http-response-headers-for-enhanced-security)
+ [6.7. Constantly and automatically inspect for vulnerable dependencies `#strategic`](#-67-constantly-and-automatically-inspect-for-vulnerable-dependencies)
+ [6.8. Protect Users' Passwords/Secrets using bcrypt or scrypt `#strategic`](#-68-protect-users-passwordssecrets-using-bcrypt-or-scrypt)
+ [6.9. Escape HTML, JS and CSS output](#-69-escape-html-js-and-css-output)
+ [6.10. Validate incoming JSON schemas `#strategic`](#-610-validate-incoming-json-schemas)
+ [6.11. Support blocklisting JWTs](#-611-support-blocklisting-jwts)
+ [6.12. Prevent brute-force attacks against authorization `#advanced`](#-612-prevent-brute-force-attacks-against-authorization)
+ [6.13. Run Node.js as non-root user](#-613-run-nodejs-as-non-root-user)
+ [6.14. Limit payload size using a reverse-proxy or a middleware](#-614-limit-payload-size-using-a-reverse-proxy-or-a-middleware)
+ [6.15. Avoid JavaScript eval statements](#-615-avoid-javascript-eval-statements)
+ [6.16. Prevent evil RegEx from overloading your single thread execution](#-616-prevent-evil-regex-from-overloading-your-single-thread-execution)
+ [6.17. Avoid module loading using a variable](#-617-avoid-module-loading-using-a-variable)
+ [6.18. Run unsafe code in a sandbox](#-618-run-unsafe-code-in-a-sandbox)
+ [6.19. Take extra care when working with child processes `#advanced`](#-619-take-extra-care-when-working-with-child-processes)
+ [6.20. Hide error details from clients](#-620-hide-error-details-from-clients)
+ [6.21. Configure 2FA for npm or Yarn `#strategic`](#-621-configure-2fa-for-npm-or-yarn)
+ [6.22. Modify session middleware settings](#-622-modify-session-middleware-settings)
+ [6.23. Avoid DOS attacks by explicitly setting when a process should crash `#advanced`](#-623-avoid-dos-attacks-by-explicitly-setting-when-a-process-should-crash)
+ [6.24. Prevent unsafe redirects](#-624-prevent-unsafe-redirects)
+ [6.25. Avoid publishing secrets to the npm registry](#-625-avoid-publishing-secrets-to-the-npm-registry)
+ [6.26. 6.26 Inspect for outdated packages](#-626-inspect-for-outdated-packages)
+ [6.27. Import built-in modules using the 'node:' protocol `#new`](#-627-import-built-in-modules-using-the-node-protocol)
+
+
+
+
+
+ 7. ביצועים (2) (בתהליך ✍️)
+
+
+ [7.1. Don't block the event loop](#-71-dont-block-the-event-loop)
+ [7.2. Prefer native JS methods over user-land utils like Lodash](#-72-prefer-native-js-methods-over-user-land-utils-like-lodash)
+
+
+
+
+
+ 8. דוקר (15)
+
+
+ [8.1 Use multi-stage builds for leaner and more secure Docker images `#strategic`](#-81-use-multi-stage-builds-for-leaner-and-more-secure-docker-images)
+ [8.2. Bootstrap using node command, avoid npm start](#-82-bootstrap-using-node-command-avoid-npm-start)
+ [8.3. Let the Docker runtime handle replication and uptime `#strategic`](#-83-let-the-docker-runtime-handle-replication-and-uptime)
+ [8.4. Use .dockerignore to prevent leaking secrets](#-84-use-dockerignore-to-prevent-leaking-secrets)
+ [8.5. Clean-up dependencies before production](#-85-clean-up-dependencies-before-production)
+ [8.6. Shutdown smartly and gracefully `#advanced`](#-86-shutdown-smartly-and-gracefully)
+ [8.7. Set memory limits using both Docker and v8 `#advanced` `#strategic`](#-87-set-memory-limits-using-both-docker-and-v8)
+ [8.8. Plan for efficient caching](#-88-plan-for-efficient-caching)
+ [8.9. Use explicit image reference, avoid latest tag](#-89-use-explicit-image-reference-avoid-latest-tag)
+ [8.10. Prefer smaller Docker base images](#-810-prefer-smaller-docker-base-images)
+ [8.11. Clean-out build-time secrets, avoid secrets in args `#strategic #new`](#-811-clean-out-build-time-secrets-avoid-secrets-in-args)
+ [8.12. Scan images for multi layers of vulnerabilities `#advanced`](#-812-scan-images-for-multi-layers-of-vulnerabilities)
+ [8.13 Clean NODE_MODULE cache](#-813-clean-node_module-cache)
+ [8.14. Generic Docker practices](#-814-generic-docker-practices)
+ [8.15. Lint your Dockerfile `#new`](#-815-lint-your-dockerfile)
+
+
+
+
+
+# `1. מבנה הפרוייקט`
+
+## ![✔] 1.1 בנו את הפרוייקט לפי רכיבים עסקיים
+
+**אמ;לק:** בסיס המערכת צריך לכלול תיקיות או מאגרים שמייצג בצורה הגיונית את המידול העסקי. כל רכיב מייצג תחום מוצר (כלומר הקשר מוגבל), למשל 'משתמשים', 'הזמנות', וכולי... כל רכיב מכיל את ה API, לוגיקה ומסד הנתונים שלו. מה המטרה של זה? כאשר יש סביבה עצמאית כל שינוי משפיע אך ורק על החלק הרלוונטי - העומס הנפשי, סיבוכיות הפיתוח והחשש מפריסה חדשה של הרכיב הרבה יותר קטן. כתוצאה מכך, מתכנתים יכולים לפתח הרבה יותר מהר. זה לא דורש בהכרח הפרדה פיזית ויכול להיות מושג גם בMonorepo או multi-repo.
+
+```bash
+my-system
+├─ apps (components)
+│ ├─ orders
+│ ├─ users
+│ ├─ payments
+├─ libraries (generic cross-component functionality)
+│ ├─ logger
+│ ├─ authenticator
+```
+
+**אחרת:** כאשר מוצרים של מודולים או נושאים שונים מעורבבים יחד, ישנו סיכוי גבוה שתיווצר מערכת ספגטי בעלת צימוד גבוה. לדוגמה, בארכיטקטורה שבה 'מודול א`' קורא לשירות מ'מודול ב;', אין הפרדה ברורהבין המודולים השונים - כל שינוי בקוד עלול להשפיע על משהו אחר. עם הגישה הזאת , מתכנתים שצריכים להוסיף מוצר חדש למערכת יאבקו בה בהבנה על מה השינוי שלהם יכול להשפיע. כתוצאה מכך, הם חששו לשבור מודולים אחרים, וכל פריסה נהייתה איטית יותר ומסוכנת יותר.
+
+🔗 [**לקריאה נוספת: בנייה לפי רכיבים**](./sections/projectstructre/breakintcomponents.md)
+
+
+
+## ![✔] 1.2 חלוקת הרכיבים ל3 שכבות, שמירה על שכבת הווב בגבולותיה
+
+**אמ;לק:** כל רכיב צריך לכלול 'שכבות' - תיקייה יעודית עם אחריות משותפת: 'entry-point' איפה שחלקי השליטה נמצאים, 'domain' איפה שהלוגיקה נמצאת ו 'data-access'. העיקרון המנחה של הארכיטקטורות המובילות בשוק הוא להפריד את האחריות הטכנית (למשל: HTTP, DB ועוד) מהלוגיקה היעודית של המוצר כך שהמתכנתים יוכלו לקודד יותר תכולות בלי לדאוג לגבי ניהול תשתיות. השמה של כל שכבה בתיקייה יעודית, שידועה גם כ-[מודל 3 השכבות](https://he.wikipedia.org/wiki/%D7%90%D7%A8%D7%9B%D7%99%D7%98%D7%A7%D7%98%D7%95%D7%A8%D7%94_%D7%A8%D7%91-%D7%A9%D7%9B%D7%91%D7%AA%D7%99%D7%AA#%D7%90%D7%A8%D7%9B%D7%99%D7%98%D7%A7%D7%98%D7%95%D7%A8%D7%AA_%D7%A9%D7%9C%D7%95%D7%A9_%D7%A9%D7%9B%D7%91%D7%95%D7%AA) ([באנגלית](https://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture)) זאת הדרך _הפשוטה_ להשיג את המטרה.
+
+```bash
+my-system
+├─ apps (components)
+│ ├─ component-a
+ │ ├─ entry-points
+ │ │ ├─ api # controller comes here
+ │ │ ├─ message-queue # message consumer comes here
+ │ ├─ domain # features and flows: DTO, services, logic
+ │ ├─ data-access # DB calls w/o ORM
+```
+
+**אחרת:** לעתים דחופות נתקלים בכך שהמתכנתים מעבירים אובייקטי תקשורת כדוגמת request/reqponse לפונקציות בשכבות של הלוגיקה או ניהול המידע - דבר זה פוגע בעיקרון ההפרדה וגורם לכך שבעתיד יהיה קשה יותר להנגיש את הלוגיקה לסוגי קלינטים אחרים כדוגמת: בדיקות יחידה, משימות מתוזמנות וmessage queues.
+
+🔗 [**לקריאה נוספת: חלק את המוצר לשכבות**](./sections/projectstructre/createlayers.md)
+
+
+
+## ![✔] 1.3 עטפו כלים משותפים בחבילות, שקלו את הפצתם
+
+**אמ;לק:** מקמו את כל הכלים שאפשר לשתף אותם בתיקייה ייעודית, למשל 'libraries' וכל כלי בתיקייה פנימית נפרדת, למשל '/libraries/logger'. הפכו את הכלי לחבילה בלתי תלויה עם קובץ ה package.json שלו וזאת כדי להגדיל את הכימוס (encapsulation), ואפשרו הפצה עתידית למאגר. כאשר הפרוייקט שלכם בנוי בתצורת monorepo, כלים אלו יכולים להיות מוגדרים על ידי שימוש ב 'npm linking' לכתובת הפיזית שלהם על ידי שימוש ב ts-paths או על ידי הפצה והתקנה על ידימנהל חבילות כדוגמת 'npm registry'.
+
+```bash
+my-system
+├─ apps (components)
+ │ ├─ component-a
+├─ libraries (generic cross-component functionality)
+│ ├─ logger
+│ │ ├─ package.json
+│ │ ├─ src
+│ │ │ ├─ index.js
+
+```
+
+**אחרת:** צרכנים של כלי יהיו צמודים לפונקציונליות הפנימית שלו. על ידי הגדרה של package.json בשורש הכלי מישהו יכול להגדיר קובץ package.json.main או package.json.exports כדי להצהיר במפורש אילו קבצים ופונקציולניות היא חלק מהחלקים הנגישים של הכלי.
+
+🔗 [**לקריאה נוספת: בנייה לפי תכונה**](./sections/projectstructre/wraputilities.md)
+
+
+
+## ![✔] 1.4 השתמשו בקונפיגורציה עם משתני סביבה באופן מודע, מאובטח והיררכי
+
+**אמ;לק:** הגדרת סביבה מושלמת צריכה להבטיח כי (א) שמות משתנים יכולים להיקרא מקבצים כמו גם ממשתני סביבה (ב) סודות נשמרים מחוץ לקוד ששייך למאגר (ג) הקונפיגורציה היא היררכית לצורך חיפוש קל יותר (ד) תמיכה בסוגים שונים של משתנים (ה) וידוא מוקדם של משתנים לא תקינים (ו) הגדרת ברירת מחדל לכל שדה. ישנן מספר ספריות שעונות על רוב הדרישות הללו כמו [convict](https://www.npmjs.com/package/convict), [env-var](env-var), [zod](https://github.com/colinhacks/zod), ועוד...
+
+**אחרת:** נניח וישנו משתנה סביבה הכרחי שלא הוגדר, המערכת תתחיל לרוץ בהצלחה, תענה לבקשות, חלק מהמידע יעודכן במסד הנתונים, ולפתע יהיה חסר לה שדה הכרחי להמשך התהליך ושבלעדיו היא לא יכולה לסיים את הפעולה, מה שייצור מערכת במצב "מלוכלך".
+
+🔗 [**לקריאה נוספת: שיטות עבודה של קונפיגורציה**](./sections/projectstructre/configguide.md)
+
+
+
+## ![✔] 1.5 שקלו את כל ההשלכות בעת בחירת מסגרת
+
+**אמ;לק:** כאשר בונים אפליקציות ו API-ים, שימוש בפריימוורק הוא חובה. קל להתעלם מהאפשרויות השונות שקיימות ומשיקולים חשובים ובסופו של דבר להשתמש באפשרות שפחות תואמת לדרישות של המוצר. נכון ל2023/2024 אנו מאמינים כי ארבעת הפריימוורקים הללו הם הכדאיים ביותר להשוואה: [Nest.js](https://nestjs.com/), [Fastify](https://www.fastify.io/), [express](https://expressjs.com/), ו [Koa](https://koajs.com/). לחצו על לקריאה נוספת בהמשך כדי לקרוא פרטים נוספים בעד ונגד כל אחת מהאפשרויות. באופן פשטני, אנו מאמינים כי Node.js זאת ההתאמה הכי טובה לצוותים שרוצים לעבוד בשיטת OOP או לבנות מוצרים שמיועדים לגדול בצורה ניכרת ואי אפשר לחלק אותם לרכיבים קטנים _ועצמאיים_. ההמלצה שלנו היא Fastify עבור מערכות בגודל סבירents (כמו Microservices) שמושתתים על עקרונות פשוטים של Node.js.
+
+**אחרת:** בשל הכמות העצומה של השיקולים, קל לקבל החלטה על בסיס מידע חלקי ולהשוות תפוחים לתפוזים. למשל, ישנה הנחה רווחת שFastify הוא web-server מינימלי שראוי להשוות לexpress בלבד. בפועל, זהו פריימוורק עשיר עם הרבה הרחבות רשמיות שמכסות הרבה צרכים.
+
+🔗 [**לקריאה נוספת: בחירת הפריימוורק הנכון**](./sections/projectstructre/choose-framework.md)
+
+## ![✔] 1.6 השתמשו ב-TypeScript במידתיות ובצורה מושכלת
+
+**אמ;לק:** קידוד ללא מקדמי בטיחות של סיווג משתנים הוא כבר לא אפשרות בת קיימא, TypeScript מהווה את האפשרות הפופולרית ביותר למשימה זו. משתמשים בה להגדרת סוגי משתנים וערכי החזרה של פונקציות. עם זאת, זוהי חרב פיפיות שיכולה בקלות ליצור מורכבות בשל בסביבות 50 מילות מפתח נוספות שיש לה ותכונות מתוחכמות שצריך לדעת להשתמש בהן. שימוש בה צריך להיעשות במידה, בעדיפות להגדרות פשוטות של משתנים, ושימוש ביכולות מתקדמות רק כאשר צורך הכרחי מופיע.
+
+**אחרת:** [מחקרים](https://earlbarr.com/publications/typestudy.pdf) מראים כי שימוש ב-TypeScript יכול לעזור בזיהוי כ20% מהבאגים בשלבים מוקדמים יותר. ללא TypeScript חווית הפיתוח ב IDE נהיית בלתי נסבלת. מהצד השני, 80% מהבאגים היא לא עוזרת לזהות. כתוצאה מכך, שימוש בTypeScript מוסיף ערך מוגבל. רק הוספה של בדיקות איכותיות יכולה לעזור לזהות את מגוון הבאגים הרחב, כולל כאלו שנגרמים מאפיון לא תקין של סוג המשתנה. שימוש לא טוב גם עלול להרוג את המטרה, תכונות מורכבות של קוד מעלות אתמורכבות הקוד מה שבאופן ישיר מעלה את מספר הבאגים וזמן התיקון של כל באג.
+
+🔗 [**לקריאה נוספת: שיקולים לשימוש ב-TypeScript**](./sections/projectstructre/typescript-considerations.md)
+
+
+
+# `2. ניהול שגיאות`
+
+## ![✔] 2.1 השתמשו ב Async-Await או הבטחות לניהול שגיאות אסינכרוניות
+
+**אמ;לק:** ניהול שגיאות אסינכרוניות על ידי שימוש ב-callbacks זו הדרך המהירה לגהינום (הידועה בשם [פירמידת דום](https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming))). המתנה הטובה ביותר שאפשר לתת לקוד הוא שימוש ב-promises בסגנון async-await דבר שמאפשר קוד הרבה יותר נקי ומסודר וסינטקס דומה ל try-catch.
+
+**אחרת:** סגנון הכתיבה `function(err, response)` הכולל שימוש ב-callbacks של Node.js, סולל דרך בטוחה לקוד שאי אפשר לתחזק בשל הערבוב בין ניהול שגיאות לניהול התהליך התקני של המערכת, עם קינון מוגזם וסגנון קוד מוזר.
+
+🔗 [**לקריאה נוספת: הימנעות מ-callbacks**](./sections/errorhandling/asyncerrorhandling.md)
+
+
+
+## ![✔] 2.2 הרחיבו את מבנה אוביקט השגיאה המובנה `Error`
+
+**אמ;לק:** ישנן ספריות שזורקות שגיאה כמחרוזת או כאובייקט פרי מחשבת כותבי הקוד של הספריה - דבר שיוצר מורכבות בניהול השגיאות וביצירת מכנה משותף בין מודולים שונים. במקום זאת, השקיעו ביצירת אובייקט או מחלקת (class) שגיאה שיורשת מאובייקט השגיאה המובנה של השפה והשתמשו בזה בכל פעם שצריך לדחות את המצב, לזרוק שגיאה או להפיץ שגיאה. השגיאה האפליקטיבית צריכה להוסיף שדות נוספים כדוגמת שם השגיאה ורמת החומרה שלה. על ידי כך, לכל השגיאות ישנו מבנה אחיד והן מאפשרות תמיכה טובה יותר בניהול שגיאות. ישנו כלל של `no-throw-literal` ESLint שבודק בצורה מיטבית את השימוש הזה (על אף שיש לזה קצת [מגבלות](https://eslint.org/docs/rules/no-throw-literal) שיכולות להסתדר על ידי שימוש ב-TypeScript והגדרת החוק `@typescript-eslint/no-throw-literal`)
+
+**אחרת:** כאשר מפעילים רכיב כלשהו, אם ישנה אי וודאות איזה סוג של שגיאה יגיע - זה גורם לכך שניהול השגיאות יהיה הרבה יותר מורכב. גרוע מכך, שימוש באובייקטים מומצאים לתיאור שגיאות עלול להוביל לאיבוד של שגיאות קריטיות בעלות מידע חשוב כמו מעקב אחר מקור השגיאה!
+
+🔗 [**לקריאה נוספת: שימוש באובייקט השגיאה המובנה**](./sections/errorhandling/useonlythebuiltinerror.md)
+
+
+
+## ![✔] 2.3 הבחינו בין שגיאות קטסטרופליות לבין שגיאות תפעוליות
+
+**אמ;לק:** שגיאות תפעוליות (למשל קלט לא תקין בפנייה ל-API) מתייחסות למקרים ידועים בהם ההשפעה של השגיאה מובנת לחלוטין ויכולה להיות מנוהלת בצורה מחושבת. מצד שני, שגיאות קטסטרופליות (ידועות גם כשגיאות תכנות) מתייחסות לשגיאות לא צפויות במערכת שדורשות אתחול בטוח שלה.
+
+**אחרת:** אתם עלולים לאתחל את המערכת בעקבות כל שגיאה. אבל למה לגרום לכ-5000 משתמשים לחוות התנתקות בגלל שגיאה תפעולית צפויה ושולית? ההיפך הוא גם לא אידיאלי - להשאיר את המערכת עובדת כאשר קטסטרופה לא צפויה קרתה בה והיא עלולה לגרור התנהגות בלתי צפויה. הבדלה בין שני המקרים מאפשרת התמודדות מושכלת ומאוזנת בהתאם להקשר.
+
+🔗 [**לקריאה נוספת: שגיאות תפעוליות מול שגיאות תכנות**](./sections/errorhandling/operationalvsprogrammererror.md)
+
+
+
+## ![✔] 2.4 נהלו את השגיאות במרוכז ולא באמצעות כלי ביניים
+
+**אמ;לק:** מימוש הניהול של השגיאות כמו למשל תעוד השגיאה, החלטה אם לקרוס ואילו מדדים לנטר צריך להיות מרוכז במקום אחד שכל הכניסות למערכת (למשל APIs, cron jobs, scheduled jobs) משתמשות בו כאשר חלה בהן שגיאה.
+
+**אחרת:** אם לא מנהלים את השגיאות במקום אחד אז במהרה יהיה שכפול קוד וכנראה ניהול לא תקין של חלק מהשגיאות.
+
+🔗 [**לקריאה נוספת: ניהול השגיאות במקום מרוכז**](./sections/errorhandling/centralizedhandling.md)
+
+
+
+## ![✔] 2.5 תעדו את שגיאות ה-API באמצעות OpenAPI או GraphQL
+
+**אמ;לק:** אפשרו למשתמשי ה-API שלכם לדעת אילו שגיאות עלולות להגיע כתשובה, כך שהם יוכלו להתמודד איתן בצורה מושכלת במקום לקרוס. ל-API מבוסס REST זה נעשה בדרך כלל באמצעות כלי תעוד כמו OpenAPI. אם אתם משתמשים ב-GraphQL, אתם יכולים להשתמש בסכמה ובהערות בשביל להשיג את המטרה.
+
+**אחרת:** מי שמשתמש ב-API שלנו עלול להחליט לגרום למערכת שלו לקרוס ולאתחל את עצמה רק בגלל שהוא קיבל שגיאה שהוא לא הצליח להבין. שימו לב: המשתמש של ה-API שלכם יכול להיות אתם (מה שקורה הרבה כשמשתמשים במיקרוסרוויסים).
+
+🔗 [**לקריאה נוספת: תיעוד שגיאות ה-API באמצעות OpenAPI או GraphQL**](./sections/errorhandling/documentingusingswagger.md)
+
+
+
+## ![✔] 2.6 הורידו את התהליך בצורה מסודרת כאשר זר בא לבקר
+
+**אמ;לק:** כאשר שגיאה לא ידועה חלה (שגיאה קטסטרופלית, ראו תובנה 2.3) - ישנה חוסר ודאות לגבי הבריאות והיציבות של המערכת. במקרה כזה, אין דרך לברוח מלגרום לשגיאה להיות ברת צפייה, סגירת חיבוריות לרכיבים נוספים והורדה של התהליך. כל סביבת ריצה מהימנה כדוגמת שירותי Docker או שירותי ענן שמספקים פתרונות ללא שרת (serverless) יוודאו שהתהליך יעלה מחדש עבורכם.
+
+**אחרת:** כאשר שגיאה לא צפויה קורית, רכיב כלשהו עלול להיות במצב לא תקין (למשל event emitter גלובאלי שמפסיק להפיץ אירועים בשל כשלון פנימי) והחל מעכשיו שאר הבקשות שמשתמשות ברכיב זה עלולות להיכשל או להתנהג באופן ממש לא צפוי.
+
+🔗 [**לקריאה נוספת: הורדת התהליך**](./sections/errorhandling/shuttingtheprocess.md)
+
+
+
+## ![✔] 2.7 השתמשו ב-Logger מוכר ואמין כדי להגדיל את הקְרִיאוּת של השגיאות
+
+**אמ;לק:** כלי לוגים איכותי כדוגמת [Pino](https://github.com/pinojs/pino) או [Winston](https://github.com/winstonjs/winston) מגדיל את הקריאות וההבנה של הלוגים על ידי שימוש ברמת חומרה, עימוד, עיצוב, צבעים ועוד. ל-`console.log` אין את היכולות הללו וראוי להימנע משימוש בו. העיפרון החד ביותר בתחום מאפשר הוספה של שדות שימושיים נוספים ללא תקורה גבוהה של ביצועים. מפתחים צריכים לכתוב את הלוגים ל-`stdout` ולתת לתשתית להעביר את המידע לכלי המתאים עבור כל מקרה.
+
+**אחרת:** רפרוף על שורות console.log או בצורה ידנית על קבצי טקסט עמוסים לעייפה ללא כלי חיפוש ותצוגה מותאמים עלולים להשאיר אתכם לעבוד עד השעות הקטנות של הלילה.
+
+🔗 [**לקריאה נוספת: שימוש ב-Logger אמין**](./sections/errorhandling/usematurelogger.md)
+
+
+
+## ![✔] 2.8 בידקו את תגובת המערכת לשגיאות על ידי שימוש בכלי הבדיקות האהוב עליכם
+
+**אמ;לק:** בין אם יש לכם כלי QA אוטומטי ומקצועי ובין אם אחד המפתחים מבצע את הבדיקות - ודאו כי לא רק המסלול הבטוח של הקוד מכוסה, אלא גם ניהול השגיאות ושחוזרות השגיאות שאמורות לחזור במקרה של תקלה. נוסף על כך, בידקו מקרים מורכבים יותר של שגיאות, כמו למשל שגיאות בלתי צפויות, כדי לוודא שהרכיב שמטפל בשגיאות מבצע זאת כראוי (ראו דוגמאות קוד בקישור "לקריאה נוספת")
+
+**אחרת:** ללא בדיקות כלל, לא ידניות ולא אוטומטיות, לא תוכלו לסמוך על הקוד שלכם שיחזיר את השגיאה הנכונה. ללא שגיאות משמעותיות לא תוכלו לטפל בשגיאות.
+
+🔗 [**לקריאה נוספת: בדיקת התנהגות בעת שגיאה**](./sections/errorhandling/testingerrorflows.md)
+
+
+
+## ![✔] 2.9 גלו שגיאות וזמני השבתה על ידי שימוש בכלי APM
+
+**אמ;לק:** כלי ניטור ובדיקת ביצועים (מוכרים כ-APM) מודדים באופן יזום את הקוד או ה-API כך שבאופן קסום הם מציגים שגיאות, התרסקויות וחלקים שעובדים לאט מהצפוי ואתם לא שמים לב אליהם.
+
+**אחרת:** אתם עלולים להתאמץ רבות במדידה של בעיות ביצועים וזמני השבתה של המערכת, כנראה שלעולם לא תהיו מודעים לאיזה חלקים במערכת הם האיטיים ביותר ואיך זה משפיע על חווית המשתמש.
+
+🔗 [**לקריאה נוספת: שימוש ב-APM**](./sections/errorhandling/apmproducts.md)
+
+
+
+## ![✔] 2.10 תפסו מקרים לא מטופלים של דחיות של הבטחות
+
+**אמ;לק:** כל שגיאה או דחייה שחוזרת מהבטחה תיבלע, אלא אם כן בשלב הפיתוח יטפלו בה כמו שצריך. אפילו אם יש בקוד האזנה ל `process.uncaughtException`! כדי להתגבר על זה צריך להאזין גם ל `process.unhandledRejection`.
+
+**אחרת:** השגיאות במערכת יבלעו ויעלמו ללא עקבות. לא משהו שצריך לדאוג ממנו...
+
+🔗 [**לקריאה נוספת: תפיסה של דחיות של הבטחות**](./sections/errorhandling/catchunhandledpromiserejection.md)
+
+
+
+## ![✔] 2.11 היכשלו מהר, ודאו את משתני הקלט באמצעות ספריה יעודית
+
+**אמ;לק:** הגדירו תבנית קלט קשיחה ל-API כדי להימנע מבאגים מלוכלכים שקשה הרבה יותר לעקוב אחריהם. כתיבת קוד האימות הוא תהליך מייגע, אלא אם כן תשתמשו באחת הספריות המוכרות כיום כמו [ajv](https://www.npmjs.com/package/ajv), [zod](https://github.com/colinhacks/zod), או [typebox](https://github.com/sinclairzx81/typebox).
+
+**אחרת:** חשבו על זה - הפונקציה שלכם מצפה לקבל כקלט משתנה `discount` מספרי שמי שקרה לפונקציה שכח להעביר. בהמשך, הקוד בודק אם `discount != 0` (כמות ההנחה שאפשר לקבל גדולה מאפס), ואם כן אז המשתמש יהנה מההנחה. וואו, זה באג מלוכלך, ראיתם???
+
+🔗 [**לקריאה נוספת: כשלון מהיר**](./sections/errorhandling/failfast.md)
+
+
+
+## ![✔] 2.12 תמיד המתינו לתשובה מההבטחות לפני שאתם מעבירים את התשובה הלאה כדי להימנע ממעקב חלקי
+
+**אמ;לק:** תמיד כתבו `return await` כאשר מחזירים תוצאה של הבטחה וזאת כדי להשיג ערך מלא של מעקב אחר מקור השגיאה (stacktrace). אם פונקציה מחזירה הבטחה היא חייבת להיות מוגדרת כפונקציה אסינכרונית ובמפורש לחכות להבטחה שהיא מחזירה.
+
+```js
+async function promisifyFunction() {
+ // some logic
+ return await new Promise(...);
+}
+```
+
+**אחרת:** הפונקציה שמחזירה הבטחה ללא המתנה לא תופיע בנתיב המעקב אחרי השגיאה (stacktrace). חוסרים כאלו עלולים לסבך את ההבנה של זרימת המערכת שגרמה לשגיאה, במיוחד אם הגורם להתנהגות הלא צפויה קרה בפונקציה החסרה.
+
+🔗 [**לקריאה נוספת: החזרת הבטחות**](./sections/errorhandling/returningpromises.md)
+
+
+
+# `3. תבניות קוד וסגנון עיצוב`
+
+## ![✔] 3.1 השתמשו ב-ESLint
+
+**אמ;לק:** [ESLint](https://eslint.org) הוא הסטנדרט דה-פקטו למציאת שגיאות בקוד ותיקון של סגנונות קוד, לא רק זיהוי של רווח סורר שעלול ליצור תקלה אלא גם זיהוי של קוד שלא עומד בסטנדרטים (anti-pattern) כמו זריקת שגיאות ללא סיווג. אמנם ESLint יכול לתקן באופן אוטומטי סגנונות קוד, אך כלים אחרים כדוגמת [prettier](https://www.npmjs.com/package/prettier) טובים יותר בעיצוב וסגנון הקוד ועובדים בשילוב עם ESLint.
+
+**אחרת:** מפתחים ישתעממו תוך כדי השקעת זמנם במציאת רווחים סוררים וידאגו לאורך השורה והזמן היקר שלהם יבוזבז על איך לשמור על סגנון הקוד של הפרוייקט.
+
+🔗 [**לקריאה נוספת: שימוש ב-ESLint ו-Prettier**](./sections/codestylepractices/eslint_prettier.md)
+
+
+
+## ![✔] 3.2 השתמשו בתוספים של Node.js שמרחיבים את ESLint
+
+**אמ;לק:** על גבי הסטנדרט של חוקי ESLint שמכסים את שפת JavaScript, הוסיפו את התוספים היעודיים של Node.js כמו [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), [eslint-plugin-require](https://www.npmjs.com/package/eslint-plugin-require), [eslint-plugin-jest](https://www.npmjs.com/package/eslint-plugin-jest) ועוד תוספים שמממשים חוקים נוספים ומועילים.
+
+**אחרת:** הרבה תבניות קוד לא תקינות שבשימוש ב-Node.js נעלמות מתחת לרדאד. לדוגמה, מפתחים יכתבו `require(variableAsPath)` עם משתנה שמאפשר גישה לתיקיה בקוד, דבר שמאפשר לתוקפים להריץ כל קוד JS. אם תשתמשו בחוקי Node.js תוכלו לזהות את הטעות הזאת ולקבל עליה התראה מבעוד מועד.
+
+
+
+## ![✔] 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 הפרידו בין ההצהרות השונות בצורה תקנית
+
+בין אם אתם משתמשים בנקודה-פסיק (;) בשביל להפריד בין ההצהרות על המשתנים ובין אם לא, עצם הידיעה על ההשלכות של ירידת שורה במקום הלא מתאים או של הוספה אוטומטית של נקודה-פסיק, יעזרו לכם לזהות שגיאות סינטקס רגילות.
+
+**אמ;לק:** שימוש ב-ESLint כדי להעלות את המודעות לגבי הסיכון הכרוך בזה. כלים כמו [Prettier](https://prettier.io/) או [Standardjs](https://standardjs.com/) יכולים באופן אוטומטי לפתור את הבעיות הללו.
+
+**אחרת:** כמו שראינו בסעיף הקודם, "המתורגמן" (interpreter) של JavaScript מוסיף אוטומטית נקודה-פסיק בסוף כל הצהרה במידה ואין, או שהוא מחליט כי ההצהרה מסתיימת במקום אחר מהמתוכנן על ידינו, דבר שעלול להוביל לתוצאות בלתי צפויות. אפשר להשתמש בהשמות ולהימנע מ [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) כדי להימנע מרוב ההתנהגויות הבלתי צפויות.
+
+### דוגמה
+
+```javascript
+// Do
+function doThing() {
+ // ...
+}
+
+doThing()
+
+// Do
+
+const items = [1, 2, 3]
+items.forEach(console.log)
+
+// Avoid — throws exception
+const m = new Map()
+const a = [1,2,3]
+[...m.values()].forEach(console.log)
+> [...m.values()].forEach(console.log)
+> ^^^
+> SyntaxError: Unexpected token ...
+
+// Avoid — throws exception
+const count = 2 // it tries to run 2(), but 2 is not a function
+(function doSomething() {
+ // do something amazing
+}())
+// put a semicolon before the immediate invoked function, after the const definition, save the return value of the anonymous function to a variable or avoid IIFEs altogether
+```
+
+🔗 [**לקריאה נוספת:** "Semi ESLint rule"](https://eslint.org/docs/rules/semi)
+
+🔗 [**לקריאה נוספת:** "No unexpected multiline ESLint rule"](https://eslint.org/docs/rules/no-unexpected-multiline)
+
+
+
+## ![✔] 3.5 תנו לפונקציה שם
+
+**אמ;לק:** תנו שמות לכל הפונקציות, כולל closures ו-callbacks. הימנעו מפונקציות אנונימיות. זה מאוד שימושי כשבודקים אפליקציות Node.js. מתן שמות לכל הפונקציות יאפשר לכם להבין בקלות על מה אתם מסתכלים כשאתם צופים בתמונת מצב של הזיכרון של האפליקציה.
+
+**אחרת:** לדבג את גרסת היצור (production) על בסיס תמונת מצב של הזיכרון (core dump) עלול להיות מאתגר כשהבעיות של הזיכרון קורות בכל מיני פונקציות אנונימיות.
+
+
+
+## ![✔] 3.6 השתמשו במוסכמות קבועות במתן שמות למשתנים, לקבועים, לפונקציות ולמחלקות
+
+**אמ;לק:** השתמשו ב-**_lowerCamelCase_** כאשר אתם נותנים שמות לקבועים, משתנים ופונקציות, **_UpperCamelCase_** (גם האות הראשונה גדולה) כאשר אתם נותנים שמות למחלקות ו-**_UPPER_SNAKE_CASE_** כאשר אתם נותנים שמות למשתנים גלובליים או סטטיים. סדר זה יאפשר לכם להבחין בקלות בין משתנים רגילים ופונקציות לבין מחלקות שדורשות אתחול ולבין משתנים גלובליים. השתמשו בשמות שמתארים היטב את משמעות המשתנה, אך שיהיה קצר.
+
+**אחרת:** JavaScript היא השפה היחידה בעולם שתאפשר לכם לקרוא ל-constructor ("Class") ישירות ללא אתחול. לכן, חשוב מאוד להבדיל בין שמות מחלקות ושמות פונקציות על ידי שימוש ב-UpperCamelCase.
+
+### דוגמאות
+
+```javascript
+// for global variables names we use the const/let keyword and UPPER_SNAKE_CASE
+let MUTABLE_GLOBAL = "mutable value";
+const GLOBAL_CONSTANT = "immutable value";
+const CONFIG = {
+ key: "value",
+};
+
+// examples of UPPER_SNAKE_CASE convention in nodejs/javascript ecosystem
+// in javascript Math.PI module
+const PI = 3.141592653589793;
+
+// https://github.com/nodejs/node/blob/b9f36062d7b5c5039498e98d2f2c180dca2a7065/lib/internal/http2/core.js#L303
+// in nodejs http2 module
+const HTTP_STATUS_OK = 200;
+const HTTP_STATUS_CREATED = 201;
+
+// for class name we use UpperCamelCase
+class SomeClassExample {
+ // for static class properties we use UPPER_SNAKE_CASE
+ static STATIC_PROPERTY = "value";
+}
+
+// for functions names we use lowerCamelCase
+function doSomething() {
+ // for scoped variable names we use the const/let keyword and lowerCamelCase
+ const someConstExample = "immutable value";
+ let someMutableExample = "mutable value";
+}
+```
+
+
+
+## ![✔] 3.7 העדיפו const על פני let. ניטשו את var
+
+**אמ;לק:** שימוש ב-`const` משמעותו היא שלאחר שהמשתנה מאותחל לראשונה הוא לא יכול להיות מאותחל שוב. העדפת שימוש ב-`const` תעזור לכם לא להתפתות ולהשתמש שוב באותו משתנה לצרכים שונים ותהפוך את הקוד שלכם לקריא יותר. אם משתנה צריך להיות מאותחל מחדש, למשל בתוך לולאת for, אז השתמשו ב-`let` לצורך כך. נקודה נוספת שחשוב לציין היא ששימוש ב-`let` אפשרית רק בתוך אותו הבלוק שהיא הוגדרה בו. `var` נצמד לscope של הפונקציה שהוא מוגדר בו ולא לבלוק ספציפי ולכן [צריך לא להשתמש בו ב-ES6](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70) כשאפשר להשתמש ב-`const` וב-`let`.
+
+**אחרת:** דיבוג הופך להיות מאוד מסורבל כאשר משתנה משתנה לעיתים דחופות.
+
+🔗 [**לקריאה נוספת: JavaScript ES6+: var, let, or const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 טענו מודולים בתחילה, ולא בקריאה לפונקציות
+
+**אמ;לק:** טענו את המודולים (require...) בתחילת כל קובץ, לפני כל הפונקציות. שיטת עבודה פשוטה זו לא רק שתעזור לכם בקלות ובמהירות לזהות את התלויות של קובץ מסוים, אלא גם תמנע מספר בעיות אפשריות.
+
+**אחרת:** טעינת מודולים היא תהליך סינכרוני ב-Node.js. אם הטעינה תתבצע מתוך פונקציה היא עלולה לחסום טיפול בבקשות אחרות בזמן קריטי. בנוסף לכך, אם מודול חיוני או מישהו שהוא תלוי בו יזרקו שגיאה ויפילו את השרת, מומלץ שזה יוודע כמה שיותר מוקדם, מה שלא בטוח יקרה במקרה שהמודול נטען מתוך פונקציה.
+
+
+
+## ![✔] 3.9 הגדירו כניסה מסודרת לספריה שלכם
+
+**אמ;לק:** בעת פיתוח מודול או ספריה, הגדירו קובץ בסיס שמייצא את הקוד המיועד לשימוש חיצוני. מנעו מהמשתמשים של הקוד שלכם את הצורך לייבא קבצים שיושבים עמוק אצלכם ואת הצורך שלהם להבין את מבנה הקבצים שלכם. כאשר עובדים בשיטת commonjs (require), זה יכול להיעשות על ידי שימוש בקובץ index.js שיושב בתיקיה הראשית או בהגדרת השדה main בקובץ package.json. כאשר עובדים בשיטת ESM (import), אם קובץ package.json קיים בתיקיה הראשית, אז השדה "exports" מאפשר את הגדרת הקובץ הראשי. אך אם אין קובץ package.json, אז שימוש בקובץ index.js בתיקיה הראשית ייצא את כל הפונקציונליות שמיועדת לשימוש חיצוני.
+
+**אחרת:** קיומו של קובץ ראשי רשמי משמש כממשק חיצוני שמסתיר את החלקים הפנימיים של הספריה, מקשר את המשתמש ישירות לקוד הזמין ומאפשר שינויים עתידיים ללא צורך לשבוראת החוזה.
+
+### דוגמה
+
+```javascript
+// Avoid: client has deep familiarity with the internals
+
+// Client code
+const SMSWithMedia = require("./SMSProvider/providers/media/media-provider.js");
+
+// Better: explicitly export the public functions
+
+//index.js, module code
+module.exports.SMSWithMedia = require("./SMSProvider/providers/media/media-provider.js");
+
+// Client code
+const { SMSWithMedia } = require("./SMSProvider");
+```
+
+
+
+## ![✔] 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, המנעו מ-callbacks
+
+**אמ;לק:** async-await זו הדרך הפשוטה ביותר לכתוב קוד אסינכרוני שירגיש כמו קוד סינכרוני. הקוד שיכתב בשיטת async-await הוא גם הרבה יותר פשוט ותומך במנגנון ה-try-catch. שיטה זו מחליפה את הצורך ב-callbacks ו-promises ברוב המקרים. שימוש בשיטה זו בקוד היא כנראה אחת המתנות הטובות יותר שאפשר לתת למי שיקרא את הקוד.
+
+**אחרת:** טיפול בשגיאות אסינכרוניות בשיטת callback היא כנראה הדרך המהירה לגהנום - מכיוון ששיטה זו מחייבת בדיקת שגיאות בכל שלב, יוצרת קינון מוזר בקוד ומקשה על הבנת תהליך הזרימה של הקוד.
+
+🔗[**לקריאה נוספת:** מדריך ל-async-await](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 השתמשו בפונקציות חץ (=>)
+
+**אמ;לק:** אמנם מומלץ להשתמש ב async-await ולהימנע מהגדרת פרמטרים בפונקציות כאשר מתעסקים עם API ישן שתומך ב-callbacks או הבטחות - פונקציות חץ מאפשרות לארגן את הקוד קומפקטי יותר וכמובן ששומרות על הקונטקסט של פונקצית המעטפת (`this`).
+
+**אחרת:** קוד ארוך יותר (על בסיס פונקציות של ES5) חשוף ליותר באגים וקשה יותר לקריאה.
+
+🔗 [**לקריאה נוספת: הגיע הזמן לאמץ את פונקציות החץ**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
+
+
+
+## ![✔] 3.13 הימנעו מהשפעות צדדיות מחוץ לפונקציות
+
+**אמ;לק:** הימנעו מכתיבת קוד עם השפעות צדדיות כמו פעולת רשת או פניה למסד נתונים מחוץ לפונקציה. אם כן תכתבו קוד כזה הוא ירוץ מיד כאשר קובץ אחר פונה לקובץ הזה. הקוד 'הצף' הזה עלול לרוץ כאשר התשתית אותה הוא מבקש עוד לא זמינה עבורו. זה גם פוגע בביצועים אפילו אם אין צורך בפונקציה שעבורה מתבצעת הפעולה בזמן הריצה. דבר אחרון, כתיבת כיסוי לפעולה זו בשביל בדיקות הרבה יותר מורכבת כשהיא לא נעשית בפונקציה. במקום זאת, שימו את הקוד הזה בפונקציה שצריכה להיקרא במפורש. אם הקוד הזה צריך להיקרא ישר בעת עליית המערכת, שיקלו שימוש ב-factory או בתבנית אחרת שמתאימה לדרישה כזאת.
+
+**אחרת:** תשתיות סטנדרטיות בעולם הווב מגדירות ניהול שגיאות, משתני סביבה וניטור תקלות. אם הפעולה תתבצע לפני שהתשתית מאותחלת אז לא יהיה ניטור של המקרה או שהפעולה תיכשל בשל חוסר בהגדרות שטרם נטענו.
+
+
+
+# `4. בדיקות ובקרת איכות`
+
+> יש לנו מדריכים יעודיים לכתיבת בדיקות. רשימת שיטות העבודה המומלצות פה היא סיכום כללי של המדריכים הללו.
+>
+> א. [שיטות עבודה מומלצות בכתיבת בדיקות ל-JavaScript](https://github.com/goldbergyoni/javascript-testing-best-practices)
+> ב. [בדיקות ב-Node.js - מעבר ליסודות](https://github.com/testjavascript/nodejs-integration-tests-best-practices)
+
+
+## ![✔] 4.1 לפחות, כיתבו בדיקות API לרכיבים השונים
+
+**אמ;לק:** ברוב הפרויקטים אין בדיקות אוטומטיות כלל בשל לוח זמנים קצר, או שהתחילו לנסות להוסיף בדיקות בפרויקט נוסף אך זה יצא משליטה וננטש עם הזמן. לכן, לתעדף ולהתחיל בדיקות API שזאת הדרך הקלה לכתוב בדיקות ולספק כיסוי (בדיקות) של הקוד מאשר בבדיקות יחידה של פונקציות בודדות (אפשר להשתמש בשביל זה גם בכלים חיצוניים ללא כתיבת קוד, למשל שימוש ב-[Postman](https://www.getpostman.com/)). לאחר מכן, אם יש לכם יותר משאבים וזמן תמשיכו עם בדיקות מתקדמות יותר כגון בדיקות יחידה, בדיקות מול מסדי הנתונים בדיקות ביצועים ועוד.
+
+**אחרת:** אתם עלולים לבזבז ימים שלמים על כתיבת בדיקות יחידה בלבד ולגלות בסופו של דבר שכיסיתם רק 20% מהמערכת.
+
+
+
+## ![✔] 4.2 סווגו 3 חלקים במתן שם לכל בדיקה
+
+**אמ;לק:** גירמו לבדיקה לתאר את שלב הדרישות כך שהיא תסביר את עצמה גם לQA או לאחרים (כולל אתכם בעתיד הלא רחוק) שלא בקיאים בחלקים הפנימיים של הקוד. ציינו בבדיקה (1) איזה חלק נבדק, (2) באילו תנאים (3) ומה התוצאה שמצפים שתחול.
+
+**אחרת:** ההתקנה בדיוק נכשלה, בדיקה בשם “Add product” נכשלה. האם זה מתאר מה בדיוק לא תיפקד?
+
+🔗 [**לקריאה נוספת: סווגו 3 חלקים במתן שם לכל בדיקה**](./sections/testingandquality/3-parts-in-name.md)
+
+
+
+## ![✔] 4.3 חלקו את הבדיקות לפי תבנית ה-AAA
+
+**אמ;לק:** חלקו את הבדיקות לשלושה חלקים נפרדים: Arrange (ארגן), Act (פעל) & Assert (ודא) (AAA). החלק הראשון כולל את ההכנה של הסביבה לבדיקה, החלק השני את ההרצה במצב בדיקות, ולבסוף החלק שמוודא שהתקבלה התוצאה הרצויה. שימוש במבנה זה בעקביות מבטיח שהקורא לא יבזבז זמן מחשבה של הבנת הבדיקה.
+
+**אחרת:** לא מספיק שיתבזבז זמן נרחב מהיום על הבנת הקוד, עכשיו גם החלק הקל ביום (הבנת הבדיקות) ישרוף את המוח.
+
+🔗 [**לקריאה נוספת: חלקו את הבדיקות לפי תבנית ה-AAA**](./sections/testingandquality/aaa.md)
+
+
+
+## ![✔] 4.4 וודאו כי גרסת ה-Node אחידה
+
+**אמ;לק:** השתמשו בכלים המעודדים או אוכפים שימוש באותה גרסת Node.js בסביבות השונות ועל ידי שאר המפתחים. כלים כמו [nvm](https://github.com/nvm-sh/nvm), ו-[Volta](https://volta.sh/) מאפשרים להגדיר במפורש את הגרסה הנדרשת בפרויקט בקובץ כך שכל חברי הצוות יכולים על ידי הרצת פקודה אחת ליישר קו עם גרסת הפרויקט. ישנה אפשרות שגרסה זו גם תשתקף לתהליך ה-CI וסביבת היצור/לקוחות (לדוגמה על ידי העתקת מספר הגרסה המבוקש ל-`.Dockerfile` ולקבצי ההגדרות של תהליך ה-CI).
+
+**אחרת:** מפתחת עלולה להיתקל או לפספס שגיאה מכיוון שהיא משתמשת בגרסת Node.js שונה משאר הצוות. או גרוע מכך, סביבת היצור רצה באמצעות גרסה שונה מזו שהורצו עליה הבדיקות.
+
+
+
+## ![✔] 4.5 הימנעו מאתחול מידע גרעיני משותף, הגדירו לפי צורך של בדיקה
+
+**אמ;לק:** כדי להימנע מצמידות ותלות בין בדיקות שונות וכדי שיהיה ברור יותר איך להסביר מה קורה בשלבים השונים של הבדיקה, ראוי שכל בדיקה תוסיף ותנהל את המידע העוטף שלה (למשל שורות בטבלה). במקרה ובדיקה צריכה לצרוך מידע מטבלה או להניח שהוא קיים שם - היא צריכה קודם לכן להוסיף את המידע במפורש ולהימנע משינוי מידע של בדיקה אחרת.
+
+**אחרת:** תארו לכם מקרה בו הפצת גרסה נכשלה בשל שגיאה בבדיקות, הצוות משנס מותניים לחקור את הסיבה ומגיע אם התובנה העצובה שהמערכת עובדת תקין אבל הבדיקות דורסות מידע אחת לשניה ולכן נכשלו ועצרו את תהליך ההפצה.
+
+🔗 [**לקריאה נוספת: הימנעו מאתחול מידע גרעיני משותף**](./sections/testingandquality/avoid-global-test-fixture.md)
+
+
+
+## ![✔] 4.6 תייגו את הבדיקות
+
+**אמ;לק:** בדיקות שונות צריכות לרוץ בתרחישים שונים: בדיקות שפיות (quick smoke/sanity), IO-less, בדיקות בעת שמירת קובץ או commit, בדיקות מלאות מקצה לקצה (e2e) כאשר נפתח PR וכולי... התרחישים השונים יכולים להיות מוגדרים בעזרת תיוג בדיקות שונות עם מילות מפתח כמו #cold #api #sanity דבר המאפשר להגדיר קבוצת בדיקות בהתאם לצורך ולהריץ רק אותה. למשל, זאת השיטה להריץ רק את קבוצת בדיקות השפיות באמצעות [Mocha](https://mochajs.org/): `mocha --grep 'sanity'`.
+
+**אחרת:** הרצה של כל הבדיקות כולל כאלו שמבצעות עשרות פניות למסד נתונים בכל פעם שמפתח עושה שינוי קטן יאט את קצב הפיתוח בצורה ניכרת ותמנע מצוות הפיתוח להריץ בדיקות.
+
+
+
+## ![✔] 4.7 בידקו את רמת כיסוי הבדיקות שלכם, זה יעזור לזהות דפוסי בדיקות שגויים
+
+**אמ;לק:** כלים לבדיקת כיסוי הקוד על ידי בדיקות כמו [Istanbul](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc) מצוינים בשל שלוש סיבות: הם בחינם (אין עלות לדו"חות שהם מספקים), הם עוזרים לזהות ירידה באחוזי הכיסוי, ואחרון חביב הם מדגישים מקרים של אי התאמה בבדיקות: על ידי צפייה בצבעים שהדוחות הללו מספקים אפשר לזהות למשל שיש קטעי קוד שלא נבדקים לעולם כמו הסתעפויות של `catch` (מה שאומר שיש בדיקות רק למסלול המצליח ולא למקרים של השגיאות). רצוי להגדיר את זה כך שזה יפיל את תהליכי יצירת הגרסאות במידה והכיסוי לא עובר סף מסוים.
+
+**אחרת:** לא יהיה שום אמצעי מדידה שידווח שקטעים נרחבים מהקוד לא נבדקים כלל.
+
+
+
+## ![✔] 4.8 Use production-like environment 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. Use an environment which is as close to your real production environment as possible like a-continue (Missed -continue here, needs content. Judging by the **Otherwise** clause, this should mention docker-compose)
+
+**אחרת:** 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 שכתבו את הקוד באופן קבוע בעזרת כלי ניתוח סטטי
+
+**אמ;לק:** שימוש בכלי ניתוח סטטי (static analysis tools) עוזר בכך שהוא נותן דרכים מתאימות לשפר את איכות הקוד ולשמור על הקוד מתוחזק. אפשר להוסיף כלים כאלו לשלבי הבנייה ב-CI כך שיפילו את התהליך במידה והם מזהים ניחוחות בקוד. אחד היתרונות העיקריים שלהם על פני כלים פשוטים יותר הוא היכולת לזהות פגמים באיכות הקוד על פני מספר קבצים (כמו כפל קוד), מורכבות גבוהה של קוד ומעקב אחרי ההיסטוריה וההתקדמות של הקוד. שני כלים מומלצים לשימוש הם [Sonarqube](https://www.sonarqube.org/) (7,900+ [stars](https://github.com/SonarSource/sonarqube)) ו [Code Climate](https://codeclimate.com/) (2,400+ [stars](https://github.com/codeclimate/codeclimate)).
+
+**אחרת:** אם הקוד באיכות נמוכה, תקלות ובעיות ביצועים תמיד יהוו אתגר שאף ספריה חדשה ונוצצת או פתרון טכנולוגי חדיש יוכלו לפתור.
+
+🔗 [**לקריאה נוספת: שכתוב!**](./sections/testingandquality/refactoring.md)
+
+
+
+## ![✔] 4.10 הדמיית תשובות של שרתי HTTP חיצוניים
+
+**אמ;לק:** השתמשו בכלי הדמיה של המידע שמגיע מהרשת עבור תשובות שמגיעות משירותים חיצוניים (כמו בקשות REST ו GraphQL). זה הכרחי לא רק כדי לבודד את הרכיב שנבדק אלא בעיקר כדי לבדוק מצבים לא צפויים. כלים כמו [nock](https://github.com/nock/nock) או [Mock-Server](https://www.mock-server.com/) מאפשרים להגדיר תשובה מסוימת לבקשה לשירות חיצוני בשורת קוד בודדה. חשוב לא לשכוח לדמות גם שגיאות, עיכובים, timeouts, וכל אירוע אחר שכנראה יקרה בסביבת הייצור.
+
+**אחרת:** לאפשר לרכיב לגשת למידע אמיתי משירותים חיצוניים בדרך כלל יסתיים בבדיקות פשוטות שמכסות בעיקר את המקרים שהכל טוב. בנוסף לכך הבדיקות לפעמים יכשלו ויהיו איטיות יותר.
+
+🔗 [**לקריאה נוספת: הדמיית שירותים חיצוניים**](./sections/testingandquality/mock-external-services.md)
+
+
+
+## ![✔] 4.11 בידקו את פונקציות הביניים בנפרד
+
+**אמ;לק:** כאשר פונקציית ביניים (middleware) אוחזת נתח משמעותי של לוגיקה שמשתרעת על פני מספר עצום של בקשות, כדאי לבדוק אותה בצורה מבודדת ללא צורך לטעון את כל תשתית הפריימוורק. אפשר להשיג את הפעולה הזאת בקלות על ידי עטיפה או הדמיה של `{req, res, next}`.
+
+**אחרת:** באג בפונקציות ביניים ב-`express` === באג ברוב הקריטי של הבקשות.
+
+🔗 [**לקריאה נוספת: לבדוק פונקציות ביניים בנפרד**](./sections/testingandquality/test-middlewares.md)
+
+
+
+## ![✔] 4.12 קבעו את הפורט בייצור, הגדירו אקראי לבדיקות
+
+**אמ;לק:** כאשר מבצעים בדיקות מול API, זה רצוי ואף נהוג לאתחל את השרת בתוך הבדיקות. תנו לשרת לבחור פורט באופן אקראי כאשר מריצים בדיקות כדי למנוע התנגשויות. אם אתם משתמשים בשרת HTTP של Node.js (בשימוש על ידי רוב ספריות התשתית), כדי להשיג את היכולת הזאת אין צורך לעשות כלום מלבד להעביר port=0 - זה כבר יגרום להקצאה דינאמית של פורט.
+
+**אחרת:** הגדרה של פורט ספציפי ימנע את האפשרות להריץ שני טסטים במקביל. רוב הכלים שמריצים כיום טסטים - מריצים במקביל כברירת מחדל.
+
+🔗 [**לקריאה נוספת: הגדירו פורט אקראי לבדיקות**](./sections/testingandquality/randomize-port.md)
+
+
+
+## ![✔] 4.13 בידקו את חמשת התוצאות האפשריות
+
+**אמ;לק:** בעת בדיקת מקרה, ודאו שאתם מכסים את חמשת הקטגוריות האפשריות. בכל פעם שפעולה חלה (למשל קריאת API), מתחילה תגובה, **תוצאה** משמעותית נוצרת ומתבצעת קריאה לבדיקה. ישנן חמש סוגי תוצאות לכל מקרה: תגובה, שינוי נראה לעין (כמו עדכון במסד הנתונים), שליחת קריאה ל-
+API, הודעה חדשה נרשמת לתור, וקריאה לכלי צפיה במידע (כמו לוגר ואנליטיקות). [רשימת בדיקות בסיסיות](https://testjavascript.com/wp-content/uploads/2021/10/the-backend-checklist.pdf). כל סוג של תוצאה מגיע אם אתגרים יחודיים ושיטות להמתיק את האתגרים הללו - כתבנו מדריך יעודי על נושא זה [בדיקות ב-Node.js - מעבר ליסודות](https://github.com/testjavascript/nodejs-integration-tests-best-practices)
+
+**אחרת:** תארו לעצמכם מקרה של בדיקת הוספה של מוצר חדש למערכת. נפוץ לראות בדיקות שמכסות אך ורק את המקרים של תשובה תקינה. מה יקרה אם המוצר לא יתווסף על אף התשובה החיובית? מה צריך להיעשות במידה ובעת הוספת מוצר יש גם קריאה לשירות חיצוני או הוספת הודעה לתור - האם הבדיקה לא צריכה להתייחס גם לזה? קל להתעלם ממגוון מקרים, ובנקודה זאת [רשימת הבדיקות](https://testjavascript.com/wp-content/uploads/2021/10/the-backend-checklist.pdf) עוזרת.
+
+🔗 [**לקריאה נוספת: בדיקת חמשת התוצאות**](./sections/testingandquality/test-five-outcomes.md)
+
+
+
+# `5. עלייה לאוויר`
+
+## ![✔] 5.1. ניטור
+
+**אמ;לק:** ניטור הוא משחק של מציאת בעיות לפני שהמשתמשים מוצאים אותן - מובן מאליו שזה צריך להיות בראש סדר העדיפויות. השוק מוצף בהצעות להגדרות מה הם המדדים הבסיסיים שחייבים לעקוב אחריהם (ההמלצות שלנו בהמשך), לאחר מכן לעבור על כל היכולות המעניינות שכל מוצר מציע ולבחור את הפתרון המיטבי עבור הדרישות שלכם. בכל מקרה, ארבעת השכבות הניתנות לצפייה חייבות להימדד: (1) Uptime - מציינת האם המערכת זמינה, (2) Metrics - מציינת מהי ההתנהגות המצטברת של המערכת (האם 99% מהבקשות נענות), (3) Logging - בודקת אם בקשה מסויימת מסתיימת בהצלחה, (4) Distributed tracing - בודקת האם המערכת יציבה בין הרכיבים המבוזרים שלה.
+
+**אחרת:** כשלון === לקוחות מאוכזבים. פשוט מאוד.
+
+🔗 [**לקריאה נוספת: ניטור!**](./sections/production/monitoring.md)
+
+
+
+## ![✔] 5.2. הגדילו את יכולת הצפייה בעזרת לוגים איכותיים
+
+**אמ;לק:** לוגים יכולים להיות פח הזבל של שלל מצבים שהמפתחים רצו לדבג או לחלופין מסך מהמם שמתאר את המצב של המוצר. תכננו את הלוגים שלכם מהיום הראשון: איך הם נאספים, איפה הם נשמרים ואיך הם מנותחים כדי להבטיח שהמידע ההכרחי (אחוז שגיאות, מעקב אחר פעולה בין מספר שירותים וכו') באמת נגיש ובר שימוש.
+
+**אחרת:** יש לכם קופסה שחורה שקשה להבין למה היא מגיעה למצב הנוכחי, ורק עכשיו אתם מתחילים לשכתב את כל הלוגים שלכם כדי שיהיה מידע רלוונטי.
+
+🔗 [**לקריאה נוספת: הגדלת השקיפות על ידי לוגים איכותיים**](./sections/production/smartlogging.md)
+
+
+
+## ![✔] 5.3. האצילו כל מה שאפשר (לדוגמה gzip, SSL) לשירות נפרד
+
+**אמ;לק:** Node.js גרוע בלבצע פעולות שדורשות עוצמת חישוב גבוהה מה-CPU, כמו למשל דחיסה, סיום תהליך SSL, וכו'... כדאי שתשתמשו בתשתיות כמו nginx, HAproxy או שירותי ענן אחרים לשם כך.
+
+**אחרת:** הת'רד הבודד והמסכן שלכם יישאר עסוק במשימות תשתיתיות במקום להתעסק בלב המערכת שלכם והביצועים יישחקו בהתאם.
+
+🔗 [**לקריאה נוספת: האצלת כל מה שאפשר (לדוגמה gzip, SSL) לשירות נפרד**](./sections/production/delegatetoproxy.md)
+
+
+
+## ![✔] 5.4. קיבוע תלויות
+
+**אמ;לק:** הקוד שלכם צריך להיות זהה בכל הסביבות, אך ללא קובץ יעודי npm יאפשר שימוש בתלויות שונות בכל סביבה. ודאו כי יש לכם `package-lock.json` כך שכל הסביבות יהיו זהות.
+
+**אחרת:** אנשי הבדיקות יאשרו גרסה שתתנהג אחרת בסביבת ייצור. גרוע מכך, שרתים שונים באותה סביבה יריצו קוד שונה.
+
+🔗 [**לקריאה נוספת: קיבוע תלויות**](./sections/production/lockdependencies.md)
+
+
+
+## ![✔] 5.5. הבטיחו את זמינות המערכת בעזרת הכלי המתאים
+
+**אמ;לק:** המערכת צריכה להמשיך לעבוד ולהתאתחל במידה וקרתה שגיאה קריטית. סביבות ריצה חדשות כמו למשל כאלו המבוססות דוקר (כמו קוברנטיס), או Serverless מטפלות בזה בצורה אוטומטית. כאשר המוצר מותקן על שרת אמיתי פיזי, יש צורך לנהל את משאבי המערכת בעזרת כלי כמו [systemd](https://systemd.io/). אך יש להימנע מלעשות זאת כאשר משתמשים בתשתיות שכבר מבצעות את הניטור מכיוון שזה יגרום לבליעת שגיאות. כאשר לתשתית אין מודעות לשגיאות, אין לה יכולת של ביצוע שלבי פיחות משאבים כמו העברת האינסטנס של המערכת למקום אחר ברשת.
+
+**אחרת:** הרצה של עשרות אינסטנסים ללא סיבה ברורה ויותר מידי כלי תשתית יחד (cluster management, docker, PM2) עלול לגרום לכאוס עבור ה-DevOps.
+
+🔗 [**לקריאה נוספת: הבטיחו את זמינות המערכת בעזרת הכלי המתאים**](./sections/production/guardprocess.md)
+
+
+
+## ![✔] 5.6. השתמשו בכל מעבדי ה-CPU
+
+**אמ;לק:** בתצורה הבסיסית שלה, מערכת מבוססת Node.js תרוץ על מעבד CPU אחד ושאר המעבדים ינוחו. מחובתכם לשכפל את התהליך ולנהל את המערכת ככה שתרוץ על כל המעבדים. רוב תשתיות הריצה החדשות (כמו קוברנטיס) מאפשרות לשכפל את התהליכים למספר מעבדים, אך הן לא מבטיחות להשתמש בכל המעבדים - זאת האחריות שלכם! אם המוצר מותקן על שרת פיזי, אז כחלק מאחריותכם אתם צריכים גם להשתמש בפתרונות שיבצעו את השכפול של התהליך (כמו systemd).
+
+**אחרת:** המוצר שלכם ינצל לכל היותר 25% מהמשאבים הזמינים(!). זכרו שלשרת רגיל יש 4 מעבדי CPU או יותר, והתקנה סטנדרטית של תהליך Node.js משתמשת רק במעבד אחד (גם שירותים בשיטת PaaS כמו AWS beanstalk!).
+
+🔗 [**לקריאה נוספת: השתמשו בכל מעבדי ה-CPU**](./sections/production/utilizecpu.md)
+
+
+
+## ![✔] 5.7. תיצרו ‘maintenance endpoint’
+
+**אמ;לק:** חישפו מידע רלוונטי על המערכת, למשל מצב הזיכרון ו -[REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop), באמצעות API מאובטח. על אף שמומלץ להישען על כלים יעודיים לשם כך, את חלק מהמידע והפעולות יותר פשוט לבדוק באמצעות כתיבת קוד.
+
+**אחרת:** תגלו שאתם מבצעים הרבה “diagnostic deploys” – העלאת קוד לסביבת הייצור רק כדי להשיג עוד קצת מידע אבחנתי על המערכת.
+
+🔗 [**לקריאה נוספת: יצירת ‘maintenance endpoint’**](./sections/production/createmaintenanceendpoint.md)
+
+
+
+## ![✔] 5.8. גלו את הלא ידוע בעזרת מוצרי APM
+
+**אמ;לק:** שיקלו הוספת שכבה נוספת של בטיחות למוצר שלכם - [APM](https://en.wikipedia.org/wiki/Application_performance_management) (Application monitoring and performance products). אמנם רוב הסממנים והגורמים יכולים להימצא על ידי טכניקות ניטור סטנדרטיות, אך במערכות מבוזרות יש עוד רבדים סמויים מן העין. ניטור מערכות ובדיקת ביצועים (או בקיצור APM) יכולים באופן קסום להוסיף שכבה נוספת של חוויית פיתוח מעבר למה שמספקים הכלים הסטנדרטיים. לדוגמה, ישנם כלי APM שיכולים להדגיש טרנזקציה שטוענת לאט מידי את **צד הלקוח** ולהציע מה הסיבה לכך. כלים אלו גם מספקים יותר הקשר לצוות הפיתוח שמנסים לחקור שגיאה וזאת על ידי הצגה של העומסים שהיו בשרת בזמן שחלה השגיאה.
+
+**אחרת:** אתם משקיעים זמן ניכר במדידת ביצועי API ואי זמינות של המערכת, כנראה שלעולם לא תהיו מודעים לאילו חלקים בקוד הם האיטיים ביותר בזמן אמת ואיך זה משפיע על חווית המשתמש.
+
+🔗 [**לקריאה נוספת: גילוי שגיאות וזמני השבתה בעזרת מוצרי APM**](./sections/production/apmproducts.md)
+
+
+
+## ![✔] 5.9. כתבו את הקוד מותאם להתקנה
+
+**אמ;לק:** קודדו כאשר התוצאה הסופית במחשבותיכם, התכוננו להתקנה בסביבת יצור כבר מהיום הראשון. זה אמנם נשמע קצת מעורפל ולכן בקישור ישנן מספר המלצות הקשורות לתמיכה במוצר שכבר הותקן.
+
+**אחרת:** אלופי העולם של IT/DevOps לא ינסו להציל מערכת שכתובה גרוע.
+
+🔗 [**לקריאה נוספת: כתבו את הקוד מותאם להתקנה**](./sections/production/productioncode.md)
+
+
+
+## ![✔] 5.10. מדדו ושימרו את ניצול הזיכרון
+
+**אמ;לק:** ל-Node.js ישנה מערכת יחסים מורכבת עם ניהול הזיכרון: למנוע ה-v8 ישנם גבולות עדינים של צריכת זיכרון (1.4GB) וישנן דרכים ידועות איך לגרום לזליגת זיכרון בקוד של Node.js - ולכן מעקב אחר צריכת הזיכרון של תהליך Node.js הוא חובה. במוצרים קטנים, אפשר לאמוד את צריכת הזיכרון כל כמה זמן בעזרת פקודות shell, אבל במוצרים בינוניים-גדולים צריך לתעדף שימוש בכלים חזקים לניטור מצב הזיכרון.
+
+**אחרת:** זולגים לכם מאות MB כל יום מהתהליך כמו שקרה ב[וולמארט](https://www.joyent.com/blog/walmart-node-js-memory-leak)
+
+🔗 [**לקריאה נוספת: מדידה ושמירה על ניצול הזיכרון**](./sections/production/measurememory.md)
+
+
+
+## ![✔] 5.11. Get your frontend assets out of Node
+
+**אמ;לק:** Serve frontend content using a specialized infrastructure (nginx, S3, CDN) because Node performance gets hurt when dealing with many static files due to its single-threaded model. One exception to this guideline is when doing server-side rendering
+
+**אחרת:** 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. Strive to be stateless
+
+**אמ;לק:** Store any type of _data_ (e.g. user sessions, cache, uploaded files) within external data stores. When the app holds data in-process this adds additional layer of maintenance complexity like routing users to the same instance and higher cost of restarting a process. To enforce and encourage a stateless approach, most modern runtime platforms allows 'reapp-ing' instances periodically
+
+**אחרת:** 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
+
+**אמ;לק:** Even the most reputable dependencies such as Express have known vulnerabilities (from time to time) that can put a system at risk. This can be easily be 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 you 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 a transaction id to each log statement
+
+**אמ;לק:** Assign the same identifier, transaction-id: uuid(), to each log entry within a single request (also known as correlation-id/tracing-id/request-context). Then when inspecting errors in logs, easily conclude what happened before and after. Node has a built-in mechanism, [AsyncLocalStorage](https://nodejs.org/api/async_context.html), for keeping the same context across asynchronous calls. 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
+
+🔗 [**Read More: Assign ‘TransactionId’ to each log statement**](./sections/production/assigntransactionid.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 – some npm packages determine the current environment and optimize their code for production
+
+**אחרת:** Omitting this simple property might greatly degrade performance when dealing with some specific libraries like Express server-side rendering
+
+🔗 [**Read More: Set NODE_ENV=production**](./sections/production/setnodeenv.md)
+
+
+
+## ![✔] 5.16. Design automated, atomic and zero-downtime deployments
+
+**אמ;לק:** Research shows that teams who perform many deployments lower the probability of severe production issues. Fast and automated deployments that don’t require risky manual steps and service downtime significantly improve the deployment process. You should probably achieve this using Docker combined with CI tools as they became the industry standard for streamlined deployment
+
+**אחרת:** Long deployments -> production downtime & human-related error -> team unconfident in making deployment -> fewer deployments and features
+
+
+
+## ![✔] 5.17. Use an LTS release of Node.js
+
+**אמ;לק:** 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
+
+🔗 [**Read More: Use an LTS release of Node.js**](./sections/production/LTSrelease.md)
+
+
+
+## ![✔] 5.18. Log to stdout, avoid specifying log destination within the app
+
+**אמ;לק:** Log destinations should not be hard-coded by developers within the application code, but instead should be defined by the execution environment the application runs in. Developers should write logs to `stdout` using a logger utility and then let the execution environment (container, server, etc.) pipe the `stdout` stream to the appropriate destination (i.e. Splunk, Graylog, ElasticSearch, etc.).
+
+**אחרת:** If developers set the log routing, less flexibility is left for the ops professional who wishes to customize it. Beyond this, if the app tries to log directly to a remote location (e.g., Elastic Search), in case of panic or crash - further logs that might explain the problem won't arrive
+
+🔗 [**Read More: Log Routing**](./sections/production/logrouting.md)
+
+
+
+## ![✔] 5.19. Install your packages with `npm ci`
+
+**אמ;לק:** Run `npm ci` to strictly do a clean install of your dependencies matching package.json and package-lock.json. Obviously production code must use the exact version of the packages that were used for testing. While package-lock.json file sets strict version for dependencies, in case of mismatch with the file package.json, the command 'npm install' will treat package.json as the source of truth. On the other hands, the command 'npm ci' will exit with error in case of mismatch between these files
+
+**אחרת:** QA will thoroughly test the code and approve a version that will behave differently in production. Even worse, different servers in the same production cluster might run different code.
+
+🔗 [**Read More: Use npm ci**](./sections/production/installpackageswithnpmci.md)
+
+
+
+## ![✔] 6.1. Embrace linter security rules
+
+
+
+**אמ;לק:** 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, preferably 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
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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, [rate-limiter-flexible](https://www.npmjs.com/package/rate-limiter-flexible) package, or (for smaller and less critical apps) a rate-limiting middleware (e.g. [express-rate-limit](https://www.npmjs.com/package/express-rate-limit))
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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 resort, 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
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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 against injection attacks.
+
+**אחרת:** 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
+
+**אמ;לק:** This is a collection of security advice that is 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
+
+
+
+**אמ;לק:** 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).
+
+**אחרת:** Attackers could perform direct attacks on your application's users, leading to huge security vulnerabilities
+
+🔗 [**Read More: Using secure headers in your application**](./sections/security/secureheaders.md)
+
+
+
+## ![✔] 6.7. Constantly and automatically inspect for vulnerable dependencies
+
+
+
+**אמ;לק:** 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.
+
+**אחרת:** An attacker could detect your web framework and attack all its known vulnerabilities.
+
+🔗 [**Read More: Dependency security**](./sections/security/dependencysecurity.md)
+
+
+
+## ![✔] 6.8. Protect Users' Passwords/Secrets using bcrypt or scrypt
+
+
+
+**אמ;לק:** Passwords or secrets (e.g. API keys) should be stored using a secure hash + salt function like `bcrypt`,`scrypt`, or worst case `pbkdf2`.
+
+**אחרת:** Passwords and secrets that are stored without using a secure function are vulnerable to brute forcing and dictionary attacks that will lead to their disclosure eventually.
+
+🔗 [**Read More: User Passwords**](./sections/security/userpasswords.md)
+
+
+
+## ![✔] 6.9. Escape HTML, JS and CSS output
+
+
+
+**אמ;לק:** Untrusted data that is sent down to the browser might get executed instead of just being displayed, this is commonly 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)
+
+**אחרת:** An attacker might store 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
+
+
+
+**אמ;לק:** Validate the incoming requests' body payload and ensure it meets 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)
+
+**אחרת:** 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 blocklisting JWTs
+
+
+
+**אמ;לק:** 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 blocklist of untrusted tokens that are validated on each request.
+
+**אחרת:** 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: Blocklist JSON Web Tokens**](./sections/security/expirejwt.md)
+
+
+
+## ![✔] 6.12. Prevent brute-force attacks against authorization
+
+
+
+**אמ;לק:** A simple and powerful technique is to limit authorization attempts using two metrics:
+
+1. The first is number of consecutive failed attempts by the same user unique ID/name and IP address.
+2. The second is number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day.
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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 user's behalf by invoking the container with the flag "-u username"
+
+**אחרת:** 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 their 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
+
+
+
+**אמ;לק:** 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
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** `eval` is evil as it allows executing 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.
+
+**אחרת:** Malicious JavaScript code finds a way into 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
+
+
+
+**אמ;לק:** 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
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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
+
+**אחרת:** 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 file system, or access already existing system files.
+
+🔗 [**Read More: Safe module loading**](./sections/security/safemoduleloading.md)
+
+
+
+## ![✔] 6.18. Run unsafe code in a sandbox
+
+
+
+**אמ;לק:** 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 act as a sandbox
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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.
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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.
+
+**אחרת:** [Have you heard about the eslint developer whose 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
+
+
+
+**אמ;לק:** 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)
+
+**אחרת:** 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
+
+
+
+**אמ;לק:** 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)
+
+**אחרת:** 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
+
+
+
+## ![✔] 6.24. Prevent unsafe redirects
+
+
+
+**אמ;לק:** Redirects that do not validate user input can enable attackers to launch phishing scams, steal user credentials, and perform other malicious actions.
+
+**אחרת:** If an attacker discovers that you are not validating external, user-supplied input, they may exploit this vulnerability by posting specially-crafted links on forums, social media, and other public places to get users to click it.
+
+🔗 [**Read More: Prevent unsafe redirects**](./sections/security/saferedirects.md)
+
+
+
+## ![✔] 6.25. Avoid publishing secrets to the npm registry
+
+
+
+**אמ;לק:** Precautions should be taken to avoid the risk of accidentally publishing secrets to public npm registries. An `.npmignore` file can be used to ignore specific files or folders, or the `files` array in `package.json` can act as an allow list.
+
+**אחרת:** Your project's API keys, passwords or other secrets are open to be abused by anyone who comes across them, which may result in financial loss, impersonation, and other risks.
+
+🔗 [**Read More: Avoid publishing secrets**](./sections/security/avoid_publishing_secrets.md)
+
+
+
+## ![✔] 6.26 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 outdated packages, 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
+
+
+
+## ![✔] 6.27. Import built-in modules using the 'node:' protocol
+
+
+
+**אמ;לק:** Import or require built-in Node.js modules using the 'node protocol' syntax:
+
+```javascript
+import { functionName } from "node:module"; // note that 'node:' prefix
+```
+
+For example:
+
+```javascript
+import { createServer } from "node:http";
+```
+
+This style ensures that there is no ambiguity with global npm packages and makes it clear for the reader that the code refers to a well-trusted official module. This style can be enforced with the eslint rule ['prefer-node-protocol'](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md)
+
+**אחרת:** Using the import syntax without 'node:' prefix opens the door for [typosquatting attacks](https://en.wikipedia.org/wiki/Typosquatting) where one could mistakenly mistype a module name (e.g., 'event' instead of 'events) and get a malicious package that was built only to trick users into installing them
+
+
+
+# `7. טיוטה: ביצועים`
+
+## Our contributors are working on this section. [Would you like to join?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
+
+
+
+## ![✔] 7.1. Don't block the event loop
+
+**אמ;לק:** Avoid CPU intensive tasks as they will block the mostly single-threaded Event Loop and offload those to a dedicated thread, process or even a different technology based on the context.
+
+**אחרת:** As the Event Loop is blocked, Node.js will be unable to handle other request thus causing delays for concurrent users. **3000 users are waiting for a response, the content is ready to be served, but one single request blocks the server from dispatching the results back**
+
+🔗 [**Read More: Do not block the event loop**](./sections/performance/block-loop.md)
+
+
+
+## ![✔] 7.2. Prefer native JS methods over user-land utils like Lodash
+
+**אמ;לק:** It's often more penalising to use utility libraries like `lodash` and `underscore` over native methods as it leads to unneeded dependencies and slower performance.
+Bear in mind that with the introduction of the new V8 engine alongside the new ES standards, native methods were improved in such a way that it's now about 50% more performant than utility libraries.
+
+**אחרת:** You'll have to maintain less performant projects where you could have simply used what was **already** available or dealt with a few more lines in exchange of a few more files.
+
+🔗 [**Read More: Native over user land utils**](./sections/performance/nativeoverutil.md)
+
+
+
+# `8. דוקר`
+
+🏅 Many thanks to [Bret Fisher](https://github.com/BretFisher) from whom we learned many of the following practices
+
+
+
+## ![✔] 8.1 Use multi-stage builds for leaner and more secure Docker images
+
+**אמ;לק:** Use multi-stage build to copy only necessary production artifacts. A lot of build-time dependencies and files are not needed for running your application. With multi-stage builds these resources can be used during build while the runtime environment contains only what's necessary. Multi-stage builds are an easy way to get rid of overweight and security threats.
+
+**אחרת:** Larger images will take longer to build and ship, build-only tools might contain vulnerabilities and secrets only meant for the build phase might be leaked.
+
+### Example Dockerfile for multi-stage builds
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY . .
+RUN npm ci && npm run build
+
+
+FROM node:slim-14.4.0
+
+USER node
+EXPOSE 8080
+
+COPY --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/package-lock.json ./
+RUN npm ci --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+🔗 [**Read More: Use multi-stage builds**](./sections/docker/multi_stage_builds.md)
+
+
+
+## ![✔] 8.2. Bootstrap using `node` command, avoid `npm start`
+
+**אמ;לק:** Use `CMD ['node','server.js']` to start your app, avoid using npm scripts which don't pass OS signals to the code. This prevents problems with child-processes, signal handling, graceful shutdown and having zombie processes
+
+Update: [Starting from npm 7, npm claim](https://docs.npmjs.com/cli/v7/using-npm/changelog#706-2020-10-27) to pass signals. We follow and will update accordingly
+
+**אחרת:** When no signals are passed, your code will never be notified about shutdowns. Without this, it will lose its chance to close properly possibly losing current requests and/or data
+
+[**Read More: Bootstrap container using node command, avoid npm start**](./sections/docker/bootstrap-using-node.md)
+
+
+
+## ![✔] 8.3. Let the Docker runtime handle replication and uptime
+
+**אמ;לק:** When using a Docker run time orchestrator (e.g., Kubernetes), invoke the Node.js process directly without intermediate process managers or custom code that replicate the process (e.g. PM2, Cluster module). The runtime platform has the highest amount of data and visibility for making placement decision - It knows best how many processes are needed, how to spread them and what to do in case of crashes
+
+**אחרת:** Container keeps crashing due to lack of resources will get restarted indefinitely by the process manager. Should Kubernetes be aware of that, it could relocate it to a different roomy instance
+
+🔗 [**Read More: Let the Docker orchestrator restart and replicate processes**](./sections/docker/restart-and-replicate-processes.md)
+
+
+
+## ![✔] 8.4. Use .dockerignore to prevent leaking secrets
+
+**TL;DR**: Include a `.dockerignore` file that filters out common secret files and development artifacts. By doing so, you might prevent secrets from leaking into the image. As a bonus the build time will significantly decrease. Also, ensure not to copy all files recursively rather explicitly choose what should be copied to Docker
+
+**Otherwise**: Common personal secret files like `.env`, `.aws` and `.npmrc` will be shared with anybody with access to the image (e.g. Docker repository)
+
+🔗 [**Read More: Use .dockerignore**](./sections/docker/docker-ignore.md)
+
+
+
+## ![✔] 8.5. Clean-up dependencies before production
+
+**אמ;לק:** Although Dev-Dependencies are sometimes needed during the build and test life-cycle, eventually the image that is shipped to production should be minimal and clean from development dependencies. Doing so guarantees that only necessary code is shipped and the amount of potential attacks (i.e. attack surface) is minimized. When using multi-stage build (see dedicated bullet) this can be achieved by installing all dependencies first and finally running `npm ci --production`
+
+**אחרת:** Many of the infamous npm security breaches were found within development packages (e.g. [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes))
+
+🔗 Read More: [Remove development dependencies](./sections/docker/install-for-production.md)
+
+
+
+## ![✔] 8.6. Shutdown smartly and gracefully
+
+**אמ;לק:** Handle the process SIGTERM event and clean-up all existing connection and resources. This should be done while responding to ongoing requests. In Dockerized runtimes, shutting down containers is not a rare event, rather a frequent occurrence that happen as part of routine work. Achieving this demands some thoughtful code to orchestrate several moving parts: The load balancer, keep-alive connections, the HTTP server and other resources
+
+**אחרת:** Dying immediately means not responding to thousands of disappointed users
+
+🔗 [**Read More: Graceful shutdown**](./sections/docker/graceful-shutdown.md)
+
+
+
+## ![✔] 8.7. Set memory limits using both Docker and v8
+
+**אמ;לק:** Always configure a memory limit using both Docker and the JavaScript runtime flags. The Docker limit is needed to make thoughtful container placement decision, the --v8's flag max-old-space is needed to kick off the GC on time and prevent under utilization of memory. Practically, set the v8's old space memory to be a just bit less than the container limit
+
+**אחרת:** The docker definition is needed to perform thoughtful scaling decision and prevent starving other citizens. Without also defining the v8's limits, it will under utilize the container resources - Without explicit instructions it crashes when utilizing ~50-60% of its host resources
+
+🔗 [**Read More: Set memory limits using Docker only**](./sections/docker/memory-limit.md)
+
+
+
+## ![✔] 8.8. Plan for efficient caching
+
+**אמ;לק:** Rebuilding a whole docker image from cache can be nearly instantaneous if done correctly. The less updated instructions should be at the top of your Dockerfile and the ones constantly changing (like app code) should be at the bottom.
+
+**אחרת:** Docker build will be very long and consume lot of resources even when making tiny changes
+
+🔗 [**Read More: Leverage caching to reduce build times**](./sections/docker/use-cache-for-shorter-build-time.md)
+
+
+
+## ![✔] 8.9. Use explicit image reference, avoid `latest` tag
+
+**אמ;לק:** Specify an explicit image digest or versioned label, never refer to `latest`. Developers are often led to believe that specifying the `latest` tag will provide them with the most recent image in the repository however this is not the case. Using a digest guarantees that every instance of the service is running exactly the same code.
+
+In addition, referring to an image tag means that the base image is subject to change, as image tags cannot be relied upon for a deterministic install. Instead, if a deterministic install is expected, a SHA256 digest can be used to reference an exact image.
+
+**אחרת:** A new version of a base image could be deployed into production with breaking changes, causing unintended application behaviour.
+
+🔗 [**Read More: Understand image tags and use the "latest" tag with caution**](./sections/docker/image-tags.md)
+
+
+
+## ![✔] 8.10. Prefer smaller Docker base images
+
+**אמ;לק:** Large images lead to higher exposure to vulnerabilities and increased resource consumption. Using leaner Docker images, such as Slim and Alpine Linux variants, mitigates this issue.
+
+**אחרת:** Building, pushing, and pulling images will take longer, unknown attack vectors can be used by malicious actors and more resources are consumed.
+
+🔗 [**Read More: Prefer smaller images**](./sections/docker/smaller_base_images.md)
+
+
+
+## ![✔] 8.11. Clean-out build-time secrets, avoid secrets in args
+
+**אמ;לק:** Avoid secrets leaking from the Docker build environment. A Docker image is typically shared in multiple environment like CI and a registry that are not as sanitized as production. A typical example is an npm token which is usually passed to a dockerfile as argument. This token stays within the image long after it is needed and allows the attacker indefinite access to a private npm registry. This can be avoided by coping a secret file like `.npmrc` and then removing it using multi-stage build (beware, build history should be deleted as well) or by using Docker build-kit secret feature which leaves zero traces
+
+**אחרת:** Everyone with access to the CI and docker registry will also get access to some precious organization secrets as a bonus
+
+🔗 [**Read More: Clean-out build-time secrets**](./sections/docker/avoid-build-time-secrets.md)
+
+
+
+## ![✔] 8.12. Scan images for multi layers of vulnerabilities
+
+**אמ;לק:** Besides checking code dependencies vulnerabilities also scan the final image that is shipped to production. Docker image scanners check the code dependencies but also the OS binaries. This E2E security scan covers more ground and verifies that no bad guy injected bad things during the build. Consequently, it is recommended running this as the last step before deployment. There are a handful of free and commercial scanners that also provide CI/CD plugins
+
+**אחרת:** Your code might be entirely free from vulnerabilities. However it might still get hacked due to vulnerable version of OS-level binaries (e.g. OpenSSL, TarBall) that are commonly being used by applications
+
+🔗 [**Read More: Scan the entire image before production**](./sections/docker/scan-images.md)
+
+
+
+## ![✔] 8.13 Clean NODE_MODULE cache
+
+**אמ;לק:** After installing dependencies in a container remove the local cache. It doesn't make any sense to duplicate the dependencies for faster future installs since there won't be any further installs - A Docker image is immutable. Using a single line of code tens of MB (typically 10-50% of the image size) are shaved off
+
+**אחרת:** The image that will get shipped to production will weigh 30% more due to files that will never get used
+
+🔗 [**Read More: Clean NODE_MODULE cache**](./sections/docker/clean-cache.md)
+
+
+
+## ![✔] 8.14. Generic Docker practices
+
+**אמ;לק:** This is a collection of Docker advice that is 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: Generic Docker practices**](./sections/docker/generic-tips.md)
+
+
+
+## ![✔] 8.15. Lint your Dockerfile
+
+**אמ;לק:** Linting your Dockerfile is an important step to identify issues in your Dockerfile which differ from best practices. By checking for potential flaws using a specialised Docker linter, performance and security improvements can be easily identified, saving countless hours of wasted time or security issues in production code.
+
+**אחרת:** Mistakenly the Dockerfile creator left Root as the production user, and also used an image from unknown source repository. This could be avoided with with just a simple linter.
+
+🔗 [**Read More: Lint your Dockerfile**](./sections/docker/lint-dockerfile.md)
+
+
+
+# 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/goldbergyoni/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
+
+-  [Brazilian Portuguese](./README.brazilian-portuguese.md) - Courtesy of [Marcelo Melo](https://github.com/marcelosdm)
+-  [Chinese](./README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
+-  [Russian](./README.russian.md) - Courtesy of [Alex Ivanov](https://github.com/contributorpw)
+-  [Polish](./README.polish.md) - Courtesy of [Michal Biesiada](https://github.com/mbiesiad)
+-  [Japanese](./README.japanese.md) - Courtesy of [Yuki Ota](https://github.com/YukiOta), [Yuta Azumi](https://github.com/YA21)
+-  [Basque](README.basque.md) - Courtesy of [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuesta
+
+### Translations in progress
+
+-  [French](./README.french.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  Hebrew ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Spanish](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turkish ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/139))
+
+
+
+## Steering Committee
+
+Meet the steering committee members - the people who work together to provide guidance and future direction to the project. In addition, each member of the committee leads a project tracked under our [GitHub projects](https://github.com/goldbergyoni/nodebestpractices/projects).
+
+
+
+[Yoni Goldberg](https://github.com/goldbergyoni)
+
+
+
+Independent Node.js consultant who works with customers in the USA, Europe, and Israel on building large-scale Node.js applications. Many of the best practices above were first published at [goldbergyoni.com](https://goldbergyoni.com). Reach Yoni at [@goldbergyoni](https://github.com/goldbergyoni) or [me@goldbergyoni.com](mailto:me@goldbergyoni.com)
+
+
+
+
+
+[Josh Hemphill](https://github.com/josh-hemphill)
+
+
+
+
+Full Stack Software Engineer / Developer specializing in Security, DevOps/DevSecOps, and ERP Integrations.
+
+
+
+
+
+[Raz Luvaton](https://github.com/rluvaton)
+
+
+
+Full Stack Developer who knows how to exit from Vim and loves Architecture, Virtualization and Security.
+
+
+
+## Contributing
+
+If you've ever wanted to contribute to open source, now is your chance! See the [contributing docs](.operations/CONTRIBUTING.md) for more information.
+
+## Contributors ✨
+
+Thanks goes to these wonderful people who have contributed to this repository!
+
+
+
+
+
+
+
+
+
+
+
+### Steering Committee Emeriti
+
+[Bruno Scheufler](https://github.com/BrunoScheufler)
+
+
+💻 full-stack web engineer, Node.js & GraphQL enthusiast
+
+
+
+
+
+[Kyle Martin](https://github.com/js-kyle)
+
+
+
+Full Stack Developer & Site Reliability Engineer based in New Zealand, interested in web application security, and architecting and building Node.js applications to perform at global scale.
+
+
+
+
+
+[Kevyn Bruyere](https://github.com/kevynb)
+
+
+Independent full-stack developer with a taste for Ops and automation.
+
+
+
+
+
+[Sagir Khan](https://github.com/sagirk)
+
+
+
+
+Deep specialist in JavaScript and its ecosystem — React, Node.js, TypeScript, GraphQL, MongoDB, pretty much anything that involves JS/JSON in any layer of the system — building products using the web platform for the world’s most recognized brands. Individual Member of the Node.js Foundation.
diff --git a/README.indonesian.md b/README.indonesian.md
new file mode 100644
index 000000000..f4d2d2f71
--- /dev/null
+++ b/README.indonesian.md
@@ -0,0 +1,1634 @@
+[✔]: assets/images/checkbox-small-blue.png
+
+# Praktik Terbaik Node.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+[](https://twitter.com/nodepractices/) **Ikuti kami di Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+
+Baca dalam bahasa yang berbeda: [**CN**](./README.chinese.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**PL**](./README.polish.md), [**EU**](./README.basque.md) [(**ES**, **FR**, **HE**, **KR** dan **TR** dalam proses!)](#translations)
+
+
+
+###### Dibuat dan dijaga oleh [Komite Pengarah](#komite-pengarah) dan [kolaborator](#Kolaborator)
+
+# Praktik Terbaik Terbaru dan Berita
+
+- **✅ Praktik terbaik baru:** Poin 2.12 oleh [Alexsey](https://github.com/Alexsey) menunjukkan bagaimana melakukan return tanpa await ke fungsi asinkron dapat mengarah ke _stacktraces_ parsial. Ini dapat menjadi masalah besar saat melakukan pemecahan masalah exception di produksi yang kekurangan beberapa bingkai eksekusi
+
+- **✅ Praktik terbaik baru:** Poin 6.8 oleh Josh Hemphill menyarankan "Protect Users' Passwords/Secrets using BCrypt or Script". Ini mengandung penjelasan secara mendalam tentang kapan dan kenapa setiap opsi sesuai untuk proyek tertentu. Jangan lewatkan panduan singkat ini dengan gambaran singkat tentang berbagai opsi hashing
+
+- **:whale: Praktik terbaik Node.js + Docker**: Kami baru saja merilis seksi Docker dengan Node.js yang mengandung 15 poin tentang teknik pengkodean yang lebih baik dengan Docker
+
+
+
+# Selamat Datang! 3 Hal Yang Harus Anda Ketahui
+
+**1. Anda sedang membaca berbagai artikel Node.js terbaik -** repositori ini adalah ringkasan dan kurasi dari konten peringkat teratas dalam praktik terbaik Node.js, serta konten yang ditulis oleh kolaborator
+
+**2. Ini adalah kompilasi terbesar, dan berkembang tiap minggu -** saat ini, lebih dari 80 praktik terbaik, panduan gaya, dan tips arsitektural tersajikan. Issue baru dan pull request dibuat setiap hari agar kontennya tetap diperbarui. Kami senang melihat Anda berkontribusi di sini, maupun itu memperbaiki kesalahan kode, membantu dalam terjemahan, atau menyarankan ide cemerlang yang baru. Lihat [pedoman menulis](./.operations/writing-guidelines.md) kami
+
+**3. Praktik terbaik mempunyai informasi tambahan -** kebanyakan poin mempunyai tautan **🔗Baca selengkapnya** yang memperluas praktiknya dengan contoh kode, kutipan dari blog terpilih, dan informasi lebih lanjut
+
+
+
+## Daftar Isi
+
+1. [Praktik Struktur Proyek (5)](#1-praktik-struktur-proyek)
+2. [Praktik Penanganan Kesalahan (11) ](#2-praktik-penanganan-kesalahan)
+3. [Praktik Gaya Kode (12) ](#3-praktik-gaya-kode)
+4. [Praktik Pengujian dan Kualitas Secara Keseluruhan (13) ](#4-praktik-pengujian-dan-kualitas-secara-keseluruhan)
+5. [Praktik Dalam Produksi(19) ](#5-praktik-dalam-produksi)
+6. [Praktik Keamanan (25)](#6-praktik-terbaik-keamanan)
+7. [Praktik Performa (2) (Pekerjaan Dalam Proses ✍️)](#7-draf-praktik-terbaik-performa)
+8. [Praktik Docker (15)](#8-praktik-terbaik-docker)
+
+
+
+# `1. Praktik Struktur Proyek`
+
+## ![✔] 1.1 Susun solusi Anda berdasarkan komponen
+
+**TL;DR:** Masalah terburuk pada aplikasi besar adalah mengurus basis kode yang sangat besar dengan ratusan dependensi - monolit seperti itu memperlambat pengembang saat mereka mencoba untuk menambahkan fitur baru. Sebaiknya, partisi kode Anda menjadi beberapa komponen, setiap komponen mendapatkan foldernya sendiri atau basis kode tersendiri, dan pastikan setiap unit untuk tetap kecil dan sederhana. Kunjungi 'Baca selengkapnya' di bawah ini untuk melihat contoh struktur proyek yang benar
+
+**Jika tidak:** Saat pengembang yang menambahkan fitur baru kesusahan untuk melihat dampak dari perubahan mereka dan takut akan merusak komponen lain yang bergantung - _deployment_ menjadi lebih lambat dan berisiko. Kode juga dianggap lebih sulit untuk dikembangkan ketika semua unit bisnis tidak dipisahkan
+
+🔗 [**Baca selengkapnya: structure by components**](./sections/projectstructre/breakintcomponents.md)
+
+
+
+## ![✔] 1.2 Lapisi komponen Anda, pastikan lapisan web tetap dalam batasannya
+
+**TL;DR:** Setiap komponen harus mengandung 'lapisan' - objek khusus untuk web, logika, dan kode akses data. Hal ini tidak hanya menggambarkan _separation of concerns_ dengan jelas namun juga memudahkan _mocking_ dan pengujian sistem. Meskipun ini adalah pola yang sangan umum, pengembang API cenderung mencampur lapisan dengan meneruskan objek lapisan web (misalnya Express req, res) ke logika bisnis dan lapisan data - ini membuat aplikasi Anda bergantung dan hanya bisa diakses oleh framework web tertentu
+
+**Jika tidak:** Aplikasi yang menggabungkan objek web dengan lapisan lain tidak dapat diakses oleh kode pengujian, pekerjaan CRON, triggers dari message queues, dll.
+
+🔗 [**Baca selengkapnya: layer your app**](./sections/projectstructre/createlayers.md)
+
+
+
+## ![✔] 1.3 Bungkus utilitas umum sebagai paket npm
+
+**TL;DR:** Pada aplikasi besar yang memiliki basis kode yang besar, utilitas _cross-cutting-concern_ seperti logger, enkripsi dan yang serupa, harus dibungkus oleh kode Anda dan terekspos sebagai paket npm tersendiri. Ini memungkinkan untuk membagikan utilitas tersebut di antara beberapa basis kode dan proyek
+
+**Jika tidak:** Anda harus membuat cara _deployment_ dan _dependency_ Anda sendiri
+
+🔗 [**Baca selengkapnya: Structure by feature**](./sections/projectstructre/wraputilities.md)
+
+
+
+## ![✔] 1.4 Pisahkan 'app' dan 'server' Express
+
+**TL;DR:** Hindari kebiasaan buruk dalam mendefinisikan seluruh aplikasi [Express](https://expressjs.com/) dalam satu file besar - pisahkan definisi 'Express' Anda menjadi setidaknya dua file: deklarasi untuk API (app.js) dan untuk jaringan (WWW). Untuk struktur yang lebih baik lagi, letak deklarasi API Anda di dalam komponen
+
+**Jika tidak:** API Anda hanya dapat diakses untuk pengujian melalui panggilan HTTP (lebih lambat and lebih susah untuk membuat laporan cakupan pengujian). Mengurus ratusan baris kode dalam satu file mungkin bukanlah hal yang menyenangkan
+
+🔗 [**Baca selengkapnya: separate Express 'app' and 'server'**](./sections/projectstructre/separateexpress.md)
+
+
+
+## ![✔] 1.5 Gunakan konfigurasi yang sadar atas lingkungan, aman dan hierarkis
+
+**TL;DR:** Pengaturan konfigurasi yang sempurna harus memastikan (a) kunci dapat dibaca dari file DAN dari variabel lingkungan (b) rahasia disimpan di luar kode (c) konfigurasi bersifat hierarkis agar mudah ditemukan. Ada beberapa paket yang dapat mempermudah pengaturan tersebut seperti [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config), dan [convict](https://www.npmjs.com/package/convict).
+
+**Jika tidak:** Gagal untuk memenuhi salah satu persyaratan konfigurasi hanya akan menghambat tim pengembang atau DevOps. Mungkin keduanya
+
+🔗 [**Baca selengkapnya: configuration best practices**](./sections/projectstructre/configguide.md)
+
+
+
+# `2. Praktik Penanganan Kesalahan`
+
+## ![✔] 2.1 Gunakan Async-Await atau promise untuk penanganan kesalahan asinkron
+
+**TL;DR:** Menangani kesalahan asinkron dalam panggilan balik mungkin adalah cara terburuk (a.k.a the pyramid of doom). Hal terbaik yang dapat Anda berikan ke kode Anda adalah dengan menggunakan pustaka promise dengan reputasi yang baik atau gunakan async-await yang membuat sintaks kode menjadi lebih ringkas dan familier seperti try-catch
+
+**Jika tidak:** Gaya panggilan balik Node.js, function(err, response), adalah cara yang menjanjikan untuk kode yang tidak dapat dipelihara karena campuran dari penanganan kesalahan dengan kode kasual, bersarang yang berlebihan, dan pola pengkodean yang canggung
+
+🔗 [**Baca selengkapnya: avoiding callbacks**](./sections/errorhandling/asyncerrorhandling.md)
+
+
+
+## ![✔] 2.2 Gunakan hanya objek Error bawaan
+
+**TL;DR:** Banyak pengembang melempar error sebagai string atau tipe khusus – ini mempersulit logika penanganan kesalahan dan interoperabilitas antar modul. Maupun Anda menolak sebuah _promise_, melontarkan sebuah pengecualian atau mengeluarkan error – dengan hanya menggunakan objek Error bawaan (atau objek yang memperluas objek Error bawaan) dapat meningkatkan keseragaman dan mencegah hilangnya informasi
+
+**Jika tidak:** Saat menjalankan beberapa komponen, karena tidak yakin jenis kesalahan yang akan di lempar – ini membuat penanganan kesalahan yang benar jauh lebih sulit. Lebih buruk lagi, menggunakan tipe khusus untuk mendeskripsikan kesalahan dapat menyebabkan hilangnya informasi kesalahan kritis seperti _stack trace_!
+
+🔗 [**Baca selengkapnya: using the built-in error object**](./sections/errorhandling/useonlythebuiltinerror.md)
+
+
+
+## ![✔] 2.3 Membedakan kesalahan operasional dan kesalahan pengembang
+
+**TL;DR:** Kesalahan operasional (contohnya API menerima masukan yang tidak valid) merupakan kasus kesalahan yang diketahui di mana dampak dari kesalahannya dapat dipahami sepenuhnya dan dapat ditangani dengan cermat. Di sisi lain, kesalahan pengembang (contohnya mencoba membaca variabel yang tidak ditentukan) merupakan kegagalan kode yang tidak diketahui yang menentukan untuk memulai ulang aplikasi dengan baik
+
+**Jika tidak:** Anda selalu dapat memulai ulang aplikasi Anda ketika kesalahan muncul, namun kenapa mengecewakan ~5000 pengguna hanya karena kesalahan operasional yang kecil dan dapat diprediksi? hal sebaliknya juga tidak ideal – membiarkan aplikasi tetap berjalan ketika terdapat kesalahan yang tidak diketahui (kesalahan oleh pengembang) dapat menyebabkan perilaku yang tidak terduga. Membedakan kedua kesalahan tersebut memungkinkan untuk melakukan tindakan yang benar dan menerapkan cara penyelesaian masalah yang sesuai dengan konteks yang diberikan
+
+🔗 [**Baca selengkapnya: operational vs programmer error**](./sections/errorhandling/operationalvsprogrammererror.md)
+
+
+
+## ![✔] 2.4 Tangani kesalahan secara terpusat, bukan dalam middleware
+
+**TL;DR:** Logika penanganan kesalahan seperti pengiriman pesan ke admin dan pencatatan harus dikemas dalam objek khusus dan terpusat yang dipanggil oleh semua endpoint (contohnya middleware Express, pekerjaan cron, pengujian unit) ketika ada kesalahan
+
+**Jika tidak:** Tidak menangani kesalahan dalam satu tempat akan menyebabkan duplikasi kode dan mungkin kesalahan yang tidak ditangani dengan tepat
+
+🔗 [**Baca selengkapnya: handling errors in a centralized place**](./sections/errorhandling/centralizedhandling.md)
+
+
+
+## ![✔] 2.5 Mendokumentasikan kesalahan API menggunakan Swagger atau GraphQL
+
+**TL;DR:** Beri tahu pemanggil API Anda kesalahan apa yang mungkin dapat diterima sehingga mereka dapat menanganinya dengan baik tanpa merusak aplikasinya. Untuk API RESTful, hal ini biasanya dilakukan dengan framework dokumentasi seperti Swagger. Jika Anda menggunakan GraphQL, Anda juga dapat memanfaatkan skema dan komentar.
+
+**Jika tidak:** Klien API mungkin memutuskan untuk memberhentikan aplikasi dan memulai ulang hanya karena menerima kesalahan yang tidak dapat dipahami. Catatan: pemanggil API mungkin adalah Anda (sangat umum dalam lingkungan _microservice_)
+
+🔗 [**Baca selengkapnya: documenting API errors in Swagger or GraphQL**](./sections/errorhandling/documentingusingswagger.md)
+
+
+
+## ![✔] 2.6 Hentikan proses dengan benar ketika orang asing datang ke kota
+
+**TL;DR:** Ketika terjadi kesalahan yang tidak diketahui (kesalahan pengembang, lihat praktik terbaik 2.3) - ada ketidakpastian tentang kesehatan aplikasi. Praktik umum menyarankan untuk memulai kembali proses dengan hati-hati menggunakan alat manajemen proses seperti [Forever](https://www.npmjs.com/package/forever) atau [PM2](http://pm2.keymetrics.io/)
+
+**Jika tidak:** Ketika pengecualian yang tidak dikenal terjadi, beberapa objek mungkin dalam keadaan rusak (contohnya event emitter yang digunakan secara global dan tidak dapat mengaktifkan event lagi karena kesalahan internal) dan semua panggilan yang akan datang mungkin akan gagal atau tidak berperilaku dengan normal
+
+🔗 [**Baca selengkapnya: shutting the process**](./sections/errorhandling/shuttingtheprocess.md)
+
+
+
+## ![✔] 2.7 Gunakan alat pencatat yang baik untuk meningkatkan visibilitas kesehatan
+
+**TL;DR:** Satu set alat pencatat yang baik seperti [Pino](https://github.com/pinojs/pino) atau [Log4js](https://www.npmjs.com/package/log4js), akan mempercepat penemuan dan pemahaman suatu kesalahan. Jadi tinggalkan console.log
+
+**Jika tidak:** Melihat beberapa console.log atau secara manual melalui file teks yang berantakan tanpa alat kueri atau penampil catatan yang baik dapat membuat Anda sibuk di tempat kerja hingga larut
+
+🔗 [**Baca selengkapnya: using a mature logger**](./sections/errorhandling/usematurelogger.md)
+
+
+
+## ![✔] 2.8 Uji aliran kesalahan menggunakan framework pengujian favorit Anda
+
+**TL;DR:** Maupun itu QA otomatis profesional ataupun pengujian manual oleh pengembang – Pastikan bahwa kode Anda tidak hanya memenuhi skenario positif namun juga menangani dan mengembalikan jenis kesalahan yang tepat. Framework testing seperti Mocha & Chai dapat menangani ini dengan mudah (lihat contoh kode dalam "Gist popup")
+
+**Jika tidak:** Tanpa testing, maupun secara otomatis ataupun manual, Anda tidak dapat mengandalkan kode Anda untuk mengembalikan jenis kesalahan yang tepat. Tanpa jenis kesalahan yang berarti – tidak ada penanganan kesalahan
+
+🔗 [**Baca selengkapnya: testing error flows**](./sections/errorhandling/testingerrorflows.md)
+
+
+
+## ![✔] 2.9 Temukan kesalahan dan waktu henti menggunakan produk APM
+
+**TL;DR:** Produk pemantauan dan kinerja (a.k.a APM) secara proaktif mengukur basis kode atau API sehingga mereka dapat secara otomatis menyorot kesalahan, kerusakan, dan bagian lambat yang Anda lewatkan
+
+**Jika tidak:** Anda mungkin menghabiskan banyak usaha untuk mengukur kinerja dan waktu henti API, mungkin Anda tidak akan menyadari bagian kode mana yang paling lambat dalam skenario dunia nyata dan bagaimana hal ini dapat memengaruhi pengalaman pengguna
+
+🔗 [**Baca selengkapnya: using APM products**](./sections/errorhandling/apmproducts.md)
+
+
+
+## ![✔] 2.10 Tangkap penolakan _promise_ yang tidak tertangani
+
+**TL;DR:** Semua pengecualian yang dilemparkan ke dalam _promise_ akan ditelan dan dibuang kecuali pengembang tidak lupa untuk menanganinya secara eksplisit. Meskipun kode Anda berlangganan ke `process.uncaughtException`! Atasi ini dengan mendaftarkan ke event `process.unhandledRejection`
+
+**Jika tidak:** Kesalahan dari kode Anda akan ditelan dan hilang tanpa jejak. Tidak ada yang perlu dikhawatirkan
+
+🔗 [**Baca selengkapnya: catching unhandled promise rejection**](./sections/errorhandling/catchunhandledpromiserejection.md)
+
+
+
+## ![✔] 2.11 Gagal lebih dini, validasi argumen menggunakan pustaka khusus
+
+**TL;DR:** Tegaskan masukan API untuk menghindari bug yang lebih sulit dilacak nantinya. Kode untuk validasi biasanya berantakan kecuali Anda menggunakan pustaka pembantu yang keren seperti [ajv](https://www.npmjs.com/package/ajv) dan [Joi](https://www.npmjs.com/package/joi)
+
+**Jika tidak:** Anggap seperti ini – jika fungsi Anda mengharapkan argumen numerik “Diskon” yang lupa diletak oleh pemanggil, kemudian, kode Anda memeriksa jika Diskon!=0 (jumlah diskon yang diizinkan lebih besar dari nol), maka itu akan memungkinkan pengguna untuk menikmati diskon. OMG, bug yang sangat buruk. Bisakah Anda melihatnya?
+
+🔗 [**Baca selengkapnya: failing fast**](./sections/errorhandling/failfast.md)
+
+
+
+## ![✔] 2.12 Selalu _await promise_ sebelum mengembalikan nilai untuk menghindari _stacktrace_ yang tidak lengkap
+
+**TL;DR:** Selalu lakukan `return await` ketika mengembalikan sebuah _promise_ untuk memanfaatkan _stacktrace_ kesalahan yang lengkap. Jika sebuah fungsi mengembalikan _promise_, fungsi tersebut harus dideklarasikan sebagai fungsi `async` dan `await` fungsi tersebut secara eksplisit sebelum mengembalikannya
+
+**Jika tidak:** Fungsi yang mengembalikan _promise_ tanpa `await` tidak akan muncul di _stacktrace_.
+Kerangka yang hilang seperti itu mungkin akan mempersulit pemahaman tentang aliran yang mengarah ke kesalahan,
+terutama jika penyebab perilaku yang tidak normal ada di dalam fungsi yang hilang itu
+
+🔗 [**Baca selengkapnya: returning promises**](./sections/errorhandling/returningpromises.md)
+
+
+
+# `3. Praktik Gaya Kode`
+
+## ![✔] 3.1 Gunakan ESLint
+
+**TL;DR:** [ESLint](https://eslint.org) adalah standar de-facto untuk memeriksa kemungkinan kesalahan kode dan memperbaiki gaya kode, bukan hanya untuk mengidentifikasi masalah spasi tetapi juga untuk mendeteksi kode anti-pola yang serius seperti pengembang melemparkan kesalahan tanpa klasifikasi. Meskipun ESLint dapat memperbaiki gaya kode secara otomatis, alat lain seperti [prettier](https://www.npmjs.com/package/prettier) dan [beautify](https://www.npmjs.com/package/js-beautify) lebih baik dalam memformat perbaikan kodenya dan dapat bekerja sama dengan ESLint
+
+**Jika tidak:** Pengembang akan fokus pada masalah spasi dan lebar garis dan waktu mungkin akan terbuang hanya untuk memikirkan gaya kode pada proyek
+
+🔗 [**Baca selengkapnya: Using ESLint and Prettier**](./sections/codestylepractices/eslint_prettier.md)
+
+
+
+## ![✔] 3.2 Plugin khusus Node.js
+
+**TL;DR:** Selain aturan standar ESLint yang mencakup vanilla JavaScript, tambahkan plugin khusus Node.js seperti [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) dan [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security)
+
+**Jika tidak:** Banyak pola kode Node.js yang salah dapat lolos dari radar. Contohnya, pengembang mungkin melakukan require(variableAsPath) pada file dengan variabel sebagai path yang memungkinkan penyerang untuk mengeksekusi skrip JS apa pun. Linters Node.js dapat mendeteksi pola tersebut dan memberikan peringatan lebih awal
+
+
+
+## ![✔] 3.3 Mulai kurung kurawal pada blok kode pada baris yang sama
+
+**TL;DR:** Tanda kurung kurawal pembuka blok kode harus di baris yang sama dengan statement pembuka
+
+### Contoh Kode
+
+```javascript
+// Lakukan
+function someFunction() {
+ // blok kode
+}
+
+// Hindari
+function someFunction() {
+ // blok kode
+}
+```
+
+**Jika tidak:** Tidak mengikuti praktik terbaik ini dapat menyebabkan hasil yang tidak terduga, seperti yang terlihat pada thread StackOverflow di bawah ini:
+
+🔗 [**Baca selengkapnya:** "Why do 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 Pisahkan statement Anda dengan benar
+
+Tidak peduli jika Anda menggunakan titik koma atau tidak untuk memisahkan statement Anda, mengetahui akibat umum dari pemutusan baris yang tidak tepat atau penyisipan titik koma otomatis, akan membantu Anda mengurangi kesalahan sintaks biasa.
+
+**TL;DR:** Gunakan ESLint untuk mendapatkan perhatian tentang masalah pemisahan. [Prettier](https://prettier.io/) atau [Standardjs](https://standardjs.com/) dapat menyelesaikan masalah ini secara otomatis.
+
+**Jika tidak:** Seperti yang terlihat di bagian sebelumnya, penerjemah JavaScript secara otomatis menambah titik koma pada akhir statement jika tidak ada, atau anggap sebuah statement tidak diakhiri di tempat yang seharusnya, yang dapat mengarah pada hasil yang tidak diinginkan. Anda dapat menggunakan penetapan dan hindari penggunaan ekspresi fungsi yang langsung dipanggil untuk mencegah sebagian besar masalah yang tidak terduga.
+
+### Contoh kode
+
+```javascript
+// Lakukan
+function doThing() {
+ // ...
+}
+
+doThing()
+
+// Lakukan
+
+const items = [1, 2, 3]
+items.forEach(console.log)
+
+// Hindari — melempar pengecualian
+const m = new Map()
+const a = [1,2,3]
+[...m.values()].forEach(console.log)
+> [...m.values()].forEach(console.log)
+> ^^^
+> SyntaxError: Unexpected token ...
+
+// Hindari — melempar pengecualian
+const count = 2 // mencoba menjalankan 2(), tapi 2 bukanlah sebuah fungsi
+(function doSomething() {
+ // lakukan sesuatu
+}())
+// letakkan titik koma sebelum fungsi yang langsung dipanggil, setelah pendefinisian const, simpan nilai kembali dari fungsi anonim ke sebuah variabel atau hindari IIFE (ekspresi fungsi yang langsung dipanggil) sepenuhnya
+```
+
+🔗 [**Baca selengkapnya:** "Semi ESLint rule"](https://eslint.org/docs/rules/semi)
+🔗 [**Baca selengkapnya:** "No unexpected multiline ESLint rule"](https://eslint.org/docs/rules/no-unexpected-multiline)
+
+
+
+## ![✔] 3.5 Namakan fungsi Anda
+
+**TL;DR:** Namakan semua fungsi, termasuk closure dan panggilan balik. Hindari fungsi anonim. Ini sangat berguna saat mengukur sebuah aplikasi node. Menamakan semua fungsi memungkinkan Anda untuk memahami dengan mudah apa yang Anda lihat saat memeriksa snapshot memori
+
+**Jika tidak:** Men-debug masalah produksi menggunakan core dump (snapshot memori) dapat menjadi tantangan karena Anda melihat konsumsi memori yang signifikan dari fungsi anonim
+
+
+
+## ![✔] 3.6 Gunakan konvensi penamaan untuk variabel, konstanta, fungsi dan kelas
+
+**TL;DR:** Gunakan **_lowerCamelCase_** saat memberi nama konstanta, variabel dan fungsi dan **_UpperCamelCase_** (huruf besar pada huruf pertama) saat memberi nama kelas. Ini akan membantu Anda dengan mudah untuk membedakan variabel/fungsi biasa, dan kelas yang membutuhkan instansiasi. Gunakan nama yang deskriptif, tetapi usahakan untuk tetap pendek
+
+**Jiak tidak:** Javascript adalah satu-satunya bahasa di dunia yang memungkinkan pemanggilan konstruktor kelas ("Class") secara langsung tanpa membuat instansinya terlebih dahulu. Akibatnya, kelas dan fungsi-konstruktor dibedakan dimulai dengan UpperCamelCase
+
+### 3.6 Contoh Kode
+
+```javascript
+// untuk nama kelas kita gunakan UpperCamelCase
+class SomeClassExample {}
+
+// untuk nama const kita gunakan kata kunci const dan lowerCamelCase
+const config = {
+ key: "value",
+};
+
+// untuk nama variabel dan fungsi kita gunakan lowerCamelCase
+let someVariableExample = "value";
+function doSomething() {}
+```
+
+
+
+## ![✔] 3.7 Utamakan penggunaan const daripada let. Singkirkan var
+
+**TL;DR:** Menggunakan `const` berarti bahwa setelah nilai variabel itu ditetapkan, nilainya tidak dapat ditetapkan kembali. Menggunakan `const` akan membantu Anda untuk tidak tergoda untuk menggunakan variabel yang sama untuk penggunaan yang berbeda, dan membuat kode Anda lebih jelas. Jika sebuah variabel perlu ditetapkan kembali nilainya, di dalam perulangan for, misalnya, deklarasikan menggunakan `let`. Aspek penting lainnya dari `let` adalah variabel yang dideklarasikan menggunakan `let` hanya tersedia di dalam cakupan blok di mana variabel itu didefinisikan. `var` memiliki cakupan dalam fungsi, bukan dalam blok, dan [tidak boleh digunakan di ES6](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70) setelah Anda mempunyai `const` dan `let`
+
+**Jika tidak:** Men-debug menjadi lebih rumit saat mengikuti variabel yang sering berubah
+
+🔗 [**Baca selengkapnya: JavaScript ES6+: var, let, or const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 _Require_ modul terlebih dahulu, bukan di dalam fungsi
+
+**TL;DR:** _Require_ modul di awal setiap file, sebelum dan di luar semua fungsi. Praktik terbaik sederhana ini tidak hanya membantu Anda dengan mudah dan cepat untuk mengetahui dependensi file di awal sebuah file tetapi juga menghindari beberapa potensi masalah
+
+**Jika tidak:** _Require_ dijalankan secara sinkron oleh Node.js. Jika mereka dipanggil dalam sebuah fungsi, ini mungkin dapat memblokir permintaan lain untuk ditangani pada waktu yang lebih kritis. Selain itu, jika modul yang diperlukan atau salah satu dependensinya menimbulkan kesalahan dan merusak server, akan lebih baik untuk mengetahuinya sesegera mungkin, yang mungkin tidak akan terjadi jika modul itu dipanggil dalam sebuah fungsi
+
+
+
+## ![✔] 3.9 _Require_ modul berdasarkan folder, bukan file secara langsung
+
+**TL;DR:** Saat mengembangkan sebuah modul/pustaka dalam sebuah folder, letak file index.js yang mengekspos modul internal sehingga setiap konsumen akan melewatinya. Ini berfungsi sebagai 'antarmuka' ke modul Anda dan memudahkan perubahan di masa mendatang tanpa merusak kontrak
+
+**Jika tidak:** Mengubah struktur internal sebuah file atau tanda tangannya dapat merusak antarmuka dengan klien
+
+### 3.9 Contoh kode
+
+```javascript
+// Lakukan
+module.exports.SMSProvider = require("./SMSProvider");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver");
+
+// Hindari
+module.exports.SMSProvider = require("./SMSProvider/SMSProvider.js");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver/SMSNumberResolver.js");
+```
+
+
+
+## ![✔] 3.10 Gunakan operator `===`
+
+**TL;DR:** Utamakan operator persamaan ketat `===` daripada operator persamaan abstrak `==` yang lebih lemah. `==` akan membandingkan dua variabel setelah mengubahnya ke tipe umum. Tidak ada konversi tipe di `===`, dan kedua variabel harus sejenis agar sama
+
+**Jika tidak:** Variabel yang tidak sama dapat mengembalikan _true_ ketika dibandingkan dengan operator `==`
+
+### 3.10 Contoh kode
+
+```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
+```
+
+Semua pernyataan di atas akan mengembalikan nilai _false_ jika menggunakan `===`
+
+
+
+## ![✔] 3.11 Gunakan Async Await, hindari panggilan balik
+
+**TL;DR:** Node 8 LTS sekarang memiliki dukungan penuh untuk Async-await. Ini adalah cara baru untuk menangani kode asinkron yang menggantikan panggilan balik dan _promise_. Async-await bersifat tidak memblokir, dan ini membuat kode asinkron terlihat seperti sinkron. Hadiah terbaik yang dapat Anda berikan untuk kode Anda adalah menggunakan async-await yang menyediakan sintaks yang lebih ringkas dan akrab seperti try-catch
+
+**Jika tidak:** Menangani kesalahan asinkron dalam gaya panggilan balik mungkin adalah cara terburuk - gaya ini memeriksa kesalahan secara menyeluruh, menangani tumpukan kode yang canggung, dan menyulitkan untuk menjelaskan aliran kode
+
+🔗[**Baca selengkapnya:** Guide to async-await 1.0](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 Gunakan ekspresi fungsi panah (=>)
+
+**TL;DR:** Meskipun disarankan untuk menggunakan async-await dan menghindari parameter fungsi saat berurusan dengan API lama yang menerima promise atau panggilan balik - fungsi panah membuat struktur kode lebih ringkas dan menjaga konteks leksikal dari akar fungsi (contohnya `this`)
+
+**Jika tidak:** Kode yang lebih panjang (dalam fungsi ES5) lebih rentan terhadap masalah dan rumit untuk dibaca
+
+🔗 [**Baca selengkapnya: 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)
+
+
+
+# `4. Praktik Pengujian dan Kualitas Secara Keseluruhan`
+
+## ![✔] 4.1 Paling tidak, buat pengujian API (komponen)
+
+**TL;DR:** Sebagian besar proyek tidak memiliki pengujian otomatis karena jadwal yang singkat atau 'proyek pengujian' sering tidak terkendali dan ditinggalkan. Oleh karena itu, prioritaskan dan mulailah dengan pengujian API yang merupakan cara termudah untuk menulis dan memberikan cakupan yang lebih dari pengujian unit (Anda bahkan dapat membuat pengujian API tanpa kode menggunakan alat seperti [Postman](https://www.getpostman.com/). Setelah itu, jika Anda mempunyai waktu dan sumber daya yang lebih, lanjutkan dengan pengujian yang lebih tinggi seperti pengujian unit, pengujian DB, pengujian performa, dll.
+
+**Jika tidak:** Anda mungkin menghabiskan waktu yang lama untuk menulis pengujian unit untuk mengetahui bahwa Anda hanya mencakup 20% dari sistem
+
+
+
+## ![✔] 4.2 Sertakan 3 bagian di setiap nama pengujian
+
+**TL;DR:** Buatlah pengujian yang setara dengan tingkat persyaratan sehingga cukup jelas untuk _Engineer_ QA dan pengembang yang tidak terbiasa dengan kode internal. Sebutkan dalam nama pengujian apa yang akan diuji (unit dalam pengujian), dalam keadaan apa, dan apa hasil yang diharapkan
+
+**Jika tidak:** Deployment baru saja gagal, sebuah pengujian bernama “Tambah produk” gagal. Apakah ini memberi tahu Anda dengan tepat apa yang tidak berfungsi?
+
+🔗 [**Baca selengkapnya: Include 3 parts in each test name**](./sections/testingandquality/3-parts-in-name.md)
+
+
+
+## ![✔] 4.3 Strukturkan pengujian Anda dengan pola AAA
+
+**TL;DR:** Strukturkan pengujian dengan 3 bagian yang terpisah dengan baik: _Arrange, Act & Assert_ (AAA). Bagian pertama mencakup penyiapan untuk pengujian, kemudian eksekusi unit yang akan diuji, dan yang terakhir fase _assertion_. Mengikuti struktur ini menjamin bahwa pembaca tidak menghabiskan tenaga otak untuk memahami rencana pengujian
+
+**Jika tidak:** Tidak hanya Anda menghabiskan waktu yang lama untuk memahami kode utama, tetapi sekarang hal paling mudah dari hari Anda (melakukan pengujian) dapat meregangkan otak Anda
+
+🔗 [**Baca selengkapnya: Structure tests by the AAA pattern**](./sections/testingandquality/aaa.md)
+
+
+
+## ![✔] 4.4 Deteksi masalah kode dengan _linter_
+
+**TL;DR:** Gunakan _linter_ kode untuk memeriksa kualitas dasar dan mendeteksi anti-pola sejak dini. Jalankan _linter_ sebelum pengujian dan tambahkan _linter_ sebagai pra-commit git-hook untuk meminimalkan waktu yang dibutuhkan untuk meninjau dan memperbaiki masalah apa pun. Periksa juga [Bagian 3](#3-praktik-gaya-kode) tentang Praktik Gaya Kode
+
+**Jika Tidak:** Anda dapat membiarkan beberapa kode dengan anti-pola dan mungkin kode yang tidak aman masuk ke lingkungan produksi Anda.
+
+
+
+## ![✔] 4.5 Hindari perlengkapan dan benih global pada pengujian, tambah data pada setiap pengujian
+
+**TL;DR:** Untuk mencegah pengujian yang tersambung dan memudahkan untuk memahami alur pengujian, setiap pengujian harus menambah dan bertindak pada kumpulan data di DB-nya sendiri. Setiap kali pengujian perlu menarik atau mengasumsikan keberadaan suatu data pada DB - pengujian tersebut harus menambah data tersebut secara eksplisit dan hindari memutasi kumpulan data lainnya
+
+**Jika tidak:** Anggap sebuah skenario di mana _deployment_ gagal karena pengujian yang gagal, tim sekarang akan menghabiskan waktu yang berharga untuk melakukan investigasi yang berakhir dengan kesimpulan yang menyedihkan: sistem berfungsi dengan baik, namun pengujian saling mengganggu dan merusak _build_-nya
+
+🔗 [**Baca selengkapnya: Avoid global test fixtures**](./sections/testingandquality/avoid-global-test-fixture.md)
+
+
+
+## ![✔] 4.6 Periksa terus menerus dependensi yang rentan
+
+**TL;DR:** Bahkan dependensi yang paling terkemuka seperti Express memiliki kerentanan yang diketahui. Hal ini dapat dimitigasi dengan mudah menggunakan alat dari komunitas atau komersial seperti 🔗 [npm audit](https://docs.npmjs.com/cli/audit) dan 🔗 [snyk.io](https://snyk.io) yang dapat dipanggil dari CI Anda pada setiap _build_
+
+**Jika tidak:** Menjaga kode Anda bersih dari kerentanan tanpa alat khusus mengharuskan Anda untuk mengikuti publikasi online tentang ancaman baru. Cukup membosankan
+
+
+
+## ![✔] 4.7 Tandai pengujian Anda
+
+**TL;DR:** Pengujian yang berbeda harus dijalankan pada skenario yang berbeda: _quick smoke_, _IO-less_, pengujian harus dijalankan ketika pengembang menyimpan atau melakukan _commit_ pada file, pengujian _end-to-end_ biasanya dijalankan saat _pull request_ baru dikirimkan, dst. Hal ini dapat dicapai dengan menandai pengujian dengan kata kunci seperti _#cold #api #sanity_ sehingga Anda dapat melakukan `grep` pada pengujian Anda dan menjalankan subset yang diinginkan. Contohnya, ini adalah cara untuk memanggil pengujian pada kelompok _sanity_ dengan [Mocha](https://mochajs.org/): mocha --grep 'sanity'
+
+**Jika tidak:** Menjalankan semua pengujian, termasuk pengujian yang menjalankan banyak kueri DB, setiap kali pengembang membuat perubahan kecil bisa sangat lambat dan menjauhkan pengembang dari menjalankan pengujian
+
+
+
+## ![✔] 4.8 Periksa cakupan pengujian Anda, ini membantu untuk mengidentifikasikan pola pengujian yang salah
+
+**TL;DR:** Alat cakupan kode seperti [Istanbul](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc) sangat bagus karena 3 alasan: gratis (sangat mudah untuk memanfaatkan laporan ini), alat ini membantu mengidentifikasikan pengurangan cakupan pengujian, dan yang terakhir, alat ini menyoroti ketidakcocokan pengujian: dengan melihat kode warna pada laporan cakupan Anda dapat melihat, misalnya, area kode yang tidak pernah diuji seperti klausa _catch_ (artinya pengujian hanya mengambil jalur yang benar dan bukan bagaimana aplikasi akan berperilaku jika ada kesalahan). Setel agar _build_-nya gagal jika cakupannya berada di bawah batas tertentu
+
+**Jika tidak:** Tidak akan ada metrik otomatis yang memberi tahu Anda saat sebagian besar kode Anda tidak tercakup dalam pengujian
+
+
+
+## ![✔] 4.9 Periksa paket yang kedaluwarsa
+
+**TL;DR:** Gunakan alat pilihan Anda (misalnya 'npm outdated' atau [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) untuk mendeteksi paket yang kedaluwarsa, masukkan pemeriksaan ini ke _pipeline CI_ dan bahkan gagalkan _build_-nya dalam skenario yang buruk. Contohnya, skenario yang buruk mungkin terjadi ketika paket yang digunakan tertinggal 5 _patch commit_ (misalnya versi lokal adalah 1.3.1 dan versi repositori adalah 1.3.8) atau paketnya ditandai _deprecated_ oleh pembuatnya - matikan _build_-nya dan cegah _deployment_ pada versi ini
+
+**Jika tidak:** Produksi Anda akan menggunakan paket yang ditandai berisiko oleh pembuatnya secara eksplisit
+
+
+
+## ![✔] 4.10 Gunakan lingkungan yang mirip dengan produksi untuk pengujian e2e
+
+**TL;DR:** Pengujian _End to end_ (e2e) yang mencakup data asli dulunya merupakan titik terlemah pada proses CI karena pengujian itu bergantung pada beberapa layanan berat seperti DB. Gunakan lingkungan yang semirip mungkin dengan lingkungan pada produksi Anda seperti a-seterusnya (-seterusnya hilang, konten dibutuhkan. Dilihat dari klausa **Jika tidak**, hal ini seharusnya menyebutkan tentang docker-compose)
+
+**Jika tidak:** Tanpa docker-compose, tim harus mengurus DB pengujian untuk setiap lingkungan pengujian termasuk mesin yang dimiliki oleh pengembang, pastikan semua DB tersebut tetap sinkron sehingga hasil pengujian tidak akan berbeda di lingkungan yang berbeda
+
+
+
+## ![✔] 4.11 Sering lakukan refactor menggunakan alat analisis statis
+
+**TL;DR:** Menggunakan alat analisis statis membantu dengan memberikan cara yang obyektif untuk meningkatkan kualitas kode dan tetap menjaga kode Anda. Anda dapat menambahkan alat analisis statis ke _build_ CI untuk menggagalkan _build_-nya jika alat itu menemukan kode yang jelek. Nilai jual utamanya dibandingkan dengan _linting_ biasa adalah kemampuan untuk memeriksa kualitas dalam konteks beberapa file (contohnya mendeteksi duplikasi), melakukan analisis lanjutan (contohnya kompleksitas kode), dan mengikuti riwayat dan perkembangan masalah kode. Dua contoh alat yang dapat Anda gunakan adalah [Sonarqube](https://www.sonarqube.org/) (2,600+ [bintang](https://github.com/SonarSource/sonarqube)) dan [Code Climate](https://codeclimate.com/) (1,500+ [bintang](https://github.com/codeclimate/codeclimate)).
+
+**Jika tidak:** Dengan kualitas kode yang buruk, _bug_ dan performa selalu akan selalu menjadi masalah yang tidak dapat diperbaiki oleh pustaka baru atau fitur-fitur canggih
+
+🔗 [**Baca selengkapnya: Refactoring!**](./sections/testingandquality/refactoring.md)
+
+
+
+## ![✔] 4.12 Pilih platform CI Anda dengan hati-hati (Jenkins vs CircleCI vs Travis vs yang lainnya)
+
+**TL;DR:** Platform _continuous integration_ (CICD) Anda akan mempunyai semua alat berkualitas (seperti test, lint) sehingga seharusnya dilengkapi dengan ekosistem plugin yang dinamis. [Jenkins](https://jenkins.io/) dulunya merupakan aplikasi default untuk banyak proyek karena mempunyai komunitas terbesar bersama dengan platform yang sangat kuat dengan kekurangan persiapan yang rumit yang menuntut kurva pembelajaran yang tajam. Saat ini, persiapan solusi CI jauh lebih mudah menggunakan alat SaaS seperti [CircleCI](https://circleci.com) dan lainnya. Alat ini memungkinkan pembuatan pipeline CI yang fleksibel tanpa beban untuk mengelola seluruh infrastruktur. Pada akhirnya, ini merupakan keseimbangan antara kecepatan dan kekuatan - pilih dengan hati-hati
+
+**Jika tidak:** Memilih vendor khusus mungkin akan membatasi Anda ketika Anda membutuhkan penyesuaian tingkat lanjut. Di sisi lain, menggunakan Jenkins dapat menghabiskan waktu berharga dalam penyiapan infrastruktur
+
+🔗 [**Baca selengkapnya: Choosing CI platform**](./sections/testingandquality/citools.md)
+
+## ![✔] 4.13 Uji middleware Anda secara terpisah
+
+**TL;DR:** Ketika middleware mempunyai beberapa logika besar yang mencakup banyak permintaan, ada baiknya untuk mengujinya secara terpisah tanpa membangun seluruh framework web. Hal ini dapat dicapai dengan mudah dengan melakukan _stubbing_ dan _spying_ pada objek {req, res, next}
+
+**Otherwise:** Sebuah _bug_ di middleware Express === sebuah bug di semua atau banyak _request_
+
+🔗 [**Baca selengkapnya: Test middlewares in isolation**](./sections/testingandquality/test-middlewares.md)
+
+
+
+# `5. Praktik Dalam Produksi`
+
+## ![✔] 5.1. Pemantauan
+
+**TL;DR:** Pemantauan adalah permainan mencari suatu masalah sebelum pelanggan menemukannya terlebih dahulu – yang jelas masalah itu merupakan masalah yang belum pernah terjadi sebelumnya. Pasar kewalahan dengan penawaran sehingga mempertimbangkan untuk memulai dengan menentukan metrik dasar yang harus Anda ikuti (saran saya di dalam), kemudian pertimbangkan fitur-fitur mewah tambahan dan pilih solusi yang mencentang semua kotak. Klik ‘Intinya’ di bawah untuk ringkasan dari berbagai solusi
+
+**Jika tidak:** Kegagalan === pelanggan kecewa. Sederhana
+
+🔗 [**Baca selengkapnya: Monitoring!**](./sections/production/monitoring.md)
+
+
+
+## ![✔] 5.2. Tingkatkan transparansi dengan menggunakan logging yang cerdas
+
+**TL;DR:** _Log_ dapat menjadi gudang statement debug yang bodoh atau papan cantik yang menceritakan kisah aplikasi Anda. Rencanakan platform logging Anda dari hari pertama: bagaimana log dikumpulkan, disimpan dan dianalisis untuk memastikan bahwa informasi yang diinginkan (misalnya tingkat kesalahan, mengikuti seluruh transaksi melalui layanan dan server, dst.) benar-benar dapat diekstrak
+
+**Jika tidak:** Anda berakhir dengan kotak hitam yang sulit dimengerti, kemudian Anda mulai menulis ulang semua statement log untuk menambahkan informasi tambahan
+
+🔗 [**Baca selengkapnya: Increase transparency using smart logging**](./sections/production/smartlogging.md)
+
+
+
+## ![✔] 5.3. Delegasikan apa pun yang mungkin (misalnya gzip, SSL) ke sebuah _reverse proxy_
+
+**TL;DR:** Node sangat buruk dalam melakukan pekerjaan yang intensif CPU seperti melakukan gzip, penghentian SSL, dll. Anda harus menggunakan layanan middleware yang ‘asli’ seperti nginx, HAproxy atau layanan vendor cloud
+
+**Jika tidak:** Thread utama Anda akan tetap sibuk melakukan tugas infrastruktur alih-alih menangani inti aplikasi Anda dan performa akan menurun karenanya
+
+🔗 [**Baca selengkapnya: Delegate anything possible (e.g. gzip, SSL) to a reverse proxy**](./sections/production/delegatetoproxy.md)
+
+
+
+## ![✔] 5.4. Kunci dependensi
+
+**TL;DR:** Kode Anda harus identik di semua lingkungan, namun npm dapat membiarkan dependensi berubah di lingkungan yang berbeda – saat Anda menginstal paket di lingkungan lain npm mencoba menginstal versi terbaru dari paket tersebut. Atasi ini dengan menggunakan file konfigurasi , .npmrc, yang memberi tahu setiap lingkungan untuk menyimpan versi yang tepat (bukan yang terbaru) dari setiap paket. Alternatifnya, untuk kontrol yang lebih baik, gunakan `npm shrinkwrap`. \*Pembaruan: pada NPM5, dependensi dikunci secara default. Manajer paket yang baru, Yarn, juga melakukan hal ini
+
+**Jika tidak:** QA akan menguji kode secara menyeluruh dan menyetujui versi yang kemudian akan berperilaku berbeda dalam produksi. Lebih buruk lagi, server yang berbeda dalam kelompok produksi mungkin menjalankan kode yang berbeda
+
+🔗 [**Baca selengkapnya: Lock dependencies**](./sections/production/lockdependencies.md)
+
+
+
+## ![✔] 5.5. Jaga uptime proses menggunakan alat yang tepat
+
+**TL;DR:** Proses harus tetap berjalan dan dimulai ulang jika terjadi kegagalan. Untuk skenario simpel, alat manajemen proses seperti PM2 mungkin sudah cukup namun di era ‘dockerized’, alat management cluster juga harus dipertimbangkan
+
+**Jika tidak:** Menjalankan banyak instansi tanpa strategi yang jelas dan terlalu banyak alat (manajemen cluster, docker, PM2) dapat menyebabkan kekacauan DevOps
+
+🔗 [**Baca selengkapnya: Guard process uptime using the right tool**](./sections/production/guardprocess.md)
+
+
+
+## ![✔] 5.6. Manfaatkan semua core CPU
+
+**TL;DR:** Pada dasarnya, aplikasi Node berjalan pada satu core CPU sementara core lainnya tidak digunakan. Ini merupakan tugas Anda untuk mereplika proses Node dan menggunakan semua CPU – Untuk aplikasi kecil-menengah Anda dapat menggunakan Node Cluster atau PM2. Untuk aplikasi yang lebih besar pertimbangkan untuk mereplika proses menggunakan beberapa Docker cluster (misalnya K8S, ECS) atau skrip _deployment_ yang didasarkan pada sistem Linux init (misalnya systemd)
+
+**Jika tidak:** Aplikasi Anda kemungkinan hanya menggunakan 25% dari sumber daya yang tersedia(!) atau bahkan kurang. Ingat bahwa server tipikal memiliki 4 core CPU atau lebih, _deployment_ Node.js yang naif hanya menggunakan 1 (bahkan jika menggunakan layanan PaaS seperti AWS beanstalk!)
+
+🔗 [**Baca selengkapnya: Utilize all CPU cores**](./sections/production/utilizecpu.md)
+
+
+
+## ![✔] 5.7. Buat ‘endpoint pemeliharaan’
+
+**TL;DR:** Sediakan sekumpulan informasi terkait sistem, seperti penggunaan memori dan REPL, dll. dalam API yang aman. Meskipun sangat disarankan untuk mengandalkan alat standar dan battle-test, beberapa informasi penting dan operasi lebih mudah dilakukan melalui kode
+
+**Jika tidak:** Anda akan melakukan banyak “deploy diagnostik” – mendeploy kode ke produksi hanya untuk mengekstrak beberapa informasi untuk keperluan diagnostik
+
+🔗 [**Baca selengkapnya: Create a ‘maintenance endpoint’**](./sections/production/createmaintenanceendpoint.md)
+
+
+
+## ![✔] 5.8. Temukan kesalahan dan downtime menggunakan produk APM
+
+**TL;DR:** _Application monitoring and performance products_ (a.k.a APM) secara proaktif mengukur basis kode dan API sehingga mereka dapat secara otomatis melampaui pemantauan tradisional dan mengukur pengalaman pengguna secara keseluruhan di semua layanan dan tingkatan. Misalnya, beberapa produk APM dapat menyoroti transaksi yang terlalu lambat di sisi pengguna sambil menyarankan penyebab utamanya
+
+**Jika tidak:** Anda mungkin menghabiskan banyak tenaga untuk mengukur kinerja dan downtime API, mungkin Anda tidak akan pernah tau bagian kode mana yang paling lambat dalam skenario dunia nyata dan bagaimana hal ini dapat memengaruhi pengalaman pengguna
+
+🔗 [**Baca selengkapnya: Discover errors and downtime using APM products**](./sections/production/apmproducts.md)
+
+
+
+## ![✔] 5.9. Buat kode Anda siap produksi
+
+**TL;DR:** Buat kode dengan tujuan akhir ada dalam pikiran Anda, rencanakan untuk produksi dari hari pertama. Ini terdengar kurang jelas jadi saya telah mengumpulkan beberapa tips pengembangan yang berkaitan erat dengan perawatan produksi (klik intinya di bawah)
+
+**Jika tidak:** Seorang juara dunia IT/DevOps tidak akan memperbaiki sistem yang ditulis dengan buruk
+
+🔗 [**Baca selengkapnya: Make your code production-ready**](./sections/production/productioncode.md)
+
+
+
+## ![✔] 5.10. Ukur dan jaga penggunaan memori
+
+**TL;DR:** Node.js memiliki hubungan yang kontroversial dengan memori: mesin v8 memiliki batas memori yang rendah (1.4GB) dan terdapat cara yang diketahui untuk terjadinya kebocoran memori dalam kode Node – sehingga mengamati memori proses Node adalah suatu keharusan. Pada aplikasi kecil, Anda dapat mengukur memori Anda secara berkala menggunakan perintah _shell_ namun di aplikasi menengah-besar pertimbangkan untuk membuat sistem pemantauan yang kuat untuk mengamati memori
+
+**Jika tidak:** Memori proses Anda mungkin bocor ratusan megabyte sehari seperti yang terjadi pada [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)
+
+🔗 [**Baca selengkapnya: Measure and guard the memory usage**](./sections/production/measurememory.md)
+
+
+
+## ![✔] 5.11. Keluarkan aset _frontend_ Anda dari Node
+
+**TL;DR:** Sajikan konten _frontend_ menggunakan middleware khusus (nginx, S3, CDN) karena performa Node dapat berkurang ketika menangani banyak file statis karena model thread tunggalnya
+
+**Jika tidak:** Thread tunggal Node Anda akan sibuk mengirimkan ratusan file html/gambar/angular/react alih-alih mengalokasikan semua sumber dayanya untuk tugas yang seharusnya – menyajikan konten dinamis
+
+🔗 [**Baca selengkapnya: Get your frontend assets out of Node**](./sections/production/frontendout.md)
+
+
+
+## ![✔] 5.12. Buat aplikasi yang stateless, matikan server Anda hampir setiap hari
+
+**TL;DR:** Simpan semua jenis data (misalnya sesi pengguna, cache, file yang diunggah) ke tempat penyimpanan eksternal. Pertimbangkan untuk ‘mematikan’ server Anda secara berkala atau gunakan platform ‘serverless’ (misalnya AWS Lambda) yang secara eksplisit mengharuskan sifat stateless
+
+**Jika tidak:** Kegagalan di server tertentu akan mengakibatkan downtime aplikasi, bukannya hanya mematikan mesin yang rusak. Selain itu, elastisitas penskalaan akan menjadi lebih sulit karena ketergantungan pada server tertentu
+
+🔗 [**Baca selengkapnya: Be stateless, kill your Servers almost every day**](./sections/production/bestateless.md)
+
+
+
+## ![✔] 5.13. Gunakan alat yang pendeteksi kerentanan secara otomatis
+
+**TL;DR:** Bahkan dependensi yang paling terkemuka seperti Express memiliki kerentanan yang diketahui (dari waktu ke waktu) yang dapat membahayakan sistem. Hal ini dapat dimitigasi dengan mudah menggunakan alat dari komunitas atau komersial yang terus-menerus memeriksa kerentanan dan memberi peringatan (secara lokal atau di GitHub), beberapa bahkan dapat langsung memperbaikinya
+
+**Jika tidak:** Menjaga kode Anda bersih dari kerentanan tanpa alat khusus mengharuskan Anda untuk mengikuti publikasi online tentang ancaman baru. Cukup membosankan
+
+🔗 [**Baca selengkapnya: Use tools that automatically detect vulnerabilities**](./sections/production/detectvulnerabilities.md)
+
+
+
+## ![✔] 5.14. Tetapkan id transaksi di seetiap statement catatan
+
+**TL;DR:** Tetapkan pengenal yang sama, transaksi-id: {sebuah nilai}, ke setiap entri catatan dalam satu permintaan. Kemudian saat memeriksa kesalahan di dalam catatan, simpulkan dengan mudah apa yang terjadi sebelum dan sesudahnya. Sayangnya, hal ini tidak mudah untuk dicapai di Node karena sifat asinkron-nya, lihat contoh kode di dalam
+
+**Jika tidak:** Melihat catatan kesalahan produksi tanpa konteks – apa yang terjadi sebelumnya – membuat Anda lebih sulit untuk memahami penyebab kesalahannya
+
+🔗 [**Baca selengkapnya: Assign ‘TransactionId’ to each log statement**](./sections/production/assigntransactionid.md)
+
+
+
+## ![✔] 5.16. Atur NODE_ENV=production
+
+**TL;DR:** Atur variabel lingkungan NODE_ENV ke ‘production’ or ‘development’ untuk menandai apakah pengoptimalan produksi harus diaktifkan – banyak paket npm melihat lingkungan yang digunakan dan mengoptimalkan kodenya untuk produksi
+
+**Jika tidak:** Mengabaikan properti sederhana ini dapat menurunkan performa. Contohnya, pada saat menggunakan Express untuk rendering sisi server menghilangkan `NODE_ENV` membuat proses render lebih lambat hingga 3 kali lipat!
+
+🔗 [**Baca selengkapnya: Set NODE_ENV=production**](./sections/production/setnodeenv.md)
+
+
+
+## ![✔] 5.16. Rancang deployment otomatis, atomic dan tanpa downtime
+
+**TL;DR:** Penelitian menunjukkan bahwa tim yang melakukan banyak deployment menurunkan kemungkinan masalah produksi yang buruk. Deployment yang otomatis dan cepat tidak memerlukan langkah manual yang berisiko dan waktu downtime layanan meningkatkan proses deployment. Anda mungkin harus melakukan ini menggunakan Docker yang dikombinasikan dengan alat CI karena mereka menjadi standar industri untuk deployment yang efisien
+
+**Jika tidak:** Deployment yang lama -> downtime produksi & kesalahan oleh manusia -> tim ragu dalam melakukan deployment -> lebih sedikit deployment dan fitur
+
+
+
+## ![✔] 5.17. Gunakan versi LTS pada Node.js
+
+**TL;DR:** Pastikan Anda menggunakan versi LTS pada Node.js untuk menerima perbaikan bug yang kritis, pembaruan keamanan dan peningkatan performa
+
+**Otherwise:** Bug atau kerentanan yang baru ditemukan dapat digunakan untuk mengeksploitasi aplikasi yang sedang berjalan dalam produksi, dan aplikasi Anda mungkin menjadi tidak didukung oleh berbagai modul dan lebih sulit untuk di dipelihara
+
+🔗 [**Baca selengkapnya: Use an LTS release of Node.js**](./sections/production/LTSrelease.md)
+
+
+
+## ![✔] 5.18. Jangan rutekan catatan di dalam aplikasi
+
+**TL;DR:** Tempat catatan tidak boleh dibuat oleh pengembang dalam kode aplikasi, tetapi harus ditentukan oleh lingkungan eksekusi dimana aplikasi itu dijalankan. Pengembang harus menuliskan catatan ke `stdout` menggunakan utilitas logger dan membiarkan lingkungan eksekusi (container, server, dll.) menyalurkan `stdout` ke tujuan yang sesuai (misalnya Splunk, Graylog, ElasticSearch, dll.).
+
+**Jika tidak:** Aplikasi menangani rute catatan === sulit untuk dikembangkan, kehilangan catatan, dan _separation of concerns_ yang buruk
+
+🔗 [**Baca selengkapnya: Log Routing**](./sections/production/logrouting.md)
+
+
+
+## ![✔] 5.19. Install paket menggunakan `npm ci`
+
+**TL;DR:** Anda harus memastikan bahwa kode produksi menggunakan versi paket yang sama dengan yang Anda gunakan pada saat pengujian. Jalankan `npm ci` untuk melakukan instalasi bersih dari dependensi di dalam package.json dan package-lock.json. Penggunaan perintah ini sangat direkomendasikan dalam lingkungan otomatis seperti pipeline continuous integration.
+
+**Jika tidak:** QA akan menguji kode secara menyeluruh dan menyetujui versi yang kemudian akan berperilaku berbeda dalam produksi. Lebih buruk lagi, server yang berbeda dalam kelompok produksi mungkin menjalankan kode yang berbeda.
+
+🔗 [**Baca selengkapnya: Use npm ci**](./sections/production/installpackageswithnpmci.md)
+
+
+
+## ![✔] 6.1. Terapkan aturan keamanan linter
+
+
+
+**TL;DR:** Manfaatkan plugin linter yang berhubungan dengan keamanan seperti [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security) untuk menangkap kerentanan dan masalah keamanan sedini mungkin, lebih baik lagi jika dalam proses pembuatan kode. Hal ini dapat membantu menangkap keamanan yang lemah seperti penggunaan eval, menjalankan child process atau memanggil modul menggunakan literal string (misalnya masukan pengguna). Klik 'Baca selengkapnya' di bawah ini untuk melihat contoh kode yang akan dideteksi oleh linter keamanan
+
+**Jika tidak:** Kelemahan keamanan yang jelas selama masa pengembangan malah menjadi masalah besar dalam produksi. Selain itu, proyek mungkin tidak mengikuti praktik kode keamanan yang konsisten, yang mengarah ke kerentanan baru, atau rahasia sensitif yang ter-_commit_ ke dalam repositori remote
+
+🔗 [**Baca selengkapnya: Lint rules**](./sections/security/lintrules.md)
+
+
+
+## ![✔] 6.2. Batasi request serentak dengan menggunakan middleware
+
+
+
+**TL;DR:** Serangan DOS sangat populer dan relatif mudah untuk dilakukan. Terapkan pembatasan rate menggunakan layanan eksternal seperti _cloud load balancers_, _cloud firewalls_, nginx, paket [rate-limiter-flexible](https://www.npmjs.com/package/rate-limiter-flexible), atau (untuk aplikasi yang lebih kecil dan kurang penting) sebuah middleware _rate-limiting_ (misalnya [express-rate-limit](https://www.npmjs.com/package/express-rate-limit))
+
+**Jika tidak:** Aplikasi dapat terkena serangan _denial of service_ sementara pengguna asli menggunakan layanan yang terdegradasi atau tidak tersedia.
+
+🔗 [**Baca selengkapnya: Implement rate limiting**](./sections/security/limitrequests.md)
+
+
+
+## ![✔] 6.3 Keluarkan rahasia dari file konfigurasi atau gunakan paket untuk mengenkripsinya
+
+
+
+**TL;DR:** Jangan pernah menyimpan rahasia dalam bentuk teks biasa dalam file konfigurasi atau kode sumber. Sebagai gantinya, gunakan sistem manajemen rahasia seperti produk _Vault_, _Kubernetes/Docker Secrets_, atau gunakan variabel lingkungan. Sebagai cara terakhir, rahasia yang disimpan di kontrol kode harus terenkripsi dan teratur (kunci bergulir, kedaluwarsa, audit, dll.). Manfaatkan hook pra-_commit_/_push_ untuk mencegah agar rahasia tidak ter-_commit_ secara tidak sengaja
+
+**Jika tidak:** Kontrol sumber, bahkan untuk repositori pribadi, dapat di buat publik secara tidak sengaja, di mana semua rahasia dapat terungkap. Akses kontrol sumber dari pihak eksternal dapat memberikan akses ke sistem terkait (database, api, layanan, dll.) secara tidak sengaja.
+
+🔗 [**Baca selengkapnya: Secret management**](./sections/security/secretmanagement.md)
+
+
+
+## ![✔] 6.4. Cegah injeksi kueri dengan menggunakan pustaka ORM/ODM
+
+
+
+**TL;DR:** Untuk mencegah injeksi SQL/NoSQL dan serangan buruk lainnya, selalu gunakan ORM/ODM atau pustaka database yang melakukan _escape_ pada data atau mendukung kueri berparameter yang bernama atau diindeks, dan tangani validasi masukan pengguna agar sesuai dengan tipe yang diharapkan. Jangan pernah hanya menggunakan template string JavaScript atau penggabungan string untuk memasukkan nilai ke dalam kueri karena ini membuka aplikasi Anda ke spektrum kerentanan yang luas. Semua pustaka akses data pada Node.js (misalnya [Sequelize](https://github.com/sequelize/sequelize), [Knex](https://github.com/tgriesser/knex), [mongoose](https://github.com/Automattic/mongoose)) memiliki perlindungan bawaan untuk menghindari serangan injeksi.
+
+**Jika tidak:** Masukan pengguna yang tidak divalidasi atau tidak disanitasi dapat menyebabkan injeksi operator saat menggunakan MongoDB untuk NoSQL, dan dengan tidak menggunakan sistem sanitasi atau ORM dapat memungkinkan serangan injeksi SQL, membuat suatu kerentanan yang besar.
+
+🔗 [**Baca selengkapnya: Query injection prevention using ORM/ODM libraries**](./sections/security/ormodmusage.md)
+
+
+
+## ![✔] 6.5. Kumpulan praktik terbaik keamanan umum
+
+**TL;DR:** Ini adalah kumpulan saran keamanan yang tidak berhubungan langsung dengan Node.js - implementasi pada Node tidak jauh berbeda dengan implementasi pada bahasa lain. Klik 'Baca selengkapnya' untuk membaca sekilas.
+
+🔗 [**Baca selengkapnya: Common security best practices**](./sections/security/commonsecuritybestpractices.md)
+
+
+
+## ![✔] 6.6. Sesuaikan header response HTTP untuk meningkatkan keamanan
+
+
+
+**TL;DR:** Aplikasi Anda harus menggunakan _header_ yang aman untuk mencegah penyerang dari serangan umum seperti _cross-site scripting_ (XSS), _clickjacking_ dan serangan berbahaya lainnya. Hal ini dapat dikonfigurasikan dengan mudah menggunakan modul seperti [helmet](https://www.npmjs.com/package/helmet).
+
+**Jika tidak:** Penyerang dapat melakukan serangan langsung pada pengguna aplikasi, yang menyebabkan kerentanan keamanan yang sangat besar
+
+🔗 [**Baca selengkapnya: Using secure headers in your application**](./sections/security/secureheaders.md)
+
+
+
+## ![✔] 6.7. Selalu periksa dependensi dari kerentanan secara otomatis
+
+
+
+**TL;DR:** Dengan ekosistem npm, sangat umum pada suatu proyek untuk memiliki banyak dependensi. Dependensi harus selalu diperiksa ketika kerentanan baru ditemukan. Gunakan alat seperti [npm audit](https://docs.npmjs.com/cli/audit) atau [snyk](https://snyk.io/) untuk melacak, memantau dan memperbaiki dependensi yang rentan. Integrasikan alat-alat ini dengan setup CI Anda sehingga Anda dapat menemukan dependensi yang rentan sebelum masuk ke produksi.
+
+**Jika tidak:** Penyerang dapat mendeteksi framework web Anda dan menyerang semua kerentanan yang diketahui.
+
+🔗 [**Baca selengkapnya: Dependency security**](./sections/security/dependencysecurity.md)
+
+
+
+## ![✔] 6.8. Lindungi kata sandi/rahasia pengguna menggunakan bcrypt atau scrypt
+
+
+
+**TL;DR:** Kata sandi atau rahasia (seperti API keys) harus disimpan menggunakan fungsi hash + salt yang aman seperti `bcrypt`,`scrypt`, atau setidaknya `pbkdf2`.
+
+**Jika tidak:** Kata sandi dan rahasia yang disimpan tanpa fungsi yang aman akan rentan terhadap _brute force_ dan penyerangan kamus yang pada akhirnya akan mengarah pada data rahasia yang terekspos.
+
+🔗 [**Baca selengkapnya: User Passwords**](./sections/security/userpasswords.md)
+
+
+
+## ![✔] 6.9. Escape keluaran HTML, JS dan CSS
+
+
+
+**TL;DR:** Data yang tidak terpercaya yang dikirim ke browser mungkin akan tereksekusi alih-alih hanya ditampilkan, hal ini biasanya disebut dengan serangan _cross-site-scripting_ (XSS). Hindari hal ini dengan menggunakan pustaka khusus yang secara eksplisit menandai data sebagai konten yang tidak boleh dieksekusi (misalnya encoding, escaping)
+
+**Jika tidak:** Penyerang mungkin menyimpan kode JavaScript yang berbahaya di DB Anda yang kemudian akan dikirim apa adanya ke pengguna
+
+🔗 [**Baca selengkapnya: Escape output**](./sections/security/escape-output.md)
+
+
+
+## ![✔] 6.10. Validasi skema JSON yang diterima
+
+
+
+**TL;DR:** Validasi muatan _body_ pada request dan pastikan agar muatan memenuhi ekspektasi, gagalkan dengan cepat jika muatan tidak memenuhi ekspektasi. Untuk menghindari kode validasi yang berantakan dalam setiap rute Anda dapat menggunakan validasi skema berbasis JSON yang ringan seperti [jsonschema](https://www.npmjs.com/package/jsonschema) atau [joi](https://www.npmjs.com/package/joi)
+
+**Jika tidak:** Kemurahan hati dan cara permisif Anda dapat meningkatkan kemungkinan penyerangan dan mendorong penyerang untuk mencoba banyak masukan sampai mereka menemukan beberapa kombinasi untuk merusak aplikasi
+
+🔗 [**Baca selengkapnya: Validate incoming JSON schemas**](./sections/security/validation.md)
+
+
+
+## ![✔] 6.11. Dukung daftar hitam JWT
+
+
+
+**TL;DR:** Ketika menggunakan _JSON Web Tokens_ (misalnya, dengan [Passport.js](https://github.com/jaredhanson/passport)), secara default tidak ada cara untuk mencabut akses dari token yang dibuat. Setelah Anda menemukan beberapa aktifitas pengguna yang berbahaya, tidak ada cara untuk mengentikan mereka dari mengakses sistem selama mereka mempunyai token yang valid. Hindari ini dengan menerapkan daftar hitam untuk token yang tidak tepercaya yang divalidasi pada setiap request.
+
+**Jika tidak:** Token yang kedaluwarsa atau salah ditempatkan dapat digunakan secara jahat oleh pihak ketiga untuk mengakses aplikasi dan menyamar sebagai pemilik token.
+
+🔗 [**Baca selengkapnya: Blacklist JSON Web Tokens**](./sections/security/expirejwt.md)
+
+
+
+## ![✔] 6.12. Cegah serangan _brute-force_ terhadap otorisasi
+
+
+
+**TL;DR:** Teknik sederhana dan kuat adalah membatasi upaya otorisasi menggunakan dua metrik:
+
+1. Pertama adalah upaya gagal berturut-turut oleh ID / nama unik dan alamat IP yang sama.
+2. Kedua adalah jumlah upaya gagal dari sebuah alamat IP selama jangka waktu yang lama. Misalnya, blokir alamat IP jika IP tersebut melakukan 100 upaya gagal dalam satu hari.
+
+**Jika tidak:** Penyerang dapat melakukan percobaan kata sandi otomatis tanpa batas untuk mendapatkan akses ke akun yang memiliki hak istimewa pada suatu aplikasi
+
+🔗 [**Baca selengkapnya: Login rate limiting**](./sections/security/login-rate-limit.md)
+
+
+
+## ![✔] 6.13. Jalankan Node.js sebagai pengguna yang bukan root
+
+
+
+**TL;DR:** Ada skenario umum di mana Node.js dijalankan sebagai pengguna root dengan izin tanpa batas. Misalnya, ini adalah perilaku default di kontainer Docker. Direkomendasikan untuk membuat pengguna yang bukan root dan _bake_ pengguna itu ke dalam _Docker image_ (contoh ada di bawah) atau jalankan proses atas nama pengguna ini dengan menjalankan kontainer dengan _flag_ "-u username"
+
+**Jika tidak:** Penyerang yang berhasil menjalankan skrip di server mendapatkan kekuatan tak terbatas atas mesin lokal (misalnya mengganti iptable dan merutekan ulang traffic ke servernya)
+
+🔗 [**Baca selengkapnya: Run Node.js as non-root user**](./sections/security/non-root-user.md)
+
+
+
+## ![✔] 6.14. Batasi ukuran payload menggunakan reverse-proxy atau middleware
+
+
+
+**TL;DR:** Semakin besar ukuran payload-nya, semakin sulit thread tunggal Anda untuk memprosesnya. Ini adalah kesempatan bagi penyerang untuk membuat server bertekuk lutut tanpa banyak mengirimkan request (penyerangan DOS/DDOS). Hindari ini dengan membatasi ukuran body dari request yang masuk di ujung (misalnya firewall, ELB) atau mengonfigurasi [express body parser](https://github.com/expressjs/body-parser) agar hanya menerima payload dengan ukuran kecil
+
+**Jika tidak:** Aplikasi Anda harus menangani request yang besar, tidak dapat memproses pekerjaan penting lainnya yang harus diselesaikan, yang mengarah ke implikasi performa dan kerentanan terhadap serangan DOS
+
+🔗 [**Baca selengkapnya: Limit payload size**](./sections/security/requestpayloadsizelimit.md)
+
+
+
+## ![✔] 6.15. Hindari statement eval pada JavaScript
+
+
+
+**TL;DR:** `eval` sangat buruk karena memungkinkan untuk mengeksekusi kode JavaScript dalam _run time_. Ini bukan hanya menjadi perhatian dalam performa tetapi juga perhatian dalam masalah keamanan penting karena kode JavaScript dapat bersumber dari masukan pengguna. Fitur bahasa lain yang harus dihindari adalah konstruktor `new Function`. `setTimeout` dan `setInterval` juga tidak boleh diberikan kode JavaScript yang dinamis.
+
+**Jika tidak:** Kode JavaScript yang berbahaya menemukan jalan ke dalam teks yang diteruskan ke `eval` atau fungsi evaluasi _real-time_ bahasa Javascript lainnya, dan akan mendapatkan akses penuh ke izin JavaScript di halaman tersebut. Kerentanan ini sering kali diwujudkan sebagai serangan XSS.
+
+🔗 [**Baca selengkapnya: Avoid JavaScript eval statements**](./sections/security/avoideval.md)
+
+
+
+## ![✔] 6.16. Cegah RegEx yang buruk agar tidak membebani eksekusi thread tunggal Anda
+
+
+
+**TL;DR:** _Regular Expressions_, meskipun berguna, dapat menimbulkan ancaman pada aplikasi JavaScript secara luas, dan platform Node.js pada khususnya. Masukan teks pengguna mungkin memerlukan jumlah siklus CPU yang luar biasa untuk diproses. Pemrosesan RegEx mungkin tidak efisien sampai-sampai satu request yang memvalidasi 10 kata dapat memblokir seluruh event loop selama 6 detik dan membuat CPU-nya 🔥. Oleh karena itu, gunakan paket validasi pihak ketiga seperti [validator.js](https://github.com/chriso/validator.js) daripada menuliskan pola Regex Anda sendiri, atau gunakan [safe-regex](https://github.com/substack/safe-regex) untuk mendeteksi pola regex yang rentan
+
+**Jika tidak:** Regex yang ditulis dengan buruk dapat rentan terhadap serangan DoS Regular Expression yang akan memblokir event loop sepenuhnya. MIsalnya, paket `moment` yang populer ditemukan rentan terhadap penggunaan Regex pada November 2017
+
+🔗 [**Baca selengkapnya: Prevent malicious RegEx**](./sections/security/regex.md)
+
+
+
+## ![✔] 6.17. Hindari pemuatan modul menggunakan variabel
+
+
+
+**TL;DR:** Hindari pemuatan file lain dengan jalur yang diberikan sebagai parameter karena dikhawatirkan dapat berasal dari masukan pengguna. Aturan ini dapat diperluas untuk mengakses file secara umum (yaitu `fs.readFile()`) atau pengaksesan sumber sensitif lainnya dengan variabel dinamis yang berasal dari masukan pengguna. Linter [Eslint-plugin-security](https://www.npmjs.com/package/eslint-plugin-security) dapat menangkap pola seperti itu dan memberi peringatan cukup dini
+
+**Jika tidak:** Masukan pengguna yang berbahaya dapat menemukan jalannya ke parameter yang digunakan untuk memuat file, misalnya, file yang sebelumnya diunggah ke sistem file, atau pengaksesan file sistem yang sudah ada.
+
+🔗 [**Baca selengkapnya: Safe module loading**](./sections/security/safemoduleloading.md)
+
+
+
+## ![✔] 6.18. Jalankan kode yang tidak aman di sandbox
+
+
+
+**TL;DR:** Saat ditugaskan untuk menjalankan kode eksternal yang diberikan pada run-time (misalnya plugin), gunakan segala jenis lingkungan eksekusi 'sandbox' yang mengisolasi dan melindungi kode utama dari plugin tersebut. Hal ini dapat dicapai dengan menggunakan proses khusus (misalnya `cluster.fork()`), lingkungan _serverless_ atau paket npm khusus yang bertindak sebagai sandbox
+
+**JIka tidak:** Sebuah plugin dapat menyerang dengan berbagai pilihan seperti perulangan tak terbatas, memberi muatan lebih pada memori, dan mengakses variabel lingkungan sensitif pada proses
+
+🔗 [**Baca selengkapnya: Run unsafe code in a sandbox**](./sections/security/sandbox.md)
+
+
+
+## ![✔] 6.19. Berhati-hati saat menggunakan _child processes_
+
+
+
+**TL;DR:** Hindari penggunaan _child processes_ jika memungkinkan dan validasi serta sanitasi masukan untuk menghindari serangan injeksi shell jika Anda masih perlu menggunakannya. Utamakan penggunaan `child_process.execFile` yang menurut definisi hanya akan menjalankan satu perintah dengan sekumpulan atribut dan tidak akan mengizinkan perluasan parameter shell.
+
+**Jika tidak:** Penggunaan child process yang naif dapat mengakibatkan eksekusi perintah secara remote atau serangan injeksi shell karena masukan pengguna yang berbahaya diteruskan ke perintah sistem yang tidak disanitasi.
+
+🔗 [**Baca selengkapnya: Be cautious when working with child processes**](./sections/security/childprocesses.md)
+
+
+
+## ![✔] 6.20. Sembunyikan detail kesalahan dari klien
+
+
+
+**TL;DR:** Penangan kesalahan express menyembunyikan detail kesalahan secara default. Namun, besar kemungkinan Anda menerapkan logika penanganan kesalahan Anda sendiri dengan objek Error kustom (dianggap sebagai praktik terbaik oleh banyak orang). Jika iya, pastikan Anda tidak mengembalikan seluruh objek error ke klien, yang mungkin mengandung beberapa informasi aplikasi yang sensitif
+
+**Jika tidak:** Informasi sensitif aplikasi seperti path file server, modul pihak ketiga yang digunakan, dan alur kerja internal aplikasi lainnya yang dapat dieksploitasi oleh penyerang, dapat dibocorkan dari informasi yang ditemukan di dalam stack trace
+
+🔗 [**Baca selengkapnya: Hide error details from client**](./sections/security/hideerrors.md)
+
+
+
+## ![✔] 6.21. Konfigurasi 2FA untuk npm atau Yarn
+
+
+
+**TL;DR:** Setiap langkah dalam rantai pengembangan harus dilindungi dengan MFA (_multi-factor authentication_), npm/Yarn menjadi peluang yang bagus bagi penyerang yang ingin mendapatkan kata sandi pengembang. Dengan menggunakan kredensial pengembang, penyerang dapat memasukkan kode berbahaya ke dalam pustaka yang diinstal secara luas di seluruh proyek dan layanan. Bahkan mungkin di seluruh web jika dipublikasikan. Mengaktifkan _2-factor-authentication_ dalam npm akan meninggalkan hampir nol peluang bagi penyerang untuk mengubah kode paket Anda.
+
+**Jika tidak:** [Pernahkah Anda mendengar tentang pengembang eslint yang kata sandinya dibajak?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
+
+
+
+## ![✔] 6.22. Ubah pengaturan middleware sesi
+
+
+
+**TL;DR:** Setiap framework dan teknologi web mempunyai kelemahannya masing-masing - memberi tahu penyerang framework web apa yang digunakan sangat membantu mereka. Menggunakan setelan default untuk middleware sesi dapat membuat aplikasi Anda terkena pembajakan spesifik untuk module dan framework dengan cara yang mirip dengan header `X-Powered-By`. Coba sembunyikan apa pun yang mengidentifikasikan dan mengungkapkan teknologi yang Anda gunakan (misalnya Node.js, express)
+
+**Jika tidak:** Cookie dapat dikirim melalui koneksi yang tidak aman, dan penyerang dapat menggunakan identifikasi sesi untuk mengidentifikasi framework dari aplikasi web, serta kerentanan masing-masing modul
+
+🔗 [**Baca selengkapnya: Cookie and session security**](./sections/security/sessions.md)
+
+
+
+## ![✔] 6.23. Hindari serangan DOS dengan mengatur kapan proses harus berhenti secara eksplisit
+
+
+
+**TL;DR:** Proses Node akan berhenti ketika ada kesalahan yang tidak ditangani. Banyak praktik terbaik bahkan merekomendasikan untuk menghentikan aplikasi meskipun ada kesalahan yang tertangkap dan ditangani. Express, misalnya, akan berhenti jika ada kesalahan asinkron apa pun - kecuali Anda membungkus rute dengan klausa catch. Ini memberikan kesempatan serangan yang sangat bagus bagi penyerang yang mengetahui masukan apa yang memberhentikan proses dan mengirim request yang sama berulang kali. Tidak ada solusi instan untuk ini tapi ada beberapa teknik yang dapat mengurangi hal ini: Beri peringatan kritis setiap kali proses berhenti karena ada kesalahan yang ditangani, validasi masukan dan hindari memberhentikan proses karena masukan pengguna tidak valid, bungkus semua rute dengan catch dan pertimbangkan untuk tidak memberhentikan aplikasi ketika kesalahan berasal dari dalam request (alih-alih apa yang terjadi secara global)
+
+**Jika tidak:** Ini hanya tebakan: mengingat banyak aplikasi Node.js, jika kita memberikan JSON kosong ke semua request POST - banyak aplikasi akan berhenti. Pada saat itu, kita dapat mengirim permintaan yang sama berulang kali untuk memberhentikan aplikasi itu dengan mudah
+
+
+
+## ![✔] 6.24. Hindari pengalihan yang tidak aman
+
+
+
+**TL;DR:** Pengalihan yang tidak memvalidasi masukan pengguna dapat memungkinkan penyerang untuk meluncurkan penipuan phising, mencuri kredensial pengguna, dan melakukan tindakan berbahaya lainnya.
+
+**Jika tidak:** Jika penyerang menemukan bahwa Anda tidak memvalidasi masukan eksternal yang diberikan oleh pengguna, mereka dapat mengeksploitasi kerentanan ini dengan memposting tautan yang dibuat khusus di forum, media sosial, dan tempat publik lainnya agar pengguna mengkliknya.
+
+🔗 [**Baca selengkapnya: Prevent unsafe redirects**](./sections/security/saferedirects.md)
+
+
+
+## ![✔] 6.25. Hindari menerbitkan rahasia ke registri npm
+
+
+
+**TL;DR:** Tindakan pencegahan harus diambil untuk menghindari risiko penerbitan rahasia ke registri publik npm secara tidak sengaja. File `.npmignore` dapat digunakan untuk memasukkan file atau folder ke dalam blacklist, atau array `files` dalam `package.json` dapat digunakan sebagai whitelist.
+
+**Jika tidak:** Kunci API, kata sandi atau rahasia lain proyek Anda dapat disalahgunakan oleh siapapun yang menemukannya, yang dapat mengakibatkan kerugian finansial, peniruan identitas, dan risiko lainnya.
+
+🔗 [**Baca selengkapnya: Avoid publishing secrets**](./sections/security/avoid_publishing_secrets.md)
+
+
+# `7. Draf: Praktik Terbaik Performa`
+
+## Kontributor kami sedang mengerjakan bagian ini. [Ingin bergabung?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
+
+
+
+## ![✔] 7.1. Jangan memblokir _event loop_
+
+**TL;DR:** Hindari pekerjaan yang intensif CPU karena mereka akan memblokir _Event Loop_ dalam satu _thread_ dan pindahkan pekerjaan ini ke _thread_ khusus, proses atau bahkan teknologi yang berbeda berdasarkan konteksnya.
+
+**Jika tidak:** Ketika _Event Loop_ diblokir, Node.js tidak akan dapat menangani permintaan lain sehingga menyebabkan penundaan bagi pengguna lain. **3000 pengguna sedang menunggu tanggapan, konten siap diberikan, tapi satu permintaan mencegah server-nya untuk mengirimkan hasilnya**
+
+🔗 [**Baca selengkapnya: Do not block the event loop**](./sections/performance/block-loop.md)
+
+
+
+## ![✔] 7.2. Utamakan penggunaan metode JS asli daripada utilitas berlebihan seperti Lodash
+
+**TL;DR:** Sering kali lebih merugikan jika menggunakan pustaka seperti `lodash` dan `underscore` daripada metode asli karena mengarah kepada dependensi yang tidak diperlukan dan memperlambat performa.
+Ingatlah bahwa dengan diperkenalkannya mesin V8 baru bersama dengan standar ES baru, metode asli telah ditingkatkan sehingga sekarang sekitar 50% lebih baik daripada pustaka utilitas.
+
+**Jika tidak:** Anda harus mengurus proyek dengan kinerja yang lebih rendah di mana Anda dapat menggunakan apa yang **sudah** ada atau berurusan dengan lebih sedikit baris namun lebih banyak file sebagai gantinya.
+
+🔗 [**Baca selengkapnya: Native over user land utils**](./sections/performance/nativeoverutil.md)
+
+
+
+# `8. Praktik Terbaik Docker`
+
+🏅 Terima kasih banyak kepada [Bret Fisher](https://github.com/BretFisher) yang mengajari kami banyak dari praktik berikut
+
+
+
+## ![✔] 8.1 Gunakan build multi tahap untuk gambar Docker yang lebih kecil dan aman
+
+**TL;DR:** Gunakan build multi tahap hanya untuk menyalin artefak produksi yang diperlukan. Banyak file dan dependensi build-time yang tidak diperlukan untuk menjalankan aplikasi Anda. Dengan build multi tahap resource ini dapat digunakan selama build sementara lingkungan runtime hanya berisikan dengan resource yang diperlukan. Build multi tahap adalah cara mudah untuk menyingkirkan kelebihan berat dan ancaman keamanan.
+
+**Jika tidak:** Gambar yang lebih besar akan memakan waktu yang lebih lama untuk di-build dan dikirim, alat khusus build mungkin mengandung kerentanan dan rahasia yang hanya dimaksudkan untuk fase build mungkin dapat bocor.
+
+### Contoh dockerfle untuk build multi tahap
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY . .
+RUN npm ci && npm run build
+
+
+FROM node:slim-14.4.0
+
+USER node
+EXPOSE 8080
+
+COPY --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/package-lock.json ./
+RUN npm ci --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+🔗 [**Baca selengkapnya: Use multi-stage builds**](./sections/docker/multi_stage_builds.md)
+
+
+
+## ![✔] 8.2. Lakukan bootstrap menggunakan perintah 'node', hindari npm start
+
+**TL;DR:** Gunakan `CMD ['node','server.js']` untuk memulai aplikasi Anda, hindari menggunakan skrip npm yang tidak meneruskan sinyal OS ke kode. Ini mencegah masalah dengan proses anak, penanganan sinyal, pemberhentian yang baik dan proses zombie.
+
+**Jika tidak:** Ketika tidak ada sinyal yang dilewatkan, kode Anda tidak akan pernah diberi tahu tentang penghentian. Tanpa itu, kode Anda akan kehilangan kesempatan untuk berhenti dengan benar dan kehilangan permintaan dan/atau data dapat terjadi.
+
+[**Baca selengkapnya: Bootstrap container using node command, avoid npm start**](./sections/docker/bootstrap-using-node.md)
+
+
+
+## ![✔] 8.3. Biarkan runtime Docker menangani replikasi dan uptime
+
+**TL;DR:** Ketika menggunakan orkestrator run time Docker (misalnya Kubernetes), aktifkan proses Node.js seecara langsung tanpa manajer proses perantara atau kode khusus yang mereplikasi proses (misalnya PM2, modul Cluster). Platform runtime mempunyai jumlah data dan visibilitas tertinggi untuk membuat keputusan penempatan - Platform ini mengetahui dengan baik berapa banyak proses yang diperlukan, cara menyebarkannya dan apa yang harus dilakukan jika terjadi kerusakan
+
+**Jika tidak:** Kontainer tetap rusak karena kekurangan sumber daya akan dimulai ulang tanpa batas oleh manajer proses. Jika Kubernetes menyadari hal ini, Kubernetes dapat memindahkannya ke banyak instance yang berbeda
+
+🔗 [**Baca selengkapnya: Let the Docker orchestrator restart and replicate processes**](./sections/docker/restart-and-replicate-processes.md)
+
+
+
+## ![✔] 8.4. Gunakan .dockerignore untuk mencegah pembocoran rahasia
+
+**TL;DR**: Sertakan file `.dockerignore` yang memfilter file rahasia umum dan artefak pengembangan. Dengan melakukan itu, Anda dapat mencegah kebocoran rahasia ke dalam gambar. Sebagai bonus waktu build akan berkurang secara signifikan. Pastikan juga untuk tidak menyalin semua file secara rekursif melainkan pilih file yang harus disalin ke Docker secara eksplisit
+
+**Jika tidak**: File rahasia pribadi umum seperti `.env`, `.aws` dan `.npmrc` akan dibagikan dengan siapapun yang memiliki akses ke image (misalnya repositori Docker)
+
+🔗 [**Baca selengkapnya: Use .dockerignore**](./sections/docker/docker-ignore.md)
+
+
+
+## ![✔] 8.5. Bersihkan dependensi sebelum produksi
+
+**TL;DR:** Meskipun dependensi pengembangan terkadang diperlukan selama siklus hidup build pengujian, pada akhirnya gambar yang dikirim ke produksi harus minimal dan bersih dari dependensi pengembangan. Hal tersebut dapat menjamin hanya kode yang diperlukan yang dikirim dan jumlah potensi serangan (misalnya attack surface) diminimalkan. Ketika menggunakan build multi tahap (lihat poin khusus) hal ini dapat dicapai dengan menginstal semua dependensi terlebih dahulu dan kemudian menjalankan `npm ci --production`
+
+**Jika tidak:** Banyak penerobosan keamanan npm yang buruk ditemukan dalam paket pengembangan (misalnya [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes))
+
+🔗 [\*\*Baca selengkapnya: Remove development dependencies](./sections/docker/install-for-production.md)
+
+
+
+## ![✔] 8.6. Matikan aplikasi dengan baik dan cerdas
+
+**TL;DR:** Tangani proses event SIGTERM dan bersihkan semua koneksi dan sumber daya yang ada. Hal ini harus dilakukan sambil menanggapi permintaan yang sedang berlangsung. Dalam runtime Docker, mematikan kontainer bukanlah peristiwa yang jarang terjadi, melainkan sesuatu yang sering terjadi sebagai bagian dari pekerjaan rutin. Untuk mencapai hal ini, diperlukan beberapa kode yang baik untuk mengatur beberapa bagian yang bergerak: load balancer, koneksi keep-alive, server HTTP dan sumber daya lainnya
+
+**Jika tidak:** Mematikan aplikasi secara langsung berarti tidak menanggapi ribuan pengguna yang kecewa
+
+🔗 [**Baca selengkapnya: Graceful shutdown**](./sections/docker/graceful-shutdown.md)
+
+
+
+## ![✔] 8.7. Tetapkan batas memori menggunakan Docker dan v8
+
+**TL;DR:** Selalu konfigurasikan batas memori menggunakan Docker dan runtime flag JavaScript. Batas pada Docker diperlukan untuk membuat keputusan penempatan kontainer yang baik, flag `max-old-space` pada --v8 diperlukan untuk memulai GC tepat waktu untuk mencegah penggunaan memori yang kurang. Secara praktis, tetapkan batas memori `max-old-space` pada v8 sedikit lebih rendah dari pada batas memori kontainer
+
+**Jika tidak:** Definisi Docker diperlukan untuk melakukan keputusan penskalaan yang baik dan mencegah kelaparan warga lain. Tanpa menentukan batas pada v8 juga, sumber daya kontainer juga akan kurang digunakan oleh Node - Tanpa instruksi eksplisit Node akan berhenti saat menggunakan ~50-60% dari sumber daya hostnya
+
+🔗 [**Baca selengkapnya: Set memory limits using Docker only**](./sections/docker/memory-limit.md)
+
+
+
+## ![✔] 8.8. Rencanakan caching yang efisien
+
+**TL;DR:** Membangun ulang seluruh image docker dari cache dapat dilakukan hampir seketika jika dilakukan dengan benar. Instruksi yang jarang diperbarui harus berada di atas Dockerfile Anda dan yang terus berubah (seperti kode app) harus berada di bawah.
+
+**Jika tidak:** Build Docker akan sangat lama dan memakan banyak sumber daya bahkan saat melakukan perubahan kecil
+
+🔗 [**Baca selengkapnya: Leverage caching to reduce build times**](./sections/docker/use-cache-for-shorter-build-time.md)
+
+
+
+## ![✔] 8.9. Gunakan referensi gambar eksplisit, hindari tag `latest`
+
+**TL;DR:** Tentukan `digest` eksplisit gambar atau label berversi, jangan pernah merujuk ke `latest`. Pengembang sering kali percaya bahwa menetapkan tag `latest` akan memberi mereka gambar terbaru di repositori namun hal ini tidak benar. Menggunakan `digest` menjamin bahwa setiap instansi layanan menjalankan kode yang sama persis.
+
+Selain itu, merujuk ke sebuah tag gambar berarti gambar dasar dapat berubah, karena tag image tidak dapat diandalkan untuk penginstalan deterministik. Jika penginstalan deterministik diharapkan, digest SHA256 dapat digunakan untuk mereferensikan ke gambar yang tepat.
+
+**Jika tidak:** Versi baru gambar dasar dapat dideploy ke produksi dengan perubahan yang dapat merusak, menyebabkan perilaku aplikasi yang tidak diinginkan.
+
+🔗 [**Baca selengkapnya: Understand image tags and use the "latest" tag with caution**](./sections/docker/image-tags.md)
+
+
+
+## ![✔] 8.10. Utamakan gambar dasar Docker yang lebih kecil
+
+**TL;DR:** Gambar yang besar mempunyai tingkat kerentanan yang lebih tinggi dan meningkatkan konsumsi sumber daya. Menggunakan gambar docker yang lebih ramping, seperti varian Linux Slim dan Alpine, dapat mengurangi masalah ini.
+
+**Jika tidak:** Membangun, mendorong, dan menarik gambar akan membutuhkan waktu yang lebih lama, vektor serangan yang tidak diketahui dapat digunakan oleh aktor jahat dan lebih banyak sumber daya yang dikonsumsi.
+
+🔗 [**Baca selengkapnya: Prefer smaller images**](./sections/docker/smaller_base_images.md)
+
+
+
+## ![✔] 8.11. Bersihkan rahasia pada build-time, hindari rahasia di args
+
+**TL;DR:** Hindari rahasia yang bocor dari lingkungan build Docker. Gambar Docker biasanya terbagi di beberapa lingkungan seperti CI dan registri yang tidak disterilkan seperti lingkungan produksi. Contoh tipikalnya adalah token npm yang biasanya diteruskan ke dockerfile sebagai argumen. Token ini tetap berada di dalam gambar lama setelah diperlukan dan memungkinkan penyerang mengakses tanpa batas ke registri npm pribadi. Hal ini dapat dihindari dengan mengatasi file rahasia seperti `.npmrc` dan kemudian menghapusnya menggunakan build mutli tahap (hati-hati, rahasia build juga harus dihapus) atau dengan menggunakan fitur rahasia build-kit Docker yang tidak meninggalkan jejak
+
+**Jika tidak:** Setiap orang yang mempunyai akses ke CI dan registri Docker juga akan mendapatkan akses ke rahasia organisasi yang berharga sebagai bonus
+
+🔗 [**Baca selengkapnya: Clean-out build-time secrets**](./sections/docker/avoid-build-time-secrets.md)
+
+
+
+## ![✔] 8.12. Pindai gambar untuk menemukan lapisan kerentanan
+
+**TL;DR:** Selain memeriksa kerentanan kode dependensi pastikan juga untuk memindai gambar akhir yang dikirim ke produksi. Pemindai gambar Docker memeriksa kode dependensi tapi juga binari OS. Pemindaian keamanan E2E ini mencakup lebih banyak hal dan memverifikasi bahwa tidak ada orang jahat yang menginjeksi hal-hal buruk selama build. Oleh karena itu, disarankan untuk menjalankan hal ini sebagai langkah terakhir sebelum proses deployment. Ada beberapa pemindai gratis dan komersial yang juga menyediakan plugin CI/CD
+
+**Jika tidak:** Kode Anda mungkin sepenuhnya bebas dari kerentanan. Namun itu mungkin masih dapat diretas karena versi binari OS-level yang rentan (misalnya OpenSSL, TarBall) yang biasanya digunakan oleh aplikasi
+
+🔗 [**Baca selengkapnya: Generic Docker practices**](./sections/docker/scan-images.md)
+
+
+
+## ![✔] 8.13 Bersihkan cache NODE_MODULE
+
+**TL;DR:** Setelah menginstal dependensi dalam kontainer, hapus cache lokal. Tidak masuk akal untuk menduplikasi dependensi untuk penginstalan lebih cepat di masa mendatang karena tidak akan ada penginstalan lagi seterusnya - Image Docker tidak dapat diubah. Dengan menggunakan satu baris kode, puluhan MB (biasanya 10-50% dari ukuran gambar) dihilangkan
+
+**Jika tidak:** Gambar yang akan dikirim ke produksi akan menjadi 30% lebih besar karena file yang tidak akan pernah digunakan
+
+🔗 [**Baca selengkapnya: Clean NODE_MODULE cache**](./sections/docker/clean-cache.md)
+
+
+
+## ![✔] 8.14. Praktik Docker umum
+
+**TL;DR:** Ini adalah kumpulan saran Docker yang tidak terkait langsung dengan Node.js - implementasi pada Node tidak jauh berbeda dengan bahasa lain. Klik baca selengkapnya untuk membaca sekilas.
+
+🔗 [**Baca selengkapnya: Generic Docker practices**](./sections/docker/generic-tips.md)
+
+
+
+## ![✔] 8.15. Lint Dockerfile Anda
+
+**TL;DR:** Melakukan lint pada Dockerfile Anda adalah langkah yang penting untuk mengidentifikasi masalah di Dockerfile Anda yang tidak ada di praktik terbaik. Dengan memeriksa potensi kekurangan menggunakan linter Docker khusus, peningkatan performa dan keamanan dapat dengan mudah diidentifikasi, menghemat waktu yang terbuang atau mengurangi masalah keamanan dalam kode produksi.
+
+**Jika tidak:** Secara tidak sengaja pembuat Dockerfile meninggalkan Root sebagai pengguna produksi, dan juga menggunakan gambar dari repositori yang tidak dikenal. Hal ini dapat dihindari hanya dengan linter sederhana.
+
+🔗 [**Baca selengkapnya: Lint your Dockerfile**](./sections/docker/lint-dockerfile.md)
+
+
+
+# Tonggak Sejarah
+
+Untuk menjaga panduan ini agar tetap mutakir, kami terus memperbarui dan meningkatkan pedoman dan praktik terbaik ini dengan bantuan komunitas. Anda dapat mengikuti [milestones](https://github.com/goldbergyoni/nodebestpractices/milestones) dan bergabung dalam kelompok kerja jika Anda ingin berkontribusi pada proyek ini
+
+
+
+## Terjemahan
+
+Semua terjemahan merupakan kontribusi dari komunitas. Kami akan dengan senang hati mendapatkan bantuan baik untuk terjemahan yang telah selesai, sedang berlangsung atau yang baru!
+
+### Terjemahan selesai
+
+-  [Portugis Brazil](./README.brazilian-portuguese.md) - Terima kasih kepada [Marcelo Melo](https://github.com/marcelosdm)
+-  [Cina](./README.chinese.md) - Terima kasih kepada [Matt Jin](https://github.com/mattjin)
+-  [Rusia](./README.russian.md) - Terima kasih kepada [Alex Ivanov](https://github.com/contributorpw)
+-  [Polandia](./README.polish.md) - Terima kasih kepada [Michal Biesiada](https://github.com/mbiesiad)
+-  [Basque](README.basque.md) - Terima kasih kepada [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuesta
+
+### Terjemahan dalam proses
+
+-  [Prancis](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Diskusi](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  Ibrani ([Diskusi](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Korea](README.korean.md) - Terima kasih kepada [Sangbeom Han](https://github.com/uronly14me) ([Diskusi](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Spanyol](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Diskusi](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turki ([Diskusi](https://github.com/goldbergyoni/nodebestpractices/issues/139))
+
+
+
+## Komite Pengarah
+
+Memperkenalkan anggota komite pengarah - orang-orang yang bekerja sama untuk memberikan panduan dan arahan masa depan proyek. Selain itu, setiap anggota komite memimpin proyek yang dilacak dalam [Github projects](https://github.com/goldbergyoni/nodebestpractices/projects) kami.
+
+
+
+[Yoni Goldberg](https://github.com/goldbergyoni)
+
+
+
+Konsultan Node.js independen yang bekerja dengan pelanggan di AS, Eropa, dan Israel dalam membangun aplikasi Node.js berskala besar. Banyak praktik terbaik di atas pertama kali dipublikasikan di [goldbergyoni.com](https://goldbergyoni.com). Hubungi Yoni di [@goldbergyoni](https://github.com/goldbergyoni) atau [me@goldbergyoni.com](mailto:me@goldbergyoni.com)
+
+
+
+
+
+[Bruno Scheufler](https://github.com/BrunoScheufler)
+
+
+💻 Engineer web full-stack, penggemar Node.js & GraphQL
+
+
+
+
+
+[Kyle Martin](https://github.com/js-kyle)
+
+
+
+Pengembang Full Stack & Site Reliability Engineer yang berbasis di Selandia Baru, tertarik pada keamanan aplikasi web, dan merancang serta membangun aplikasi Node.js untuk bekerja dalam skala global.
+
+
+
+
+
+[Kevyn Bruyere](https://github.com/kevynb)
+
+
+Pengembang full-stack independen dengan selera untuk Ops dan otomatisasi.
+
+
+
+### Mantan Komite Pengarah
+
+
+
+[Sagir Khan](https://github.com/sagirk)
+
+
+
+
+Spesialis mendalam dalam JavaScript dan ekosistemnya — React, Node.js, TypeScript, GraphQL, MongoDB, hampir semua hal yang berhubungan dengan JS/JSON di setiap lapisan sistem — membuat produk menggunakan platform web untuk merek paling terkenal di dunia. Anggota perorangan dari Node.js Foundation.
+
+
+
+## Kolaborator
+
+Terima kasih untuk semua kolaborator kami! 🙏
+
+Kolaborator kami adalah anggota yang sering berkontribusi ke repositori ini, melalui menyarankan praktik terbaik baru, menyortir masalah, meninjau pull request dan banyak lagi. Jika Anda tertarik untuk membantu kami memandu ribuan orang untuk membuat aplikasi Node.js yang lebih baik, silakan baca [contributor guidelines](./.operations/CONTRIBUTING.md) 🎉
+
+| | |
+| :---------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
+| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
+
+### Mantan Kolaborator
+
+| |
+| :-------------------------------------------------------------------------------------------------------------------------: |
+| [Refael Ackermann](https://github.com/refack) |
+
+
+
+## Kontribusi
+
+Jika Anda pernah ingin berkontribusi pada open source, sekarang kesempatan Anda! Lihat [contributing docs](.operations/CONTRIBUTING.md) untuk informasi lebih lanjut.
+
+## Kontributor ✨
+
+Terima kasih kepada orang-orang hebat ini yang telah berkontribusi pada repositori ini!
+
+
+
+
+
+
+# `7. Draft: パフォーマンスのプラクティス`
+
+## Our contributors are working on this section. [Would you like to join?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
+
+
-
-
-
-[](https://twitter.com/nodepractices/) **트위터에서 팔로우 하세요!** [**@nodepractices**](https://twitter.com/nodepractices/)
-
-
-
-다른 언어로 읽기: [**CN**](/README.chinese.md) [(**ES**, **FR**, **HE**, **KR**, **RU**, **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 🔗 [npm audit](https://docs.npmjs.com/cli/audit) and 🔗 [snyk.io](https://snyk.io) 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](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc) 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/productioncode.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) 을 보고 참여하십시오.
-
-
-
-## 번역
-
-모든 번역은 커뮤니티에 의해 기여되고 있습니다. 이미 완성된 번역이나, 진행중, 새로운 번역에 대한 도움은 언제나 환영합니다!
-
-### 번역 작업 완료
-
-*  [Chinese](README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
-
-### 번역 작업중
-
-*  [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/129))
-*  Hebrew ([Discussion](https://github.com/i0natan/nodebestpractices/issues/156))
-*  [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/94))
-*  [Russian](https://github.com/i0natan/nodebestpractices/blob/russian-translation/README.russian.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/454))
-*  [Spanish](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/95))
-*  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
-
-We appreciate any contribution, from a single word fix to a new best practice. View our contributors and [contributing documentation here!](CONTRIBUTORS.md)
-
-
+
+
+
+[](https://twitter.com/nodepractices/) **트위터에서 팔로우 하세요!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+
+[:green_book: 포괄적인 Node.js 테스트 & 품질 모범사례 강의](https://testjavascript.com/)
+
+
+
+다른 언어로 읽기: [**CN**](./README.chinese.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**EU**](./README.basque.md) [(**ES**, **FR**, **HE**, **KR** and **TR** 은 작업중입니다!)](#translations)
+
+
+
+###### [운영 위원회](#운영-위원회)와 [협력자분들](#공동-저자)에 의해 구축되고 유지되고 있습니다
+
+# 최근 모범사례와 뉴스
+
+- ** 프랑스어 번역!1! :** 우리의 국제 가이드에 합류한 최신 번역은 프랑스어입니다. Bienvenue(어서오세요.)
+
+- **🇯🇵 Japanese translation:** 우리 가이드는 이제 일본어로도 번역됩니다! 뛰어난 [YukiOta](https://github.com/YukiOta)와 [Yuta Azumi](https://github.com/YA21)의 제공입니다.
+
+- **🎊 60,000 stars!**: 우리 리포지토리는 60,100명의 개발자에게 별을 받고 신뢰를 얻었습니다. 말문이 막힐 정도입니다.
+
+
+
+# 어서오세요! 먼저 이 3가지를 알아두세요
+
+**1. 이 문서를 읽는 것은 베스트 Node.js 문서 수십개를 읽는 것과 같습니다. -** 이 문서는 Node.js 의 가장 일반적인 Best Practice 모범사례들을 모은 요약집 및 큐레이션입니다.
+
+**2. 가장 큰 모음집이며, 매주 성장하고 있습니다. -** 현재 80개 이상의 모범사례들과 스타일 가이드 및 아키텍처 관련 팁들을 제공하고 있습니다. 이 문서를 계속 갱신하는 새로운 이슈들과 PR들이 매일 나오고 있습니다. 이 문서의 잘못된 코드를 고치거나 새로운 아이디어들을 제안하는 것은 매우 환영합니다. [글쓰기 지침은 여기](./.operations/writing-guidelines.md)서 확인하세요
+
+**3. 항목 대부분은 추가적인 정보가 있습니다 -** 항목 옆쪽에 존재하는 **🔗자세히 보기** 링크에서 코드 예제, 참조 블로그 또는 기타 정보들을 확인 할 수 있습니다.
+
+
+
+## 목차
+
+1. [프로젝트 구조 설계 (5)](#1-프로젝트-구조-설계)
+2. [에러 처리 방법 (11)](#2-에러-처리-방법)
+3. [코드 스타일 (12) ](#3-코드-스타일)
+4. [테스트 및 전체 품질 관리 (13) ](#4-테스트-및-전체-품질-관리)
+5. [운영 환경으로 전환하기 (19) ](#5-운영-환경으로-전환하기)
+6. [보안 (25)](#6-보안)
+7. [성능 (2) (현재진행형 ✍️)](#7-초안-성능)
+
+
+
+# `1. 프로젝트 구조 설계`
+
+## ![✔] 1.1 컴포넌트 기반으로 설계하라
+
+**핵심요약:** 큰 프로젝트에서 빠지기 쉬운 최악의 함정은 수백개의 의존성을 가진 커다란 소스코드를 유지보수하는 것이다. 그렇게 단일로 통째로 짜여진 monolith 코드는 개발자가 새로운 기능을 추가하는 속도가 느려지게 한다. 그 대신에 코드를 컴포넌트로 나누고, 각각의 컴포넌트가 자신의 폴더 혹은 할당된 코드베이스를 안에서 작고 간단한 단위로 유지되도록 해라. 아래의 '자세히 보기'를 눌러 올바른 프로젝트 구조의 예시를 확인해라.
+
+**그렇게 하지 않을 경우:** 새로운 기능을 작성하는 개발자가 변경사항이 어떤 영향을 미치는지 알기가 힘들면 의존하고 있는 다른 컴포넌트를 망칠까 두려워 하게 되고, 이는 배포를 더 느리고 더 불안전하게 만든다. 비지니스 단위가 나눠져 있지 않으면 확장(scale-out)하기도 쉽지 않게 된다.
+
+🔗 [**자세히 보기: 컴포넌트로 구조화하기**](./sections/projectstructre/breakintcomponents.korean.md)
+
+
+
+## ![✔] 1.2 컴포넌트를 계층화(layer)하고, Express를 그 경계 안에 둬라
+
+**핵심요약:** 각각의 컴포넌트는 웹, 로직, 데이터 접근 코드을 위한 객체인 '계층'을 포함해야 한다. 이것은 우려할 만한 요소들을 깨끗하게 분리할 뿐만 아니라 모의 객체(mock)를 만들어 테스트하기 굉장히 쉽게 만든다. 이것이 굉장히 일반적인 패턴임에도, API 개발자들은 웹 계층의 객체 (Express req, res)를 비지니스 로직과 데이터 계층으로 보내서 계층을 뒤섞어버리는 경향이 있다. 그렇게 하는것은 당신의 어플리케이션에 의존성을 만들고 Express에서만 접근 가능하도록 만든다.
+
+**그렇게 하지 않을 경우:** 웹 객체와 다른 계층을 뒤섞은 앱은 테스트 코드, CRON 작업이나 Express가 아닌 다른 곳에서의 접근을 불가능하게 한다.
+
+🔗 [**자세히 보기: 앱을 계층화하기**](./sections/projectstructre/createlayers.korean.md)
+
+
+
+## ![✔] 1.3 공유 유틸리티들은 NPM 패키지로 감싸라 (wrap)
+
+**핵심요약:** 커다란 코드 기반으로 구성되어있는 커다란 앱에서는 로깅, 암호화 같은 횡단 관심사(cross-cutting-concern)가 있는 유틸의 경우 당신이 쓴 코드로 감싸진 private NPM package의 형태로 노출이 되어야 한다. 이것은 여러 코드 기반과 프로젝트들에게 그것들을 공유할 수 있도록 해준다.
+
+**그렇게 하지 않을 경우:** 당신 자신만의 배포 및 종속 바퀴(dependency wheel)를 새로이 발명해야 할 것이다.
+
+🔗 [**자세히 보기: 기능으로 구조화 하기**](./sections/projectstructre/wraputilities.korean.md)
+
+
+
+## ![✔] 1.4 Express의 app과 server를 분리하라
+
+**핵심요약:** [Express](https://expressjs.com/) 앱을 통째로 하나의 큰 파일에 정의하는 나쁜 습관은 피해라 - 'Express' 정의를 최소한 둘로는 나누자: API 선언(app.js)과 네트워크 부분(WWW)으로. 더 좋은 구조는 API 선언을 컴포넌트 안에 놓는 것이다.
+
+**그렇게 하지 않을 경우:** HTTP 요청으로만 API 테스트가 가능하게 된다 (커버리지 보고서를 생성하기가 더 느려지고 훨씬 힘들어진다). 수백줄의 코드를 하나의 파일에서 관리하는 것이 크게 즐겁지는 않을 것이다.
+
+🔗 [**자세히 보기: 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), [convict](https://www.npmjs.com/package/convict)와 같이 이러한 요구사항을 동작하게 해주는 몇가지 패키지가 존재한다.
+
+**그렇게 하지 않을 경우:** 위의 구성 요구사항 중 하나라도 만족시키지 못한다면 개발팀이나 데브옵스팀을 늪으로 몰아갈 수 있다. 십중팔구 둘 다.
+
+🔗 [**자세히 보기: 구성 모범 사례**](./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를 호출자들에게 어떤 에러가 돌아올 수 있는지 미리 알려주어서 에러를 충돌없이 신중하게 처리 할 수 있게 해주어라. RESTful API같은 경우엔 Swagger 같은 API 문서화 프레임워크를 통해 이루어진다. GraphQL의 경우엔 개요(schema)와 주석을 활용할 수 있다.
+
+**그렇게 하지 않을 경우:** API 클라이언트는 알수 없는 에러로 인한 충돌 후에 재시작을 결정할수도 있을 것이다. 참고로 당신의 API를 호출한 사람이 당신 자신 일수도 있다 (마이크로서비스 환경에서는 아주 일반적이다).
+
+🔗 [**자세히 보기: Swagger에서 에러 문서화하기**](./sections/errorhandling/documentingusingswagger.korean.md)
+
+
+
+## ![✔] 2.6 낯선이가 들어오면 프로세스를 적절하게 중단하라
+
+**핵심요약:** 알수 없는 에러(프로그래머 에러, 모범사례 2.3번 참조)가 발생하면 어플리케이션의 건강상태가 불확실해진다. 일반적인 방법은 [Forever](https://www.npmjs.com/package/forever)나 [PM2](http://pm2.keymetrics.io/) 같은 '재시작' 도구로 프로세스를 다시 시작하는 것이다.
+
+**그렇게 하지 않을 경우:** 익숙치 않은 예외가 발생하면 일부 객체가 오류 상태 (예를 들어 전역적으로 사용되지만 내부 오류로 인해 이벤트를 더이상 내보내지 않는 event emitter)라서 향후의 모든 요청을 실패시키거나 미친것처럼 작동할 수 있다.
+
+🔗 [**자세히 보기: 프로세스 중단하기**](./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
+// 좋은 예
+function someFunction() {
+ // 코드 블록
+}
+
+// 나쁜 예
+function someFunction()
+{
+ // 코드 블록
+}
+```
+
+**그렇게 하지 않을 경우:** 이 모범사례를 적용하지 않는 것은 아래의 StackOverflow 스레드에서 보는 바와 같이 예기치못한 결과로 이어질 수 있다.
+
+🔗 [**자세히 보기:** "왜 결과가 중괄호의 위치에 따라 달라지는 거죠?" (Stackoverflow)](https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement)
+
+
+
+## ![✔] 3.4 문장을 제대로 분리해라
+
+당신이 문장 끝에 세미콜론을 붙이든 아니든, 제대로 문장을 끝내지 않거나 자동 세미콜론 삽입과 관련된 흔한 실수들을 알아두면 잦은 구문 오류 (syntax error)를 제거하는데 도움이 된다.
+
+**핵심요약:** ESLint를 써서 제대로 문장을 끝내고 있는지 경각심을 불러일으켜라. [Prettier](https://prettier.io/) or [Standardjs](https://standardjs.com/)는 자동으로 이 문제를 해결해준다.
+
+**그렇게 하지 않을 경우:** 이전 섹션에서 본것처럼 자바스크립트의 인터프리터는 세미콜론이 없으면 자동으로 문장의 끝에 세미콜론을 붙이거나, 문장이 끝났어야 함에도 끝났다고 인지하지 못하여 의도되지 않은 결과를 야기할 수 있다. 대부분의 의도하지 않은 에러들은 assignment를 사용하고 imediate invoked function expression을 사용하는 것을 피함으로써 예방할 수 있다.
+
+### 3.4 코드 예제
+
+```javascript
+// 좋은 예
+function doThing() {
+ // ...
+}
+
+doThing()
+
+// 좋은 예
+
+const items = [1, 2, 3]
+items.forEach(console.log)
+
+// 나쁜 예 — 예외 발생
+const m = new Map()
+const a = [1,2,3]
+[...m.values()].forEach(console.log)
+> [...m.values()].forEach(console.log)
+> ^^^
+> SyntaxError: Unexpected token ...
+
+// 나쁜 예 — 예외 발생
+const count = 2 // 2()를 호출하려 하지만, 2는 함수가 아니다
+(function doSomething() {
+ // 이쁜짓
+}())
+// immediate invoked function 전에 세미콜론을 놓던나, const 정의 후에 놓거나, 익명함수의 반환값을 변수에 저장하던가, 아니면 아예 IIFE를 쓰지 마라
+```
+
+🔗 [**Read more:** "Semi ESLint rule"](https://eslint.org/docs/rules/semi)
+🔗 [**Read more:** "No unexpected multiline ESLint rule"](https://eslint.org/docs/rules/no-unexpected-multiline)
+
+
+
+## ![✔] 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 파일을 거치도록 해라. 이것은 모듈의 '인터페이스'역할을 하며 계약을 위반하지 않으면서 미래의 변경사항에 대해 유연하게 대처하도록 해준다.
+
+**그렇게 하지 않을 경우:** 파일 내부의 구조 혹은 서명을 변경하면 클라이언트와의 인터페이스가 손상될 수 있다.
+
+### 3.9 코드 예제
+
+```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로 반환 될 수있다.
+
+### 3.10 코드 예제
+
+```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의 함수 내의) 긴 코드는 버그에 취약하고 읽기도 번거롭다.
+
+🔗 [**Read mode: 화살표 함수를 받아들일 시간이다**](https://medium.com/javascript-scene/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)
+
+
+
+# `4. 테스트 및 전체 품질 관리`
+
+## ![✔] 4.1 다른건 못해도 최소한 API (컴포넌트) 테스트는 써라
+
+**핵심요약:** 대부분의 프로젝트는 짧은 일정으로 인해 자동화 된 테스트가 없거나 후일 통제를 벗어난 이른바 "시험용 프로젝트" 라는 이유로 버려진다. 그러므로, 쓰기에도 제일 쉽고 유닛 테스트보다 더 넓게 커버할 수 있는 API 테스트를 우선으로 시작해라. ([포스트맨](https://www.getpostman.com/) 같은 도구를 이용하지 않고도 API 테스트를 쓸 수 있다.) 나중에 시간과 자원이 더 나면 그때 유닛테스트, DB 테스트, 성능 테스트 등의 좀 더 발전된 테스트 종류를 계속 더해라.
+
+**그렇게 하지 않을 경우:** 유닛 테스트 쓰는데 시간을 몇 날 며칠을 쓰고선 시스템 커버리지가 20% 밖에 안된다는걸 깨닫게 될 수 있다.
+
+
+
+## ![✔] 4.2 테스트 이름에 이 3가지를 포함해라
+
+**핵심요약:** 코드 내부에 익숙하지 않은 QA 엔지니어들과 개발자들에게 따로 설명이 필요 없도록 requirement 계층에서 이미 자명하도록 해라. 무엇을 (unit under test), 어떤 환경에서, 어떤 결과를 예상하고 테스트 하는 것인지 테스트 이름에 명시해라.
+
+**그렇게 하지 않을 경우:** 배포에 실패하였습니다, “프로덕트 추가” 라는 테스트가 실패했습니다. 이런 메시지를 보고 정확히 뭐가 잘못되었는지 알 수 있는가?
+
+🔗 [**자세히 보기: Include 3 parts in each test name**](./sections/testingandquality/3-parts-in-name.md)
+
+
+
+## ![✔] 4.3 AAA 패턴을 따라 테스트를 구축해라
+
+**핵심요약:** 테스트를 다음 세가지 부분으로 명확히 나누어라: 준비 (arrange), 실행 (act), 표명 (assert). 제일 먼저 테스트를 준비하고, 그 다음 테스트 단위(unit under test)를 실행하고, 마지막은 확인 단계다. 이 구조를 따르는 것은 읽는이가 힘들여 머리를 쓰지 않고도 테스트 설계를 이해할 수 있도록 보장한다.
+
+**그렇게 하지 않을 경우:** 매일 하루종일 주요 코드를 읽는데 시간을 오래 쓰는 것도 모자라 간단해야하는 테스트 부분에도 열심히 머리를 써야 할 것이다.
+
+🔗 [**Read More: Structure tests by the AAA pattern**](./sections/testingandquality/aaa.md)
+
+
+
+## ![✔] 4.4 린터를 사용해서 코드의 문제점을 찾아내라
+
+**핵심요약:** 코드 린터를 사용해서 기본적인 품질을 확인하고 안티패턴을 초기에 찾아내라. 테스트 하기도 전에 먼저 돌리고, pre-commit git-hook으로 추가해서 문제를 검토하고 정정하는 시간을 최소화해라. [3문단](#3-코드-스타일)의 코드 스타일 관례들도 확인해라.
+
+**그렇게 하지 않을 경우:** 안티패턴과 취약한 코드가 상용환경에 넘어갈 수도 있다.
+
+
+
+## ![✔] 4.5 고정적인 공용 테스트 데이터나 seeds는 피하고, 테스트별로 데이타를 붙여라
+
+**핵심요약:** 테스트간의 간섭과 결합도(coupling)를 최소화하고 테스트 흐름을 추론하기 쉽도록 테스트들은 각자 자신만의 DB 행 (row) 집합을 만들어 써야 한다. 테스트가 DB 데이터를 가져오거나 데이터가 존재한다고 간주해야 할 때마다 다른 레코드를 변형시키지 않도록 그 데이터를 직접 추가하여야 한다.
+
+**그렇게 하지 않을 경우:** 실패하는 테스트때문에 전개(deployment)가 중단되었다고 가정해 보자. 이제 팀원들은 소중한 시간을 조사하는데 소모한 뒤 슬픈 결론을 내릴 것이다: 시스템은 잘 작동하지만, 테스트간의 상호 간섭으로 빌드 실패.
+
+🔗 [**자세히 보기: Avoid global test fixtures**](./sections/testingandquality/avoid-global-test-fixture.md)
+
+
+
+## ![✔] 4.6 끊임없이 취약한 dependency를 점검해라
+
+**핵심요약:** Express같은 네임드 dependency도 알려진 취약점이 있다. 이건CI에서 매 빌드마다 호출할 수 있는 🔗 [npm audit](https://docs.npmjs.com/cli/audit)나 🔗 [snyk.io](https://snyk.io)같은 커뮤니티 혹은 상업용 도구를 사용하면 쉽게 해결할 수 있다.
+
+**그렇게 하지 않을 경우:** 전용 도구없이 코드를 취약점 없이 깨끗하게 유지하려면 온라인 출판물들을 항상 유심히 찾아읽어야 한다. 한마디로 노가다.
+
+
+
+## ![✔] 4.7 테스트를 태그하라 (#테스트)
+
+**핵심요약:** 다른 종류의 테스트는 서로 다른 시나리오를 바탕으로 실행해야한다: 빌드 성공유무 테스트(quick smoke)나 IO 입출력이 없는 테스트는 개발자가 파일을 저장하거나 commit 할 때마다 실행하고, 더 포괄적인 단대단 (end-to-end) 테스트는 보통 풀리퀘스트를 제출 할 때마다 실행한다. 이건 테스트를 #cold #api #sanity 와 같은 키워드로 태그해서 원하는 테스트들만 부분적으로 grep 으로 test harness를 검색해서 실행하면 된다. 예를 들면, [모카](https://mochajs.org/)에서 sanity 테스트 그룹만 실행하고 싶다면 이렇게 하면 된다: mocha --grep 'sanity'
+
+**그렇게 하지 않을 경우:** 개발자가 조금씩 코드를 바꿀때마다 DB 쿼리를 한다스씩 보내는 테스트까지 포함해서 전부 실행하면 개발 속도도 느려지고 개발자들도 점점 테스트를 실행하는걸 꺼리게 된다
+
+
+
+## ![✔] 4.8 테스트 범위를 확인하여 안좋은 테스트 패턴을 잡아내라
+
+**핵심요약:** [이스탄불](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc)같은 코드 커버리지 도구가 좋은 이유는 세가지가 있다: 무료이고 (거져먹는거다), 테스트 범위가 줄어드는것을 잡아내주고, 마지막으로 테스트 부조화를 하이라이트한다: 색으로 나타낸 코드 커버리지 리포트를 보다보면 catch 절 같이 테스트 하지 않는 부분들을 알아채기 시작할것이다. (테스트는 보통 경로만 테스트하기에 앱이 에러가 날 경우에는 어떻게 반응하는지는...) 커버리지가 일정 기준 이하로 떨어지면 빌드가 자동으로 실패하게 해라.
+
+**그렇게 하지 않을 경우:** 코드의 상당한 범위가 테스트로 커버되지 않더라도 자동으로 측정되지 않으니 알 길이 없다.
+
+
+
+## ![✔] 4.9 오래되어 뒤떨어진 패키지는 없는지 검사해라
+
+**핵심요약:** 설치된 패키지중 outdated 된 패키지는 없는지 선호하는 도구 (예: 'npm outdated'나 [npm-check-updates](https://www.npmjs.com/package/npm-check-updates))를 써서 확인하고, 심할 경우 빌드가 실패하도록 CI 경로에 이 체크를 주입해라. 이를테면 설치된 패키지가 패치 commit 5개 이상 뒤쳐졌거나 (예: 로컬은 1.3.1버젼인데 repository 버젼은 1.3.8이라던가) 제작자가 deprecated 되었다고 태그하면 빌드를 죽이고 이 버젼을 배포하지 못하게 막아라.
+
+**그렇게 하지 않을 경우:** 제작자가 직접 불안정하다고 태그한 패키지가 프로덕션에서 놀아날 수 있다
+
+
+
+## ![✔] 4.10 프로덕션과 비슷한 환경에서 e2e 테스트를 실행해라
+
+**핵심요약:** 실제 데이터를 쓰는 end to end 테스트는 DB같은 여러 묵직한 서비스에 의존하기에 CI 프로세스의 취약점이었다. 가능한 한 프로덕션과는 최대한 동떨어진 환경을 써라.
+
+**그렇게 하지 않을 경우:** docker-compose 없이는 팀들이 테스트 환경별로 (각 개발자의 컴퓨터 포함) 테스트 DB를 유지하고, 환경에 따라 테스트 결과가 다르게 나오지 않도록 이 모든 DB들을 동기화해야한다.
+
+
+
+## ![✔] 4.11 정적분석도구를 이용해서 refactor를 정기적으로 해라
+
+**핵심요약:** 정적분석도구(static analysis tool)는 코드의 품질을 객관적으로 개선하고 코드 유지를 쉽게 해준다. 코드스멜을 감지하면 CI 빌드가 실패하도록 정적분석도구를 넣어주면 된다. 이게 단순한 린보팅다 나은 주된 이유로는 여러 파일에 걸친 맥락에서 품질을 점검할 수 있다는 점 (예: 중복된 코드 감지), 더 발달된 분석을 할 수 있다는 점 (예: 코드 복잡도), 코드 문제의 전적과 진전을 따라 볼 수 있다는 점이 있다. 쓸만한 도구의 예를 두가지를 들자면 [Sonarqube](https://www.sonarqube.org/) (2,600+ [stars](https://github.com/SonarSource/sonarqube)) 와 [Code Climate](https://codeclimate.com/) (1,500+ [stars](https://github.com/codeclimate/codeclimate))가 있다.
+
+**그렇게 하지 않을 경우:** 아무리 반짝이는 새로나온 라이브러리나 최첨단 기능을 써봤자 코드 품질이 불량하면 버그와 성능은 못고친다
+
+🔗 [**자세히 보기: Refactoring!**](./sections/testingandquality/refactoring.md)
+
+
+
+## ![✔] 4.12 CI 플랫폼은 신중하게 선택해라 (Jenkins vs CircleCI vs Travis vs 나머지)
+
+**핵심요약:** 지속적 통합 플랫폼(CICD)은 품질 관리 도구(예: 테스트, 린트)들을 돌릴 수 있게 플러그인 생태계가 활발해야 한다. 예전에는 대부분의 프로젝트들이 배우기는 어려워도 커뮤니티도 제일 크고 강력한 플랫폼을 가진 [Jenkins](https://jenkins.io/)를 기본으로 썼다. 요즘엔 [CircleCI](https://circleci.com)등의 SaaS 해결책을 쓰는게 훨씬 더 쉬워졌다. 이런 도구들은 인프라 전체를 관리하는 부담 없이도 유연한 CI 경로를 만들 수 있게 해준다. 결국에는 안전성과 빠름의 상호 절충이다 - 조심해서 선택해라.
+
+**그렇게 하지 않을 경우:** 잘 알려지지 않은 중소 솔루션 업체를 쓰다간 흔치 않은 고급 설정을 커스터마이징 해야할 때 막혀버릴 수도 있다. 하지만 반대로, Jenkins를 택하면 인프라를 수축하는데 소중한 시간을 다 빼앗길 수도 있다.
+
+🔗 [**자세히 보기: Choosing CI platform**](./sections/testingandquality/citools.korean.md)
+
+## ![✔] 4.13 미들웨어들은 격리시켜 테스트해라
+
+**핵심요약:** 여러 요청에 걸친 막대한 로직을 미들웨어가 수용하는 경우, 웹 프레임워크 전체를 깨우지 않고 격리 상태로 테스트 할만한 가치가 있다. {req, res, next} 객체들을 스텁(stub)하여 염탐(spy)하면 쉽게 달성할 수 있다.
+
+**그렇게 하지 않을 경우:** Express 미들웨어의 버그 === 거의 모든 요청의 버그
+
+🔗 [**자세히 보기: Test middlewares in isolation**](./sections/testingandquality/test-middlewares.md)
+
+
+
+# `5. 운영환경으로 전환하기`
+
+## ![✔] 5.1. 모니터링
+
+**핵심요약:** 모니터링은 고객이 문제를 발견하기 전에 먼저 발견하는 게임이다. 모니터링에는 분명히 전례가없는 중요성을 부여해야한다. 솔루션에 너무 많은 기능들이 들어가 있을 가능성이 있으므로 확인해야만하는 기본 항목을 내부적으로 정의하고 나서 추가적인 기능들을 살펴보고 필요한 기능들이 모두 들어있는 솔루션을 선택하라. 아래의 'gist'를 클릭하면 솔루션 개요를 볼 수 있다
+
+**그렇게 하지 않을 경우:** 오류 === 고객의 실망. 간단하다
+
+🔗 [**자세히 보기: 모니터링!**](./sections/production/monitoring.md)
+
+
+
+## ![✔] 5.2. 스마트 로깅으로 투명성을 높여라
+
+**핵심요약:** 로그는 디버그 텍스트가 모여있는 의미없는 창고일 수도 있고, 앱의 상태를 대시보드로 볼 수 있도록 만들어 줄 수 있는 유용한 데이터일 수도 있다. 원하는 정보 (예: 오류율, 트랜잭션이 서비스와 서버를 거치는 경로를 따라가기, 기타등등)를 쉽게 추출 할 수 있도록 로그를 어떻게 수집, 저장 및 분석하는지 첫날부터 미리 계획해라.
+
+**그렇게 하지 않을 경우:** 이해하기 힘든 블랙박스가 되어버려서 필요한 정보를 추가하기 위해 모든 로그를 다시 작성하게 될것이다
+
+🔗 [**자세히 보기: Increase transparency using smart logging**](./sections/production/smartlogging.md)
+
+
+
+## ![✔] 5.3. 가능한 모든 것들(예: gzip, SSL)을 reverse proxy에 위임하라
+
+**핵심요약:** Node는 gzip이나 SSL Termination과 같이 CPU 집약적인 작업에 약하다. 이런게 필요할 경우 '실제' 미들웨어 서비스인 nginx, HAproxy 혹은 클라우드 서비스를 사용해야한다
+
+**그렇게 하지 않을 경우:** 불쌍한 싱글 스레드가 어플리케이션의 코어를 처리하는 대신 인프라 작업을 수행하느라 바빠져서 성능이 저하될 것이다
+
+🔗 [**자세히 보기: 가능한 모든 것들(예: gzip, SSL)을 reverse proxy에 위임하라**](./sections/production/delegatetoproxy.md)
+
+
+
+## ![✔] 5.4. 의존성을 잠궈라(Lock dependencies)
+
+**핵심요약:** 코드는 모든 환경에서 동일해야하지만 놀랍게도 npm을 사용하면 기본적으로 환경간에 종속성이 달라질 수 있는데, 다양한 환경에서 패키지를 설치하면 패키지의 최신 패치 버전을 가져오기 때문이다. npm config 파일인 .npmrc를 사용하여이 문제를 극복해라. 각 환경에 각 패키지의 최신 버전이 아닌 정확한 버전을 저장하도록 알려준다. 또는 세밀하게 제어하려면 `npm shrinkwrap`을 사용하라. \* 업데이트 : NPM5부터는 종속성이 기본적으로 잠겨 있다. 새로운 패키지 관리자인 Yarn도 기본적으로 잠겨 있다.
+
+**그렇게 하지 않을 경우:** QA팀은 코드를 철저히 테스트 했음에도 테스트 환경과는 다르게 작동하는 버전을 승인할 것이다. 심지어 같은 프로덕션 클러스터의 여러 서버가 서로 다른 코드를 실행할 수도 있다.
+
+🔗 [**자세히 보기: Lock dependencies**](./sections/production/lockdependencies.md)
+
+
+
+## ![✔] 5.5. 올바른 도구를 이용해 프로세스 가동시간을 사수해라
+
+**핵심요약:** 프로세스는 계속 진행되어야 하며 실패시 다시 시작해야한다. 간단한 시나리오의 경우 PM2와 같은 프로세스 관리 도구로도 충분하지만 오늘날 '도커화 된' 세계에서는 클러스터 관리 도구도 고려해야한다
+
+**그렇게 하지 않을 경우:** 명확한 전략없이 수십 개의 인스턴스와 너무 많은 도구 (클러스터 관리, 도커, PM2)를 실행하면 데브옵스가 혼란을 겪을 수 있다
+
+🔗 [**자세히 보기: Guard process uptime using the right tool**](./sections/production/guardprocess.md)
+
+
+
+## ![✔] 5.6. 모든 CPU를 활용하라
+
+**핵심요약:** 기본적으로 Node 어플리케이션은 하나의 CPU 코어에서 실행되고 다른 CPU는 동작하지 않는다. 노드 프로세스를 복제하여 모든 CPU를 활용하는 것은 당신의 몫이다. 중소형 어플리케이션의 경우 노드 클러스터 또는 PM2를 사용하면 된다. 더 큰 앱의 경우 Docker 클러스터(예: K8S, ECS) 또는 Linux 초기화 시스템(예: systemd)을 기반으로하는 배포 스크립트를 사용하여 프로세스를 복제하는 것이 좋다
+
+**그렇게 하지 않을 경우:** 앱이 사용 가능한 리소스 중 25%(!)에도 못 미치게 활용할 것이다. 일반적인 서버는 CPU 코어가 4개 이상임에도 Node를 기본형으로 배포하면 그 중 단 1 개만 사용하게 될것이다 (AWS beanstalk과 같은 PaaS 서비스 사용해도 마찬가지)
+
+🔗 [**자세히 보기: 모든 CPU를 활용하라**](./sections/production/utilizecpu.md)
+
+
+
+## ![✔] 5.7. ‘유지 관리용 엔드 포인트’를 따로 만들어라
+
+**핵심요약:** 보안적으로 안전한 API에서 메모리 사용 및 REPL 등과 같은 시스템 관련 정보를 노출하라. 표준 및 실전 테스트(battle-tests) 도구를 사용하는 것이 좋기는 하지만 몇몇 유용한 정보와 작업은 코드를 통해 쉽게 수행 할 수 있다
+
+**그렇게 하지 않을 경우:** 단지 서버 진단을 목적으로 일부 정보를 추출하기 위하여 상용서버에 코드를 배포하는 "진단용 배포"를 자주 수행하고 있게 될 것이다
+
+🔗 [**자세히 보기: Create a ‘maintenance endpoint’**](./sections/production/createmaintenanceendpoint.md)
+
+
+
+## ![✔] 5.8. APM을 사용하여 오류 및 가동 중지 시간을 발견하라
+
+**핵심요약:** 어플리케이션 성능 관리 제품(Application Performance Management, APM)은 코드베이스 및 API를 사전에 측정하여 기존 모니터링 시스템을 뛰어 넘어 서비스 및 계층 전반에서 사용자 경험을 측정한다. 예를 들어 일부 APM 제품은 최종 사용자 측면에서 느리게 로드되는 트랜잭션을 강조 표시 하면서 근본 원인을 제시할 수 있다
+
+**그렇게 하지 않을 경우:** API 성능 및 가동 중지 시간을 측정하는 데 많은 노력을 기울임에도 실전에서 가장 느린 코드 부분이 어느것인지, 그리고 이것이 UX에 미치는 영향을 알지 못할 것이다
+
+🔗 [**자세히 보기: Discover errors and downtime using APM products**](./sections/production/apmproducts.md)
+
+
+
+## ![✔] 5.9. 당신의 코드는 언제든 상용에 배포될수 있다
+
+**핵심요약:** 첫날부터 끝을 염두에두고 코드를 작성하라. 다소 모호하게 들릴것 같아서 상용 유지 보수와 밀접하게 관련된 몇 가지 개발 팁을 편찬해 두었다 (아래의 gist를 클릭하라)
+
+**그렇게 하지 않을 경우:** 세계 최고의 IT/DevOps 전문가도 형편없이 쓰여진 코드로 이루어진 시스템은 구하지 못한다
+
+🔗 [**자세히 보기: Make your code production-ready**](./sections/production/productioncode.md)
+
+
+
+## ![✔] 5.10. 메모리 사용량을 측정하고 보호해라
+
+**핵심요약:** Node.js는 메모리와 관련하여 논란의 여지가 있다: v8 엔진은 메모리 사용량 (1.4GB)에 대한 제한이 있으며 노드의 코드에서 메모리 누수가 발생하는 알려진 방법이 존재하므로 노드의 프로세스 메모리를 관찰하는 것이 필수적이다. 작은 응용 프로그램에서는 Shell 명령을 사용하여 주기적으로 메모리를 측정 할 수 있지만 중대형 어플리케이션에서는 강력한 모니터링 시스템을 통해 메모리를 감시하는 것을 고려하라
+
+**그렇게 하지 않을 경우:** [월마트](https://www.joyent.com/blog/walmart-node-js-memory-leak)에서 일어났던 것처럼 메모리가 하루에 수백 메가바이트씩 누수 될 수 있다
+
+🔗 [**자세히 보기: 메모리 사용량 측정 및 보호**](./sections/production/measurememory.md)
+
+
+
+## ![✔] 5.11. Node.js에서 프론트 엔드 자산을 빼라
+
+**핵심요약:** Node는 단일 스레드 모델을 쓰기 때문에 정적 파일을 많이 처리하게 되면 성능이 많이 저하되기 때문에 전용 미들웨어(nginx, S3, CDN 등)를 사용하여 프론트 엔드 컨텐츠를 제공하는게 좋다
+
+**그렇게 하지 않을 경우:** 단일 노드 스레드는 수백 개의 html/이미지/angular/react 파일을 스트리밍 하느라 바빠서 정작 천직인 동적 컨텐츠를 전달하는 작업에는 신경쓸 겨를이 없을것이다.
+
+🔗 [**자세히 보기: Get your frontend assets out of Node**](./sections/production/frontendout.md)
+
+
+
+## ![✔] 5.12. 무상태(stateless)로 운영하고, 거의 매일 서버를 재부팅하라
+
+**핵심요약:** 어떤 유형의 데이터(예: 유저 세션, 캐시, 업로드된 파일)든 외부 데이터 저장소에 저장하라. 서버를 주기적으로 재부팅/교체하는 것을 고려하거나 명시적으로 무상태로 운영하게 만드는 Serverless 플랫폼(예: AWS Lambda)을 사용하는 것을 고려하라
+
+**그렇게 하지 않을 경우:** 해당서버에 오류가 발생하면 해당 서버만 제거하면 되는 것이 아니라 어플리케이션의 다운타임이 발생하게된다. 게다가 특정 서버에 의존하기 때문에 수평적 확장이 힘들어질 것이다
+
+🔗 [**자세히 보기: Be stateless, kill your Servers almost every day**](./sections/production/bestateless.md)
+
+
+
+## ![✔] 5.13. 취약점을 자동으로 탐지하는 도구를 사용해라
+
+**핵심요약:** Express와 같은 가장 신뢰할만한 모듈조차도 시스템을 위험에 빠뜨릴 수있는 알려진 취약점이 존재한다. 이는 취약성을 지속적으로 (로컬 또는 GitHub에서) 확인하고 경고하는 커뮤니티 및 상용 도구를 사용하면 쉽게 길들일 수 있으며 일부는 즉시 패치 할 수도 있다
+
+**그렇게 하지 않을 경우:** 전용 도구없이 취약점으로부터 코드를 깨끗하게 유지하려면 새로운 취약점에 대한 데이터를 지속적으로 확인해야 할것이다
+
+🔗 [**자세히 보기: Use tools that automatically detect vulnerabilities**](./sections/production/detectvulnerabilities.md)
+
+
+
+## ![✔] 5.14. 로깅을 할때 트랜잭션 ID를 할당하라
+
+**핵심요약:** 하나의 요청 내에서 각 로그에 동일한 식별자(transaction-id: {some value})를 할당하라. 그렇게하면 로그를 분석할때 에러 전과 후에 어떤 일이 생겼는지 쉽게 알수있다. 비동기적인 특성때문에 Node.js에서 구현하기 쉽지는 않다. 아래의 예제를 확인하라
+
+**그렇게 하지 않을 경우:** 이전에 어떤일이 일어났는지에 대한 컨텍스트 없이 에러 로그를 확인하는 것은 문제를 해결하는 것을 더 어렵고 느리게 만든다
+
+🔗 [**자세히 보기: Assign ‘TransactionId’ to each log statement**](./sections/production/assigntransactionid.md)
+
+
+
+## ![✔] 5.15. `NODE_ENV=production`로 설정하라
+
+**핵심요약:** 상용 최적화가 활성화 되어야하는지 아닌지를 표시하기 위해 `NODE_ENV`를 'production' 혹은 'development'로 설정하라. 많은 npm 패키지가 현재 환경을 확인하고 최적화한다
+
+**그렇게 하지 않을 경우:** 이 단순한 속성을 빠뜨리면 성능이 크게 저하된다. 예를 들어 Express에서 서버 사이드 렌더링(Server Side Rendering, SSP)을 사용할때 `NODE_ENV`를 빠뜨리면 3배 느려진다
+
+🔗 [**자세히 보기: Set NODE_ENV=production**](./sections/production/setnodeenv.md)
+
+
+
+## ![✔] 5.16. 원자성의 자동화된 무중단 배포를 설계하라
+
+**핵심요약:** 연구 결과에 따르면 자주 배포를 하는 팀이 상용버전에서 심각한 에러가 발생할 가능성을 낮춘다고 한다. 위험이 따르는 수동적인 과정과 서비스 다운타임이 필요하지 않은 빠르고 자동화된 배포는 배포 프로세스를 크게 향상시킨다. 간소화된 배포의 표준이 된 Docker와 CI 도구를 결합하여 이를 달성할 수 있다.
+
+**그렇게 하지 않을 경우:** 오래걸리는 배포 작업 -> 상용버전 중지시간 및 사람에 의한 에러 -> 배포를 하는 것에 자신감이 없어진 팀 -> 더 적은 배포와 기능들
+
+
+
+## ![✔] 5.17. Node.js의 LTS 릴리즈 버전을 사용해라
+
+**핵심요약:** LTS 버전의 Node.js를 사용하여 중요한 버그 수정, 보안 업데이트 및 성능 향상을 받아라
+
+**그렇게 하지 않을 경우:** 새로 발견된 버그나 취약점이 상용에서 운영중인 어플리케이션을 악용하는데 사용될 수 있으며, 다양한 모듈들에서 지원을 하지 않게 되고 유지보수하는 것이 힘들어 지게될것이다
+
+🔗 [**자세히 보기: Use an LTS release of Node.js**](./sections/production/LTSrelease.md)
+
+
+
+## ![✔] 5.18. 앱 내에서 로그를 라우팅하지 말라
+
+**핵심요약:** 로그의 목적지는 개발자가 어플리케이션 코드에 하드코딩해서는 안되고, 대신 프로그램이 실행되는 실행환경에서 정의되어야 한다. 개발자는 로거 유틸리티를 이용하여 로그를 `stdout`에 작성하고 상용환경(컨테이너, 서버 등)이 해당 `stdout`스트림을 적절한 목적지(즉 Splunk, Graylog, ElasticSearch 등)로 수송해야한다
+
+**그렇게 하지 않을 경우:** 어플리케이션 로그 라우팅 처리 === 확장성 저하, 로그 유실, 관심사의 분리 실패(Separation of Concerns, SoC)
+
+🔗 [**자세히 보기: Log Routing**](./sections/production/logrouting.md)
+
+
+
+## ![✔] 5.19. `npm ci`로 패키지를 설치해라
+
+**핵심요약** 상용환경에서 쓰는 코드가 테스트할떄 쓴 패키지 버젼과 동일하다는 것을 반드시 보장해야 한다. `npm ci`를 써서 의존하는 패키지를 모두 package.json과 package-lock.json만들 따른 클린설치를 해라.
+
+**그렇게 하지 않을 경우:** QA팀이 코드를 승인하기 전에 철저히 테스트해도 상용환경에서는 다르게 작동할것이다. 게다가 같은 프로덕션 클러스터의 다른 서버들이 서로 다른 코드를 실행할 수도 있다.
+
+🔗 [**자세히 보기: npm ci 쓰기**](./sections/production/installpackageswithnpmci.md)
+
+
+
+## ![✔] 6.1. linter 보안 규칙 수용
+
+
+
+**핵심요약:** [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security)와 같은 보안 관련 linter 플러그인을 사용하여 보안 취약점과 문제점을 가능한 한 빨리 잡아라. 이것은 eval 사용, 자식 프로세스 호출, string literal(예: 사용자 입력)을 쓰는 모듈 불러오기 같은 보안 취약점을 잡는데 도움이 될 수 있다. 보안 linter가 잡는 코드를 보려면, 아래의 '자세히 보기'을 클릭해라.
+
+**그렇게 하지 않을 경우:** 개발과정에서는 이해하기 쉬운 보안 약점이었음에도 상용환경에서는 주요쟁점이 된다. 또, 프로젝트가 일관된 보안 프렉티스를 따르지 않아, 취약점이 노출되거나 민감한 정보가 원격 저장소에 유출될 수 있다.
+
+🔗 [**자세히 보기: Lint rules**](./sections/security/lintrules.md)
+
+
+
+## ![✔] 6.2. 미들웨어로 병행연산 (concurrent) 요청들을 제한해라
+
+
+
+**핵심요약:** DOS 서비스 거부 공격은 흔하며 하기에도 비교적 쉽다. 클라우드 로드밸런서, 클라우드 방화벽, nginx, [rate-limiter-flexible](https://www.npmjs.com/package/rate-limiter-flexible) 패키지나, (소규모의 덜 중요한 앱의 경우) 비율제한 미들웨어(예: [express-rate-limit](https://www.npmjs.com/package/express-rate-limit))를 써서 비율제한을 시행해라.
+
+**그렇게 하지 않을 경우:** 애플리케이션이 서비스 거부 공격을 받으면 실제 이용자들이 받는 서비스가 저하되거나 먹통이 된다.
+
+🔗 [**자세히 보기: Implement rate limiting**](./sections/security/limitrequests.md)
+
+
+
+## ![✔] 6.3 기밀은 설정 파일에서 빼거나 패키지를 이용해서 암호화해라
+
+
+
+**핵심요약:** 기밀사항은 절대 평문 형태로 설정 파일이나 소스코드에 저장하지 말아라. 그 대신 Vault나 Kubernetes/Docker Secrets나 환경변수 같은 기밀사항 관리 시스템을 써라. 부득이하게 소스 콘트롤에 기밀사항을 저장해야 하는 경우, 반드시 암호화해서 관리해라 (rolling keys, 만료, 감사 등). pre-commit/push hook을 사용해서 실수로 기밀사항을 버젼 콘트롤에 커밋하는 것을 막아라.
+
+**그렇게 하지 않을 경우:** 비공개 저장소라 하여도 소스 제어가 실수로 공개되면 모든 기밀사항이 그대로 드러난다. 외부관계자가 소스제어에 접근이 가능해지면 의도치 않아도 관련 시스템(데이터베이스, API, 서비스 등)에도 접근을 허락하는것과 마찬가지다.
+
+🔗 [**자세히 보기: Secret management**](./sections/security/secretmanagement.md)
+
+
+
+## ![✔] 6.4. ORM/ODM 라이브러리를 사용해 쿼리 주입 공격을 막아라
+
+
+
+**핵심요약:** SQL/NoSQL 주입과 같은 악의적인 공격을 막기 위해서는 ORM/ODM을 쓰거나, 데이터를 항상 이스케이프 처리 해 주거나 named or indexed parameterized queries를 지지하고, expected data type의 사용자 입력을 확인해주는 데이터베이스 라이브러리를 항상 활용해라. 자바스크립트 템플릿 문자열(template strings)이나 문자열 병합(string concatenation)으로 값을 주입하면 앱을 광범위한 취약점에 노출시키므로 절대 그대로 써서는 안된다. 평판이 좋은 Node.js 데이터 접근 라이브러리들(예: [Sequelize](https://github.com/sequelize/sequelize), [Knex](https://github.com/tgriesser/knex), [mongoose](https://github.com/Automattic/mongoose))은 모두 주입 공격을 막아주는 보호대책이 내장되어있다.
+
+**그렇게 하지 않을 경우:** 확인되지 않거나 (unvalidated) 살균되지 않은 (unsanitized) 사용자 입력은 MangoDB for NoSQL를 쓸 때 operator injection를 초래할 수 있고, 제대로 된 위생처리 시스템이나 ORM을 쓰지 않는것은 SQL 주입 공격을 쉽게 만들어 엄청난 취약점을 만들어낼 수 있다.
+
+🔗 [**자세히 보기: Query injection prevention using ORM/ODM libraries**](./sections/security/ormodmusage.md)
+
+
+
+## ![✔] 6.5. 일반적인 보안 모범사례 모음
+
+**핵심요약:** 이것은 Node.js와는 직접적으로 관련되지 않은 보안과 관련된 조언 모음집이지만, Node의 시행도 다른 언어들과 그닥 다르지 않다. 자세히 보기를 클릭해서 읽어봐라.
+
+🔗 [**자세히 보기: Common security best practices**](./sections/security/commonsecuritybestpractices.md)
+
+
+
+## ![✔] 6.6. HTTP 응답 헤더를 조정해서 보안을 강화해라
+
+
+
+**핵심요약:** 보안 헤더를 사용해서 교차사이트 스트립팅 (XSS), 클릭재킹과 같이 자주 있는 악의적인 공격들을 막아라. [helmet](https://www.npmjs.com/package/helmet)과 같은 모듈을 사용하면 쉽게 설정할 수 있다.
+
+**그렇게 하지 않을 경우:** 공격자들이 애플리케이션 사용자들을 직접적으로 공격할 수 있게되면 엄청난 보안 취약점을 초래할 수 있다
+
+🔗 [**자세히 보기: Using secure headers in your application**](./sections/security/secureheaders.md)
+
+
+
+## ![✔] 6.7. 끊임없이 자동적으로 취약한 의존성은 없는지 검사해라
+
+
+
+**핵심요약:** npm 생태계의 프로젝트들은 의존성이 여럿 있는것이 보통이다. 의존성들은 새로운 취약점들이 발견 될 때마다 고쳐야 한다. [npm audit](https://docs.npmjs.com/cli/audit)이나 [snyk](https://snyk.io/) 같은 도구들을 이용해 취약한 의존성을 감시하고 패치해라. 이런 도구들을 CI 체재와 통합시켜 취약한 의존성이 상용버젼까지 새어 나가기 전에 잡아라
+
+**그렇게 하지 않을 경우:** 공격자가 당신의 웹 프레임워크를 감지하면 알려진 모든 취약점을 공격할 수 있다.
+
+🔗 [**자세히 보기: Dependency security**](./sections/security/dependencysecurity.md)
+
+
+
+## ![✔] 6.8. 암호를 처리할 때는 Node.js의 암호 라이브러리 대신 Bcrypt를 써라
+
+
+
+**핵심요약:** 암호나 기밀사항(API keys)들은 `bcrypt` 같은 보안 해시+솔트 함수를 쓰는것이 자바스크립트 implementation을 쓰는 것보다 보안이나 성능면에서 더 낫다.
+
+**그렇게 하지 않을 경우:** 보안함수(secure function)를 쓰지 않고 저장된 암호나 기밀사항들은 억지기법이나 사전공격에 취약해져 결국엔 다 뚫리게 된다.
+
+🔗 [**자세히 보기: Use Bcrypt**](./sections/security/userpasswords.md)
+
+
+
+## ![✔] 6.9. HTML, JS and CSS 출력은 이스케이프 해라
+
+
+
+**핵심요약:** 신뢰할 수 없는 데이터가 브라우져에 보내져 보여지기만 하는게 아니라 실행이되는것을 교차 사이트 스크립팅 (XSS) 이라고 한다. 데이터를 명백하게 절대 실행되어서는 안되는 콘텐트라고 (즉 엔코딩이라던가 이스케이프한다던가) 표시하는 것 전용 라이브러리를 써서 이것을 완화시켜라
+
+**그렇게 하지 않을 경우:** 공격자가 악의적인 자바스크립트 코드를 당신 DB에 저장하면 불쌍한 클라이언트에게 그대로 보내질 수 있다
+
+🔗 [**자세히 보기: Escape output**](./sections/security/escape-output.md)
+
+
+
+## ![✔] 6.10. 들어오는 JSON 스키마를 검사해라
+
+
+
+**핵심요약:** 들어오는 요청들의 body payload를 검사하여 기대에 부응하지는지 확인하고, 하지 않을경우 실패시켜버려라. [jsonschema](https://www.npmjs.com/package/jsonschema)나 [joi](https://www.npmjs.com/package/joi) 같은 JSON-기반의 경량의 validation schema를 쓰면 성가시게 매 경로마다 검사를 코딩해야 하는 일을 피할 수 있다.
+
+**그렇게 하지 않을 경우:** 입력에 대해 너그럽고 관대하면 공격 받을 수 있는 면적이 넓어지고, 공격자에게 애플리케이션을 끌어내리는 조합을 찾을때까지 다양한 입력값을 시도해보도록 장려하는 꼴이 된다.
+
+🔗 [**자세히 보기: Validate incoming JSON schemas**](./sections/security/validation.md)
+
+
+
+## ![✔] 6.11. JWT 블랙리스트를 지원해라
+
+
+
+**핵심요약:** JSON Web Token(이를테면 [Passport.js](https://github.com/jaredhanson/passport)같은)을 쓰는 경우, 기본적으로 발행된 토큰의 권한을 취소하는 메커니즘은 없다. 사용자가 악의적인 행동을 한다 해도 유효한 토큰이 있는한 막을 길이 없다. 신뢰할 수 없는 토큰 블랙리스트를 만들어 매 요청마다 검사해서 완화시켜라.
+
+**그렇게 하지 않을 경우:** 제삼자가 만료되었거나 부적절한 토큰을 악의적으로 사용하여 애플리케이션에 접근하거나 토큰 소유자인 척 가장할 수 있다.
+
+🔗 [**자세히 보기: Blacklist JSON Web Tokens**](./sections/security/expirejwt.md)
+
+
+
+## ![✔] 6.12. 권한부여 억지기법 공격을 예방해라
+
+
+
+**핵심요약:** 간단하지만 강력한 테크닉은 다음 두가지를 측량하여 권한부여 (authorization) 시도를 제한하는 것이다:
+
+1. 첫째는 같은 사용자의 고유 아이디/이름과 IP주소로부터의 연이은 실패 시도 갯수
+2. 두번째는 오랜 시간 동안 같은 IP 주소에서부터의 실패 시도 갯수. 예를 들면, 같은 IP 주소로부터 하루 사이 실패 시도가 100개라면 차단해버려라.
+
+**그렇게 하지 않을 경우:** 공격자가 무제한으로 암호를 시도해서 특권있는 계좌에 접근할 수 있다
+
+🔗 [**자세히 보기: Login rate limiting**](./sections/security/login-rate-limit.md)
+
+
+
+## ![✔] 6.13. Node.js를 루트가 아닌 사용자로써 실행하라
+
+
+
+**핵심요약:** Node.js가 승인에 제한이 없는 루트 사용자로써 실행하는 일이 비일비재하다. 예를 들면, 도커 컨테이너 안에서는 이것이 기본적인 설정이다. 루트가 아닌 사용자를 만들어 도커 이미지에 구워넣거나 (아래예시) 프로세스를 "-u username" 플래그를 써서 이 사용자를 대신해서 실행하는것을 추천한다.
+
+**그렇게 하지 않을 경우:** 공격자가 서버에 스크립트를 실행하는데 성공하면 로컬 머신을 마음대로 할 권리를 무제한으로 갖게 된다 (예: iptable을 바꾼다던가 트래픽 경로를 자기 서버로 변경 한다던가)
+
+🔗 [**자세히 보기: Run Node.js as non-root user**](./sections/security/non-root-user.md)
+
+
+
+## ![✔] 6.14. 리버스 프록시나 미들웨어를 사용해서 페이로드 크기를 제한해라
+
+
+
+**핵심요약:** 페이로드 사이즈가 클수록, 단일 스레드가 이것을 처리하는데 더 열심히 일해야 한다. 이것은 공격자들이 엄청난 양의 요청(DOS/DDOS 공격)을 쓰지 않고도 서버를 끌어내릴 수 있는 기회를 제공한다. 가장자리(예: 방화벽, ELB)에서 들어오는 요청들의 바디 크기를 제한하거나, 소규모의 페이로드만 받아들이도록 [express body parser](https://github.com/expressjs/body-parser)를 설정해라
+
+**그렇게 하지 않을 경우:** 애플리케이션이 커다란 요청을 처리해야하면 다른 중요한 일을 완수할 수 없게 되어 성능이 영향을 받고 DOS 공격에 취약하게 된다
+
+🔗 [**자세히 보기: Limit payload size**](./sections/security/requestpayloadsizelimit.md)
+
+
+
+## ![✔] 6.15. 자바스크립트 eval statement를 피하라
+
+
+
+**핵심요약:** `eval`은 임의적인 자바스크립트 코드를 런타임시 실행하는것을 허용하기에 사악하다. 이는 성능면에서 문제가 될 뿐 아니라 사용자 입력을 근원으로 한 악의적인 자바스크립트 코드 때문에 보안면에서도 문제가 된다. 피해야 할 또다른 언어 특색으로는 `new Function` constructor 생성자가 있다. `setTimeout`와 `setInterval` 또한 절대로 동적이 자바스크립트 코드를 주어서는 안된다.
+
+**그렇게 하지 않을 경우:** 악의적인 자바스크립트 코드가 `eval`같이 실시간으로 평가하는 자바스크립트 언어 함수에 넘어가면 페이지 안의 자바스크립트 승인을 완전히 장악하게 된다. 이 취약점은 XSS 공격 형태로 자주 나타난다.
+
+🔗 [**자세히 보기: Avoid JavaScript eval statements**](./sections/security/avoideval.md)
+
+
+
+## ![✔] 6.16. 악성 정규표현(RegEx)이 단일 스레드 실행을 과부하시키는것을 막아라
+
+
+
+**핵심요약:** 정규표현은 유용하긴 하지만 자바스크립트 애플리케이션, 특히나 Node.js 플랫폼의 경우 전체적으로 위협을 가한다. 사용자 입력 텍스트를 비교하여 처리하는데는 엄청난 양의 CPU 사이클이 요구된다. 단어 10개를 검사하는 단 하나의 요청이 이벤트 루프 전체를 6초동안 정체시키고 CPU를 🔥지를 만큼 RegEx 처리는 비효율적이다. 이 때문에,직접 정규표현 패턴을 작성하기 보다는 [validator.js](https://github.com/chriso/validator.js) 같은 써드파티 검사 패키지를 쓰거나, [safe-regex](https://github.com/substack/safe-regex)를 써서 취약한 정규표한 패턴을 감지해라
+
+**그렇게 하지 않을 경우:** 저조하게 쓰여진 정규표현들은 이벤트 루프를 완전히 정체시킬 수 있는 정규표현 DOS 공격에 취약해진다. 예를들면, 자주 쓰이는 `moment` 패키지 또한 2017년 11월에 악성 정규표현 사용에 취약하다는 것이 발견되었다
+
+🔗 [**자세히 보기: Prevent malicious RegEx**](./sections/security/regex.md)
+
+
+
+## ![✔] 6.17. 변수를 사용해 모듈을 로딩하는것을 피해라
+
+
+
+**핵심요약:** 매개변수가 사용자 입력이 원천지일 염려가 있으므로 다른 파일을 파라메터 형태의 경로로 require/import 하는것은 피해라. 이건 일반적으로 사용자 입력을 원천지로 한 다른 동적 변수로 파일이나 (즉 `fs.readFile()`) 다른 민감한 리소스에 접근할 때도 해당한다. [Eslint-plugin-security](https://www.npmjs.com/package/eslint-plugin-security) 린터를 쓰면 이런 패턴들을 초반에 잡아내어 경고해준다
+
+**그렇게 하지 않을 경우:** 악의적인 사용자 입력이 이전에 파일시스템에 업로드되었거나 이미 시스템에 존재하는 흑화된 파일을 require 하는데 쓰이는 매개변수로 들어가게 될 수 있다.
+
+🔗 [**자세히 보기: Safe module loading**](./sections/security/safemoduleloading.md)
+
+
+
+## ![✔] 6.18. 위험한 코드는 샌드박스 안에서 실행해라
+
+
+
+**핵심요약:** 런타임에 주어진 외부 코드(예: 플러그인)를 실행해야 하는 경우, 메인 코드를 플러그인으로부터 격리시켜 보호하는 샌드박스 실행 환경을 무엇이든 써라. 전용 프로세스나 (예: `cluster.fork()`), 서버리스 환경이나 샌드박스 역할을 하는 전용 npm 패키지를 사용하면 달성할 수 있다.
+
+**그렇게 하지 않을 경우:** 플러그인이 무한 루프나, 메모리 과부화나, 민감한 프로세스 환경 변수로의 접근과 같이 무한히 가지각색으로 공격할 수 있다
+
+🔗 [**자세히 보기: Run unsafe code in a sandbox**](./sections/security/sandbox.md)
+
+
+
+## ![✔] 6.19. 자식 프로세스를 다룰 땐 특히 조심해라
+
+
+
+**핵심요약:** 자식 프로세스를 쓰는것은 가능한 한 피하고, 부득이하게 써야 한다면 입력은 검사하고 무결처리해서 shell 주입 공격을 완화시켜라. 정의상 속성 집합이 있는 단일 명령어만 수행하고 shell 매개변수 확장을 허가하지 않는 `child_process.execFile` 쓰는것을 선호해라.
+
+**그렇게 하지 않을 경우:** 순진무구하게 자식 프로세스를 썼다가는 악의적인 사용자 입력이 무결처리 되지 않은 시스템 명령어로 인한 원격 커맨드 실행이나 쉘 주입 공격을 초래할 수 있다.
+
+🔗 [**자세히 보기: Be cautious when working with child processes**](./sections/security/childprocesses.md)
+
+
+
+## ![✔] 6.20. 에러 세부사항은 클라이언트로부터 숨겨라
+
+
+
+**핵심요약:** 통합된 express 에러 핸들러는 기본적으로 에러 세부사항을 감춘다. 허나, 당신이 커스텀 에러 처리 로직을 만들어 쓰고 있을 가능성이 높다 (많은이들이 이게 모범사례라고 여긴다). 그럴 경우 민감한 애플리케이션 세부사항을 포함할 수 있는 에러 객체를 절대로 통째로 클라이언트에 보내주지 않도록 해라
+
+**그렇게 하지 않을 경우:** 서버 파일 경로나, 사용중인 제삼자 모듈, 그리고 그 외 애플리케이션 내부 작업 순서 같이 공격자가 악용할 수 있는 민감한 애플리케이션 세부사항이 스택트레이스에 보여지는 정보로 새어나갈 수 있다
+
+🔗 [**자세히 보기: Hide error details from client**](./sections/security/hideerrors.md)
+
+
+
+## ![✔] 6.21. npm이나 yarn 이중인증(2FA)을 설정해라
+
+
+
+**핵심요약:** 개발 과정의 모든 단계는 다중인증(MFA: multi-factor authentication)을 사용해서 보호해야한다. npm이나 Yarn은 공격자들이 개발자 암호를 수집할 수 있는 절호의 기회다. 공격자들은 개발자의 크리덴셜을 사용하면 악의적인 코드를 다양한 프로젝트와 서비스에 널리 설치된 라이브러리에 주입할 수 있다. 공개 출판 되었다면 웹상에서도 가능하다. npm 이중인증을 활성화 해 두면 공격자들이 패키지 코드를 변경할 확률이 0에 가까워진다.
+
+**그렇게 하지 않을 경우:** [암호를 하이재킹 당한 eslint 개발자에 대해 들어봤는가?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
+
+
+
+## ![✔] 6.22. 세션 미들웨어 설정을 수정해라
+
+
+
+**핵심요약:** 웹 프레임워크나 장비는 각각 고유의 약점이 있다-공격자에게 어떤 웹 프레임워크를 쓰는지 알려주는 것은 그들을 돕는 꼴이 된다. 세션 미들웨어 기본설정을 쓰는 것은 `X-Powered-By` 헤더같이 모듈이나 프레임워크 관련 하이재킹 공격에 앱이 취약해지게 만든다. 테크 스택의 신분(예: Node.js, express)을 드러내는 것은 일단 감추고 봐라
+
+**그렇게 하지 않을 경우:** 쿠키가 insecure 연결로 송신되면 공격자가 세션 ID를 보고 웹 어플리케이션 프레임워크를 식별하고, 모듈관련 취약점도 찾아낼 수 있다
+
+🔗 [**자세히 보기: Cookie and session security**](./sections/security/sessions.md)
+
+
+
+## ![✔] 6.23. 프로세스가 언제 충돌해야 하는지 명백히 해서 DOS 공격을 피해라
+
+
+
+**핵심요약:** Node 프로세스는 에러가 처리되지 않으면 충돌한다. 많은 모범사례들이 에러를 받아 처리했음에도 exit 하는것을 권장한다. Express로 예를 들자면, 비동기 에러가 발생한 경우, route를 catch clause로 감싸지 않는 한 항상 충돌로 이어진다. 이건 어떤 입력이 프로세스를 충돌시키는지 아는 공격자들이 같은 요청을 계속 보내는 공격을 할 수 있게 만들어 버린다. 이것을 바로 고칠 수 있는 방안은 없지만, 통증을 완화시킬 수 있는 방법이 몇 개 존재한다: 프로세스가 처리되지 않은 에러로 인해 충돌할 때마다 치명적인 심각성으로 경보를 발하고, 입력을 검사하며 무효한 사용자 입력으로 인한 충돌을 피하고, 모든 route들을 catch로 감싸고, 에러의 원인지가 요청이면 충돌하지 않는것을 고려해라 (에러가 global하게 나는것과 반대로)
+
+**그렇게 하지 않을 경우:** 경험에서 우러난 추측이긴 하지만: Node.js 애플리케이션이 여럿 있을때, 모든 POST 요청에 빈 JSON body를 붙여 보내면 그중 애플리케이션이 몇 개 충돌한다. 그 시점으로부터는 계속 같은 요청을 보내면 나머지 애플리케이션들을 쉽게 흐너뜨릴 수 있다.
+
+
+
+## ![✔] 6.24. 위험한 리디렉트는 막아라
+
+
+
+**핵심요약:** 사용자 입력을 검사하지 않는 리디렉트는 공격자가 피싱 사기나 사용자 자격 절도와 같이 악의적인 공격을 할 수 있게 한다.
+
+**그렇게 하지 않을 경우:** 공격자가 당신이 외부 유저로부터 조달된 입력을 검사하지 않는다는 것을 발견 할 경우, 특수 조작된 포럼 링크를 포럼이나 소셜 미디어, 그 외 공공 장소에 게재해서 유저들이 클릭하도록 해서 이 취약점을 악용할 수 있다.
+
+🔗 [**자세히 보기: Prevent unsafe redirects**](./sections/security/saferedirects.md)
+
+
+
+## ![✔] 6.25. 기밀사항을 npm registry에 출판하는것을 막아라
+
+
+
+**핵심요약:** 공공 npm 레지스트리에 기밀사항을 실수로 발행하는 것을 미리 예방해라. `.npmignore` 파일을 사용해서 특정 파일이나 폴더를 블랙리스트하거나, `package.json` 안의 `files` 배열이 화이트리스트 역할을 할 수 있다.
+
+**그렇게 하지 않을 경우:** 프로젝트의 API key나, 암호나, 그 외 기밀사항들이 이것들을 우연히 발견한 이들 누구나에 의해 남용되면 재정적 손실이나 사칭과 같은 위험을 초래할 수 있다.
+
+🔗 [**자세히 보기: Avoid publishing secrets**](./sections/security/avoid_publishing_secrets.md)
+
+
+## ![✔] 7.1. 이벤트 루프를 막지 말아라
+
+**핵심요약:** CPU 집약적인 과제들은 거의 단일 스레드로 된 이벤드 루프를 블로킹하고 전용 스레드나 프로세스, 혹은 컨텍스트에 따라 그 외 다른 기술에 떠넘기므로 피하라.
+
+**그렇게 하지 않을 경우:** 이벤트 루프가 블로킹되면 Node.js는 다른 요청을 처리할 수 없게 되어 동시성 (concurrent) 사용자들을 지체하게 한다. **사용자 3000명이 응답을 기다리고 있고, 콘텐츠도 제공될 준비가 되어있는데, 단 하나의 요청이 서버가 결과물을 발송하지 못하도록 블로킹 할 수 있다**
+
+🔗 [**자세히 보기: Do not block the event loop**](./sections/performance/block-loop.md)
+
+
+
+## ![✔] 7.2. Lodash같은 user-land 유틸 대신 네이티브 자바스크립트 메소드를 택해라
+
+**핵심요약:** 네이티브 메소드 대신 `lodash` 나 `underscore` 같은 유틸 라이브러리를 쓰는 것은 불필요한 의존성이나 성능 저하를 야기할 수 있기에 보통 페날티가 붙는다.
+새로운 V8 엔진과 함께 새로운 ES 기준이 도입되고부터 네이티브 메소드가 유틸리티 라이브러리보다 50% 더 능률적이라는 것을 명심해라.
+
+**그렇게 하지 않을 경우:** 기본적으로 **이미** 내장된 코드를 쓰거나 코드를 몇줄 더 써서 파일을 몇개 더 써야 하는 것을 막을 수 있었음에도 불구하고 더 비능률적인 프로젝트를 유지해야 할 것이다.
+
+🔗 [**자세히 보기: Native over user land utils**](./sections/performance/nativeoverutil.md)
+
+
+
+# 마일스톤
+
+이 가이드를 관리하고 최신 버전을 유지하기 위해, 우리는 지속해서 가이드라인과 모범 사례들을 커뮤니티의 도움으로 업데이트하고 개선해 나가고 있습니다. [마일스톤](https://github.com/goldbergyoni/nodebestpractices/milestones)을 확인하시고 이 프로젝트에 기여하고 싶다면 작업중인 그룹에 참여하세요!
+
+
+
+## 번역
+
+모든 번역은 커뮤니티에 의해 기여되고 있습니다. 이미 완성된 번역이나, 진행중, 새로운 번역에 대한 도움은 언제나 환영합니다!
+
+### 번역 작업 완료
+
+-  [브라질식 포르투갈어](./README.brazilian-portuguese.md) - [마르셀로 멜로](https://github.com/marcelosdm) 제공
+-  [중국어](./README.chinese.md) - [맷 진](https://github.com/mattjin) 제공
+-  [러시아어](./README.russian.md) - [알렉스 이바노브](https://github.com/contributorpw) 제공
+
+### 번역 작업중
+
+-  [프랑스어](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  히브리어 ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [한국어](README.korean.md) - [한상범](https://github.com/uronly14me) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/94)) 제공
+-  [스페인어](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  터키어 ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/139))
+
+
+
+## 운영 위원회
+
+프로젝트를 지도하고 앞으로 나아갈 방향을 제시하는데 함께 일하는 운영 위원회 일원들을 소개합니다. 추가로, 위원회원들은 각자 [Github 프로젝트](https://github.com/goldbergyoni/nodebestpractices/projects) 아래에 인행되는 프로젝트들을 인솔합니다.
+
+
+
+[요니 골드버그](https://github.com/goldbergyoni)
+
+
+
+미국, 유럽과 이스라엘의 고객들과 대규모 Node.js 애플리케이션 건축하는데 일하는 독립적인 Node.js 컨설턴트입니다. 모범사례 중 다수는 [goldbergyoni.com](https://goldbergyoni.com)에 처음 게재되었던 것들입니다. [@goldbergyoni](https://github.com/goldbergyoni)나 [me@goldbergyoni.com](mailto:me@goldbergyoni.com)로 요니에게 연락하세요.
+
+
+
+
+
+[브루노 슈플러](https://github.com/BrunoScheufler)
+
+
+💻 풀스택 웹 엔지니어, Node.js & GraphQL 광팬
+
+
+
+
+
+[카일 마틴](https://github.com/js-kyle)
+
+
+
+뉴질랜드에 거주하는 풀스택 개발자 & 사이트 신뢰성 엔지니어이며, 웹 애플리케이션 보안과 글로벌한 규모에서 수행하는 Node.js 애플리케이션을 설계하고 건축하는데 관심이 있습니다.
+
+
+
+
+
+[사기르 칸](https://github.com/sagirk)
+
+
+
+
+웹 플랫폼을 사용해 세계적으로 유명한 브랜드들을 위한 상품을 만드는 자바스크립트 및 생태계 (React, Node.js, MongoDB 외 시스템 어느 계층에서건 자바스크립트/JSON 사용과 관련된 것은 어떤것이든) 전문가 입니다. Node.js 단체의 개인 일원이며, 공동체 위원회의 웹사이트 재설계 계획에 협력하고 있습니다.
+
+
+
+## 공동 저자
+
+모든 공동 저자 분들께 감사드립니다! 🙏
+
+공동 저자들은 새로운 모범사례를 제안하거나, 사안을 분류하거나, 풀리퀘스트를 검토하는 등 리포지토리에 정기적으로 기여하는 일원들입니다. 수천명의 사람들이 더 나은 Node.js 애플리케이션을 만들 수 있도록 안내하며 돕는데 관심이 있으시다면 [기여자 지침서](./.operations/CONTRIBUTING.md)를 읽어주세요 🎉
+
+| | | |
+| :---------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------: |
+| [이도 릭터 (창립주)](https://github.com/idori) | [키스 홀리데이](https://github.com/TheHollidayInn) | [케빈 브뤼예르](https://github.com/kevynb) |
+
+### 전 공동 저자
+
+| |
+| :-------------------------------------------------------------------------------------------------------------------------: |
+| [Refael Ackermann](https://github.com/refack) |
+
+
+
+## 기여하기
+
+오픈소스에 참여하고 싶으시다면 지금이 바로 기회! [기여자 지침서](.operations/CONTRIBUTING.md)에서 더 자세한 내용을 확인하세요.
+
+## 기여자 ✨
+
+이 리포지터리에 기여해 주신 여기 이 모든 분께 감사드립니다!
+
+
+
+
+
-[](https://twitter.com/nodepractices/) **Follow us on Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
+[](https://twitter.com/nodepractices/) **Follow us on Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
-Read in a different language: [**CN**](/README.chinese.md), [**BR**](/README.brazilian-portuguese.md), [**RU**](/README.russian.md) [(**ES**, **FR**, **HE**, **KR** and **TR** in progress!)](#translations)
+Read in a different language: [**CN**](./README.chinese.md), [**FR**](./README.french.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**PL**](./README.polish.md), [**JA**](./README.japanese.md), [**EU**](./README.basque.md) [(**ES**, **HE**, **KR** and **TR** in progress! )](#translations)
-###### Built and maintained by our [Steering Committee](#steering-committee) and [Collaborators](#collaborators)
+# 🎊 2024 edition is here!
-# Latest Best Practices and News
+- **🛰 Modernized to 2024**: Tons of text edits, new recommended libraries, and some new best practices
-- **✅ New best practice:** 7.1: [Don't block the event loop](#7-draft-performance-best-practices) by Keith Holliday
+- **✨ Easily focus on new content**: Already visited before? Search for `#new` or `#updated` tags for new content only
-- **🇷🇺 Russian translation:** The amazing Alex Ivanov has just published a [Russian translation](/README.russian.md)
-
-- **We seek typescript contributors:** want to help contributing TypeScript examples? please approach by opening an issue
+- **🔖 Curious to see examples? We have a starter**: Visit [Practica.js](https://github.com/practicajs/practica), our application example and boilerplate (beta) to see some practices in action
# Welcome! 3 Things You Ought To Know First
-**1. You are, in fact, reading dozens of the best Node.js articles -** this repository is a summary and curation of the top-ranked content on Node.js best practices, as well as content written here by collaborators
+**1. You are reading dozens of the best Node.js articles -** this repository is a summary and curation of the top-ranked content on Node.js best practices, as well as content written here by collaborators
+
+**2. It is the largest compilation, and it is growing every week -** currently, more than 80 best practices, style guides, and architectural tips are presented. New issues and pull requests are created every day to keep this live book updated. We'd love to see you contributing here, whether that is fixing code mistakes, helping with translations, or suggesting brilliant new ideas. See our [writing guidelines here](./.operations/writing-guidelines.md)
+
+**3. Best practices have additional info -** most bullets include a **🔗Read More** link that expands on the practice with code examples, quotes from selected blogs, and more information
+
+
-**2. It is the largest compilation, and it is growing every week -** currently, more than 80 best practices, style guides, and architectural tips are presented. New issues and pull requests are created every day to keep this live book updated. We'd love to see you contributing here, whether that is fixing code mistakes, helping with translations, or suggesting brilliant new ideas. See our [writing guidelines here](/.operations/writing-guidelines.md)
+# By Yoni Goldberg
-**3. Most best practices have additional info -** most bullets include a **🔗Read More** link that expands on the practice with code examples, quotes from selected blogs and more information
+### Learn with me: As a consultant, I engage with worldwide teams on various activities like workshops and code reviews. 🎉AND... Hold on, I've just launched my [beyond-the-basics testing course, which is on a 🎁 limited-time sale](https://testjavascript.com/) until August 7th
## 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 (12) ](#4-testing-and-overall-quality-practices)
-5. [Going To Production Practices (18) ](#5-going-to-production-practices)
-6. [Security Practices (25)](#6-security-best-practices)
-7. [Performance Practices (2) (Work In Progress️ ✍️)](#7-draft-performance-best-practices)
+
+
+ 1. Project Architecture Practices (6)
+
+
+ [1.1 Structure your solution by components `#strategic` `#updated`](#-11-structure-your-solution-by-business-components)
+ [1.2 Layer your components, keep the web layer within its boundaries `#strategic` `#updated`](#-12-layer-your-components-with-3-tiers-keep-the-web-layer-within-its-boundaries)
+ [1.3 Wrap common utilities as packages, consider publishing](#-13-wrap-common-utilities-as-packages-consider-publishing)
+ [1.4 Use environment aware, secure and hierarchical config `#updated`](#-14-use-environment-aware-secure-and-hierarchical-config)
+ [1.5 Consider all the consequences when choosing the main framework `#new`](#-15-consider-all-the-consequences-when-choosing-the-main-framework)
+ [1.6 Use TypeScript sparingly and thoughtfully `#new`](#-16-use-typescript-sparingly-and-thoughtfully)
+
+
+
+
+
+ 2. Error Handling Practices (12)
+
+
+ [2.1 Use Async-Await or promises for async error handling](#-21-use-async-await-or-promises-for-async-error-handling)
+ [2.2 Extend the built-in Error object `#strategic` `#updated`](#-22-extend-the-built-in-error-object)
+ [2.3 Distinguish operational vs programmer errors `#strategic` `#updated`](#-23-distinguish-catastrophic-errors-from-operational-errors)
+ [2.4 Handle errors centrally, not within a middleware `#strategic`](#-24-handle-errors-centrally-not-within-a-middleware)
+ [2.5 Document API errors using OpenAPI or GraphQL](#-25-document-api-errors-using-openapi-or-graphql)
+ [2.6 Exit the process gracefully when a stranger comes to town `#strategic`](#-26-exit-the-process-gracefully-when-a-stranger-comes-to-town)
+ [2.7 Use a mature logger to increase errors visibility `#updated`](#-27-use-a-mature-logger-to-increase-errors-visibility)
+ [2.8 Test error flows using your favorite test framework `#updated`](#-28-test-error-flows-using-your-favorite-test-framework)
+ [2.9 Discover errors and downtime using APM products](#-29-discover-errors-and-downtime-using-apm-products)
+ [2.10 Catch unhandled promise rejections `#updated`](#-210-catch-unhandled-promise-rejections)
+ [2.11 Fail fast, validate arguments using a dedicated library](#-211-fail-fast-validate-arguments-using-a-dedicated-library)
+ [2.12 Always await promises before returning to avoid a partial stacktrace `#new`](#-212-always-await-promises-before-returning-to-avoid-a-partial-stacktrace)
+ [2.13 Subscribe to event emitters 'error' event `#new`](#-213-subscribe-to-event-emitters-and-streams-error-event)
+
+
+
+
+
+ 3. Code Style Practices (12)
+
+
+ [3.1 Use ESLint `#strategic`](#-31-use-eslint)
+ [3.2 Use Node.js eslint extension plugins `#updated`](#-32-use-nodejs-eslint-extension-plugins)
+ [3.3 Start a Codeblock's Curly Braces on the Same Line](#-33-start-a-codeblocks-curly-braces-on-the-same-line)
+ [3.4 Separate your statements properly](#-34-separate-your-statements-properly)
+ [3.5 Name your functions](#-35-name-your-functions)
+ [3.6 Use naming conventions for variables, constants, functions and classes](#-36-use-naming-conventions-for-variables-constants-functions-and-classes)
+ [3.7 Prefer const over let. Ditch the var](#-37-prefer-const-over-let-ditch-the-var)
+ [3.8 Require modules first, not inside functions](#-38-require-modules-first-not-inside-functions)
+ [3.9 Set an explicit entry point to a module/folder `#updated`](#-39-set-an-explicit-entry-point-to-a-modulefolder)
+ [3.10 Use the === operator](#-310-use-the--operator)
+ [3.11 Use Async Await, avoid callbacks `#strategic`](#-311-use-async-await-avoid-callbacks)
+ [3.12 Use arrow function expressions (=>)](#-312-use-arrow-function-expressions-)
+ [3.13 Avoid effects outside of functions `#new`](#-313-avoid-effects-outside-of-functions)
+
+
+
+
+
+ 4. Testing And Overall Quality Practices (13)
+
+
+ [4.1 At the very least, write API (component) testing `#strategic`](#-41-at-the-very-least-write-api-component-testing)
+ [4.2 Include 3 parts in each test name `#new`](#-42-include-3-parts-in-each-test-name)
+ [4.3 Structure tests by the AAA pattern `#strategic`](#-43-structure-tests-by-the-aaa-pattern)
+ [4.4 Ensure Node version is unified `#new`](#-44-ensure-node-version-is-unified)
+ [4.5 Avoid global test fixtures and seeds, add data per-test `#strategic`](#-45-avoid-global-test-fixtures-and-seeds-add-data-per-test)
+ [4.6 Tag your tests `#advanced`](#-46-tag-your-tests)
+ [4.7 Check your test coverage, it helps to identify wrong test patterns](#-47-check-your-test-coverage-it-helps-to-identify-wrong-test-patterns)
+ [4.8 Use production-like environment for e2e testing](#-48-use-production-like-environment-for-e2e-testing)
+ [4.9 Refactor regularly using static analysis tools](#-49-refactor-regularly-using-static-analysis-tools)
+ [4.10 Mock responses of external HTTP services #advanced `#new` `#advanced`](#-410-mock-responses-of-external-http-services)
+ [4.11 Test your middlewares in isolation](#-411-test-your-middlewares-in-isolation)
+ [4.12 Specify a port in production, randomize in testing `#new`](#-412-specify-a-port-in-production-randomize-in-testing)
+ [4.13 Test the five possible outcomes #strategic `#new`](#-413-test-the-five-possible-outcomes)
+
+
+
+
+
+ 5. Going To Production Practices (19)
+
+
+ [5.1. Monitoring `#strategic`](#-51-monitoring)
+ [5.2. Increase the observability using smart logging `#strategic`](#-52-increase-the-observability-using-smart-logging)
+ [5.3. Delegate anything possible (e.g. gzip, SSL) to a reverse proxy `#strategic`](#-53-delegate-anything-possible-eg-gzip-ssl-to-a-reverse-proxy)
+ [5.4. Lock dependencies](#-54-lock-dependencies)
+ [5.5. Guard process uptime using the right tool](#-55-guard-process-uptime-using-the-right-tool)
+ [5.6. Utilize all CPU cores](#-56-utilize-all-cpu-cores)
+ [5.7. Create a ‘maintenance endpoint’](#-57-create-a-maintenance-endpoint)
+ [5.8. Discover the unknowns using APM products `#advanced` `#updated`](#-58-discover-the-unknowns-using-apm-products)
+ [5.9. Make your code production-ready](#-59-make-your-code-production-ready)
+ [5.10. Measure and guard the memory usage `#advanced`](#-510-measure-and-guard-the-memory-usage)
+ [5.11. Get your frontend assets out of Node](#-511-get-your-frontend-assets-out-of-node)
+ [5.12. Strive to be stateless `#strategic`](#-512-strive-to-be-stateless)
+ [5.13. Use tools that automatically detect vulnerabilities](#-513-use-tools-that-automatically-detect-vulnerabilities)
+ [5.14. Assign a transaction id to each log statement `#advanced`](#-514-assign-a-transaction-id-to-each-log-statement)
+ [5.15. Set NODE_ENV=production](#-515-set-node_envproduction)
+ [5.16. Design automated, atomic and zero-downtime deployments `#advanced`](#-516-design-automated-atomic-and-zero-downtime-deployments)
+ [5.17. Use an LTS release of Node.js](#-517-use-an-lts-release-of-nodejs)
+ [5.18. Log to stdout, avoid specifying log destination within the app `#updated`](#-518-log-to-stdout-avoid-specifying-log-destination-within-the-app)
+ [5.19. Install your packages with npm ci `#new`](#-519-install-your-packages-with-npm-ci)
+
+
+
+
+
+ 6. Security Practices (25)
+
+
+ [6.1. Embrace linter security rules](#-61-embrace-linter-security-rules)
+ [6.2. Limit concurrent requests using a middleware](#-62-limit-concurrent-requests-using-a-middleware)
+ [6.3 Extract secrets from config files or use packages to encrypt them `#strategic`](#-63-extract-secrets-from-config-files-or-use-packages-to-encrypt-them)
+ [6.4. Prevent query injection vulnerabilities with ORM/ODM libraries `#strategic`](#-64-prevent-query-injection-vulnerabilities-with-ormodm-libraries)
+ [6.5. Collection of generic security best practices](#-65-collection-of-generic-security-best-practices)
+ [6.6. Adjust the HTTP response headers for enhanced security](#-66-adjust-the-http-response-headers-for-enhanced-security)
+ [6.7. Constantly and automatically inspect for vulnerable dependencies `#strategic`](#-67-constantly-and-automatically-inspect-for-vulnerable-dependencies)
+ [6.8. Protect Users' Passwords/Secrets using bcrypt or scrypt `#strategic`](#-68-protect-users-passwordssecrets-using-bcrypt-or-scrypt)
+ [6.9. Escape HTML, JS and CSS output](#-69-escape-html-js-and-css-output)
+ [6.10. Validate incoming JSON schemas `#strategic`](#-610-validate-incoming-json-schemas)
+ [6.11. Support blocklisting JWTs](#-611-support-blocklisting-jwts)
+ [6.12. Prevent brute-force attacks against authorization `#advanced`](#-612-prevent-brute-force-attacks-against-authorization)
+ [6.13. Run Node.js as non-root user](#-613-run-nodejs-as-non-root-user)
+ [6.14. Limit payload size using a reverse-proxy or a middleware](#-614-limit-payload-size-using-a-reverse-proxy-or-a-middleware)
+ [6.15. Avoid JavaScript eval statements](#-615-avoid-javascript-eval-statements)
+ [6.16. Prevent evil RegEx from overloading your single thread execution](#-616-prevent-evil-regex-from-overloading-your-single-thread-execution)
+ [6.17. Avoid module loading using a variable](#-617-avoid-module-loading-using-a-variable)
+ [6.18. Run unsafe code in a sandbox](#-618-run-unsafe-code-in-a-sandbox)
+ [6.19. Take extra care when working with child processes `#advanced`](#-619-take-extra-care-when-working-with-child-processes)
+ [6.20. Hide error details from clients](#-620-hide-error-details-from-clients)
+ [6.21. Configure 2FA for npm or Yarn `#strategic`](#-621-configure-2fa-for-npm-or-yarn)
+ [6.22. Modify session middleware settings](#-622-modify-session-middleware-settings)
+ [6.23. Avoid DOS attacks by explicitly setting when a process should crash `#advanced`](#-623-avoid-dos-attacks-by-explicitly-setting-when-a-process-should-crash)
+ [6.24. Prevent unsafe redirects](#-624-prevent-unsafe-redirects)
+ [6.25. Avoid publishing secrets to the npm registry](#-625-avoid-publishing-secrets-to-the-npm-registry)
+ [6.26. 6.26 Inspect for outdated packages](#-626-inspect-for-outdated-packages)
+ [6.27. Import built-in modules using the 'node:' protocol `#new`](#-627-import-built-in-modules-using-the-node-protocol)
+
+
+
+
+
+ 7. Performance Practices (2) (Work In Progress️ ✍️)
+
+
+ [7.1. Don't block the event loop](#-71-dont-block-the-event-loop)
+ [7.2. Prefer native JS methods over user-land utils like Lodash](#-72-prefer-native-js-methods-over-user-land-utils-like-lodash)
+
+
+
+
+
+ 8. Docker Practices (15)
+
+
+ [8.1 Use multi-stage builds for leaner and more secure Docker images `#strategic`](#-81-use-multi-stage-builds-for-leaner-and-more-secure-docker-images)
+ [8.2. Bootstrap using node command, avoid npm start](#-82-bootstrap-using-node-command-avoid-npm-start)
+ [8.3. Let the Docker runtime handle replication and uptime `#strategic`](#-83-let-the-docker-runtime-handle-replication-and-uptime)
+ [8.4. Use .dockerignore to prevent leaking secrets](#-84-use-dockerignore-to-prevent-leaking-secrets)
+ [8.5. Clean-up dependencies before production](#-85-clean-up-dependencies-before-production)
+ [8.6. Shutdown smartly and gracefully `#advanced`](#-86-shutdown-smartly-and-gracefully)
+ [8.7. Set memory limits using both Docker and v8 `#advanced` `#strategic`](#-87-set-memory-limits-using-both-docker-and-v8)
+ [8.8. Plan for efficient caching](#-88-plan-for-efficient-caching)
+ [8.9. Use explicit image reference, avoid latest tag](#-89-use-explicit-image-reference-avoid-latest-tag)
+ [8.10. Prefer smaller Docker base images](#-810-prefer-smaller-docker-base-images)
+ [8.11. Clean-out build-time secrets, avoid secrets in args `#strategic #new`](#-811-clean-out-build-time-secrets-avoid-secrets-in-args)
+ [8.12. Scan images for multi layers of vulnerabilities `#advanced`](#-812-scan-images-for-multi-layers-of-vulnerabilities)
+ [8.13 Clean NODE_MODULE cache](#-813-clean-node_module-cache)
+ [8.14. Generic Docker practices](#-814-generic-docker-practices)
+ [8.15. Lint your Dockerfile `#new`](#-815-lint-your-dockerfile)
+
+
+
+
+
+# `1. Project Architecture Practices`
+
+## ![✔] 1.1 Structure your solution by business components
+
+### `📝 #updated`
+
+**TL;DR:** The root of a system should contain folders or repositories that represent reasonably sized business modules. Each component represents a product domain (i.e., bounded context), like 'user-component', 'order-component', etc. Each component has its own API, logic, and logical database. What is the significant merit? With an autonomous component, every change is performed over a granular and smaller scope - the mental overload, development friction, and deployment fear are much smaller and better. As a result, developers can move much faster. This does not necessarily demand physical separation and can be achieved using a Monorepo or with a multi-repo
+
+```bash
+my-system
+├─ apps (components)
+│ ├─ orders
+│ ├─ users
+│ ├─ payments
+├─ libraries (generic cross-component functionality)
+│ ├─ logger
+│ ├─ authenticator
+```
+
+**Otherwise:** when artifacts from various modules/topics are mixed together, there are great chances of a tightly-coupled 'spaghetti' system. For example, in an architecture where 'module-a controller' might call 'module-b service', there are no clear modularity borders - every code change might affect anything else. With this approach, developers who code new features struggle to realize the scope and impact of their change. Consequently, they fear breaking other modules, and each deployment becomes slower and riskier
+
+🔗 [**Read More: structure by components**](./sections/projectstructre/breakintcomponents.md)
-# `1. Project Structure Practices`
+## ![✔] 1.2 Layer your components with 3-tiers, keep the web layer within its boundaries
-## ![✔] 1.1 Structure your solution by components
+### `📝 #updated`
-**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
+**TL;DR:** Each component should contain 'layers' - a dedicated folder for common concerns: 'entry-point' where controller lives, 'domain' where the logic lives, and 'data-access'. The primary principle of the most popular architectures is to separate the technical concerns (e.g., HTTP, DB, etc) from the pure logic of the app so a developer can code more features without worrying about infrastructural concerns. Putting each concern in a dedicated folder, also known as the [3-Tier pattern](https://en.wikipedia.org/wiki/Multitier_architecture), is the _simplest_ way to meet this goal
-**Otherwise:** When developers who code new features struggle to realize the impact of their change and fear to break other dependent components - deployments become slower and riskier. It's also considered harder to scale-out when all the business units are not separated
+```bash
+my-system
+├─ apps (components)
+│ ├─ component-a
+ │ ├─ entry-points
+ │ │ ├─ api # controller comes here
+ │ │ ├─ message-queue # message consumer comes here
+ │ ├─ domain # features and flows: DTO, services, logic
+ │ ├─ data-access # DB calls w/o ORM
+```
+
+**Otherwise:** It's often seen that developer pass web objects like request/response to functions in the domain/logic layer - this violates the separation principle and makes it harder to access later the logic code by other clients like testing code, scheduled jobs, message queues, etc
-🔗 [**Read More: structure by components**](/sections/projectstructre/breakintcomponents.md)
+🔗 [**Read More: layer your app**](./sections/projectstructre/createlayers.md)
-## ![✔] 1.2 Layer your components, keep Express within its boundaries
+## ![✔] 1.3 Wrap common utilities as packages, consider publishing
-**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 dependent on and accessible by Express only
+**TL;DR:** Place all reusable modules in a dedicated folder, e.g., "libraries", and underneath each module in its own folder, e.g., "/libraries/logger". Make the module an independent package with its own package.json file to increase the module encapsulation, and allows future publishing to a repository. In a Monorepo setup, modules can be consumed by 'npm linking' to their physical paths, using ts-paths or by publishing and installing from a package manager repository like the npm registry
-**Otherwise:** App that mixes web objects with other layers cannot be accessed by testing code, CRON jobs, and other non-Express callers
+```bash
+my-system
+├─ apps (components)
+ │ ├─ component-a
+├─ libraries (generic cross-component functionality)
+│ ├─ logger
+│ │ ├─ package.json
+│ │ ├─ src
+│ │ │ ├─ index.js
+
+```
-🔗 [**Read More: layer your app**](/sections/projectstructre/createlayers.md)
+**Otherwise:** Clients of a module might import and get coupled to internal functionality of a module. With a package.json at the root, one can set a package.json.main or package.json.exports to explicitly tell which files and functions are part of the public interface
+
+🔗 [**Read More: Structure by feature**](./sections/projectstructre/wraputilities.md)
-## ![✔] 1.3 Wrap common utilities as npm packages
+## ![✔] 1.4 Use environment aware, secure and hierarchical config
+
+### `📝 #updated`
-**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
+**TL;DR:** A 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 (d) typing support (e) validation for failing fast (f) Specify default for each key. There are a few packages that can help tick most of those boxes like [convict](https://www.npmjs.com/package/convict), [env-var](https://github.com/evanshortiss/env-var), [zod](https://github.com/colinhacks/zod), and others
-**Otherwise:** You'll have to invent your own deployment and dependency wheel
+**Otherwise:** Consider a mandatory environment variable that wasn't provided. The app starts successfully and serve requests, some information is already persisted to DB. Then, it's realized that without this mandatory key the request can't complete, leaving the app in a dirty state
-🔗 [**Read More: Structure by feature**](/sections/projectstructre/wraputilities.md)
+🔗 [**Read More: configuration best practices**](./sections/projectstructre/configguide.md)
-## ![✔] 1.4 Separate Express 'app' and 'server'
+## ![✔] 1.5 Consider all the consequences when choosing the main framework
-**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
+### `🌟 #new`
-**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
+**TL;DR:** When building apps and APIs, using a framework is mandatory. It's easy to overlook alternative frameworks or important considerations and then finally land on a sub optimal option. As of 2023/2024, we believe that these four frameworks are worth considering: [Nest.js](https://nestjs.com/), [Fastify](https://www.fastify.io/), [express](https://expressjs.com/), and [Koa](https://koajs.com/). Click read more below for a detailed pros/cons of each framework. Simplistically, we believe that Nest.js is the best match for teams who wish to go OOP and/or build large-scale apps that can't get partitioned into smaller _autonomous_ components. Fastify is our recommendation for apps with reasonably-sized components (e.g., Microservices) that are built around simple Node.js mechanics. Read our [full considerations guide here](./sections/projectstructre/choose-framework.md)
-🔗 [**Read More: separate Express 'app' and 'server'**](/sections/projectstructre/separateexpress.md)
+**Otherwise:** Due to the overwhelming amount of considerations, it's easy to make decisions based on partial information and compare apples with oranges. For example, it's believed that Fastify is a minimal web-server that should get compared with express only. In reality, it's a rich framework with many official plugins that cover many concerns
-
+🔗 [**Read More: Choosing the right framework**](./sections/projectstructre/choose-framework.md)
-## ![✔] 1.5 Use environment aware, secure and hierarchical config
+## ![✔] 1.6 Use TypeScript sparingly and thoughtfully
-**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)
+### `🌟 #new`
-**Otherwise:** Failing to satisfy any of the config requirements will simply bog down the development or devops team. Probably both
+**TL;DR:** Coding without type safety is no longer an option, TypeScript is the most popular option for this mission. Use it to define variables and functions return types. With that, it is also a double edge sword that can greatly _encourage_ complexity with its additional ~ 50 keywords and sophisticated features. Consider using it sparingly, mostly with simple types, and utilize advanced features only when a real need arises
-🔗 [**Read More: configuration best practices**](/sections/projectstructre/configguide.md)
+**Otherwise:** [Researches](https://earlbarr.com/publications/typestudy.pdf) show that using TypeScript can help in detecting ~20% bugs earlier. Without it, also the developer experience in the IDE is intolerable. On the flip side, 80% of other bugs were not discovered using types. Consequently, typed syntax is valuable but limited. Only efficient tests can discover the whole spectrum of bugs, including type-related bugs. It might also defeat its purpose: sophisticated code features are likely to increase the code complexity, which by itself increases both the amount of bugs and the average bug fix time
+
+🔗 [**Read More: TypeScript considerations**](./sections/projectstructre/typescript-considerations.md)
@@ -114,133 +334,171 @@ Read in a different language: [**CN**](/README.chines
## ![✔] 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
+**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 Promises with async-await 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)
+🔗 [**Read More: avoiding callbacks**](./sections/errorhandling/asyncerrorhandling.md)
-## ![✔] 2.2 Use only the built-in Error object
+## ![✔] 2.2 Extend the built-in Error object
+
+### `📝 #updated`
-**TL;DR:** Many throw 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 emit an error – using only the built-in Error object will increase uniformity and prevent loss of information
+**TL;DR:** Some libraries throw errors as a string or as some custom type – this complicates the error handling logic and the interoperability between modules. Instead, create app error object/class that extends the built-in Error object and use it whenever rejecting, throwing or emitting an error. The app error should add useful imperative properties like the error name/code and isCatastrophic. By doing so, all errors have a unified structure and support better error handling. There is `no-throw-literal` ESLint rule that strictly checks that (although it has some [limitations](https://eslint.org/docs/rules/no-throw-literal) which can be solved when using TypeScript and setting the `@typescript-eslint/no-throw-literal` rule)
**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)
+🔗 [**Read More: using the built-in error object**](./sections/errorhandling/useonlythebuiltinerror.md)
-## ![✔] 2.3 Distinguish operational vs programmer errors
+## ![✔] 2.3 Distinguish catastrophic errors from operational 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
+### `📝 #updated`
-**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
+**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, catastrophic error (also known as programmer errors) refers to unusual code failures that dictate to gracefully restart the application
-🔗 [**Read More: operational vs programmer error**](/sections/errorhandling/operationalvsprogrammererror.md)
+**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 catastrophic 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
+## ![✔] 2.4 Handle errors centrally, not within a 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
+**TL;DR:** Error handling logic such as logging, deciding whether to crash and monitoring metrics should be encapsulated in a dedicated and centralized object that all entry-points (e.g. APIs, cron jobs, scheduled jobs) 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)
+🔗 [**Read More: handling errors in a centralized place**](./sections/errorhandling/centralizedhandling.md)
-## ![✔] 2.5 Document API errors using Swagger or GraphQL
+## ![✔] 2.5 Document API errors using OpenAPI or GraphQL
-**TL;DR:** Let your API callers know which errors might come in return so they can handle these thoughtfully without crashing. For RESTful APIs, this is usually done with documentation frameworks like Swagger. If you're using GraphQL, you can utilize your schema and comments as well.
+**TL;DR:** Let your API callers know which errors might come in return so they can handle these thoughtfully without crashing. For RESTful APIs, this is usually done with documentation frameworks like OpenAPI. If you're using GraphQL, you can utilize your schema and comments as well
**Otherwise:** An API client might decide to crash and restart only because it received back an error it couldn’t understand. Note: the caller of your API might be you (very typical in a microservice environment)
-🔗 [**Read More: documenting API errors in Swagger or GraphQL**](/sections/errorhandling/documentingusingswagger.md)
+🔗 [**Read More: documenting API errors in Swagger or GraphQL**](./sections/errorhandling/documentingusingswagger.md)
## ![✔] 2.6 Exit the process gracefully when a stranger comes to town
-**TL;DR:** When an unknown error occurs (a developer error, see best practice 2.3) - there is uncertainty about the application healthiness. A common practice suggests restarting the process carefully using a process management tool like [Forever](https://www.npmjs.com/package/forever) or [PM2](http://pm2.keymetrics.io/)
+**TL;DR:** When an unknown error occurs (catastrophic error, see best practice 2.3) - there is uncertainty about the application healthiness. In this case, there is no escape from making the error observable, shutting off connections and exiting the process. Any reputable runtime framework like Dockerized services or cloud serverless solutions will take care to restart
**Otherwise:** When an unfamiliar exception occurs, 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)
+🔗 [**Read More: shutting the process**](./sections/errorhandling/shuttingtheprocess.md)
-## ![✔] 2.7 Use a mature logger to increase error visibility
+## ![✔] 2.7 Use a mature logger to increase errors visibility
+
+### `📝 #updated`
-**TL;DR:** A set of mature logging tools like [Winston](https://www.npmjs.com/package/winston), [Bunyan](https://github.com/trentm/node-bunyan), [Log4js](http://stritti.github.io/log4js/) or [Pino](https://github.com/pinojs/pino), will speed-up error discovery and understanding. So forget about console.log
+**TL;DR:** A robust logging tools like [Pino](https://github.com/pinojs/pino) or [Winston](https://github.com/winstonjs/winston) increases the errors visibility using features like log-levels, pretty print coloring and more. Console.log lacks these imperative features and should be avoided. The best in class logger allows attaching custom useful properties to log entries with minimized serialization performance penalty. Developers should write logs to `stdout` and let the infrastructure pipe the stream to the appropriate log aggregator
**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)
+🔗 [**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 scenarios but also handles and returns the right errors. Testing frameworks like Mocha & Chai can handle this easily (see code examples within the "Gist popup")
+### `📝 #updated`
+
+**TL;DR:** Whether professional automated QA or plain manual developer testing – Ensure that your code not only satisfies positive scenarios but also handles and returns the right errors. On top of this, simulate deeper error flows like uncaught exceptions and ensure that the error handler treat these properly (see code examples within the "read more" section)
**Otherwise:** Without testing, whether automatically or manually, you can’t rely on your code to return the right errors. Without meaningful errors – there’s no error handling
-🔗 [**Read More: testing error flows**](/sections/errorhandling/testingerrorflows.md)
+🔗 [**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
+**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)
+🔗 [**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`
+### `📝 #updated`
+
+**TL;DR:** Any exception thrown within a promise will get swallowed and discarded unless a developer didn’t forget to explicitly handle it. 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)
+🔗 [**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
+**TL;DR:** 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 modern validation library like [ajv](https://www.npmjs.com/package/ajv), [zod](https://github.com/colinhacks/zod), or [typebox](https://github.com/sinclairzx81/typebox)
**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)
+🔗 [**Read More: failing fast**](./sections/errorhandling/failfast.md)
+
+
+
+## ![✔] 2.12 Always await promises before returning to avoid a partial stacktrace
+
+### `🌟 #new`
+
+**TL;DR:** Always do `return await` when returning a promise to benefit full error stacktrace. If a
+function returns a promise, that function must be declared as `async` function and explicitly
+`await` the promise before returning it
+
+**Otherwise:** The function that returns a promise without awaiting won't appear in the stacktrace.
+Such missing frames would probably complicate the understanding of the flow that leads to the error,
+especially if the cause of the abnormal behavior is inside of the missing function
+
+🔗 [**Read More: returning promises**](./sections/errorhandling/returningpromises.md)
+
+
+
+## ![✔] 2.13 Subscribe to event emitters and streams 'error' event
+
+### `🌟 #new`
+
+**TL;DR:** Unlike typical functions, a try-catch clause won't get errors that originate from Event Emitters and anything inherited from it (e.g., streams). Instead of try-catch, subscribe to an event emitter's 'error' event so your code can handle the error in context. When dealing with [EventTargets](https://nodejs.org/api/events.html#eventtarget-and-event-api) (the web standard version of Event Emitters) there are no 'error' event and all errors end in the process.on('error) global event - in this case, at least ensure that the process crash or not based on the desired context. Also, mind that error originating from _asynchronous_ event handlers are not get caught unless the event emitter is initialized with {captureRejections: true}
+
+**Otherwise:** Event emitters are commonly used for global and key application functionality such as DB or message queue connection. When this kind of crucial objects throw an error, at best the process will crash due to unhandled exception. Even worst, it will stay alive as a zombie while a key functionality is turned off
-# `3. Code Style Practices`
+# `3. Code Patterns And 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
+**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) 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 the project's code style
-🔗 [**Read More: Using ESLint and Prettier**](/sections/codestylepractices/eslint_prettier.md)
+🔗 [**Read More: Using ESLint and Prettier**](./sections/codestylepractices/eslint_prettier.md)
-## ![✔] 3.2 Node.js specific plugins
+## ![✔] 3.2 Use Node.js eslint extension plugins
+
+### `📝 #updated`
-**TL;DR:** On top of ESLint standard rules that cover vanilla JavaScript, add Node.js 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)
+**TL;DR:** On top of ESLint standard rules that cover vanilla JavaScript, add Node.js 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), [eslint-plugin-require](https://www.npmjs.com/package/eslint-plugin-require), [/eslint-plugin-jest](https://www.npmjs.com/package/eslint-plugin-jest) and other useful rules
-**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
+**Otherwise:** Many faulty Node.js code patterns might escape under the radar. For example, developers might require(variableAsPath) files with a variable given as a path which allows attackers to execute any JS script. Node.js linters can detect such patterns and complain early
@@ -275,7 +533,7 @@ No matter if you use semicolons or not to separate your statements, knowing the
**TL;DR:** Use ESLint to gain awareness about separation concerns. [Prettier](https://prettier.io/) or [Standardjs](https://standardjs.com/) can automatically resolve these issues.
-**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, or considers a statement as not ended where it should, which might lead to some undesired results. You can use assignments and avoid using immediate invoked function expressions to prevent most of unexpected errors.
+**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, or considers a statement as not ended where it should, which might lead to some undesired results. You can use assignments and avoid using immediately invoked function expressions to prevent most of the unexpected errors.
### Code example
@@ -305,7 +563,7 @@ const count = 2 // it tries to run 2(), but 2 is not a function
(function doSomething() {
// do something amazing
}())
-// put a semicolon before the immediate invoked function, after the const definition, save the return value of the anonymous function to a variable or avoid IIFEs alltogether
+// put a semicolon before the immediate invoked function, after the const definition, save the return value of the anonymous function to a variable or avoid IIFEs altogether
```
🔗 [**Read more:** "Semi ESLint rule"](https://eslint.org/docs/rules/semi)
@@ -323,31 +581,48 @@ const count = 2 // it tries to run 2(), but 2 is not a function
## ![✔] 3.6 Use 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
+**TL;DR:** Use **_lowerCamelCase_** when naming constants, variables and functions, **_UpperCamelCase_** (capital first letter as well) when naming classes and **_UPPER_SNAKE_CASE_** when naming global or static variables. This will help you to easily distinguish between plain variables, functions, classes that require instantiation and variables declared at global module scope. 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
+**Otherwise:** JavaScript is the only language in the world that allows invoking a constructor ("Class") directly without instantiating it first. Consequently, Classes and function-constructors are differentiated by starting with UpperCamelCase
### 3.6 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 global variables names we use the const/let keyword and UPPER_SNAKE_CASE
+let MUTABLE_GLOBAL = "mutable value";
+const GLOBAL_CONSTANT = "immutable value";
+const CONFIG = {
+ key: "value",
};
-// for variables and functions names we use lowerCamelCase
-let someVariableExample = 'value';
-function doSomething() {}
+// examples of UPPER_SNAKE_CASE convention in nodejs/javascript ecosystem
+// in javascript Math.PI module
+const PI = 3.141592653589793;
+
+// https://github.com/nodejs/node/blob/b9f36062d7b5c5039498e98d2f2c180dca2a7065/lib/internal/http2/core.js#L303
+// in nodejs http2 module
+const HTTP_STATUS_OK = 200;
+const HTTP_STATUS_CREATED = 201;
+
+// for class name we use UpperCamelCase
+class SomeClassExample {
+ // for static class properties we use UPPER_SNAKE_CASE
+ static STATIC_PROPERTY = "value";
+}
+
+// for functions names we use lowerCamelCase
+function doSomething() {
+ // for scoped variable names we use the const/let keyword and lowerCamelCase
+ const someConstExample = "immutable value";
+ let someMutableExample = "mutable value";
+}
```
## ![✔] 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
+**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
@@ -359,26 +634,33 @@ function doSomething() {}
**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
+**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 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 Require modules by folders, opposed to the files directly
+## ![✔] 3.9 Set an explicit entry point to a module/folder
+
+### `📝 #updated`
-**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
+**TL;DR:** When developing a module/library, set an explicit root file that exports the public and interesting code. Discourage the client code from importing deep files and becoming familiar with the internal structure. With commonjs (require), this can be done with an index.js file at the folder's root or the package.json.main field. With ESM (import), if a package.json exists on the root, the field "exports" allow specifying the module's root file. If no package.json exists, you may put an index.js file on the root which re-exports all the public functionality
-**Otherwise:** Changing the internal structure of files or the signature may break the interface with clients
+**Otherwise:** Having an explicit root file acts like a public 'interface' that encapsulates the internal, directs the caller to the public code and facilitates future changes without breaking the contract
-### 3.9 Code example
+### 3.9 Code example - avoid coupling the client to the module structure
```javascript
-// Do
-module.exports.SMSProvider = require('./SMSProvider');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver');
+// Avoid: client has deep familiarity with the internals
-// Avoid
-module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
+// Client code
+const SMSWithMedia = require("./SMSProvider/providers/media/media-provider.js");
+
+// Better: explicitly export the public functions
+
+//index.js, module code
+module.exports.SMSWithMedia = require("./SMSProvider/providers/media/media-provider.js");
+
+// Client code
+const { SMSWithMedia } = require("./SMSProvider");
```
@@ -392,18 +674,18 @@ module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolve
### 3.10 Code example
```javascript
-'' == '0' // false
-0 == '' // true
-0 == '0' // true
+"" == "0"; // false
+0 == ""; // true
+0 == "0"; // true
-false == 'false' // false
-false == '0' // true
+false == "false"; // false
+false == "0"; // true
-false == undefined // false
-false == null // false
-null == undefined // true
+false == undefined; // false
+false == null; // false
+null == undefined; // true
-' \t\r\n ' == 0 // true
+" \t\r\n " == 0; // true
```
All statements above will return false if used with `===`
@@ -412,11 +694,11 @@ 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
+**TL;DR:** Async-await is the simplest way to express an asynchronous flow as it makes asynchronous code look synchronous. Async-await will also result in much more compact code and support for try-catch. This technique now supersedes callbacks and promises in _most_ cases. Using it in your code is probably the best gift one can give to the code reader
-**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 makes it difficult to reason about the code flow
+**Otherwise:** Handling async errors in callback style are probably the fastest way to hell - this style forces to check errors all over, deal with awkward code nesting, and makes it difficult to reason about the code flow
-🔗[**Read more:** Guide to async await 1.0](https://github.com/yortus/asyncawait)
+🔗[**Read more:** Guide to async-await 1.0](https://github.com/yortus/asyncawait)
@@ -428,15 +710,31 @@ All statements above will return false if used with `===`
🔗 [**Read more: 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)
+
+
+## ![✔] 3.13 Avoid effects outside of functions
+
+### `🌟 #new`
+
+**TL;DR:** Avoid putting code with effects like network or DB calls outside of functions. Such a code will be executed immediately when another file requires the file. This 'floating' code might get executed when the underlying system is not ready yet. It also comes with a performance penalty even when this module's functions will finally not be used in runtime. Last, mocking these DB/network calls for testing is harder outside of functions. Instead, put this code inside functions that should get called explicitly. If some DB/network code must get executed right when the module loads, consider using the factory or revealing module patterns
+
+**Otherwise:** A typical web framework sets error handler, environment variables and monitoring. When DB/network calls are made before the web framework is initialized, they won't be monitored or fail due to a lack of configuration data
+
# `4. Testing And Overall Quality Practices`
+\_We have dedicated guides for testing, see below. The best practices list here is a brief summary of these guides
+
+a. [JavaScript testing best practices](https://github.com/goldbergyoni/javascript-testing-best-practices)
+b. [Node.js testing - beyond the basics](https://github.com/testjavascript/nodejs-integration-tests-best-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' ran out of control and was abandoned. For that reason, prioritize and start with API testing which is the easiest way to write and provides 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
+**TL;DR:** Most projects just don't have any automated testing due to short timetables or often the 'testing project' ran out of control and was abandoned. For that reason, prioritize and start with API testing which is the easiest way to write and provides more coverage than unit testing (you may even craft API tests without code using tools like [Postman](https://www.getpostman.com/)). Afterwards, 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
@@ -444,51 +742,49 @@ All statements above will return false if used with `===`
## ![✔] 4.2 Include 3 parts in each test name
-**TL;DR:** Make the test speak at the requirements level so it's self explanatory also to QA engineers and developers who are not familiar with the code internals. State in the test name what is being tested (unit under test), under what circumstances and what is the expected result
+### `🌟 #new`
+
+**TL;DR:** Make the test speak at the requirements level so it's self-explanatory also to QA engineers and developers who are not familiar with the code internals. State in the test name what is being tested (unit under test), under what circumstances, and what is the expected result
**Otherwise:** A deployment just failed, a test named “Add product” failed. Does this tell you what exactly is malfunctioning?
-🔗 [**Read More: Include 3 parts in each test name**](/sections/testingandquality/3-parts-in-name.md)
+🔗 [**Read More: Include 3 parts in each test name**](./sections/testingandquality/3-parts-in-name.md)
## ![✔] 4.3 Structure tests by the AAA pattern
-**TL;DR:** Structure your tests with 3 well-separated sections: Arrange, Act & Assert (AAA). The first part includes the test setup, then the execution of the unit under test and finally the assertion phase. Following this structure guarantees that the reader spends no brain CPU on understanding the test plan
+### `🌟 #new`
-**Otherwise:** Not only you spend long daily hours on understanding the main code, now also what should have been the simple part of the day (testing) stretches your brain
+**TL;DR:** Structure your tests with 3 well-separated sections: Arrange, Act & Assert (AAA). The first part includes the test setup, then the execution of the unit under test, and finally the assertion phase. Following this structure guarantees that the reader spends no brain CPU on understanding the test plan
-🔗 [**Read More: Structure tests by the AAA pattern**](/sections/testingandquality/aaa.md)
+**Otherwise:** Not only you spend long daily hours on understanding the main code, but now also what should have been the simple part of the day (testing) stretches your brain
+
+🔗 [**Read More: Structure tests by the AAA pattern**](./sections/testingandquality/aaa.md)
-## ![✔] 4.4 Detect code issues with a linter
+## ![✔] 4.4 Ensure Node version is unified
+
+### `🌟 #new`
-**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](#3-code-style-practices) on Code Style Practices
+**TL;DR:** Use tools that encourage or enforce the same Node.js version across different environments and developers. Tools like [nvm](https://github.com/nvm-sh/nvm), and [Volta](https://volta.sh/) allow specifying the project's version in a file so each team member can run a single command to conform with the project's version. Optionally, this definition can be replicated to CI and the production runtime (e.g., copy the specified value to .Dockerfile build and to the CI declaration file)
-**Otherwise:** You may let pass some anti-pattern and possible vulnerable code to your production environment.
+**Otherwise:** A developer might face or miss an error because she uses a different Node.js version than her teammates. Even worse - the production runtime might be different than the environment where tests were executed
## ![✔] 4.5 Avoid global test fixtures and seeds, add data per-test
-**TL;DR:** To prevent tests coupling and easily reason about the test flow, each test should add and act on its own set of DB rows. Whenever a test needs to pull or assume the existence of some DB data - it must explicitly add that data and avoid mutating any other records
+**TL;DR:** To prevent test coupling and easily reason about the test flow, each test should add and act on its own set of DB rows. Whenever a test needs to pull or assume the existence of some DB data - it must explicitly add that data and avoid mutating any other records
**Otherwise:** Consider a scenario where deployment is aborted due to failing tests, team is now going to spend precious investigation time that ends in a sad conclusion: the system works well, the tests however interfere with each other and break the build
-🔗 [**Read More: Avoid global test fixtures**](/sections/testingandquality/avoid-global-test-fixture.md)
-
-
-
-## ![✔] 4.6 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 🔗 [npm audit](https://docs.npmjs.com/cli/audit) and 🔗 [snyk.io](https://snyk.io) 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
+🔗 [**Read More: Avoid global test fixtures**](./sections/testingandquality/avoid-global-test-fixture.md)
-## ![✔] 4.7 Tag your tests
+## ![✔] 4.6 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'
@@ -496,7 +792,7 @@ All statements above will return false if used with `===`
-## ![✔] 4.8 Check your test coverage, it helps to identify wrong test patterns
+## ![✔] 4.7 Check your test coverage, it helps to identify wrong test patterns
**TL;DR:** Code coverage tools like [Istanbul](https://github.com/istanbuljs/istanbuljs)/[NYC](https://github.com/istanbuljs/nyc) 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
@@ -504,39 +800,61 @@ All statements above will return false if used with `===`
-## ![✔] 4.9 Inspect for outdated packages
+## ![✔] 4.8 Use production-like environment for e2e testing
-**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
+**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. Use an environment which is as close to your real production environment as possible like a-continue (Missed -continue here, needs content. Judging by the **Otherwise** clause, this should mention docker-compose)
-**Otherwise:** Your production will run packages that have been explicitly tagged by their author as risky
+**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.10 Use production-like env for e2e testing
+## ![✔] 4.9 Refactor regularly using static analysis tools
-**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. Use an environment which is as closed to your real production as possible like a-continue
+**TL;DR:** Using static analysis tools helps by giving objective ways to improve code quality and keeps 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:** 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
+**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)
-## ![✔] 4.11 Refactor regularly using static analysis tools
+## ![✔] 4.10 Mock responses of external HTTP services
-**TL;DR:** Using static analysis tools helps by giving objective ways to improve code quality and keeps 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)).
+### `🌟 #new`
-**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
+**TL;DR:** Use network mocking tools to simulate responses of external collaborators' services that are approached over the network (e.g., REST, Graph). This is imperative not only to isolate the component under test but mostly to simulate non-happy path flows. Tools like [nock](https://github.com/nock/nock) (in-process) or [Mock-Server](https://www.mock-server.com/) allow defining a specific response of external service in a single line of code. Remember to simulate also errors, delays, timeouts, and any other event that is likely to happen in production
-🔗 [**Read More: Refactoring!**](/sections/testingandquality/refactoring.md)
+**Otherwise:** Allowing your component to reach real external services instances will likely result in naive tests that mostly cover happy paths. The tests might also be flaky and slow
-
+🔗 [**Read More: Mock external services**](./sections/testingandquality/mock-external-services.md)
+
+## ![✔] 4.11 Test your middlewares in isolation
+
+**TL;DR:** When a middleware holds some immense logic that spans many requests, it is worth testing it in isolation without waking up the entire web framework. This can be easily achieved by stubbing and spying on the {req, res, next} objects
+
+**Otherwise:** A bug in Express middleware === a bug in all or most requests
-## ![✔] 4.12 Carefully choose your CI platform (Jenkins vs CircleCI vs Travis vs Rest of the world)
+🔗 [**Read More: Test middlewares in isolation**](./sections/testingandquality/test-middlewares.md)
-**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 has become 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
+## ![✔] 4.12 Specify a port in production, randomize in testing
-**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
+### `🌟 #new`
-🔗 [**Read More: Choosing CI platform**](/sections/testingandquality/citools.md)
+**TL;DR:** When testing against the API, it's common and desirable to initialize the web server inside the tests. Let the server randomize the web server port in testing to prevent collisions. If you're using Node.js http server (used by most frameworks), doing so demands nothing but passing a port number zero - this will randomize an available port
+
+**Otherwise:** Specifying a fixed port will prevent two testing processes from running at the same time. Most of the modern test runners run with multiple processes by default
+
+🔗 [**Read More: Randomize a port for testing**](./sections/testingandquality/randomize-port.md)
+
+## ![✔] 4.13 Test the five possible outcomes
+
+### `🌟 #new`
+
+**TL;DR:** When testing a flow, ensure to cover five potential categories. Any time some action is triggered (e.g., API call), a reaction occurs, a meaningful **outcome** is produced and calls for testing. There are five possible outcome types for every flow: a response, a visible state change (e.g., DB), an outgoing API call, a new message in a queue, and an observability call (e.g., logging, metric). See a [checklist here](https://testjavascript.com/wp-content/uploads/2021/10/the-backend-checklist.pdf). Each type of outcome comes with unique challenges and techniques to mitigate those challenges - we have a dedicated guide about this topic: [Node.js testing - beyond the basics](https://github.com/testjavascript/nodejs-integration-tests-best-practices)
+
+**Otherwise:** Consider a case when testing the addition of a new product to the system. It's common to see tests that assert on a valid response only. What if the product was failed to persist regardless of the positive response? what if when adding a new product demands calling some external service, or putting a message in the queue - shouldn't the test assert these outcomes as well? It's easy to overlook various paths, this is where a [checklist comes handy](https://testjavascript.com/wp-content/uploads/2021/10/the-backend-checklist.pdf)
+
+🔗 [**Read More: Test five outcomes**](./sections/testingandquality/test-five-outcomes.md)
@@ -546,91 +864,93 @@ All statements above will return false if used with `===`
## ![✔] 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
+**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. In any case, the 4 layers of observability must be covered: uptime, metrics with focus on user-facing symptoms and Node.js technical metrics like event loop lag, distributed flows measurement with Open Telemetry and logging. Click ‘Read More’ below for an overview of the solutions
**Otherwise:** Failure === disappointed customers. Simple
-🔗 [**Read More: Monitoring!**](/sections/production/monitoring.md)
+🔗 [**Read More: Monitoring!**](./sections/production/monitoring.md)
-## ![✔] 5.2. Increase transparency using smart logging
+## ![✔] 5.2. Increase the observability 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)
+🔗 [**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
+**TL;DR:** Node is quite bad at doing CPU intensive tasks like gzipping, SSL termination, etc. You should use specialized infrastructure 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)
+🔗 [**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 grained 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
+**TL;DR:** Your code must be identical across all environments, but without a special lockfile npm lets dependencies drift across environments. Ensure to commit your package-lock.json so all the environments will be identical
**Otherwise:** QA will thoroughly test the code and approve a version that will behave differently in production. Even worse, different servers in the same production cluster might run different code
-🔗 [**Read More: Lock dependencies**](/sections/production/lockdependencies.md)
+🔗 [**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, process management tools like PM2 might be enough but in today's ‘dockerized’ world, cluster management tools should be considered as well
+**TL;DR:** The process must go on and get restarted upon failures. Modern runtime platforms like Docker-ized platforms (e.g. Kubernetes), and Serverless take care for this automatically. When the app is hosted on a bare metal server, one must take care for a process management tools like [systemd](https://systemd.io/). Avoid including a custom process management tool in a modern platform that monitors an app instance (e.g., Kubernetes) - doing so will hide failures from the infrastructure. When the underlying infrastructure is not aware of errors, it can't perform useful mitigation steps like re-placing the instance in a different location
**Otherwise:** Running dozens of instances without a clear strategy and too many tools together (cluster management, docker, PM2) might lead to DevOps chaos
-🔗 [**Read More: Guard process uptime using the right tool**](/sections/production/guardprocess.md)
+🔗 [**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 others 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)
+**TL;DR:** At its basic form, a Node app runs on a single CPU core while all others are left idling. It’s your duty to replicate the Node process and utilize all CPUs. Most of the modern run-times platform (e.g., Kubernetes) allow replicating instances of the app but they won't verify that all cores are utilized - this is your duty. If the app is hosted on a bare server, it's also your duty to use some process replication solution (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)
+🔗 [**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
+**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-tested 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)
+🔗 [**Read More: Create a ‘maintenance endpoint’**](./sections/production/createmaintenanceendpoint.md)
-## ![✔] 5.8. Discover errors and downtime using APM products
+## ![✔] 5.8. Discover the unknowns using APM products
-**TL;DR:** Application 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
+### `📝 #updated`
+
+**TL;DR:** Consider adding another safety layer to the production stack - APM. While the majority of symptoms and causes can be detected using traditional monitoring techniques, in a distributed system there is more than meets the eye. Application monitoring and performance products (a.k.a. APM) can auto-magically go beyond traditional monitoring and provide additional layer of discovery and developer-experience. For example, some APM products can highlight a transaction that loads too slow on the **end-user's side** while suggesting the root cause. APMs also provide more context for developers who try to troubleshoot a log error by showing what was the server busy with when the error occurred. To name a few example
**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 affect the UX
-🔗 [**Read More: Discover errors and downtime using APM products**](/sections/production/apmproducts.md)
+🔗 [**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)
+**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 'Read More')
**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/productioncode.md)
+🔗 [**Read More: Make your code production-ready**](./sections/production/productioncode.md)
@@ -640,27 +960,27 @@ All statements above will return false if used with `===`
**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)
+🔗 [**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
+**TL;DR:** Serve frontend content using a specialized infrastructure (nginx, S3, CDN) because Node performance gets hurt when dealing with many static files due to its single-threaded model. One exception to this guideline is when doing server-side rendering
**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)
+🔗 [**Read More: Get your frontend assets out of Node**](./sections/production/frontendout.md)
-## ![✔] 5.12. Be stateless, kill your servers almost every day
+## ![✔] 5.12. Strive to be stateless
-**TL;DR:** Store any type of data (e.g. user sessions, 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
+**TL;DR:** Store any type of _data_ (e.g. user sessions, cache, uploaded files) within external data stores. When the app holds data in-process this adds additional layer of maintenance complexity like routing users to the same instance and higher cost of restarting a process. To enforce and encourage a stateless approach, most modern runtime platforms allows 'reapp-ing' instances periodically
**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)
+🔗 [**Read More: Be stateless, kill your Servers almost every day**](./sections/production/bestateless.md)
@@ -670,27 +990,27 @@ All statements above will return false if used with `===`
**Otherwise:** Keeping your code clean from vulnerabilities without dedicated tools will require you to constantly follow online publications about new threats. Quite tedious
-🔗 [**Read More: Use tools that automatically detect vulnerabilities**](/sections/production/detectvulnerabilities.md)
+🔗 [**Read More: Use tools that automatically detect vulnerabilities**](./sections/production/detectvulnerabilities.md)
## ![✔] 5.14. Assign a transaction id 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
+**TL;DR:** Assign the same identifier, transaction-id: uuid(), to each log entry within a single request (also known as correlation-id/tracing-id/request-context). Then when inspecting errors in logs, easily conclude what happened before and after. Node has a built-in mechanism, [AsyncLocalStorage](https://nodejs.org/api/async_context.html), for keeping the same context across asynchronous calls. 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)
+🔗 [**Read More: Assign ‘TransactionId’ to each log statement**](./sections/production/assigntransactionid.md)
-## ![✔] 5.15. Set NODE_ENV=production
+## ![✔] 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 determine the current environment and optimize their code for production
+**TL;DR:** Set the environment variable `NODE_ENV` to ‘production’ or ‘development’ to flag whether production optimizations should get activated – some npm packages determine 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 it slower by a factor of three!
+**Otherwise:** Omitting this simple property might greatly degrade performance when dealing with some specific libraries like Express server-side rendering
-🔗 [**Read More: Set NODE_ENV=production**](/sections/production/setnodeenv.md)
+🔗 [**Read More: Set NODE_ENV=production**](./sections/production/setnodeenv.md)
@@ -708,17 +1028,29 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Use an LTS release of Node.js**](./sections/production/LTSrelease.md)
-## ![✔] 5.18. Don't route logs within the app
+## ![✔] 5.18. Log to stdout, avoid specifying log destination within the app
+
+### `📝 #updated`
**TL;DR:** Log destinations should not be hard-coded by developers within the application code, but instead should be defined by the execution environment the application runs in. Developers should write logs to `stdout` using a logger utility and then let the execution environment (container, server, etc.) pipe the `stdout` stream to the appropriate destination (i.e. Splunk, Graylog, ElasticSearch, etc.).
-**Otherwise:** Application handling log routing === hard to scale, loss of logs, poor separation of concerns
+**Otherwise:** If developers set the log routing, less flexibility is left for the ops professional who wishes to customize it. Beyond this, if the app tries to log directly to a remote location (e.g., Elastic Search), in case of panic or crash - further logs that might explain the problem won't arrive
+
+🔗 [**Read More: Log Routing**](./sections/production/logrouting.md)
+
+
+
+## ![✔] 5.19. Install your packages with `npm ci`
+
+**TL;DR:** Run `npm ci` to strictly do a clean install of your dependencies matching package.json and package-lock.json. Obviously production code must use the exact version of the packages that were used for testing. While package-lock.json file sets strict version for dependencies, in case of mismatch with the file package.json, the command 'npm install' will treat package.json as the source of truth. On the other hand, the command 'npm ci' will exit with error in case of mismatch between these files
-🔗 [**Read More: Log Routing**](/sections/production/logrouting.md)
+**Otherwise:** QA will thoroughly test the code and approve a version that will behave differently in production. Even worse, different servers in the same production cluster might run different code.
+
+🔗 [**Read More: Use npm ci**](./sections/production/installpackageswithnpmci.md)
@@ -738,7 +1070,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Lint rules**](./sections/security/lintrules.md)
@@ -750,7 +1082,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Implement rate limiting**](./sections/security/limitrequests.md)
@@ -762,7 +1094,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Secret management**](./sections/security/secretmanagement.md)
@@ -774,7 +1106,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Query injection prevention using ORM/ODM libraries**](./sections/security/ormodmusage.md)
@@ -782,7 +1114,7 @@ All statements above will return false if used with `===`
**TL;DR:** This is a collection of security advice that is 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)
+🔗 [**Read More: Common security best practices**](./sections/security/commonsecuritybestpractices.md)
@@ -794,7 +1126,7 @@ All statements above will return false if used with `===`
**Otherwise:** Attackers could perform direct attacks on your application's users, leading to huge security vulnerabilities
-🔗 [**Read More: Using secure headers in your application**](/sections/security/secureheaders.md)
+🔗 [**Read More: Using secure headers in your application**](./sections/security/secureheaders.md)
@@ -806,19 +1138,19 @@ All statements above will return false if used with `===`
**Otherwise:** An attacker could detect your web framework and attack all its known vulnerabilities.
-🔗 [**Read More: Dependency security**](/sections/security/dependencysecurity.md)
+🔗 [**Read More: Dependency security**](./sections/security/dependencysecurity.md)
-## ![✔] 6.8. Avoid using the Node.js crypto library for handling passwords, use Bcrypt
+## ![✔] 6.8. Protect Users' Passwords/Secrets using bcrypt or scrypt
-**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.
+**TL;DR:** Passwords or secrets (e.g. API keys) should be stored using a secure hash + salt function like `bcrypt`,`scrypt`, or worst case `pbkdf2`.
-**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.
+**Otherwise:** Passwords and secrets that are stored 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)
+🔗 [**Read More: User Passwords**](./sections/security/userpasswords.md)
@@ -830,7 +1162,7 @@ All statements above will return false if used with `===`
**Otherwise:** An attacker might store 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)
+🔗 [**Read More: Escape output**](./sections/security/escape-output.md)
@@ -842,19 +1174,19 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Validate incoming JSON schemas**](./sections/security/validation.md)
-## ![✔] 6.11. Support blacklisting JWTs
+## ![✔] 6.11. Support blocklisting 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.
+**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 blocklist 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)
+🔗 [**Read More: Blocklist JSON Web Tokens**](./sections/security/expirejwt.md)
@@ -869,7 +1201,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Login rate limiting**](./sections/security/login-rate-limit.md)
@@ -879,9 +1211,9 @@ All statements above will return false if used with `===`
**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 user's 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)
+**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 their server)
-🔗 [**Read More: Run Node.js as non-root user**](/sections/security/non-root-user.md)
+🔗 [**Read More: Run Node.js as non-root user**](./sections/security/non-root-user.md)
@@ -893,7 +1225,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Limit payload size**](./sections/security/requestpayloadsizelimit.md)
@@ -905,7 +1237,7 @@ All statements above will return false if used with `===`
**Otherwise:** Malicious JavaScript code finds a way into 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)
+🔗 [**Read More: Avoid JavaScript eval statements**](./sections/security/avoideval.md)
@@ -917,7 +1249,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Prevent malicious RegEx**](./sections/security/regex.md)
@@ -927,9 +1259,9 @@ All statements above will return false if used with `===`
**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.
+**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 file system, or access already existing system files.
-🔗 [**Read More: Safe module loading**](/sections/security/safemoduleloading.md)
+🔗 [**Read More: Safe module loading**](./sections/security/safemoduleloading.md)
@@ -941,7 +1273,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Run unsafe code in a sandbox**](./sections/security/sandbox.md)
@@ -953,7 +1285,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Be cautious when working with child processes**](./sections/security/childprocesses.md)
@@ -965,7 +1297,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Hide error details from client**](./sections/security/hideerrors.md)
@@ -975,7 +1307,7 @@ All statements above will return false if used with `===`
**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)
+**Otherwise:** [Have you heard about the eslint developer whose password was hijacked?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
@@ -987,7 +1319,7 @@ All statements above will return false if used with `===`
**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)
+🔗 [**Read More: Cookie and session security**](./sections/security/sessions.md)
@@ -1009,7 +1341,7 @@ All statements above will return false if used with `===`
**Otherwise:** If an attacker discovers that you are not validating external, user-supplied input, they may exploit this vulnerability by posting specially-crafted links on forums, social media, and other public places to get users to click it.
-🔗 [**Read More: Prevent unsafe redirects**](/sections/security/saferedirects.md)
+🔗 [**Read More: Prevent unsafe redirects**](./sections/security/saferedirects.md)
@@ -1017,18 +1349,51 @@ All statements above will return false if used with `===`
-**TL;DR:** Precautions should be taken to avoid the risk of accidentally publishing secrets to public npm registries. An `.npmignore` file can be used to blacklist specific files or folders, or the `files` array in `package.json` can act as a whitelist.
+**TL;DR:** Precautions should be taken to avoid the risk of accidentally publishing secrets to public npm registries. An `.npmignore` file can be used to ignore specific files or folders, or the `files` array in `package.json` can act as an allow list.
**Otherwise:** Your project's API keys, passwords or other secrets are open to be abused by anyone who comes across them, which may result in financial loss, impersonation, and other risks.
-🔗 [**Read More: Avoid publishing secrets**](/sections/security/avoid_publishing_secrets.md)
+🔗 [**Read More: Avoid publishing secrets**](./sections/security/avoid_publishing_secrets.md)
+
+
+
+## ![✔] 6.26 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 outdated packages, 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
+
+
+
+## ![✔] 6.27. Import built-in modules using the 'node:' protocol
+
+### `🌟 #new`
+
+
+
+**TL;DR:** Import or require built-in Node.js modules using the 'node protocol' syntax:
+
+```javascript
+import { functionName } from "node:module"; // note that 'node:' prefix
+```
+
+For example:
+
+```javascript
+import { createServer } from "node:http";
+```
+
+This style ensures that there is no ambiguity with global npm packages and makes it clear for the reader that the code refers to a well-trusted official module. This style can be enforced with the eslint rule ['prefer-node-protocol'](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md)
+
+**Otherwise:** Using the import syntax without 'node:' prefix opens the door for [typosquatting attacks](https://en.wikipedia.org/wiki/Typosquatting) where one could mistakenly mistype a module name (e.g., 'event' instead of 'events) and get a malicious package that was built only to trick users into installing them
+
# `7. Draft: Performance Best Practices`
-## Our contributors are working on this section. [Would you like to join?](https://github.com/i0natan/nodebestpractices/issues/256)
+## Our contributors are working on this section. [Would you like to join?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
@@ -1038,26 +1403,210 @@ All statements above will return false if used with `===`
**Otherwise:** As the Event Loop is blocked, Node.js will be unable to handle other request thus causing delays for concurrent users. **3000 users are waiting for a response, the content is ready to be served, but one single request blocks the server from dispatching the results back**
-🔗 [**Read More: Do not block the event loop**](/sections/performance/block-loop.md)
+🔗 [**Read More: Do not block the event loop**](./sections/performance/block-loop.md)
-
## ![✔] 7.2. Prefer native JS methods over user-land utils like Lodash
- **TL;DR:** It's often more penalising to use utility libraries like `lodash` and `underscore` over native methods as it leads to unneeded dependencies and slower performance.
- Bear in mind that with the introduction of the new V8 engine alongside the new ES standards, native methods were improved in such a way that it's now about 50% more performant than utility libraries.
+**TL;DR:** It's often more penalising to use utility libraries like `lodash` and `underscore` over native methods as it leads to unneeded dependencies and slower performance.
+Bear in mind that with the introduction of the new V8 engine alongside the new ES standards, native methods were improved in such a way that it's now about 50% more performant than utility libraries.
**Otherwise:** You'll have to maintain less performant projects where you could have simply used what was **already** available or dealt with a few more lines in exchange of a few more files.
-🔗 [**Read More: Native over user land utils**](/sections/performance/nativeoverutil.md)
+🔗 [**Read More: Native over user land utils**](./sections/performance/nativeoverutil.md)
+
+# `8. Docker Best Practices`
+
+🏅 Many thanks to [Bret Fisher](https://github.com/BretFisher) from whom we learned many of the following practices
+
+
+
+## ![✔] 8.1 Use multi-stage builds for leaner and more secure Docker images
+
+**TL;DR:** Use multi-stage build to copy only necessary production artifacts. A lot of build-time dependencies and files are not needed for running your application. With multi-stage builds these resources can be used during build while the runtime environment contains only what's necessary. Multi-stage builds are an easy way to get rid of overweight and security threats.
+
+**Otherwise:** Larger images will take longer to build and ship, build-only tools might contain vulnerabilities and secrets only meant for the build phase might be leaked.
+
+### Example Dockerfile for multi-stage builds
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY . .
+RUN npm ci && npm run build
+
+
+FROM node:slim-14.4.0
+
+USER node
+EXPOSE 8080
+
+COPY --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/package-lock.json ./
+RUN npm ci --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+🔗 [**Read More: Use multi-stage builds**](./sections/docker/multi_stage_builds.md)
+
+
+
+## ![✔] 8.2. Bootstrap using `node` command, avoid `npm start`
+
+**TL;DR:** Use `CMD ['node','server.js']` to start your app, avoid using npm scripts which don't pass OS signals to the code. This prevents problems with child-processes, signal handling, graceful shutdown and having zombie processes
+
+Update: [Starting from npm 7, npm claim](https://docs.npmjs.com/cli/v7/using-npm/changelog#706-2020-10-27) to pass signals. We follow and will update accordingly
+
+**Otherwise:** When no signals are passed, your code will never be notified about shutdowns. Without this, it will lose its chance to close properly possibly losing current requests and/or data
+
+[**Read More: Bootstrap container using node command, avoid npm start**](./sections/docker/bootstrap-using-node.md)
+
+
+
+## ![✔] 8.3. Let the Docker runtime handle replication and uptime
+
+**TL;DR:** When using a Docker run time orchestrator (e.g., Kubernetes), invoke the Node.js process directly without intermediate process managers or custom code that replicate the process (e.g. PM2, Cluster module). The runtime platform has the highest amount of data and visibility for making placement decision - It knows best how many processes are needed, how to spread them and what to do in case of crashes
+
+**Otherwise:** Container keeps crashing due to lack of resources will get restarted indefinitely by the process manager. Should Kubernetes be aware of that, it could relocate it to a different roomy instance
+
+🔗 [**Read More: Let the Docker orchestrator restart and replicate processes**](./sections/docker/restart-and-replicate-processes.md)
+
+
+
+## ![✔] 8.4. Use .dockerignore to prevent leaking secrets
+
+**TL;DR**: Include a `.dockerignore` file that filters out common secret files and development artifacts. By doing so, you might prevent secrets from leaking into the image. As a bonus the build time will significantly decrease. Also, ensure not to copy all files recursively rather explicitly choose what should be copied to Docker
+
+**Otherwise**: Common personal secret files like `.env`, `.aws` and `.npmrc` will be shared with anybody with access to the image (e.g. Docker repository)
+
+🔗 [**Read More: Use .dockerignore**](./sections/docker/docker-ignore.md)
+
+
+
+## ![✔] 8.5. Clean-up dependencies before production
+
+**TL;DR:** Although Dev-Dependencies are sometimes needed during the build and test life-cycle, eventually the image that is shipped to production should be minimal and clean from development dependencies. Doing so guarantees that only necessary code is shipped and the amount of potential attacks (i.e. attack surface) is minimized. When using multi-stage build (see dedicated bullet) this can be achieved by installing all dependencies first and finally running `npm ci --production`
+
+**Otherwise:** Many of the infamous npm security breaches were found within development packages (e.g. [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes))
+
+🔗 Read More: [Remove development dependencies](./sections/docker/install-for-production.md)
+
+
+
+## ![✔] 8.6. Shutdown smartly and gracefully
+
+**TL;DR:** Handle the process SIGTERM event and clean-up all existing connection and resources. This should be done while responding to ongoing requests. In Dockerized runtimes, shutting down containers is not a rare event, rather a frequent occurrence that happen as part of routine work. Achieving this demands some thoughtful code to orchestrate several moving parts: The load balancer, keep-alive connections, the HTTP server and other resources
+
+**Otherwise:** Dying immediately means not responding to thousands of disappointed users
+
+🔗 [**Read More: Graceful shutdown**](./sections/docker/graceful-shutdown.md)
+
+
+
+## ![✔] 8.7. Set memory limits using both Docker and v8
+
+**TL;DR:** Always configure a memory limit using both Docker and the JavaScript runtime flags. The Docker limit is needed to make thoughtful container placement decision, the --v8's flag max-old-space is needed to kick off the GC on time and prevent under utilization of memory. Practically, set the v8's old space memory to be a just bit less than the container limit
+
+**Otherwise:** The docker definition is needed to perform thoughtful scaling decision and prevent starving other citizens. Without also defining the v8's limits, it will under utilize the container resources - Without explicit instructions it crashes when utilizing ~50-60% of its host resources
+
+🔗 [**Read More: Set memory limits using Docker only**](./sections/docker/memory-limit.md)
+
+
+
+## ![✔] 8.8. Plan for efficient caching
+
+**TL;DR:** Rebuilding a whole docker image from cache can be nearly instantaneous if done correctly. The less updated instructions should be at the top of your Dockerfile and the ones constantly changing (like app code) should be at the bottom.
+
+**Otherwise:** Docker build will be very long and consume lot of resources even when making tiny changes
+
+🔗 [**Read More: Leverage caching to reduce build times**](./sections/docker/use-cache-for-shorter-build-time.md)
+
+
+
+## ![✔] 8.9. Use explicit image reference, avoid `latest` tag
+
+**TL;DR:** Specify an explicit image digest or versioned label, never refer to `latest`. Developers are often led to believe that specifying the `latest` tag will provide them with the most recent image in the repository however this is not the case. Using a digest guarantees that every instance of the service is running exactly the same code.
+
+In addition, referring to an image tag means that the base image is subject to change, as image tags cannot be relied upon for a deterministic install. Instead, if a deterministic install is expected, a SHA256 digest can be used to reference an exact image.
+
+**Otherwise:** A new version of a base image could be deployed into production with breaking changes, causing unintended application behaviour.
+
+🔗 [**Read More: Understand image tags and use the "latest" tag with caution**](./sections/docker/image-tags.md)
+
+
+
+## ![✔] 8.10. Prefer smaller Docker base images
+
+**TL;DR:** Large images lead to higher exposure to vulnerabilities and increased resource consumption. Using leaner Docker images, such as Slim and Alpine Linux variants, mitigates this issue.
+
+**Otherwise:** Building, pushing, and pulling images will take longer, unknown attack vectors can be used by malicious actors and more resources are consumed.
+
+🔗 [**Read More: Prefer smaller images**](./sections/docker/smaller_base_images.md)
+
+
+
+## ![✔] 8.11. Clean-out build-time secrets, avoid secrets in args
+
+### `🌟 #new`
+
+**TL;DR:** Avoid secrets leaking from the Docker build environment. A Docker image is typically shared in multiple environment like CI and a registry that are not as sanitized as production. A typical example is an npm token which is usually passed to a dockerfile as argument. This token stays within the image long after it is needed and allows the attacker indefinite access to a private npm registry. This can be avoided by coping a secret file like `.npmrc` and then removing it using multi-stage build (beware, build history should be deleted as well) or by using Docker build-kit secret feature which leaves zero traces
+
+**Otherwise:** Everyone with access to the CI and docker registry will also get access to some precious organization secrets as a bonus
+
+🔗 [**Read More: Clean-out build-time secrets**](./sections/docker/avoid-build-time-secrets.md)
+
+
+
+## ![✔] 8.12. Scan images for multi layers of vulnerabilities
+
+**TL;DR:** Besides checking code dependencies vulnerabilities also scan the final image that is shipped to production. Docker image scanners check the code dependencies but also the OS binaries. This E2E security scan covers more ground and verifies that no bad guy injected bad things during the build. Consequently, it is recommended running this as the last step before deployment. There are a handful of free and commercial scanners that also provide CI/CD plugins
+
+**Otherwise:** Your code might be entirely free from vulnerabilities. However it might still get hacked due to vulnerable version of OS-level binaries (e.g. OpenSSL, TarBall) that are commonly being used by applications
+
+🔗 [**Read More: Scan the entire image before production**](./sections/docker/scan-images.md)
+
+
+
+## ![✔] 8.13 Clean NODE_MODULE cache
+
+**TL;DR:** After installing dependencies in a container remove the local cache. It doesn't make any sense to duplicate the dependencies for faster future installs since there won't be any further installs - A Docker image is immutable. Using a single line of code tens of MB (typically 10-50% of the image size) are shaved off
+
+**Otherwise:** The image that will get shipped to production will weigh 30% more due to files that will never get used
+
+🔗 [**Read More: Clean NODE_MODULE cache**](./sections/docker/clean-cache.md)
+
+
+
+## ![✔] 8.14. Generic Docker practices
+
+**TL;DR:** This is a collection of Docker advice that is 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: Generic Docker practices**](./sections/docker/generic-tips.md)
+
+
+
+## ![✔] 8.15. Lint your Dockerfile
+
+### `🌟 #new`
+
+**TL;DR:** Linting your Dockerfile is an important step to identify issues in your Dockerfile which differ from best practices. By checking for potential flaws using a specialised Docker linter, performance and security improvements can be easily identified, saving countless hours of wasted time or security issues in production code.
+
+**Otherwise:** Mistakenly the Dockerfile creator left Root as the production user, and also used an image from unknown source repository. This could be avoided with with just a simple linter.
+
+🔗 [**Read More: Lint your Dockerfile**](./sections/docker/lint-dockerfile.md)
+
+
# 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
+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/goldbergyoni/nodebestpractices/milestones) and join the working groups if you want to contribute to this project
@@ -1067,84 +1616,361 @@ All translations are contributed by the community. We will be happy to get any h
### Completed translations
--  [Brazilian Portuguese](./README.brazilian-portuguese.md) - Courtesy of [Marcelo Melo](https://github.com/marcelosdm)
--  [Chinese](./README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
--  [Russian](./README.russian.md) - Courtesy of [Alex Ivanov](https://github.com/contributorpw)
+-  [Brazilian Portuguese](./README.brazilian-portuguese.md) - Courtesy of [Marcelo Melo](https://github.com/marcelosdm)
+-  [Chinese](./README.chinese.md) - Courtesy of [Matt Jin](https://github.com/mattjin)
+-  [Russian](./README.russian.md) - Courtesy of [Alex Ivanov](https://github.com/contributorpw)
+-  [Polish](./README.polish.md) - Courtesy of [Michal Biesiada](https://github.com/mbiesiad)
+-  [Japanese](./README.japanese.md) - Courtesy of [Yuki Ota](https://github.com/YukiOta), [Yuta Azumi](https://github.com/YA21)
+-  [Basque](README.basque.md) - Courtesy of [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuesta
### Translations in progress
--  [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/129))
--  Hebrew ([Discussion](https://github.com/i0natan/nodebestpractices/issues/156))
--  [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/94))
--  [Spanish](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/95))
--  Turkish ([Discussion](https://github.com/i0natan/nodebestpractices/issues/139))
+-  [French](./README.french.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  [Hebrew](./README.hebrew.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Spanish](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turkish ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/139))
## Steering Committee
-Meet the steering committee members - the people who work together to provide guidance and future direction to the project. In addition, each member of the committee leads a project tracked under our [Github projects](https://github.com/i0natan/nodebestpractices/projects).
+Meet the steering committee members - the people who work together to provide guidance and future direction to the project. In addition, each member of the committee leads a project tracked under our [GitHub projects](https://github.com/goldbergyoni/nodebestpractices/projects).
-
+
-[Yoni Goldberg](https://github.com/i0natan)
-
-
+[Yoni Goldberg](https://github.com/goldbergyoni)
+
+
-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 at [goldbergyoni.com](https://goldbergyoni.com). Reach Yoni at @goldbergyoni or me@goldbergyoni.com
+Independent Node.js consultant who works with customers in the USA, Europe, and Israel on building large-scale Node.js applications. Many of the best practices above were first published at [goldbergyoni.com](https://goldbergyoni.com). Reach Yoni at [@goldbergyoni](https://github.com/goldbergyoni) or [me@goldbergyoni.com](mailto:me@goldbergyoni.com)
-
+
-[Bruno Scheufler](https://github.com/BrunoScheufler)
-
+[Josh Hemphill](https://github.com/josh-hemphill)
+
+
+
-💻 full-stack web engineer, Node.js & GraphQL enthusiast
+Full Stack Software Engineer / Developer specializing in Security, DevOps/DevSecOps, and ERP Integrations.
-
+
-[Kyle Martin](https://github.com/js-kyle)
-
-
+[Raz Luvaton](https://github.com/rluvaton)
+
+
-Full Stack Developer & Site Reliability Engineer based in New Zealand, interested in web application security, and architecting and building Node.js applications to perform at global scale.
+Full Stack Developer who knows how to exit from Vim and loves Architecture, Virtualization and Security.
-
+## Contributing
+
+If you've ever wanted to contribute to open source, now is your chance! See the [contributing docs](.operations/CONTRIBUTING.md) for more information.
+
+## Contributors ✨
+
+Thanks goes to these wonderful people who have contributed to this repository!
+
+
+
+
+
+
+
+
+
+
+
+### Steering Committee Emeriti
-[Sagir Khan](https://github.com/sagirk)
-
-
-
+[Bruno Scheufler](https://github.com/BrunoScheufler)
+
-Deep specialist in JavaScript and its ecosystem — React, Node.js, MongoDB, pretty much anything that involves using JavaScript/JSON in any layer of the system — building products using the web platform for the world’s most recognized brands. Individual Member of the Node.js Foundation, collaborating on the Community Committee's Website Redesign Initiative.
+💻 full-stack web engineer, Node.js & GraphQL enthusiast
-## Collaborators
+
-Thank you to all our collaborators! 🙏
+[Kyle Martin](https://github.com/js-kyle)
+
+
-Our collaborators are members who are contributing to the repository on a regular basis, through suggesting new best practices, triaging issues, reviewing pull requests and more. If you are interested in helping us guide thousands of people to craft better Node.js applications, please read our [contributor guidelines](/.operations/CONTRIBUTING.md) 🎉
+Full Stack Developer & Site Reliability Engineer based in New Zealand, interested in web application security, and architecting and building Node.js applications to perform at global scale.
-| | |
-| :--: | :--: |
-| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
+
-### Past collaborators
+
-| |
-| :--: |
-| [Refael Ackermann](https://github.com/refack) |
+[Kevyn Bruyere](https://github.com/kevynb)
+
+
+Independent full-stack developer with a taste for Ops and automation.
-## Thank You Notes
+
-We appreciate any contribution, from a single word fix to a new best practice. View our contributors and [contributing documentation here!](CONTRIBUTORS.md)
+[Sagir Khan](https://github.com/sagirk)
+
+
+
-
+Deep specialist in JavaScript and its ecosystem — React, Node.js, TypeScript, GraphQL, MongoDB, pretty much anything that involves JS/JSON in any layer of the system — building products using the web platform for the world’s most recognized brands. Individual Member of the Node.js Foundation.
diff --git a/README.polish.md b/README.polish.md
new file mode 100644
index 000000000..3fdae83d2
--- /dev/null
+++ b/README.polish.md
@@ -0,0 +1,1148 @@
+[✔]: assets/images/checkbox-small-blue.png
+
+# Node.js - Najlepsze praktyki
+
+
+
+
+
+
+
+
+
+
+
+
+
+[](https://twitter.com/nodepractices/) **Follow us on Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
+
+
+
+Przeczytaj także w innych językach: [**CN**](./README.chinese.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**EU**](./README.basque.md) [(**ES**, **FR**, **HE**, **KR**, **TR** w trakcie! )](#tłumaczenia)
+
+
+
+###### Zbudowane i utrzymywane przez nasz [Steering Committee](#steering-committee) oraz [Collaborators](#współpracownicy)
+
+# Najnowsze najlepsze praktyki i aktualności
+
+- **✅ Nowa najlepsza praktyka:** 7.1: [Nie blokuj pętli zdarzeń](#7-wersja-robocza-najlepsze-praktyki-dotyczące-wydajności) od Keith Holliday
+
+- **🇷🇺 Rosyjskie tłumaczenie:** Niesamowity Alex Ivanov właśnie opublikował [rosyjskie tłumaczenie](./README.russian.md)
+
+- **Szukamy autorów TypeScript:** chcesz pomóc w tworzeniu przykładów TypeScript? Weź udział, otwierając issue
+
+
+
+# Witamy! 3 rzeczy, które musisz wiedzieć na początku
+
+**1. W rzeczywistości czytasz dziesiątki najlepszych artykułów na temat Node.js -** to repozytorium jest podsumowaniem i zbiorem najlepszych pozycji na temat najlepszych praktyk Node.js, a także treści napisanych tutaj przez współpracowników
+
+**2. Jest to największa kompilacja, która rośnie z każdym tygodniem -** obecnie prezentowanych jest ponad 80 najlepszych praktyk, przewodników po stylach i wskazówek architektonicznych. Nowe wydania i pull requesty są tworzone codziennie, aby aktualizować tę książkę na żywo. Chcielibyśmy zobaczyć Twój wkład w to, czy naprawiasz błędy w kodzie, pomagasz w tłumaczeniach, czy sugerujesz nowe genialne pomysły. Zobacz nasze [wskazówki dotyczące pisania tutaj](https://github.com/mbiesiad/nodebestpractices/blob/master/.operations/writing-guidelines.polish.md)
+
+**3. Większość najlepszych praktyk ma dodatkowe informacje -** większość pocisków zawiera link **🔗Przeczytaj więcej**, który rozszerza praktykę o przykłady kodu, cytaty z wybranych blogów i więcej informacji
+
+
+## Spis treści
+
+1. [Praktyki dotyczące struktury projektu (5)](#1-praktyki-dotyczące-struktury-projektu)
+2. [Procedury obsługi błędów (11) ](#2-procedury-obsługi-błędów)
+3. [Praktyki stylu kodu (12) ](#3-praktyki-stylu-kodu)
+4. [Testy i ogólne praktyki jakości (12) ](#4-testy-i-ogólne-praktyki-jakości)
+5. [Przejście do praktyk produkcyjnych (18) ](#5-przejście-do-praktyk-produkcyjnych)
+6. [Praktyki bezpieczeństwa (25)](#6-najlepsze-praktyki-bezpieczeństwa)
+7. [Praktyki wydajnościowe (2) (Work In Progress️ ✍️)](#7-wersja-robocza-najlepsze-praktyki-dotyczące-wydajności)
+
+
+
+# `1. Praktyki dotyczące struktury projektu`
+
+## ![✔] 1.1 Skonstruuj swoje rozwiązanie według komponentów
+
+**TL;DR:** Najgorszym problemem związanym z dużymi aplikacjami jest utrzymanie ogromnej bazy kodu z setkami zależności - taki monolit spowalnia programistów, którzy próbują wprowadzić nowe funkcje. Zamiast tego podziel kod na części, każdy otrzyma własny folder lub dedykowaną bazę kodów i zapewni, że każda jednostka będzie niewielka i prosta. Odwiedź „Czytaj więcej” poniżej, aby zobaczyć przykłady prawidłowej struktury projektu
+
+**W przeciwnym razie:** Gdy programiści, którzy kodują nowe funkcje, walczą o uświadomienie sobie wpływu ich zmian i boją się zniszczyć inne zależne komponenty - wdrożenia stają się wolniejsze i bardziej ryzykowne. Trudniej jest także skalować, gdy wszystkie jednostki biznesowe nie są rozdzielone
+
+🔗 [**Czytaj więcej: struktura według komponentów**](./sections/projectstructre/breakintcomponents.polish.md)
+
+
+
+## ![✔] 1.2 Nakładaj warstwy na komponenty, zachowując Express w granicach
+
+**TL;DR:** Każdy komponent powinien zawierać „warstwy” - dedykowany obiekt dla sieci, logiki i kodu dostępu do danych. Nie tylko pozwala to na wyraźne oddzielenie problemów, ale także znacznie ułatwia mockowanie i testowanie systemu. Chociaż jest to bardzo powszechny wzorzec, programiści API mają tendencję do mieszania warstw, przekazując obiekty warstwy internetowej (wymagania Express, res) do logiki biznesowej i warstw danych - dzięki temu aplikacja jest zależna i dostępna tylko przez Express
+
+**W przeciwnym razie:** Nie można uzyskać dostępu do aplikacji, która miesza obiekty internetowe z innymi warstwami, testując kod, zadania CRON i inne obiekty wywołujące inne niż Express
+
+🔗 [**Czytaj więcej: warstwa twojej aplikacji**](./sections/projectstructre/createlayers.polish.md)
+
+
+
+## ![✔] 1.3 Opakuj typowe narzędzia jako pakiety npm
+
+**TL;DR:** W dużej aplikacji, która stanowi dużą bazę kodu, kluczowe narzędzia, takie jak rejestrator, szyfrowanie i podobne, powinny być owinięte własnym kodem i udostępnione jako prywatne pakiety npm. Pozwala to na dzielenie się nimi między wieloma bazami kodów i projektami
+
+**W przeciwnym razie:** Będziesz musiał wymyślić własne koło wdrażania i zależności
+
+🔗 [**Czytaj więcej: Struktura według funkcji**](./sections/projectstructre/wraputilities.polish.md)
+
+
+
+## ![✔] 1.4 Oddzielna „aplikacja” i „serwer” Express
+
+**TL;DR:** Unikaj nieprzyjemnego nawyku definiowania całości aplikacji [Express](https://expressjs.com/) w jednym dużym pliku - rozdziel definicję „Express” na co najmniej dwa pliki: deklarację API (app.js) i problemy z siecią (WWW). Aby uzyskać jeszcze lepszą strukturę, znajdź deklarację API w komponentach
+
+**W przeciwnym razie:** Twój interfejs API będzie dostępny do testowania tylko za pośrednictwem połączeń HTTP (wolniejsze i znacznie trudniejsze do generowania raportów zasięgu). Utrzymanie setek linii kodu w jednym pliku prawdopodobnie nie będzie wielką przyjemnością
+
+🔗 [**Czytaj więcej: oddzielna aplikacja „Express” i „serwer”**](./sections/projectstructre/separateexpress.polish.md)
+
+
+
+## ![✔] 1.5 Używaj konfiguracji przyjaznej środowisku, bezpiecznej i hierarchicznej
+
+**TL;DR:** Idealne i bezbłędne ustawienie konfiguracji powinno zapewnić, że (a) klucze można odczytać z pliku ORAZ ze zmiennych środowiskowych (b) dane wrażliwe są przechowywane poza zatwierdzonym kodem (c) konfiguracja jest hierarchiczna dla łatwiejszego wyszukiwania. Istnieje kilka pakietów, które mogą pomóc zaznaczyć większość z tych pól, takich jak [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) i [convict](https://www.npmjs.com/package/convict)
+
+**W przeciwnym razie:** Niespełnienie któregokolwiek z wymagań konfiguracji po prostu ugrzęźnie w zespole programistów lub DevOps. Prawdopodobnie jedno i drugie
+
+🔗 [**Czytaj więcej: najlepsze praktyki dotyczące konfiguracji**](./sections/projectstructre/configguide.polish.md)
+
+
+
+# `2. Procedury obsługi błędów`
+
+## ![✔] 2.1 Użyj Async-Await lub promises do obsługi błędów asynchronicznych
+
+**TL;DR:** Obsługa błędów asynchronicznych w stylu wywołania zwrotnego jest prawdopodobnie najszybszą drogą do piekła (znane też jako Piramida zagłady). Najlepszy prezent, jaki możesz dać kodowi, to skorzystanie z renomowanej biblioteki promise lub async-await zamiast tego, co umożliwia znacznie bardziej zwartą i znaną składnię kodu, taką jak try-catch
+
+**W przeciwnym razie:** styl wywołania zwrotnego Node.js, funkcja (błąd, odpowiedź) jest obiecującym sposobem na niemożliwy do utrzymania kod ze względu na połączenie obsługi błędów z przypadkowym kodem, nadmiernym zagnieżdżaniem i niewygodnymi wzorcami kodowania
+
+🔗 [**Czytaj więcej: avoiding callbacks**](./sections/errorhandling/asyncerrorhandling.polish.md)
+
+
+
+## ![✔] 2.2 Używaj tylko wbudowanego obiektu Error
+
+**TL;DR:** Wiele z nich wyrzuca błędy jako ciąg znaków lub jako niestandardowy typ - komplikuje to logikę obsługi błędów i interoperacyjność między modułami. Niezależnie od tego, czy odrzucisz promise, rzucisz wyjątek, czy wyślesz błąd - użycie tylko wbudowanego obiektu Error (lub obiektu, który rozszerza wbudowany obiekt Error) zwiększy jednolitość i zapobiegnie utracie informacji
+
+**W przeciwnym razie:** Podczas wywoływania jakiegoś komponentu brak pewności, jaki rodzaj błędów w zamian wraca - znacznie utrudnia prawidłowe zarządzanie błędami. Co gorsza, używanie niestandardowych typów do opisywania błędów może prowadzić do utraty krytycznych informacji o błędach, takich jak stack trace!
+
+🔗 [**Czytaj więcej: using the built-in error object**](./sections/errorhandling/useonlythebuiltinerror.polish.md)
+
+
+
+## ![✔] 2.3 Rozróżnij błędy operacyjne i programistyczne
+
+**TL;DR:** Błędy operacyjne (np. API otrzymało niepoprawne dane wejściowe) odnoszą się do znanych przypadków, w których wpływ błędu jest w pełni zrozumiały i można go starannie rozpatrzyć. Z drugiej strony błąd programisty (np. próba odczytania niezdefiniowanej zmiennej) odnosi się do nieznanych błędów kodu, które zmuszają do płynnego restartu aplikacji
+
+**W przeciwnym razie:** Zawsze możesz ponownie uruchomić aplikację, gdy pojawi się błąd, ale dlaczego zawieść ~5000 użytkowników online z powodu drobnego, przewidywanego błędu operacyjnego? Drugie rozwiązanie nie jest też idealne - utrzymanie aplikacji w stanie, gdy wystąpi nieznany problem (błąd programisty), może prowadzić do nieprzewidzianego zachowania. Rozróżnienie tych dwóch pozwala działać taktownie i stosować zrównoważone podejście oparte na danym kontekście
+
+🔗 [**Czytaj więcej: operational vs programmer error**](./sections/errorhandling/operationalvsprogrammererror.polish.md)
+
+
+
+## ![✔] 2.4 Obsługuj błędy centralnie, a nie w oprogramowaniu pośrednim Express
+
+**TL;DR:** Obsługa błędów związanych z logiką, taką jak poczta do administratora i rejestrowanie, powinna być zamknięta w dedykowanym i scentralizowanym obiekcie, do którego wywoływane są wszystkie punkty końcowe (np. Express middleware, zadania cron, testy jednostkowe), gdy pojawia się błąd
+
+**W przeciwnym razie:** Brak obsługi błędów w jednym miejscu prowadzi do duplikacji kodu i prawdopodobnie do nieprawidłowej obsługi błędów
+
+🔗 [**Czytaj więcej: handling errors in a centralized place**](./sections/errorhandling/centralizedhandling.polish.md)
+
+
+
+## ![✔] 2.5 Dokumentuj błędy interfejsu API za pomocą Swagger lub GraphQL
+
+**TL;DR:** Poinformuj osoby odwołujące się do interfejsu API, które błędy mogą w zamian otrzymać, aby mogły je starannie obsługiwać bez awarii. W przypadku interfejsów API RESTful odbywa się to zwykle w ramach frameworków takich jak Swagger. Jeśli korzystasz z GraphQL, możesz również wykorzystać swój schemat i komentarze.
+
+**W przeciwnym razie:** Klient API może zdecydować o awarii i ponownym uruchomieniu tylko dlatego, że otrzymał błąd, którego nie mógł zrozumieć. Uwaga: osobą wywołującą interfejs API możesz być Ty (bardzo typowe w środowisku mikrousług)
+
+🔗 [**Czytaj więcej: documenting API errors in Swagger or GraphQL**](./sections/errorhandling/documentingusingswagger.polish.md)
+
+
+
+## ![✔] 2.6 Opuść ten proces z wdziękiem, gdy do miasta przyjedzie nieznajomy
+
+**TL;DR:** Gdy wystąpi nieznany błąd (błąd programisty, patrz najlepsza praktyka 2.3) - nie ma pewności co do kondycji aplikacji. Powszechna praktyka sugeruje ostrożne ponowne uruchomienie procesu za pomocą narzędzia do zarządzania procesami, takiego jak [Forever](https://www.npmjs.com/package/forever) lub [PM2](http://pm2.keymetrics.io/)
+
+**W przeciwnym razie:** Gdy wystąpi nieznany wyjątek, niektóre obiekty mogą znajdować się w stanie wadliwym (np. Emiter zdarzeń, który jest używany globalnie i nie uruchamia już zdarzeń z powodu pewnych wewnętrznych awarii), a wszystkie przyszłe żądania mogą zawieść lub zachowywać się szaleńczo
+
+🔗 [**Czytaj więcej: shutting the process**](./sections/errorhandling/shuttingtheprocess.polish.md)
+
+
+
+## ![✔] 2.7 Użyj dojrzałego programu rejestrującego, aby zwiększyć widoczność błędów
+
+**TL;DR:** Zestaw dojrzałych narzędzi do rejestrowania, takich jak [Winston](https://www.npmjs.com/package/winston), [Bunyan](https://github.com/trentm/node-bunyan), [Log4js](http://stritti.github.io/log4js/) lub [Pino](https://github.com/pinojs/pino), przyspieszy wykrywanie błędów i zrozumienie. Więc zapomnij o console.log
+
+**W przeciwnym razie:** Przeglądanie w pliku console.logs lub ręcznie przez niechlujny plik tekstowy bez korzystania z narzędzi zapytań lub porządnej przeglądarki dziennika może być zajęciem w pracy do późna
+
+🔗 [**Czytaj więcej: using a mature logger**](./sections/errorhandling/usematurelogger.polish.md)
+
+
+
+## ![✔] 2.8 Przepływy błędów testowych przy użyciu ulubionego środowiska testowego
+
+**TL;DR:** Niezależnie od tego, czy jest to profesjonalna automatyczna kontrola jakości, czy zwykłe ręczne testowanie programisty - upewnij się, że Twój kod nie tylko spełnia pozytywne scenariusze, ale także obsługuje i zwraca odpowiednie błędy. Ramy testowe, takie jak Mocha i Chai, mogą sobie z tym poradzić (zobacz przykłady kodu w "Gist popup")
+
+**W przeciwnym razie:** Bez testowania, automatycznie lub ręcznie, nie można polegać na kodzie, który zwraca prawidłowe błędy. Bez znaczących błędów - nie ma obsługi błędów
+
+🔗 [**Czytaj więcej: testing error flows**](./sections/errorhandling/testingerrorflows.polish.md)
+
+
+
+## ![✔] 2.9 Odkryj błędy i przestoje przy użyciu produktów APM
+
+**TL;DR:** Produkty do monitorowania i wydajności (np. APM) proaktywnie oceniają twoją bazę kodu lub interfejs API, aby mogły automatycznie zaznaczać błędy, awarie i spowalniające brakujące części
+
+**W przeciwnym razie:** Możesz poświęcić wiele wysiłku na pomiar wydajności interfejsu API i przestojów, prawdopodobnie nigdy nie będziesz wiedział, jakie są twoje najwolniejsze części kodu w rzeczywistym scenariuszu i jak wpływają one na UX
+
+🔗 [**Czytaj więcej: using APM products**](./sections/errorhandling/apmproducts.polish.md)
+
+
+
+## ![✔] 2.10 Złap nieobsługiwane odrzucenia promise
+
+**TL;DR:** Każdy wyjątek zgłoszony w ramach promise zostanie połknięty i odrzucony, chyba że programista nie zapomni o jawnej obsłudze. Nawet jeśli Twój kod jest subskrybowany w `process.uncaughtException`! Sforsuj to, rejestrując się na wydarzeniu `process.unhandledRejection`
+
+**W przeciwnym razie:** Twoje błędy zostaną połknięte i nie pozostawiają śladu. Nie ma się o co martwić
+
+🔗 [**Czytaj więcej: catching unhandled promise rejection**](./sections/errorhandling/catchunhandledpromiserejection.polish.md)
+
+
+
+## ![✔] 2.11 Szybko się nie powiedzie, sprawdź poprawność argumentów za pomocą dedykowanej biblioteki
+
+**TL;DR:** Powinno to być częścią najlepszych praktyk Express - Assert API, aby uniknąć nieprzyjemnych błędów, które później będą znacznie trudniejsze do wyśledzenia. Kod weryfikacyjny jest zwykle uciążliwy, chyba że używasz bardzo fajnej biblioteki pomocniczej, takiej jak Joi
+
+**W przeciwnym razie:** Rozważ to - twoja funkcja oczekuje argumentu liczbowego „Discount”, który wywołujący zapomina przekazać, a następnie kod sprawdza, czy Discount!=0 (kwota dozwolonego discounta jest większa od zera), a następnie pozwoli użytkownikowi cieszyć się discountem. OMG, co za paskudny błąd. Widzisz to?
+
+🔗 [**Czytaj więcej: failing fast**](./sections/errorhandling/failfast.polish.md)
+
+
+
+# `3. Praktyki stylu kodu`
+
+## ![✔] 3.1 Użyj ESLint
+
+**TL;DR:** [ESLint](https://eslint.org) jest de facto standardem sprawdzania możliwych błędów kodu i ustalania stylu kodu, nie tylko w celu zidentyfikowania drobiazgowych problemów z odstępami, ale także w celu wykrycia poważnych anty-wzorców kodu, takich jak programiści zgłaszający błędy bez klasyfikacji. Chociaż ESLint może automatycznie naprawiać style kodu, inne narzędzia, takie jak [prettier](https://www.npmjs.com/package/prettier) i [beautify](https://www.npmjs.com/package/js-beautify) mają większą moc formatowania poprawki i współpracują z ESLint
+
+**W przeciwnym razie:** Programiści skoncentrują się na żmudnych odstępach i problemach z szerokością linii, a czas może zostać zmarnowany na przemyślenie stylu kodu projektu
+
+🔗 [**Czytaj więcej: Using ESLint and Prettier**](./sections/codestylepractices/eslint_prettier.polish.md)
+
+
+
+## ![✔] 3.2 Specyficzne wtyczki Node.js
+
+**TL;DR:** Oprócz standardowych reguł ESLint obejmujących vanilla JavaScript, dodaj wtyczki Node.js, takie jak [eslint-plugin-node](https://www.npmjs.com/package/eslint-plugin-node), [eslint-plugin- mocha](https://www.npmjs.com/package/eslint-plugin-mocha) i [eslint-plugin-node-security](https://www.npmjs.com/package/eslint-plugin-security)
+
+**W przeciwnym razie:** Wiele wadliwych wzorców kodu Node.js może uciekać pod radarem. Na przykład programiści mogą wymagać plików (zmiennaAsPath) ze zmienną podaną jako ścieżka, która umożliwia atakującym wykonanie dowolnego skryptu JS. Linters Node.js mogą wcześnie wykrywać takie wzorce i narzekać
+
+
+
+## ![✔] 3.3 Uruchom nawiasy klamrowe Codeblock na tej samej linii
+
+**TL;DR:** Nawiasy klamrowe otwierające bloki kodu powinny znajdować się w tym samym wierszu, co instrukcja otwierająca
+
+### Przykład kodu
+
+```javascript
+// Do
+function someFunction() {
+ // code block
+}
+
+// Avoid
+function someFunction()
+{
+ // code block
+}
+```
+
+**W przeciwnym razie:** Odstąpienie od tej najlepszej praktyki może prowadzić do nieoczekiwanych rezultatów, jak widać w poniższym wątku StackOverflow:
+
+🔗 [**Czytaj więcej:** "Why do 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 Oddziel swoje deklaracje poprawnie
+
+Bez względu na to, czy używasz średników, czy też nie rozdzielasz swoich instrukcji, znajomość typowych pułapek niewłaściwych podziałów linii lub automatycznego wstawiania średników pomoże Ci wyeliminować regularne błędy składniowe.
+
+**TL;DR:** Użyj ESLint, aby zyskać świadomość problemów związanych z separacją. [Prettier](https://prettier.io/) lub [Standardjs](https://standardjs.com/) może automatycznie rozwiązać te issues.
+
+**W przeciwnym razie:** Jak widać w poprzedniej sekcji, interpreter JavaScript automatycznie dodaje średnik na końcu instrukcji, jeśli nie istnieje, lub uważa instrukcję za niezakończoną tam, gdzie powinna, co może prowadzić do niepożądanych wyników. Możesz używać przypisań i unikać używania natychmiastowych wywoływanych wyrażeń funkcyjnych, aby zapobiec większości nieoczekiwanych błędów.
+
+### Przykład Kodu
+
+```javascript
+// Do
+function doThing() {
+ // ...
+}
+
+doThing()
+
+// Do
+
+const items = [1, 2, 3]
+items.forEach(console.log)
+
+// Avoid — throws exception
+const m = new Map()
+const a = [1,2,3]
+[...m.values()].forEach(console.log)
+> [...m.values()].forEach(console.log)
+> ^^^
+> SyntaxError: Unexpected token ...
+
+// Avoid — throws exception
+const count = 2 // it tries to run 2(), but 2 is not a function
+(function doSomething() {
+ // do something amazing
+}())
+// put a semicolon before the immediate invoked function, after the const definition, save the return value of the anonymous function to a variable or avoid IIFEs alltogether
+```
+
+🔗 [**Czytaj więcej:** "Semi ESLint rule"](https://eslint.org/docs/rules/semi)
+🔗 [**Czytaj więcej:** "No unexpected multiline ESLint rule"](https://eslint.org/docs/rules/no-unexpected-multiline)
+
+
+
+## ![✔] 3.5 Nazwij swoje funkcje
+
+**TL;DR:** Nazwij wszystkie funkcje, w tym zamknięcia i połączenia zwrotne. Unikaj anonimowych funkcji. Jest to szczególnie przydatne podczas profilowania aplikacji Node. Nazewnictwo wszystkich funkcji pozwoli ci łatwo zrozumieć, na co patrzysz podczas sprawdzania migawki pamięci
+
+**W przeciwnym razie:** Debugowanie problemów produkcyjnych przy użyciu zrzutu pamięci (migawki pamięci) może stać się trudnym zadaniem, ponieważ zauważysz znaczne zużycie pamięci przez funkcje anonimowe
+
+
+
+## ![✔] 3.6 Użyj konwencji nazewnictwa dla zmiennych, stałych, funkcji i klas
+
+**TL;DR:** Użyj **_lowerCamelCase_** podczas nazywania stałych, zmiennych i funkcji oraz **_UpperCamelCase_** (również pierwsza litera) podczas nazywania klas. Pomoże Ci to łatwo odróżnić zwykłe zmienne / funkcje od klas wymagających tworzenia instancji. Używaj opisowych nazw, ale staraj się, aby były krótkie
+
+**W przeciwnym razie:** JavaScript jest jedynym językiem na świecie, który umożliwia bezpośrednie wywoływanie konstruktora („klasy”) bez uprzedniego jego tworzenia. W konsekwencji klasy i konstruktory funkcji są zróżnicowane, zaczynając od UpperCamelCase
+
+### 3.6 Przykład kodu
+
+```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 Wolę const nad let. Porzuć var
+
+**TL;DR:** Używanie `const` oznacza, że po przypisaniu zmiennej nie można jej ponownie przypisać. Preferowanie `const` pomoże ci nie ulec pokusie użycia tej samej zmiennej do różnych zastosowań i sprawi, że twój kod będzie wyraźniejszy. Jeśli zmienna wymaga ponownego przypisania, na przykład w pętli for, użyj `let`, aby ją zadeklarować. Innym ważnym aspektem „let” jest to, że zmienna zadeklarowana przy użyciu tej zmiennej jest dostępna tylko w zakresie bloku, w którym została zdefiniowana. `var` ma zasięg działania, a nie blok, i [nie powinien być używany w ES6](https://hackernoon.com/why-you-shouldnt-use-var-anymore-f109a58b9b70) teraz masz `const` i `let` do Twojej dyspozycji
+
+**W przeciwnym razie:** Debugowanie staje się znacznie bardziej kłopotliwe, gdy podąża się za często zmieniającą się zmienną
+
+🔗 [**Czytaj więcej: JavaScript ES6+: var, let, or const?** ](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
+
+
+
+## ![✔] 3.8 Wymagaj najpierw modułów, a nie funkcji wewnętrznych
+
+**TL;DR:** Wymagaj modułów na początku każdego pliku, przed dowolnymi funkcjami i poza nimi. Ta prosta najlepsza praktyka nie tylko pomoże ci łatwo i szybko określić zależności pliku na samej górze, ale także pozwoli uniknąć kilku potencjalnych problemów
+
+**W przeciwnym razie:** Wymagania są uruchamiane synchronicznie przez Node.js. Jeśli są wywoływane z funkcji, może blokować obsługę innych żądań w bardziej krytycznym momencie. Ponadto, jeśli wymagany moduł lub dowolna z jego zależności zgłasza błąd i powoduje awarię serwera, najlepiej dowiedzieć się o nim jak najszybciej, co może nie mieć miejsca, jeśli moduł ten jest wymagany z funkcji
+
+
+
+## ![✔] 3.9 Wymagaj modułów według folderów, a nie bezpośrednio plików
+
+**TL;DR:** Podczas opracowywania modułu / biblioteki w folderze umieść plik index.js, który ujawnia elementy wewnętrzne modułu, aby każdy konsument mógł przez niego przejść. Służy to jako „interfejs” do modułu i ułatwia przyszłe zmiany bez zerwania umowy
+
+**W przeciwnym razie:** Zmiana wewnętrznej struktury plików lub podpisu może uszkodzić interfejs z klientami
+
+### 3.9 Przykład kodu
+
+```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 Używaj operatora `===`
+
+**TL;DR:** Preferuj operator ścisłej równości `===` zamiast słabszego abstrakcyjnego operatora równości `==`. `==` porówna dwie zmienne po przekształceniu ich we wspólny typ. W `===` nie ma konwersji typu i obie zmienne muszą być tego samego typu, aby były równe
+
+**W przeciwnym razie:** Nierówne zmienne mogą zwracać wartość true w porównaniu z operatorem `==`
+
+### 3.10 Przykład kodu
+
+```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
+```
+
+Wszystkie powyższe instrukcje zwrócą wartość false, jeśli zostaną użyte z `===`
+
+
+
+## ![✔] 3.11 Użyj Async Await, unikaj połączeń zwrotnych
+
+**TL;DR:** Node 8 LTS teraz ma pełne wsparcie dla Async-await. Jest to nowy sposób radzenia sobie z kodem asynchronicznym, który zastępuje wywołania zwrotne i obiecuje. Oczekiwanie na asynchronizację nie jest blokowane i sprawia, że kod asynchroniczny wygląda na synchroniczny. Najlepszym prezentem, jaki możesz dać kodowi, jest użycie funkcji async-await, która zapewnia znacznie bardziej zwartą i znaną składnię kodu, taką jak try-catch
+
+**W przeciwnym razie:** Obsługa błędów asynchronicznych w stylu wywołania zwrotnego jest prawdopodobnie najszybszą drogą do piekła - ten styl zmusza do sprawdzania błędów, radzenia sobie z dziwnym zagnieżdżaniem kodu i utrudnia uzasadnienie przepływu kodu
+
+🔗[**Czytaj więcej:** Guide to async await 1.0](https://github.com/yortus/asyncawait)
+
+
+
+## ![✔] 3.12 Użyj wyrażeń arrow function (=>)
+
+**TL;DR:** Chociaż zaleca się stosowanie asynchronicznego oczekiwania i unikania parametrów funkcji w przypadku starszych interfejsów API, które akceptują promise lub wywołania zwrotne - funkcje strzałek sprawiają, że struktura kodu jest bardziej zwarta i zachowuje kontekst leksykalny funkcji root (np. `this`)
+
+**W przeciwnym razie:** Dłuższy kod (w funkcjach ES5) jest bardziej podatny na błędy i trudny do odczytania
+
+🔗 [**Czytaj więcej: 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)
+
+
+
+# `4. Testy i ogólne praktyki jakości`
+
+## ![✔] 4.1 Przynajmniej napisz testowanie API (komponentu)
+
+**TL;DR:** Większość projektów po prostu nie ma żadnych automatycznych testów z powodu krótkich harmonogramów lub często „projekt testowy” wymykał się spod kontroli i został porzucony. Z tego powodu ustal priorytetyzację i zacznij od testowania interfejsu API, który jest najłatwiejszym sposobem pisania i zapewnia większy zasięg niż testowanie jednostkowe (możesz nawet tworzyć testy API bez kodu za pomocą narzędzi takich jak [Postman](https://www.getpostman.com/). Następnie, jeśli masz więcej zasobów i czasu, kontynuuj zaawansowane typy testów, takie jak testy jednostkowe, testy DB, testy wydajności itp.
+
+**W przeciwnym razie:** Możesz spędzać długie dni na pisaniu testów jednostkowych, aby dowiedzieć się, że masz tylko 20% zasięgu systemu
+
+
+
+## ![✔] 4.2 Dołącz 3 części do każdej nazwy testu
+
+**TL;DR:** Spraw, aby test mówił na poziomie wymagań, aby był zrozumiały również dla inżynierów i programistów kontroli jakości, którzy nie znają wewnętrznych elementów kodu. Podaj w nazwie testu, co jest testowane (testowana jednostka), w jakich okolicznościach i jaki jest oczekiwany wynik
+
+**W przeciwnym razie:** Wdrożenie właśnie nie powiodło się, test o nazwie „Dodaj produkt” nie powiódł się. Czy to mówi ci, co dokładnie działa nieprawidłowo?
+
+🔗 [**Czytaj więcej: Include 3 parts in each test name**](./sections/testingandquality/3-parts-in-name.polish.md)
+
+
+
+## ![✔] 4.3 Testy struktury według wzorca AAA
+
+**TL;DR:** Ustrukturyzuj swoje testy za pomocą 3 dobrze oddzielonych sekcji: Arrange, Act & Assert (AAA). Pierwsza część obejmuje konfigurację testu, następnie wykonanie testowanego urządzenia i wreszcie fazę asercji. Przestrzeganie tej struktury gwarantuje, że czytelnik nie poświęci mózgu procesora na zrozumienie planu testu
+
+**W przeciwnym razie:** Nie tylko spędzasz długie codzienne godziny na zrozumieniu głównego kodu, ale także to, co powinno być prostą częścią dnia (testowanie) rozciąga Twój mózg
+
+🔗 [**Czytaj więcej: Structure tests by the AAA pattern**](./sections/testingandquality/aaa.polish.md)
+
+
+
+## ![✔] 4.4 Wykryj problemy z kodem za pomocą lintera
+
+**TL;DR:** Użyj lintera kodu, aby sprawdzić podstawową jakość i wcześnie wykryć anty-wzorce. Uruchom go przed jakimkolwiek testem i dodaj jako git-hook przed zatwierdzeniem, aby zminimalizować czas potrzebny na sprawdzenie i naprawienie dowolnego problemu. Sprawdź także [Część 3](#3-praktyki-stylu-kodu) w części Praktyki stylu kodu
+
+**W przeciwnym razie:** Możesz przekazać kod anty-wzorcowy i potencjalnie podatny na atak do środowiska produkcyjnego.
+
+
+
+## ![✔] 4.5 Unikaj globalnych urządzeń testowych i seeds, dodawaj dane na test
+
+**TL;DR:** Aby zapobiec sprzężeniu testów i łatwo uzasadnić przebieg testu, każdy test powinien dodawać i działać na swoim własnym zestawie wierszy DB. Ilekroć test wymaga wyciągnięcia lub założenia istnienia niektórych danych DB - musi jawnie dodać te dane i unikać mutowania jakichkolwiek innych rekordów
+
+**W przeciwnym razie:** Rozważmy scenariusz, w którym wdrożenie zostało przerwane z powodu nieudanych testów, zespół zamierza teraz poświęcić cenny czas na dochodzenie, które kończy się smutnym wnioskiem: system działa dobrze, testy jednak przeszkadzają sobie nawzajem i przerywają kompilację
+
+🔗 [**Czytaj więcej: Avoid global test fixtures**](./sections/testingandquality/avoid-global-test-fixture.polish.md)
+
+
+
+## ![✔] 4.6 Nieustannie sprawdzaj wrażliwe zależności
+
+**TL;DR:** Nawet najbardziej renomowane zależności, takie jak Express, mają znane luki w zabezpieczeniach. Można to łatwo oswoić za pomocą narzędzi społecznościowych i komercyjnych, takich jak 🔗 [npm audit](https://docs.npmjs.com/cli/audit) i 🔗 [snyk.io](https://snyk.io), które mogą być wywoływane z twojego CI na każdej kompilacji
+
+**W przeciwnym razie:** Utrzymywanie kodu w czystości przed lukami bez dedykowanych narzędzi będzie wymagało ciągłego śledzenia publikacji online na temat nowych zagrożeń. Dość nudne
+
+
+
+## ![✔] 4.7 Oznacz swoje testy
+
+**TL;DR:** Różne testy muszą być uruchamiane w różnych scenariuszach: quick smoke, IO-less, testy powinny być uruchamiane, gdy programista zapisuje lub zatwierdza plik, pełne kompleksowe testy zwykle uruchamiane są po przesłaniu nowego pull requesta itp. Można to osiągnąć poprzez oznaczenie testów słowami kluczowymi takimi jak #cold #api #sanity, aby można było grepować za pomocą uprzęży testującej i wywołać pożądany podzbiór. Na przykład w ten sposób można wywoływać tylko grupę testową rozsądku [Mocha](https://mochajs.org/): mocha --grep 'sanity'
+
+**W przeciwnym razie:** Uruchamianie wszystkich testów, w tym testów, które wykonują dziesiątki zapytań DB, za każdym razem, gdy programista wprowadzi małą zmianę, może to być bardzo powolne i powstrzymuje programistów przed uruchomieniem testów
+
+
+
+## ![✔] 4.8 Sprawdź zasięg testu, pomaga zidentyfikować nieprawidłowe wzorce testowe
+
+**TL;DR:** Narzędzia pokrycia kodu, takie jak [Istanbul](https://github.com/istanbuljs/istanbuljs) / [NYC](https://github.com/istanbuljs/nyc) są świetne z 3 powodów: przychodzi za darmo (bez wysiłku jest niezbędny do skorzystania z tych raportów), pomaga zidentyfikować zmniejszenie zasięgu testowania, a na koniec podkreśla niedopasowania testowania: patrząc na kolorowe raporty pokrycia kodu można zauważyć, na przykład, obszary kodu, które nigdy nie są testowane jak klauzule catch (co oznacza, że testy wywołują tylko szczęśliwe ścieżki, a nie zachowanie aplikacji w przypadku błędów). Ustaw na niepowodzenia kompilacji, jeśli zasięg spadnie poniżej określonego progu
+
+**W przeciwnym razie:** Nie będzie żadnych zautomatyzowanych danych informujących, kiedy duża część kodu nie jest objęta testowaniem
+
+
+
+## ![✔] 4.9 Sprawdź nieaktualne pakiety
+
+**TL;DR:** Użyj preferowanego narzędzia (np. „npm outdated” lub [npm-check-updates](https://www.npmjs.com/package/npm-check-updates), aby wykryć zainstalowane pakiety, które są nieaktualne, wstrzyknij to w pipeline CI, a nawet zbuduj w trudnym scenariuszu. Na przykład poważnym scenariuszem może być sytuacja, gdy zainstalowany pakiet ma 5 łatek zatwierdzeń (np. Wersja lokalna to 1.3.1, a wersja repozytorium to 1.3.8) lub jest oznaczony jako przestarzałe przez jego autora - zabije kompilację i uniemożliwi wdrożenie tej wersji
+
+**W przeciwnym razie:** Produkcja będzie uruchamiać pakiety, które zostały wyraźnie oznaczone przez autora jako ryzykowne
+
+
+
+## ![✔] 4.10 Do testowania e2e używaj env zbliżonego do produkcji
+
+**TL;DR:** Testy end-to-end (e2e), które obejmują dane na żywo, były najsłabszym ogniwem procesu CI, ponieważ zależy to od wielu ciężkich usług, takich jak DB. Skorzystaj ze środowiska, które jest jak najbardziej zbliżone do Twojej rzeczywistej produkcji, jak a-continue
+
+**W przeciwnym razie:** Bez zespołów tworzących dokery muszą utrzymywać testową bazę danych dla każdego środowiska testowego, w tym na komputerach programistów, synchronizuj wszystkie te bazy danych, aby wyniki testów nie różniły się w zależności od środowiska
+
+
+
+## ![✔] 4.11 Refaktoryzuj regularnie za pomocą narzędzi do analizy statycznej
+
+**TL;DR:** Korzystanie z narzędzi analizy statycznej pomaga, zapewniając obiektywne sposoby poprawy jakości kodu i utrzymując kod w łatwości konserwacji. Możesz dodać narzędzia analizy statycznej do kompilacji CI, aby zawieść, gdy wykryje code smells. Jego głównymi zaletami w stosunku do zwykłego szarpania jest możliwość kontroli jakości w kontekście wielu plików (np. wykrywanie duplikacji), przeprowadzania zaawansowanej analizy (np. złożoności kodu) oraz śledzenia historii i postępu problemów z kodem. Dwa przykłady narzędzi, których możesz użyć, to [Sonarqube](https://www.sonarqube.org/) (2600+ [gwiazdek](https://github.com/SonarSource/sonarqube)) i [Code Climate](https://codeclimate.com/) (1500+ [gwiazdek](https://github.com/codeclimate/codeclimate)).
+
+**W przeciwnym razie:** Przy złej jakości kodu błędy i wydajność zawsze będą stanowić problem, którego nie będzie w stanie naprawić żadna nowa błyszcząca biblioteka ani najnowocześniejsze funkcje
+
+🔗 [**Czytaj więcej: Refactoring!**](./sections/testingandquality/refactoring.polish.md)
+
+
+
+## ![✔] 4.12 Ostrożnie wybierz swoją platformę CI (Jenkins vs CircleCI vs Travis vs Reszta świata)
+
+**TL;DR:** Twoja platforma ciągłej integracji (CICD) będzie hostować wszystkie narzędzia wysokiej jakości (np. test, lint), więc powinna mieć żywy ekosystem wtyczek. [Jenkins](https://jenkins.io/) był domyślny dla wielu projektów, ponieważ ma największą społeczność wraz z bardzo potężną platformą w cenie złożonej konfiguracji, która wymaga stromej krzywej uczenia się. Obecnie znacznie łatwiej jest skonfigurować rozwiązanie CI za pomocą narzędzi SaaS, takich jak [CircleCI](https://circleci.com) i innych. Narzędzia te umożliwiają stworzenie elastycznego potoku CI bez konieczności zarządzania całą infrastrukturą. Ostatecznie jest to kompromis między wytrzymałością a szybkością - wybierz stronę ostrożnie
+
+**W przeciwnym razie:** Wybranie jakiegoś niszowego dostawcy może spowodować zablokowanie użytkownika, gdy będzie potrzebne zaawansowane dostosowanie. Z drugiej strony pójście z Jenkinsem może skrócić cenny czas na konfigurację infrastruktury
+
+🔗 [**Czytaj więcej: Choosing CI platform**](./sections/testingandquality/citools.polish.md)
+
+
+
+# `5. Przejście do praktyk produkcyjnych`
+
+## ![✔] 5.1. Monitoring
+
+**TL;DR:** Monitorowanie to gra polegająca na wykrywaniu problemów, zanim zrobią to klienci - oczywiście należy nadać niespotykane znaczenie. Rynek jest przytłoczony ofertami, dlatego rozważ rozpoczęcie od zdefiniowania podstawowych wskaźników, których należy przestrzegać (moje sugestie w środku), a następnie przejrzyj dodatkowe wymyślne funkcje i wybierz rozwiązanie, które zaznacza wszystkie pola. Kliknij „The Gist” poniżej, aby wyświetlić przegląd rozwiązań
+
+**W przeciwnym razie:** Awaria === rozczarowani klienci. Proste
+
+🔗 [**Czytaj więcej: Monitoring!**](./sections/production/monitoring.polish.md)
+
+
+
+## ![✔] 5.2. Zwiększ przejrzystość za pomocą inteligentnego rejestrowania
+
+**TL;DR:** Dzienniki mogą być głupim magazynem instrukcji debugowania lub aktywować piękny pulpit nawigacyjny, który opowiada historię Twojej aplikacji. Zaplanuj swoją platformę rejestrowania od pierwszego dnia: w jaki sposób dzienniki są gromadzone, przechowywane i analizowane, aby zapewnić, że pożądane informacje (np. poziom błędu, po całej transakcji za pośrednictwem usług i serwerów itp.) mogą być naprawdę wydobyte
+
+**W przeciwnym razie:** W rezultacie pojawia się czarna skrzynka, o której trudno uzasadnić, a następnie zaczynasz ponownie pisać wszystkie instrukcje rejestrowania, aby dodać dodatkowe informacje
+
+🔗 [**Czytaj więcej: Increase transparency using smart logging**](./sections/production/smartlogging.polish.md)
+
+
+
+## ![✔] 5.3. Deleguj wszystko, co możliwe (np. Gzip, SSL) na zwrotny serwer proxy
+
+**TL;DR:** Node jest strasznie kiepski w wykonywaniu zadań intensywnie wykorzystujących procesor, takich jak gzipping, zakończenie SSL itp. Zamiast tego należy używać „rzeczywistych” usług oprogramowania pośredniego, takich jak nginx, HAproxy lub usług dostawcy w chmurze
+
+**W przeciwnym razie:** Twój słaby pojedynczy wątek pozostanie zajęty wykonywaniem zadań infrastrukturalnych zamiast zajmowania się rdzeniem aplikacji, a wydajność odpowiednio się obniży
+
+🔗 [**Czytaj więcej: Delegate anything possible (e.g. gzip, SSL) to a reverse proxy**](./sections/production/delegatetoproxy.polish.md)
+
+
+
+## ![✔] 5.4. Zablokuj zależności
+
+**TL;DR:** Twój kod musi być identyczny we wszystkich środowiskach, ale zadziwiająco npm pozwala domyślnie dryfować zależnościom między środowiskami - podczas instalowania pakietów w różnych środowiskach próbuje pobrać najnowszą wersję łatek. Aby temu zaradzić, użyj plików konfiguracyjnych npm, .npmrc, które każą każdemu środowisku zapisać dokładną (nie najnowszą) wersję każdego pakietu. Alternatywnie, dla dokładniejszej kontroli grained, użyj „npm shrinkwrap”. \ \* Aktualizacja: od NPM5 zależności są domyślnie zablokowane. Nowy menedżer pakietów w mieście, Yarn, również domyślnie nas objął
+
+**W przeciwnym razie:** Dział kontroli jakości dokładnie przetestuje kod i zatwierdzi wersję, która będzie zachowywać się inaczej w środowisku produkcyjnym. Co gorsza, różne serwery w tym samym klastrze produkcyjnym mogą uruchamiać inny kod
+
+🔗 [**Czytaj więcej: Lock dependencies**](./sections/production/lockdependencies.polish.md)
+
+
+
+## ![✔] 5.5. Zabezpiecz czas pracy bez przestojów za pomocą odpowiedniego narzędzia
+
+**TL;DR:** Proces musi trwać i uruchamiać się ponownie w przypadku awarii. W przypadku prostych scenariuszy narzędzia do zarządzania procesami, takie jak PM2, mogą być wystarczające, ale w dzisiejszym świecie „zadokowanym” należy również wziąć pod uwagę narzędzia do zarządzania klastrami
+
+**W przeciwnym razie:** Uruchomienie dziesiątek instancji bez jasnej strategii i zbyt wielu narzędzi razem (zarządzanie klastrami, okno dokowane, PM2) może doprowadzić do chaosu DevOps
+
+🔗 [**Czytaj więcej: Guard process uptime using the right tool**](./sections/production/guardprocess.polish.md)
+
+
+
+## ![✔] 5.6. Wykorzystaj wszystkie rdzenie procesora
+
+**TL;DR:** W swojej podstawowej formie aplikacja Node działa na jednym rdzeniu procesora, podczas gdy wszystkie pozostałe pozostają bezczynne. Twoim obowiązkiem jest replikacja procesu Node i wykorzystanie wszystkich procesorów - w przypadku małych i średnich aplikacji możesz użyć Node Cluster lub PM2. W przypadku większej aplikacji rozważ replikację procesu przy użyciu klastra Docker (np. K8S, ECS) lub skryptów wdrażania opartych na systemie inicjującym Linux (np. systemd)
+
+**W przeciwnym razie:** Twoja aplikacja prawdopodobnie wykorzysta tylko 25% dostępnych zasobów (!) lub nawet mniej. Zauważ, że typowy serwer ma 4 rdzenie procesora lub więcej, naiwne wdrożenie Node.js wykorzystuje tylko 1 (nawet przy użyciu usług PaaS, takich jak AWS beanstalk!)
+
+🔗 [**Czytaj więcej: Utilize all CPU cores**](./sections/production/utilizecpu.polish.md)
+
+
+
+## ![✔] 5.7. Utwórz „punkt końcowy konserwacji”
+
+**TL;DR:** Ujawnij zestaw informacji związanych z systemem, takich jak użycie pamięci i REPL itp. W zabezpieczonym interfejsie API. Chociaż wysoce zalecane jest poleganie na standardowych i narzędziach do testów bitewnych, niektóre cenne informacje i operacje można łatwiej wykonać za pomocą kodu
+
+**W przeciwnym razie:** Przekonasz się, że wykonujesz wiele „wdrożeń diagnostycznych” - wysyłasz kod do produkcji tylko po to, aby wyodrębnić niektóre informacje do celów diagnostycznych
+
+🔗 [**Czytaj więcej: Create a ‘maintenance endpoint’**](./sections/production/createmaintenanceendpoint.polish.md)
+
+
+
+## ![✔] 5.8. Odkryj błędy i przestoje przy użyciu produktów APM
+
+**TL;DR:** Produkty do monitorowania aplikacji i wydajności (np. APM) proaktywnie oceniają bazę kodu i interfejs API, dzięki czemu mogą automatycznie wykraczać poza tradycyjny monitoring i mierzyć ogólne wrażenia użytkownika na różnych usługach i poziomach. Na przykład niektóre produkty APM mogą wyróżniać transakcję, która ładuje się zbyt wolno po stronie użytkowników końcowych, sugerując jednocześnie główną przyczynę
+
+**W przeciwnym razie:** Możesz poświęcić wiele wysiłku na pomiar wydajności interfejsu API i przestojów, prawdopodobnie nigdy nie będziesz wiedział, jakie są twoje najwolniejsze części kodu w rzeczywistym scenariuszu i jak wpływają one na UX
+
+🔗 [**Czytaj więcej: Discover errors and downtime using APM products**](./sections/production/apmproducts.polish.md)
+
+
+
+## ![✔] 5.9. Przygotuj kod do produkcji
+
+**TL;DR:** Kod z myślą o końcu, plan produkcji od pierwszego dnia. Brzmi to nieco niejasno, dlatego opracowałem kilka wskazówek programistycznych, które są ściśle związane z utrzymaniem produkcji (kliknij przycisk Gist poniżej)
+
+**W przeciwnym razie:** Mistrz świata IT / DevOps nie uratuje źle napisanego systemu
+
+🔗 [**Czytaj więcej: Make your code production-ready**](./sections/production/productioncode.polish.md)
+
+
+
+## ![✔] 5.10. Zmierz i zabezpiecz zużycie pamięci
+
+**TL;DR:** Node.js ma kontrowersyjne relacje z pamięcią: silnik v8 ma miękkie limity wykorzystania pamięci (1,4 GB) i istnieją znane ścieżki wycieku pamięci w kodzie Node - dlatego oglądanie pamięci procesu Node jest koniecznością. W małych aplikacjach możesz okresowo mierzyć pamięć za pomocą poleceń powłoki, ale w średnio-dużych aplikacjach rozważ umieszczenie zegarka pamięci w solidnym systemie monitorowania
+
+**W przeciwnym razie:** Pamięć procesowa może przeciekać sto megabajtów dziennie, jak to się stało w [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak)
+
+🔗 [**Czytaj więcej: Measure and guard the memory usage**](./sections/production/measurememory.polish.md)
+
+
+
+## ![✔] 5.11. Wydobądź swoje zasoby frontendowe Node
+
+**TL;DR:** Podawaj zawartość interfejsu użytkownika za pomocą dedykowanego oprogramowania pośredniego (nginx, S3, CDN), ponieważ wydajność węzła naprawdę spada podczas pracy z wieloma plikami statycznymi ze względu na model jednowątkowy
+
+**W przeciwnym razie:** Twój pojedynczy wątek Node'a będzie zajęty przesyłaniem strumieniowym setek plików HTML / images / Angular / React zamiast przydzielania wszystkich swoich zasobów do zadania, dla którego się urodził - udostępniania treści dynamicznych
+
+🔗 [**Czytaj więcej: Get your frontend assets out of Node**](./sections/production/frontendout.polish.md)
+
+
+
+## ![✔] 5.12. Bądź bezstanowy, zabijaj serwery prawie codziennie
+
+**TL;DR:** Przechowuj wszelkiego rodzaju dane (np. sesje użytkownika, pamięć podręczną, przesłane pliki) w zewnętrznych magazynach danych. Rozważ „zabijanie” swoich serwerów okresowo lub skorzystaj z platformy „bezserwerowej” (np. AWS Lambda), która wyraźnie wymusza zachowanie bezstanowe
+
+**W przeciwnym razie:** Awaria na danym serwerze spowoduje przestoje aplikacji, a nie tylko zabicie wadliwego komputera. Co więcej, elastyczność skalowania stanie się trudniejsza ze względu na zależność od konkretnego serwera
+
+🔗 [**Czytaj więcej: Be stateless, kill your Servers almost every day**](./sections/production/bestateless.polish.md)
+
+
+
+## ![✔] 5.13. Użyj narzędzi, które automatycznie wykrywają luki w zabezpieczeniach
+
+**TL;DR:** Nawet najbardziej renomowane zależności, takie jak Express, mają znane luki (od czasu do czasu), które mogą stanowić zagrożenie dla systemu. Można to łatwo oswoić za pomocą narzędzi społecznościowych i komercyjnych, które stale sprawdzają luki w zabezpieczeniach i ostrzegają (lokalnie lub w GitHub), niektóre mogą nawet natychmiast je załatać
+
+**W przeciwnym razie:** Utrzymanie kodu w czystości przed lukami bez dedykowanych narzędzi będzie wymagało ciągłego śledzenia publikacji online na temat nowych zagrożeń. Dość nudne
+
+🔗 [**Czytaj więcej: Use tools that automatically detect vulnerabilities**](./sections/production/detectvulnerabilities.polish.md)
+
+
+
+## ![✔] 5.14. Przypisz identyfikator transakcji do każdej instrukcji dziennika
+
+**TL;DR:** Przypisz ten sam identyfikator, identyfikator transakcji: {pewna wartość} do każdego wpisu dziennika w ramach jednego żądania. Następnie podczas sprawdzania błędów w logach łatwo wyciągnij wnioski przed i po. Niestety, nie jest to łatwe do osiągnięcia w Node ze względu na jego asynchroniczny charakter, patrz przykłady kodu wewnątrz
+
+**W przeciwnym razie:** Patrzenie na dziennik błędów produkcyjnych bez kontekstu - co zdarzyło się wcześniej - sprawia, że znacznie trudniej i wolniej jest myśleć o problemie
+
+🔗 [**Czytaj więcej: Assign ‘TransactionId’ to each log statement**](./sections/production/assigntransactionid.polish.md)
+
+
+
+## ![✔] 5.15. Ustaw NODE_ENV = produkcja
+
+**TL;DR:** Ustaw zmienną środowiskową NODE_ENV na 'production' lub 'development', aby oznaczyć, czy optymalizacje produkcji powinny zostać aktywowane - wiele pakietów npm określa bieżące środowisko i optymalizuje kod do produkcji
+
+**W przeciwnym razie:** Pominięcie tej prostej właściwości może znacznie obniżyć wydajność. Na przykład, używając Express do renderowania po stronie serwera, pominięcie `NODE_ENV` powoduje spowolnienie trzykrotnie!
+
+🔗 [**Czytaj więcej: Set NODE_ENV=production**](./sections/production/setnodeenv.polish.md)
+
+
+
+## ![✔] 5.16. Projektowanie wdrożeń zautomatyzowanych, atomowych i bez przestojów
+
+**TL;DR:** Badania pokazują, że zespoły wykonujące wiele wdrożeń zmniejszają prawdopodobieństwo poważnych problemów produkcyjnych. Szybkie i zautomatyzowane wdrożenia, które nie wymagają ryzykownych ręcznych kroków i przestojów usług, znacznie usprawniają proces wdrażania. Prawdopodobnie powinieneś to osiągnąć za pomocą Dockera w połączeniu z narzędziami CI, ponieważ stały się one standardem branżowym dla usprawnionego wdrażania
+
+**W przeciwnym razie:** Długie wdrożenia -> przestoje produkcyjne i błąd związany z człowiekiem -> zespół nie jest pewny co do wdrożenia -> mniej wdrożeń i funkcji
+
+
+
+## ![✔] 5.17. Użyj wersji LTS środowiska Node.js
+
+**TL;DR:** Upewnij się, że używasz wersji LTS Node.js , aby otrzymywać krytyczne poprawki błędów, aktualizacje zabezpieczeń i ulepszenia wydajności
+
+**W przeciwnym razie:** Nowo odkryte błędy lub luki można wykorzystać do wykorzystania aplikacji działającej w środowisku produkcyjnym, a aplikacja może nie być obsługiwana przez różne moduły i trudniejsza do utrzymania
+
+🔗 [**Czytaj więcej: Use an LTS release of Node.js**](./sections/production/LTSrelease.polish.md)
+
+
+
+## ![✔] 5.18. Nie kieruj dzienników w aplikacji
+
+**TL;DR:** Miejsca docelowe dziennika nie powinny być zakodowane na stałe przez programistów w kodzie aplikacji, ale powinny być zdefiniowane przez środowisko wykonawcze, w którym działa aplikacja. Programiści powinni zapisywać dzienniki na `stdout` za pomocą narzędzia rejestrującego, a następnie pozwolić środowisku wykonawczemu (kontener, serwer itp.) potokuj strumień `stdout` do odpowiedniego miejsca docelowego (tj. Splunk, Graylog, ElasticSearch itp.).
+
+**W przeciwnym razie:** Trasowanie dzienników obsługi aplikacji === trudne do skalowania, utrata dzienników, słaba separacja problemów
+
+🔗 [**Czytaj więcej: Log Routing**](./sections/production/logrouting.polish.md)
+
+
+
+## ![✔] 6.1. Ustanowienie zasad bezpieczeństwa linter
+
+
+
+**TL;DR:** Skorzystaj z wtyczek liniowych związanych z bezpieczeństwem, takich jak [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security), aby wychwycić luki w zabezpieczeniach i problemy jak najwcześniej, najlepiej gdy są one kodowane. Może to pomóc w wykrywaniu słabych punktów bezpieczeństwa, takich jak używanie eval, wywoływanie procesu potomnego lub importowanie modułu z literałem łańcucha (np. dane wejściowe użytkownika). Kliknij „Czytaj więcej” poniżej, aby zobaczyć przykłady kodu, które zostaną złapane przez linijkę bezpieczeństwa
+
+**W przeciwnym razie:** To, co mogło być bezpośrednią słabością bezpieczeństwa podczas programowania, staje się poważnym problemem w produkcji. Ponadto projekt może nie być zgodny ze spójnymi praktykami bezpieczeństwa kodu, co prowadzi do wprowadzenia luk w zabezpieczeniach lub poufnych danych wrażliwych wrzuconych w zdalnych repozytoriach
+
+🔗 [**Czytaj więcej: Lint rules**](./sections/security/lintrules.polish.md)
+
+
+
+## ![✔] 6.2. Ogranicz równoczesne żądania przy użyciu oprogramowania pośredniego
+
+
+
+**TL;DR:** Ataki DOS są bardzo popularne i stosunkowo łatwe do przeprowadzenia. Wdrażanie ograniczenia prędkości za pomocą usługi zewnętrznej, takiej jak usługi równoważenia obciążenia w chmurze, zapory w chmurze, nginx, pakiet [rate-limiting middleware](https://www.npmjs.com/package/rate-limiter-fiętki) lub (dla mniejszych i mniej krytycznych aplikacji) ograniczające szybkość oprogramowanie pośrednie (np. [express-rate-limit](https://www.npmjs.com/package/express-rate-limit))
+
+**W przeciwnym razie:** Aplikacja może zostać zaatakowana, co spowoduje odmowę usługi, w wyniku której prawdziwi użytkownicy otrzymają usługę o obniżonej jakości lub niedostępną.
+
+🔗 [**Czytaj więcej: Implement rate limiting**](./sections/security/limitrequests.polish.md)
+
+
+
+## ![✔] 6.3 Wyodrębnij dane wrażliwe z plików konfiguracyjnych lub użyj pakietów, aby je zaszyfrować
+
+
+
+**TL;DR:** Nigdy nie przechowuj danych wrażliwych jako zwykły tekst w plikach konfiguracyjnych lub kodzie źródłowym. Zamiast tego skorzystaj z systemów zarządzania danymi wrażliwymi, takich jak produkty Vault, Kubernetes / Docker Secrets lub wykorzystując zmienne środowiskowe. W ostateczności dane wrażliwe przechowywane w kontroli źródła muszą być szyfrowane i zarządzane (klucze, wygasanie, kontrola itp.). Skorzystaj z hooks poprzedzających zatwierdzenie / push, aby zapobiec przypadkowemu commitowaniu danych wrażliwych
+
+**W przeciwnym razie:** Kontrola źródła, nawet w przypadku prywatnych repozytoriów, może zostać omyłkowo upubliczniona, w którym to momencie ujawniane są wszystkie dane wrażliwe. Dostęp do kontroli źródła dla strony zewnętrznej nieumyślnie zapewni dostęp do powiązanych systemów (baz danych, API, usług itp.).
+
+🔗 [**Czytaj więcej: Secret management**](./sections/security/secretmanagement.polish.md)
+
+
+
+## ![✔] 6.4. Zapobiegaj podatności na wstrzykiwanie zapytań w bibliotekach ORM / ODM
+
+
+
+**TL;DR:** Aby zapobiec wstrzykiwaniu SQL / NoSQL i innym złośliwym atakom, zawsze używaj ORM / ODM lub biblioteki bazy danych, która ucieka przed danymi lub obsługuje nazwane lub indeksowane zapytania sparametryzowane, i dba o sprawdzenie poprawności danych wejściowych użytkownika dla oczekiwanych typów. Nigdy nie używaj ciągów szablonów JavaScript ani konkatenacji ciągów, aby wstrzykiwać wartości do zapytań, ponieważ otwiera to aplikację na szeroki zakres luk. Wszystkie renomowane biblioteki dostępu do danych Node.js (np. [Sequelize](https://github.com/sequelize/sequelize), [Knex](https://github.com/tgriesser/knex), [mongoose](https://github.com/Automattic/mongoose)) mają wbudowaną ochronę przed atakami iniekcyjnymi.
+
+**W przeciwnym razie:** Nieprawidłowe lub niezaangażowane dane wejściowe użytkownika mogą prowadzić do wstrzyknięcia przez operatora podczas pracy z MongoDB dla NoSQL, a niestosowanie odpowiedniego systemu odkażania lub ORM z łatwością pozwoli na ataki z zastrzykiem SQL, tworząc ogromną lukę.
+
+🔗 [**Czytaj więcej: Query injection prevention using ORM/ODM libraries**](./sections/security/ormodmusage.polish.md)
+
+
+
+## ![✔] 6.5. Zbiór ogólnych dobrych praktyk w zakresie bezpieczeństwa
+
+**TL;DR:** Jest to zbiór porad bezpieczeństwa, które nie są bezpośrednio związane z Node.js - implementacja Node nie różni się niczym od żadnego innego języka. Kliknij Czytaj więcej, aby przejrzeć.
+
+🔗 [**Czytaj więcej: Common security best practices**](./sections/security/commonsecuritybestpractices.polish.md)
+
+
+
+## ![✔] 6.6. Dostosuj nagłówki odpowiedzi HTTP, aby zwiększyć bezpieczeństwo
+
+
+
+**TL;DR:** Twoja aplikacja powinna korzystać z bezpiecznych nagłówków, aby uniemożliwić atakującym typowe ataki, takie jak skrypty cross-site scripting (XSS), kliknięcia i inne złośliwe ataki. Można je łatwo skonfigurować za pomocą modułów takich jak [helmet](https://www.npmjs.com/package/helmet).
+
+**W przeciwnym razie:** Atakujący mogą wykonywać bezpośrednie ataki na użytkowników aplikacji, co prowadzi do ogromnych luk w zabezpieczeniach
+
+🔗 [**Czytaj więcej: Using secure headers in your application**](./sections/security/secureheaders.polish.md)
+
+
+
+## ![✔] 6.7. Stale i automatycznie sprawdzaj wrażliwe zależności
+
+
+
+**TL;DR:** W ekosystemie npm często występuje wiele zależności dla projektu. Zależności powinny być zawsze kontrolowane w miarę wykrycia nowych luk. Użyj narzędzi takich jak [npm audit](https://docs.npmjs.com/cli/audit) lub [snyk](https://snyk.io/) do śledzenia, monitorowania i łatania podatnych na zagrożenia zależności. Zintegruj te narzędzia z konfiguracją CI, aby złapać wrażliwą zależność, zanim przejdzie ona do produkcji.
+
+**W przeciwnym razie:** Osoba atakująca może wykryć strukturę sieci i zaatakować wszystkie znane luki w zabezpieczeniach.
+
+🔗 [**Czytaj więcej: Dependency security**](./sections/security/dependencysecurity.polish.md)
+
+
+
+## ![✔] 6.8. Unikaj używania biblioteki kryptograficznej Node.js do obsługi haseł, użyj Bcrypt
+
+
+
+**TL;DR:** Hasła lub dane wrażliwe (klucze API) powinny być przechowywane przy użyciu bezpiecznej funkcji hash + salt, takiej jak `bcrypt`, co powinno być preferowanym wyborem w stosunku do implementacji JavaScript ze względu na wydajność i bezpieczeństwo.
+
+**W przeciwnym razie:** Hasła lub dane wrażliwe, które są utrwalane bez korzystania z bezpiecznej funkcji, są podatne na brute force i ataki słownikowe, które ostatecznie doprowadzą do ich ujawnienia.
+
+🔗 [**Czytaj więcej: Use Bcrypt**](./sections/security/bcryptpasswords.polish.md)
+
+
+
+## ![✔] 6.9. Unikaj danych wyjściowych HTML, JS i CSS
+
+
+
+**TL;DR:** Niezaufane dane wysyłane do przeglądarki mogą zostać wykonane zamiast po prostu wyświetlane, jest to powszechnie nazywane atakiem typu cross-site-scripting (XSS). Ogranicz to, używając dedykowanych bibliotek, które jawnie oznaczają dane jako czystą treść, która nigdy nie powinna zostać wykonana (tj. kodowanie, ucieczka)
+
+**W przeciwnym razie:** Osoba atakująca może przechowywać złośliwy kod JavaScript w bazie danych, który zostanie następnie wysłany „tak jak jest” do biednych klientów
+
+🔗 [**Czytaj więcej: Escape output**](./sections/security/escape-output.polish.md)
+
+
+
+## ![✔] 6.10. Sprawdź poprawność przychodzących schematów JSON
+
+
+
+**TL;DR:** Zweryfikuj ładowność treści przychodzących żądań i upewnij się, że spełnia oczekiwania, jeśli nie, szybko zawiedzie. Aby uniknąć żmudnego kodowania sprawdzania poprawności na każdej trasie, możesz użyć lekkich schematów sprawdzania poprawności opartych na JSON, takich jak [jsonschema](https://www.npmjs.com/package/jsonschema) lub [joi](https://www.npmjs.com/package/joi)
+
+**W przeciwnym razie:** Twoja hojność i liberalne podejście znacznie zwiększa powierzchnię ataku i zachęca atakującego do wypróbowania wielu danych wejściowych, dopóki nie znajdzie kombinacji umożliwiającej zawieszenie aplikacji
+
+🔗 [**Czytaj więcej: Validate incoming JSON schemas**](./sections/security/validation.polish.md)
+
+
+
+## ![✔] 6.11. Obsługa czarnych list JWT
+
+
+
+**TL;DR:** Podczas korzystania z tokenów WWW JSON (na przykład z [Passport.js](https://github.com/jaredhanson/passport)) domyślnie nie ma mechanizmu, aby odwołać dostęp z wydanych tokenów. Gdy odkryjesz jakąś szkodliwą aktywność użytkownika, nie ma sposobu, aby powstrzymać ich przed dostępem do systemu, o ile posiadają prawidłowy token. Ogranicz to, wdrażając czarną listę niezaufanych tokenów, które są sprawdzane przy każdym żądaniu.
+
+**W przeciwnym razie:** Wygasłe lub niewłaściwie umieszczone tokeny mogą być złośliwie wykorzystywane przez osoby trzecie do uzyskiwania dostępu do aplikacji i podszywania się pod właściciela tokena.
+
+🔗 [**Czytaj więcej: Blacklist JSON Web Tokens**](./sections/security/expirejwt.polish.md)
+
+
+
+## ![✔] 6.12. Zapobiegaj brute force na autoryzację
+
+
+
+**TL;DR:** Prostą i skuteczną techniką jest ograniczenie prób autoryzacji przy użyciu dwóch wskaźników:
+
+1. Pierwszy to liczba kolejnych nieudanych prób tego samego unikalnego identyfikatora / nazwy użytkownika i adresu IP.
+2. Druga to liczba nieudanych prób z adresu IP w dłuższym okresie czasu. Na przykład zablokuj adres IP, jeśli wykona 100 nieudanych prób w ciągu jednego dnia.
+
+**W przeciwnym razie:** Osoba atakująca może podejmować nieograniczoną liczbę zautomatyzowanych prób uzyskania hasła w celu uzyskania dostępu do uprzywilejowanych kont w aplikacji
+
+🔗 [**Czytaj więcej: Login rate limiting**](./sections/security/login-rate-limit.polish.md)
+
+
+
+## ![✔] 6.13. Uruchom Node.js jako użytkownik inny niż root
+
+
+
+**TL;DR:** Istnieje częsty scenariusz, w którym Node.js działa jako użytkownik root z nieograniczonymi uprawnieniami. Na przykład jest to domyślne zachowanie w kontenerach Docker. Zalecane jest utworzenie użytkownika innego niż root i upieczenie go w obrazie Docker (przykłady podane poniżej) lub uruchomienie procesu w imieniu tego użytkownika przez wywołanie kontenera z flagą "-u username"
+
+**W przeciwnym razie:** Atakujący, któremu uda się uruchomić skrypt na serwerze, uzyskuje nieograniczoną władzę nad maszyną lokalną (np. zmienia iptable i przekierowuje ruch do swojego serwera)
+
+🔗 [**Czytaj więcej: Run Node.js as non-root user**](./sections/security/non-root-user.polish.md)
+
+
+
+## ![✔] 6.14. Ogranicz rozmiar ładunku przy użyciu odwrotnego proxy lub oprogramowania pośredniego
+
+
+
+**TL;DR:** Im większy jest ładunek ciała, tym trudniej jest przetwarzać pojedynczy wątek. Jest to okazja dla atakujących, aby postawić serwery na kolanach bez ogromnej liczby żądań (ataki DOS / DDOS). Ogranicz to, ograniczając rozmiar ciała przychodzących żądań na krawędzi (np. zapora ogniowa, ELB) lub konfigurując [ekspresowy parser treści](https://github.com/expressjs/body-parser), aby akceptował tylko małe ładunki
+
+**W przeciwnym razie:** Twoja aplikacja będzie musiała poradzić sobie z dużymi żądaniami, niezdolna do przetworzenia innej ważnej pracy, którą musi wykonać, co będzie miało wpływ na wydajność i podatność na ataki DOS
+
+🔗 [**Czytaj więcej: Limit payload size**](./sections/security/requestpayloadsizelimit.polish.md)
+
+
+
+## ![✔] 6.15. Unikaj instrukcji eval JavaScript
+
+
+
+**TL;DR:** `eval` jest złe, ponieważ pozwala na wykonanie niestandardowego kodu JavaScript w czasie wykonywania. Jest to nie tylko kwestia wydajności, ale także ważna kwestia bezpieczeństwa ze względu na złośliwy kod JavaScript, który może pochodzić z danych wejściowych użytkownika. Inną cechą językową, której należy unikać, jest konstruktor `new Function`. `setTimeout` i`setInterval` nigdy nie powinny być przekazywane dynamicznemu kodowi JavaScript.
+
+**W przeciwnym razie:** Złośliwy kod JavaScript znajduje drogę do tekstu przekazywanego do `eval` lub innych funkcji języka JavaScript oceniających w czasie rzeczywistym, i uzyskuje pełny dostęp do uprawnień JavaScript na stronie. Luka ta często objawia się jako atak XSS.
+
+🔗 [**Czytaj więcej: Avoid JavaScript eval statements**](./sections/security/avoideval.polish.md)
+
+
+
+## ![✔] 6.16. Zapobiegaj złemu Regex'owi przed przeciążeniem wykonania pojedynczego wątku
+
+
+
+**TL;DR:** Wyrażenia regularne, chociaż są przydatne, stanowią prawdziwe zagrożenie dla aplikacji JavaScript w ogóle, w szczególności dla platformy Node.js. Wprowadzanie przez użytkownika tekstu w celu dopasowania może wymagać przetworzenia dużej liczby cykli procesora. Przetwarzanie Regex może być nieefektywne w takim stopniu, że pojedyncze żądanie, które potwierdza 10 słów, może zablokować całą pętlę zdarzeń na 6 sekund i ustawić procesor na on. Z tego powodu preferuj pakiety walidacyjne innych firm, takie jak [validator.js](https://github.com/chriso/validator.js) zamiast pisać własne wzorce Regex, lub skorzystaj z [safe-regex](https://github.com/substack/safe-regex) do wykrywania wrażliwych wzorców wyrażeń regularnych
+
+**W przeciwnym razie:** Źle napisane wyrażenia regularne mogą być podatne na ataki DoS wyrażeń regularnych, które całkowicie zablokują pętlę zdarzeń. Na przykład popularny pakiet `moment` został uznany za podatny na złośliwe użycie Regex w listopadzie 2017r.
+
+🔗 [**Czytaj więcej: Prevent malicious RegEx**](./sections/security/regex.polish.md)
+
+
+
+## ![✔] 6.17. Unikaj ładowania modułu za pomocą zmiennej
+
+
+
+**TL;DR:** Unikaj wymagania / importowania innego pliku ze ścieżką podaną jako parametr ze względu na obawy, że mógł on pochodzić z danych wejściowych użytkownika. Regułę tę można rozszerzyć w celu uzyskania ogólnego dostępu do plików (tj. `Fs.readFile ()`) lub innego poufnego dostępu do zasobów za pomocą zmiennych dynamicznych pochodzących z danych wprowadzanych przez użytkownika. [Eslint-plugin-security](https://www.npmjs.com/package/eslint-plugin-security) linter potrafi złapać takie wzorce i odpowiednio wcześnie ostrzec
+
+**W przeciwnym razie:** Złośliwe dane wejściowe użytkownika mogą znaleźć drogę do parametru wymaganego do zmodyfikowania plików, na przykład wcześniej przesłanego pliku do systemu plików lub uzyskania dostępu do już istniejących plików systemowych.
+
+🔗 [**Czytaj więcej: Safe module loading**](./sections/security/safemoduleloading.polish.md)
+
+
+
+## ![✔] 6.18. Uruchom niebezpieczny kod w piaskownicy
+
+
+
+**TL;DR:** W przypadku zadania uruchomienia kodu zewnętrznego, który jest podawany w czasie wykonywania (np. wtyczki), użyj dowolnego środowiska wykonawczego „piaskownicy”, które izoluje i chroni główny kod przed wtyczką. Można to osiągnąć za pomocą dedykowanego procesu (np. `Cluster.fork ()`), środowiska bezserwerowego lub dedykowanych pakietów npm, które działają jak piaskownica
+
+**W przeciwnym razie:** Wtyczka może atakować poprzez nieskończoną różnorodność opcji, takich jak nieskończone pętle, przeciążenie pamięci i dostęp do wrażliwych zmiennych środowiskowych procesu
+
+🔗 [**Czytaj więcej: Run unsafe code in a sandbox**](./sections/security/sandbox.polish.md)
+
+
+
+## ![✔] 6.19. Zachowaj szczególną ostrożność podczas pracy z procesami potomnymi
+
+
+
+**TL;DR:** Jeśli to możliwe, unikaj korzystania z procesów potomnych, a jeśli to konieczne, sprawdzaj poprawność i odkażaj dane wejściowe, aby złagodzić ataki polegające na wstrzykiwaniu powłoki. Wolę używać `child_process.execFile`, który z definicji wykona tylko jedno polecenie z zestawem atrybutów i nie pozwoli na rozszerzenie parametrów powłoki.
+
+**W przeciwnym razie:** Naiwne użycie procesów potomnych może spowodować zdalne wykonanie poleceń lub ataki polegające na wstrzyknięciu powłoki z powodu wprowadzenia złośliwego użytkownika do niezarządzanego polecenia systemowego.
+
+🔗 [**Czytaj więcej: Be cautious when working with child processes**](./sections/security/childprocesses.polish.md)
+
+
+
+## ![✔] 6.20. Ukryj szczegóły błędów przed klientami
+
+
+
+**TL;DR:** Zintegrowana ekspresowa obsługa błędów domyślnie ukrywa szczegóły błędu. Jednak duże są szanse na wdrożenie własnej logiki obsługi błędów za pomocą niestandardowych obiektów Error (uważanych przez wielu za najlepszą praktykę). Jeśli to zrobisz, pamiętaj, aby nie zwracać całego obiektu Error do klienta, który może zawierać pewne wrażliwe szczegóły aplikacji
+
+**W przeciwnym razie:** Wrażliwe szczegóły aplikacji, takie jak ścieżki plików serwera, używane moduły stron trzecich i inne wewnętrzne przepływy pracy aplikacji, które mogą zostać wykorzystane przez atakującego, mogą zostać wyciekły z informacji znalezionych w stack trace
+
+🔗 [**Czytaj więcej: Hide error details from client**](./sections/security/hideerrors.polish.md)
+
+
+
+## ![✔] 6.21. Skonfiguruj 2FA dla npm lub Yarn
+
+
+
+**TL;DR:** Każdy krok w łańcuchu programowania powinien być chroniony za pomocą MFA (uwierzytelnianie wieloskładnikowe), npm / Yarn to słodka okazja dla atakujących, którzy mogą zdobyć hasło jakiegoś programisty. Korzystając z poświadczeń programistów, osoby atakujące mogą wstrzykiwać złośliwy kod do bibliotek szeroko instalowanych w projektach i usługach. Może nawet w Internecie, jeśli zostanie opublikowany publicznie. Włączenie uwierzytelniania 2-czynnikowego w npm pozostawia niemal zerowe szanse atakującym na zmianę kodu pakietu.
+
+**W przeciwnym razie:** [Czy słyszałeś o programiście eslint, którego hasło zostało przejęte?](https://medium.com/@oprearocks/eslint-backdoor-what-it-is-and-how-to-fix-the-issue-221f58f1a8c8)
+
+
+
+## ![✔] 6.22. Zmodyfikuj ustawienia oprogramowania pośredniego sesji
+
+
+
+**TL;DR:** Każda platforma sieciowa i technologia ma swoje znane słabości - informowanie atakującego, której struktury sieciowej używamy, jest dla nich bardzo pomocne. Korzystanie z domyślnych ustawień dla pośrednich sesji może narazić twoją aplikację na ataki przejmujące specyficzne dla modułu i frameworka w podobny sposób jak nagłówek `X-Powered-By`. Spróbuj ukryć wszystko, co identyfikuje i ujawnia Twój stos technologii (np. Node.js, Express)
+
+**W przeciwnym razie:** Pliki cookie mogą być przesyłane za pośrednictwem niezabezpieczonych połączeń, a osoba atakująca może użyć identyfikacji sesji w celu zidentyfikowania podstawowej struktury aplikacji internetowej, a także podatności na uszkodzenia specyficzne dla modułu
+
+🔗 [**Czytaj więcej: Cookie and session security**](./sections/security/sessions.polish.md)
+
+
+
+## ![✔] 6.23. Unikaj ataków DOS, jawnie określając, kiedy proces powinien ulec awarii
+
+
+
+**TL;DR:** Proces Node'a ulega awarii, gdy błędy nie są obsługiwane. Wiele najlepszych praktyk zaleca nawet wyjście, nawet jeśli błąd został wykryty i naprawiony. Na przykład program Express zawiesza się przy każdym błędzie asynchronicznym - chyba że zawiniesz trasy klauzulą catch. Otwiera to bardzo słodkie miejsce ataku dla atakujących, którzy rozpoznają, co powoduje, że proces ulega awarii i wielokrotnie wysyłają to samo żądanie. Nie ma na to natychmiastowego rozwiązania, ale kilka technik może złagodzić ból: za każdym razem, gdy proces ulega awarii z powodu nieobsługiwanego błędu, ostrzegaj z krytyczną dotkliwością, sprawdzaj dane wejściowe i unikaj awarii procesu z powodu nieprawidłowego wprowadzania danych przez użytkownika, owiń wszystkie trasy chwytaniem i rozważ, aby nie upaść, gdy błąd wystąpił w żądaniu (w przeciwieństwie do tego, co dzieje się globalnie)
+
+**W przeciwnym razie:** To tylko wyuczone przypuszczenie: biorąc pod uwagę wiele aplikacji Node.js, jeśli spróbujemy przekazać puste ciało JSON do wszystkich żądań POST - garść aplikacji ulegnie awarii. W tym momencie możemy po prostu powtórzyć wysyłanie tego samego żądania, aby z łatwością usunąć aplikacje
+
+
+
+## ![✔] 6.24. Zapobiegaj niebezpiecznym przekierowaniom
+
+
+
+**TL;DR:** Przekierowania, które nie sprawdzają poprawności danych wejściowych użytkownika, mogą umożliwić atakującym uruchamianie oszustw związanych z wyłudzaniem informacji, kradzieży poświadczeń użytkownika i wykonywania innych złośliwych działań.
+
+**W przeciwnym razie:** Jeśli osoba atakująca odkryje, że nie weryfikujesz danych zewnętrznych dostarczonych przez użytkownika, może wykorzystać tę lukę, publikując specjalnie spreparowane łącza na forach, w mediach społecznościowych i innych miejscach publicznych, aby użytkownicy mogli ją kliknąć.
+
+🔗 [**Czytaj więcej: Prevent unsafe redirects**](./sections/security/saferedirects.polish.md)
+
+
+
+## ![✔] 6.25. Unikaj publikowania danych wrażliwych w rejestrze npm
+
+
+
+**TL;DR:** Należy podjąć środki ostrożności, aby uniknąć ryzyka przypadkowego opublikowania danych wrażliwych w publicznych rejestrach npm. Plik `.npmignore` może być użyty do umieszczenia na czarnej liście określonych plików lub folderów, lub tablica`files` w `package.json` może działać jako biała lista.
+
+**W przeciwnym razie:** Klucze API, hasła i inne dane wrażliwe twojego projektu są otwarte na wykorzystywanie przez każdego, kto je napotka, co może spowodować straty finansowe, podszywanie się pod inne osoby i inne ryzyko.
+
+🔗 [**Czytaj więcej: Avoid publishing secrets**](./sections/security/avoid_publishing_secrets.polish.md)
+
+
+# `7. Wersja robocza: Najlepsze praktyki dotyczące wydajności`
+
+## Nasi współpracownicy pracują nad tą sekcją. [Chciałbyś dołączyć?](https://github.com/goldbergyoni/nodebestpractices/issues/256)
+
+
+
+## ![✔] 7.1. Nie blokuj pętli zdarzeń
+
+**TL;DR:** Unikaj zadań intensywnie wykorzystujących procesor, ponieważ będą blokować głównie jednowątkową pętlę zdarzeń i odciążą ją do dedykowanego wątku, procesu lub nawet innej technologii zależnej od kontekstu.
+
+**W przeciwnym razie:** Ponieważ pętla zdarzeń jest zablokowana, Node.js nie będzie w stanie obsłużyć innych żądań, co spowoduje opóźnienia dla równoczesnych użytkowników. **3000 użytkowników czeka na odpowiedź, treść jest gotowa do wyświetlenia, ale jedno pojedyncze żądanie blokuje serwerowi odesłanie wyników z powrotem**
+
+🔗 [**Czytaj więcej: Do not block the event loop**](./sections/performance/block-loop.polish.md)
+
+
+
+## ![✔] 7.2. Preferuj natywne metody JS, niż narzędzia ponad powierzchnią użytkownika, takie jak Lodash
+
+**TL;DR:** Korzystanie z bibliotek narzędziowych takich jak `lodash` i `underscore` w porównaniu z metodami natywnymi jest często bardziej karalne, ponieważ prowadzi do niepotrzebnych zależności i spowalnia działanie.
+Należy pamiętać, że wraz z wprowadzeniem nowego silnika V8 wraz z nowymi standardami ES, natywne metody zostały ulepszone w taki sposób, że są teraz o około 50% wydajniejsze niż biblioteki narzędziowe.
+
+**W przeciwnym razie:** Będziesz musiał utrzymywać mniej wydajne projekty, w których mógłbyś po prostu użyć tego, co było **już** dostępne lub zająć się kilkoma kolejnymi liniami w zamian za kilka dodatkowych plików.
+
+🔗 [**Czytaj więcej: Native over user land utils**](./sections/performance/nativeoverutil.polish.md)
+
+
+
+# Milestones
+
+Aby utrzymać ten przewodnik i aktualizować go, stale aktualizujemy i ulepszamy wytyczne i najlepsze praktyki z pomocą społeczności. Możesz śledzić nasze [kamienie milowe](https://github.com/goldbergyoni/nodebestpractices/milestones) i dołączyć do grup roboczych, jeśli chcesz przyczynić się do tego projektu
+
+
+
+## Tłumaczenia
+
+Wszystkie tłumaczenia pochodzą od społeczności. Z przyjemnością uzyskamy wszelką pomoc dotyczącą ukończonych, bieżących lub nowych tłumaczeń!
+
+### Ukończone tłumaczenia
+
+-  [Brazilian Portuguese](./README.brazilian-portuguese.md) - Dzięki uprzejmości [Marcelo Melo](https://github.com/marcelosdm)
+-  [Chinese](./README.chinese.md) - Dzięki uprzejmości [Matt Jin](https://github.com/mattjin)
+-  [Russian](./README.russian.md) - Dzięki uprzejmości [Alex Ivanov](https://github.com/contributorpw)
+-  [Polish](./README.polish.md) - Dzięki uprzejmości [Michal Biesiada](https://github.com/mbiesiad)
+-  [Basque](README.basque.md) - Dzięki uprzejmości [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuesta
+
+### Tłumaczenia w trakcie
+
+-  [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  Hebrew ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Korean](README.korean.md) - Courtesy of [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Spanish](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turkish ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/139))
+
+
+
+## Steering Committee
+
+Spotkaj się z członkami komitetu sterującego - ludźmi, którzy pracują razem, aby zapewnić wytyczne i przyszłe kierunki projektu. Ponadto każdy członek komitetu prowadzi projekt śledzony w ramach naszych [projektów GitHub](https://github.com/goldbergyoni/nodebestpractices/projects).
+
+
+
+[Yoni Goldberg](https://github.com/goldbergyoni)
+
+
+
+Niezależny konsultant Node.js, który współpracuje z klientami w USA, Europie i Izraelu przy tworzeniu dużych aplikacji Node.js. Wiele z powyższych dobrych praktyk opublikowano po raz pierwszy na stronie [goldbergyoni.com](https://goldbergyoni.com). Dosięgnij Yoni'ego na [@goldbergyoni](https://github.com/goldbergyoni) lub [me@goldbergyoni.com](mailto:me@goldbergyoni.com)
+
+
+
+
+
+[Bruno Scheufler](https://github.com/BrunoScheufler)
+
+
+💻 full-stack web engineer, entuzjasta Node.js & GraphQL
+
+
+
+
+
+[Kyle Martin](https://github.com/js-kyle)
+
+
+
+Full Stack Developer & Site Reliability Engineer z siedzibą w Nowej Zelandii, zainteresowany bezpieczeństwem aplikacji internetowych oraz architekturą i budowaniem aplikacji Node.js dla działania w skali globalnej.
+
+
+
+
+
+[Sagir Khan](https://github.com/sagirk)
+
+
+
+
+Doświadczony specjalista w JavaScript i jego ekosystemie - React, Node.js, MongoDB, prawie wszystko co wymaga użycia JavaScript / JSON w dowolnej warstwie systemu - tworzenie produktów przy użyciu platformy internetowej dla najbardziej rozpoznawalnych marek na świecie. Członek Fundacji Node.js, współpracujący przy inicjatywie redesign witryny internetowej komitetu społeczności.
+
+
+
+## Współpracownicy
+
+Dziękujemy wszystkim wpółpracownikom! 🙏
+
+Nasi współpracownicy są członkami, którzy regularnie współuczestniczą w repozytorium, sugerując nowe najlepsze praktyki, analizując problemy, sprawdzając pull requesty i wiele więcej. Jeśli chcesz pomóc nam poprowadzić tysiące ludzi do tworzenia lepszych aplikacji Node.js, przeczytaj nasze [wytyczne dla współpracowników](./.operations/CONTRIBUTING.md) 🎉
+
+| | |
+| :---------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
+| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
+
+### Wcześniejsza współpraca
+
+| |
+| :-------------------------------------------------------------------------------------------------------------------------: |
+| [Refael Ackermann](https://github.com/refack) |
+
+
+
+## Dziękujemy za uwagi
+
+Doceniamy każdy wkład, od poprawki pojedynczego słowa, po nową najlepszą praktykę. Zobacz naszych autorów i [dokumentację CONTRIBUTORS tutaj!](./README.md#contributors-)
+
diff --git a/README.russian.md b/README.russian.md
index e396460a9..7030112dd 100644
--- a/README.russian.md
+++ b/README.russian.md
@@ -3,22 +3,22 @@
# Node.js Лучшие практики
-
+
-
+
-[](https://twitter.com/nodepractices/) **Следите за нами в Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
+[](https://twitter.com/nodepractices/) **Следите за нами в Twitter!** [**@nodepractices**](https://twitter.com/nodepractices/)
-Читайте на других языках: [**CN**](/README.chinese.md), [**BR**](/README.brazilian-portuguese.md), [**RU**](/README.russian.md) [(**ES**, **FR**, **HE**, **KR** and **TR** in progress!)](#translations)
+Читайте на других языках: [**CN**](./README.chinese.md), [**BR**](./README.brazilian-portuguese.md), [**RU**](./README.russian.md), [**EU**](./README.basque.md) [(**ES**, **FR**, **HE**, **KR** and **TR** in progress! )](#translations)
@@ -26,19 +26,19 @@
# Последние лучшие практики и новости
-- **✅ Новая лучшая практика:** 7.1: [Не блокируйте цикл событий](#7-draft-performance-best-practices) by Keith Holliday
+- **✅ Новая лучшая практика:** 7.1: [Не блокируйте цикл событий](#-71-не-блокируйте-цикл-событий) by Keith Holliday
-- **🇷🇺 Перевод на русский:** Alex Ivanov недавно опубликовал опубликовал [Russian translation](/README.russian.md)
+- **🇷🇺 Перевод на русский:** Alex Ivanov недавно опубликовал [Russian translation](./README.russian.md)
- **Мы ищем авторов текстов:** хотите помочь с примерами TypeScript? Пожалуйста, обратитесь, открыв вопрос.
-# Добро пожаловать! 3 вещи, которые вы должны знать в первую очередь:
+# Добро пожаловать! 3 вещи, которые вы должны знать в первую очередь
**1. На самом деле вы читаете десятки лучших статей Node.js -** этот репозиторий представляет собой краткий обзор и список наиболее популярных материалов по рекомендациям Node.js, а также материалов, написанных здесь соавторами.
-**2. Это самая большая подборка, и она растет каждую неделю -** в настоящее время представлено более 80 2передовых практик, руководств по стилю и архитектурных советов. Новые выпуски и запросы на добавление, чтобы обновлять эту живую книгу, создаются каждый день. Мы бы хотели, чтобы вы внесли свой вклад здесь, будь то исправление ошибок в коде, помощь с переводами или предложение блестящих новых идей. Смотрите наши [правила написания здесь](/.operations/writing-guidelines.md).
+**2. Это самая большая подборка, и она растет каждую неделю -** в настоящее время представлено более 80 передовых практик, руководств по стилю и архитектурных советов. Новые выпуски и запросы на добавление, чтобы обновлять эту живую книгу, создаются каждый день. Мы бы хотели, чтобы вы внесли свой вклад здесь, будь то исправление ошибок в коде, помощь с переводами или предложение блестящих новых идей. Смотрите наши [правила написания здесь](./.operations/writing-guidelines.md).
**3. У большинства лучших практик есть дополнительная информация -** большинство маркеров включают в себя ссылку **🔗 Подробнее**, которая расширяет практику с примерами кода, цитатами из выбранных блогов и дополнительной информацией.
@@ -46,13 +46,13 @@
## Оглавление
-1. [Практики структуры проекта (5)](#1-Практики-структуры-проекта)
-2. [Практики обработки ошибок (11)](#2-Практики-обработки-ошибок)
-3. [Практики стиля кода (12)](#3-Практики-стиля-кода)
-4. [Тестирование и общие методы контроля качества (12)](#4-Тестирование-и-общие-методы-контроля-качества)
-5. [Переход к производственным практикам (18)](#5-Переход-к-производственным-практикам)
-6. [Практики безопасности (25)](#6-Практики-безопасности)
-7. [Практики эффективности (2) (Работа в процессе️ ✍️)](#7-Практики-эффективности)
+1. [Практики структуры проекта (5)](#1-Практики-структуры-проекта)
+2. [Практики обработки ошибок (11)](#2-Практики-обработки-ошибок)
+3. [Практики стиля кода (12)](#3-Практики-стиля-кода)
+4. [Тестирование и общие методы контроля качества (12)](#4-Тестирование-и-общие-методы-контроля-качества)
+5. [Переход к производственным практикам (18)](#5-Переход-к-производственным-практикам)
+6. [Практики безопасности (25)](#6-Практики-безопасности)
+7. [Практики эффективности (2) (Работа в процессе️ ✍️)](#7-черновик-практики-эффективности)
@@ -64,7 +64,7 @@
**Иначе:** Когда разработчики, которые пишут новые функции, изо всех сил пытаются понять влияние своих изменений и боятся сломать другие зависимые компоненты, развертывания становятся медленнее и рискованнее. Также считается сложнее масштабировать, когда все бизнес-единицы не разделены.
-🔗 [**Подробнее: Структурируйте свое решение по компонентам**](/sections/projectstructre/breakintcomponents.russian.md)
+🔗 [**Подробнее: Структурируйте свое решение по компонентам**](./sections/projectstructre/breakintcomponents.russian.md)
@@ -74,7 +74,7 @@
**Иначе:** Приложение, которое смешивает веб-объекты с другими слоями, не может быть доступно для тестирования кода, заданий CRON и других вызовов в обход Express.
-🔗 [**Подробнее: Выделяйте ваши компоненты в отдельный слой, держите Express в его границах**](/sections/projectstructre/createlayers.russian.md)
+🔗 [**Подробнее: Выделяйте ваши компоненты в отдельный слой, держите Express в его границах**](./sections/projectstructre/createlayers.russian.md)
@@ -84,27 +84,27 @@
**Иначе:** Вам придется изобрести собственный велосипед для развертывания и поддержания зависимостей.
-🔗 [**Подробнее: Оборачивайте общие утилиты в пакеты npm**](/sections/projectstructre/wraputilities.russian.md)
+🔗 [**Подробнее: Оборачивайте общие утилиты в пакеты npm**](./sections/projectstructre/wraputilities.russian.md)
## ![✔] 1.4 Разделяйте Express "приложение" и "сервер"
-**TL;DR:** Избегайте неприятной привычки определять все приложение [Express] (https://expressjs.com/) в одном огромном файле -- разделите определение "Экспресс" как минимум на два файла: декларация API (app.js) и сетевые задачи (www). Для еще лучшей структуры локализуйте объявление API в компонентах.
+**TL;DR:** Избегайте неприятной привычки определять все приложение [Express](https://expressjs.com/) в одном огромном файле -- разделите определение "Экспресс" как минимум на два файла: декларация API (app.js) и сетевые задачи (www). Для еще лучшей структуры локализуйте объявление API в компонентах.
-**Иначе:** Ваш API будет доступен для тестирования только через HTTP-вызовы (медленнее и намного сложнее создавать отчеты о покрытии). Скорее всего, не составит большого труда хранить сотни строк кода в одном файле.
+**Иначе:** Ваш API будет доступен для тестирования только через HTTP-вызовы (медленнее и намного сложнее создавать отчеты о покрытии). Скорее всего, вы не будете испытывать огромное удовольствие, если будете хранить сотни строк кода в одном файле.
-🔗 [**Подробнее: Разделяйте Express "приложение" и "сервер"**](/sections/projectstructre/separateexpress.russian.md)
+🔗 [**Подробнее: Разделяйте Express "приложение" и "сервер"**](./sections/projectstructre/separateexpress.russian.md)
-## ![✔] 1.5 Используйте конфигурацию с учетом среды, безопасную и иерархическую конфигурацию
+## ![✔] 1.5 Используйте безопасную и иерархическую конфигурацию с учетом среды
-**TL;DR:** Идеальная и безупречная конфигурация конфигурации должна обеспечивать (а) считывание ключей из файла И из переменной среды, (б) хранение секретов вне основной кодовой базы, (в) иерархическую структуру для облегчения поиска. Есть несколько пакетов, которые могут помочь поставить галочку в большинстве таких полей, как [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) and [config](https://www.npmjs.com/package/config)
+**TL;DR:** Идеальная и безупречная конфигурация должна обеспечивать (а) считывание ключей из файла И из переменной среды, (б) хранение секретов вне основной кодовой базы, (в) иерархическую структуру для облегчения поиска. Есть несколько пакетов, которые могут помочь поставить галочку в большинстве таких полей, как [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config), and [convict](https://www.npmjs.com/package/convict)
-**Иначе:** Невыполнение каких-либо требований к конфигурации приведет к срывам в работе разработчиков или devops командой. Вероятно, и тех и других.
+**Иначе:** Невыполнение каких-либо требований к конфигурации приведет к срывам в работе разработчиков или devops-команды. А вероятно, и тех и других.
-🔗 [**Подробнее: Используйте конфигурацию с учетом среды, безопасную и иерархическую конфигурацию**](/sections/projectstructre/configguide.russian.md)
+🔗 [**Подробнее: Используйте конфигурацию с учетом среды, безопасную и иерархическую конфигурацию**](./sections/projectstructre/configguide.russian.md)
@@ -116,9 +116,9 @@
**TL;DR:** Обработка асинхронных ошибок в стиле обратного вызова, вероятно, является самым быстрым путем в ад (еще говорят "Callback Hell" или "The Pyramid of Doom"). Лучший подарок, который вы можете сделать своему коду, -- это использовать надежную библиотеку обещаний или async-await, что позволяет использовать более компактный и знакомый синтаксис кода, такой как try-catch.
-**Иначе:** Стиль обратного вызова Node.js, функция (err, response), является многообещающим способом создания непригодного для использования кода из-за сочетания обработки ошибок со случайным кодом, чрезмерных вложений и слабых шаблонов кодирования.
+**Иначе:** Callback-стиль Node.js, function(err, response), является многообещающим способом создания непригодного для использования кода из-за сочетания таких проблем, как обработка ошибок со случайным кодом, чрезмерные вложения и неудобные шаблоны проектирования.
-🔗 [**Подробнее: Используйте Async-Await или обещания для асинхронной обработки ошибок**](/sections/errorhandling/asyncerrorhandling.russian.md)
+🔗 [**Подробнее: Используйте Async-Await или обещания для асинхронной обработки ошибок**](./sections/errorhandling/asyncerrorhandling.russian.md)
@@ -128,27 +128,27 @@
**Иначе:** При вызове какого-либо компонента нельзя быть уверенным, какой тип ошибок приходит в ответ -- это значительно затрудняет правильную обработку ошибок. Хуже того, использование пользовательских типов для описания ошибок может привести к потере информации о критических ошибках, таких как трассировка стека!
-🔗 [**Подробнее: Используйте только встроенный объект Error**](/sections/errorhandling/useonlythebuiltinerror.russian.md)
+🔗 [**Подробнее: Используйте только встроенный объект Error**](./sections/errorhandling/useonlythebuiltinerror.russian.md)
-## ![✔] 2.3 Различайте ошибки в работе и программировании
+## ![✔] 2.3 Различайте операционные ошибки и ошибки программиста
-**TL;DR:** Операционные ошибки (например, API получил неверный ввод) относятся к известным случаям, когда влияние ошибки полностью осознается и может быть обработано вдумчиво. С другой стороны, ошибка программиста (например, попытка прочитать неопределенную переменную) относится к неизвестным ошибкам кода, которые требуют изящного перезапуска приложения.
+**TL;DR:** Операционные ошибки (например, API получил неверный ввод) относятся к таким случаям, когда влияние ошибки полностью осознается и может быть обработано вдумчиво. Ошибка программиста (например, попытка прочитать undefined-переменную) относится к неизвестным ошибкам, которые требуют безопасного перезапуска приложения.
-**Иначе:** Вы всегда можете перезапустить приложение, когда появляется ошибка, но зачем подводить ~5000 онлайн-пользователей из-за незначительной, прогнозируемой, операционной ошибки? Обратное также не идеально -- поддержание приложения в том случае, если возникла неизвестная проблема (ошибка программиста), может привести к непредсказуемому поведению. Разграничение между ними позволяет действовать тактично и применять сбалансированный подход, основанный на данном контексте.
+**Иначе:** Вы всегда можете перезапустить приложение, когда появляется ошибка, но зачем подводить ~5000 онлайн-пользователей из-за незначительной и прогнозируемой операционной ошибки? Обратное также не является идеальным -- отсутствие перезапуска приложения в случае, если возникла неизвестная проблема (ошибка программиста), может привести к непредсказуемому поведению. Понимание типа ошибки позволит действовать тактично и применять сбалансированный подход, основанный на предоставленном контексте.
-🔗 [**Подробнее: Различайте операционные и программистские ошибки**](/sections/errorhandling/operationalvsprogrammererror.russian.md)
+🔗 [**Подробнее: Различайте операционные ошибки и ошибки программиста**](./sections/errorhandling/operationalvsprogrammererror.russian.md)
-## ![✔] 2.4 Обрабатывате ошибки централизованно, а не в промежуточном слое Express
+## ![✔] 2.4 Обрабатывате ошибки централизованно, а не в промежуточных обработчиках Express
-**TL;DR:** Логика обработки ошибок, такая как уведомление по почте администратора или ведение журнала, должна быть заключена в выделенный и централизованный объект, который вызывается всеми конечными точками (например, промежуточные слои Express, задания cron, модульное тестирование) при возникновении ошибки.
+**TL;DR:** Логика обработки ошибок, например, как уведомление по почте администратора или ведение журнала, должна быть инкапсулирована в выделенный и централизованный объект, который вызывается всеми точками входа (обработчиками Express, cron-задачами, юнит-тестами) при возникновении ошибки.
-**Иначе:** Необработка ошибок в одном месте приведет к дублированию кода и, возможно, к ошибкам, обработанным неправильно.
+**Иначе:** Отсутствие обработки ошибок в едином месте приведет к дублированию кода и, возможно, к неверной обработке ошибок.
-🔗 [**Подробнее: Обрабатывайте ошибки централизованно. Не в промежуточных слоях**](/sections/errorhandling/centralizedhandling.russian.md)
+🔗 [**Подробнее: Обрабатывайте ошибки централизованно. Не в промежуточных слоях**](./sections/errorhandling/centralizedhandling.russian.md)
@@ -158,7 +158,7 @@
**Иначе:** Клиент API может принять решение о сбое и перезапуске только потому, что он получил ошибку, которую он не может понять. Примечание: вызывающим абонентом вашего API можете быть и вы сами (очень типично для микросервисной среды)
-🔗 [**Подробнее: Документироваие ошибок API при использовании Swagger или GraphQL**](/sections/errorhandling/documentingusingswagger.russian.md)
+🔗 [**Подробнее: Документироваие ошибок API при использовании Swagger или GraphQL**](./sections/errorhandling/documentingusingswagger.russian.md)
@@ -168,7 +168,7 @@
**Иначе:** Когда происходит незнакомое исключение, некоторый объект может быть в неисправном состоянии (например, источник событий, который используется глобально и больше не генерирует события из-за некоторого внутреннего сбоя), и все будущие запросы могут давать сбой или вести себя безумно.
-🔗 [**Подробнее: Изящно выходите из процесса, когда неизвестное случается**](/sections/errorhandling/shuttingtheprocess.russian.md)
+🔗 [**Подробнее: Изящно выходите из процесса, когда неизвестное случается**](./sections/errorhandling/shuttingtheprocess.russian.md)
@@ -178,7 +178,7 @@
**Иначе:** Сканирование через console.logs или вручную через грязный текстовый файл без запросов инструментов или приличного просмотра журнала может занять вас на работе до поздна.
-🔗 [**Подробнее: Используйте проверенный логгер, чтобы увеличить видимость ошибок**](/sections/errorhandling/usematurelogger.russian.md)
+🔗 [**Подробнее: Используйте проверенный логгер, чтобы увеличить видимость ошибок**](./sections/errorhandling/usematurelogger.russian.md)
@@ -188,7 +188,7 @@
**Иначе:** Без тестирования, будь то автоматически или вручную, вы не сможете полагаться на свой код для возврата правильных ошибок. Без значения ошибок -- нет обработки ошибок.
-🔗 [**Подробнее: Тестируйте потоки ошибок с использованием вашей любимой тестовой среды**](/sections/errorhandling/testingerrorflows.russian.md)
+🔗 [**Подробнее: Тестируйте потоки ошибок с использованием вашей любимой тестовой среды**](./sections/errorhandling/testingerrorflows.russian.md)
@@ -198,7 +198,7 @@
**Иначе:** Вы можете потратить огромные усилия на измерение производительности и времени простоя API, возможно, вы никогда самостоятельно не узнаете, какие части кода в реально сценарии самые медленные, и как они влияют на UX.
-🔗 [**Подробнее: Обнаружение ошибок и простоев с использованием продуктов APM**](/sections/errorhandling/apmproducts.russian.md)
+🔗 [**Подробнее: Обнаружение ошибок и простоев с использованием продуктов APM**](./sections/errorhandling/apmproducts.russian.md)
@@ -208,7 +208,7 @@
**Иначе:** Ваши ошибки будут проглочены и не оставят следов. Не о чем беспокоиться!
-🔗 [**Подробнее: Перехватывайте необработанные отказы от обещаний**](/sections/errorhandling/catchunhandledpromiserejection.russian.md)
+🔗 [**Подробнее: Перехватывайте необработанные отказы от обещаний**](./sections/errorhandling/catchunhandledpromiserejection.russian.md)
@@ -218,10 +218,25 @@
**Иначе:** Учтите это -- ваша функция ожидает числовой аргумент "Скидка", который вызывающая сторона забывает передать, позже ваш код проверяет, если Скидка !=0 (сумма разрешенной скидки больше нуля), тогда она позволит пользователю пользоваться скидкой. О, Боже, какая неприятная ошибка! Видишь?
-🔗 [**Подробнее: Быстро проваливайтесь, проверяя аргументы, используя выделенную библиотеку**](/sections/errorhandling/failfast.russian.md)
+🔗 [**Подробнее: Быстро проваливайтесь, проверяя аргументы, используя выделенную библиотеку**](./sections/errorhandling/failfast.russian.md)
+
+## ![✔] 2.12 Для полноты стектрейсов всегда делайте await промисам прежде чем вернуть их из функции
+
+**TL;DR:** Дабы не иметь пропусков вызовов в стектрейсах, при возвращении промисов всегда
+выполняйте `return await`. Если функция возвращает промис то эта функция обязана быть объявлена
+как `async` и явно разрешить промис через `await` прежде чем
+вернуть его
+
+**Иначе:** Функция возвращающая неразрешенный промис будет отсутствовать в стектрейсе. Такие
+пропуски, вероятнее всего, усложнят процесс понимания пути возникновения ошибки, особенно если
+причина ненормального поведения как раз в отсутствующей функции и находится
+
+🔗 [**Подробнее: возвращение промисов**](./sections/errorhandling/returningpromises.russian.md)
+
# `3. Практики стиля кода`
@@ -232,7 +247,7 @@
**Иначе:** Разработчики сосредоточатся на утомительных проблемах с интервалами и шириной линии, и время может быть потрачено впустую на продумывание стиля кода проекта.
-🔗 [**Подробнее: Использование ESLint и Prettier**](/sections/codestylepractices/eslint_prettier.russian.md)
+🔗 [**Подробнее: Использование ESLint и Prettier**](./sections/codestylepractices/eslint_prettier.russian.md)
@@ -244,7 +259,7 @@
-##! [✔] 3.3 Начинайте кодовый блок фигурными скобками на той же линии.
+## ! [✔] 3.3 Начинайте кодовый блок фигурными скобками на той же линии
**TL;DR:** Открывающие фигурные скобки блока кода должны находиться на той же строке, что и оператор открытия.
@@ -269,7 +284,7 @@ function someFunction()
-##! [✔] 3.4 Разделяйте свои выражения правильно
+## ! [✔] 3.4 Разделяйте свои выражения правильно
Независимо от того, используете ли вы точки с запятой или нет для разделения своих операторов, знание общих ошибок неправильных разрывов строк или автоматической вставки точек с запятой поможет вам устранить обычные синтаксические ошибки.
@@ -277,7 +292,7 @@ function someFunction()
**Иначе:** Как видно из предыдущего раздела, интерпретатор JavaScript автоматически добавляет точку с запятой в конце оператора, если его нет, или считает, что оператор не завершен, где он должен, что может привести к нежелательным результатам. , Вы можете использовать присваивания и избегать немедленного вызова выражений функций для предотвращения большинства непредвиденных ошибок.
-### Пример кода
+### 3.4 Пример кода
```javascript
// Делайте так
@@ -317,7 +332,7 @@ const count = 2 // it tries to run 2(), but 2 is not a function
**TL;DR:** Назовите все функции, включая замыкания и обратные вызовы. Избегайте анонимных функций. Это особенно полезно при профилировании приложения узла. Обозначение всех функций позволит вам легко понять, на что вы смотрите при проверке снимка памяти.
-**Иначе:** Отладка производственных проблем с использованием дампа ядра (снимока памяти) может стать сложной, так как вы замечаете значительное потребление памяти анонимными функциями.
+**Иначе:** Отладка производственных проблем с использованием дампа ядра (снимка памяти) может стать сложной, так как вы замечаете значительное потребление памяти анонимными функциями.
@@ -327,7 +342,7 @@ const count = 2 // it tries to run 2(), but 2 is not a function
**Иначе:** Javascript -- это единственный язык в мире, который позволяет напрямую вызывать конструктор ("Class") без его инициализации. Следовательно, классы и конструкторы функций должщны различаться, начинаясь с UpperCamelCase.
-### Пример кода
+### 3.6 Пример кода
```javascript
// для класса мы используем UpperCamelCase
@@ -335,11 +350,11 @@ class SomeClassExample {}
// для константы мы используем служебное слово const и lowerCamelCase
const config = {
- key: 'value'
+ key: "value",
};
// для переменных и функций мы используем lowerCamelCase
-let someVariableExample = 'value';
+let someVariableExample = "value";
function doSomething() {}
```
@@ -369,16 +384,16 @@ function doSomething() {}
**Иначе:** Изменение внутренней структуры файлов или подписи может нарушить интерфейс с клиентами.
-### Пример кода
+### 3.9 Пример кода
```javascript
// Делайте так
-module.exports.SMSProvider = require('./SMSProvider');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver');
+module.exports.SMSProvider = require("./SMSProvider");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver");
// Избегайте
-module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
-module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
+module.exports.SMSProvider = require("./SMSProvider/SMSProvider.js");
+module.exports.SMSNumberResolver = require("./SMSNumberResolver/SMSNumberResolver.js");
```
@@ -389,21 +404,21 @@ module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolve
**Иначе:** Неравные переменные могут возвращать true при сравнении с оператором `==`.
-### Пример кода
+### 3.10 Пример кода
```javascript
-'' == '0' // false
-0 == '' // true
-0 == '0' // true
+"" == "0"; // false
+0 == ""; // true
+0 == "0"; // true
-false == 'false' // false
-false == '0' // true
+false == "false"; // false
+false == "0"; // true
-false == undefined // false
-false == null // false
-null == undefined // true
+false == undefined; // false
+false == null; // false
+null == undefined; // true
-' \t\r\n ' == 0 // true
+" \t\r\n " == 0; // true
```
Все приведенные выше операторы вернут false, если используются с `===`.
@@ -448,17 +463,17 @@ null == undefined // true
**Иначе:** Развертывание только что прошло, тест под названием "Добавить продукт" не прошел. Это говорит вам, что именно работает со сбоями?
-🔗 [**Подробнее: Включите 3 части в каждое название теста**](/sections/testingandquality/3-parts-in-name.russian.md)
+🔗 [**Подробнее: Включите 3 части в каждое название теста**](./sections/testingandquality/3-parts-in-name.russian.md)
-## ![✔] 4.3 Структурные тесты AAA-подходом]
+## ![✔] 4.3 Структурные тесты AAA-подходом
**TL;DR:** Структурируйте свои тесты с тремя хорошо разделенными секциями: Arrange, Act & Assert AAA). Первая часть включает в себя настройку теста, затем выполнение тестируемого модуля и, наконец, этап подтверждения. Следование этой структуре гарантирует, что читатель не тратит мозговые ЦП на понимание плана тестирования.
**Иначе:** Не только вы тратите долгие ежедневные часы на понимание основного кода, теперь и то, что должно было быть простой частью дня (тестирование), напрягает ваш мозг.
-🔗 [**Read More: Structure tests by the AAA pattern**](/sections/testingandquality/aaa.russian.md)
+🔗 [**Read More: Structure tests by the AAA pattern**](./sections/testingandquality/aaa.russian.md)
@@ -476,7 +491,7 @@ null == undefined // true
**Иначе:** Рассмотрим сценарий, в котором развертывание прерывается из-за неудачных тестов, теперь команда собирается потратить драгоценное время на исследование, которое заканчивается печальным выводом: система работает хорошо, однако тесты мешают друг другу и нарушают сборку.
-🔗 [**Подробнее: Избегайте глобальных тестовых приспособлений и параметров, добавляйте данные для каждого теста**](/sections/testingandquality/avoid-global-test-fixture.russian.md)
+🔗 [**Подробнее: Избегайте глобальных тестовых приспособлений и параметров, добавляйте данные для каждого теста**](./sections/testingandquality/avoid-global-test-fixture.russian.md)
@@ -526,7 +541,7 @@ null == undefined // true
**Иначе:** При плохом качестве кода ошибки и производительность всегда будут проблемой, которую не может исправить ни одна блестящая новая библиотека или современные функции.
-🔗 [**Подробнее: Рефакторинг**](/sections/testingandquality/refactoring.russian.md)
+🔗 [**Подробнее: Рефакторинг**](./sections/testingandquality/refactoring.russian.md)
@@ -536,7 +551,7 @@ null == undefined // true
**Иначе:** Выбор какого-либо нишевого поставщика может заблокировать вас, когда вам понадобится дополнительная настройка. С другой стороны, работа с Jenkins может потратить драгоценное время на настройку инфраструктуры.
-🔗 [**Подробнее: Тщательно выбирайте платформу CI**](/sections/testingandquality/citools.russian.md)
+🔗 [**Подробнее: Тщательно выбирайте платформу CI**](./sections/testingandquality/citools.russian.md)
@@ -544,13 +559,13 @@ null == undefined // true
# `5. Переход к производственным практикам`
-## ![✔] 5.1. Мониторинг!
+## ![✔] 5.1. Мониторинг
**TL;DR:** Мониторинг -- это игра для выявления проблем до того, как их решат клиенты, очевидно, этому следует придать беспрецедентную важность. Рынок перегружен предложениями, поэтому подумайте о том, чтобы начать с определения основных метрик, которым вы должны следовать (мои предложения в подробностях), затем перейти к дополнительным необычным функциям и выбрать решение, которое помечает все поля. Нажмите "Подробнее" ниже для обзора решений.
**Иначе:** Отказ === разочарованные клиенты. Просто.
-🔗 [**Подробнее: Мониторинг!**](/sections/production/monitoring.russian.md)
+🔗 [**Подробнее: Мониторинг!**](./sections/production/monitoring.russian.md)
@@ -560,7 +575,7 @@ null == undefined // true
**Иначе:** Вы в конечном итоге получаете черный ящик, о котором трудно подумать, затем вы начинаете переписывать все операторы регистрации, чтобы добавить дополнительную информацию.
-🔗 [**Подробнее: Сделайте ваше приложение прозрачным, используя умные логи**](/sections/production/smartlogging.russian.md)
+🔗 [**Подробнее: Сделайте ваше приложение прозрачным, используя умные логи**](./sections/production/smartlogging.russian.md)
@@ -570,7 +585,7 @@ null == undefined // true
**Иначе:** Ваш бедный одиночный поток будет занят выполнением инфраструктурных задач вместо того, чтобы работать с ядром приложения, и производительность будет соответственно снижаться.
-🔗 [**Подробнее: Делегируйте все возможное (например, gzip, SSL) обратному прокси**](/sections/production/delegatetoproxy.russian.md)
+🔗 [**Подробнее: Делегируйте все возможное (например, gzip, SSL) обратному прокси**](./sections/production/delegatetoproxy.russian.md)
@@ -580,7 +595,7 @@ null == undefined // true
**Иначе:** QA тщательно протестирует код и утвердит версию, которая будет вести себя по-другому в производстве. Хуже того, на разных серверах в одном и том же производственном кластере может выполняться другой код.
-🔗 [**Подробнее: Блокируйте зависимости**](/sections/production/lockdependencies.russian.md)
+🔗 [**Подробнее: Блокируйте зависимости**](./sections/production/lockdependencies.russian.md)
@@ -590,7 +605,7 @@ null == undefined // true
**Иначе:** Запуск десятков экземпляров без четкой стратегии и слишком большого количества инструментов (управление кластером, docker, PM2) может привести к хаосу DevOps.
-🔗 [**Подробнее: Защищайте и перезапускайте свой процесс в случае неудачи (используя правильный инструмент)**](/sections/production/guardprocess.russian.md)
+🔗 [**Подробнее: Защищайте и перезапускайте свой процесс в случае неудачи (используя правильный инструмент)**](./sections/production/guardprocess.russian.md)
@@ -600,7 +615,7 @@ null == undefined // true
**Иначе:** Ваше приложение, скорее всего, будет использовать только 25% доступных ресурсов (!) Или даже меньше. Обратите внимание, что типичный сервер имеет 4 или более ядер ЦП, для простого развертывания Node.js используется только 1 (даже при использовании сервисов PaaS, таких как AWS beanstalk!)
-🔗 [**Подробнее: Используйте все ядра процессора**](/sections/production/utilizecpu.russian.md)
+🔗 [**Подробнее: Используйте все ядра процессора**](./sections/production/utilizecpu.russian.md)
@@ -610,7 +625,7 @@ null == undefined // true
**Иначе:** Вы обнаружите, что выполняете много "диагностических развертываний" -- отправка кода в производство только для извлечения некоторой информации в диагностических целях.
-🔗 [**Подробнее: Создавайте конечную точку обслуживания**](/sections/production/createmaintenanceendpoint.russian.md)
+🔗 [**Подробнее: Создавайте конечную точку обслуживания**](./sections/production/createmaintenanceendpoint.russian.md)
@@ -620,7 +635,7 @@ null == undefined // true
**Иначе:** Вы можете потратить огромные усилия на измерение производительности и времени простоя API, возможно, вы никогда не узнаете, какие ваши самые медленные части кода в реальном сценарии и как они влияют на UX.
-🔗 [**Подробнее: Уверенный пользовательский опыт с продуктами APM**](/sections/production/apmproducts.russian.md)
+🔗 [**Подробнее: Уверенный пользовательский опыт с продуктами APM**](./sections/production/apmproducts.russian.md)
@@ -630,7 +645,7 @@ null == undefined // true
**Иначе:** Чемпион мира по IT/DevOps не спасет плохо написанную систему.
-🔗 [**Подробнее: Делайте ваш код готовым к работе**](/sections/production/productioncode.russian.md)
+🔗 [**Подробнее: Делайте ваш код готовым к работе**](./sections/production/productioncode.russian.md)
@@ -640,7 +655,7 @@ null == undefined // true
**Иначе:** Ваша память процесса может пропускать сотни мегабайт в день, как это было в [Walmart](https://www.joyent.com/blog/walmart-node-js-memory-leak).
-🔗 [**Подробнее: Измеряйте и защищайте использование памяти**](/sections/production/measurememory.russian.md)
+🔗 [**Подробнее: Измеряйте и защищайте использование памяти**](./sections/production/measurememory.russian.md)
@@ -650,7 +665,7 @@ null == undefined // true
**Иначе:** Ваш единственный поток Node будет занят потоковой передачей сотен файлов html/images/angular/react вместо того, чтобы выделять все свои ресурсы на задачи, для которой он был создан -- обслуживание динамического контента.
-🔗 [**Подробнее: Получайте ваши внешние ресурсы вне Node**](/sections/production/frontendout.russian.md)
+🔗 [**Подробнее: Получайте ваши внешние ресурсы вне Node**](./sections/production/frontendout.russian.md)
@@ -660,7 +675,7 @@ null == undefined // true
**Иначе:** Сбой на данном сервере приведет к простою приложения, а не просто к гибели неисправного компьютера. Более того, гибкость масштабирования станет более сложной из-за зависимости от конкретного сервера.
-🔗 [**Подробнее: Не прописывайтесь на постоянку, убивайте свои серверы почти каждый день**](/sections/production/bestateless.md)
+🔗 [**Подробнее: Не прописывайтесь на постоянку, убивайте свои серверы почти каждый день**](./sections/production/bestateless.md)
@@ -670,7 +685,7 @@ null == undefined // true
**Иначе:** Для обеспечения чистоты кода от уязвимостей без использования специальных инструментов вам потребуется постоянно следить за публикациями в Интернете о новых угрозах. Довольно утомительно.
-🔗 [**Подробнее: Используйте инструменты, которые автоматически обнаруживают уязвимые зависимости**](/sections/production/detectvulnerabilities.russian.md)
+🔗 [**Подробнее: Используйте инструменты, которые автоматически обнаруживают уязвимые зависимости**](./sections/production/detectvulnerabilities.russian.md)
@@ -680,7 +695,7 @@ null == undefined // true
**Иначе:** Глядя на журнал ошибок производства без контекста -- что произошло раньше -- становится намного сложнее и медленнее рассуждать о проблеме.
-🔗 [**Read More: Назначьте "TransactionId" для каждого вхождения журнала логирования**](/sections/production/assigntransactionid.russian.md)
+🔗 [**Read More: Назначьте "TransactionId" для каждого вхождения журнала логирования**](./sections/production/assigntransactionid.russian.md)
@@ -690,7 +705,7 @@ null == undefined // true
**Иначе:** Пропуск этого простого свойства может значительно снизить производительность. Например, при использовании Express для рендеринга на стороне сервера пропуск `NODE_ENV` замедляет его в три раза!
-🔗 [**Подробнее: Устанавливайте NODE_ENV=production**](/sections/production/setnodeenv.russian.md)
+🔗 [**Подробнее: Устанавливайте NODE_ENV=production**](./sections/production/setnodeenv.russian.md)
@@ -708,7 +723,7 @@ null == undefined // true
**Иначе:** Недавно обнаруженные ошибки или уязвимости могут быть использованы для эксплуатации приложения, работающего в производственной среде, и ваше приложение может стать неподдерживаемым различными модулями и усложнить поддержку.
-🔗 [**Подробнее: Используйте LTS-релиз Node.js в производстве**](/sections/production/LTSrelease.russian.md)
+🔗 [**Подробнее: Используйте LTS-релиз Node.js в производстве**](./sections/production/LTSrelease.russian.md)
@@ -718,7 +733,7 @@ null == undefined // true
**Иначе:** Маршрутизация журналов обработки приложения === трудности масштабирования, потеря журналов, плохое разделение задач
-🔗 [**Подробнее: Код вашего приложения не должен обрабатывать журналы маршрутизации**](/sections/production/logrouting.russian.md)
+🔗 [**Подробнее: Код вашего приложения не должен обрабатывать журналы маршрутизации**](./sections/production/logrouting.russian.md)
@@ -738,7 +753,7 @@ null == undefined // true
**Иначе:** То, что могло быть простым недостатком безопасности во время разработки, становится основной проблемой в производстве. Кроме того, проект может не следовать согласованным методам обеспечения безопасности кода, что приводит к появлению уязвимостей или секретных секретов, передаваемых в удаленные репозитории.
-🔗 [**Подробнее: Пользуйтесь правилами безопасности линтера**](/sections/security/lintrules.russian.md)
+🔗 [**Подробнее: Пользуйтесь правилами безопасности линтера**](./sections/security/lintrules.russian.md)
@@ -750,7 +765,7 @@ null == undefined // true
**Иначе:** Приложение может подвергнуться атаке, приводящей к отказу в обслуживании, когда реальные пользователи получают ухудшенный или недоступный сервис.
-🔗 [**Подробнее: Ограничивайте одновременные запросы с использованием балансировщика или промежуточного программного обеспечения**](/sections/security/limitrequests.russian.md)
+🔗 [**Подробнее: Ограничивайте одновременные запросы с использованием балансировщика или промежуточного программного обеспечения**](./sections/security/limitrequests.russian.md)
@@ -762,7 +777,7 @@ null == undefined // true
**Иначе:** Контроль источников, даже для частных репозиториев, может быть ошибочно обнародован, после чего все секреты будут раскрыты. Доступ к управлению исходным кодом для внешней стороны непреднамеренно предоставит доступ к связанным системам (базам данных, API, службам и т.д.).
-🔗 [**Подробнее: Извлекайте секреты из конфигурационных файлов или используйте пакет npm, который их шифрует**](/sections/security/secretmanagement.russian.md)
+🔗 [**Подробнее: Извлекайте секреты из конфигурационных файлов или используйте пакет npm, который их шифрует**](./sections/security/secretmanagement.russian.md)
@@ -774,15 +789,15 @@ null == undefined // true
**Иначе:** Непроверенный или недеанонимизированный пользовательский ввод может привести к внедрению оператора при работе с MongoDB для NoSQL, а отсутствие надлежащей системы очистки или ORM легко разрешит атаки с использованием SQL-инъекции, создав гигантскую уязвимость.
-🔗 [**Подробнее: Предотвращайте уязвимости при внедрении базы данных с помощью библиотек ORM/ODM или других пакетов DAL**](/sections/security/ormodmusage.russian.md)
+🔗 [**Подробнее: Предотвращайте уязвимости при внедрении базы данных с помощью библиотек ORM/ODM или других пакетов DAL**](./sections/security/ormodmusage.russian.md)
-##! [✔] 6.5. Сборник общих рекомендаций по безопасности
+## ! [✔] 6.5. Сборник общих рекомендаций по безопасности
**TL;DR:** Это набор рекомендаций по безопасности, которые не связаны напрямую с Node.js -- реализация Node мало чем отличается от любого другого языка. Нажмите "Подробнее", чтобы просмотреть.
-🔗 [**Подробнее: Общие рекомендации по безопасности Node.js**](/sections/security/commonsecuritybestpractices.russian.md)
+🔗 [**Подробнее: Общие рекомендации по безопасности Node.js**](./sections/security/commonsecuritybestpractices.russian.md)
@@ -794,7 +809,7 @@ null == undefined // true
**Иначе:** Злоумышленники могут выполнять прямые атаки на пользователей вашего приложения, что приводит к огромным уязвимостям безопасности.
-🔗 [**Подробнее: Используйте связанные с безопасностью заголовки для защиты вашего приложения от распространенных атак**](/sections/security/secureheaders.russian.md)
+🔗 [**Подробнее: Используйте связанные с безопасностью заголовки для защиты вашего приложения от распространенных атак**](./sections/security/secureheaders.russian.md)
@@ -806,7 +821,7 @@ null == undefined // true
**Иначе:** Злоумышленник может обнаружить ваш веб-фреймворк и атаковать все его известные уязвимости.
-🔗 [**Подробнее: Постоянно и автоматически проверяйте наличие уязвимых зависимостей**](/sections/security/dependencysecurity.russian.md)
+🔗 [**Подробнее: Постоянно и автоматически проверяйте наличие уязвимых зависимостей**](./sections/security/dependencysecurity.russian.md)
@@ -818,11 +833,11 @@ null == undefined // true
**Иначе:** Пароли или секреты, которые сохраняются без использования защищенной функции, уязвимы для взлома и атак по словарю, которые в конечном итоге приведут к их раскрытию.
-🔗 [**Подробнее: Не используйте криптографическую библиотеку Node.js для паролей, используйте Bcrypt**](/sections/security/bcryptpasswords.russian.md)
+🔗 [**Подробнее: Не используйте криптографическую библиотеку Node.js для паролей, используйте Bcrypt**](./sections/security/bcryptpasswords.russian.md)
-##! [✔] 6.9. Экранируйте вывод HTML, JS и CSS
+## ! [✔] 6.9. Экранируйте вывод HTML, JS и CSS
@@ -830,7 +845,7 @@ null == undefined // true
**Иначе:** Злоумышленник может сохранить вредоносный код JavaScript в вашей БД, который затем будет отправлен бедным клиентам как есть.
-🔗 [**Подробнее: Экранируйте вывод**](/sections/security/escape-output.russian.md)
+🔗 [**Подробнее: Экранируйте вывод**](./sections/security/escape-output.russian.md)
@@ -842,7 +857,7 @@ null == undefined // true
**Иначе:** Ваша щедрость и разрешительный подход значительно увеличивают поверхность атаки и побуждают злоумышленника опробовать множество входных данных, пока они не найдут какую-то комбинацию для сбоя приложения.
-🔗 [**Подробнее: Проверяйте входящие JSON схемы**](/sections/security/validation.russian.md)
+🔗 [**Подробнее: Проверяйте входящие JSON схемы**](./sections/security/validation.russian.md)
@@ -854,7 +869,7 @@ null == undefined // true
**Иначе:** Устаревшие или неуместные токены могут быть использованы злонамеренно для доступа к приложению третьей стороной, которая может выдавать себя за владельца токена.
-🔗 [**Подробнее: Реализовывайте поддержку внесения JWT в черный список**](/sections/security/expirejwt.russian.md)
+🔗 [**Подробнее: Реализовывайте поддержку внесения JWT в черный список**](./sections/security/expirejwt.russian.md)
@@ -869,7 +884,7 @@ null == undefined // true
**Иначе:** Злоумышленник может выполнить неограниченное количество автоматических попыток ввода пароля для получения доступа к привилегированным учетным записям в приложении.
-🔗 [**Подробнее: Предотвращайте атаки методом грубой силы против авторизации**](/section/security/login-rate-limit.russian.md)
+🔗 [**Подробнее: Предотвращайте атаки методом грубой силы против авторизации**](./sections/security/login-rate-limit.russian.md)
@@ -881,7 +896,7 @@ null == undefined // true
**Иначе:** Злоумышленник, которому удается запустить скрипт на сервере, получает неограниченную власть над локальной машиной (например, он может изменить iptable и перенаправить трафик на свой сервер).
-🔗 [**Подробнее: Запускайте Node.js как пользователь без полномочий root**](/sections/security/non-root-user.russian.md)
+🔗 [**Подробнее: Запускайте Node.js как пользователь без полномочий root**](./sections/security/non-root-user.russian.md)
@@ -893,7 +908,7 @@ null == undefined // true
**Иначе:** Вашему приложению придется иметь дело с большими запросами, неспособными обработать другую важную работу, которую он должен выполнить, что приводит к снижению производительности и уязвимости к атакам DOS.
-🔗 [**Подробнее: Ограничивайте размер полезной нагрузки с помощью обратного прокси или промежуточного ПО**](/sections/security/requestpayloadsizelimit.russian.md)
+🔗 [**Подробнее: Ограничивайте размер полезной нагрузки с помощью обратного прокси или промежуточного ПО**](./sections/security/requestpayloadsizelimit.russian.md)
@@ -901,11 +916,11 @@ null == undefined // true
-**TL;DR:** `eval` -- это зло, поскольку оно позволяет выполнять пользовательский код JavaScript во время выполнения. Это не только проблема производительности, но и важная проблема безопасности из-за вредоносного кода JavaScript, который может быть получен из пользовательского ввода. Другой языковой особенностью, которую следует избегать, является конструктор `new Function`. `setTimeout` и` setInterval` также никогда не должны передавать динамический код JavaScript.
+**TL;DR:** `eval` -- это зло, поскольку оно позволяет выполнять пользовательский код JavaScript во время выполнения. Это не только проблема производительности, но и важная проблема безопасности из-за вредоносного кода JavaScript, который может быть получен из пользовательского ввода. Другой языковой особенностью, которую следует избегать, является конструктор `new Function`. `setTimeout` и`setInterval` также никогда не должны передавать динамический код JavaScript.
**Иначе:** Вредоносный код JavaScript находит путь в текст, передаваемый в `eval` или другие функции оценки языка JavaScript в режиме реального времени, и получает полный доступ к разрешениям JavaScript на странице. Эта уязвимость часто проявляется как атака XSS.
-🔗 [**Подробнее: Избегайте JavaScript eval утверждений**](/sections/security/avoideval.russian.md)
+🔗 [**Подробнее: Избегайте JavaScript eval утверждений**](./sections/security/avoideval.russian.md)
@@ -917,7 +932,7 @@ null == undefined // true
**Иначе:** Плохо написанные регулярные выражения могут быть подвержены DoS-атакам регулярного выражения, которые полностью блокируют цикл обработки событий. Например, популярный пакет `момент` был посчитан уязвимым для вредоносного использования RegEx в ноябре 2017 года.
-🔗 [**Подробнее: Предотвращайте ваше однопоточное выполнение от перегрузки злонамеренным RegEx**](/sections/security/regex.russian.md)
+🔗 [**Подробнее: Предотвращайте ваше однопоточное выполнение от перегрузки злонамеренным RegEx**](./sections/security/regex.russian.md)
@@ -929,7 +944,7 @@ null == undefined // true
**Иначе:** Вредоносный пользовательский ввод может найти путь к параметру, который используется для запроса измененных файлов, например, ранее загруженного файла в файловой системе, или для доступа к уже существующим системным файлам.
-🔗 [**Подробнее: Избегайте загрузки модулей с использованием переменных**](/sections/security/safemoduleloading.russian.md)
+🔗 [**Подробнее: Избегайте загрузки модулей с использованием переменных**](./sections/security/safemoduleloading.russian.md)
@@ -941,7 +956,7 @@ null == undefined // true
**Иначе:** Плагин может атаковать с помощью бесконечного множества вариантов, таких как бесконечные циклы, перегрузка памяти и доступ к чувствительным переменным среды процесса.
-🔗 [**Подробнее: Запускайте небезопасный код в песочнице**](/sections/security/sandbox.russian.md)
+🔗 [**Подробнее: Запускайте небезопасный код в песочнице**](./sections/security/sandbox.russian.md)
@@ -953,7 +968,7 @@ null == undefined // true
**Иначе:** Наивное использование дочерних процессов может привести к удаленному выполнению команды или атакам внедрения оболочки из-за того, что злонамеренный пользовательский ввод передан неантизированной системной команде.
-🔗 [**Подробнее: Будьте осторожны при работе с дочерними процессами**](/sections/security/childprocesses.russian.md)
+🔗 [**Подробнее: Будьте осторожны при работе с дочерними процессами**](./sections/security/childprocesses.russian.md)
@@ -965,7 +980,7 @@ null == undefined // true
**Иначе:** Чувствительная информация о приложении, такая как пути к файлам сервера, используемые сторонние модули и другие внутренние рабочие процессы приложения, которые могут быть использованы злоумышленником, может быть утечка из информации, найденной в трассировке стека.
-🔗 [**Подробнее: Скрывайте детали ошибок от клиентов**](/sections/security/hideerrors.russian.md)
+🔗 [**Подробнее: Скрывайте детали ошибок от клиентов**](./sections/security/hideerrors.russian.md)
@@ -987,7 +1002,7 @@ null == undefined // true
**Иначе:** Файлы cookie могут быть отправлены по незащищенным соединениям, и злоумышленник может использовать идентификатор сеанса для определения базовой структуры веб-приложения, а также уязвимостей, специфичных для модуля.
-🔗 [**Подробнее: Изменяйте настройки промежуточного программного обеспечения сеанса по умолчанию**](/sections/security/sessions.russian.md)
+🔗 [**Подробнее: Изменяйте настройки промежуточного программного обеспечения сеанса по умолчанию**](./sections/security/sessions.russian.md)
@@ -1009,7 +1024,7 @@ null == undefined // true
**Иначе:** Если злоумышленник обнаружит, что вы не проверяете внешний вводимый пользователем ввод, он может воспользоваться этой уязвимостью, разместив специально созданные ссылки на форумах, в социальных сетях и других общедоступных местах, чтобы пользователи могли щелкнуть по нему.
-🔗 [**Подробнее: Предотвращайте небезопасные перенаправления**](/sections/security/saferedirects.russian.md)
+🔗 [**Подробнее: Предотвращайте небезопасные перенаправления**](./sections/security/saferedirects.russian.md)
@@ -1017,18 +1032,18 @@ null == undefined // true
-**TL;DR:** Следует принять меры предосторожности, чтобы избежать риска случайной публикации секретов в открытых реестрах npm. Файл `.npmignore` может использоваться для внесения в черный список определенных файлов или папок, или массив` files` в `package.json` может выступать в качестве белого списка.
+**TL;DR:** Следует принять меры предосторожности, чтобы избежать риска случайной публикации секретов в открытых реестрах npm. Файл `.npmignore` может использоваться для внесения в черный список определенных файлов или папок, или массив`files` в `package.json` может выступать в качестве белого списка.
**Иначе:** Ключи API вашего проекта, пароли или другие секреты открыты для злоупотребления любым, кто сталкивается с ними, что может привести к финансовым потерям, подлогу и другим рискам.
-🔗 [**Подробнее: Избегайте публикации секретов в реестре npm**](/sections/security/avoid_publishing_secrets.russian.md)
+🔗 [**Подробнее: Избегайте публикации секретов в реестре npm**](./sections/security/avoid_publishing_secrets.russian.md)
# `7. Черновик: Практики эффективности`
-## Наши соавторы работают над этим разделом. [Хотите присоединиться?](Https://github.com/i0natan/nodebestpractices/issues/256)
+## Наши соавторы работают над этим разделом. [Хотите присоединиться?](Https://github.com/goldbergyoni/nodebestpractices/issues/256)
@@ -1038,11 +1053,10 @@ null == undefined // true
**Иначе:** Поскольку цикл обработки событий заблокирован, Node.js не сможет обработать другой запрос, что приведет к задержкам для одновременных пользователей. **3000 пользователей ждут ответа, контент готов к отправке, но один-единственный запрос не позволяет серверу отправить результаты обратно**
-🔗 [**Read More: Не блокируйте цикл событий**](/sections/performance/block-loop.russian.md)
+🔗 [**Read More: Не блокируйте цикл событий**](./sections/performance/block-loop.russian.md)
-
## ![✔] 7.2. Предпочитайте нативные методы JS, а не пользовательские утилиты типа Lodash
**TL;DR:** Часто более утомительно использовать служебные библиотеки, такие как `lodash` и `underscore`, по сравнению с нативными методами, так как это приводит к ненужным зависимостям и снижению производительности.
@@ -1050,14 +1064,13 @@ null == undefined // true
**Иначе:** Вам придется поддерживать менее эффективные проекты, где вы могли бы просто использовать то, что **уже** доступно или иметь дело с еще несколькими строками в обмен на еще несколько файлов.
-🔗 [**Подробнее: Предпочитайте нативные методы JS над пользовательскими утилитами, такими как Lodash**](/sections/performance/nativeoverutil.russian.md)
+🔗 [**Подробнее: Предпочитайте нативные методы JS над пользовательскими утилитами, такими как Lodash**](./sections/performance/nativeoverutil.russian.md)
-
# Вехи
-Чтобы поддерживать это руководство и обновлять его, мы постоянно обновляем и совершенствуем рекомендации и лучшие практики с помощью сообщества. Вы можете следить за нашими [вехами](https://github.com/i0natan/nodebestpractices/milestones) и присоединиться к рабочим группам, если хотите внести свой вклад в этот проект.
+Чтобы поддерживать это руководство и обновлять его, мы постоянно обновляем и совершенствуем рекомендации и лучшие практики с помощью сообщества. Вы можете следить за нашими [вехами](https://github.com/goldbergyoni/nodebestpractices/milestones) и присоединиться к рабочим группам, если хотите внести свой вклад в этот проект.
@@ -1067,35 +1080,36 @@ null == undefined // true
### Завершенные переводы
--  [Brazilian Portuguese](./README.brazilian-portuguese.md) - Любезно предоставлено [Marcelo Melo](https://github.com/marcelosdm)
--  [Chinese](./README.chinese.md) - Любезно предоставлено [Matt Jin](https://github.com/mattjin)
--  [Russian](./README.russian.md) - Любезно предоставлено [Alex Ivanov](https://github.com/contributorpw)
+-  [Brazilian Portuguese](./README.brazilian-portuguese.md) - Любезно предоставлено [Marcelo Melo](https://github.com/marcelosdm)
+-  [Chinese](./README.chinese.md) - Любезно предоставлено [Matt Jin](https://github.com/mattjin)
+-  [Russian](./README.russian.md) - Любезно предоставлено [Alex Ivanov](https://github.com/contributorpw)
+-  [Basque](README.basque.md) - Любезно предоставлено [Ane Diaz de Tuesta](https://github.com/anediaz) & Joxefe Diaz de Tuesta
### Переводы в процессе
--  [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/129))
--  Hebrew ([Discussion](https://github.com/i0natan/nodebestpractices/issues/156))
--  [Korean](README.korean.md) - Любезно предоставлено [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/94))
--  [Spanish](https://github.com/i0natan/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/i0natan/nodebestpractices/issues/95))
--  Turkish ([Discussion](https://github.com/i0natan/nodebestpractices/issues/139))
+-  [French](https://github.com/gaspaonrocks/nodebestpractices/blob/french-translation/README.french.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/129))
+-  Hebrew ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/156))
+-  [Korean](README.korean.md) - Любезно предоставлено [Sangbeom Han](https://github.com/uronly14me) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/94))
+-  [Spanish](https://github.com/goldbergyoni/nodebestpractices/blob/spanish-translation/README.spanish.md) ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/95))
+-  Turkish ([Discussion](https://github.com/goldbergyoni/nodebestpractices/issues/139))
## Руководящий комитет
-Познакомьтесь с членами руководящего комитета -- людьми, которые работают вместе, чтобы обеспечить управление и дальнейшее руководство проектом. Кроме того, каждый член комитета руководит проектом, отслеживаемым в рамках наших [проектов Github](https://github.com/i0natan/nodebestpractices/projects).
+Познакомьтесь с членами руководящего комитета -- людьми, которые работают вместе, чтобы обеспечить управление и дальнейшее руководство проектом. Кроме того, каждый член комитета руководит проектом, отслеживаемым в рамках наших [проектов Github](https://github.com/goldbergyoni/nodebestpractices/projects).
-
+
-[Yoni Goldberg](https://github.com/i0natan)
+[Yoni Goldberg](https://github.com/goldbergyoni)
-Независимый консультант Node.js, который работает с клиентами в США, Европе и Израиле над созданием масштабируемых масштабируемых приложений Node. Многие из приведенных выше лучших практик были впервые опубликованы на [goldbergyoni.com](https://goldbergyoni.com). Свяжитесь с Yoni как @goldbergyoni или me@goldbergyoni.com
+Независимый консультант Node.js, который работает с клиентами в США, Европе и Израиле над созданием масштабируемых приложений Node. Многие из приведенных выше лучших практик были впервые опубликованы на [goldbergyoni.com](https://goldbergyoni.com). Свяжитесь с Yoni как @goldbergyoni или me@goldbergyoni.com
-
+
[Bruno Scheufler](https://github.com/BrunoScheufler)
@@ -1104,7 +1118,7 @@ null == undefined // true
-
+
[Kyle Martin](https://github.com/js-kyle)
@@ -1114,7 +1128,7 @@ null == undefined // true
-
+
[Sagir Khan](https://github.com/sagirk)
@@ -1129,22 +1143,22 @@ null == undefined // true
Спасибо всем нашим соавторам! 🙏
-Наши соавторы являются участниками, которые регулярно вносят свой вклад в хранилище, предлагая новые лучшие практики, разбирая проблемы, просматривая запросы на изменение и многое другое. Если вы заинтересованы в том, чтобы помочь нам научить тысячи людей создавать более качественные приложения Node.js, ознакомьтесь с нашими [руководством для соавторов](/.operations/CONTRIBUTING.md) 🎉
+Наши соавторы являются участниками, которые регулярно вносят свой вклад в хранилище, предлагая новые лучшие практики, разбирая проблемы, просматривая запросы на изменение и многое другое. Если вы заинтересованы в том, чтобы помочь нам научить тысячи людей создавать более качественные приложения Node.js, ознакомьтесь с нашими [руководством для соавторов](./.operations/CONTRIBUTING.md) 🎉
-| | |
-| :--: | :--: |
-| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
+| | |
+| :---------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
+| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
### Прошлые соавторы
-| |
-| :--: |
-| [Refael Ackermann](https://github.com/refack) |
+| |
+| :-------------------------------------------------------------------------------------------------------------------------: |
+| [Refael Ackermann](https://github.com/refack) |
## Благодарности
-Мы ценим любой вклад, от одного исправленного слова до новой лучшей практики. Список участников и [документация по поддержке тут!](CONTRIBUTORS.md)
+Мы ценим любой вклад, от одного исправленного слова до новой лучшей практики. Список участников и [документация по поддержке тут!](./README.md#contributors-)
diff --git a/assets/flags/BR.jpg b/assets/flags/BR.jpg
index 1f295edff..387b7e983 100644
Binary files a/assets/flags/BR.jpg and b/assets/flags/BR.jpg differ
diff --git a/assets/flags/EN.png b/assets/flags/EN.png
new file mode 100644
index 000000000..0291e2982
Binary files /dev/null and b/assets/flags/EN.png differ
diff --git a/assets/flags/EU.png b/assets/flags/EU.png
new file mode 100644
index 000000000..ef4e2c64a
Binary files /dev/null and b/assets/flags/EU.png differ
diff --git a/assets/flags/JA.png b/assets/flags/JA.png
new file mode 100644
index 000000000..964d5b059
Binary files /dev/null and b/assets/flags/JA.png differ
diff --git a/assets/flags/PL.png b/assets/flags/PL.png
new file mode 100644
index 000000000..6857c8c60
Binary files /dev/null and b/assets/flags/PL.png differ
diff --git a/assets/images/6-parts-in-test.jpg b/assets/images/6-parts-in-test.jpg
index 46ce51992..4a7065c53 100644
Binary files a/assets/images/6-parts-in-test.jpg and b/assets/images/6-parts-in-test.jpg differ
diff --git a/assets/images/Kubernetes-graceful-shutdown-flowchart.png b/assets/images/Kubernetes-graceful-shutdown-flowchart.png
new file mode 100644
index 000000000..5772b387f
Binary files /dev/null and b/assets/images/Kubernetes-graceful-shutdown-flowchart.png differ
diff --git a/assets/images/Privatenpm.png b/assets/images/Privatenpm.png
index ce3fe3e68..d14466f78 100644
Binary files a/assets/images/Privatenpm.png and b/assets/images/Privatenpm.png differ
diff --git a/assets/images/Sketch (8).png b/assets/images/Sketch (8).png
index 47c1662b8..4b8860bb6 100644
Binary files a/assets/images/Sketch (8).png and b/assets/images/Sketch (8).png differ
diff --git a/assets/images/The backend testing checklist.png b/assets/images/The backend testing checklist.png
new file mode 100644
index 000000000..0b867d9cf
Binary files /dev/null and b/assets/images/The backend testing checklist.png differ
diff --git a/assets/images/anchore-report.png b/assets/images/anchore-report.png
new file mode 100644
index 000000000..5dccb932d
Binary files /dev/null and b/assets/images/anchore-report.png differ
diff --git a/assets/images/apm1.png b/assets/images/apm1.png
index 30dfea2db..1ec43cae4 100644
Binary files a/assets/images/apm1.png and b/assets/images/apm1.png differ
diff --git a/assets/images/apm3.png b/assets/images/apm3.png
index a6894ea31..835ebc0db 100644
Binary files a/assets/images/apm3.png and b/assets/images/apm3.png differ
diff --git a/assets/images/app-dynamics-dashboard.png b/assets/images/app-dynamics-dashboard.png
index e9f600c27..622a24e62 100644
Binary files a/assets/images/app-dynamics-dashboard.png and b/assets/images/app-dynamics-dashboard.png differ
diff --git a/assets/images/banner-1.png b/assets/images/banner-1.png
index e288c0720..8c531375f 100644
Binary files a/assets/images/banner-1.png and b/assets/images/banner-1.png differ
diff --git a/assets/images/banner-2.jpg b/assets/images/banner-2.jpg
index 41df36ded..5d18c73b3 100644
Binary files a/assets/images/banner-2.jpg and b/assets/images/banner-2.jpg differ
diff --git a/assets/images/banner-3.jpg b/assets/images/banner-3.jpg
index 18c69f9be..ded0ded3c 100644
Binary files a/assets/images/banner-3.jpg and b/assets/images/banner-3.jpg differ
diff --git a/assets/images/banner-4.jpg b/assets/images/banner-4.jpg
index 86b93d8a2..2379a7e08 100644
Binary files a/assets/images/banner-4.jpg and b/assets/images/banner-4.jpg differ
diff --git a/assets/images/circleci.png b/assets/images/circleci.png
index 949414556..3667d5b5b 100644
Binary files a/assets/images/circleci.png and b/assets/images/circleci.png differ
diff --git a/assets/images/concat-benchmark.png b/assets/images/concat-benchmark.png
index 62412363b..425318bcc 100644
Binary files a/assets/images/concat-benchmark.png and b/assets/images/concat-benchmark.png differ
diff --git a/assets/images/createmaintenanceendpoint1.png b/assets/images/createmaintenanceendpoint1.png
index a155bf246..b79509a25 100644
Binary files a/assets/images/createmaintenanceendpoint1.png and b/assets/images/createmaintenanceendpoint1.png differ
diff --git a/assets/images/docker_layers_schema.png b/assets/images/docker_layers_schema.png
new file mode 100644
index 000000000..16084e21a
Binary files /dev/null and b/assets/images/docker_layers_schema.png differ
diff --git a/assets/images/error-handling-flow.png b/assets/images/error-handling-flow.png
new file mode 100644
index 000000000..33ee988e7
Binary files /dev/null and b/assets/images/error-handling-flow.png differ
diff --git a/assets/images/eslint-plugin-security.png b/assets/images/eslint-plugin-security.png
index e43270f53..dd57f2ca7 100644
Binary files a/assets/images/eslint-plugin-security.png and b/assets/images/eslint-plugin-security.png differ
diff --git a/assets/images/event-loop.png b/assets/images/event-loop.png
index f806b6f86..3b0dd75c6 100644
Binary files a/assets/images/event-loop.png and b/assets/images/event-loop.png differ
diff --git a/assets/images/jenkins_dashboard.png b/assets/images/jenkins_dashboard.png
index 79409f75f..bbf0f9158 100644
Binary files a/assets/images/jenkins_dashboard.png and b/assets/images/jenkins_dashboard.png differ
diff --git a/assets/images/keepexpressinweb.gif b/assets/images/keepexpressinweb.gif
index 2e55d1761..d4d863ba0 100644
Binary files a/assets/images/keepexpressinweb.gif and b/assets/images/keepexpressinweb.gif differ
diff --git a/assets/images/kibana-graph-1024x550.jpg b/assets/images/kibana-graph-1024x550.jpg
index ebfb22366..d93da6505 100644
Binary files a/assets/images/kibana-graph-1024x550.jpg and b/assets/images/kibana-graph-1024x550.jpg differ
diff --git a/assets/images/kibana-raw-1024x637.png b/assets/images/kibana-raw-1024x637.png
index 36ea84802..a127cc8db 100644
Binary files a/assets/images/kibana-raw-1024x637.png and b/assets/images/kibana-raw-1024x637.png differ
diff --git a/assets/images/linkedin.svg b/assets/images/linkedin.svg
new file mode 100644
index 000000000..949c44529
--- /dev/null
+++ b/assets/images/linkedin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/logging-overview.png b/assets/images/logging-overview.png
index 96ffe500b..8897c825e 100644
Binary files a/assets/images/logging-overview.png and b/assets/images/logging-overview.png differ
diff --git a/assets/images/logs-with-transaction-id.jpg b/assets/images/logs-with-transaction-id.jpg
new file mode 100644
index 000000000..83a1e12b3
Binary files /dev/null and b/assets/images/logs-with-transaction-id.jpg differ
diff --git a/assets/images/logs-withtout-transaction-id.jpg b/assets/images/logs-withtout-transaction-id.jpg
new file mode 100644
index 000000000..09bf71ab9
Binary files /dev/null and b/assets/images/logs-withtout-transaction-id.jpg differ
diff --git a/assets/images/members/bruno.png b/assets/images/members/bruno.png
index 045a905e8..cc0519f3e 100644
Binary files a/assets/images/members/bruno.png and b/assets/images/members/bruno.png differ
diff --git a/assets/images/members/create-member-icon.md b/assets/images/members/create-member-icon.md
new file mode 100644
index 000000000..b20cf1198
--- /dev/null
+++ b/assets/images/members/create-member-icon.md
@@ -0,0 +1,44 @@
+## How to create a new color coded icon image
+
+To create a new image for yourself in either the collaborators or committee
+sections follow the directions and template below.
+
+1. Replace `[USERNAME]` in the template with your username.
+2. Replace `[BORDER_COLOR]` according to this:
+ - Committee: `#33cd32`
+ - Collaborators: `#0efeff`
+3. Paste the text into a text file with `.svg` extension.
+4. Open in an image editor of your choice that supports SVG and then export as
+ PNG (Enable transparency if it's optional)
+
+
+
+```svg
+
+```
+
+#### Tested Image Editors
+
+- [Inkscape](https://inkscape.org/)
+- [GIMP](https://www.gimp.org/)
diff --git a/assets/images/members/ido.png b/assets/images/members/ido.png
index 5cb6c4687..627a514ef 100644
Binary files a/assets/images/members/ido.png and b/assets/images/members/ido.png differ
diff --git a/assets/images/members/josh-hemphill.png b/assets/images/members/josh-hemphill.png
new file mode 100644
index 000000000..021048234
Binary files /dev/null and b/assets/images/members/josh-hemphill.png differ
diff --git a/assets/images/members/keith.png b/assets/images/members/keith.png
index fcf4c32bc..839670b08 100644
Binary files a/assets/images/members/keith.png and b/assets/images/members/keith.png differ
diff --git a/assets/images/members/kevyn.png b/assets/images/members/kevyn.png
new file mode 100644
index 000000000..8f49da4e6
Binary files /dev/null and b/assets/images/members/kevyn.png differ
diff --git a/assets/images/members/kyle.png b/assets/images/members/kyle.png
index 805956f23..055894550 100644
Binary files a/assets/images/members/kyle.png and b/assets/images/members/kyle.png differ
diff --git a/assets/images/members/raz-luvaton.jpg b/assets/images/members/raz-luvaton.jpg
new file mode 100644
index 000000000..33a5070b5
Binary files /dev/null and b/assets/images/members/raz-luvaton.jpg differ
diff --git a/assets/images/members/refael.png b/assets/images/members/refael.png
index fe57d04a2..937c1f6b1 100644
Binary files a/assets/images/members/refael.png and b/assets/images/members/refael.png differ
diff --git a/assets/images/members/sagir.png b/assets/images/members/sagir.png
index 7fe4732aa..608cb0995 100644
Binary files a/assets/images/members/sagir.png and b/assets/images/members/sagir.png differ
diff --git a/assets/images/members/yoni.png b/assets/images/members/yoni.png
index 34c4680ad..e1b53d143 100644
Binary files a/assets/images/members/yoni.png and b/assets/images/members/yoni.png differ
diff --git a/assets/images/monitoring1.png b/assets/images/monitoring1.png
index ddf126270..61d0c7331 100644
Binary files a/assets/images/monitoring1.png and b/assets/images/monitoring1.png differ
diff --git a/assets/images/monitoring2.jpg b/assets/images/monitoring2.jpg
index ed53a8a06..85e96c7e5 100644
Binary files a/assets/images/monitoring2.jpg and b/assets/images/monitoring2.jpg differ
diff --git a/assets/images/monitoring3.png b/assets/images/monitoring3.png
index 27253a0ae..7f86541aa 100644
Binary files a/assets/images/monitoring3.png and b/assets/images/monitoring3.png differ
diff --git a/assets/images/npm-audit.png b/assets/images/npm-audit.png
index 37a5ec072..75f729d2f 100644
Binary files a/assets/images/npm-audit.png and b/assets/images/npm-audit.png differ
diff --git a/assets/images/sampleMeanDiag.png b/assets/images/sampleMeanDiag.png
index ecf4a9fa4..2d10444c3 100644
Binary files a/assets/images/sampleMeanDiag.png and b/assets/images/sampleMeanDiag.png differ
diff --git a/assets/images/setnodeenv1.png b/assets/images/setnodeenv1.png
index 185800627..53701125d 100644
Binary files a/assets/images/setnodeenv1.png and b/assets/images/setnodeenv1.png differ
diff --git a/assets/images/smartlogging1.png b/assets/images/smartlogging1.png
index 36ea84802..c49a7db73 100644
Binary files a/assets/images/smartlogging1.png and b/assets/images/smartlogging1.png differ
diff --git a/assets/images/smartlogging2.jpg b/assets/images/smartlogging2.jpg
index ebfb22366..d93da6505 100644
Binary files a/assets/images/smartlogging2.jpg and b/assets/images/smartlogging2.jpg differ
diff --git a/assets/images/swaggerDoc.png b/assets/images/swaggerDoc.png
index 17eae6b44..9d05a9ce0 100644
Binary files a/assets/images/swaggerDoc.png and b/assets/images/swaggerDoc.png differ
diff --git a/assets/images/swaggerMarkup.png b/assets/images/swaggerMarkup.png
index ddc935017..26944fdba 100644
Binary files a/assets/images/swaggerMarkup.png and b/assets/images/swaggerMarkup.png differ
diff --git a/assets/images/test-report-like-requirements.jpeg b/assets/images/test-report-like-requirements.jpeg
index 58eb26d3d..d8691bf92 100644
Binary files a/assets/images/test-report-like-requirements.jpeg and b/assets/images/test-report-like-requirements.jpeg differ
diff --git a/assets/images/testingpyramid.png b/assets/images/testingpyramid.png
index 9243b7d4d..259da5682 100644
Binary files a/assets/images/testingpyramid.png and b/assets/images/testingpyramid.png differ
diff --git a/assets/images/twitter.svg b/assets/images/twitter.svg
new file mode 100644
index 000000000..8cac4f029
--- /dev/null
+++ b/assets/images/twitter.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/uptimerobot.jpg b/assets/images/uptimerobot.jpg
index bfde3fa68..ee45d3d4d 100644
Binary files a/assets/images/uptimerobot.jpg and b/assets/images/uptimerobot.jpg differ
diff --git a/assets/images/web.svg b/assets/images/web.svg
new file mode 100644
index 000000000..7c3b5254f
--- /dev/null
+++ b/assets/images/web.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/www.png b/assets/images/www.png
index 2934df0d7..ef0b291c3 100644
Binary files a/assets/images/www.png and b/assets/images/www.png differ
diff --git a/assets/images/ydnlu.png b/assets/images/ydnlu.png
index 871a391be..0882c32ba 100644
Binary files a/assets/images/ydnlu.png and b/assets/images/ydnlu.png differ
diff --git a/package.json b/package.json
new file mode 100644
index 000000000..66bf9d9a0
--- /dev/null
+++ b/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "nodebestpractices",
+ "version": "1.0.0",
+ "description": "[✔]: assets/images/checkbox-small-blue.png",
+ "main": "gen-html.js",
+ "scripts": {
+ "lint": "markdownlint ./README*.md"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/goldbergyoni/nodebestpractices.git"
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/goldbergyoni/nodebestpractices/issues"
+ },
+ "homepage": "https://github.com/goldbergyoni/nodebestpractices#readme",
+ "dependencies": {
+ "markdownlint-cli": "^0.18.0"
+ }
+}
diff --git a/sections/codestylepractices/eslint_prettier.basque.md b/sections/codestylepractices/eslint_prettier.basque.md
new file mode 100644
index 000000000..94b810259
--- /dev/null
+++ b/sections/codestylepractices/eslint_prettier.basque.md
@@ -0,0 +1,32 @@
+# Erabili ESLint eta Prettier
+
+### ESLint eta Prettier alderatzen
+
+Kode hau formateatzen baduzu ESLint erabiliz, abisu bat besterik ez dizu emango luzeegia dela esanez (zure `max-len` ezarpenaren arabera). Prettierrek zure order automatikoki formateatuko du
+
+
+```javascript
+foo(
+ argudioBenetanLuzea(),
+ aiAmaParametroPiloPiloa(),
+ hauGarbituBeharkoNuke(),
+ benetanOraindikBesteBat(),
+ txantxetanZabiltzaEzta()
+);
+```
+
+```javascript
+foo(
+ argudioBenetanLuzea(),
+ aiAmaParametroPiloPiloa(),
+ hauGarbituBeharkoNuke(),
+ benetanOraindikBesteBat(),
+ txantxetanZabiltzaEzta()
+);
+```
+
+Iturria: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
+
+### ESLint eta Prettier integratzen
+
+ESLint eta Prettier kodea formateatzeko funtzionalitateetan gainjar daitezke, baina erraz konbina daitezke [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier), eta [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) bezalako liburutegiekin. Haien arteko ezberdintasunei buruzko informazio gehiago nahi izanez gero, [hemen](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint) begira dezakezu esteka.
diff --git a/sections/codestylepractices/eslint_prettier.french.md b/sections/codestylepractices/eslint_prettier.french.md
new file mode 100644
index 000000000..f629cc879
--- /dev/null
+++ b/sections/codestylepractices/eslint_prettier.french.md
@@ -0,0 +1,26 @@
+# Utilisez ESLint et Prettier
+
+
+### Comparaison d'ESLint et de Prettier
+
+Si vous formatez ce code à l'aide d'ESLint, il vous avertira simplement qu'il est trop large (dépend de votre paramètre `max-len`). Prettier le formatera automatiquement pour vous.
+
+```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)
+
+### Intégration d'ESLint et de Prettier
+
+ESLint et Prettier se recoupent dans la fonction de formatage du code mais ils peuvent être facilement combinés en utilisant d'autres packages comme [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) et [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier). Pour plus d'informations sur leurs différences, vous pouvez consulter le lien [ici](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint).
diff --git a/sections/codestylepractices/eslint_prettier.japanese.md b/sections/codestylepractices/eslint_prettier.japanese.md
new file mode 100644
index 000000000..6c916bc61
--- /dev/null
+++ b/sections/codestylepractices/eslint_prettier.japanese.md
@@ -0,0 +1,26 @@
+# ESLint と Prettier を使う
+
+
+### ESLint と Prettier の比較
+
+以下のコードを ESLint でフォーマットすると、幅が広すぎるという警告が表示されます( `max-len` の設定によります) 。Prettier はそれを自動的にフォーマットしてくれます。
+
+```javascript
+foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne(), noWayYouGottaBeKiddingMe());
+```
+
+```javascript
+foo(
+ reallyLongArg(),
+ omgSoManyParameters(),
+ IShouldRefactorThis(),
+ isThereSeriouslyAnotherOne(),
+ noWayYouGottaBeKiddingMe()
+);
+```
+
+ソース: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
+
+### ESLint と Prettier の統合
+
+ESLint と Prettier はコードフォーマット機能で重複していますが、[prettier-eslint](https://github.com/prettier/prettier-eslint) や [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)、[eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) のような他のパッケージを使うことで簡単に組み合わせることができます。それぞれの違いについての詳細は、リンク先の[こちら](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint)をご覧ください。
diff --git a/sections/codestylepractices/eslint_prettier.korean.md b/sections/codestylepractices/eslint_prettier.korean.md
new file mode 100644
index 000000000..698de15c6
--- /dev/null
+++ b/sections/codestylepractices/eslint_prettier.korean.md
@@ -0,0 +1,25 @@
+# ESLint와 Prettier 사용하기
+
+### ESLint와 Prettier 비교하기
+
+만약 당신이 ESLint를 사용해서 이 코드를 포맷한다면, 당신에게 너무 넓다는 경고만 줄 것이다 (당신의 `mas-len` 설정에 의존해). Prettier는 자동적으로 당신을 위해 그것을 포맷할 것이다.
+
+```javascript
+foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne(), noWayYouGottaBeKiddingMe());
+```
+
+```javascript
+foo(
+ reallyLongArg(),
+ omgSoManyParameters(),
+ IShouldRefactorThis(),
+ isThereSeriouslyAnotherOne(),
+ noWayYouGottaBeKiddingMe()
+);
+```
+
+출처: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
+
+### ESLint와 Prettier 통합시키기
+
+ESLint와 Prettier는 코드 포맷팅 기능에서 겹치지만 [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier), 그리고 [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.polish.md b/sections/codestylepractices/eslint_prettier.polish.md
new file mode 100644
index 000000000..6065fc242
--- /dev/null
+++ b/sections/codestylepractices/eslint_prettier.polish.md
@@ -0,0 +1,26 @@
+# Używanie ESLint oraz Prettier
+
+
+### Porównanie ESLint i Prettier
+
+Jeśli sformatujesz ten kod za pomocą ESLint, wyświetli ostrzeżenie, że jest on zbyt szeroki (zależy od twojego ustawienia „max-len”). Prettier automatycznie go sformatuje.
+
+```javascript
+foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne(), noWayYouGottaBeKiddingMe());
+```
+
+```javascript
+foo(
+ reallyLongArg(),
+ omgSoManyParameters(),
+ IShouldRefactorThis(),
+ isThereSeriouslyAnotherOne(),
+ noWayYouGottaBeKiddingMe()
+);
+```
+
+Źródło: [https://github.com/prettier/prettier-eslint/issues/101](https://github.com/prettier/prettier-eslint/issues/101)
+
+### Integracja ESLint i Prettier
+
+ESLint i Prettier nakładają się na siebie w funkcji formatowania kodu, ale można je łatwo łączyć za pomocą innych pakietów, takich jak [prettier-eslint](https://github.com/prettier/prettier-eslint), [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier), i [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier). Aby uzyskać więcej informacji o ich różnicach, możesz zobaczyć link [tutaj](https://stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint).
diff --git a/sections/docker/avoid-build-time-secrets.basque.md b/sections/docker/avoid-build-time-secrets.basque.md
new file mode 100644
index 000000000..6b9e2fb35
--- /dev/null
+++ b/sections/docker/avoid-build-time-secrets.basque.md
@@ -0,0 +1,98 @@
+# Garbitu eraikitze faseko sekretuak, saihestu sekretuak argudioetan
+
+
+
+### Azalpena
+
+Docker irudi bat ez da soilik fitxategi pilo bat, eraikitze garaian gertatutakoa kontatzen duten geruza anitz baizik. Oso ohikoa izaten da garatzaileek npm giltza (tokena) behar izatea eraikitze garaian (gehienetan erregistro pribatuetarako), eta horretarako sasibide bat erabiltzen dute giltza eraikitze garaiko argudio bezala pasatuz. Sinplea eta segurua eman dezake, baina giltza hori garatzailearen ordenagailuko Docker historiatik, Docker erregistrotik eta IEtik eskura daiteke. Giltza eskuratzea lortzen duen erasotzailea gai izango da erakunde horren npm erregistro pribatuan idazteko. Bi aukera daude, hori baino seguruagoak direnak: bikainena, Docker --secret funtzioalitatea erabiltzea (2020ko uztailetik aurrera esperimentala), fitxategi bat antolatzea ahalbidetzen duena eraikitze garaian. Bigarrenak, lehenengo, etapa anitzeko konpilazioa argudioekin erabiltzen du; gero, konpilazioa egiten du; eta, azkenik, bakarrik beharrezkoak diren fitxategiak kopiatzen ditu ekoizpenean. Azken teknika horrek ez du sekreturik igortzen irudiekin, baina sekretuak Dockeren historian agertuko dira. Normalean, erakunde gehienenek nahikoa segurutzat jotzen dute.
+
+
+
+### Kode adibidea: erabili Docker sekretu instalatuentzat (esperimentala, baina egonkorra)
+
+
+
+Dockerfile
+
+```dockerfile
+# syntax = docker/dockerfile:1.0-experimental
+
+FROM node:12-slim
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN --mount=type=secret,id=npm,target=/root/.npmrc npm ci
+
+# Gainerakoa hemen dator
+```
+
+
+
+
+
+### Kode adibidea: modu seguruan eraiki etapa anitzeko konpilazioa erabiliz
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+ARG NPM_TOKEN
+
+WORKDIR /usr/src/app
+COPY . /dist
+RUN echo "//registry.npmjs.org/:\_authToken=\$NPM_TOKEN" > .npmrc && \
+ npm ci --production && \
+ rm -f .npmrc
+
+
+FROM build as prod
+
+COPY --from=build /dist /dist
+
+CMD ["node", "index.js"]
+
+# ARG eta .npmrc ez dira agertuko azken irudian baina Docker daemonen etiketatu gabeko irudien zerrendan ager daitezke, ziurtatu hauek ezabatu dituzula
+```
+
+
+
+
+
+### Anti ereduaren kode adibidea: erabili eraikitze garaiko argudioak
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+ARG NPM_TOKEN
+
+WORKDIR /usr/src/app
+COPY . /dist
+RUN echo "//registry.npmjs.org/:\_authToken=\$NPM_TOKEN" > .npmrc && \
+ npm ci --production && \
+ rm -f .npmrc
+
+# .npmrc copy komando berean ezabatzeari esker ez du geruzan gordeko, hala ere, irudi historian aurki ahalko dugu
+
+CMD ["node", "index.js"]
+```
+
+
+
+
+
+### Blogeko aipua: "Sekretu hauek ez dira azken Dockerean gordetzen"
+
+[Alexandra Ulsh](https://www.alexandraulsh.com/2019/02/24/docker-build-secrets-and-npmrc/?fbclid=IwAR0EAr1nr4_QiGzlNQcQKkd9rem19an9atJRO_8-n7oOZXwprToFQ53Y0KQ)en bloga
+
+> 2018ko azaroan, Docker 18.09k sekretu bandera berria gehitu zuen docker eraikuntzarentzat. Horrek aukera ematen digu gure fitxategi baten sekretuak Docker eraikuntzara pasatzeko. Sekretu horiek ez dira ez Dokeren azken irudian gordetzen, ez tarteko irudietan, ez irudiaren balioztatze historian. Eraikitze sekretuei esker, npm pakete pribatudun Docker irudiak eraiki ditzakezu, eraikitze argudiorik gabe eta etapa anitzekin.
+
+```
+
+```
diff --git a/sections/docker/avoid-build-time-secrets.chinese.md b/sections/docker/avoid-build-time-secrets.chinese.md
new file mode 100644
index 000000000..8b578a7b2
--- /dev/null
+++ b/sections/docker/avoid-build-time-secrets.chinese.md
@@ -0,0 +1,97 @@
+# 清理编译过程中的秘钥,避免使用秘钥作为参数
+
+
+
+### One Paragraph Explainer
+
+
+A Docker image isn't just a bunch of files but rather multiple layers revealing what happened during build-time. In a very common scenario, developers need the npm token during build time (mostly for private registries) - this is falsely achieved by passing the token as a build time args. It might seem innocent and safe, however this token can now be fetched from the developer's machine Docker history, from the Docker registry and the CI. An attacker who gets access to that token is now capable of writing into the organization private npm registry. There are two more secured alternatives: The flawless one is using Docker --secret feature (experimental as of July 2020) which allows mounting a file during build time only. The second approach is using multi-stage build with args, building and then copying only the necessary files to production. The last technique will not ship the secrets with the images but will appear in the local Docker history - This is typically considered as secured enough for most organizations.
+
+
+
+### Code Example – Using Docker mounted secrets (experimental but stable)
+
+
+
+Dockerfile
+
+```dockerfile
+# syntax = docker/dockerfile:1.0-experimental
+
+FROM node:12-slim
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN --mount=type=secret,id=npm,target=/root/.npmrc npm ci
+
+# The rest comes here
+```
+
+
+
+
+
+### Code Example – Building securely using multi-stage build
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+ARG NPM_TOKEN
+
+WORKDIR /usr/src/app
+COPY . /dist
+
+RUN echo "//registry.npmjs.org/:\_authToken=\$NPM_TOKEN" > .npmrc && \
+ npm ci --production && \
+ rm -f .npmrc
+
+
+FROM build as prod
+
+COPY --from=build /dist /dist
+CMD ["node", "index.js"]
+
+# The ARG and .npmrc won't appear in the final image but can be found in the Docker daemon un-tagged images list - make sure to delete those
+```
+
+
+
+
+
+### Code Example Anti Pattern – Using build time args
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+ARG NPM_TOKEN
+
+WORKDIR /usr/src/app
+COPY . /dist
+
+RUN echo "//registry.npmjs.org/:\_authToken=\$NPM_TOKEN" > .npmrc && \
+ npm ci --production && \
+ rm -f .npmrc
+
+# Deleting the .npmrc within the same copy command will not save it inside the layer, however it can be found in image history
+
+CMD ["node", "index.js"]
+```
+
+
+
+
+
+### Blog Quote: "These secrets aren’t saved in the final Docker"
+
+From the blog, [Alexandra Ulsh](https://www.alexandraulsh.com/2019/02/24/docker-build-secrets-and-npmrc/?fbclid=IwAR0EAr1nr4_QiGzlNQcQKkd9rem19an9atJRO_8-n7oOZXwprToFQ53Y0KQ)
+
+> In November 2018 Docker 18.09 introduced a new --secret flag for docker build. This allows us to pass secrets from a file to our Docker builds. These secrets aren’t saved in the final Docker image, any intermediate images, or the image commit history. With build secrets, you can now securely build Docker images with private npm packages without build arguments and multi-stage builds.
+
+```
+
+```
\ No newline at end of file
diff --git a/sections/docker/avoid-build-time-secrets.japanese.md b/sections/docker/avoid-build-time-secrets.japanese.md
new file mode 100644
index 000000000..339e6b36e
--- /dev/null
+++ b/sections/docker/avoid-build-time-secrets.japanese.md
@@ -0,0 +1,95 @@
+# ビルド時のシークレットをクリーンアウトし、引数にシークレットを含めることを避ける
+
+
+
+### ブログ引用: "These secrets aren’t saved in the final Docker"(これらのシークレットは最終的な Docker イメージに保存されません)
+
+ブログ [Alexandra Ulsh](https://www.alexandraulsh.com/2019/02/24/docker-build-secrets-and-npmrc/?fbclid=IwAR0EAr1nr4_QiGzlNQcQKkd9rem19an9atJRO_8-n7oOZXwprToFQ53Y0KQ) より:
+
+> In November 2018 Docker 18.09 introduced a new --secret flag for docker build. This allows us to pass secrets from a file to our Docker builds. These secrets aren’t saved in the final Docker image, any intermediate images, or the image commit history. With build secrets, you can now securely build Docker images with private npm packages without build arguments and multi-stage builds.
diff --git a/sections/docker/avoid-build-time-secrets.md b/sections/docker/avoid-build-time-secrets.md
new file mode 100644
index 000000000..e729f7919
--- /dev/null
+++ b/sections/docker/avoid-build-time-secrets.md
@@ -0,0 +1,100 @@
+# Clean build-time secrets, avoid secrets as args
+
+
+
+### One Paragraph Explainer
+
+
+A Docker image isn't just a bunch of files but rather multiple layers revealing what happened during build-time. In a very common scenario, developers need the npm token during build time (mostly for private registries) - this is falsely achieved by passing the token as a build time args. It might seem innocent and safe, however this token can now be fetched from the developer's machine Docker history, from the Docker registry and the CI. An attacker who gets access to that token is now capable of writing into the organization private npm registry. There are two more secured alternatives: The flawless one is using Docker --secret feature (experimental as of July 2020) which allows mounting a file during build time only. The second approach is using multi-stage build with args, building and then copying only the necessary files to production. The last technique will not ship the secrets with the images but will appear in the local Docker history - This is typically considered as secured enough for most organizations.
+
+
+
+### Code Example – Using Docker mounted secrets (experimental but stable)
+
+
+
+Dockerfile
+
+```dockerfile
+# syntax = docker/dockerfile:1.0-experimental
+
+FROM node:12-slim
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN --mount=type=secret,id=npm,target=/root/.npmrc npm ci
+
+# The rest comes here
+```
+
+
+
+
+
+### Code Example – Building securely using multi-stage build
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+ARG NPM_TOKEN
+
+WORKDIR /usr/src/app
+COPY . /dist
+
+RUN echo "//registry.npmjs.org/:\_authToken=\$NPM_TOKEN" > .npmrc && \
+ npm ci --production && \
+ rm -f .npmrc
+
+
+FROM build as prod
+
+COPY --from=build /dist /dist
+CMD ["node", "index.js"]
+
+# The ARG and .npmrc won't appear in the final image but can be found in the Docker daemon un-tagged images list - make sure to delete those
+```
+
+
+
+
+
+### Code Example Anti Pattern – Using build time args
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+ARG NPM_TOKEN
+
+WORKDIR /usr/src/app
+COPY . /dist
+
+RUN echo "//registry.npmjs.org/:\_authToken=\$NPM_TOKEN" > .npmrc && \
+ npm ci --production && \
+ rm -f .npmrc
+
+# Deleting the .npmrc within the same copy command will not save it inside the layer, however it can be found in image history
+
+CMD ["node", "index.js"]
+```
+
+
+
+
+
+### Blog Quote: "These secrets aren’t saved in the final Docker"
+
+From the blog, [Alexandra Ulsh](https://www.alexandraulsh.com/2019/02/24/docker-build-secrets-and-npmrc/?fbclid=IwAR0EAr1nr4_QiGzlNQcQKkd9rem19an9atJRO_8-n7oOZXwprToFQ53Y0KQ)
+
+> In November 2018 Docker 18.09 introduced a new --secret flag for docker build. This allows us to pass secrets from a file to our Docker builds. These secrets aren’t saved in the final Docker image, any intermediate images, or the image commit history. With build secrets, you can now securely build Docker images with private npm packages without build arguments and multi-stage builds.
+
+```
+
+```
diff --git a/sections/docker/bootstrap-using-node.basque.md b/sections/docker/bootstrap-using-node.basque.md
new file mode 100644
index 000000000..0a001735e
--- /dev/null
+++ b/sections/docker/bootstrap-using-node.basque.md
@@ -0,0 +1,81 @@
+# Abiarazi edukiontzia node komandoa erabiliz npm erabili ordez
+
+## Azalpena
+
+Ohikoa da jendeak `CMD 'npm start'` erabiltzea bere aplikazioa abiarazteko kodea egitea. Praktika txarra da hori, ordea. `npm` bitarrak ez du seinalerik birbidaliko zure aplikaziora, aplikazioa behar bezala ixtea eragozten duena (ikus [/sections/docker/graceful-shutdown.basque.md]). Bigarren mailako prozesuak erabiltzen badituzu, ez dira behar bezala garbituko ustekabeko itzaltzeren bat gertatzen bada, prozesu zonbiak utziko dituena. `npm start`ek ere onuragarria ez den prozesu bat gehiago egiten du. Erabili `CMD ['node','server.js']` zure aplikazioa abiarazteko. Zure aplikazioak bigarren mailako prozesuak baditu, erabili gainera `TINI`sarbide gisa.
+
+### Kode adibidea: abiarazi aplikazioa Node erabiliz
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+CMD ["node", "server.js"]
+```
+
+### Kode adibidea: erabili Tiny sarbide gisa
+
+```dockerfile
+FROM node:12-slim AS build
+
+# Gehitu Tini bigarren mailako prozesuak erabiltzen badituzu
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "server.js"]
+```
+
+### Anti ereduak
+
+npm start erabiliz
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# ez egin hau!
+CMD "npm start"
+```
+Node string bakarrean erabiltzeak zure komandoa egikaritzeko bash/ash shell prozesu bat abiaraziko du. Hori ia `npm` erabiltzea modukoa da
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# ez egin hau, bash abiatuko du eta
+CMD "node server.js"
+```
+
+npmrekin abiatuz, hau da prozesuaren zuhaitza:
+
+```console
+$ ps falx
+ UID PID PPID COMMAND
+ 0 1 0 npm
+ 0 16 1 sh -c node server.js
+ 0 17 16 \_ node server.js
+```
+
+Bi prozesu estra hauek edukitzeak ez du inongo abantailarik ekartzen
+
+Iturriak:
+
+https://maximorlov.com/process-signals-inside-docker-containers/
+
+https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals
diff --git a/sections/docker/bootstrap-using-node.chinese.md b/sections/docker/bootstrap-using-node.chinese.md
new file mode 100644
index 000000000..29f3d184a
--- /dev/null
+++ b/sections/docker/bootstrap-using-node.chinese.md
@@ -0,0 +1,82 @@
+# 使用node命令而不是npm启动容器
+
+## 一段解释
+
+我们经常看到开发者使用`CMD 'npm start'`启动app的代码示例。这是一个不好的做法。因为`npm`不会向您的app转发信号(signals),这将阻止应用优雅关闭(graceful shutdown),(见[/sections/docker/graceful-shutdown.md])。如果您使用了子进程(child-processes),在意外关闭时则无法正确清理它们,将僵尸进程留在主机上。同时,`npm start`也导致无意义的增加一个额外进程。使用`CMD ['node','server.js']`启动您的应用吧。假如您的应用使用了子进程(child-processes),也可以使用`TINI`作为入口(entrypoint)。
+
+### 代码示例 - 启动Node
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+CMD ["node", "server.js"]
+```
+
+
+### 代码示例 - 使用Tiny作为入口(ENTRYPOINT)
+
+```dockerfile
+FROM node:12-slim AS build
+
+# 使用子进程(child-processes)的情况下,添加Tini
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "server.js"]
+```
+
+### 反模式
+
+使用npm start
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# 不要这么做!
+CMD "npm start"
+```
+
+在同一字符串命令里面使用node,将启动一个bash/ash脚本进程去执行您的命令。它和使用`npm`的效果类似。
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# 不要这么做,它将启动bash
+CMD "node server.js"
+```
+
+使用npm启动,这里是进程树:
+```console
+$ ps falx
+ UID PID PPID COMMAND
+ 0 1 0 npm
+ 0 16 1 sh -c node server.js
+ 0 17 16 \_ node server.js
+```
+额外的两个进程没有任何好处。
+
+来源:
+
+
+https://maximorlov.com/process-signals-inside-docker-containers/
+
+
+https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals
\ No newline at end of file
diff --git a/sections/docker/bootstrap-using-node.french.md b/sections/docker/bootstrap-using-node.french.md
new file mode 100644
index 000000000..e3f5388c8
--- /dev/null
+++ b/sections/docker/bootstrap-using-node.french.md
@@ -0,0 +1,82 @@
+# Bootstrap container using node command instead of npm
+
+## One paragraph explainer
+
+We are used to see code examples where folks start their app using `CMD 'npm start'`. This is a bad practice. The `npm` binary will not forward signals to your app which prevents graceful shutdown (see [/sections/docker/graceful-shutdown.md]). If you are using child-processes they won’t be cleaned up correctly in case of unexpected shutdown, leaving zombie processes on your host. `npm start` also results in having an extra process for no benefit. To start you app use `CMD ['node','server.js']`. If your app spawns child-processes also use `TINI` as an entrypoint.
+
+### Code example - Bootsraping using Node
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+CMD ["node", "server.js"]
+```
+
+
+### Code example - Using Tiny as entrypoint
+
+```dockerfile
+FROM node:12-slim AS build
+
+# Add Tini if using child-processes
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "server.js"]
+```
+
+### Antipatterns
+
+Using npm start
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# don’t do that!
+CMD "npm start"
+```
+
+Using node in a single string will start a bash/ash shell process to execute your command. That is almost the same as using `npm`
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# don’t do that, it will start bash
+CMD "node server.js"
+```
+
+Starting with npm, here’s the process tree:
+```console
+$ ps falx
+ UID PID PPID COMMAND
+ 0 1 0 npm
+ 0 16 1 sh -c node server.js
+ 0 17 16 \_ node server.js
+```
+There is no advantage to those two extra processes.
+
+Sources:
+
+
+https://maximorlov.com/process-signals-inside-docker-containers/
+
+
+https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals
\ No newline at end of file
diff --git a/sections/docker/bootstrap-using-node.japanese.md b/sections/docker/bootstrap-using-node.japanese.md
new file mode 100644
index 000000000..e24d9d1f8
--- /dev/null
+++ b/sections/docker/bootstrap-using-node.japanese.md
@@ -0,0 +1,82 @@
+# npm の代わりに node コマンドを使用した Bootstrap コンテナ
+
+## 一段落説明
+
+`CMD 'npm start'` を使ってアプリを起動するコード例をよく見かけます。これは悪いプラクティスです。`npm` バイナリはシグナルをアプリに転送しないので、グレースフルシャットダウンができません ( [/sections/docker/graceful-shutdown.japanese.md] を参照してください)。子プロセスを使用している場合、予期せぬシャットダウンの場合には正しくクリーンアップされず、ホスト上にゾンビプロセスが残ってしまいます。また、`npm start` を実行しても、何のメリットもなく余分なプロセスが発生してしまいます。アプリを起動するには、`CMD ['node','server.js’]` を使用します。アプリが子プロセスを生成する場合は、`TINI` をエントリポイントとして使用します。
+
+### コード例 - node を使用した Bootsraping
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+CMD ["node", "server.js"]
+```
+
+
+### コード例 - エントリーポイントとしての Tiny の使用
+
+```dockerfile
+FROM node:12-slim AS build
+
+# 子プロセスを使用している場合は、Tini を追加します。
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "server.js"]
+```
+
+### アンチパターン
+
+Using npm start
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# これはしないでください!
+CMD "npm start"
+```
+
+Using node in a single string will start a bash/ash shell process to execute your command. That is almost the same as using `npm`
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# これはしないでください、bash が起動されます。
+CMD "node server.js"
+```
+
+npm でスタートすると、プロセスツリーは以下のようになります。:
+```console
+$ ps falx
+ UID PID PPID COMMAND
+ 0 1 0 npm
+ 0 16 1 sh -c node server.js
+ 0 17 16 \_ node server.js
+```
+その2つの余分なプロセスには何のメリットもありません。
+
+ソース:
+
+
+https://maximorlov.com/process-signals-inside-docker-containers/
+
+
+https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals
diff --git a/sections/docker/bootstrap-using-node.md b/sections/docker/bootstrap-using-node.md
new file mode 100644
index 000000000..7be2aa900
--- /dev/null
+++ b/sections/docker/bootstrap-using-node.md
@@ -0,0 +1,82 @@
+# Bootstrap container using node command instead of npm
+
+## One paragraph explainer
+
+We are used to see code examples where folks start their app using `CMD 'npm start'`. This is a bad practice. The `npm` binary will not forward signals to your app which prevents graceful shutdown [see](/sections/docker/graceful-shutdown.md). If you are using child-processes they won’t be cleaned up correctly in case of unexpected shutdown, leaving zombie processes on your host. `npm start` also results in having an extra process for no benefit. To start you app use `CMD ['node','server.js']`. If your app spawns child-processes also use `TINI` as an entrypoint.
+
+### Code example - Bootstrapping using Node
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+CMD ["node", "server.js"]
+```
+
+
+### Code example - Using Tiny as entrypoint
+
+```dockerfile
+FROM node:12-slim AS build
+
+# Add Tini if using child-processes
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "server.js"]
+```
+
+### Antipatterns
+
+Using npm start
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# don’t do that!
+CMD "npm start"
+```
+
+Using node in a single string will start a bash/ash shell process to execute your command. That is almost the same as using `npm`
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# don’t do that, it will start bash
+CMD "node server.js"
+```
+
+Starting with npm, here’s the process tree:
+```console
+$ ps falx
+ UID PID PPID COMMAND
+ 0 1 0 npm
+ 0 16 1 sh -c node server.js
+ 0 17 16 \_ node server.js
+```
+There is no advantage to those two extra processes.
+
+Sources:
+
+
+https://maximorlov.com/process-signals-inside-docker-containers/
+
+
+https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals
diff --git a/sections/docker/clean-cache.basque.md b/sections/docker/clean-cache.basque.md
new file mode 100644
index 000000000..7b206e2a9
--- /dev/null
+++ b/sections/docker/clean-cache.basque.md
@@ -0,0 +1,28 @@
+# Garbitu NODE_MODULE cachea
+
+
+
+### Azalpena
+
+npm eta Yarn Node paketeen kudeatzaileek cachean gordetzen dituzte lokalean instalatutako paketeak, liburutegi horien beharra dituzten etorkizuneko proiektuek urruneko biltegi batetik eskuratu beharrik izan ez dezaten. Horrek paketeak bikoiztu eta biltegiratze gehiago kontsumitzen duen arren, normalean pakete berdinak instalatzen jarraitzen duen tokiko garapen ingurunean merezi egiten du hori egitea. Docker edukiontzian biltegiratzea handitzeak ez du ezertarako balio, menpekotasuna behin bakarrik instalatzen baitu. Cachea kenduta, MB asko ezabatzen dira iruditik kode lerro bakarra erabiliz. Hori egiten ari zaren bitartean, ziurtatu zero ez den kode batekin irteten ez dela eta IE eraikitzean huts egiten duela cachearen arazoengatik. Hori ekidin daiteke --force adierazlea erantsiz.
+
+_Mesedez, kontutan hartu hau ez dela garrantzitsua etapa anitzeko konpilazioa erabiltzen duzun kasuan, ez duzu-eta pakete berririk instalatzen azken etapan_
+
+
+
+### Kode adibidea: cachea garbitu
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# Gainontzeko guztia hemen dator
+```
+
+
diff --git a/sections/docker/clean-cache.chinese.md b/sections/docker/clean-cache.chinese.md
new file mode 100644
index 000000000..5e2c09918
--- /dev/null
+++ b/sections/docker/clean-cache.chinese.md
@@ -0,0 +1,27 @@
+# 清除NODE_MODULE缓存
+
+
+
+### 代码示例 - 清除缓存
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# 剩余部分
+```
+
+
\ No newline at end of file
diff --git a/sections/docker/clean-cache.french.md b/sections/docker/clean-cache.french.md
new file mode 100644
index 000000000..1c4bad560
--- /dev/null
+++ b/sections/docker/clean-cache.french.md
@@ -0,0 +1,28 @@
+# Clean NODE_MODULE cache
+
+
+
+### One Paragraph Explainer
+
+Node package managers, npm & Yarn, cache the installed packages locally so that future projects which need the same libraries won't need to fetch from a remote repository. Although this duplicates the packages and consumes more storage - it pays off in a local development environment that typically keeps installing the same packages. In a Docker container this storage increase is worthless since it installs the dependency only once. By removing this cache, using a single line of code, tens of MB are shaved from the image. While doing so, ensure that it doesn't exit with non-zero code and fail the CI build because of caching issues - This can be avoided by including the --force flag.
+
+*Please note that this is not relevant if you are using a multi-stage build as long as you don't install new packages in the last stage*
+
+
+
+### Code Example – Clean cache
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# The rest comes here
+```
+
+
\ No newline at end of file
diff --git a/sections/docker/clean-cache.japanese.md b/sections/docker/clean-cache.japanese.md
new file mode 100644
index 000000000..5a8891dd9
--- /dev/null
+++ b/sections/docker/clean-cache.japanese.md
@@ -0,0 +1,28 @@
+# NODE_MODULE キャッシュをクリーンアップする
+
+
+
+### One Paragraph Explainer
+
+Node package managers, npm & Yarn, cache the installed packages locally so that future projects which need the same libraries won't need to fetch from a remote repository. Although this duplicates the packages and consumes more storage - it pays off in a local development environment that typically keeps installing the same packages. In a Docker container this storage increase is worthless since it installs the dependency only once. By removing this cache, using a single line of code, tens of MB are shaved from the image. While doing so, ensure that it doesn't exit with non-zero code and fail the CI build because of caching issues - This can be avoided by including the --force flag.
+
+*Please note that this is not relevant if you are using a multi-stage build as long as you don't install new packages in the last stage*
+
+
+
+### Code Example – Clean cache
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# The rest comes here
+```
+
+
diff --git a/sections/docker/docker-ignore.basque.md b/sections/docker/docker-ignore.basque.md
new file mode 100644
index 000000000..6e76a860b
--- /dev/null
+++ b/sections/docker/docker-ignore.basque.md
@@ -0,0 +1,50 @@
+# Erabili .dockerignore sekretuak filtratzea ekiditeko
+
+
+
+### Azalpena
+
+Docker konpilazio komandoak tokian tokiko fitxategiak konpilazioaren testuinguruko ingurunean kopiatzen ditu sare birtual baten bidez. Kontuz ibili, garapen eta IE karpetek .npmrc, .aws, .env fitxategiak eta beste fitxategi garrantzitsu batzuk eduki ditzakete eta. Ondorioz, gertatu daiteke Dockereko irudiek sekretuak gordetzea eta lurralde arriskutsuetan agerian uztea (esaterako Docker bilgailua, kideen zerbitzariak). Mundu hobe batean Dockerfile fitxategiak zehaztu beharko luke zer ari den kopiatzen. Horretaz gainera, azken segurtasun sare gisa, gehitu .dockerignore fitxategia, beharrezkoak ez diren karpetak eta balizko sekretuak iragazten dituena. Hori egiteak abiadura azkartzen du gainera, ekoizpenean erabilerarik ez duten garapen karpeta arruntak alde batera utziz (adibidez .git, proben emaitzak, garatze programen konfigurazioak), eraikitzaileak cachea hobeto erabil dezake eta errendimendu hobea eskuratu
+
+
+
+### One Paragraph Explainer
+
+The Docker build command copies the local files into the build context environment over a virtual network. Be careful - development and CI folders contain secrets like .npmrc, .aws, .env files and other sensitive files. Consequently, Docker images might hold secrets and expose them in unsafe territories (e.g. Docker repository, partners servers). In a better world the Dockerfile should be explicit about what is being copied. On top of this include a .dockerignore file that acts as the last safety net that filters out unnecessary folders and potential secrets. Doing so also boosts the build speed - By leaving out common development folders that have no use in production (e.g. .git, test results, IDE configuration), the builder can better utilize the cache and achieve better performance
+
+
+
+### Code Example – A good default .dockerignore for Node.js
+
+
+.dockerignore
+
+```
+**/node_modules/
+**/.git
+**/README.md
+**/LICENSE
+**/.vscode
+**/npm-debug.log
+**/coverage
+**/.env
+**/.editorconfig
+**/.aws
+**/dist
+```
+
+
+
+
+
+### Code Example Anti-Pattern – Recursive copy of all files
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+# The next line copies everything
+COPY . .
+
+# The rest comes here
+
+```
+
+
\ No newline at end of file
diff --git a/sections/docker/docker-ignore.japanese.md b/sections/docker/docker-ignore.japanese.md
new file mode 100644
index 000000000..e83bd3a4a
--- /dev/null
+++ b/sections/docker/docker-ignore.japanese.md
@@ -0,0 +1,50 @@
+# .dockerignore を使用してシークレット情報の漏洩を防ぐ
+
+
+
+### One Paragraph Explainer
+
+The Docker build command copies the local files into the build context environment over a virtual network. Be careful - development and CI folders contain secrets like .npmrc, .aws, .env files and other sensitive files. Consequently, Docker images might hold secrets and expose them in unsafe territories (e.g. Docker repository, partners servers). In a better world the Dockerfile should be explicit about what is being copied. On top of this include a .dockerignore file that acts as the last safety net that filters out unnecessary folders and potential secrets. Doing so also boosts the build speed - By leaving out common development folders that have no use in production (e.g. .git, test results, IDE configuration), the builder can better utilize the cache and achieve better performance
+
+
+
+### Code Example – A good default .dockerignore for Node.js
+
+
+.dockerignore
+
+```
+**/node_modules/
+**/.git
+**/README.md
+**/LICENSE
+**/.vscode
+**/npm-debug.log
+**/coverage
+**/.env
+**/.editorconfig
+**/.aws
+**/dist
+```
+
+
+
+
+
+### Code Example Anti-Pattern – Recursive copy of all files
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+# The next line copies everything
+COPY . .
+
+# The rest comes here
+
+```
+
+
diff --git a/sections/docker/generic-tips.basque.md b/sections/docker/generic-tips.basque.md
new file mode 100644
index 000000000..476a5d067
--- /dev/null
+++ b/sections/docker/generic-tips.basque.md
@@ -0,0 +1,29 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# Common Node.js Dockeren praktika onak
+
+Dockeren praktika arrunten atal honek programazio lengoaia guztietan araupetuta dauden praktika onak biltzen ditu, ez dira Node.jsrentzat bakarrik
+
+## ![✔] Nahiago COPY, ADD komandoa baino
+
+**TL;PL:** COPY seguruagoa da, bakarrik lekuko fitxategiak kopiatzen ditu eta; ADDek, aldiz, bestelako funtzionalitateak onartzen ditu, adibidez, urruneko webguneetatik binarioak deskargatzea
+
+## ![✔] Ekidin oinarrizko sistema eragilea eguneratzea
+
+**TL;PL:** eraikitze prozesuaren lekuko binarioak eguneratzeak (adibidez apt-get update) sendotasunik gabeko irudiak sortzen ditu exekutatzen duen bakoitzean eta pribilegio handiak eskatzen ditu. Horren ordez, erabili sarri eguneratzen diren oinarrizko irudiak
+
+## ![✔] Sailkatu irudiak etiketen bidez
+
+**TL;PL:** irudi bakoitzaren metadatuak emateak Ops-eko profesionalei modu egokian tratatzen lagundu diezaieke. Adibidez, gehitu mantentze arduradunaren izena, eraikitze data eta bestelako informazioa, irudi bat erabili behar duenari lagungarria izango zaiona
+
+## ![✔] Erabili pribilegiorik gabeko edukiontziak
+
+**TL;PL:** pribilegiodun edukiontziek erabiltzaile nagusiak (root) dituen baimen eta gaitasun berdinak ditu makina ostalariaren gainean. Hori ia inoiz ez da beharrezkoa, eta, normalean, Node irudi ofizialetan sortzen den 'node' erabiltzailea erabili behar da
+
+## ![✔] Arakatu eta egiaztatu bukaerako emaitza
+
+**TL;PL:** batzuetan erraza da eraikitze prozesuko albo efektuak ahaztea, hala nola sekretu filtratuak edota beharrezkoak ez diren fitxategiak. [Dive](https://github.com/wagoodman/dive) bezalako tresnak erabiltzeak sortutako irudia arakatzeko horrelako arazoak identifikatzen lagun dezake
+
+## ![✔] Burutu osotasunaren egiaztapena
+
+**TL;PL:** oinarrizko edo bukaerako irudiak argitaratzen ari zaren bitartean, sarea engainatu eta birbideratu egin daiteke irudi maltzurrak deskargatzeko. Dockeren protokolo estandarrak ez du ezer eragozten edukia sinatu eta egiaztatu ezean. [Docker Notary](https://docs.docker.com/notary/getting_started/) da hori lortzea ahalbidetzen duten tresnetako bat da
diff --git a/sections/docker/generic-tips.chinese.md b/sections/docker/generic-tips.chinese.md
new file mode 100644
index 000000000..ad6f322fd
--- /dev/null
+++ b/sections/docker/generic-tips.chinese.md
@@ -0,0 +1,29 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# 通用的Node.js Docker最佳实践
+
+此通用Docker指南部分包含所有编程语言中标准化的最佳实践,并没有针对Node.js的特殊解释
+
+## ![✔] 使用命令COPY优于ADD
+
+**TL;DR:** COPY更安全,因为它只复制本地文件,而ADD支持更高级的获取,比如从远程站点下载二进制文件
+
+## ![✔] 避免更新基础OS
+
+**TL;DR:** 在构建期间更新本地二进制文件(例如apt get update)会在每次运行时创建不一致的映像,并且还需要提升权限。取而代之,使用经常更新的基础镜像
+
+## ![✔] 使用标签对镜像分类
+
+**TL;DR:** 为每个镜像提供元数据(metadata)可能有助于Ops专业人员充分处理它。例如,包括维护人员姓名、构建日期和其他信息,当有人需要对映像进行推理时,这些信息可能会被证明是有用的
+
+## ![✔] 使用非特权容器
+
+**TL;DR:** 特权容器具有与主机上的根用户相同的权限和功能。这是很少需要的,作为一个经验法则,应该使用在官方Node镜像中创建的'node'用户
+
+## ![✔] 检查并验证最终结果
+
+**TL;DR:** 有时很容易忽略构建过程中的副作用,如泄露的秘密或不必要的文件。使用[Dive](https://github.com/wagoodman/dive)等工具检查生成的镜像可以很容易地帮助识别此类问题
+
+## ![✔] 执行完整性检查
+
+**TL;DR:** 在拉取基本镜像或最终镜像时,网络可能会被误导并重定向到下载恶意镜像。除非对内容进行签名和验证,否则标准Docker协议中没有任何内容可以防止这种情况。[Docker Notary](https://docs.docker.com/notary/getting_started/)是一个可以执行此类检查的工具
diff --git a/sections/docker/generic-tips.french.md b/sections/docker/generic-tips.french.md
new file mode 100644
index 000000000..5e4fba34c
--- /dev/null
+++ b/sections/docker/generic-tips.french.md
@@ -0,0 +1,29 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# Common Node.js Docker best practices
+
+This common Docker guidelines section contains best practices that are standardized among all programming languages and have no special Node.js interpretation
+
+## ![✔] Prefer COPY over ADD command
+
+**TL;DR:** COPY is safer as it copies local files only while ADD supports fancier fetches like downloading binaries from remote sites
+
+## ![✔] Avoid updating the base OS
+
+**TL;DR:** Updating the local binaries during build (e.g. apt-get update) creates inconsistent images every time it runs and also demands elevated privileges. Instead use base images that are updated frequently
+
+## ![✔] Classify images using labels
+
+**TL;DR:** Providing metadata for each image might help Ops professionals treat it adequately. For example, include the maintainer name, build date and other information that might prove useful when someone needs to reason about an image
+
+## ![✔] Use unprivileged containers
+
+**TL;DR:** Privileged container have the same permissions and capabilities as the root user over the host machine. This is rarely needed and as a rule of thumb one should use the 'node' user that is created within official Node images
+
+## ![✔] Inspect and verify the final result
+
+**TL;DR:** Sometimes it's easy to overlook side effects in the build process like leaked secrets or unnecessary files. Inspecting the produced image using tools like [Dive](https://github.com/wagoodman/dive) can easily help to identify such issues
+
+## ![✔] Perform integrity check
+
+**TL;DR:** While pulling base or final images, the network might be mislead and redirected to download malicious images. Nothing in the standard Docker protocol prevents this unless signing and verifying the content. [Docker Notary](https://docs.docker.com/notary/getting_started/) is one of the tools to achieve this
\ No newline at end of file
diff --git a/sections/docker/generic-tips.japanese.md b/sections/docker/generic-tips.japanese.md
new file mode 100644
index 000000000..59e97c69d
--- /dev/null
+++ b/sections/docker/generic-tips.japanese.md
@@ -0,0 +1,29 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# 一般的な Docker のベストプラクティス
+
+この Docker ガイドラインのセクションでは、すべてのプログラミング言語の間で共通して通用するベストプラクティスを紹介しており、Node.js に限ったものではありません。
+
+## ![✔] COPY コマンドを ADD コマンドよりも優先する
+
+**TL;DR:** ADD はリモートのサイトからバイナリをダウンロードするといった高度なフェッチ機能をサポートしていますが、COPY はローカルファイルをコピーするためより安全です。
+
+## ![✔] ベース OS をアップデートすることを避ける
+
+**TL;DR:** ビルド中にローカルのバイナリをアップデートする(例:apt-get update)と、実行のたびに一貫性のないイメージが作成され、高度な権限が要求されます。代わりに、頻繁に更新されるベースイメージを利用してください。
+
+## ![✔] ラベルを利用してイメージを分類する
+
+**TL;DR:** 各イメージにメタデータを提供することで、Ops の専任者がイメージを適切に扱うことの助けになるかもしれません。例えば、管理者名やビルド日時、その他の情報を含めることで、誰かがイメージについて推測する必要がある際に有用となる場合があります。
+
+## ![✔] 権限の無いコンテナを利用する
+
+**TL;DR:** 権限を持つコンテナは、ホストマシンの root ユーザと同じ権限と機能を持っています。このような権限が必要になることは滅多に無く、経験則として、公式の Node イメージ内で作成された「node」ユーザを使用するべきです。
+
+## ![✔] 最終的な結果を検査し、検証する
+
+**TL;DR:** シークレットの漏洩や、不要なファイルなど、ビルドプロセスでの副作用を見落としがちなことがあります。[Dive](https://github.com/wagoodman/dive) のようなツールを利用することで、作成されたイメージを検査し、そのような問題を用意に特定することができます。
+
+## ![✔] 完全性チェックを行う
+
+**TL;DR:** ベースイメージや最終イメージをプルする際に、ネットワークがミスリードされて悪意のあるイメージをダウンロードするようにリダイレクトされる可能性があります。コンテンツに署名して検証しない限り、標準の Docker プロトコルではこれを防ぐことはできません。[Docker Notary](https://docs.docker.com/notary/getting_started/) はこれ防ぐためのツールの一つです。
diff --git a/sections/docker/generic-tips.md b/sections/docker/generic-tips.md
new file mode 100644
index 000000000..54570d5c4
--- /dev/null
+++ b/sections/docker/generic-tips.md
@@ -0,0 +1,29 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# Common Node.js Docker best practices
+
+This common Docker guidelines section contains best practices that are standardized among all programming languages and have no special Node.js interpretation
+
+## ![✔] Prefer COPY over ADD command
+
+**TL;DR:** COPY is safer as it copies local files only while ADD supports fancier fetches like downloading binaries from remote sites
+
+## ![✔] Avoid updating the base OS
+
+**TL;DR:** Updating the local binaries during build (e.g. apt-get update) creates inconsistent images every time it runs and also demands elevated privileges. Instead use base images that are updated frequently
+
+## ![✔] Classify images using labels
+
+**TL;DR:** Providing metadata for each image might help Ops professionals treat it adequately. For example, include the maintainer name, build date and other information that might prove useful when someone needs to reason about an image
+
+## ![✔] Use unprivileged containers
+
+**TL;DR:** Privileged container have the same permissions and capabilities as the root user over the host machine. This is rarely needed and as a rule of thumb one should use the 'node' user that is created within official Node images
+
+## ![✔] Inspect and verify the final result
+
+**TL;DR:** Sometimes it's easy to overlook side effects in the build process like leaked secrets or unnecessary files. Inspecting the produced image using tools like [Dive](https://github.com/wagoodman/dive) can easily help to identify such issues
+
+## ![✔] Perform integrity check
+
+**TL;DR:** While pulling base or final images, the network might be mislead and redirected to download malicious images. Nothing in the standard Docker protocol prevents this unless signing and verifying the content. [Docker Notary](https://docs.docker.com/notary/getting_started/) is one of the tools to achieve this
diff --git a/sections/docker/graceful-shutdown.basque.md b/sections/docker/graceful-shutdown.basque.md
new file mode 100644
index 000000000..174f88a7f
--- /dev/null
+++ b/sections/docker/graceful-shutdown.basque.md
@@ -0,0 +1,80 @@
+# Itzalaldi dotorea
+
+
+
+### Azalpena
+
+Kubernetes bezalako exekuzio ingurune Dockerizatu batean, edukiontziak sarri jaio eta hiltzen dira. Erroreak jaurtitzen direnean gertatzen da hori, baina baita bestelako arrazoi onak direla eta, hala nola edukiontziak berrerabiltzeagatik edo kontainerrak bertsio berriago batekin ordezkatzeagatik. Eta hori lortzen da prozesuari 30 segunduko itxarote iraupena duen abisu bat (SIGTERM seinalea) bidaliz. Horrek erronka bat gehitzen dio garatzaileari bermatu behar baitu aplikazioa modu egokian ari dela kudeatzen une horretan bertan egikaritzen ari diren eskaerak eta garbiketako baliabideak. Bestela, milaka erabiltzaile goibelduko lirateke erantzunik jasoko ez luketelako. Inplementazioari dagokionez, itzaltze kodeak itxoin beharko du uneko eskaera guztiak bukatuta egon eta ondoren baliabideak garbituta egon arte. Errazagoa da esatea egitea baino, ordea, praktikan hainbat zati kudeatzea eskatzen du eta: esan LoadBalancerari aplikazioak ezin duela eskaera gehiago onartu (health-checkaren bidez), itxaron uneko eskariak amaituta egon arte, ekidin eskaera berriak kudeatzea, garbitu baliabideak eta, azkenik, erregistratu informazio baliagarria hil aurretik. Bizirik matentzeko konexioak (Keep-Alive) erabiliz gero, konexio berriak sortu behar direla jakinarazi behar zaie erabiltzaileei. [Stoppable](https://github.com/hunterloftis/stoppable) bezalako liburutegia laguntza handia izan daiteke hori lortzeko.
+
+
+
+### Kode adibidea: Node.js prozesu errotzat definitzeak kodeari seinaleak pasatzea ahalbidetzen du ([ikusi abiarazi node erabiliz](./bootstrap-using-node.basque.md))
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Eraikitze logika hemen dago
+
+CMD ["node", "index.js"]
+#Hemengo ilarak Node.js prozesu erroa (PID1) bilakatuko du
+
+```
+
+
+
+
+
+### Kode adibidea: erabili Tily prozesu kudeatzailea seinaleak Noderi berbidaltzeko
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Eraikitze logika hemen dago
+
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "index.js"]
+#Hemendik aurrera Nodek PID1 bezala jokatuko duten TINIren azpi prozesuak abiatuko ditu
+
+```
+
+
+
+
+
+### Anti ereduaren kode adibidea: erabili npm scriptak prozesua hasieratzeko
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Eraikitze logika hemen dator
+
+CMD ["npm", "start"]
+#Hemendik aurrera Nodek bigarren mailako prozesuak abiatuko ditu eta npmek ez ditu seinaleak jasoko
+
+```
+
+
+
+
+
+### One Paragraph Explainer
+
+In a Dockerized runtime like Kubernetes, containers are born and die frequently. This happens not only when errors are thrown but also for good reasons like relocating containers, replacing them with a newer version and more. It's achieved by sending a notice (SIGTERM signal) to the process with a 30 second grace period. This puts a challenge on the developer to ensure the app is handling the ongoing requests and clean-up resources in a timely fashion. Otherwise thousands of sad users will not get a response. Implementation-wise, the shutdown code should wait until all ongoing requests are flushed out and then clean-up resources. Easier said than done, practically it demands orchestrating several parts: Tell the LoadBalancer that the app is not ready to serve more requests (via health-check), wait for existing requests to be done, avoid handling new requests, clean-up resources and finally log some useful information before dying. If Keep-Alive connections are being used, the clients must also be notified that a new connection should be established - A library like [Stoppable](https://github.com/hunterloftis/stoppable) can greatly help achieving this.
+
+
+
+
+### Code Example – Placing Node.js as the root process allows passing signals to the code (see [bootstrap using node](./bootstrap-using-node.md))
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Build logic comes here
+
+CMD ["node", "index.js"]
+#This line above will make Node.js the root process (PID1)
+
+```
+
+
+
+
+
+### Code Example – Using Tiny process manager to forward signals to Node
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Build logic comes here
+
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "index.js"]
+#Now Node will run a sub-process of TINI which acts as PID1
+
+```
+
+
+
+
+
+### Code Example Anti Pattern – Using npm scripts to initialize the process
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Build logic comes here
+
+CMD ["npm", "start"]
+#Now Node will run a sub-process of npm and won't receive signals
+
+```
+
+
+
+
+
+### Example - The shutdown phases
+
+From the blog, [Rising Stack](https://blog.risingstack.com/graceful-shutdown-node-js-kubernetes/)
+
+
\ No newline at end of file
diff --git a/sections/docker/graceful-shutdown.japanese.md b/sections/docker/graceful-shutdown.japanese.md
new file mode 100644
index 000000000..697f45e44
--- /dev/null
+++ b/sections/docker/graceful-shutdown.japanese.md
@@ -0,0 +1,81 @@
+# グレースフルにシャットダウンする
+
+
+
+### One Paragraph Explainer
+
+In a Dockerized runtime like Kubernetes, containers are born and die frequently. This happens not only when errors are thrown but also for good reasons like relocating containers, replacing them with a newer version and more. It's achieved by sending a notice (SIGTERM signal) to the process with a 30 second grace period. This puts a challenge on the developer to ensure the app is handling the ongoing requests and clean-up resources in a timely fashion. Otherwise thousands of sad users will not get a response. Implementation-wise, the shutdown code should wait until all ongoing requests are flushed out and then clean-up resources. Easier said than done, practically it demands orchestrating several parts: Tell the LoadBalancer that the app is not ready to serve more requests (via health-check), wait for existing requests to be done, avoid handling new requests, clean-up resources and finally log some useful information before dying. If Keep-Alive connections are being used, the clients must also be notified that a new connection should be established - A library like [Stoppable](https://github.com/hunterloftis/stoppable) can greatly help achieving this.
+
+
+
+
+### Code Example – Placing Node.js as the root process allows passing signals to the code (see [bootstrap using node](./bootstrap-using-node.md))
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Build logic comes here
+
+CMD ["node", "index.js"]
+#This line above will make Node.js the root process (PID1)
+
+```
+
+
+
+
+
+### Code Example – Using Tiny process manager to forward signals to Node
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Build logic comes here
+
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN chmod +x /tini
+ENTRYPOINT ["/tini", "--"]
+
+CMD ["node", "index.js"]
+#Now Node will run a sub-process of TINI which acts as PID1
+
+```
+
+
+
+
+
+### Code Example Anti Pattern – Using npm scripts to initialize the process
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# Build logic comes here
+
+CMD ["npm", "start"]
+#Now Node will run a sub-process of npm and won't receive signals
+
+```
+
+
+
+
+
+### Example - The shutdown phases
+
+From the blog, [Rising Stack](https://blog.risingstack.com/graceful-shutdown-node-js-kubernetes/)
+
+
diff --git a/sections/docker/image-tags.basque.md b/sections/docker/image-tags.basque.md
new file mode 100644
index 000000000..c276d2746
--- /dev/null
+++ b/sections/docker/image-tags.basque.md
@@ -0,0 +1,30 @@
+# Ulertu irudi etiketak eta laburpenak eta erabili "azken" (latest) etiketak kontu handiz
+
+### Azalpena
+
+Ekoizpen aldian segurtasuna eta egonkortasuna garrantzitsuak dira, eta "erosotasuna" ez da erabakitze faktore egokiena. Gainera, `:latest` Dockeren lehenetsitako etiketa da. Horrek esan nahi du etiketa esplizitua gehitzea ahaztu duen garatzaileak nahi gabe irudi baten bertsio berria argitaratuko duela, espero gabeko emaitzak sor ditzakeena `latest` etiketa ekoizpeneko azken irudia izatea erabakiz gero.
+
+### Kode adibidea:
+
+```bash
+$ docker build -t company/image_name:0.1 .
+# :azken irudia ez da eguneratua
+$ docker build -t company/image_name
+# :azken irudia eguneratua da
+$ docker build -t company/image_name:0.2 .
+# :azken irudia ez da eguneratua
+$ docker build -t company/image_name:latest .
+# :azken irudia eguneratua da
+```
+
+### Beste bloglariek diotena
+
+[Vladislav Supalov](https://vsupalov.com/docker-latest-tag/)en bloga:
+
+> Batzuek espero dute :latestek beti irudi baten bertsio berrienari erreferentzia egingo diola. Hori ez da egia.
+
+[Docker success center](https://success.docker.com/article/images-tagging-vs-digests) bloga
+
+>
+
+
diff --git a/sections/docker/image-tags.french.md b/sections/docker/image-tags.french.md
new file mode 100644
index 000000000..f770243da
--- /dev/null
+++ b/sections/docker/image-tags.french.md
@@ -0,0 +1,27 @@
+# Understand image tags vs digests and use the `:latest` tag with caution
+
+### One Paragraph Explainer
+
+If this is a production situation and security and stability are important then just "convenience" is likely not the best deciding factor. In addition the `:latest` tag is Docker's default tag. This means that a developer who forgets to add an explicit tag will accidentally push a new version of an image as `latest`, which might end in very unintended results if the `latest` tag is being relied upon as the latest production image.
+
+### Code example:
+
+```bash
+$ docker build -t company/image_name:0.1 .
+# :latest image is not updated
+$ docker build -t company/image_name
+# :latest image is updated
+$ docker build -t company/image_name:0.2 .
+# :latest image is not updated
+$ docker build -t company/image_name:latest .
+# :latest image is updated
+```
+
+### What Other Bloggers Say
+From the blog by [Vladislav Supalov](https://vsupalov.com/docker-latest-tag/):
+> Some people expect that :latest always points to the most-recently-pushed version of an image. That’s not true.
+
+From the [Docker success center](https://success.docker.com/article/images-tagging-vs-digests)
+>
+
+
\ No newline at end of file
diff --git a/sections/docker/image-tags.japanese.md b/sections/docker/image-tags.japanese.md
new file mode 100644
index 000000000..3ee50f6eb
--- /dev/null
+++ b/sections/docker/image-tags.japanese.md
@@ -0,0 +1,27 @@
+# イメージタグ vs ダイジェストを理解し、`:latest` タグは注意深く利用する
+
+### 一段落説明
+
+本番環境で、セキュリティと安定性を重視するのであれば、「利便性」はベストな決定要因ではないかもしれません。`:latest` タグは Docker のデフォルトタグです。これが意味することは、明示的なタグを追加し忘れた開発者は誤って新しいバージョンのイメージを `latest` としてプッシュしてしまうかもしれないということです。`latest` タグが最新の本番環境のイメージとして利用されている場合には、意図しない結果を招く可能性があります。
+
+### コード例:
+
+```bash
+$ docker build -t company/image_name:0.1 .
+# :latest イメージはアップデートされない
+$ docker build -t company/image_name
+# :latest イメージはアップデートされる
+$ docker build -t company/image_name:0.2 .
+# :latest イメージはアップデートされない
+$ docker build -t company/image_name:latest .
+# :latest イメージはアップデートされる
+```
+
+### 他のブロガーが言っていること
+
+[Vladislav Supalov](https://vsupalov.com/docker-latest-tag/) のブログより:
+> 一部の人は、:latest タグは直近でプッシュされたバージョンのイメージを指していると思っています。しかし、そうではありません。
+
+[Docker success center](https://success.docker.com/article/images-tagging-vs-digests)
+
+
diff --git a/sections/docker/image-tags.md b/sections/docker/image-tags.md
new file mode 100644
index 000000000..293dabdd4
--- /dev/null
+++ b/sections/docker/image-tags.md
@@ -0,0 +1,27 @@
+# Understand image tags vs digests and use the `:latest` tag with caution
+
+### One Paragraph Explainer
+
+If this is a production situation and security and stability are important then just "convenience" is likely not the best deciding factor. In addition the `:latest` tag is Docker's default tag. This means that a developer who forgets to add an explicit tag will accidentally push a new version of an image as `latest`, which might end in very unintended results if the `latest` tag is being relied upon as the latest production image.
+
+### Code example:
+
+```bash
+$ docker build -t company/image_name:0.1 .
+# :latest image is not updated
+$ docker build -t company/image_name
+# :latest image is updated
+$ docker build -t company/image_name:0.2 .
+# :latest image is not updated
+$ docker build -t company/image_name:latest .
+# :latest image is updated
+```
+
+### What Other Bloggers Say
+From the blog by [Vladislav Supalov](https://vsupalov.com/docker-latest-tag/):
+> Some people expect that :latest always points to the most-recently-pushed version of an image. That’s not true.
+
+From the [Docker success center](https://success.docker.com/article/images-tagging-vs-digests)
+>
+
+
diff --git a/sections/docker/install-for-production.basque.md b/sections/docker/install-for-production.basque.md
new file mode 100644
index 000000000..8ca1564e9
--- /dev/null
+++ b/sections/docker/install-for-production.basque.md
@@ -0,0 +1,89 @@
+# Ezabatu garapen menpekotasunak
+
+
+
+### Azalpena
+
+Garapen menpekotasunek asko handitzen dute edukiontziaren eraso azalera (esaterako, segurtasun ahulezia potentzialak) eta edukiontziaren tamaina. Adibide gisa, npm segurtasun zulo handienak [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes) bezakako garapen menpekotasunek sortuak izan ziren, edo [nodemonek erabilitako ebentu katea](https://snyk.io/blog/a-post-mortem-of-the-malicious-event-stream-backdoor/) bezalako garapenerako paketeek. Arrazoi horiek direla eta, ekoizpenerako bidaliko den irudiak segurua eta txikia izan behar du. Hasiera bikaina da npm install komandoa `--production`ekin abiatzea. Hala ere, `npm ci` erabiltzea oraindik seguruagoa da, hutsetik sortutako instalazioa eta sarrail filtxategiaren sorrera ziurtatzen ditu eta. Tokiko cachea ezabatzeak hamarkada MB gehiago berreskuratzen lagun dezake. Sarritan edukiontzi batean probatu edo araztu behar izaten da devDependencies erabiliz. Kasu horretan, [etapa anitzeko konpilazioek](./multi_stage_builds.basque.md) menpekotasun multzo zenbaita izaten lagun dezakete eta, azkenik, ekoizpenerako behar direnak soilik.
+
+
+
+### Kode adibidea: ekoizpenerako instalazioa
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm clean cache --force
+
+# Gainontzeko guztia hemen dator
+```
+
+
+
+
+
+### Anti ereduaren kode adibidea: instalatu menpekotasun guztiak Dockerfile fitxategiko etapa bakarrean
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+# Bi akatz hemen: Garapen menpekotasunak instalatu eta cachea ez ezabatu npm install egin ondoren
+RUN npm install
+
+# Gainontzeko guztia hemen dator
+```
+
+
+
+
+
+### Blogeko aipua: "gainera, instalazio arrunta baino zorrotzagoa da npm ci"
+
+[npmen dokumentazioa](https://docs.npmjs.com/cli/ci.html)
+
+> Komando hau npm-installen antzekoa da, salbu eta ingurune automatizatuetan erabiltzeko sortua dela, hala nola, proben plataformak, integrazio eta inplementazio jarraituak, edo zure menpekotasunen instalazio garbi bat egiten ari zarela ziur zauden egoeretan. npm install askoz azkarragoa izan liteke komando arrunta baino, erabiltzaileentzako funtzionalitate batzuk alde batera uzten dituelako. Instalazio arrunt bat baino zorrotzagoa ere bada, npm erabiltzaile gehienek gutxinaka-gutxinaka instalatutako tokiko inguruneek sortzen dituzten erroreak edo kontraesanak identifikatzen lagungarri izan daitekeena.
diff --git a/sections/docker/install-for-production.french.md b/sections/docker/install-for-production.french.md
new file mode 100644
index 000000000..6f19612b1
--- /dev/null
+++ b/sections/docker/install-for-production.french.md
@@ -0,0 +1,90 @@
+# Remove development dependencies
+
+
+
+### One Paragraph Explainer
+
+Dev dependencies greatly increase the container attack surface (i.e. potential security weakness) and the container size. As an example, some of the most impactful npm security breaches were originated from devDependencies like [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes) or affected dev packages like [event-stream that was used by nodemon](https://snyk.io/blog/a-post-mortem-of-the-malicious-event-stream-backdoor/). For those reasons the image that is finally shipped to production should be safe and minimal. Running npm install with a `--production` is a great start, however it gets even safer to run `npm ci` that ensures a fresh install and the existence of a lock file. Removing the local cache can shave additional tens of MB. Often there is a need to test or debug within a container using devDependencies - In that case, [multi stage builds](./multi_stage_builds.md) can help in having different sets of dependencies and finally only those for production.
+
+
+
+### Code Example – Installing for production
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# The rest comes here
+```
+
+
+
+
+
+### Code Example Anti-Pattern – Installing all dependencies in a single stage dockerfile
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+# Two mistakes below: Installing dev dependencies, not deleting the cache after npm install
+RUN npm install
+
+# The rest comes here
+```
+
+
+
+
+
+### Blog Quote: "npm ci is also more strict than a regular install"
+
+From [npm documentation](https://docs.npmjs.com/cli/ci.html)
+
+> This command is similar to npm-install, except it’s meant to be used in automated environments such as test platforms, continuous integration, and deployment – or any situation where you want to make sure you’re doing a clean install of your dependencies. It can be significantly faster than a regular npm install by skipping certain user-oriented features. It is also more strict than a regular install, which can help catch errors or inconsistencies caused by the incrementally-installed local environments of most npm users.
\ No newline at end of file
diff --git a/sections/docker/install-for-production.japanese.md b/sections/docker/install-for-production.japanese.md
new file mode 100644
index 000000000..03994e9ed
--- /dev/null
+++ b/sections/docker/install-for-production.japanese.md
@@ -0,0 +1,90 @@
+# 開発依存性の除去
+
+
+
+### アンチパターン コード例 – すべての依存関係を1つのステージの dockerfile にインストールする
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+# 以下2つのミスがあります: dev の依存関係のインストールをし、npm インストール後にキャッシュを削除していません
+RUN npm install
+
+# The rest comes here
+```
+
+
+
+
+
+### ブログ引用: "npm ci is also more strict than a regular install(npm ci は通常のインストールよりも厳格です)"
+
+[npm documentation](https://docs.npmjs.com/cli/ci.html) より
+
+> このコマンドは npm-install と似ていますが、テストプラットフォームや継続的インテグレーション、デプロイメントなどの自動化された環境や、依存関係をクリーンにインストールしたい状況での使用を想定しています。ユーザー指向の機能をスキップすることで、通常の npm インストールよりも大幅に高速になります。また、通常のインストールよりも厳格で、ほとんどの npm ユーザのローカル環境がインクリメンタルにインストールされていることによるエラーや不整合を検出するのに役立ちます。
diff --git a/sections/docker/install-for-production.md b/sections/docker/install-for-production.md
new file mode 100644
index 000000000..d95afed98
--- /dev/null
+++ b/sections/docker/install-for-production.md
@@ -0,0 +1,90 @@
+# Remove development dependencies
+
+
+
+### One Paragraph Explainer
+
+Dev dependencies greatly increase the container attack surface (i.e. potential security weakness) and the container size. As an example, some of the most impactful npm security breaches were originated from devDependencies like [eslint-scope](https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes) or affected dev packages like [event-stream that was used by nodemon](https://snyk.io/blog/a-post-mortem-of-the-malicious-event-stream-backdoor/). For those reasons the image that is finally shipped to production should be safe and minimal. Running npm install with a `--production` is a great start, however it gets even safer to run `npm ci` that ensures a fresh install and the existence of a lock file. Removing the local cache can shave additional tens of MB. Often there is a need to test or debug within a container using devDependencies - In that case, [multi stage builds](./multi_stage_builds.md) can help in having different sets of dependencies and finally only those for production.
+
+
+
+### Code Example – Installing for production
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+RUN npm ci --production && npm cache clean --force
+
+# The rest comes here
+```
+
+
+
+
+
+### Code Example Anti-Pattern – Installing all dependencies in a single stage dockerfile
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim AS build
+
+WORKDIR /usr/src/app
+COPY package.json package-lock.json ./
+# Two mistakes below: Installing dev dependencies, not deleting the cache after npm install
+RUN npm install
+
+# The rest comes here
+```
+
+
+
+
+
+### Blog Quote: "npm ci is also more strict than a regular install"
+
+From [npm documentation](https://docs.npmjs.com/cli/ci.html)
+
+> This command is similar to npm-install, except it’s meant to be used in automated environments such as test platforms, continuous integration, and deployment – or any situation where you want to make sure you’re doing a clean install of your dependencies. It can be significantly faster than a regular npm install by skipping certain user-oriented features. It is also more strict than a regular install, which can help catch errors or inconsistencies caused by the incrementally-installed local environments of most npm users.
diff --git a/sections/docker/lint-dockerfile.basque.md b/sections/docker/lint-dockerfile.basque.md
new file mode 100644
index 000000000..02ad85f67
--- /dev/null
+++ b/sections/docker/lint-dockerfile.basque.md
@@ -0,0 +1,26 @@
+# Garbitu zure Dockerfile fitxategia
+
+### Azalpena
+
+Gure oinarrizko aplikazioaren kodea praktika onen arabera lan egiteko eta arazo bihurtu aurretik arazoak eta akatsak ezabatzeko eratuta dago, eta gure Dockerfile fitxategiek ere hala beharko lukete. Dockerfile fitxategiak garbitzeak ekoizpen arazoak garaiz atzemateko aukerak handitzea dakar oso ahalegin txikiarekin. Adibidez, zure Dockefileetan zehaztutako logikarekin eta aginduekin inolako egiturazko arazorik ez dagoela ziurtatu dezake; esaterako, existitzen ez den etapa bat kopiatzea, onlineko biltegi ezezagun batetik kopiak egitea, aplikazioa super erabiltzailearekin (SUDO) exekutatzea eta beste hainbat. Dockerfile fitxategiren [Hadolint](https://github.com/hadolint/hadolint) linter irekia (Open Source) eskuz edota IE prozesuaren zati gisa erabil daiteke zure Dockerfile fitxategia(k) garbitzeko. Hadolint Dockerfile fitxategi garbitzaile aurreratua da, [Dockerren praktika onak](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) bultzatzen dituena.
+
+
+
+### Kode adibidea: arakatu Dockerfile fitxategia hadolint erabiliz
+
+```bash
+hadolint production.Dockerfile
+hadolint --ignore DL3003 --ignore DL3006 # arau zehatzak burutu
+hadolint --trusted-registry my-company.com:500 # Erabiltzailea jakinarazi irudi fidaezinak erabiltzeagatik
+```
+
+### Beste bloglariek diotena
+
+[Josh Reichardt](https://thepracticalsysadmin.com/lint-your-dockerfiles-with-hadolint/)en bloga:
+
+> Oraindik ez badaukazu zure Dockerfile fitxategiak garbitzeko ohiturarik, ohitu zaitez egiten. Kode garbiketa software garapeneko praktika arrunta da, arazo eta akatsak aurkitu, identifikatu eta ezabatzen laguntzen duena benetako arazo bihurtu aurretik. Zure kodea garbitzearen abantaila handienetako bat da akats txiki korapilasuak atzematen eta ezabatzen laguntzen duela, arazo bihurtu aurretik.
+
+[Jamie Phillips](https://www.phillipsj.net/posts/hadolint-linting-your-dockerfile/)en bloga:
+
+> Garbitzaileak edota linterrak sarri erabiltzen dira garapenean, lan taldeei programazio eta estilo erroreak atzematen laguntzeko. Hadolint Haskell erabiliz Dockerfile fitxategientzat sortutako garbitzailea (linterra) da. Tresna horrek zure Dockerfile fitxategiaren sintaxia aztertzen du eta Dockerek zehaztutako praktika onak kontutan hartu. Plataforma nagusi gehienetarako balio du, eta tutorial honek edukiontzia erabiliko du Dockerfile fitxategi batean garbiketa egiteko.
+>
diff --git a/sections/docker/lint-dockerfile.french.md b/sections/docker/lint-dockerfile.french.md
new file mode 100644
index 000000000..64ff2df01
--- /dev/null
+++ b/sections/docker/lint-dockerfile.french.md
@@ -0,0 +1,25 @@
+# Lint your Dockerfile
+
+### One Paragraph Explainer
+
+As our core application code is linted to conform to best practices and eliminate issues and bugs before it could become a problem, so too should our Dockerfiles. Linting the Dockerfile means increasing the chances of catching production issues on time with very light effort. For example, it can ensure that there aren’t any structural problems with the logic and instructions specified in your Dockerfiles like trying to copy from non-existing stage, copying from unknown online repository, running the app with power user (SUDO) and many more. The Open Source Dockerfile linter [Hadolint](https://github.com/hadolint/hadolint) can be used manually or as part of a CI process to lint your Dockerfile/s. Hadolint is a specialized Dockerfile linter that aims to embrace the [Docker best practices.](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
+
+
+
+
+### Code example: Inspecting a Dockerfile using hadolint
+
+```bash
+hadolint production.Dockerfile
+hadolint --ignore DL3003 --ignore DL3006 # exclude specific rules
+hadolint --trusted-registry my-company.com:500 # Warn when using untrusted FROM images
+```
+
+### What Other Bloggers Say
+
+From the blog by [Josh Reichardt](https://thepracticalsysadmin.com/lint-your-dockerfiles-with-hadolint/):
+> If you haven’t already gotten in to the habit of linting your Dockerfiles you should. Code linting is a common practice in software development which helps find, identify and eliminate issues and bugs before they are ever able to become a problem. One of the main benefits of linting your code is that it helps identify and eliminate nasty little bugs before they ever have a chance to become a problem.
+
+From the blog by [Jamie Phillips](https://www.phillipsj.net/posts/hadolint-linting-your-dockerfile/)
+> Linters are commonly used in development to help teams detect programmatic and stylistic errors. Hadolint is a linter created for Dockerfiles using Haskell. This tool validates against the best practices outlined by Docker and takes a neat approach to parse the Dockerfile that you should checkout. It supports all major platforms, and this tutorial will be leveraging the container to perform the linting on an example Dockerfile.
+
\ No newline at end of file
diff --git a/sections/docker/lint-dockerfile.japanese.md b/sections/docker/lint-dockerfile.japanese.md
new file mode 100644
index 000000000..6b0a41e99
--- /dev/null
+++ b/sections/docker/lint-dockerfile.japanese.md
@@ -0,0 +1,25 @@
+# Dockerfile を lint する
+
+### 一段落説明
+
+コアアプリケーションのコードをベストプラクティスに従わせ、問題になる前にイシューやバグを取り除くために lint を利用するように、Dockerfile も同様に linting されるべきです。Dockerfile を linting することは、非常に軽い労力でプロダクションの問題をオンタイムで捕らえることができる可能性を高めることを意味します。例えば、存在しないステージからコピーを試みたり、不明なオンラインリポジトリからコピーしてきたり、パワーユーザー(SUDO)でアプリケーションを実行したりなど、Dockerfile に記述されたロジックや命令に構造的な問題が無いことを確認することができます。オープンソースの Dockerfile linter である [Hadolint](https://github.com/hadolint/hadolint) は、手動または CI プロセスの一部として利用することができます。Hadolint は、[Docker ベストプラクティス](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) に従うことを目的とした Dockerfile 専用の linter です。
+
+
+
+
+### コード例: hadolint を使用して Dockerfile を検査する
+
+```bash
+hadolint production.Dockerfile
+hadolint --ignore DL3003 --ignore DL3006 # 特定のルールを除外する
+hadolint --trusted-registry my-company.com:500 # 信頼されていない FROM イメージを利用している場合に警告を出す
+```
+
+### 他のブロガーが言っていること
+
+[Josh Reichardt](https://thepracticalsysadmin.com/lint-your-dockerfiles-with-hadolint/) のブログより:
+> もしまだ Dockerfile を linting する習慣を取り入れていないのであれば、いますぐ取り入れるべきです。コードの linting はソフトウェア開発における一般的な慣習であり、問題となる前にイシューやバグを特定し、排除するのに役立ちます。コードを linting することの主な利点の1つは、問題が発生する前に、厄介な些細なバグを特定し排除する手助けをしてくれることです。
+
+[Jamie Phillips](https://www.phillipsj.net/posts/hadolint-linting-your-dockerfile/) のブログより:
+> Linter は、開発チームがプログラム的なエラーやスタイルエラーを検出しやすくするために、開発現場では一般的に利用されています。Hadolint は Haskell で Dockerfile のために実装された linter です。このツールは、Docker によって示されたベストプラクティスに照らし合わせて検証し、チェックするべき Dockerfile をパースするために、きちんとしたアプローチを取ります。これはすべての主要なプラットフォームをサポートしており、このチュートリアルではコンテナを利用してサンプル Dockerfile 上で linting を行います。
+
diff --git a/sections/docker/lint-dockerfile.md b/sections/docker/lint-dockerfile.md
new file mode 100644
index 000000000..b9793fd4f
--- /dev/null
+++ b/sections/docker/lint-dockerfile.md
@@ -0,0 +1,25 @@
+# Lint your Dockerfile
+
+### One Paragraph Explainer
+
+As our core application code is linted to conform to best practices and eliminate issues and bugs before it could become a problem, so too should our Dockerfiles. Linting the Dockerfile means increasing the chances of catching production issues on time with very light effort. For example, it can ensure that there aren’t any structural problems with the logic and instructions specified in your Dockerfiles like trying to copy from non-existing stage, copying from unknown online repository, running the app with power user (SUDO) and many more. The Open Source Dockerfile linter [Hadolint](https://github.com/hadolint/hadolint) can be used manually or as part of a CI process to lint your Dockerfile/s. Hadolint is a specialized Dockerfile linter that aims to embrace the [Docker best practices.](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
+
+
+
+
+### Code example: Inspecting a Dockerfile using hadolint
+
+```bash
+hadolint production.Dockerfile
+hadolint --ignore DL3003 --ignore DL3006 # exclude specific rules
+hadolint --trusted-registry my-company.com:500 # Warn when using untrusted FROM images
+```
+
+### What Other Bloggers Say
+
+From the blog by [Josh Reichardt](https://thepracticalsysadmin.com/lint-your-dockerfiles-with-hadolint/):
+> If you haven’t already gotten in to the habit of linting your Dockerfiles you should. Code linting is a common practice in software development which helps find, identify and eliminate issues and bugs before they are ever able to become a problem. One of the main benefits of linting your code is that it helps identify and eliminate nasty little bugs before they ever have a chance to become a problem.
+
+From the blog by [Jamie Phillips](https://www.phillipsj.net/posts/hadolint-linting-your-dockerfile/)
+> Linters are commonly used in development to help teams detect programmatic and stylistic errors. Hadolint is a linter created for Dockerfiles using Haskell. This tool validates against the best practices outlined by Docker and takes a neat approach to parse the Dockerfile that you should checkout. It supports all major platforms, and this tutorial will be leveraging the container to perform the linting on an example Dockerfile.
+
diff --git a/sections/docker/memory-limit.basque.md b/sections/docker/memory-limit.basque.md
new file mode 100644
index 000000000..fce834f5d
--- /dev/null
+++ b/sections/docker/memory-limit.basque.md
@@ -0,0 +1,70 @@
+# Ezarri memoria mugak Docker eta v8 erabiliz
+
+
+
+### Azalpena
+
+Memoria mugatzeak prozesuari/edukiontziari adierazten dio zer tamainako memoria erabiltzeko baimena duen gehienez ere. Tamaina horretatik gorako eskaerak edo erabilerak prozesua hil egingo du (OOMKill). Hori egitea jarraibide bikaina da ziurtatzeko herritar batek zuku guztia berak bakarrik edaten ez duela, beste guztiak egarriz akabatzen utzita. Memoria mugek, gainera, exekuzio garaian edukiontzia instantzia egokian ipintzea ahalbidetzen du; izan ere, 500MB erabiltzen dituen edukiontzi bat 300MB dituen instantzia baten ipintzeak arazoak ekar litzake. Bi aukerek muga konfiguratzen laguntzen dute: V8 banderak (--max-old-space-size) eta Docker abiatze denbora, biak guztiz beharrezkoak dira. Ziurtatu beti Dockeren iraupen mugak konfiguratu dituzula, osasun erabaki egokiak hartzeko ikuspegi askoz zabalagoa baitu: muga hori izanda, exekuzioak badaki baliabide gehiago eskalatzen eta sortzen. Noiz huts egin behar duen erabaki dezake: kontainerrean, memoria eskaeran, eztanda labur bat gertatzen bada eta ostatatutako instantzia horri eusteko gai bada, Dockerek bizirik egoten utziko dio edukiontziari. Azkenik, Dockeri esker, Ops adituak hainbat memoria konfigurazio ezar ditzake, ekoizpenean kontutan hartuak izan daitezkeenak, adibidez, memoriaren trukea (memory swap). Hori bera bakarrik ez da nahikoa izango, v8ren --max-old-space-size gabe, JavaScript abiatze inguruneak ez du zabor biltzea bultzatuko memoriaren mugatik gertu egotean, eta krask egingo du soilik ostatatutako ingurunearen % 50-60 erabiltzean. Ondorioz, ezarri v8n muga Dockeren memoria mugaren %75-100 izan dadin.
+
+
+
+### Kode adibidea: memoriaren muga Dockerrekin
+
+
+Bash
+
+```bash
+docker run --memory 512m nire-node-aplikazioa
+```
+
+
+
+
+
+### Kubernetesen dokumentazioa: "Memoriaren muga zehaztu ezean"
+
+[K8Sen dokumentazioa](https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/)
+
+> Edukiontziak ez du erabiltzen duen memoriaren gehieneko muga. Egikaritzen ari den Nodean erabilgarri dagoen memoria guztia erabil dezake edukiontziak , eta horrek OOM Killer errorea dei dezake. Gainera, OOM Kill bat gertatuz gero, mugarik gabeko edukiontzi batek aukera gehiago izango du akabatua izateko.
+
+
+
+### Dockeren dokumentazioa: "Jaurti OOME errore bat eta hasi prozesuak hiltzen"
+
+[Dockeren dokumentu ofiziala](https://docs.docker.com/config/containers/resource_constraints/)
+
+> Garrantzitsua da exekutatzen ari den edukiontzi bati ez uztea ostatatutako makinaren memoria gehiegi erabiltzen. Linux ostalarietan, kernelak sistemako funtzio garrantzitsuak egiteko haina memoria ez dagoela atzematen badu, OOME bat jaurtitzen du, Out Of Memory Exception (Memoria Faltaren Salbuespena), eta prozesuak akabatzen hasten da memoria eskuratzeko.
+
+
+
+### Node.jsren dokumentazioa: "V8k denbora gehiago pasako du zabor bilketan"
+
+[Node.jsren dokumentu ofiziala](https://nodejs.org/api/cli.html#cli_max_old_space_size_size_in_megabytes)
+
+> Ezarri V8ren atal zaharraren gehienezko memoria tamaina. Memoriaren kontsumoa mugara gerturatzen denean, V8k denbora gehiago pasako du zabor bilketan, erabili gabeko memoria askatzen baino. 2GBko memoria duen makina batean, komeni da 1536Mgb (1.5GB) ezartzea, beste erabiltzaileentzat memoria pixkat bat uzteko eta memoria trukea ekiditeko.
diff --git a/sections/docker/memory-limit.french.md b/sections/docker/memory-limit.french.md
new file mode 100644
index 000000000..93204f016
--- /dev/null
+++ b/sections/docker/memory-limit.french.md
@@ -0,0 +1,70 @@
+# Set memory limits using both Docker and v8
+
+
+
+### One Paragraph Explainer
+
+A memory limit tells the process/container the maximum allowed memory usage - a request or usage beyond this number will kill the process (OOMKill). Applying this is a great practice to ensure one citizen doesn't drink all the juice alone and leaves other components to starve. Memory limits also allow the runtime to place a container in the right instance - placing a container that consumes 500MB in an instance with 300MB memory available will lead to failures. Two different options allow configuring this limit: V8 flags (--max-old-space-size) and the Docker runtime, both are absolutely needed. Ensure to always configure the Docker runtime limits as it has a much wider perspective for making the right health decisions: Given this limit, the runtime knows how to scale and create more resources. It can also make a thoughtful decision on when to crash - if a container has a short burst in memory request and the hosting instance is capable of supporting this, Docker will let the container stay alive. Last, with Docker the Ops experts can set various production memory configurations that can be taken into account like memory swap. This by itself won't be enough - Without setting v8's --max-old-space-size, the JavaScript runtime won't push the garbage collection when getting close to the limits and will also crash when utilizing only 50-60% of the host environment. Consequently, set v8's limit to be 75-100% of Docker's memory limit.
+
+
+
+### Code Example – Memory limit with Docker
+
+
+Bash
+
+```bash
+docker run --memory 512m my-node-app
+```
+
+
+
+
+
+### Kubernetes documentation: "If you do not specify a memory limit"
+
+From [K8S documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/)
+
+> The Container has no upper bound on the amount of memory it uses. The Container could use all of the memory available on the Node where it is running which in turn could invoke the OOM Killer. Further, in case of an OOM Kill, a container with no resource limits will have a greater chance of being killed.
+
+
+
+### Docker documentation: "it throws an OOME and starts killing processes "
+
+From [Docker official docs](https://docs.docker.com/config/containers/resource_constraints/)
+
+> It is important not to allow a running container to consume too much of the host machine’s memory. On Linux hosts, if the kernel detects that there is not enough memory to perform important system functions, it throws an OOME, or Out Of Memory Exception, and starts killing processes to free up memory.
+
+
+
+### Node.js documentation: "V8 will spend more time on garbage collection"
+
+From [Node.js official docs](https://nodejs.org/api/cli.html#cli_max_old_space_size_size_in_megabytes)
+
+> Sets the max memory size of V8's old memory section. As memory consumption approaches the limit, V8 will spend more time on garbage collection in an effort to free unused memory. On a machine with 2GB of memory, consider setting this to 1536 (1.5GB) to leave some memory for other uses and avoid swapping.
\ No newline at end of file
diff --git a/sections/docker/memory-limit.japanese.md b/sections/docker/memory-limit.japanese.md
new file mode 100644
index 000000000..d91b149e7
--- /dev/null
+++ b/sections/docker/memory-limit.japanese.md
@@ -0,0 +1,70 @@
+# Docker と v8 の両方を使ってメモリ制限を設定する
+
+
+
+### Kubernetes のドキュメント: "If you do not specify a memory limit(メモリ制限を指定しない場合)"
+
+[K8S ドキュメント](https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/) より
+
+> コンテナは使用するメモリ量に上限はありません。コンテナは、それが実行されているノードで利用可能なすべてのメモリを使用することができ、その結果、OOM Killer を呼び出すことができます。さらに、OOM Killer の場合、リソースの制限がないコンテナは kill される可能性が高くなります。
+
+
+
+### Docker のドキュメント: "it throws an OOME and starts killing processes(OOME を投げてプロセスを殺し始めます)"
+
+[Docker 公式ドキュメント](https://docs.docker.com/config/containers/resource_constraints/) より
+
+> 実行中のコンテナがホストマシンのメモリを消費しすぎないようにすることが重要です。Linux ホストでは、カーネルが重要なシステム機能を実行するのに十分なメモリがないことを検出すると、OOME (Out Of Memory Exception) をスローし、メモリを解放するためにプロセスの kill を開始します。
+
+
+
+### Node.js のドキュメント: "V8 will spend more time on garbage collection(V8 はガベージコレクションにより時間を費やすことになります)"
+
+[Node.js 公式ドキュメント](https://nodejs.org/api/cli.html#cli_max_old_space_size_size_in_megabytes) より
+
+> V8 の古いメモリセクションの最大メモリサイズを設定します。メモリ消費量が限界に近づくと、V8 は未使用のメモリを解放するためにガベージコレクションに多くの時間を費やします。メモリが2GBのマシンでは、これを1536 (1.5GB)に設定して、他の用途のためにメモリを残し、スワップを避けることを検討してください。
diff --git a/sections/docker/memory-limit.md b/sections/docker/memory-limit.md
new file mode 100644
index 000000000..8198228f8
--- /dev/null
+++ b/sections/docker/memory-limit.md
@@ -0,0 +1,70 @@
+# Set memory limits using both Docker and v8
+
+
+
+### One Paragraph Explainer
+
+A memory limit tells the process/container the maximum allowed memory usage - a request or usage beyond this number will kill the process (OOMKill). Applying this is a great practice to ensure one citizen doesn't drink all the juice alone and leaves other components to starve. Memory limits also allow the runtime to place a container in the right instance - placing a container that consumes 500MB in an instance with 300MB memory available will lead to failures. Two different options allow configuring this limit: V8 flags (--max-old-space-size) and the Docker runtime, both are absolutely needed. Ensure to always configure the Docker runtime limits as it has a much wider perspective for making the right health decisions: Given this limit, the runtime knows how to scale and create more resources. It can also make a thoughtful decision on when to crash - if a container has a short burst in memory request and the hosting instance is capable of supporting this, Docker will let the container stay alive. Last, with Docker the Ops experts can set various production memory configurations that can be taken into account like memory swap. This by itself won't be enough - Without setting v8's --max-old-space-size, the JavaScript runtime won't push the garbage collection when getting close to the limits and will also crash when utilizing only 50-60% of the host environment. Consequently, set v8's limit to be 75-100% of Docker's memory limit.
+
+
+
+### Code Example – Memory limit with Docker
+
+
+Bash
+
+```bash
+docker run --memory 512m my-node-app
+```
+
+
+
+
+
+### Kubernetes documentation: "If you do not specify a memory limit"
+
+From [K8S documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/)
+
+> The Container has no upper bound on the amount of memory it uses. The Container could use all of the memory available on the Node where it is running which in turn could invoke the OOM Killer. Further, in case of an OOM Kill, a container with no resource limits will have a greater chance of being killed.
+
+
+
+### Docker documentation: "it throws an OOME and starts killing processes "
+
+From [Docker official docs](https://docs.docker.com/config/containers/resource_constraints/)
+
+> It is important not to allow a running container to consume too much of the host machine’s memory. On Linux hosts, if the kernel detects that there is not enough memory to perform important system functions, it throws an OOME, or Out Of Memory Exception, and starts killing processes to free up memory.
+
+
+
+### Node.js documentation: "V8 will spend more time on garbage collection"
+
+From [Node.js official docs](https://nodejs.org/api/cli.html#cli_max_old_space_size_size_in_megabytes)
+
+> Sets the max memory size of V8's old memory section. As memory consumption approaches the limit, V8 will spend more time on garbage collection in an effort to free unused memory. On a machine with 2GB of memory, consider setting this to 1536 (1.5GB) to leave some memory for other uses and avoid swapping.
diff --git a/sections/docker/multi_stage_builds.basque.md b/sections/docker/multi_stage_builds.basque.md
new file mode 100644
index 000000000..7155723d1
--- /dev/null
+++ b/sections/docker/multi_stage_builds.basque.md
@@ -0,0 +1,115 @@
+# Erabili etapa anitzeko konpilazioak
+
+### Azalpena
+
+Etapa anitzeko konpilazioek aukera ematen dute eraikuntzei eta exekuzio denborari dagozkion inguruneko xehetasunak bereizteko, hala nola eskuragarri dauden binarioak, agerian dauden inguruneko aldagaiak eta baita azpiko sistema eragilea ere. Zure Docker fitxategiak etapa anitzetan banatzeak azken irudia eta edukiontziaren tamaina murrizten lagunduko dizu, zure aplikazioa egikaritzeko behar duzuna bakarrik bidaliko baituzu. Batzuetan, konpilazio fasean soilik beharrezkoak diren tresnak sartu beharko dituzu, adibidez garapenerako menpekotasunak, hala nola TypeScripten CLI. Konpilazio fasean instalatu dezakezu, eta azken irteera exekuzio fasean bakarrik erabili. Horrek esan nahi du zure irudia txikitu egingo dela, menpekotasun batzuk ez baitira kopiatuko. Agian, egikaritze aldian egon behar ez luketen inguruneko aldagai batzuk agerian jarri beharko dituzu eraikuntzan (aztertu [nola saihestu konpilazio aldiko sekretuak](./avoid-build-time-secrets.basque.md)), hala nola API giltzak eta zerbitzu zehatzekin komunikatzeko erabiltzen diren sekretuak. Azken fasean, aurrez eraikitako baliabideak kopiatu ditzakezu, hala nola zure konpilazio karpeta edo soilik ekoizpenekoak diren menpekotasunak, hurrengo urratsean ere eskuratu ditzakezunak.
+
+### Adibidea
+
+Eman dezagun direktorio egitura hau
+
+```
+- Dockerfile
+- src/
+ - index.ts
+- package.json
+- yarn.lock
+- .dockerignore
+- docs/
+ - README.md
+```
+Dagoeneko zure aplikazioa eraikitzeko eta exekutatzeko beharrezkoak ez diren fitxategiak iragaziko ditu zure [.dockerignore](../docker/docker-ignore.basque.md)-k.
+
+```
+# Ez kopiatu existitzen diren node_modules karpetan, gure node_modules propioa berreskuratuko dugu
+
+# Docs are large, we don't need them in our Docker image
+docs
+```
+
+#### Etapa anitzeko Dockerfile fitxategia
+
+Docker maiz etengabeko integrazio inguruneetan erabiltzen denez, `npm ci` komandoa erabiltzea gomendatzen da (`npm install` komandoa beharrean). Azkarragoa da, zorrotzagoa ere bai, eta inkoherentziak murrizten ditu package-lock.json fitxategian zehaztutako bertsioak soilik erabiliz gero. Begiratu [hau](https://docs.npmjs.com/cli/ci.html#description) informazio gehiago lortzeko. Adibide horrek yarn erabiltzen du pakete kudeatzaile gisa eta horretarako `yarn install --frozen-lockfile` [komandoa](https://classic.yarnpkg.com/en/docs/cli/install/) da `npm ci`-ren baliokidea.
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+FROM node:14.4.0
+
+USER node
+EXPOSE 8080
+
+# Aurreko etapatik emaitzak kopiatu
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### Docker fitxategia etapa anitzekin eta oinarrizko irudiekin
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+# Honek exekuzio garairako oinarri-irudi minimoa erabiliko du
+FROM node:14.4.0-alpine
+
+USER node
+EXPOSE 8080
+
+# Kopiatu emaitzak aurreko etapatik
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### Dockerfile osoa etapa anitzekin eta oinarrizko irudiekin
+
+Gure Docker fitxategiak bi fase izango ditu: bata, aplikazioa eraikitzekoa, Node.js Docker irudia erabiliz funtzio guztietan; eta bigarren fasea, aplikazioa exekutatzeko, Alpine irudi minimoan oinarritutakoa. Bigarren fasean konpilatutako fitxategiak bakarrik kopiatuko ditugu, eta gero produkzioaren menpekotasunak instalatuko ditugu.
+
+```dockerfile
+# Funtzionalitate guztiak dituen Node.js oinarri-irudiarekin hasi
+FROM node:14.4.0 AS build
+
+USER node
+WORKDIR /home/node/app
+
+# Menpekotasun informazioa kopiatu eta menpekotasun guztiak instalatu
+COPY --chown=node:node package.json yarn.lock ./
+
+RUN yarn install --frozen-lockfile
+
+# Iturburu kodea kopiatu (eta beste fitxategi garrantzitsu guztiak)
+COPY --chown=node:node src ./src
+
+# Kodea eraiki
+RUN yarn build
+
+
+# Exekuzio-garaiaren etapa
+FROM node:14.4.0-alpine
+
+# Zehaztu erro erabiltzailea ez dena eta agerian utzi 8080 portua
+USER node
+EXPOSE 8080
+
+WORKDIR /home/node/app
+
+# Menpekotasunen informazioa kopiatu eta soilik ekoizpenerako beharrezko dire menpekotasunak instalatu
+COPY --chown=node:node package.json yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+# Aurreko etapatik emaitzak kopiatu
+COPY --chown=node:node --from=build /home/node/app/dist ./dist
+
+CMD [ "node", "dist/app.js" ]
+```
diff --git a/sections/docker/multi_stage_builds.french.md b/sections/docker/multi_stage_builds.french.md
new file mode 100644
index 000000000..b7d3ac854
--- /dev/null
+++ b/sections/docker/multi_stage_builds.french.md
@@ -0,0 +1,121 @@
+# Use multi-stage builds
+
+### One Paragraph Explainer
+
+Multi-stage builds allow to separate build- and runtime-specific environment details, such as available binaries, exposed environment variables, and even the underlying operating system. Splitting up your Dockerfiles into multiple stages will help to reduce final image and container size as you'll only ship what you really need to run your application. Sometimes you'll need to include tools that are only needed during the build phase, for example development dependencies such as the TypeScript CLI. You can install it during the build stage and only use the final output in the run stage. This also means your image will shrink as some dependencies won't get copied over. You might also have to expose environment variables during build that should not be present at runtime (see [avoid build time secrets](./avoid-build-time-secrets.md)), such as API Keys and secrets used for communicating with specific services. In the final stage, you can copy in pre-built resources such as your build folder, or production-only dependencies (which you can also fetch in a subsequent step).
+
+### Example
+
+Let's imagine the following directory structure
+
+```
+- Dockerfile
+- src/
+ - index.ts
+- package.json
+- yarn.lock
+- .dockerignore
+- docs/
+ - README.md
+```
+
+Your [.dockerignore](../docker/docker-ignore.md) will already filter out files that won't be needed for building and running your application.
+
+
+sections/docker/docker-ignore.md
+```
+# Don't copy in existing node_modules, we'll fetch our own
+node_modules
+
+# Docs are large, we don't need them in our Docker image
+docs
+```
+
+#### Dockerfile with multiple stages
+
+Since Docker is often used in continuous integration environments it is recommended to use the `npm ci` command (instead of `npm install`). It is faster, stricter and reduces inconsistencies by using only the versions specified in the package-lock.json file. See [here](https://docs.npmjs.com/cli/ci.html#description) for more info. This example uses yarn as package manager for which the equivalent to `npm ci` is the `yarn install --frozen-lockfile` [command](https://classic.yarnpkg.com/en/docs/cli/install/).
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+FROM node:14.4.0
+
+USER node
+EXPOSE 8080
+
+# Copy results from previous stage
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### Dockerfile with multiple stages and different base images
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+# This will use a minimal base image for the runtime
+FROM node:14.4.0-alpine
+
+USER node
+EXPOSE 8080
+
+# Copy results from previous stage
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### Full Dockerfile with multiple stages and different base images
+
+Our Dockerfile will contain two phases: One for building the application using the fully-featured Node.js Docker image,
+and a second phase for running the application, based on the minimal Alpine image. We'll only copy over the built files to our second stage,
+and then install production dependencies.
+
+```dockerfile
+# Start with fully-featured Node.js base image
+FROM node:14.4.0 AS build
+
+USER node
+WORKDIR /home/node/app
+
+# Copy dependency information and install all dependencies
+COPY --chown=node:node package.json yarn.lock ./
+
+RUN yarn install --frozen-lockfile
+
+# Copy source code (and all other relevant files)
+COPY --chown=node:node src ./src
+
+# Build code
+RUN yarn build
+
+
+# Run-time stage
+FROM node:14.4.0-alpine
+
+# Set non-root user and expose port 8080
+USER node
+EXPOSE 8080
+
+WORKDIR /home/node/app
+
+# Copy dependency information and install production-only dependencies
+COPY --chown=node:node package.json yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+# Copy results from previous stage
+COPY --chown=node:node --from=build /home/node/app/dist ./dist
+
+CMD [ "node", "dist/app.js" ]
+```
\ No newline at end of file
diff --git a/sections/docker/multi_stage_builds.japanese.md b/sections/docker/multi_stage_builds.japanese.md
new file mode 100644
index 000000000..cd160cf5c
--- /dev/null
+++ b/sections/docker/multi_stage_builds.japanese.md
@@ -0,0 +1,117 @@
+# マルチステージビルドを使用する
+
+### 一段落説明
+
+マルチステージビルドでは、利用可能なバイナリや公開されている環境変数、さらには基礎となるOSなど、ビルドとランタイム固有の環境の詳細を分離することができます。Dockerfile を複数のステージに分割することで、アプリケーションの実行に本当に必要なものだけをリリースすることができるので、最終的なイメージやコンテナのサイズを小さくすることができます。ビルド段階でのみ必要となるツール、例えば TypeScript CLI のような開発依存のツールを含める必要があることもあるでしょう。これらのツールはビルド段階でインストールし、最終的な出力のみ実行段階で使用することができます。これは、いくつかの依存関係がコピーオーバーされないため、イメージが縮小されることを意味します。また、実行時には存在してはいけない API キーや特定のサービスとの通信に使われるシークレットなどの環境変数をビルド中に公開しなければならないかもしれません([ビルド時のシークレットを避ける](./avoid-build-time-secrets.japanese.md) を参照してください。) 最終ステージでは、ビルドフォルダのようなビルド済みのリソースや本番環境専用の依存関係 (これは後のステップで取得することもできます) をコピーすることができます。
+
+### 例
+
+以下のようなディレクトリ構造を想像してみましょう。
+
+```
+- Dockerfile
+- src/
+ - index.ts
+- package.json
+- yarn.lock
+- .dockerignore
+- docs/
+ - README.md
+```
+
+[.dockerignore](./docker-ignore.japanese.md) では、アプリケーションのビルドや実行に必要のないファイルをすでにフィルタリングしています。
+
+```
+# 既存の node_modules をコピーしないで、自分たちで取得します。
+node_modules
+
+# ドキュメントは大きいので、Docker イメージには必要ありません。
+docs
+```
+
+#### 複数のステージがある Dockerfile
+
+Docker は継続的インテグレーション環境で使用されることが多いので、`npm install` ではなく `npm ci` コマンドを使用することをお勧めします。package-lock.json ファイルで指定されたバージョンのみを使用することで、より速く、より厳密になり、矛盾を減らすことができます。詳細は [こちら](https://docs.npmjs.com/cli/ci.html#description) を参照してください。この例ではパッケージマネージャとして yarn を使用していますが、`npm ci` と同等のものは `yarn install --frozen-lockfile` [command](https://classic.yarnpkg.com/en/docs/cli/install/) です。
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+FROM node:14.4.0
+
+USER node
+EXPOSE 8080
+
+# 前のステージの結果をコピー
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### 複数のステージと異なるベースイメージを持つ Dockerfile
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+# ランタイム用に最小のベースイメージを使用
+FROM node:14.4.0-alpine
+
+USER node
+EXPOSE 8080
+
+# 前のステージの結果をコピー
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### 複数のステージと異なるベースイメージを持つフル Dockerfile
+
+私たちの Dockerfile には2つのフェーズが含まれています: 1つ目のフェーズは、フル機能を備えた Node.js の Docker イメージを使ってアプリケーションを構築するためのものです。2つ目のフェーズは、最小限の Alpine イメージに基づいて、アプリケーションを実行するためのものです。ビルドされたファイルのみを第二段階にコピーし、本番環境の依存関係をインストールします。
+
+```dockerfile
+# フル機能の Node.js ベースのイメージでスタート
+FROM node:14.4.0 AS build
+
+USER node
+WORKDIR /home/node/app
+
+# 依存関係情報をコピーし、すべての依存関係をインストール
+COPY --chown=node:node package.json yarn.lock ./
+
+RUN yarn install --frozen-lockfile
+
+# ソースコード(およびその他すべての関連ファイル)をコピー
+COPY --chown=node:node src ./src
+
+# コードのビルド
+RUN yarn build
+
+
+# ランタイムステージ
+FROM node:14.4.0-alpine
+
+# 非 root ユーザを設定し、ポート 8080 を公開
+USER node
+EXPOSE 8080
+
+WORKDIR /home/node/app
+
+# 依存関係情報をコピーして、本番環境のみの依存関係をインストール
+COPY --chown=node:node package.json yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+# 前のステージの結果をコピー
+COPY --chown=node:node --from=build /home/node/app/dist ./dist
+
+CMD [ "node", "dist/app.js" ]
+```
diff --git a/sections/docker/multi_stage_builds.md b/sections/docker/multi_stage_builds.md
new file mode 100644
index 000000000..de24b1d0b
--- /dev/null
+++ b/sections/docker/multi_stage_builds.md
@@ -0,0 +1,121 @@
+# Use multi-stage builds
+
+### One Paragraph Explainer
+
+Multi-stage builds allow to separate build- and runtime-specific environment details, such as available binaries, exposed environment variables, and even the underlying operating system. Splitting up your Dockerfiles into multiple stages will help to reduce final image and container size as you'll only ship what you really need to run your application. Sometimes you'll need to include tools that are only needed during the build phase, for example development dependencies such as the TypeScript CLI. You can install it during the build stage and only use the final output in the run stage. This also means your image will shrink as some dependencies won't get copied over. You might also have to expose environment variables during build that should not be present at runtime (see [avoid build time secrets](./avoid-build-time-secrets.md)), such as API Keys and secrets used for communicating with specific services. In the final stage, you can copy in pre-built resources such as your build folder, or production-only dependencies (which you can also fetch in a subsequent step).
+
+### Example
+
+Let's imagine the following directory structure
+
+```
+- Dockerfile
+- src/
+ - index.ts
+- package.json
+- yarn.lock
+- .dockerignore
+- docs/
+ - README.md
+```
+
+Your [.dockerignore](../docker/docker-ignore.md) will already filter out files that won't be needed for building and running your application.
+
+
+sections/docker/docker-ignore.md
+```
+# Don't copy in existing node_modules, we'll fetch our own
+node_modules
+
+# Docs are large, we don't need them in our Docker image
+docs
+```
+
+#### Dockerfile with multiple stages
+
+Since Docker is often used in continuous integration environments it is recommended to use the `npm ci` command (instead of `npm install`). It is faster, stricter and reduces inconsistencies by using only the versions specified in the package-lock.json file. See [here](https://docs.npmjs.com/cli/ci.html#description) for more info. This example uses yarn as package manager for which the equivalent to `npm ci` is the `yarn install --frozen-lockfile` [command](https://classic.yarnpkg.com/en/docs/cli/install/).
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+FROM node:14.4.0
+
+USER node
+EXPOSE 8080
+
+# Copy results from previous stage
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### Dockerfile with multiple stages and different base images
+
+```dockerfile
+FROM node:14.4.0 AS build
+
+COPY --chown=node:node . .
+RUN yarn install --frozen-lockfile && yarn build
+
+
+# This will use a minimal base image for the runtime
+FROM node:14.4.0-alpine
+
+USER node
+EXPOSE 8080
+
+# Copy results from previous stage
+COPY --chown=node:node --from=build /home/node/app/dist /home/node/app/package.json /home/node/app/yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+CMD [ "node", "dist/app.js" ]
+```
+
+#### Full Dockerfile with multiple stages and different base images
+
+Our Dockerfile will contain two phases: One for building the application using the fully-featured Node.js Docker image,
+and a second phase for running the application, based on the minimal Alpine image. We'll only copy over the built files to our second stage,
+and then install production dependencies.
+
+```dockerfile
+# Start with fully-featured Node.js base image
+FROM node:14.4.0 AS build
+
+USER node
+WORKDIR /home/node/app
+
+# Copy dependency information and install all dependencies
+COPY --chown=node:node package.json yarn.lock ./
+
+RUN yarn install --frozen-lockfile
+
+# Copy source code (and all other relevant files)
+COPY --chown=node:node src ./src
+
+# Build code
+RUN yarn build
+
+
+# Run-time stage
+FROM node:14.4.0-alpine
+
+# Set non-root user and expose port 8080
+USER node
+EXPOSE 8080
+
+WORKDIR /home/node/app
+
+# Copy dependency information and install production-only dependencies
+COPY --chown=node:node package.json yarn.lock ./
+RUN yarn install --frozen-lockfile --production
+
+# Copy results from previous stage
+COPY --chown=node:node --from=build /home/node/app/dist ./dist
+
+CMD [ "node", "dist/app.js" ]
+```
diff --git a/sections/docker/restart-and-replicate-processes.basque.md b/sections/docker/restart-and-replicate-processes.basque.md
new file mode 100644
index 000000000..e01c0977d
--- /dev/null
+++ b/sections/docker/restart-and-replicate-processes.basque.md
@@ -0,0 +1,43 @@
+# Utzi Dockeren exekuzio denborari erreplikatu eta jardueraren iraupena kudeatzen
+
+
+
+### Azalpena
+
+Dockeren exekuzio denboraren kudeatzaileak, Kubernetes bezala, benetan onak dira edukiontzien osasun eta ezarpen erabakiak hartzen: edukiontzi kopurua maximizatzen, edukiontziak zonaldeen artean orekatzen eta klusterren faktore ugari kontuan hartzen dituzte erabaki horiek hartzen dituzten bitartean. Esan gabe doa: huts egiten duten prozesuak (hau da, edukiontziak) identifikatzen dituzte eta leku egokian berrabiarazten dituzte. Hala ere, batzuek kode pertsonalizatuak edo tresnak erabiltzeko tentazioa izan dezakete Node prozesua erreplikatuz PUZa erabili eta, huts eginez gero, prozesua berrabiarazte aldera (adibidez,PM2 kluster modulua, ). Tokiko tresna horiek ez dituzte kluster mailako ikuspegia eta eskuragarri dauden datuak. Adibidez, instantzien baliabideek 3 edukiontzi eta 2 eskualde ostatatu ditzaketenean, edukiontziak hainbat eskualdetan hedatzen arduratuko da Kubernetes. Horrela, zonaldeak edo eskualdeak huts egitea gertatuz gero, aplikazioak bizirik jarraituko du. Aitzitik, tokiko tresnak erabiltzean prozesua berrekiteko, Dockeren kudeatzailea ez da erroreez jabetzen eta ezin du ondo pentsatutako erabakirik hartu, edukiontzia zonalde edo instantzia berri batean ipintzea bezala.
+
+
+
+### Kode adibidea: deitu Node.js zuzenean, tarteko tresnarik gabe
+
+
+
+Dockerfile fitxategia
+
+```dockerfile
+FROM node:12-slim
+
+# Eraikitze logika hemen dago
+
+CMD ["node", "index.js"]
+```
+
+
+
+
+
+### Anti ereduaren kode adibidea: erabili prozesu kudeatzailea
+
+
+
+Dockerfile fitxategia
+
+```dockerfile
+FROM node:12-slim
+
+# Eraikitze logika hemen dago
+
+CMD ["pm2-runtime", "indes.js"]
+```
+
+
diff --git a/sections/docker/restart-and-replicate-processes.french.md b/sections/docker/restart-and-replicate-processes.french.md
new file mode 100644
index 000000000..3f6bff00a
--- /dev/null
+++ b/sections/docker/restart-and-replicate-processes.french.md
@@ -0,0 +1,43 @@
+# Let the Docker orchestrator restart and replicate processes
+
+
+
+### One Paragraph Explainer
+
+Docker runtime orchestrators like Kubernetes are really good at making containers health and placement decisions: They will take care to maximize the number of containers, balance them across zones, and take into account many cluster factors while making these decisions. Goes without words, they identify failing processes (i.e., containers) and restart them in the right place. Despite that some may be tempted to use custom code or tools to replicate the Node process for CPU utilization or restart the process upon failure (e.g., Cluster module, PM2). These local tools don't have the perspective and the data that is available on the cluster level. For example, when the instances resources can host 3 containers and given 2 regions or zones, Kubernetes will take care to spread the containers across zones. This way, in case of a zonal or regional failure, the app will stay alive. On the contrary side when using local tools for restarting the process the Docker orchestrator is not aware of the errors and can not make thoughtful decisions like relocating the container to a new instance or zone.
+
+
+
+### Code Example – Invoking Node.js directly without intermediate tools
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# The build logic comes here
+
+CMD ["node", "index.js"]
+```
+
+
+
+
+
+### Code Example Anti Pattern – Using a process manager
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# The build logic comes here
+
+CMD ["pm2-runtime", "indes.js"]
+```
+
+
\ No newline at end of file
diff --git a/sections/docker/restart-and-replicate-processes.japanese.md b/sections/docker/restart-and-replicate-processes.japanese.md
new file mode 100644
index 000000000..95e8e05c7
--- /dev/null
+++ b/sections/docker/restart-and-replicate-processes.japanese.md
@@ -0,0 +1,42 @@
+# プロセスを再起動と複製をDocker オーケストレーターに任せる
+
+
+
+### One Paragraph Explainer
+
+Docker runtime orchestrators like Kubernetes are really good at making containers health and placement decisions: They will take care to maximize the number of containers, balance them across zones, and take into account many cluster factors while making these decisions. Goes without words, they identify failing processes (i.e., containers) and restart them in the right place. Despite that some may be tempted to use custom code or tools to replicate the Node process for CPU utilization or restart the process upon failure (e.g., Cluster module, PM2). These local tools don't have the perspective and the data that is available on the cluster level. For example, when the instances resources can host 3 containers and given 2 regions or zones, Kubernetes will take care to spread the containers across zones. This way, in case of a zonal or regional failure, the app will stay alive. On the contrary side when using local tools for restarting the process the Docker orchestrator is not aware of the errors and can not make thoughtful decisions like relocating the container to a new instance or zone.
+
+
+
+### Code Example – Invoking Node.js directly without intermediate tools
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# The build logic comes here
+
+CMD ["node", "index.js"]
+```
+
+
+
+
+
+### Code Example Anti Pattern – Using a process manager
+
+
+
+Dockerfile
+
+```dockerfile
+FROM node:12-slim
+
+# The build logic comes here
+
+CMD ["pm2-runtime", "index.js"]
+```
+
+
diff --git a/sections/docker/scan-images.basque.md b/sections/docker/scan-images.basque.md
new file mode 100644
index 000000000..9e35cce5b
--- /dev/null
+++ b/sections/docker/scan-images.basque.md
@@ -0,0 +1,30 @@
+# Eskaneatu irudi osoa ekoiztu aurretik
+
+
+
+### Azalpena
+
+Kodea eskaneatzea ahultasunak aurkitzeko ekintza baliotsua da, baina ez du mehatxu guztietatik babesten. Zergatik? Sistema eragilean ere badirelako ahultasunak, eta Shell, Tarball eta OpenSSL bezalako binarioak exekuta ditzakeelako aplikazioak. Gainera, erasogarriak diren menpekotasunak kodea eskaneatu ondoren gehitu daitezke (adibidez hornikuntza katearen erasoak). Hori dela eta, zuzenena da bukaerako irudia eskaneatzea zehazki ekoizpenera bidali aurretik. Ideia horrek E2E proben antza du, zati bakoitza modu isolatuan probatu ondoren, guztiak batutako paketea probatzea komeni da. 3 eskaner familia nagusi daude: tokiko/IEko binarioak, cachean ahultasunak dituzten datu base eta guzti; hodeiko zerbitzu gisa antolatutako eskanerrak; eta baliabide sorta bat, dockera bera konpilatu bitartean eskaneatzen duena. Lehenengo taldea da ezagunena eta normalean azkarrena. Merezi du [Trivvy](https://github.com/aquasecurity/trivy), [Anchore](https://github.com/anchore/anchore) eta [Snyk](https://support.snyk.io/hc/en-us/articles/360003946897-Container-security-overview) bezalako tresnak ikertzea. IE hornitzaile gehienek lekuko plugin bat proposatzen dute, eskaner horiekin elkarrekintza errazten dutenak. Kontuan izan behar da eskaner horiek eremu handiak hartzen dituztela, eta, beraz, emaitzak izaten dituztela ia eskaneatze guztietan. Aztertu ez ote den komeni atalase maila handi samarra ezartzea larrialdiak izatea ekiditeko.
+
+
+
+### Txosten adibidea: Docker eskanerraren emaitzak (Anchoren eskutik)
+
+
diff --git a/sections/docker/scan-images.french.md b/sections/docker/scan-images.french.md
new file mode 100644
index 000000000..aa9ad2504
--- /dev/null
+++ b/sections/docker/scan-images.french.md
@@ -0,0 +1,30 @@
+# Scan the entire image before production
+
+
+
+### One Paragraph Explainer
+
+Scanning the code for vulnerabilities is a valuable act but it doesn't cover all the potential threats. Why? Because vulnerabilities also exist on the OS level and the app might execute those binaries like Shell, Tarball, OpenSSL. Also, vulnerable dependencies might be injected after the code scan (i.e. supply chain attacks) - hence scanning the final image just before production is in order. This idea resembles E2E tests - after testing the various pieces in-isolation, it's valuable to finally check the assembled deliverable. There are 3 main scanner families: Local/CI binaries with a cached vulnerabilities DB, scanners as a service in the cloud and a niche of tools which scan during the docker build itself. The first group is the most popular and usually the fastest - Tools like [Trivvy](https://github.com/aquasecurity/trivy), [Anchore](https://github.com/anchore/anchore) and [Snyk](https://support.snyk.io/hc/en-us/articles/360003946897-Container-security-overview) are worth exploring. Most CI vendors provide a local plugin that facilitates the interaction with these scanners. It should be noted that these scanners cover a lot of ground and therefore will show findings in almost every scan - consider setting a high threshold bar to avoid getting overwhelmed
+
+
+
+### レポート例 – Docker スキャン結果 (Anchore)
+
+
diff --git a/sections/docker/scan-images.md b/sections/docker/scan-images.md
new file mode 100644
index 000000000..32ea896f5
--- /dev/null
+++ b/sections/docker/scan-images.md
@@ -0,0 +1,30 @@
+# Scan the entire image before production
+
+
+
+### One Paragraph Explainer
+
+Scanning the code for vulnerabilities is a valuable act but it doesn't cover all the potential threats. Why? Because vulnerabilities also exist on the OS level and the app might execute those binaries like Shell, Tarball, OpenSSL. Also, vulnerable dependencies might be injected after the code scan (i.e. supply chain attacks) - hence scanning the final image just before production is in order. This idea resembles E2E tests - after testing the various pieces in-isolation, it's valuable to finally check the assembled deliverable. There are 3 main scanner families: Local/CI binaries with a cached vulnerabilities DB, scanners as a service in the cloud and a niche of tools which scan during the docker build itself. The first group is the most popular and usually the fastest - Tools like [Trivvy](https://github.com/aquasecurity/trivy), [Anchore](https://github.com/anchore/anchore) and [Snyk](https://support.snyk.io/hc/en-us/articles/360003946897-Container-security-overview) are worth exploring. Most CI vendors provide a local plugin that facilitates the interaction with these scanners. It should be noted that these scanners cover a lot of ground and therefore will show findings in almost every scan - consider setting a high threshold bar to avoid getting overwhelmed
+
+
+
+### Report Example – Docker scan results (By Anchore)
+
+
diff --git a/sections/docker/smaller_base_images.basque.md b/sections/docker/smaller_base_images.basque.md
new file mode 100644
index 000000000..1cb0dbcfa
--- /dev/null
+++ b/sections/docker/smaller_base_images.basque.md
@@ -0,0 +1,10 @@
+# Hobetsi Docker oinarrizko irudi txikiagoak
+
+Docker irudi handiek ahultasun gehiago sor ditzakete eta baliabideen kontsumoa handitu. Askotan, exekutatzeko garaian instalatutako zenbait pakete ez dituzu behar konpilatzeko orduan. Zenbat eta irudi handiagoak argitaratu eta gorde, garestiagoa izango da eskalatzerako orduan. Gerta daiteke irudi txikiak diseinuz ez etortzea aldez aurretik instalatuta ohiko liburutegi arruntetan (adibidez, curl), modulu natiboak sortu edo arazketak egiteko erabilgarriak diren paketeak sortzeko beharrezkoak direnak. Alpine Linuxen irudien aldaerak erabiltzeak aztarna murriztarazi dezake, erabilitako baliabideei eta sistema guztietan dauden eraso bektoreei dagokienez. Node.jsren v14.4.0 Docker irudiak gutxi gora behera 345MBko tamaina du; Alpine bertsioak, aldiz, 39MB, hau da, ia 10 aldiz txikiagoa da. Aukera bikaina da ere Debianen oinarritutako aldaera arina (Slim), 38 MB besterik ez duena eta Node.js exekutatzeko behar diren gutxieneko paketeak dituena.
+
+### Blogeko aipua: "Zure zerbitzuen abiaratzea azkarragoa eta seguruagoa izan dadin Docker irudiak txikiagoak izatea nahi baduzu, probatu Alpine."
+
+[Nick Janetakis](https://nickjanetakis.com/blog/the-3-biggest-wins-when-using-alpine-as-a-base-docker-image)-en bloga
+
+> Gaur egun jakina da Dockerek Alpine maiz erabiltzen duela Dockeren irudi ofizialetarako. Mugimendu hori 2016ko hasieran hasi zen gutxi gora-behera. [...]
+> Zerbitzari berri batean Docker irudiak argitaratzean, espero dezakezu hasierako argitalpena pixka bat azkarragoa izatea. Sarea gero eta motelagoa izan, ezberdintasuna orduan eta handiagoa izango da. [...] Tamaina txikiaren beste abantailetako bat da erasotze azala txikiagoa dela. Zure sisteman pakete eta liburutegi asko ez dagoenean, oso gauza gutxi daude gaizki irten daitezkeenak.
diff --git a/sections/docker/smaller_base_images.french.md b/sections/docker/smaller_base_images.french.md
new file mode 100644
index 000000000..591011d34
--- /dev/null
+++ b/sections/docker/smaller_base_images.french.md
@@ -0,0 +1,12 @@
+
+Large Docker images can lead to higher exposure to vulnerabilities and increased resource consumption. Often you don't need certain packages installed at runtime that are needed for building.
+Pulling and storing larger images will become more expensive at scale, when dealing with larger images. By design minimal images may not come with common libraries needed for building native modules or packages useful for debugging (e.g. curl) pre-installed.
+Using the Alpine Linux variants of images can lead to a reduced footprint in terms of resources used and the amount of attack vectors present in fully-featured systems. The Node.js v14.4.0 Docker image is ~345MB in size versus ~39MB for the Alpine version, which is almost 10x smaller.
+A Slim variant based on Debian, which is only 38MB in size and contains the minimal packages needed to run Node.js, is also a great choice.
+
+### Blog Quote: "If you want to shrink your Docker images, have your services start faster and be more secure then try Alpine out."
+
+From [Nick Janetakis' blog](https://nickjanetakis.com/blog/the-3-biggest-wins-when-using-alpine-as-a-base-docker-image)
+
+> It’s no secret by now that Docker is heavily using Alpine as a base image for official Docker images. This movement started near the beginning of 2016. [...]
+ When pulling down new Docker images onto a fresh server, you can expect the initial pull to be quite a bit faster on Alpine. The slower your network is, the bigger the difference it will be. [...] Another perk of being much smaller in size is that the surface area to be attacked is much less. When there’s not a lot of packages and libraries on your system, there’s very little that can go wrong.
\ No newline at end of file
diff --git a/sections/docker/smaller_base_images.japanese.md b/sections/docker/smaller_base_images.japanese.md
new file mode 100644
index 000000000..e4dc99ab7
--- /dev/null
+++ b/sections/docker/smaller_base_images.japanese.md
@@ -0,0 +1,13 @@
+# 小さな Docker ベースイメージを優先する
+
+サイズの大きな Docker イメージは脆弱性にさらされる可能性を高め、リソースの消費量を増加させます。多くの場合、ビルド時に必要なパッケージは実行時にインストールする必要はありません。
+大きイメージを扱う場合において、イメージをプルして保存することは、規模が大きくなるにつれてコストが高くなるでしょう。設計上、ミニマルイメージには、ネイティブモジュールの構築に必要な共通して利用されるライブラリや、デバッグに便利なパッケージ(例:curl)がプリインストールされていない場合があります。
+Alpine Linux のイメージを利用することで、使用されるリソースと、フル機能を備えたシステムに存在する攻撃の因子の総数の観点において、その度合を抑えることができます。Node.js v14.4.0 Docker イメージは ~345MB であるのに対し、Alpine バージョンのイメージは ~39MB と、10倍近く小さくなっています。
+Debian をベースとした Slim 版も良い選択肢です。わずかサイズ 38MB であり、Node.js を実行するために必要な最小限のパッケージを含んでいます。
+
+### ブログ引用: "If you want to shrink your Docker images, have your services start faster and be more secure then try Alpine out."(Docker イメージを縮小させ、サービスの起動を高速化し、より安全性を高めたい場合は、Alpine を試してください)
+
+[Nick Janetakis のブログ](https://nickjanetakis.com/blog/the-3-biggest-wins-when-using-alpine-as-a-base-docker-image)より
+
+> Docker が、公式の Docker イメージのベースとなるイメージとして Alpine を多用していることは、もう周知の事実です。[...]
+> 新しいサーバーに新しい Docker イメージをプルする際は、Alpine を利用することで最初のプルが速くなると予想されます。ネットワークが遅ければ遅いほど、その差は歴然となります。[...] サイズがより小さくなることのもうひとつの利点は、攻撃される領域が小さくなることです。システム上のパッケージやライブラリの数が少ない場合、問題が発生する可能性は低くなります。
diff --git a/sections/docker/smaller_base_images.md b/sections/docker/smaller_base_images.md
new file mode 100644
index 000000000..fc5a951b7
--- /dev/null
+++ b/sections/docker/smaller_base_images.md
@@ -0,0 +1,12 @@
+
+Large Docker images can lead to higher exposure to vulnerabilities and increased resource consumption. Often you don't need certain packages installed at runtime that are needed for building.
+Pulling and storing larger images will become more expensive at scale, when dealing with larger images. By design minimal images may not come with common libraries needed for building native modules or packages useful for debugging (e.g. curl) pre-installed.
+Using the Alpine Linux variants of images can lead to a reduced footprint in terms of resources used and the amount of attack vectors present in fully-featured systems. The Node.js v14.4.0 Docker image is ~345MB in size versus ~39MB for the Alpine version, which is almost 10x smaller.
+A Slim variant based on Debian, which is only 38MB in size and contains the minimal packages needed to run Node.js, is also a great choice.
+
+### Blog Quote: "If you want to shrink your Docker images, have your services start faster and be more secure then try Alpine out."
+
+From [Nick Janetakis' blog](https://nickjanetakis.com/blog/the-3-biggest-wins-when-using-alpine-as-a-base-docker-image)
+
+> It’s no secret by now that Docker is heavily using Alpine as a base image for official Docker images. This movement started near the beginning of 2016. [...]
+ When pulling down new Docker images onto a fresh server, you can expect the initial pull to be quite a bit faster on Alpine. The slower your network is, the bigger the difference it will be. [...] Another perk of being much smaller in size is that the surface area to be attacked is much less. When there’s not a lot of packages and libraries on your system, there’s very little that can go wrong.
diff --git a/sections/docker/use-cache-for-shorter-build-time.basque.md b/sections/docker/use-cache-for-shorter-build-time.basque.md
new file mode 100644
index 000000000..b7d862dcc
--- /dev/null
+++ b/sections/docker/use-cache-for-shorter-build-time.basque.md
@@ -0,0 +1,120 @@
+# Baliatu cachea konpilazio denborak murrizteko
+
+## Azalpena
+
+Docker irudiak geruzen konbinazioak dira. Izan ere, zure Dockerfile fitxategiko agindu bakoitzak geruza bat sortzen du. Dockeren daemonak konpilazioen arteko geruza horiek erabil ditzake, aginduak berdinak badira edo `COPY` edo `ADD` fitxategiak berdinak badira. ⚠️ Cachea ezin bada geruza jakin batean erabili, ondorengo geruza guztiak ere ezgaituak izango dira. Horrexegatik, ordena garrantzitsua da. Zure Dockerfile fitxategia zuzen diseinatzea ezinbestekoa da, zure konpilazioan atal mugikorren kopurua murrizteko; gutxien eguneratzen diren aginduak goialdean egon beharko lirateke, eta etengabe aldatzen ari diren aginduak (aplikazioaren kodea, esaterako), berriz, behe aldean.
+Baita ere, garrantzitsua da jakitea operazio luzeak abiarazten dituzten aginduek puntu gorenaren inguruan egon beharko luketeela, horrela bermatuko delako bakarrik beharrezkoak direnean gertatzea (docker irudia eraikitzen duzun bakoitzean aldatzen ez badira behintzat). Cachetik Docker irudi bat berreraikitzea ia-ia berehalakoa izan daiteke era egokian eginez gero.
+
+
+
+- [Digging into Docker layers](https://medium.com/@jessgreb01/digging-into-docker-layers-c22f948ed612)-etik hartutako irudia, jessgreb01-i esker\*
+
+### Arauak
+
+#### Ekidin une oro aldatzen den Avoid LABEL (etiketa)
+
+Zure Dockerfile fitxategiaren hasieran konpilazio zenbakia duen etiketaren bat badaukazu, cachea baliogabetua izango da konpilazio bakoitzean
+
+```Dockerfile
+#Fitxategiaren hasiea
+FROM node:10.22.0-alpine3.11 as builder
+
+# Ez egin hau hemen!
+LABEL build_number="483"
+
+#... Dockerfile fitxategiaren gainontzeko guztia
+```
+
+#### Eduki .dockerignore fitxategi egokia
+
+[**Begiratu: docker ignoreren garrantzia**](./docker-ignore.basque.md)
+
+Cachearen logika hondatu dezaketen fitxategien kopia ekiditen dute Docker ignorek, adibidez proben emaitzen txostenak, erregistroak edota aldi baterako fitxategiak.
+
+#### Instalatu lehenik "sistemaren" paketeak
+
+Gomendagarria da erabiltzen dituzun sistema pakete guztiak dituen docker irudi base bat sortzea. **Benetan** `apt`,`yum`,`apk` edo antzerako komandoak erabiliz paketeak instalatzeko beharra baduzu, horiek izan beharko lirateke zure lehenengo aginduak. Ez duzu make, gcc edo g ++ berriro instalatu nahi izango zure node aplikazioa konpilatzen duzun bakoitzean. **Ez instalatu paketea erosoa delako soilik, ekoizpen aplikazio bat da.**
+
+#### Lehendabizi, GEHITU soilik zure package.json eta lockfile
+
+```Dockerfile
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+```
+
+lockfile eta package.json gutxiagotan aldatzen dira. Beraiek lehendabizi kopiatzeak `npm install` etapa cachean utziko du, horrek denbora baliotsua aurrezten du.
+
+### Ondoren kopiatu zure fitxategiak eta exekutatu konpilazio etapa (beharrezkoa bada)
+
+```Dockerfile
+COPY . .
+RUN npm run build
+```
+
+## Adibideak
+
+### Onarrizko adibidea sistema eragileko menpekotasunak behar dituzten node_modulesekin
+
+```Dockerfile
+#Sortu node irudi bertsioaren ezizena
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci --production
+COPY . "./"
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+COPY --from=builder /app/ "./"
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+### Konpilazio etaparen adibidea (esaterako typescript erabiltzerakoan)
+
+```Dockerfile
+#Sortu node irudi bertsioaren ezizena
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+COPY . .
+RUN npm run build
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+# Behar ditugun fitxategiak bakarrik kopiatu
+COPY --from=builder /app/node_modules node_modules
+COPY --from=builder /app/package.json .
+COPY --from=builder /app/dist dist
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+## Esteka erabilgarriak
+
+Dockeren dokumentazioa: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
diff --git a/sections/docker/use-cache-for-shorter-build-time.french.md b/sections/docker/use-cache-for-shorter-build-time.french.md
new file mode 100644
index 000000000..e69d3841d
--- /dev/null
+++ b/sections/docker/use-cache-for-shorter-build-time.french.md
@@ -0,0 +1,119 @@
+# Leverage caching to reduce build times
+
+## One paragraph explainer
+
+Docker images are a combination of layers, each instruction in your Dockerfile creates a layer. The docker daemon can reuse those layers between builds if the instructions are identical or in the case of a `COPY` or `ADD` files used are identical. ⚠️ If the cache can't be used for a particular layer all the subsequent layers will be invalidated too. That's why order is important. It is crucial to layout your Dockerfile correctly to reduce the number of moving parts in your build; the less updated instructions should be at the top and the ones constantly changing (like app code) should be at the bottom. It's also important to think that instructions that trigger long operation should be close to the top to ensure they happen only when really necessary (unless it changes every time you build your docker image). Rebuilding a whole docker image from cache can be nearly instantaneous if done correctly.
+
+
+
+* Image taken from [Digging into Docker layers](https://medium.com/@jessgreb01/digging-into-docker-layers-c22f948ed612) by jessgreb01*
+
+### Rules
+
+#### Avoid LABEL that change all the time
+
+If you have a label containing the build number at the top of your Dockerfile, the cache will be invalidated at every build
+
+```Dockerfile
+#Beginning of the file
+FROM node:10.22.0-alpine3.11 as builder
+
+# Don't do that here!
+LABEL build_number="483"
+
+#... Rest of the Dockerfile
+```
+
+#### Have a good .dockerignore file
+
+[**See: On the importance of docker ignore**](./docker-ignore.md)
+
+The docker ignore avoids copying files that could bust our cache logic, like tests results reports, logs or temporary files.
+
+#### Install "system" packages first
+
+It is recommended to create a base docker image that has all the system packages you use. If you **really** need to install packages using `apt`,`yum`,`apk` or the likes, this should be one of the first instructions. You don't want to reinstall make,gcc or g++ every time you build your node app.
+**Do not install package only for convenience, this is a production app.**
+
+#### First, only ADD your package.json and your lockfile
+
+```Dockerfile
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+```
+
+The lockfile and the package.json change less often. Copying them first will keep the `npm install` step in the cache, this saves precious time.
+
+### Then copy your files and run build step (if needed)
+
+```Dockerfile
+COPY . .
+RUN npm run build
+```
+
+## Examples
+
+### Basic Example with node_modules needing OS dependencies
+```Dockerfile
+#Create node image version alias
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci --production
+COPY . "./"
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+COPY --from=builder /app/ "./"
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+
+### Example with a build step (when using typescript for example)
+```Dockerfile
+#Create node image version alias
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+COPY . .
+RUN npm run build
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+# Only copying the files that we need
+COPY --from=builder /app/node_modules node_modules
+COPY --from=builder /app/package.json .
+COPY --from=builder /app/dist dist
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+## Useful links
+
+Docker docs: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
\ No newline at end of file
diff --git a/sections/docker/use-cache-for-shorter-build-time.japanese.md b/sections/docker/use-cache-for-shorter-build-time.japanese.md
new file mode 100644
index 000000000..5a6c9a899
--- /dev/null
+++ b/sections/docker/use-cache-for-shorter-build-time.japanese.md
@@ -0,0 +1,121 @@
+# キャッシュを活用してビルド時間を短縮する
+
+## 一段落説明
+
+Docker イメージはレイヤーの組み合わせであり、Dockerfile 内の各指示はそれぞれレイヤーを作成します。もし指示が同じであるか、`COPY` や `ADD` の利用が同じであれば、docker デーモンはビルド間でそれらのレイヤーを再利用することができます。⚠️ キャッシュが特定のレイヤーで利用できなかった場合は、それ以降のすべてのレイヤーも無効になります。そのため、順番が重要なのです。Dockerfile を正しくレイアウトすることは、ビルドにおいて可変となっている部分の数を減らすために非常に重要です; あまり更新されない処理は Dockerfile の上の方に記述し、更新が多い処理(アプリケーションのコードなど)は下の方に記述するべきです。また、時間のかかるオペレーションをトリガーする指示は、(docker イメージをビルドするたびに変更されない限り)本当に必要なときにのみ実行されるように、上部に近い位置に配置するべきです。正しく行えば、ほぼ瞬時にキャッシュから Docker イメージ全体をリビルドすることができます。
+
+
+
+* jessgreb01 による [Digging into Docker layers](https://medium.com/@jessgreb01/digging-into-docker-layers-c22f948ed612) から画像引用*
+
+### ルール
+
+#### 毎回変わるラベルの使用を避ける
+
+もし Dockerfile の上部にビルド番号を含むラベルを記述している場合、毎回のビルドでキャッシュが無効化されてしまいます。
+
+```Dockerfile
+# ファイルの先頭
+FROM node:10.22.0-alpine3.11 as builder
+
+# ここでラベルの指定をしないでください!
+LABEL build_number="483"
+
+#... Dockerfile の残りの部分がここにきます
+```
+
+#### 良い .dockerignore ファイルを持つ
+
+[**参照: docker ignore の重要性について**](./docker-ignore.md)
+
+docker ignore ファイルは、テスト結果レポートやログ、一時ファイルなど、キャッシュのロジックを壊す可能性のあるファイルのコピーを回避します。
+
+#### 「system」パッケージを最初にインストールする
+
+使用するすべてのシステムパッケージが入ったベース Docker イメージを作成することをおすすめします。もし`apt` や `yum`、`apk` などを利用してパッケージインストールする必要が **本当に** あるのであれば、最初の指示にすべきです。Node アプリケーションをビルドするのに毎回 make や gcc、g++ を再インストールしたくはないでしょう。
+**プロダクションアプリケーションなので、便宜のためだけにパッケージをインストールしてはいけません。**
+
+#### まず最初に、package.json と lockfile を追加するだけにする
+
+```Dockerfile
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+```
+
+lockfile と package.json はあまり頻繁に変更されません。それらを最初にコピーしておくことで、`npm install` ステップをキャッシュすることができ、貴重な時間を節約できます。
+
+### その後、ファイルをコピーしてビルドステップを実行する(必要なら)
+
+```Dockerfile
+COPY . .
+RUN npm run build
+```
+
+## 例
+
+### OS 依存関係を必要とする node_modules の基本的な例
+
+```Dockerfile
+# node イメージバージョンのエイリアスを作成する
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci --production
+COPY . "./"
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+COPY --from=builder /app/ "./"
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+
+### ビルドステップの例(例えば、typescript を利用する場合)
+
+```Dockerfile
+# node イメージバージョンのエイリアスを作成する
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+COPY . .
+RUN npm run build
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+# 必要なファイルのみをコピーする
+COPY --from=builder /app/node_modules node_modules
+COPY --from=builder /app/package.json .
+COPY --from=builder /app/dist dist
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+## 便利なリンク
+
+Docker ドキュメント: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
diff --git a/sections/docker/use-cache-for-shorter-build-time.md b/sections/docker/use-cache-for-shorter-build-time.md
new file mode 100644
index 000000000..c7556b35b
--- /dev/null
+++ b/sections/docker/use-cache-for-shorter-build-time.md
@@ -0,0 +1,119 @@
+# Leverage caching to reduce build times
+
+## One paragraph explainer
+
+Docker images are a combination of layers, each instruction in your Dockerfile creates a layer. The docker daemon can reuse those layers between builds if the instructions are identical or in the case of a `COPY` or `ADD` files used are identical. ⚠️ If the cache can't be used for a particular layer all the subsequent layers will be invalidated too. That's why order is important. It is crucial to layout your Dockerfile correctly to reduce the number of moving parts in your build; the less updated instructions should be at the top and the ones constantly changing (like app code) should be at the bottom. It's also important to think that instructions that trigger long operation should be close to the top to ensure they happen only when really necessary (unless it changes every time you build your docker image). Rebuilding a whole docker image from cache can be nearly instantaneous if done correctly.
+
+
+
+* Image taken from [Digging into Docker layers](https://medium.com/@jessgreb01/digging-into-docker-layers-c22f948ed612) by jessgreb01*
+
+### Rules
+
+#### Avoid LABEL that change all the time
+
+If you have a label containing the build number at the top of your Dockerfile, the cache will be invalidated at every build
+
+```Dockerfile
+#Beginning of the file
+FROM node:10.22.0-alpine3.11 as builder
+
+# Don't do that here!
+LABEL build_number="483"
+
+#... Rest of the Dockerfile
+```
+
+#### Have a good .dockerignore file
+
+[**See: On the importance of docker ignore**](./docker-ignore.md)
+
+The docker ignore avoids copying files that could bust our cache logic, like tests results reports, logs or temporary files.
+
+#### Install "system" packages first
+
+It is recommended to create a base docker image that has all the system packages you use. If you **really** need to install packages using `apt`,`yum`,`apk` or the likes, this should be one of the first instructions. You don't want to reinstall make,gcc or g++ every time you build your node app.
+**Do not install package only for convenience, this is a production app.**
+
+#### First, only ADD your package.json and your lockfile
+
+```Dockerfile
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+```
+
+The lockfile and the package.json change less often. Copying them first will keep the `npm install` step in the cache, this saves precious time.
+
+### Then copy your files and run build step (if needed)
+
+```Dockerfile
+COPY . .
+RUN npm run build
+```
+
+## Examples
+
+### Basic Example with node_modules needing OS dependencies
+```Dockerfile
+#Create node image version alias
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci --production
+COPY . "./"
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+COPY --from=builder /app/ "./"
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+
+### Example with a build step (when using typescript for example)
+```Dockerfile
+#Create node image version alias
+FROM node:10.22.0-alpine3.11 as builder
+
+RUN apk add --no-cache \
+ build-base \
+ gcc \
+ g++ \
+ make
+
+USER node
+WORKDIR /app
+COPY "package.json" "package-lock.json" "./"
+RUN npm ci
+COPY . .
+RUN npm run build
+
+
+FROM node as app
+
+USER node
+WORKDIR /app
+# Only copying the files that we need
+COPY --from=builder /app/node_modules node_modules
+COPY --from=builder /app/package.json .
+COPY --from=builder /app/dist dist
+RUN npm prune --production
+
+CMD ["node", "dist/server.js"]
+```
+
+## Useful links
+
+Docker docs: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
diff --git a/sections/drafts/readme-general-toc-1.md b/sections/drafts/readme-general-toc-1.md
index 463cedaed..3d13f35a9 100644
--- a/sections/drafts/readme-general-toc-1.md
+++ b/sections/drafts/readme-general-toc-1.md
@@ -1,12 +1,12 @@
-
+
-
+
-
+
-
+
# Welcome to Node.js Best Practices
@@ -31,7 +31,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
**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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -41,7 +41,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -51,7 +51,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
**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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -71,7 +71,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
* **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**](../errorhandling/asyncerrorhandling.md)
diff --git a/sections/drafts/readme-general-toc-2.md b/sections/drafts/readme-general-toc-2.md
index fe3c5af07..586239afe 100644
--- a/sections/drafts/readme-general-toc-2.md
+++ b/sections/drafts/readme-general-toc-2.md
@@ -1,8 +1,8 @@
# Node.js Best Practices
-
+
-
+
# Welcome to Node.js Best Practices
@@ -25,7 +25,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
**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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -35,7 +35,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -45,7 +45,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
**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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
# `Code Style Practices`
@@ -61,7 +61,7 @@ Welcome to the biggest compilation of Node.js best practices. The content below
**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**](../errorhandling/asyncerrorhandling.md)
diff --git a/sections/drafts/readme-general-toc-3.md b/sections/drafts/readme-general-toc-3.md
index 6bb3f9c60..1a11e5745 100644
--- a/sections/drafts/readme-general-toc-3.md
+++ b/sections/drafts/readme-general-toc-3.md
@@ -1,12 +1,12 @@
-
+
-
+
-
+
-
+
# Welcome to Node.js Best Practices
@@ -37,7 +37,7 @@ Welcome to the biggest compilation of Node.js best practices, based on our check
**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
-🔗 [**Read More: Structure by feature*](/sections/errorhandling/asyncawait.md)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -48,7 +48,7 @@ Welcome to the biggest compilation of Node.js best practices, based on our check
**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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -65,7 +65,7 @@ Welcome to the biggest compilation of Node.js best practices, based on our check
**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**](../errorhandling/asyncerrorhandling.md)
diff --git a/sections/drafts/readme-general-toc-4.md b/sections/drafts/readme-general-toc-4.md
index 19f42ea1c..3db7b68a7 100644
--- a/sections/drafts/readme-general-toc-4.md
+++ b/sections/drafts/readme-general-toc-4.md
@@ -1,12 +1,12 @@
-
+
-
+
-
+
-
+
# Welcome to Node.js Best Practices
@@ -23,33 +23,33 @@ Welcome to the biggest compilation of Node.js best practices, based on our check
# `Project Setup Practices`
-##  1. Structure your solution by feature ('microservices')
+##  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.
+**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. Partitioning 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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
-##  2. Layer your app, keep Express within its boundaries
+##  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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
-##  3. Configure ESLint with node-specific plugins
+##  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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
@@ -60,45 +60,45 @@ Welcome to the biggest compilation of Node.js best practices, based on our check
# `Code Style Practices`
-##  1. Use async-await
+##  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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
-##  2. Break into small classes or objects
+##  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)
+🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
-## Use async-await for async error handling
+## 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**](../errorhandling/asyncerrorhandling.md)
-## Use async-await for async error handling
+## 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**](../errorhandling/asyncerrorhandling.md)
diff --git a/sections/errorhandling/apmproducts.basque.md b/sections/errorhandling/apmproducts.basque.md
new file mode 100644
index 000000000..0ea3a2126
--- /dev/null
+++ b/sections/errorhandling/apmproducts.basque.md
@@ -0,0 +1,27 @@
+# Aurkitu erroreak eta jardunik gabeko uneak APM produktuak erabiliz
+
+### Azalpena
+
+Salbuespena != Errorea. Erroreen kudeaketa tradizionalak kodearekin erlazionatutako arazotzat hartzen ditu salbuespenak, baina aplikazioen erroreak formularioko kode bide motelen, APIen jardunik gabeko uneen eta baliabide konputazionalen gabezien ondorio izan daitezke. Horra non APM produktuak oso erabilgarriak diren, "lurperatutako" askotariko gaiak modu proaktiboan detektatzeko aukera ematen baitute gutxieneko konfigurazioarekin. APM produktuen ohiko funtzionalitateen artean daude, adibidez, HTTP APIak erroreak bidaltzen dituenean alerta jotzea, APIaren erantzunaren denbora aurretik zehaztutako denbora muga baino luzeagoa denean antzematea, ‘kode usainak’ hautematea, monitorizazio zerbitzariaren baliabideentzako funtzionalitateak, operazio inteligentziadun panelak (dashboard) IT metrikekin eta beste funtzionalitate batzuk oso erabilgarriak direnak. Hornitzaile gehienek dohaineko plana eskaintzen dute
+
+### Wikipedia APMri buruz
+
+Informazioaren teknologien eta sistemen kudeaketaren alorretan, Application Performance Management (APM) software aplikazioen errendimendu eta erabilgarritasunaren monitorizazio eta kudeaketa da. APM aplikazioen errendimendu arazo konplexuak atzeman eta diagnostikatzen saiatzen da, esperotako zerbitzu maila mantentzeko. APM "IT metrikak negozioaren esanahira ([esaterako] balioa)" itzultzea da. Produktu eta segmentu nagusiak. APM "IT metrikak negozioaren esanahira ([esaterako] balioa)" itzultzea da. Produktu eta segmentu nagusiak
+
+### APM merkatua ulertzen
+
+APM produktuek 3 segmentu nagusi dituzte:
+
+1. Webgune edo APIen monitorizazioa, martxan egondako denbora eta errendimuendua HTTP eskaeren bidez etengabe monitorizatzen dituzten kanpo zerbitzuak. Minutu gutxi batzuetan ezar daiteke. Hurrengo hauek dira aukeratutako lehiakide batzuk: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), eta [New Relic](https://newrelic.com/application-monitoring)
+
+2. Kodearen instrumentazioa, kode motelaren atzematea, salbuespenen estatistikak, errendimenduaren monitorizazioa eta holako beste funtzionalitate batzuk erabiltzeko agente bat aplikazioan txertatzea eskatzen duen produktu familia da. Hurrengo hauek dira aukeratutako lehiakide batzuk: New Relic, App Dynamics
+
+3. Adimen operatiboaren panela produktuen linea bat da, operazio taldeari metrika eta eduki aukeratuak eskaintzen dizkiona eta aplikazioaren errendimendua zein den jakitera behartzen duena. Horrek informazio iturri anitz (aplikazioen erregistroak, DB erregistroak, zerbitzarien erregistroa, etab.) eta aurrez aurreko arbelaren diseinua batzea eskatzen du. Hurrengo hauek dira aukeratutako lehiakide batzuk: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/)
+
+### Adibidea: UpTimeRobot.Com: webguneak monitorizatzeko panela
+
+
+
+### Adibidea: AppDynamics.Com: hasieratik amaierarainoko monitorizazioa kode instrumentazioarekin konbinatutakoa
+
+
diff --git a/sections/errorhandling/apmproducts.brazilian-portuguese.md b/sections/errorhandling/apmproducts.brazilian-portuguese.md
index 886424ded..459e50f10 100644
--- a/sections/errorhandling/apmproducts.brazilian-portuguese.md
+++ b/sections/errorhandling/apmproducts.brazilian-portuguese.md
@@ -22,7 +22,7 @@ Os produtos APM constituem 3 segmentos principais:
### Exemplo: UpTimeRobot.Com - Painel de monitoramento de site
-
+
### Example: AppDynamics.Com – monitoramento de ponta a ponta combinado com instrumentação de código
-
+
diff --git a/sections/errorhandling/apmproducts.chinese.md b/sections/errorhandling/apmproducts.chinese.md
index eed5aecc3..0777b7359 100644
--- a/sections/errorhandling/apmproducts.chinese.md
+++ b/sections/errorhandling/apmproducts.chinese.md
@@ -21,7 +21,7 @@ APM 产品由3个主要部分构成:
### 示例: UpTimeRobot.Com – 网站监控仪表板
-
+
### 示例: AppDynamics.Com – 与代码检测结合的端到端监视
-
+
diff --git a/sections/errorhandling/apmproducts.french.md b/sections/errorhandling/apmproducts.french.md
new file mode 100644
index 000000000..bfe5f5916
--- /dev/null
+++ b/sections/errorhandling/apmproducts.french.md
@@ -0,0 +1,28 @@
+# Découvrez les erreurs et les indisponibilités à l'aide des produits de gestion de la performance applicative
+
+
+### Un paragraphe d'explication
+
+Exception != Erreur. Le traitement traditionnel des erreurs suppose l'existence d'une exception en raison d'un problème lié au code, mais les erreurs d'application peuvent se présenter sous la forme de parcours de code lents, d'indisponibilité de l'API, de manque de ressources de calcul, etc. C’est là que les produits de gestion de la performance applicative (En anglais Application Performance Management : APM) sont utiles car ils permettent de détecter de manière proactive une grande variété de problèmes « cachés » avec une configuration minimale. Parmi les caractéristiques communes des produits APM, on trouve par exemple les alertes lorsque l'API HTTP renvoie des erreurs, la détection lorsque le temps de réponse de l'API tombe en dessous d'un certain seuil, la détection des « [codes smells](https://fr.wikipedia.org/wiki/Code_smell) », les fonctionnalités de surveillance des ressources du serveur, le tableau de bord de l'intelligence opérationnelle avec des mesures informatiques et plusieurs autres fonctionnalités utiles. La plupart des fournisseurs proposent un forfait gratuit.
+
+### APM sur Wikipédia
+
+Dans les domaines des technologies de l'information et de la gestion des systèmes, « Application Performance Management » (APM) est la surveillance et la gestion des performances et de la disponibilité des applications logicielles. APM s'efforce de détecter et de diagnostiquer les problèmes de performances des applications complexes pour maintenir un niveau de service souhaité. APM est « la traduction des métriques informatiques en signification métier (c'est-à-dire en valeur) ».
+
+### Comprendre le marché APM
+
+Les produits APM regroupent 3 pôles principaux :
+
+1. Surveillance de site Web ou d'API - services externes qui surveillent constamment la disponibilité et les performances via des requêtes HTTP. Peut être installé en quelques minutes. Voici quelques candidats sélectionnés : [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/) et [New Relic](https://newrelic.com/application-monitoring).
+
+2. Instrumentation de code - famille de produits qui nécessite d'incorporer un agent dans l'application pour utiliser les fonctionnalités telles que la détection de code lent, les statistiques d'exception, la surveillance des performances et bien d'autres. Voici quelques candidats sélectionnés : New Relic, App Dynamics.
+
+3. Tableau de bord de l'intelligence opérationnelle - cette gamme de produits vise à faciliter la tâche de l'équipe d'exploitation avec des mesures et un contenu organisé qui permettent de rester facilement au fait de la performance des applications. Cela implique généralement l'agrégation de plusieurs sources d'informations (journaux d'application, journaux de base de données, journaux des serveurs, etc.) et le travail de conception du tableau de bord initial. Voici quelques candidats sélectionnés : [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/).
+
+
+
+ ### Exemple : UpTimeRobot.Com - Tableau de bord de surveillance de site Web
+
+
+ ### Exemple : AppDynamics.Com - Surveillance de bout en bout combinée à une instrumentation de code
+
diff --git a/sections/errorhandling/apmproducts.japanese.md b/sections/errorhandling/apmproducts.japanese.md
new file mode 100644
index 000000000..5e8b56f80
--- /dev/null
+++ b/sections/errorhandling/apmproducts.japanese.md
@@ -0,0 +1,28 @@
+# APM 製品を利用してエラーとダウンタイムを発見する
+
+
+### 一段落説明
+
+例外 != エラーです。従来のエラー処理では、コードが関連する問題としての例外の存在を想定していましたが、アプリケーションエラーは処理の遅いコードの実行パス、API のダウンタイム、計算リソースの不足といった形で発生する可能性があります。そこで、最小限の設定で広範囲に渡る「埋もれた」問題をプロアクティブに検出することができるものとして、 APM 製品が役に立ちます。APM 製品の一般的な機能として、例えば HTTP の API がエラーを返した際のアラート、API の応答時間が閾値を下回った瞬間の検出、「コードの臭い」の検出、サーバーリソースをモニタリングする機能、IT メトリクスを確認できる運用管理ダッシュボード、そのほか多くの便利な機能があります。多くのベンダーは無料プランを提供しています。
+
+### Wikipedia「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 – ウェブサイトモニタリングダッシュボード
+
+
+ ### 例: AppDynamics.Com – コード計測が統合されたエンドツーエンドモニタリング
+
diff --git a/sections/errorhandling/apmproducts.korean.md b/sections/errorhandling/apmproducts.korean.md
index 2861667e8..fd4ae438e 100644
--- a/sections/errorhandling/apmproducts.korean.md
+++ b/sections/errorhandling/apmproducts.korean.md
@@ -22,7 +22,7 @@ APM products constitute 3 major segments:
### Example: UpTimeRobot.Com – Website monitoring dashboard
-
+
### Example: AppDynamics.Com – end to end monitoring combined with code instrumentation
-
+
diff --git a/sections/errorhandling/apmproducts.md b/sections/errorhandling/apmproducts.md
index 2861667e8..ae6fc82ec 100644
--- a/sections/errorhandling/apmproducts.md
+++ b/sections/errorhandling/apmproducts.md
@@ -3,7 +3,7 @@
### 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.
+Exception != Error. Traditional error handling assumes the existence of exception as a code related problem 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
@@ -22,7 +22,7 @@ APM products constitute 3 major segments:
### Example: UpTimeRobot.Com – Website monitoring dashboard
-
+
### Example: AppDynamics.Com – end to end monitoring combined with code instrumentation
-
+
diff --git a/sections/errorhandling/apmproducts.polish.md b/sections/errorhandling/apmproducts.polish.md
new file mode 100644
index 000000000..2a10799a8
--- /dev/null
+++ b/sections/errorhandling/apmproducts.polish.md
@@ -0,0 +1,28 @@
+# Odkryj błędy i przestoje przy użyciu produktów APM
+
+
+### Wyjaśnienie jednego akapitu
+
+Wyjątek != Błąd. Tradycyjna obsługa błędów zakłada istnienie wyjątku jako problemu związanego z kodem, ale błędy aplikacji mogą pojawiać się w postaci wolnych ścieżek kodu, przestojów API, braku zasobów obliczeniowych i innych. W tym miejscu przydają się produkty APM, które pozwalają proaktywnie wykrywać wiele „zakopanych” problemów przy minimalnej konfiguracji. Wśród typowych funkcji produktów APM są na przykład alarmowanie, gdy HTTP API zwraca błędy, wykrywanie, gdy czas odpowiedzi API spada poniżej pewnego progu, wykrywanie „code smells”, funkcje monitorowania zasobów serwera, pulpit nawigacyjny wywiadu operacyjnego z miernikami IT i wiele innych przydatnych funkcji. Większość dostawców oferuje bezpłatny plan.
+
+### Wikipedia na temat APM
+
+W dziedzinie technologii informatycznych i zarządzania systemami zarządzanie wydajnością aplikacji (APM) to monitorowanie wydajności i dostępności aplikacji oraz zarządzanie nimi. APM stara się wykrywać i diagnozować złożone problemy z wydajnością aplikacji, aby utrzymać oczekiwany poziom usług. APM to „przełożenie wskaźników IT na znaczenie biznesowe ([tj.] wartość)”. Główne produkty i segmenty.
+
+### Zrozumienie rynku APM
+
+Produkty APM stanowią 3 główne segmenty:
+
+1. Monitorowanie witryny lub interfejsu API - usługi zewnętrzne, które stale monitorują czas działania i wydajność za pośrednictwem żądań HTTP. Można skonfigurować za kilka minut. Oto kilka wybranych pretendentów: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), i [New Relic](https://newrelic.com/application-monitoring)
+
+2. Instrumentacja kodu - rodzina produktów, która wymaga osadzenia agenta w aplikacji w celu korzystania z funkcji takich jak powolne wykrywanie kodu, statystyki wyjątków, monitorowanie wydajności i wiele innych. Oto kilka wybranych pretendentów: New Relic, App Dynamics
+
+3. Operational intelligence dashboard - ta linia produktów koncentruje się na ułatwianiu zespołowi operacyjnemu pomiarów i dobranych treści, które pozwalają łatwo utrzymać najwyższą wydajność aplikacji. Zwykle wymaga to agregacji wielu źródeł informacji (dzienników aplikacji, dzienników BD, dzienników serwerów itp.) I wstępnych prac projektowych na dashboardzie. Oto kilka wybranych kandydatów: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/)
+
+
+
+ ### Przykład: UpTimeRobot.Com – Website monitoring dashboard
+
+
+ ### Przykład: AppDynamics.Com – end to end monitoring combined with code instrumentation
+
diff --git a/sections/errorhandling/apmproducts.russian.md b/sections/errorhandling/apmproducts.russian.md
index 137aec1ab..e4c23d814 100644
--- a/sections/errorhandling/apmproducts.russian.md
+++ b/sections/errorhandling/apmproducts.russian.md
@@ -22,7 +22,7 @@
### Пример: UpTimeRobot.Com - панель мониторинга сайта
-
+
### Пример: AppDynamics.Com – сквозной мониторинг в сочетании с инструментарием кода
-
+
diff --git a/sections/errorhandling/asyncerrorhandling.basque.md b/sections/errorhandling/asyncerrorhandling.basque.md
new file mode 100644
index 000000000..0ae082ac9
--- /dev/null
+++ b/sections/errorhandling/asyncerrorhandling.basque.md
@@ -0,0 +1,118 @@
+# Erabili Async-Await edo errore asinkronoak kudeatzeko promesak
+
+### Azalpena
+
+Callbackak ez dira kudea errazak programatzaile gehienek ez dituzte ondo ezagutzen eta. Callbackek etengabeko errore egiaztatzea eskatzen dute, kode korapilotsua jasanaraziz eta kodigoaren fluxuaren ulergarritasuna zailduz. BlueBird, async, eta Q bezalako promesa liburutegiek kodigo estilo estandarra RETURN eta THROW erabiliz paketatzen dute, programaren fluxua kontrolatzeko. Zehazki, kodigo nagusia funtzio bakoitzean erroreak kudeatzetik askatzea ahalbidetzen duen try-catch errore kudeaketa estilo gogokoena onartzen dute
+
+### Kode adibidea: promesen erabilera erroreak antzemateko
+
+```javascript
+return aFuntzioa()
+ .then(bFuntzioa)
+ .then(cFuntzioa)
+ .then(dFuntzioa)
+ .catch((errorea) => logger.error(errorea))
+ .then(betiExekutatuFuntzioHau);
+```
+
+### Kode adibidea: async/awaiten erabilera erroreak antzemateko
+
+```javascript
+async function exekutatuAtazaAsinkronoBat() {
+ try {
+ const aBalioa = await aFuntzioa();
+ const bBalioa = await bFuntzioa(aBalioa);
+ const cBalioa = await cFuntzioa(bBalioa);
+ return await dFuntzioa(cBalioa);
+ } catch (errorea) {
+ logger.error(errorea);
+ } finally {
+ await betiExekutatuFuntzioHau();
+ }
+}
+```
+
+### Anti ereduaren kode adibidea: callbackaren estiloko errore kudeaketa
+
+
+Javascript
+
+```javascript
+datuakEskuratu(parametrorenBat, function (errorea, emaitza) {
+ if (errorea !== null) {
+ // bueltatutako callback funtzioa deitzea moduko zerbait egin eta errorea pasatu
+ datuGehiagoEskuratu(a, function (errorea, emaitza) {
+ if (errorea !== null) {
+ // bueltatutako callback funtzioa deitzea moduko zerbait egin eta errorea pasatu
+ datuGehiagoEskuratu(b, function (c) {
+ datuGehiagoEskuratu(d, function (e) {
+ if (errorea !== null) {
+ // ulertu duzu ideia?
+ }
+ });
+ });
+ }
+ });
+ }
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+datuakEskuratu(
+ parametrorenBat,
+ function (errorea: Error | null, aEmaitza: ResultA) {
+ if (errorea !== null) {
+ // bueltatutako callback funtzioa deitzea moduko zerbait egin eta errorea pasatu
+ datuGehiagoEskuratu(
+ aEmaitza,
+ function (errorea: Error | null, bEmaitza: ResultB) {
+ if (errorea !== null) {
+ // bueltatutako callback funtzioa deitzea moduko zerbait egin eta errorea pasatu
+ datuGehiagoEskuratu(bEmaitza, function (cEmaitza: ResultC) {
+ datuGehiagoEskuratu(
+ cEmaitza,
+ function (errorea: Error | null, d: ResultD) {
+ if (errorea !== null) {
+ // ulertu duzu ideia?
+ }
+ }
+ );
+ });
+ }
+ }
+ );
+ }
+ }
+);
+```
+
+
+
+### Blog aipua: "Promesekin arazo bat dugu"
+
+pouchdb.com bloga
+
+> ……Izatez, callbackek zerbait oraindik maltzurragoa egiten dute: pilaz gabetzen gaituzte, programazio lengoaietan sarri egintzat jotzen duguna. Kodea pila gabe idaztea kotxe bat freno pedalik gabe gidatzea bezala da: ez zara konturatzen zein puntura arte behar duzun erabiltzen saiatu eta ez dagoela konturatzen zaren momentura arte. Promesen helburu nagusia da asinkronoa (async) erabiltzean galdutako lengoaien oinarri guztiak berreskuratzea: return, throw eta pila. Baina promesak modu egokian erabiltzen jakin beharra dago beraiei probetxua ateratzeko
+
+### Blog aipua: "Promesen metodoa askoz ere trinkoagoa da"
+
+gosquared.com bloga
+
+> ………Promesen metodoa askoz ere trinkoagoa, argiagoa eta idazteko azkarragoa da. Errore edo salbuespen bat gertatzen bada, .catch() kudeatzaile bakar batek maneiatzen du. Errore guztiak kudeatzeko leku bakarra edukitzeak erroreen egiaztatzea lanaren fase bakoitzean idatzi beharrik ez dagoela adierazten du
+
+### Blog aipua: "Promesak jatorrizko ES6 dira, eta sorgailuekin erabil daitezke"
+
+StrongLoop bloga
+
+> ……Callbackek erroreen kudeaketa istorio kaskarra dute. Promesak hobeak dira. Promesekin, erabili Expressen errore kudeaketa kapsulatua eta horrela salbuespenen bat ez antzemateko aukerak murriztuko dituzu. Promesak jatorriz ES6ak dira, eta generatzaileekin eta ES7ren async/await bezalako proposamenekin erabil daitezke Babel bezalako konpilatzaileetan
+
+### Blog aipua: "Ohiko fluxu kontrol erregularren egitura guzti horiek guztiz apurtuta daude"
+
+Benno’s bloga
+
+> ……Asinkronoaren, hau da, callbacketan oinarritutako programazioaren gauza hoberenetako bat da ohituta zauden fluxu kontrol erregularren egitura guzti horiek guztiz apurtuta daudela. Hala ere, salbuespenen kudeaketa da niretzat apurtuen dagoena. Javascriptek nahiko try…catch egitura ezaguna hornitzen du. Salbuespenen arazoa da, erroreak pila batean ekiditeko aukera ona eman arren, errorea beste pila batean gertatzen bada guztiz alferrikakoak izaten bukatzen dutela…
diff --git a/sections/errorhandling/asyncerrorhandling.chinese.md b/sections/errorhandling/asyncerrorhandling.chinese.md
index ef2f12e51..24725eabd 100644
--- a/sections/errorhandling/asyncerrorhandling.chinese.md
+++ b/sections/errorhandling/asyncerrorhandling.chinese.md
@@ -1,25 +1,43 @@
-# 对于异步的错误处理,请使用Async-Await或者promise
-
+# 对于异步的错误处理,请使用 Async-Await 或者 promises
### 一段解释
+由于大多数的程序员不熟悉回调,不能很好的掌控回调函数,导致被迫到处检测错误,处理让人不快的代码嵌套和难以理解的代码流程。Promise 的库,比如 BlueBird,async,和 Q 封装了一些代码,使用者可以使用 RETURN 和 THROW 的方式来控制程序的流程。具体来说,就是它们支持最受欢迎的 try-catch 错误处理风格,这使得主流程代码从在每一个方法中处理错误的方式中解放出来。
-由于回调对于大多数的程序员来说不熟悉,被迫随处检测错误,让人不快的代码内嵌和难以理解的代码流程,它没有形成一定规模。promise的库,比如BlueBird,async,和Q封装了一种标准的代码风格, 它通过使用return和throw来控制程序流程。具体来说,它们支持最受欢迎的try-catch错误处理风格,这使得主流程代码从在每一个方法中处理错误的方式中解放出来。
-
+### 代码示例 – 使用 promises 捕获错误
-### 代码示例 – 使用promise捕获错误
+```javascript
+doWork()
+ .then(doWork)
+ .then(doOtherWork)
+ .then((result) => doWork)
+ .catch((error) => {
+ throw error;
+ })
+ .then(verify);
+```
+### 代码示例 - 使用 async/await 捕获错误
```javascript
-doWork()
- .then(doWork)
- .then(doOtherWork)
- .then((result) => doWork)
- .catch((error) => {throw error;})
- .then(verify);
+async function executeAsyncTask() {
+ try {
+ const valueA = await functionA();
+ const valueB = await functionB(valueA);
+ const valueC = await functionC(valueB);
+ return await functionD(valueC);
+ } catch (err) {
+ logger.error(err);
+ } finally {
+ await alwaysExecuteThisFunction();
+ }
+}
```
### 代码示例 反模式 – 回调方式的错误处理
+
+Javascript
+
```javascript
getData(someParameter, function(err, result){
if(err != null)
@@ -27,30 +45,61 @@ getData(someParameter, function(err, result){
getMoreData(a, function(err, result){
if(err != null)
//做一些事情类似于调用给定的回调函数并传递错误
- getMoreData(b, function(c){
- getMoreData(d, function(e){
+ getMoreData(b, function(c){
+ getMoreData(d, function(e){
if(err != null)
- //你有什么想法?
+ //你有什么想法?
+ });
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+getData(someParameter, function (err: Error | null, resultA: ResultA) {
+ if (err !== null) {
+ //做一些事情类似于调用给定的回调函数并传递错误
+ getMoreData(resultA, function (err: Error | null, resultB: ResultB) {
+ if (err !== null) {
+ //做一些事情类似于调用给定的回调函数并传递错误
+ getMoreData(resultB, function (resultC: ResultC) {
+ getMoreData(resultC, function (err: Error | null, d: ResultD) {
+ if (err !== null) {
+ // 你有什么想法?
+ }
+ });
+ });
+ }
});
+ }
});
```
-### 博客引用: "我们使用promise有一个问题"
- 摘自博客pouchdb.com
-
- > ……实际上, 回调会做一些更险恶的事情: 他们剥夺了我们的stack, 这是我们通常在编程语言中想当然的事情。编写没有堆栈的代码很像驾驶一辆没有刹车踏板的汽车: 你没有意识到你有多么需要它, 直到你伸手去找它, 而它不在那里。promise的全部目的是让我们回到我们在异步时丢失的语言基础: return,throw和stack。但你必须知道如何正确使用promise, 以便利用他们。
+
+
+### 博客引用: "我们使用 promise 有一个问题"
+
+摘自博客 pouchdb.com
+
+> ……实际上, 回调会做一些更险恶的事情: 他们剥夺了我们的 stack, 这是我们通常在编程语言中想当然的事情。编写没有堆栈的代码很像驾驶一辆没有刹车踏板的汽车: 你没有意识到你有多么需要它, 直到你伸手去找它, 而它不在那里。promise 的全部目的是让我们回到我们在异步时丢失的语言基础: return,throw 和 stack。但你必须知道如何正确使用 promise, 以便利用他们。
+
+### 博客引用: "promise 方法更加紧凑"
-### 博客引用: "promise方法更加紧凑"
- 摘自博客gosquared.com
-
- > ………promise的方法更紧凑, 更清晰, 写起来更快速。如果在任何ops中发生错误或异常,则由单个.catch()处理程序处理。有这个单一的地方来处理所有的错误意味着你不需要为每个阶段的工作写错误检查。
+摘自博客 gosquared.com
-### 博客引用: "原生ES6支持promise,可以和generator一起使用"
- 摘自博客StrongLoop
-
- > ….回调有一个糟糕的错误处理的报道。promise更好。将express内置的错误处理与promise结合起来, 大大降低了uncaught exception的几率。原生ES6支持promise, 通过编译器babel,它可以与generator,ES7提议的技术(比如async/await)一起使用。
+> ………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错误的很好的方法, 但最终由于不同堆栈上发生的错误导致完全无用…
+
+摘自博客 Benno’s
+
+> ……关于基于异步、回调编程的最好的事情之一是, 基本上所有那些您习惯的常规流量控制结构, 完全被打破。然而, 我发现最易打破的是处理异常。Javascript 提供了一个相当熟悉的 try...catch 结构来处理异常。异常的问题是, 它们提供了在一个调用堆栈上 short-cutting 错误的很好的方法, 但最终由于不同堆栈上发生的错误导致完全无用…
diff --git a/sections/errorhandling/asyncerrorhandling.french.md b/sections/errorhandling/asyncerrorhandling.french.md
new file mode 100644
index 000000000..29ebd9d0b
--- /dev/null
+++ b/sections/errorhandling/asyncerrorhandling.french.md
@@ -0,0 +1,109 @@
+# Utilisez Async-Await ou les promesses pour le traitement des erreurs asynchrones
+
+### Un paragraphe d'explication
+
+Les fonctions de rappels n'évoluent pas bien car la plupart des programmeurs ne les connaissent pas bien. Elles obligent à vérifier les erreurs partout, à gérer l'imbrication de code désagréable et à rendre difficile le raisonnement sur le flux du code. Les bibliothèques de promesse comme BlueBird, async et Q contiennent un style de code standard en utilisant RETURN et THROW pour contrôler le flux du programme. Plus précisément, elles prennent en charge le style de gestion des erreurs de try-catch qui permet de libérer le chemin du code principal de la gestion des erreurs dans chaque fonction.
+
+### Exemple de code - utiliser des promesses pour détecter les erreurs
+
+```javascript
+return fonctionA()
+ .then(fonctionB)
+ .then(fonctionC)
+ .then(fonctionD)
+ .catch((err) => logger.error(err))
+ .then(toujoursExecuterCetteFonction)
+```
+
+
+### Exemple de code - utiliser async/await pour détecter les erreurs
+
+```javascript
+async function executeAsyncTask () {
+ try {
+ const valueA = await fonctionA();
+ const valueB = await fonctionB(valueA);
+ const valueC = await fonctionC(valueB);
+ return await fonctionD(valueC);
+ }
+ catch (err) {
+ logger.error(err);
+ } finally {
+ await toujoursExecuterCetteFonction();
+ }
+}
+```
+
+### Contre exemple de code - gestion des erreurs avec des fonctions de rappel
+
+
+Javascript
+
+```javascript
+getData(someParameter, function(err, result) {
+ if(err !== null) {
+ // faire quelque chose comme appeler la fonction de rappel donnée et passer l'erreur
+ getMoreData(a, function(err, result) {
+ if(err !== null) {
+ // faire quelque chose comme appeler la fonction de rappel donnée et passer l'erreur
+ getMoreData(b, function(c) {
+ getMoreData(d, function(e) {
+ if(err !== null ) {
+ // vous avez une idée ?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
+
+
+Typescript
+
+```typescript
+getData(someParameter, function(err: Error | null, resultA: ResultA) {
+ if(err !== null) {
+ // faire quelque chose comme appeler la fonction de rappel donnée et passer l'erreur
+ getMoreData(resultA, function(err: Error | null, resultB: ResultB) {
+ if(err !== null) {
+ // faire quelque chose comme appeler la fonction de rappel donnée et passer l'erreur
+ getMoreData(resultB, function(resultC: ResultC) {
+ getMoreData(resultC, function(err: Error | null, d: ResultD) {
+ if(err !== null) {
+ // vous avez une idée ?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
+
+### Citation de blog : « Nous avons un problème avec les promesses »
+
+ Extrait du blog de pouchdb.com
+
+ > …. Et en fait, les fonctions de rappel font quelque chose d'encore plus sinistre : elles nous privent de la pile, ce que nous tenons généralement pour acquis en langage de programmation. Écrire du code sans pile, c'est un peu comme conduire une voiture sans pédale de frein : vous ne réalisez pas à quel point vous en avez besoin tant que vous ne l'avez pas atteint et qu'il n'est pas là. Le but des promesses est de nous rendre les bases linguistiques que nous avons perdues quand nous sommes devenus asynchrones : return, throw et la pile. Mais il faut savoir utiliser correctement les promesses pour en profiter.
+
+### Citation de blog : « La méthode des promesses est beaucoup plus compacte »
+
+ Extrait du blog de gosquared.com
+
+ > …. La méthode des promesses est beaucoup plus compacte, plus claire et plus rapide à écrire. Si une erreur ou une exception se produit dans l'une des opérations, elle est gérée par l'unique gestionnaire .catch (). Avoir cet emplacement unique pour gérer toutes les erreurs signifie que vous n'avez pas besoin d'écrire la vérification des erreurs pour chaque étape du travail.
+
+### Citation de blog : « Les promesses sont natives en ES6, elles peuvent être utilisées avec des générateurs »
+
+ Extrait du blog de StrongLoop
+
+> …. Les fonctions de rappel ont un mauvais historique de gestion des erreurs. Les promesses sont meilleures. Marier la gestion des erreurs intégrée dans Express avec des promesses permet de réduire considérablement les chances d'une exception non capturée. Les promesses sont natives en ES6, elles peuvent être utilisées avec des générateurs et des propositions ES7 comme async/await via des compilateurs comme Babel.
+
+### Citation de blog : « Toutes ces constructions de contrôle de flux auxquelles vous êtes habitué sont complètement cassées »
+
+Extrait du blog de Benno’s
+
+ > …L'un des meilleurs atouts de l'asynchrone, pour la programmation basée sur des fonctions de rappel, c'est que fondamentalement toutes ces constructions de contrôle de flux auxquelles vous êtes habitué sont complètement cassées. Cependant, celle que je trouve la plus cassée, c'est la gestion des exceptions. Javascript fournit une construction try…catch assez familière pour gérer les exceptions. Le problème avec les exceptions, c'est qu'elles fournissent un excellent moyen de court-circuiter les erreurs dans une pile d'appels, mais finissent par être complètement inutiles si l'erreur se produit sur une autre pile…
diff --git a/sections/errorhandling/asyncerrorhandling.japanese.md b/sections/errorhandling/asyncerrorhandling.japanese.md
new file mode 100644
index 000000000..1966b8cc6
--- /dev/null
+++ b/sections/errorhandling/asyncerrorhandling.japanese.md
@@ -0,0 +1,109 @@
+# 非同期エラーハンドリングに Async-Await または promises を使う
+
+### 一段落説明
+
+コールバックはあまりスケールしません。なぜなら、ほとんどのプログラマーはコールバックに馴染みがないからです。コールバックによって、エラーをくまなくチェックすることが強制され、厄介なコードの入れ子構造を扱うことになり、またコードのフローを推測することが困難になります。BlueBird や async、そして Q といった promise ライブラリは、RETURN や THROW を使ってプログラムのフローを制御している標準コードを包み込みます。特にそれらのライブラリは、みなの大好きな try-catch エラーハンドリングスタイルをサポートしており、それぞれの関数においてメインコードをエラー処理と分けて扱うことを可能にしています。
+
+### コード例 – エラーの捕捉に promises を使う
+
+```javascript
+return functionA()
+ .then(functionB)
+ .then(functionC)
+ .then(functionD)
+ .catch((err) => logger.error(err))
+ .then(alwaysExecuteThisFunction)
+```
+
+
+### コード例 - エラーの捕捉に async/await を使う
+
+```javascript
+async function executeAsyncTask () {
+ try {
+ const valueA = await functionA();
+ const valueB = await functionB(valueA);
+ const valueC = await functionC(valueB);
+ return await functionD(valueC);
+ }
+ catch (err) {
+ logger.error(err);
+ } finally {
+ await alwaysExecuteThisFunction();
+ }
+}
+```
+
+### アンチパターン – コールバックスタイルのエラーハンドリング
+
+
+Javascript
+
+```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 ) {
+ // もうおわかりですよね?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
+
+
+Typescript
+
+```typescript
+getData(someParameter, function(err: Error | null, resultA: ResultA) {
+ if(err !== null) {
+ // 渡されたコールバック関数を呼び出してエラーを渡す、といったことをします
+ getMoreData(resultA, function(err: Error | null, resultB: ResultB) {
+ if(err !== null) {
+ // 渡されたコールバック関数を呼び出してエラーを渡す、といったことをします
+ getMoreData(resultB, function(resultC: ResultC) {
+ getMoreData(resultC, function(err: Error | null, d: ResultD) {
+ if(err !== null) {
+ // もうおわかりですよね?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
+
+### ブログ引用: "We have a problem with promises" (promises には問題がある)
+
+ブログ pouchdb.com より
+
+ > ……そして実際、コールバックはさらに厄介なことをします: 私たちがプログラミング言語において存在して当たり前だと思っているスタックを奪うのです。スタックの無いプログラミングは、まるでブレーキの無い車を運転するようなものです: それがどれくらいあなたにとって必要なものなのか、無くなってみないとわからないでしょう。promises の大事なポイントは、私たちが非同期に足を踏み入れたときに失った言語の基本要素、return、throw、そしてスタックを私たちの元へ返してくれることです。ただし、それらの恩恵を受けるためにも、promises を正しく使う方法を知っておかなければなりません。
+
+### ブログ引用: "The promises method is much more compact" (promises メソッドはよりコンパクトだ)
+
+ブログ gosquared.com より
+
+ > ………その promises メソッドはよりいっそうコンパクトで、明快で、素早く書けます。いかなるオペレーションの中でエラーや例外が起こったとしても、一つの .catch() ハンドラで扱うことができます。すべてのエラーを処理するために単一の場所を持つことは、各処理の段階でいちいちエラーチェックを行うコードを書く必要がないことを意味します。
+
+### ブログ引用: "Promises are native ES6, can be used with generators" (promises はネイティブ ES6 であり、ジェネレーターと一緒に利用できる)
+
+ブログ StrongLoop より
+
+ > ….コールバックはお粗末なエラーハンドリングの層を持っています。プロミスの方が優れています。promises を用いた Express のビルトインエラーハンドリングと結びつき、捕捉されない例外の可能性を大きく下げて下さい。Promises はネイティブ ES6であり generators とともに活用でき、そしてバベルのようなコンパイラを通して async/await のような ES7 での提案となっています。
+
+### ブログ引用: "All those regular flow control constructs you are used to are completely broken" (あなたが慣れ親しんでいる全ての通常のフロー制御構造は、完全に崩壊しています)
+
+ブログ Benno’s より
+
+ > ……非同期なコールバックベースのプログラミングについていえる最高のことのひとつは、基本的にあなたが慣れ親しんでいる全ての通常のフロー制御構造は、完全に崩壊しているということです。しかし、私が最も崩壊していると思った点は、例外の処理です。例外に対処するために、JavaScript はかなり一般的になった try...catch 構造を提供しています。例外の問題は、それらはコールスタック上でエラーをショートカットする素晴らしい方法を提供する一方で、異なるスタックでエラーが起こったときに全く役に立たずに終わるということです...
diff --git a/sections/errorhandling/asyncerrorhandling.polish.md b/sections/errorhandling/asyncerrorhandling.polish.md
new file mode 100644
index 000000000..3f51d13ef
--- /dev/null
+++ b/sections/errorhandling/asyncerrorhandling.polish.md
@@ -0,0 +1,109 @@
+# Użyj Async-Await lub promises do obsługi błędów asynchronicznych
+
+### Wyjaśnienie jednym akapitem
+
+Callbacks nie skalują się dobrze, ponieważ większość programistów nie zna ich. Zmuszają do sprawdzania błędów, radzenia sobie z nieprzyjemnym zagnieżdżaniem kodu i utrudniają rozumowanie przepływu kodu. Biblioteki promises takie jak BlueBird, async i Q pakują standardowy styl kodu za pomocą RETURN i THROW do sterowania przebiegiem programu. W szczególności obsługują ulubiony styl obsługi błędów try-catch, który pozwala uwolnić główną ścieżkę kodu od radzenia sobie z błędami w każdej funkcji
+
+### Przykład kodu - używanie promises do wychwytywania błędów
+
+```javascript
+return functionA()
+ .then(functionB)
+ .then(functionC)
+ .then(functionD)
+ .catch((err) => logger.error(err))
+ .then(alwaysExecuteThisFunction)
+```
+
+
+### Przykład kodu - używanie async/await do wychwytywania błędów
+
+```javascript
+async function executeAsyncTask () {
+ try {
+ const valueA = await functionA();
+ const valueB = await functionB(valueA);
+ const valueC = await functionC(valueB);
+ return await functionD(valueC);
+ }
+ catch (err) {
+ logger.error(err);
+ } finally {
+ await alwaysExecuteThisFunction();
+ }
+}
+```
+
+### Przykład kodu antywzorca - obsługa błędów stylu wywołania zwrotnego
+
+
+Javascript
+
+```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?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
+
+
+Typescript
+
+```typescript
+getData(someParameter, function(err: Error | null, resultA: ResultA) {
+ if(err !== null) {
+ // do something like calling the given callback function and pass the error
+ getMoreData(resultA, function(err: Error | null, resultB: ResultB) {
+ if(err !== null) {
+ // do something like calling the given callback function and pass the error
+ getMoreData(resultB, function(resultC: ResultC) {
+ getMoreData(resultC, function(err: Error | null, d: ResultD) {
+ if(err !== null) {
+ // you get the idea?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
+
+### Cytat z Bloga: "Mamy problem z promises"
+
+ Z bloga 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.
+
+### Cytat z Bloga: "The promises method is much more compact"
+
+ Z bloga 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.
+
+### Cytat z Bloga: "Promises are native ES6, can be used with generators"
+
+ Z bloga 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
+
+### Cytat z Bloga: "All those regular flow control constructs you are used to are completely broken"
+
+Z bloga Benno’a
+
+ > ……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 if the error happens on a different stack…
diff --git a/sections/errorhandling/asyncerrorhandling.russian.md b/sections/errorhandling/asyncerrorhandling.russian.md
index 907cd70c8..5cf3ad2c4 100644
--- a/sections/errorhandling/asyncerrorhandling.russian.md
+++ b/sections/errorhandling/asyncerrorhandling.russian.md
@@ -2,17 +2,17 @@
### Объяснение в один абзац
-Обратные вызовы плохо масштабируются, так как большинство программистов не знакомы с ними. Они заставляют проверять ошибки повсюду, имеют дело с неприятным вложением кода и затрудняют анализ потока кода. Библиотеки Promise, такие как BlueBird, async и Q, упаковывают стандартный стиль кода, используя RETURN и THROW для управления потоком программы. В частности, они поддерживают любимый стиль обработки ошибок try-catch, который позволяет освободить путь к основному коду от ошибок в каждой функции
+Обратные вызовы плохо масштабируются, так как большинство программистов не знакомы с ними. Они заставляют проверять ошибки повсюду, иметь дело с неприятной вложенностью кода и затрудняют анализ потока кода. Библиотеки обещаний (promise), такие как BlueBird, async и Q, упаковывают стандартный стиль кода, используя RETURN и THROW для управления потоком программы. В частности, они поддерживают наилучший стиль обработки ошибок try-catch, который позволяет освободить основной код от обработки ошибок в каждой функции.
### Пример кода – использование обещаний для отлова ошибок
```javascript
return functionA()
- .then((valueA) => functionB(valueA))
- .then((valueB) => functionC(valueB))
- .then((valueC) => functionD(valueC))
+ .then(functionB)
+ .then(functionC)
+ .then(functionD)
.catch((err) => logger.error(err))
- .then(alwaysExecuteThisFunction())
+ .then(alwaysExecuteThisFunction)
```
### Пример кода - использование async/await для отлова ошибок
@@ -25,7 +25,7 @@ async function executeAsyncTask () {
const valueC = await functionC(valueB);
return await functionD(valueC);
}
- catch(err) {
+ catch (err) {
logger.error(err);
} finally {
await alwaysExecuteThisFunction();
@@ -33,19 +33,22 @@ async function executeAsyncTask () {
}
```
-### Пример кода шаблона - обработка ошибок в стиле обратного вызова
+### Антипаттерн. Обработка ошибок в callback-стиле
+
+
+Javascript
```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?
+ // вы поняли идею?
}
})
});
@@ -54,6 +57,31 @@ getData(someParameter, function(err, result) {
}
});
```
+
+
+
+Typescript
+
+```typescript
+getData(someParameter, function(err: Error | null, resultA: ResultA) {
+ if(err !== null) {
+ // вызываем коллбек функцию и передаем ошибку
+ getMoreData(resultA, function(err: Error | null, resultB: ResultB) {
+ if(err !== null) {
+ // вызываем коллбек функцию и передаем ошибку
+ getMoreData(resultB, function(resultC: ResultC) {
+ getMoreData(resultC, function(err: Error | null, d: ResultD) {
+ if(err !== null) {
+ // вы поняли идею?
+ }
+ })
+ });
+ }
+ });
+ }
+});
+```
+
### Цитата из блога: "У нас проблема с обещаниями"
@@ -61,20 +89,20 @@ getData(someParameter, function(err, result) {
> … На самом деле, обратные вызовы делают что-то еще более зловещее: они лишают нас стека, что мы обычно принимаем как должное в языках программирования. Написание кода без стека очень похоже на вождение автомобиля без педали тормоза: вы не понимаете, насколько сильно оно вам нужно, пока не дойдете до него, а его там нет. Весь смысл обещаний состоит в том, чтобы вернуть нам языковые основы, которые мы потеряли при асинхронности: возврат, выброс и стек. Но вы должны знать, как правильно использовать обещания, чтобы воспользоваться ими.
-### Цитата блога: "Метод обещаний гораздо более компактен"
+### Цитата блога: "Подход с обещаниями гораздо более компактен"
Из блога gosquared.com
-> … Метод обещаний гораздо компактнее, понятнее и быстрее для написания. Если ошибка или исключение происходят в любом из операций, они обрабатываются одним обработчиком .catch(). Наличие единого места для обработки всех ошибок означает, что вам не нужно писать проверку ошибок для каждого этапа работы.
+> … Подход с обещаниями гораздо компактнее, понятнее и быстрее для написания. Если ошибка или исключение происходят в любой из операций, они обрабатываются одним обработчиком .catch(). Наличие единого места для обработки всех ошибок означает, что вам не нужно писать проверку ошибок для каждого этапа работы.
-### Цитата блога: "Обещания являются родными ES6, могут использоваться с генераторами"
+### Цитата блога: "Обещания являются нативными в ES6, могут использоваться с генераторами"
Из блога StrongLoop
-> … Обратные вызовы имеют паршивую историю обработки ошибок. Обещания лучше. Объедините встроенную обработку ошибок в Express с обещаниями и значительно снизьте вероятность возникновения необработанного исключения. Обещания являются родными ES6, могут использоваться с генераторами, а предложения ES7, такие как async/await, через компиляторы, такие как Babel.
+> … Обратные вызовы имеют паршивую историю обработки ошибок. Обещания лучше. Объедините встроенную обработку ошибок в Express с обещаниями и значительно снизьте вероятность возникновения необработанного исключения. Обещания являются нативными в ES6, могут использоваться с генераторами, а proposals из ES7, такие как async/await, могут использоваться через компиляторы, такие как Babel.
### Цитата из блога: "Все те обычные конструкции управления потоком, к которым вы привыкли, полностью разрушены"
Из блога Бенно
-> … Одно из лучших преимуществ асинхронного программирования на основе обратного вызова состоит в том, что в основном все эти обычные конструкции управления потоком, к которым вы привыкли, полностью разрушены. Тем не менее, я считаю, что больше всего разрушения коснулись обработки исключений. Javascript предоставляет довольно знакомую конструкцию try…catch для работы с исключениями. Проблема с исключениями состоит в том, что они обеспечивают отличный способ сокращения ошибок в стеке вызовов, но в конечном итоге оказываются совершенно бесполезными, если ошибка происходит в другом стеке…
+> … Одно из лучших преимуществ асинхронного программирования на основе обратного вызова состоит в том, что в основном все эти обычные конструкции управления потоком, к которым вы привыкли, полностью разрушены. Тем не менее, я считаю, что больше всего разрушения коснулась обработка исключений. Javascript предоставляет довольно знакомую конструкцию try…catch для работы с исключениями. Проблема с исключениями состоит в том, что они обеспечивают отличный способ сокращения ошибок в стеке вызовов, но в конечном итоге оказываются совершенно бесполезными, если ошибка происходит в другом стеке…
\ No newline at end of file
diff --git a/sections/errorhandling/catchunhandledpromiserejection.basque.md b/sections/errorhandling/catchunhandledpromiserejection.basque.md
new file mode 100644
index 000000000..727ed1b99
--- /dev/null
+++ b/sections/errorhandling/catchunhandledpromiserejection.basque.md
@@ -0,0 +1,88 @@
+# Atzeman kudeatu gabeko agintzen arbuioak
+
+
+
+### Azalpena
+
+Normalean, Node.js/Express aplikazio kode moderno gehienek promesen barruan funtzionatzen dute, .then kudeatzailearen, callback funtzio baten edota catch bloke baten barruan. Harrigarria bada ere, garatzaile batek .catch klausula bat gehitu zuela gogoratu ezean, leku hauetan jaurtitako erroreak ez dira uncaughtException ebentu kudeatzaileaz kudeatuak izaten, eta desagertu egiten dira. Noderen bertsio berrienek ohartarazpen mezu bat gehitu dute tratatu gabeko errefusa agertzen denean; egia da horrek, gauzak ondo ez doazenean, ohartzen lagun dezakeela, baina argi dago ez dela erroreak kudeatzeko modu egokia. Konponbide samurrena da ez ahaztea promesa kateko dei bakoitzaren barruan .catch klausula erabiltzen eta errore kudeatzaile zentralizatu batera desbideratzea. Hala ere, hauskorra da erroreak kudeatzeko estrategia garatzailearen diziplinan soilik oinarritzea. Ondorioz, oso gomendagarria da atzera egite dotorea erabiltzea eta `process.on('unhandledRejection', callback)`-ra harpidetzea, horrek ziurtatuko baitu promesa erroreek, bere tratamendua izango dutela, lokalki kudeatzen ez badira
+
+
+
+### Kode adibidea: errore hauek ez ditu inolako errore kudeatzailek atzemango (unhandledRejection-ek izan ezik)
+
+```javascript
+DAL.berreskuratuErabiltzaileaIdBidez(1).then((johnSnow) => {
+ // errore hau desagertu egingo da
+ if (johnSnow.bizirikDago === false) throw new Error("ahhhh");
+});
+```
+
+
+
+### Kode adibidea: kudeatu gabeko eta baztertutako promesak atzematen
+
+
+Javascript
+
+```javascript
+process.on("unhandledRejection", (arrazoia, p) => {
+ // Kudeatu gabeko baztertutako promesa bat harrapatu dut,
+ // iada kudeatu gabeko erroreentzat atzera-egite kudeatzailea dugunez (begiratu beherago),
+ // utzi jaurtitzen eta utzi berari hori kudeatzen
+ throw arrazoia;
+});
+
+process.on("uncaughtException", (errorea) => {
+ // Aurretik inoiz kudeatu gabeko errorea jaso berri dut, hau kudeatzeko eta berrekite bat beharrezkoa den erabakitzeko garaia da
+ erroreKudeaketa.kudeatzailea.erroreaKudeatu(errorea);
+ if (!erroreKudeaketa.kudeatzailea.erroreFidagarriaDa(errorea))
+ process.exit(1);
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+process.on("unhandledRejection", (arrazioa: string, p: Promise) => {
+ // Kudeatu gabeko baztertutako promesa bat harrapatu dut,
+ // iada kudeatu gabeko erroreentzat atzera-egite kudeatzailea dugunez (begiratu beherago),
+ // utzi jaurtitzen eta utzi berari hori kudeatzen
+ throw arrazoia;
+});
+
+process.on("uncaughtException", (errorea: Error) => {
+ // Aurretik inoiz kudeatu gabeko errorea jaso berri dut, hau kudeatzeko eta berrekite bat beharrezkoa den erabakitzeko garaia da
+ erroreKudeaketa.kudeatzailea.erroreaKudeatu(errorea);
+ if (!erroreKudeaketa.kudeatzailea.erroreFidagarriaDa(errorea))
+ process.exit(1);
+});
+```
+
+
+
+
+
+### Blog aipua: "Erroreren bat egiteko gai bazara, momenturen batean egin egingo duzu"
+
+James Nelson bloga
+
+> Proba dezagun zure ulermena. Hauetako zeinek uste duzu erakutsiko duela errore bat kontsolan?
+
+```javascript
+Promise.resolve("agindutako balioa").then(() => {
+ throw new Error("errorea");
+});
+
+Promise.reject("errore balioa").catch(() => {
+ throw new Error("errorea");
+});
+
+new Promise((resolve, reject) => {
+ throw new Error("errorea");
+});
+```
+
+> Ez dakit zer pentsatzen duzun, baina nire erantzuna da guztietan bistaratuko dela erroreren bat, eta errealitatea da JavaScript ingurune moderno gehienek kasu hauetako batentzat ere ez dituztela erroreak bistaratuko. Gizakien arazoa da, erroreen bat egiteko gai bazara, momenturen batean egingo duzula. Hori argi edukita, begibistakoa dirudi gauzak diseinatu behar direla erroreen erruz ahalik eta gutxien hondatzeko, eta horrek erroreak beti kudeatu beharra dagoela esan nahi du, alde batera utzi beharrean.
diff --git a/sections/errorhandling/catchunhandledpromiserejection.french.md b/sections/errorhandling/catchunhandledpromiserejection.french.md
new file mode 100644
index 000000000..583cf3093
--- /dev/null
+++ b/sections/errorhandling/catchunhandledpromiserejection.french.md
@@ -0,0 +1,87 @@
+# Capturez les rejets de promesses non gérés
+
+
+
+### Un paragraphe d'explication
+
+En règle générale, la plupart du code d'application Node.js/Express moderne s'exécute dans le cadre de promesse - que ce soit dans le gestionnaire .then, un rappel de fonction ou dans un bloc catch. Étonnamment, à moins qu'un développeur n'ait pensé à ajouter une clause .catch, les erreurs lancées à ces endroits ne sont pas traitées par le gestionnaire d'événement uncaughtException et disparaissent. Les versions récentes de Node ont ajouté un message d'avertissement lorsqu'un rejet non géré apparaît, bien que cela puisse aider à remarquer quand les choses tournent mal, mais ce n'est évidemment pas une bonne méthode de gestion des erreurs. La solution simple consiste à ne jamais oublier d'ajouter des clauses .catch dans chaque appel de chaîne de promesse et de rediriger vers un gestionnaire d'erreurs centralisé. Cependant, la construction de votre stratégie de gestion des erreurs uniquement sur la discipline du développeur est quelque peu fragile. Par conséquent, il est fortement recommandé d'utiliser une solution de secours élégante et de vous abonner à `process.on('unhandledRejection', callback)` - cela garantira que toute erreur de promesse, si elle n'est pas traitée localement, sera traitée.
+
+
+
+### Exemple de code : ces erreurs ne seront détectées par aucun gestionnaire d'erreurs (sauf unhandledRejection)
+
+```javascript
+DAL.getUserById(1).then((johnSnow) => {
+ // cette erreur disparaîtra
+ if(johnSnow.isAlive === false)
+ throw new Error('ahhhh');
+});
+```
+
+
+
+### Exemple de code : capturer des promesses non résolues et rejetées
+
+
+Javascript
+
+```javascript
+process.on('unhandledRejection', (reason, p) => {
+ // Je viens d'attraper un rejet de promesse non géré,
+ // puisque nous avons déjà un gestionnaire de secours pour les erreurs non gérées (voir ci-dessous),
+ // laissons throw et laissons-le gérer cela
+ throw reason;
+});
+
+process.on('uncaughtException', (error) => {
+ // Je viens de recevoir une erreur qui n'a jamais été traitée, il est temps de la gérer et de décider ensuite si un redémarrage est nécessaire
+ errorManagement.handler.handleError(error);
+ if (!errorManagement.handler.isTrustedError(error))
+ process.exit(1);
+});
+```
+
+
+
+Typescript
+
+```typescript
+process.on('unhandledRejection', (reason: string, p: Promise) => {
+// Je viens d'attraper un rejet de promesse non géré,
+ // puisque nous avons déjà un gestionnaire de secours pour les erreurs non gérées (voir ci-dessous),
+ // laissons throw et laissons-le gérer cela
+ throw reason;
+});
+
+process.on('uncaughtException', (error: Error) => {
+ // Je viens de recevoir une erreur qui n'a jamais été traitée, il est temps de la gérer et de décider ensuite si un redémarrage est nécessaire
+ errorManagement.handler.handleError(error);
+ if (!errorManagement.handler.isTrustedError(error))
+ process.exit(1);
+});
+```
+
+
+
+
+### Citation de blog : « Si vous pouvez faire une erreur, vous la ferez à un moment donné »
+
+Extrait du blog de James Nelson
+
+ > Testons votre compréhension. Lequel des éléments suivants devrez afficher une erreur sur la 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');
+});
+```
+
+> Je ne sais pas pour vous, mais ma réponse est que je m'attends à ce que tous affichent une erreur. Cependant, la réalité est qu'un certain nombre d'environnements JavaScript modernes n'imprimeront d'erreurs pour aucun d'entre eux. Le problème avec l'être humain est que si vous pouvez faire une erreur, vous la ferez à un moment donné. En gardant cela à l'esprit, il semble évident que nous devons concevoir les choses de manière à ce que les erreurs fassent le moins de mal possible, ce qui signifie gérer les erreurs par défaut, et non les éliminer.
diff --git a/sections/errorhandling/catchunhandledpromiserejection.japanese.md b/sections/errorhandling/catchunhandledpromiserejection.japanese.md
new file mode 100644
index 000000000..eca8e8b66
--- /dev/null
+++ b/sections/errorhandling/catchunhandledpromiserejection.japanese.md
@@ -0,0 +1,87 @@
+# 未処理の reject された promise を捕捉する
+
+
+
+### ブログ引用: "If you can make a mistake, at some point you will"(ミスをすることができるなら、いつかするでしょう)
+
+ブログ 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.polish.md b/sections/errorhandling/catchunhandledpromiserejection.polish.md
new file mode 100644
index 000000000..4d5330016
--- /dev/null
+++ b/sections/errorhandling/catchunhandledpromiserejection.polish.md
@@ -0,0 +1,87 @@
+# Złap nieobsłużone odrzucenia promises
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Zazwyczaj większość współczesnego kodu aplikacji Node.js / Express działa w ramach obietnic - czy to w .then handler, wywołaniu zwrotnym funkcji, czy w bloku catch. Zaskakujące jest to, że jeśli programista nie pamięta o dodaniu klauzuli .catch, błędy zgłaszane w tych miejscach nie są obsługiwane przez moduł obsługi zdarzeń uncaughtException i znikają. Najnowsze wersje Node dodały komunikat ostrzegawczy, gdy pojawia się nieobsługiwane odrzucenie, chociaż może to pomóc w zauważeniu, że coś pójdzie nie tak, ale oczywiście nie jest to właściwa metoda obsługi błędów. Prostym rozwiązaniem jest, aby nigdy nie zapomnieć o dodaniu klauzul .catch w każdym wywołaniu łańcucha obietnicy i przekierowaniu do scentralizowanej procedury obsługi błędów. Jednak budowanie strategii radzenia sobie z błędami wyłącznie w oparciu o dyscyplinę programisty jest dość kruche. W związku z tym zaleca się stosowanie płynnego wycofywania się i zapisanie się na `process.on ('unhandledRejection', callback)` - zapewni to, że każdy błąd obietnicy, jeśli nie zostanie złapany lokalnie, zostanie obsłużony.
+
+
+
+### Przykład kodu: błędy te nie zostaną złapane przez żadną procedurę obsługi błędów (z wyjątkiem unhandledRejection)
+
+```javascript
+DAL.getUserById(1).then((johnSnow) => {
+ // this error will just vanish
+ if(johnSnow.isAlive === false)
+ throw new Error('ahhhh');
+});
+```
+
+
+
+### Przykład kodu: Łapanie nierozwiązanych i odrzuconych promises
+
+
+Javascript
+
+```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);
+});
+```
+
+
+
+Typescript
+
+```typescript
+process.on('unhandledRejection', (reason: string, p: Promise) => {
+ // 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: 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);
+});
+```
+
+
+
+
+### Cytat z Bloga: "If you can make a mistake, at some point you will"
+
+ Z bloga 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/catchunhandledpromiserejection.russian.md b/sections/errorhandling/catchunhandledpromiserejection.russian.md
index 2109847e9..eeb6d31e5 100644
--- a/sections/errorhandling/catchunhandledpromiserejection.russian.md
+++ b/sections/errorhandling/catchunhandledpromiserejection.russian.md
@@ -13,29 +13,54 @@
```javascript
DAL.getUserById(1).then((johnSnow) => {
// this error will just vanish
- if(johnSnow.isAlive == false)
+ if(johnSnow.isAlive === false)
throw new Error('ahhhh');
});
-
```
### Пример кода: отлов нерешенных и отклоненных обещаний
+
+Javascript
+
```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
+ // 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);
});
+```
+
+
+
+Typescript
+
+```typescript
+process.on('unhandledRejection', (reason: string, p: Promise) => {
+ // 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: 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);
+});
```
+
@@ -46,16 +71,16 @@ process.on('uncaughtException', (error) => {
> Давайте проверим ваше понимание. Что из следующего вы ожидаете увидеть как ошибку в консоли?
```javascript
-Promise.resolve(‘promised value’).then(() => {
- throw new Error(‘error’);
-});
+Promise.resolve('promised value').then(() => {
+ throw new Error('error');
+})
-Promise.reject(‘error value’).catch(() => {
- throw new Error(‘error’);
+Promise.reject('error value').catch(() => {
+ throw new Error('error')
});
new Promise((resolve, reject) => {
- throw new Error(‘error’);
+ throw new Error('error');
});
```
diff --git a/sections/errorhandling/centralizedhandling.basque.md b/sections/errorhandling/centralizedhandling.basque.md
new file mode 100644
index 000000000..1676370f2
--- /dev/null
+++ b/sections/errorhandling/centralizedhandling.basque.md
@@ -0,0 +1,175 @@
+# Kudeatu erroreak gune bakar batean, Express middleware erabili partez
+
+### Azalpena
+
+Erroreak kudeatzeko objektu dedikaturik gabe, handiagoak dira erroreak inkoherentziaz kudeatzeko aukerak: web eskaeren barruan izandako erroreak eta hasierako fasean planteatutakoen edo programatutako lanek sortutakoen desberdinak izan daitezke. Horrek eragina izan dezake oker kudeatzen ari diren errore mota batzuetan. Erroreak kudeatzen dituen objektu bakar horren ardura da erroreak begi bistan jartzea, adibidez ondo formateatutako erregistro batean idatziz edo monitorizazio produktu batzuk erabiliz ([Prometheus](https://prometheus.io/), [CloudWatch](https://aws.amazon.com/cloudwatch/), [DataDog](https://www.datadoghq.com/) eta [Sentry](https://sentry.io/) bezalakoak); eta, gainera, berak erabakitzen du prozesuak huts egin behar duen ala ez. Web plataforma gehienek erroreak atzemateko middleware mekanismoa eskaintzen dute. Errore tipikoa izaten da middlewarearen erroreen kudeaketa kodea jartzea. Horrela, ezin izango duzu kudeatzaile bera berrerabili eszenatoki desberdinetan atzemandako erroreetarako, hala nola, programatutako lanak, harpidedunen mezu ilarak eta atzeman gabeko salbuespenak. Ondorioz, errorearen middlewareak erroreak atzeman eta kudeatzailera bidali beharko lituzke. Hau izan liteke errore kudeaketaren fluxu tipikoa: moduluren batzuek errore bat jaurtitzen dute -> API bideratzaileak errorea atzematen du -> erroreak atzemateaz arduratzen den middlewarera bidaltzen du (edo eskaera mailako erroreak atzemateko beste mekanismo batera) -> errore kudeatzaile zentralizatu bati deitzen zaio
+
+### Kode adibidea: ohiko errore fluxua
+
+
+Javascript
+
+```javascript
+// DAL (Data Access Layer) geruza, ez ditugu erroreak hemen kudeatzen
+DB.gehituDokumentua(bezeroBerria, (errorea, emaitza) => {
+ if (errorea)
+ throw new Error('Errore azalpen bikaina dator hemen', bestelako parametro erabilgarri batzuk)
+});
+
+// API bide kodea, errore sinkrono eta asinkronoak harrapatu eta middlewarera desbideratzen ditugu hemen
+try {
+ bezeroZerbitzua.gehituBerria(req.body).then((emaitza) => {
+ res.status(200).json(emaitza);
+ }).catch((errorea) => {
+ next(errorea)
+ });
+}
+catch (errorea) {
+ next(errorea);
+}
+
+// Errore-kudeaketa middlewarea, errore kudeatzaile zentralizatuari uzten diogu errore kudeaketa
+app.use(async (errorea, req, res, next) => {
+ const operazioErroreaDa = await erroreKudeatzailea.kudeatuErrorea(errorea);
+ if (!operazioErroreaDa) {
+ next(errorea);
+ }
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+// DAL (Data Access Layer) geruza, ez ditugu erroreak hemen kudeatzen
+DB.gehituDokumentua(bezeroBerria, (errorea: Error, emaitza: Result) => {
+ if (errorea)
+ throw new Error('Errore azalpen bikaina dator hemen', bestelako parametro erabilgarri batzuk)
+});
+
+// API bide kodea, errore sinkrono eta asinkronoak harrapatu eta middlewarera desbideratzen ditugu hemen
+try {
+ bezeroZerbitzua.gehituBerria(req.body).then((emaitza: Result) => {
+ res.status(200).json(emaitza);
+ }).catch((errorea: Error) => {
+ next(errorea)
+ });
+}
+catch (errorea) {
+ next(errorea);
+}
+
+// Errore-kudeaketa middlewarea, errore kudeatzaile zentralizatuari uzten diogu errore kudeaketa
+app.use(async (errorea: Error, req: Request, res: Response, next: NextFunction) => {
+ const operazioErroreaDa = await erroreKudeatzailea.kudeatuErrorea(errorea);
+ if (!operazioErroreaDa) {
+ next(errorea);
+ }
+});
+```
+
+
+
+### Kode adibidea: erroreen kudeaketa ardura bakarreko objektuekin
+
+
+Javascript
+
+```javascript
+module.exports.kudeatzailea = new erroreKudeatzailea();
+
+function erroreKudeatzailea() {
+ this.erroreaKudeatu = async (errorea) => {
+ await logger.erroreaErregistratu(errorea);
+ await kritikoaBadaAdministrariariPostaElektronikoaBidali;
+ await kritikoaBadaOperazioZerrendanGorde;
+ await erabakiIaOperazioErroreaDen;
+ };
+}
+```
+
+
+
+
+Typescript
+
+```typescript
+class ErroreKudeatzailea {
+ public async erroreaKudeatu(errorea: Error): Promise {
+ await logger.erroreaErregistratu(errorea);
+ await kritikoaBadaAdministrariariPostaElektronikoaBidali();
+ await kritikoaBadaOperazioZerrendanGorde();
+ await erabakiIaOperazioErroreaDen();
+ }
+}
+
+export const kudeatzailea = new ErroreKudeatzailea();
+```
+
+
+
+### Anti ereduaren kode adibidea: kudeatu erroreak middleware barruan
+
+
+Javascript
+
+```javascript
+// zuzeneko errore kudeaketa middlewarean, Cron atazak eta frogatze erroreak kudeatuko dituena?
+app.use((errorea, req, res, next) => {
+ logger.erroreaErregistratu(errorea);
+ if (errorea.larritasuna == erroreak.altua) {
+ posta.postaElektronikoaBidali(
+ konfigurazioa.administrariPostaElektronikoa,
+ "Errore kritikoa gertatu da",
+ errorea
+ );
+ }
+ if (!errorea.operazioErroreaDa) {
+ next(errorea);
+ }
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+// zuzeneko errore kudeaketa middlewarean, Cron atazak eta frogatze erroreak kudeatuko dituena?
+app.use((errorea: Error, req: Request, res: Response, next: NextFunction) => {
+ logger.erroreaErregistratu(errorea);
+ if (errorea.larritasuna == erroreak.altua) {
+ posta.postaElektronikoaBidali(
+ konfigurazioa.administrariPostaElektronikoa,
+ "Errore kritikoa gertatu da",
+ errorea
+ );
+ }
+ if (!errorea.operazioErroreaDa) {
+ next(errorea);
+ }
+});
+```
+
+
+
+### Blog aipua: "Batzuetan maila baxuagoek beren deitzaileari errorea bidaltzea baino ezer praktikoagorik ezin dute egin"
+
+Joyent blogeko “Node.js errore kudeaketa" hitz gako bati esker sailkatua
+
+> …Errore bera pilaren maila askotan kudeatzen bukatuko duzu. Hau gertatzen da maila baxuenek beren deitzaileei (eta beste haiek beren deitzaileei, etab.) errorea bidaltzea baino beste ezer egokiagorik ezin dutenean egin. Askotan, soilik goi mailako deitzaileak daki zein den erantzun zuzena, ia ahalegin operazio berria den, erabiltzaileari errorearen berri eman behar dion, edo beste edozer. Baina horrek ez du esan nahi errore guztiak goi mailako callback bakar bati jakinarazi behar dizkiozunik, callback horrek ere errorea zein testuingurutan gertatu den ez daki eta…
+
+### Blog aipua: "Errore bakoitza bakarka kudeatzea bikoizte galanta izan daiteke"
+
+JS Recipes blogeko “Node.js errore kudeaketa" 17 hitz gakori esker sailkatua
+
+> ……Hackathoneko Starter api.js kontrolatzaile bakarrean, 79 errore objektu inguru daude. Errore bakoitza bakarka kudeatzeak kodea ikaragarri bikoiztea eragin dezake. Hurrengo egin dezakezun gauza hoberena da errore kudeaketa logika Express middleware bati uztea…
+
+### Blog aipua: "HTTP erroreak ezin dira zure datu basearen kodean egon"
+
+Daily JS blogeko “Node.js errore kudeaketa" 14 hitz gakori esker sailkatua
+
+> ……Errore objektuetan ezaugarri erabilgarriak zehaztu beharko zenituzke, baina ezaugarri horiek tinko erabiliz. Eta, ez gurutzatu korronteak: HTTP erroreak ezin dira zure datu basearen kodean egon. Edota, nabigatzaile garatzaileentzat, Ajax erroreak zerbitzariarekin hitz egiten duten kodean egon daitezke, baina Mustache txantiloiak prozesatzen dituen koderik ez…
diff --git a/sections/errorhandling/centralizedhandling.chinese.md b/sections/errorhandling/centralizedhandling.chinese.md
index cc95a2c63..06a4f31bc 100644
--- a/sections/errorhandling/centralizedhandling.chinese.md
+++ b/sections/errorhandling/centralizedhandling.chinese.md
@@ -43,11 +43,11 @@ app.use(function (err, req, res, next) {
```javascript
module.exports.handler = new errorHandler();
-function errorHandler(){
+function errorHandler() {
this.handleError = function (err) {
return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
}
-
+}
```
### 代码示例 – 反模式:在中间件内处理错误
diff --git a/sections/errorhandling/centralizedhandling.french.md b/sections/errorhandling/centralizedhandling.french.md
new file mode 100644
index 000000000..ca1f2849a
--- /dev/null
+++ b/sections/errorhandling/centralizedhandling.french.md
@@ -0,0 +1,176 @@
+# Gérez les erreurs de manière centralisée, pas dans les middlewares
+
+### Un paragraphe d'explication
+
+Sans un objet dédié au traitement des erreurs, les risques de traitement incohérent des erreurs sont plus grands : les erreurs lancées à l'intérieur des requêtes web peuvent être traitées différemment de celles qui sont levées lors de la phase de démarrage et de celles qui sont levées par les jobs planifiés. Cela peut conduire à certains types d'erreurs qui sont mal gérés. Cet objet unique de traitement des erreurs est chargé de rendre l'erreur visible, par exemple, en écrivant dans un journal bien formaté, en envoyant des mesures à l'aide d'un produit de surveillance (comme [Prometheus](https://prometheus.io/), [CloudWatch](https://aws.amazon.com/cloudwatch/), [DataDog](https://www.datadoghq.com/) et [Sentry](https://sentry.io/)) et de décider si le processus doit planter. La plupart des frameworks web fournissent un mécanisme de middleware pour la détection des erreurs - une erreur typique consiste à placer le code de gestion des erreurs dans ce middelware. Ce faisant, vous ne pourrez pas réutiliser le même gestionnaire pour les erreurs qui sont détectées dans différents scénarios comme les tâches planifiées, les abonnés à la file d'attente des messages et les exceptions non détectées. Par conséquent, le middleware de gestion des erreurs ne doit que capturer les erreurs et les transmettre au gestionnaire. Un flux typique de traitement des erreurs pourrait être : un module lance une erreur -> le routeur API capture l'erreur -> il propage l'erreur au middleware (par exemple ou à un autre mécanisme de capture d'erreur au niveau de la requête) qui est responsable de la capture des erreurs -> un gestionnaire d'erreur centralisé est appelé.
+
+### Exemple de code - un flux d'erreur typique
+
+
+Javascript
+
+```javascript
+// Strate de la DAL, nous ne gérons pas les erreurs ici
+DB.addDocument(newCustomer, (error, result) => {
+ if (error)
+ throw new Error('Une bonne explication de l\'erreur à cet endroit', autres parametres utiles)
+});
+
+// Code de l'API route, nous interceptons les erreurs synchrone et asynchrone et les transmettons au middleware
+try {
+ customerService.addNew(req.body).then((result) => {
+ res.status(200).json(result);
+ }).catch((error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+// Gestion des erreurs du middleware, nous déléguons la gestion au gestionnaire d'erreurs centralisé
+app.use(async (err, req, res, next) => {
+ await errorHandler.handleError(err, res);//Le gestionnaire d'erreur enverra une réponse
+});
+
+process.on("uncaughtException", error => {
+ errorHandler.handleError(error);
+});
+
+process.on("unhandledRejection", (reason) => {
+ errorHandler.handleError(reason);
+});
+```
+
+
+
+Typescript
+
+```typescript
+// Strate de la DAL, nous ne gérons pas les erreurs ici
+DB.addDocument(newCustomer, (error: Error, result: Result) => {
+ if (error)
+ throw new Error('Une bonne explication de l\'erreur à cet endroit', autres parametres utiles)
+});
+
+// Code de l'API route, nous interceptons les erreurs synchrone et asynchrone et les transmettons au middleware
+try {
+ customerService.addNew(req.body).then((result: Result) => {
+ res.status(200).json(result);
+ }).catch((error: Error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+// Gestion des erreurs du middleware, nous déléguons la gestion au gestionnaire d'erreurs centralisé
+app.use(async (err: Error, req: Request, res: Response, next: NextFunction) => {
+ await errorHandler.handleError(err, res);
+});
+
+process.on("uncaughtException", (error:Error) => {
+ errorHandler.handleError(error);
+});
+
+process.on("unhandledRejection", (reason) => {
+ errorHandler.handleError(reason);
+});
+```
+
+
+
+### Exemple de code - gestion des erreurs dans un objet dédié
+
+
+Javascript
+
+```javascript
+module.exports.handler = new errorHandler();
+
+function errorHandler() {
+ this.handleError = async (error, responseStream) => {
+ await logger.logError(error);
+ await fireMonitoringMetric(error);
+ await crashIfUntrustedErrorOrSendResponse(error, responseStream);
+ };
+}
+```
+
+
+
+Typescript
+
+```typescript
+class ErrorHandler {
+ public async handleError(error: Error, responseStream: Response): Promise {
+ await logger.logError(error);
+ await fireMonitoringMetric(error);
+ await crashIfUntrustedErrorOrSendResponse(error, responseStream);
+ };
+}
+
+export const handler = new ErrorHandler();
+```
+
+
+
+### Contre exemple de code - gestion des erreurs dans le middleware
+
+
+Javascript
+
+```javascript
+// middleware traitant l'erreur directement, qui va gérer les tâches Cron et tester les erreurs ?
+app.use((err, req, res, next) => {
+ logger.logError(err);
+ if (err.severity == errors.high) {
+ mailer.sendMail(configuration.adminMail, 'Une erreur critique s\'est produite', err);
+ }
+ if (!err.isOperational) {
+ next(err);
+ }
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+// middleware traitant l'erreur directement, qui va gérer les tâches Cron et tester les erreurs ?
+app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
+ logger.logError(err);
+ if (err.severity == errors.high) {
+ mailer.sendMail(configuration.adminMail, 'Une erreur critique s\'est produite', err);
+ }
+ if (!err.isOperational) {
+ next(err);
+ }
+});
+```
+
+
+### Illustration : Les acteurs et le flux du traitement des erreurs
+
+
+
+### Citation de blog : « Parfois, les niveaux inférieurs ne peuvent rien faire d'utile, sauf propager l'erreur à leur appelant »
+
+Extrait du blog de Joyent classé en 1ere position pour les mots clés “Node.js error handling”
+
+> …Vous pouvez finir par gérer la même erreur à plusieurs niveaux de la pile. Cela se produit lorsque les niveaux inférieurs ne peuvent rien faire d'autre d'utile que de propager l'erreur à leur appelant, qui propage l'erreur à son appelant et ainsi de suite. Souvent, seul l'appelant de niveau supérieur sait quelle est la réponse appropriée, que ce soit pour réessayer l'opération, signaler une erreur à l'utilisateur ou autre chose. Mais cela ne signifie pas que vous devez essayer de signaler toutes les erreurs à une seule fonction de rappel de niveau supérieur, car cette fonction de rappel elle-même ne peut pas savoir dans quel contexte l'erreur s'est produite.…
+
+### Citation de blog : « Gérer chaque erreur individuellement entraînerait une énorme duplication »
+
+Extrait du blog de JS Recipes classé en 17eme position pour les mots clés “Node.js error handling”
+
+> ……Uniquement dans le contrôleur api.js de Hackathon Starter, il y a plus de 79 occurrences d'objets d'erreur. Gérer chaque erreur individuellement entraînerait une énorme duplication de code. La meilleure chose à faire est de déléguer toute la logique de gestion des erreurs à un middleware Express…
+
+### Citation de blog : « les erreurs HTTP n'ont pas leur place dans le code de votre base de données »
+
+Extrait du blog de Daily JS classé en 14eme position pour les mots clés “Node.js error handling”
+
+> ……Vous devez définir des propriétés utiles dans les objets d'erreur, mais utilisez ces propriétés de manière cohérente. Et ne traversez pas les flux : les erreurs HTTP n'ont pas leur place dans le code de votre base de données. Ou pour les développeurs dans les navigateurs, les erreurs Ajax ont une place dans le code qui parle au serveur, mais pas dans le code qui traite les templates de Mustache…
diff --git a/sections/errorhandling/centralizedhandling.japanese.md b/sections/errorhandling/centralizedhandling.japanese.md
new file mode 100644
index 000000000..e9b910f17
--- /dev/null
+++ b/sections/errorhandling/centralizedhandling.japanese.md
@@ -0,0 +1,164 @@
+# エラー処理を一元化し、ミドウェア内で処理をしない
+
+### 一段落説明
+
+エラー処理専用のオブジェクトがないと、不適切な処理が原因となって重要なエラーが発見されない可能性が高くなります。エラー処理オブジェクトは、エラーを可視化する責任をもちます。例えば、整形されたロガーに書き込んだり、[Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/), [Raygun](https://raygun.com/) のようなモニタリングサービスにイベントを送信したりするといったことなどです。[Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers) のようなほとんどの Web フレームワークは、エラー処理ミドルウェア機構を提供しています。典型的なエラー処理の流れは以下のようになります。いくつかのモジュールがエラーを投げる -> API router がエラーを捕捉する -> エラー捕捉に責任を持つミドルウェア(例: Express、KOA)にエラーを伝搬する -> 一元化されているエラーハンドラが呼び出される -> ミドルウェアは、補足したエラーが信頼されていないエラーかどうか(操作上のエラーでないか)が伝えられているので、アプリを直ちに再起動することができるようになっています。Express ミドルウェア内でエラー処理をすることは一般的ですが、実際には間違っていることに注意してください ー そうしてしまうと、ウェブ以外のインタフェースで投げられたエラーをカバーすることができません。
+
+### コード例 – 典型的なエラーフロー
+
+
+Javascript
+
+```javascript
+// DAL(データアクセスレイヤー), ここではエラー処理を行いません
+DB.addDocument(newCustomer, (error, result) => {
+ if (error)
+ throw new Error('Great error explanation comes here', other useful parameters)
+});
+
+// API route コード, 同期エラーと非同期エラーの両方を捕捉し、ミドルウェアへ進みます
+try {
+ customerService.addNew(req.body).then((result) => {
+ res.status(200).json(result);
+ }).catch((error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+// エラー処理ミドルウェア、一元化されたエラーハンドラに処理を委譲します
+app.use(async (err, req, res, next) => {
+ const isOperationalError = await errorHandler.handleError(err);
+ if (!isOperationalError) {
+ next(err);
+ }
+});
+```
+
+
+
+Typescript
+
+```typescript
+// DAL(データアクセスレイヤー), ここではエラー処理を行いません
+DB.addDocument(newCustomer, (error: Error, result: Result) => {
+ if (error)
+ throw new Error('Great error explanation comes here', other useful parameters)
+});
+
+// API route コード, 同期エラーと非同期エラーの両方を捕捉し、ミドルウェアへ進みます
+try {
+ customerService.addNew(req.body).then((result: Result) => {
+ res.status(200).json(result);
+ }).catch((error: Error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+// エラー処理ミドルウェア、一元化されたエラーハンドラに処理を委譲します
+app.use(async (err: Error, req: Request, res: Response, next: NextFunction) => {
+ const isOperationalError = await errorHandler.handleError(err);
+ if (!isOperationalError) {
+ next(err);
+ }
+});
+```
+
+
+
+### コード例 – 専用オブジェクト内でのエラー処理
+
+
+Javascript
+
+```javascript
+module.exports.handler = new errorHandler();
+
+function errorHandler() {
+ this.handleError = async (err) => {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical;
+ await saveInOpsQueueIfCritical;
+ await determineIfOperationalError;
+ };
+}
+```
+
+
+
+Typescript
+
+```typescript
+class ErrorHandler {
+ public async handleError(err: Error): Promise {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical();
+ await saveInOpsQueueIfCritical();
+ await determineIfOperationalError();
+ };
+}
+
+export const handler = new ErrorHandler();
+```
+
+
+
+### コード例 – アンチパターン: ミドルウェア内でのエラー処理
+
+
+Javascript
+
+```javascript
+// エラーを直接的に処理するミドルウェア、Cron ジョブやテストエラーは誰が処理するのでしょうか?
+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);
+ }
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+// エラーを直接的に処理するミドルウェア、Cron ジョブやテストエラーは誰が処理するのでしょうか?
+app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
+ logger.logError(err);
+ if (err.severity == errors.high) {
+ mailer.sendMail(configuration.adminMail, 'Critical error occured', err);
+ }
+ if (!err.isOperational) {
+ next(err);
+ }
+});
+```
+
+
+### ブログ引用: "Sometimes lower levels can’t do anything useful except propagate the error to their caller"(時に下位レベルはエラーを呼び出し元に伝搬すること以外に役に立ちません)
+
+ブログ Joyent(“Node.js error handling”というキーワードで 1 位)より
+
+> …スタックの複数レベルで同じエラーを処理することになるかもしれません。これは、呼び出し元にエラーを伝搬させ、その呼び出し元が伝搬されたエラーをその呼び出し元に伝搬させる、ということ繰り返す以外に、下位レベルの呼び出し元が役立つことをできない場合に起こります。多くの場合、操作を再試行するのか、ユーザーにエラーを報告するのか、はたまた何か他のことをするのか、最上位レベルの呼び出し元だけが適切な対応が何であるのかを知っています。しかし、これはすべてのエラーを単一のトップレベルのコールバックに報告しようとするべきだということを意味しているわけではありません。なぜならコールバック自身が、どのようなコンテキストでエラーが発生したのかを知ることができないためです。…
+
+### ブログ引用: "Handling each err individually would result in tremendous duplication"(各エラーを個別に処理することは途方も無い重複をもたらします)
+
+ブログ JS Recipes(“Node.js error handling”というキーワードで 17 位)より
+
+> ……Hackathon Starter の api.js コントローラーだけでも、79 個以上のエラーオブジェクトが存在しています。それぞれのエラーを個別に処理することは、途方も無い量のコードの重複をもたらします。次にできる最も優れた方法は、すべてのエラー処理ロジックを Express のミドルウェアに委譲することです。…
+
+### ブログ引用: "HTTP errors have no place in your database code"(データベースコードに HTTP エラーの居場所はありません)
+
+ブログ Daily JS(“Node.js error handling”というキーワードで 14 位)より
+
+> ……エラーオブジェクトには便利なプロパティを設定するべきですが、設定したプロパティは一貫して使用して下さい。また、ストリームをまたいではいけません: データベースコードには HTTP エラーの居場所はありません。ブラウザ開発者にとっては、Ajax のエラーは、サーバーと通信をしているコードの中にありますが、Mustache テンプレートを処理するコードの中には無いのです。…
diff --git a/sections/errorhandling/centralizedhandling.korean.md b/sections/errorhandling/centralizedhandling.korean.md
index 097a99223..a8b43baf1 100644
--- a/sections/errorhandling/centralizedhandling.korean.md
+++ b/sections/errorhandling/centralizedhandling.korean.md
@@ -1,10 +1,10 @@
-# 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.
+에러 처리를 위한 전용 객체가 없으면 잘못된 처리로 인해 중요한 에러가 숨어있을 가능성이 더 커진다. 예를 들어, 에러 처리 객체는 [Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/), 또는 [Raygun](https://raygun.com/))와 같은 모니터링 프로그램에 이벤트를 보내 에러를 가시적으로 만드는 역할을 한다. [Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers),와 같은 대부분의 웹 프레임워크는 미들웨어 메커니즘 에러처리를 제공한다. 일반적인 에러 처리 흐름은 다음과 같다: 일부 모듈이 에러를 던진다 -> API 라우터가 에러를 잡는다 -> 에러를 에러 검출을 담당하는 미들웨어(예: Express, KOA)에 전달한다 -> 중앙 에러 처리기가 호출된다 -> 미들웨어는 이 에러가 신뢰할 수 없는 에러인지(작동하지 않음) 알려 앱을 정상적으로 재시작 할 수 있다. Express 미들웨어 내에서 오류를 처리하는 것이 일반적이지만 잘못된 관습이다 – 이렇게 하면 웹 이외의 인터페이스에 발생하는 에러를 해결 할 수 없다.
-### Code Example – a typical error flow
+### 코드 예시 – 일반적인 에러 흐름
```javascript
// DAL layer, we don't handle errors here
@@ -34,7 +34,7 @@ app.use(async (err, req, res, next) => {
});
```
-### Code example – handling errors within a dedicated object
+### 코드 예시 – 전용 객체에서 에러 처리
```javascript
module.exports.handler = new errorHandler();
@@ -49,7 +49,7 @@ function errorHandler() {
}
```
-### Code Example – Anti Pattern: handling errors within the middleware
+### 코드 예시 – 좋지않은 패턴: 미들웨어에서 에러 처리
```javascript
// middleware handling the error directly, who will handle Cron jobs and testing errors?
@@ -64,20 +64,20 @@ app.use((err, req, res, next) => {
});
```
-### 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”
+Joyent 블로그에서 "Node.js 에러 처리" 키워드 1위에 위치했다
-> …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”
+JS Recipes 블로그에서 "Node.js 에러 처리" 키워드 17위에 위치했다
-> ……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…
+> ……Hackathon Starter api.js 컨트롤러에서만 79개 이상의 오류 객체가 있다. 각 에러를 개별적으로 처리하면 엄청난 중복이 발생할 수 있다. 다음으로 가장 좋은 방법은 모든 에러 처리 로직을 Express 미들웨어에 위임하는 것이다…
-### Blog Quote: "HTTP errors have no place in your database code"
+### 블로그 인용: "HTTP 에러는 데이터베이스 코드에 포함되지 않는다"
-From the blog Daily JS ranked 14 for the keywords “Node.js error handling”
+Daily JS 블로그에서 "Node.js 에러 처리" 키워드 14위에 위치했다
-> ……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…
+> ……에러 객체에 유용한 속성을 설정해야 하지만, 이런 속성은 일관되게 사용해야 한다. 그리고, 스트림을 넘지 마라: HTTP 에러는 데이터베이스 코드에 포함되지 않는다. 또한 브라우저 개발자의 경우, Ajax 에러는 서버와 통신하는 코드가 있지만, 머스테치(Mustache) 템플릿을 처리하는 코드는 아니다…
\ No newline at end of file
diff --git a/sections/errorhandling/centralizedhandling.md b/sections/errorhandling/centralizedhandling.md
index 1d184626d..7a8f7a6d6 100644
--- a/sections/errorhandling/centralizedhandling.md
+++ b/sections/errorhandling/centralizedhandling.md
@@ -2,7 +2,7 @@
### 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.
+Without one dedicated object for error handling, greater are the chances for inconsistent errors handling: Errors thrown within web requests might get handled differently from those raised during the startup phase and those raised by scheduled jobs. This might lead to some types of errors that are being mismanaged. This single error handler object is responsible for making the error visible, for example, by writing to a well-formatted logger, firing metrics using some monitoring product (like [Prometheus](https://prometheus.io/), [CloudWatch](https://aws.amazon.com/cloudwatch/), [DataDog](https://www.datadoghq.com/), and [Sentry](https://sentry.io/)) and to decide whether the process should crash. Most web frameworks provide an error catching middleware mechanism - A typical mistake is to place the error handling code within this middleware. By doing so, you won't be able to reuse the same handler for errors that are caught in different scenarios like scheduled jobs, message queue subscribers, and uncaught exceptions. Consequently, the error middleware should only catch errors and forward them to the handler. 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. or to other mechanism for catching request-level error) who is responsible for catching errors -> a centralized error handler is called.
### Code Example – a typical error flow
@@ -30,10 +30,15 @@ catch (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);
- }
+ await errorHandler.handleError(err, res);//The error handler will send a response
+});
+
+process.on("uncaughtException", error => {
+ errorHandler.handleError(error);
+});
+
+process.on("unhandledRejection", (reason) => {
+ errorHandler.handleError(reason);
});
```
@@ -62,10 +67,15 @@ catch (error) {
// Error handling middleware, we delegate the handling to the centralized error handler
app.use(async (err: Error, req: Request, res: Response, next: NextFunction) => {
- const isOperationalError = await errorHandler.handleError(err);
- if (!isOperationalError) {
- next(err);
- }
+ await errorHandler.handleError(err, res);
+});
+
+process.on("uncaughtException", (error:Error) => {
+ errorHandler.handleError(error);
+});
+
+process.on("unhandledRejection", (reason) => {
+ errorHandler.handleError(reason);
});
```
@@ -80,11 +90,10 @@ app.use(async (err: Error, req: Request, res: Response, next: NextFunction) => {
module.exports.handler = new errorHandler();
function errorHandler() {
- this.handleError = async (err) => {
- await logger.logError(err);
- await sendMailToAdminIfCritical;
- await saveInOpsQueueIfCritical;
- await determineIfOperationalError;
+ this.handleError = async (error, responseStream) => {
+ await logger.logError(error);
+ await fireMonitoringMetric(error);
+ await crashIfUntrustedErrorOrSendResponse(error, responseStream);
};
}
```
@@ -95,11 +104,10 @@ function errorHandler() {
```typescript
class ErrorHandler {
- public async handleError(err: Error): Promise {
- await logger.logError(err);
- await sendMailToAdminIfCritical();
- await saveInOpsQueueIfCritical();
- await determineIfOperationalError();
+ public async handleError(error: Error, responseStream: Response): Promise {
+ await logger.logError(error);
+ await fireMonitoringMetric(error);
+ await crashIfUntrustedErrorOrSendResponse(error, responseStream);
};
}
@@ -145,6 +153,10 @@ app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
```
+ ### Illustration: The error handling actors and flow
+
+
+
### 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”
diff --git a/sections/errorhandling/centralizedhandling.polish.md b/sections/errorhandling/centralizedhandling.polish.md
new file mode 100644
index 000000000..7fbd6a772
--- /dev/null
+++ b/sections/errorhandling/centralizedhandling.polish.md
@@ -0,0 +1,164 @@
+# Obsługuj błędy centralnie. Nie w ramach oprogramowania pośredniego
+
+### Wyjaśnienie jednym akapitem
+
+Bez jednego obiektu dedykowanego do obsługi błędów większe są szanse na poważne błędy ukryte pod radarem z powodu niewłaściwej obsługi. Obiekt obsługi błędów jest odpowiedzialny za uwidocznienie błędu, na przykład poprzez napisanie do dobrze sformatowanego programu rejestrującego, wysyłanie zdarzeń do jakiegoś produktu monitorującego, takiego jak [Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/) lub [Raygun](https://raygun.com/). Większość frameworków internetowych, takich jak [Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers), udostępnia mechanizm pośredniej obsługi błędów. Typowy przepływ obsługi błędów może być następujący: Niektóre moduły zgłaszają błąd -> router API łapie błąd -> propaguje błąd do oprogramowania pośredniego (np. Express, KOA), który jest odpowiedzialny za wychwytywanie błędów -> scentralizowany moduł obsługi błędów -> oprogramowanie pośredniczące jest informowane, czy ten błąd jest niezaufanym błędem (nie działa), aby mógł z wdziękiem ponownie uruchomić aplikację. Pamiętaj, że częstą, ale niepoprawną praktyką jest obsługa błędów w oprogramowaniu pośrednim Express - takie postępowanie nie obejmie błędów zgłaszanych w interfejsach innych niż internetowe.
+
+### Przykład kodu - typowy przepływ błędów
+
+
+Javascript
+
+```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);
+ }
+});
+```
+
+
+
+Typescript
+
+```typescript
+// DAL layer, we don't handle errors here
+DB.addDocument(newCustomer, (error: Error, result: 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: Result) => {
+ res.status(200).json(result);
+ }).catch((error: Error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+// Error handling middleware, we delegate the handling to the centralized error handler
+app.use(async (err: Error, req: Request, res: Response, next: NextFunction) => {
+ const isOperationalError = await errorHandler.handleError(err);
+ if (!isOperationalError) {
+ next(err);
+ }
+});
+```
+
+
+
+### Przykład kodu - obsługa błędów w obiekcie dedykowanym
+
+
+Javascript
+
+```javascript
+module.exports.handler = new errorHandler();
+
+function errorHandler() {
+ this.handleError = async (err) => {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical;
+ await saveInOpsQueueIfCritical;
+ await determineIfOperationalError;
+ };
+}
+```
+
+
+
+Typescript
+
+```typescript
+class ErrorHandler {
+ public async handleError(err: Error): Promise {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical();
+ await saveInOpsQueueIfCritical();
+ await determineIfOperationalError();
+ };
+}
+
+export const handler = new ErrorHandler();
+```
+
+
+
+### Przykład kodu - Antywzorzec: obsługa błędów w oprogramowaniu pośrednim
+
+
+Javascript
+
+```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);
+ }
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+// middleware handling the error directly, who will handle Cron jobs and testing errors?
+app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
+ logger.logError(err);
+ if (err.severity == errors.high) {
+ mailer.sendMail(configuration.adminMail, 'Critical error occured', err);
+ }
+ if (!err.isOperational) {
+ next(err);
+ }
+});
+```
+
+
+### Cytat z Bloga: "Sometimes lower levels can’t do anything useful except propagate the error to their caller"
+
+Z bloga Joyent, w rankingu 1 dla słów kluczowych “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…
+
+### Cytat z Bloga: "Handling each err individually would result in tremendous duplication"
+
+Z bloga JS Recipes w rankingu 17 dla słów kluczowych “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…
+
+### Cytat z Bloga: "HTTP errors have no place in your database code"
+
+Z bloga Daily JS w rankingu 14 dla słów kluczowych “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/centralizedhandling.russian.md b/sections/errorhandling/centralizedhandling.russian.md
index 345591772..30329ba9e 100644
--- a/sections/errorhandling/centralizedhandling.russian.md
+++ b/sections/errorhandling/centralizedhandling.russian.md
@@ -2,18 +2,22 @@
### Объяснение в один абзац
-Без специального выделенного объекта для обработки ошибок больше шансов на то, что важные ошибки скрываются под радаром из-за неправильного обращения. Объект обработчика ошибок отвечает за отображение ошибки, например, путем записи в хорошо отформатированный регистратор, отправки событий в некоторые продукты мониторинга, такие как [Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/) или [Raygun](https://raygun.com/). Большинство веб-фреймворков, таких как [Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers), предоставляют механизм промежуточного программного обеспечения для обработки ошибок. Типичный поток обработки ошибок может быть следующим: какой-то модуль выдает ошибку -> маршрутизатор API перехватывает ошибку -> он передает ошибку промежуточному программному обеспечению (например, Express, KOA), которое отвечает за перехват ошибок -> вызывается централизованный обработчик ошибок -> промежуточному программному обеспечению сообщается, является ли эта ошибка ненадежной (не работающей), чтобы она могла корректно перезапустить приложение. Обратите внимание, что обычная, но неправильная практика - обрабатывать ошибки в промежуточном программном обеспечении Express - это не распространяется на ошибки, возникающие в не-веб-интерфейсах.
+Без выделенного объекта для обработки ошибок есть больше шансов на то, что ошибки потеряются с радара из-за их неправильной обработки. Объект обработчика ошибок отвечает за отображение ошибки, например, путем записи в логгер, отправки событий в сервисы мониторинга, такие как [Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/) или [Raygun](https://raygun.com/). Большинство веб-фреймворков, таких как [Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers), предоставляют механизм обработки ошибок с помощью функций промежуточной обработки (**middlewares**). Типичный поток обработки ошибок может выглядеть следующим образом: какой-то модуль выдает ошибку -> API-маршрутизатор перехватывает ошибку -> он передает ошибку функции промежуточной обработки (Express, KOA), которая отвечает за перехват ошибок -> вызывается централизованный обработчик ошибок -> функции промежуточной обработки передается информация о том, что является ли эта ошибка ненадежной (необрабатываемой), чтобы она могла корректно перезапустить приложение. Обратите внимание, что обычная, но неправильная практика - обрабатывать ошибки в функции промежуточной обработки Express - это не распространяется на ошибки, возникающие в не-веб-интерфейсах.
### Пример кода - типичный поток ошибок
+
+Javascript
+
```javascript
-// DAL layer, we don't handle errors here
+// DAL-слой, мы не обрабатываем ошибки тут
DB.addDocument(newCustomer, (error, result) => {
if (error)
- throw new Error("Great error explanation comes here", other useful parameters)
+ 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
+// код API-маршрутизатора, мы обрабатываем как sync
+// так и async ошибки и переходим к middleware
try {
customerService.addNew(req.body).then((result) => {
res.status(200).json(result);
@@ -25,7 +29,7 @@ catch (error) {
next(error);
}
-// Error handling middleware, we delegate the handling to the centralized error handler
+// Обработка ошибок в middleware, мы делегируем обработку централизованному обработчику ошибок
app.use(async (err, req, res, next) => {
const isOperationalError = await errorHandler.handleError(err);
if (!isOperationalError) {
@@ -33,26 +37,87 @@ app.use(async (err, req, res, next) => {
}
});
```
+
+
+
+Typescript
+
+```typescript
+// DAL-слой, мы не обрабатываем ошибки тут
+DB.addDocument(newCustomer, (error: Error, result: Result) => {
+ if (error)
+ throw new Error('Great error explanation comes here', other useful parameters)
+});
+
+// код API-маршрутизатора, мы обрабатываем как sync
+// так и async ошибки и переходим к middleware
+try {
+ customerService.addNew(req.body).then((result: Result) => {
+ res.status(200).json(result);
+ }).catch((error: Error) => {
+ next(error)
+ });
+}
+catch (error) {
+ next(error);
+}
+
+// Обработка ошибок в middleware, мы делегируем обработку централизованному обработчику ошибок
+app.use(async (err: Error, req: Request, res: Response, next: NextFunction) => {
+ const isOperationalError = await errorHandler.handleError(err);
+ if (!isOperationalError) {
+ next(err);
+ }
+});
+```
+
+
### Пример кода - обработка ошибок в выделенном объекте
+
+Javascript
+
```javascript
module.exports.handler = new errorHandler();
function errorHandler() {
- this.handleError = async function(err) {
+ this.handleError = async (err) {
await logger.logError(err);
- await sendMailToAdminIfCritical;
- await saveInOpsQueueIfCritical;
- await determineIfOperationalError;
+ await sendMailToAdminIfCritical(err);
+ await saveInOpsQueueIfCritical(err);
+ await determineIfOperationalError(err);
};
}
```
+
+
+
+Typescript
-### Пример кода - антипаттерн: обработка ошибок в промежуточном программном обеспечении
+```typescript
+class ErrorHandler {
+ public async handleError(err: Error): Promise {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical(err);
+ await saveInOpsQueueIfCritical(err);
+ await determineIfOperationalError(err);
+ };
+}
+
+export const handler = new ErrorHandler();
+```
+
+
+
+### Пример кода - антипаттерн: обработка ошибок в middleware
+
+
+Javascript
```javascript
-// middleware handling the error directly, who will handle Cron jobs and testing errors?
+// middleware, обрабатывающий ошибки напрямую.
+// А кто будет обрабатывать ошибки возникшие в Cron или при юнит-тестировании?
app.use((err, req, res, next) => {
logger.logError(err);
if (err.severity == errors.high) {
@@ -63,21 +128,41 @@ app.use((err, req, res, next) => {
}
});
```
+
+
+
+
+Typescript
+
+```typescript
+// middleware, обрабатывающий ошибки напрямую.
+// А кто будет обрабатывать ошибки возникшие в Cron или при юнит-тестировании?
+app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
+ logger.logError(err);
+ if (err.severity == errors.high) {
+ mailer.sendMail(configuration.adminMail, 'Critical error occured', err);
+ }
+ if (!err.isOperational) {
+ next(err);
+ }
+});
+```
+
-### Цитата из блога: "Иногда нижние уровни не могут сделать ничего полезного, кроме как сообщить об ошибке вызывающей стороне"
+### Цитата из блога: "Иногда нижние слои не могут сделать ничего полезного, кроме как сообщить об ошибке вызывающему слою"
-Из блога Joyent, занимающий 1 место по ключевым словам "Обработка ошибок Node.js"
+Из блога Joyent, занимающего 1 место по ключевым словам "Обработка ошибок Node.js"
-> … Вы можете обработать одну и ту же ошибку на нескольких уровнях стека. Это происходит, когда нижние уровни не могут сделать ничего полезного, кроме как передать ошибку вызывающей стороне, которая передает ошибку своей вызывающей стороне, и так далее. Зачастую только вызывающий пользователь верхнего уровня знает, что является подходящим ответом: попытка повторить операцию, сообщить пользователю об ошибке или что-то еще. Но это не значит, что вы должны пытаться сообщать обо всех ошибках в один обратный вызов верхнего уровня, потому что сам этот обратный вызов не может знать, в каком контексте произошла ошибка …
+> … Вы можете обработать одну и ту же ошибку на нескольких слоях. Это происходит, когда нижние слои не могут сделать ничего полезного, кроме как передать ошибку вызывающему слою, который передаст ошибку своему вызывающему слою, и так далее. Зачастую только самый верхний слой знает, что является подходящим действием на ошибку: попытка повторить операцию, сообщить пользователю об ошибке или что-то еще. Но это не значит, что вы должны пытаться сообщать обо всех ошибках в один верхний callback, потому что этот callback не может знать, в каком контексте произошла ошибка …
-### Цитата из блога: "Обработка каждой ошибки по отдельности приведет к огромному дублированию"
+### Цитата из блога: "Обработка каждой ошибки по отдельности приведет к ужасному дублированию"
-Из блога JS Recipes, занимающий 17 место по ключевым словам "Обработка ошибок Node.js"
+Из блога JS Recipes, занимающего 17 место по ключевым словам "Обработка ошибок Node.js"
-> … Только в контроллере api.js Hackathon Starter имеется более 79 случаев появления объектов ошибок. Обработка каждой ошибки в отдельности привела бы к огромному количеству дублирования кода. Следующее, что вы можете сделать, это делегировать всю логику обработки ошибок в промежуточное ПО Express …
+> … Только в контроллере api.js Hackathon Starter имеется более 79 объектов ошибок. Обработка каждой ошибки в отдельности привела бы к ужасному дублированию кода. Следующее, что вы можете сделать, это делегировать всю логику обработки ошибок в middleware Express …
### Цитата из блога: "В коде вашей базы данных нет места ошибкам HTTP"
Из блога Daily JS, занимающем 14 место по ключевым словам "Обработка ошибок Node.js"
-> … Вы должны установить полезные свойства в объектах ошибок, но использовать их последовательно. И не пересекайте потоки: в коде вашей базы данных нет места ошибкам HTTP. Или для разработчиков браузеров, ошибки Ajax имеют место в коде, который общается с сервером, но не в коде, который обрабатывает шаблоны усов …
+> … Вы должны добавлять полезные свойства в объекты ошибок, но использовать их согласовано. И не пересекайте логику: в коде вашей базы данных нет места ошибкам HTTP. Или, например, для frontend-разработчиков, ошибки Ajax имеют место в коде, который общается с сервером, но не в коде, который работает с шаблонами Mustache …
diff --git a/sections/errorhandling/documentingusingswagger.basque.md b/sections/errorhandling/documentingusingswagger.basque.md
new file mode 100644
index 000000000..e88ba2e41
--- /dev/null
+++ b/sections/errorhandling/documentingusingswagger.basque.md
@@ -0,0 +1,50 @@
+# Dokumentatu API erroreak OpenAPI (aurretik Swagger bezala ezagutua) edo GraphQL-ren laguntzarekin
+
+### Azalpena
+
+REST APIek HTTP estatus kodigoak erabiliz bueltatzen dituzte emaitzak. APIaren erabiltzailearentzat guztiz beharrezkoa da APIaren egituraren eta baita ere errore posibleen berri izatea, erabiltzaileak errorea atzeman eta kontu handiz kudea dezake eta. Adibidez, zure APIaren dokumentazioak aurrez azaldu behar du 409 HTTP estatus kodea bueltatzen dela bezeroaren izena iada existitzen denean (APIak bezero berriak gordetzen dituela ziurtzat joz), APIaren erabiltzaileak egoera bakoitzerako bistaratze egokiena proposa dezan. OpenAPI (aitzina Swagger) APIaren dokumentaziorako eskema bat zehazten duen estandar bat da, dokumentazioa online modu errazean sortzea ahalbidetzen duten tresna ekosistema bat proposatuz. Begiratu hurrengo pantailako argazkiak beherago
+
+Dagoeneko GraphQL erabiltzen baduzu zure APIaren helburuetarako, zure eskemak iada zorrozki bermatzen du zein errorek zein itxura eduki beharko luketen ([dokumentuan laburbilduta](https://facebook.github.io/graphql/June2018/#sec-Errors)) eta nola kudeatu beharko liratekeen zure bezero tresnekin. Gainera, komentarioz osatutako dokumentazioa ere gehi zenezake
+
+### GraphQL errore baten adibidea
+
+> Adibide honek [SWAPI](https://graphql.org/swapi-graphql) erabiltzen du, Star Warsen APIa.
+
+```graphql
+# huts egin beharko luke id ez baita zuzena
+{
+ filmea(id: "1ZmlsbXM6MQ==") {
+ izenburua
+ }
+}
+```
+
+```json
+{
+ "erroreak": [
+ {
+ "mezua": "Ez dago sarrerarik cache lokalean https://swapi.co/api/films/.../-rentzat",
+ "lekuak": [
+ {
+ "ilara": 2,
+ "zutabea": 3
+ }
+ ],
+ "bidea": ["filmea"]
+ }
+ ],
+ "datuak": {
+ "filmea": null
+ }
+}
+```
+
+### Blog aipua: "Zure deitzaileei zein errore gertatu diren esan behar diezu"
+
+Joyent blogeko “Node.js erregistratzea“ hitz gako bati esker sailkatua
+
+> Erroreak nola kudeatu behar diren aztertu dugu, baina funtzio berri bat idazten ari zarenean, nola bidaltzen dizkiozu erroreak zure funtzioa deitu duen kodeari? …Zein errore gerta litezkeen edo haiek zer esan nahi duten ez badakizu, esan nahi du zure programa ezin litekeela zuzena izan, txiripaz izan ezean. Beraz, funtzio berri bat idazten ari bazara, zure deitzaileei zein errore gerta litezkeen eta haiek zer esan nahi duten esan behar diezu…
+
+### Tresna erabilgarria: Swagger Online Dokumentazio Sortzailea
+
+
diff --git a/sections/errorhandling/documentingusingswagger.brazilian-portuguese.md b/sections/errorhandling/documentingusingswagger.brazilian-portuguese.md
index fe208d712..781337b42 100644
--- a/sections/errorhandling/documentingusingswagger.brazilian-portuguese.md
+++ b/sections/errorhandling/documentingusingswagger.brazilian-portuguese.md
@@ -49,4 +49,4 @@ Do blog Joyent, classificado como 1 para as palavras-chave “Node.js logging”
### Ferramenta Útil: Swagger Criação de Documentação Online
-
+
diff --git a/sections/errorhandling/documentingusingswagger.chinese.md b/sections/errorhandling/documentingusingswagger.chinese.md
index e7f5addfa..3cf8cc0e3 100644
--- a/sections/errorhandling/documentingusingswagger.chinese.md
+++ b/sections/errorhandling/documentingusingswagger.chinese.md
@@ -13,4 +13,4 @@ REST API使用HTTP代码返回结果, API用户不仅绝对需要了解API schem
### 有用的工具: Swagger 在线文档创建工具
-
\ No newline at end of file
+
diff --git a/sections/errorhandling/documentingusingswagger.french.md b/sections/errorhandling/documentingusingswagger.french.md
new file mode 100644
index 000000000..0b57ce6d3
--- /dev/null
+++ b/sections/errorhandling/documentingusingswagger.french.md
@@ -0,0 +1,52 @@
+# Documentez les erreurs de l'API à l'aide de Swagger ou GraphQL
+
+### Un paragraphe d'explication
+
+Les API REST renvoient des résultats à l'aide de codes d'état HTTP, il est absolument nécessaire que l'utilisateur de l'API soit informé non seulement du schéma de l'API, mais également des erreurs potentielles - l'appelant peut alors détecter une erreur et la gérer avec tact. Par exemple, la documentation de votre API peut indiquer à l'avance que l'état HTTP 409 est renvoyé lorsque le nom du client existe déjà (en supposant que l'API enregistre de nouveaux utilisateurs) afin que l'appelant puisse rendre en conséquence la meilleure expérience utilisateur pour la situation donnée. Swagger est une norme qui définit le schéma de la documentation de l'API offrant un éco-système d'outils permettant de créer facilement de la documentation en ligne, consulter les copies écrans ci-dessous.
+
+Si vous avez déjà adopté GraphQL pour vos points de terminaison de l'API, votre schéma contient déjà des garanties strictes quant à la nature des erreurs à rechercher ([celles décrites dans la spécification](https://facebook.github.io/graphql/June2018/#sec-Errors)) et comment elles doivent être traités par vos outils côté client. De plus, vous pouvez également les compléter avec une documentation basée sur des commentaires.
+
+### Exemple d'erreur GraphQL
+
+> Cet exemple utilise [SWAPI](https://graphql.org/swapi-graphql), l'API de Star Wars.
+
+```graphql
+# devrait échouer car l'id n'est pas valide
+{
+ film(id: "1ZmlsbXM6MQ==") {
+ title
+ }
+}
+```
+
+```json
+{
+ "errors": [
+ {
+ "message": "Aucune entrée dans le cache local pour https://swapi.co/api/films/.../",
+ "locations": [
+ {
+ "line": 2,
+ "column": 3
+ }
+ ],
+ "path": [
+ "film"
+ ]
+ }
+ ],
+ "data": {
+ "film": null
+ }
+}
+```
+
+### Citation de blog : « Vous devez dire à vos appelants quelles erreurs peuvent se produire »
+
+Extrait du blog de Joyent classé en 1ere position pour les mots clés “Node.js logging”
+
+ > Nous avons parlé de la façon de gérer les erreurs, mais lorsque vous écrivez une nouvelle fonction, comment envoyez-vous des erreurs au code qui a appelé votre fonction ? … Si vous ne savez pas quelles erreurs peuvent se produire ou si vous ne savez pas ce qu'elles signifient, alors votre programme ne peut être correct que par accident. Donc, si vous écrivez une nouvelle fonction, vous devez dire à vos appelants quelles erreurs peuvent se produire et ce qu'elles signifient…
+
+### Outil utile : créateur de documentation en ligne Swagger
+
+
diff --git a/sections/errorhandling/documentingusingswagger.japanese.md b/sections/errorhandling/documentingusingswagger.japanese.md
new file mode 100644
index 000000000..10882d198
--- /dev/null
+++ b/sections/errorhandling/documentingusingswagger.japanese.md
@@ -0,0 +1,52 @@
+# Swagger または GraphQL を利用して API のエラーをドキュメント化する
+
+### 一段落説明
+
+REST API は HTTP ステータスコードを利用して結果を返しますが、API の利用者は、API のスキーマだけでなく潜在的なエラーについても意識しておくことが絶対に必要です ー そうすることで、利用者がエラーを捕捉して機転の利いた処理をできるかもしれません。例えばAPI ドキュメントに、(API が新規ユーザーを登録しようとしていると仮定して)顧客名が既に存在する場合に、HTTP ステータス 409 が返されることを前もって記載しておくことで、呼び出し元はそれに応じて最適な UX を提供することができるようになります。Swagger は API ドキュメントのスキーマを定義する標準仕様であり、オンラインで簡単にドキュメントを作成することを可能にするツール群を提供しています。下部のスクリーンショットを参照して下さい。
+
+もし既に API エンドポイントとして GraphQL を採用している場合、スキーマは、エラーがどのように見えるか([仕様書に記載されています](https://facebook.github.io/graphql/June2018/#sec-Errors))や、クライアントサイドのツールでどのように処理されるべきかについて、厳密な保証をしています。さらに、コメントベースのドキュメントでそれらを補足することもできます。
+
+### GraphQL エラー例
+
+> この例は、スターウォーズ API として知れられている [SWAPI](https://graphql.org/swapi-graphql) を使用しています
+
+```graphql
+# id が無効な値のため、失敗するはずです
+{
+ film(id: "1ZmlsbXM6MQ==") {
+ title
+ }
+}
+```
+
+```json
+{
+ "errors": [
+ {
+ "message": "No entry in local cache for https://swapi.co/api/films/.../",
+ "locations": [
+ {
+ "line": 2,
+ "column": 3
+ }
+ ],
+ "path": [
+ "film"
+ ]
+ }
+ ],
+ "data": {
+ "film": null
+ }
+}
+```
+
+### ブログ引用: "You have to tell your callers what errors can happen"(どのようなエラーが起こりうるか、呼び出す側に示さなければなりません)
+
+ブログ Joyent(“Node.js logging”というキーワードで 1 位)より
+
+ > これまでエラー処理の方法について話してきましたが、新たな関数を書くときに、どのようにしてその関数を呼び出したコードにエラーを届けるのでしょうか?…もしどのようなエラーが起こりうるかを知らなかったり、またそのエラーが意味することがわからなかった場合、プログラムは、偶然を除けば正しいものにはなりえません。ですから、もしあなたが新たな関数を書くのであれば、どのようなエラーが起こりうるか、そしてそれらの意味することを呼び出し側に示さなければなりません…
+
+### 便利ツール: Swagger Online Documentation Creator
+
+
diff --git a/sections/errorhandling/documentingusingswagger.korean.md b/sections/errorhandling/documentingusingswagger.korean.md
index b71cfead5..a101e668a 100644
--- a/sections/errorhandling/documentingusingswagger.korean.md
+++ b/sections/errorhandling/documentingusingswagger.korean.md
@@ -49,4 +49,4 @@ From the blog Joyent, ranked 1 for the keywords “Node.js logging”
### Useful Tool: Swagger Online Documentation Creator
-
+
diff --git a/sections/errorhandling/documentingusingswagger.md b/sections/errorhandling/documentingusingswagger.md
index b71cfead5..836f07364 100644
--- a/sections/errorhandling/documentingusingswagger.md
+++ b/sections/errorhandling/documentingusingswagger.md
@@ -1,8 +1,8 @@
-# Document API errors using Swagger or GraphQL
+# Document API errors using OpenAPI Specification (earlier known as Swagger) or GraphQL
### 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
+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. OpenAPI (eka 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
If you have already adopted GraphQL for your API endpoints, your schema already contains strict guarantees as to what errors should look like ([outlined in the spec](https://facebook.github.io/graphql/June2018/#sec-Errors)) and how they should be handled by your client-side tooling. In addition, you can also supplement them with comment-based documentation.
@@ -49,4 +49,4 @@ From the blog Joyent, ranked 1 for the keywords “Node.js logging”
### Useful Tool: Swagger Online Documentation Creator
-
+
diff --git a/sections/errorhandling/documentingusingswagger.polish.md b/sections/errorhandling/documentingusingswagger.polish.md
new file mode 100644
index 000000000..b6f1dfcd8
--- /dev/null
+++ b/sections/errorhandling/documentingusingswagger.polish.md
@@ -0,0 +1,52 @@
+# Dokumentuj błędy interfejsu API za pomocą Swagger lub GraphQL
+
+### Wyjaśnienie jednym akapitem
+
+REST API zwracają wyniki przy użyciu kodów stanu HTTP, użytkownik API musi bezwzględnie wiedzieć nie tylko o schemacie interfejsu API, ale także o potencjalnych błędach - osoba wywołująca może wtedy złapać błąd i taktownie go obsłużyć. Na przykład dokumentacja interfejsu API może z góry stwierdzać, że status HTTP 409 jest zwracany, gdy nazwa klienta już istnieje (zakładając, że interfejs API rejestruje nowych użytkowników), aby osoba wywołująca mogła odpowiednio wyświetlić najlepszy UX dla danej sytuacji. Swagger to standard definiujący schemat dokumentacji API oferujący ekosystem narzędzi umożliwiających łatwe tworzenie dokumentacji online, patrz ekrany drukowania poniżej.
+
+Jeśli już przyjąłeś GraphQL dla punktów końcowych API, twój schemat zawiera już ścisłe gwarancje, jak powinny wyglądać błędy ([przedstawione w specyfikacji](https://facebook.github.io/graphql/June2018/#sec-Errors)) i jak powinny być obsługiwane przez narzędzia po stronie klienta. Ponadto można również uzupełnić je dokumentacją opartą na komentarzach.
+
+### Przykład błędu GraphQL
+
+> Ten przykład używa [SWAPI](https://graphql.org/swapi-graphql), API Star Wars.
+
+```graphql
+# should fail because id is not valid
+{
+ film(id: "1ZmlsbXM6MQ==") {
+ title
+ }
+}
+```
+
+```json
+{
+ "errors": [
+ {
+ "message": "No entry in local cache for https://swapi.co/api/films/.../",
+ "locations": [
+ {
+ "line": 2,
+ "column": 3
+ }
+ ],
+ "path": [
+ "film"
+ ]
+ }
+ ],
+ "data": {
+ "film": null
+ }
+}
+```
+
+### Cytat z bloga: "You have to tell your callers what errors can happen"
+
+Z bloga Joyent, w rankingu 1 dla słów kluczowych “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…
+
+### Przydatne narzędzie: Swagger Online Documentation Creator
+
+
diff --git a/sections/errorhandling/documentingusingswagger.russian.md b/sections/errorhandling/documentingusingswagger.russian.md
index 525d14897..f225e3ca8 100644
--- a/sections/errorhandling/documentingusingswagger.russian.md
+++ b/sections/errorhandling/documentingusingswagger.russian.md
@@ -49,4 +49,4 @@ API-интерфейсы REST возвращают результаты с ис
### Полезный инструмент: Swagger Online Documentation Creator
-
+
diff --git a/sections/errorhandling/failfast.basque.md b/sections/errorhandling/failfast.basque.md
new file mode 100644
index 000000000..927d5c4ba
--- /dev/null
+++ b/sections/errorhandling/failfast.basque.md
@@ -0,0 +1,71 @@
+# Huts eragin azkar, balidatu argudioak liburutegi dedikatu baten laguntzarekin
+
+### Azalpena
+
+Denok dakigu argudioak egiaztatzea eta azkar huts egitea garrantzitsua dela ezkutuko erroreak ekiditeko (ikusi ereduaren aurkako kodearen adibidea behean). Bestela, irakurri zerbait programazio esplizituaren eta babes programazioaren gainean. Errealitatean, hori ekiditeko ohitura daukagu, kodea idazteak suposatzen duen gogaikarritasuna dela eta (adibidez pentsatu posta elektronikoa eta datak bezalako alorrak dituen JSON objektu hierarkiko bat balioztatzea). Joi eta Validator bezalako liburutegiek asko leuntzen dute lan hori
+
+### Wikipedia: programazio defentsiboa
+
+Programazio defentsiboa softwarea eta iturburu kodea hobetzeko ikuspuntua da, kalitate orokorrari dagokionez, software errore eta arazo kopurua murriztuz. Iturburu kodea ulergarria izango bada, irakurgarria eta ulergarria izan behar da kode auditoria batean onartua izan dadin. Softwarea aurreikusteko moduko eran jokatzeko egin behar da, ustekabeko sarrerak edo erabiltzaile ekintzak gertatu arren
+
+### Kode adibidea: balioztatu JSON sarrera koplexua ‘Joi’ erabiliz
+
+```javascript
+var kideEskema = Joi.object().keys({
+ pasahitza: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
+ jaioteguna: Joi.number().integer().min(1900).max(2013),
+ postaElektronikoa: Joi.string().email(),
+});
+
+function kideBerriaGehitu(kideBerria) {
+ // lehenengo baieztapena dator
+ Joi.assert(kideBerria, kideEskema); //jaurti balioztatzeak huts egiten badu
+ // bestelako logika hemen
+}
+```
+
+### Anti eredua: balioztatze ezak errore kaskarrak dakartza
+
+
+Javascript
+
+```javascript
+// deskontua positiboa bada, bidali erabiltzailea bere deskontu tiketak inprimatzera
+function bidaliDeskontuTiketakInprimatzera(httpResponse, kidea, deskontua) {
+ if (deskontua != 0) {
+ httpResponse.redirect(`/deskontuInpresioBistaratzea/${kidea.id}`);
+ }
+}
+
+bidaliDeskontuTiketakInprimatzera(httpResponse, kiderenBat);
+// deskontu parametroa pasatzea ahaztuta, orduan zergatik bidali da erabiltzailea deskontu pantailara?
+```
+
+
+
+
+Typescript
+
+```typescript
+// deskontua positiboa bada bidali erabiltzailea bere deskontu tiketak inprimatzera
+function bidaliDeskontuTiketakInprimatzera(
+ httpResponse: Response,
+ kidea: Member,
+ deskontua: number
+) {
+ if (deskontua != 0) {
+ httpResponse.redirect(`/deskontuInpresioBistaratzea/${kidea.id}`);
+ }
+}
+
+bidaliDeskontuTiketakInprimatzera(httpResponse, kiderenBat, -12);
+// deskontu parametro negatiboa pasatu dugu, We passed a negative parameter discount, orduan zergatik bidali da erabiltzailea deskontu pantailara?
+```
+
+
+
+### Blog aipua: "Errore hauek zuzenean jaurti beharko zenituzke"
+
+Joyent bloga
+
+> Kasu degeneratu bat da norbaitek funtzio asinkrono bat callback gabe deitzea atzera deirik egin gabe. Errore horiek berehala jaurti beharko zenituzke programa apurtuta baitago eta hori arazteak gutxienez pila arrastoa eta errorearen lekuko fitxategia berreskuratzea eskatzen du. Hori egiteko, funtzioaren hasieran argudio guztien motak balioztatzea gomendatzen dugu
diff --git a/sections/errorhandling/failfast.french.md b/sections/errorhandling/failfast.french.md
new file mode 100644
index 000000000..a3af42ac3
--- /dev/null
+++ b/sections/errorhandling/failfast.french.md
@@ -0,0 +1,67 @@
+# Échouez rapidement, valider les arguments à l'aide d'une bibliothèque dédiée
+
+### Un paragraphe d'explication
+
+Nous savons tous combien il est important de vérifier les arguments et d'échouer rapidement pour éviter les bogues cachés (voir le contre exemple de code ci-dessous). Si ce n'est pas le cas, renseignez-vous sur la programmation explicite et la programmation défensive. En réalité, nous avons tendance à l'éviter en raison de la pénibilité de son codage (par exemple, pensez à valider un objet JSON hiérarchique avec des champs comme l'email et les dates) - des bibliothèques comme Joi et Validator transforment cette tâche fastidieuse en un jeu d'enfant.
+
+### Wikipedia : la programmation défensive
+
+La programmation défensive est une approche pour améliorer les logiciels et le code source, en termes de qualité générale - en réduisant le nombre de bogues et de problèmes logiciels. Rendre le code source compréhensible - le code source doit être lisible et compréhensible afin qu'il soit approuvé lors d'un audit de code. Faire en sorte que le logiciel se comporte de manière prévisible malgré des entrées ou des actions utilisateur inattendues.
+
+### Exemple de code : validation d'une entrée JSON complexe à l'aide de « Joi »
+
+```javascript
+const 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) {
+ // les vérifications sont faites en premier
+ Joi.assert(newMember, memberSchema); // lève une exception si la validation échoue
+ // d'autres logiques ici
+}
+```
+
+
+
+### Contre exemple de code : aucune validation ne donne de méchants bogues
+
+
+Javascript
+
+```javascript
+// si discount est positif, redirige l'utilisateur pour imprimer ses coupons de réduction
+function redirectToPrintDiscount(httpResponse, member, discount) {
+ if (discount != 0) {
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+ }
+}
+
+redirectToPrintDiscount(httpResponse, someMember);
+// J'ai oublié de passer le paramètre discount, pourquoi diable l'utilisateur a-t-il été redirigé vers l'écran de remise ?
+```
+
+
+
+Typescript
+
+```typescript
+// si discount est positif, redirige l'utilisateur pour imprimer ses coupons de réduction
+function redirectToPrintDiscount(httpResponse: Response, member: Member, discount: number) {
+ if (discount != 0) {
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+ }
+}
+
+redirectToPrintDiscount(httpResponse, someMember, -12);
+// Nous avons passé un paramètre discount négatif, pourquoi diable l'utilisateur a-t-il été redirigé vers l'écran de remise ?
+```
+
+
+### Citation de blog : « Vous devriez rejeter ces erreurs immédiatement »
+
+ Extrait du blog de Joyent
+
+ > Un cas de dégénération est celui où quelqu'un appelle une fonction asynchrone mais ne passe pas de fonction de rappel. Vous devriez rejeter ces erreurs immédiatement car le programme est cassé et la meilleure chance de le déboguer implique d'obtenir au moins une trace de pile et idéalement un fichier core au niveau de l'erreur. Pour ce faire, nous vous recommandons de valider les types de tous les arguments au début de la fonction.
diff --git a/sections/errorhandling/failfast.japanese.md b/sections/errorhandling/failfast.japanese.md
new file mode 100644
index 000000000..e61430e4e
--- /dev/null
+++ b/sections/errorhandling/failfast.japanese.md
@@ -0,0 +1,67 @@
+# 専用のライブラリを利用して引数の検証を高速に行う
+
+### 一段落説明
+
+隠れたバグを避けるためには、引数をチェックすること、そして高速に失敗することが重要であると誰もが知っています(下記のアンチパターンコード例を参照)。もし知らないのであれば、明示的プログラミングと防御的プログラミングについて読んでみてください。実際には、コーディングをするのが面倒なので避けがちですが(例えば、メールアドレスや日時のようなフィールドを持つ階層的な JSON オブジェクトの検証をすることを考えてみてください)、Joi や Validator のようなライブラリはこの面倒なタスクを簡単にしてくれます。
+
+### Wikipedia「防御的プログラミング」
+
+防御的プログラミング(Defensive programming)は、ソフトウェアのバグや問題の数を減少させるという一般的な品質の観点において、ソフトウェアやソースコードを改善するためのアプローチです。ソースコードを理解しやすいものにすること ー コード監査で承認されるように、ソースコードは可読性が高く、わかりやすいものであるべきです。想定外の入力やユーザーアクションに対しても、ソフトウェアに予測可能な挙動をさせるべきです。
+
+### コード例: 「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) {
+ // アサーションがまず最初に来る
+ Joi.assert(newMember, memberSchema); // もし検証が失敗したら例外を投げます
+ // その他のロジックがここに来ます
+}
+```
+
+
+
+### アンチパターン: 検証をしないと厄介なバグが発生する
+
+
+Javascript
+
+```javascript
+// もし discount が正の値なら、ユーザーを割引クーポンを発行するためにユーザーをリダイレクトさせましょう
+function redirectToPrintDiscount(httpResponse, member, discount) {
+ if (discount != 0) {
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+ }
+}
+
+redirectToPrintDiscount(httpResponse, someMember);
+// discount パラメータを渡すのを忘れてしまいました。一体なぜユーザーは割引クーポン発行画面へリダイレクトされたのでしょうか?
+```
+
+
+
+Typescript
+
+```typescript
+// もし discount が正の値なら、ユーザーを割引クーポンを発行するためにユーザーをリダイレクトさせましょう
+function redirectToPrintDiscount(httpResponse: Response, member: Member, discount: number) {
+ if (discount != 0) {
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+ }
+}
+
+redirectToPrintDiscount(httpResponse, someMember, -12);
+// discount パラメータとして負の値を渡しました。一体なぜユーザーは割引クーポン発行画面へリダイレクトされたのでしょうか?
+```
+
+
+### ブログ引用: "You should throw these errors immediately"(エラーは直ちに投げるべきです)
+
+ブログ Joyentより
+
+> 悪化したケースとして、非同期関数を呼び出したもののコールバックを渡さなかった場合があります。プログラムは壊れていますし、デバッグに最適なのは少なくともスタックトレースを取得、理想的にはエラーが発生した地点のコアファイルを取得することなので、このようなエラーは直ちに投げるべきです。これを行うために、関数の開始時にすべての引数の型を検証することをおすすめします。
diff --git a/sections/errorhandling/failfast.md b/sections/errorhandling/failfast.md
index 805d7ac9b..486ae45d5 100644
--- a/sections/errorhandling/failfast.md
+++ b/sections/errorhandling/failfast.md
@@ -11,7 +11,7 @@ Defensive programming is an approach to improve software and source code, in ter
### Code example: validating complex JSON input using ‘Joi’
```javascript
-var memberSchema = Joi.object().keys({
+const 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()
diff --git a/sections/errorhandling/failfast.polish.md b/sections/errorhandling/failfast.polish.md
new file mode 100644
index 000000000..57ff9de22
--- /dev/null
+++ b/sections/errorhandling/failfast.polish.md
@@ -0,0 +1,67 @@
+# Szybko się nie powiedzie, sprawdź poprawność argumentów za pomocą dedykowanej biblioteki
+
+### Wyjaśnienie jednym akapitem
+
+Wszyscy wiemy, jak sprawdzanie argumentów i szybkie niepowodzenie jest ważne, aby uniknąć ukrytych błędów (patrz przykład kodu anty-wzorca poniżej). Jeśli nie, przeczytaj o programowaniu jawnym i programowaniu defensywnym. W rzeczywistości staramy się go unikać ze względu na irytację związaną z jego kodowaniem (np. myśl o sprawdzeniu poprawności hierarchicznego obiektu JSON za pomocą pól takich jak e-mail i daty) - biblioteki takie jak Joi i Validator zmieniają to żmudne zadanie w bryłę.
+
+### Wikipedia: Defensive Programming
+
+Programowanie defensywne to podejście do ulepszania oprogramowania i kodu źródłowego pod względem ogólnej jakości - zmniejszające liczbę błędów oprogramowania i problemów. Uczynienie kodu źródłowego zrozumiałym - kod źródłowy powinien być czytelny i zrozumiały, aby został zatwierdzony podczas audytu kodu. Sprawiając, że oprogramowanie zachowuje się w przewidywalny sposób, pomimo nieoczekiwanych danych wejściowych lub działań użytkownika.
+
+### Przykład kodu: sprawdzanie poprawności złożonego wejścia JSON przy użyciu ‘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
+}
+```
+
+
+
+### Antywzorzec: brak sprawdzania poprawności powoduje nieprzyjemne błędy
+
+
+Javascript
+
+```javascript
+// if the discount is positive let's then redirect the user to print 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?
+```
+
+
+
+Typescript
+
+```typescript
+// if the discount is positive let's then redirect the user to print his discount coupons
+function redirectToPrintDiscount(httpResponse: Response, member: Member, discount: number) {
+ if (discount != 0) {
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+ }
+}
+
+redirectToPrintDiscount(httpResponse, someMember, -12);
+// We passed a negative parameter discount, why the heck was the user redirected to the discount screen?
+```
+
+
+### Cytat z Bloga: "You should throw these errors immediately"
+
+Z bloga: 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/failfast.russian.md b/sections/errorhandling/failfast.russian.md
index b48416298..a95883589 100644
--- a/sections/errorhandling/failfast.russian.md
+++ b/sections/errorhandling/failfast.russian.md
@@ -22,11 +22,15 @@ function addNewMember(newMember) {
Joi.assert(newMember, memberSchema); //throws if validation fails
// other logic here
}
-
```
+
+
### Анти-шаблон: проверка не приводит к неприятным ошибкам
+
+Javascript
+
```javascript
// if the discount is positive let's then redirect the user to print his discount coupons
function redirectToPrintDiscount(httpResponse, member, discount) {
@@ -37,8 +41,24 @@ function redirectToPrintDiscount(httpResponse, member, discount) {
redirectToPrintDiscount(httpResponse, someMember);
// forgot to pass the parameter discount, why the heck was the user redirected to the discount screen?
+```
+
+
+
+Typescript
+
+```typescript
+// if the discount is positive let's then redirect the user to print his discount coupons
+function redirectToPrintDiscount(httpResponse: Response, member: Member, discount: number) {
+ if (discount != 0) {
+ httpResponse.redirect(`/discountPrintView/${member.id}`);
+ }
+}
+redirectToPrintDiscount(httpResponse, someMember, -12);
+// We passed a negative parameter discount, why the heck was the user redirected to the discount screen?
```
+
### Цитата блога: "Вы должны немедленно выбросить эти ошибки"
diff --git a/sections/errorhandling/monitoring.french.md b/sections/errorhandling/monitoring.french.md
new file mode 100644
index 000000000..85071884a
--- /dev/null
+++ b/sections/errorhandling/monitoring.french.md
@@ -0,0 +1,17 @@
+# Surveillance
+
+### Un paragraphe d'explication
+
+> Au niveau le plus élémentaire, la surveillance signifie que vous pouvez facilement identifier quand de mauvaises choses se produisent en production. Par exemple, en étant averti par email ou Slack. Le défi est de choisir le bon ensemble d'outils qui répondra à vos besoins sans vous ruiner. Permettez-moi de vous suggérer de commencer par définir l'ensemble des paramètres de base qui doivent être surveillés pour garantir un état sain - CPU, RAM du serveur, RAM du processus de Node (moins de 1,4 GB), le nombre d'erreurs dans la dernière minute, le nombre de redémarrages du processus , temps de réponse moyen. Ensuite, passez en revue certaines fonctionnalités avancées dont vous pourriez avoir envie et ajoutez-les à votre liste de souhaits. Quelques exemples d'une fonction de surveillance de luxe : profilage de base de données, mesure interservices (c.-à-d. mesurer les transactions commerciales), intégration frontale, exposer les données brutes aux clients BI personnalisés, notifications Slack et bien d'autres.
+
+La réalisation des fonctionnalités avancées nécessite une configuration longue ou l'achat d'un produit commercial tel que Datadog, newrelic et similaires. Malheureusement, atteindre même les bases n'est pas une promenade de santé car certaines mesures sont liées au matériel (CPU) et d'autres vivent dans le processus de Node (erreurs internes), donc tous les outils simples nécessitent une configuration supplémentaire. Par exemple, les solutions de surveillance des fournisseurs de cloud (par exemple AWS CloudWatch, Google StackDriver) vous informeront immédiatement de la métrique du matériel, mais rien du comportement de l'application interne. À l'autre extrémité, les solutions basées sur les journaux telles que ElasticSearch manquent par défaut de la vue matérielle. La solution consiste à étendre votre choix avec des mesures manquantes, par exemple, un choix populaire consiste à envoyer des journaux d'application à la pile Elastic et à configurer un agent supplémentaire (par exemple Beat) pour partager des informations liées au matériel pour obtenir une image complète.
+
+### Citation de blog : « Nous avons un problème avec les promesses"
+
+ Extrait du blog de pouchdb.com classé en 11eme position pour les mots clés “Node Promises”
+
+ > … Nous vous recommandons de surveiller ces signaux pour tous vos services : Taux d'erreur : parce que les erreurs sont confrontées à l'utilisateur et affectent immédiatement vos clients.
+Temps de réponse : car la latence affecte directement vos clients et votre entreprise.
+Débit : le trafic vous aide à comprendre le contexte de l'augmentation des taux d'erreur et de la latence également.
+Saturation : il indique à quel point votre service est « saturé ». Si l'utilisation du processeur est de 90%, votre système peut-il gérer plus de trafic ?
+…
diff --git a/sections/errorhandling/monitoring.japanese.md b/sections/errorhandling/monitoring.japanese.md
new file mode 100644
index 000000000..57213a831
--- /dev/null
+++ b/sections/errorhandling/monitoring.japanese.md
@@ -0,0 +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?
+…
diff --git a/sections/errorhandling/operationalvsprogrammererror.basque.md b/sections/errorhandling/operationalvsprogrammererror.basque.md
new file mode 100644
index 000000000..7fb594357
--- /dev/null
+++ b/sections/errorhandling/operationalvsprogrammererror.basque.md
@@ -0,0 +1,100 @@
+# Bereizi eragiketa erroreak eta programazio erroreak
+
+### Azalpena
+
+Ondorengo bi errore mota hauek bereizteak zure aplikazioaren matxura denbora gutxitu eta programazio errore eroak ekiditen lagunduko dizu. Batetik, eragiketa erroreak daude, gertatutako arazoa eta haren ondorioak ulertzen dituzunean (adibidez, HTTP zerbitzu bati egindako deiak huts egitea, konexio arazoak direla eta. Bestetik, errorea zergatik eta nondik etorri den ez dakizun egoerei programatze errore deritze (balio zehaztugabe bat irakurtzen saiatzen den kodea edo memoria ihes egiten dion datu basea izan daitezke). Eragiketa erroreak besteen aldean kudea errazak dira, eta normalean nahikoa izaten da errorea erregistratzea. Gauzak konplikatuagoak izan daitezke garatzaile errore bat tupustean agertzen denean, aplikazioa egoera aldakorrean aurki baitaiteke. Horrelakoetan, aplikazioa berrabiarazi baino irtenbide hoberik ez duzu
+
+### Kode adibidea: erroreak eragiketa errore (konfiantzazko) bihurtu
+
+
+Javascript
+
+```javascript
+// errore objektu bat eragiketa errore bihurtu
+const nireErrorea = new Error(
+ "Nola gehi dezaket produktu bat baliorik ez duenean?"
+);
+nireErrorea.funtzionatzenDu = true;
+
+// edota errore eraikitzaile zentralizaturen bat erabiltzen baduzu (begiratu beste adibide batzuk "Erabili soilik “Errorea” objektu kapsulatua", 2.2, atalean)
+class AppErrorea {
+ constructor(ohikoMota, deskribapena, funtzionatzenDu) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.ohikoMota = ohikoMota;
+ this.deskribapena = deskribapena;
+ this.funtzionatzenDu = funtzionatzenDu;
+ }
+}
+
+throw new AppErrorea(
+ erroreKudeatzailea.ohikoErroreak.SarreraOkerra,
+ "Deskribatu hemen gertatutakoa",
+ true
+);
+```
+
+
+
+
+Typescript
+
+```typescript
+// errore eraikitzaile zentralizatu batzuk (begiratu beste adibide batzuk "Erabili soilik “Errorea” objektu kapsulatua", 2.2, atalean)
+export class AppErrorea extends Error {
+ public readonly ohikoMota: string;
+ public readonly funtzionatzenDu: boolean;
+
+ constructor(
+ ohikoMota: string,
+ description: string,
+ funtzionatzenDu: boolean
+ ) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
+
+ this.ohikoMota = ohikoMota;
+ this.funtzionatzenDu = funtzionatzenDu;
+
+ Error.atzemanErrorePila(this);
+ }
+}
+
+// errore objektu bat eragiketa errore bihurtu (true)
+throw new AppErrorea(
+ erroreKudeatzailea.ohikoErroreak.SarreraOkerra,
+ "Deskribatu hemen gertatutakoa",
+ true
+);
+```
+
+
+
+### Blog aipua: "Programatzaileen erroreak programatze erroreak dira programan"
+
+Joyent blogeko “Node.js errore kudeaketa" hitz gako bati esker sailkatua
+
+> …Programatzaile erroreak gainditzeko modurik hoberena berehala huts eragitea da. Huts egiteren bat gertatzean automatikoki berrekingo dituen berrekite sistemaren bat erabiliz exekutatu beharko zenituzten zure programak. Berrekite sistemei esker, huts egitea da modurik azkarrena programatzaile errore iragankorrak gertatzean zerbitzua berreskuratzeko modu fidagarrian…
+
+### Blog aipua: "Alde egiteko modu segururik ez dago zehaztugabeko egoera hauskorrik sortu gabe"
+
+Node.js dokumentazio ofiziala
+
+> …Throw-ek JavaScripten nola funtzionatzen duen kontuan izanda, ez dago ia inoiz ataza bati modu seguruan “bertan behera utzitako puntuan segida ematerik” erreferentziak galdu gabe edota bestelako egoera hauskor zehaztugaberik sortu gabe. Jaurtitako erroreei erantzuteko modurik seguruena prozesua gelditzea da. Jakina, web zerbitzari arruntetan, konexio ugari eduki ahal ditzakezu irekita, eta ez da zentzuzkoa tupustean haiek ixtea beste batek eragindako errore batengatik. Planteamendu hoberena da errorea bidali duen eskariari errore erantzun bat bidaltzea, besteei beren atazak bukatzeko denbora emanez, eta eskari berriei kasu egiteari utzi prozesu horretan
+
+### Blog aipua: "Bestela zure aplikazioaren egoera arriskuan jar dezakezu"
+
+debugable.com blogeko “Node.js atzeman gabeko salbuespena" 3 hitz gakoari esker sailkatua
+
+> …Beraz, baldin eta benetan zer egiten ari zaren jakinez gero, “uncaughtException” salbuespen gertaera jaso ostean zure zerbitzuari berrekin beharko zenioke, behar bezala berrekin ere. Bestela, zure aplikazioaren egoera arriskuan jar dezakezu, edota haren liburutegiak aldakor bihurtuarazi, mota guztietako errore zoroak eraginez…
+
+### Blog aipua: "Errore kudeaketaren inguruko hiru ideia eskola daude"
+
+JS Recipes bloga
+
+> …Errore kudeaketaren inguruko hiru ideia eskola daude:
+
+1. Utzi aplikazioak huts egin dezan eta ondoren berrekin.
+2. Kudeatu errore posible guztiak eta inoiz ez huts egin.
+3. Bien arteko planteamendu bat.
diff --git a/sections/errorhandling/operationalvsprogrammererror.chinese.md b/sections/errorhandling/operationalvsprogrammererror.chinese.md
index c8c070e49..768dbb79f 100644
--- a/sections/errorhandling/operationalvsprogrammererror.chinese.md
+++ b/sections/errorhandling/operationalvsprogrammererror.chinese.md
@@ -34,8 +34,7 @@ throw new appError(errorManagement.commonErrors.InvalidInput, "Describe here wha
### 博客引用: "不伴随着创建一些未定义的脆性状态,没有安全的方式可以离开"
摘自Node.JS官方文档
- > …在 JavaScript 中, throw的工作性质, 几乎没有任何方法可以安全地"在你离开的地方重新捡起",没有泄漏引用, 或者创建一些其他形式的未定义的脆性状态,。对引发的错误进行响应的最安全方法是关闭进程。当然, 在普通的 web 服务器中, 您可能会打开许多连接, 并且由于其他人触发了错误而突然关闭这些连接是不合理的。更好的方法是向触发错误的请求发送错误响应, 同时让其他人在正常时间内完成, 并停止侦听该工作人员中的新请求。
-
+ > …从 JavaScript throw 的工作原理上讲, 几乎没有任何方法可以安全地“在你跌倒的地方重新爬起来”而不引发泄漏且不创建一些其他形式的未定义的脆性状态。响应(未定义的)抛出错误的最安全方法是关闭进程。当然, 通常 web 服务器可能会有许多连接正在通信, 由于某个人触发了错误而突然关闭那些连接是不合理的。更好的方法是让该工作进程向触发错误的请求发送错误响应, 同时保持其它请求正常进行直至完成, 并停止侦听的新的请求。(译者注:为优雅重启做准备)
### 博客引用: "否则,您置您应用的状态于风险之中"
摘自博客 debugable.com, 对于关键字“Node.JS uncaught exception”排名第3
diff --git a/sections/errorhandling/operationalvsprogrammererror.french.md b/sections/errorhandling/operationalvsprogrammererror.french.md
new file mode 100644
index 000000000..165d8bb65
--- /dev/null
+++ b/sections/errorhandling/operationalvsprogrammererror.french.md
@@ -0,0 +1,85 @@
+# Distinguez les erreurs opérationnelles des erreurs de programmation
+
+### Un paragraphe d'explication
+
+La distinction des deux types d'erreur suivants minimisera l'indisponibilité de votre application et aidera à éviter les bogues fous : les erreurs opérationnelles se rapportent à des situations où vous comprenez ce qui s'est passé et son impact - par exemple, une requête vers un service HTTP a échoué en raison d'un problème de connexion. D'un autre côté, les erreurs de programmation se rapportent à des cas où vous n'avez aucune idée de la raison et parfois de l'origine d'une erreur - il peut s'agir d'un code qui a tenté de lire une valeur non définie ou d'un pool de connexions DB qui a une fuite mémoire. Les erreurs opérationnelles sont relativement faciles à gérer - la journalisation de l'erreur suffit généralement. Les choses deviennent compliquées lorsqu'une erreur de programmation apparaît, l'application peut être dans un état incohérent et il n'y a rien de mieux que de redémarrer en douceur.
+
+### Exemple de code - marquer une erreur comme opérationnelle (fiable)
+
+
+Javascript
+
+```javascript
+// marquer un objet Error comme opérationnel
+const myError = new Error('Comment puis-je ajouter un nouveau produit lorsqu\'aucune valeur n\'est fournie ?');
+myError.isOperational = true;
+
+// ou si vous utilisez une fabrique d'erreurs centralisée (voir d'autres exemples pour le point "Utilisez uniquement l'objet intégré Error")
+class AppError {
+ constructor (commonType, description, isOperational) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.commonType = commonType;
+ this.description = description;
+ this.isOperational = isOperational;
+ }
+};
+
+throw new AppError(errorManagement.commonErrors.InvalidInput, 'Décrivez ici ce qui s\'est passé', true);
+
+```
+
+
+
+Typescript
+
+```typescript
+// une fabrique d'erreurs centralisée (voir d'autres exemples pour le point "Utilisez uniquement l'objet intégré Error")
+export class AppError extends Error {
+ public readonly commonType: string;
+ public readonly isOperational: boolean;
+
+ constructor(commonType: string, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // restaure la chaîne du prototype
+
+ this.commonType = commonType;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// marquer un objet Error comme opérationnel (true)
+throw new AppError(errorManagement.commonErrors.InvalidInput, 'Describe here what happened', true);
+
+```
+
+
+### Citation de blog : « Les erreurs du programmeur sont des bogues dans le programme »
+
+Extrait du blog de Joyent classé en 1ere position pour les mots clés “Node.js error handling”
+
+ > …La meilleure façon de récupérer des erreurs de programmation est de planter immédiatement. Vous devez exécuter vos programmes à l'aide d'un « outil de redémarrage » qui redémarrera automatiquement le programme en cas de plantage. Avec un « outil de redémarrage » en place, le plantage est le moyen le plus rapide de restaurer un service fiable face à une erreur de programmation transitoire…
+
+### Citation de blog : « Aucune solution sûre pour sortir sans créer un état fragile indéfini »
+
+Extrait de la documentation officielle de Node.js
+
+ > …De par la nature même du fonctionnement de throw en JavaScript, il n'y a presque jamais aucun moyen de « reprendre là où vous vous étiez arrêté » en toute sécurité, sans fuite de références, ou sans créer une autre sorte d'état fragile non défini. Le moyen le plus sûr de répondre à une erreur levée est d'arrêter le processus. Bien sûr, dans un serveur Web normal, de nombreuses connexions peuvent être ouvertes et il n'est pas raisonnable de les fermer brutalement car une erreur a été déclenchée par quelqu'un d'autre. La meilleure approche consiste à envoyer une réponse d'erreur à la demande qui a déclenché l'erreur tout en laissant les autres se terminer dans leur temps normal et à cesser d'écouter les nouvelles demandes de ce processus.
+
+### Citation de blog : « Sinon, vous risquez l'état de votre application »
+
+Extrait du blog de debugable.com classé en 3ème position pour les mots clés “Node.js uncaught exception”
+
+ > …Donc, à moins que vous sachiez vraiment ce que vous faites, vous devez effectuer un redémarrage en douceur de votre service après avoir reçu un événement d'exception « uncaughtException ». Sinon, vous risquez que l'état de votre application, ou celui des bibliothèques tierces, ne devienne incohérent, conduisant à toutes sortes de bugs fous…
+
+### Citation de blog : « Il y a principalement trois écoles de réflexion sur la gestion des erreurs »
+
+Extrait du blog de JS Recipes
+
+> …Il y a principalement trois écoles de réflexion sur la gestion des erreurs :
+1. Laissez l'application se planter et redémarrez-la.
+2. Gérez toutes les erreurs possibles et ne plantez jamais.
+3. Une approche équilibrée entre les deux
diff --git a/sections/errorhandling/operationalvsprogrammererror.japanese.md b/sections/errorhandling/operationalvsprogrammererror.japanese.md
new file mode 100644
index 000000000..7770451e3
--- /dev/null
+++ b/sections/errorhandling/operationalvsprogrammererror.japanese.md
@@ -0,0 +1,85 @@
+# 操作上のエラーとプログラマーのエラーを区別する
+
+### 一段落説明
+
+操作上のエラーとプログラマーのエラーという 2 つのエラーを区別することは、アプリケーションのダウンタイムを最小化し、とんでもないバグを避ける手助けになります: 操作上のエラーは、発生したことおよびその影響を理解できるエラー状態のことを指します ー 例えば、接続の問題が原因となってある HTTP サービスに対するクエリが失敗した状況などです。一方で、プログラマーのエラーは、エラーがなぜ起こったのか、そしてどこで発生したのかわからないエラー状態のことを指します ー これは、あるコードが未定義の値を参照している場合や、DB コネクションプールがメモリをリークしている場合などがあります。操作上のエラーは比較的処理が簡単です ー 通常、エラーをロギングするだけで十分です。プログラマーのエラーが発生した場合は厄介であり、アプリケーションが不安定な状況に陥り、すぐさま再起動するしかありません。
+
+### コード例 – 操作上のエラーとしてマークする
+
+
+Javascript
+
+```javascript
+// 操作上のエラーとしてエラーオブジェクトをマークする例
+const myError = new Error('How can I add new product when no value provided?');
+myError.isOperational = true;
+
+// もしくは、集中化されたエラーファクトリーを使っている場合の例(他の例は「組み込みのエラーオブジェクトのみを使用する」のセクションをご覧ください)
+class AppError {
+ constructor (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);
+
+```
+
+
+
+Typescript
+
+```typescript
+// 集中化されたエラーファクトリーを使っている場合の例(他の例は「組み込みのエラーオブジェクトのみを使用する」のセクションをご覧ください)
+export class AppError extends Error {
+ public readonly commonType: string;
+ public readonly isOperational: boolean;
+
+ constructor(commonType: string, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // プロトタイプチェーンを復元する
+
+ this.commonType = commonType;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// 操作上のエラーとしてエラーオブジェクトをマーク (true の部分)
+throw new AppError(errorManagement.commonErrors.InvalidInput, 'Describe here what happened', true);
+
+```
+
+
+### ブログ引用: "Programmer errors are bugs in the program"(プログラマーのエラーはプログラムにおけるバグです)
+
+ブログ Joyent(“Node.js error handling”というキーワードで 1 位)より
+
+ > …プログラマーのエラーから復帰する最も良い方法は直ちにクラッシュさせることです。プログラムがクラッシュしたときに自動的に再起動してくれるリスターターを備えた、プログラムを動かすべきです。リスターターを備えている場合、一時的なプログラマーのエラーに直面した際に、安定したサービスへと復旧させるための一番手っ取り早い方法は、クラッシュさせることになります。
+
+### ブログ引用: "No safe way to leave without creating some undefined brittle state"(不明瞭で不安定な状態を作り出すことなしに、安全に中断する方法はありません)
+
+Node.js 公式ドキュメントより
+
+ > …JavaScript における throw の挙動の性質上、参照をリークさせたり、不明瞭で不安定な状態を作り出したりすることなく、安全に「中断したところから再開する」方法はほぼありません。投げられたエラーに対応する最も安全な方法は、プロセスをシャットダウンすることです。もちろん、通常のウェブサーバーでは、多くのコネクションがオープン状態になっているかもしれず、エラーが他の誰かによって引き起こされたからといって、それらを急にシャットダウンすることは合理的ではありません。より良いアプローチは、エラーの引き金となったリクエストにエラーレスポンスを送り、他のリクエストは通常の時間内に終了するようにして、そのワーカーにおいて新しいリクエストの受信を停止することです。
+
+### ブログ引用: "Otherwise you risk the state of your application"(さもなければアプリケーションの状態を危険にさらします)
+
+ブログ debugable.com(“Node.js uncaught exception”というキーワードで 3 位)より
+
+ > …ですから、自分が本当に何をしているのか理解していない限り、「uncaughtException」例外イベント受信後は直ちにサービスを再起動すべきです。そうしないと、アプリケーションの状態やサードパーティのライブラリの状態が一貫性を失い、あらゆる種類のとんでもないバグにつながる危険性があります。
+
+### ブログ引用: "There are three schools of thoughts on error handling"(エラー処理について、3 つの考え方があります)
+
+ブログ JS Recipes より
+
+> …エラー処理について、主に以下の3つの考え方があります:
+1. アプリケーションをクラッシュさせ、再起動させる
+2. 起こりうるすべてのエラーを処理し、決してクラッシュさせない
+3. 上記 2 つをバランスよく取り入れたアプローチ
diff --git a/sections/errorhandling/operationalvsprogrammererror.korean.md b/sections/errorhandling/operationalvsprogrammererror.korean.md
index a6175c23a..3d263886c 100644
--- a/sections/errorhandling/operationalvsprogrammererror.korean.md
+++ b/sections/errorhandling/operationalvsprogrammererror.korean.md
@@ -1,10 +1,10 @@
-# Distinguish operational vs programmer errors
+# 동작상의 에러 vs 프로그래머 에러
-### 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
+다음 두 가지의 에러 유형을 구별하면 앱 다운타임(downtime)을 최소화하고 심각한 버그를 방지하는데 도움이 될 것이다: 동작 오류는 발생한 일과 영향에 대해 어떤 상황인지 말한다 – 예를 들면, 연결 문제로 인한 일부 HTTP 서비스 쿼리 실패가 있다. 반면에, 프로그래머 에러는 어디에서 에러가 발생했는지 왜 발생했는지 모르는 경우를 말한다 – 이것은 정의되지 않은 값이나 메모리 누수되는 데이터베이스 연결 풀(connection pool)을 읽으려는 코드일 수 있다. 동작 상의 에러는 비교적 다루기 쉽다 – 보통은 에러를 기록하면 충분하다. 프로그래머 에러가 발생하면, 응용 프로그램이 일관된 상태가 아닐 수도 있으며 이 땐 다시 시작하는 것보다 더 좋은 방법은 없다
-### Code Example – marking an error as operational (trusted)
+### 코드 예시 – 동작상의 에러 표시 (신뢰됨)
```javascript
// marking an error object as operational
@@ -26,29 +26,29 @@ throw new AppError(errorManagement.commonErrors.InvalidInput, "Describe here wha
```
-### Blog Quote: "Programmer errors are bugs in the program"
+### 블로그 인용: "프로그램에서 프로그래머 에러는 버그다"
-From the blog, Joyent ranked 1 for the keywords “Node.js error handling”
+Joyent 블로그에서 "Node.js 에러 처리" 키워드 1위에 위치했다
- > …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…
+ > …프로그래머 에러를 복구하는 가장 좋은 방법은 즉시 충돌하는 것이다. 충돌 시 자동으로 프로그램을 다시 시작하는 리스타터(restarter)를 사용하여 프로그램을 실행해야 한다. 리스타터(restarter)를 사용하는 경우, 일시적인 프로그래머 오류에 직면하면 신뢰할 수 있는 서비스를 복구하는 가장 빠른 방법은 충돌이다…
-### Blog Quote: "No safe way to leave without creating some undefined brittle state"
+### 블로그 인용: "정의되지 않은 취약 상태를 만들지 않고 떠나는 안전한 방법은 없다"
-From Node.js official documentation
+Node.js 공식문서에서
- > …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.
+ > …자바스크립트에서 던지기(throw) 방식의 특성상, 정의되지 않은 종류의 취약 상태를 만들거나 참조 누수 없이는, 안전하게 "중단한 곳에서 픽업(pick up)" 할 수 있는 방법은 거의 없다. 던져진 에러를 처리하는 가장 안전한 방법은 프로세스를 종료하는 것이다. 물론, 일반적인 웹 서버에서는 많은 연결이 열려 있을 수 있으며, 다른 누군가에 의해 오류가 발생했을 수도 있기 때문에 갑자기 연결을 종료하는 것은 적절하지 않다. 더 나은 방법은 다른 사람들이 정상적인 시간에 완료할 수 있도록 하면서 에러를 발생시킨 요청에 대한 에러 응답을 보내고, 새 요청에 대한 응답을 중지하는 것이다.
-### Blog Quote: "Otherwise you risk the state of your application"
+### 블로그 인용: "그렇지 않으면 당신의 애플리케이션 상태가 위험해질 수 있음"
-From the blog, debugable.com ranked 3 for the keywords “Node.js uncaught exception”
+debugable.com 블로그에서 "Node.js 예상치 못한 예외 처리" 키워드 3위에 위치했다
- > …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…
+ > …그래서, 당신이 정말로 무엇을 하고 있는 지 모른다면, "예상치 못한 예외 처리(uncaughtException)" 예외 이벤트를 받은 후 서비스를 다시 시작해야한다. 그렇지 않으면, 애플리케이션 상태나 제 3자 라이브러리의 상태가 일관되지 않아 모든 종류의 심각한 버그가 발생할 위험이 있다…
-### Blog Quote: "There are three schools of thoughts on error handling"
+### 블로그 인용: "에러 처리에는 주로 세 가지 방법이 있다"
-From the blog: JS Recipes
+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
+> …에러 처리에는 주로 세 가지 방법이 있다:
+1. 애플리케이션을 중지하고 다시 시작하기.
+2. 가능한 모든 에러를 처리하고 충돌하지 않게 하기.
+3. 이 두가지 사이의 균형잡힌 접근
\ No newline at end of file
diff --git a/sections/errorhandling/operationalvsprogrammererror.md b/sections/errorhandling/operationalvsprogrammererror.md
index 69ccee2c3..162e09495 100644
--- a/sections/errorhandling/operationalvsprogrammererror.md
+++ b/sections/errorhandling/operationalvsprogrammererror.md
@@ -80,6 +80,6 @@ From the blog, debugable.com ranked 3 for the keywords “Node.js uncaught excep
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
+>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/operationalvsprogrammererror.polish.md b/sections/errorhandling/operationalvsprogrammererror.polish.md
new file mode 100644
index 000000000..f4eb15304
--- /dev/null
+++ b/sections/errorhandling/operationalvsprogrammererror.polish.md
@@ -0,0 +1,85 @@
+# Rozróżnij błędy operacyjne i programistyczne
+
+### Wyjaśnienie jednym akapitem
+
+Rozróżnienie następujących dwóch typów błędów zminimalizuje przestoje aplikacji i pomoże uniknąć szalonych błędów: Błędy operacyjne odnoszą się do sytuacji, w których rozumiesz, co się stało i ich wpływ - na przykład zapytanie do jakiejś usługi HTTP nie powiodło się z powodu problemu z połączeniem. Z drugiej strony błędy programisty odnoszą się do przypadków, w których nie masz pojęcia, dlaczego, a czasem skąd pochodzi błąd - może to być jakiś kod, który próbował odczytać niezdefiniowaną wartość lub pula połączeń BD, z której wycieka pamięć. Błędy operacyjne są stosunkowo łatwe w obsłudze - zwykle wystarczy zarejestrować błąd. Gdy pojawia się błąd programisty, rzeczy stają się zagmatwane, aplikacja może być niespójna i nie ma nic lepszego niż ją po prostu zrestartować.
+
+### Przykład kodu - oznaczenie błędu jako działającego (zaufanego)
+
+
+Javascript
+
+```javascript
+// marking an error object as operational
+const 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")
+class AppError {
+ constructor (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);
+
+```
+
+
+
+Typescript
+
+```typescript
+// some centralized error factory (see other examples at the bullet "Use only the built-in Error object")
+export class AppError extends Error {
+ public readonly commonType: string;
+ public readonly isOperational: boolean;
+
+ constructor(commonType: string, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
+
+ this.commonType = commonType;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// marking an error object as operational (true)
+throw new AppError(errorManagement.commonErrors.InvalidInput, 'Describe here what happened', true);
+
+```
+
+
+### Cytat z Bloga: "Programmer errors are bugs in the program"
+
+Z bloga, 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…
+
+### Cytat z Bloga: "No safe way to leave without creating some undefined brittle state"
+
+Z oficjalnej dokumentacji Node.js
+
+ > …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.
+
+### Cytat z Bloga: "Otherwise you risk the state of your application"
+
+Z bloga, 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…
+
+### Cytat z Bloga: "There are three schools of thoughts on error handling"
+
+Z bloga: 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/operationalvsprogrammererror.russian.md b/sections/errorhandling/operationalvsprogrammererror.russian.md
index b4942cb1c..bfb78c40d 100644
--- a/sections/errorhandling/operationalvsprogrammererror.russian.md
+++ b/sections/errorhandling/operationalvsprogrammererror.russian.md
@@ -1,17 +1,20 @@
-# Различайте операционные и программистские ошибки
+# Различайте операционные ошибки и ошибки программиста
### Объяснение в один абзац
-Различение следующих двух типов ошибок минимизирует время простоя вашего приложения и помогает избежать сумасшедших ошибок: Операционные ошибки относятся к ситуациям, когда вы понимаете, что произошло, и влияние этого - например, запрос к какой-либо службе HTTP не выполнен из-за проблемы с подключением. С другой стороны, ошибки программиста относятся к случаям, когда вы не знаете, почему, а иногда и откуда возникла ошибка - это может быть какой-то код, который пытался прочитать неопределенное значение или пул соединений с БД, который приводит к утечке памяти. Операционные ошибки относительно легко обрабатываются - обычно достаточно регистрации ошибки. Вещи становятся неприятными, когда появляется ошибка программиста, приложение может быть в несовместимом состоянии, и нет ничего лучше, чем перезапуск изящно.
+Разделение ошибок на эти два типа минимизирует время простоя вашего приложения и помогает избежать сумасшедших ошибок: операционные ошибки относятся к ситуациям, когда вы понимаете происходящее и влияние ошибки на программу. Например, запрос к какой-нибудь службе HTTP не выполнен из-за проблемы с подключением. С другой стороны, ошибки программиста относятся к случаям, когда вы не знаете, почему, а иногда и откуда возникла ошибка - это может быть какой-то код, который пытался прочитать undefined-значение или код, который использует пул соединений с БД и приводит к утечке памяти. Операционные ошибки относительно легко обрабатываются - обычно достаточно логирования ошибки. Хуже становиться, когда появляется ошибка программиста, приложение может быть в несогласованном состоянии, и все, что вы можете сделать - перезапустить приложение.
-### Пример кода - пометка ошибки как рабочей (доверенной)
+### Пример кода - помечаем ошибку как операционную (доверенную)
+
+
+Javascript
```javascript
-// marking an error object as operational
-const myError = new Error("How can I add new product when no value provided?");
+// помечаем объект ошибки, как операционный
+const myError = new Error('Как мы можем добавить продукт, если значение не задано?');
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")
+// или, если вы используете централизированную фабрику ошибок (смотрите другие примеры в статье "Используйте только встроенный объект Error")
class AppError {
constructor (commonType, description, isOperational) {
Error.call(this);
@@ -22,33 +25,61 @@ class AppError {
}
};
-throw new AppError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
+throw new AppError(errorManagement.commonErrors.InvalidInput, 'Описываем, что произошло', true);
+
+```
+
+
+
+Typescript
+
+```typescript
+// или, если вы используете централизированную фабрику ошибок (смотрите другие примеры в статье "Используйте только встроенный объект Error")
+export class AppError extends Error {
+ public readonly commonType: string;
+ public readonly isOperational: boolean;
+
+ constructor(commonType: string, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // восстанавливаем цепочку прототипов
+
+ this.commonType = commonType;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// помечаем объект ошибки, как операционный (true)
+throw new AppError(errorManagement.commonErrors.InvalidInput, 'Describe here what happened', true);
```
+
### Цитата блога: "Ошибки программиста - это ошибки в программе"
-Из блога Джойент, занявшему 1 место по ключевым словам "Обработка ошибок Node.js"
+Из блога Джойент, занявшего 1 место по ключевым словам "Обработка ошибок Node.js"
-> … Лучший способ исправить ошибки программиста - это сразу же аварийно завершить работу. Вы должны запустить свои программы, используя перезапуск, который автоматически перезапустит программу в случае сбоя. С перезапуском на месте сбой является самым быстрым способом восстановления надежного сервиса перед лицом временной ошибки программиста …
+> … Лучший способ исправить ошибки программиста - это сразу же аварийно завершить работу. Вы должны запускать свои программы, используя сервис перезапуска, который автоматически будет перезапускать программу в случае сбоя. Сервис перезапуска является самым простым способом надежного восстановления сервиса при возникновении временной ошибки программиста…
-### Цитата из блога: "Нет безопасного способа уйти, не создав неопределенного хрупкого состояния"
+### Цитата из блога: "Нет безопасного способа продолжить без возникновения хрупкого undefined-состояния системы"
Из официальной документации Node.js
-> … По самой природе того, как throw работает в JavaScript, почти никогда не существует способа безопасно "выбрать то, на чем остановился", без утечки ссылок или создания какого-либо другого неопределенного хрупкого состояния. Самый безопасный способ отреагировать на возникшую ошибку - завершить процесс. Конечно, на обычном веб-сервере у вас может быть открыто много подключений, и нет смысла внезапно закрывать их, потому что кто-то еще вызвал ошибку. Лучший подход - отправить ответ об ошибке на запрос, который вызвал ошибку, позволяя остальным завершить работу в обычное время, и прекратить прослушивание новых запросов этого работника.
+> …По самой природе того, как throw работает в JavaScript, почти всегда нет способа безопасно "начать оттуда, где мы остановились", без утечки ссылок или создания другого undefined-состояния. Самый безопасный способ отреагировать на возникшую ошибку - завершить процесс. Конечно, на обычном веб-сервере у вас может быть открыто много подключений, и нет смысла внезапно закрывать все, потому что кто-то другой выбросил ошибку. Лучший вариант - отправить ответ об ошибке на запрос, который ее вызвал, позволяя остальным завершить работу в удобное время, и после прекратить прослушивание новых запросов в воркере, в котором возникла ошибка.
### Цитата блога: "В противном случае вы рискуете состоянием вашего приложения"
Из блога debugable.com, занявшего 3 место по ключевым словам "Node.js uncaught exception"
-> … Итак, если вы действительно не знаете, что делаете, вам следует выполнить постепенный перезапуск службы после получения события исключения "uncaughtException". В противном случае вы рискуете привести к несогласованности состояния вашего приложения или сторонних библиотек, что приведет к всевозможным сумасшедшим ошибкам …
+> …Итак, если вы действительно не знаете, что делаете, вам следует выполнить постепенный перезапуск службы после получения события исключения "uncaughtException". В противном случае вы рискуете привести к несогласованности состояния вашего приложения или сторонних библиотек, что приведет к всевозможным сумасшедшим ошибкам…
### Цитата блога: "Есть три школы мысли об обработке ошибок"
Из блога: JS Recipes
-> … Существует три основных направления работы с ошибками:
+> …Существует три основных направления работы с ошибками:
1. Дайте приложению упасть и перезапустите его.
-2. Обрабатывайте все возможные ошибоки и никогда не роняйте.
-3. Сбалансированный подход между двумя предыдущими.
+2. Обрабатывайте все возможные ошибоки и никогда не роняйте сервис.
+3. Сбалансированный подход между двумя предыдущими.
\ No newline at end of file
diff --git a/sections/errorhandling/returningpromises.basque.md b/sections/errorhandling/returningpromises.basque.md
new file mode 100644
index 000000000..41b8cb5bd
--- /dev/null
+++ b/sections/errorhandling/returningpromises.basque.md
@@ -0,0 +1,259 @@
+# Agintzak itzultzea
+
+
+
+### Azalpena
+
+Errore bat gertatzen denean fluxu sinkrono edo asinkrono batetik abiatuta, derrigorrezkoa da errore fluxuaren pila aztarna osoa edukitzea. Harrigarria bada ere, funtzio asinkrono batek (adibidez beste funtzio asinkrono bat deitzen duena) itxaron gabe (await) promesak itzultzen dituenean, errore bat gertatuko litzateke eta jatorrizko funtzio horren izena ez litzateke pilaren aztarnan agertu beharko. Horrek informazio partziala emango dio errorea diagnostikatzen duenari, are gehiago errorearen zergatiak jatorrizko funtzioan badu oinarria. Badago "zero-kostuko pila aztarna asinkronoak" deitzen den v8 funtzionalitate bat, pila aztarnak azken gertatu berri den `await`ean moztuak ez izatea ahalbidetzen duena. Garrantzirik gabeko inplementazio xehetasunak direla eta, horrek ez du funtzionatuko funtzioak bueltatzen duen balioa (sinkronoa edo asinkronoa) promesa bat baldin bada. Promesak deuseztatzen direnean pilaren aztarnan zuloak egotea ekiditeko, promesak beti esplizituki ebatzi behar ditugu `await` erabiliz beraiek funtzioetatik bueltatu baino lehen
+
+
+
+### Anti ereduaren kode adibidea: funtzio asinkronoak deitu itxaron gabe
+
+Javascript
+
+
+```javascript
+async function asyncJaurti(mezua) {
+ await null // benetako asinkronoa den zerbaiti itxaron beharra (begiratu #2 puntua)
+ throw Error(mezua)
+}
+
+async function bueltatuItxaronGabe () {
+ return asyncJaurti('bueltatuItxaronGabe falta da pilaren aztarnan')
+}
+
+// 👎 EZ du edukiko bueltatuItxaronGabe pilaren aztarnan
+bueltatuItxaronGabe().catch(console.log)
+```
+
+erregistratuko du
+
+```
+Errorea: bueltatuItxaronGabe falta da pilaren aztarnan
+ asyncJaurti-ren barruan ([...])
+```
+
+
+
+### Kode adibidea: zuzenean deitu eta itxaron
+
+Javascript
+
+
+```javascript
+async function asyncJaurti(mezua) {
+ await null // benetako asinkronoa den zerbaiti itxaron beharra (begiratu #2 puntua)
+ throw Error(mezua)
+}
+
+async function bueltatuItxaronda() {
+ return await asyncJaurti('zati guztiak edukiz')
+}
+
+// 👍bueltatuItxaronda edukiko du pilaren aztarnan
+bueltatuItxaronda().catch(console.log)
+```
+
+erregistratuko du
+
+```
+Error: zati guztiak edukiz
+ asyncJaurti-ren barruan ([...])
+ bueltatuItxaronda-ren barruan ([...])
+```
+
+
+
+
+
+
+### Anti ereduaren kode adibidea: itzuli promesak funtzioak asinkronotzat etiketatu gabe
+
+Javascript
+
+
+```javascript
+async function asyncJaurti () {
+ await null // benetako asinkronoa den zerbaiti itxaron beharra (begiratu #2 puntua)
+ throw Error('syncFn falta da pilaren aztarnan')
+}
+
+function syncFn () {
+ return asyncJaurti()
+}
+
+async function asyncFn () {
+ return await syncFn()
+}
+
+// 👎 ez dut edukiko syncFn pilaren aztarnan promesak itzultzen dituelako sinkronizatzen den ari den bitartean
+asyncFn().catch(console.log)
+```
+
+erregistratuko du
+
+```
+Error: syncFn falta da pilaren aztarnan
+ asyncJaurti-ren barruan ([...])
+ async asyncFn-en barruan ([...])
+```
+
+
+
+
+### Kode adibidea: etiketatu promesak asinkrono gisa itzultzen dituen funtzioa
+
+Javascript
+
+
+```javascript
+async function asyncJaurti () {
+ await null // benetako asinkronoa den zerbaiti itxaron beharra (begiratu #2 puntua)
+ throw Error('zati guztiak edukiz')
+}
+
+async function syncEtikAsyncFnraAldatua() {
+ return await asyncJaurti()
+}
+
+async function asyncFn () {
+ return await syncEtikAsyncFnraAldatua()
+}
+
+// 👍 orain syncEtikAsyncFnraAldatua pilaren aztarnan agertuko da
+asyncFn().catch(console.log)
+```
+
+erregistratuko du
+
+```
+Error: zati guztiak edukiz
+ asyncJaurti-ren barruan ([...])
+ syncEtikAsyncFnraAldatua-ren barruan ([...])
+ async asyncFn-en barruan ([...])
+```
+
+
+
+
+
+
+### #3 anti ereduaren kode adibidea: callback asinkronoen erabilera zuzena callback sinkronoa espero zen lekuan
+
+Javascript
+
+
+```javascript
+async function berreskuratuErabiltzailea (id) {
+ await null
+ if (!id) throw Error('pilaren aztarna falta da berreskuratuErabiltzailea deitu den lekuan')
+ return {id}
+}
+
+const erabiltzaileIdak = [1, 2, 0, 3]
+
+// 👎 pilaren aztarnak berreskuratuErabiltzailea funtzioa edukiko du baina ez du zehaztuko non izan den deitua
+Promise.all(erabiltzaileIdak.map(berreskuratuErabiltzailea)).catch(console.log)
+```
+
+erregistratuko du
+
+```
+Error: pilaren aztarna falta da berreskuratuErabiltzailea deitu den lekuan
+ berreskuratuErabiltzailea-en barruan ([...])
+ async Promise.all-en barruan (index 2)
+```
+
+*Apunte bat*: pentsa liteke `Promise.all (index 2)`ek `berreskuratuErabiltzailea` deitua izan den lekua ulertzen lagundu dezakela, baina [guztiz ezberdina den v8ko akatsa](https://bugs.chromium.org/p/v8/issues/detail?id=9023) dela eta, `(index 2)` v8 barneko lerro bat da
+
+
+
+
+### Kode adibidea: bildu callback asinkronoa funtzio asinkrono faltsu batean callback sinkrono gisa bidali aurretik
+
+Javascript
+
+
+*1.oharra*: callbacka deituko duen funtzioaren kodea kontrolatuz gero, soilik aldatu funtzio hau asinkronora eta gehitu `await` callback deiaren aurretik. Callbacka deitzen duen kodearen ardurandu ez zarela kontsideratu dut behean (edo honen aldaketa onartezina da adibidez atzeranzko-konpatibilitatea dela eta)
+
+*2.oharra*: sarri, callback sinrkono bat espero den lekuetan callback asinkronoak erabiltzeak ez du inola ere funtzionatuko. Hau ez da funtzionatzen ez duen kodea nola konpontzeari buruz, kodea behar bezala funtzionatzen ari denean pilaren aztarna nola konpontzeari buruz baizik
+
+```javascript
+async function berreskuratuErabiltzailea (id) {
+ await null
+ if (!id) throw Error('zati guztiak edukiz')
+ return {id}
+}
+
+const erabiltzaileIdak = [1, 2, 0, 3]
+
+// 👍 orain azpiko lerroa pilaren aztarnan dago
+Promise.all(erabiltzaileIdak.map(async id => await berreskuratuErabiltzailea(id))).catch(console.log)
+```
+
+erregistratuko du
+
+```
+Error: zati guztiak edukiz
+ berreskuratuErabiltzailea-ren barruan ([...])
+ async-en barruan ([...])
+ async Promise.all-en barruan (index 2)
+```
+
+`map` barruko `await` explizituari esker, `async-ren barruan ([...])` lerroaren bukaerak `berreskuratuErabiltzailea` deitua izan den puntu zehatza adieraziko du
+
+*Apunte bat*: `berreskuratuErabiltzailea` biltzen duen funtzio asinkrono batek `await` ahazten badu zerbait bueltatu aurretik (anti-eredua #1 + anti-eredua #3), zati bat bakarrik izango da mantendua pilaren aztarnan:
+
+
+```javascript
+[...]
+
+// 👎 anti-pattern 1 + anti-pattern 3 - only one frame left in stacktrace
+Promise.all(erabiltzaileIdak.map(async id => berreskuratuErabiltzailea(id))).catch(console.log)
+```
+
+erregistratuko du
+
+```
+Error: [...]
+ berreskuratuErabiltzailea-ren barruan ([...])
+```
+
+
+
+
+
+
+Zero kostuko pila aztarna asinkronoak" deitzen den v8 funtzionalitate bat
+
+## Azalpen aurreratua
+
+Oso ezberdinak dira funtzio sinkronoen pila aztarnen eta funtzio asinkronoen pila aztarnen mekanismoak v8ren ezarpenetan: pila aztarna asinkronoa oinarritua dago Node.js martxan dagoen sistema eragileak emandako **pila**n (programazio lengoaia gehienak bezala). Funtzio asinkrono bat exekutatzen ari denean, sistema eragileko **pila** agerian jartzen da funtzioa bere lehen `await`era iristen den momentuan. Beraz, pilaren aztarna nahasketa bat da, hain zuzen, sistema eragilearen pilaren eta baztertutako **promesa ebazpen katea**rena. Zero kostuko pila aztarna asinkronoen ezarpenak **promesaren ebazpen katea** luzatzen du bakarrik promesa `itxaroten` [¹](#1) ari den bitartean. Funtzio asinkronoek bakarrik (`async`) itxaron (`await`) ahal dutenez, beti galduko da funtzio asinkronoa pilaren aztarna asinkrono batean, operazio asinkronoren bat izan bada funtzioa deitu eta gero [²](#2)
+
+### Erdibidea
+
+`await` bakoitzak mikro ataza berri bat sortzen du gertaeraren begiztan. Beraz, `await` gehiago gehitzeak errendimendu zigorra ekarriko luke. Hala ere, sareak edota datu baseak sortutako errendimendu isuna [ikaragarri handiagoa](https://colin-scott.github.io/personal_website/research/interactive_latency.html) da, eta, beraz, gehitutako `await`aren zigorra ez da zerbitzariak edo CLIak garatzeko orduan kontutan hartu beharreko zerbait, eskaera edo komando bakoitzeko oso kode beroa izan ezean behintzat. Orduan, `await`ak ezabatzeak `return await`etan errendimendu bultzada nabarmena bilatzeko azken lekua izan beharko luke eta, zalantzarik gabe, inoiz ez litzateke aldez aurretik egin beharko
+
+
+### Zergatik jotzen zen await bueltatzea anti eredutzat iraganean
+
+[Artikulu bikain](https://jakearchibald.com/2017/await-vs-return-vs-return-await/) ugari daude azaltzen dutenak zergatik `return await`ak ez diren inoiz `try` bloketik kanpo erabili behar, bai eta [ESLint arau](https://eslint.org/docs/rules/no-return-await) bat ere hori debekatzen duena. Horren arrazoia da async/await erabilgarri bihurtu izana Node.js 0.10ko transpilagailuekin (eta jatorrizko laguntza lortu dutela Node.js 7.6 bertsioan), eta "zero kostuko pila aztarna asinkronoak" Node.js 10era gehitua izana, eta ondoren Node.js 12tik kendua, `return await` eta `return` guztiz parekoak zirela, edozein `try` kode bloketik kanpo. Oraindik ere berdina izaten jarraituko du seguraski ES motoreentzat. Horregatik, Node.jsrentzat praktika onena da promesak kalkulatzea beraiek bueltatu aurretik. EcmaScriptentzat, ordea, hori ez praktika onena
+
+### Oharrak:
+
+1. Pila aztarna asinkronoak halako ezarpen korapilatsua izatearen beste arrazoi bat da pila aztarna beti modu sinkronoan eraiki behar dela, gertaeraren begiztaren [¹](#1) momentu berean
+
+2. `throwAsync` barruan `await` gabe, gertaera begiztaren fase berean exekutatuko litzateke kodea. Hori, degeneratutako kasua da: sistema eragilearen **pila** ez litzateke hustuko, eta pila aztarna beteko litzateke funtzioaren emaitzari berariaz itxaron gabe ere. Normalean, promesen erabilerak operazio asinkrono batzuk edukitzen dituenez, pilaren aztarnaren zati batzuk galdu egingo lirateke
+
+3. Zero kostuko pila aztarna asinkronoek ez lukete funtzionatuko promesa erabileren kasu korapilatsuetan: promesa bakar bati hainbat aldiz eta leku ezberdinetan itxaron beharra dagoenean, adibidez
+
+
+### Erreferentziak:
+ 1. [v8ko zero kostuko pila aztarna asinkronoak blog argitarapena](https://v8.dev/blog/fast-async)
+
+
+ 2. [zero kostuko pila aztarna asinkronoei inguruko dokumentazioa ezarpen xehetasunekin hemen](
+ https://docs.google.com/document/d/13Sy_kBIJGP0XT34V1CV3nkWya4TwYx9L3Yv45LdGB6Q/edit
+ )
+
diff --git a/sections/errorhandling/returningpromises.french.md b/sections/errorhandling/returningpromises.french.md
new file mode 100644
index 000000000..bdbe22e1a
--- /dev/null
+++ b/sections/errorhandling/returningpromises.french.md
@@ -0,0 +1,285 @@
+# Le retour des promesses
+
+
+
+### Un paragraphe d'explication
+
+Lorsqu'une erreur se produit, qu'elle provienne d'un flux synchrone ou asynchrone, il est impératif de disposer d'une trace de pile complète du flux d'erreurs. Étonnamment, lorsqu'une fonction `async` renvoie une promesse sans `await` (par exemple, elle appelle une autre fonction `async`), si une erreur se produit, la fonction appelante n'apparaîtra pas dans la trace de la pile. La personne qui diagnostiquera l'erreur ne disposera donc que d'une information partielle - d'autant plus si la cause de l'erreur se situe dans cette fonction d'appel. Il existe une fonctionnalité v8 appelée "zero-cost async stacktraces" qui permet de ne pas couper les traces de pile sur les `await` les plus récents. Mais sans certaines modalités de mise en œuvre non négligeables, elle ne fonctionnera pas si la valeur de retour d'une fonction (sync ou async) est une promesse. Donc, pour éviter les trous dans les traces de pile lorsque des promesses retournées sont rejetées, nous devons toujours résoudre explicitement les promesses avec `await` avant de les retourner à partir des fonctions.
+
+
+
+### Exemple de code incorrect : appel d'une fonction async sans await
+
+Javascript
+
+
+```javascript
+async function throwAsync(msg) {
+ await null // il faut attendre au moins quelque chose pour être vraiment asynchrone (voir note n° 2)
+ throw Error(msg)
+}
+
+async function returnWithoutAwait () {
+ return throwAsync('manque returnWithoutAwait dans la trace de pile')
+}
+
+// 👎 N'aura PAS la fonction returnWithoutAwait dans la trace de pile
+returnWithoutAwait().catch(console.log)
+```
+
+log reçu
+
+```
+Error: manque returnWithoutAwait dans la trace de pile
+ at throwAsync ([...])
+```
+
+
+
+### Exemple de code : appel d'une fonction async avec await approprié
+
+Javascript
+
+
+```javascript
+async function throwAsync(msg) {
+ await null // il faut attendre au moins quelque chose pour être vraiment asynchrone (voir note n° 2)
+ throw Error(msg)
+}
+
+async function returnWithAwait() {
+ return await throwAsync('avec toutes les instructions présentes')
+}
+
+// 👍 aura la fonction returnWithoutAwait dans la trace de pile
+returnWithAwait().catch(console.log)
+```
+
+log reçu
+
+```
+Error: avec toutes les instructions présentes
+ at throwAsync ([...])
+ at async returnWithAwait ([...])
+```
+
+
+
+
+
+
+### Exemple de code incorrect : retourner une promesse sans marquer la fonction comme async
+
+Javascript
+
+
+```javascript
+async function throwAsync () {
+ await null // il faut attendre au moins quelque chose pour être vraiment asynchrone (voir note n° 2)
+ throw Error('manque syncFn dans la trace de pile')
+}
+
+function syncFn () {
+ return throwAsync()
+}
+
+async function asyncFn () {
+ return await syncFn()
+}
+
+// 👎 syncFn manquera dans la trace de pile parce qu'elle renverra une promesse alors qu'elle est sync
+asyncFn().catch(console.log)
+```
+
+log reçu
+
+```
+Error: manque syncFn dans la trace de pile
+ at throwAsync ([...])
+ at async asyncFn ([...])
+```
+
+
+
+
+### Exemple de code : marquer la fonction comme async car elle renvoie une promesse
+
+Javascript
+
+
+```javascript
+async function throwAsync () {
+ await null // il faut attendre au moins quelque chose pour être vraiment asynchrone (voir note n° 2)
+ throw Error('avec toutes les instructions présentes')
+}
+
+async function changedFromSyncToAsyncFn () {
+ return await throwAsync()
+}
+
+async function asyncFn () {
+ return await changedFromSyncToAsyncFn()
+}
+
+// 👍 maintenant changedFromSyncToAsyncFn sera présent dans la trace de la pile
+asyncFn().catch(console.log)
+```
+
+log reçu
+
+```
+Error: avec toutes les instructions présentes
+ at throwAsync ([...])
+ at changedFromSyncToAsyncFn ([...])
+ at async asyncFn ([...])
+```
+
+
+
+
+
+
+### Exemple de code incorrect : utilisation directe du rappel async lorsque le rappel sync est attendu
+
+Javascript
+
+
+```javascript
+async function getUser (id) {
+ await null
+ if (!id) throw Error('la trace de pile n\'indique pas l\'endroit où getUser a été appelé')
+ return {id}
+}
+
+const userIds = [1, 2, 0, 3]
+
+// 👎 la trace de pile aura la fonction getUser mais ne donnera aucune indication sur l'endroit où elle a été appelée
+Promise.all(userIds.map(getUser)).catch(console.log)
+```
+
+log reçu
+
+```
+Error: la trace de pile n'indique pas l'endroit où getUser a été appelé
+ at getUser ([...])
+ at async Promise.all (index 2)
+```
+
+*Remarque complémentaire* : on pourrait croire que `Promise.all (index 2)` peut aider à comprendre l'endroit où `getUser` a été appelé,
+mais en raison d'un [bogue complètement différent dans la v8](https://bugs.chromium.org/p/v8/issues/detail?id=9023), `(index 2)` est
+une ligne interne de v8
+
+
+
+
+### Exemple de code : envelopper le rappel async dans une fonction async factice avant de le passer en rappel sync
+
+Javascript
+
+
+*Remarque 1* : si vous contrôlez le code de la fonction qui appelle le rappel, changez simplement cette fonction
+en async et ajoutez `await` avant l'appel du rappel. Ci-dessous, je suppose que vous n'êtes pas en charge du code qui appelle
+le rappel (ou que son changement est inacceptable, par exemple en raison de la rétrocompatibilité)
+
+*Remarque 2* : très souvent, l'utilisation du rappel async dans les endroits où l'on s'attend à ce qu'il soit sync ne fonctionnerait pas du tout. Il ne s'agit pas
+de savoir comment réparer le code qui ne fonctionne pas - il s'agit de savoir comment réparer la trace de pile au cas où le code fonctionne déjà
+comme prévu
+
+```javascript
+async function getUser (id) {
+ await null
+ if (!id) throw Error('avec toutes les instructions présentes')
+ return {id}
+}
+
+const userIds = [1, 2, 0, 3]
+
+// 👍 maintenant la ligne ci-dessous est dans la trace de la pile
+Promise.all(userIds.map(async id => await getUser(id))).catch(console.log)
+```
+
+log reçu
+
+```
+Error: avec toutes les instructions présentes
+ at getUser ([...])
+ at async ([...])
+ at async Promise.all (index 2)
+```
+
+grâce au `await` explicite dans `map`, la fin de la ligne `at async ([...])` indique l'endroit exact où
+`getUser` est appelé
+
+*Remarque complémentaire* : si la fonction async qui enveloppe `getUser` n'a pas `await` avant le retour (exemple incorrect n°1 + exemple incorrect n°3)
+alors il ne restera qu'une seule instruction dans la trace de la pile :
+
+```javascript
+[...]
+
+// 👎 exemple incorrect n°1 + exemple incorrect n°3 - une seule instruction dans la trace de la pile
+Promise.all(userIds.map(async id => getUser(id))).catch(console.log)
+```
+
+log reçu
+
+```
+Error: [...]
+ at getUser ([...])
+```
+
+
+
+
+
+
+## Explication approfondie
+
+Les mécanismes des traces de piles des fonctions de sync et des fonctions async dans l'implémentation de la v8 sont très différents :
+La trace de pile sync est basée sur la **pile** fournie par le système d'exploitation sur lequel tourne Node.js (comme dans la plupart des langages
+de programmation). Lorsqu'une fonction async est en cours d'exécution, la **pile** du système d'exploitation l'a sort dès que la
+fonction est arrivée à son premier `await`. Donc la trace de pile async est un mélange de la **pile** du système d'exploitation et d'une
+**chaîne de résolution des promesses** rejetées. L'implémentation "zero-cost async stacktraces" étend la **chaîne de résolution des promesses**
+uniquement lorsque la promesse est `awaited` [¹](#1). Parce que seules les fonctions `async` peuvent `await`,
+la fonction sync sera toujours manquante dans la trace de la pile async si une opération async a été effectuée après que la fonction
+a été appelé [²](#2)
+
+### Le compromis
+
+Chaque `await` crée une nouvelle micro-tâche dans la boucle d'événement, donc l'ajout d'autres `await` dans le code
+introduit une certaine pénalité de performance. Néanmoins, la pénalité de performance introduite par le réseau ou
+la base de données est [énormément plus grande](https://colin-scott.github.io/personal_website/research/interactive_latency.html)
+donc la pénalité supplémentaire `await` n'est pas quelque chose qui devrait être considéré pendant le développement de serveurs web ou de CLI
+sauf pour un code très chaud par requête ou commande. Donc, la suppression de `await` dans
+les `return await` devrait être l'un des derniers moyens pour améliorer sensiblement les performances
+et ne doit absolument pas être fait en amont.
+
+
+### Pourquoi return await était considéré comme incorrect dans le passé
+
+Un certain nombre d'[excellents articles](https://jakearchibald.com/2017/await-vs-return-vs-return-await/) expliquent
+pourquoi `return await` ne devrait jamais être utilisée en dehors du bloc `try` et même une
+[règle ESLint](https://eslint.org/docs/rules/no-return-await) l'interdit. La raison, c'est que depuis que async/await
+est disponible avec des transpileurs dans Node.js 0.10 (et a obtenu un support natif dans Node.js 7.6) et jusqu'à ce
+que "zero-cost async stacktraces" a été introduit dans Node.js 10 et démarqué dans Node.js 12, `return await` était absolument
+équivalent à `return` pour tout code en dehors du bloc `try`. Il se peut que ce soit encore le cas pour certains autres moteurs ES.
+C'est pourquoi la résolution des promesses avant de les retourner est la meilleure pratique pour Node.js et non pour EcmaScript en général
+
+### Remarques :
+
+1. Une autre raison pour laquelle la trace de pile async a une implémentation aussi délicate, c'est que la trace de pile
+doit toujours être construite de manière synchrone, sur le même rythme que la boucle d'événement [¹](#1)
+2. Sans `await` dans `throwAsync`, le code serait exécuté dans la même phase de la boucle d'événements. C'est un cas
+dégradé où la **pile** de l'OS ne serait pas vide et la trace de pile serait pleine même sans attendre
+explicitement le résultat de la fonction. Habituellement, l'utilisation des promesses inclut des opérations asynchrones
+et des parties de la trace de la pile sont perdues
+3. Zero-cost async stacktraces ne fonctionnera toujours pas pour les usages compliqués de la promesse, par exemple la promesse unique
+attendue à plusieurs reprises dans différents endroits
+
+### Références :
+ 1. [article de blog sur zero-cost async stacktraces en v8](https://v8.dev/blog/fast-async)
+
+
+ 2. [Document sur zero-cost async stacktraces avec les détails de mise en œuvre mentionnés ici](
+ https://docs.google.com/document/d/13Sy_kBIJGP0XT34V1CV3nkWya4TwYx9L3Yv45LdGB6Q/edit
+ )
+
diff --git a/sections/errorhandling/returningpromises.md b/sections/errorhandling/returningpromises.md
new file mode 100644
index 000000000..11ebc5a67
--- /dev/null
+++ b/sections/errorhandling/returningpromises.md
@@ -0,0 +1,285 @@
+# Returning promises
+
+
+
+### One Paragraph Explainer
+
+When an error occurs, whether from a synchronous or asynchronous flow, it's imperative to have a full stacktrace of the error flow. Surprisingly, if an async function returns a promise (e.g. calls other async function) without awaiting, should an error occur then the caller function won't appear in the stacktrace. This will leave the person who diagnoses the error with partial information - All the more if the error cause lies within that caller function. There is a v8 feature called "zero-cost async stacktraces" that allows stacktraces to not be cut on the most recent `await`. But due to non-trivial implementation details, it will not work if the return value of a function (sync or async) is a promise. So, to avoid holes in stacktraces when returned promises would be rejected, we must always explicitly resolve promises with `await` before returning them from functions
+
+
+
+### Code example Anti-Pattern: Calling async function without awaiting
+
+Javascript
+
+
+```javascript
+async function throwAsync(msg) {
+ await null // need to await at least something to be truly async (see note #2)
+ throw Error(msg)
+}
+
+async function returnWithoutAwait () {
+ return throwAsync('missing returnWithoutAwait in the stacktrace')
+}
+
+// 👎 will NOT have returnWithoutAwait in the stacktrace
+returnWithoutAwait().catch(console.log)
+```
+
+would log
+
+```
+Error: missing returnWithoutAwait in the stacktrace
+ at throwAsync ([...])
+```
+
+
+
+### Code example: Calling and awaiting as appropriate
+
+Javascript
+
+
+```javascript
+async function throwAsync(msg) {
+ await null // need to await at least something to be truly async (see note #2)
+ throw Error(msg)
+}
+
+async function returnWithAwait() {
+ return await throwAsync('with all frames present')
+}
+
+// 👍 will have returnWithAwait in the stacktrace
+returnWithAwait().catch(console.log)
+```
+
+would log
+
+```
+Error: with all frames present
+ at throwAsync ([...])
+ at async returnWithAwait ([...])
+```
+
+
+
+
+
+
+### Code example Anti-Pattern: Returning a promise without tagging the function as async
+
+Javascript
+
+
+```javascript
+async function throwAsync () {
+ await null // need to await at least something to be truly async (see note #2)
+ throw Error('missing syncFn in the stacktrace')
+}
+
+function syncFn () {
+ return throwAsync()
+}
+
+async function asyncFn () {
+ return await syncFn()
+}
+
+// 👎 syncFn would be missing in the stacktrace because it returns a promise while being sync
+asyncFn().catch(console.log)
+```
+
+would log
+
+```
+Error: missing syncFn in the stacktrace
+ at throwAsync ([...])
+ at async asyncFn ([...])
+```
+
+
+
+
+### Code example: Tagging the function that returns a promise as async
+
+Javascript
+
+
+```javascript
+async function throwAsync () {
+ await null // need to await at least something to be truly async (see note #2)
+ throw Error('with all frames present')
+}
+
+async function changedFromSyncToAsyncFn () {
+ return await throwAsync()
+}
+
+async function asyncFn () {
+ return await changedFromSyncToAsyncFn()
+}
+
+// 👍 now changedFromSyncToAsyncFn would present in the stacktrace
+asyncFn().catch(console.log)
+```
+
+would log
+
+```
+Error: with all frames present
+ at throwAsync ([...])
+ at changedFromSyncToAsyncFn ([...])
+ at async asyncFn ([...])
+```
+
+
+
+
+
+
+### Code Example Anti-pattern #3: direct usage of async callback where sync callback is expected
+
+Javascript
+
+
+```javascript
+async function getUser (id) {
+ await null
+ if (!id) throw Error('stacktrace is missing the place where getUser has been called')
+ return {id}
+}
+
+const userIds = [1, 2, 0, 3]
+
+// 👎 the stacktrace would include getUser function but would give no clue on where it has been called
+Promise.all(userIds.map(getUser)).catch(console.log)
+```
+
+would log
+
+```
+Error: stacktrace is missing the place where getUser has been called
+ at getUser ([...])
+ at async Promise.all (index 2)
+```
+
+*Side-note*: it may look like `Promise.all (index 2)` can help understanding the place where `getUser` has been called,
+but due to a [completely different bug in v8](https://bugs.chromium.org/p/v8/issues/detail?id=9023), `(index 2)` is
+a line from internals of v8
+
+
+
+
+### Code example: wrap async callback in a dummy async function before passing it as a sync callback
+
+Javascript
+
+
+*Note 1*: if you control the code of the function that would call the callback - just change that function to
+`async` and add `await` before the callback call. Below I assume that you are not in charge of the code that is calling
+the callback (or its change is unacceptable for example because of backward compatibility)
+
+*Note 2*: quite often usage of async callback in places where sync one is expected would not work at all. This is not about
+how to fix the code that is not working - it's about how to fix stacktrace in case if code is already working as
+expected
+
+```javascript
+async function getUser (id) {
+ await null
+ if (!id) throw Error('with all frames present')
+ return {id}
+}
+
+const userIds = [1, 2, 0, 3]
+
+// 👍 now the line below is in the stacktrace
+Promise.all(userIds.map(async id => await getUser(id))).catch(console.log)
+```
+
+would log
+
+```
+Error: with all frames present
+ at getUser ([...])
+ at async ([...])
+ at async Promise.all (index 2)
+```
+
+where thanks to explicit `await` in `map`, the end of the line `at async ([...])` would point to the exact place where
+`getUser` has been called
+
+*Side-note*: if async function that wrap `getUser` lacks `await` before return (anti-pattern #1 + anti-pattern #3)
+then only one frame would be left in the stacktrace:
+
+```javascript
+[...]
+
+// 👎 anti-pattern 1 + anti-pattern 3 - only one frame left in stacktrace
+Promise.all(userIds.map(async id => getUser(id))).catch(console.log)
+```
+
+would log
+
+```
+Error: [...]
+ at getUser ([...])
+```
+
+
+
+
+
+
+## Advanced explanation
+
+The mechanisms behind sync functions stacktraces and async functions stacktraces in v8 implementation are quite different:
+sync stacktrace is based on **stack** provided by the operating system Node.js is running on (just like in most programming
+languages). When an async function is executing, the **stack** of the operating system is popping it out as soon as the
+function gets to its first `await`. So async stacktrace is a mix of operating system **stack** and a rejected
+**promise resolution chain**. Zero-cost async stacktraces implementation extends the **promise resolution chain**
+only when the promise is getting `awaited` [¹](#1). Because only `async` functions may `await`,
+sync function would always be missing from async stacktrace if any async operation has been performed after the function
+has been called [²](#2)
+
+### The tradeoff
+
+Every `await` creates a new microtask in the event loop, so adding more `await`s to the code would
+introduce some performance penalty. Nevertheless, the performance penalty introduced by network or
+database is [tremendously larger](https://colin-scott.github.io/personal_website/research/interactive_latency.html)
+so additional `await`s penalty is not something that should be considered during web servers or CLI
+development unless for a very hot code per request or command. So removing `await`s in
+`return await`s should be one of the last places to search for noticeable performance boost and
+definitely should never be done up-front
+
+
+### Why return await was considered as anti-pattern in the past
+
+There is a number of [excellent articles](https://jakearchibald.com/2017/await-vs-return-vs-return-await/) explaining
+why `return await` should never be used outside of `try` block and even an
+[ESLint rule](https://eslint.org/docs/rules/no-return-await) that disallows it. The reason for that is the fact that
+since async/await become available with transpilers in Node.js 0.10 (and got native support in Node.js 7.6) and until
+"zero-cost async stacktraces" was introduced in Node.js 10 and unflagged in Node.js 12, `return await` was absolutely
+equivalent to `return` for any code outside of `try` block. It may still be the same for some other ES engines. This
+is why resolving promises before returning them is the best practice for Node.js and not for ECMAScript in general
+
+### Notes:
+
+1. One other reason why async stacktrace has such tricky implementation is the limitation that stacktrace
+must always be built synchronously, on the same tick of event loop [¹](#1)
+2. Without `await` in `throwAsync` the code would be executed in the same phase of event loop. This is a
+degenerated case when OS **stack** would not get empty and stacktrace be full even without explicitly
+awaiting the function result. Common usage of promises includes some async operations and so parts of
+the stacktrace would get lost
+3. Zero-cost async stacktraces still would not work for complicated promise usages e.g. single promise
+awaited many times in different places
+
+### References:
+ 1. [Blog post on zero-cost async stacktraces in v8](https://v8.dev/blog/fast-async)
+
+
+ 2. [Document on zero-cost async stacktraces with mentioned here implementation details](
+ https://docs.google.com/document/d/13Sy_kBIJGP0XT34V1CV3nkWya4TwYx9L3Yv45LdGB6Q/edit
+ )
+
diff --git a/sections/errorhandling/returningpromises.russian.md b/sections/errorhandling/returningpromises.russian.md
new file mode 100644
index 000000000..01df84106
--- /dev/null
+++ b/sections/errorhandling/returningpromises.russian.md
@@ -0,0 +1,289 @@
+# Возвращение промисов
+
+
+
+### Короткое объяснение
+
+У v8 есть особая способность, называемая "бесплатные асинхронные стектрейсы", которая позволяет стектрейсам не
+обрываться на самом позднем `await`. Но, из-за нетривиальных нюансов реализации, она не сработает если возвращаемое
+значение функции (синхронной или асинхронной) является промис. По этому, для того чтобы избежать дыр в стектрейсах
+после отказа (rejection) возвращаемого промиса, следует всегда явно разрешать (resolve) промисы при помощи `await`
+перед тем как возвращать их из функций
+
+
+
+### Анти-паттерн №1: return `promise`
+
+Javascript
+
+
+```javascript
+async function throwAsync(msg) {
+ await null // нужно выполнить await для того что бы функция была по-настоящему асинхронной (см. заметку №2)
+ throw Error(msg)
+}
+
+async function returnWithoutAwait () {
+ return throwAsync('missing returnWithoutAwait in the stacktrace')
+}
+
+// 👎 returnWithoutAwait будет отсутствовать в стектрейсе
+returnWithoutAwait().catch(console.log)
+```
+
+выведет в лог
+
+```
+Error: missing returnWithoutAwait in the stacktrace
+ at throwAsync ([...])
+```
+
+
+
+```javascript
+async function throwAsync(msg) {
+ await null // нужно выполнить await для того что бы функция была по-настоящему асинхронной (см. заметку №2)
+ throw Error(msg)
+}
+
+async function returnWithAwait() {
+ return await throwAsync('with all frames present')
+}
+
+// 👍 returnWithAwait будет присутствовать в стектрейсе
+returnWithAwait().catch(console.log)
+```
+
+выведет в лог
+
+```
+Error: with all frames present
+ at throwAsync ([...])
+ at async returnWithAwait ([...])
+```
+
+
+
+```javascript
+async function throwAsync () {
+ await null // нужно выполнить await для того что бы функция была по-настоящему асинхронной (см. заметку №2)
+ throw Error('missing syncFn in the stacktrace')
+}
+
+function syncFn () {
+ return throwAsync()
+}
+
+async function asyncFn () {
+ return await syncFn()
+}
+
+// 👎 syncFn будет отсутствовать в стектрейсе так как она синхронная и возвращает промис
+asyncFn().catch(console.log)
+```
+
+would log
+
+```
+Error: missing syncFn in the stacktrace
+ at throwAsync ([...])
+ at async asyncFn ([...])
+```
+
+
+
+
+### Как правильо: объявить функцию возвращающую промис как асинхронную
+
+Javascript
+
+
+```javascript
+async function throwAsync () {
+ await null // нужно выполнить await для того что бы функция была по-настоящему асинхронной (см. заметку №2)
+ throw Error('with all frames present')
+}
+
+async function changedFromSyncToAsyncFn () {
+ return await throwAsync()
+}
+
+async function asyncFn () {
+ return await changedFromSyncToAsyncFn()
+}
+
+// 👍 теперь changedFromSyncToAsyncFn будет присутствовать в стектрейсе
+asyncFn().catch(console.log)
+```
+
+would log
+
+```
+Error: with all frames present
+ at throwAsync ([...])
+ at changedFromSyncToAsyncFn ([...])
+ at async asyncFn ([...])
+```
+
+
+
+
+
+
+### Анти-паттерн №3: прямая передача асинхронного коллбэка в месте где ожидается синхронный коллбек
+
+Javascript
+
+
+```javascript
+async function getUser (id) {
+ await null
+ if (!id) throw Error('stacktrace is missing the place where getUser has been called')
+ return {id}
+}
+
+const userIds = [1, 2, 0, 3]
+
+// 👎 хотя в стектрейсе будет присутствовать функция getUser, в нем не будет места где она была вызвана
+Promise.all(userIds.map(getUser)).catch(console.log)
+```
+
+выведет в лог
+
+```
+Error: stacktrace is missing the place where getUser has been called
+ at getUser ([...])
+ at async Promise.all (index 2)
+```
+
+*Между прочим*: может показаться что `Promise.all (index 2)` может помоч понять где `getUser` была вызвана, но из-за
+[совершенно другого бага в v8](https://bugs.chromium.org/p/v8/issues/detail?id=9023), `(index 2)` является строкой из
+внутреннего кода v8
+
+
+
+
+### Как правильно: обернуть асинхронный коллбэк в асинхронную функция перед тем как передать его как синхронный коллбэк
+
+Javascript
+
+
+*Заметка 1*: в случае если вы отвечаете за код функции которая в итоге вызовет коллбэк - просто сделаете ее асинхронной и
+добавьте `await` перед вызовом коллбэка. Далее я предполагаю что вы не имеете контроля над кодом функции которая
+вызывает коллбэк (или ее изменение таким образом недопустимо, например, из соображений обратной совместимости)
+
+*Заметка 2*: Имейте ввиду, часто передача асинхронного коллбэка в место где ожидается синхронный коллбэк вообще не будет работать.
+Тут описывается не как починить такой код а лишь как починить стектрейсы если код уже работает как ожидается
+
+```javascript
+async function getUser (id) {
+ await null
+ if (!id) throw Error('with all frames present')
+ return {id}
+}
+
+const userIds = [1, 2, 0, 3]
+
+// 👍 теперь строка вызова getUser присутствует в стектрейсе
+Promise.all(userIds.map(async id => await getUser(id))).catch(console.log)
+```
+
+выведет в лог
+
+```
+Error: with all frames present
+ at getUser ([...])
+ at async ([...])
+ at async Promise.all (index 2)
+```
+
+где, благодаря явному `await` в `map`, конец строки `at async ([...])` указывает на место где `getUser` была вызвана
+
+*Между прочим*: если оберточная асинхронная функция для `getUser` не сделает явный `await` перед возвратом (то есть
+комбинация анти-паттерн 1 + анти-паттерн 3), то стектрейс останется вообще всегда с одним кадром:
+
+```javascript
+[...]
+
+// 👎 анти-паттерн 1 + анти-паттерн 3 - в стектрейсе осталась только getUser
+Promise.all(userIds.map(async id => getUser(id))).catch(console.log)
+```
+
+выведет в лог
+
+```
+Error: [...]
+ at getUser ([...])
+```
+
+
+
+
+
+
+### Углубленное объяснение
+
+Механизмы стоящие за построением синхронных и асинхронных стектрейсов в v8 довольно сильно отличаются: синхронные
+стектрейсы основаны на **стеке** операционной системы на которой запущен Node.js (как и для многих других языков
+программирования). Во время выполнения асинхронной функции, **стек** операционной системы выталкивает функцию как
+только та доходит до первого-же `await`. По этому асинхронные стектрейсы представляют собой смесь **стека**
+операционной системы и **цепочки разрешения отказанного (rejected) промиса**. "Бесплатные асинхронные стектрейсы"
+реализованны таким образом что **цепочка разрешения промиса** расширяется только когда на промисе исполняется `await`
+[¹](#1). По сколько только асинхронные функции могут использовать `await`, синхронные функции
+всегда будут упущены из асинхронного стектрейса если любая асинхронная операция была исполнена после момента вызова
+этой синхронной функции [²](#2)
+
+### Компромисc
+
+Каждый `await` создает дополнительную микрозадачу (microtask) в цикле событий (event loop), по
+этому дополнительные `await`-ы в коде создадут определенную дополнительную нагрузку. Тем ни менее,
+задержки создаваемые сетью и базой данных [несоизмеримо выше](https://colin-scott.github.io/personal_website/research/interactive_latency.html)
+по этому нагрузка создаваемая дополнительными `await`-ами не является чем-то что стоит принимать во
+внимание при разработке веб-серверов или интерфейсов командной строки (CLI), разве что для очень
+горячих участков кода на запрос или команду. По этому убирание `await`-ов из `return await` должно
+быть одним из последних мест для поиска значимых улучшений производительности приложения и точно не
+должно выполняться наперед
+
+### Почему return await раньше считалось анти-паттерном
+
+Существует ряд [отличных статей](https://jakearchibald.com/2017/await-vs-return-vs-return-await/) объясняющих почему
+`return await` никогда не должен быть использован за пределами `try` блока и даже
+[правело ESLint](https://eslint.org/docs/rules/no-return-await) которое такое использование запрещает. Причина
+заключается в том что с момента когда async/await стали доступны с помощью транспайлеров в Node.js 0.10 (и получил
+встроенную поддержку с Node.js 7.6) и до момента пока не появились "бесплатные асинхронные стектрейсы", `return await`
+было абсолютно эквивалентно `await` для любого кода за пределами `try` блока. Для каких-то ES движков это все так-же
+может оставаться правдой. По этой причине разрешение (resolve) промисов перед возвращением является лучшей практикой
+для Node.js, а не для EcmaScript в целом
+
+### Заметки:
+1. Одной из причин почему асинхронные сетктрейсы имеют столь нетривиальную реализация является требование к
+стектрейсу быть созданными синхронно, в пределах одного цикла петли событий (event loop) [¹](#1)
+2. без `await` в `throwAsync` весь код выполнится в одной фазе петли событий (event loop). Это вырожденный случай
+когда **стек** операционной системы не успеет опустошиться и стектрейс будет полным даже без явного `await` результата
+вызова функции. Обычно использование промисов подразумевает исполнение асинхронных операций, а значит части стектрейса
+все-же будут утрачены
+3. "Бесплатные асинхронные стектрейсы" не работают для особо сложных потоков промисов, например когда `await`
+выполняется для одного и того-же промиса в разных местах
+
+### References:
+ 1. [Блогпост о бесплатных асинхронных стектрейсах в v8](https://v8.dev/blog/fast-async)
+
+
+ 2. [Документ о бесплатных асинхронных стектрейсах в v8 с упомянутыми тут деталями реализации](
+ https://docs.google.com/document/d/13Sy_kBIJGP0XT34V1CV3nkWya4TwYx9L3Yv45LdGB6Q/edit
+ )
+
diff --git a/sections/errorhandling/shuttingtheprocess.basque.md b/sections/errorhandling/shuttingtheprocess.basque.md
new file mode 100644
index 000000000..693bad28e
--- /dev/null
+++ b/sections/errorhandling/shuttingtheprocess.basque.md
@@ -0,0 +1,99 @@
+# Irten prozesutik elegantziarekin kanpoko norbait iristen denean hirira
+
+### Azalpena
+
+Zure kodearen lekuren batean, erroreren bat gertatzen denean erroreen kudeaketa objektuaren ardura da erabakitzea nola jokatu, eta, errorea konfiantzazkoa bada, nahikoa izango da erregistro fitxategian idaztea; errorea operazionala bada, berriz, irakurri azalpen osatuagoa #3 jarraibide egokian). Gauzak okertzen dira errorea ezezaguna denean, horrek osagairen bat egoera txarrean dagoela eta hurrengo eskaera guztiek huts egiteko aukera handia dutela esan nahi du eta. Adibidez, eman dezagun, singleton bat edukita, token batek salbuespen bat igorri duela eta ondoren bere egoera galdu duen zerbitzu batekin arazoa duela; hortik aurrera ustekabean joka dezake eta eskaera guztiek huts egitea eragin. Egoera horren aurrean, prozesua gelditu eta 'Berrekite tresna' erabili (Forever, PM2, etab. bezalakoak) egoera garbi batekin berriz hasteko
+
+### Kode adibidea: huts eragin ala ez erabakitzen
+
+
+Javascript
+
+```javascript
+// Garatzaileek operazio erroreak errorea.operazioErroreaDa=true zehazten dutela ziurtzat joz, irakur ezazu #3 jarraibide egokia
+process.on('uncaughtException', (errorea) => {
+ erroreKudeaketa.kudeatzailea.kudeatuErrorea(errorea);
+ if(!erroreKudeaketa.kudeatzailea.erroreFidagarriaDa(errorea))
+ process.exit(1)
+});
+
+// errore kudeatzaile zentralizatuak errore-kudeaketa logika kapsulatzen du
+function erroreKudeatzailea() {
+ this.kudeatuErrorea = (errorea) => {
+ return logger.erroreaErregistratu(errorea)
+ .then(kritikoaBadaAdministrariariPostaElektronikoaBidali)
+ .then(kritikoaBadaOperazioZerrendanGorde)
+ .then(erabakiIaOperazioErroreaDen);
+ }
+
+ this.erroreFidagarriaDa = (errorea) => {
+ return errorea.operazioErroreaDa;
+ }
+}
+```
+
+
+
+Typescript
+
+```typescript
+// Garatzaileek operazio erroreak errorea.operazioErroreaDa=true zehazten dutela ziurtzat joz, irakur ezazu #3 jarraibide egokia
+process.on('uncaughtException', (errorea: Error) => {
+ erroreKudeaketa.kudeatzailea.kudeatuErrorea(errorea);
+ if(!erroreKudeaketa.kudeatzailea.erroreFidagarriaDa(errorea))
+ process.exit(1)
+});
+
+// Nodeko Erroretik datorren errore objektu zentralizatua
+export class AppErrorea extends Error {
+ public readonly operazioErroreaDa: boolean;
+
+ constructor(deskribapena: string, operazioErroreaDa: boolean) {
+ super(deskribapena);
+ Object.setPrototypeOf(this, new.target.prototype); // prototipo katea berreskuratu
+ this.operazioErroreaDa = operazioErroreaDa;
+ Error.captureStackTrace(this);
+ }
+}
+
+// errore kudeatzaile zentralizatuak errore-kudeaketa logika kapsulatzen du
+class ErroreKudeatzailea {
+ public async kudeatuErrorea(errorea: Error): Promise {
+ await logger.erroreaErregistratu(errorea);
+ await kritikoaBadaAdministrariariPostaElektronikoaBidali();
+ await kritikoaBadaOperazioZerrendanGorde();
+ await erabakiIaOperazioErroreaDen();
+ };
+
+ public erroreFidagarriaDa(errorea: Error) {
+ if (errorea instanceof AppErrorea) {
+ return errorea.operazioErroreaDa;
+ }
+ return false;
+ }
+}
+
+export const kudeatzailea = new ErroreKudeatzailea();
+```
+
+
+### Blog aipua: "Irtenbiderik hoberena huts eragitea da"
+
+Joyent bloga
+
+> …Programatzaileen erroreak konpontzeko modurik hoberena berehala krak egitea da. Programaren batek huts eginez gero, berrabiarazle bat erabiliz exekutatu beharko zenuke, automatikoki berrabiaraziko baitu. Berrabiarazlea dagoenean, huts egitea da programa fidagarria berreskuratzeko biderik azkarrena programatzailearen errore iragankor baten aurrean ...
+
+### Blog aipua: "Errore kudeaketaren inguruko hiru ideia eskola daude"
+
+JS Recipes bloga
+
+> …Errore kudeaketaren inguruko hiru ideia eskola nagusi daude:
+1. Utzi aplikazioari huts egiten eta ondoren berrabiarazi
+2. Errore posible guztiak kudeatu eta inoiz ez huts egin
+3. Bien arteko planteamendu bat
+
+### Blog aipua: "Ez dago modu segururik irteteko zehaztugabeko egoera hauskorrik sortu gabe"
+
+Node.js dokumentazio ofiziala
+
+> …JavaScripten lanak nola exekutatzen diren kontuan izanda, ez dago ia inoiz lan bati ziurtasunez jarraipena emateko biderik utzitako puntuan hasita, erreferentziak galdu gabe edota bestelako zehaztugabeko egoera hauskorrik sortu gabe. Jaurtitako errore bati erantzuteko modurik seguruena prozesua itzaltzea da. Jakina, web zerbitzari arruntetan, konexio ugari eduki ahal dituzu irekita, eta ez da zentzuzkoa tupustean haiek ixtea beste batek eragindako errore batengatik. Planteamendu hoberena da bidaltzea errore erantzun bat errorea bidali duen eskariari, besteei beren atazak bukatzeko denbora utziz, eta eskari berriei kasu egiteari uztea prozesu horretan
diff --git a/sections/errorhandling/shuttingtheprocess.french.md b/sections/errorhandling/shuttingtheprocess.french.md
new file mode 100644
index 000000000..517ac53e5
--- /dev/null
+++ b/sections/errorhandling/shuttingtheprocess.french.md
@@ -0,0 +1,99 @@
+# Quittez le processus avec élégance lorsqu'un étranger arrive en ville
+
+### Un paragraphe d'explication
+
+Quelque part dans votre code, un objet gestionnaire d'erreur est chargé de décider comment procéder lorsqu'une erreur est levée - si l'erreur est fiable (c.-à-d. une erreur opérationnelle, voir plus d'explications dans la bonne pratique n° 3), alors l'écriture dans le fichier journal peut être suffisante. Les choses deviennent floues si l'erreur n'est pas familière - cela signifie que certains composants peuvent être dans un état défectueux et toutes les demandes futures sont susceptibles d'échouer. Par exemple, en supposant un service émetteur de jetons avec un état unique qui a levé une exception et a perdu son état - à partir de ce moment, il pourrait se comporter de manière inattendue et entraîner l'échec de toutes les demandes. Dans ce scénario, arrêtez le processus et utilisez un « outil de redémarrage » (comme Forever, PM2, etc.) pour recommencer avec un état propre.
+
+### Exemple de code : décider s'il faut planter
+
+
+Javascript
+
+```javascript
+// En supposant que les développeurs marquent les erreurs opérationnelles connues avec error.isOperational = true, lisez la bonne pratique n° 3
+process.on('uncaughtException', (error) => {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+// le gestionnaire d'erreurs centralisé encapsule la logique liée à la gestion des erreurs
+function errorHandler() {
+ this.handleError = (error) => {
+ return logger.logError(error)
+ .then(sendMailToAdminIfCritical)
+ .then(saveInOpsQueueIfCritical)
+ .then(determineIfOperationalError);
+ }
+
+ this.isTrustedError = (error) => {
+ return error.isOperational;
+ }
+}
+```
+
+
+
+Typescript
+
+```typescript
+// En supposant que les développeurs marquent les erreurs opérationnelles connues avec error.isOperational = true, lisez la bonne pratique n° 3
+process.on('uncaughtException', (error: Error) => {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+// objet d'erreur centralisé qui dérive de l'Error de Node
+export class AppError extends Error {
+ public readonly isOperational: boolean;
+
+ constructor(description: string, isOperational: boolean) {
+ super(description);
+ Object.setPrototypeOf(this, new.target.prototype); // restaurer la chaîne du prototype
+ this.isOperational = isOperational;
+ Error.captureStackTrace(this);
+ }
+}
+
+// le gestionnaire d'erreurs centralisé encapsule la logique liée à la gestion des erreurs
+class ErrorHandler {
+ public async handleError(err: Error): Promise {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical();
+ await saveInOpsQueueIfCritical();
+ await determineIfOperationalError();
+ };
+
+ public isTrustedError(error: Error) {
+ if (error instanceof AppError) {
+ return error.isOperational;
+ }
+ return false;
+ }
+}
+
+export const handler = new ErrorHandler();
+```
+
+
+### Citation de blog : « La meilleure façon est de planter »
+
+Extrait du blog de Joyent
+
+> …La meilleure façon de récupérer des erreurs de programmation est de planter immédiatement. Vous devez exécuter vos programmes à l'aide d'un « outil de redémarrage » qui redémarrera automatiquement le programme en cas de plantage. Avec un « outil de redémarrage » en place, le plantage est le moyen le plus rapide de restaurer un service fiable face à une erreur de programmation transitoire…
+
+### Citation de blog : « Il y a principalement trois écoles de réflexion sur la gestion des erreurs »
+
+Extrait du blog de JS Recipes
+
+> …Il y a principalement trois écoles de réflexion sur la gestion des erreurs :
+1. Laissez l'application se planter et redémarrez-la.
+2. Gérez toutes les erreurs possibles et ne plantez jamais.
+3. Une approche équilibrée entre les deux
+
+### Citation de blog : « Aucune solution sûre pour sortir sans créer un état fragile indéfini »
+
+Extrait de la documentation officielle de Node.js
+
+> …De par la nature même du fonctionnement de throw en JavaScript, il n'y a presque jamais aucun moyen de « reprendre là où vous vous étiez arrêté » en toute sécurité, sans fuite de références, ou sans créer une autre sorte d'état fragile non défini. Le moyen le plus sûr de répondre à une erreur levée est d'arrêter le processus. Bien sûr, dans un serveur Web normal, de nombreuses connexions peuvent être ouvertes et il n'est pas raisonnable de les fermer brutalement car une erreur a été déclenchée par quelqu'un d'autre. La meilleure approche consiste à envoyer une réponse d'erreur à la demande qui a déclenché l'erreur tout en laissant les autres se terminer dans leur temps normal et à cesser d'écouter les nouvelles demandes de ce processus.
diff --git a/sections/errorhandling/shuttingtheprocess.japanese.md b/sections/errorhandling/shuttingtheprocess.japanese.md
new file mode 100644
index 000000000..b1c491f6b
--- /dev/null
+++ b/sections/errorhandling/shuttingtheprocess.japanese.md
@@ -0,0 +1,99 @@
+# 見ず知らずの事象が起きたら潔くプロセスを終了する
+
+### 一段落説明
+
+コード内のどこかで、エラーハンドラオブジェクトがエラー発生時にどのように処理するかを決定することに責任を負っているとき ー エラーが信頼されている場合は(すなわち、操作上のエラーのことです。ベストプラクティス 2.3 の説明を参照してください)、ログファイルに書き込むだけで十分かもしれません。不明なエラーの場合は、複雑になります ー 一部のコンポーネントが不完全な状態にあり、後に来るリクエストは失敗の対象となることを意味しています。例えば、シングルトンでステートフルなトークン発行者サービスが例外を投げて、保持していた状態を消失したと仮定しましょう ー これは、予期せぬ挙動をしたり、全てのリクエストが失敗する原因となっているかもしれません。このようなケースの場合は、プロセスを kill して、(Forever や PM2 などの)「再起動ツール」を利用してクリーンな状態からやり直してください。
+
+### コード例: クラッシュするかどうか決定する
+
+
+Javascript
+
+```javascript
+// 開発者は既知のエラーに対して error.isOperational=true とマークをつけることを仮定しています。ベストプラクティス 2.3 を参照してください
+process.on('uncaughtException', (error) => {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+// エラー処理関連のロジックをカプセル化した、集中化されたエラーハンドラ
+function errorHandler() {
+ this.handleError = (error) => {
+ return logger.logError(error)
+ .then(sendMailToAdminIfCritical)
+ .then(saveInOpsQueueIfCritical)
+ .then(determineIfOperationalError);
+ }
+
+ this.isTrustedError = (error) => {
+ return error.isOperational;
+ }
+}
+```
+
+
+
+Typescript
+
+```typescript
+// 開発者は既知のエラーに対して error.isOperational=true とマークをつけることを仮定しています。ベストプラクティス 2.3 を参照してください
+process.on('uncaughtException', (error: Error) => {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+// Node のエラーオブジェクトを継承した、集中化されたエラーオブジェクト
+export class AppError extends Error {
+ public readonly isOperational: boolean;
+
+ constructor(description: string, isOperational: boolean) {
+ super(description);
+ Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
+ this.isOperational = isOperational;
+ Error.captureStackTrace(this);
+ }
+}
+
+// エラー処理関連のロジックをカプセル化した、集中化されたエラーハンドラ
+class ErrorHandler {
+ public async handleError(err: Error): Promise {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical();
+ await saveInOpsQueueIfCritical();
+ await determineIfOperationalError();
+ };
+
+ public isTrustedError(error: Error) {
+ if (error instanceof AppError) {
+ return error.isOperational;
+ }
+ return false;
+ }
+}
+
+export const handler = new ErrorHandler();
+```
+
+
+### ブログ引用: "The best way is to crash"(最善の方法はクラッシュすることです)
+
+ブログ Joyent より
+
+> …プログラマーのエラーから復帰する最も良い方法は直ちにクラッシュさせることです。プログラムがクラッシュしたときに自動的に再起動してくれるリスターターを備えた、プログラムを動かすべきです。リスターターを備えている場合、一時的なプログラマーのエラーに直面した際に、安定したサービスへと復旧させるための一番手っ取り早い方法は、クラッシュさせることになります。
+
+### ブログ引用: "There are three schools of thoughts on error handling"(エラー処理について、3 つの考え方があります)
+
+ブログ JS Recipes より
+
+> …エラー処理について、主に以下の3つの考え方があります:
+1. アプリケーションをクラッシュさせ、再起動させる
+2. 起こりうるすべてのエラーを処理し、決してクラッシュさせない
+3. 上記 2 つをバランスよく取り入れたアプローチ
+
+### ブログ引用: "No safe way to leave without creating some undefined brittle state"(不明瞭で不安定な状態を作り出すことなしに、安全に中断する方法はありません)
+
+Node.js 公式ドキュメントより
+
+> …JavaScript における throw の挙動の性質上、参照をリークさせたり、不明瞭で不安定な状態を作り出したりすることなく、安全に「中断したところから再開する」方法はほぼありません。投げられたエラーに対応する最も安全な方法は、プロセスをシャットダウンすることです。もちろん、通常のウェブサーバーでは、多くのコネクションがオープン状態になっているかもしれず、エラーが他の誰かによって引き起こされたからといって、それらを急にシャットダウンすることは合理的ではありません。より良いアプローチは、エラーの引き金となったリクエストにエラーレスポンスを送り、他のリクエストは通常の時間内に終了するようにして、そのワーカーにおいて新しいリクエストの受信を停止することです。
diff --git a/sections/errorhandling/shuttingtheprocess.md b/sections/errorhandling/shuttingtheprocess.md
index e7f8b9ee3..69dd6ee0a 100644
--- a/sections/errorhandling/shuttingtheprocess.md
+++ b/sections/errorhandling/shuttingtheprocess.md
@@ -88,9 +88,9 @@ From the blog Joyent
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
+>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"
diff --git a/sections/errorhandling/shuttingtheprocess.polish.md b/sections/errorhandling/shuttingtheprocess.polish.md
new file mode 100644
index 000000000..d3eda50e1
--- /dev/null
+++ b/sections/errorhandling/shuttingtheprocess.polish.md
@@ -0,0 +1,99 @@
+# Opuść ten proces z wdziękiem, gdy do miasta przybywa nieznajomy
+
+### Wyjaśnienie jednym akapitem
+
+Gdzieś w twoim kodzie obiekt procedury obsługi błędów jest odpowiedzialny za podjęcie decyzji, jak postępować, gdy błąd zostanie zgłoszony - jeśli błąd jest zaufany (tj. błąd operacyjny, zobacz dalsze wyjaśnienie w najlepszych praktykach #3), zapisywanie w pliku dziennika może być wystarczające. Sprawa staje się pokręcona, jeśli błąd nie jest znany - oznacza to, że niektóre komponenty mogą być wadliwe, a wszystkie przyszłe żądania mogą ulec awarii. Na przykład, zakładając singletonowy serwis stateful token issuer, który zgłosił wyjątek i utracił swój stan - od teraz może zachowywać się niespodziewanie i powodować niepowodzenie wszystkich żądań. W tym scenariuszu zabij proces i użyj „narzędzia Restarter” (takiego jak Forever, PM2 itp.), Aby zacząć od nowa z czystym stanem.
+
+### Przykład kodu: decydowanie o awarii
+
+
+Javascript
+
+```javascript
+// Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
+process.on('uncaughtException', (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 = (error) => {
+ return logger.logError(error)
+ .then(sendMailToAdminIfCritical)
+ .then(saveInOpsQueueIfCritical)
+ .then(determineIfOperationalError);
+ }
+
+ this.isTrustedError = (error) => {
+ return error.isOperational;
+ }
+}
+```
+
+
+
+Typescript
+
+```typescript
+// Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
+process.on('uncaughtException', (error: Error) => {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+// centralized error object that derives from Node’s Error
+export class AppError extends Error {
+ public readonly isOperational: boolean;
+
+ constructor(description: string, isOperational: boolean) {
+ super(description);
+ Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
+ this.isOperational = isOperational;
+ Error.captureStackTrace(this);
+ }
+}
+
+// centralized error handler encapsulates error-handling related logic
+class ErrorHandler {
+ public async handleError(err: Error): Promise {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical();
+ await saveInOpsQueueIfCritical();
+ await determineIfOperationalError();
+ };
+
+ public isTrustedError(error: Error) {
+ if (error instanceof AppError) {
+ return error.isOperational;
+ }
+ return false;
+ }
+}
+
+export const handler = new ErrorHandler();
+```
+
+
+### Cytat z bloga: "The best way is to crash"
+
+Z bloga 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…
+
+### Cytat z bloga: "There are three schools of thoughts on error handling"
+
+Z bloga: 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
+
+### Cytat z bloga: "No safe way to leave without creating some undefined brittle state"
+
+Z oficjalnej dokumentacji Node.js
+
+> …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/shuttingtheprocess.russian.md b/sections/errorhandling/shuttingtheprocess.russian.md
index e0d58f935..15f17043b 100644
--- a/sections/errorhandling/shuttingtheprocess.russian.md
+++ b/sections/errorhandling/shuttingtheprocess.russian.md
@@ -6,28 +6,76 @@
### Пример кода: решение о сбое
+
+Javascript
+
```javascript
// Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
-process.on('uncaughtException', function(error) {
+process.on('uncaughtException', (error) => {
errorManagement.handler.handleError(error);
if(!errorManagement.handler.isTrustedError(error))
- process.exit(1)
+ process.exit(1)
});
// centralized error handler encapsulates error-handling related logic
function errorHandler() {
- this.handleError = function (error) {
- return logger.logError(err)
+ this.handleError = (error) => {
+ return logger.logError(error)
.then(sendMailToAdminIfCritical)
.then(saveInOpsQueueIfCritical)
.then(determineIfOperationalError);
}
- this.isTrustedError = function (error) {
+ this.isTrustedError = (error) => {
return error.isOperational;
}
}
```
+
+
+
+Typescript
+
+```typescript
+// Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
+process.on('uncaughtException', (error: Error) => {
+ errorManagement.handler.handleError(error);
+ if(!errorManagement.handler.isTrustedError(error))
+ process.exit(1)
+});
+
+// centralized error object that derives from Node’s Error
+export class AppError extends Error {
+ public readonly isOperational: boolean;
+
+ constructor(description: string, isOperational: boolean) {
+ super(description);
+ Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
+ this.isOperational = isOperational;
+ Error.captureStackTrace(this);
+ }
+}
+
+// centralized error handler encapsulates error-handling related logic
+class ErrorHandler {
+ public async handleError(err: Error): Promise {
+ await logger.logError(err);
+ await sendMailToAdminIfCritical();
+ await saveInOpsQueueIfCritical();
+ await determineIfOperationalError();
+ };
+
+ public isTrustedError(error: Error) {
+ if (error instanceof AppError) {
+ return error.isOperational;
+ }
+ return false;
+ }
+}
+
+export const handler = new ErrorHandler();
+```
+
### Цитата из блога: "Лучший способ - это рухнуть"
diff --git a/sections/errorhandling/testingerrorflows.basque.md b/sections/errorhandling/testingerrorflows.basque.md
new file mode 100644
index 000000000..994251bf7
--- /dev/null
+++ b/sections/errorhandling/testingerrorflows.basque.md
@@ -0,0 +1,94 @@
+# Testeatu erroreen fluxua zure test framework gustukoena erabiliz
+
+### Azalpena
+
+Bide ‘alaiak’ probatzea ez da hutsegiteak probatzea baino hobea. Probako kodeen estaldura ona da salbuespenezko bideak probatzeko. Bestela, ez dago inolako konfidantzarik salbuespenak zuzen kudeatuta dauden. Unitateen azterketa esparru guztiek, [Mocha](https://mochajs.org/) eta [Chai](http://chaijs.com/)k bezala, onartzen dituzte salbuespen probak (kode adibideak beherago). Gogaikarria iruditzen bazaizu funtzio eta salbuespen bakoitza probatzea, REST APIen HTTP erroreak bakarrik probatzea erabaki zenezake
+
+
+### Kode adibidea: ziurtatu salbuespen egokia jaurtitzen dela Mocha eta Chai erabiliz
+
+
+Javascript
+
+```javascript
+describe("Facebooken txata", () => {
+ it("Jakinarazi txateko mezu berria iristean", () => {
+ const txatZerbitzua = new txatZerbitzua();
+ txatZerbitzua.parteHartzaileak = eskuratuDeskonektatutakoParteHartzaileak();
+ expect(txatZerbitzua.mezuaBidali.bind({ mezua: "Aupa" })).to.throw(
+ KonexioErrorea
+ );
+ });
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+describe("Facebooken txata", () => {
+ it("Jakinarazi txateko mezu berria iristean", () => {
+ const txatZerbitzua = new txatZerbitzua();
+ txatZerbitzua.parteHartzaileak = eskuratuDeskonektatutakoParteHartzaileak();
+ expect(txatZerbitzua.mezuaBidali.bind({ mezua: "Aupa" })).to.throw(
+ KonexioErrorea
+ );
+ });
+});
+```
+
+
+
+### Kodearen adibidea: APIak HTTP errore kode zuzena bueltatzen duela ziurtatu
+
+
+Javascript
+
+```javascript
+it("Facebookeko talde berria sortu", () => {
+ const taldeOkerrarenInformazioa = {};
+ return httpRequest({
+ method: "POST",
+ uri: "facebook.com/api/groups",
+ resolveWithFullResponse: true,
+ body: taldeOkerrarenInformazioa,
+ json: true,
+ })
+ .then((response) => {
+ expect.fail(
+ "kodea bloke honetan exekutatu nahi bagenu, goiko operazioan errorerik ez da izan"
+ );
+ })
+ .catch((response) => {
+ expect(400).to.equal(response.statusCode);
+ });
+});
+```
+
+
+
+
+Typescript
+
+```typescript
+it("Facebookeko talde berria sortu", async () => {
+ let taldeOkerrarenInformazioa = {};
+ try {
+ const response = await httpRequest({
+ method: "POST",
+ uri: "facebook.com/api/groups",
+ resolveWithFullResponse: true,
+ body: taldeOkerrarenInformazioa,
+ json: true,
+ });
+ // kodea bloke honetan exekutatu nahi bagenu, goiko operazioan errorerik ez da izan
+ expect.fail("Eskaerak huts egin behar izango luke");
+ } catch (response) {
+ expect(400).to.equal(response.statusCode);
+ }
+});
+```
+
+
diff --git a/sections/errorhandling/testingerrorflows.french.md b/sections/errorhandling/testingerrorflows.french.md
new file mode 100644
index 000000000..2e385ecbb
--- /dev/null
+++ b/sections/errorhandling/testingerrorflows.french.md
@@ -0,0 +1,81 @@
+# Testez les flux d'erreurs en utilisant votre framework de test préféré
+
+### Un paragraphe d'explication
+
+Tester les chemins « du bonheur » n’est pas mieux que de tester les échecs. Une bonne couverture du code de test exige de tester des chemins inhabituels. Sinon, il n'est pas certain que les exceptions soient effectivement gérées correctement. Chaque framework de tests unitaires, comme [Mocha](https://mochajs.org/) et [Chai](http://chaijs.com/), prend en charge les tests d'exception (exemples de code ci-dessous). Si vous trouvez fastidieux de tester chaque fonction interne et chaque exception, vous pouvez vous contenter de tester uniquement les erreurs HTTP de l'API REST.
+
+### Exemple de code : s'assurer que la bonne exception est levée à l'aide de Mocha & Chai
+
+
+Javascript
+
+```javascript
+describe('Facebook chat', () => {
+ it('Avertit en cas de nouveau message dans la discussion', () => {
+ const chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: 'Salut' })).to.throw(ConnectionError);
+ });
+});
+```
+
+
+
+Typescript
+
+```typescript
+describe('Facebook chat', () => {
+ it('Avertit en cas de nouveau message dans la discussion', () => {
+ const chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: 'Salut' })).to.throw(ConnectionError);
+ });
+});
+```
+
+
+### Exemple de code: s'assurer que l'API renvoie le bon code erreur HTTP
+
+
+Javascript
+
+```javascript
+it('Crée un nouveau groupe Facebook', () => {
+ const invalidGroupInfo = {};
+ return httpRequest({
+ method: 'POST',
+ uri: 'facebook.com/api/groups',
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ }).then((response) => {
+ expect.fail('si nous devions exécuter le code dans ce bloc, aucune erreur n\'a été levée dans l\'opération ci-dessus')
+ }).catch((response) => {
+ expect(400).to.equal(response.statusCode);
+ });
+});
+```
+
+
+
+Typescript
+
+```typescript
+it('Crée un nouveau groupe Facebook', async () => {
+ let invalidGroupInfo = {};
+ try {
+ const response = await httpRequest({
+ method: 'POST',
+ uri: 'facebook.com/api/groups',
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ })
+ // si nous devions exécuter le code dans ce bloc, aucune erreur n'a été levée dans l'opération ci-dessus
+ expect.fail('La requête aurait dû échouer')
+ } catch(response) {
+ expect(400).to.equal(response.statusCode);
+ }
+});
+```
+
\ No newline at end of file
diff --git a/sections/errorhandling/testingerrorflows.japanese.md b/sections/errorhandling/testingerrorflows.japanese.md
new file mode 100644
index 000000000..8d587d234
--- /dev/null
+++ b/sections/errorhandling/testingerrorflows.japanese.md
@@ -0,0 +1,81 @@
+# お気に入りのテストフレームワークを使用してエラーフローをテストする
+
+### 一段落説明
+
+「ハッピー」パスをテストすることは、失敗をテストすることも同然です。良いテストコードカバレッジは、例外パスをテストすることを要求します。さもなければ、例外が実際に正しく処理されるという信用はありません。[Mocha](https://mochajs.org/) や [Chai](http://chaijs.com/) といったすべてのユニットテストフレームワークは、例外テストをサポートしています(下記のコード例参照)。もしすべての内部関数や例外をテストすることが面倒だと感じたら、REST API の HTTP エラーのみをテストすることに落ち着くかもしれません。
+
+### コード例: Mocha と Chai を利用して正しい例外が投げられることを確認する
+
+
+Javascript
+
+```javascript
+describe('Facebook chat', () => {
+ it('Notifies on new chat message', () => {
+ const chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
+ });
+});
+```
+
+
+
+Typescript
+
+```typescript
+describe('Facebook chat', () => {
+ it('Notifies on new chat message', () => {
+ const chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
+ });
+});
+```
+
+
+### コード例: API が正しい HTTP エラーコードを返すことを確認する
+
+
+Javascript
+
+```javascript
+it('Creates new Facebook group', () => {
+ const invalidGroupInfo = {};
+ return httpRequest({
+ method: 'POST',
+ uri: 'facebook.com/api/groups',
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ }).then((response) => {
+ expect.fail('if we were to execute the code in this block, no error was thrown in the operation above')
+ }).catch((response) => {
+ expect(400).to.equal(response.statusCode);
+ });
+});
+```
+
+
+
+Typescript
+
+```typescript
+it('Creates new Facebook group', async () => {
+ let invalidGroupInfo = {};
+ try {
+ const response = await httpRequest({
+ method: 'POST',
+ uri: 'facebook.com/api/groups',
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ })
+ // このブロックで下記コードを実行した場合、上記オペレーションではエラーが発生しなかったことを意味します
+ expect.fail('The request should have failed')
+ } catch(response) {
+ expect(400).to.equal(response.statusCode);
+ }
+});
+```
+
\ No newline at end of file
diff --git a/sections/errorhandling/testingerrorflows.md b/sections/errorhandling/testingerrorflows.md
index 552ca1f53..ac03f4146 100644
--- a/sections/errorhandling/testingerrorflows.md
+++ b/sections/errorhandling/testingerrorflows.md
@@ -10,72 +10,69 @@ Testing ‘happy’ paths is no better than testing failures. Good testing code
Javascript
```javascript
-describe('Facebook chat', () => {
- it('Notifies on new chat message', () => {
+describe("Facebook chat", () => {
+ it("Notifies on new chat message", () => {
const chatService = new chatService();
chatService.participants = getDisconnectedParticipants();
- expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
+ expect(chatService.sendMessage.bind({ message: "Hi" })).to.throw(ConnectionError);
});
});
```
+
+### Code example: ensuring API returns the right HTTP error code and log properly
+
-Typescript
+Javascript
-```typescript
-describe('Facebook chat', () => {
- it('Notifies on new chat message', () => {
- const chatService = new chatService();
- chatService.participants = getDisconnectedParticipants();
- expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
+```javascript
+test("When exception is throw during request, Then logger reports the mandatory fields", async () => {
+ //Arrange
+ const orderToAdd = {
+ userId: 1,
+ productId: 2,
+ };
+
+ sinon
+ .stub(OrderRepository.prototype, "addOrder")
+ .rejects(new AppError("saving-failed", "Order could not be saved", 500));
+ const loggerDouble = sinon.stub(logger, "error");
+
+ //Act
+ const receivedResponse = await axiosAPIClient.post("/order", orderToAdd);
+
+ //Assert
+ expect(receivedResponse.status).toBe(500);
+ expect(loggerDouble.lastCall.firstArg).toMatchObject({
+ name: "saving-failed",
+ status: 500,
+ stack: expect.any(String),
+ message: expect.any(String),
});
});
```
+
-### Code example: ensuring API returns the right HTTP error code
+### Code example: ensuring that are uncaught exceptions are handled as well
Javascript
```javascript
-it('Creates new Facebook group', () => {
- const invalidGroupInfo = {};
- return httpRequest({
- method: 'POST',
- uri: 'facebook.com/api/groups',
- resolveWithFullResponse: true,
- body: invalidGroupInfo,
- json: true
- }).then((response) => {
- expect.fail('if we were to execute the code in this block, no error was thrown in the operation above')
- }).catch((response) => {
- expect(400).to.equal(response.statusCode);
- });
-});
-```
-
+test("When unhandled exception is throw, Then the logger reports correctly", async () => {
+ //Arrange
+ await api.startWebServer();
+ const loggerDouble = sinon.stub(logger, "error");
+ const errorToThrow = new Error("An error that wont be caught 😳");
-
-Typescript
-
-```typescript
-it('Creates new Facebook group', async () => {
- let invalidGroupInfo = {};
- try {
- const response = await httpRequest({
- method: 'POST',
- uri: 'facebook.com/api/groups',
- resolveWithFullResponse: true,
- body: invalidGroupInfo,
- json: true
- })
- // if we were to execute the code in this block, no error was thrown in the operation above
- expect.fail('The request should have failed')
- } catch(response) {
- expect(400).to.equal(response.statusCode);
- }
+ //Act
+ process.emit("uncaughtException", errorToThrow);
+
+ // Assert
+ expect(loggerDouble.calledWith(errorToThrow));
});
```
-
\ No newline at end of file
+
+
diff --git a/sections/errorhandling/testingerrorflows.polish.md b/sections/errorhandling/testingerrorflows.polish.md
new file mode 100644
index 000000000..7cf2f347b
--- /dev/null
+++ b/sections/errorhandling/testingerrorflows.polish.md
@@ -0,0 +1,81 @@
+# Przepływy błędów testowych przy użyciu ulubionego środowiska testowego
+
+### Wyjaśnienie jednym akapitem
+
+Testowanie „szczęśliwych” ścieżek nie jest lepsze niż testowanie błędów. Dobry zasięg kodu testowego wymaga testowania wyjątkowych ścieżek. W przeciwnym razie nie ma zaufania, że wyjątki rzeczywiście są obsługiwane poprawnie. Każda platforma testowania jednostek, jak [Mocha](https://mochajs.org/) i [Chai](http://chaijs.com/), obsługuje testowanie wyjątków (przykłady kodu poniżej). Jeśli okaże się, że testowanie każdej funkcji wewnętrznej i wyjątku jest uciążliwe, możesz zadowolić się testowaniem tylko błędów HTTP interfejsu REST API.
+
+### Przykład kodu: upewnienie się, że odpowiedni wyjątek jest zgłaszany za pomocą Mocha i Chai
+
+
+Javascript
+
+```javascript
+describe('Facebook chat', () => {
+ it('Notifies on new chat message', () => {
+ const chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
+ });
+});
+```
+
+
+
+Typescript
+
+```typescript
+describe('Facebook chat', () => {
+ it('Notifies on new chat message', () => {
+ const chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
+ });
+});
+```
+
+
+### Przykład kodu: upewnienie się, że API zwraca prawidłowy kod błędu HTTP
+
+
+Javascript
+
+```javascript
+it('Creates new Facebook group', () => {
+ const invalidGroupInfo = {};
+ return httpRequest({
+ method: 'POST',
+ uri: 'facebook.com/api/groups',
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ }).then((response) => {
+ expect.fail('if we were to execute the code in this block, no error was thrown in the operation above')
+ }).catch((response) => {
+ expect(400).to.equal(response.statusCode);
+ });
+});
+```
+
+
+
+Typescript
+
+```typescript
+it('Creates new Facebook group', async () => {
+ let invalidGroupInfo = {};
+ try {
+ const response = await httpRequest({
+ method: 'POST',
+ uri: 'facebook.com/api/groups',
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ })
+ // if we were to execute the code in this block, no error was thrown in the operation above
+ expect.fail('The request should have failed')
+ } catch(response) {
+ expect(400).to.equal(response.statusCode);
+ }
+});
+```
+
diff --git a/sections/errorhandling/testingerrorflows.russian.md b/sections/errorhandling/testingerrorflows.russian.md
index 4b0429c34..300069881 100644
--- a/sections/errorhandling/testingerrorflows.russian.md
+++ b/sections/errorhandling/testingerrorflows.russian.md
@@ -6,33 +6,76 @@
### Пример кода: обеспечение правильного исключения с помощью Mocha & Chai
+
+Javascript
+
```javascript
-describe("Facebook chat", () => {
- it("Notifies on new chat message", () => {
- var chatService = new chatService();
+describe('Facebook chat', () => {
+ it('Notifies on new chat message', () => {
+ const chatService = new chatService();
chatService.participants = getDisconnectedParticipants();
- expect(chatService.sendMessage.bind({ message: "Hi" })).to.throw(ConnectionError);
+ expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
});
});
+```
+
+
+Typescript
+
+```typescript
+describe('Facebook chat', () => {
+ it('Notifies on new chat message', () => {
+ const chatService = new chatService();
+ chatService.participants = getDisconnectedParticipants();
+ expect(chatService.sendMessage.bind({ message: 'Hi' })).to.throw(ConnectionError);
+ });
+});
```
+
### Пример кода: застрахованное API возвращает правильный код ошибки HTTP
+
+Javascript
+
```javascript
-it("Creates new Facebook group", function (done) {
- var invalidGroupInfo = {};
- httpRequest({
+it('Creates new Facebook group', () => {
+ const invalidGroupInfo = {};
+ return httpRequest({
method: 'POST',
- uri: "facebook.com/api/groups",
+ 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.fail('if we were to execute the code in this block, no error was thrown in the operation above')
+ }).catch((response) => {
expect(400).to.equal(response.statusCode);
- done();
});
});
```
+
+
+
+Typescript
+
+```typescript
+it('Creates new Facebook group', async () => {
+ let invalidGroupInfo = {};
+ try {
+ const response = await httpRequest({
+ method: 'POST',
+ uri: 'facebook.com/api/groups',
+ resolveWithFullResponse: true,
+ body: invalidGroupInfo,
+ json: true
+ })
+ // if we were to execute the code in this block, no error was thrown in the operation above
+ expect.fail('The request should have failed')
+ } catch(response) {
+ expect(400).to.equal(response.statusCode);
+ }
+});
+```
+
\ No newline at end of file
diff --git a/sections/errorhandling/usematurelogger.basque.md b/sections/errorhandling/usematurelogger.basque.md
new file mode 100644
index 000000000..2c20e5497
--- /dev/null
+++ b/sections/errorhandling/usematurelogger.basque.md
@@ -0,0 +1,41 @@
+# Erabili erregistratze tresna heldu bat erroreen ikusgaitasuna handitzeko
+
+### Azalpena
+
+Gustuko dugu console.log, baina [Pino][pino] bezalako erregistratzaile tresna ospetsu eta iraunkorra (errendimenduan zentratutako aukera berriagoa) ezinbestekoa da proiektu serioetarako. Errendimendu handiko erregistratze tresnek erroreak eta arazo posibleak identifikatzen laguntzen dute. Erregistratze aholkuen artean:
+
+1. Maiz erregistratu maila ezberdinak erabiliz (debug, info, error)
+2. Erregistratzerako orduan, eman testuinguruaren informazioa JSON objektu eran
+3. Monitorizatu erregistro kontsultak API batekin (erregistro sistema ezberdinetarako erabilgarria) edota erregistro ikustailearen software batekin
+4. Erakutsi erregistroen informazioa [Splunk][splunk] bezalako operazio inteligentzia tresnekin
+
+[pino]: https://www.npmjs.com/package/pino
+[splunk]: https://www.splunk.com/
+
+### Kode adibidea
+
+```JavaScript
+const pino = require('pino');
+
+// zure erregistro objektu zentralizatua
+const erregistratzailea = pino();
+
+// erregistratzailea erabiltzen duen zure kode propioa
+erregistratzailea.info({ anything: 'Hau metadatua da' }, 'Frogatu Erregistro Mezua %s parametroren batekin', 'parametroren bat');
+```
+
+### Blog aipua: "Erregistratzailearen betebeharrak"
+
+StrongLoop bloga ("Winston eta Bunyanen Node.js Erregistratzaile sistemak konparatzen" Alex Corbatcheven eskutik, 2014ko ekainaren 24a):
+
+> Identifika ditzagun betebehar gutxi batzuk (erregistratzaile batentzat):
+>
+> 1. Denboran seilatu erregistro ilara bakoitza. Nahiko argi dago, erregistroko sarrera bakoitza noiz gertatu den esateko gai izan behar duzu
+> 2. Erregistro formatua ulergarria izan behar da bai gizakientzat eta baita makinentzat ere
+> 3. Korronte ezberdin ugari onartu behar ditu. Adibidez, errore erregistroak fitxategi batean idazten ari den unean erroreren bat atzemanez gero, fitxategi beraren barruan idatzi, errorearen fitxategian ere idatzi, eta posta elektronikoa bidali, dena aldi berean, egiteko aukera eman behar du
+
+### Non dago Winston?
+
+Zergatik ohiko faboritoak (adibidez, Winston) ez dauden aholkatutako pratika onenen egungo zerrendan jakiteko, begiratu # [#684][#684]an
+
+[#684]: https://github.com/goldbergyoni/nodebestpractices/issues/684
diff --git a/sections/errorhandling/usematurelogger.french.md b/sections/errorhandling/usematurelogger.french.md
new file mode 100644
index 000000000..e9fb1fc87
--- /dev/null
+++ b/sections/errorhandling/usematurelogger.french.md
@@ -0,0 +1,41 @@
+# Utilisez un outil de journalisation mature pour augmenter la visibilité des erreurs
+
+### Un paragraphe d'explication
+
+Nous adorons console.log mais un logger réputé et persistant comme [Pino][pino] (une option plus récente axée sur les performances) est obligatoire pour les projets sérieux.
+Des outils de journalisation très performants permettent d'identifier les erreurs et les problèmes éventuels. Les recommandations en matière de journalisation sont :
+
+1. Enregistrer fréquemment en utilisant différents niveaux (débogage, info, erreur).
+2. Lors de la journalisation, fournir des informations contextuelles sous forme d'objets JSON.
+3. Surveiller et filtrer les journaux à l'aide d'une API d'interrogation des journaux (intégrée à de nombreux enregistreurs) ou d'un logiciel de visualisation des journaux.
+4. Exposer et conserver les déclarations de journal avec des outils de renseignement opérationnel tels que [Splunk][splunk].
+
+[pino]: https://www.npmjs.com/package/pino
+[splunk]: https://www.splunk.com/
+
+### Exemple de code
+
+```javascript
+const pino = require('pino');
+
+// votre objet de journalisation centralisé
+const logger = pino();
+
+// code personnalisé quelque part à l'aide de l'outil de journalisation
+logger.info({ anything: 'This is metadata' }, 'Test Log Message with some parameter %s', 'some parameter');
+```
+
+### Citation de blog : « Exigences d'un outil de journalisation »
+
+ Extrait du blog de Strong Loop ("Comparing Winston and Bunyan Node.js Logging" par Alex Corbatchev, 24 juin 2014) :
+
+> Permet d'identifier quelques exigences (pour un outil de journalisation) :
+> 1. Chaque ligne du journal est horodatée. Celle-ci est assez explicite - vous devriez pouvoir dire quand chaque entrée du journal s'est produite.
+> 2. Le format d'enregistrement doit être facilement assimilable par les humains ainsi que par les machines.
+> 3. Permet plusieurs flux de destination configurables. Par exemple, vous pouvez écrire des journaux de trace dans un fichier, mais lorsqu'une erreur se produit, cela écrit dans le même fichier, puis dans le fichier d'erreur et envoi un e-mail en même temps…
+
+### Où est Winston ?
+
+Pour plus d'informations sur les raisons pour lesquelles les favoris traditionnels (par exemple, Winston) peuvent ne pas être inclus dans la liste actuelle des meilleures pratiques recommandées, veuillez consulter [#684][#684].
+
+[#684]: https://github.com/goldbergyoni/nodebestpractices/issues/684
diff --git a/sections/errorhandling/usematurelogger.japanese.md b/sections/errorhandling/usematurelogger.japanese.md
new file mode 100644
index 000000000..d895a9404
--- /dev/null
+++ b/sections/errorhandling/usematurelogger.japanese.md
@@ -0,0 +1,50 @@
+# エラーの可視性を高めるために成熟したロガーを使用する
+
+### 一段落説明
+
+私たちはみな console.log を愛用していますが、明らかに [Winston][winston](非常に人気)や [Pino][pino](パフォーマンスにフォーカスした新参者)のような、評価が高く永続的なロガーが真面目なプロジェクトにおいて必須となります。一連のプラクティスやツール群は、より素早くエラーについての考察を行うことに役立ちます ー(1)ログレベルを使い分ける(debug、info、error)、(2)ロギングする際は、JSON オブジェクトとしてコンテキスト情報を提供する(下記の例を参照)、(3)(多くのロガーに組み込まれている)ログクエリ API やログビューアソフトウェアを使用して、ログの確認やフィルタリングを行う、(4)Splunk のような運用ツールを使用して、運用チームのためにログステートメントを公開し、まとめる
+
+[winston]: https://www.npmjs.com/package/winston
+[pino]: https://www.npmjs.com/package/pino
+
+### コード例 – Winston 実践
+
+```javascript
+// 集中化されたロガーオブジェクト
+const logger = new winston.Logger({
+ level: 'info',
+ transports: [
+ new (winston.transports.Console)()
+ ]
+});
+
+// ロガーを使用したカスタムコード
+logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
+```
+
+### コード例 – ログフォルダをクエリする(エントリを検索する)
+
+```javascript
+const options = {
+ from: Date.now() - 24 * 60 * 60 * 1000,
+ until: new Date(),
+ limit: 10,
+ start: 0,
+ order: 'desc',
+ fields: ['message']
+};
+
+// 1日前から今にかけてのログを見つける
+winston.query(options, (err, results) => {
+ // results を受け取ってコールバックを実行する
+});
+```
+
+### ブログ引用: "Logger Requirements"(ロガーの要件)
+
+ブログ Strong Loop より
+
+> (ロガーのための)いくつかの要件を確認してみましょう:
+1. 各ログ行にタイムスタンプをつけましょう。これは非常に自明です ー 各ログエントリがいつ発生したのかをはっきりさせることができるはずです。
+2. ロギングフォーマットは、機械だけでなく人間にとっても容易に解釈できるものであるべきです。
+3. 複数の設定可能な送信先ストリームを許可しましょう。例えば、あるファイルにトレースログを書き込み、一方でエラーが発生した際は同様のファイルに書き込むと同時にエラーファイルにも書き込み、そして e メールを送信するかもしれません。
diff --git a/sections/errorhandling/usematurelogger.md b/sections/errorhandling/usematurelogger.md
index 237de5309..68fd3de65 100644
--- a/sections/errorhandling/usematurelogger.md
+++ b/sections/errorhandling/usematurelogger.md
@@ -1,50 +1,42 @@
-# Use a mature logger to increase errors visibility
+# Use a mature logger to increase error visibility
### One Paragraph Explainer
-We all love console.log but obviously, a reputable and persistent logger like [Winston][winston] (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.
+We love console.log but a reputable and persistent logger like [Pino][pino] (a newer option focused on performance) is mandatory for serious projects.
+High-performance logging tools help identify errors and possible issues. Logging recommendations include:
+
+1. Log frequently using different levels (debug, info, error).
+2. When logging, provide contextual information as JSON objects.
+3. Monitor and filter logs with a log querying API (built-in to many loggers) or log viewer software.
+4. Expose and curate log statements with operational intelligence tools such as [Splunk][splunk].
-[winston]: https://www.npmjs.com/package/winston
[pino]: https://www.npmjs.com/package/pino
+[splunk]: https://www.splunk.com/
+
+### Code Example
-### Code Example – Winston Logger in action
+```JavaScript
+const pino = require('pino');
-```javascript
// your centralized logger object
-const logger = new winston.Logger({
- level: 'info',
- transports: [
- new (winston.transports.Console)()
- ]
-});
+const logger = pino();
// 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
-const options = {
- from: Date.now() - 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, (err, results) => {
- // execute callback with results
-});
+logger.info({ anything: 'This is metadata' }, 'Test Log Message with some parameter %s', 'some parameter');
```
### Blog Quote: "Logger Requirements"
- From the blog Strong Loop
+ From the StrongLoop blog ("Comparing Winston and Bunyan Node.js Logging" by Alex Corbatchev, Jun 24, 2014):
+
+> Let's 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.
+
+### Where's Winston?
+
+For more information on why traditional favorites (e.g., Winston) may not be included in the current list of recommended best practices, please see [#684][#684].
+
+[#684]: https://github.com/goldbergyoni/nodebestpractices/issues/684
-> 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/usematurelogger.polish.md b/sections/errorhandling/usematurelogger.polish.md
new file mode 100644
index 000000000..d8d407c52
--- /dev/null
+++ b/sections/errorhandling/usematurelogger.polish.md
@@ -0,0 +1,50 @@
+# Użyj dojrzałego programu rejestrującego, aby zwiększyć widoczność błędów
+
+### Wyjaśnienie jednym akapitem
+
+Wszyscy kochamy console.log, ale oczywiście poważny projekt to renomowany i trwały rejestrator, taki jak [Winston] [winston] (bardzo popularny) lub [Pino] [pino] (nowy dzieciak w mieście, który koncentruje się na wydajności). Zestaw praktyk i narzędzi pomoże znacznie szybciej uzasadnić błędy - (1) często rejestruj dane przy użyciu różnych poziomów (debugowanie, informacje, błąd), (2) podczas logowania, podaj informacje kontekstowe jako obiekty JSON, patrz przykład poniżej. (3) Oglądaj i filtruj dzienniki za pomocą interfejsu API do wysyłania zapytań (wbudowanego w większość programów rejestrujących) lub oprogramowania do przeglądania dzienników. (4) Ujawnij i wyślij oświadczenie dziennika dla zespołu operacyjnego za pomocą narzędzi wywiadu operacyjnego, takich jak Splunk.
+
+[winston]: https://www.npmjs.com/package/winston
+[pino]: https://www.npmjs.com/package/pino
+
+### Przykład kodu - Winston Logger w akcji
+
+```javascript
+// your centralized logger object
+const logger = new winston.Logger({
+ level: 'info',
+ transports: [
+ new (winston.transports.Console)()
+ ]
+});
+
+// custom code somewhere using the logger
+logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
+```
+
+### Przykład kodu - zapytanie do folderu dziennika (wyszukiwanie wpisów)
+
+```javascript
+const options = {
+ from: Date.now() - 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, (err, results) => {
+ // execute callback with results
+});
+```
+
+### Cytat z Bloga: "Logger Requirements"
+
+ Z Bloga 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/usematurelogger.russian.md b/sections/errorhandling/usematurelogger.russian.md
index a96158f32..30c356bca 100644
--- a/sections/errorhandling/usematurelogger.russian.md
+++ b/sections/errorhandling/usematurelogger.russian.md
@@ -11,7 +11,7 @@
```javascript
// your centralized logger object
-var logger = new winston.Logger({
+const logger = new winston.Logger({
level: 'info',
transports: [
new (winston.transports.Console)()
@@ -20,24 +20,22 @@ var logger = new winston.Logger({
// custom code somewhere using the 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,
+const options = {
+ from: Date.now() - 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) {
+winston.query(options, (err, results) => {
// execute callback with results
});
```
diff --git a/sections/errorhandling/useonlythebuiltinerror.basque.md b/sections/errorhandling/useonlythebuiltinerror.basque.md
new file mode 100644
index 000000000..008ddd5f8
--- /dev/null
+++ b/sections/errorhandling/useonlythebuiltinerror.basque.md
@@ -0,0 +1,136 @@
+# Erabili soilik “Errorea” objektu kapsulatua
+
+### Azalpena
+
+JavaScriptek berezko permisibitatea du, eta, bere kode fluxuaren aukera ugariarekin (adibidez EventEmitter, Callbackak, Promesak ...), garatzaileek erroreak kudeatzeko modu anitzak edukitzea eragiten du: batzuek stringak erabiltzen dituzte, besteek beren mota pertsonalizatuak zehazten dituzte. Node.jsren "Errorea" objektu kapsulatua erabiltzeak zure kodearen eta bestelako liburutegien arteko uniformetasuna gordetzen laguntzen du, eta gainera StracTracea bezalako informazio esanguratsua gordetzen du. Salbuespen bat jaurtitzean, jarraibide egokia da errorearen izena edo erlazionatutako HTTP errore kodea bezalako testuinguru ezaugarriekin osatzea. Uniformetasun eta praktika hau lortzeko, saiatu "Errorea" objektua beharrezko ezaugarriekin osatzen, baina kontu izan gehiegitan ez egiten. Orokorrean ideia ona da "Errorea" objektu kapsulatua behin bakarrik osatzea AppErrore batekin aplikazioaren maila guztietako erroreentzat, eta beharrezko duzun informazioa argumentu gisa pasatuz errore klase ezberdinak ezberdintzeko. Ez da beharrezkoa "Errorea" objektua askotan osatzea (errore kasu bakoitzerako behin, adibidez DbError, HttpError...). Begiratu ondorengo kode adibideak
+
+### Kode adibidea: era zuzenean egin
+
+```javascript
+// ohizko funtzio batean Error objektua jaurti, sinkronoa dela edo asinkronoa dela (sync async)
+if (!gehitzekoProduktua)
+ throw new Error("Nola gehi dezaket produktu bat baliorik ez duenean?");
+
+// Error objektua jaurti EventEmitteretik
+const myEmitter = new MyEmitter();
+nireEmitter.emit("error", new Error("whoops!"));
+
+// Error objektua jaurti Promesa batetik
+const gehituProduktua = async (gehitzekoProduktua) => {
+ try {
+ const existitzenDenProduktua = await DAL.eskuratuProduktua(
+ gehitzekoProduktua.id
+ );
+ if (existitzenDenProduktua !== null) {
+ throw new Error("Produktua iada existitzen da!");
+ }
+ } catch (err) {
+ // ...
+ }
+};
+```
+
+### Anti jarraibidearen kode adibidea
+
+```javascript
+// string baten jaurtiketak edozein pila informazio eta datu ezaugarri garrantzitsu falta ditu
+if (!gehitzekoProduktua)
+ throw "Nola gehi dezaket produktu bat baliorik ez duenean?";
+```
+
+### Kode adibidea: oraindik ere era zuzenagoan egin
+
+
+Javascript
+
+```javascript
+// Noderen Error objektutik eratortzen den errore objektu zentralizatua
+function AppErrorea(izena, httpKodea, deskribapena, funtzionatzenDu) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.izena = izena;
+ //...hemen zehaztuta beste ezaugarri batzuk
+}
+
+AppErrorea.prototype = Object.create(Error.prototype);
+AppErrorea.prototype.constructor = AppErrorea;
+
+module.exports.AppErrorea = AppErrorea;
+
+// erabiltzailea exzepzio bat jaurtitzen
+if (erabiltzailea == null)
+ throw new AppErrorea(
+ commonErrors.resourceNotFound,
+ commonHTTPErrors.notFound,
+ "azalpen osatuagoa",
+ true
+ );
+```
+
+
+
+
+Typescript
+
+```typescript
+// Noderen Error objektutik eratortzen den errore objektu zentralizatua
+export class AppErrorea extends Error {
+ public readonly izena: string;
+ public readonly httpKodea: HttpCode;
+ public readonly funtzionatzenDu: boolean;
+
+ constructor(
+ izena: string,
+ httpKodea: HttpCode,
+ deskribapena: string,
+ funtzionatzenDu: boolean
+ ) {
+ super(deskribapena);
+
+ Object.setPrototypeOf(this, new.target.prototype); // prototipo katea berrezarri
+
+ this.izena = izena;
+ this.httpKodea = httpKodea;
+ this.funtzionatzenDu = funtzionatzenDu;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// erabiltzailea exzepzio bat jaurtitzen
+if (erabiltzailea == null)
+ throw new AppErrorea(
+ commonErrors.resourceNotFound,
+ commonHTTPErrors.notFound,
+ "azalpen osatuagoa",
+ true
+ );
+```
+
+
+
+_`Object.setPrototypeOf`ri buruzko azalpena Typescripten: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget_
+
+### Blogeko aipua: "Ez diot interesik ikusten mota ezberdin ugari edukitzeari"
+
+Ben Nadel-en blogeko “Node.js errore objektua” 5 hitz gakori esker sailkatua
+
+> …”Nik neuk, ez diot interesik ikusten errore objektu klase ezberdin ugari edukitzeari [bakarra edukitzearekin alderatuz]. Ez dirudi JavaScriptek, lengoaia gisa, eraikitzailez oinarritutako errore harrapaketa hornitzen duenik. Horrela, objektu baten ezaugarriak bereizteak Eraikitzaile klaseak bereiztea baino errazagoa dirudi…
+
+### Blog aipua: "String bat ez da errore bat"
+
+devthought.com blogeko “Node.js errore objektua” 6 hitz gakori esker sailkatua
+
+> …String baten ordez errore bat pasatzeak moduluen arteko elkarreragintasuna murrizten du. instanceof errore egiaztapen arrakastatsuak izan litezkeen kontratuak apurtzen ditu APIekin. Ikusiko dugun bezala, errore objektuek, eraikitzaileari pasatutako mezua kontserbatzeaz gain, Javascript motore modernoetan ezaugarri interesgarriak dituzte…
+
+### Blog aipua: "Erroretik jaraunsteak ez du balio askorik gehitzen"
+
+machadogj bloga
+
+> …Errore klasea jaraunsteko erraza ez izatea arazo bat da. Noski, klasea jaraunts dezakezu eta zure HttpError, DbError, etab. bezalako Error klase propioak sortu. Hala ere, horrek denbora eskatzen du, eta ez du balio askorik gehitzen [AppError batentzat behin bakarrik jaraunsteaz alderatuz], baldin eta klaseekin zerbait egiten ez bazabiltza. Batzuetan, soilik mezu bat gehitu nahi duzu eta barruko errorea mantendu; beste batzuetan, ordea, errorea parametroekin edo bestelako informazioekin osatu nahi zenezake…
+
+### Blog aipua: "Node.jsk jaurtitako JavaScript eta System errore guztiak "Error" objektutik datoz"
+
+Node.js dokumentazio ofiziala
+
+> …Node.jsk jaurtitako JavaScript eta System errore guztiak JavaScripten "Error" klase estandarretik datoz edo "Error" objektuaren instantziak dira, eta gutxienez horrelako ezaugarri erabilgarriak hornitzea bermatzen dute. JavaScript Error objektu generiko bat da, errorea zergatik gertatu den inolako berariazko baldintzarik adierazten ez duena. Error objektuek "pila aztarna" bat atzematen dute, Error instantziatua izan den kodearen lekua zehaztuz, eta errorearen testu deskribapena eduki dezakete. Node.jsk sortutako errore guztiak, System eta JavaScript erroreak barne, Error klasetik eratorritakoak edo Error motaren instantziak izango dira…
diff --git a/sections/errorhandling/useonlythebuiltinerror.french.md b/sections/errorhandling/useonlythebuiltinerror.french.md
new file mode 100644
index 000000000..a8e2e7d56
--- /dev/null
+++ b/sections/errorhandling/useonlythebuiltinerror.french.md
@@ -0,0 +1,117 @@
+# Utilisez uniquement l'objet intégré Error
+
+### Un paragraphe d'explication
+
+La nature permissive de JavaScript ainsi que sa variété d'options de flux de code (par exemple, EventEmitter, fonction de rappel, promesses, etc.) peut faire varier considérablement la façon dont les développeurs génèrent des erreurs - certains utilisent des chaînes, d'autres définissent leurs propres types personnalisés. L'utilisation de l'objet Error intégré de Node.js aide à maintenir l'uniformité dans votre code et avec les bibliothèques tierces, il préserve également des informations importantes comme la StackTrace. Lors de la levée de l'exception, il est généralement recommandé de la remplir avec des propriétés contextuelles supplémentaires telles que le nom de l'erreur et le code d'erreur HTTP associé. Pour atteindre cette uniformité et ces pratiques, envisagez d'étendre l'objet Error avec des propriétés supplémentaires, mais attention à ne pas en faire trop. Il est généralement judicieux d'étendre l'objet Error une seule fois avec un AppError pour toutes les erreurs au niveau de l'application, et de passer en argument toutes les données dont vous avez besoin pour différencier les différents types d'erreurs. Il n'est pas nécessaire d'étendre l'objet Error plusieurs fois (une fois pour chaque cas d'erreur, comme DbError, HttpError). Consulter l'exemple de code ci-dessous.
+
+### Exemple de code - la bonne méthode
+
+```javascript
+// lève une Error depuis une fonction typique, qu'elle soit synchrone ou asynchrone
+if(!productToAdd)
+ throw new Error('Comment puis-je ajouter un nouveau produit lorsqu\'aucune valeur n\'est fournie ?');
+
+// 'lève' une Error depuis EventEmitter
+const myEmitter = new MyEmitter();
+myEmitter.emit('error', new Error('Oups !'));
+
+// 'lève' une Error depuis une promesse
+const addProduct = async (productToAdd) => {
+ try {
+ const existingProduct = await DAL.getProduct(productToAdd.id);
+ if (existingProduct !== null) {
+ throw new Error('Le produit existe déjà !');
+ }
+ } catch (err) {
+ // ...
+ }
+}
+```
+
+### Exemple de code - la mauvaise méthode
+
+```javascript
+// lève une chaîne qui ne contient aucune information de trace de pile et autres propriétés de données importantes
+if(!productToAdd)
+ throw ('Comment puis-je ajouter un nouveau produit lorsqu\'aucune valeur n\'est fournie ?');
+```
+
+### Exemple de code - une méthode encore meilleure
+
+
+Javascript
+
+```javascript
+// objet d'erreur centralisé qui dérive de Error de Node
+function AppError(name, httpCode, description, isOperational) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.name = name;
+ //...d'autres propriétés attribuées ici
+};
+
+AppError.prototype = Object.create(Error.prototype);
+AppError.prototype.constructor = AppError;
+
+module.exports.AppError = AppError;
+
+// le client levant une exception
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'plus d\'explications', true)
+```
+
+
+
+Typescript
+
+```typescript
+// objet d'erreur centralisé qui dérive de Error de Node
+export class AppError extends Error {
+ public readonly name: string;
+ public readonly httpCode: HttpCode;
+ public readonly isOperational: boolean;
+
+ constructor(name: string, httpCode: HttpCode, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // restaure la chaîne du prototype
+
+ this.name = name;
+ this.httpCode = httpCode;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// le client levant une exception
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'plus d\'explications', true)
+```
+
+
+*Explication sur `Object.setPrototypeOf` en Typescript : https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget*
+
+### Citation de blog : « Je ne vois pas l'intérêt d'avoir beaucoup de types d'objets d'erreur différents »
+
+Extrait du blog de Ben Nadel classé en 5ème position pour les mots clés “Node.js error object”
+
+>… Personnellement, je ne vois pas l'intérêt d'avoir beaucoup de types d'objets d'erreur différents [comparé à l'extension d'une seule fois de AppError] - JavaScript, en tant que langage, ne semble pas répondre à la capture d'erreurs basée sur le constructeur. En tant que tel, la différenciation sur une propriété d'objet semble beaucoup plus facile que la différenciation sur un type de constructeur…
+
+### Citation de blog : « Une chaîne n'est pas une erreur »
+
+Extrait du blog de devthought.com classé en 6ème position pour les mots clés “Node.js error object”
+
+> …le passage d'une chaîne au lieu d'une erreur entraîne une interopérabilité réduite entre les modules. Il rompt les contrats avec les API qui pourraient effectuer des vérifications d'Error avec `instanceof`, ou qui veulent en savoir plus sur l'erreur. Les objets d'Error, comme nous le verrons, ont des propriétés très intéressantes dans les moteurs JavaScript modernes en plus de contenir le message transmis au constructeur…
+
+### Citation de blog : « L'héritage d'Error n'ajoute pas trop de valeur »
+
+Extrait du blog de machadogj
+
+> …Un problème que j'ai avec la classe Error est qu'il n'est pas si simple à étendre. Bien sûr, vous pouvez hériter de la classe et créer vos propres classes d'erreur comme HttpError, DbError, etc. Cependant, cela prend du temps et n'ajoute pas trop de valeur [que de l'étendre une seule fois pour une AppError] à moins que vous ne fassiez quelque chose avec des types. Parfois, vous voulez simplement ajouter un message et conserver l'erreur interne, et parfois vous voudrez peut-être étendre l'erreur avec des paramètres, etc.…
+
+### Citation de blog : « Toutes les erreurs JavaScript et Système levées par Node.js héritent de Error »
+
+Extrait de la documentation officielle de Node.js
+
+> …Toutes les erreurs JavaScript et Système levées par Node.js héritent de, ou sont des instances de, la classe Error du JavaScript standard et sont garantes de fournir au moins les propriétés disponibles sur cette classe. Un objet Error JavaScript générique n'indique aucune circonstance particulière expliquant pourquoi l'erreur s'est produite. Les objets d'erreur capturent une « trace de la pile » détaillant le point dans le code où l'erreur a été instanciée et peuvent fournir une description textuelle de l'erreur. Toutes les erreurs générées par Node.js, y compris toutes les erreurs système et JavaScript, seront des instances ou hériteront de la classe Error…
diff --git a/sections/errorhandling/useonlythebuiltinerror.japanese.md b/sections/errorhandling/useonlythebuiltinerror.japanese.md
new file mode 100644
index 000000000..57199a0c3
--- /dev/null
+++ b/sections/errorhandling/useonlythebuiltinerror.japanese.md
@@ -0,0 +1,117 @@
+# 組み込みのエラーオブジェクトのみを使用する
+
+### 一段落説明
+
+多くのコードフローの選択肢(EventEmitter、コールバック、Promises など)を持っているという JavaScript の寛容な性質が、開発者のエラー発生方法に大きな差をもたらしています - 文字列を使用する人もいれば、独自のカスタム型を定義する人もいます。Node.js の組み込みエラーオブジェクトを使用することは、コード内やサードパーティのライブラリ間において一貫性を保つことを助け、さらにスタックトレースのような重要な情報を保持します。通常、例外を発生させるときは、エラー名や関連する HTTP エラーコードといった追加のコンテキスト属性情報を付与することがベストプラクティスです。この一貫性保持やプラクティスを達成するために、エラーオブジェクトを追加プロパティで拡張することを考えますが、やりすぎには注意が必要です。一般的に、すべてのアプリケーションレベルのエラーに対して、AppError という形で一度だけ組み込みのエラーオブジェクトを拡張し、異なる種類のエラーを区別するために必要なデータを引数として渡すことをおすすめします。何回も(DbError、HttpError のようにそれぞれのケースに応じて)エラーオブジェクトを拡張する必要はありません。以下のコード例を参考にしてください。
+
+### コード例 – 正しい方法
+
+```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 からエラーを「投げる」
+const addProduct = async (productToAdd) => {
+ try {
+ const existingProduct = await DAL.getProduct(productToAdd.id);
+ if (existingProduct !== null) {
+ throw new Error('Product already exists!');
+ }
+ } catch (err) {
+ // ...
+ }
+}
+```
+
+### コード例 – アンチパターン
+
+```javascript
+// 文字列を投げると、スタックトレース情報やその他の重要なデータプロパティを失います
+if(!productToAdd)
+ throw ('How can I add new product when no value provided?');
+```
+
+### コード例 – より優れた方法
+
+
+Javascript
+
+```javascript
+// Node のエラーから派生した、集中化されたエラーオブジェクト
+function AppError(name, httpCode, description, isOperational) {
+ Error.call(this);
+ Error.captureStackTrace(this);
+ this.name = name;
+ //...他のプロパティがここで割り当てられます
+};
+
+AppError.prototype = Object.create(Error.prototype);
+AppError.prototype.constructor = AppError;
+
+module.exports.AppError = AppError;
+
+// 例外を投げるクライアント
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'further explanation', true)
+```
+
+
+
+Typescript
+
+```typescript
+// Node のエラーから派生した、集中化されたエラーオブジェクト
+export class AppError extends Error {
+ public readonly name: string;
+ public readonly httpCode: HttpCode;
+ public readonly isOperational: boolean;
+
+ constructor(name: string, httpCode: HttpCode, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // プロトタイプチェーンを復元する
+
+ this.name = name;
+ this.httpCode = httpCode;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// 例外を投げるクライアント
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'further explanation', true)
+```
+
+
+*TypeScript における `Object.setPrototypeOf` の説明: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget*
+
+### ブログ引用: "I don’t see the value in having lots of different types"(たくさんの型を持つことに価値があるとは思えません)
+
+ブログ Ben Nadel(「Node.js error object」というキーワードで 5 位)より
+
+>…「個人的には、(ただ一つのエラーオブジェクト型を持つことに比べて)たくさんのエラーオブジェクト型を持つことに価値があると思えません - JavaScript は言語として、コンストラクタベースのエラー捕捉には適していないようです。このように、オブジェクトのプロパティで区別することは、コンストラクタの型で区別するよりはるかに簡単です…
+
+### ブログ引用: "A string is not an error"(文字列はエラーではありません)
+
+ブログ devthought.com(「Node.js error object」というキーワードで 6 位)より
+
+> …エラーの結果ではなく文字列を渡すことは、モジュール間の相互運用性を低下させます。`instanceof` エラーチェックを実施しているかもしれない、またはエラーについてより詳しく知りたい API との決まりごとを破壊します。エラーオブジェクトは、コンストラクタに渡されたメッセージを保持する以外にも、モダンな JavaScript エンジンにおいては非常に興味深いプロパティを持ってます…
+
+### ブログ引用: "Inheriting from Error doesn’t add too much value"(Error からの継承はあまり付加価値がありません)
+
+ブログ machadogj より
+
+> …Error クラスが抱える一つの問題は、拡張することが単純ではないということです。もちろん、Error クラスを継承して、HttpError や DbError といった独自のエラークラスを作成することも可能です。しかしながら、手間もかかりますし、型を使って何かをしない限りは(AppError といった形で一度だけ拡張することに比べて)あまり付加価値がありません。ただメッセージを加えて内部エラーを保持したいときもあれば、パラメータでエラーを拡張したい場合もあるでしょう…
+
+### ブログ引用: "All JavaScript and System errors raised by Node.js inherit from Error"(Node.js で発生する全ての JavaScript エラーおよびシステムエラーは Error を継承しています)
+
+Node.js 公式ドキュメントより
+
+> …Node.js で発生する全ての JavaScript エラーおよびシステムエラーは、標準 JavaScript Error クラスを継承しているか、そのインスタンスとなっており、少なくともその標準クラスにおいて利用可能なプロパティが提供されることは保証されています。一般的な JavaScript エラーオブジェクトは、エラーが発生した原因の特定の状況を示しません。エラーオブジェクトは、エラーがインスタンス化されたコード内の箇所を詳細に示す「スタックトレース」をキャプチャし、エラーについてのテキスト説明を提供することができます。システムや JavaScript のエラーを含む、Node.js において作成されるすべてのエラーは、Error クラスのインスタンスであるか、クラスを継承したものとなるでしょう…
diff --git a/sections/errorhandling/useonlythebuiltinerror.korean.md b/sections/errorhandling/useonlythebuiltinerror.korean.md
index f2ec0cddf..8420e4efa 100644
--- a/sections/errorhandling/useonlythebuiltinerror.korean.md
+++ b/sections/errorhandling/useonlythebuiltinerror.korean.md
@@ -1,10 +1,10 @@
-# Use only the built-in Error object
+# 내장된 Error 객체만 사용하라
-### 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
+다양한 코드 흐름 옵션(예:EventEmitter, Callbacks, Promises 등)과 함께 JS의 허용 가능한 특성은 개발자가 오류를 발생시키는 방법에 큰 차이를 둔다. – 일부 개발자들은 문자열을 사용하고, 일부는 그들만의 커스텀 타입을 정의한다. Node.js 내장 Error 객체를 사용하면 당신의 코드와 제 3자 라이브러리의 균일성을 유지할 수 있도록 도와주며, 또한 스택정보(StrackTrace)와 같은 중요한 정보도 보존할 수 있다. 예외가 발생할 때, 일반적으로 오류 이름이나 관련 HTTP 오류 코드같은 상황별로 추가적인 속성으로 채우는 것이 좋은 방법이다. 이 균일성과 관행을 얻을려면, Error 객체를 추가 속성으로 확장하라, 아래 코드 예 참조
-### Code Example – doing it right
+### 코드 예시 – 제대로 하기
```javascript
// throwing an Error from typical function, whether sync or async
@@ -28,7 +28,7 @@ const addProduct = async (productToAdd) => {
}
```
-### Code example – Anti Pattern
+### 코드 예시 - 좋지않은 패턴
```javascript
// throwing a string lacks any stack trace information and other important data properties
@@ -36,7 +36,7 @@ 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
@@ -57,26 +57,26 @@ 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”
+Ben Nadel 블로그에서 "Node.js error 객체" 키워드 5위에 위치했다.
->…”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”
+devthought.com 블로그에서 "Node.js error 객체" 키워드 6위에 위치했다.
-> …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…
+> …오류 대신 문자열을 전달함으로써 모듈 간의 상호운용성이 줄어들었다. 문자열을 사용하면 `instanceof` 에러로 검사하는 API 계약을 깨뜨리는 데다가 오류의 자세한 정보도 알기 어렵다. 뒤에서 설명하겠지만, 최신 자바스크립트 엔진의 Error 객체에는 유용한 속성을 많이 있으며 생성자에 전달된 메시지도 포함된다…
-### Blog Quote: "Inheriting from Error doesn’t add too much value"
+### 블로그 인용: "에러로 부터 상속해도 많은 값을 추가하지 않는다"
-From the blog machadogj
+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…
+> …Error 클래스와 관련된 한 가지 문제는 확장하기가 그리 간단하지 않다는 것이다. 물론 클래스를 상속하고 HttpError, DbError 등 자신만의 에러 클래스를 만들 수 있다. 그러나, 당신이 타입으로 무엇인가를 하지 않는 한 이것은 시간이 걸리며 많은 값을 추가하지 않는다. 때로 당신은 메시지 추가와 내부 에러를 유지하길 원하고 때로는 매개 변수를 사용하여 에러를 확장하길 원할 것이다, 등등…
-### Blog Quote: "All JavaScript and System errors raised by Node.js inherit from Error"
+### 블로그 인용: "모든 자바스크립트와 시스템 에러들은 node.js이 상속한 에러로 부터 발생한다"
-From Node.js official documentation
+Node.js 공식문서에서
-> …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…
+> …Node.js에 의해 발생된 모든 자바스크립트 및 시스템 에러는 표준 자바스크립트 에러 클래스에서 상속되거나 표준 자바스크립트 에러 클래스의 인스턴스이며 최소한 그 클래스에서 사용할 수 있는 속성을 제공할 수 있도록 보장된다. 에러가 발생한 이유에 대한 특정 상황을 나타내지 않는 일반 자바스크립트 에러 객체. 에러 객체는 에러가 인스턴스화된 코드에서 포인트를 자세히 설명하는 "스택 추적"을 캡처(capture)하며, 에러에 대한 텍스트 설명을 제공할 수도 있다. 모든 시스템과 자바스크립트 에러를 포함한 Node.js에 의해, 생성된 모든 에러는, 에러 클래스의 인스턴스이거나, 상속 받은 것이다.…
diff --git a/sections/errorhandling/useonlythebuiltinerror.md b/sections/errorhandling/useonlythebuiltinerror.md
index bbe929322..36bdec01d 100644
--- a/sections/errorhandling/useonlythebuiltinerror.md
+++ b/sections/errorhandling/useonlythebuiltinerror.md
@@ -2,7 +2,7 @@
### One Paragraph Explainer
-The permissive nature of JavaScript along with its variety of 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
+The permissive nature of JavaScript along with its variety of 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, but be careful not to overdo it. It's generally a good idea to extend the built-in Error object only once with an AppError for all the application level errors, and pass any data you need to differentiate between different kinds of errors as arguments. No need to extend the Error object multiple times (one for each error case, such as DbError, HttpError) See code examples below
### Code Example – doing it right
@@ -96,7 +96,7 @@ if(user == null)
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…
+>…”Personally, I don’t see the value in having lots of different types of error objects [in contrast with having only one] – 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"
@@ -108,7 +108,7 @@ From the blog, devthought.com ranked 6 for the keywords “Node.js error object
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…
+> …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 [compared to extending it only once for an AppError] 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"
diff --git a/sections/errorhandling/useonlythebuiltinerror.polish.md b/sections/errorhandling/useonlythebuiltinerror.polish.md
new file mode 100644
index 000000000..f45feeed3
--- /dev/null
+++ b/sections/errorhandling/useonlythebuiltinerror.polish.md
@@ -0,0 +1,117 @@
+# Używaj tylko wbudowanego obiektu Error
+
+### Wyjaśnienie jednym akapitem
+
+Zezwalająca natura JavaScript wraz z różnorodnymi opcjami przepływu kodu (np. EventEmitter, Callbacki, Promises itp.) popycha do dużej rozbieżności w sposobie, w jaki programiści zgłaszają błędy - niektóre ciągi znaków, inne definiują własne typy niestandardowe. Korzystanie z wbudowanego obiektu Error Node.js pomaga zachować jednolitość w kodzie, a dzięki bibliotekom stron trzecich zachowuje również istotne informacje, takie jak StackTrace. Zgłaszając wyjątek, zwykle dobrą praktyką jest wypełnienie go dodatkowymi właściwościami kontekstowymi, takimi jak nazwa błędu i powiązany kod błędu HTTP. Aby osiągnąć tę jednolitość i praktyki, rozważ rozszerzenie obiektu Error o dodatkowe właściwości, ale uważaj, aby go nie przesadzić. Ogólnie dobrym pomysłem jest rozszerzenie wbudowanego obiektu Error tylko raz o AppError dla wszystkich błędów na poziomie aplikacji i przekazanie wszelkich danych potrzebnych do rozróżnienia różnych rodzajów błędów jako argumentów. Nie trzeba wielokrotnie rozszerzać obiektu Error (jeden dla każdego przypadku błędu, takiego jak DbError, HttpError) Zobacz przykłady kodu poniżej
+
+### Przykład kodu - robienie tego dobrze
+
+```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
+const addProduct = async (productToAdd) => {
+ try {
+ const existingProduct = await DAL.getProduct(productToAdd.id);
+ if (existingProduct !== null) {
+ throw new Error('Product already exists!');
+ }
+ } catch (err) {
+ // ...
+ }
+}
+```
+
+### Przykład kodu - Antywzorzec
+
+```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?');
+```
+
+### Przykład kodu – robienie tego nawet lepiej
+
+
+Javascript
+
+```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 = Object.create(Error.prototype);
+AppError.prototype.constructor = AppError;
+
+module.exports.AppError = AppError;
+
+// client throwing an exception
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'further explanation', true)
+```
+
+
+
+Typescript
+
+```typescript
+// centralized error object that derives from Node’s Error
+export class AppError extends Error {
+ public readonly name: string;
+ public readonly httpCode: HttpCode;
+ public readonly isOperational: boolean;
+
+ constructor(name: string, httpCode: HttpCode, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
+
+ this.name = name;
+ this.httpCode = httpCode;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// client throwing an exception
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'further explanation', true)
+```
+
+
+*Wytłumaczenie na temat `Object.setPrototypeOf` w Typescript: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget*
+
+### Cytat z Bloga: "I don’t see the value in having lots of different types"
+
+Z bloga, Ben Nadel w rankingu 5 słów kluczowych “Node.js error object”
+
+>…”Personally, I don’t see the value in having lots of different types of error objects [in contrast with having only one] – 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…
+
+### Cytat z Bloga: "A string is not an error"
+
+Z bloga, devthought.com w rankingu 6 słów kluczowych “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…
+
+### Cytat z Bloga: "Inheriting from Error doesn’t add too much value"
+
+Z bloga 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 [compared to extending it only once for an AppError] 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…
+
+### Cytat z Bloga: "All JavaScript and System errors raised by Node.js inherit from Error"
+
+Z oficjalnej dokumentacji Node.js
+
+> …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/errorhandling/useonlythebuiltinerror.russian.md b/sections/errorhandling/useonlythebuiltinerror.russian.md
index 98e2bdaf2..4688bbcfb 100644
--- a/sections/errorhandling/useonlythebuiltinerror.russian.md
+++ b/sections/errorhandling/useonlythebuiltinerror.russian.md
@@ -2,25 +2,25 @@
### Объяснение в один абзац
-Лозволяющая природа JavaScript наряду с его разнообразием параметров потока кода (например, EventEmitter, Callbacks, Promises и т.д.) приводит к значительному расхождению в том, как разработчики выдают ошибки - некоторые используют строки, другие определяют свои собственные пользовательские типы. Использование встроенного объекта Error в Node.js помогает сохранить единообразие в вашем коде, а с помощью сторонних библиотек он также сохраняет важную информацию, такую как StackTrace. При возникновении исключения обычно рекомендуется заполнить его дополнительными контекстными свойствами, такими как имя ошибки и связанный код ошибки HTTP. Чтобы добиться этого единообразия и практики, рассмотрите возможность расширения объекта Error дополнительными свойствами, см. пример кода ниже.
+Гибкая природа JavaScript наряду с его разнообразием вариантов потока кода (например, EventEmitter, Callbacks, Promises и т.д.) приводит к значительному расхождению в том, как разработчики выдают ошибки - некоторые используют строки, другие определяют свои собственные пользовательские типы. Использование встроенного объекта Error в Node.js помогает сохранить единообразие в вашем коде, а с помощью сторонних библиотек он также сохраняет важную информацию, такую как StackTrace. При возникновении исключения обычно рекомендуется заполнить его дополнительными контекстными свойствами, такими как имя ошибки и связанный код ошибки HTTP. Чтобы добиться этого единообразия и практики, рассмотрите возможность расширения объекта Error дополнительными свойствами, см. пример кода ниже.
### Пример кода - делай все правильно
```javascript
-// throwing an Error from typical function, whether sync or async
+// пробрасываем Error из типичной async или sync функции
if(!productToAdd)
- throw new Error("How can I add new product when no value provided?");
+ throw new Error('How can I add new product when no value provided?');
-// 'throwing' an Error from EventEmitter
+// пробрасываем Error из EventEmitter
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
-// 'throwing' an Error from a Promise
+// пробрасываем Error из Promise
const addProduct = async (productToAdd) => {
try {
const existingProduct = await DAL.getProduct(productToAdd.id);
if (existingProduct !== null) {
- throw new Error("Product already exists!");
+ throw new Error('Product already exists!');
}
} catch (err) {
// ...
@@ -31,20 +31,23 @@ const addProduct = async (productToAdd) => {
### Пример кода - антипаттерн
```javascript
-// throwing a string lacks any stack trace information and other important data properties
+// пробрасывая строку, теряем информацию о stack trace и другие важные параметры
if(!productToAdd)
- throw ("How can I add new product when no value provided?");
+ throw ('How can I add new product when no value provided?');
```
-### Пример кода - делаем это еще лучше
+### Пример кода - делаем еще лучше
+
+
+Javascript
```javascript
-// centralized error object that derives from Node’s Error
+// главные объект ошибки производный от нодовского Error
function AppError(name, httpCode, description, isOperational) {
Error.call(this);
Error.captureStackTrace(this);
this.name = name;
- //...other properties assigned here
+ //... другие параметры тут
};
AppError.prototype = Object.create(Error.prototype);
@@ -52,31 +55,63 @@ AppError.prototype.constructor = AppError;
module.exports.AppError = AppError;
-// client throwing an exception
+// клиент пробрасывает исключение
if(user == null)
- throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "further explanation", true)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'further explanation', true)
```
+
+
+
+Typescript
+
+```typescript
+// главные объект ошибки производный от нодовского Error
+export class AppError extends Error {
+ public readonly name: string;
+ public readonly httpCode: HttpCode;
+ public readonly isOperational: boolean;
+
+ constructor(name: string, httpCode: HttpCode, description: string, isOperational: boolean) {
+ super(description);
+
+ Object.setPrototypeOf(this, new.target.prototype); // восстанавливаем цепочку прототипов
+
+ this.name = name;
+ this.httpCode = httpCode;
+ this.isOperational = isOperational;
+
+ Error.captureStackTrace(this);
+ }
+}
+
+// клиент пробрасывает исключение
+if(user == null)
+ throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, 'further explanation', true)
+```
+
+
+*Объяснение `Object.setPrototypeOf` в Typescript: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget*
### Цитата блога: "Я не вижу смысла в том, чтобы иметь много разных типов"
Из блога Бен Надель, занял 5 место по ключевым словам "объект ошибки Node.js"
-> … Лично я не вижу смысла в том, чтобы иметь множество различных типов объектов ошибок - JavaScript, как язык, похоже, не предназначен для поиска ошибок на основе конструктора. Таким образом, дифференцирование по свойству объекта кажется гораздо проще, чем по типу Constructor …
+> … Лично я не вижу смысла в том, чтобы иметь множество различных типов объектов ошибок - JavaScript, как язык, похоже, не предназначен для поиска ошибок на основе конструктора. Таким образом, определение по свойству объекта кажется гораздо проще, чем по типу Constructor …
### Цитата блога: "Строка не является ошибкой"
Из блога devthought.com, занял 6 место по ключевым словам "Объект ошибки Node.js"
-> … передача строки вместо ошибки приводит к снижению совместимости между модулями. Он нарушает контракты с API, которые могут выполнять проверки ошибок instanceof или хотят узнать больше об ошибке. Объекты ошибок, как мы увидим, обладают очень интересными свойствами в современных механизмах JavaScript, помимо хранения сообщения, переданного конструктору …
+> … передача строки вместо ошибки приводит к снижению совместимости между модулями. Это нарушает контракты с API, которые могут выполнять проверки ошибок с помощью instanceof или хотят узнать больше об ошибке. Объекты ошибок, как мы увидим, обладают очень интересными свойствами в современных механизмах JavaScript, помимо хранения сообщения, переданного конструктору …
-### Цитата из блога: "Наследование от ошибки не увеличивает ценность"
+### Цитата из блога: "Наследование от ошибки не увеличивает их ценность"
Из блога Machadogj
> … Одна проблема, которую я имею с классом Error, заключается в том, что его не так просто расширить. Конечно, вы можете наследовать класс и создавать свои собственные классы ошибок, такие как HttpError, DbError и т.д. Однако это занимает время и не добавляет слишком много значения, если вы не делаете что-то с типами. Иногда вам просто нужно добавить сообщение и сохранить внутреннюю ошибку, а иногда вам может понадобиться расширить ошибку с помощью параметров, и так далее …
-### Цитата из блога: "Все ошибки JavaScript и системы, возникающие в Node.js, наследуются от ошибок"
+### Цитата из блога: "Все ошибки JavaScript и системы, возникающие в Node.js, наследуются от Error"
Из официальной документации Node.js
-> … Все ошибки JavaScript и System, возникающие в Node.js, наследуются или являются экземплярами стандартного класса JavaScript Error и гарантированно предоставляют как минимум свойства, доступные в этом классе. Общий объект JavaScript Error, который не обозначает каких-либо конкретных обстоятельств, по которым произошла ошибка. Объекты ошибок фиксируют "трассировку стека", детализирующую точку в коде, в которой был создан экземпляр ошибки, и могут предоставлять текстовое описание ошибки. Все ошибки, сгенерированные Node.js, включая все системные ошибки и ошибки JavaScript, будут либо экземплярами класса Error, либо наследоваться от него …
+> … Все ошибки JavaScript и System, возникающие в Node.js, наследуются или являются экземплярами стандартного класса JavaScript Error и гарантированно предоставляют как минимум свойства, доступные в этом классе. Общий объект JavaScript Error, который не обозначает каких-либо конкретных обстоятельств, по которым произошла ошибка. Объекты ошибок фиксируют "трассировку стека", детализирующую точку в коде, в которой был создан экземпляр ошибки, и могут предоставлять текстовое описание ошибки. Все ошибки, сгенерированные Node.js, включая все системные ошибки и ошибки JavaScript, будут либо экземплярами класса Error, либо наследоваться от него …
\ No newline at end of file
diff --git a/sections/examples/dockerfile/.dockerignore b/sections/examples/dockerfile/.dockerignore
new file mode 100644
index 000000000..9d284936d
--- /dev/null
+++ b/sections/examples/dockerfile/.dockerignore
@@ -0,0 +1,13 @@
+node_modules/
+.git
+README.md
+LICENSE
+.vscode
+.idea
+npm-debug.log
+coverage
+.env
+.editorconfig
+.aws
+dist
+.npmrc
diff --git a/sections/examples/dockerfile/.npmrc b/sections/examples/dockerfile/.npmrc
new file mode 100644
index 000000000..e69de29bb
diff --git a/sections/examples/dockerfile/Dockerfile b/sections/examples/dockerfile/Dockerfile
new file mode 100644
index 000000000..19d89f70a
--- /dev/null
+++ b/sections/examples/dockerfile/Dockerfile
@@ -0,0 +1,42 @@
+# This is a multistage Dockerfile.
+# In the first stage we install system build dependencies, copy project files and build them
+# In the second stage, we start fresh and only copy necessary files. We also purge node_modules devDependencies.
+
+#### Build stage ####
+FROM node:14.8.0-alpine AS build
+
+# Install system build dependencies (if needed) at the top ✅ See bullet point #8.8 about caching
+RUN apk add --update --no-cache bash make gcc g++ lcms2-dev libpng-dev autoconf automake
+
+# Only copy node dependency information and install all dependencies first
+COPY --chown=node:node package.json package-lock.json ./
+
+# Install packages using the lockfiles as source of truth ✅ See bullet point #8.5 about npm ci
+RUN npm ci
+
+# Copy source code (and all other relevant files)
+COPY --chown=node:node src ./src
+
+# Build code
+RUN npm run build
+
+#### Run-time stage ####
+# ✅ See bullet point #8.10 about smaller docker base images
+FROM node:14.8.0-alpine as app
+
+# Set non-root user and expose port 3000
+USER node
+EXPOSE 3000
+
+WORKDIR /home/node/app
+
+# Copy dependency information and build output from previous stage
+COPY --chown=node:node --from=build package.json package-lock.json ./
+COPY --chown=node:node --from=build node_modules ./node_modules
+COPY --chown=node:node --from=build dist ./dist
+
+# Clean dev dependencies ✅ See bullet point #8.5
+RUN npm prune --production && npm cache clean --force
+
+# ✅ See bullet point #8.2 about avoiding npm start
+CMD [ "node", "dist/app.js" ]
diff --git a/sections/examples/dockerfile/package.json b/sections/examples/dockerfile/package.json
new file mode 100644
index 000000000..2c9330e4f
--- /dev/null
+++ b/sections/examples/dockerfile/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "node-app-with-docker",
+ "version": "1.0.0",
+ "description": "An example node app that uses docker to be built",
+ "main": "src/app.ts",
+ "scripts": {
+ "start": "node dist/app.js",
+ "build": "tsc --outDir dist -m commonjs -t ES2020 src/app.ts",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/goldbergyoni/nodebestpractices.git"
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/goldbergyoni/nodebestpractices/issues"
+ },
+ "homepage": "https://github.com/goldbergyoni/nodebestpractices#readme",
+ "dependencies": {
+ "express": "^4.17.1"
+ },
+ "devDependencies": {
+ "@types/express": "^4.17.7",
+ "typescript": "^3.9.7"
+ }
+}
diff --git a/sections/examples/dockerfile/src/app.ts b/sections/examples/dockerfile/src/app.ts
new file mode 100644
index 000000000..93131f2e9
--- /dev/null
+++ b/sections/examples/dockerfile/src/app.ts
@@ -0,0 +1,10 @@
+import * as express from 'express';
+const app = express();
+
+app.get('/', (req, res) => {
+ res.send('Hello World!')
+})
+
+app.listen(3000, () => {
+ console.log('Navigate to http://localhost:3000');
+});
diff --git a/sections/performance/block-loop.basque.md b/sections/performance/block-loop.basque.md
new file mode 100644
index 000000000..adf5f3e63
--- /dev/null
+++ b/sections/performance/block-loop.basque.md
@@ -0,0 +1,53 @@
+# Ez blokeatu gertaeren begizta
+
+
+
+Nodek gertaeren begizta nagusiki hari bakarraren barruan kudeatzen du, hainbat ilaren artean txandakatuz. Prozesu horretan, bada eragile bat baino gehiago gertaeren begizta geldiaraz dezakeena, hala nola konplexutasun handiko ekintzak, json fitxategi handien sintaxi analisiak, logikaren erabilera sorta oso handietan, seguruak ez diren adierazpen erregularren kontsultak eta sarrera/irteera operazio garrantzitsuak. Ekidin ataza intentsibo horiek PUZetik zerbitzu dedikatu batera pasatzea (adibidez, ataza zerbitzaria) edo ataza luzeak urrats txikietan banatzea eta gero Worker Pool erabiltzea. Horiexek dira gertaeren begizta blokeatzea ekiditeko bideetako batzuk.
+
+### Adibidea: gertaeren begizta blokeatzea
+
+Ikusi [Node Clinic](https://clinicjs.org/documentation/doctor/05-fixing-event-loop-problem)-en adibide bat
+
+```javascript
+function lokartu(ms) {
+ const etorkizuna = Date.now() + ms;
+ while (Date.now() < etorkizuna);
+}
+
+server.get("/", (req, res, next) => {
+ lokartu(30);
+ res.send({});
+ next();
+});
+```
+
+Aplikazio honen probak egitean, 'while' komandoak sortutako latentzia ikusiko dugu
+
+### Egikaritu proben segida
+
+`clinic doctor --on-port 'autocannon localhost:$PORT' -- node slow-event-loop`
+
+### Emaitzak
+
+```
+┌────────────┬────────┬────────┬────────┬────────┬────────────────┬──────────┬───────────┐
+│ Statistika │ 2.5% │ 50% │ 97.5% │ 99% │ Baztazbestekoa │ Stdev │ Max │
+├────────────┼────────┼────────┼────────┼────────┼────────────────┼──────────┼───────────┤
+│ Latentzia │ 270 ms │ 300 ms │ 328 ms │ 331 ms │ 300.56 ms │ 38.55 ms │ 577.05 ms │
+└────────────┴────────┴────────┴────────┴────────┴────────────────┴──────────┴───────────┘
+┌────────────┬────────┬────────┬────────┬────────┬────────────────┬──────────┬───────────┐
+│ Statistika │ 1% │ 2.5% │ 50% │ 97.5% │ Baztazbestekoa │ Stdev │ Min │
+├────────────┼────────┼────────┼────────┼────────┼────────────────┼──────────┼───────────┤
+│ Req/Sec │ 31 │ 31 │ 33 │ 34 │ 32.71 │ 1.01 │ 31 │
+├────────────┼────────┼────────┼────────┼────────┼────────────────┼──────────┼───────────┤
+```
+
+## Gertaeren begiztaren irudia
+
+
+
+> Hemen duzu oinarrizko arau bat zure Node zerbitzaria azkarra izaten jarraitzeko: Node azkarra da une jakin batean bezero bakoitzarekin lotutako lana "txikia" denean.
+> [Ez blokeatu gertaeren begizta (edota atazen begizta) | Node.js](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)
+
+> Gehiengo batek huts egiten du beren lehenengo NodeJS aplikazioak egiterako orduan, gertaeren begizta, erroreen kudeaketa eta asinkronoaren inguruko kontzeptuak ez ulertzeagatik.
+> [Gertaeren begiztaren jarraibide egokiak — NodeJS gertaeren begizta, 5.partea](https://jsblog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
diff --git a/sections/performance/block-loop.french.md b/sections/performance/block-loop.french.md
new file mode 100644
index 000000000..fd7c99b1f
--- /dev/null
+++ b/sections/performance/block-loop.french.md
@@ -0,0 +1,58 @@
+# Don't block the event loop
+
+
+
+Node handles the Event Loop mostly on a single thread rotating through multiple queues. Operations with high complexity, large json parsing, applying logic over huge arrays, unsafe regex queries, and large IO operations are some of the operations that can cause the Event Loop to stall. Avoid this off-loading CPU intensive tasks to a dedicated service (e.g. job server), or breaking long tasks into small steps then using the Worker Pool are some examples of how to avoid blocking the Event Loop.
+
+### Example: blocking the event loop
+Let's take a look at an example from [Node Clinic](https://clinicjs.org/documentation/doctor/05-fixing-event-loop-problem).
+```javascript
+function sleep (ms) {
+ const future = Date.now() + ms
+ while (Date.now() < future);
+}
+
+server.get('/', (req, res, next) => {
+ sleep(30)
+ res.send({})
+ next()
+})
+```
+
+And when we benchmark this app, we start to see the latency caused by the long
+while loop.
+
+### Run the benchmark
+`clinic doctor --on-port 'autocannon localhost:$PORT' -- node slow-event-loop`
+
+### The results
+
+```
+┌─────────┬────────┬────────┬────────┬────────┬───────────┬──────────┬───────────┐
+│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
+├─────────┼────────┼────────┼────────┼────────┼───────────┼──────────┼───────────┤
+│ Latency │ 270 ms │ 300 ms │ 328 ms │ 331 ms │ 300.56 ms │ 38.55 ms │ 577.05 ms │
+└─────────┴────────┴────────┴────────┴────────┴───────────┴──────────┴───────────┘
+┌───────────┬─────────┬─────────┬─────────┬────────┬─────────┬───────┬─────────┐
+│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
+├───────────┼─────────┼─────────┼─────────┼────────┼─────────┼───────┼─────────┤
+│ Req/Sec │ 31 │ 31 │ 33 │ 34 │ 32.71 │ 1.01 │ 31 │
+├───────────┼─────────┼─────────┼─────────┼────────┼─────────┼───────┼─────────┤
+```
+
+## Image of the Event Loop
+
+
+
+### "Here's a good rule of thumb for keeping your Node server speedy: _Node is fast when the work associated with each client at any given time is 'small'_."
+From Node.js Documentation - [Don't Block the Event Loop (or the Worker Pool)](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)
+
+> The secret to the scalability of Node.js is that it uses a small number of threads to handle many clients.
+> If Node.js can make do with fewer threads, then it can spend more of your system's time and memory working on clients rather than on paying space and time overheads for threads (memory, context-switching).
+> But because Node.js has only a few threads, you must structure your application to use them wisely.
+>
+> Here's a good rule of thumb for keeping your Node.js server speedy: Node.js is fast when the work associated with each client at any given time is "small".
+> This applies to callbacks on the Event Loop and tasks on the Worker Pool.
+
+### "Most people fail their first few NodeJS apps merely due to the lack of understanding of the concepts such as the Event Loop, Error handling and asynchrony"
+From Deepal's Blog - [Event Loop Best Practices — NodeJS Event Loop Part 5](https://blog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
diff --git a/sections/performance/block-loop.japanese.md b/sections/performance/block-loop.japanese.md
new file mode 100644
index 000000000..7d2a42f57
--- /dev/null
+++ b/sections/performance/block-loop.japanese.md
@@ -0,0 +1,49 @@
+# イベントループをブロックしない
+
+
+
+Node はほとんどの場合、複数のキューをローテーションする単一のスレッド上でイベントループを処理します。複雑度の高い操作、大きな json の解析、巨大な配列へのロジックの適用、安全ではない正規表現クエリ、そして大きな IO 操作は、イベントループを停止させる原因となる操作です。これを避けるために、CPU集約的なタスクを専用サービス(ジョブサーバーなど)にオフロードしたり、長いタスクを小さなステップに分けてワーカープールを使用したりすることは、イベントループをブロックしないようにする方法のいくつかの例です。
+
+### 例: イベントループをブロックする
+[Node Clinic](https://clinicjs.org/documentation/doctor/05-fixing-event-loop-problem) の例を見てみましょう。
+```javascript
+function sleep (ms) {
+ const future = Date.now() + ms
+ while (Date.now() < future);
+}
+
+server.get('/', (req, res, next) => {
+ sleep(30)
+ res.send({})
+ next()
+})
+```
+
+そして、このアプリをベンチマークしてみると、長時間の while ループによるレイテンシを確認することができます。
+
+### ベンチマークの実行
+`clinic doctor --on-port 'autocannon localhost:$PORT' -- node slow-event-loop`
+
+### 結果
+
+```
+─────────┬────────┬────────┬────────┬────────┬───────────┬──────────┬───────────┐
+│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
+├─────────┼────────┼────────┼────────┼────────┼───────────┼──────────┼───────────┤
+│ Latency │ 270 ms │ 300 ms │ 328 ms │ 331 ms │ 300.56 ms │ 38.55 ms │ 577.05 ms │
+└─────────┴────────┴────────┴────────┴────────┴───────────┴──────────┴───────────┘
+┌───────────┬─────────┬─────────┬─────────┬────────┬─────────┬───────┬─────────┐
+│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
+├───────────┼─────────┼─────────┼─────────┼────────┼─────────┼───────┼─────────┤
+│ Req/Sec │ 31 │ 31 │ 33 │ 34 │ 32.71 │ 1.01 │ 31 │
+├───────────┼─────────┼─────────┼─────────┼────────┼─────────┼───────┼─────────┤
+```
+
+## イベントループのイメージ図
+
+
+>ここに、Node サーバを高速に保つための良い経験則があります: Node は、与えられた時間にそれぞれのクライアントに関連する作業が 「小さい」 場合に高速です。
+>[イベントループ(またはワーカープール)をブロックしない | Node.js](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)
+
+> イベントループ、エラー処理、非同期などの概念を理解していないことが原因で、ほとんどの人が最初の数回の NodeJS アプリで失敗します。
+[イベントループのベストプラクティス - NodeJS イベントループ Part 5](https://jsblog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
diff --git a/sections/performance/block-loop.md b/sections/performance/block-loop.md
index 531de7fef..cba98a3c4 100644
--- a/sections/performance/block-loop.md
+++ b/sections/performance/block-loop.md
@@ -28,7 +28,7 @@ while loop.
### The results
```
-─────────┬────────┬────────┬────────┬────────┬───────────┬──────────┬───────────┐
+┌─────────┬────────┬────────┬────────┬────────┬───────────┬──────────┬───────────┐
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
├─────────┼────────┼────────┼────────┼────────┼───────────┼──────────┼───────────┤
│ Latency │ 270 ms │ 300 ms │ 328 ms │ 331 ms │ 300.56 ms │ 38.55 ms │ 577.05 ms │
@@ -41,10 +41,19 @@ while loop.
```
## Image of the Event Loop
-
+
->Here's a good rule of thumb for keeping your Node server speedy: Node is fast when the work associated with each client at any given time is "small".
->[Don't Block the Event Loop (or the Worker Pool) | Node.js](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)
-> Most people fail their first few NodeJS apps merely due to the lack of understanding of the concepts such as the Event Loop, Error handling and asynchrony
-[Event Loop Best Practices — NodeJS Event Loop Part 5](https://jsblog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
+### "Here's a good rule of thumb for keeping your Node server speedy: _Node is fast when the work associated with each client at any given time is 'small'_."
+From Node.js Documentation - [Don't Block the Event Loop (or the Worker Pool)](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)
+
+> The secret to the scalability of Node.js is that it uses a small number of threads to handle many clients.
+> If Node.js can make do with fewer threads, then it can spend more of your system's time and memory working on clients rather than on paying space and time overheads for threads (memory, context-switching).
+> But because Node.js has only a few threads, you must structure your application to use them wisely.
+>
+> Here's a good rule of thumb for keeping your Node.js server speedy: Node.js is fast when the work associated with each client at any given time is "small".
+> This applies to callbacks on the Event Loop and tasks on the Worker Pool.
+
+### "Most people fail their first few NodeJS apps merely due to the lack of understanding of the concepts such as the Event Loop, Error handling and asynchrony"
+From Deepal's Blog - [Event Loop Best Practices — NodeJS Event Loop Part 5](https://blog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
+
diff --git a/sections/performance/block-loop.polish.md b/sections/performance/block-loop.polish.md
new file mode 100644
index 000000000..ab7cb013c
--- /dev/null
+++ b/sections/performance/block-loop.polish.md
@@ -0,0 +1,50 @@
+# Nie blokuj pętli zdarzeń
+
+
+
+Node obsługuje pętlę zdarzeń głównie w jednym wątku obracającym się przez wiele kolejek. Operacje o wysokim stopniu złożoności, dużym parsowaniu jsonów, stosowaniu logiki na wielkich tablicach, niebezpiecznych zapytaniach regularnych i dużych operacjach We / Wy to niektóre z operacji, które mogą powodować zawieszanie się pętli zdarzeń. Unikaj odciążania zadań intensywnie wykorzystujących procesor do dedykowanej usługi (np. serwera zadań) lub dzielenia długich zadań na małe kroki, a następnie używanie puli pracowników to kilka przykładów tego, jak uniknąć blokowania pętli zdarzeń.
+
+### Przykład: blokowanie pętli zdarzeń
+Spójrzmy na przykład z [Node Clinic](https://clinicjs.org/documentation/doctor/05-fixing-event-loop-problem).
+```javascript
+function sleep (ms) {
+ const future = Date.now() + ms
+ while (Date.now() < future);
+}
+
+server.get('/', (req, res, next) => {
+ sleep(30)
+ res.send({})
+ next()
+})
+```
+
+Kiedy porównujemy tę aplikację, zaczynamy dostrzegać opóźnienia spowodowane długą
+pętlą while.
+
+### Uruchom benchmark
+`clinic doctor --on-port 'autocannon localhost:$PORT' -- node slow-event-loop`
+
+### Wyniki
+
+```
+─────────┬────────┬────────┬────────┬────────┬───────────┬──────────┬───────────┐
+│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
+├─────────┼────────┼────────┼────────┼────────┼───────────┼──────────┼───────────┤
+│ Latency │ 270 ms │ 300 ms │ 328 ms │ 331 ms │ 300.56 ms │ 38.55 ms │ 577.05 ms │
+└─────────┴────────┴────────┴────────┴────────┴───────────┴──────────┴───────────┘
+┌───────────┬─────────┬─────────┬─────────┬────────┬─────────┬───────┬─────────┐
+│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
+├───────────┼─────────┼─────────┼─────────┼────────┼─────────┼───────┼─────────┤
+│ Req/Sec │ 31 │ 31 │ 33 │ 34 │ 32.71 │ 1.01 │ 31 │
+├───────────┼─────────┼─────────┼─────────┼────────┼─────────┼───────┼─────────┤
+```
+
+## Obraz pętli zdarzeń
+
+
+>Here's a good rule of thumb for keeping your Node server speedy: Node is fast when the work associated with each client at any given time is "small".
+>[Don't Block the Event Loop (or the Worker Pool) | Node.js](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)
+
+> Most people fail their first few NodeJS apps merely due to the lack of understanding of the concepts such as the Event Loop, Error handling and asynchrony
+[Event Loop Best Practices — NodeJS Event Loop Part 5](https://jsblog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
diff --git a/sections/performance/block-loop.russian.md b/sections/performance/block-loop.russian.md
index 3657a9bac..88b24c4a4 100644
--- a/sections/performance/block-loop.russian.md
+++ b/sections/performance/block-loop.russian.md
@@ -6,13 +6,13 @@ Node обрабатывает цикл событий в основном в о
### Example: blocking the event loop
Давайте посмотрим на пример из [Node Clinic](https://clinicjs.org/documentation/doctor/05-fixing-event-loop-problem).
-```
+```javascript
function sleep (ms) {
const future = Date.now() + ms
while (Date.now() < future);
}
-server.get('/', function (req, res, next) {
+server.get('/', (req, res, next) => {
sleep(30)
res.send({})
next()
@@ -41,10 +41,10 @@ while loop.
```
## Изображение цикла событий
-
+
Вот хорошее эмпирическое правило для поддержания скорости вашего Node-сервера: Node работает быстро, когда работа, связанная с каждым клиентом в любой момент времени, "мала".
>[Don't Block the Event Loop (or the Worker Pool) | Node.js](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)
> Большинство людей терпят неудачу в своих первых нескольких приложениях NodeJS просто из-за отсутствия понимания таких понятий, как цикл обработки событий, обработка ошибок и асинхронность
-[Event Loop Best Practices — NodeJS Event Loop Part 5](https://jsblog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
\ No newline at end of file
+[Event Loop Best Practices — NodeJS Event Loop Part 5](https://jsblog.insiderattack.net/event-loop-best-practices-nodejs-event-loop-part-5-e29b2b50bfe2)
diff --git a/sections/performance/nativeoverutil.basque.md b/sections/performance/nativeoverutil.basque.md
new file mode 100644
index 000000000..cc0a1ad68
--- /dev/null
+++ b/sections/performance/nativeoverutil.basque.md
@@ -0,0 +1,73 @@
+# Hobetsi jatorrizko JS metodoak Lodash bezalako erabiltzaileen baliabideak baino
+
+
+
+### Azalpena
+
+Batzuetan, hobe da jatorrizko metodoak erabiltzea _lodash_ edo _underscore_ bezalako liburutegiak erabili beharra izatea baino, liburutegi horiek errendimendu galera bat ekar baitezakete eta beharrezko baino memoria gehiago erabili. Jatorrizko funtzioak erabiltzeak [%50 inguruko erabateko irabazia](https://github.com/Berkmann18/NativeVsUtils/blob/master/analysis.xlsx) lor dezake, adibidez, funtzio hauek: `Array.concat`, `Array.fill`, `Array.filter`, `Array.map`, `(Array|String).indexOf`, `Object.find`, …
+
+
+
+
+
+
+### Abididea: konparaketa probak - Lodash versus V8 (jatorrizkoa)
+
+Beheko grafikoak [Lodashen metodo ugariren proben erreferentzien](https://github.com/Berkmann18/NativeVsUtils/blob/master/nativeVsLodash.ods) batez bestekoa erakusten du. Horrek erakusten du Lodash metodoek batez beste %146,23 denbora gehiago behar dutela V8 metodoen ataza berdinak burutzeko.
+
+
+
+### Kode adibidea: `_.concat`/`Array.concat`en proba
+
+```javascript
+const _ = require("lodash");
+const __ = require("underscore");
+const Suite = require("benchmark").Suite;
+const opts = require("./utils"); //cf. https://github.com/Berkmann18/NativeVsUtils/blob/master/utils.js
+
+const concatSuite = new Suite("concat", opts);
+const array = [0, 1, 2];
+
+concatSuite
+ .add("lodash", () => _.concat(array, 3, 4, 5))
+ .add("underscore", () => __.concat(array, 3, 4, 5))
+ .add("native", () => array.concat(3, 4, 5))
+ .run({ async: true });
+```
+
+Non hau bueltatzen duen:
+
+
+
+[Hemen](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.txt) duzu proba erreferentzia puntuen zerrenda luzeago bat edo, bestela, [egikaritu hau](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.js), hori bera erakutsiko dizu, baina koloretan.
+
+### Blog aipua: "(baliteke) Ez duzu Lodash/Underscoreren beharrik (ez izatea)"
+
+[Lodash eta Underscoren inguruko gaiei buruzko txostena](https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore).
+
+> JavaScripten baliabideen liburutegi moderno bikainak dira Lodash eta Underscore, eta Front-end garatzaileen artean oso erabiliak. Hala ere, nabigatzaile modernoak jomugatzat dituzunean, pentsa dezakezu ECMAScript5ek [ES5] eta ECMAScript2015ek [ES6] badituztela jatorriz funtzio horietako asko. Zure proiektuak menpekotasun gutxiago edukitzea nahi baduzu, eta argi badaukazu zein nabilgatzaile duzun helburutzat, baliteke behar ez izatea Lodash/Underscore.
+
+### Adibidea: jatorrizkoak ez diren metodoak erabiltzeko linting-a
+
+Badago [ESLint plugin](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore) bat behar ez dituzun liburutegiak atzeman eta aholkuak ematen dizkizuna (behean duzu adibidea). Plugin hori erabili nahi baduzu, gehitu `eslint-plugin-you-dont-need-lodash-underscore` plugina zure ESLint ezarpen fitxategiari:
+
+```json
+{
+ "extends": ["plugin:you-dont-need-lodash-underscore/compatible"]
+}
+```
+
+### Adibidea: linter bat erabiliz, atzeman beharrezko ez diren v8 funtzionalitateen erabilera
+
+Eman begirada bat azpiko fitxategiari:
+
+```js
+const _ = require("lodash");
+// ESLintek azpiko lerroa markatuko du iradokizun batekin
+console.log(_.map([0, 1, 2, 4, 8, 16], (x) => `d${x}`));
+```
+
+Hementxe dago ESLintek bistaratuko lukeena YDNLU plugina erabiliz.
+
+
+Noski, adibide horrek ez du errealista ematen egungo kodeek dutena kontutan hartuta, baina bai balio du ulertzeko.
diff --git a/sections/performance/nativeoverutil.brazilian-portuguese.md b/sections/performance/nativeoverutil.brazilian-portuguese.md
index 22d80e426..e7fa0942e 100644
--- a/sections/performance/nativeoverutil.brazilian-portuguese.md
+++ b/sections/performance/nativeoverutil.brazilian-portuguese.md
@@ -47,7 +47,7 @@ Do [repositório sobre esse assunto que foca em Lodash e Underscore](https://git
> O Lodash e o Underscore são ótimas bibliotecas de utilitários JavaScript moderno e são amplamente utilizados por desenvolvedores front-end. No entanto, quando você está focando nos navegadores modernos, você pode descobrir que existem muitos métodos que já são suportados nativamente graças ao ECMAScript5 [ES5] e ao ECMAScript2015 [ES6]. Se você quer que seu projeto exija menos dependências, e você conhece claramente o seu navegador de destino, talvez você não precise do Lodash/Underscore.
### Exemplo: Linting para uso de métodos não nativos
-Existe um [plugin de ESLint](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore) que detecta onde você está usando bibliotecas, mas não precisa, alertando com sugestões (veja o exemplo abaixo).
+Existe um [plugin de ESLint](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore) que detecta onde você está usando bibliotecas, mas não precisa, alertando com sugestões (veja o exemplo abaixo).
A maneira de configurá-lo é adicionando o plugin `eslint-plugin-you-dont-need-lodash-underscore` no seu arquivo de configuração do ESLint:
```json
{
diff --git a/sections/performance/nativeoverutil.french.md b/sections/performance/nativeoverutil.french.md
new file mode 100644
index 000000000..7b79ddc65
--- /dev/null
+++ b/sections/performance/nativeoverutil.french.md
@@ -0,0 +1,70 @@
+# Prefer native JS methods over user-land utils like Lodash
+
+
+
+
+### One Paragraph Explainer
+
+Sometimes, using native methods is better than requiring _lodash_ or _underscore_ because those libraries can lead to performance loss or take up more space than needed.
+The performance using native methods result in an [overall ~50% gain](https://github.com/Berkmann18/NativeVsUtils/blob/master/analysis.xlsx) which includes the following methods: `Array.concat`, `Array.fill`, `Array.filter`, `Array.map`, `(Array|String).indexOf`, `Object.find`, ...
+
+
+
+
+
+
+### Example: benchmark comparison - Lodash vs V8 (Native)
+The graph below shows the [mean of the benchmarks for a variety of Lodash methods](https://github.com/Berkmann18/NativeVsUtils/blob/master/nativeVsLodash.ods), this shows that Lodash methods take on average 146.23% more time to complete the same tasks as V8 methods.
+
+
+
+### Code Example – Benchmark test on `_.concat`/`Array.concat`
+```javascript
+const _ = require('lodash');
+const __ = require('underscore');
+const Suite = require('benchmark').Suite;
+const opts = require('./utils'); //cf. https://github.com/Berkmann18/NativeVsUtils/blob/master/utils.js
+
+const concatSuite = new Suite('concat', opts);
+const array = [0, 1, 2];
+
+concatSuite.add('lodash', () => _.concat(array, 3, 4, 5))
+ .add('underscore', () => __.concat(array, 3, 4, 5))
+ .add('native', () => array.concat(3, 4, 5))
+ .run({ 'async': true });
+```
+
+Which returns this:
+
+
+
+You can find a bigger list of benchmarks [here](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.txt) or alternatively [run this](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.js) which would show the same but with colours.
+
+### Blog Quote: "You don't (may not) need Lodash/Underscore"
+
+From the [repo on this matter which focuses on Lodash and Underscore](https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore).
+
+ > Lodash and Underscore are great modern JavaScript utility libraries, and they are widely used by Front-end developers. However, when you are targeting modern browsers, you may find out that there are many methods which are already supported natively thanks to ECMAScript5 [ES5] and ECMAScript2015 [ES6]. If you want your project to require fewer dependencies, and you know your target browser clearly, then you may not need Lodash/Underscore.
+
+### Example: Linting for non-native methods usage
+There's an [ESLint plugin](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore) which detects where you're using libraries but don't need to by warning you with suggestions (cf. example below).
+The way you set it up is by adding the `eslint-plugin-you-dont-need-lodash-underscore` plugin to your ESLint configuration file:
+```json
+{
+ "extends": [
+ "plugin:you-dont-need-lodash-underscore/compatible"
+ ]
+}
+```
+
+### Example: detecting non-v8 util usage using a linter
+Consider the file below:
+```js
+const _ = require('lodash');
+// ESLint will flag the line above with a suggestion
+console.log(_.map([0, 1, 2, 4, 8, 16], x => `d${x}`));
+```
+Here's what ESLint would output when using the YDNLU plugin.
+
+
+Of course, the example above doesn't seem realistic considering what actual codebases would have but you get the idea.
diff --git a/sections/performance/nativeoverutil.japanese.md b/sections/performance/nativeoverutil.japanese.md
new file mode 100644
index 000000000..c9875c59d
--- /dev/null
+++ b/sections/performance/nativeoverutil.japanese.md
@@ -0,0 +1,69 @@
+# Lodash のようなユーザーランドのユーティリティよりも、ネイティブの JS メソッドを選ぶ
+
+
+
### One Paragraph Explainer
-
-Sometimes, using native methods is better than requiring `lodash` or `underscore` because it will not lead in a performance boost and use more space than necessary.
+Sometimes, using native methods is better than requiring _lodash_ or _underscore_ because those libraries can lead to performance loss or take up more space than needed
The performance using native methods result in an [overall ~50% gain](https://github.com/Berkmann18/NativeVsUtils/blob/master/analysis.xlsx) which includes the following methods: `Array.concat`, `Array.fill`, `Array.filter`, `Array.map`, `(Array|String).indexOf`, `Object.find`, ...
@@ -47,7 +46,7 @@ From the [repo on this matter which focuses on Lodash and Underscore](https://gi
> Lodash and Underscore are great modern JavaScript utility libraries, and they are widely used by Front-end developers. However, when you are targeting modern browsers, you may find out that there are many methods which are already supported natively thanks to ECMAScript5 [ES5] and ECMAScript2015 [ES6]. If you want your project to require fewer dependencies, and you know your target browser clearly, then you may not need Lodash/Underscore.
### Example: Linting for non-native methods usage
-There's an [ESLint plugin](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore) which detects where you're using libraries but don't need to by warning you with suggestions (cf. example below).
+There's an [ESLint plugin](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore) which detects where you're using libraries but don't need to by warning you with suggestions (cf. example below).
The way you set it up is by adding the `eslint-plugin-you-dont-need-lodash-underscore` plugin to your ESLint configuration file:
```json
{
diff --git a/sections/performance/nativeoverutil.polish.md b/sections/performance/nativeoverutil.polish.md
new file mode 100644
index 000000000..d0e0bb581
--- /dev/null
+++ b/sections/performance/nativeoverutil.polish.md
@@ -0,0 +1,69 @@
+# Preferuj natywne metody JS niż narzędzia użytkowników, takie jak Lodash
+
+
+
+
+### Wyjaśnienie jednym akapitem
+Czasami użycie metod natywnych jest lepsze niż wymaganie _lodash_ lub _underscore_, ponieważ te biblioteki mogą prowadzić do utraty wydajności lub zajmować więcej miejsca niż potrzeba.
+Wydajność przy użyciu metod rodzimych skutkuje [ogólnym ~50% zyskiem](https://github.com/Berkmann18/NativeVsUtils/blob/master/analysis.xlsx), który obejmuje następujące metody: `Array.concat`,` Array.fill`, `Array.filter`, `Array.map`, `(Array|String).indexOf`, `Object.find`, ...
+
+
+
+
+
+
+### Przykład: benchmark comparison - Lodash vs V8 (Native)
+Poniższy wykres pokazuje [średnią wyników dla różnych metod Lodasha](https://github.com/Berkmann18/NativeVsUtils/blob/master/nativeVsLodash.ods), pokazuje to, że metody Lodash zajmują średnio 146,23% więcej czasu na wykonanie tych samych zadań, co metody V8.
+
+
+
+### Przykład kodu – Benchmark test on `_.concat`/`Array.concat`
+```javascript
+const _ = require('lodash');
+const __ = require('underscore');
+const Suite = require('benchmark').Suite;
+const opts = require('./utils'); //cf. https://github.com/Berkmann18/NativeVsUtils/blob/master/utils.js
+
+const concatSuite = new Suite('concat', opts);
+const array = [0, 1, 2];
+
+concatSuite.add('lodash', () => _.concat(array, 3, 4, 5))
+ .add('underscore', () => __.concat(array, 3, 4, 5))
+ .add('native', () => array.concat(3, 4, 5))
+ .run({ 'async': true });
+```
+
+Co zwraca to:
+
+
+
+Możesz znaleźć większą listę benchmarków [tutaj](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.txt) lub alternatywnie [uruchom to](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.js) które pokazałyby to samo, ale z kolorami.
+
+### Cytat z bloga: "You don't (may not) need Lodash/Underscore"
+
+Z [repozytorium na ten temat, które koncentruje się na Lodash i Underscore](https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore).
+
+ > Lodash and Underscore are great modern JavaScript utility libraries, and they are widely used by Front-end developers. However, when you are targeting modern browsers, you may find out that there are many methods which are already supported natively thanks to ECMAScript5 [ES5] and ECMAScript2015 [ES6]. If you want your project to require fewer dependencies, and you know your target browser clearly, then you may not need Lodash/Underscore.
+
+### Przykład: Linting for non-native methods usage
+Istnieje [wtyczka ESLint](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore) która wykrywa, gdzie korzystasz z bibliotek, ale nie musisz, ostrzegając Cię sugestiami (porównaj z przykładem poniżej).
+Sposób konfiguracji polega na dodaniu wtyczki `eslint-plugin-you-dont-need-lodash-underscore` do pliku konfiguracyjnego ESLint:
+```json
+{
+ "extends": [
+ "plugin:you-dont-need-lodash-underscore/compatible"
+ ]
+}
+```
+
+### Przykład: detecting non-v8 util usage using a linter
+Consider the file below:
+```js
+const _ = require('lodash');
+// ESLint will flag the line above with a suggestion
+console.log(_.map([0, 1, 2, 4, 8, 16], x => `d${x}`));
+```
+Oto, co wyświetli ESLint podczas korzystania z wtyczki YDNLU.
+
+
+Oczywiście powyższy przykład nie wydaje się realistyczny, biorąc pod uwagę, jakie byłyby rzeczywiste bazy kodów, ale masz pomysł.
diff --git a/sections/performance/nativeoverutil.russian.md b/sections/performance/nativeoverutil.russian.md
index 953d64996..be05f010b 100644
--- a/sections/performance/nativeoverutil.russian.md
+++ b/sections/performance/nativeoverutil.russian.md
@@ -20,10 +20,10 @@
### Пример кода - бенчмарк-тест для `_.concat`/`Array.concat`
```javascript
-const _ = require('lodash'),
- __ = require('underscore'),
- Suite = require('benchmark').Suite,
- opts = require('./utils'); //cf. https://github.com/Berkmann18/NativeVsUtils/blob/master/utils.js
+const _ = require('lodash');
+const __ = require('underscore');
+const Suite = require('benchmark').Suite;
+const opts = require('./utils'); //cf. https://github.com/Berkmann18/NativeVsUtils/blob/master/utils.js
const concatSuite = new Suite('concat', opts);
const array = [0, 1, 2];
@@ -47,7 +47,7 @@ concatSuite.add('lodash', () => _.concat(array, 3, 4, 5))
> Lodash и Underscore - отличные современные библиотеки утилит JavaScript, и они широко используются разработчиками Front-end. Однако, когда вы ориентируетесь на современные браузеры, вы можете обнаружить, что есть много методов, которые уже изначально поддерживаются благодаря ECMAScript5 [ES5] и ECMAScript2015 [ES6]. Если вы хотите, чтобы вашему проекту требовалось меньше зависимостей, и вы четко знаете целевой браузер, то вам может не потребоваться Lodash/Underscore.
### Пример: Linting для использования неродных методов
-Существует [плагин ESLint](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore), который определяет, где вы используете библиотеки, но не должен предупреждать вас с предложениями (см. пример ниже).
+Существует [плагин ESLint](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore), который определяет, где вы используете библиотеки, но не должен предупреждать вас с предложениями (см. пример ниже).
Вы можете настроить его, добавив плагин `eslint-plugin-you-dont-need-lodash-underscore` в файл конфигурации ESLint:
```json
{
diff --git a/sections/production/LTSrelease.basque.md b/sections/production/LTSrelease.basque.md
new file mode 100644
index 000000000..6069f91f3
--- /dev/null
+++ b/sections/production/LTSrelease.basque.md
@@ -0,0 +1,21 @@
+# Erabili Node.js LTS bertsioa ekoizpenean
+
+### Azalpena
+
+Ziurtatu ekoizpenean NTS.jsen LTS (Long Term Support) bertsioa erabiltzen ari zarela erroreen konponketa kritikoak, segurtasun eguneratzeak eta errendimendu hobekuntzak jasotzeko.
+
+Node.jsren LTS bertsioak gutxienez 18 hilabetez onartzen dira, eta bertsio zenbaki bikoitien bidez adierazten dira (adibidez, 4, 6, 8). Bertsioak onenak dira ekoizpenerako, LTS bertsio lerroa egonkortasunera eta segurtasunera bideratuta baitago, "Oraingo" bertsio lerroak, berriz, bizitza motzagoa eta maizago eguneratzen du kodea. LTS bertsioen aldaketak egonkortasuna, segurtasun eguneratzeak, npm eguneratze posibleak, dokumentazio eguneratzeak eta lehendik dauden aplikazioak ez apurtzeko frogatu daitezkeen zenbait errendimendu hobekuntzetara mugatzen dira.
+
+
+
+### Jarraitu irakurtzen
+
+🔗 [Node.jsren bertsioen definizioak](https://nodejs.org/en/about/releases/)
+
+🔗 [Node.js kaleratze egutegia](https://github.com/nodejs/Release)
+
+🔗 [Funtsezko urratsak; Rod Vagg-en epe luzeko laguntza Node.jsrentzat](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
+
+> ...Hauetako bakoitzaren bertsio inkrementalen egutegia erroreen konponketen, segurtasun konponketen eta beste aldaketa txiki baina garrantzitsu batzuen eskuragarritasunaren araberakoa izango da. Fokua egonkortasuna da, baina errore ezagunen kopurua minimizatzea eta segurtasun arazoak sortu ahala haien berri jakitea ere bada egonkortasuna bermatzea.
+
+
+
+### 继续读下去
+
+🔗 [ Node.js版本定义 ](https://nodejs.org/en/about/releases/)
+
+🔗 [ Node.js发布时间表 ](https://github.com/nodejs/Release)
+
+🔗 [必要步骤:Long Term Support for Node.js by Rod Vagg(Node.js的长期支持by Rod Vagg)](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
+> ...每个增量发布计划将由错误修复、安全修复和其他小但重要的更改的可用性来驱动。重点将放在稳定性上,但稳定性还包括最大程度地减少已知错误的数量,和持续关注重大的安全问题。
+
+
diff --git a/sections/production/LTSrelease.french.md b/sections/production/LTSrelease.french.md
new file mode 100644
index 000000000..e4abe1882
--- /dev/null
+++ b/sections/production/LTSrelease.french.md
@@ -0,0 +1,20 @@
+# Utilisez une version LTS de Node.js en production
+
+### Un paragraphe d'explication
+
+Assurez-vous d'utilise une version LTS (Long Term Support) de Node.js en production pour recevoir les corrections de bogues critiques, les mises à jour de sécurité et les améliorations de performance.
+
+Les versions LTS de Node.js sont prises en charge pendant au moins 18 mois et sont indiquées par des numéros de version pairs (par exemple 4, 6, 8). Elles sont idéales pour la production car la ligne de version LTS est axée sur la stabilité et la sécurité, alors que la ligne de version "Current" a une durée de vie plus courte et des mises à jour plus fréquentes du code. Les modifications apportées aux versions LTS se limitent à des corrections de bogues pour la stabilité, des mises à jour de sécurité, d'éventuelles mises à jour npm, des mises à jour de la documentation et certaines améliorations des performances dont il peut être prouvé qu'elles ne nuisent pas aux applications existantes.
+
+
+
+### A lire
+
+🔗 [Définitions des versions de Node.js](https://nodejs.org/en/about/releases/)
+
+🔗 [Calendrier de diffusion de Node.js](https://github.com/nodejs/Release)
+
+🔗 [Étapes essentielles : Support à long terme (Long Term Support) pour Node.js par Rod Vagg](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
+> ...le calendrier des versions incrémentales de chacune d'entre elles sera déterminé par la disponibilité des corrections de bogues, des corrections de sécurité et d'autres changements, petits mais importants. L'accent sera mis sur la stabilité, mais la stabilité implique également de minimiser le nombre de bogues connus et de rester au fait des problèmes de sécurité au fur et à mesure qu'ils surviennent.
+
+
+
+### 続きを読む
+
+🔗 [Node.js のリリース定義](https://nodejs.org/en/about/releases/)
+
+🔗 [Node.js リリーススケジュール](https://github.com/nodejs/Release)
+
+🔗 [Essential Steps: Long Term Support for Node.js by Rod Vagg (必須ステップ: Node.js の長期サポート by Rod Vagg)](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
+> ...これらの中での増分リリースのスケジュールは、バグ修正、セキュリティ修正、その他の小さいが重要な変更の有無によって決定されます。安定性に重点が置かれますが、安定性には既知のバグの数を最小限に抑え、セキュリティ上の懸念事項が発生した場合には、それを常に把握しておくことも含まれます。
+
+
diff --git a/sections/production/LTSrelease.polish.md b/sections/production/LTSrelease.polish.md
new file mode 100644
index 000000000..6382b5e5a
--- /dev/null
+++ b/sections/production/LTSrelease.polish.md
@@ -0,0 +1,20 @@
+# Użyj wersji LTS Node.js w produkcji
+
+### Wyjaśnienie jednym akapitem
+
+Upewnij się, że korzystasz z wersji LTS (Long Term Support) Node.js w produkcji, aby otrzymywać krytyczne poprawki błędów, aktualizacje zabezpieczeń i ulepszenia wydajności.
+
+Wersje Lode Node.js są obsługiwane przez co najmniej 18 miesięcy i są oznaczone parzystymi numerami wersji (np. 4, 6, 8). Najlepiej nadają się do produkcji, ponieważ linia wydania LTS koncentruje się na stabilności i bezpieczeństwie, podczas gdy linia wydania „Bieżąca” ma krótszą żywotność i częstsze aktualizacje kodu. Zmiany w wersjach LTS ograniczają się do poprawek błędów dotyczących stabilności, aktualizacji bezpieczeństwa, możliwych aktualizacji npm, aktualizacji dokumentacji i pewnych ulepszeń wydajności, które można wykazać, aby nie powodować awarii istniejących aplikacji.
+
+
+
+### Czytaj
+
+🔗 [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.
+
+
+
+### Azalpena
+
+APM (aplikazioaren errendimenduaren jarraipena) produktu familia bat da, aplikazioaren errendimendua hasieratik amaierara kontrolatzea helburu duena, baita bezeroaren ikuspegitik ere. Jarraipen tradizionaleko irtenbideak salbuespenetan eta metrika tekniko independenteetan oinarritzen dira (adibidez, erroreen jarraipena, zerbitzariaren amaiera puntu motelak, etab.). Mundu errealean, aldiz, gure aplikazioak erabiltzaile etsiak sor ditzake inolako kode salbuespenik gabe, adibidez, middleware zerbitzu batzuek oso geldo lan egiten badute. APM produktuek erabiltzaileen esperientzia neurtzen dute hasieratik bukaerara, adibidez, frontend interfazea eta banatutako zerbitzu anitzak biltzen dituen sistema ematen dutenean; APM produktu batzuek maila desberdinetako transakzio batek zenbateraino irauten duen jakin dezakete. Erabiltzailearen esperientzia ona den ala ez esan eta arazoa seinalatu dezake. Eskaintza erakargarri horrek prezio nahiko altua duenez, egokia da produktu konplexu eta jarraipen soiletik haratago joan beharra duten eskala handikoekin lan egiteko
+
+
+
+### APM adibidea: zerbitzuen arteko aplikazioen errendimendua ikusarazten duen produktu komertziala
+
+
+
+
+
+### APM adibidea: erabiltzailearen esperientziaren puntuazioa azpimarratzen duen produktu komertziala
+
+
+
+
+
+### APM adibidea: kode geldoen bideak nabarmentzen dituen produktu komertziala
+
+
diff --git a/sections/production/apmproducts.brazilian-portuguese.md b/sections/production/apmproducts.brazilian-portuguese.md
index ce46992b9..d51ebf68c 100644
--- a/sections/production/apmproducts.brazilian-portuguese.md
+++ b/sections/production/apmproducts.brazilian-portuguese.md
@@ -10,16 +10,16 @@ O APM (monitoramento de desempenho de aplicação) refere-se a uma família de p
### Exemplo de APM - um produto comercial que visualiza o desempenho de aplicações de serviço cruzado
-
+
### Exemplo de APM - um produto comercial que enfatiza a pontuação da experiência do usuário
-
+
### Exemplo de APM - um produto comercial que destaca caminhos de código lento
-
+
diff --git a/sections/production/apmproducts.chinese.md b/sections/production/apmproducts.chinese.md
index 4c82d0739..1d4e32cc6 100644
--- a/sections/production/apmproducts.chinese.md
+++ b/sections/production/apmproducts.chinese.md
@@ -11,16 +11,16 @@ APM(应用程序性能监视)指的是一个产品系列, 目的是从端到
### APM 示例 – 一种可视化显示跨服务应用性能的商业产品
-
+
### APM 示例 – 一种突出显示慢速代码路径的商业产品
-
+
diff --git a/sections/production/apmproducts.french.md b/sections/production/apmproducts.french.md
new file mode 100644
index 000000000..959bcf009
--- /dev/null
+++ b/sections/production/apmproducts.french.md
@@ -0,0 +1,25 @@
+# Une expérience utilisateur sûre avec les produits APM
+
+
+
+### Un paragraphe d'explication
+
+APM (NdT, « Application Performance Monitoring » : surveillance des performances des applications) fait référence à une famille de produits qui vise à surveiller les performances des applications de bout en bout, également du point de vue du client. Alors que les solutions de surveillance classiques se concentrent sur les exceptions et les mesures techniques autonomes (par exemple, le suivi des erreurs, les points de terminaison de serveur lents, etc.), dans le monde réel, notre application pourrait décevoir des utilisateurs sans aucune erreur de code, par exemple, si certains services du middleware fonctionnent très lentement. Les produits APM mesurent l'expérience utilisateur de bout en bout, par exemple, prenons un système qui englobe l'interface utilisateur frontale et de multiples services distribués - certains produits APM peuvent dire à quelle vitesse s'effectue une transaction qui traverse plusieurs niveaux. Ils peuvent indiquer si l'expérience utilisateur est solide et indiquer le problème. Cette offre attrayante a un prix relativement élevé, elle est donc recommandée pour les produits à grande échelle et complexes qui nécessitent d'aller au-delà de la simple surveillance.
+
+
+
+### Exemple APM – un produit commercial qui visualise les performances des applications interservices
+
+
+
+
+
+### Exemple APM – un produit commercial qui met l'accent sur le score de l'expérience utilisateur
+
+
+
+
+
+### Exemple APM – un produit commercial qui met en évidence les chemins de code lents
+
+
diff --git a/sections/production/apmproducts.japanese.md b/sections/production/apmproducts.japanese.md
new file mode 100644
index 000000000..d726dbf9a
--- /dev/null
+++ b/sections/production/apmproducts.japanese.md
@@ -0,0 +1,25 @@
+# APM 製品の確かなユーザー体験
+
+
+
+### APM の例 – 遅いコードパスをハイライトする商用製品
+
+
diff --git a/sections/production/apmproducts.korean.md b/sections/production/apmproducts.korean.md
index bd7e5754b..d5f0fbf80 100644
--- a/sections/production/apmproducts.korean.md
+++ b/sections/production/apmproducts.korean.md
@@ -10,16 +10,16 @@ APM (application performance monitoring) refers to a family of products that aim
### APM example – a commercial product that visualizes cross-service app performance
-
+
### APM example – a commercial product that emphasizes the user experience score
-
+
### APM example – a commercial product that highlights slow code paths
-
+
diff --git a/sections/production/apmproducts.md b/sections/production/apmproducts.md
index bd7e5754b..d5f0fbf80 100644
--- a/sections/production/apmproducts.md
+++ b/sections/production/apmproducts.md
@@ -10,16 +10,16 @@ APM (application performance monitoring) refers to a family of products that aim
### APM example – a commercial product that visualizes cross-service app performance
-
+
### APM example – a commercial product that emphasizes the user experience score
-
+
### APM example – a commercial product that highlights slow code paths
-
+
diff --git a/sections/production/apmproducts.polish.md b/sections/production/apmproducts.polish.md
new file mode 100644
index 000000000..f34c54ee9
--- /dev/null
+++ b/sections/production/apmproducts.polish.md
@@ -0,0 +1,25 @@
+# Zapewnij użytkownikom wygodę korzystania z produktów APM
+
+
+
+### Wyjaśnienie jednym akapitem
+
+APM (application performance monitoring) odnosi się do rodziny produktów, która ma na celu monitorowanie wydajności aplikacji od początku do końca, również z perspektywy klienta. Podczas gdy tradycyjne rozwiązania monitorujące koncentrują się na wyjątkach i niezależnych pomiarach technicznych (np. śledzeniu błędów, powolnych punktach końcowych serwera itp.), w prawdziwym świecie nasza aplikacja może tworzyć rozczarowanych użytkowników bez żadnych wyjątków kodu, na przykład, jeśli niektóre usługi oprogramowania pośredniego działają naprawdę wolno. Produkty APM mierzą wrażenia użytkownika end-to-end, na przykład, biorąc pod uwagę system, który obejmuje interfejs użytkownika frontend i wiele usług rozproszonych - niektóre produkty APM mogą powiedzieć, jak szybko trwa transakcja obejmująca wiele poziomów. Może stwierdzić, czy wrażenia użytkownika są solidne i wskazać problem. Ta atrakcyjna oferta ma stosunkowo wysoką cenę, dlatego jest zalecana do dużych i złożonych produktów, które wymagają wykraczania poza proste monitorowanie.
+
+
+
+### APM przykład - produkt komercyjny, który wizualizuje wydajność aplikacji między usługami
+
+
+
+
+
+### APM przykład - produkt komercyjny, który podkreśla ocenę doświadczenia użytkownika
+
+
+
+
+
+### APM przykład - produkt komercyjny, który wyróżnia wolne ścieżki kodu
+
+
diff --git a/sections/production/apmproducts.russian.md b/sections/production/apmproducts.russian.md
index 6dda2dc50..9c019723f 100644
--- a/sections/production/apmproducts.russian.md
+++ b/sections/production/apmproducts.russian.md
@@ -10,16 +10,16 @@ APM (мониторинг производительности приложен
### Пример APM - коммерческий продукт, который визуализирует производительность кросс-сервисного приложения
-
+
### Пример APM - коммерческий продукт, который подчеркивает оценку пользовательского опыта
-
+
### Пример APM - коммерческий продукт, который выделяет медленные пути кода
-
+
diff --git a/sections/production/assigntransactionid.basque.md b/sections/production/assigntransactionid.basque.md
new file mode 100644
index 000000000..01d89bcfd
--- /dev/null
+++ b/sections/production/assigntransactionid.basque.md
@@ -0,0 +1,39 @@
+# Esleitu transakzio identifikazio bana adierazpen erregistro bakoitzari
+
+
+
+### Azalpena
+
+Ohiko erregistroa osagai eta eskaera guztien sarreren biltegia da. Lerro edo errore susmagarriren bat atzeman ondoren, zaila izaten da fluxu bereko beste lerro batzuekin bat etortzea (adibidez, "John" erabiltzailea zerbait erosten saiatu zen). Hori are kritikoagoa eta zailagoa bihurtzen da mikrozerbitzu ingurune batean eskaera/transakzio bat ordenagailu askotan zehar sor daitekeenean. Esleitu eskaera bateko sarrera guztiei transakzio identifikatzaile balio bakarra, eta, horrela, lerro bat atzematean, IDa/identifikazioa kopiatu eta antzeko transakzio IDa/identifikazioa duen lerro bakoitza bilatu ahal izango da eta. Hala ere, In Node hori lortzea ez da erraza, hari bakarra erabiltzen baita eskaera guztiei erantzuteko. Aztertu ez ote zaizun komeni liburutegi bat erabiltzea datuak bil ditzakeena eskaera mailan. Ikusi hurrengo diapositibako kode adibidea. Beste mikrozerbitzu batzuk deitzean, igorri transakzioaren IDa "x-transaction-id" bezalako HTTP goiburua erabiliz testuinguru bera mantentzeko.
+
+
+
+### Kode adibidea: Express konfigurazio tipikoa
+
+```javascript
+// eskaera berria jasotzean, kontextu isolatu berria hasi eta transakzio identifikazioa ezarri. Hurrengo adibideak continuation-local-storage npm liburutegia erabiltzen du eskaerak isolatzeko
+
+const { createNamespace } = require("continuation-local-storage");
+const 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");
+});
+
+// Orain, beste edozein zerbitzu edo osagarrik kotextuko datuak eskura ditzake
+class someService {
+ getById(id) {
+ logger.info("Starting to get something by id");
+ // beste logika hemen dator
+ }
+}
+
+// Erregistroak transakzio identifikazioa gehi diezaieke sarrera bakoitzari, horrela eskaera bereko sarrerek balio bera edukiko dute
+class logger {
+ info(message) {
+ console.log(`${message} ${session.get("transactionId")}`);
+ }
+}
+```
diff --git a/sections/production/assigntransactionid.french.md b/sections/production/assigntransactionid.french.md
new file mode 100644
index 000000000..49339bed4
--- /dev/null
+++ b/sections/production/assigntransactionid.french.md
@@ -0,0 +1,198 @@
+# Attribuez un ‘TransactionId’ à chaque relevé du journal
+
+
+
+### Un paragraphe d'explication
+
+Un journal typique est un registre des entrées de tous les composants et requêtes. Lorsqu'une ligne ou une erreur suspecte est détectée, il devient difficile de faire correspondre d'autres lignes appartenant au même flux spécifique (par exemple, l'utilisateur "John" a essayé d'acheter quelque chose). Cela devient encore plus critique et difficile dans un environnement de micro-services lorsqu'une requête/transaction peut concerner plusieurs ordinateurs. Il convient de remédier à ce problème en attribuant une valeur d'identification de transaction unique à toutes les entrées d'une même requête, de sorte qu'en détectant une ligne, on puisse copier l'identifiant et rechercher toutes les lignes qui ont un identifiant de transaction similaire. Toutefois, la réalisation de cette opération dans Node n'est pas simple, car un seul processus est utilisé pour toutes les requêtes - envisagez d'utiliser une bibliothèque qui peut regrouper les données au niveau de la requête - voir l'exemple de code suivant. Lorsque vous appelez d'autres micro-services, transmettez l'identifiant de la transaction en utilisant une entête HTTP comme "x-transaction-id" pour conserver le même contexte.
+
+
+
+### Exemple de code : partage de TransactionId entre les fonctions de requête et entre les services à l'aide de [async-local-storage](https://nodejs.org/api/async_hooks.html#async_hooks_class_asynclocalstorage)
+
+ **Qu'est ce que async-local-storage ?** Vous pouvez le considérer comme l'alternative de Node pour le stockage local des threads.
+ Il s'agit essentiellement d'un stockage pour les flux asynchrones dans Node. Vous pouvez en savoir plus [ici](https://www.freecodecamp.org/news/async-local-storage-nodejs/).
+
+```javascript
+const express = require('express');
+const { AsyncLocalStorage } = require('async_hooks');
+const uuid = require('uuid/v4');
+
+const asyncLocalStorage = new AsyncLocalStorage();
+
+// Définit le TransactionId des requêtes entrantes
+const transactionIdMiddleware = (req, res, next) => {
+ // Le premier argument de asyncLocalStorage.run est l'initialisation de l'état du stockage, le second argument est la fonction qui a accès à ce stockage
+ asyncLocalStorage.run(new Map(), () => {
+ // Essaye d'extraire le TransactionId de l'entête de la requête, ou en génére un nouveau s'il n'existe pas
+ const transactionId = req.headers['transactionId'] || uuid();
+
+ // Définit le TransactionId à l'intérieur du stockage
+ asyncLocalStorage.getStore().set('transactionId', transactionId);
+
+ // En appelant next() dans la fonction, nous nous assurons que tous les autres middlewares fonctionnent dans le même contexte AsyncLocalStorage
+ next();
+ });
+};
+
+const app = express();
+app.use(transactionIdMiddleware);
+
+// Définit le TransactionId des requêtes sortantes
+app.get('/', (req, res) => {
+ // Une fois que TransactionId a été initialisé dans le middleware, il est accessible à tout moment pour le flux de requêtes.
+ const transactionId = asyncLocalStorage.getStore().get('transactionId');
+
+ try {
+ // Ajoute TransactionId comme entête afin de le passer au service suivant
+ const response = await axios.get('https://externalService.com/api/getAllUsers', headers: {
+ 'x-transaction-id': transactionId
+ });
+ } catch (err) {
+ // L'erreur est transmise au middleware, et il n'est pas nécessaire d'envoyer le TransactionId
+ next(err);
+ }
+
+ logger.info('externalService a été appelé avec succès avec l\'entête TransactionId');
+
+ res.send('OK');
+});
+
+// Un middleware de gestion des erreurs appelle le journal
+app.use(async (err, req, res, next) => {
+ await logger.error(err);
+});
+
+// Le journal peut désormais ajouter le TransactionId à chaque entrée, de sorte que les entrées d'une même requête aient la même valeur
+class logger {
+ error(err) {
+ console.error(`${err} ${asyncLocalStorage.getStore().get('transactionId')}`);
+ }
+
+ info(message) {
+ console.log(`${message} ${asyncLocalStorage.getStore().get('transactionId')}`);
+ }
+}
+```
+
+
+
+Exemple de code : utilisation d'une bibliothèque pour simplifier la syntaxe
+
+Partage du TransactionId entre les fonctions de requête actuelles en utilisant [cls-rtracer](https://www.npmjs.com/package/cls-rtracer) (une bibliothèque basée sur async-local-storage, implémentée pour les middlewares Express & Koa et les plugins Fastify & Hapi)
+
+```javascript
+const express = require('express');
+const rTracer = require('cls-rtracer');
+
+const app = express();
+
+app.use(rTracer.expressMiddleware());
+
+app.get('/getUserData/{id}', async (req, res, next) => {
+ try {
+ const user = await usersRepo.find(req.params.id);
+
+ // Le TransactionId est accessible de l'intérieur du journal, il n'est pas nécessaire de l'envoyer
+ logger.info(`les données de l'utilisateur ${user.id} ont été récupérées avec succès`);
+
+ res.json(user);
+ } catch (err) {
+ // L'erreur est transmise au middleware
+ next(err);
+ }
+})
+
+// Un middleware de gestion des erreurs appelle le journal
+app.use(async (err, req, res, next) => {
+ await logger.error(err);
+});
+
+// Le journal peut désormais ajouter le TransactionId à chaque entrée, de sorte que les entrées d'une même requête aient la même valeur
+class logger {
+ error(err) {
+ console.error(`${err} ${rTracer.id()}`);
+ }
+
+ info(message) {
+ console.log(`${message} ${rTracer.id()}`);
+ }
+}
+```
+
+
+Partage le TransactionId entre les micro services
+
+```javascript
+// cls-tracer a la capacité de stocker le TransactionId sur les entêtes des requêtes sortantes de votre service, et d'extraire le TransactionId des entêtes des requêtes entrantes, en remplaçant simplement la configuration par défaut du middleware
+app.use(rTracer.expressMiddleware({
+ // Ajoute le TransactionId à l'entête
+ echoHeader: true,
+ // Respecte le TransactionId de l'entête
+ useHeader: true,
+ // Nom de l'entête TransactionId
+ headerName: 'x-transaction-id'
+}));
+
+const axios = require('axios');
+
+// Maintenant, le service extérieur obtiendra automatiquement le TransactionId actuel comme entête
+const response = await axios.get('https://externalService.com/api/getAllUsers');
+```
+
+
+
+**REMARQUE : l'utilisation de async-local-storage est soumise à deux restrictions :**
+1. Il nécessite Node v.14.
+2. Il est basé sur une construction de niveau inférieur dans Node appelé async_hooks qui est encore expérimental, donc vous pouvez craindre des problèmes de performance. Même s'ils existent, ils sont très négligeables, mais vous devriez faire vos propres choix.
+
+
+
+
+Exemple de code - configuration Express typique sans dépendance de async-local-storage
+
+```javascript
+// à la réception d'une nouvelle requête, commencez un nouveau contexte isolé et définissez un identifiant de transaction. L'exemple suivant utilise la bibliothèque npm continuation-local-storage pour isoler les requêtes
+
+const { createNamespace } = require('continuation-local-storage');
+const session = createNamespace('my session');
+
+router.get('/:id', (req, res, next) => {
+ session.set('transactionId', 'un GUID unique');
+ someService.getById(req.params.id);
+ logger.info('Début de l\'identification');
+});
+
+// Désormais, tout autre service ou composant peut avoir accès aux données contextuelles par requête
+class someService {
+ getById(id) {
+ logger.info('Début de l\'identification');
+ // une autre logique vient ici
+ }
+}
+
+// Le journal peut désormais ajouter l'identifiant de la transaction à chaque entrée, de sorte que les entrées d'une même requête aient la même valeur
+class logger {
+ info (message) {
+ console.log(`${message} ${session.get('transactionId')}`);
+ }
+}
+```
+
+
+
+
+### Bon : Journaux avec un TransactionId attribué - peut être utilisé comme filtre pour ne voir qu'un seul flux
+
+
+
+### Mauvais : journaux sans TransactionId - pas de possibilité d'utiliser un filtre et de ne voir qu'un seul flux, vous devez comprendre par vous-même quels journaux sont pertinents entre tous les « bruits » environnants
+
+
+
+
+### Citation de blog : « La notion d'ID de corrélation est simple. C'est une valeur qui est commune à toutes les requêtes, messages et réponses dans une transaction donnée. Avec cette simplification, vous obtenez beaucoup de pouvoir ».
+
+Extrait de [rapid7](https://blog.rapid7.com/2016/12/23/the-value-of-correlation-ids/)
+
+> Dans le passé, lorsque le comportement transactionnel se déroulait dans un seul domaine, dans le cadre de procédures par étapes, le suivi du comportement des requêtes et des réponses était une tâche simple. Cependant, aujourd'hui, une requête vers un domaine particulier peut impliquer une myriade de requêtes asynchrones ultérieures du domaine de départ vers d'autres domaines. Par exemple, vous envoyez une requête à Expedia, mais en coulisse, Expedia transmet votre requête sous forme de message à un gestionnaire de messages. Ce message est ensuite consommé par un hôtel, une compagnie aérienne et une agence de location de voitures qui répondent également de manière asynchrone. La question se pose donc, alors que votre seule requête est transmise à une multitude de consommateurs en cours de traitement, comment pouvons-nous suivre la transaction ? La réponse est : utiliser un identifiant de corrélation.
\ No newline at end of file
diff --git a/sections/production/assigntransactionid.japanese.md b/sections/production/assigntransactionid.japanese.md
new file mode 100644
index 000000000..8aa6113a9
--- /dev/null
+++ b/sections/production/assigntransactionid.japanese.md
@@ -0,0 +1,39 @@
+# 各ログ文に 'TransactionId' を割り当てる
+
+
+
+### 一段落説明
+
+典型的なログは、すべてのコンポーネントとリクエストからのエントリーの倉庫です。不審なラインやエラーが検出されると、同じ特定のフローに属する他のラインをマッチさせるのが面倒になります(例えば、ユーザの ”John” が何かを買おうとしたなど)。これは、リクエスト/トランザクションが複数のコンピュータにまたがる可能性がある場合、マイクロサービスの環境ではさらに重要で困難になります。これに対処するには、同じリクエストからのすべてのエントリに一意のトランザクション識別子の値を割り当てることで、1つの行を検出するときに、 ID をコピーして、類似のトランザクション ID を持つすべての行を検索できるようにします。しかし、1つのスレッドがすべてのリクエストを処理するために使用されるので、これを実現するためには Node では簡単ではありません - リクエストレベルでデータをグループ化できるライブラリを使用することを考えてください – 次のスライドのコード例を参照してください。他のマイクロサービスを呼び出す際には、同じコンテキストを保つために、”x-transaction-id” のような HTTP ヘッダを使ってトランザクション ID を渡してください。
+
+
+
+### コード例: 典型的な Express の設定
+
+```javascript
+// 新しいリクエストを受信したときに、新しい独立したコンテキストを開始し、トランザクション ID を設定します。次の例は、npm ライブラリ continuation-local-storage を使用してリクエストを分離しています。
+
+const { createNamespace } = require('continuation-local-storage');
+const 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 to get something by id');
+ // other logic comes here
+ }
+}
+
+// ロガーは、同じリクエストからのエントリが同じ値を持つように、各エントリにトランザクション ID を追加することができるようになりました。
+class logger {
+ info (message) {
+ console.log(`${message} ${session.get('transactionId')}`);
+ }
+}
+```
diff --git a/sections/production/assigntransactionid.md b/sections/production/assigntransactionid.md
index 15eaaa1b8..0130d65ab 100644
--- a/sections/production/assigntransactionid.md
+++ b/sections/production/assigntransactionid.md
@@ -4,14 +4,155 @@
### 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.
+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 microservices, pass the transaction id using an HTTP header like “x-transaction-id” to keep the same context.
-
+
+
+### Code example: sharing TransactionId among request functions and between services using [async-local-storage](https://nodejs.org/api/async_hooks.html#async_hooks_class_asynclocalstorage)
+
+ **What is async-local-storage?** You can think of it as the Node alternative to thread local storage.
+ It is basically a storage for asynchronous flows in Node. You can read more about it [here](https://www.freecodecamp.org/news/async-local-storage-nodejs/).
+
+```javascript
+const express = require('express');
+const { AsyncLocalStorage } = require('async_hooks');
+const uuid = require('uuid/v4');
+
+const asyncLocalStorage = new AsyncLocalStorage();
+
+// Set incoming requests TransactionId
+const transactionIdMiddleware = (req, res, next) => {
+ // The first asyncLocalStorage.run argument is the initialization of the store state, the second argument is the function that has access to that store
+ asyncLocalStorage.run(new Map(), () => {
+ // Try to extract the TransactionId from the request header, or generate a new one if it doesn't exist
+ const transactionId = req.headers['transactionId'] || uuid();
+
+ // Set the TransactionId inside the store
+ asyncLocalStorage.getStore().set('transactionId', transactionId);
+
+ // By calling next() inside the function, we make sure all other middlewares run within the same AsyncLocalStorage context
+ next();
+ });
+};
+
+const app = express();
+app.use(transactionIdMiddleware);
+
+// Set outgoing requests TransactionId
+app.get('/', (req, res) => {
+ // Once TransactionId has been initialized inside the middleware, it's accessible at any point of the request flow
+ const transactionId = asyncLocalStorage.getStore().get('transactionId');
+
+ try {
+ // Add TransactionId as header in order to pass it to the next service
+ const response = await axios.get('https://externalService.com/api/getAllUsers', headers: {
+ 'x-transaction-id': transactionId
+ });
+ } catch (err) {
+ // The error is being passed to the middleware, and there's no need to send over the TransactionId
+ next(err);
+ }
+
+ logger.info('externalService was successfully called with TransactionId header');
+
+ res.send('OK');
+});
+
+// Error handling middleware calls the logger
+app.use(async (err, req, res, next) => {
+ await logger.error(err);
+});
+
+// The logger can now append the TransactionId to each entry so that entries from the same request will have the same value
+class logger {
+ error(err) {
+ console.error(`${err} ${asyncLocalStorage.getStore().get('transactionId')}`);
+ }
+
+ info(message) {
+ console.log(`${message} ${asyncLocalStorage.getStore().get('transactionId')}`);
+ }
+}
+```
+
+
+
+Code example: Using helper library to simplify the syntax
+
+Sharing TransactionId among current request functions using [cls-rtracer](https://www.npmjs.com/package/cls-rtracer) (a library based on async-local-storage, implemented for Express & Koa middlewares and Fastify & Hapi plugins)
+
+```javascript
+const express = require('express');
+const rTracer = require('cls-rtracer');
+
+const app = express();
+
+app.use(rTracer.expressMiddleware());
-### Code example: typical Express configuration
+app.get('/getUserData/{id}', async (req, res, next) => {
+ try {
+ const user = await usersRepo.find(req.params.id);
+
+ // The TransactionId is reachable from inside the logger, there's no need to send it over
+ logger.info(`user ${user.id} data was fetched successfully`);
+
+ res.json(user);
+ } catch (err) {
+ // The error is being passed to the middleware
+ next(err);
+ }
+})
+
+// Error handling middleware calls the logger
+app.use(async (err, req, res, next) => {
+ await logger.error(err);
+});
+
+// The logger can now append the TransactionId to each entry so that entries from the same request will have the same value
+class logger {
+ error(err) {
+ console.error(`${err} ${rTracer.id()}`);
+ }
+
+ info(message) {
+ console.log(`${message} ${rTracer.id()}`);
+ }
+}
+```
+
+
+Sharing TransactionId among microservices
+
+```javascript
+// cls-tracer has the ability to store the TransactionId on your service outgoing requests headers, and extract the TransactionId from incoming requests headers, just by overriding the default middleware config
+app.use(rTracer.expressMiddleware({
+ // Add TransactionId to the header
+ echoHeader: true,
+ // Respect TransactionId from header
+ useHeader: true,
+ // TransactionId header name
+ headerName: 'x-transaction-id'
+}));
+
+const axios = require('axios');
+
+// Now, the external service will automaticlly get the current TransactionId as header
+const response = await axios.get('https://externalService.com/api/getAllUsers');
+```
+
+
+
+**NOTICE: there are two restrictions on using async-local-storage:**
+1. It requires Node v.14.
+2. It is based on a lower level construct in Node called async_hooks which is still experimental, so you may have the fear of performance problems. Even if they do exist, they are very negligible, but you should make your own considerations.
+
+
+
+
+Code example - typical Express configuration without async-local-storage dependence
```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
+// 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');
const session = createNamespace('my session');
@@ -19,21 +160,39 @@ const 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');
+ 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');
+ 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
+// 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')}`);
}
}
```
+
+
+
+
+### Good: Logs with an assigned TransactionId - can be used as filter to see only a single flow
+
+
+
+### Bad: logs without a TransactionId - no option to use a filter and see only a single flow, you need to understand by yourself which logs are relevant between all the "noise" around
+
+
+
+
+### Blog Quote: "The notion of a Correlation ID is simple. It’s a value that is common to all requests, messages and responses in a given transaction. With this simplicity you get a lot of power."
+
+From [rapid7](https://blog.rapid7.com/2016/12/23/the-value-of-correlation-ids/)
+
+> In the old days when transactional behavior happened in a single domain, in step-by-step procedures, keeping track of request/response behavior was a simple undertaking. However, today one request to a particular domain can involve a myriad of subsequent asynchronous requests from the starting domain to others. For example, you send a request to Expedia, but behind the scenes Expedia is forwarding your request as a message to a message broker. Then that message is consumed by a hotel, airline and car rental agency that responds asynchronously too. So the question comes up, with your one request being passed about to a multitude of processing consumers, how do we keep track of the transaction? The answer is: use a Correlation ID.
\ No newline at end of file
diff --git a/sections/production/assigntransactionid.polish.md b/sections/production/assigntransactionid.polish.md
new file mode 100644
index 000000000..866d3833a
--- /dev/null
+++ b/sections/production/assigntransactionid.polish.md
@@ -0,0 +1,39 @@
+# Przypisz ‘TransactionId’ do każdej instrukcji dziennika
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Typowy dziennik to magazyn wpisów ze wszystkich komponentów i żądań. Po wykryciu jakiejś podejrzanej linii lub błędu staje się pokręcony, aby dopasować inne linie należące do tego samego określonego przepływu (np. użytkownik „John” próbował coś kupić). Staje się to jeszcze bardziej krytyczne i trudne w środowisku mikrousług, gdy żądanie / transakcja może obejmować wiele komputerów. Należy rozwiązać ten problem, przypisując unikalną wartość identyfikatora transakcji do wszystkich wpisów z tego samego żądania, aby po wykryciu jednej linii można skopiować identyfikator i wyszukać każdą linię o podobnym identyfikatorze transakcji. Jednak osiągnięcie tego w Node nie jest proste, ponieważ pojedynczy wątek służy do obsługi wszystkich żądań - rozważ użycie biblioteki, która może grupować dane na poziomie żądań - patrz przykład kodu na następnym slajdzie. Podczas wywoływania innej mikrousługi przekaż identyfikator transakcji za pomocą nagłówka HTTP, takiego jak „x-transaction-id”, aby zachować ten sam kontekst.
+
+
+
+### Przykład kodu: typowa konfiguracja Express
+
+```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');
+const 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/assigntransactionid.russian.md b/sections/production/assigntransactionid.russian.md
index 6041dcfa1..9d5ee1670 100644
--- a/sections/production/assigntransactionid.russian.md
+++ b/sections/production/assigntransactionid.russian.md
@@ -14,7 +14,7 @@
// 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');
+const session = createNamespace('my session');
router.get('/:id', (req, res, next) => {
session.set('transactionId', 'some unique GUID');
@@ -25,14 +25,15 @@ router.get('/:id', (req, res, next) => {
// 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”);
+ 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')}`);}
+ info (message) {
+ console.log(`${message} ${session.get('transactionId')}`);
+ }
}
```
diff --git a/sections/production/bestateless.basque.md b/sections/production/bestateless.basque.md
new file mode 100644
index 000000000..7144118ab
--- /dev/null
+++ b/sections/production/bestateless.basque.md
@@ -0,0 +1,45 @@
+# Izan aberrigabea, hil zure zerbitzariak ia egunero
+
+
+
+### Azalpena
+
+Inoiz aurkitu duzu produkzio arazo larri bat, zerbitzari batek ezarpen edo datu batzuk falta zituela, adibidez? Baiezkotan, seguruenik, inplementazioaren parte ez den tokiko aktiboekiko menpekotasun ezbeharrezkoren batengatik izango zen. Produktu arrakastatsu askok Fenix hegaztiak balira bezala tratatzen dituzte zerbitzariak: behin eta berriro jaio eta hiltzen dira, inolako kalterik gabe. Beste modu batera esanda, zure kodea denbora batez exekutatzen duen hardwarea besterik ez da zerbitzaria, eta ondoren ordezkatua izan ohi da. Antolaketa horrek
+
+- eskalatzea ahalbidetzen du zerbitzariak dinamikoki gehituz eta kenduz albo efekturik gabe.
+- mantentze lanak errazten ditu askatzen baikaitu zerbitzari bakoitza ebaluatzetik.
+
+
+
+### Anti ereduaren kode adibideak
+
+```javascript
+// Akats arrunta 1: kargatutako fitxategiak zerbitzari batean era lokalean gordetzea
+const multer = require("multer"); // express middlewarea fitxategien kargak kudeatzeko
+const upload = multer({ dest: "uploads/" });
+
+app.post("/photos/upload", upload.array("photos", 12), (req, res, next) => {});
+
+// Akats arrunta 2: autentikazio sesioak fitxategi lokal batean edota memorian gordetzea
+const FileStore = require("session-file-store")(session);
+app.use(
+ session({
+ store: new FileStore(options),
+ secret: "keyboard cat",
+ })
+);
+
+// Akats arrunta 3: objektu globalean informazioa gordetzea
+Global.someCacheLike.result = { somedata };
+```
+
+
+
+### Beste blogari batzuek diotena
+
+[Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html)en bloga:
+
+> ...Egun batean eragiketetarako ziurtagiri zerbitzua martxan jartzeko fantasia izan nuen. Zertan zetzan ebaluazioa baina? Lankide bat eta biok korporazioko datu zentrora joan eta produkzio zerbitzari kritikoetan hasi behar genuen lanean beisbol makila, motozerra bat eta ur pistola bana esketan genuela. Eragiketen talde horrek aplikazio guztiak berriro martxan jartzeko zenbat denbora behar zuen, horixe zen ebaluatu beharrekoa. Alimaleko fantasia inozoa dirudien arren, badago jakinduria ttantta bat horretan.
+> Beisbol makilak erabiltzeari uko egin beharko bazenio ere, egokia litzateke zure zerbitzariak aldian behin erreko bazenitu. Zerbitzari batek fenix bat bezalakoa izan beharko luke, aldizka errautsetatik berpizten dena...
+
+
diff --git a/sections/production/bestateless.french.md b/sections/production/bestateless.french.md
new file mode 100644
index 000000000..7f114fa44
--- /dev/null
+++ b/sections/production/bestateless.french.md
@@ -0,0 +1,42 @@
+# Soyez sans état, tuez vos serveurs presque tous les jours
+
+
+
+### Un paragraphe d'explication
+
+Avez-vous déjà rencontré un grave problème en production où il manquait un élément de configuration ou une donnée sur un serveur ? Cela est probablement dû à une dépendance inutile avec une ressource locale qui ne fait pas partie du déploiement. De nombreux produits à succès traitent les serveurs comme un oiseau phénix - il meurt et renaît périodiquement sans aucun dommage. En d'autres termes, un serveur n'est qu'une pièce de matériel qui exécute votre code pendant un certain temps et qui est ensuite remplacé.
+Cette approche
+
+- permet une mise à l'échelle par l'ajout et la suppression dynamiques de serveurs sans aucun effet secondaire.
+- simplifie la maintenance car elle libère notre esprit de l'évaluation de l'état de chaque serveur.
+
+
+
+### Exemple de code incorrect
+
+```javascript
+// Erreur typique 1 : enregistrement des fichiers téléchargés localement sur un serveur
+const multer = require('multer'); // un middleware express pour gérer les téléchargements en plusieurs parties
+const upload = multer({ dest: 'uploads/' });
+
+app.post('/photos/upload', upload.array('photos', 12), (req, res, next) => {});
+
+// Erreur typique 2 : stockage des sessions d'authentification (passeport) dans un fichier ou une mémoire locale
+const FileStore = require('session-file-store')(session);
+app.use(session({
+ store: new FileStore(options),
+ secret: 'keyboard cat'
+}));
+
+// Erreur typique 3 : stockage d'informations sur l'objet global
+Global.someCacheLike.result = { somedata };
+```
+
+
+
+### Ce que disent les autres blogueurs
+
+Extrait du blog de [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html) :
+> ...Un jour, j'ai eu le délire de lancer un service de certification des exploitations. L'évaluation de la certification consisterait pour un collègue et moi à nous rendre au centre de données de l'entreprise et à nous occuper des serveurs de production critiques avec une batte de base-ball, une tronçonneuse et un pistolet à eau. L'évaluation serait basée sur le temps qu'il faudrait à l'équipe d'exploitation pour remettre toutes les applications en marche. C'est peut-être une idée folle, mais il y a là une pincée de bon sens. Bien que vous deviez renoncer aux battes de base-ball, il est bon de détruire virtuellement vos serveurs à intervalles réguliers. Un serveur doit être comme un phénix, renaissant régulièrement de ses cendres...
+
+
diff --git a/sections/production/bestateless.polish.md b/sections/production/bestateless.polish.md
new file mode 100644
index 000000000..38a77b136
--- /dev/null
+++ b/sections/production/bestateless.polish.md
@@ -0,0 +1,42 @@
+# Bądź stateless, zabijaj serwery prawie codziennie
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Czy kiedykolwiek napotkałeś poważny problem z produkcją, w którym na jednym serwerze brakowało jakiejś konfiguracji lub danych? Jest to prawdopodobnie spowodowane niepotrzebną zależnością od lokalnego zasobu, który nie jest częścią wdrożenia. Wiele udanych produktów traktuje serwery jak feniksa - umiera i odradza się okresowo bez żadnych uszkodzeń. Innymi słowy, serwer to tylko część sprzętu, która wykonuje twój kod przez pewien czas, a następnie jest wymieniana.
+To podejście
+
+- umożliwia skalowanie poprzez dynamiczne dodawanie i usuwanie serwerów bez żadnych skutków ubocznych.
+- upraszcza konserwację, ponieważ uwalnia nasz umysł od oceny każdego stanu serwera.
+
+
+
+### Przykład kodu: antywzorce
+
+```javascript
+// Typical mistake 1: saving uploaded files locally on a server
+const multer = require('multer'); // express middleware for handling multipart uploads
+const upload = multer({ dest: 'uploads/' });
+
+app.post('/photos/upload', upload.array('photos', 12), (req, res, next) => {});
+
+// Typical mistake 2: storing authentication sessions (passport) in a local file or memory
+const 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 };
+```
+
+
+
+### Co mówią inni blogerzy
+
+Z bloga [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/bestateless.russian.md b/sections/production/bestateless.russian.md
index 5d9303e0f..853bd4136 100644
--- a/sections/production/bestateless.russian.md
+++ b/sections/production/bestateless.russian.md
@@ -16,13 +16,13 @@
```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/' });
+const multer = require('multer'); // express middleware for handling multipart uploads
+const 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);
+const FileStore = require('session-file-store')(session);
app.use(session({
store: new FileStore(options),
secret: 'keyboard cat'
diff --git a/sections/production/createmaintenanceendpoint.basque.md b/sections/production/createmaintenanceendpoint.basque.md
new file mode 100644
index 000000000..1ca7f1556
--- /dev/null
+++ b/sections/production/createmaintenanceendpoint.basque.md
@@ -0,0 +1,48 @@
+# Sortu mantentze lanen amaiera puntua
+
+
+
+### Azalpena
+
+Mantentze lanen amaiera puntua oso HTTP API segurua da, aplikazioaren kodearen parte dena, eta bere helburua da operazioek edo ekoizpen taldeek mantentze funtzionalitatea kontrolatzeko eta erakusteko erabilia izatea. Adibidez, prozesuaren biltegiratzea (memoriaren argazkia) itzul dezake, memoria ihes batzuk dauden ala ez jakinarazi eta REPL komandoak zuzenean exekutatzeko baimena eman dezake. Amaiera hori beharrezkoa da ohiko DevOps tresnek (kontrolagailuak, erregistroak eta abar) ezin dutenean informazio mota zehatz bat bildu edo tresna horiek ez erostea edo ez instalatzea aukeratzen duzunean. Urrezko araua da produkzioa kontrolatzeko eta mantentzeko kanpoko tresna profesionalak erabiltzea, sendoagoak eta zehatzagoak izan ohi dira eta. Hori esanda, litekeena da tresna generikoek atera ezin izatea Noderen edo zure aplikazioren berariazko informaziorik. Adibidez, GC-k ziklo bat burutu duen momentuan memoriaren argazki bat sortu nahi baduzu, npm liburutegi gutxi egongo dira prest lan hori zuretzat egiteko, baina jarraipena egiteko tresna ezagunek funtzionaltasun hori galdu egingo dute. Garrantzitsua da amaiera puntu horren sarbidea mugatzea, administratzaileak soilik sartu ahal izateko, DDOS erasoen jomuga bihur baitaiteke.
+
+
+
+### Gomendatutako baliabideak
+
+[Zure Node.js aplikazioaren ekoizpena prestatzea (diapositibak)](http://naugtur.pl/pres3/node2prod)
+
+▶ [Zure Node.js aplikazioaren ekoizpena prestatzea (bideoa)](https://www.youtube.com/watch?v=lUsNne-_VIk)
+
+
diff --git a/sections/production/createmaintenanceendpoint.brazilian-portuguese.md b/sections/production/createmaintenanceendpoint.brazilian-portuguese.md
index 1b0a15bbf..7f93feef8 100644
--- a/sections/production/createmaintenanceendpoint.brazilian-portuguese.md
+++ b/sections/production/createmaintenanceendpoint.brazilian-portuguese.md
@@ -42,4 +42,4 @@ router.get('/ops/heapdump', (req, res, next) => {
▶ [Preparando sua aplicação Node.js para produção (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
-
+
diff --git a/sections/production/createmaintenanceendpoint.chinese.md b/sections/production/createmaintenanceendpoint.chinese.md
index 90f7f84a8..68ce7b5f9 100644
--- a/sections/production/createmaintenanceendpoint.chinese.md
+++ b/sections/production/createmaintenanceendpoint.chinese.md
@@ -34,4 +34,4 @@ router.get('/ops/headump', (req, res, next) => {
▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
-
+
diff --git a/sections/production/createmaintenanceendpoint.french.md b/sections/production/createmaintenanceendpoint.french.md
new file mode 100644
index 000000000..96bc5b42a
--- /dev/null
+++ b/sections/production/createmaintenanceendpoint.french.md
@@ -0,0 +1,45 @@
+# Créez un « point de terminaison de maintenance »
+
+
+
+### Un paragraphe d'explication
+
+Un point de terminaison de maintenance est une API HTTP hautement sécurisée qui fait partie du code de l'application et dont l'objectif est d'être utilisé par l'équipe d'exploitation/production pour surveiller et exposer les fonctionnalités de maintenance. Par exemple, il peut retourner un vidage de mémoire (instantané de la mémoire) du processus, signaler s'il y a des fuites de mémoire et même permettre d'exécuter directement des commandes REPL. Ce point de terminaison est nécessaire lorsque les outils DevOps classiques (produits de surveillance, journaux, etc.) ne parviennent pas à collecter un certain type d'informations spécifiques ou si vous choisissez de ne pas acheter/installer de tels outils. La règle d'or est d'utiliser des outils professionnels et externes pour le suivi et la maintenance de la production, ceux-ci sont généralement plus robustes et plus précis. Cela dit, il est probable que les outils génériques ne parviennent pas à extraire des informations spécifiques de Node ou de votre application - par exemple, si vous souhaitez générer un instantané de mémoire au moment où le GC (Garbage collection, NdT : [« Ramasse-miettes »](https://fr.wikipedia.org/wiki/Ramasse-miettes_(informatique))) a terminé un cycle - quelques bibliothèques npm se feront un plaisir de vous le faire, mais les outils de surveillance populaires manqueront probablement cette fonctionnalité. Il est important de garder ce point de terminaison privé et accessible uniquement par les administrateurs, car il peut devenir la cible d'une attaque DDOS.
+
+
+
+### Exemple de code : génération d'un vidage mémoire via du code
+
+```javascript
+const heapdump = require('heapdump');
+
+// Vérifie si la requête est autorisée
+function isAuthorized(req) {
+ // ...
+}
+
+router.get('/ops/heapdump', (req, res, next) => {
+ if (!isAuthorized(req)) {
+ return res.status(403).send('Vous n\'êtes pas autorisé !');
+ }
+
+ logger.info('À propos de la génération du vidage mémoire');
+
+ heapdump.writeSnapshot((err, filename) => {
+ console.log('le fichier heapdump est prêt à être envoyé au demandeur', filename);
+ fs.readFile(filename, 'utf-8', (err, data) => {
+ res.end(data);
+ });
+ });
+});
+```
+
+
+
+### Ressources recommandées
+
+[Préparez votre application Node.js pour la production (Slides)](http://naugtur.pl/pres3/node2prod)
+
+▶ [Préparez votre application Node.js pour la production (Vidéo)](https://www.youtube.com/watch?v=lUsNne-_VIk)
+
+
diff --git a/sections/production/createmaintenanceendpoint.japanese.md b/sections/production/createmaintenanceendpoint.japanese.md
new file mode 100644
index 000000000..0e54d9874
--- /dev/null
+++ b/sections/production/createmaintenanceendpoint.japanese.md
@@ -0,0 +1,45 @@
+# メンテナンスエンドポイントの作成
+
+
+
+### コード例: コードによるヒープダンプの生成
+
+```javascript
+const heapdump = require('heapdump');
+
+// リクエストが許可されているかどうかを確認する
+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);
+ });
+ });
+});
+```
+
+
+
+### 推奨リソース
+
+[Node.js アプリの制作準備 (スライド)](http://naugtur.pl/pres3/node2prod)
+
+▶ [Node.js アプリの制作準備 (ビデオ)](https://www.youtube.com/watch?v=lUsNne-_VIk)
+
+
diff --git a/sections/production/createmaintenanceendpoint.korean.md b/sections/production/createmaintenanceendpoint.korean.md
index 405ad5bc0..023f9ad80 100644
--- a/sections/production/createmaintenanceendpoint.korean.md
+++ b/sections/production/createmaintenanceendpoint.korean.md
@@ -42,4 +42,4 @@ router.get('/ops/heapdump', (req, res, next) => {
▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
-
+
diff --git a/sections/production/createmaintenanceendpoint.md b/sections/production/createmaintenanceendpoint.md
index 2db04a8b6..179958705 100644
--- a/sections/production/createmaintenanceendpoint.md
+++ b/sections/production/createmaintenanceendpoint.md
@@ -42,4 +42,4 @@ router.get('/ops/heapdump', (req, res, next) => {
▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)
-
+
diff --git a/sections/production/createmaintenanceendpoint.polish.md b/sections/production/createmaintenanceendpoint.polish.md
new file mode 100644
index 000000000..b2e643d0d
--- /dev/null
+++ b/sections/production/createmaintenanceendpoint.polish.md
@@ -0,0 +1,45 @@
+# Utwórz punkt końcowy konserwacji
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Punkt końcowy konserwacji to wysoce bezpieczny interfejs API HTTP, który jest częścią kodu aplikacji, a jego celem jest wykorzystanie go przez zespół operacyjny / produkcyjny do monitorowania i udostępniania funkcji konserwacji. Na przykład może zwrócić zrzut stosu (migawkę pamięci) procesu, zgłosić, czy występują wycieki pamięci, a nawet pozwolić na bezpośrednie wykonywanie poleceń REPL. Ten punkt końcowy jest potrzebny tam, gdzie konwencjonalne narzędzia DevOps (produkty do monitorowania, logi itp.) Nie zbierają niektórych określonych informacji lub nie kupujesz / nie instalujesz takich narzędzi. Złotą zasadą jest stosowanie profesjonalnych i zewnętrznych narzędzi do monitorowania i utrzymania produkcji, które są zwykle bardziej niezawodne i dokładne. To powiedziawszy, mogą wystąpić przypadki, w których ogólne narzędzia nie wyodrębnią informacji specyficznych dla Node lub aplikacji - na przykład, jeśli chcesz wygenerować migawkę pamięci w momencie, gdy GC zakończy cykl - kilka bibliotek npm chętnie to zrobi za Ciebie, ale popularne narzędzia do monitorowania prawdopodobnie nie będą miały tej funkcji. Ważne jest, aby zachować ten punkt końcowy jako prywatny i dostępny tylko dla administratorów, ponieważ może on stać się celem ataku DDOS.
+
+
+
+### Przykład kodu: generowanie zrzutu sterty za pomocą kodu
+
+```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);
+ });
+ });
+});
+```
+
+
+
+### Polecane źródła
+
+[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)
+
+
diff --git a/sections/production/createmaintenanceendpoint.russian.md b/sections/production/createmaintenanceendpoint.russian.md
index 729dd05a8..20754e555 100644
--- a/sections/production/createmaintenanceendpoint.russian.md
+++ b/sections/production/createmaintenanceendpoint.russian.md
@@ -27,7 +27,7 @@ router.get('/ops/heapdump', (req, res, next) => {
heapdump.writeSnapshot((err, filename) => {
console.log('heapdump file is ready to be sent to the caller', filename);
- fs.readFile(filename, "utf-8", (err, data) => {
+ fs.readFile(filename, 'utf-8', (err, data) => {
res.end(data);
});
});
@@ -42,4 +42,4 @@ router.get('/ops/heapdump', (req, res, next) => {
▶ [Подготовка вашего приложения Node.js к производственому запуску (видео)](https://www.youtube.com/watch?v=lUsNne-_VIk)
-
+
diff --git a/sections/production/delegatetoproxy.basque.md b/sections/production/delegatetoproxy.basque.md
new file mode 100644
index 000000000..e182d6be9
--- /dev/null
+++ b/sections/production/delegatetoproxy.basque.md
@@ -0,0 +1,52 @@
+# Delegatu ahal den guztia (adibidez, eduki estatikoa, gzip) alderantzizko proxy batean
+
+
+
+### Azalpena
+
+Oso tentagarria da cargo-cult Express-a kargatzea, eta haren middleware eskaintza aberatsa erabiltzea sarearekin zerikusia duten zereginetarako, hala nola, fitxategi estatikoak zerbitzatzea, gzip kodetzea, eskaerak murriztea, SSL amaierak, etab. Hori denbora alperrik galtzea da, zeren eta, azpiprozesu bakarrekoa izanik, PUZa denbora luzez edukiko baitu lanean (Gogoan izan Noderen exekuzio eredua optimizatuta dagoela zeregin laburretarako edo E / S zeregin asinkronizatuetarako). Egokiagoa da sareko zereginetan erabili ohi den tresnaren bat erabiltzea. Ezagunenak nginx eta HAproxy dira, hodeiko saltzaile handienek Node.jsren prozesuetan sarrerako karga arintzeko ere erabiltzen dituztenak.
+
+
+
+### Beste blogari batzuek diotena
+
+- [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications) bloga
+
+> …Oso erraza da tranpa honetan erortzea - Express bezalako pakete bat ikusten duzu eta pentsatzen duzu "Ikaragarria! Has gaitezen ". Ekin diozu kodetzeari eta nahi duzuna egiten duen aplikazioa duzu. Hori bikaina da eta, egia esan, ia-ia irabazia duzu borroka . Hala ere, gerra galduko duzu zure aplikazioa zerbitzari batera igotzen baduzu eta zure HTTP atakan entzuten baduzu. Izan ere, oso gauza erabakigarria ahaztu duzu: Node ez da web zerbitzaria. **Zure aplikaziora trafiko bolumen handia iristen hasi bezain laster, ohartuko zara gauzak gaizki hasten direla: konexioak erori egin dira, aktiboak zerbitzurik gabe daude edo, okerrenean, zure zerbitzariak huts egin du. Izan ere, egiten ari zarena da Noderi eskatzea bere gain har ditzala web zerbitzari zaildu batek oso ondo egiten dituen gauza korapilatsu guztiak. Zergatik asmatu gurpila?** > **Node eskaera bakarrerako da, irudi bakarrerako. Zure aplikazioak datu basea irakurtzea edo logika korapilatsua kudeatzea bezalako gauza garrantzitsuetarako erabil lezakeen memoria alperrik xahutzen ari da ez dagokion zereginetan. Zergatik alboratu zure eskaera erosotasunagatik?**
+
+- [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load) bloga
+
+> Express.jsk middleware konektatuen bidez fitxategi estatikoen kudeaketa integratua egiten duen arren, ez zenuke inoiz erabili beharko. **Nginx-ek askoz hobeto kudea ditzake fitxategi estatikoak eta ekidin dezake eduki ez dinamikoko eskaerek blokeatzea gure node prozesuak**…
diff --git a/sections/production/delegatetoproxy.french.md b/sections/production/delegatetoproxy.french.md
new file mode 100644
index 000000000..423ed8238
--- /dev/null
+++ b/sections/production/delegatetoproxy.french.md
@@ -0,0 +1,51 @@
+# Déléguez tout ce qui est possible (par exemple gzip, SSL) à un proxy inverse
+
+
+
+### Un paragraphe d'explication
+
+Il est très tentant de faire appel à cargo-cult d'Express et d'utiliser son riche middleware pour les tâches liées au réseau, comme le service de fichiers statiques, l'encodage gzip, les requêtes de restriction, la terminaison SSL, etc. C'est une perte de performance due à son modèle de processus unique qui gardera le CPU occupé pendant de longues périodes (Rappelez-vous, le modèle d'exécution de Node est optimisé pour des tâches courtes ou des tâches liées à des E/S asynchrones). Une meilleure approche est d'utiliser un outil qui maîtrise les tâches réseau - les plus populaires sont nginx et HAproxy qui sont également utilisés par les plus grands vendeurs du cloud pour alléger la charge entrante sur les processus node.js.
+
+
+
+### Exemple de configuration Nginx - Utilisation de nginx pour compresser les réponses du serveur
+
+```nginx
+# configure la compression gzip
+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;
+}
+
+# définition du serveur web
+server {
+ # configure le serveur avec ssl et des pages d'erreur
+ listen 80;
+ listen 443 ssl;
+ ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
+ error_page 502 /errors/502.html;
+
+ # gestion du contenu statique
+ 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;
+}
+```
+
+
+
+### Ce que disent les autres blogueurs
+
+* Extrait du blog de [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
+> …Il est très facile de tomber dans ce piège - Vous voyez un paquet comme Express et pensez « Génial ! Commençons » - vous codez et vous avez une application qui fait ce que vous voulez. C'est excellent et, pour être honnête, vous avez gagné beaucoup de bataille. Cependant, vous perdrez la guerre si vous téléchargez votre application sur un serveur et que vous la faites écouter sur votre port HTTP parce que vous avez oublié une chose très cruciale : Node n'est pas un serveur Web. **Aussitôt qu'un volume de trafic quelconque commence à toucher votre application, vous remarquerez que les choses commencent à mal tourner : les connexions sont interrompues, les ressources cessent d'être servis ou, au pire, votre serveur se plante. Ce que vous faites est d'essayer de faire en sorte que Node s'occupe de toutes les choses compliquées qu'un serveur web éprouvé fait très bien. Pourquoi réinventer la roue ?**
+> **C'est juste pour une requête ou une image et en gardant à l'esprit que cette mémoire peut être utilisée par votre application pour des choses plus importantes comme la lecture d'une base de données ou la manipulation d'une logique compliquée, pourquoi paralyser votre application pour des raisons de commodité ?**
+
+* Extrait du blog de [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load) :
+> Bien qu'express.js ait une gestion intégrée des fichiers statiques via un middleware de connexion, vous ne devez jamais l'utiliser. **Nginx peut faire un bien meilleur travail de gestion des fichiers statiques et peut empêcher les requêtes de contenu non dynamique de saturer nos processus de Node**…
diff --git a/sections/production/delegatetoproxy.japanese.md b/sections/production/delegatetoproxy.japanese.md
new file mode 100644
index 000000000..c660863e6
--- /dev/null
+++ b/sections/production/delegatetoproxy.japanese.md
@@ -0,0 +1,51 @@
+# 可能な限りのこと全て(静的コンテンツや gzip など)をリバースプロキシに委譲する
+
+
+
+### Wyjaśnienie jednym akapitem
+
+To bardzo kuszące dla kultowego Expressa i korzystania z bogatej oferty oprogramowania pośredniego do zadań związanych z siecią, takich jak serwowanie plików statycznych, kodowanie gzip, żądania ograniczania przepustowości, zakończenie SSL itp. Jest to zabójstwo wydajności ze względu na model jednowątkowy, który zachowa procesor zajęty przez długi czas (pamiętaj, że model wykonania węzła jest zoptymalizowany do krótkich zadań lub asynchronicznych zadań związanych z We / Wy). Lepszym rozwiązaniem jest użycie narzędzia, które specjalizuje się w zadaniach sieciowych - najbardziej popularne to nginx i HAproxy, które są również używane przez największych dostawców usług w chmurze, aby zmniejszyć obciążenie procesów procesowych Node.js.
+
+
+
+### Przykład konfiguracji Nginx - Użycie nginx do kompresji odpowiedzi serwera
+
+```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;
+}
+```
+
+
+
+### Co mówią inni blogerzy
+
+* Z bloga [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?**
+
+* Z bloga [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.basque.md b/sections/production/detectvulnerabilities.basque.md
new file mode 100644
index 000000000..c19b298df
--- /dev/null
+++ b/sections/production/detectvulnerabilities.basque.md
@@ -0,0 +1,19 @@
+# Erabili menpekotasunak automatikoki atzematen dituzten tresnak
+
+
+
+### Azalpena
+
+Noderen aplikazio modernoek hamarnaka eta batzuetan ehunaka menpekotasun dituzte. Erabiltzen dituzun menpekotasunen batek segurtasun ahultasun ezaguna badu, zure aplikazioa ere ahula da.
+Tresna hauek automatikoki egiaztatzen dituzte zure menpekotasunetako segurtasun ahultasunak:
+
+- [npm audit](https://docs.npmjs.com/cli/audit) - npm auditoria
+- [snyk](https://snyk.io/) - etengabe bilatu eta konpondu ahultasunak zure menpekotasunetan
+
+
+
+### Beste blogari batzuek diotena
+
+[StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) bloga:
+
+> ...Zure aplikazioaren menpekotasunak kudeatzeko erabiltzea indartsua eta erosoa da. Erabiltzen dituzun paketeek zure aplikazioan ere eragina izan dezaketen segurtasun ahultasun larriak izan ditzakete. Zure aplikazioaren segurtasuna zure menpekotasunen "esteka ahulena" bezain sendoa da. Zorionez, bi tresna lagungarri daude erabiltzen dituzun hirugarren paketeak ziurtatzeko erabil ditzakezunak: nsp eta requireSafe. Bi tresna horiek gauza bera egiten dute neurri handi batean. Beraz, biak erabiltzea gehiegizkoa izan badaiteke ere, "hobe seguru jokatzea, damutzea baino". Hitz horiek, segurtasunari dagokionez, zuzenak eta egokiak dira...
diff --git a/sections/production/detectvulnerabilities.french.md b/sections/production/detectvulnerabilities.french.md
new file mode 100644
index 000000000..5768a042d
--- /dev/null
+++ b/sections/production/detectvulnerabilities.french.md
@@ -0,0 +1,20 @@
+# Utilisez des outils qui détectent automatiquement les dépendances vulnérables
+
+
+
+### Un paragraphe d'explication
+
+Les applications modernes de Node ont des dizaines et parfois des centaines de dépendances. Si l'une des dépendances que
+vous utilisez présente une faille de sécurité connue, votre application est également vulnérable.
+Les outils suivants vérifient automatiquement les vulnérabilités de sécurité connues dans vos dépendances :
+
+- [npm audit](https://docs.npmjs.com/cli/audit) - audit de npm
+- [snyk](https://snyk.io/) - Trouve et corrige continuellement les vulnérabilités de vos dépendances
+
+
+
+### Ce que disent les autres blogueurs
+
+Extrait du blog de [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) :
+
+> ...L'utilisation pour gérer les dépendances de votre application est puissante et pratique. Mais les paquets que vous utilisez peuvent contenir des vulnérabilités de sécurité critiques qui pourraient également affecter votre application. La sécurité de votre application est uniquement assurée par le « maillon le plus faible » de vos dépendances. Heureusement, il existe deux outils utiles pour garantir la sécurité des paquets tiers que vous utilisez : nsp et requireSafe. Ces deux outils font en grande partie la même chose, donc les utiliser tous les deux peut être excessif, mais « mieux vaut prévenir que guérir » sont des mots à respecter en matière de sécurité...
diff --git a/sections/production/detectvulnerabilities.japanese.md b/sections/production/detectvulnerabilities.japanese.md
new file mode 100644
index 000000000..e019e5265
--- /dev/null
+++ b/sections/production/detectvulnerabilities.japanese.md
@@ -0,0 +1,19 @@
+# 脆弱な依存関係を自動的に検出するツールを使用する
+
+
+
+### 他のブロガーが言っていること
+
+ブログ [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) より:
+
+> ...アプリケーションの依存関係を管理するために使用することは、強力で便利です。しかし、使用しているパッケージには重要なセキュリティ上の脆弱性が含まれている可能性があり、アプリケーションにも影響を与える可能性があります。アプリのセキュリティは、依存関係の「最も弱いリンク」と同じくらい強力です。幸いなことに、使用するサードパーティ製パッケージのセキュリティを確保するために使用できる 2 つの便利なツールがあります: nsp と requireSafe です。この2つのツールは大体同じことをするので、両方を使うのはやりすぎかもしれませんが、セキュリティに関しては「後悔するよりも安全な方がいい」という言葉が生きてくるでしょう。...
diff --git a/sections/production/detectvulnerabilities.polish.md b/sections/production/detectvulnerabilities.polish.md
new file mode 100644
index 000000000..d089f91c3
--- /dev/null
+++ b/sections/production/detectvulnerabilities.polish.md
@@ -0,0 +1,20 @@
+# Użyj narzędzi, które automatycznie wykrywają podatne na zagrożenia zależności
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Nowoczesne aplikacje Node mają dziesiątki, a czasem setki zależności. Jeśli którakolwiek z zależności, z której korzystasz
+ma znaną lukę w zabezpieczeniach, Twoja aplikacja też.
+Następujące narzędzia automatycznie sprawdzają znane luki bezpieczeństwa w twoich zależnościach:
+
+- [npm audit](https://docs.npmjs.com/cli/audit) - npm audit
+- [snyk](https://snyk.io/) - Ciągle znajduj i usuwaj luki w swoich zależnościach
+
+
+
+### Co mówią inni blogerzy
+
+Z bloga [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/):
+
+> ...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: nsp 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.basque.md b/sections/production/frontendout.basque.md
new file mode 100644
index 000000000..6e3a69a83
--- /dev/null
+++ b/sections/production/frontendout.basque.md
@@ -0,0 +1,47 @@
+# Atera frontend modulu eko aktiboak Nodetik
+
+
+
+### Azalpena
+
+Web aplikazio klasiko batean backend-ak elementu grafikoak helarazten dizkio
+nabigatzaileari. Noderen munduan oso ohikoa da Express middleware estatikoa erabiltzea bezeroaren fitxategi estatikoak optimizatzeko. BAINA Node ez da web aplikazio tipikoa, fitxategi asko aldi berean hornitzeko optimizatuta ez dagoen hari bakarra erabiltzen baitu. Horren ordez, aztertu ez ote den hobe erabiltzea alderantzizko proxy bat (adibidez, nginx, HAProxy), hodeiko biltegiren bat edo CDN (adibidez, AWS S3, Azure Blob Storage, etab.), zeregin horretarako optimizazio asko erabiltzen dituen eta errendimendu askoz hobea lortzen duena. Adibidez, nginx bezalako middleware espezializatuak zuzeneko lotuneak dauzka fitxategi sistemaren eta sareko txartelaren artean, eta prozesu anitzeko antolaketa erabiltzen du eskaera anitzen arteko esku hartzea minimizatzeko.
+
+Hauetako bat izan daiteke zure irtenbide egokiena:
+
+1. Alderantzizko proxy bat erabiltzea: zure fitxategi estatikoak Node aplikazioaren ondoan kokatuko dira, eta Node aplikazioaren aurrean jartzen den proxy batek (adibidez, nginx) bideratuko ditu fitxategien karpeta estatikoari egindako eskaerak.
+ Horrela, zure Node aplikazioa arduratzen da fitxategi estatikoak hedatzeaz, baina ez zerbitzatzeaz. Zure frontden/interfazeko lankideari asko gustatuko zaio antolaketa hau, frontden/interfazeko eskaerak galarazten baititu.
+
+2. Hodeian biltegiratzea: zure fitxategi estatikoak EZ dira zure Node aplikazioaren edukiaren zati izango, eginkizun horretarako sortu diren AWS S3, Azure BlobStorage edo antzeko beste zerbitzu batzuetara igoko dira eta. Antolaketa hau erabiliz, zure Node aplikazioak ez du fitxategi estatikoak hedatzeko ardurarik izango, ezta horiek zerbitzatzeko ere; beraz, Node eta Frontenda/interfazea erabat banatuta egongo dira, edonola ere talde desberdinek kudeatuta baitaude.
+
+
+
+### Beste blogari batzuek diotena
+
+[StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/) bloga:
+
+> …Garapenean, [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) erabil dezakezu fitxategi estatikoak hornitzeko. Baina ez egin hori ekoizpenean, funtzio horrek fitxategi sistematik irakurtzen baitu fitxategi eskaera bakoitza; beraz, denbora asko beharko erantzuteko, eta aplikazioaren errendimendu orokorrari eragingo dio. Kontuan izan res.sendFile () ez dela sendfile sistemaren deiarekin inplementatzen, eta hori askoz ere eraginkorragoa izango litzateke. Horren ordez, erabili zerbitzu estatikoa duen middlewareren bat (edo baliokidea den zerbait), hau da, Express aplikazioetarako fitxategiak hornitzeko optimizatuta dagoen tresnaren bat. Aukera hobea da alderantzizko proxy bat erabiltzea fitxategi estatikoak hornitzeko. Informazio gehiago nahi baduzu, ikusi “Erabili alderantzizko proxy bat”…
+
+
diff --git a/sections/production/frontendout.french.md b/sections/production/frontendout.french.md
new file mode 100644
index 000000000..8de2da260
--- /dev/null
+++ b/sections/production/frontendout.french.md
@@ -0,0 +1,45 @@
+# Retirez vos ressources frontend de Node
+
+
+
+### Un paragraphe d'explication
+
+Dans une application web classique, le backend fournit le frontend/les graphiques au navigateur. Une approche très courante dans le monde de Node consiste à utiliser le middleware statique Express pour transmettre les fichiers statiques au client. MAIS - Node n'est pas une application web classique car il utilise un seul processus qui n'est pas optimisé pour servir plusieurs fichiers à la fois. Il faut plutôt envisager d'utiliser un proxy inverse (par exemple nginx, HAProxy), un stockage dans le cloud ou un CDN (par exemple, AWS S3, Azure Blob Storage, etc.) qui utilisent de nombreuses optimisations pour cette tâche et obtiennent un bien meilleur débit. Par exemple, un middleware spécialisé comme nginx comporte des hooks directs entre le système de fichiers et la carte réseau et utilise une approche multi-processus pour minimiser l'intervention parmi les multiples requêtes.
+
+Votre solution optimale pourrait prendre l'une des formes suivantes :
+
+1. En utilisant un proxy inverse - vos fichiers statiques seront situés juste à côté de votre application Node, seules les requêtes vers le dossier des fichiers statiques seront servies par un proxy qui se trouve devant votre application Node comme nginx. En utilisant cette approche, votre application Node est responsable du déploiement des fichiers statiques mais pas de leur distribution. Le responsable de votre application frontend aimera cette approche car elle permet d'éviter les requêtes d'origine croisée depuis le frontend.
+
+2. Stockage dans le cloud - vos fichiers statiques NE feront PAS partie du contenu de votre application Node, ils seront téléchargés vers des services comme AWS S3, Azure BlobStorage, ou d'autres services similaires qui sont conçus pour cette mission. En utilisant cette approche, votre application Node n'est pas responsable du déploiement des fichiers statiques ni de leur utilisation, d'où un dissociation complète entre Node et le Frontend qui est de toute façon géré par des équipes différentes.
+
+
+
+### Exemple de configuration : configuration typique de nginx pour servir des fichiers statiques
+
+```nginx
+# configuration de la compression gzip
+gzip on;
+keepalive 64;
+
+# définition du serveur web
+server {
+listen 80;
+listen 443 ssl;
+
+# gestion du contenu statique
+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;
+}
+```
+
+
+
+### Ce que disent les autres blogueurs
+
+Extrait du blog de [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
+
+>…En développement, vous pouvez utiliser [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) pour fournir des fichiers statiques. Mais ne le faites pas en production, car cette fonction doit lire dans le système de fichiers pour chaque requête de fichier, elle rencontrera donc une latence importante et affectera la performance globale de l'application. Remarquez que res.sendFile() n'est pas implémentée avec l'appel système sendfile, ce qui la rendrait bien plus efficace. Utilisez plutôt un middleware de type serveur statique (ou quelque chose d'équivalent), qui est optimisé pour servir des fichiers pour les applications Express. Une option encore meilleure est d'utiliser un proxy inverse pour servir des fichiers statiques; consultez Utiliser un proxy inverse pour plus d'informations…
+
+
diff --git a/sections/production/frontendout.polish.md b/sections/production/frontendout.polish.md
new file mode 100644
index 000000000..74b0b6311
--- /dev/null
+++ b/sections/production/frontendout.polish.md
@@ -0,0 +1,45 @@
+# Wyciągnij zasoby frontendu z Node'a
+
+
+
+### Wyjaśnienie jednym akapitem
+
+W klasycznej aplikacji internetowej backend obsługuje frontend / grafikę w przeglądarce, bardzo powszechnym podejściem w świecie Node jest użycie Express'owego oprogramowania pośredniego do usprawnienia plików statycznych w kliencie. ALE - Node nie jest typową aplikacją internetową, ponieważ wykorzystuje pojedynczy wątek, który nie jest zoptymalizowany do obsługi wielu plików jednocześnie. Zamiast tego rozważ użycie reverse-proxy (np. Nginx, HAProxy), magazynu w chmurze lub CDN (np. AWS S3, Azure Blob Storage itp.), który wykorzystuje wiele optymalizacji tego zadania i uzyskuje znacznie lepszą przepustowość. Na przykład specjalistyczne oprogramowanie pośrednie, takie jak nginx, zawiera bezpośrednie przechwytywanie między systemem plików a kartą sieciową i wykorzystuje podejście wielowątkowe, aby zminimalizować interwencję między wieloma żądaniami.
+
+Twoje optymalne rozwiązanie może mieć jedną z następujących postaci:
+
+1. Korzystanie z reverse-proxy - twoje pliki statyczne będą znajdować się tuż obok aplikacji Node, tylko żądania do folderu plików statycznych będą obsługiwane przez proxy, które znajduje się przed aplikacją Node, taką jak nginx. Dzięki takiemu podejściu aplikacja Node jest odpowiedzialna za wdrażanie plików statycznych, ale nie za ich obsługę. Twój kolega z interfejsu użytkownika pokocha to podejście, ponieważ zapobiega ono prośbom o pochodzenie z tego interfejsu.
+
+2. Przechowywanie w chmurze - pliki statyczne NIE będą częścią zawartości aplikacji Node, zostaną przesłane do usług takich jak AWS S3, Azure BlobStorage lub innych podobnych usług, które powstały w ramach tej misji. Korzystając z tego podejścia, twoja aplikacja Node nie jest odpowiedzialna za wdrażanie plików statycznych ani ich obsługę, dlatego następuje całkowite rozdzielenie pomiędzy Node i Frontendem, które i tak jest obsługiwane przez różne zespoły.
+
+
+
+### Co mówią inni blogerzy
+
+Z bloga [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.basque.md b/sections/production/guardprocess.basque.md
new file mode 100644
index 000000000..3b82b5f34
--- /dev/null
+++ b/sections/production/guardprocess.basque.md
@@ -0,0 +1,19 @@
+# Babestu eta berrabiarazi zure prozesua huts egitean (tresna egokiak erabiliz)
+
+
+
+### Azalpena
+
+Oinarrizko mailan, Node prozesuak babestu eta berrabiarazi behar dira hutsegiteak gertatzen direnean. Hitz gutxitan, aplikazio txikientzat eta edukiontzirik erabiltzen ez dutenentzat, [PM2](https://www.npmjs.com/package/pm2-docker) bezalako tresnak ezin hobeak dira sinpletasuna, berrabiarazteko gaitasunak eta Noderekin integrazio aberatsa ere eskaintzen baitute. Linuxekin ondo moldatzen direnek systemd erabil dezakete eta Node zerbitzu gisa exekutatu. Askoz errazagoa da Docker edo edozein edukiontzi teknologia erabiltzen duten aplikazioen egoera, izan ere, eskuarki klusterrak antolatu eta kudeatzeko tresnak izaten dituzte (adibidez, [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/), etab.), edukiontziak inplementatu, kontrolatu eta konpontzen dituztenak. Klusterrak kudeatzeko tresna baliagarri horiek guztiak edukita (edukiontziak berrabiaraztekoak barne), zergatik korapilatu PM2 bezalako beste tresna batzuekin? Ez dago erabateko irtenbiderik eskaintzen duen erantzunik. Badira pisuzko arrazoiak PM2 edukiontzien barruan mantentzeko lehen mailako babesgarri gisa (batez ere bere [pm2-docker](https://www.npmjs.com/package/pm2-docker) bertsioa, berariaz edukiontzientzat prestatua): askoz ere bizkorragoa da prozesua berrabiaraztea, eta Noderen ezaugarri zehatzak eskaintzea, hala nola, kodea markatzea, ostatatzeko edukiontziak hala eskatzen duenean. Beste batzuek beharrezkoak ez diren geruzak ekiditea aukeratu dezakete. Amaitzeko, ez dago guztientzako moduko irtenbiderik, eta garrantzitsuena da zer aukera dauden jakitea.
+
+
+
+### Beste blogari batzuek diotena
+
+- [Express Produkzioaren Praktika Onak](https://expressjs.com/en/advanced/best-practice-performance.html): bloga:
+
+> ... Garapenean, zure aplikazioa komando lerrotik hasi zenuen node server.js edo antzeko zerbait erabiliz. **Baina hori bera ekoizpenean egitea hondamendiaren errezeta da. Aplikazioak huts egiten badu, lineaz kanpo egongo da** berrabiarazi arte. Aplikazioak huts egiten badu berrabiarazten dela ziurtatzeko, erabili prozesu kudeatzailea. Prozesuen kudeatzailea inplementazioa errazten duen, erabilgarritasun handia eskaintzen duen eta aplikazioa exekuzio garaian kudeatzeko aukera ematen duen "edukiontzia" da.
+
+- Medium blogeko [Noderen klusterrak ulertzea](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3) artikulua:
+
+> ... Oso garrantzitsua da Node.js Clustering Docker-Land ulertzea. “Docker edukiontziak ingurune birtual arinak eta errazak dira, prozesuak ahalik eta gehien sinplifikatzeko diseinatuak. Baliabide propioak kudeatu eta koordinatzen dituzten prozesuak jada ez dira hain baliotsuak. **Gaur egun, ordea, Kubernetes, Mesos eta Cattle bezalako kudeaketa pilek aldarrikatzen dute baliabide horiek guztiak azpiegitura osoan kudeatu behar direla**. "Antolatzaileek" esleitzen dituzte PUZeko eta memoriako baliabideak; eta sareko baliabideak, pilak emandako karga orekatzaileek.
diff --git a/sections/production/guardprocess.brazilian-portuguese.md b/sections/production/guardprocess.brazilian-portuguese.md
index 3a71f0207..894edc2b6 100644
--- a/sections/production/guardprocess.brazilian-portuguese.md
+++ b/sections/production/guardprocess.brazilian-portuguese.md
@@ -4,7 +4,7 @@
### Explicação em um Parágrafo
-No nível base, os processos do Node devem ser protegidos e reiniciados após falhas. Simplificando, para aplicativos pequenos e para aqueles que não usam contêineres - ferramentas como [PM2](https://www.npmjs.com/package/pm2-docker) são perfeitas, pois trazem simplicidade, reiniciando recursos e também uma rica integração com o Node. Outros com fortes habilidades em Linux podem usar o systemd e executar o Node como um serviço. As coisas ficam mais interessantes para aplicativos que usam o Docker ou qualquer outra tecnologia de contêineres, pois geralmente são acompanhados por ferramentas de gerenciamento e orquestração de clusters (por exemplo, [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome) .html), [Kubernetes](https://kubernetes.io/), etc) que implantam, monitoram e curam contêineres. Com todos esses recursos avançados de gerenciamento de cluster, incluindo reinício do contêiner, por que mexer com outras ferramentas como o PM2? Não há resposta à prova de balas. Há boas razões para manter o PM2 dentro de contêineres (principalmente a versão específica de contêineres [pm2-docker](https://www.npmjs.com/package/pm2-docker)) como o primeiro nível de proteção - é muito mais rápido reiniciar um processe e fornecer recursos específicos do Node, como sinalizar ao código quando o contêiner de hospedagem solicitar a reinicialização normal. Outros podem optar por evitar camadas desnecessárias. Para concluir este artigo, nenhuma solução serve para todos eles e conhecer as opções é o mais importante.
+No nível base, os processos do Node devem ser protegidos e reiniciados após falhas. Simplificando, para aplicativos pequenos e para aqueles que não usam contêineres - ferramentas como [PM2](https://www.npmjs.com/package/pm2-docker) são perfeitas, pois trazem simplicidade, reiniciando recursos e também uma rica integração com o Node. Outros com fortes habilidades em Linux podem usar o systemd e executar o Node como um serviço. As coisas ficam mais interessantes para aplicativos que usam o Docker ou qualquer outra tecnologia de contêineres, pois geralmente são acompanhados por ferramentas de gerenciamento e orquestração de clusters (por exemplo, [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome)), [Kubernetes](https://kubernetes.io/), etc) que implantam, monitoram e curam contêineres. Com todos esses recursos avançados de gerenciamento de cluster, incluindo reinício do contêiner, por que mexer com outras ferramentas como o PM2? Não há resposta à prova de balas. Há boas razões para manter o PM2 dentro de contêineres (principalmente a versão específica de contêineres [pm2-docker](https://www.npmjs.com/package/pm2-docker)) como o primeiro nível de proteção - é muito mais rápido reiniciar um processe e fornecer recursos específicos do Node, como sinalizar ao código quando o contêiner de hospedagem solicitar a reinicialização normal. Outros podem optar por evitar camadas desnecessárias. Para concluir este artigo, nenhuma solução serve para todos eles e conhecer as opções é o mais importante.
diff --git a/sections/production/guardprocess.french.md b/sections/production/guardprocess.french.md
new file mode 100644
index 000000000..c508a4d36
--- /dev/null
+++ b/sections/production/guardprocess.french.md
@@ -0,0 +1,17 @@
+# Protégez et redémarrez votre processus en cas d'échec (en utilisant le bon outil)
+
+
+
+### Un paragraphe d'explication
+
+A la base, les processus de Node doivent être protégés et redémarrés en cas de défaillance. Autrement dit, pour les petites applications et celles qui n'utilisent pas de conteneurs - des outils comme [PM2](https://www.npmjs.com/package/pm2-docker) sont parfaits car ils apportent la simplicité, des capacités de redémarrage et également une intégration riche avec Node. D'autres personnes avec de solides compétences Linux peuvent utiliser systemd et exécuter Node en tant que service. Les choses deviennent plus intéressantes pour les applications qui utilisent Docker ou n'importe quelle technologie de conteneur, car ils sont généralement accompagnées d'outils de gestion et d'orchestration de cluster (par exemple [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/), etc.) qui déploient, surveillent et réparent les conteneurs. Avec toutes ces fonctionnalités riches de gestion de cluster, y compris le redémarrage des conteneurs, pourquoi jouer avec d'autres outils comme PM2 ? Il n'y a pas de réponse à toute épreuve. Il existe de bonnes raisons de conserver PM2 dans les conteneurs (principalement sa version spécifique aux conteneurs [pm2-docker](https://www.npmjs.com/package/pm2-docker)) comme premier niveau de protection - il est beaucoup plus rapide de redémarrer un processus et de fournir des fonctionnalités spécifiques de Node comme le marquage du code lorsque le conteneur d'hébergement demande de redémarrer correctement. D'autres pourraient choisir d'éviter les couches inutiles. Pour conclure cet article, aucune solution ne conviendra à tous et l'important est de connaître les options.
+
+
+
+### Ce que disent les autres blogueurs
+
+* Extrait des [Bonnes pratiques d'Express en production](https://expressjs.com/en/advanced/best-practice-performance.html) :
+> ... Lors du développement, vous avez démarré votre application simplement à partir de la ligne de commande avec server.js de Node ou quelque chose de similaire. **Mais faire cela en production est une recette catastrophique. Si l'application se bloque, elle sera hors ligne** jusqu'à ce que vous la redémarriez. Pour vous assurer que votre application redémarre en cas de panne, utilisez un gestionnaire de processus. Un gestionnaire de processus est un « conteneur » pour les applications qui facilite le déploiement, offre une haute disponibilité et vous permet de gérer l'application au moment de l'exécution.
+
+* Extrait du blog Medium [Comprendre le clustering de Node](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3) :
+> ... Comprendre le clustering de Node.js dans Docker-Land : « Les conteneurs Docker sont des environnements virtuels légers et rationalisés, conçus pour simplifier les processus au strict minimum. Les processus qui gèrent et coordonnent leurs propres ressources n'ont plus la même valeur. **Au lieu de cela, les couches de gestion comme Kubernetes, Mesos et Cattle ont popularisé le concept selon lequel ces ressources devraient être gérées au niveau de l'infrastructure**. Les ressources CPU et mémoire sont allouées par des « planificateurs » et les ressources réseau sont gérées par des équilibreurs de charge (NdT, « load balancers ») fournis par la couche.
diff --git a/sections/production/guardprocess.japanese.md b/sections/production/guardprocess.japanese.md
new file mode 100644
index 000000000..fabeece47
--- /dev/null
+++ b/sections/production/guardprocess.japanese.md
@@ -0,0 +1,17 @@
+# 障害が発生した場合は、プロセスを保護して再起動します(適切なツールを使用します)
+
+
+
+### 他のブロガーが言っていること
+
+* [Express Production Best Practices(Express プロダクションのベストプラクティス)](https://expressjs.com/en/advanced/best-practice-performance.html) より:
+> ...開発では、node server.js などを使ってコマンドラインからアプリを起動するだけでした。**しかし、本番でこれを行うことは災いのもとです。アプリがクラッシュした場合、オフラインになってしまうでしょう。** 再起動するまで。 アプリがクラッシュした場合に確実に再起動するには、プロセスマネージャを使用します。プロセスマネージャは、デプロイを容易にし、高可用性を提供し、実行時にアプリケーションを管理できるようにするアプリケーションのための「コンテナ」です。
+
+* Medium のブログポスト [Understanding Node Clustering(Node クラスタリングを理解する)](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3) より:
+> ...Docker-Land で Node.js クラスタリングを理解する Docker コンテナは、プロセスを最小限に簡素化するために設計された、合理化された軽量な仮想環境です。自らの資源を管理・調整するプロセスは、もはや価値がありません。**代わりに、Kubernetes、Mesos、Cattle のような管理スタックは、これらのリソースをインフラストラクチャ全体で管理すべきだという概念を普及させてきました**。 CPUやメモリのリソースは「スケジューラ」によって割り当てられ、ネットワークリソースはスタック提供のロードバランサによって管理されます。
diff --git a/sections/production/guardprocess.md b/sections/production/guardprocess.md
index 719e85a73..29447cc30 100644
--- a/sections/production/guardprocess.md
+++ b/sections/production/guardprocess.md
@@ -4,7 +4,7 @@
### 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
+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) 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
diff --git a/sections/production/guardprocess.polish.md b/sections/production/guardprocess.polish.md
new file mode 100644
index 000000000..ee74e7f99
--- /dev/null
+++ b/sections/production/guardprocess.polish.md
@@ -0,0 +1,17 @@
+# Chroń i wznawiaj swoje procesy w przypadku awarii (za pomocą odpowiedniego narzędzia)
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Na poziomie podstawowym procesy węzłów muszą być chronione i restartowane w przypadku awarii. Mówiąc prosto, dla małych aplikacji i tych, którzy nie używają kontenerów - narzędzia takie jak [PM2](https://www.npmjs.com/package/pm2-docker) są idealne, ponieważ zapewniają prostotę, możliwości ponownego uruchamiania oraz bogatą integrację z węzłem. Inni z dużymi umiejętnościami w Linuksie mogą używać systemd i uruchamiać Node jako usługę. Sprawy stają się bardziej interesujące dla aplikacji korzystających z Dockera lub dowolnej technologii kontenerowej, ponieważ zwykle towarzyszą im narzędzia do zarządzania klastrami i organizacji (np. [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/) itp.), które wdrażają, monitorują i leczą kontenery. Mając te wszystkie bogate funkcje zarządzania klastrami, w tym restart kontenera, po co mieszać się z innymi narzędziami, takimi jak PM2? Nie ma kuloodpornej odpowiedzi. Istnieją dobre powody, aby trzymać PM2 w kontenerach (głównie jego specyficzna wersja kontenerów [pm2-docker](https://www.npmjs.com/package/pm2-docker)) jako pierwsza warstwa ochronna - znacznie szybciej jest zrestartować przetwarzać i udostępniać funkcje specyficzne dla węzłów, takie jak oznaczanie kodu, gdy kontener hostujący prosi o wdzięczne ponowne uruchomienie. Inni mogą unikać niepotrzebnych warstw. Na zakończenie tego podsumowania żadne rozwiązanie nie pasuje do nich wszystkich, a poznanie opcji jest ważne.
+
+
+
+### Co mówią inni blogerzy
+
+* Z [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.
+
+* Z posta na blogu Medium [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/installpackageswithnpmci.basque.md b/sections/production/installpackageswithnpmci.basque.md
new file mode 100644
index 000000000..7eaf296f4
--- /dev/null
+++ b/sections/production/installpackageswithnpmci.basque.md
@@ -0,0 +1,35 @@
+# Instalatu npm ci paketeak ekoizpenean
+
+
+
+### Azalpena
+
+Zure menpekotasunak blokeatu dituzu [**Blokeatu menpekotasunak**](./lockdependencies.basque.md) jarraituz, baina orain ziurtatu behar duzu pakete bertsio zehatzak erabiltzen direla ekoizpenean.
+
+Paketeak instalatzeko `npm ci` erabiltzen baduzu, hori eta gehiago lortuko duzu.
+
+- Zure `package.json` eta `package-lock.json` bat ez badatoz (hala behar lukete) edo blokeo fitxategirik ez baduzu, huts egingo du instalazioak
+- `node_modules` karpeta badago, automatikoki kenduko du instalatu aurretik
+- Azkarragoa da! [Argitaratutako bloga](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)ren arabera, ia bi aldiz azkarragoa
+
+### Noiz egon daiteke erabilgarri?
+
+Ziur egon IE inguruneak edo QAk probatuko duzula zure softwarea geroago ekoizpenera bidaliko duzun pakete bertsio berarekin.
+Gainera, arrazoiren batengatik norbaitek package.json eskuz aldatzen badu, ez cli komando baten bidez, baizik eta package.json zuzenean editatuz, tarte bat sortzen da package.json eta package-lock.jsonen artean, eta errore bat jaurtitzen da.
+
+### npmek dioena
+
+[npm ciren dokumentazio](https://docs.npmjs.com/cli/ci.html)tik hartua
+
+> Komando hau npm-installen antzekoa da, salbu eta ingurune automatizatuetan erabiltzeko dela, hala nola, proba plataformetan, etengabeko integrazio eta inplementazioetan, edo zure menpekotasunen instalazio garbia egiten ari zarela ziurtatu nahi duzun edozein egoeratan.
+
+[`ci` komandoaren jaregitea iragartzen duen blogeko mezua](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)
+
+> Komandoak hobekuntza handiak eskaintzen dizkie eraikuntzen errendimenduari eta fidagarritasunari etengabeko integrazio/ inplementazio prozesuetarako, esperientzia koherentea eta azkarra eskainiz CI/CD erabiltzen duten garatzaileei beren lan-fluxuan.
+
+[npmjs: menpekotasunak versus garatze-menpekotasunak (npmjs: dependencies and devDepencies)](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file)
+
+> "dependencies": zure aplikazioak ekoizpenean eskatzen dituen paketeak.
+> "devDependencies": tokiko garapenerako eta probetarako soilik behar diren paketeak.
+
+
diff --git a/sections/production/installpackageswithnpmci.french.md b/sections/production/installpackageswithnpmci.french.md
new file mode 100644
index 000000000..6b0a63f55
--- /dev/null
+++ b/sections/production/installpackageswithnpmci.french.md
@@ -0,0 +1,30 @@
+# Installez vos paquets avec npm ci en production
+
+
+
+### Un paragraphe d'explication
+
+Vous avez verrouillé vos dépendances en utilisant [**Verrouillez les dépendances**](./lockdependencies.french.md), mais maintenant, vous devez vous assurer que ces versions précises des paquets sont utilisées en production.
+
+L'utilisation de `npm ci` pour installer des paquets fera exactement cela et plus encore.
+* Il échouera si votre `package.json` et votre `package-lock.json` ne correspondent pas (ils devraient) ou si vous n'avez pas de fichier lock
+* Si un dossier `node_modules` est présent, il sera automatiquement supprimé avant l'installation
+* C'est plus rapide ! Près de deux fois plus rapide selon [l'article de version du blog](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)
+
+### Quand cela peut-il être utile ?
+Vous avez la garantie que votre environnement CI ou de qualité testera votre logiciel avec exactement la même version que celle que vous enverrez plus tard en production.
+De plus, si pour une raison quelconque quelqu'un modifie manuellement le fichier package.json, sans utiliser une commande du cli mais plutôt en éditant directement le fichier package.json, un écart entre le package.json et le package-lock.json est engendré et une erreur sera levée.
+
+### Ce que dit npm
+
+Extrait de la [documentation npm ci](https://docs.npmjs.com/cli/ci.html)
+> Cette commande est similaire à npm-install, sauf qu'elle est destinée à être utilisée dans des environnements automatisés tels que les plateformes de test, l'intégration continue et le déploiement, ou toute situation où vous voulez vous assurer que vous faites une installation propre de vos dépendances.
+
+[Article du blog annonçant la sortie de la commande `ci`](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)
+> La commande offre des améliorations considérables à la fois en termes de performance et de fiabilité des builds pour les intégrations continues/processus de déploiement continus, offrant une expérience cohérente et rapide aux développeurs qui utilisent les CI/CD dans leur flux de travail.
+
+[npmjs: dependencies et devDepencies](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file)
+> "dependencies": Paquets requis par votre application en production.
+> "devDependencies": Paquets qui ne sont nécessaires que pour le développement local et les tests.
+
+
diff --git a/sections/production/installpackageswithnpmci.japanese.md b/sections/production/installpackageswithnpmci.japanese.md
new file mode 100644
index 000000000..88c2d184e
--- /dev/null
+++ b/sections/production/installpackageswithnpmci.japanese.md
@@ -0,0 +1,30 @@
+# 本番環境に npm ci を使ってパッケージをインストールする
+
+
diff --git a/sections/production/installpackageswithnpmci.md b/sections/production/installpackageswithnpmci.md
new file mode 100644
index 000000000..bc43a4022
--- /dev/null
+++ b/sections/production/installpackageswithnpmci.md
@@ -0,0 +1,30 @@
+# Install packages with npm ci in production
+
+
+
+### One Paragraph Explainer
+
+You locked your dependencies following [**Lock dependencies**](./lockdependencies.md) but you now need to make sure those exact package versions are used in production.
+
+Using `npm ci` to install packages will do exactly that and more.
+* It will fail if your `package.json` and your `package-lock.json` do not match (they should) or if you don't have a lock file
+* If a `node_modules` folder is present it will automatically remove it before installing
+* It is faster! Nearly twice as fast according to [the release blog post](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)
+
+### When can this be useful?
+You are guaranteed that you CI environment or QA will test your software with exactly the same package version that the one you will later send to production.
+Also, if for some reason someone manually changes package.json, not through a cli command but rather by directly editing package.json, a gap between package.json & package-lock.json is created and an error will be thrown.
+
+### What npm says
+
+From [npm ci documentation](https://docs.npmjs.com/cli/ci.html)
+> This command is similar to npm-install, except it’s meant to be used in automated environments such as test platforms, continuous integration, and deployment – or any situation where you want to make sure you’re doing a clean install of your dependencies.
+
+[Blog post announcing the release of `ci` command](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)
+> The command offers massive improvements to both the performance and reliability of builds for continuous integration / continuous deployment processes, providing a consistent and fast experience for developers using CI/CD in their workflow.
+
+[npmjs: dependencies and devDepencies](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file)
+> "dependencies": Packages required by your application in production.
+> "devDependencies": Packages that are only needed for local development and testing.
+
+
+
+### Azalpena
+
+Zure kodea kanpoko pakete askoren menpe dago. Esan dezagun momentjs-2.1.4 ‘behar‘ eta erabiltzen duela eta, lehenespenez, ekoizpenean erabiltzen duzunean, npmek zmomentjs 2.1.5 eskura dezake, tamalez errore berri batzuk ekarriko dituena mahaira. Npm konfigurazio fitxategiak eta `–save-exact=true` argumentuak erabiltzeak adierazten dio npm-ri instalatutako bertsio berbera erabili behar duela, eta, beraz, `npm install` exekutatzen duzun hurrengo aldian (ekoizpenean edo probak egiteko bidali nahi duzu Docker edukiontzi baten barruan) menpeko bertsio bera eskuratuko du. Horren ordez, aukera egokia eta ezaguna da `.shrinkwrap` fitxategia erabiltzea (npm erabiliz erraz sortzen dena), berak adieraziko baitu zein pakete eta bertsio instalatu beharko liratekeen inongo inguruneak tentaziorik izan ez dezan espero baino bertsio berriagorik bilatzeko.
+
+- **Eguneratzea:** npm 5etik aurrera, menpekotasunak automatikoki blokeatzen dira .shrinkwrap erabiliz gero. Yarn pakete kudeatzaile sortu berriak ere menpekotasunak blokeatzen ditu lehenespenez.
+
+
+
+### Kode adibidea: .npmrc fitxategi mota bat da, npmri agindua ematen diona bertsio zehatzak erabiltzeko
+
+```npmrc
+// gorde hau .npmrc fitxategi gisa zure proiektuan
+save-exact:true
+```
+
+
+
+### Un paragraphe d'explication
+
+Votre code dépend de nombreux paquets externes, disons qu'il "requiert" et utilise momentjs-2.1.4, puis par défaut lorsque vous déployez en production, npm peut récupérer momentjs 2.1.5, ce qui malheureusement apporte quelques nouveaux bogues. L'utilisation de fichiers de configuration npm et de l'argument ```–save-exact=true``` indique à npm de se référer à la version *strictement* identique à celle qui a été installée, donc la prochaine fois que vous exécuterez ```npm install``` (en production ou dans un conteneur Docker que vous prévoyez d'expédier pour test), la même version dépendante sera récupérée. Une approche alternative et populaire utilise un fichier `.shrinkwrap` (facilement généré à l'aide de npm) qui indique exactement quels packages et versions doivent être installés afin qu'aucun environnement ne soit tenté de récupérer des versions plus récentes que prévu.
+
+* **Mise à jour :** à partir de npm 5, les dépendances sont verrouillées automatiquement à l'aide de .shrinkwrap. Yarn, un nouveau gestionnaire de packages, verrouille également les dépendances par défaut.
+
+
+
+### Exemple de code : fichier .npmrc qui demande à npm d'utiliser des versions exactes
+
+```npmrc
+// enregistrez-le en tant que fichier .npmrc dans le répertoire du projet
+save-exact:true
+```
+
+
+
+### コード例: npm 5 依存関係ロックファイル - package-lock.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/lockdependencies.md b/sections/production/lockdependencies.md
index 4bacd048a..61800062f 100644
--- a/sections/production/lockdependencies.md
+++ b/sections/production/lockdependencies.md
@@ -4,9 +4,7 @@
### 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.
+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. Due to this, starting from npm version 5 a package-lock.json file is generated in every install. This lock file pins all the dependencies and child dependencies versions. When the file is committed, any future install the gets a copy of the app will install the same dependencies version
+
+### Wyjaśnienie jednym akapitem
+
+Twój kod zależy od wielu zewnętrznych pakietów, powiedzmy, że „wymaga” i używa momentjs-2.1.4, a następnie domyślnie po wdrożeniu do produkcji npm może pobrać momentjs 2.1.5, co niestety wprowadza kilka nowych błędów do tabeli. Użycie plików konfiguracyjnych npm i argumentu ``–save-exact = true`` instruuje npm, aby odwoływał się do *dokładnie* tej samej wersji, która została zainstalowana, więc gdy następnym razem uruchomisz ``npm install`` (w wersji produkcyjnej lub w kontenerze Docker, który planujesz wysłać do testowania), zostanie pobrana ta sama zależna wersja. Alternatywnym i popularnym podejściem jest użycie pliku `.shrinkwrap` (łatwego do wygenerowania przy użyciu npm), który dokładnie określa, które pakiety i wersje powinny zostać zainstalowane, aby żadne środowisko nie mogło ulec pokusie pobierania nowszych wersji niż oczekiwano.
+
+* **Aktualizacja:** od npm 5 zależności są blokowane automatycznie przy użyciu .shrinkwrap. Yarn, nowy menedżer pakietów, domyślnie blokuje również zależności.
+
+
+
+### Przykład kodu: plik .npmrc, który instruuje npm, aby używał dokładnych wersji
+
+```npmrc
+// save this as .npmrc file on the project directory
+save-exact:true
+```
+
+
+
+### Azalpena
+
+Aplikazioaren kodeak ez luke erregistroen bideraketa kudeatu behar, baina erregistro tresnaren bat erabili beharko luke `stdout/stderr`-era idazteko. "Erregistroen bideratzeak" esan nahi du zure eskaerara edo eskaera prozesua ez den beste kokapen batera eraman eta bultzatzea erregistroak, adibidez, erregistroak fitxategi batean, datu basean eta abar idaztea. Bi dira, batez ere, horren arrazoiak: 1) kezkak bereiztea eta 2) [aplikazio modernoen 12 faktoreko praktika onak](https://12factor.net/logs).
+
+"Kezkak bereiztea" esatean, askotan pentsatzen dugu zerbitzuen arteko kode zatiei eta zerbitzuen euren arteko loturei buruz ari garela, baina hori "azpiegitura" osagaiei ere aplikatzen zaie. Aplikazioaren kodeak ez luke kudeatu behar azpiegiturak/exekuzio inguruneak (egun gehienetan, edukiontziak) kudeatu beharko lukeen zerbait. Zer gertatzen da aplikazioko erregistroen kokapenak zehazten badituzu, baina geroago kokapen hori aldatu behar baduzu? Horrek kode aldaketa eta inplementazioa eragiten ditu. Edukiontzietan/hodeian oinarritutako plataformekin lan egiten denean, edukiontziak biratu eta itxi egin daitezke errendimendu eskaeretara eskalatzean, eta, beraz, ezin dugu ziurtatu non amaituko diren erregistroen fitxategiak. Exekuzio inguruneak (edukiontziak) erabaki beharko luke nora bideratuko diren erregistro fitxategiak. Aplikazioak zer behar duen erregistratu beharko luke `stdout` / `stderr`-en, eta exekuzio ingurunea konfiguratuta egon beharko litzateke erregistro fluxua han jaso eta joan behar duen lekura bideratzeko. Halaber, erregistroen helmugak zehaztu edo / eta aldatu behar dituzten taldeko kideak askotan ez dira aplikazioen garatzaileak, baizik eta DevOps-eko kideak, eta agian ez dute aplikazioaren kodea ezagutzen. Horrek eragozten die aldaketak erraz egitea.
+Anti ereduaren kode adibidea: erregistroaren bideratzea aplikazioari hertsiki lotua
+
+
+
+### Anti ereduaren kode adibidea: erregistroaren bideratzea aplikazioari hertsiki lotua
+
+```javascript
+const { createLogger, transports, winston } = require("winston");
+/**
+ * `winston-mongodb` eskatzeak
+ * `winston.transports.MongoDB` agerian utziko du
+ */
+require("winston-mongodb");
+
+// bi fitxategi ezberdin erregistratu, honela aplikazioa hauekin lotuta egongo da
+const logger = createLogger({
+ transports: [new transports.File({ filename: "combined.log" })],
+ exceptionHandlers: [new transports.File({ filename: "exceptions.log" })],
+});
+
+// MongoDB-n erregistratu, honela aplikazioa hauekin lotuta egongo da
+winston.add(winston.transports.MongoDB, options);
+```
+
+Horrela eginez gero, aplikazioak kudeatuko ditu bai aplikazio/ negozio logika, bai erregistroen bideratze logika!
+
+
+
+### Kodea adibidea: erregistroen tratamendu onena + Docker adibidea
+
+In the application:
+
+```javascript
+const logger = new winston.Logger({
+ level: "info",
+ transports: [new winston.transports.Console()],
+});
+
+logger.log(
+ "info",
+ "Test Log Message with some parameter %s",
+ "some parameter",
+ { anything: "This is metadata" }
+);
+```
+
+Then, in the docker container `daemon.json`:
+
+```json5
+{
+ "log-driver": "splunk", // Splunk erabiliaz, adibide gisa, beste gordetze mota bat izango genuke
+ "log-opts": {
+ "splunk-token": "",
+ "splunk-url": "",
+ //...
+ },
+}
+```
+
+Beraz adibide honek `log -> stdout -> Docker container -> Splunk`-en antza du
+
+
+
+### Blogaren aipua: "O'Reilly"
+
+[O'Reilly](https://www.oreilly.com/ideas/a-cloud-native-approach-to-logs) bloga,
+
+> Zerbitzari kopuru konkretu batean instantzia kopuru finko bat duzunean, ematen du erregistroak diskoan gordetzea zentzuzkoa dela. Hala ere, zure aplikazioa dinamikoki exekutatzen ari den instantzia batetik 100era pasa daitekeenean eta instantzia horiek non exekutatzen diren ez dakizunean, zure hodei hornitzaileak erregistro horiek zure partez gehitu beharko ditu zure partez.
+
+
+
+### Aipua: "12 faktorea"
+
+[Saioa hasteko 12 faktoreko praktika onenak](https://12factor.net/logs) testutik hartua:
+
+> Hamabi faktoreko aplikazio bat ez da inoiz bere irteera korrontea bideratzeaz edo biltegiratzeaz arduratzen. Ez luke saiatu behar erregistro fitxategietan idazten edo kudeatzen. Horren ordez, exekutatzen ari den prozesu bakoitzak bere gertaeren korrontea, bufferrik gabekoa, stdout-era idazten du.
+
+> Proba edo produkzio inplementazioetan, exekuzio inguruneak harrapatuko du prozesu bakoitzeko korrontea, aplikazioko beste korronte guztiekin batera bildu eta azken helmuga batera edo gehiagora bideratuko ditu ikusteko eta epe luzerako artxibatzeko. Aplikazioak ezin ditu artxiboko helmuga horiek ikusi, ezta konfiguratu ere, eta exekuzio ingurunea da kudeatzen dituen bakarra.
+
+
+
+### Adibidea: arkitekturaren ikuspegi orokorra Docker eta Splunk erabiliz adibide gisa
+
+
+
+
diff --git a/sections/production/logrouting.brazilian-portuguese.md b/sections/production/logrouting.brazilian-portuguese.md
index 5fb771a96..f18d24c97 100644
--- a/sections/production/logrouting.brazilian-portuguese.md
+++ b/sections/production/logrouting.brazilian-portuguese.md
@@ -79,6 +79,6 @@ Do [guia de boas práticas 12-Factor](https://12factor.net/logs),
### Exemplo: Visão geral da arquitetura usando o Docker e o Splunk como exemplo
-
+
diff --git a/sections/production/logrouting.french.md b/sections/production/logrouting.french.md
new file mode 100644
index 000000000..ebba94f23
--- /dev/null
+++ b/sections/production/logrouting.french.md
@@ -0,0 +1,87 @@
+# Votre application ne doit pas gérer la redirection du journal
+
+
+
+### Un paragraphe d'explication
+
+Le code de l'application ne devrait pas gérer le routage des journaux, mais plutôt utiliser un utilitaire de journalisation pour écrire dans `stdout/stderr`. Le « routage des journaux » signifie qu'il faut récupérer et pousser les journaux vers un autre endroit que votre application ou processus d'application, par exemple, écrire les journaux dans un fichier, une base de données, etc. La raison en est essentiellement double : 1) la séparation des préoccupations et 2) [12-Factor les meilleures pratiques pour les applications modernes](https://12factor.net/logs).
+
+Nous pensons souvent à la « séparation des préoccupations » en termes de morceaux de code entre les services et entre les services eux-mêmes, mais cela s'applique également aux éléments plus « infrastructurels ». Votre code d'application ne doit pas gérer quelque chose qui devrait être géré par l'infrastructure/l'environnement d'exécution (le plus souvent de nos jours, les conteneurs). Que se passe-t-il si vous définissez les emplacements des journaux dans votre application, mais que vous devez ensuite modifier cet emplacement ? Cela entraîne un changement de code et un déploiement. Lorsque l'on travaille avec des plateformes basées sur des conteneurs ou le cloud, les conteneurs peuvent démarrer et s'arrêter lors de la mise à l'échelle en fonction des exigences de performance, donc nous ne pouvons pas savoir où un fichier journal sera placé. L'environnement d'exécution (conteneur) devrait plutôt décider où les fichiers journaux sont dirigés. L'application doit simplement enregistrer ce dont elle a besoin dans `stdout` / `stderr`, et l'environnement d'exécution doit être configuré pour récupérer le flux de données de cet enregistrement et le diriger vers l'endroit où il doit aller. De plus, les membres de l'équipe qui doivent spécifier et/ou modifier les destinations des journaux ne sont souvent pas des développeurs d'applications mais font partie de DevOps, et ils peuvent ne pas être familiers avec le code de l'application. Cela les empêche d'apporter facilement des modifications.
+
+
+
+### Exemple de code incorrect : acheminement des logs étroitement couplé à l'application
+
+```javascript
+const { createLogger, transports, winston } = require('winston');
+/**
+ * Le fait d'exiger `winston-mongodb` exposera
+ * `winston.transports.MongoDB`
+ */
+require('winston-mongodb');
+
+// journalisation vers deux fichiers différents, sur lesquels l'application doit maintenant se concentrer
+const logger = createLogger({
+ transports: [
+ new transports.File({ filename: 'combined.log' }),
+ ],
+ exceptionHandlers: [
+ new transports.File({ filename: 'exceptions.log' })
+ ]
+});
+
+// journalisation vers MongoDB, which the application now must be concerned with
+winston.add(winston.transports.MongoDB, options);
+```
+En procédant ainsi, l'application gère à la fois la logique applicative/métier ET la logique de routage des journaux !
+
+
+
+### Exemple de code - Meilleure gestion des journaux + exemple Docker
+Dans l'application :
+```javascript
+const logger = new winston.Logger({
+ level: 'info',
+ transports: [
+ new (winston.transports.Console)()
+ ]
+});
+
+logger.log('info', 'Test message du journal avec certains paramètres %s', 'certains paramètres', { anything: 'Voici les métadonnées' });
+```
+Puis, dans le conteneur du docker `daemon.json` :
+```json5
+{
+ "log-driver": "splunk", // en utilisant Splunk comme exemple, il pourrait s'agir d'un autre type de stockage
+ "log-opts": {
+ "splunk-token": "",
+ "splunk-url": "",
+ //...
+ }
+}
+```
+Cet exemple se présente donc comme suit : `log -> stdout -> conteneur Docker -> Splunk`
+
+
+
+### Citation du blog : « O'Reilly »
+
+Extrait du [blog de O'Reilly](https://www.oreilly.com/ideas/a-cloud-native-approach-to-logs),
+ > Lorsque vous avez un nombre fixe d'instances sur un nombre fixe de serveurs, le stockage des journaux sur disque semble logique. Cependant, lorsque votre application peut passer dynamiquement d'une instance à 100, et que vous n'avez aucune idée de l'endroit où ces instances sont exécutées, vous avez besoin que votre fournisseur du cloud s'occupe de l'agrégation de ces journaux en votre nom.
+
+
+
+### Citation : « 12-Factor »
+
+Extrait de [12-Factor les meilleures pratiques pour la journalisation](https://12factor.net/logs),
+ > Une application à douze facteurs ne se préoccupe jamais du routage ou du stockage de son flux de sortie. Elle ne doit pas essayer d'écrire dans les fichiers journaux ou de les gérer. Au lieu de cela, chaque processus en cours d'exécution écrit son flux d'événements, sans bufferisation, sur stdout.
+
+ > Lors des déploiements d'environnement de test ou de production, chaque flux de processus sera capturé par l'environnement d'exécution, regroupé avec tous les autres flux de l'application, et acheminé vers une ou plusieurs destinations finales pour être visionné et archivé à long terme. Ces destinations d'archivage ne sont pas visibles ou configurables par l'application, mais sont entièrement gérées par l'environnement d'exécution.
+
+
+
+ ### Exemple : aperçu de l'architecture en utilisant Docker et Splunk comme exemple
+
+
+
+
diff --git a/sections/production/logrouting.md b/sections/production/logrouting.md
index 9fac3f52a..e290263fb 100644
--- a/sections/production/logrouting.md
+++ b/sections/production/logrouting.md
@@ -82,6 +82,6 @@ From the [12-Factor best practices for logging](https://12factor.net/logs),
### Example: Architecture overview using Docker and Splunk as an example
-
+
diff --git a/sections/production/logrouting.polish.md b/sections/production/logrouting.polish.md
new file mode 100644
index 000000000..02116825c
--- /dev/null
+++ b/sections/production/logrouting.polish.md
@@ -0,0 +1,87 @@
+# Kod aplikacji nie powinien obsługiwać routingu dziennika
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Kod aplikacji nie powinien obsługiwać routingu dziennika, ale zamiast tego powinien używać narzędzia logger do pisania w `stdout / stderr`. „Log routing” oznacza pobieranie i przekazywanie dzienników do innej lokalizacji niż aplikacja lub proces aplikacji, na przykład zapisywanie dzienników w pliku, bazie danych itp. Powód tego jest w większości dwojaki: 1) separation of concerns oraz 2) [12-Factor best practices for modern applications](https://12factor.net/logs).
+
+Często myślimy o "separation of concerns" jeśli chodzi o fragmenty kodu między usługami i między samymi usługami, ale dotyczy to również komponentów bardziej „infrastrukturalnych”. Twój kod aplikacji nie powinien obsługiwać czegoś, co powinno być obsługiwane przez infrastrukturę / środowisko wykonawcze (najczęściej obecnie kontenery). Co się stanie, jeśli zdefiniujesz lokalizacje dzienników w aplikacji, ale później będziesz musiał zmienić tę lokalizację? Powoduje to zmianę kodu i wdrożenie. Podczas pracy z platformami opartymi na kontenerach / chmurach kontenery mogą się obracać i zamykać podczas skalowania do wymagań wydajności, więc nie jesteśmy pewni, gdzie skończy się plik dziennika. Środowisko wykonawcze (kontener) powinno decydować, do którego miejsca kierowane są pliki dziennika. Aplikacja powinna po prostu zarejestrować to, czego potrzebuje do `stdout` /` stderr`, a środowisko wykonawcze powinno być skonfigurowane tak, aby pobierało strumień dziennika stamtąd i kierowało go tam, gdzie musi się udać. Ponadto członkowie zespołu, którzy muszą określić i / lub zmienić miejsca docelowe dziennika, często nie są programistami aplikacji, ale są częścią DevOps i mogą nie znać kodu aplikacji. Zapobiega to łatwym wprowadzaniu zmian.
+
+
+
+### Przykład kodu - Antywzorzec: routing dziennika jest ściśle powiązany z aplikacją
+
+```javascript
+const { createLogger, transports, winston } = require('winston');
+/**
+ * Requiring `winston-mongodb` will expose
+ * `winston.transports.MongoDB`
+ */
+require('winston-mongodb');
+
+// log to two different files, which the application now must be concerned with
+const logger = createLogger({
+ transports: [
+ new transports.File({ filename: 'combined.log' }),
+ ],
+ exceptionHandlers: [
+ new transports.File({ filename: 'exceptions.log' })
+ ]
+});
+
+// log to MongoDB, which the application now must be concerned with
+winston.add(winston.transports.MongoDB, options);
+```
+Robiąc to w ten sposób, aplikacja obsługuje teraz zarówno logikę aplikacji / biznesu ORAZ logikę routingu dziennika!
+
+
+
+### Przykład kodu - Lepsza obsługa dziennika + przykład Docker
+W aplikacji:
+```javascript
+const logger = new winston.Logger({
+ level: 'info',
+ transports: [
+ new (winston.transports.Console)()
+ ]
+});
+
+logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
+```
+Następnie, w kontenerze dockera `daemon.json`:
+```json5
+{
+ "log-driver": "splunk", // just using Splunk as an example, it could be another storage type
+ "log-opts": {
+ "splunk-token": "",
+ "splunk-url": "",
+ //...
+ }
+}
+```
+Ten przykład wygląda mniej więcej tak `log -> stdout -> Docker container -> Splunk`
+
+
+
+### Cytat z Bloga: "O'Reilly"
+
+Z [O'Reilly blog](https://www.oreilly.com/ideas/a-cloud-native-approach-to-logs),
+ > When you have a fixed number of instances on a fixed number of servers, storing logs on disk seems to make sense. However, when your application can dynamically go from 1 running instance to 100, and you have no idea where those instances are running, you need your cloud provider to deal with aggregating those logs on your behalf.
+
+
+
+### Cytat: "12-Factor"
+
+Z [12-Factor best practices for logging](https://12factor.net/logs),
+ > A twelve-factor app never concerns itself with routing or storage of its output stream. It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to stdout.
+
+ > In staging or production deploys, each process’ stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment.
+
+
+
+ ### Przykład: Przegląd architektury na przykładzie Docker i Splunk
+
+
+
+
diff --git a/sections/production/logrouting.russian.md b/sections/production/logrouting.russian.md
index b74664679..be00f9eeb 100644
--- a/sections/production/logrouting.russian.md
+++ b/sections/production/logrouting.russian.md
@@ -14,13 +14,16 @@
```javascript
const { createLogger, transports, winston } = require('winston');
-const winston-mongodb = require('winston-mongodb');
+/**
+ * Requiring `winston-mongodb` will expose
+ * `winston.transports.MongoDB`
+ */
+require('winston-mongodb');
// log to two different files, which the application now must be concerned with
const logger = createLogger({
transports: [
new transports.File({ filename: 'combined.log' }),
-
],
exceptionHandlers: [
new transports.File({ filename: 'exceptions.log' })
@@ -47,13 +50,13 @@ const logger = new winston.Logger({
logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
```
Затем в Docker-контейнере `daemon.json`:
-```javascript
+```json5
{
"log-driver": "splunk", // just using Splunk as an example, it could be another storage type
"log-opts": {
"splunk-token": "",
"splunk-url": "",
- ...
+ //...
}
}
```
@@ -79,6 +82,6 @@ logger.log('info', 'Test Log Message with some parameter %s', 'some parameter',
### Пример: обзор архитектуры с использованием Docker и Splunk в качестве примера
-
+
diff --git a/sections/production/measurememory.basque.md b/sections/production/measurememory.basque.md
new file mode 100644
index 000000000..b3ca472cb
--- /dev/null
+++ b/sections/production/measurememory.basque.md
@@ -0,0 +1,25 @@
+# Neurtu eta zaindu memoriaren erabilera
+
+
+
+### Azalpena
+
+Mundu perfektu batean, web garatzaile batek ez luke memoria ihesei aurre egin beharko. Egia esan, memoria arazoak Nodek duen arazo ezaguna da eta ezagutu egin behar dena. Node erabiltzen denean, batez ere, memoriaren erabilera etengabe kontrolatu beharra dago. Garapen eta produkzio txikiko guneetan, neurketa eskuz egin dezakezu Linux komandoak edo npm tresnak eta liburutegiak erabiliz, nodo-inspector eta memwatch bezalakoak. Eskuzko jarduera horren eragozpen nagusia da eskatzen dutela jarraipena gizaki batek egitea modu aktiboan. Ekoizpen gune serioetarako, guztiz funtsezkoa da kontrol tresna sendoak erabiltzea, adibidez (AWS CloudWatch, DataDog edo antzeko edozein sistema proaktibo), iragazkia gertatzen denean ohartarazten duena. Badaude garapen praktika gutxi batzuk ere ihesak saihesteko: saihestu datuak gordetzea maila globalean, erabili tamaina dinamikoa duten datuentzako fluxuak, mugatu aldagaiak let eta const erabiliz.
+
+
+
+### Beste blogari batzuek diotena
+
+[Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/) bloga:
+
+> ... ”Dagoeneko badakigun bezala, Node.jsren V8k jatorrizko kodean konpilatzen du JavaScript. Sortzen diren jatorrizko datu egiturek ez dute zerikusi handirik jatorrizko irudikapenarekin, eta V8k kudeatzen ditu soilik. Horrek esan nahi du ezin dugula memoria aktiboki esleitu edo banatu JavaScripten. V8k zabor bilketa izeneko mekanismo ezaguna erabiltzen du arazo horri aurre egiteko".
+
+[Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load) bloga:
+
+> ... ... "Adibide honek ageriko emaitzak lortzen baditu ere, prozesua beti berdina da: sortu pila zabortegiak denbora pixka bat eta memoria asko esleituta. Konparatu zabortegi batzuk zer hazten ari den jakiteko"
+
+[Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/) bloga:
+
+> ... “hutsegitea, Node.js 1,5 GB memoria inguru erabiltzen saiatuko da, eta hori mugatu egin behar da memoria gutxiago duten sistemetan exekutatzen denean. Hori da espero den jokabidea, zabor bilketa oso operazio garestia baita. Horren irtenbidea izan zen Node.js prozesuari beste parametro bat gehitzea: nodo –max_old_space_size = 400 server.js –production . "
+
+“Zergatik da garestia zabor bilketa? V8 JavaScript motorrak zaborra biltzeko erabiltzen duen mekanismoa mundu osoa gelditzeko modukoa da. Praktikan, horrek esan nahi du programak exekuzioa gelditu egiten duela zabor bilketa martxan dagoen bitartean".
diff --git a/sections/production/measurememory.brazilian-portuguese.md b/sections/production/measurememory.brazilian-portuguese.md
index 9bcaa29be..1792e3b15 100644
--- a/sections/production/measurememory.brazilian-portuguese.md
+++ b/sections/production/measurememory.brazilian-portuguese.md
@@ -10,7 +10,7 @@ Em um mundo perfeito, um desenvolvedor Web não deve lidar com vazamentos de mem
### O que Outros Blogueiros Dizem
-* Do blog [Dyntrace](http://apmblog.dynatrace.com/):
+* Do blog [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/):
> ... ”Como já aprendemos, no Node.js o JavaScript é compilado para código nativo pelo V8. As estruturas de dados nativas resultantes não têm muito a ver com a representação original e são gerenciadas exclusivamente pelo V8. Isso significa que não podemos alocar ou desalocar ativamente a memória em JavaScript. O V8 usa um mecanismo bem conhecido chamado coleta de lixo para resolver esse problema.”
* Do blog [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
@@ -18,7 +18,7 @@ Em um mundo perfeito, um desenvolvedor Web não deve lidar com vazamentos de mem
Crie dumps de heap com algum tempo e uma boa quantidade de alocação de memória entre
Compare alguns dumps para descobrir o que está crescendo”
-* Do blog [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+* Do blog [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/):
> ... “falha, o Node.js tentará usar cerca de 1,5 GB de memória, que deve ser limitado quando executado em sistemas com menos memória. Esse é o comportamento esperado, pois a coleta de lixo é uma operação muito cara.
A solução para isso foi adicionar um parâmetro extra ao processo Node.js:
node –max_old_space_size=400 server.js –production ”
diff --git a/sections/production/measurememory.chinese.md b/sections/production/measurememory.chinese.md
index 97cdd9c1f..63a06d4c0 100644
--- a/sections/production/measurememory.chinese.md
+++ b/sections/production/measurememory.chinese.md
@@ -11,13 +11,13 @@
### 其他博客说了什么
-* 摘自博客 [Dyntrace](http://apmblog.dynatrace.com/):
+* 摘自博客 [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/):
> ... ”正如我们所了解到的,在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):
+* 摘自博客 [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/):
> ... “故障, 在内存较少的系统上运行时必须限制内存,Node.js会尝试使用大约1.5GB的内存。这是预期的行为,垃圾收集是一个代价很高的操作。
解决方案是为Node.js进程添加一个额外的参数:
node –max_old_space_size=400 server.js –production ”
diff --git a/sections/production/measurememory.french.md b/sections/production/measurememory.french.md
new file mode 100644
index 000000000..b8f2256bd
--- /dev/null
+++ b/sections/production/measurememory.french.md
@@ -0,0 +1,25 @@
+# Mesurez et protégez l'utilisation de la mémoire
+
+
+
+### Un paragraphe d'explication
+
+Dans un monde parfait, un développeur web ne devrait pas s'occuper des fuites de mémoire. En réalité, les problèmes de mémoire sont des phénomènes connus de Node dont il faut être conscient. Surtout, l'utilisation de la mémoire doit être constamment surveillée. Dans les sites de développement et les petits sites de production, vous pouvez mesurer manuellement en utilisant des commandes Linux ou des outils et des bibliothèques npm comme node-inspector et memwatch. Le principal inconvénient de ces activités manuelles est qu'elles nécessitent un être humain qui surveille activement - pour les sites de production sérieux, il est absolument vital d'utiliser des outils de surveillance robustes (AWS CloudWatch, DataDog ou tout autre système proactif similaire), par exemple qui alertent lorsqu'une fuite se produit. Il existe également peu de recommandations de développement pour anticiper des fuites : évitez de stocker les données au niveau global, utilisez des flux (NdT *streams*) pour les données de taille dynamique, limitez la portée des variables en utilisant des let et des const.
+
+
+
+### Ce que disent les autres blogueurs
+
+* Extrait du blog de [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/) :
+> ... « Comme nous l'avons déjà appris, dans Node.js, JavaScript est compilé en code natif par V8. Les structures de données natives résultantes n'ont pas grand-chose à voir avec leur représentation d'origine et sont uniquement gérées par V8. Cela signifie que nous ne pouvons pas allouer ou désallouer activement de la mémoire en JavaScript. V8 utilise un mécanisme bien connu appelé le [ramasse-miettes](https://fr.wikipedia.org/wiki/Ramasse-miettes_(informatique)) (NdT *garbage collection*) pour résoudre ce problème. »
+
+* Extrait du blog de [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load) :
+> ... « Bien que cet exemple mène à des résultats évidents, le processus est toujours le même :
+Créez des copies de mémoires sur une certaine période avec une bonne quantité d'allocation de mémoire entre les deux
+Comparez ces copies pour découvrir ce qui augmente »
+
+* Extrait du blog de [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/) :
+> ... « Par défaut, Node.js essaiera d'utiliser environ 1,5GB de mémoire, ce qui doit être plafonné lors de l'exécution sur des systèmes avec moins de mémoire. C'est le comportement attendu car la récupération de place est une opération très coûteuse.
+La solution pour cela a été d'ajouter un paramètre supplémentaire au processus de Node.js :
+node –max_old_space_size=400 server.js –production »
+« Pourquoi le ramasse-miettes coûte-t-il aussi cher ? Le moteur JavaScript V8 utilise un mécanisme d'arrêt lors du ramasse-miettes. En pratique, cela signifie que le programme arrête son exécution pendant que la récupération du ramasse-miettes est en cours. »
diff --git a/sections/production/measurememory.japanese.md b/sections/production/measurememory.japanese.md
new file mode 100644
index 000000000..ba3307ed9
--- /dev/null
+++ b/sections/production/measurememory.japanese.md
@@ -0,0 +1,25 @@
+# メモリ使用量を測定してガードする
+
+
+
+### 他のブロガーが言っていること
+
+* ブログ [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/) より:
+> ... ”すでに学習したように、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) より:
+> ... “この例では明らかな結果が得られますが、プロセスは常に同じです。:
+ある程度の時間をかけてヒープダンプを作成し、その間にかなりの量のメモリ割り当てを行います。
+いくつかのダンプを比較して、何が成長しているかを確認します。”
+
+* ブログ [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/) より:
+> ... “デフォルトでは、Node.js は約1.5 GB のメモリを使用しようとしますが、メモリの少ないシステムで実行する場合は上限を設定する必要があります。ガベージコレクションは非常にコストのかかる操作なので、これは予想される動作です。
+これを解決するには、Node.js のプロセスに余分なパラメータを追加する必要がありました。:
+node –max_old_space_size=400 server.js –production ”
+“なぜガベージコレクションはコストがかかるのでしょうか?V8 JavaScript エンジンは、stop-the-world ガベージコレクタ機構を採用しています。これは実際には、ガベージコレクションの実行中にプログラムの実行を停止することを意味します。”
diff --git a/sections/production/measurememory.korean.md b/sections/production/measurememory.korean.md
index 3b5b31d21..d4946c0ff 100644
--- a/sections/production/measurememory.korean.md
+++ b/sections/production/measurememory.korean.md
@@ -10,7 +10,7 @@ In a perfect world, a web developer shouldn’t deal with memory leaks. In reali
### What Other Bloggers Say
-* From the blog [Dyntrace](http://apmblog.dynatrace.com/):
+* From the blog [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/):
> ... ”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):
@@ -18,7 +18,7 @@ In a perfect world, a web developer shouldn’t deal with memory leaks. In reali
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):
+* From the blog [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/):
> ... “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 ”
diff --git a/sections/production/measurememory.md b/sections/production/measurememory.md
index 3b5b31d21..d4946c0ff 100644
--- a/sections/production/measurememory.md
+++ b/sections/production/measurememory.md
@@ -10,7 +10,7 @@ In a perfect world, a web developer shouldn’t deal with memory leaks. In reali
### What Other Bloggers Say
-* From the blog [Dyntrace](http://apmblog.dynatrace.com/):
+* From the blog [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/):
> ... ”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):
@@ -18,7 +18,7 @@ In a perfect world, a web developer shouldn’t deal with memory leaks. In reali
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):
+* From the blog [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/):
> ... “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 ”
diff --git a/sections/production/measurememory.polish.md b/sections/production/measurememory.polish.md
new file mode 100644
index 000000000..1e68071cb
--- /dev/null
+++ b/sections/production/measurememory.polish.md
@@ -0,0 +1,25 @@
+# Zmierz i zabezpiecz zużycie pamięci
+
+
+
+### Wyjaśnienie jednym akapitem
+
+W idealnym świecie programista nie powinien zajmować się wyciekami pamięci. W rzeczywistości problemy z pamięcią to znane problemy węzłów, o których trzeba pamiętać. Przede wszystkim należy stale monitorować zużycie pamięci. W witrynach programistycznych i małych zakładach produkcyjnych można ręcznie oceniać za pomocą poleceń systemu Linux lub narzędzi i bibliotek npm, takich jak inspektor węzłów i memwatch. Główną wadą tych ręcznych czynności jest to, że wymagają one aktywnego monitorowania przez człowieka - w przypadku poważnych zakładów produkcyjnych absolutnie niezbędne jest użycie solidnych narzędzi monitorowania, np. (AWS CloudWatch, DataDog lub inny podobny proaktywny system), który ostrzega o wystąpieniu wycieku. Istnieje również kilka wskazówek programistycznych, aby zapobiec wyciekom: unikaj przechowywania danych na poziomie globalnym, używaj strumieni danych o dynamicznym rozmiarze, ogranicz zakres zmiennych za pomocą let i const.
+
+
+
+### Co mówią inni blogerzy
+
+* Z bloga [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/):
+> ... ”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.”
+
+* Z bloga [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”
+
+* Z bloga [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/):
+> ... “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/measurememory.russian.md b/sections/production/measurememory.russian.md
index 494d37cb2..08cd29b73 100644
--- a/sections/production/measurememory.russian.md
+++ b/sections/production/measurememory.russian.md
@@ -10,7 +10,7 @@
### Что говорят другие блоггеры
-* Из блога [Dyntrace](http://apmblog.dynatrace.com/):
+* Из блога [Dyntrace](https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/):
> ... "Как мы уже узнали, в 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):
@@ -18,7 +18,7 @@
Создайте дампы кучи с некоторым временем и достаточным количеством памяти, выделяемой между ними
Сравните несколько свалок, чтобы узнать, что растет"
-* Из блога [Dyntrace](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
+* Из блога [Rising Stack](https://blog.risingstack.com/finding-a-memory-leak-in-node-js/):
> ... "ошибка, Node.js попытается использовать около 1,5ГБ памяти, которая должна быть ограничена при работе в системах с меньшим объемом памяти. Это ожидаемое поведение, поскольку сборка мусора является очень дорогостоящей операцией.
Решением для этого было добавление дополнительного параметра в процесс Node.js:
node –max_old_space_size=400 server.js –production"
diff --git a/sections/production/monitoring.basque.md b/sections/production/monitoring.basque.md
new file mode 100644
index 000000000..b12599773
--- /dev/null
+++ b/sections/production/monitoring.basque.md
@@ -0,0 +1,39 @@
+# Monitorizazioa!
+
+
+
+### Azalpena
+
+Mailarik oinarrizkoenean, kontrolak esan nahi du produkzioan _erraz_ identifikatu ahal izango duzula gauza txarrak noiz gertatzen diren, posta elektronikoz edo Slack bidez jakinaraziz, adibidez. Zure eskakizunak aseko dituen tresna multzo egokia aukeratzea da erronka, zure ekonomia lur jota geratu gabe. Proposatzen dizut zehatz dezazun egoera osasuntsu bat bermatzeko ezarri beharreko metrika multzo nagusia: PUZa, zerbitzariaren RAMa, Nodo prozesuaren RAMa (1,4 GB baino gutxiago), azken minutuko errore kopurua, prozesuaren berrabiarazte kopurua eta batez besteko erantzun denbora. Ondoren, aukeratu zure gustuko ezaugarri aurreratuak eta gehitu zure nahien zerrendara. Luxuzko monitorizazio funtzioaren adibide batzuk: DB profilak, zerbitzu gurutzatuak neurtzea (hau da, negozio transakzioa neurtzea), front-end integrazioa, datu gordinak BI pertsonalizatutako bezeroen aurrean uztea, Slack jakinarazpenak eta beste hainbat.
+
+Funtzio aurreratuak lortu nahi badituzu, konfigurazio luzea egin beharko duzu edo, bestela, Datadog, NewRelic eta antzeko produktu komertzialak erosi beharko dituzu. Zoritxarrez, oinarriak ere lortzea ez da parkean paseoan ibiltzea. Izan ere, metrika batzuk (PUZ) hardwarearekin lotuta daude eta beste batzuk nodoaren prozesuan bizi dira (barne erroreak), eta, beraz, tresna zuzen guztiek konfigurazio osagarria eskatzen dute. Adibidez, saltzaileen hodeiko kontrol irtenbideek (adibidez, [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) berehala emango dizute hardwarearen metrikaren berri, baina ez barneko aplikazioaren portaerarena. Beste aldetik, egunkarietan oinarritutako ElasticSearch bezalako irtenbideek ez dute lehenetsita hardwarearen ikuspegia. Irtenbidea zure aukera handitzea da falta diren metrikekin osatuz; adibidez, aukera ezagun bat aplikazioen erregistroak [Elastic stack](https://www.elastic.co/products)era bidaltzea da eta agente osagarri batzuk konfiguratzea (adibidez, [Beat](https://www.elastic.co/products)) hardwarearekin lotutako informazioa partekatuz argazki osoa lortzeko.
+
+
+
+### Jarraipen adibidea: AWS cloudwatch panel lehenetsia. Zaila da aplikazioko metrika ateratzea
+
+
+
+
+
+### Jarraipen adibidea: StackDriver panel lehenetsia. Zaila da aplikazioko metrika ateratzea
+
+
+
+
+
+### Adibidea: Grafana datu gordinak bistaratzen dituen UI geruza gisa
+
+
+
+
+
+### Beste blogari batzuek diotena
+
+[Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/) bloga :
+
+> …Zure zerbitzu guztietako seinale horiek ikustea gomendatzen dizugu.
+> Errorea: erroreek erabiltzaileei aurre egiten dietelako eta zure bezeroei berehala eragiten dietelako
+> Erantzuteko denbora: latentziak zure bezeroei eta negozioari zuzenean eragiten dielako.
+> Trafikoa: trafikoak errore tasaren hazkundearen testuingurua ulertzen laguntzen dizu, bai eta latentzia ere.
+> Saturazioa: zure zerbitzua zeinen "betea" den adierazten du. PUZaren erabilera % 90 bada, zure sistemak trafiko gehiago kudeatu al dezake? …
diff --git a/sections/production/monitoring.brazilian-portuguese.md b/sections/production/monitoring.brazilian-portuguese.md
index b45947ce3..0b2b4fb7d 100644
--- a/sections/production/monitoring.brazilian-portuguese.md
+++ b/sections/production/monitoring.brazilian-portuguese.md
@@ -12,25 +12,25 @@ Atingir os recursos avançados exige uma configuração demorada ou a compra de
### Exemplo de monitoramento: painel padrão do AWS cloudwatch. Difícil de extrair métricas na aplicação
-
+
### Exemplo de monitoramento: painel padrão do StackDriver. Difícil de extrair métricas na aplicação
-
+
### Exemplo de monitoramento: Grafana como camada de interface do usuário que visualiza dados brutos
-
+
### O que Outros Blogueiros Dizem
-Do blog [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
+Do blog [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/):
> …Recomendamos que você observe esses sinais para todos os seus serviços:
> Taxa de erros: porque os erros são enfrentados pelo usuário e afetam imediatamente seus clientes.
diff --git a/sections/production/monitoring.chinese.md b/sections/production/monitoring.chinese.md
index 9f28a6fe2..c0edcc6f4 100644
--- a/sections/production/monitoring.chinese.md
+++ b/sections/production/monitoring.chinese.md
@@ -13,24 +13,24 @@
### 监控示例:AWS cloudwatch默认仪表板。很难提取应用内指标
-
+
### 监控示例:StackDriver默认仪表板。很难提取应用内指标
-
+
### 监控示例:Grafana作为可视化原始数据的UI层
-
+
+
+### Un paragraphe d'explication
+
+Au niveau le plus élémentaire, la surveillance signifie que vous pouvez facilement identifier quand de mauvaises choses se produisent en production. Par exemple, en étant averti par email ou Slack. Le défi est de choisir le bon ensemble d'outils qui répondra à vos besoins sans vous ruiner. Permettez-moi de vous suggérer de commencer par définir l'ensemble des paramètres de base qui doivent être surveillés pour garantir un état sain - CPU, RAM du serveur, RAM du processus de Node (moins de 1,4 GB), le nombre d'erreurs dans la dernière minute, le nombre de redémarrages du processus , temps de réponse moyen. Ensuite, passez en revue certaines fonctionnalités avancées dont vous pourriez avoir envie et ajoutez-les à votre liste de souhaits. Quelques exemples d'une fonction de surveillance de luxe : profilage de base de données, mesure interservices (c.-à-d. mesurer les transactions commerciales), intégration frontale, exposer les données brutes aux clients BI personnalisés, notifications Slack et bien d'autres.
+
+La réalisation des fonctionnalités avancées nécessite une configuration longue ou l'achat d'un produit commercial tel que Datadog, newrelic et similaires. Malheureusement, atteindre même les bases n'est pas une promenade de santé car certaines mesures sont liées au matériel (CPU) et d'autres vivent dans le processus de Node (erreurs internes), donc tous les outils simples nécessitent une configuration supplémentaire. Par exemple, les solutions de surveillance des fournisseurs de cloud (par exemple [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) vous informeront immédiatement de la métrique du matériel, mais rien du comportement de l'application interne. À l'autre extrémité, les solutions basées sur les journaux telles que ElasticSearch manquent par défaut de la vue matérielle. La solution consiste à étendre votre choix avec des mesures manquantes, par exemple, un choix populaire consiste à envoyer des journaux d'application à la [pile Elastic](https://www.elastic.co/products) et à configurer un agent supplémentaire (par exemple [Beat](https://www.elastic.co/products)) pour partager des informations liées au matériel pour obtenir une image complète.
+
+
+
+### Exemple de surveillance : tableau de bord par défaut AWS cloudwatch. Difficile d'extraire des mesures intégrées à l'application
+
+
+
+
+
+### Exemple de surveillance : tableau de bord par défaut de StackDriver. Difficile d'extraire des mesures intégrées à l'application
+
+
+
+
+
+### Exemple de surveillance : Grafana comme couche d'interface utilisateur qui visualise les données brutes
+
+
+
+
+
+### Ce que disent les autres blogueurs
+
+Extrait du blog de [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/) :
+
+> …Nous vous recommandons de surveiller ces signaux pour tous vos services :
+> Taux d'erreur : parce que les erreurs sont confrontées à l'utilisateur et affectent immédiatement vos clients.
+> Temps de réponse : car la latence affecte directement vos clients et votre entreprise.
+> Débit : le trafic vous aide à comprendre le contexte de l'augmentation des taux d'erreur et de la latence également.
+> Saturation : il indique à quel point votre service est « saturé ». Si l'utilisation du processeur est de 90%, votre système peut-il gérer plus de trafic ? …
diff --git a/sections/production/monitoring.japanese.md b/sections/production/monitoring.japanese.md
new file mode 100644
index 000000000..b7c943718
--- /dev/null
+++ b/sections/production/monitoring.japanese.md
@@ -0,0 +1,38 @@
+# モニタリング!
+
+
+
+### 他のブロガーが言っていること
+
+[Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/) のブログより:
+
+> ...すべてのサービスのために、これらの信号を見ることをお勧めします:
+> エラー率: なぜなら、エラーはユーザーが直面するものであり、すぐに顧客に影響を与えるからです。
+> 応答時間: 待ち時間が直接顧客やビジネスに影響を与えるからです。
+> スループット: トラフィックは、エラー率と遅延の増加のコンテキストを理解するのに役立ちます。
+> 飽和: サービスがどの程度「フル」であるかを示します。CPU 使用率が 90% の場合、システムはより多くのトラフィックを処理できますか?…
diff --git a/sections/production/monitoring.korean.md b/sections/production/monitoring.korean.md
index 75b0f753e..8d05329ea 100644
--- a/sections/production/monitoring.korean.md
+++ b/sections/production/monitoring.korean.md
@@ -12,25 +12,25 @@ Achieving the advanced features demands lengthy setup or buying a commercial pro
### Monitoring example: AWS cloudwatch default dashboard. Hard to extract in-app metrics
-
+
### Monitoring example: StackDriver default dashboard. Hard to extract in-app metrics
-
+
### Monitoring example: Grafana as the UI layer that visualizes raw data
-
+
### What Other Bloggers Say
-From the blog [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
+From the blog [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/):
> …We recommend you to watch these signals for all of your services:
> Error Rate: Because errors are user facing and immediately affect your customers.
diff --git a/sections/production/monitoring.md b/sections/production/monitoring.md
index 75b0f753e..8d05329ea 100644
--- a/sections/production/monitoring.md
+++ b/sections/production/monitoring.md
@@ -12,25 +12,25 @@ Achieving the advanced features demands lengthy setup or buying a commercial pro
### Monitoring example: AWS cloudwatch default dashboard. Hard to extract in-app metrics
-
+
### Monitoring example: StackDriver default dashboard. Hard to extract in-app metrics
-
+
### Monitoring example: Grafana as the UI layer that visualizes raw data
-
+
### What Other Bloggers Say
-From the blog [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
+From the blog [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/):
> …We recommend you to watch these signals for all of your services:
> Error Rate: Because errors are user facing and immediately affect your customers.
diff --git a/sections/production/monitoring.polish.md b/sections/production/monitoring.polish.md
new file mode 100644
index 000000000..c5d39dd74
--- /dev/null
+++ b/sections/production/monitoring.polish.md
@@ -0,0 +1,39 @@
+# Monitorowanie!
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Na bardzo podstawowym poziomie monitorowanie oznacza *łatwe* rozpoznanie, kiedy coś złego dzieje się na produkcji. Na przykład, otrzymując powiadomienie e-mailem lub Slack. Wyzwanie polega na wybraniu odpowiedniego zestawu narzędzi, które spełnią Twoje wymagania bez rozbijania banku. Mogę zasugerować, zacznij od zdefiniowania podstawowego zestawu wskaźników, które należy obserwować, aby zapewnić zdrowy stan - procesor, pamięć RAM serwera, pamięć RAM procesu węzła (mniej niż 1,4 GB), liczba błędów w ostatniej chwili, liczba ponownych uruchomień procesu, średni czas reakcji. Następnie zapoznaj się z zaawansowanymi funkcjami, które mogą ci się spodobać, i dodaj do swojej listy życzeń. Niektóre przykłady luksusowej funkcji monitorowania: profilowanie BD, pomiar między usługami (tj. mierzenie transakcji biznesowej), integracja frontendu, udostępnianie surowych danych niestandardowym klientom BI, powiadomienia Slack i wiele innych.
+
+Osiągnięcie zaawansowanych funkcji wymaga długiej konfiguracji lub zakupu komercyjnego produktu, takiego jak Datadog, NewRelic i tym podobne. Niestety, osiągnięcie nawet podstaw nie jest spacerem w parku, ponieważ niektóre metryki są związane ze sprzętem (CPU), a inne żyją w procesie węzła (błędy wewnętrzne), dlatego wszystkie proste narzędzia wymagają dodatkowej konfiguracji. Na przykład rozwiązania do monitorowania dostawców w chmurze (np. [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) poinformują Cię natychmiast o metrykach sprzętowych, ale nie o wewnętrznym zachowaniu aplikacji. Z drugiej strony w rozwiązaniach opartych na logach, takich jak ElasticSearch, domyślnie brakuje widoku sprzętu. Rozwiązaniem jest zwiększenie wyboru o brakujące dane, na przykład popularnym wyborem jest wysyłanie dzienników aplikacji do [Elastic stack](https://www.elastic.co/products) i konfigurowanie dodatkowego agenta (np. [Beat](https://www.elastic.co/products)) w celu udostępnienia informacji związanych ze sprzętem w celu uzyskania pełnego obrazu.
+
+
+
+### Przykład monitorowania: domyślny pulpit nawigacyjny AWS Cloudwatch. Trudno wyodrębnić dane w aplikacji
+
+
+
+
+
+### Przykład monitorowania: domyślny pulpit nawigacyjny StackDriver. Trudno wyodrębnić dane w aplikacji
+
+
+
+
+
+### Przykład monitorowania: Grafana jako warstwa interfejsu użytkownika, która wizualizuje surowe dane
+
+
+
+
+
+### Co mówią inni blogerzy
+
+Z bloga [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/):
+
+> …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/monitoring.russian.md b/sections/production/monitoring.russian.md
index 834ac395f..20b3de311 100644
--- a/sections/production/monitoring.russian.md
+++ b/sections/production/monitoring.russian.md
@@ -12,25 +12,25 @@
### Пример мониторинга: панель инструментов AWS cloudwatch по умолчанию. Трудно извлечь метрики в приложении
-
+
### Пример мониторинга: панель мониторинга по умолчанию для StackDriver. Трудно извлечь метрики в приложении
-
+
### Пример мониторинга: Grafana как слой пользовательского интерфейса, который визуализирует необработанные данные
-
+
### Что говорят другие блоггеры
-Из блога [Rising Stack](http://mubaloo.com/best-practices-deploying-node-js-applications/):
+Из блога [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/):
> … Мы рекомендуем вам смотреть эти сигналы для всех ваших услуг:
> Частота ошибок: потому что ошибки связаны с пользователем и сразу же влияют на ваших клиентов.
diff --git a/sections/production/productioncode.basque.md b/sections/production/productioncode.basque.md
new file mode 100644
index 000000000..f06216754
--- /dev/null
+++ b/sections/production/productioncode.basque.md
@@ -0,0 +1,16 @@
+# Neurtu eta zaindu memoriaren erabilera
+
+
+
+### Azalpena
+
+Hona hemen produkzioaren mantentzean eta egonkortasunean asko eragiten duten garapen aholkuen zerrenda:
+
+- Hamabi faktoreen gida: ezagutu [hamabi faktoreen](https://12factor.net/) gida
+- Izan aberrigabea: ez gorde daturik tokiko web zerbitzari jakin batean (ikusi buleta bereizia: 'Izan aberrigabea)
+- Cachea: erabili asko cachea, baina inoiz ez huts eragin cache ez datorrelako bat
+- Probatu memoria: neurtu memoriaren erabilera eta ihesak zure garapen fluxuaren zati gisa; "memwatch" bezalako tresnek asko erraz dezakete zeregin hori
+- Izen funtzioak: gutxitu funtzio anonimoen erabilera (hau da, lineako deiak itzultzea), memoria profilatzaile tipiko batek metodoaren izen bakoitzeko memoria erabiliko baitu
+- Erabili CI tresnak: erabili CI tresna hutsegiteak antzemateko produkziora bidali aurretik. Adibidez, erabili ESLint erreferentzia erroreak eta zehaztu gabeko aldagaiak antzemateko. Erabili –trace-sync-io API sinkronoak erabiltzen dituen kodea identifikatzeko (bertsio asinkronoaren ordez)
+- Erregistratze zentzuzkoa: sartu egunkari adierazpen bakoitzean testuinguruaren informazioa ahal baduzu JSON formatuan, Elastic bezalako erregistroen tresnek propietate horiek bilatu ahal ditzaten (ikusi buleta bereizia 'Areagotu ikusgarritasuna erregistro adimendunak erabiliz'). Gainera, sartu eskaera bakoitza identifikatzen duen eta transakzioa deskribatzen duten lerroak erlazionatzeko aukera ematen duen transakzio IDa (ikusi buleta bereizia: 'Sartu Transakzio IDa')
+- Akatsen kudeaketa: erroreen tratamendua Akilesen orpoa da Node.js ekoizpen guneetan. Noderen prozesu asko blokeatzen dira errore txikien ondorioz, beste batzuek bizirik jarraitzen duten bitartean errore egoeran, huts egin beharrean. Oso garrantzitsua da erabakitzea zer estrategia jarraituko duzun erroreak kudeatzeko. Irakurri hemen nire [praktika onak erroreak kudeatzeko](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
diff --git a/sections/production/productioncode.french.md b/sections/production/productioncode.french.md
new file mode 100644
index 000000000..e9e44d09c
--- /dev/null
+++ b/sections/production/productioncode.french.md
@@ -0,0 +1,16 @@
+# Préparez votre code pour la production
+
+
+
+### Un paragraphe d'explication
+
+Voici une liste de conseils de développement qui ont un impact important sur la maintenance et la stabilité de la production :
+
+* Le guide douze facteurs – Familiarisez-vous avec le guide [Douze facteurs](https://12factor.net/fr/)
+* Soyez sans état – N'enregistrez aucune donnée localement sur un serveur web spécifique (consultez le point – « Soyez sans état »)
+* Mettez en cache – Utilisez beaucoup le cache, mais ne faites jamais échouer en raison de la non-concordance du cache
+* Testez la mémoire – Mesurez l'utilisation de la mémoire et les fuites dans le cadre de votre flux de développement, des outils tels que « memwatch » peuvent grandement faciliter cette tâche
+* Nommez les fonctions – Minimisez l'utilisation des fonctions anonymes (c'est à dire de fonction de rappel en ligne) car un profileur de mémoire classique fournit l'utilisation de la mémoire avec le nom de la méthode
+* Utilisez les outils CI – Utilisez l'outil CI pour détecter les échecs avant d'envoyer en production. Par exemple, utilisez ESLint pour détecter les erreurs de référence et les variables non définies. Utilisez –trace-sync-io pour identifier le code qui utilise des API synchrones (au lieu de la version asynchrone)
+* Journalisez à bon escient – Incluez dans le journal des informations contextuelles pour chaque instruction, si possible au format JSON, afin que les outils d'agrégation de journaux tels qu'Elastic puissent rechercher ces propriétés (consultez le point - « Augmentez la clarté à l'aide de la journalisation intelligente »). Incluez également l'ID de transaction qui identifie chaque requête et permet de corréler les lignes qui décrivent la même transaction (consultez le point - « Attribuez un ID de transaction à chaque relevé du journal »)
+* Gérez les erreurs – La gestion des erreurs est le talon d'Achille des sites de production de Node.js - de nombreux processus Node se bloquent en raison d'erreurs mineures tandis que d'autres restent en vie dans un état défectueux au lieu de se bloquer. La définition de votre stratégie de traitement des erreurs est absolument essentielle, lisez ici mes [meilleures pratiques de gestion des erreurs](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
diff --git a/sections/production/productioncode.japanese.md b/sections/production/productioncode.japanese.md
new file mode 100644
index 000000000..7a17971a1
--- /dev/null
+++ b/sections/production/productioncode.japanese.md
@@ -0,0 +1,16 @@
+# コードを本番に即したものにする
+
+
+
+### 一段落説明
+
+以下は、プロダクションのメンテナンスと安定性に大きく影響する開発のヒントのリストです。:
+
+* 12要素ガイド – [12要素](https://12factor.net/)のガイドに慣れる
+* ステートレスであれ – 特定の Web サーバーにデータをローカルに保存しない (別箇条を参照してください – 「ステートレスであれ」)
+* キャッシュ – キャッシュを多用しているが、キャッシュの不一致で失敗することはない
+* テストメモリ – 開発フローの一部としてメモリ使用量やリークを測定し、「memwatch」などのツールがこのタスクを大幅に促進します。
+* 関数に名前をつける – 一般的なメモリプロファイラでは、メソッド名ごとにメモリ使用量が表示されるため、匿名関数(インラインコールバックなど)の使用を最小限に抑えます。
+* CI ツールを使用する – CI ツールを使って、本番に送る前に失敗を検出する。例えば、ESLint を使って参照エラーや未定義変数を検出します。同期 API を使用するコードを識別するために -trace-sync-io を使用します (非同期バージョンではなく)。
+* 賢くログを取る – Elastic のようなログアグリゲータツールがそれらのプロパティを検索できるように、各ログ文にコンテキスト情報を含めて、できれば JSON 形式で表示してください(別項「スマートログを使った可視性の向上」を参照)。また、各リクエストを識別するトランザクション ID を含め、同じトランザクションを記述する行を関連付けることができます(別項の「トランザクション ID を含める」を参照)。
+* エラー管理 – エラー処理は Node.js プロダクションサイトのアキレス腱です。 – 多くのノードプロセスは小さなエラーのためにクラッシュしていますが、他のプロセスはクラッシュせずに障害のある状態で生き残っています。エラー処理戦略を設定することは絶対に重要です。私の [エラー処理のベストプラクティス](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/) を読んでください。
diff --git a/sections/production/productioncode.md b/sections/production/productioncode.md
index a86047312..6fb624a6c 100644
--- a/sections/production/productioncode.md
+++ b/sections/production/productioncode.md
@@ -6,11 +6,12 @@
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/)
+- 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’)
+- Test like production - Make developers machine quite close to the production infrastructure (e.g., with Docker-Compose). Avoid if/else clauses in testing that check if we're in testing environment but rather run the same code always
+- 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/productioncode.polish.md b/sections/production/productioncode.polish.md
new file mode 100644
index 000000000..15a7b856d
--- /dev/null
+++ b/sections/production/productioncode.polish.md
@@ -0,0 +1,16 @@
+# Przygotuj kod do produkcji
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Poniżej znajduje się lista wskazówek programistycznych, które znacznie wpływają na utrzymanie produkcji i stabilność:
+
+* Dwunastoczęściowy przewodnik - zapoznaj się z przewodnikiem [Dwanaście czynników](https://12factor.net/)
+* Bądź bezstanowy - nie zapisuj danych lokalnie na określonym serwerze internetowym (patrz oddzielny punkt - „Bądź bezstanowy”)
+* Pamięć podręczna - mocno wykorzystuj pamięć podręczną, ale nigdy nie zawiedzie z powodu niedopasowania pamięci podręcznej
+* Pamięć testowa - mierzy zużycie pamięci i wycieki w ramach rozwoju, narzędzia takie jak „memwatch” mogą znacznie ułatwić to zadanie
+* Funkcje nazw - zminimalizuj użycie funkcji anonimowych (tj. wbudowane wywołanie zwrotne), ponieważ typowy profiler pamięci zapewni użycie pamięci według nazwy metody
+* Użyj narzędzi CI - użyj narzędzia CI do wykrywania awarii przed wysłaniem do produkcji. Na przykład użyj ESLint do wykrywania błędów odniesienia i niezdefiniowanych zmiennych. Użyj –trace-sync-io, aby zidentyfikować kod korzystający z synchronicznych interfejsów API (zamiast wersji asynchronicznej)
+* Loguj mądrze - dołącz do każdej informacji kontekstowej instrukcji dziennika, miejmy nadzieję w formacie JSON, aby narzędzia agregujące logi, takie jak Elastic, mogły przeszukiwać te właściwości (patrz oddzielny punkt - „Zwiększ widoczność za pomocą inteligentnych logów”). Dołącz także identyfikator transakcji, który identyfikuje każde żądanie i pozwala na korelację wierszy opisujących tę samą transakcję (patrz oddzielny punkt - „Dołącz identyfikator transakcji”)
+* Zarządzanie błędami - obsługa błędów to pięta achillesowa witryn produkcyjnych Node.js - wiele procesów Node ulega awarii z powodu drobnych błędów, podczas gdy inne zawieszają się żywe w wadliwym stanie zamiast awarii. Ustawienie strategii obsługi błędów jest absolutnie niezbędne, przeczytaj tutaj moje [najlepsze praktyki obsługi błędów](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
diff --git a/sections/production/setnodeenv.basque.md b/sections/production/setnodeenv.basque.md
new file mode 100644
index 000000000..87d0d9286
--- /dev/null
+++ b/sections/production/setnodeenv.basque.md
@@ -0,0 +1,35 @@
+# Ezarri NODE_ENV = produkzioa
+
+
+
+### Azalpena
+
+Prozesuaren ingurune aldagaiak balio giltzen bikoteen multzo bat dira, eskuarki ezarpenetan erabiltzen direnak eta exekutatzen ari den edozein programatan eskuragarri daudenak.
+Edozein aldagai erabil daitekeen arren, Nodek NODE_ENV izeneko aldagaia erabilera bultzatzen du, oraintxe bertan ekoizten ari garen ala ez adierazteko. Determinazio horri esker, osagaiek diagnostiko hobeak egin ditzakete garapenean zehar, adibidez cachea desgaituz edo hitz erregistroen adierazpenak igorriz. Edozein ezarpen tresna modernok (Chef, Puppet, CloudFormation, besteak) inguruneko aldagaiak ezartzea onartzen du hedapenean.
+
+
+
+### Kode adibidea: NODE_ENV ingurumen aldagaia ezarri eta irakurtzea
+
+```shell script
+// Ingurumen aldagaiak bash-en ezarri node prozesua hasi aurretik
+$ NODE_ENV=development
+$ node
+```
+
+```javascript
+// Kodea erabiliz ingurumen aldagaia irakurri
+if (process.env.NODE_ENV === "production") useCaching = true;
+```
+
+
+
+### Beste blogari batzuek diotena
+
+[Dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) bloga:
+
+> ...Node.jsk badu uneko modua ezartzean NODE_ENV izeneko aldagaia erabiltzeko konbentzioa. Izan ere, NODE_ENV irakurtzen du eta, konfiguratuta ez badago, 'garapena' ezarpena lehenesten dio. Argi ikusten dugu NODE_ENV ekoizpenean ezartzean, Node.jsk kudea dezakeen eskaera kopurua bi heren inguruko hazkundea duela PUZaren erabilera zertxobait jaisten den bitartean. _Azpimarratu beharra dago NODE_ENV ekoizpenean ezartzeak zure aplikazioa 3 aldiz azkarragoa bihurtzen duela._
+
+
+
+
diff --git a/sections/production/setnodeenv.brazilian-portuguese.md b/sections/production/setnodeenv.brazilian-portuguese.md
index dc0637487..8059ed20b 100644
--- a/sections/production/setnodeenv.brazilian-portuguese.md
+++ b/sections/production/setnodeenv.brazilian-portuguese.md
@@ -27,6 +27,6 @@ if (process.env.NODE_ENV === “production”)
Do blog [dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
> ...No Node.js há uma convenção para usar uma variável chamada NODE_ENV para definir o modo atual. Vimos que, de fato, NODE_ENV é lida e o padrão é "development", se não estiver definido. Observamos claramente que, configurando NODE_ENV para produção, o número de requisições que o Node.js pode manipular aumenta em cerca de dois terços, enquanto o uso da CPU cai um pouco. Deixe-me enfatizar isso: A configuração NODE_ENV para produção torna sua aplicação 3 vezes mais rápida!*
-
+
diff --git a/sections/production/setnodeenv.french.md b/sections/production/setnodeenv.french.md
new file mode 100644
index 000000000..ceb10410a
--- /dev/null
+++ b/sections/production/setnodeenv.french.md
@@ -0,0 +1,34 @@
+# Définissez NODE_ENV = production
+
+
+
+### Un paragraphe d'explication
+
+Les variables d'environnement de processus sont un ensemble de paires de clé-valeur mises à la disposition de tout programme en cours d'exécution, généralement à des fins de configuration. Bien que toutes les variables puissent être utilisées, Node encourage d'utiliser par convention une variable appelée NODE_ENV pour signaler si nous sommes en production en ce moment. Cette indication permet aux composants de fournir de meilleurs diagnostics pendant le développement, par exemple en désactivant la mise en cache ou en diffusant des déclarations verbeuses dans le journal. Tout outil de déploiement moderne (Chef, Puppet, CloudFormation, autres) permet de définir des variables d'environnement pendant le déploiement.
+
+
+
+### Exemple de code : définition et lecture de la variable d'environnement NODE_ENV
+
+```shell script
+// Définition des variables d environnement en bash avant de lancer le processus node
+$ NODE_ENV=development
+$ node
+```
+
+```javascript
+// Lecture de la variable d'environnement à l'aide d'un code
+if (process.env.NODE_ENV === 'production')
+ useCaching = true;
+```
+
+
+
+### Ce que disent les autres blogueurs
+
+Extrait du blog de [dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) :
+> ...Dans Node.js, il y a une convention pour définir le mode actuel, c'est d'utiliser une variable appelée NODE_ENV. Nous constatons qu'en fait, il lit NODE_ENV et se met par défaut en « development » si elle n'est pas définie. Nous voyons clairement qu'en définissant NODE_ENV sur production, le nombre de requêtes que Node.js peut traiter augmente d'environ deux tiers alors que l'utilisation du CPU diminue même légèrement. *Permettez-moi d'insister sur ce point : en mettant NODE_ENV sur production, votre application est 3 fois plus rapide !*
+
+
+
+
diff --git a/sections/production/setnodeenv.japanese.md b/sections/production/setnodeenv.japanese.md
new file mode 100644
index 000000000..f5ac6219a
--- /dev/null
+++ b/sections/production/setnodeenv.japanese.md
@@ -0,0 +1,34 @@
+# NODE_ENV = production を設定する
+
+
diff --git a/sections/production/setnodeenv.korean.md b/sections/production/setnodeenv.korean.md
index 31bd6d017..c2ab68c0d 100644
--- a/sections/production/setnodeenv.korean.md
+++ b/sections/production/setnodeenv.korean.md
@@ -27,6 +27,6 @@ if (process.env.NODE_ENV === “production”)
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!*
-
+
diff --git a/sections/production/setnodeenv.md b/sections/production/setnodeenv.md
index 4c721fec4..59337b215 100644
--- a/sections/production/setnodeenv.md
+++ b/sections/production/setnodeenv.md
@@ -29,6 +29,12 @@ if (process.env.NODE_ENV === 'production')
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!*
-
+
+
+
+
+
+From the Synk blog [10 best practices to containerize Node.js web applications with Docker](https://snyk.io/blog/10-best-practices-to-containerize-nodejs-web-applications-with-docker/#:~:text=Some%20frameworks%20and,As%20an%20example):
+> ...Some frameworks and libraries may only turn on the optimized configuration that is suited to production if that NODE_ENV environment variable is set to production. Putting aside our opinion on whether this is a good or bad practice for frameworks to take, it is important to know this.
diff --git a/sections/production/setnodeenv.polish.md b/sections/production/setnodeenv.polish.md
new file mode 100644
index 000000000..5e5465fe2
--- /dev/null
+++ b/sections/production/setnodeenv.polish.md
@@ -0,0 +1,34 @@
+# Ustaw NODE_ENV = production
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Procesowe zmienne środowiskowe to zestaw par klucz-wartość udostępniony dowolnemu działającemu programowi, zwykle w celach konfiguracyjnych. Mimo że można używać dowolnych zmiennych, Node zachęca do korzystania ze zmiennej o nazwie NODE_ENV w celu oznaczenia, czy obecnie jesteśmy w produkcji. To określenie umożliwia komponentom lepszą diagnostykę podczas programowania, na przykład poprzez wyłączenie buforowania lub wysyłanie pełnych instrukcji dziennika. Każde nowoczesne narzędzie do wdrażania - Chef, Puppet, CloudFormation i inne - obsługuje ustawianie zmiennych środowiskowych podczas wdrażania
+
+
+
+### Przykład kodu: ustawianie i odczytywanie zmiennej środowiskowej NODE_ENV
+
+```shell script
+// Setting environment variables in bash before starting the node process
+$ NODE_ENV=development
+$ node
+```
+
+```javascript
+// Reading the environment variable using code
+if (process.env.NODE_ENV === 'production')
+ useCaching = true;
+```
+
+
+
+### Co mówią inni blogerzy
+
+Z bloga [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!*
+
+
+
+
diff --git a/sections/production/setnodeenv.russian.md b/sections/production/setnodeenv.russian.md
index 8ed8111e6..caa69364e 100644
--- a/sections/production/setnodeenv.russian.md
+++ b/sections/production/setnodeenv.russian.md
@@ -10,13 +10,15 @@
### Пример кода: установка и чтение переменной среды NODE_ENV
-```javascript
+```shell script
// Setting environment variables in bash before starting the node process
$ NODE_ENV=development
$ node
+```
+```javascript
// Reading the environment variable using code
-if (process.env.NODE_ENV === “production”)
+if (process.env.NODE_ENV === 'production')
useCaching = true;
```
@@ -27,6 +29,6 @@ if (process.env.NODE_ENV === “production”)
Из блога [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 в рабочее состояние, количество запросов Node.js может обрабатывать скачки примерно на две трети, в то время как загрузка ЦП даже немного падает. *Позвольте мне подчеркнуть это: установка NODE_ENV в рабочий режим делает ваше приложение в 3 раза быстрее!*
-
+
diff --git a/sections/production/smartlogging.basque.md b/sections/production/smartlogging.basque.md
new file mode 100644
index 000000000..3810526f0
--- /dev/null
+++ b/sections/production/smartlogging.basque.md
@@ -0,0 +1,41 @@
+# Gardentasuna handitu erregistratze plataforma adimendunak erabiliz
+
+
+
+### Azalpena
+
+Erregistroen adierazpenak inprimatzen dituzu eta, jakina, produkzioari buruzko informazioa biltzen duen interfazearen beharra duzu, erroreen eta oinarrizko metriken jarraipena egiteko (adibidez, zenbat errore gertatzen diren orduoro eta zein den APIaren amaierako puntu motelena). Hori horrela izanik, zergatik ez duzu ahalegin neurritsua egiten laukitxo guztiak markatuko dituen erregistro esparru sendo batean? Hori lortzeko, gogoeta egin eta erabakia hiru urratsetan hartu behar duzu:
+
+**1. Erregistro adimenduna:** gutxi-gutxienez [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) bezalako erregistro liburutegi entzutetsuren bat erabili behar duzu eta transakzio bakoitzaren hasieran eta amaieran informazio esanguratsua idatzi. Pentsatu ez ote den komeni, eragiketa taldeak eremu horietan jardun dezan, erregistro adierazpenak JSON gisa formateatzea eta testuinguruaren propietate guztiak eskaintzea (adibidez, erabiltzailearen IDa, eragiketa mota, etab.). Sartu transakzio ID bakarra erregistro lerro bakoitzean. Informazio gehiago nahi izanez gero, idatzi "Idatzi transakzio id-a erregistroan" azpian dagoen bulletean. Azkenik, kontuan hartu behar da ez ote den komeni sistemaren baliabideak erregistratuko dituen eragileren bat (memoria, adibidez) eta PUZa (Elastic Beat, esaterako) sartzea.
+
+**2. Agregazio adimenduna:** zure zerbitzariaren fitxategi sisteman informazio zabala eskuratu duzunean, garaia da aldizka datu horiek agregatu, erraztu eta bistaratzen dituen sistema batera bultzatzeko. Pila elastikoa, adibidez, oso aukera popularra eta ezaguna da, datuak bildu eta bistaratzeko osagai guztiak eskaintzen dituena. Produktu komertzial askok antzeko funtzionalitatea eskaintzen dute, baina konfigurazio denbora asko murrizten dute eta ez dute ostatatu beharrik.
+
+**3. Bistaratze adimenduna:** orain informazioa batu eta bila daiteke; bat pozik egon daiteke erregistroak erraz bilatzeko ahalmena duelako bakarrik; baina hori askoz ere gehiago lor daiteke kodetu beharrik izan gabe edo ahalegin handirik egin gabe. Orain metrika operatibo garrantzitsuak erakusteko moduan gaude: hala nola, errore tasa, batez besteko PUZa egunean zehar, zenbat erabiltzaile berri sartu diren azken orduan eta gure aplikazioa gobernatzen eta hobetzen laguntzen duen beste edozein metrika.
+
+
+
+### Bistaratze adibidea: Kibana-k (Elastic stack-en zati bat) erregistroen edukian bilaketa aurreratua errazten du
+
+ erregistroen edukian bilaketa aurreratua errazten du")
+
+
+
+### Bistaratze adibidea: Kibana-k (Elastic stack-eko zati bat) erregistroetan oinarritutako datuak bistaratzen ditu
+
+ erregistroetan oinarritutako datuak bistaratzen ditu")
+
+
+
+### Blogeko aipua: erregistroaren eskakizunak
+
+[Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/) bloga
+
+> Hona hemen jarraibide batzuk (erregistratzaile batentzat):
+>
+> 1. Erregistro lerro bakoitzeko denbora marka. Hau nahiko argia da, erregistro sarrera bakoitza noiz gertatu den jakin beharko zenuke.
+> 2. Gizakiek nahiz makinek erraz uler dezakete Erregistro formatua.
+> 3. Konfiguragarriak diren hainbat helmuga fluxu izateko aukera ematen du. Adibidez, erroreren bat gertatzen bada jarraipen erregistroak idazten ari zarenean fitxategi batean, lehenengo idatzi fitxategi horretan eta gero errore fitxategian, eta bidali mezu elektronikoa aldi berean ...
+
+
+
+
diff --git a/sections/production/smartlogging.brazilian-portuguese.md b/sections/production/smartlogging.brazilian-portuguese.md
index d1ccbaac4..02c88711f 100644
--- a/sections/production/smartlogging.brazilian-portuguese.md
+++ b/sections/production/smartlogging.brazilian-portuguese.md
@@ -16,13 +16,13 @@ Já que você imprime declarações de log de qualquer maneira e obviamente prec
### Exemplo de visualização: Kibana (parte do stack Elastic) facilita a pesquisa avançada no conteúdo do log
-
+
### Exemplo de visualização: Kibana (parte do stack Elastic) visualiza dados com base em logs
-
+
diff --git a/sections/production/smartlogging.chinese.md b/sections/production/smartlogging.chinese.md
index 6824835aa..9bd9ced11 100644
--- a/sections/production/smartlogging.chinese.md
+++ b/sections/production/smartlogging.chinese.md
@@ -17,12 +17,12 @@
### 可视化示例: Kibana(Elastic stack的一部分)促进了对日志内容的高级搜索
-
+
### 可视化示例: Kibana(Elastic stack的一部分)基于日志来可视化数据
-
+
diff --git a/sections/production/smartlogging.french.md b/sections/production/smartlogging.french.md
new file mode 100644
index 000000000..ff1fbe0d3
--- /dev/null
+++ b/sections/production/smartlogging.french.md
@@ -0,0 +1,40 @@
+# Rendez votre application plus claire à l'aide de journaux intelligents
+
+
+
+### Un paragraphe d'explication
+
+Puisque vous produisez de toute façon des relevés de log et que vous avez manifestement besoin d'une interface qui regroupe les informations de production et qui vous permette de suivre les erreurs et les mesures de base (par exemple, combien d'erreurs se produisent chaque heure ? Quel est le point de terminaison de votre API le plus lent ?), pourquoi ne pas investir un effort modéré dans un framework robuste de log qui cochera toutes les cases ? Pour y parvenir, il faut prendre une décision réfléchie en trois étapes :
+
+**1. enregistrement intelligent** – au minimum, vous devez utiliser une bibliothèque de journalisation réputée comme [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) et écrire des informations significatives à chaque début et fin de transaction. Pensez également à formater les relevés du journal en JSON et à fournir toutes les propriétés contextuelles (par exemple, l'ID utilisateur, le type d'opération, etc.) afin que l'équipe d'exploitation puisse agir sur ces champs. Incluez également un ID de transaction unique sur chaque ligne de journal, pour plus d'informations, reportez-vous à l'un des points suivants « Attribuez un ID de transaction à chaque relevé du journal ». Un dernier point à considérer, c'est également d'inclure un agent qui enregistre les ressources système de la mémoire et du processeur comme Elastic Beat.
+
+**2. agrégation intelligente** – une fois que vous disposez d'informations complètes sur le système de fichiers de votre serveur, il est temps de les pousser périodiquement vers un système qui agrège, facilite et visualise ces données. Elastic stack, par exemple, est un choix populaire et gratuit qui offre tous les composants pour agréger et visualiser les données. De nombreux produits commerciaux offrent des fonctionnalités similaires, mais ils réduisent considérablement le temps d'installation et ne nécessitent pas d'hébergement.
+
+**3. visualisation intelligente** – maintenant que l'information est agrégée et consultable, on ne peut être que satisfait de la puissance d'une recherche facile dans les logs mais cela peut aller beaucoup plus loin sans codage ni effort. Nous pouvons maintenant afficher d'importantes mesures opérationnelles comme le taux d'erreur, le CPU moyen au cours de la journée, le nombre de nouveaux utilisateurs qui se sont inscrits au cours de la dernière heure et toute autre mesure qui aide à gérer et à améliorer notre application.
+
+
+
+### Exemple de visualisation : Kibana (faisant partie de Elastic stack) facilite la recherche avancée sur le contenu des journaux
+
+
+
+
+
+### Exemple de visualisation : Kibana (qui fait partie de Elastic stack) visualise les données sur la base des journaux
+
+
+
+
+
+### Citation de blog : « Exigences pour un enregistreur de journal »
+
+Extrait du blog [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/) :
+
+> Permet d'identifier quelques exigences (pour un outil de journalisation) :
+1. Chaque ligne du journal est horodatée. Celle-ci est assez explicite - vous devriez pouvoir dire quand chaque entrée du journal s'est produite.
+2. Le format d'enregistrement doit être facilement assimilable par les humains ainsi que par les machines.
+3. Permet plusieurs flux de destination configurables. Par exemple, vous pouvez écrire des journaux de trace dans un fichier, mais lorsqu'une erreur se produit, cela écrit dans le même fichier, puis dans le fichier d'erreur et envoi un e-mail en même temps…
+
+
diff --git a/sections/production/smartlogging.korean.md b/sections/production/smartlogging.korean.md
index bcb7bc4af..6983967e7 100644
--- a/sections/production/smartlogging.korean.md
+++ b/sections/production/smartlogging.korean.md
@@ -16,13 +16,13 @@ Since you print out log statements anyway and you're obviously in a need of some
### Visualization Example: Kibana (part of the Elastic stack) facilitates advanced searching on log content
-
+
### Visualization Example: Kibana (part of the Elastic stack) visualizes data based on logs
-
+
diff --git a/sections/production/smartlogging.md b/sections/production/smartlogging.md
index bcb7bc4af..b67db66a9 100644
--- a/sections/production/smartlogging.md
+++ b/sections/production/smartlogging.md
@@ -8,21 +8,21 @@ Since you print out log statements anyway and you're obviously in a need of some
**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.
+**2. smart aggregation** – once you have comprehensive information on your server's file system, it’s time to periodically push these to a system that aggregates, facilitates 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
+**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
-
+
### Visualization Example: Kibana (part of the Elastic stack) visualizes data based on logs
-
+
diff --git a/sections/production/smartlogging.polish.md b/sections/production/smartlogging.polish.md
new file mode 100644
index 000000000..72f600c78
--- /dev/null
+++ b/sections/production/smartlogging.polish.md
@@ -0,0 +1,40 @@
+# Uczyń swoją aplikację przejrzystą za pomocą inteligentnych dzienników
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Ponieważ i tak drukujesz instrukcje dziennika i oczywiście potrzebujesz interfejsu, który zawija informacje produkcyjne, w których możesz śledzić błędy i podstawowe dane (np. ile błędów występuje co godzinę i który jest twój najwolniejszy punkt końcowy interfejsu API), dlaczego nie inwestować umiarkowanych wysiłków w solidne ramy rejestrowania, które zaznaczą wszystkie pola? Osiągnięcie tego wymaga przemyślanej decyzji w trzech krokach:
+
+**1. smart logging** – co najmniej musisz korzystać z renomowanej biblioteki rejestrowania, takiej jak [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) i pisać istotne informacje na początku i na końcu każdej transakcji. Rozważ także sformatowanie instrukcji dziennika jako JSON i zapewnienie wszystkich właściwości kontekstowych (np. identyfikator użytkownika, typ operacji itp.), aby zespół operacyjny mógł działać na tych polach. Dołącz także unikalny identyfikator transakcji w każdym wierszu dziennika, aby uzyskać więcej informacji, patrz punkt poniżej „Zapisuj identyfikator transakcji do dziennika”. Ostatnim punktem, który należy wziąć pod uwagę, jest także agent rejestrujący zasoby systemowe, takie jak pamięć i procesor, takie jak Elastic Beat.
+
+**2. smart aggregation** – po uzyskaniu wyczerpujących informacji o systemie plików serwerów nadszedł czas, aby okresowo przekazywać je do systemu, który agreguje, udostępnia i wizualizuje te dane. Na przykład Elastic stack jest popularnym i bezpłatnym wyborem, który oferuje wszystkie komponenty do agregowania i wizualizacji danych. Wiele komercyjnych produktów zapewnia podobną funkcjonalność, ale znacznie skraca czas instalacji i nie wymaga hostingu.
+
+**3. smart visualization** – teraz informacje są agregowane i możliwe do przeszukiwania, można zadowolić się jedynie mocą łatwego przeszukiwania dzienników, ale może to pójść znacznie dalej bez kodowania lub nakładania dużego wysiłku. Możemy teraz wyświetlać ważne wskaźniki operacyjne, takie jak wskaźnik błędów, średni procesor w ciągu dnia, ilu nowych użytkowników wyraziło zgodę w ciągu ostatniej godziny oraz wszelkie inne dane, które pomagają zarządzać naszą aplikacją i ją ulepszać
+
+
+
+### Przykład wizualizacji: Kibana (część Elastic stack) ułatwia zaawansowane wyszukiwanie zawartości dziennika
+
+
+
+
+
+### Przykład wizualizacji: Kibana (część Elastic stack) wizualizuje dane na podstawie logów
+
+
+
+
+
+### Cytat na blogu: Logger Requirements
+
+Z bloga [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/smartlogging.russian.md b/sections/production/smartlogging.russian.md
index ca2f0046a..4f7bd482f 100644
--- a/sections/production/smartlogging.russian.md
+++ b/sections/production/smartlogging.russian.md
@@ -16,13 +16,13 @@
### Пример визуализации: Kibana (часть стека Elastic) облегчает расширенный поиск по содержимому журнала
-
+
### Пример визуализации: Kibana (часть стека Elastic) визуализирует данные на основе журналов
-
+
diff --git a/sections/production/utilizecpu.basque.md b/sections/production/utilizecpu.basque.md
new file mode 100644
index 000000000..17bae37de
--- /dev/null
+++ b/sections/production/utilizecpu.basque.md
@@ -0,0 +1,31 @@
+# Erabili PUZeko nukleo guztiak
+
+
+
+### Azalpena
+
+Agian ez da harritzekoa Nodek, bere oinarrizko forman, hari bakarra = prozesu bakarra = PUZ bakarra exekutatzea. 4 edo 8 PUZeko hardware sendoa ordaintzea eta bakarra erabiltzea zoragarria da, ezta? Node Cluster modulua da tamaina ertaineko aplikazioetara egokitzen den irtenbiderik azkarrena. 10 kode lerrotan nukleo logiko bakoitzerako prozesua sortzen du eta prozesuen arteko eskaerak biribilgune estiloan (round-robin) bideratzen ditu. Are hobe, erabili PM2, izan ere, monitoretzako erabiltzailearen interfaze soil eta ezin hobearekin biltzen baitu kluster modulua. Soluzio horrek ohiko aplikazioetan ondo funtzionatzen duen arren, gerta liteke eskas ibiltzea goi mailako errendimendua eta DevOps fluxu sendoa eskatzen duten aplikazioetan. Erabilera aurreratuetarako, aztertu ez ote zaizun komeni Node prozesua erreplikatzea pertsonalizatutako inplementazioko scripten baten bidez, eta orekatzea nginx bezalako tresna espezializatuak erabiliz; edo, bestela, erabili AWS ECS edo Kubernetees bezalako edukiontzi motorren bat prozesuak inplementatzeko eta erreplikatzeko, oso ezaugarri aurreratuak dituzte eta.
+
+Erabilera aurreratuen kasuetarako, pentsa ezazu NODE prozesua errepikatzea pertsonalizatutako inplementazioko scriptaren bidez eta orekatu nginx bezalako tresna espezializatua erabiliz edo erabili edukiontzi motorra, hala nola AWS ECS edo Kubernetees, prozesuak inplementatzeko eta erreplikatzeko ezaugarri aurreratuak dituztenak.
+
+
+
+### Alderaketa: Noderen klusterra versus nginx
+
+
+
+
+
+### Beste blogari batzuek diotena
+
+- [Node.jsren dokumentazioa](https://nodejs.org/api/cluster.html#cluster_how_it_works):
+
+> ... Bigarren planteamendua, teorian Node klusterrak eman beharko luke errendimendu onena. Praktikan, ordea, banaketa oso desorekatua izan ohi da sistema eragilearen antolatzaileen gorabeheren ondorioz. Atzeman da hainbat kasutan konexio guztien % 70a baino gehiago kargak bi prozesutan soilik egin direla, zortzitan egin beharrean...
+
+- [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/) bloga:
+
+> ... Noderen kluster moduluarekin posible da klusterrak batzea. Horrek ahalbidetzen du prozesu maisu batek lan prozesuak sortzea eta sarrerako konexioak langileen artean banatzea. Hala ere, modulu hori zuzenean erabiltzea baino hobe da lan hori automatikoki egiten duten tresna ugarietako bat erabiltzea; adibidez, node-pm edo cluster-service ...
+
+- Medium blogeko [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) artikulua:
+
+> ... Noderen klusterra erraza da inplementatzen eta konfiguratzen. Izan ere, osagaiak Noderen eremuan gordetzen dira beste software baten menpe egon gabe. Gogoratu zure prozesu nagusiak zure langile prozesuak bezainbeste funtzionatuko duela, eta bere eskaera tasa beste irtenbideena baino apur bat txikiagoa izango dela ...
diff --git a/sections/production/utilizecpu.brazilian-portuguese.md b/sections/production/utilizecpu.brazilian-portuguese.md
index 910b7278d..e1df7b19c 100644
--- a/sections/production/utilizecpu.brazilian-portuguese.md
+++ b/sections/production/utilizecpu.brazilian-portuguese.md
@@ -10,7 +10,7 @@ Pode não ser uma surpresa que, em sua forma básica, o Node seja executado em u
### Comparação: balanceamento usando o cluster do Node versus o nginx
-
+
diff --git a/sections/production/utilizecpu.chinese.md b/sections/production/utilizecpu.chinese.md
index 027a459af..9255adbb4 100644
--- a/sections/production/utilizecpu.chinese.md
+++ b/sections/production/utilizecpu.chinese.md
@@ -13,7 +13,7 @@
### 比较:使用Node的clustre vs nginx做负载均衡
-
+
diff --git a/sections/production/utilizecpu.french.md b/sections/production/utilizecpu.french.md
new file mode 100644
index 000000000..695631f50
--- /dev/null
+++ b/sections/production/utilizecpu.french.md
@@ -0,0 +1,26 @@
+# Utilisez tous les cœurs du CPU
+
+
+
+### Un paragraphe d'explication
+
+Il n'est pas surprenant que dans sa forme de base, Node fonctionne sur un unique thread=un unique processus=un seul CPU. Payer pour du matériel costaud avec 4 ou 8 CPU et n'en utiliser qu'un seul semble fou, non ? La solution la plus rapide qui convient aux applications de taille moyenne est l'utilisation du module Cluster de Node qui, en 10 lignes de code, génère un processus pour chaque cœur logique et achemine les requêtes entre les processus dans un style à tour de rôle. Mieux encore, utilisez PM2 qui enrobe le module de clustering avec une interface simple et une interface utilisateur de surveillance sympa. Bien que cette solution fonctionne bien pour les applications traditionnelles, elle pourrait ne pas convenir aux applications qui exigent des performances de premier ordre et un flux DevOps robuste. Pour ces cas d'utilisation avancés, envisagez de répliquer le processus NODE à l'aide d'un script de déploiement personnalisé et d'équilibrage (NdT, « balancing ») en utilisant un outil spécialisé tel que nginx ou utilisez un moteur de conteneur tel que AWS ECS ou Kubernetees qui disposent de fonctionnalités avancées pour le déploiement et la réplication des processus.
+
+
+
+### Comparaison : équilibrage à l'aide du cluster de Node vs nginx
+
+
+
+
+
+### Ce que disent les autres blogueurs
+
+* Extrait de la [documentation de Node.js](https://nodejs.org/api/cluster.html#cluster_how_it_works):
+> ... La seconde approche, les clusters de Node, devrait, en théorie, donner les meilleures performances. Dans la pratique, cependant, la distribution a tendance à être très déséquilibrée en raison des aléas du planificateur du système d'exploitation. Des charges ont été observées où plus de 70% de toutes les connexions se sont uniquement terminées sur deux processus, sur un total de huit ...
+
+* Extrait du blog de [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
+> ... Le clustering est rendu possible avec le module de cluster de Node. Cela permet à un processus maître de générer des processus de travail et de répartir les connexions entrantes entre les processus de travail. Cependant, plutôt que d'utiliser directement ce module, il est préférable d'utiliser l'un des nombreux outils qui le font automatiquement pour vous; par exemple node-pm ou cluster-service ...
+
+* Extrait de l'article [Performance de l'équilibre de charge du processus Node.js : comparaison entre le module de cluster, iptables et Nginx](https://medium.com/@fermads/node-js-process-load-balancing-comparing-cluster-iptables-and-nginx-6746aaf38272) de Medium
+> ... Le cluster Node est simple à implémenter et à configurer, les choses sont conservées dans le domaine Node sans dépendre d'autres logiciels. N'oubliez pas que votre processus maître fonctionnera presque autant que vos processus de travail et avec un peu moins de taux de requête que les autres solutions. ...
diff --git a/sections/production/utilizecpu.japanese.md b/sections/production/utilizecpu.japanese.md
new file mode 100644
index 000000000..74874a23c
--- /dev/null
+++ b/sections/production/utilizecpu.japanese.md
@@ -0,0 +1,26 @@
+# すべての CPU コアを利用する
+
+
+
+### 比較: Node クラスタと nginx それぞれを使ったバランシング
+
+
+
+
+
+### 他のブロガーが言っていること
+
+* [Node.js documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works) より:
+> ... 2番目のアプローチである Node クラスタは、理論的には最高のパフォーマンスを発揮するはずです。しかし、実際には、オペレーティングシステムのスケジューラのばらつきのために、ディストリビューションは非常にアンバランスになる傾向があります。8つの全てのプロセスのうち、70%以上の接続が2つのプロセスで終了するという負荷が観測されています。 ...
+
+* ブログ [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/) より:
+> ... クラスタリングは Node のクラスタモジュールで可能になります。これにより、マスタープロセスがワーカープロセスを spawn し、ワーカー間で着信接続を分配できるようになります。しかし、このモジュールを直接使用するよりも、自動的にそれを行ってくれる多くのツールのうちの一つを使用する方がはるかに良いでしょう; node-pm やクラスタサービスなど ...
+
+* Medium のポスト [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 クラスタは実装と設定が簡単で、他のソフトウェアに依存することなくノードの領域内に保持されます。マスタープロセスは、他のソリューションに比べてリクエスト率が若干低くても、作業者のプロセスとほぼ同等に機能することを覚えておいてください。 ...
diff --git a/sections/production/utilizecpu.korean.md b/sections/production/utilizecpu.korean.md
index 301a0fc78..5c18f204d 100644
--- a/sections/production/utilizecpu.korean.md
+++ b/sections/production/utilizecpu.korean.md
@@ -10,7 +10,7 @@ It might not come as a surprise that in its basic form, Node runs over a single
### Comparison: Balancing using Node’s cluster vs nginx
-
+
diff --git a/sections/production/utilizecpu.md b/sections/production/utilizecpu.md
index 301a0fc78..5c18f204d 100644
--- a/sections/production/utilizecpu.md
+++ b/sections/production/utilizecpu.md
@@ -10,7 +10,7 @@ It might not come as a surprise that in its basic form, Node runs over a single
### Comparison: Balancing using Node’s cluster vs nginx
-
+
diff --git a/sections/production/utilizecpu.polish.md b/sections/production/utilizecpu.polish.md
new file mode 100644
index 000000000..19f706ac8
--- /dev/null
+++ b/sections/production/utilizecpu.polish.md
@@ -0,0 +1,26 @@
+# Wykorzystaj wszystkie rdzenie procesora
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Nic dziwnego, że w swojej podstawowej formie Node działa na jednym wątku = pojedynczy proces = pojedynczy procesor. Płacenie za mocny sprzęt z 4 lub 8 procesorami i używanie tylko jednego brzmi szalenie, prawda? Najszybszym rozwiązaniem, które pasuje do średnich aplikacji jest użycie modułu klastrowania Node, który w 10 liniach kodu tworzy proces dla każdego logicznego rdzenia i kieruje żądania między procesami w stylu round-robin. Jeszcze lepiej, użyj PM2, który otacza moduł klastrowania prostym interfejsem i fajnym interfejsem monitorowania. Chociaż to rozwiązanie działa dobrze w przypadku tradycyjnych aplikacji, może nie być wystarczające w przypadku aplikacji, które wymagają najwyższej wydajności i niezawodnego przepływu DevOps. W przypadku zaawansowanych przypadków użycia rozważ replikację procesu NODE przy użyciu niestandardowego skryptu wdrażania i równoważenie za pomocą specjalistycznego narzędzia, takiego jak nginx, lub użyj silnika kontenera, takiego jak AWS ECS lub Kubernetees, które mają zaawansowane funkcje wdrażania i replikacji procesów.
+
+
+
+### Porównanie: równoważenie za pomocą Node cluster vs nginx
+
+
+
+
+
+### Co mówią inni blogerzy
+
+* Z [dokumentacji Node.js](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 ...
+
+* Z bloga [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 ...
+
+* Z posta na Medium [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/production/utilizecpu.russian.md b/sections/production/utilizecpu.russian.md
index c6213998d..866afb499 100644
--- a/sections/production/utilizecpu.russian.md
+++ b/sections/production/utilizecpu.russian.md
@@ -10,7 +10,7 @@
### Сравнение: балансировка с использованием кластера Node против nginx
-
+
diff --git a/sections/projectstructre/breakintcomponents.basque.md b/sections/projectstructre/breakintcomponents.basque.md
new file mode 100644
index 000000000..a5483d82d
--- /dev/null
+++ b/sections/projectstructre/breakintcomponents.basque.md
@@ -0,0 +1,35 @@
+# Antolatu zure proiektua atal eta osagai txikiagotan
+
+
+
+### Azalpena
+
+Tamaina ertaineko nahiz handiko aplikazioetarako, monolitoak benetan kaltegarriak dira. Menpekotasun asko dituen software handi bat edukitzea zaila da hausnartzeko eta maiz espageti kodea eragiten du. Arkitekto azkarrek ere, piztia mantsotzeko eta zatikatzeko haina gaitasun dituztenek, diseinuan esfortzu mental handiak egiten dituzte, eta aldaketa bakoitzak menpeko beste objektuekiko eragina arretaz aztertzea eskatzen du. Azken irtenbidea software txikia garatzean datza: banandu kode pila osoa fitxategiak beste inorekin partekatzen ez dituzten aparteko osagaietan, bakoitza fitxategi gutxi batzuekin osatua egonik (APIa, zerbitzuak, datuen sarbidea, egiaztatzeak, etab.) oso erraza da hausnartzeko. Askok 'mikrozerbitzu' egitura deitzen diote horri, garrantzitsua da ulertzea mikrozerbitzuak oinarri sorta bat direla eta ez derrigorrez jarraitu beharreko zehaztapenak. Printzipio ugari erabil ditzakezu mikrozerbitzudun egitura handi batean edota gutxi batzuk soilik. Biak dira zuzenak zure softwarearen konplexutasuna baxua den bitartean. Gutxienez, egin zenezakeen beste zerbait da osagaien artean oinarrizko mugak sortzea, zure proiektuaren erroan karpeta bat egokitzea osagai logiko bakoitzarentzat eta autonono bihurtzea: beste osagaiek haren funtzionalitatea erabili ahal izango dute soilik bere interfaze publikotik edo APItik pasatuz. Hori oinarrizkoa da zure osagaiak sinpleak izateko, menpekotasunen korapiloa ekiditeko eta zure aplikazioa mikrozerbitzu egitura handietarako prestatzeko.
+
+
+### Blog aipua: "Eskalatzeak aplikazio osoaren eskalatzea eskatzen du"
+
+[MartinFowler.com](https://martinfowler.com/articles/microservices.html) bloga
+
+> Aplikazio monolitikoak arrakastatsuak izan daitezke, baina jendeak gero eta frustrazio gehiago ditu beraiekin, batez ere gero eta aplikazio gehiago inplementatzen direlako lainoan. Aldaketa zikloak elkarrekin lotuta daude: aplikazioaren zati txiki batean egindako aldaketak monolito osoa birsortzea eta inplementatzea eskatzen du. Askotan zaila da denbora aurrera joan ahala moduluzko egitura egokia mantentzea, modulu batean bakarrik eragina izango dituzten aldaketak mantentzea. Eskalatzeak aplikazio osoaren eskalatzea eskatzen du
+
+
+### Blog aipua: "Zergatik egiten du garrasi zure aplikazioaren egiturak?"
+
+[uncle-bob](https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html) bloga
+
+> ...Liburutegi baten egitura begiratuko bazenu, ziurrenik sarrera handi batekin aurkituko zinateke, erregistro bulego lekuekin, irakurketa lekuekin, biltzar toki txikiekin, eta liburutegiko liburu guztiak edukitzeko beste apal dituzten galeria ugarirekin. Egitura horrek honakoa oihukatu beharko luke: Liburutegia.
+
+Beraz, zer oihukatzen du zure aplikazioaren egiturak? Zure direktorioko egituraren maila altuena eta maila altueneko paketeko iturburu fitxategiak begiratzen dituzunean, zer oihukatzen dute: Osasun Sistema, Kontabilitate Sistema edo Inbentarioa Kudeatzeko Sistema? Edo zera oihukatzen al dute: Rails, Spring/Hibernate edo ASP?
+
+
+
+### Zuzena: antolatu zure proiektua aparteko osagaietan
+
+
+
+
+
+### Okerra: taldekatu zure fitxategiak rol teknikoen arabera
+
+
diff --git a/sections/projectstructre/breakintcomponents.brazilian-portuguese.md b/sections/projectstructre/breakintcomponents.brazilian-portuguese.md
index df18e206b..f208f3b2c 100644
--- a/sections/projectstructre/breakintcomponents.brazilian-portuguese.md
+++ b/sections/projectstructre/breakintcomponents.brazilian-portuguese.md
@@ -9,7 +9,7 @@ Para aplicações de tamanho médio e acima, os monólitos são muito ruins - te
### Citação de Blog: "O escalonamento requer escalonamento de todo o aplicativo"
- Do blog MartinFowler.com
+ Do blog [MartinFowler.com](https://martinfowler.com/articles/microservices.html)
> Aplicações monolíticas podem ser bem-sucedidas, mas cada vez mais as pessoas estão sentindo frustrações com elas - especialmente à medida que mais aplicativos são implantados na nuvem. Os ciclos de mudança estão interligados - uma alteração feita em uma pequena parte do aplicativo requer que todo o monólito seja reconstruído e implantado. Ao longo do tempo, muitas vezes é difícil manter uma boa estrutura modular, tornando mais difícil manter as alterações que devem afetar apenas um módulo dentro desse módulo. O escalonamento requer escalonamento de todo o aplicativo, em vez de partes dele que exigem maior recurso.
@@ -17,7 +17,7 @@ Para aplicações de tamanho médio e acima, os monólitos são muito ruins - te
### Citação de Blog: "Então, o que a arquitetura do seu aplicativo grita?"
- Do blog [uncle-bob](https://8thlight.com/blog/uncle-bob/2011/09/30/Screaming-Architecture.html)
+ Do blog [uncle-bob](https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html)
> ...se você estivesse olhando para a arquitetura de uma biblioteca, provavelmente veria uma grande entrada, uma área para funcionários de check-in-out, áreas de leitura, pequenas salas de conferência e galeria após galeria, capaz de guardar estantes de livros para todos os livros. a biblioteca. Essa arquitetura iria gritar: Biblioteca.
@@ -27,10 +27,10 @@ Então, o que a arquitetura da sua aplicação grita? Quando você olha para a e
### Bom: estruture sua solução por componentes independentes
-
+
### Ruim: Agrupe seus arquivos por papel técnico
-
+
diff --git a/sections/projectstructre/breakintcomponents.chinese.md b/sections/projectstructre/breakintcomponents.chinese.md
index 1de6e5561..7c43b787b 100644
--- a/sections/projectstructre/breakintcomponents.chinese.md
+++ b/sections/projectstructre/breakintcomponents.chinese.md
@@ -11,14 +11,14 @@
### 博客引用: "伸缩需要对整个应用程序进行伸缩设计"
- 摘自博客 MartinFowler.com
-
+ 摘自博客 [MartinFowler.com](https://martinfowler.com/articles/microservices.html)
+
> 单个应用程序可以成功, 但越来越多的人对它们感到失望 - 尤其是随着更多的应用程序被部署到云中。更改周期被捆绑在一起 - 对应用程序的一小部分进行更改, 需要重建和部署整个整体。随着时间的推移, 通常很难保持一个良好的模块化结构, 这使得更改哪怕只会影响该模块中的一个模块变得更加困难。伸缩设计需要扩展整个应用程序, 而不是它的部分,这往往需要更多资源。
### 推荐: 通过独立组件构建解决方案
-
+
### 避免: 按技术角色对文件进行分组
-
+
diff --git a/sections/projectstructre/breakintcomponents.french.md b/sections/projectstructre/breakintcomponents.french.md
new file mode 100644
index 000000000..2fa18c5e9
--- /dev/null
+++ b/sections/projectstructre/breakintcomponents.french.md
@@ -0,0 +1,37 @@
+# Organisez votre projet en composants
+
+
+
+### Un paragraphe d'explication
+
+Pour les applications de taille moyenne et supérieure, les monolithes sont vraiment mauvais - avoir un gros logiciel avec de nombreuses dépendances est difficile à appréhender et mène souvent à du code spaghetti. Même les architectes intelligents - ceux qui sont suffisamment qualifiés pour apprivoiser la bête et la « modulariser » - consacrent un temps considérable à sa conception, et chaque changement nécessite d'évaluer soigneusement l'impact sur d'autres objets dépendants. La solution ultime est de développer de petits logiciels : divisez la pile entière en composants autonomes qui ne partagent pas de fichiers avec d'autres, chacun constituant très peu de fichiers (par exemple API, service, accès aux données, test, etc.) de sorte qu'il soit très facile à raisonner à ce sujet. Certains peuvent appeler cette architecture de « microservices » - il est important de comprendre que les microservices ne sont pas une spécification que vous devez suivre, mais plutôt un ensemble de principes. Vous pouvez adopter tous les principes dans une architecture de microservices ou en adopter seulement quelques-uns. Les deux sont bons tant que la complexité du logiciel est faible. Le moins que vous puissiez faire est de créer des frontières de base entre les composants, d'assigner un dossier à la racine de votre projet pour chaque composant métier et de le rendre autonome - les autres composants ne sont autorisés à utiliser ses fonctionnalités que via son interface publique ou son API. C'est la base pour garder vos composants simples, éviter l'enfer des dépendances et ouvrir à l'avenir la voie à des véritables microservices une fois que votre application se développera.
+
+
+
+### Citation de blog : « La mise à l'échelle nécessite la mise à l'échelle de l'application entière »
+
+ Extrait du blog de [MartinFowler.com](https://martinfowler.com/articles/microservices.html)
+
+> Les applications monolithiques peuvent réussir, mais de plus en plus de personnes ressentent des frustrations à leur égard, d'autant plus que davantage d'applications sont déployées dans le cloud. Les cycles de changement sont liés les uns aux autres - une modification apportée à une petite partie de l'application nécessite la reconstruction et le déploiement du monolithe entier. Au fil du temps, il est souvent difficile de conserver une bonne structure modulaire, ce qui rend plus difficile la conservation des modifications qui ne devraient affecter qu'un module au sein de ce module. La mise à l'échelle nécessite la mise à l'échelle de l'application entière plutôt que les parties concernées, cela nécessitent donc plus de ressources.
+
+
+
+### Citation de blog : « Alors, est-ce que est l'architecture de votre application parle d'elle-même ? »
+
+ Extrait du blog de [uncle-bob](https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html)
+
+> ...si vous regardiez l'architecture d'une bibliothèque, vous verriez probablement une grande entrée, un espace pour les préposés à l'enregistrement, des salles de lecture, de petites salles de conférence et des galeries pouvant accueillir tous les livres de la bibliothèque. Cette architecture parle d'elle-même : c'est une Bibliothèque. >
+
+Alors, est-ce que est l'architecture de votre application parle d'elle-même ? Quand vous regardez la structure du répertoire du niveau supérieur, et les fichiers sources dans le paquet du niveau supérieur, est-ce qu'ils parlent d'eux-mêmes : c'est un système de soins de santé, un système de comptabilité ou un système de gestion des stocks ? Ou est-ce qu'ils vous parlent de : Rails, Spring/Hibernate ou ASP ?
+
+
+
+### Bon : Organisez votre solution avec des composants autonomes
+
+
+
+
+
+### Mauvais : Regroupez vos fichiers selon leur rôle technique
+
+
diff --git a/sections/projectstructre/breakintcomponents.japanese.md b/sections/projectstructre/breakintcomponents.japanese.md
index f6afe33c4..4d5e1f32e 100644
--- a/sections/projectstructre/breakintcomponents.japanese.md
+++ b/sections/projectstructre/breakintcomponents.japanese.md
@@ -1,84 +1,37 @@
-
-
-# コンポーネントによってソリューションを構築する
-
-
-
-### 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
-
-
-
-
-
-### Bad: Group your files by technical role
-
-
+# 컴포넌트 기반으로 설계하라
+
+
+
+### 한문단 설명
+
+중소규모 이상의 앱부터는 단일암체 monolith는 정말 좋지 않다 - 의존성이 여럿 있는 커다란 하나의 소프트웨어를 쓰는 것은 꼬일대로 꼬인 스파게티 코드를 초래한다. 이 괴물을 '모듈화'하여 길들일만큼 숙련된 똑똑한 설계자들조차 디자인에 엄청난 정신력을 쏟아붓고, 모든 변화는 다른 의존하는 프로젝트에 어떤 영향을 미치는지 신중히 감정할것을 필요로 한다. 궁극적인 해결책은 소규모의 소프트웨어를 개발하는 것이다: 스택 전체를 다른이들과 파일을 공유하지 않는 자족적(self-contained)인 컴포넌트로 나누고, 추론하기 쉽게 극소수의 파일로만 구성되어야 한다 (예: API, 서비스, 데이터 접근, 테스트 등). 이것을 "마이크로서비스" 설계라고 부르기도 하는데, 마이크로서비스는 따라야 하는 사양이 아니라 원칙들이란 것을 아는 것이 중요하다. 원칙을 여럿 받아들여 완전한 마이크로서비스 설계를 할 수도 있고, 아니면 그 중 소수만 받아들일 수도 있다. 소프트웨어의 복잡하게 하지 않는 한 둘 다 좋은 방법이다. 최소한 컴포넌트 사이에 경계를 나누고, 프로젝트 최상위 루트에 각각의 비지니스 컴포넌트를 각기 다른 폴더에 배치하여 다른 컴포넌트들은 공용 인터페이스나 API로만 기능을 소비할 수 있게 자족적으로 만들 것. 이것이 컴포넌트를 간단하게 하고, 의존성 지옥을 방지하며 미래에 앱이 완전한 마이크로서비스로 자라나는 길을 닦는 기반이다.
+
+
+
+### 블로그 인용: "확장하려면 애플리케이션 전체를 확장해야한다"
+
+[MartinFowler.com](https://martinfowler.com/articles/microservices.html) 블로그로부터
+
+> 단일암체 애플리케이션도 성공적일 수 있지만, 점점 더 많은 사람들이 불만을 느끼고 있다 - 특히 더 많은 애플리케이션들이 클라우드로 전개될수록. 변화 주기는 다 같이 묶여 있다 - 애플리케이션의 조그마한 부분을 바꾸면 단일암체 전체를 재건하고 재배치하여야 한다. 시간이 흐를수록 좋은 모듈식의 구조를 유지하는것이 힘들어지고, 모듈 하나에만 작용해야 할 변화가 그 모듈 이내에서만 작용하도록 하는것이 힘들어진다. 더 많은 자원을 필요로 하는 부분만 확장하는 것이 아니라, 확장하려면 애플리케이션 전체를 확장해야한다.
+
+
+
+### 블로그 인용: "그러니 당신의 어플리케이션의 설계를 보면 어떤 감이 오는가?"
+
+[uncle-bob](https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html) 블로그로부터
+
+> ...도서관 설계도를 보면, 아마도 커다란 입구, 체크인/체크아웃 구역, 독서실, 소규모 회의실들, 도서관의 모든 책을 수용할 수 있게 책꽂이들을 놓을 만한 공간들이 보일 것이다. 설계도를 보면 도서관이라고 바로 감이 올 것이다.
+
+그러니 당신의 어플리케이션의 설계를 보면 어떤 감이 오는가? 최상위 디렉토리 구조와 최고위 레벨의 패키지의 소스 파일을 보면 건강 관리 시스템인지, 회계 시스템인지, 재고관리 시스템인지 바로 감이 오는가? 아니면 Rails이나 Spring/Hibernate, 혹은 ASP라는 감이 오는가?.
+
+
+
+### 좋은예: 자족적인 컴포넌트 기반으로 설계하라
+
+
+
+
+
+### 나쁜예: 파일을 기술적인 역할별로 모아라
+
+
diff --git a/sections/projectstructre/breakintcomponents.md b/sections/projectstructre/breakintcomponents.md
index 4b1c0b36d..91df46d17 100644
--- a/sections/projectstructre/breakintcomponents.md
+++ b/sections/projectstructre/breakintcomponents.md
@@ -4,13 +4,13 @@
### 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.
+For medium sized apps and above, *non-modular* monoliths are really bad - having one big software with 'spaghetti' of dependencies is just hard to reason about. The ultimate solution is to develop smaller software: divide the whole stack into self-contained components that don't share files with others, each is a standalone logical app (e.g. has its own API, service, data access, test, etc.) so that onboarding into it and changing the code is much easier than dealing with the whole system. 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. The very least you should do is create basic borders between components, assign a folder or repository in your system 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
+ From the blog [MartinFowler.com](https://martinfowler.com/articles/microservices.html)
> 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.
@@ -18,7 +18,7 @@ For medium sized apps and above, monoliths are really bad - having one big softw
### 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)
+ From the blog [uncle-bob](https://blog.cleancoder.com/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.
@@ -28,10 +28,38 @@ So what does the architecture of your application scream? When you look at the t
### Good: Structure your solution by self-contained components
-
+```bash
+my-system
+├─ apps (components)
+│ ├─ orders
+│ │ ├─ package.json
+│ │ ├─ api
+│ │ ├─ domain
+│ │ ├─ data-access
+│ ├─ users
+│ ├─ payments
+├─ libraries (generic cross-component functionality)
+│ ├─ logger
+│ ├─ authenticator
+```
+
### Bad: Group your files by technical role
-
+```bash
+my-system
+├─ controllers
+│ ├─ user-controller.js
+│ ├─ order-controller.js
+│ ├─ payment-controller.js
+├─ services
+│ ├─ user-service.js
+│ ├─ order-service.js
+│ ├─ payment-service.js
+├─ models
+│ ├─ user-model.js
+│ ├─ order-model.js
+│ ├─ payment-model.js
+```
\ No newline at end of file
diff --git a/sections/projectstructre/breakintcomponents.polish.md b/sections/projectstructre/breakintcomponents.polish.md
new file mode 100644
index 000000000..17a7ea2ed
--- /dev/null
+++ b/sections/projectstructre/breakintcomponents.polish.md
@@ -0,0 +1,36 @@
+# Skonstruuj swoje rozwiązanie według komponentów
+
+
+
+### Wyjaśnienie jednym akapitem
+
+W przypadku średnich aplikacji i wyższych monolity są naprawdę złe - posiadanie jednego dużego oprogramowania z wieloma zależnościami jest po prostu trudne do uzasadnienia i często prowadzi do kodu spaghetti. Nawet inteligentni architekci - ci, którzy są wystarczająco wykwalifikowani, aby oswoić bestię i ją „zmodularyzować” - poświęcają wielki wysiłek umysłowy na projektowanie, a każda zmiana wymaga starannej oceny wpływu na inne zależne obiekty. Ostatecznym rozwiązaniem jest opracowanie małego oprogramowania: podziel cały stos na niezależne komponenty, które nie współużytkują plików z innymi, każdy stanowi bardzo niewiele plików (np. API, usługa, dostęp do danych, test itp.), Dzięki czemu jest bardzo łatwo to uzasadnić. Niektórzy mogą nazywać tę architekturę „mikrousługami” - ważne jest, aby zrozumieć, że mikrousługi nie są specyfikacją, której należy przestrzegać, ale raczej zbiorem zasad. Możesz zastosować wiele zasad w pełnej architekturze mikrousług lub zastosować tylko kilka. Oba są dobre, o ile złożoność oprogramowania jest niska. To co, co najmniej powinieneś zrobić, to utworzyć podstawowe granice między komponentami, przypisać folder w katalogu głównym projektu dla każdego komponentu biznesowego i uczynić go samodzielnym - inne komponenty mogą korzystać z jego funkcji tylko za pośrednictwem publicznego interfejsu lub interfejsu API. Jest to podstawa do uproszczenia komponentów, uniknięcia piekła zależności i utorowania drogi do pełnej obsługi mikrousług w przyszłości, gdy Twoja aplikacja się rozwinie.
+
+
+### Cytat z Bloga: "Skalowanie wymaga skalowania całej aplikacji"
+
+ Z bloga [MartinFowler.com](https://martinfowler.com/articles/microservices.html)
+
+> 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.
+
+
+
+### Cytat z Bloga: "Więc co krzyczy architektura Twojej aplikacji?"
+
+ Z bloga [uncle-bob](https://blog.cleancoder.com/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.
+
+Więc co krzyczy architektura twojej aplikacji? Gdy spojrzysz na strukturę katalogów najwyższego poziomu i pliki źródłowe w pakiecie najwyższego poziomu; czy krzyczą: system opieki zdrowotnej, system rachunkowości lub system zarządzania zapasami? A może krzyczą: Railsy, Spring / Hibernate lub ASP ?.
+
+
+
+### Dobre: Skonstruuj swoje rozwiązanie według samodzielnych komponentów
+
+
+
+
+
+### Złe: Pogrupuj pliki według roli technicznej
+
+
diff --git a/sections/projectstructre/breakintcomponents.russian.md b/sections/projectstructre/breakintcomponents.russian.md
index b6935d20d..cd7647b4f 100644
--- a/sections/projectstructre/breakintcomponents.russian.md
+++ b/sections/projectstructre/breakintcomponents.russian.md
@@ -10,7 +10,7 @@
### Цитата из блога: "Масштабирование требует масштабирования всего приложения"
-Из блога MartinFowler.com
+Из блога [MartinFowler.com](https://martinfowler.com/articles/microservices.html)
> Монолитные приложения могут быть успешными, но люди все чаще испытывают разочарование в связи с ними, особенно когда в облаке развертывается все бо̀льшие приложений. Циклы изменений связаны друг с другом - изменение, внесенное в небольшую часть приложения, требует перестройки и развертывания всего монолита. Со временем зачастую трудно сохранить хорошую модульную структуру, что усложняет сохранение изменений, которые должны затрагивать только один модуль в этом модуле. Масштабирование требует масштабирования всего приложения, а не его частей, которые требуют больших ресурсов.
@@ -18,7 +18,7 @@
### Цитата из блога: "Так что же кричит в архитектуре вашего приложения?"
-Из блога [uncle-bob](https://8thlight.com/blog/uncle-bob/2011/09/30/Screaming-Architecture.html)
+Из блога [uncle-bob](https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html)
> ... если бы вы смотрели на архитектуру библиотеки, вы бы, скорее всего, увидели парадный вход, зону для клерков, места для чтения, небольшие конференц-залы и галерею за галереей, способную вместить книжные полки для все книги в библиотеке. Эта архитектура будет кричать: "Библиотека!".
@@ -28,10 +28,10 @@
### Хорошо: структурируйте свое решение по отдельным компонентам
-
+
### Плохо: сгруппируйте файлы по техническим ролям
-
+
diff --git a/sections/projectstructre/choose-framework.md b/sections/projectstructre/choose-framework.md
new file mode 100644
index 000000000..6af330a0f
--- /dev/null
+++ b/sections/projectstructre/choose-framework.md
@@ -0,0 +1,39 @@
+# Consider all the consequences when choosing the main framework
+
+
+
+### Recommended frameworks: Pros and cons
+
+Unlike other choices, choosing the core framework determines strategic factors like the development style and how likely the team is to hit a wall. We believe that framework popularity is a supreme consideration and put our focus on the top 4 most popular frameworks in terms of downloads and GitHub stars. The text below outlines the pros and cons of each framework and how to match a framework to the right application type
+
+**express.js**
+
+Pros: Unmatched popularity; gigantic eco-system of extensions and middleware; simple to learn and use; familiar to almost every Node.js developer; tons of community articles and videos are based on express
+
+Cons: Covers a small subset of a typical application needs - merely a web server that invokes the app function per URL. Choosing express means leaving a handful of app concerns uncovered; outdated mechanics - no native support for async-await; barely maintained and updated; Slower than others
+
+**Nest.js**
+
+Pros: More batteries than any other option - covers many application concern including message queues, scheduled jobs and more; OOP-style is an advantage for teams who appreciate this design style; awesome docs; well-maintained; high popularity with a vibrant community
+
+Cons: High-level abstractions that cloud built-in Node.js conventions; The inclusion of many features, heavy usage of TypeScript and reference to sophisticated patterns might push teams for increased complexity; Steeper learning curve due to a handful of unique narratives (e.g., interceptors, guards, modules, and more); Highly opinionated
+
+**Fastify**
+
+Pros: Relatively simple and lean; mostly based on Node.js/JavaScript standards; relatively shallow learning curve; with its official plugins cover many application concerns though not as rich as Nest.js;
+
+Cons: Younger than others and not as popular yet; smaller eco-system compared to express and Nest.js
+
+**Koa**
+
+Pros: When compared with express: it's Simpler and nimbler; modern API with async/await support; better performance
+
+Cons: Covers a small subset of a typical application needs - leaves a handful of app concerns uncovered; Not as popular as express and Nest.js
+
+### A brief choosing guide
+
+**Prefer express.js when** - having an experienced architect onboard _and_ in a need to control the fine-grained pieces of the puzzle. In this circumstances, Koa is also a solid option with a more modern API than express but a much smaller eco-system
+
+**Prefer Fastify when -** The app consists of reasonably-sized components/Microservices (i.e., not a huge monolith); for teams who have solid JavaScript & Node.js knowledge; when sticking to Node.js narratives and spirit is desirable
+
+**Prefer Nest.js when** - It's desirable to design and code in OOP style; when the team is highly experienced with Java/Spring/Angular or similar; for large size app that can't be broken down (i.e. monolith) to autonomous component; for a team that lacks fundamental JavaScript/Node.js skills (not exclusively, this yet another consideration); when the decision-making overhead should be minimized; when the time to the first delivery is a critical factor
diff --git a/sections/projectstructre/configguide.basque.md b/sections/projectstructre/configguide.basque.md
new file mode 100644
index 000000000..6061e5bf2
--- /dev/null
+++ b/sections/projectstructre/configguide.basque.md
@@ -0,0 +1,43 @@
+# Erabili ingurunea errespetatzen duen konfigurazio seguru eta hierarkiko bat
+
+
+
+### Azalpena
+
+Konfigurazio datuekin jardutean, hainbat gauza gogaikarri eta moteltzaile aurki genitzake:
+
+1. prozesuaren inguruneko aldagaiak erabiliz giltza guztiak ezartzea benetan gogaikarria bihurtzen da 100 giltza injektatu behar ditugunean (haiek soilik konfigurazio fitxategi batean argitaratu partez), hala ere, fitxategiekin jardutean, soilik DevOps administrariak dira gai jokaera aldatzeko, kodea aldatu gabe. Konfigurazio sistema fidagarriek konfigurazio fitxategiak eta prozesu aldagaien berridazketa konbinatu beharko lituzkete
+
+2. giltza guztiak JSON batean zehaztean, balioak aurkitu eta aldatzea frustragarria da zerrenda handitzen doan heinean. Ataletan antolatuta dagoen JSON fitxategi hierarkiko batek arazo hori konpondu dezake. Gainera, konfigurazio liburutegi gutxi batzuek konfigurazioa hainbat fitxategitan gordetzea ahalbidetzen dute eta guztiak exekuzio garaian bateratzea. Begiratu beheko adibidea
+
+3. jakina da ez dela gomendagarria datu baseko pasahitza bezalako informazio garrantzitsua gordetzea, baina ez da irtenbide azkar eta praktikorik existitzen erronka honetarako. Konfigurazio liburutegi batzuek fitxategiak enkriptatzeko aukera ematen dute, beste batzuek GIT argitarapen prozesuen bitartean enkriptatzen dituzte balio horiek edota ez dituzte balio errealak gordetzen, baizik eta ingurune aldagaien bidez zehazten dituzte inplementazio prozesuaren bitartean
+
+4. konfigurazio egoera aurreratu batzuek konfigurazio giltzak komando sarrera bidez (vargs) injektatzea eskatzen dute, edota konfigurazio informazioa sinkronizatzea Redis bezalako cache memoria erabiliz, zerbitzari ugarik konfigurazio datu berak erabiltzea ahalbidetuz
+
+5. aplikazioak ahalik eta azkarren huts egin behar du eta berehalako erantzuna eman aplikazioaren abiaraztean, beharrezko ingurune aldagaiak zehaztuta ez badaude. Konfigurazioa balioztatzeko [convict](https://www.npmjs.com/package/convict) erabiliz lor daiteke hori
+
+Konfigurazio liburutegi batzuek aipatutako funtzionalitate gehienak dohainik eskaintzen dituzte. Eman begiratu bat [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config), eta [convict](https://www.npmjs.com/package/convict) bezalako npm liburutegiei, non aipatutako ezaugarri gehienak betetzen dituzten
+
+
+
+### Kode adibidea: konfigurazio hierarkikoak balioak aurkitzen eta konfigurazio fitxategi handiak mantentzen laguntzen du
+
+```json5
+{
+ // Bezeroen konfigurazio modulua
+ Bezeroa: {
+ dbConfig: {
+ host: "localhost",
+ port: 5984,
+ dbName: "bezeroak",
+ },
+ credit: {
+ initialLimit: 100,
+ // Ezarri balio txikia garapenerako
+ initialDays: 1,
+ },
+ },
+}
+```
+
+
diff --git a/sections/projectstructre/configguide.brazilian-portuguese.md b/sections/projectstructre/configguide.brazilian-portuguese.md
index 92a74f51d..39eda1fe7 100644
--- a/sections/projectstructre/configguide.brazilian-portuguese.md
+++ b/sections/projectstructre/configguide.brazilian-portuguese.md
@@ -14,7 +14,7 @@ Ao lidar com dados de configuração, muitas coisas podem simplesmente incomodar
4. Alguns cenários de configuração avançada exigem a injeção de valores de configuração via linha de comando (vargs) ou informações de configuração de sincronização por meio de um cache centralizado, como o Redis, para que vários servidores usem os mesmos dados de configuração.
-Algumas bibliotecas de configuração podem fornecer a maioria desses recursos gratuitamente, dê uma olhada nas bibliotecas npm como [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) e [config](https://www.npmjs.com/package/config) que satisfazem muitos desses requisitos.
+Algumas bibliotecas de configuração podem fornecer a maioria desses recursos gratuitamente, dê uma olhada nas bibliotecas npm como [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) e [convict](https://www.npmjs.com/package/convict) que satisfazem muitos desses requisitos.
diff --git a/sections/projectstructre/configguide.french.md b/sections/projectstructre/configguide.french.md
new file mode 100644
index 000000000..8cf42d94d
--- /dev/null
+++ b/sections/projectstructre/configguide.french.md
@@ -0,0 +1,43 @@
+# Utilisez une configuration respectueuse de l'environnement, sécurisée et hiérarchique
+
+
+
+### Un paragraphe d'explication
+
+Lorsqu'il s'agit de données de configuration, beaucoup de choses peuvent tout simplement vous énerver et vous freiner :
+
+1. le paramétrage de toutes les clés à l'aide de variables d'environnement de processus devient très fastidieux lorsqu'il faut injecter 100 clés (au lieu de simplement les livrer dans un fichier de configuration), cependant, lorsque l'on traite uniquement des fichiers, les administrateurs DevOps ne peuvent pas modifier le comportement sans modifier le code. Une solution de configuration fiable doit combiner les deux : fichiers de configuration + écrasements des variables de processus.
+
+2. lorsque vous spécifiez toutes les clés d'un JSON plat, il devient frustrant de trouver et de modifier des entrées lorsque la liste s'allonge. Un fichier JSON hiérarchique regroupé en sections peut résoudre ce problème + quelques bibliothèques de configuration permettent de stocker la configuration dans plusieurs fichiers et de de prendre soin de les unifier lors de l'exécution. Voir l'exemple ci-dessous
+
+3. le stockage d'informations sensibles comme le mot de passe de la base de données n'est évidemment pas recommandé, mais aucune solution rapide et pratique n'existe pour ce défi. Certaines bibliothèques de configuration permettent de crypter les fichiers, d'autres cryptent ces entrées pendant les commits GIT ou simplement ne stockent pas les valeurs réelles de ces entrées et spécifient la valeur réelle pendant le déploiement via les variables d'environnement.
+
+4. certains scénarios de configuration avancés nécessitent d'injecter des valeurs de configuration via la ligne de commande (vargs) ou de synchroniser les informations de configuration via un cache centralisé comme Redis afin que plusieurs serveurs utilisent les mêmes données de configuration.
+
+5. l'application doit échouer le plus rapidement possible et fournir un retour immédiat si les variables d'environnement requises ne sont pas présentes au démarrage, ceci peut être réalisé en utilisant [convict](https://www.npmjs.com/package/convict) pour valider la configuration.
+
+Certaines bibliothèques de configuration peuvent fournir gratuitement la plupart de ces fonctionnalités, jetez un œil aux bibliothèques npm comme [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) et [convict](https://www.npmjs.com/package/convict) qui traitent un bon nombre de ces exigences.
+
+
+
+### Exemple de code - la configuration hiérarchique aide à trouver des entrées et à maintenir d'énormes fichiers de configuration
+
+```json5
+{
+ // Configurations du module Customer
+ "Customer": {
+ "dbConfig": {
+ "host": "localhost",
+ "port": 5984,
+ "dbName": "customers"
+ },
+ "credit": {
+ "initialLimit": 100,
+ // Régler un niveau bas pour le développement
+ "initialDays": 1
+ }
+ }
+}
+```
+
+
diff --git a/sections/projectstructre/configguide.korean.md b/sections/projectstructre/configguide.korean.md
index 6e7b36633..930941884 100644
--- a/sections/projectstructre/configguide.korean.md
+++ b/sections/projectstructre/configguide.korean.md
@@ -14,7 +14,7 @@ When dealing with configuration data, many things can just annoy and slow down:
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.
+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), [config](https://www.npmjs.com/package/config), and [convict](https://www.npmjs.com/package/convict) which tick many of these requirements.
diff --git a/sections/projectstructre/configguide.md b/sections/projectstructre/configguide.md
index 24a419f1f..81d7918a0 100644
--- a/sections/projectstructre/configguide.md
+++ b/sections/projectstructre/configguide.md
@@ -16,7 +16,7 @@ When dealing with configuration data, many things can just annoy and slow down:
5. the application should fail as fast as possible and provide the immediate feedback if the required environment variables are not present at start-up, this can be achieved by using [convict](https://www.npmjs.com/package/convict) to validate the configuration.
-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.
+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), [config](https://www.npmjs.com/package/config), and [convict](https://www.npmjs.com/package/convict) which tick many of these requirements.
diff --git a/sections/projectstructre/configguide.polish.md b/sections/projectstructre/configguide.polish.md
new file mode 100644
index 000000000..fc871afaf
--- /dev/null
+++ b/sections/projectstructre/configguide.polish.md
@@ -0,0 +1,43 @@
+# Używaj konfiguracji przyjaznej środowisku, bezpiecznej i hierarchicznej
+
+
+
+### Wyjaśnienie jednym akapitem
+
+W przypadku danych konfiguracyjnych wiele rzeczy może po prostu denerwować i spowalniać:
+
+1. ustawienie wszystkich kluczy przy użyciu zmiennych środowiskowych procesu staje się bardzo żmudne, gdy trzeba wstrzyknąć 100 kluczy (zamiast po prostu zatwierdzić je w pliku konfiguracyjnym), jednak podczas pracy z plikami tylko administratorzy DevOps nie mogą zmienić zachowania bez zmiany kodu. Niezawodne rozwiązanie konfiguracyjne musi łączyć oba pliki konfiguracyjne + przesłonięcia zmiennych procesowych
+
+2. przy określaniu wszystkich kluczy w płaskim JSON, frustracją jest szukanie i modyfikowanie wpisów, gdy lista powiększa się. Hierarchiczny plik JSON zgrupowany w sekcje może rozwiązać ten problem + kilka bibliotek konfiguracji pozwala przechowywać konfigurację w wielu plikach i zadbać o połączenie wszystkich w czasie wykonywania. Zobacz przykład poniżej
+
+3. przechowywanie poufnych informacji, takich jak hasło BD, oczywiście nie jest zalecane, ale nie istnieje szybkie i wygodne rozwiązanie tego wyzwania. Niektóre biblioteki konfiguracyjne pozwalają na szyfrowanie plików, inne szyfrują te wpisy podczas zatwierdzeń GIT lub po prostu nie przechowują rzeczywistych wartości tych wpisów i określają rzeczywistą wartość podczas wdrażania za pomocą zmiennych środowiskowych.
+
+4. niektóre zaawansowane scenariusze konfiguracji wymagają wprowadzenia wartości konfiguracji za pomocą wiersza poleceń (vargs) lub zsynchronizowania informacji o konfiguracji za pośrednictwem scentralizowanej pamięci podręcznej, takiej jak Redis, aby wiele serwerów używało tych samych danych konfiguracyjnych.
+
+5. aplikacja powinna zakończyć się tak szybko, jak to możliwe i przekazać natychmiastowe informacje zwrotne, jeśli wymagane zmienne środowiskowe nie są obecne podczas uruchamiania, można to osiągnąć za pomocą [convict](https://www.npmjs.com/package/convict) aby sprawdzić poprawność konfiguracji.
+
+Niektóre biblioteki konfiguracyjne mogą zapewniać większość tych funkcji za darmo, zobacz biblioteki npm, takie jak [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) i [convict](https://www.npmjs.com/package/convict) które spełniają wiele z tych wymagań.
+
+
+
+### Przykład kodu - konfiguracja hierarchiczna pomaga znaleźć wpisy i zarządzać dużymi plikami konfiguracyjnymi
+
+```json5
+{
+ // 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.russian.md b/sections/projectstructre/configguide.russian.md
index 52f2b87a4..bfeddd13e 100644
--- a/sections/projectstructre/configguide.russian.md
+++ b/sections/projectstructre/configguide.russian.md
@@ -16,13 +16,13 @@
5. Приложение должно работать как можно быстрее и обеспечивать немедленную обратную связь, если требуемые переменные среды отсутствуют при запуске, можно использовать [convict](https://www.npmjs.com/package/convict) для проверки конфигурации.
-Некоторые библиотеки конфигурации могут предоставить большинство этих функций бесплатно, посмотрите библиотеки npm, такие как [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf) и [config](https://www.npmjs.com/package/config), которые отмечают многие из этих требований.
+Некоторые библиотеки конфигурации могут предоставить большинство этих функций бесплатно, посмотрите библиотеки npm, такие как [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) и [convict](https://www.npmjs.com/package/convict), которые отмечают многие из этих требований.
### Пример кода - иерархическая конфигурация помогает находить записи и поддерживать огромные конфигурационные файлы
-```js
+```json5
{
// Customer module configs
"Customer": {
diff --git a/sections/projectstructre/createlayers.basque.md b/sections/projectstructre/createlayers.basque.md
new file mode 100644
index 000000000..6c13bc0ee
--- /dev/null
+++ b/sections/projectstructre/createlayers.basque.md
@@ -0,0 +1,13 @@
+# Antolatu zure aplikazioa geruzatan, mantendu Express bere esparruaren barruan
+
+
+
+### Osagaien kodea geruzatan banandu: web, zerbitzuak, eta Datuen Sarbide Geruza (DSG) (Ingelesez Data Access Layer, DAL)
+
+
+
+
+
+### Minutu bateko azalpena: geruzak nahastearen eragozpena
+
+
diff --git a/sections/projectstructre/createlayers.brazilian-portuguese.md b/sections/projectstructre/createlayers.brazilian-portuguese.md
index 78e181a67..8d015ce45 100644
--- a/sections/projectstructre/createlayers.brazilian-portuguese.md
+++ b/sections/projectstructre/createlayers.brazilian-portuguese.md
@@ -4,10 +4,10 @@
### Separe o código do componente em camadas: web, serviços e DAL
-
+
### Explicação em 1 minuto: A desvantagem de misturar camadas
-
+
diff --git a/sections/projectstructre/createlayers.chinese.md b/sections/projectstructre/createlayers.chinese.md
index 6a0866330..4d431f0f9 100644
--- a/sections/projectstructre/createlayers.chinese.md
+++ b/sections/projectstructre/createlayers.chinese.md
@@ -3,9 +3,9 @@
### 将组件代码分成web, services, DAL层
-
+
### 1分钟说明:混合层的缺点
-
+
diff --git a/sections/projectstructre/createlayers.french.md b/sections/projectstructre/createlayers.french.md
new file mode 100644
index 000000000..a6d4d4d7e
--- /dev/null
+++ b/sections/projectstructre/createlayers.french.md
@@ -0,0 +1,13 @@
+# Organisez vos composants en strates, laissez Express gérer ses responsabilités
+
+
+
+ ### Séparez le code des composants en strates : web, services et couche d'accès aux données (DAL)
+
+
+
+
+
+### Explication en 1 min : l'inconvénient de mélanger les strates
+
+
diff --git a/sections/projectstructre/createlayers.japanese.md b/sections/projectstructre/createlayers.japanese.md
new file mode 100644
index 000000000..dda7fb23c
--- /dev/null
+++ b/sections/projectstructre/createlayers.japanese.md
@@ -0,0 +1,13 @@
+# アプリケーションを階層化し、 Express を境界内に収める
+
+
+
+### 1分解説: レイヤーを混ぜることのデメリット
+
+
diff --git a/sections/projectstructre/createlayers.korean.md b/sections/projectstructre/createlayers.korean.md
index 029924a57..0278b8f20 100644
--- a/sections/projectstructre/createlayers.korean.md
+++ b/sections/projectstructre/createlayers.korean.md
@@ -1,13 +1,13 @@
-# Layer your app, keep Express within its boundaries
-
-
-
- ### Separate component code into layers: web, services, and DAL
-
-
-
-
-
-### 1 min explainer: The downside of mixing layers
-
-
+# 컴포넌트를 계층화(layer)하고, Express를 그 경계 안에 둬라
+
+
+
+ ### 컴포넌트 코드를 웹, 서비스, 데이터 접근 언어(DAL) 계층으로 나누어라
+
+
+
+
+
+### 1분 설명: 계층을 섞으면 불리한 점
+
+
diff --git a/sections/projectstructre/createlayers.md b/sections/projectstructre/createlayers.md
index 029924a57..f67f88cec 100644
--- a/sections/projectstructre/createlayers.md
+++ b/sections/projectstructre/createlayers.md
@@ -2,12 +2,27 @@
- ### Separate component code into layers: web, services, and DAL
+### Separate component code into 3 layers
-
+The root of every component should hold 3 folders that represent common concerns and stages of every transaction:
-
+```bash
+my-system
+├─ apps (components)
+│ ├─ component-a
+ │ ├─ entry-points
+ │ │ ├─ api # controller comes here
+ │ │ ├─ message-queue # message consumer comes here
+ │ ├─ domain # features and flows: DTO, services, logic
+ │ ├─ data-access # DB calls w/o ORM
+```
-### 1 min explainer: The downside of mixing layers
+**- Entry-points -** This is where requests and flows start, whether it's REST API, Graph, message queue, scheduled jobs or any other _door_ to the application. This layer's responsibility is quite minimal - adapt the payload (e.g., JSON) to the app format, including first validation, call the logic/domain layer and return a response. This is typically achieved with a few lines of code. Many use the term "controller" for this type of code also technically, its just an adapter
-
+**- Domain -** This is where the app flows, logic and data live. This layer accepts protocol-agnostic payload, plain JavaScript object and returns one as well. Technically it contains common code objects like services, dto/entities, and clients that call external services. It also typically calls the data-access layer to retrieve or persist information
+
+**- Data-access -** This is where the app holds code that interacts with DB. Ideally, it should externalize an interface that returns/gets plain JavaScript object that is DB agnostic (also known as the repository-pattern). This layer involves DB helper utilities like query builders, ORMs, DB drivers and other implementation libraries
+
+**What is the merit? -** When having flexible infrastructure that allows adding more API calls and DB queries promptly, a developer can code a feature faster by focusing on the domain folder. In other words, less time is spent on technical activities and more on activities with added value. This is a ubiquitous trait that is at the heart of most software architectures like DDD, hexagonal, clean-architecture and others. On top of this, when the domain layer is not aware of any edge protocol, it can serve any client and not only HTTP calls
+
+**Why not MVC or clean architecture? -** The 3-tier pattern strikes a great balance between achieving the separation goal while still keeping the structure simple. It also lacks abstractions - each tier represents real-world physical tier where every request will visit. On the other hand, MVC is a simplistic pattern where the letters VC represent a few lines of a code only and the letter M means anything else. Clean architecture is architecture with high level of abstractions that can achieve even greater separation but the price tag is unproportionally higher due to the increased complexity
\ No newline at end of file
diff --git a/sections/projectstructre/createlayers.polish.md b/sections/projectstructre/createlayers.polish.md
new file mode 100644
index 000000000..a9d30263c
--- /dev/null
+++ b/sections/projectstructre/createlayers.polish.md
@@ -0,0 +1,13 @@
+# Nakładaj warstwę na aplikację i trzymaj Express w jej granicach
+
+
+
+ ### Rozdziel kod komponentu na warstwy: sieć, usługi i DAL
+
+
+
+
+
+### 1 minuta wyjaśniania: Minusem mieszanie warstw
+
+
diff --git a/sections/projectstructre/createlayers.russian.md b/sections/projectstructre/createlayers.russian.md
index 8b0383087..b7c2865b0 100644
--- a/sections/projectstructre/createlayers.russian.md
+++ b/sections/projectstructre/createlayers.russian.md
@@ -1,13 +1,13 @@
-# Выделяйте ваши компоненты в отдельный слой, держите Express в его граница
+# Выделяйте ваши компоненты в отдельный слой, держите Express в его границах
### Разделить код компонента на слои: веб, сервисы и DAL
-
+
### 1 минутное объяснение: обратная сторона смешения слоев
-
+
diff --git a/sections/projectstructre/separateexpress.basque.md b/sections/projectstructre/separateexpress.basque.md
new file mode 100644
index 000000000..a47b8e6fb
--- /dev/null
+++ b/sections/projectstructre/separateexpress.basque.md
@@ -0,0 +1,102 @@
+# Banandu Express 'aplikazioa' eta 'zerbitzaria'
+
+
+
+### Azalpena
+
+Azken Express sorgailuak mantentzea merezi duen sekulako praktika bikaina du. Izan ere, APIaren deklarazioa sarearekin erlazionatutako ezarpenetatik (portua, protokoloa, etab.) banandua dago. Horrek ahalbidetzen du APIa egiaztatzea prozesua martxan den bitartean, sare deirik egin gabe eta horrek dakartzan onura guztiekin: egiaztatze azkarren exekuzioa eta estalduraren metrikak eskuratzea. API bera sare baldintza malgu eta ezberdinetan inplementatzea ere ahalbidetzen du. Gehigarria: arduren bereizte hobea eta kode garbiagoa
+
+
+
+### Kode adibidea: APIaren deklarazioak app.js/app.ts-en barruan egon beharko luke
+
+```javascript
+const app = express();
+app.use(bodyParser.json());
+app.use("/api/events", events.API);
+app.use("/api/forms", forms);
+```
+
+### Kode adibidea: zerbitzari sarearen deklarazioak /bin/www-en barruan egon beharko luke
+
+
+Javascript
+
+```javascript
+const app = require("../app");
+const http = require("http");
+
+// Ingurunearen portua eskuratu eta Expressen gorde.
+const port = normalizePort(process.env.PORT || "3000");
+app.set("port", port);
+
+// Sortu HTTP zerbitzaria.
+const server = http.createServer(app);
+```
+
+
+
+
+Typescript
+
+```typescript
+import app from "../app";
+import http from "http";
+
+// Ingurunearen portua eskuratu eta Expressen gorde.
+const port = normalizePort(process.env.PORT || "3000");
+app.set("port", port);
+
+// Sortu HTTP zerbitzaria.
+const server = http.createServer(app);
+```
+
+
+
+### Kode adibidea: zure APIa prozesua martxan den bitartean probatu supertest (probentzako pakete ospetsua) erabiliz
+
+
+Javascript
+
+```javascript
+const request = require("supertest");
+const app = express();
+
+app.get("/user", (req, res) => {
+ res.status(200).json({ name: "tobi" });
+});
+
+request(app)
+ .get("/user")
+ .expect("Content-Type", /json/)
+ .expect("Content-Length", "15")
+ .expect(200)
+ .end((err, res) => {
+ if (err) throw err;
+ });
+```
+
+
+
+
+Typescript
+
+```typescript
+import * as request from "supertest";
+const app = express();
+
+app.get("/user", (req: Request, res: Response) => {
+ res.status(200).json({ name: "tobi" });
+});
+
+request(app)
+ .get("/user")
+ .expect("Content-Type", /json/)
+ .expect("Content-Length", "15")
+ .expect(200)
+ .end((err: Error) => {
+ if (err) throw err;
+ });
+```
+
+
diff --git a/sections/projectstructre/separateexpress.french.md b/sections/projectstructre/separateexpress.french.md
new file mode 100644
index 000000000..dea000f63
--- /dev/null
+++ b/sections/projectstructre/separateexpress.french.md
@@ -0,0 +1,100 @@
+# Séparez Express 'app' et 'server'
+
+
+
+### Un paragraphe d'explication
+
+Le dernier générateur Express est livré avec une excellente pratique qui vaut la peine d'être conservée - la déclaration de l'API est séparée de la configuration liée au réseau (port, protocole, etc.). Cela permet de tester l'API en cours de traitement, sans effectuer d'appels réseau, avec tous les avantages qu'elle apporte : exécution rapide des tests et obtention des mesures de couverture du code. Il permet également de déployer la même API dans des conditions de réseau flexibles et différentes. Bonus : une meilleure séparation des préoccupations et un code plus propre.
+
+
+
+### Exemple de code : la déclaration de l'API doit résider dans app.js/app.ts
+
+```javascript
+const app = express();
+app.use(bodyParser.json());
+app.use('/api/events', events.API);
+app.use('/api/forms', forms);
+```
+
+### Exemple de code : la déclaration du réseau du serveur doit résider dans /bin/www
+
+
+Javascript
+
+```javascript
+const app = require('../app');
+const http = require('http');
+
+// Obtenir le port de l'environnement et le stockez dans Express.
+const port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+// Créer un serveur HTTP.
+const server = http.createServer(app);
+```
+
+
+
+Typescript
+
+```typescript
+import app from '../app';
+import http from 'http';
+
+// Obtenir le port de l'environnement et le stockez dans Express.
+const port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+// Créer un serveur HTTP.
+const server = http.createServer(app);
+```
+
+
+### Exemple : testez votre API en cours de traitement à l'aide de supertest (package de test populaire)
+
+
+Javascript
+
+```javascript
+const request = require('supertest');
+const app = express();
+
+app.get('/user', (req, res) => {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end((err, res) => {
+ if (err) throw err;
+ });
+```
+
+
+
+
+Typescript
+
+```typescript
+import * as request from "supertest";
+const app = express();
+
+app.get('/user', (req: Request, res: Response) => {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end((err: Error) => {
+ if (err) throw err;
+ });
+
+```
+
\ No newline at end of file
diff --git a/sections/projectstructre/separateexpress.japanese.md b/sections/projectstructre/separateexpress.japanese.md
new file mode 100644
index 000000000..43ce37282
--- /dev/null
+++ b/sections/projectstructre/separateexpress.japanese.md
@@ -0,0 +1,100 @@
+# Express の「アプリ」と「サーバー」を分離する
+
+
+
+### 一段落説明
+
+最新の Express ジェネレーターは、維持する価値がある素晴らしいプラクティスが付属しています。- API 宣言はネットワーク関連の設定 (ポート、プロトコルなど) から分離されています。これにより、ネットワークコールを実行せずに API をインプロセスでテストすることができ、高速なテスト実行やコードのカバレッジメトリクスの取得などのメリットが得られます。 また、柔軟で異なるネットワーク条件の下で同じ API をデプロイすることができます。ボーナス:懸念事項のより良い分離とよりクリーンなコード
+
+
+
+### コード例: API 宣言は app.js/app.ts にあるべき
+
+```javascript
+const app = express();
+app.use(bodyParser.json());
+app.use('/api/events', events.API);
+app.use('/api/forms', forms);
+```
+
+### コード例: サーバーネットワーク定義は /bin/www にあるべき
+
+
+Javascript
+
+```javascript
+const app = require('../app');
+const http = require('http');
+
+// Get port from environment and store in Express.
+const port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+// Create HTTP server.
+const server = http.createServer(app);
+```
+
+
+
+Typescript
+
+```typescript
+import app from '../app';
+import http from 'http';
+
+// Get port from environment and store in Express.
+const port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+// Create HTTP server.
+const server = http.createServer(app);
+```
+
+
+### 例: supertest (一般的なテストパッケージ) を使用して API をインプロセスでテストする
+
+
+Javascript
+
+```javascript
+const request = require('supertest');
+const app = express();
+
+app.get('/user', (req, res) => {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end((err, res) => {
+ if (err) throw err;
+ });
+```
+
+
+
+
+Typescript
+
+```typescript
+import * as request from "supertest";
+const app = express();
+
+app.get('/user', (req: Request, res: Response) => {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end((err: Error) => {
+ if (err) throw err;
+ });
+
+```
+
diff --git a/sections/projectstructre/separateexpress.md b/sections/projectstructre/separateexpress.polish.md
similarity index 63%
rename from sections/projectstructre/separateexpress.md
rename to sections/projectstructre/separateexpress.polish.md
index 679b2a8be..77cba2980 100644
--- a/sections/projectstructre/separateexpress.md
+++ b/sections/projectstructre/separateexpress.polish.md
@@ -1,98 +1,98 @@
-# 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/app.ts
-
-```javascript
-const 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
-
-```javascript
-const app = require('../app');
-const http = require('http');
-
-// Get port from environment and store in Express.
-const port = normalizePort(process.env.PORT || '3000');
-app.set('port', port);
-
-// Create HTTP server.
-const server = http.createServer(app);
-```
-
-
-
-Typescript
-
-```typescript
-import app from '../app';
-import http from 'http';
-
-// Get port from environment and store in Express.
-const port = normalizePort(process.env.PORT || '3000');
-app.set('port', port);
-
-// Create HTTP server.
-const server = http.createServer(app);
-```
-
-
-### Example: test your API in-process using supertest (popular testing package)
-
-
-Javascript
-
-```javascript
-const app = express();
-
-app.get('/user', (req, res) => {
- res.status(200).json({ name: 'tobi' });
-});
-
-request(app)
- .get('/user')
- .expect('Content-Type', /json/)
- .expect('Content-Length', '15')
- .expect(200)
- .end((err, res) => {
- if (err) throw err;
- });
-```
-
-
-
-
-Typescript
-
-```typescript
-const app = express();
-
-app.get('/user', (req: Request, res: Response) => {
- res.status(200).json({ name: 'tobi' });
-});
-
-request(app)
- .get('/user')
- .expect('Content-Type', /json/)
- .expect('Content-Length', '15')
- .expect(200)
- .end((err: Error) => {
- if (err) throw err;
- });
-
-```
-
\ No newline at end of file
+# Oddzielna „aplikacja” i „serwer” Express
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Najnowszy generator Express ma świetną praktykę, którą warto zachować - deklaracja API jest oddzielona od konfiguracji związanej z siecią (port, protokół itp.). Umożliwia to testowanie interfejsu API w trakcie procesu, bez wykonywania połączeń sieciowych, ze wszystkimi korzyściami, które przynosi do tabeli: szybkie wykonywanie testów i uzyskiwanie wskaźników zasięgu kodu. Pozwala także na wdrożenie tego samego interfejsu API w elastycznych i różnych warunkach sieciowych. Bonus: lepsze rozdzielenie problemów i czystszy kod
+
+
+
+### Przykład kodu: deklaracja API, powinna znajdować się w app.js/app.ts
+
+```javascript
+const app = express();
+app.use(bodyParser.json());
+app.use('/api/events', events.API);
+app.use('/api/forms', forms);
+```
+
+### Przykład kodu: Deklaracja sieci serwera powinna znajdować się w /bin/www
+
+
+Javascript
+
+```javascript
+const app = require('../app');
+const http = require('http');
+
+// Get port from environment and store in Express.
+const port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+// Create HTTP server.
+const server = http.createServer(app);
+```
+
+
+
+Typescript
+
+```typescript
+import app from '../app';
+import http from 'http';
+
+// Get port from environment and store in Express.
+const port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+// Create HTTP server.
+const server = http.createServer(app);
+```
+
+
+### Przykład: przetestuj swój interfejs API za pomocą supertestu (popularny pakiet testowy)
+
+
+Javascript
+
+```javascript
+const app = express();
+
+app.get('/user', (req, res) => {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end((err, res) => {
+ if (err) throw err;
+ });
+```
+
+
+
+
+Typescript
+
+```typescript
+const app = express();
+
+app.get('/user', (req: Request, res: Response) => {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end((err: Error) => {
+ if (err) throw err;
+ });
+
+```
+
diff --git a/sections/projectstructre/separateexpress.russian.md b/sections/projectstructre/separateexpress.russian.md
index 2f87ec283..f7190f071 100644
--- a/sections/projectstructre/separateexpress.russian.md
+++ b/sections/projectstructre/separateexpress.russian.md
@@ -8,43 +8,58 @@
-### Пример кода: объявление API, должно находиться в app.js
+### Пример кода: объявление API, должно находиться в app.js/app.ts
```javascript
-var app = express();
+const app = express();
app.use(bodyParser.json());
-app.use("/api/events", events.API);
-app.use("/api/forms", forms);
+app.use('/api/events', events.API);
+app.use('/api/forms', forms)
```
-
-
### Пример кода: сетевое объявление сервера должно находиться в /bin/www
-```javascript
-var app = require('../app');
-var http = require('http');
+
+Javascript
-/**
- * Get port from environment and store in Express.
- */
+```javascript
+const app = require('../app');
+const http = require('http');
-var port = normalizePort(process.env.PORT || '3000');
+// Get port from environment and store in Express.
+const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
-/**
- * Create HTTP server.
- */
+// Create HTTP server.
+const server = http.createServer(app);
+```
+
+
+
+Typescript
+
+```typescript
+import app from '../app';
+import http from 'http';
-var server = http.createServer(app);
+// Get port from environment and store in Express.
+const port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+// Create HTTP server.
+const server = http.createServer(app);
```
+
### Пример: протестируйте свой API в процессе, используя supertest (популярный пакет тестирования)
+
+Javascript
+
```javascript
const app = express();
-app.get('/user', function(req, res) {
+app.get('/user', (req, res) => {
res.status(200).json({ name: 'tobi' });
});
@@ -53,7 +68,31 @@ request(app)
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
- .end(function(err, res) {
+ .end((err, res) => {
if (err) throw err;
});
-````
+```
+
+
+
+
+Typescript
+
+```typescript
+const app = express();
+
+app.get('/user', (req: Request, res: Response) => {
+ res.status(200).json({ name: 'tobi' });
+});
+
+request(app)
+ .get('/user')
+ .expect('Content-Type', /json/)
+ .expect('Content-Length', '15')
+ .expect(200)
+ .end((err: Error) => {
+ if (err) throw err;
+ });
+
+```
+
\ No newline at end of file
diff --git a/sections/projectstructre/thincomponents.chinese.md b/sections/projectstructre/thincomponents.chinese.md
index d55704b02..5b036ddb4 100644
--- a/sections/projectstructre/thincomponents.chinese.md
+++ b/sections/projectstructre/thincomponents.chinese.md
@@ -18,9 +18,9 @@
### 推荐: 通过自包含的组件来构造解决方案
-
+
### 避免: 通过技术角色对文件进行分组
-
+
diff --git a/sections/projectstructre/thincomponents.french.md b/sections/projectstructre/thincomponents.french.md
new file mode 100644
index 000000000..91c5e05c0
--- /dev/null
+++ b/sections/projectstructre/thincomponents.french.md
@@ -0,0 +1,27 @@
+# Organisez votre projet en composants
+
+
+
+### Un paragraphe d'explication
+
+Pour les applications de taille moyenne et supérieure, les monolithes sont vraiment mauvais - avoir un gros logiciel avec de nombreuses dépendances est difficile à appréhender et mène souvent à du code spaghetti. Même les architectes intelligents - ceux qui sont suffisamment qualifiés pour apprivoiser la bête et la « modulariser » - consacrent un temps considérable à sa conception, et chaque changement nécessite d'évaluer soigneusement l'impact sur d'autres objets dépendants. La solution ultime est de développer de petits logiciels : divisez la pile entière en composants autonomes qui ne partagent pas de fichiers avec d'autres, chacun constituant très peu de fichiers (par exemple API, service, accès aux données, test, etc.) de sorte qu'il soit très facile à raisonner à ce sujet. Certains peuvent appeler cette architecture de « microservices » - il est important de comprendre que les microservices ne sont pas une spécification que vous devez suivre, mais plutôt un ensemble de principes. Vous pouvez adopter tous les principes dans une architecture de microservices ou en adopter seulement quelques-uns. Les deux sont bons tant que la complexité du logiciel est faible. Le moins que vous puissiez faire est de créer des frontières de base entre les composants, d'assigner un dossier à la racine de votre projet pour chaque composant métier et de le rendre autonome - les autres composants ne sont autorisés à utiliser ses fonctionnalités que via son interface publique ou son API. C'est la base pour garder vos composants simples, éviter l'enfer des dépendances et ouvrir à l'avenir la voie à des véritables microservices une fois que votre application se développera.
+
+
+
+### Citation de blog : « La mise à l'échelle nécessite la mise à l'échelle de l'application entière »
+
+ Extrait du blog de MartinFowler.com
+
+ > Les applications monolithiques peuvent réussir, mais de plus en plus de personnes ressentent des frustrations à leur égard, d'autant plus que davantage d'applications sont déployées dans le cloud. Les cycles de changement sont liés les uns aux autres - une modification apportée à une petite partie de l'application nécessite la reconstruction et le déploiement du monolithe entier. Au fil du temps, il est souvent difficile de conserver une bonne structure modulaire, ce qui rend plus difficile la conservation des modifications qui ne devraient affecter qu'un module au sein de ce module. La mise à l'échelle nécessite la mise à l'échelle de l'application entière plutôt que les parties concernées, cela nécessitent donc plus de ressources.
+
+
+
+### Bon : Organisez votre solution avec des composants autonomes
+
+
+
+
+
+### Mauvais : Regroupez vos fichiers selon leur rôle technique
+
+
diff --git a/sections/projectstructre/thincomponents.japanese.md b/sections/projectstructre/thincomponents.japanese.md
new file mode 100644
index 000000000..e586d6884
--- /dev/null
+++ b/sections/projectstructre/thincomponents.japanese.md
@@ -0,0 +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
+
+
+
+
+
+### Bad: Group your files by technical role
+
+
diff --git a/sections/projectstructre/thincomponents.md b/sections/projectstructre/thincomponents.md
index b248637b4..e586d6884 100644
--- a/sections/projectstructre/thincomponents.md
+++ b/sections/projectstructre/thincomponents.md
@@ -18,10 +18,10 @@ For medium sized apps and above, monoliths are really bad - one big software wit
### Good: Structure your solution by self-contained components
-
+
### Bad: Group your files by technical role
-
+
diff --git a/sections/projectstructre/thincomponents.russian.md b/sections/projectstructre/thincomponents.russian.md
index 4aa6baecb..6f3c6a1be 100644
--- a/sections/projectstructre/thincomponents.russian.md
+++ b/sections/projectstructre/thincomponents.russian.md
@@ -18,10 +18,10 @@
### Хорошо: структурируйте свое решение по отдельным компонентам
-
+
### Плохо: сгруппируйте файлы по техническим ролям
-
+
diff --git a/sections/projectstructre/typescript-considerations.md b/sections/projectstructre/typescript-considerations.md
new file mode 100644
index 000000000..fcf881111
--- /dev/null
+++ b/sections/projectstructre/typescript-considerations.md
@@ -0,0 +1,23 @@
+# Use TypeScript sparingly and thoughtfully
+
+
+
+### One Paragraph Explainer
+
+TypeScript has won the community's hearts and is almost a standard for modern JavaScript apps. Compared to plain JS, it brings much better coding ergonomics, facilitates editor code completions, even for historical libraries that were written with JavaScript and was proven to [prevent specific type of bugs](https://earlbarr.com/publications/typestudy.pdf). With that, if you look carefully under the hype, TypeScript actually brings two **mutually-exclusive** offerings to the table: type-safety and advanced design constructs like abstract classes, interfaces, namespaces and more. Many teams chose TypeScript for better type safety yet _unintentionally_, without any proper planning, use it for other purposes, such as OOP. These teams change their design style unintentionally due to the ['law of the instruments'](https://en.wikipedia.org/wiki/Law_of_the_instrument) — a cognitive bias that involves using the tooling in hand whether they are the right choice for the mission or not. In other words, if an 'abstract class' exists in the toolbox — developers will use it. If teams consciously opted for the coding techniques mentioned above — that's fair and legit. For others, positively consider coding with classic JavaScript, plain functions and objects, which are simply decorated with primitive types. The latter option is likely to result in lower complexity
+
+
+
+### Research Quote: "15% less bugs"
+
+From the research [To Type or Not to Type](https://earlbarr.com/publications/typestudy.pdf)
+
+> "our central finding is that both static type systems find an important percentage of public bugs: both Flow 0.30 and TypeScript 2.0 successfully detect 15%!"
+
+
+
+### Blog Quote: "TypeScript will always miss 80% of bugs"
+
+From the post [The TypeScript tax](https://medium.com/javascript-scene/the-typescript-tax-132ff4cb175b)
+
+> "Some will argue that TypeScript provides realtime bug feedback, so you can catch the bugs earlier, but so do type inference, lint, and testing... You may argue that these other measures have a cost, but because TypeScript will always miss 80% of bugs, you can’t safely skip them either way, so their cost applies to both sides of the ROI math, and is already factored in"
diff --git a/sections/projectstructre/wraputilities.basque.md b/sections/projectstructre/wraputilities.basque.md
new file mode 100644
index 000000000..18efeeb0f
--- /dev/null
+++ b/sections/projectstructre/wraputilities.basque.md
@@ -0,0 +1,15 @@
+# Kokatu baliabide komunak npm paketetan
+
+
+
+### Azalpena
+
+Hazten hasi eta zerbitzari ezberdinetan antzeko baliabideak erabiltzen dituzten gero eta osagai ezberdin gehiago dituzun heinean, menpekotasunak kudeatzen hasi beharko zenuke. Nola gorde zenezakeen zure baliabidearen iturburu kodearen kopia bat eta beste osagaiei hura erabiltzen eta inplementatzen utzi? Bada, npm izeneko tresna bat badago horretarako... Hasi baliabide paketeetan zure kodea jartzen, etorkizunean kodearen ordezkapena errazteko, eta argitaratu zure kode propioa npm pakete pribatu gisa. Horrela, zure kodeak beste kode hori inportatu ahal izango du, debaldeko menpekotasun kudeaketa tresnari esker. Posible da zure erabilera pribaturako npm paketeak argitaratzea, haiek publikoki partekatu gabe, [modulu pribatuak](https://docs.npmjs.com/private-modules/intro), [erregistro pribatua](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) edo [npm pakete lokalak](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc) erabiliz
+
+
+
+
+
+### Partekatu zure baliabide propioak ingurune eta osagaietan
+
+
diff --git a/sections/projectstructre/wraputilities.brazilian-portuguese.md b/sections/projectstructre/wraputilities.brazilian-portuguese.md
index 95b643bc1..13d54d763 100644
--- a/sections/projectstructre/wraputilities.brazilian-portuguese.md
+++ b/sections/projectstructre/wraputilities.brazilian-portuguese.md
@@ -10,4 +10,4 @@ Quando você começa a crescer e tem componentes diferentes em servidores difere
### Compartilhando seus próprios utilitários comuns em ambientes e componentes
-
+
diff --git a/sections/projectstructre/wraputilities.chinese.md b/sections/projectstructre/wraputilities.chinese.md
index 1d3f14457..aa9e1a96b 100644
--- a/sections/projectstructre/wraputilities.chinese.md
+++ b/sections/projectstructre/wraputilities.chinese.md
@@ -11,4 +11,4 @@
### 在环境和组件中共享你自己的公用实用工具
-
+
diff --git a/sections/projectstructre/wraputilities.french.md b/sections/projectstructre/wraputilities.french.md
new file mode 100644
index 000000000..523c5fc52
--- /dev/null
+++ b/sections/projectstructre/wraputilities.french.md
@@ -0,0 +1,13 @@
+# Externalisez les utilitaires communs en paquets NPM
+
+
+
+### Un paragraphe d'explication
+
+Une fois que vous commencez à vous développer et que vous avez différents composants sur différents serveurs qui consomment des utilitaires similaires, vous devez commencer à gérer les dépendances - comment pouvez-vous conserver une copie de votre code utilitaire et laisser plusieurs composants consommateurs l'utiliser et le déployer ? Eh bien, il y a un outil pour ça, ça s'appelle npm ... Commencez par emballer des paquets d'utilitaires tiers avec votre propre code pour le rendre facilement remplaçable à l'avenir et publiez votre propre code en tant que package npm privé. Désormais, toute votre base de code peut importer ce code et bénéficier d'un outil de gestion des dépendances gratuit. Il est possible de publier des packages npm pour votre propre usage privé sans le partager publiquement à l'aide de [modules privés](https://docs.npmjs.com/private-modules/intro), [registre privé](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) ou de [paquets npm locaux](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc).
+
+
+
+### Partage de vos propres utilitaires communs entre les environnements et les composants
+
+
diff --git a/sections/projectstructre/wraputilities.japanese.md b/sections/projectstructre/wraputilities.japanese.md
new file mode 100644
index 000000000..52060026e
--- /dev/null
+++ b/sections/projectstructre/wraputilities.japanese.md
@@ -0,0 +1,13 @@
+# 一般的なユーティリティを npm パッケージとしてラップする
+
+
-
-### 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
-
-
+# 공유 유틸리티들은 NPM 패키지로 감싸라 (wrap)
+
+
+
+### 한문단 설명
+
+자라나기 시작하면서 비슷한 유틸리티들을 소비하는 다른 서버의 다른 컴포넌트들이 생겨나면 의존성을 관리하기 시작해야 한다 - 유틸리티 코드 한 부를 어떻게 소비자 컴포넌트 여럿이서 같이 쓰고 배치할 수 있게 하는가? 자, 여기 쓸만한 도구가 여기 있다...npm이라 불리는. 먼저 제삼자 유틸리티 패키지를 자신만의 코드로 감싸 미래에 대체하기 쉽게 하고 그 코드를 private npm 패키지로 publish해라. 이제 당신의 모든 코드 기반은 그 코드를 수입하여 무료 의존성 관리 도구의 혜택을 볼 수 있다. [private 모듈](https://docs.npmjs.com/private-modules/intro)이나 [private 레지스트리](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html), 혹은 [로컬 npm 패키지](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)를 사용하면 npm 패키지를 공개적으로 공유하지 않고도 자용으로 쓸 수 있게 출판할 수 있다.
+
+
+
+### 당신만의 공유 유틸리티들을 환경과 컴포넌츠에 공유하기
+
+
diff --git a/sections/projectstructre/wraputilities.md b/sections/projectstructre/wraputilities.md
index 4b52ff6db..4d9e3da62 100644
--- a/sections/projectstructre/wraputilities.md
+++ b/sections/projectstructre/wraputilities.md
@@ -10,4 +10,4 @@ Once you start growing and have different components on different servers which
### Sharing your own common utilities across environments and components
-
+
diff --git a/sections/projectstructre/wraputilities.polish.md b/sections/projectstructre/wraputilities.polish.md
new file mode 100644
index 000000000..bbd4432a1
--- /dev/null
+++ b/sections/projectstructre/wraputilities.polish.md
@@ -0,0 +1,13 @@
+# Zawiń typowe narzędzia jako pakiety npm
+
+
+
+### Wyjaśnienie jednym akapitem
+
+Kiedy zaczniesz się rozwijać i będziesz mieć różne komponenty na różnych serwerach, które zużywają podobne narzędzia, powinieneś zacząć zarządzać zależnościami - w jaki sposób możesz zachować 1 kopię kodu narzędzia i pozwolić, aby wiele komponentów konsumenckich używało go i wdrażało? Cóż, istnieje narzędzie do tego, nazywa się npm... Zacznij od zawinięcia pakietów narzędziowych stron trzecich własnym kodem, aby w przyszłości można go łatwo było wymienić i opublikować własny kod jako prywatny pakiet npm. Teraz cała baza kodu może zaimportować ten kod i bezpłatne narzędzie do zarządzania zależnościami. Możliwe jest publikowanie pakietów NPM na własny użytek bez publicznego udostępniania go za pomocą [prywatnych modułów](https://docs.npmjs.com/private-modules/intro), [prywatnego rejestru](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) lub [lokalnych pakietów npm](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
+
+
+
+### Udostępnianie własnych wspólnych narzędzi w różnych środowiskach i komponentach
+
+
diff --git a/sections/projectstructre/wraputilities.russian.md b/sections/projectstructre/wraputilities.russian.md
index 25d79804c..3520ef383 100644
--- a/sections/projectstructre/wraputilities.russian.md
+++ b/sections/projectstructre/wraputilities.russian.md
@@ -10,4 +10,4 @@
### Совместное использование собственных общих утилит в средах и компонентах
-
+
diff --git a/sections/security/avoid_publishing_secrets.basque.md b/sections/security/avoid_publishing_secrets.basque.md
new file mode 100644
index 000000000..fab83a08a
--- /dev/null
+++ b/sections/security/avoid_publishing_secrets.basque.md
@@ -0,0 +1,49 @@
+# Saihestu npm erregistroan sekretuak argitaratzea
+
+### Azalpena
+
+Arreta eduki behar da npm erregistroetan sekretuak istripuz argitaratzeko arriskua dago eta. `.npmignore` fitxategia erabil daiteke fitxategi eta karpeta zehatz batzuk zerrenda beltzean jartzeko, edota `files` zerrendak `package.json`en zerrenda txuri gisa joka dezake.
+
+npmek erregistroan benetan argitaratzen duenaren ikuspegia edukitzeko, `--dry-run` gehi daiteke npm publish komandora sortutako paketearen ikuspegi esanguratsua edukitzeko.
+
+Garrantzitsua da kontutan edukitzea, proiektu batek `.npmignore` eta `.gitignore` fitxategiak erabiltzen baditu, `.npmignore`ren barruan dagoena erregistroan argitaratuko dela (esaterako, `.npmignore` fitxategiak `.gitignore` berridazten du). Baldintza hori nahasgarria izan daiteke eta sekretuak argitaratzeko arriskua ekar dezake. Programatzaileek `.gitignore` fitxategia egunera dezakete, baina `.npmignore` eguneratzea ahaztu, eta horrek fitxategi garrantzitsuak iturburu kontrolean ez argitaratzea ekar dezake, npm paketean egon arren
+
+### Kode adibidea
+
+.npmignore fitxategiaren adibidea
+
+```
+# Probak
+test
+coverage
+
+# Eraikitze tresnak
+.travis.yml
+.jenkins.yml
+
+# Ingurunea
+.env
+.config
+
+```
+
+"files" zerrenda package.jsonen erabiltzearen adibidea
+
+```json
+{
+ "files" : [
+ "dist/moment.js",
+ "dist/moment.min.js"
+ ]
+}
+```
+
+### Beste blogari batzuek diotena
+
+[Liran Tal & Juan Picado at Snyk](https://snyk.io/blog/ten-npm-security-best-practices/) bloga:
+
+> ... Erabil beharreko beste jarduera egoki bat package.json fitxategiko files ezaugarria da, zerrenda zuri bezala funtzionatzen duena eta sortu eta instalatu beharreko paketean fitxategien multzoa zehazten duena (aintzakotzat ez hartzeko (ignore) fitxategiak zerrenda beltz gisa funtzionatzen duelarik). Filesen ezaugarria eta aintzakotzat ez hartzeko fitxategiak batera erabil daitezke esplizituki zein fitxategi gehitu edo baztertu behar diren zehazteko. Biak erabiltzean, package.jsoneko aurreko filesen ezagugarriak lehentasuna hartzen du aintzakotzat ez hartzeko fitxategiaren parean.
+
+[npm blog](https://blog.npmjs.org/post/165769683050/publishing-what-you-mean-to-publish)a:
+
+> ... npm publish exekutatzean, npmek lekuko direktorioko fitxategi guztiak bateratzen ditu. Zer gehitu eta alde batera zer utzi erabakitzen du zure ordez. Erabaki horiek hartzeko zure proiektuko direktorioko hainbat fitxategiren edukiak erabiltzen ditu. Fitxategi horien artean, .gitignore, .npmingnore eta package.jsoneko files zerrenda aurkitzen dira. Gainera, beti gehitzen ditu fitxategi jakin batzuk, eta beste batzuk alde batera utzi.
diff --git a/sections/security/avoid_publishing_secrets.brazilian-portuguese.md b/sections/security/avoid_publishing_secrets.brazilian-portuguese.md
index dea51020e..23c9fabed 100644
--- a/sections/security/avoid_publishing_secrets.brazilian-portuguese.md
+++ b/sections/security/avoid_publishing_secrets.brazilian-portuguese.md
@@ -10,15 +10,15 @@ Para obter uma visão do que o npm publish realmente publicará no registro, o s
### Exemplo de Código
Exemplo de arquivo .npmignore
```
-#tests
+# Tests
test
coverage
-#build tools
+# Build tools
.travis.yml
.jenkins.yml
-#environment
+# Environment
.env
.config
@@ -26,7 +26,7 @@ coverage
Exemplo uso de uma lista de arquivos no package.json
-```
+```json
{
"files" : [
"dist/moment.js",
diff --git a/sections/security/avoid_publishing_secrets.french.md b/sections/security/avoid_publishing_secrets.french.md
new file mode 100644
index 000000000..ad3d8ee70
--- /dev/null
+++ b/sections/security/avoid_publishing_secrets.french.md
@@ -0,0 +1,44 @@
+# Éviter de publier les secrets dans le registre npm
+
+### Un paragraphe d'explication
+Des précautions doivent être prises pour éviter de publier accidentellement des secrets dans un registre public npm. Un fichier `.npmignore` peut être utilisé pour ignorer des fichiers ou dossiers spécifiques, ou le tableau `files` du `package.json` peut être utilisé comme une liste blanche.
+
+Pour savoir ce que npm publish va vraiment publier sur le registre, l'option `--dry-run` peut être ajoutée à la commande npm publish pour obtenir un résultat verbeux du package crée.
+
+Il est important de noter que si un projet utilise à la fois des fichiers `.npmignore` et `.gitignore`, tout ce qui n'est pas dans `.npmignore` est publié dans le registre (c'est-à-dire que le fichier `.npmignore` écrase `.gitignore`). Cette condition est communément une source de confusion et un problème qui peut mener à la fuite de secrets. Les développeurs ont l'habitude de mettre à jour le fichier `.gitignore`, mais peuvent oublier de faire de même avec `.npmignore`, ce qui peut conduire à ce qu'un potentiel fichier sensible ne soit pas envoyé sur l'outil de gestion des versions, mais soit toujours inclus dans le package npm.
+
+### Exemple de code
+Fichier d'exemple .npmignore
+```
+# Tests
+test
+coverage
+
+# Build tools
+.travis.yml
+.jenkins.yml
+
+# Environment
+.env
+.config
+
+```
+
+Exemple d'usage du tableau files de package.json
+
+```json
+{
+ "files" : [
+ "dist/moment.js",
+ "dist/moment.min.js"
+ ]
+}
+```
+
+### Ce que disent les autres blogueurs
+
+Extrait du blog de [Liran Tal & Juan Picado sur Snyk](https://snyk.io/blog/ten-npm-security-best-practices/):
+> ... Une autre bonne pratique à adopter est d'utiliser la propriété files du package.json, qui fonctionne comme une liste blanche et spécifie un tableau de fichiers à inclure dans le package qui sera créé et installé (tandis que le fichier .npmignore fonctionne comme une liste noire). La propriété files et le fichier .npmignore peuvent être utilisés ensemble pour déterminer explicitement quels fichiers doivent être inclus, et exclus, du package. Quand les deux sont utilisés, la propriété files du package.json a la priorité sur le fichier .npmignore.
+
+Extrait du blog de [blog de npm](https://blog.npmjs.org/post/165769683050/publishing-what-you-mean-to-publish)
+> ... Quand vous exécutez npm publish, npm met dans le package l'ensemble des fichiers du répertoire courant. Il prend quelques décisions pour vous à propos de ce qu'il faut inclure et de ce qu'il faut ignorer. Pour prendre ces décisions, il utilise le contenu de plusieurs fichiers dans le répertoire de votre projet. Ces fichiers incluent .gitignore, .npmignore, et le tableau files dans package.json. De plus, il inclut toujours certains fichiers et en ignore d'autres.
\ No newline at end of file
diff --git a/sections/security/avoid_publishing_secrets.japanese.md b/sections/security/avoid_publishing_secrets.japanese.md
new file mode 100644
index 000000000..3011094eb
--- /dev/null
+++ b/sections/security/avoid_publishing_secrets.japanese.md
@@ -0,0 +1,44 @@
+# npm レジストリへのシークレットの公開を避ける
+
+### 一段落説明
+誤ってシークレットをパブリック npm レジストリに公開してしまうリスクを回避するように、注意を払ってください。`.npmignore` ファイルを利用して、特定のファイルやフォルダをブラックリスト化したり、`package.json` 内の `files` 配列をホワイトリストとして利用することができます。
+
+npm publish が実際にレジストリに何をパブリッシュするのかを確認するために、`--dry-run` フラグを npm publish コマンドに追加して、作成されたパッケージの詳細情報を表示させることができます。
+
+プロジェクトが `.npmignore` と `.gitignore` ファイルの両方を利用している場合には、`.npmignore` 内に記載されていないものはすべてレジストリにパブリッシュされる(つまり、`.npmigore` ファイルは `.gitignore` ファイルを上書きする)ことに注意することが重要です。この制約は、よくある混乱の元凶であり、シークレットを漏洩することに繋がりうる問題です。開発者は最終的に `.gitignore` ファイルを更新するかもしれませんが、`.npmignore` を更新することを忘れ、潜在的に機密なファイルが、ソースコントロールにはプッシュされていないが、npm パッケージには依然含まれている、という状況になりえます。
+
+### コード例
+.npmignore file の例
+```
+# Tests
+test
+coverage
+
+# Build tools
+.travis.yml
+.jenkins.yml
+
+# Environment
+.env
+.config
+
+```
+
+package.json 内の files 配列の利用例
+
+```json
+{
+ "files" : [
+ "dist/moment.js",
+ "dist/moment.min.js"
+ ]
+}
+```
+
+### 他のブロガーが言っていること
+
+[Liran Tal & Juan Picado at Snyk](https://snyk.io/blog/ten-npm-security-best-practices/) のブログより:
+> ... その他のグッドプラクティスは、package.json の files プロパティを利用することです。これは(ignore files はブラックリストとして機能する一方で)ホワイトリストとして機能し、作成されてインストールされるパッケージに含むファイルの配列を指定します。パッケージに含まれるべきファイルとそうでないファイルを決定するために、files プロパティと ignore files の両方を同時に利用することができます。両方を利用する際は、package.json の files プロパティが ignore ファイルよりも優先されます。
+
+[npm blog](https://blog.npmjs.org/post/165769683050/publishing-what-you-mean-to-publish) より:
+> ... npm publish を実行すると、npm はカレントディレクトリのファイルすべてをバンドル化します。どのファイルを含み、どのファイルを無視するかについて、いくつかの決定が必要です。この決定をするには、プロジェクトディレクトリ内のいくつかのファイルを利用します。その該当ファイルには、.gitignore や .npmignore、そして package.json 内の files 配列が含まれます。また、それは常に特定のファイルを含め、他のものを無視します。
diff --git a/sections/security/avoid_publishing_secrets.md b/sections/security/avoid_publishing_secrets.md
index 934325bb5..ca68234af 100644
--- a/sections/security/avoid_publishing_secrets.md
+++ b/sections/security/avoid_publishing_secrets.md
@@ -10,15 +10,15 @@ It is important to note that if a project is utilising both `.npmignore` and `.g
### Code example
Example .npmignore file
```
-#tests
+# Tests
test
coverage
-#build tools
+# Build tools
.travis.yml
.jenkins.yml
-#environment
+# Environment
.env
.config
@@ -26,7 +26,7 @@ coverage
Example use of files array in package.json
-```
+```json
{
"files" : [
"dist/moment.js",
diff --git a/sections/security/avoid_publishing_secrets.polish.md b/sections/security/avoid_publishing_secrets.polish.md
new file mode 100644
index 000000000..4b29aa89b
--- /dev/null
+++ b/sections/security/avoid_publishing_secrets.polish.md
@@ -0,0 +1,44 @@
+# Unikaj publikowania danych wrażliwych w rejestrze npm
+
+### Wyjaśnienie jednym akapitem
+Należy podjąć środki ostrożności, aby uniknąć ryzyka przypadkowego opublikowania danych wrażliwych w publicznych rejestrach npm. Plik `.npmignore` może być użyty do umieszczenia na czarnej liście określonych plików lub folderów, lub tablica `files` w `package.json` może działać jako biała lista.
+
+Aby uzyskać widok tego, co publikacja npm naprawdę opublikuje w rejestrze, można dodać flagę `--dry-run` do polecenia npm opublikuj, aby zapewnić pełny widok utworzonego pakietu tarbell.
+
+Ważne jest, aby pamiętać, że jeśli projekt wykorzystuje zarówno pliki `.npmignore`, jak i `.gitignore`, wszystko, czego nie ma w pliku .npmignore, jest publikowane w rejestrze (tzn. plik `.npmignore` zastępuje `.gitignore`). Ten stan jest powszechnym źródłem zamieszania i stanowi problem, który może prowadzić do ujawnienia danych wrażliwych. Deweloperzy mogą w końcu zaktualizować plik `.gitignore`, ale zapomnieć zaktualizować również` .npmignore`, co może doprowadzić do tego, że potencjalnie wrażliwy plik nie zostanie przekazany do kontroli źródła, ale nadal będzie zawarty w pakiecie npm.
+
+### Przykład kodu
+Example .npmignore file
+```
+# Tests
+test
+coverage
+
+# Build tools
+.travis.yml
+.jenkins.yml
+
+# Environment
+.env
+.config
+
+```
+
+Przykład zastosowania tablicy plików w package.json
+
+```json
+{
+ "files" : [
+ "dist/moment.js",
+ "dist/moment.min.js"
+ ]
+}
+```
+
+### Co mówią inni blogerzy
+
+Z bloga od [Liran Tal & Juan Picado at Snyk](https://snyk.io/blog/ten-npm-security-best-practices/):
+> ... Another good practice to adopt is making use of the files property in package.json, which works as a whitelist and specifies the array of files to be included in the package that is to be created and installed (while the ignore file functions as a blacklist). The files property and an ignore file can both be used together to determine which files should explicitly be included, as well as excluded, from the package. When using both, the former the files property in package.json takes precedence over the ignore file.
+
+Z [bloga npm](https://blog.npmjs.org/post/165769683050/publishing-what-you-mean-to-publish)
+> ... When you run npm publish, npm bundles up all the files in the current directory. It makes a few decisions for you about what to include and what to ignore. To make these decisions, it uses the contents of several files in your project directory. These files include .gitignore, .npmignore, and the files array in the package.json. It also always includes certain files and ignores others.
diff --git a/sections/security/avoid_publishing_secrets.russian.md b/sections/security/avoid_publishing_secrets.russian.md
index cee60ef3f..7e8170313 100644
--- a/sections/security/avoid_publishing_secrets.russian.md
+++ b/sections/security/avoid_publishing_secrets.russian.md
@@ -10,15 +10,15 @@
### Пример кода
Example .npmignore file
```
-#tests
+# Tests
test
coverage
-#build tools
+# Build tools
.travis.yml
.jenkins.yml
-#environment
+# Environment
.env
.config
@@ -26,7 +26,7 @@ coverage
Пример использования массива файлов в package.json
-```
+```json
{
"files" : [
"dist/moment.js",
diff --git a/sections/security/avoideval.basque.md b/sections/security/avoideval.basque.md
new file mode 100644
index 000000000..9de3032ef
--- /dev/null
+++ b/sections/security/avoideval.basque.md
@@ -0,0 +1,23 @@
+# Saihestu JavaScript eval adierazpenak
+
+### Azalpena
+
+`eval()`, `setTimeout()`, `setInterval()`, eta `new Function()` funtzio globalak dira, Node.jsen maiz erabiltzen direnak, eta JavaScript expresio bat, adierazpen bat edo adierazpen segida bat jasotzen dituen kate parametroak onartzen dituztenak. Funtzio horiek erabiltzeak segurtasun arazoak sortzen ditu. Izan ere, fidagarria ez den erabiltzaileren bat sartzen bada zerbitzarian kodea exekutatu eta zerbitzaria arriskuan jarri ahal izango du, erabiltzaile kodearen ebaluazioa gainditzeak ahalmena ematen baitie erasotzaileei nahi dituzten ekintzak burutzeko. Gomendagarria da kodea garbitzea, funtzio horiek bukaerako funtzioari pasatu eta exekutatuak izatea ekiditeko.
+
+### Kode adibidea
+
+```javascript
+// erasotzailea sartzeko gai izan den kode maltzurraren adibidea
+const erabiltzaileSarrera =
+ "require('child_process').spawn('rm', ['-rf', '/'])";
+
+// exekutatutako kode maltzurra
+eval(erabiltzaileSarrera);
+```
+
+### Beste bloglari batzuk diotena
+
+[Liran Tal](https://leanpub.com/nodejssecurity)-en Essential Node.js Security liburua:
+
+> Berharbada, segurtasunaren ikuspuntutik, eval() funtzioa gaizkien ikusita dagoen JavaScripten ataletako bat da. JavaScript kateak testu moduan aztertzen ditu eta JavaScript kodea balitz bezala exekutatzen ditu.
+> Horrekin batera, fidagarria ez den erabiltzaileren bat sartzen bada kodearen egiaztapena gaindituz, hondamendirako bide arriskutsua da, zerbitzariaren funtzionamendua larriki kaltetu dezakeena.
diff --git a/sections/security/avoideval.french.md b/sections/security/avoideval.french.md
new file mode 100644
index 000000000..3a1775e74
--- /dev/null
+++ b/sections/security/avoideval.french.md
@@ -0,0 +1,20 @@
+# Éviter les déclarations d'évaluation de JS
+
+### Un paragraphe d'explication
+
+`eval()`, `setTimeout()`, `setInterval()`, et `new Function()` sont des fonctions globales, souvent utilisées dans Node.js, qui acceptent comme paramètre une châine de caractères représentant une expression Javascript, une déclaration ou une suite de déclarations. Le problème de sécurité que pose ces fonctionnalités est la possibilité que les entrées d'un utilisateur non fiable se retrouvent dans le code exécuté, ce qui pourrait compromettre le serveur, l'évaluation du code permettant essentiellement à un attaquant d'effectuer toutes les actions possibles. Il est suggéré de refactoriser le code pour ne pas se fier à ces fonctions où les entrées de l'utilisateur pourraient y être passées et exécutées.
+
+### Exemple de code
+
+```javascript
+// exemple d'un code malicieux qui permettait à un attaquant d'entrer
+const userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
+
+// code malicieux exécuté
+eval(userInput);
+```
+
+### Ce que disent les autres blogueurs
+
+Extrait du livre « Essential Node.js Security » de [Liran Tal](https://leanpub.com/nodejssecurity):
+> La fonction eval() est peut-être l'une des plus mal vues dans JavaScript du point de vue de la sécurité. Elle analyse une chaîne de caractère JavaScript comme du texte, et l'exécute comme si c'était du code JavaScript. En mélangeant cela avec des entrées d'utilisateurs non fiables qui pourraient trouver un moyen d'accéder à la fonction eval(), on obtient la recette d'un désastre qui peut finir par compromettre le serveur.
diff --git a/sections/security/avoideval.japanese.md b/sections/security/avoideval.japanese.md
new file mode 100644
index 000000000..a91c80f81
--- /dev/null
+++ b/sections/security/avoideval.japanese.md
@@ -0,0 +1,22 @@
+# JavaScript の eval 構文を避ける
+
+### 一段落説明
+
+`eval()`、`setTimeout()`、`setInterval()`、そして `new Function()` は Node.js でしばしば利用される、JavaScript の式、文そして連続した文を表す文字列パラメータを受け取るグローバル関数です。これらの関数を利用することをセキュリティ的な懸念は、ユーザーのコードを評価することは本質的には攻撃者にあらゆるアクションを実行することを許すことなので、信頼されていないユーザーの入力がコード実行の中に入り込み、サーバーを危険にさらす可能性があるということです。ユーザーの入力が渡されて実行されるような関数の利用に依存しないようにコードをリファクタすることが推奨されています。
+
+### コード例
+
+```javascript
+// 攻撃者が入力できる悪意のあるコードの例
+const userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
+
+// 悪意のあるコードが実行される
+eval(userInput);
+```
+
+### 他のブロガーが言っていること
+
+[Liran Tal](https://leanpub.com/nodejssecurity) による書籍 Essential Node.js Security より:
+> セキュリティの観点から見ると、eval() 関数はおそらく JavaScript の中でもっとも忌み嫌われている部分でしょう。
+> それは JavaScript の文字列をテキストにパースし、まるで JavaScript コードのように実行します。
+> これを、eval() へ渡されることが分かっているかもしれない信頼されていないユーザー入力と混ぜることは、サーバーを危険にさらすことになる、崩壊へのレシピといえるでしょう。
diff --git a/sections/security/avoideval.polish.md b/sections/security/avoideval.polish.md
new file mode 100644
index 000000000..7dceabfd3
--- /dev/null
+++ b/sections/security/avoideval.polish.md
@@ -0,0 +1,23 @@
+# Unikaj JS eval statements
+
+### Wyjaśnienie jednym akapitem
+
+`eval()`, `setTimeout()`, `setInterval()`, i `new Function()` są funkcjami globalnymi, często używanymi w Node.js, które akceptują parametr ciągu znaków reprezentujący wyrażenie JavaScript, instrukcję lub sekwencję instrukcji. Problemem związanym z bezpieczeństwem korzystania z tych funkcji jest możliwość, że niezaufane dane wejściowe użytkownika mogą znaleźć drogę do wykonania kodu prowadzącego do naruszenia bezpieczeństwa serwera, ponieważ ocena kodu użytkownika zasadniczo pozwala atakującemu na wykonanie dowolnych działań. Sugeruje się, aby kod refaktoryzować, aby nie polegał na użyciu tych funkcji, w których dane wejściowe użytkownika mogą być przekazywane do funkcji i wykonywane.
+
+### Przykład kodu
+
+```javascript
+// example of malicious code which an attacker was able to input
+const userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
+
+// malicious code executed
+eval(userInput);
+```
+
+### Co mówią inni blogerzy
+
+Z książki Essential Node.js Security od [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.
diff --git a/sections/security/avoideval.russian.md b/sections/security/avoideval.russian.md
index c23ff1a45..8721fa6d2 100644
--- a/sections/security/avoideval.russian.md
+++ b/sections/security/avoideval.russian.md
@@ -8,7 +8,7 @@
```javascript
// example of malicious code which an attacker was able to input
-userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
+const userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
// malicious code executed
eval(userInput);
diff --git a/sections/security/bcryptpasswords.japanese.md b/sections/security/bcryptpasswords.japanese.md
new file mode 100644
index 000000000..151a16973
--- /dev/null
+++ b/sections/security/bcryptpasswords.japanese.md
@@ -0,0 +1,32 @@
+# パスワードの処理に Node.js の crypto ライブラリではなく Bcrypt を利用する
+
+### 一段落説明
+
+ユーザーのパスワードを保存する際には、ネイティブの Node.js crypto モジュールを使用するのではなく、[bcrypt npm モジュール](https://www.npmjs.com/package/bcrypt)が提供するbcrypt のような、適応性のあるハッシュアルゴリズムを使用することをおすすめします。`Math.random()` は予測可能性があるため、パスワードやトークン生成の一部としては決して使用しないでください。
+
+JavaScript の実装ではなく、`bcrypt` モジュールなどを使用しなければなりません。`bcrypt` を使う場合、安全なハッシュを提供するために 'ラウンド数' を指定することができます。これはワークファクターもしくはデータが処理される回数を指定し、ハッシュのラウンド数が増えるほど、より安全なハッシュが算出されます(ただし、CPU 計算時間のコストがかかります)。ハッシュラウンドの導入は、1回試行するために必要な時間を増加させることでパスワードクラッカーが減速されるため、ブルートフォース要因が大幅に削減されることを意味します。
+
+### コード例
+
+```javascript
+try {
+// 10回のハッシュラウンドを設定して、非同期にセキュアなパスワードを生成する
+ const hash = await bcrypt.hash('myPassword', 10);
+ // セキュアなハッシュをユーザレコードに保存する
+
+ // 与えられたパスワード入力を保存されたハッシュと比較する
+ const match = await bcrypt.compare('somePassword', hash);
+ if (match) {
+ // パスワードが合致した場合
+ } else {
+ // パスワードが合致しなかった場合
+ }
+} catch {
+ logger.error('could not hash password.')
+}
+```
+
+### 他のブロガーが言っていること
+
+[Max McCarty](https://dzone.com/articles/nodejs-and-password-storage-with-bcrypt) のブログより:
+> ... 正しいハッシュアルゴリズムを使うだけではありません。正しいツールがパスワードハッシュアルゴリズムの一部として 「時間」という必要不可欠な要素を含んでいることと、それがブルートフォースでパスワードを解読しようとしている攻撃者にとって何を意味するのかについて、広範囲にわたって話してきました。
diff --git a/sections/security/bcryptpasswords.md b/sections/security/bcryptpasswords.md
deleted file mode 100644
index 03a73a3ce..000000000
--- a/sections/security/bcryptpasswords.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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 its 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
-try {
-// asynchronously generate a secure password using 10 hashing rounds
- const hash = await bcrypt.hash('myPassword', 10);
- // Store secure hash in user record
-
- // compare a provided password input with saved hash
- const match = await bcrypt.compare('somePassword', hash);
- if (match) {
- // Passwords match
- } else {
- // Passwords don't match
- }
-} catch {
- logger.error('could not hash password.')
-}
-```
-
-### 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/bcryptpasswords.polish.md b/sections/security/bcryptpasswords.polish.md
new file mode 100644
index 000000000..fe694442f
--- /dev/null
+++ b/sections/security/bcryptpasswords.polish.md
@@ -0,0 +1,32 @@
+# Unikaj używania biblioteki Crypto Node.js dla haseł, używaj Bcrypt
+
+### Wyjaśnienie jednym akapitem
+
+Podczas przechowywania haseł użytkowników zalecane jest użycie adaptacyjnego algorytmu haszującego, takiego jak bcrypt, oferowanego przez [bcrypt npm module](https://www.npmjs.com/package/bcrypt), w przeciwieństwie do korzystania z natywnego modułu kryptograficznego Node.js . `Math.random ()` również nie powinien być nigdy używany jako część generowania haseł lub tokenów ze względu na jego przewidywalność.
+
+Moduł `bcrypt` lub podobny powinien być używany w przeciwieństwie do implementacji JavaScript, ponieważ podczas korzystania z `bcrypt` można określić kilka „rund” w celu zapewnienia bezpiecznego skrótu. Określa współczynnik pracy lub liczbę „rund”, dla których przetwarzane są dane, a więcej rund mieszających prowadzi do bezpieczniejszego skrótu (chociaż odbywa się to kosztem czasu procesora). Wprowadzenie rund mieszających oznacza, że czynnik brute force jest znacznie zmniejszony, ponieważ łamacze haseł są spowalniane, co zwiększa czas wymagany do wygenerowania jednej próby.
+
+### Przykład kodu
+
+```javascript
+try {
+// asynchronously generate a secure password using 10 hashing rounds
+ const hash = await bcrypt.hash('myPassword', 10);
+ // Store secure hash in user record
+
+ // compare a provided password input with saved hash
+ const match = await bcrypt.compare('somePassword', hash);
+ if (match) {
+ // Passwords match
+ } else {
+ // Passwords don't match
+ }
+} catch {
+ logger.error('could not hash password.')
+}
+```
+
+### Co inni blogerzy mówią
+
+Z bloga od [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/bcryptpasswords.russian.md b/sections/security/bcryptpasswords.russian.md
index 25a3cccbc..90fd453b7 100644
--- a/sections/security/bcryptpasswords.russian.md
+++ b/sections/security/bcryptpasswords.russian.md
@@ -9,19 +9,21 @@
### Пример кода
```javascript
+try {
// asynchronously generate a secure password using 10 hashing rounds
-bcrypt.hash('myPassword', 10, function(err, hash) {
+ const hash = await bcrypt.hash('myPassword', 10);
// Store secure hash in user record
-});
-// compare a provided password input with saved hash
-bcrypt.compare('somePassword', hash, function(err, match) {
- if(match) {
+ // compare a provided password input with saved hash
+ const match = await bcrypt.compare('somePassword', hash);
+ if (match) {
// Passwords match
} else {
// Passwords don't match
}
-});
+} catch {
+ logger.error('could not hash password.')
+}
```
### Что говорят другие блогеры
diff --git a/sections/security/childprocesses.basque.md b/sections/security/childprocesses.basque.md
new file mode 100644
index 000000000..244fd40fa
--- /dev/null
+++ b/sections/security/childprocesses.basque.md
@@ -0,0 +1,29 @@
+# Kontuz ibili bigarren mailako prozesuekin lan egitean
+
+### Azalpena
+
+Bigarren mailako prozesuak oso erabilgarriak izan badaitezke ere, kontuz erabili behar da haiekin. Izan ere, erabiltzaileen sarrera desinfektatu egin behar da, edo, bestela, guztiz baztertu beharra dago. Mugagabeak dira sistemako logika egikaritzen duten desinfektatu gabeko sarreren arriskuak: norbaitek kodea urrunetik egikaritzea suertatu daiteke, sistemaren datu sentikorrak agerian jartzea gerta daiteke, eta datuak galtzerainoko arazoak gerta daitezke ere. Itxura hau izan dezake prestaketen egiaztapen zerrendak:
+
+- eragotzi erabiltzailearen sarrera kasu guztietan, bestela balioztatu eta saneatu
+- guraso eta seme-alaben prozesuen pribilegioak mugatu erabiltzaile/talde identitateak erabiliz
+- exekutatu zure prozesua ingurune isolatu baten barruan, nahi ez dituzun bigarren mailako ondorioak ekiditeko beste prestaketek huts egiten badute ere
+
+### Kode adibidea: desinfektatu gabeko bigarren mailako prozesuen exekuzioen arriskuak
+
+```javascript
+const { exec } = require('child_process');
+
+...
+
+// adibide gisa, bi argudio hartzen dituen scripta hartu, bietako bat garbitu gabeko erabiltzaile sarrera delarik
+exec('"/path/to/test file/someScript.sh" --someOption ' + input);
+
+// -> imaginatu zer gertatuko litzatekeen erabiltzaileak '&& rm -rf --no-preserve-root /' bezalako zerbait idatziz gero
+// espero gabeko sorpresa hartuko zenuke
+```
+
+### Baliabide osagarriak
+
+Node.js bigarren mailako prozesuaren [dokumentazioa](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback):
+
+> Ez inoiz pasatu erabiltzaile sarrerarik funtzio honetara higienizatu gabe. Shell metakarakereak duen edozein sarrera erabil daiteke komando arbitrarioen exekuzioa abiarazteko.
diff --git a/sections/security/childprocesses.french.md b/sections/security/childprocesses.french.md
new file mode 100644
index 000000000..7a34fdab0
--- /dev/null
+++ b/sections/security/childprocesses.french.md
@@ -0,0 +1,31 @@
+# Soyez prudent lorsque vous travaillez avec des processus enfants
+
+### Un paragraphe d'explication
+
+Aussi importants que soient les processus enfants, ils doivent être utilisés avec prudence. Les entrées des utilisateurs qui y sont passées doivent être assainies (NdT *sanitize*), voire évitées.
+Les dangers d'une entrée non assainie exécutant une logique au niveau du système sont illimités, allant de l'exécution de code à distance à l'exposition de données système sensibles et aussi de perte de données.
+Une liste de contrôle des préparatifs pourrait ressembler à ceci :
+
+- éviter les entrées des utilisateurs dans tous les cas, autrement les valider et les assainir
+- limiter les privilèges du parent et des processus enfants en utilisant les identités de groupe et d'utilisateur
+- exécuter votre processus dans un environnement isolé pour prévenir des effets secondaires indésirables si les autres préparations échouent
+
+### Exemple de code : Les dangers de l'exécution de processus enfants non assainis
+
+```javascript
+const { exec } = require('child_process');
+
+...
+
+// comme exemple, prenons un script qui prend deux arguments, l'un d'entre eux est une entrée utilisateur non assainie
+exec('"/path/to/test file/someScript.sh" --someOption ' + input);
+
+// -> imaginez ce qu'il se passerait si un utilisateur entrait simplement quelque chose comme '&& rm -rf --no-preserve-root /'
+// vous auriez une surprise indésirable
+```
+
+### Ressources supplémentaires
+
+Extrait de la [documentation](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback) Node.js sur les processus enfants :
+
+> Ne jamais passer une entrée utilisateur non assainie à cette fonction. Toute entrée comportant des métacaractères du shell peut être utilisée pour déclencher une commande arbitrairement
\ No newline at end of file
diff --git a/sections/security/childprocesses.japanese.md b/sections/security/childprocesses.japanese.md
new file mode 100644
index 000000000..c70df1d10
--- /dev/null
+++ b/sections/security/childprocesses.japanese.md
@@ -0,0 +1,29 @@
+# 子プロセスで処理を行う場合は注意する
+
+### 一段落説明
+
+子プロセスは素晴らしいものですが、注意して使用する必要があります。ユーザー入力の受け渡しは、利用しないのでなければ、サニタイズされていなければなりません。サニタイズされていない入力がシステムレベルのロジックを実行する危険性は無限にあり、リモートコードの実行からセンシティブなシステムデータの漏洩、そしてデータ損失にまで及びます。準備のためのチェックリストは以下のようになります。
+
+- すべての場合でユーザー入力を避け、そうでない場合は検証とサニタイズを行う
+- ユーザー/グループアイデンティを利用して、親プロセスと子プロセスの権限を制限する
+- 上記が機能しなかった場合の望まない副作用を防ぐために、プロセスを隔離された環境で実行する
+
+### コード例: サニタイズされていない子プロセス実行の危険性
+
+```javascript
+const { exec } = require('child_process');
+
+...
+
+// 例として、2つのうち1つがサニタイズされていないユーザー入力であるスクリプトを考えてみましょう
+exec('"/path/to/test file/someScript.sh" --someOption ' + input);
+
+// -> ユーザー入力が '&& rm -rf --no-preserve-root /' だった場合に、何が起こるか想像してみてください
+// 望まない結果に驚くことでしょう
+```
+
+### その他のリソース
+
+Node.js child process の[ドキュメント](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback) より:
+
+> サニタイズされていないユーザー入力をこの関数に決して渡さないでください。シェルのメタ文字を含んでいるどんな入力も、任意のコマンド実行を引き起こすために利用される可能性があります。
diff --git a/sections/security/childprocesses.polish.md b/sections/security/childprocesses.polish.md
new file mode 100644
index 000000000..fc95c370a
--- /dev/null
+++ b/sections/security/childprocesses.polish.md
@@ -0,0 +1,31 @@
+# Zachowaj ostrożność podczas pracy z procesami potomnymi
+
+### Wyjaśnienie jednym akapitem
+
+Niezależnie od tego, jak wielkie są procesy potomne, należy ich używać ostrożnie. Przekazywanie danych wejściowych przez użytkownika musi być sanitized, jeśli w ogóle nie można go uniknąć.
+Niebezpieczeństwa związane z niezaangażowanym wejściem wykonującym logikę na poziomie systemu są nieograniczone, od zdalnego wykonania kodu po ujawnienie
+wrażliwych danych systemowych, a nawet utraty danych. Lista kontrolna przygotowań może wyglądać następująco
+
+- w każdym przypadku unikaj wprowadzania danych przez użytkownika, w przeciwnym razie waliduj i sanitize
+- ograniczenie uprawnień procesów nadrzędnych i podrzędnych przy użyciu tożsamości użytkowników / grup
+- uruchom proces w izolowanym środowisku, aby zapobiec niepożądanym skutkom ubocznym, jeśli inne przygotowania zawiodą
+
+### Przykład kodu: 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
+```
+
+### Dodatkowe zasoby
+
+Z 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.basque.md b/sections/security/commonsecuritybestpractices.basque.md
new file mode 100644
index 000000000..d5aa6ab7f
--- /dev/null
+++ b/sections/security/commonsecuritybestpractices.basque.md
@@ -0,0 +1,128 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# Node.jsren ohiko segurtasun praktika onak
+
+Ohiko segurtasun praktiken atalak esparru eta konbentzio askotan estandarizatuta dauden praktika onak biltzen ditu. Adibidez, aplikazio bat exekutatzea SSL / TLS-rekin konfigurazio guztietan erabili beharko litzatekeen praktika eta konbentzio arrunta da, horrela segurtasun abantaila handiak lortuko lirateke eta.
+
+## ![✔] Erabili SSL / TLS bezeroen zerbitzariaren konexioa enkriptatzeko
+
+**TL; DR:** [doako SSL / TLS ziurtagirien](https://letsencrypt.org/) eta haien konfigurazio errazaren garaian, ez duzu zertan pisatu zerbitzari segurua erabiltzearen abantailak eta desabantailak, argi eta garbi gailentzen baitira segurtasuna, teknologia modernoaren laguntza eta konfiantza bezalako abantailak -gutxieneko gainkarga minimoa bezalako desabantailak edukita ere- HTTP hutsaren aldean.
+
+**Bestela:** erasotzaileek erdi-erdiko erasoak egin ditzakete, zure erabiltzaileen portaera zelatatu eta are ekintza maltzurragoak egin ditzakete konexioa enkriptatu gabe dagoenean.
+
+🔗 [**Informazio gehiago: Node.js zerbitzari segurua egikaritzea**](./secureserver.basque.md)
+
+
+
+## ![✔] Balio sekretuak eta aztarnak modu seguruan alderatzea
+
+**TL; DR:** balio sekretuak edo aztarnak alderatzean HMAC laburpenak balira bezala, [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) funtzioa erabili beharko zenuke, Node.js v6.6.0 geroztik Nodek eskaintzen duena. Metodo horrek emandako bi objektu alderatzen ditu eta datuok alderatzen jarraitzen du bat ez badatoz ere. Datuak berdinak diren alderatzeko metodo lehenetsiak berez bueltatuko lirateke berriro, karakterrak bat etorriko ez balira, eta horrela eragiketaren iraupen luzeak erasoak ahalbidetuko lituzke
+
+**Bestela:** datuak berdinak diren alderatzeko metodo lehenetsiak erabiltzen badituzu, informazio kritikoa agerian jar dezakezu, zenbatekoa den bi objektu alderatzeko behar den denbora.
+
+
+
+## ![✔] Ausazko kateak sortzea Node.js erabiliz
+
+**TL; DR:** tokenetarako (giltzak) eta segurtasunaren menpekoak diren beste kasu batzuetarako sasi ausazko kateak sortzen dituen funtzio pertsonalizatua erabiltzea ez da, agian, uste bezain ausazkoa izango, eta, ondorioz, zure aplikazioa eraso kriptografikoen aurrean zaurgarria izan daditeke. Ausazko kate seguruak sortu behar dituzunean, erabili [`crypto.randomBytes(size, [callback])`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) funtzioa sistemak eskaintzen duen entropia baliatuz.
+
+**Bestela:** sasi ausazko kateak sortzen direnean kriptografikoki seguruak diren metodorik gabe, erasotzaileek sortutako emaitzak aurreikusi eta erreproduzi ditzakete, zure aplikazioa segurtasunik gabe geldituz.
+
+
+
+Jarraian, OWASP proiektuko hainbat gomendio garrantzitsu zerrendatu ditugu
+
+## ![✔] OWASP A2: hautsitako autentifikazioa
+
+- Eskatu MFA / 2FA zerbitzu eta kontu garrantzitsuetarako
+- Biratu pasahitzak eta atzitzeko gakoak maiz, SSH giltzak barne
+- Aplikatu pasahitz politika sendoak, bai operazioetarako, bai aplikazioko erabiltzaileen kudeaketarako ([🔗 OWASP pasahitz gomendioa](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
+- Ez bidali edo zabaldu zure aplikazioa lehenespenezko kredentzialekin, batez ere administratzaile erabiltzaileentzat edo menpeko dituzun kanpoko zerbitzuentzat
+- Erabili OAuth, OpenID eta horiek bezalako autentifikazio metodo estandarrak, eta **saihestu** oinarrizko autentifikazioa
+- Mugatu autentifikazio saiakera kopurua: debekatu _X_ saio saiakera baino gehiago (pasahitza berreskuratzea barne, etab.) _Y_ aldian
+- Saioa hastean huts eginez gero, ez utzi erabiltzaileari jakiten erabiltzaile izenaren egiaztatzeak edo pasahitzaren egiaztatzeak huts egin zuen; autentifikazio errore arrunta itzuli besterik ez egin
+- Aztertu ez ote den komeni erabiltzea erabiltzaileen kudeaketarako sistema zentralizaturen bat langile bakoitzeko hainbat kontu kudeatu beharra ekiditeko (adibidez, GitHub, AWS, Jenkins, etab.) eta erabiltzaileen kudeaketarako sistema ezagun eta zailduren baten onurez baliatzeko.
+
+## ![✔] OWASP A5: sarbide kontrol hautsia
+
+- Errespetatu [pribilegio txikienaren printzipioa](https://en.wikipedia.org/wiki/Principle_of_least_privilege): DevOpseko osagai eta pertsona bakoitzak soilik izan behar du aukera beharrezko informazioa eta baliabideak eskuratzeko
+- **Inoiz** ez lan egin kontsola / root (pribilegio osoa) kontuarekin kontu kudeaketan izan ezik
+- Exekutatu instantzia / edukiontzi guztiak rol / zerbitzu kontu baten izenean
+- Esleitu baimenak taldeei eta ez erabiltzaileei. Horrek baimenen kudeaketa errazagoa eta gardenagoa izatea ahalbidetu beharko luke kasu gehienetan
+
+## ![✔] OWASP A6: segurtasun okerreko konfigurazioa
+
+- Barne sarea da bide bakarra ekoizpen inguruneko barne osagaietara iristeko; erabili SSH edo beste modu batzuk erabili, baina _inoiz_ agerian jarri gabe barne zerbitzuak
+- Mugatu barne sareko sarbidea: berariaz zehaztu zein baliabide sar daitekeen beste baliabide batzuetara (adibidez, sare politika edo azpisareak)
+- Cookieak erabiltzen badituzu, konfiguratu modu "seguruan", bidalketak SSL bidez bakarrik egiteko
+- Cookieak erabiltzen badituzu, konfiguratu "gune bererako" soilik; beraz domeinu bereko eskaerek soilik izendatutako cookieak itzuliko dituzte
+- Cookieak erabiltzen badituzu, aukeratu "HttpOnly" konfigurazioa, bezeroaren JavaScript kodea sartzea galarazten duena
+- Babestu VPC bakoitza sarbide arau zorrotz eta murriztaileekin
+- Lehenetsi mehatxuak STRIDE edo DREAD bezalako segurtasun mehatxu eredu estandarrak erabiliz
+- Babestu DDoS erasoen aurka HTTP (S) eta TCP karga orekatzaileak erabiliz
+- Erakunde espezializatuek aldizka sartzeko probak egin
+
+## ![✔] OWASP A3: bereziki babestutako datuen esposizioa
+
+- Onartu SSL / TLS konexioak soilik, eta ezarri Strict-Transport-Security goiburuak erabiliz
+- Bereizi sarea segmentutan (hau da, azpisareak) eta ziurtatu nodo bakoitzak sarbide baimenak dituela beharrezko gutxieneko sarerako
+- Multzokatu Interneteko sarbiderik behar ez duten zerbitzu / instantzia guztiak eta berariaz baztertu irteerako edozein konexio (azpisare pribatua, adibidez)
+- Gorde sekretu guztiak AWS KMS, HashiCorp Vault edo Google Cloud KMS bezalako segurtasun karpetak dituzten produktuetan
+- Blokeatu izaera sentikorreko metadatuak metadatuak erabiliz
+- Enkriptatu pasoko datuak ingurune fisiko batetik irteten direnean
+- Ez sartu sekretuak egunkarietako adierazpenetan
+- Saihestu frontendean pasahitz arruntak erakustea; hartu beharrezko neurriak backendean; eta ez gorde inoiz informazio sentikorrik testu soilean
+
+
+## ![✔] OWASP A9: segurtasun ahulezia ezagunak dituzten osagaien erabilera
+
+- Eskaneatu dockeren irudiak ahulezia ezagunak aurkitzeko (Dockeren eta beste hornitzaile batzuen eskaneatze zerbitzuak erabiliz)
+- Gaitu instantzia automatikoen (makina) adabakiak eta bertsio berritzea segurtasun adabakirik ez duten sistema eragileen bertsio zaharrak exekutatzea ekiditeko
+- Eman erabiltzaileari 'id', 'sarbidea' eta 'eguneratu'ren giltzak(tokenak), sarbide giltzak (tokenak) iraupen laburra izan dezan eta giltzarekin (tokenarekin) egunera dadin
+- Erregistratu eta ikuskatu APIaren dei guztiak hodei eta kudeaketa zerbitzuetara (adibidez, nork ezabatu zuen S3 ontzia?) AWS CloudTrail bezalako zerbitzuak erabiliz
+- Exekutatu zure hodei hornitzailearen segurtasun egiaztatzailea (adibidez, AWS segurtasun fidagarritasun aholkularia)
+
+
+## ![✔] OWASP A10: erregistro eta kontrol eznahikoak
+
+- Ohartarazi ikuskaritzako gertaera aipagarri edo susmagarriez: erabiltzaileen saioa hastea, erabiltzaile berriak sortzea, baimenen aldaketa, etab
+- Ohartarazi saioa hastean hutsegiteen kopuru irregularra dela (edo ahaztutako pasahitza bezalako ekintzak)
+- Sartu eguneratzeari hasiera eman dion denbora eta erabiltzaile izena DB erregistro bakoitzean
+
+## ![✔] OWASP A7: Cross-Site-Scripting (XSS)
+
+- Erabili diseinuaren bidez XSS-i automatikoki ihes egiten dioten txantiloien motorrak edo esparruak, hala nola EJS, Pug, React edo Angular. Ezagutu XSS babes mekanismo bakoitzaren mugak eta kudeatu estaltzen ez diren erabilera kasuak
+- HTML irteerako testuinguruaren arabera fidagarriak ez diren HTTP eskaera datuak sahiestean (gorputza, atributua, JavaScript, CSS edo URLa) konpondu egingo dira islatu eta gordetako XSS ahuleziak
+- Testuinguruaren araberako kodeketa aplikatzeak DOM XSSren aurka egiten du arakatzailearen dokumentua aldatzean bezeroaren aldetik
+- Gaitu Edukien Segurtasun Politika (CSP) XSSren aurkako kontrola arintzeko defentsa sakon gisa
+
+## ![✔] Babestu pertsonalki identifikatu daitekeen informazioa (PII datuak)
+
+- Pertsonalki identifikatzeko informazioa (PII) pertsona zehatz bat identifikatzeko erabil daitekeen edozein datu da
+- Babestu aplikazioetan identifikatu daitekeen informazioa, enkriptatuz
+- Jarraitu tokian tokiko datuen pribatutasun legeak. Erreferentzia legeak:
+ - Europar Batasuna: GDPR - https://ec.europa.eu/info/law/law-topic/data-protection_en
+ - India: https://meity.gov.in/writereaddata/files/Personal_Data_Protection_Bill,2018.pdf
+ - Singapur: https://www.pdpc.gov.sg/Overview-of-PDPA/The-Legislation/Personal-Data-Protection-Act
+
+## ![✔] Izan security.txt fitxategia [PRODUKZIOA]
+
+**TL; DR:** izan ```security.txt``` izeneko testu fitxategia direktorio ```/.well-known``` azpian (/.well-known/security.txt) edo zure webgunearen edo ekoizpenean dagoen zure web aplikazioaren erro direktorioan (/security.txt). Segurtasun ikertzaileek atzemandako ahultasunen xehetasunak izan behar ditu ```security.txt``` fitxategiak, eta txostenak bidali behar zaizkion pertsona edo talde arduradunaren harremanetarako datuak ere jaso beharko ditu (posta elektronikoko IDa edo / eta telefono zenbakiak) .
+
+**Bestela:** baliteke ahulezien berri ez izatea. Galduko duzu ahuleziei garaiz eragiteko aukera.
+
+🔗 [**security.txt**](https://securitytxt.org/)
+
+
+## ![✔] Izan SECURITY.md fitxategia [ITURRI IREKIA]
+
+**TL; DR:** zure proiektuaren segurtasun ahulezien berri modu arduratsuan eman nahi badiozu jendeari jarraibideak zehazte aldera, SECURITY.md fitxategia gehi dezakezu zure biltegiko erroan, dokumentuetan edo .github karpetan. SECURITY.md fitxategiak informazio egokia eduki behar du segurtasun ikertzaileek proiektuaren ahuleziak atzeman eta txostenak bidali behar zaizkion pertsona / talde arduradunaren harremanetarako datuak (posta elektronikoko IDa edo / eta telefono zenbakiak) jaso ahal ditzaten
+
+**Bestela:** baliteke ahulezien berri ez izatea. Ahulezien gainean garaiz jarduteko aukera galduko duzu.
+
+🔗 [**Informazio gehiago: SECURITY.md**](https://help.github.com/en/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository)
+
+
+
+
+
diff --git a/sections/security/commonsecuritybestpractices.brazilian-portuguese.md b/sections/security/commonsecuritybestpractices.brazilian-portuguese.md
index 3bd0c6927..79d129c58 100644
--- a/sections/security/commonsecuritybestpractices.brazilian-portuguese.md
+++ b/sections/security/commonsecuritybestpractices.brazilian-portuguese.md
@@ -10,7 +10,7 @@ A seção de boas práticas comuns de segurança contém as práticas recomendad
**Caso contrário:** invasores podem executar ataques man-in-the-middle, espionar o comportamento de seus usuários e executar ações ainda mais maliciosas quando a conexão não é criptografada.
-🔗 [**Leia Mais: Executando um servidor Node.js seguro**](/sections/security/secureserver.brazilian-portuguese.md)
+🔗 [**Leia Mais: Executando um servidor Node.js seguro**](./secureserver.brazilian-portuguese.md)
@@ -24,7 +24,7 @@ A seção de boas práticas comuns de segurança contém as práticas recomendad
## ![✔] Gerando strings aleatórias usando Node.js
-**TL;DR:** Usar uma função personalizada que gera sequências pseudo-aleatórias para tokens e outros casos de uso sensíveis à segurança pode não ser tão aleatório quanto você pensa, tornando seu aplicativo vulnerável a ataques criptográficos. Quando você precisar gerar strings aleatórias seguras, use a função [`crypto.RandomBytes(size, [callback])`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_randombytes_size_callback) usando a entropia disponível fornecida pelo sistema.
+**TL;DR:** Usar uma função personalizada que gera sequências pseudo-aleatórias para tokens e outros casos de uso sensíveis à segurança pode não ser tão aleatório quanto você pensa, tornando seu aplicativo vulnerável a ataques criptográficos. Quando você precisar gerar strings aleatórias seguras, use a função [`crypto.randomBytes(size, [callback])`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) usando a entropia disponível fornecida pelo sistema.
**Caso contrário:** Ao gerar strings pseudo-aleatórias sem métodos criptograficamente seguros, os invasores podem prever e reproduzir os resultados gerados, tornando seu aplicativo inseguro.
diff --git a/sections/security/commonsecuritybestpractices.french.md b/sections/security/commonsecuritybestpractices.french.md
new file mode 100644
index 000000000..c9bcac371
--- /dev/null
+++ b/sections/security/commonsecuritybestpractices.french.md
@@ -0,0 +1,127 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# Meilleures pratiques de sécurité communes avec Node.js
+
+La section des directives de sécurité communes contient les meilleures pratiques qui sont normalisées dans de nombreux frameworks et conventions. L'utilisation d'une application avec SSL/TLS, par exemple, devrait être une directive et une convention commune suivie dans chaque configuration pour obtenir des grands avantages en matière de sécurité.
+
+## ![✔] Utilisez SSL/TLS pour crypter la connexion client-serveur
+
+**TL;PL :** À l'heure des [certificats SSL/TLS gratuits](https://letsencrypt.org/) et de la facilité de leur configuration, vous n'avez plus à peser les avantages et les inconvénients de l'utilisation d'un serveur sécurisé car les avantages tels que la sécurité, le support de la technologie moderne et de la confiance l'emportent clairement sur les inconvénients tels que la surcharge minimale par rapport au HTTP pur.
+
+**Autrement :** Les attaquants peuvent effectuer des attaques de type "attaque de l'homme du milieu", espionner le comportement de vos utilisateurs et effectuer des actions encore plus malveillantes lorsque la connexion n'est pas cryptée.
+
+🔗 [**Plus d'infos : exécution d'un serveur Node.js sécurisé**](./secureserver.french.md)
+
+
+
+## ![✔] Comparez les valeurs secrètes et les hachages en toute sécurité
+
+**TL;PL :** Lorsque vous comparez des valeurs secrètes ou des hachages comme les digests HMAC, vous devez utiliser la fonction [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) que Node fournit dès la version 6.6.0 de Node.js. Cette méthode compare deux objets donnés et continue de comparer même si les données ne correspondent pas. Les méthodes de comparaison d'égalité par défaut s'arrêteraient simplement après une discordance de caractères, permettant de chronométrer les attaques basées sur la longueur de l'opération.
+
+**Autrement :** En utilisant les opérateurs de comparaison d'égalité par défaut, vous pourriez exposer des informations critiques basées sur le temps nécessaire pour comparer deux objets.
+
+
+
+## ![✔] Génération de chaînes aléatoires à l'aide de Node.js
+
+**TL;PL :** L'utilisation d'une fonction personnalisée générant des chaînes pseudo-aléatoires pour les jetons et autres cas d'utilisation sensibles à la sécurité pourrait en fait ne pas être aussi aléatoire que vous le pensez, rendant votre application vulnérable aux attaques cryptographiques. Lorsque vous devez générer des chaînes aléatoires sécurisées, utilisez la fonction [`crypto.randomBytes(size, [callback])`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) en utilisant l'entropie disponible fournie par le système.
+
+**Autrement :** Lors de la génération de chaînes pseudo-aléatoires sans recourir à des méthodes cryptographiques sûres, les pirates peuvent prévoir et reproduire les résultats générés, ce qui rend votre application peu sûre.
+
+
+
+Nous avons énuméré ci-dessous quelques conseils importants tirés du projet OWASP.
+
+## ![✔] OWASP A2 : Authentification frauduleuse
+
+- Exigez MFA/2FA pour les services et comptes importants
+- Changez fréquemment les mots de passe et les clés d'accès, y compris les clés SSH
+- Appliquez des politiques strictes en matière de mots de passe, tant pour l'exploitation que pour la gestion des utilisateurs dans l'application ([🔗 OWASP recommandation sur le mot de passe](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
+- N'envoyez ou ne déployez pas votre application avec des identifiants par défaut, en particulier pour les utilisateurs de l'administration ou les services externes dont vous dépendez
+- Utilisez uniquement des méthodes d'authentification standard comme OAuth, OpenID, etc, **évitez** l'authentification de base
+- Limitez le taux d'authentification : interdisez plus de _X_ tentatives de connexion (y compris la récupération du mot de passe, etc.) pendant une période _Y_.
+- En cas d'échec de la connexion, n'indiquez pas à l'utilisateur si la vérification du nom d'utilisateur ou du mot de passe a échoué, mais renvoyez simplement une erreur d'authentification ordinaire.
+- Envisagez d'utiliser un système de gestion des utilisateurs centralisé pour éviter de gérer plusieurs comptes par employé (par exemple GitHub, AWS, Jenkins, etc.) et pour bénéficier d'un système de gestion des utilisateurs éprouvé
+
+## ![✔] OWASP A5 : Contrôle d'accès défectueux
+
+- Respectez le [principe de moindre privilège](https://fr.wikipedia.org/wiki/Principe_de_moindre_privil%C3%A8ge) - chaque composant et chaque personne du DevOps ne doit avoir accès qu'aux informations et ressources nécessaires
+- **Ne travaillez jamais** avec le compte console/root (privilège total) sauf pour la gestion de compte
+- Exécutez toutes les instances/conteneurs sous le nom d'un compte de rôle/service
+- Attribuez des autorisations à des groupes et non à des utilisateurs. Cela devrait rendre la gestion des permissions plus facile et plus transparente dans la plupart des cas
+
+## ![✔] OWASP A6 : Mauvaise configuration de la sécurité
+
+- L'accès à l'environnement interne de production se fait uniquement par le réseau interne, en utilisant SSH ou d'autres moyens, mais _n'exposez jamais_ les services internes
+- Restreignez l'accès au réseau interne - définissez explicitement quelle ressource peut accéder à quelles autres ressources (par exemple, la politique du réseau ou des sous-réseaux)
+- Si vous utilisez des cookies, configurez-les en mode « sécurisés » afin qu'ils soient envoyés uniquement via SSL
+- Si vous utilisez des cookies, configurez-les uniquement pour un « même site » afin que seules les requêtes provenant d'un même domaine puissent récupérer les cookies indiqués.
+- Si vous utilisez des cookies, préférez une configuration « HttpOnly » qui empêche le code JavaScript côté client d'accéder aux cookies
+- Protégez chaque VPC par des règles d'accès strictes et restrictives
+- Priorisez les menaces en utilisant n'importe quel modèle standard de menace de sécurité comme STRIDE ou DREAD
+- Protégez-vous contre les attaques DDoS à l'aide d'équilibreurs de charge HTTP(S) et TCP
+- Effectuez des tests de pénétration périodiques par des agences spécialisées
+
+## ![✔] OWASP A3 : Exposition des données sensibles
+
+- N'acceptez que les connexions SSL/TLS, appliquez Strict-Transport-Security en utilisant les entêtes
+- Séparez le réseau en segments (c'est-à-dire sous-réseaux) et assurez-vous que chaque nœud dispose uniquement des autorisations d'accès nécessaires au réseau
+- Regroupez tous les services/instances qui n'ont pas besoin d'accès à internet et interdisez explicitement toute connexion sortante (un sous-réseau privé)
+- Stockez tous les secrets dans un coffre-fort, des produits comme AWS KMS, HashiCorp Vault ou Google Cloud KMS
+- Verrouillez les métadonnées d'instance sensibles à l'aide de métadonnées
+- Cryptez les données en transit lorsqu'elles quittent une frontière physique
+- N'incluez pas de secrets dans les instructions de journal
+- Évitez d'afficher des mots de passe en clair dans le frontend, prenez les mesures nécessaires dans le backend et ne stockez jamais d'informations sensibles en clair
+
+## ![✔] OWASP A9 : Utilisation de composants avec des vulnérabilités de sécurité connues
+
+- Analysez les images des dockers à la recherche de vulnérabilités connues (en utilisant les services d'analyse de Docker et d'autres fournisseurs)
+- Activez les correctifs et les mises à jour automatiques des instances (machines) pour éviter d'utiliser des versions de systèmes d'exploitation anciennes qui ne disposent pas de correctifs de sécurité
+- Fournissez à l'utilisateur les jetons « id », « access » et « refresh » afin que le jeton d'accès soit de courte durée et renouvelé avec le jeton « refresh »
+- Enregistrez et auditerz chaque appel d'API vers les services de gestion et de cloud (par exemple, qui a supprimé le compartiment S3 ?) en utilisant des services comme AWS CloudTrail
+- Exécutez le contrôle de sécurité de votre fournisseur de services en ligne (par exemple, le conseiller en sécurité de AWS)
+
+
+## ![✔] OWASP A10 : Journalisation et surveillance insuffisantes
+
+- Alertez sur les événements d'audit significatifs ou suspects tels que la connexion d'un utilisateur, la création d'un nouvel utilisateur, le changement d'autorisation, etc.
+- Alertez sur le nombre irrégulier d'échecs de connexion (ou actions équivalentes comme l'oubli du mot de passe)
+- Indiquez l'heure et le nom de l'utilisateur qui a initié la mise à jour dans chaque enregistrement de la base de données
+
+## ![✔] OWASP A7 : Cross-Site-Scripting (XSS)
+
+- Utilisez des moteurs ou des frameworks de template qui échappent automatiquement le XSS par leur conception, comme EJS, Pug, React ou Angular. Apprenez les limites de chaque mécanisme de protection XSS et traiter de manière appropriée les cas d'utilisation qui ne sont pas couverts
+- Échappez les données de requête HTTP non fiables en fonction du contexte dans la sortie HTML (corps, attribut, JavaScript, CSS ou URL) résoudra les vulnérabilités XSS reflétées et stockées
+- L'application d'un encodage contextuel lors de la modification du document du navigateur côté client agit contre DOM XSS
+- Permettez une politique de sécurité des contenus (CSP) comme défense en profondeur pour atténuer le contrôle contre les XSS
+
+## ![✔] Protégez les informations personnelles identifiables (données PII)
+
+- Les informations personnelles identifiables (PII : Personally identifiable information) sont toutes les données qui peuvent être utilisées pour identifier une personne spécifique
+- Protégez les informations personnelles identifiables dans les applications en les cryptant
+- Respectez les lois du pays en matière de protection des données. Lois de référence :
+ - Union européenne : RGPD - https://ec.europa.eu/info/law/law-topic/data-protection_fr
+ - Inde : https://meity.gov.in/writereaddata/files/Personal_Data_Protection_Bill,2018.pdf
+ - Singapour : https://www.pdpc.gov.sg/Overview-of-PDPA/The-Legislation/Personal-Data-Protection-Act
+
+## ![✔] Avoir un fichier security.txt [PRODUCTION]
+
+**TL;PL :** Ayez un fichier texte appelé ```security.txt``` sous le répertoire ```/.well-known``` (/.well-known/security.txt) ou dans le répertoire racine (/security.txt) de votre site web ou de votre application web en production. Le fichier ```security.txt``` doit contenir les détails permettant aux chercheurs en sécurité de signaler des vulnérabilités, ainsi que les coordonnées de la personne/du groupe responsable (adresse électronique et/ou numéros de téléphone) à qui les rapports doivent être envoyés.
+
+**Autrement :** Il se peut que vous ne soyez pas informé des vulnérabilités. Vous manquerez l'occasion d'agir à temps sur les vulnérabilités.
+
+🔗 [**Plus d'infos : security.txt**](https://securitytxt.org/)
+
+
+## ![✔] Avoir un fichier SECURITY.md [OPEN SOURCE]
+
+**TL;PL :** Pour donner aux gens des instructions pour signaler de manière responsable les vulnérabilités de sécurité dans votre projet, vous pouvez ajouter un fichier SECURITY.md file à la racine de votre dépôt, dans le dossier docs ou .github. Le fichier SECURITY.md doit contenir les détails permettant aux chercheurs en sécurité de signaler les vulnérabilités, ainsi que les coordonnées de la personne/du groupe responsable (adresse électronique et/ou numéros de téléphone) à qui les rapports doivent être envoyés.
+
+**Autrement :** Il se peut que vous ne soyez pas informé des vulnérabilités. Vous manquerez l'occasion d'agir à temps sur les vulnérabilités.
+
+🔗 [**Plus d'infos : SECURITY.md**](https://help.github.com/en/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository)
+
+
diff --git a/sections/security/commonsecuritybestpractices.md b/sections/security/commonsecuritybestpractices.md
index 5221a7245..86a906f27 100644
--- a/sections/security/commonsecuritybestpractices.md
+++ b/sections/security/commonsecuritybestpractices.md
@@ -10,7 +10,7 @@ The common security guidelines section contains best practices that are standard
**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**](/sections/security/secureserver.md)
+🔗 [**Read More: Running a secure Node.js server**](./secureserver.md)
@@ -24,7 +24,7 @@ The common security guidelines section contains best practices that are standard
## ![✔] 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.
+**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/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
@@ -75,7 +75,7 @@ Going on, below we've listed some important bits of advice from the OWASP projec
## ![✔] OWASP A9: Using Components With Known Security Vulneraibilities
-- Scan docker images for known vulnerabilities (using Docker's and other vendors offer scanning services)
+- Scan docker images for known vulnerabilities (using Docker's and other vendors' 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
@@ -95,5 +95,33 @@ Going on, below we've listed some important bits of advice from the OWASP projec
- Applying context-sensitive encoding when modifying the browser document on the client-side acts against DOM XSS
- Enabling a Content-Security Policy (CSP) as a defense-in-depth mitigating control against XSS
+## ![✔] Protect Personally Identifyable Information (PII Data)
+
+- Personally identifiable information (PII) is any data that can be used to identify a specific individual
+- Protect Personally Identifyable Information in the Applications by encrypting them
+- Follow the data privacy laws of the land. Reference laws:
+ - European Union: GDPR - https://ec.europa.eu/info/law/law-topic/data-protection_en
+ - India: https://meity.gov.in/writereaddata/files/Personal_Data_Protection_Bill,2018.pdf
+ - Singapore: https://www.pdpc.gov.sg/Overview-of-PDPA/The-Legislation/Personal-Data-Protection-Act
+
+## ![✔] Have a security.txt File [PRODUCTION]
+
+**TL;DR:** Have a text file called ```security.txt``` under ```/.well-known``` directory (/.well-known/security.txt) or in the root directory (/security.txt) of your website or your web application in production. ```security.txt``` file should contain details using which security researchers can report vulnerabilities and also the contact details of the responsible person/group (email id and/or phone numbers) to whom the reports have to be sent.
+
+**Otherwise:** You may not be notified about the vulnerabilities. You will miss the opportunity to act on the vulnerabilities in time.
+
+🔗 [**Read More: security.txt**](https://securitytxt.org/)
+
+
+## ![✔] Have a SECURITY.md File [OPEN SOURCE]
+
+**TL;DR:** To give people instructions for responsibly reporting security vulnerabilities in your project, you can add a SECURITY.md file to your repository's root, docs, or .github folder. SECURITY.md file should contain details using which security researchers can report vulnerabilities and also the contact details of the responsible person/group (email id and/or phone numbers) to whom the reports have to be sent.
+
+**Otherwise:** You may not be notified about the vulnerabilities. You will miss the opportunity to act on the vulnerabilities in time.
+
+🔗 [**Read More: SECURITY.md**](https://help.github.com/en/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository)
+
+
+
diff --git a/sections/security/commonsecuritybestpractices.polish.md b/sections/security/commonsecuritybestpractices.polish.md
new file mode 100644
index 000000000..1638ec8ae
--- /dev/null
+++ b/sections/security/commonsecuritybestpractices.polish.md
@@ -0,0 +1,97 @@
+[✔]: ../../assets/images/checkbox-small-blue.png
+
+# Typowe najlepsze praktyki bezpieczeństwa Node.js
+
+Sekcja wspólnych wskazówek bezpieczeństwa zawiera najlepsze praktyki, które są znormalizowane w wielu ramach i konwencjach, na przykład uruchamianie aplikacji za pomocą protokołu SSL / TLS powinno być wspólną wytyczną i konwencją przestrzeganą w każdej konfiguracji, aby osiągnąć ogromne korzyści bezpieczeństwa.
+
+## ![✔] Użyj SSL / TLS, aby zaszyfrować połączenie klient-serwer
+
+**TL;DR:** W czasach [darmowych certyfikatów SSL/TLS](https://letsencrypt.org/) i ich łatwej konfiguracji, nie musisz już rozważać zalet i wad korzystania z bezpiecznego serwera, ponieważ zalety takie jak bezpieczeństwo, obsługa nowoczesnej technologii i zaufanie wyraźnie przewyższają wady takie jak minimalny narzut w porównaniu do czystego HTTP.
+
+**W przeciwnym razie:** Atakujący mogą przeprowadzać ataki typu man-in-the-middle, szpiegować zachowanie użytkowników i wykonywać jeszcze bardziej złośliwe działania, gdy połączenie nie jest szyfrowane
+
+🔗 [**Czytaj więcej: Running a secure Node.js server**](./secureserver.md)
+
+
+
+## ![✔] Bezpieczne porównywanie wartości poufnych i skrótów
+
+**TL;DR:** Porównując tajne wartości lub skróty, takie jak skróty HMAC, powinieneś użyć [`crypto.timingSafeEqual(a,b)`]](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) funkcja Node'a udostępnia od razu po instalacji od wersji Node.js v6.6.0. Ta metoda porównuje dwa podane obiekty i porównuje, nawet jeśli dane się nie zgadzają. Domyślne metody porównywania równości powróciłyby po niedopasowaniu znaków, umożliwiając ataki czasowe na podstawie długości operacji.
+
+**W przeciwnym razie:** Używając domyślnych operatorów porównania równości, możesz ujawnić krytyczne informacje na podstawie czasu potrzebnego na porównanie dwóch obiektów
+
+
+
+## ![✔] Generowanie losowych ciągów za pomocą Node.js
+
+**TL;DR:** Korzystanie z niestandardowej funkcji generującej pseudolosowe ciągi znaków dla tokenów i innych wrażliwych na bezpieczeństwo przypadków użycia może nie być tak losowe, jak myślisz, co może narazić Twoją aplikację na ataki kryptograficzne. Gdy musisz wygenerować bezpieczne losowe ciągi, użyj [`crypto.randomBytes(size,[callback])`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) przy użyciu dostępnej entropii dostarczonej przez system.
+
+**W przeciwnym razie:** Podczas generowania pseudolosowych ciągów bez metod kryptograficznych osoby atakujące mogą przewidywać i odtwarzać wygenerowane wyniki, co powoduje, że aplikacja nie jest bezpieczna
+
+
+
+Dalej, poniżej wymieniliśmy kilka ważnych porad z projektu OWASP.
+
+## ![✔] OWASP A2: Broken Authentication
+
+- Wymagaj MFA / 2FA dla ważnych usług i kont
+- Często zmieniaj hasła i klucze dostępu, w tym klucze SSH
+- Zastosuj silne zasady haseł, zarówno w przypadku operacji, jak i zarządzania użytkownikami w aplikacji ([🔗 OWASP password recommendation](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
+- Nie wysyłaj ani nie wdrażaj aplikacji z domyślnymi poświadczeniami, szczególnie dla użytkowników administracyjnych lub usług zewnętrznych, od których zależysz
+- Używaj tylko standardowych metod uwierzytelniania, takich jak OAuth, OpenID itp. - **Unikaj** Podstawowego uwierzytelnienia
+- Ograniczanie szybkości uwierzytelniania: nie zezwalaj na więcej niż _X_ prób logowania (w tym odzyskiwania hasła itp.) w okresie _Y_
+- W przypadku niepowodzenia logowania nie informuj użytkownika, czy weryfikacja nazwy użytkownika lub hasła nie powiodła się, po prostu zwróć typowy błąd uwierzytelnienia
+- Rozważ zastosowanie scentralizowanego systemu zarządzania użytkownikami, aby uniknąć zarządzania wieloma kontami na pracownika (np. GitHub, AWS, Jenkins itp.) i skorzystaj z przetestowanego w walce systemu zarządzania użytkownikami
+
+## ![✔] OWASP A5: Broken access control
+
+- Przestrzegaj [zasady najmniejszych przywilejów](https://en.wikipedia.org/wiki/Principle_of_least_privilege) - każdy komponent i osoba DevOps powinna mieć dostęp tylko do niezbędnych informacji i zasobów
+- **Nigdy** nie pracuj z console/root (pełne uprawnienia) z wyjątkiem zarządzania kontem
+- Uruchom wszystkie instancje / kontenery w imieniu konta roli / usługi
+- Przypisywanie uprawnień grupom, a nie użytkownikom. Powinno to uczynić zarządzanie uprawnieniami łatwiejszymi i bardziej przejrzystymi w większości przypadków
+
+## ![✔] OWASP A6: Security Misconfiguration
+
+- Dostęp do wewnętrznych elementów środowiska produkcyjnego odbywa się tylko przez sieć wewnętrzną, użyj SSH lub w inny sposób, ale _nigdy_ nie ujawnij usługi wewnętrznej
+- Ogranicz dostęp do sieci wewnętrznej - jawnie określ, który zasób może uzyskać dostęp do innych zasobów (np. zasad sieciowych lub podsieci)
+- Jeśli używasz plików cookie, skonfiguruj go w tryb „bezpieczny”, w którym jest wysyłany tylko przez SSL
+- Jeśli używasz plików cookie, skonfiguruj je tylko dla „tej samej strony”, aby tylko żądania z tej samej domeny odzyskały wyznaczone pliki cookie
+- W przypadku korzystania z plików cookie preferuj konfigurację „HttpOnly”, która uniemożliwia dostęp do plików cookie przez kod JavaScript po stronie klienta
+- Chroń każdego VPC za pomocą ścisłych i restrykcyjnych zasad dostępu
+- Priorytetyzuj zagrożenia za pomocą dowolnego standardowego modelowania zagrożeń bezpieczeństwa, takiego jak STRIDE lub DREAD
+- Ochrona przed atakami DDoS za pomocą równoważników obciążenia HTTP (S) i TCP
+- Przeprowadzaj okresowe testy penetracyjne przez wyspecjalizowane agencje
+
+## ![✔] OWASP A3: Sensitive Data Exposure
+
+- Akceptuj tylko połączenia SSL / TLS, wymuszaj ścisłe bezpieczeństwo transportu za pomocą nagłówków
+- Podziel sieć na segmenty (tj. podsieci) i upewnij się, że każdy węzeł ma najmniej niezbędne uprawnienia dostępu do sieci
+- Zgrupuj wszystkie usługi / wystąpienia, które nie wymagają dostępu do Internetu, i wyraźnie nie zezwalaj na żadne połączenie wychodzące (np. prywatna podsieć)
+- Przechowuj wszystkie dane wrażliwe w produktach Vault, takich jak AWS KMS, HashiCorp Vault lub Google Cloud KMS
+- Metadane instancji wrażliwej na blokadę przy użyciu metadanych
+- Szyfruj przesyłane dane, gdy opuszczą fizyczną granicę
+- Nie dołączaj danych wrażliwych do instrukcji dziennika
+- Unikaj wyświetlania prostych haseł w interfejsie użytkownika, podejmuj niezbędne środki w interfejsie i nigdy nie przechowuj poufnych informacji w postaci zwykłego tekstu
+
+## ![✔] OWASP A9: Using Components With Known Security Vulneraibilities
+
+- Skanuj obrazy dokerów w poszukiwaniu znanych luk (przy użyciu Dockera i innych dostawców oferują usługi skanowania)
+- Włącz automatyczne łatanie i aktualizowanie instancji (maszyny), aby uniknąć uruchamiania starych wersji systemu operacyjnego, które nie zawierają poprawek zabezpieczeń
+- Zapewnij użytkownikowi zarówno token „id”, „access”, jak i „refresh”, aby token dostępu był krótkotrwały i odnowiony tokenem odświeżania
+- Rejestruj i kontroluj każde wywołanie interfejsu API do usług w chmurze i usług zarządzania (np. Kto usunął segment S3?) Za pomocą usług takich jak AWS CloudTrail
+- Uruchom narzędzie do sprawdzania bezpieczeństwa dostawcy usług w chmurze (np. doradca ds. zaufania bezpieczeństwa AWS)
+
+## ![✔] OWASP A10: Insufficient Logging & Monitoring
+
+- Ostrzegaj o niezwykłych lub podejrzanych zdarzeniach kontrolnych, takich jak logowanie użytkownika, tworzenie nowego użytkownika, zmiana uprawnień itp
+- Alarm o nieregularnej liczbie błędów logowania (lub równoważnych działań, takich jak zapomnienie hasła)
+- Dołącz czas i nazwę użytkownika, które zainicjowały aktualizację do każdego rekordu BD
+
+## ![✔] OWASP A7: Cross-Site-Scripting (XSS)
+
+- Używaj szablonów lub struktur szablonów, które automatycznie uciekają z XSS zgodnie z projektem, takich jak EJS, Pug, React lub Angular. Poznaj ograniczenia każdego mechanizmu ochrony XSS i odpowiednio obsługuj przypadki użycia, które nie są objęte
+- Ucieczka niezaufanych danych żądań HTTP na podstawie kontekstu w danych wyjściowych HTML (treść, atrybut, JavaScript, CSS lub adres URL) usunie podatność na Reflected i Stored XSS
+- Zastosowanie kodowania kontekstowego podczas modyfikowania dokumentu przeglądarki po stronie klienta działa przeciwko DOM XSS
+- Włączenie polityki bezpieczeństwa treści (CSP) jako dogłębnej obrony ograniczającej kontrolę nad XSS
+
+
diff --git a/sections/security/commonsecuritybestpractices.russian.md b/sections/security/commonsecuritybestpractices.russian.md
index f62035c5f..c5bd479de 100644
--- a/sections/security/commonsecuritybestpractices.russian.md
+++ b/sections/security/commonsecuritybestpractices.russian.md
@@ -10,7 +10,7 @@
**Иначе:** Злоумышленники могут выполнять атаки "человек посередине", следить за поведением ваших пользователей и совершать еще более злонамеренные действия, когда соединение не зашифровано.
-🔗 [**Read More: Запуск безопасного Node.js сервера**](/sections/security/secureserver.russian.md)
+🔗 [**Read More: Запуск безопасного Node.js сервера**](./secureserver.russian.md)
@@ -24,7 +24,7 @@
## ![✔] Генерация случайных строк с использованием Node.js
-**TL;DR:** Использование специально созданной функции, генерирующей псевдослучайные строки для токенов и других чувствительных к безопасности случаев использования, на самом деле может быть не таким случайным, как вы думаете, что делает ваше приложение уязвимым для криптографических атак. Когда вам нужно создать безопасные случайные строки, используйте [`crypto.RandomBytes(size, [callback])`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_randombytes_size_callback), используя доступную энтропию, предоставляемую системой.
+**TL;DR:** Использование специально созданной функции, генерирующей псевдослучайные строки для токенов и других чувствительных к безопасности случаев использования, на самом деле может быть не таким случайным, как вы думаете, что делает ваше приложение уязвимым для криптографических атак. Когда вам нужно создать безопасные случайные строки, используйте [`crypto.randomBytes(size, [callback])`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback), используя доступную энтропию, предоставляемую системой.
**Иначе:** При создании псевдослучайных строк без криптографически безопасных методов злоумышленники могут прогнозировать и воспроизводить сгенерированные результаты, делая ваше приложение небезопасным
diff --git a/sections/security/dependencysecurity.basque.md b/sections/security/dependencysecurity.basque.md
new file mode 100644
index 000000000..beb8d0825
--- /dev/null
+++ b/sections/security/dependencysecurity.basque.md
@@ -0,0 +1,54 @@
+# Etengabe eta automatikoki ikuskatu mendekotasun ba ote dagoen zaurgarritik
+
+### Azalpena
+
+Node.js aplikazio gehienak inork egindako npm edo Yarn modulu ugarietan oinarritzen dira, pakete erregistro ezagunak biak, garatzeko erraztasuna eta azkartasuna dituzte eta. Hala ere, abantaila horren alde txarra da ahulezia ezezagunak dituela zure aplikazioan sartuz gero haren segurtasunari arriskuak eragin ahal dizkiona, hau da, OWASP web aplikazioen segurtasun arrisku larrien zerrendan duten lekuagatik ezagunak direnak.
+
+Node.js aplikazioetan tresna ugari erabil daitezke hirugarrenen paketeetan ahulak diren aplikazioak identifikatzen laguntzeko, zure proiektuan sartzeko arriskua arintze aldera . Horiek aldizka CLI tresnetatik erabil daitezke edo zure aplikazioaren eraikuntza prozesuaren barruan sartu.
+
+### Edukien taula
+
+- [NPM audit](#npm-audit)
+- [Snyk](#snyk)
+- [Greenkeeper](#greenkeeper)
+- [Baliabide osagarriak](#baliabide-osagarriak)
+
+### NPM Audit
+
+`npm audit` NPM @ 6-rekin batera sartutako cli tresna berria da.
+
+Npm auditoretza exekutatzeak segurtasun ahultasunen txostena sortuko du kaltetutako paketearen izenarekin, zaurgarritasunaren larritasunarekin eta deskribapenarekin, bidearekin eta bestelako informazioarekin, eta, gainera, ahultasunak konpontzeko adabakiak aplikatzeko aginduak emango ditu, eskuragarri egonez gero.
+
+
+
+🔗 [Irakurri: NPM bloga](https://docs.npmjs.com/getting-started/running-a-security-audit)
+
+### Snyk
+
+Snykek funtzio aberatsa duen CLI bat eskaintzen du, baita GitHub integrazioa ere. Horrekin Snyk urrunago doa eta, ahultasunak jakinarazteaz gain, ahuleziak konpontzen dituen erauzte eskaera berriak ere sortzen ditu automatikoki, adabakiak ahulezia ezagunetarako kaleratzen baitira.
+
+Snyken webgune aberatsak mendekotasunak ad-hoc ebaluatzeko aukera ere ematen du GitHub biltegiarekin edo npm moduluaren URLarekin hornituta. Ahuleziak dituzten npm paketeak ere bila ditzakezu zuzenean.
+
+Synk GitHub integrazioaren irteeraren adibide bat, erauzte eskaera automatikoki sortuz:
+
+
+🔗 [ Irakurri hemen: Snyk webgunea](https://snyk.io/)
+
+🔗 [Irakurri: Synk onlineko tresna npm paketeak eta GitHub moduluak egiaztatzeko](https://snyk.io/test)
+
+### Greenkeeper
+
+Greenkeeper denbora errealeko menpekotasunen eguneratzeak eskaintzen dituen zerbitzua da, aplikazioak seguruago mantentzen dituena, eguneratutako eta adabakitako menpekotasun bertsioak erabiliz beti.
+
+Greenkeeperrek biltegi baten `package.json` fitxategian zehaztutako npm menpekotasunak ikusten ditu eta automatikoki laneko adar bat sortzen du menpekotasunen eguneratze bakoitzarekin. Biltegirako CI suite exekutatuko da aplikazioan eguneratutako menpekotasun bertsiorako aldaketa aldakorrak agerian uzteko. IEk huts egiten badu menpekotasunaren eguneratzea dela eta, gai argia eta zehatza sortzen da enkantean jarri nahi den biltegian, uneko eta eguneratutako paketeen bertsioak azalduz, informazioarekin eta eguneratutako bertsioaren konpromiso historiarekin batera.
+
+Greenkeeper GitHub integrazioaren irteeraren adibide bat erauzte eskaera automatikoki sortuz:
+
+
+🔗 [Irakurri: Greenkeeper webgunea](https://greenkeeper.io/)
+
+### Baliabide osagarriak
+
+🔗 [Rising Stack bloga: Node.jsren menpekotasun arriskuak](https://blog.risingstack.com/controlling-node-js-security-risk-npm-dependencies/)
+
+🔗 [NodeSource Bloga: npmen segurtasuna hobetzea](https://nodesource.com/blog/how-to-reduce-risk-and-improve-security-around-npm)
diff --git a/sections/security/dependencysecurity.brazilian-portuguese.md b/sections/security/dependencysecurity.brazilian-portuguese.md
index 012a7ea11..54b0ebc63 100644
--- a/sections/security/dependencysecurity.brazilian-portuguese.md
+++ b/sections/security/dependencysecurity.brazilian-portuguese.md
@@ -18,7 +18,7 @@ Há várias ferramentas disponíveis para ajudar a identificar pacotes de tercei
A execução de `npm audit` produzirá um relatório de vulnerabilidades de segurança com o nome do pacote afetado, gravidade da vulnerabilidade e descrição, caminho e outras informações e, se disponíveis, comandos para aplicar correções para resolver vulnerabilidades.
-
+
🔗 [Leia em: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
@@ -29,7 +29,7 @@ O Snyk oferece uma CLI rica em recursos, bem como integração com o GitHub. O S
O site do Snyk, rico em recursos, também permite uma avaliação ad-hoc das dependências, quando fornecido com um repositório do GitHub ou url do módulo npm. Você também pode procurar por pacotes npm que possuem vulnerabilidades diretamente.
Um exemplo da saída da integração do Synk GitHub, solicitação de pull criada automaticamente:
-
+
🔗 [Leia em: Snyk website](https://snyk.io/)
@@ -43,7 +43,7 @@ O Greenkeeper observa as dependências npm especificadas no arquivo `package.jso
Um exemplo da saída da solicitação do Greenkeeper GitHub automaticamente criado pull request:
-
+
🔗 [Leia em: site do Greenkeeper](https://greenkeeper.io/)
### Recursos Adicionais
diff --git a/sections/security/dependencysecurity.french.md b/sections/security/dependencysecurity.french.md
new file mode 100644
index 000000000..b625e55cc
--- /dev/null
+++ b/sections/security/dependencysecurity.french.md
@@ -0,0 +1,54 @@
+# Inspectez constamment et automatiquement les dépendances vulnérables
+
+### Un paragraphe d'explication
+
+La majorité des applications Node.js pour des raisons de facilité et de rapidité de développement reposent largement sur un grand nombre de modules tiers de npm ou de Yarn, deux registres de paquets populaires. Cependant, l'inconvénient de cet avantage est le risque d'inclure des vulnérabilités inconnues dans votre application, risque reconnu par son classement dans la liste des principaux risques de sécurité des applications web critiques de l'OWASP.
+
+Il existe un certain nombre d'outils disponibles pour aider à identifier les paquets tiers dans les applications Node.js qui ont été identifiés comme vulnérables par la communauté afin d'atténuer le risque de les introduire dans votre projet. Ceux-ci peuvent être utilisés périodiquement à partir des outils CLI ou inclus dans le cadre du processus de construction de votre application.
+
+### Table des matières
+
+- [NPM audit](#npm-audit)
+- [Snyk](#snyk)
+- [Greenkeeper](#greenkeeper)
+- [Ressources complémentaires](#ressources-complémentaires)
+
+### NPM Audit
+
+`npm audit` est un nouvel outil cli introduit avec NPM@6.
+
+L'exécution de `npm audit` produira un rapport des vulnérabilités de sécurité avec le nom du paquet affecté, la gravité et la description de la vulnérabilité, le chemin et d'autres informations, et si disponibles, des commandes pour appliquer des correctifs pour résoudre les vulnérabilités.
+
+
+
+🔗 [A lire : NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
+
+### Snyk
+
+Snyk propose une CLI riche en fonctionnalités, ainsi qu'une intégration dans GitHub. Snyk va plus loin dans cette démarche et en plus de notifier les vulnérabilités, il crée automatiquement de nouvelles pull requests corrigeant les vulnérabilités au fur et à mesure que des correctifs sont publiés pour des vulnérabilités connues.
+
+Le site web riche en fonctionnalités de Snyk permet également une évaluation adéquate des dépendances lorsqu'il est associé avec un dépôt GitHub ou une URL de module npm. Vous pouvez également rechercher directement les paquets npm qui présentent des vulnérabilités.
+
+Un exemple d'affichage de l'intégration de Snyk avec GitHub qui crée automatiquement un pull request :
+
+
+🔗 [A lire : Site web de Snyk](https://snyk.io/)
+
+🔗 [A lire : Outil en ligne Synk pour vérifier les paquets npm et les modules GitHub](https://snyk.io/test)
+
+### Greenkeeper
+
+Greenkeeper est un service qui propose des mises à jour de dépendances en temps réel, ce qui permet de garder une application plus sûre en utilisant toujours les versions de dépendances les plus récentes et les plus corrigées.
+
+Greenkeeper surveille les dépendances npm spécifiées dans le fichier `package.json` d'un dépôt et crée automatiquement une branche de travail avec chaque mise à jour de dépendance. La suite CI du dépôt est ensuite exécutée pour révéler les changements de rupture de la version de dépendance mise à jour dans l'application. Si le CI échoue en raison de la mise à jour des dépendances, une issue claire et concise est créée dans le dépôt pour être traitée, décrivant les versions actuelles et mises à jour du paquet, ainsi que les informations et l'historique des commits de la version mise à jour.
+
+Un exemple d'affichage de l'intégration de Greenkeeper avec GitHub qui crée automatiquement un pull request :
+
+
+🔗 [A lire : Site web de Greenkeeper](https://greenkeeper.io/)
+
+### Ressources complémentaires
+
+🔗 [Blog de Rising Stack : Risques de dépendance de Node.js](https://blog.risingstack.com/controlling-node-js-security-risk-npm-dependencies/)
+
+🔗 [Blog de NodeSource : Améliorez la sécurité de npm](https://nodesource.com/blog/how-to-reduce-risk-and-improve-security-around-npm)
diff --git a/sections/security/dependencysecurity.japanese.md b/sections/security/dependencysecurity.japanese.md
new file mode 100644
index 000000000..bd03ac3ea
--- /dev/null
+++ b/sections/security/dependencysecurity.japanese.md
@@ -0,0 +1,53 @@
+# 定期的に、そして自動的に脆弱性のある依存関係を検査する
+
+### 一段落説明
+
+Node.js アプリケーションの大部分は、開発の容易化とスピードアップを目的として、人気のあるパッケージレジストリである npm や Yarn に存在する多数のサードパーティモジュールに大きく依存しています。しかし、この利点の負の側面は、未知の脆弱性をアプリケーションに含めることによるセキュリティリスクです。このリスクは、OWSAP のクリティカルなウェブアプリケーションセキュリティリスクリストにおいて上位に位置するものです。
+
+プロジェクトに脆弱性を注入してしまうリスクを軽減するために、コミュニティによって脆弱性があると識別された Node.js アプリケーションのサードパーティ製パッケージを特定することができるツールがいくつかあります。これらは CLI ツールから定期的に利用することができますし、アプリケーションのビルドプロセスの一部として含むこともできます。
+
+### 目次
+
+- [NPM audit](#npm-audit)
+- [Snyk](#snyk)
+- [Greenkeeper](#greenkeeper)
+
+### NPM Audit
+
+`npm audit` は NPM@6 において導入された新しい CLI ツールです。
+
+`npm audit` を実行すると、影響を受けるパッケージ名、脆弱性の深刻度と概要、パス、そしてその他の情報を含むセキュリティ脆弱性のレポートが作成され、さらに、利用可能な場合には脆弱性を解決するためのパッチを適用するためのコマンドが表示されます。
+
+
+
+🔗 [NPM blog で読む](https://docs.npmjs.com/getting-started/running-a-security-audit)
+
+### Snyk
+
+Snyk は機能豊富な CLI と GitHub インテグレーションを提供しています。Snyk はさらに、脆弱性を通知するだけでなく、既知の脆弱性に対するパッチがリリースされると、脆弱性を修正する新しいプルリクエストを自動的に作成します。
+
+Snyk の機能豊富なウェブサイトでは、GitHub リポジトリや npm モジュールの URL を与えると、依存性のアドホックな評価を実行することもできます。また、脆弱性がある npm パッケージを直接検索することもできます。
+
+Synk Github インテグレーションが自動的にプルリクエストを作成した際の出力結果例:
+
+
+🔗 [Snyk website で読む](https://snyk.io/)
+
+🔗 [Synk online tool to check npm packages and GitHub modules で読む](https://snyk.io/test)
+
+### Greenkeeper
+
+Greenkeeper はリアルタイムに依存関係のアップデート情報を提供するサービスで、常に最新のパッチが適用された依存関係のバージョンを使用することで、アプリケーションの安全性を維持します。
+
+Greenkeeper は、リポジトリの `package.json` ファイルで指定された npm 依存関係を監視し、依存関係のアップデートごとに作業ブランチを自動的に作成します。その後、リポジトリの CI が実行され、アプリケーション内でアップデートされた依存関係のバージョンの変更点を明らかにします。依存関係のアップデートが原因で CI が失敗した場合、現在のパッケージバージョンとアップデートされたパッケージバージョンの概要と、アップデートされたバージョンの情報とコミット履歴が記載された、明確で簡潔な issue がリポジトリに作成され、議論が交わされます。
+
+Greenkeeper GitHub インテグレーションが自動的にプルリクエストを作成した際の出力結果例:
+
+
+🔗 [Greenkeeper website で読む](https://greenkeeper.io/)
+
+### 追加資料
+
+🔗 [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/dependencysecurity.md b/sections/security/dependencysecurity.md
index 38abb514b..11478f1c3 100644
--- a/sections/security/dependencysecurity.md
+++ b/sections/security/dependencysecurity.md
@@ -11,6 +11,7 @@ There is a number of tools available to help identify third-party packages in No
- [NPM audit](#npm-audit)
- [Snyk](#snyk)
- [Greenkeeper](#greenkeeper)
+- [Additional Resources](#additional-resources)
### NPM Audit
@@ -18,7 +19,7 @@ There is a number of tools available to help identify third-party packages in No
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.
-
+
🔗 [Read on: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
@@ -28,8 +29,8 @@ Snyk offers a feature-rich CLI, as well as GitHub integration. Snyk goes further
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 vulnerabilities directly.
-An example of the output of the Synk GitHub integration automatically created pull request:
-
+An example of the output of the Snyk GitHub integration automatically created pull request:
+
🔗 [Read on: Snyk website](https://snyk.io/)
@@ -37,13 +38,13 @@ An example of the output of the Synk GitHub integration automatically created pu
### 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 is a service which offers real-time dependency updates, which keeps an application more secure by always using the most up 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 to the dependency update, a clear and concise issue is created in the repository to be auctioned, 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:
-
+
🔗 [Read on: Greenkeeper website](https://greenkeeper.io/)
### Additional resources
diff --git a/sections/security/dependencysecurity.polish.md b/sections/security/dependencysecurity.polish.md
new file mode 100644
index 000000000..47afc29dc
--- /dev/null
+++ b/sections/security/dependencysecurity.polish.md
@@ -0,0 +1,53 @@
+# Stale i automatycznie sprawdzaj podatne zależności
+
+### Wyjaśnienie jednym akapitem
+
+Większość aplikacji Node.js polega w dużej mierze na dużej liczbie modułów innych firm, npm lub Yarn, które są popularnymi rejestrami pakietów, ze względu na łatwość i szybkość programowania. Jednak wadą tej korzyści jest ryzyko związane z bezpieczeństwem wynikające z włączenia nieznanych luk w zabezpieczeniach aplikacji, które to ryzyko jest rozpoznawane po umieszczeniu go na liście najważniejszych zagrożeń bezpieczeństwa aplikacji internetowych OWASP.
+
+Dostępnych jest wiele narzędzi pomagających w identyfikacji pakietów stron trzecich w aplikacjach Node.js, które zostały zidentyfikowane przez społeczność jako podatne na zagrożenia, w celu zmniejszenia ryzyka wprowadzenia ich do projektu. Można ich używać okresowo z narzędzi CLI lub dołączać jako część procesu kompilacji aplikacji.
+
+### Spis treści
+
+- [NPM audit](#npm-audit)
+- [Snyk](#snyk)
+- [Greenkeeper](#greenkeeper)
+
+### NPM Audit
+
+`npm audit` to nowe narzędzie cli wprowadzone z NPM@6.
+
+Uruchomienie `npm audit` wygeneruje raport o słabych punktach bezpieczeństwa wraz z nazwą pakietu, istotnością i opisem podatności, ścieżką i innymi informacjami oraz, jeśli są dostępne, polecenia zastosowania łat w celu usunięcia luk.
+
+
+
+🔗 [Czytaj: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
+
+### Snyk
+
+Snyk oferuje bogaty w funkcje interfejs CLI, a także integrację z GitHub. Snyk idzie dalej i oprócz powiadamiania o lukach, automatycznie tworzy również nowe pull requesty, usuwając luki w miarę wydawania łat na znane luki.
+
+Bogata w funkcje strona internetowa Snyka pozwala również na ocenę ad-hoc zależności, jeśli jest dostarczana z repozytorium GitHub lub adresem URL modułu npm. Możesz także wyszukiwać pakiety npm, które mają luki bezpośrednio.
+
+Przykład danych wyjściowych integracji Synk GitHub automatycznie utworzony pull request:
+
+
+🔗 [Czytaj: Snyk website](https://snyk.io/)
+
+🔗 [Czytaj: Synk online tool to check npm packages and GitHub modules](https://snyk.io/test)
+
+### Greenkeeper
+
+Greenkeeper to usługa oferująca aktualizacje zależności w czasie rzeczywistym, która zapewnia bezpieczeństwo aplikacji, zawsze używając najbardziej aktualnych i poprawionych wersji zależności.
+
+Greenkeeper śledzi zależności npm określone w pliku `package.json` repozytorium i automatycznie tworzy działającą gałąź przy każdej aktualizacji zależności. Następnie uruchamiany jest pakiet CI repozytorium w celu ujawnienia wszelkich przełomowych zmian w zaktualizowanej wersji zależności w aplikacji. Jeśli CI nie powiedzie się z powodu aktualizacji zależności, w repozytorium, które ma zostać auctioned, powstaje wyraźny i zwięzły problem, przedstawiający aktualne i zaktualizowane wersje pakietów, a także informacje i historię zatwierdzeń zaktualizowanej wersji.
+
+Przykład danych wyjściowych integracji Greenkeeper GitHub tworzący automatycznie pull request:
+
+
+🔗 [Czytaj: Greenkeeper website](https://greenkeeper.io/)
+
+### Dodatkowe źródła
+
+🔗 [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/dependencysecurity.russian.md b/sections/security/dependencysecurity.russian.md
index adf4aee5d..0ebe882e7 100644
--- a/sections/security/dependencysecurity.russian.md
+++ b/sections/security/dependencysecurity.russian.md
@@ -19,7 +19,7 @@
Запуск `npm audit` выдаст отчет об уязвимостях безопасности с указанием имени уязвимого пакета, серьезности и описания уязвимости, пути и другой информации, а также, если доступно, команд для применения исправлений для устранения уязвимостей.
-
+
🔗 [Читайте еще: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
@@ -30,7 +30,7 @@ Snyk предлагает многофункциональный интерфе
Многофункциональный веб-сайт Snyk также позволяет проводить специальную оценку зависимостей, когда предоставляется GitHub-репозиторий или URL-адрес модуля npm. Вы также можете искать пакеты npm, которые имеют уязвимости напрямую.
Пример вывода интеграции Synk GitHub с автоматически созданным пул-запросом:
-
+
🔗 [Читайте еще: Snyk website](https://snyk.io/)
@@ -44,7 +44,7 @@ Greenkeeper следит за зависимостями npm, указанным
Пример вывода интеграции Greenkeeper GitHub с автоматически созданным запросом на извлечение:
-
+
🔗 [Читайте еще: Greenkeeper website](https://greenkeeper.io/)
### Дополнительные ресурсы
diff --git a/sections/security/escape-output.basque.md b/sections/security/escape-output.basque.md
new file mode 100644
index 000000000..c99a7848e
--- /dev/null
+++ b/sections/security/escape-output.basque.md
@@ -0,0 +1,66 @@
+# Ihes irteera
+
+### Azalpena
+
+HTML eta beste web lengoaia batzuek kode egikarigarriarekin nahasten dute edukia. HTML paragrafo bakar batek datuen irudikapen bisuala izan dezake JavaScript egikaritzeko argibideekin batera. HTMLa kargatzean edo APItik datuak itzultzean, gure ustez eduki hutsa denak JavaScript kodea har lezake, nabigatzaileak interpretatu eta egikaritzeko modukoa. Hori gertatzen da, adibidez, erasotzaile batek datu base batean txertatutako edukia kargatzen dugunean, adibidez ``. Hori arindu daiteke arakatzaileari aginduz konfiantzazko datuen zatiak edukitzat soilik tratatzeko eta inoiz ez interpretatzeko. Teknika horri ihes egitea deritzo. Npm liburutegi eta HTML txantiloi motor askok ihes egiteko baliabideak eskaintzen dituzte (adibidez: [escape-html](https://github.com/component/escape-html), [node-esapi](https://github.com/ESAPI/node-esapi))). HTML edukiak ez ezik CSSk eta JavaScriptek ere ihes egin beharko lukete
+
+
+
+### Kode adibidea: ez jarri fidagarritasunik gabeko daturik zure HTMLan
+
+```html
+ zuzenean scriptean
+
+ HTML komentario baten barruan
+
+ ezaugarri izen batean
+
+ tag izen batean
+
+ CSSan zuzenean
+
+```
+
+### Kode adibidea: datu base batean txerta daitekeen eduki kaltegarria
+
+```html
+
+ Komentario bat
+
+
+
+```
+
+
+
+### Blog aipua: "Pertsonaiak interpretatuak izatea nahi ez dugunean"
+
+[benramsey.com](https://benramsey.com/articles/escape-output/) bloga:
+> Datuak modu askotara irten daitezke zure aplikaziotik: web nabigatzaile bati bidalitako HTML moduan, SQL datu basera bidalita, XML RSS irakurgailura bidalita, WML haririk gabeko gailu batera bidalita, etab. Aukerak mugagabeak dira. Horietako bakoitzak bere karaktere bereziak ditu, multzoka jasotzen dituena, eta jasotako gainerako testu arruntaren aldean desberdin interpretatzen dena. Batzuetan, karaktere berezi horiek bidali nahi ditugu interpretatuak izan ahal izateko (HTML nabigatzaile batera bidalitako HTML etiketak, adibidez); beste batzuetan (erabiltzaileek edo beste iturri batzuek egindako sarreren kasuan), ez dugu nahi karaktere horiek interpretatuak izan daitezen, eta, beraz, ihes egin behar diegu.
+
+> Ihes egiteari kodetzea ere esaten zaio batzuetan: ihes egitea edo kodetzea, laburbilduz,, datuak egikaritu edo interpretatuko ez diren moduan irudikatzeko prozesua da, alegia. Adibidez, HTMLk honako testu hau letra lodiz idatziko du web nabigatzaile batean ``etiketek esanahi berezia dutelako:
+> ```html
+> Testu hau letra lodiz idatzita dago.
+> ```
+>
+> Baina, demagun etiketak nabigatzailean kargatu nahi ditudala eta haien interpretazioa ekidin nahi dudala. Orduan, HTMLan esanahi berezia duten parentesi angeluarretatik ihes egin behar dut. Hona hemen ihes egindako HTMLa:
+>
+> ```html
+> <strong>Testu hau letra lodiz idatzita dago.</strong>`
+> ```
+
+
+
+### Blog aipua: "OWASPek segurtasunera bideratutako kodeketa liburutegia erabiltzea gomendatzen du"
+
+OWASP [XSS (Cross Site Scripting) Prebentzio tranpa orria](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) bloga:
+> "Kodetzaile horiek idaztea ez da oso zaila, baina tranpa ugari daude ezkutuan. Adibidez, Javascripten bezalako lasterbide batzuk" erabiltzeko tentazioa izan dezakezu. Hala ere, balio horiek arriskutsuak dira, eta nabigatzailean habiaratutako analizatzaileek oker interpreta ditzakete. Baliteke zuri ahaztea ihes egitea ihes pertsonaiarengandik, erasotzaileek erabil dezaketeena neutralizatzeko zure segurtasun ahaleginak. **OWASPek gomendatzen du segurtasunera bideratutako kodeketa liburutegiak erabiltzea, arauak behar bezala ezartzen direla ziurtatzeko**."
+
+
+
+### Blog aipua: "Ihes sintaxia erabili behar duzu HTML zatian"
+
+OWASP [XSS (Cross Site Scripting) Prebentzio tranpa orria](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) bloga:
+> "Baina HTML entitate kodeketak ez du ondo funtzionatzen ` direto em um script
dentro de um comentário HTML
@@ -22,7 +22,7 @@ HTML e outras linguagens da Web combinam conteúdo com código executável - um
### Exemplo de código - Conteúdo mal-intencionado que pode ser injetado em um banco de dados
-```javascript
+```html
A pseudo comment to the a post
`. 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
+
+```html
+ 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
+
+```html
+
+ 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:
+>
+> ```html
+> 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:
+>
+> ```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 `
+
+### ブログ引用: "You MUST use the escape syntax for the part of the HTML"
+OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) より
+> しかし、信頼されていないデータを、` directly in a script
inside an HTML comment
@@ -22,7 +22,7 @@ HTML and other web languages mix content with executable code - a single HTML pa
### Code example - Malicious content that might be injected into a DB
-```javascript
+```html
A pseudo comment to the a post
`. Można to złagodzić, instruując przeglądarkę, aby traktowała każdą część niezaufanych danych tylko jako treść i nigdy jej nie interpretowała - ta technika nazywa się ucieczką. Wiele bibliotek NPM i silników szablonów HTML zapewnia możliwość zmiany znaczenia (przykład: [escape-html](https://github.com/component/escape-html), [node-esapi](https://github.com/ESAPI/node-esapi)). Należy unikać ucieczki nie tylko treści HTML, ale także CSS i JavaScript
+
+### Przykład kodu - Nie umieszczaj niezaufanych danych w swoim HTML
+
+```html
+ directly in a script
+
+ inside an HTML comment
+
+ in an attribute name
+
+ in a tag name
+
+ directly in CSS
+
+```
+
+### Przykład kodu - złośliwe treści, które mogą zostać wstrzyknięte do bazy danych
+
+```html
+
+ A pseudo comment to the a post
+
+
+
+```
+
+
+
+### Cytat na blogu: „Gdy nie chcemy, aby znaki były interpretowane”
+
+Z Bloga [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:
+> ```html
+> This is bold text.
+> ```
+
+
+
+### Cytat na blogu: "OWASP recommends using a security-focused encoding library"
+
+Z bloga 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**."
+
+
+
+
+### Cytat na blogu: "You MUST use the escape syntax for the part of the HTML"
+
+Z bloga 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 ` directly in a script
inside an HTML comment
@@ -22,7 +22,7 @@ HTML и другие веб-языки смешивают контент с ис
### Пример кода - вредоносный контент, который может быть введен в БД
-```javascript
+```html