# 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.
================================================
FILE: sections/docker/memory-limit.basque.md
================================================
# 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
```
### Kode adibidea: memoriaren muga Kubernetes eta V8rekin
Kubernetesen inplementaziorako yamla
```yml
apiVersion: v1
kind: Pod
metadata:
name: nire-node-aplikazioa
spec:
containers:
- name: nire-node-aplikazioa
image: nire-node-aplikazioa
resources:
requests:
memory: "400Mi"
limits:
memory: "500Mi"
command: ["node index.js --max-old-space-size=350"]
```
### 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.
================================================
FILE: sections/docker/memory-limit.french.md
================================================
# 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
```
### Code Example – Memory limit with Kubernetes and v8
Kubernetes deployment yaml
```yml
apiVersion: v1
kind: Pod
metadata:
name: my-node-app
spec:
containers:
- name: my-node-app
image: my-node-app
resources:
requests:
memory: "400Mi"
limits:
memory: "500Mi"
command: ["node index.js --max-old-space-size=350"]
```
### 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.
================================================
FILE: sections/docker/memory-limit.japanese.md
================================================
# Docker と v8 の両方を使ってメモリ制限を設定する
### 一段落説明
メモリ制限はプロセス/コンテナに許容されるメモリ使用量の最大値を伝えます - この数を超えるリクエストや使用はプロセスを強制終了させます ( OOMKill )。これを適用することは、一人の市民がジュースを一人で飲み干すことなく、他のコンポーネントを飢えさせないようにするための素晴らしいプラクティスになります。メモリ制限はまた、ランタイムがコンテナを適切なインスタンスに配置することを可能にします - 300MBのメモリが利用可能なインスタンスに500MBを消費するコンテナを配置すると失敗につながります。2つの異なるオプションでこの制限を設定することができます: V8 フラグ( --max-old-space-size )と Docker ランタイムですが、どちらも絶対に必要です。正しい健全性の判断をするためのより広い視野を持っているので、常に Docker ランタイムの制限を設定するようにしてください。この制限があると、ランタイムはどのようにスケールしてより多くのリソースを作成するかが分かります。また、いつクラッシュするかについても思慮深い判断を下すことができます - コンテナがメモリ要求の短いバーストを持っていて、ホスティングインスタンスがこれをサポートすることができる場合、Docker はコンテナを生きたままにしておきます。最後に、Docker を使って、Ops のエキスパートはメモリスワップのように考慮に入れることができる様々なプロダクションメモリの設定を設定することができます。これだけでは十分ではありません - v8 の --max-old-space-size を設定しないと、JavaScript ランタイムは限界に近づいたときにガベージコレクションをプッシュしませんし、ホスト環境の50~60%しか利用していないときにもクラッシュしてしまいます。従って、v8 の制限値を Docker のメモリ制限値の75~100%に設定します。
### コード例 – Docker でのメモリ制限
Bash
```bash
docker run --memory 512m my-node-app
```
### コード例 – Kubernetes と v8 でのメモリ制限
Kubernetes deployment yaml
```yml
apiVersion: v1
kind: Pod
metadata:
name: my-node-app
spec:
containers:
- name: my-node-app
image: my-node-app
resources:
requests:
memory: "400Mi"
limits:
memory: "500Mi"
command: ["node index.js --max-old-space-size=350"]
```
### 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)に設定して、他の用途のためにメモリを残し、スワップを避けることを検討してください。
================================================
FILE: sections/docker/memory-limit.md
================================================
# 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
```
### Code Example – Memory limit with Kubernetes and v8
Kubernetes deployment yaml
```yml
apiVersion: v1
kind: Pod
metadata:
name: my-node-app
spec:
containers:
- name: my-node-app
image: my-node-app
resources:
requests:
memory: "400Mi"
limits:
memory: "500Mi"
command: ["node index.js --max-old-space-size=350"]
```
### 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.
================================================
FILE: sections/docker/multi_stage_builds.basque.md
================================================
# 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" ]
```
================================================
FILE: sections/docker/multi_stage_builds.french.md
================================================
# 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" ]
```
================================================
FILE: sections/docker/multi_stage_builds.japanese.md
================================================
# マルチステージビルドを使用する
### 一段落説明
マルチステージビルドでは、利用可能なバイナリや公開されている環境変数、さらには基礎となる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" ]
```
================================================
FILE: sections/docker/multi_stage_builds.md
================================================
# 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" ]
```
================================================
FILE: sections/docker/restart-and-replicate-processes.basque.md
================================================
# 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"]
```
================================================
FILE: sections/docker/restart-and-replicate-processes.french.md
================================================
# 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"]
```
================================================
FILE: sections/docker/restart-and-replicate-processes.japanese.md
================================================
# プロセスを再起動と複製をDocker オーケストレーターに任せる
### 一段落説明
Kubernetes のような Docker ランタイムオーケストレータは、コンテナの健全性と配置の決定を行うのが非常に得意です。コンテナの数を最大化し、ゾーン間でバランスをとり、多くのクラスタ要因を考慮しながら、これらの決定を行います。言葉がなくても、彼らは失敗したプロセス(つまりコンテナ)を特定し、適切な場所で再起動します。にもかかわらず、CPU 利用率のためにノードプロセスを複製したり、障害時にプロセスを再起動したりするために、カスタムコードやツールを使いたくなる人もいるかもしれません(例えば、クラスタモジュール、PM2)。これらのローカルツールは、クラスタレベルで利用可能な視点やデータを持っていません。例えば、インスタンスリソースが3つのコンテナをホストでき、2つのリージョンやゾーンが与えられている場合、Kubernetes はゾーン間でコンテナを分散させるように注意します。このようにして、ゾーンやリージョナルの障害が発生してもアプリは生き続けます。逆にローカルツールを使ってプロセスを再起動する場合、Docker オーケストレータはエラーに気づかず、コンテナを新しいインスタンスやゾーンに再配置するような思慮深い決定を下すことができません。
### コード例 – 中間ツールを使わずに直接 Node.js を呼び出す
Dockerfile
```dockerfile
FROM node:12-slim
# ビルドロジックはこちら
CMD ["node", "index.js"]
```
### アンチパターン コード例 – プロセスマネージャを使用する
Dockerfile
```dockerfile
FROM node:12-slim
# ビルドロジックはこちら
CMD ["pm2-runtime", "indes.js"]
```
================================================
FILE: sections/docker/restart-and-replicate-processes.md
================================================
# 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", "index.js"]
```
================================================
FILE: sections/docker/scan-images.basque.md
================================================
# 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.
### Kode adibidea: eskaneatu Trivvyrekin
Bash
```console
$ sudo apt-get install rpm
$ wget https://github.com/aquasecurity/trivy/releases/download/{TRIVY_VERSION}/trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ sudo dpkg -i trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ trivy image [YOUR_IMAGE_NAME]
```
### Txosten adibidea: Docker eskanerraren emaitzak (Anchoren eskutik)

================================================
FILE: sections/docker/scan-images.french.md
================================================
# 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
### Code Example – Scanning with Trivvy
Bash
```console
$ sudo apt-get install rpm
$ wget https://github.com/aquasecurity/trivy/releases/download/{TRIVY_VERSION}/trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ sudo dpkg -i trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ trivy image [YOUR_IMAGE_NAME]
```
### Report Example – Docker scan results (By Anchore)

================================================
FILE: sections/docker/scan-images.japanese.md
================================================
# プロダクションの前にイメージ全体をスキャンする
### One Paragraph Explainer
脆弱性のためにコードをスキャンすることは価値のある行動ですが、すべての潜在的な脅威をカバーできるものではありません。なぜでしょうか? 理由は、脆弱性は OS レベルにも存在し、アプリケーションは Shell や Tarball、OpenSSL といったバイナリを実行する可能性があるためです。また、脆弱な依存関係がコードスキャンの後に注入される(サプライチェイン攻撃など)可能性があります - そのため、プロダクションの直前に最終的なイメージをスキャンする、といったことが順当です。このアイデアは E2E テストに似ています - 様々な要素を独立にテストした後に、組み合わせられた完成物を最終的にチェックするといったことは価値があります。主に 3 つのスキャナファミリーがあります: 脆弱性 DB をキャッシュしたローカル/CI バイナリ、クラウド上のスキャナサービス、そして docker ビルド中にスキャンするニッチなツールです。1 つめのグループは最も人気で、通常もっとも速いものです - [Trivvy](https://github.com/aquasecurity/trivy) や [Anchore](https://github.com/anchore/anchore)、そして [Snyk](https://support.snyk.io/hc/en-us/articles/360003946897-Container-security-overview) といったツールは一度見てみる価値があります。ほとんどの CI ベンダーはこういったスキャナを組み合わせて利用するためのローカルプラグインを提供しています。注意しておくべきこととして、これらのスキャナは多くの領域をカバーしているため、すべてのスキャンで何かしらの結果が表示されるといったことがあります - 圧倒されてしまうことを避けるため、高い閾値を設定することを検討してください。
### コード例 – Trivvy を用いたスキャン
Bash
```console
$ sudo apt-get install rpm
$ wget https://github.com/aquasecurity/trivy/releases/download/{TRIVY_VERSION}/trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ sudo dpkg -i trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ trivy image [YOUR_IMAGE_NAME]
```
### レポート例 – Docker スキャン結果 (Anchore)

================================================
FILE: sections/docker/scan-images.md
================================================
# 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
### Code Example – Scanning with Trivvy
Bash
```console
$ sudo apt-get install rpm
$ wget https://github.com/aquasecurity/trivy/releases/download/{TRIVY_VERSION}/trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ sudo dpkg -i trivy_{TRIVY_VERSION}_Linux-64bit.deb
$ trivy image [YOUR_IMAGE_NAME]
```
### Report Example – Docker scan results (By Anchore)

================================================
FILE: sections/docker/smaller_base_images.basque.md
================================================
# 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.
================================================
FILE: sections/docker/smaller_base_images.french.md
================================================
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.
================================================
FILE: sections/docker/smaller_base_images.japanese.md
================================================
# 小さな 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 を利用することで最初のプルが速くなると予想されます。ネットワークが遅ければ遅いほど、その差は歴然となります。[...] サイズがより小さくなることのもうひとつの利点は、攻撃される領域が小さくなることです。システム上のパッケージやライブラリの数が少ない場合、問題が発生する可能性は低くなります。
================================================
FILE: sections/docker/smaller_base_images.md
================================================
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.
================================================
FILE: sections/docker/use-cache-for-shorter-build-time.basque.md
================================================
# 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
================================================
FILE: sections/docker/use-cache-for-shorter-build-time.french.md
================================================
# 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
================================================
FILE: sections/docker/use-cache-for-shorter-build-time.japanese.md
================================================
# キャッシュを活用してビルド時間を短縮する
## 一段落説明
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
================================================
FILE: sections/docker/use-cache-for-shorter-build-time.md
================================================
# 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
================================================
FILE: sections/drafts/readme-general-toc-1.md
================================================
# Welcome to Node.js Best Practices
Welcome to the biggest compilation of Node.js best practices. The content below was gathered from all top ranked books and posts and is updated constantly - when you read here rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
## Table of Contents
* [Project Setup Practices (18)](#project-setup-practices)
* [Code Style Practices (11)](#code-style-practices)
* [Error Handling Practices (14)](#error-handling-practices)
* [Going To Production Practices (21)](#going-to-production-practices)
* [Testing Practices (9)](#deployment-practices)
* [Security Practices (8)](#security-practices)
# `Project Setup Practices`
## ✔ 1. Structure your solution by feature ('microservices')
**TL&DR:** The worst large applications pitfal is a huge code base with hundreds of dependencies that slow down they developers as they try to incorporate new features. Partioning into small units ensures that each unit is kept simple and easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
## ✔ 2. Layer your app, keep Express within its boundaries
**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
## ✔ 3. Configure ESLint with node-specific plugins
**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
# `Code Style Practices`
# `Error Handling Practices`
⬆ Return to top
## ✔ Use async-await for async error handling
* **TL;DR:** Handling async errors in callback style is probably the fastest way to hell (a.k.a the pyramid of doom). The best gift you can give to your code is using instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
* **Otherwise:** Node.js callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns
🔗 [**Use async-await for async error handling**](../errorhandling/asyncerrorhandling.md)
# `Going To Production Practices`
# `Deployment Practices`
# `Security Practices`
================================================
FILE: sections/drafts/readme-general-toc-2.md
================================================
# Node.js Best Practices

# Welcome to Node.js Best Practices
Welcome to the biggest compilation of Node.js best practices. The content below was gathered from all top ranked books and posts and is updated constantly - when you read here rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
## Table of Contents
* [Project Setup Practices (18)](#project-setup-practices)
* [Code Style Practices (11) ](#code-style-practices)
* [Error Handling Practices (14) ](#error-handling-practices)
* [Going To Production Practices (21) ](#going-to-production-practices)
* [Testing Practices (9) ](#deployment-practices)
* [Security Practices (8) ](#security-practices)
# `Project Setup Practices`
## ✔ 1. Structure your solution by feature ('microservices')
**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
## ✔ 2. Layer your app, keep Express within its boundaries
**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
## ✔ 3. Configure ESLint with node-specific plugins
**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
# `Code Style Practices`
# `Error Handling Practices`
⬆ Return to top
## ✔ Use async-await for async error handling
**TL;DR:** Handling async errors in callback style is probably the fastest way to hell (a.k.a the pyramid of doom). The best gift you can give to your code is using instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
**Otherwise:** Node.js callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns
🔗 [**Use async-await for async error handling**](../errorhandling/asyncerrorhandling.md)
# `Going To Production Practices`
# `Deployment Practices`
# `Security Practices`
================================================
FILE: sections/drafts/readme-general-toc-3.md
================================================
# Welcome to Node.js Best Practices
Welcome to the biggest compilation of Node.js best practices, based on our check it's also the largest collection on any programming language (more than 53 items). The content below was gathered from all top ranked books and posts and is updated constantly - if you read here you can rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
## Table of Contents
* [Project Setup Practices (18)](#project-setup-practices)
* [Code Style Practices (11) ](#code-style-practices)
* [Error Handling Practices (14) ](#error-handling-practices)
* [Going To Production Practices (21) ](#going-to-production-practices)
* [Testing Practices (9) ](#deployment-practices)
* [Security Practices (8) ](#security-practices)
# `Project Setup Practices`
## ✔ 1. Structure your solution by feature ('microservices')
**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. Partioning into small units ensures that each unit is kept simple and very easy to maintain. This strategy pushes the complexity to the higher level - designing the cross-component interactions.
**Otherwise:** Developing a new feature with a change to few objects demands to evaluate how this changes might affect dozends of dependants and ach deployment becomes a fear.
## ✔ 2. Layer your app, keep Express within its boundaries
**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
**Otherwise:** Application can be accessed by Express only and require to create complex testing mocks
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
## ✔ 3. Configure ESLint with node-specific plugins
**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
# `Code Style Practices`
# `Error Handling Practices`
⬆ Return to top
## ✔ Use async-await for async error handling
**TL;DR:** Handling async errors in callback style is probably the fastest way to hell (a.k.a the pyramid of doom). The best gift you can give to your code is using instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
**Otherwise:** Node.js callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns
🔗 [**Use async-await for async error handling**](../errorhandling/asyncerrorhandling.md)
# `Going To Production Practices`
# `Deployment Practices`
# `Security Practices`
================================================
FILE: sections/drafts/readme-general-toc-4.md
================================================
# Welcome to Node.js Best Practices
Welcome to the biggest compilation of Node.js best practices, based on our check it's also the largest collection on any programming language (more than 53 items). The content below was gathered from all top ranked books and posts and is updated constantly - if you read here you can rest assure that no significant tip slipped away. Feel at home - we love to discuss via PRs, issues or Gitter.
## Table of Contents
* [Project Setup Practices (18)](#project-setup-practices)
* [Code Style Practices (11) ](#code-style-practices)
* [Error Handling Practices (14) ](#error-handling-practices)
* [Going To Production Practices (21) ](#going-to-production-practices)
* [Testing Practices (9) ](#deployment-practices)
* [Security Practices (8) ](#security-practices)
# `Project Setup Practices`
##  1. Structure your solution by feature ('microservices')
**TL&DR:** The worst large applications pitfal is a huge code base where hundreds of dependencies slow down developers as try to incorporate new features. 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*](../errorhandling/asyncerrorhandling.md)
##  2. Layer your app, keep Express within its boundaries
**TL&DR:** It's very common to see Express API passes the express objects (req, res) to business logic and data layers, sometimes even to every function - this makes your application depedant on and accessible by Express only. What if your code should be reached by testing console or CRON job? instead create your own context object with cross-cutting-concern properties like the user roles and inject into other layers, or use 'thread-level variables' libraries like continuation local storage
**Otherwise:** Application can be accesses by Express only and require to create complex testing mocks
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
##  3. Configure ESLint with node-specific plugins
**TL&DR:** Monitoring is a game of finding out issues before our customers do – obviously this should be assigned unprecedented importance. The market is overwhelmed with offers thus consider starting with defining the basic metrics you must follow (my sug
**Otherwise:** You end-up with a blackbox that is hard to reason about, then you start re-writing all logging statements to add additional information
🔗 [**Read More: Structure by feature*](../errorhandling/asyncerrorhandling.md)
## Additional 15 bullets will appear here
# `Code Style Practices`
##  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*](../errorhandling/asyncerrorhandling.md)
##  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*](../errorhandling/asyncerrorhandling.md)
# `Error Handling Practices`
⬆ Return to top
##
Use async-await for async error handling
**TL;DR:** Handling async errors in callback style is probably the fastest way to hell (a.k.a the pyramid of doom). The best gift you can give to your code is using instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
**Otherwise:** Node.js callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns
🔗 [**Use async-await for async error handling**](../errorhandling/asyncerrorhandling.md)
##
Use async-await for async error handling
**TL;DR:** Handling async errors in callback style is probably the fastest way to hell (a.k.a the pyramid of doom). The best gift you can give to your code is using instead a reputable promise library or async-await which provides much compact and familiar code syntax like try-catch
**Otherwise:** Node.js callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns
🔗 [**Use async-await for async error handling**](../errorhandling/asyncerrorhandling.md)
# `Going To Production Practices`
# `Deployment Practices`
# `Security Practices`
================================================
FILE: sections/errorhandling/apmproducts.basque.md
================================================
# 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

================================================
FILE: sections/errorhandling/apmproducts.brazilian-portuguese.md
================================================
# Descubra erros e downtime usando APM
### Explicação em um Parágrafo
Exceção != Erro. O tratamento de erros tradicional pressupõe a existência de Exceção, mas os erros de aplicativo podem vir na forma de caminhos de código lento, tempo de inatividade (downtime) da API, falta de recursos computacionais e muito mais. É aqui que os produtos APM são úteis, pois permitem detectar uma ampla variedade de problemas "enterrados" de forma proativa e com uma configuração mínima. Entre os recursos comuns dos produtos APM estão, por exemplo, alertas quando a API HTTP retorna erros, detecta quando o tempo de resposta da API cai abaixo de um limite, detecção de 'códigos suspeitos', formas de monitorar recursos do servidor, painel de inteligência operacional com métricas de TI e muitos outros recursos úteis. A maioria dos fornecedores oferece um plano gratuito.
### Wikipédia sobre APM
Nos campos de tecnologia da informação e gerenciamento de sistemas, o Application Performance Management (APM) é o monitoramento e gerenciamento de desempenho e disponibilidade de aplicativos de software. O APM se esforça para detectar e diagnosticar problemas complexos de desempenho do aplicativo para manter um nível esperado de serviço. APM é "a tradução de métricas de TI em significado de negócios ([i.e.] value)". Principais produtos e segmentos.
### Entendendo o mercado de APM
Os produtos APM constituem 3 segmentos principais:
1. Monitoramento de sites ou APIs - serviços externos que monitoram constantemente o tempo de atividade e o desempenho por meio de solicitações HTTP. Pode ser configurado em poucos minutos. A seguir estão alguns candidatos selecionados: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/) e [New Relic](https://newrelic.com) / monitoramento de aplicativos)
2. Instrumentação de código - família de produtos que exige a incorporação de um agente no aplicativo para usar recursos como detecção de código lento, estatísticas de exceção, monitoramento de desempenho e muito mais. A seguir estão alguns candidatos selecionados: New Relic, App Dynamics.
3. Painel de inteligência operacional - essa linha de produtos está focada em auxiliar a equipe de operações com métricas e conteúdo de curadoria que ajuda a ficar facilmente a par do desempenho do aplicativo. Isso geralmente envolve a agregação de várias fontes de informações (logs de aplicativos, logs do BD, log de servidores, etc.) e o trabalho de design do painel inicial. A seguir estão alguns candidatos selecionados: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https: //www.zabbix. com /).
### Exemplo: UpTimeRobot.Com - Painel de monitoramento de site

### Example: AppDynamics.Com – monitoramento de ponta a ponta combinado com instrumentação de código

================================================
FILE: sections/errorhandling/apmproducts.chinese.md
================================================
# 使用 APM 产品发现错误和宕机时间
### 一段解释
异常 != 错误。传统的错误处理假定存在异常,但应用程序错误可能以代码路径慢,API停机,缺少计算资源等形式出现。因为APM产品允许使用最小的设置来先前一步地检测各种各样 "深埋" 的问题,这是运用它们方便的地方。APM产品的常见功能包括: 当HTTP API返回错误时报警, 在API响应时间低于某个阈值时能被检测, 觉察到‘code smells’,监视服务器资源,包含IT度量的操作型智能仪表板以及其他许多有用的功能。大多数供应商提供免费方案。
### 关于 APM 的维基百科
在信息技术和系统管理领域, 应用程序性能管理(APM)是对软件应用程序的性能和可用性的监视和管理。APM努力检测和诊断复杂的应用程序性能问题, 以维护预期的服务级别。APM是"将IT度量标准转换为业务含义"
### 了解 APM 市场
APM 产品由3个主要部分构成:
1. 网站或API监控 – 通过HTTP请求不断监视正常运行时间和性能的外部服务。可以在几分钟内安装。以下是少数选定的竞争者: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), 和[New Relic](https://newrelic.com/application-monitoring);
2. 代码检测 – 这类产品需要在应用程序中嵌入代理, 以实现如检测运行缓慢的代码、异常统计、性能监视等功能。以下是少数选定的竞争者: New Relic, App Dynamics;
3. 操作型智能仪表板 – 这些产品系列侧重于为ops团队提供度量和管理内容, 帮助他们轻松地保持应用程序性能维持在最佳状态。这通常涉及聚合多个信息源 (应用程序日志、DB日志、服务器日志等) 和前期仪表板设计工作。以下是少数选定的竞争者: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/);
### 示例: UpTimeRobot.Com – 网站监控仪表板

### 示例: AppDynamics.Com – 与代码检测结合的端到端监视

================================================
FILE: sections/errorhandling/apmproducts.french.md
================================================
# 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

================================================
FILE: sections/errorhandling/apmproducts.japanese.md
================================================
# 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 – コード計測が統合されたエンドツーエンドモニタリング

================================================
FILE: sections/errorhandling/apmproducts.korean.md
================================================
# Discover errors and downtime using APM products
### One Paragraph Explainer
Exception != Error. Traditional error handling assumes the existence of Exception but application errors might come in the form of slow code paths, API downtime, lack of computational resources and more. This is where APM products come in handy as they allow to detect a wide variety of ‘burried’ issues proactively with a minimal setup. Among the common features of APM products are for example alerting when the HTTP API returns errors, detect when the API response time drops below some threshold, detection of ‘code smells’, features to monitor server resources, operational intelligence dashboard with IT metrics and many other useful features. Most vendors offer a free plan.
### Wikipedia about APM
In the fields of information technology and systems management, Application Performance Management (APM) is the monitoring and management of performance and availability of software applications. APM strives to detect and diagnose complex application performance problems to maintain an expected level of service. APM is “the translation of IT metrics into business meaning ([i.e.] value)". Major products and segments.
### Understanding the APM marketplace
APM products constitute 3 major segments:
1. Website or API monitoring – external services that constantly monitor uptime and performance via HTTP requests. Can be set up in few minutes. Following are few selected contenders: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), and [New Relic](https://newrelic.com/application-monitoring)
2. Code instrumentation – product family which requires embedding an agent within the application to use features like slow code detection, exception statistics, performance monitoring and many more. Following are few selected contenders: New Relic, App Dynamics
3. Operational intelligence dashboard – this line of products is focused on facilitating the ops team with metrics and curated content that helps to easily stay on top of application performance. This usually involves aggregating multiple sources of information (application logs, DB logs, servers log, etc) and upfront dashboard design work. Following are few selected contenders: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/)
### Example: UpTimeRobot.Com – Website monitoring dashboard

### Example: AppDynamics.Com – end to end monitoring combined with code instrumentation

================================================
FILE: sections/errorhandling/apmproducts.md
================================================
# Discover errors and downtime using APM products
### One Paragraph Explainer
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
In the fields of information technology and systems management, Application Performance Management (APM) is the monitoring and management of performance and availability of software applications. APM strives to detect and diagnose complex application performance problems to maintain an expected level of service. APM is “the translation of IT metrics into business meaning ([i.e.] value)". Major products and segments.
### Understanding the APM marketplace
APM products constitute 3 major segments:
1. Website or API monitoring – external services that constantly monitor uptime and performance via HTTP requests. Can be set up in few minutes. Following are few selected contenders: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), and [New Relic](https://newrelic.com/application-monitoring)
2. Code instrumentation – product family which requires embedding an agent within the application to use features like slow code detection, exception statistics, performance monitoring and many more. Following are few selected contenders: New Relic, App Dynamics
3. Operational intelligence dashboard – this line of products is focused on facilitating the ops team with metrics and curated content that helps to easily stay on top of application performance. This usually involves aggregating multiple sources of information (application logs, DB logs, servers log, etc) and upfront dashboard design work. Following are few selected contenders: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/)
### Example: UpTimeRobot.Com – Website monitoring dashboard

### Example: AppDynamics.Com – end to end monitoring combined with code instrumentation

================================================
FILE: sections/errorhandling/apmproducts.polish.md
================================================
# 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

================================================
FILE: sections/errorhandling/apmproducts.russian.md
================================================
# Обнаружение ошибок и простоев с использованием продуктов APM
### Объяснение в один абзац
Исключение != Ошибка. Традиционная обработка ошибок предполагает наличие исключения, но ошибки приложения могут проявляться в виде медленных путей кода, времени простоя API, нехватки вычислительных ресурсов и многого другого. Именно здесь продукты APM пригодятся, поскольку они позволяют обнаруживать широкий спектр "скрытых" проблем с минимальной настройкой. Среди общих функций продуктов APM, например, оповещение, когда HTTP API возвращает ошибки, обнаружение, когда время отклика API падает ниже некоторого порога, обнаружение "запахов кода", функции для мониторинга ресурсов сервера, панель оперативной аналитики с IT-метриками и многие другие полезные функции. Большинство поставщиков предлагают бесплатные планы использования.
### Википедия о APM
В области управления информационными технологиями и системами Application Performance Management (APM) - это мониторинг и управление производительностью и доступностью программных приложений. APM стремится обнаруживать и диагностировать сложные проблемы производительности приложений, чтобы поддерживать ожидаемый уровень обслуживания. APM - это "перевод метрик ИТ в бизнес-значение ([то есть] ценность)". Основные продукты и сегменты.
### Понимание рынка APM
Продукты APM составляют 3 основных сегмента:
1. Мониторинг веб-сайтов или API - внешние сервисы, которые постоянно отслеживают время безотказной работы и производительность посредством HTTP-запросов. Можно настроить за несколько минут. Ниже приведены несколько избранных претендентов: [Pingdom](https://www.pingdom.com/), [Uptime Robot](https://uptimerobot.com/), and [New Relic](https://newrelic.com/application-monitoring).
2. Инструментарий кода - семейство продуктов, которое требует встраивания агента в приложение для использования таких функций, как медленное обнаружение кода, статистика исключений, мониторинг производительности и многое другое. Ниже приведены несколько выбранных претендентов: New Relic, App Dynamics.
3. Панель оперативных сведений - эта линейка продуктов направлена на то, чтобы упростить работу оперативной команды с помощью метрик и кураторского контента, которые помогают легко оставаться на вершине производительности приложений. Обычно это включает в себя объединение нескольких источников информации (журналы приложений, журналы БД, журналы серверов и т.д.) и предварительную работу по разработке панели мониторинга. Ниже приведены несколько избранных претендентов: [Datadog](https://www.datadoghq.com/), [Splunk](https://www.splunk.com/), [Zabbix](https://www.zabbix.com/).
### Пример: UpTimeRobot.Com - панель мониторинга сайта

### Пример: AppDynamics.Com – сквозной мониторинг в сочетании с инструментарием кода

================================================
FILE: sections/errorhandling/asyncerrorhandling.basque.md
================================================
# 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…
================================================
FILE: sections/errorhandling/asyncerrorhandling.brazilian-portuguese.md
================================================
# Use Async-Await ou promises para tratamento de erros assíncronos
### Explicação em um Parágrafo
Callbacks não tem uma boa escalabilidade, pois a maioria dos programadores não tem familiaridade com elas. Elas forçam a verificar erros em toda parte, lidar com aninhamento de código desagradável e tornam difícil o entendimento do fluxo de código. Bibliotecas de promise como BlueBird, async, e Q possuem um estilo de código padrão usando RETURN e THROW para controlar o fluxo do programa. Especificamente, eles suportam o estilo favorito de manipulação de erro try-catch que permite liberar o caminho principal do código de lidar com erros em todas as funções.
### Exemplo de código - usando promises para capturar erros
```javascript
doWork()
.then(doWork)
.then(doOtherWork)
.then((result) => doWork)
.catch((error) => {throw error;})
.then(verify);
```
### Exemplo de código anti-padrão - manipulação de erro no estilo callback
```javascript
getData(someParameter, function(err, result) {
if(err !== null) {
// fazer algo como chamar a função de retorno de chamada e passar o erro
getMoreData(a, function(err, result) {
if(err !== null) {
// fazer algo como chamar a função de retorno de chamada e passar o erro
getMoreData(b, function(c) {
getMoreData(d, function(e) {
if(err !== null ) {
// Você entendeu a ideia?
}
})
});
}
});
}
});
```
### Citação de Blog: "Temos um problema com promises"
Do blog pouchdb.com
> ……E, de fato, callbacks fazem algo ainda mais sinistro: eles nos privam do stack, que é algo que costumamos dar como certo em linguagens de programação. Escrever código sem um stack é como dirigir um carro sem pedal de freio: você não percebe o quanto você precisa até tentar usá-lo e não está lá. O ponto principal das promises é nos devolver os fundamentos da linguagem que perdemos quando usamos código assíncrono: return, throw, e o stack. Mas você precisa saber como usar promises corretamente para tirar proveito delas.
### Citação de Blog: "O método das promises é muito mais compacto"
Do blog gosquared.com
> ………O método das promises é muito mais compacto, claro e rápido de escrever. Se um erro ou exceção ocorrer em qualquer uma das operações, ele será tratado pelo único manipulador .catch (). Ter esse único local para lidar com todos os erros significa que você não precisa escrever uma verificação de erros para cada etapa do trabalho.
### Citação de Blog: "Promises são nativas do ES6, podem ser usadas com generators"
Do blog StrongLoop
> ….Callbacks têm um péssimo histórico em manipulação de erros. Promises são melhores. Case com o tratamento de erro interno no Express com promises e reduza significativamente as chances de uma exceção não capturada. Promises são nativas do ES6, podem ser usadas com generators, e propostas do ES7 como async/await através de compiladores como Babel
### Citação de Blog: "Todas aquelas construções de controle de fluxo regulares que você está acostumado estão completamente quebradas"
Do blog Benno’s
> ……Uma das melhores coisas sobre a programação assíncrona baseada em callbacks é que basicamente todas as construções de controle de fluxo regulares que você está acostumado estão completamente quebradas. No entanto, a que eu acho mais quebrada é o tratamento de exceções. Javascript fornece uma construção bastante familiar de try…catch para lidar com exceções. O problema com exceções é que elas fornecem uma ótima maneira de reduzir erros em um stack de chamadas, mas acabam sendo completamente inúteis se o erro acontece em uma pilha diferente…
================================================
FILE: sections/errorhandling/asyncerrorhandling.chinese.md
================================================
# 对于异步的错误处理,请使用 Async-Await 或者 promises
### 一段解释
由于大多数的程序员不熟悉回调,不能很好的掌控回调函数,导致被迫到处检测错误,处理让人不快的代码嵌套和难以理解的代码流程。Promise 的库,比如 BlueBird,async,和 Q 封装了一些代码,使用者可以使用 RETURN 和 THROW 的方式来控制程序的流程。具体来说,就是它们支持最受欢迎的 try-catch 错误处理风格,这使得主流程代码从在每一个方法中处理错误的方式中解放出来。
### 代码示例 – 使用 promises 捕获错误
```javascript
doWork()
.then(doWork)
.then(doOtherWork)
.then((result) => doWork)
.catch((error) => {
throw error;
})
.then(verify);
```
### 代码示例 - 使用 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) {
// 你有什么想法?
}
});
});
}
});
}
});
```
### 博客引用: "我们使用 promise 有一个问题"
摘自博客 pouchdb.com
> ……实际上, 回调会做一些更险恶的事情: 他们剥夺了我们的 stack, 这是我们通常在编程语言中想当然的事情。编写没有堆栈的代码很像驾驶一辆没有刹车踏板的汽车: 你没有意识到你有多么需要它, 直到你伸手去找它, 而它不在那里。promise 的全部目的是让我们回到我们在异步时丢失的语言基础: return,throw 和 stack。但你必须知道如何正确使用 promise, 以便利用他们。
### 博客引用: "promise 方法更加紧凑"
摘自博客 gosquared.com
> ………promise 的方法更紧凑, 更清晰, 写起来更快速。如果在任何 ops 中发生错误或异常,则由单个.catch()处理程序处理。有这个单一的地方来处理所有的错误意味着你不需要为每个阶段的工作写错误检查。
### 博客引用: "原生 ES6 支持 promise,可以和 generator 一起使用"
摘自博客 StrongLoop
> ….回调有一个糟糕的错误处理的报道。promise 更好。将 express 内置的错误处理与 promise 结合起来, 大大降低了 uncaught exception 的几率。原生 ES6 支持 promise, 通过编译器 babel,它可以与 generator,ES7 提议的技术(比如 async/await)一起使用。
### 博客引用: "所有那些您所习惯的常规的流量控制结构, 完全被打破"
摘自博客 Benno’s
> ……关于基于异步、回调编程的最好的事情之一是, 基本上所有那些您习惯的常规流量控制结构, 完全被打破。然而, 我发现最易打破的是处理异常。Javascript 提供了一个相当熟悉的 try...catch 结构来处理异常。异常的问题是, 它们提供了在一个调用堆栈上 short-cutting 错误的很好的方法, 但最终由于不同堆栈上发生的错误导致完全无用…
================================================
FILE: sections/errorhandling/asyncerrorhandling.french.md
================================================
# 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…
================================================
FILE: sections/errorhandling/asyncerrorhandling.japanese.md
================================================
# 非同期エラーハンドリングに 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 構造を提供しています。例外の問題は、それらはコールスタック上でエラーをショートカットする素晴らしい方法を提供する一方で、異なるスタックでエラーが起こったときに全く役に立たずに終わるということです...
================================================
FILE: sections/errorhandling/asyncerrorhandling.korean.md
================================================
# Use Async-Await or promises for async error handling
### One Paragraph Explainer
Callbacks don’t scale well since most programmers are not familiar with them. They force to check errors all over, deal with nasty code nesting and make it difficult to reason about the code flow. Promise libraries like BlueBird, async, and Q pack a standard code style using RETURN and THROW to control the program flow. Specifically, they support the favorite try-catch error handling style which allows freeing the main code path from dealing with errors in every function
### Code Example – using promises to catch errors
```javascript
doWork()
.then(doWork)
.then(doOtherWork)
.then((result) => doWork)
.catch((error) => {throw error;})
.then(verify);
```
### Anti pattern code example – callback style error handling
```javascript
getData(someParameter, function(err, result) {
if(err !== null) {
// do something like calling the given callback function and pass the error
getMoreData(a, function(err, result) {
if(err !== null) {
// do something like calling the given callback function and pass the error
getMoreData(b, function(c) {
getMoreData(d, function(e) {
if(err !== null ) {
// you get the idea?
}
})
});
}
});
}
});
```
### Blog Quote: "We have a problem with promises"
From the blog pouchdb.com
> ……And in fact, callbacks do something even more sinister: they deprive us of the stack, which is something we usually take for granted in programming languages. Writing code without a stack is a lot like driving a car without a brake pedal: you don’t realize how badly you need it until you reach for it and it’s not there. The whole point of promises is to give us back the language fundamentals we lost when we went async: return, throw, and the stack. But you have to know how to use promises correctly in order to take advantage of them.
### Blog Quote: "The promises method is much more compact"
From the blog gosquared.com
> ………The promises method is much more compact, clearer and quicker to write. If an error or exception occurs within any of the ops it is handled by the single .catch() handler. Having this single place to handle all errors means you don’t need to write error checking for each stage of the work.
### Blog Quote: "Promises are native ES6, can be used with generators"
From the blog StrongLoop
> ….Callbacks have a lousy error-handling story. Promises are better. Marry the built-in error handling in Express with promises and significantly lower the chances of an uncaught exception. Promises are native ES6, can be used with generators, and ES7 proposals like async/await through compilers like Babel
### Blog Quote: "All those regular flow control constructs you are used to are completely broken"
From the blog Benno’s
> ……One of the best things about asynchronous, callback-based programming is that basically all those regular flow control constructs you are used to are completely broken. However, the one I find most broken is the handling of exceptions. Javascript provides a fairly familiar try…catch construct for dealing with exceptions. The problem with exceptions is that they provide a great way of short-cutting errors up a call stack, but end up being completely useless if the error happens on a different stack…
================================================
FILE: sections/errorhandling/asyncerrorhandling.md
================================================
# Use Async-Await or promises for async error handling
### One Paragraph Explainer
Callbacks don’t scale well since most programmers are not familiar with them. They force to check errors all over, deal with nasty code nesting and make it difficult to reason about the code flow. Promise libraries like BlueBird, async, and Q pack a standard code style using RETURN and THROW to control the program flow. Specifically, they support the favorite try-catch error handling style which allows freeing the main code path from dealing with errors in every function
### Code Example – using promises to catch errors
```javascript
return functionA()
.then(functionB)
.then(functionC)
.then(functionD)
.catch((err) => logger.error(err))
.then(alwaysExecuteThisFunction)
```
### Code Example - using async/await to catch errors
```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();
}
}
```
### Anti pattern code example – callback style error handling
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?
}
})
});
}
});
}
});
```
### Blog Quote: "We have a problem with promises"
From the blog pouchdb.com
> ……And in fact, callbacks do something even more sinister: they deprive us of the stack, which is something we usually take for granted in programming languages. Writing code without a stack is a lot like driving a car without a brake pedal: you don’t realize how badly you need it until you reach for it and it’s not there. The whole point of promises is to give us back the language fundamentals we lost when we went async: return, throw, and the stack. But you have to know how to use promises correctly in order to take advantage of them.
### Blog Quote: "The promises method is much more compact"
From the blog gosquared.com
> ………The promises method is much more compact, clearer and quicker to write. If an error or exception occurs within any of the ops it is handled by the single .catch() handler. Having this single place to handle all errors means you don’t need to write error checking for each stage of the work.
### Blog Quote: "Promises are native ES6, can be used with generators"
From the blog StrongLoop
> ….Callbacks have a lousy error-handling story. Promises are better. Marry the built-in error handling in Express with promises and significantly lower the chances of an uncaught exception. Promises are native ES6, can be used with generators, and ES7 proposals like async/await through compilers like Babel
### Blog Quote: "All those regular flow control constructs you are used to are completely broken"
From the blog Benno’s
> ……One of the best things about asynchronous, callback-based programming is that basically all those regular flow control constructs you are used to are completely broken. However, the one I find most broken is the handling of exceptions. Javascript provides a fairly familiar try…catch construct for dealing with exceptions. The problem with exceptions is that they provide a great way of short-cutting errors up a call stack, but end up being completely useless if the error happens on a different stack…
================================================
FILE: sections/errorhandling/asyncerrorhandling.polish.md
================================================
# 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…
================================================
FILE: sections/errorhandling/asyncerrorhandling.russian.md
================================================
# Используйте Async-Await или обещания для асинхронной обработки ошибок
### Объяснение в один абзац
Обратные вызовы плохо масштабируются, так как большинство программистов не знакомы с ними. Они заставляют проверять ошибки повсюду, иметь дело с неприятной вложенностью кода и затрудняют анализ потока кода. Библиотеки обещаний (promise), такие как BlueBird, async и Q, упаковывают стандартный стиль кода, используя RETURN и THROW для управления потоком программы. В частности, они поддерживают наилучший стиль обработки ошибок try-catch, который позволяет освободить основной код от обработки ошибок в каждой функции.
### Пример кода – использование обещаний для отлова ошибок
```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();
}
}
```
### Антипаттерн. Обработка ошибок в callback-стиле
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) {
// вы поняли идею?
}
})
});
}
});
}
});
```
### Цитата из блога: "У нас проблема с обещаниями"
Из блога pouchdb.com
> … На самом деле, обратные вызовы делают что-то еще более зловещее: они лишают нас стека, что мы обычно принимаем как должное в языках программирования. Написание кода без стека очень похоже на вождение автомобиля без педали тормоза: вы не понимаете, насколько сильно оно вам нужно, пока не дойдете до него, а его там нет. Весь смысл обещаний состоит в том, чтобы вернуть нам языковые основы, которые мы потеряли при асинхронности: возврат, выброс и стек. Но вы должны знать, как правильно использовать обещания, чтобы воспользоваться ими.
### Цитата блога: "Подход с обещаниями гораздо более компактен"
Из блога gosquared.com
> … Подход с обещаниями гораздо компактнее, понятнее и быстрее для написания. Если ошибка или исключение происходят в любой из операций, они обрабатываются одним обработчиком .catch(). Наличие единого места для обработки всех ошибок означает, что вам не нужно писать проверку ошибок для каждого этапа работы.
### Цитата блога: "Обещания являются нативными в ES6, могут использоваться с генераторами"
Из блога StrongLoop
> … Обратные вызовы имеют паршивую историю обработки ошибок. Обещания лучше. Объедините встроенную обработку ошибок в Express с обещаниями и значительно снизьте вероятность возникновения необработанного исключения. Обещания являются нативными в ES6, могут использоваться с генераторами, а proposals из ES7, такие как async/await, могут использоваться через компиляторы, такие как Babel.
### Цитата из блога: "Все те обычные конструкции управления потоком, к которым вы привыкли, полностью разрушены"
Из блога Бенно
> … Одно из лучших преимуществ асинхронного программирования на основе обратного вызова состоит в том, что в основном все эти обычные конструкции управления потоком, к которым вы привыкли, полностью разрушены. Тем не менее, я считаю, что больше всего разрушения коснулась обработка исключений. Javascript предоставляет довольно знакомую конструкцию try…catch для работы с исключениями. Проблема с исключениями состоит в том, что они обеспечивают отличный способ сокращения ошибок в стеке вызовов, но в конечном итоге оказываются совершенно бесполезными, если ошибка происходит в другом стеке…
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.basque.md
================================================
# 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.
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.brazilian-portuguese.md
================================================
# Capture rejeições de promises não tratadas
### Explicação em um Parágrafo
Normalmente, a maioria do código de um aplicativo Node.js/Express moderno é executado dentro de promises - seja no manipulador .then, em uma função callback ou em um bloco catch. Surpreendentemente, a menos que um desenvolvedor tenha lembrado de adicionar uma cláusula .catch, os erros lançados nesses locais não serão manipulados pelo manipulador de eventos uncaughtException e desaparecerão. Versões recentes do Node adicionaram uma mensagem de aviso quando uma rejeição não tratada aparece, embora isso possa ajudar a perceber quando as coisas dão errado, obviamente não é um método adequado de tratamento de erros. A solução direta é nunca esquecer de incluir cláusulas .catch em cada chamada de cadeia de promessa e redirecionar para um manipulador de erro centralizado. No entanto, criar sua estratégia de tratamento de erros apenas contando com a disciplina do desenvolvedor é um pouco frágil. Conseqüentemente, é altamente recomendado usar uma alternativa elegante e usar o `process.on ('unhandledRejection', callback)` - isso garantirá que qualquer erro prometido, se não for tratado localmente, receba seu tratamento.
### Exemplo de código: esses erros não serão detectados por nenhum manipulador de erros (exceto unhandledRejection)
```javascript
DAL.getUserById(1).then((johnSnow) => {
// esse erro vai simplesmente desaparecer
if(johnSnow.isAlive == false)
throw new Error('ahhhh');
});
```
### Exemplo de código: captura de promises não resolvidas e rejeitadas
```javascript
process.on('unhandledRejection', (reason, p) => {
// Acabei de receber uma rejeição de promise não tratada, já que nós já temos uma alternativa para erros não manipulados (veja abaixo), vamos jogar e deixar ele lidar com isso
throw reason;
});
process.on('uncaughtException', (error) => {
// Acabei de receber um erro que nunca foi tratado, tempo para resolvê-lo e, em seguida, decidir se é necessário reiniciar
errorManagement.handler.handleError(error);
if (!errorManagement.handler.isTrustedError(error))
process.exit(1);
});
```
### Citação de Blog: "Se você pode cometer um erro, em algum momento você vai"
Do blog James Nelson
> Vamos testar sua compreensão. Qual das seguintes opções você espera que imprima um erro no 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’);
});
```
> Eu não sei sobre você, mas minha resposta é que eu esperaria que todos eles imprimissem um erro. No entanto, a realidade é que vários ambientes JavaScript modernos não imprimem erros para nenhum deles. O problema de ser humano é que, se você puder cometer um erro, em algum momento você o fará. Tendo isso em mente, parece óbvio que devemos projetar as coisas de tal maneira que os erros causem o mínimo de dano possível, e isso significa manipular erros por padrão, não descartá-los.
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.chinese.md
================================================
# 捕获未处理的promise rejections
### 一段解释
通常,大部分的现代node.js/express应用代码运行在promise里 – 或者是在.then里处理,一个回调函数中,或者在一个catch块中。令人惊讶的是,除非开发者记得添加.catch语句,在这些地方抛出的错误都不会被uncaughtException事件处理程序来处理,然后消失掉。当未处理的rejection出现,node最近的版本增加了一个警告消息,尽管当事情出错的时候这可能有助于发现问题,但这显然不是一个适当的错误处理方法。简单明了的解决方案是永远不要忘记在每个promise链式调用中添加.catch语句,并重定向到一个集中的错误处理程序。然而,只在开发人员的规程上构建错误处理策略是有些脆弱的。因此,使用一个优雅的回调并订阅到process.on('unhandledrejection',callback)是高度推荐的 – 这将确保任何promise错误,如果不是本地处理,将在这处理。
### 代码示例: 这些错误将不会得到任何错误处理程序捕获(除unhandledrejection)
```javascript
DAL.getUserById(1).then((johnSnow) =>
{
//this error will just vanish
if(johnSnow.isAlive == false)
throw new Error('ahhhh');
});
```
### 代码示例: 捕获 unresolved 和 rejected 的 promise
```javascript
process.on('unhandledRejection', (reason, p) => {
//我刚刚捕获了一个未处理的promise rejection, 因为我们已经有了对于未处理错误的后备的处理机制(见下面), 直接抛出,让它来处理
throw reason;
});
process.on('uncaughtException', (error) => {
//我刚收到一个从未被处理的错误,现在处理它,并决定是否需要重启应用
errorManagement.handler.handleError(error);
if (!errorManagement.handler.isTrustedError(error))
process.exit(1);
});
```
### 博客引用: "如果你犯了错误,在某个时候你就会犯错误。"
摘自 James Nelson 的博客
> 让我们测试一下您的理解。下列哪一项是您期望错误将会打印到控制台的?
```javascript
Promise.resolve(‘promised value’).then(() => {
throw new Error(‘error’);
});
Promise.reject(‘error value’).catch(() => {
throw new Error(‘error’);
});
new Promise((resolve, reject) => {
throw new Error(‘error’);
});
```
> 我不知道您的情况,但我的回答是我希望它们所有都能打印出一个错误。然而,现实是许多现代JavaScript环境不会为其中任何一个打印错误。做为人的问题是,如果你犯了错误,在某个时候你就会犯错误。记住这一点,很显然,我们应该设计这样一种方式,使错误尽可能少创造伤害,这意味着默认地处理错误,而不是丢弃错误。
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.french.md
================================================
# 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.
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.japanese.md
================================================
# 未処理の reject された promise を捕捉する
### 一段落説明
一般的に、モダンな Node.js/Express アプリケーションのコードの多くは、promise の中で実行されます ー .then ハンドラ、コールバック関数、あるいは catch ブロックのいずれかです。驚くべきことに、開発者が忘れずに .catch 節を追加しない限り、promise 内で投げられた例外は uncaughtException イベントハンドラで処理されず、消えてなくなります。最近の Node.js のバージョンでは、未処理の reject があった場合に警告メッセージを表示するようになりましたが、これは何かがうまくいっていないときに気づくのに役立つかもしれませんが、明らかに適切なエラー処理の方法ではありません。単純な解決策は、各 promise チェインコール内に .catch 節を追加することを絶対に忘れず、集中化されたエラーハンドラに処理をリダイレクトすることです。しかしながら、開発者の規律だけでエラー処理の方針を構築することは、いささか脆いものです。したがって、潔いフォールバックを利用すること、そして `process.on('unhandledRejection', callback)` をサブスクライブすることを強く推奨します ー これは、全ての promise エラーが、ローカルで処理されていなくても、確実に処理されることを保証します。
### コード例: これらのエラーはどのエラーハンドラにも捕捉されません(unhandledRejection を除く)
```javascript
DAL.getUserById(1).then((johnSnow) => {
// このエラーはただ消えるだけです
if(johnSnow.isAlive === false)
throw new Error('ahhhh');
});
```
### コード例: 未解決の promise や reject された promise を捕捉する
Javascript
```javascript
process.on('unhandledRejection', (reason, p) => {
// 未処理の promise の reject を捕捉しました
// すでに未処理のエラーのためのフォールバックハンドラ(下記参照)を持っているので、
// 投げて、処理させましょう
throw reason;
});
process.on('uncaughtException', (error) => {
// 未処理のエラーを受信したので、処理を行い、再起動が必要かどうかを判断してください
errorManagement.handler.handleError(error);
if (!errorManagement.handler.isTrustedError(error))
process.exit(1);
});
```
Typescript
```typescript
process.on('unhandledRejection', (reason: string, p: Promise) => {
// 未処理の promise の reject を捕捉しました
// すでに未処理のエラーのためのフォールバックハンドラ(下記参照)を持っているので、
// 投げて、処理させましょう
throw reason;
});
process.on('uncaughtException', (error: Error) => {
// 未処理のエラーを受信したので、処理を行い、再起動が必要かどうかを判断してください
errorManagement.handler.handleError(error);
if (!errorManagement.handler.isTrustedError(error))
process.exit(1);
});
```
### ブログ引用: "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 環境はどのエラーも表示しません。人間であることの問題は、ミスをすることができるなら、いつかミスをするだろう、ということです。このことを念頭に置いていれば、ミスの影響ができるだけ小さくなるように設計をするべきであることが明らかであり、そしてこれはエラーの破棄ではなく、エラー処理をデフォルトで行うこと意味します。
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.korean.md
================================================
# Catch unhandled promise rejections
### One Paragraph Explainer
Typically, most of modern Node.js/Express application code runs within promises – whether within the .then handler, a function callback or in a catch block. Surprisingly, unless a developer remembered to add a .catch clause, errors thrown at these places are not handled by the uncaughtException event-handler and disappear. Recent versions of Node added a warning message when an unhandled rejection pops, though this might help to notice when things go wrong but it's obviously not a proper error handling method. The straightforward solution is to never forget adding .catch clauses within each promise chain call and redirect to a centralized error handler. However, building your error handling strategy only on developer’s discipline is somewhat fragile. Consequently, it’s highly recommended using a graceful fallback and subscribe to `process.on(‘unhandledRejection’, callback)` – this will ensure that any promise error, if not handled locally, will get its treatment.
### Code example: these errors will not get caught by any error handler (except unhandledRejection)
```javascript
DAL.getUserById(1).then((johnSnow) => {
// this error will just vanish
if(johnSnow.isAlive == false)
throw new Error('ahhhh');
});
```
### Code example: Catching unresolved and rejected promises
```javascript
process.on('unhandledRejection', (reason, p) => {
// I just caught an unhandled promise rejection, since we already have fallback handler for unhandled errors (see below), let throw and let him handle that
throw reason;
});
process.on('uncaughtException', (error) => {
// I just received an error that was never handled, time to handle it and then decide whether a restart is needed
errorManagement.handler.handleError(error);
if (!errorManagement.handler.isTrustedError(error))
process.exit(1);
});
```
### Blog Quote: "If you can make a mistake, at some point you will"
From the blog James Nelson
> Let’s test your understanding. Which of the following would you expect to print an error to the console?
```javascript
Promise.resolve(‘promised value’).then(() => {
throw new Error(‘error’);
});
Promise.reject(‘error value’).catch(() => {
throw new Error(‘error’);
});
new Promise((resolve, reject) => {
throw new Error(‘error’);
});
```
> I don’t know about you, but my answer is that I’d expect all of them to print an error. However, the reality is that a number of modern JavaScript environments won’t print errors for any of them.The problem with being human is that if you can make a mistake, at some point you will. Keeping this in mind, it seems obvious that we should design things in such a way that mistakes hurt as little as possible, and that means handling errors by default, not discarding them.
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.md
================================================
# Catch unhandled promise rejections
### One Paragraph Explainer
Typically, most of modern Node.js/Express application code runs within promises – whether within the .then handler, a function callback or in a catch block. Surprisingly, unless a developer remembered to add a .catch clause, errors thrown at these places are not handled by the uncaughtException event-handler and disappear. Recent versions of Node added a warning message when an unhandled rejection pops, though this might help to notice when things go wrong but it's obviously not a proper error handling method. The straightforward solution is to never forget adding .catch clauses within each promise chain call and redirect to a centralized error handler. However, building your error handling strategy only on developer’s discipline is somewhat fragile. Consequently, it’s highly recommended using a graceful fallback and subscribe to `process.on('unhandledRejection', callback)` – this will ensure that any promise error, if not handled locally, will get its treatment.
### Code example: these errors will not get caught by any error handler (except unhandledRejection)
```javascript
DAL.getUserById(1).then((johnSnow) => {
// this error will just vanish
if(johnSnow.isAlive === false)
throw new Error('ahhhh');
});
```
### Code example: Catching unresolved and rejected promises
Javascript
```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);
});
```
### Blog Quote: "If you can make a mistake, at some point you will"
From the blog James Nelson
> Let’s test your understanding. Which of the following would you expect to print an error to the console?
```javascript
Promise.resolve('promised value').then(() => {
throw new Error('error');
});
Promise.reject('error value').catch(() => {
throw new Error('error');
});
new Promise((resolve, reject) => {
throw new Error('error');
});
```
> I don’t know about you, but my answer is that I’d expect all of them to print an error. However, the reality is that a number of modern JavaScript environments won’t print errors for any of them.The problem with being human is that if you can make a mistake, at some point you will. Keeping this in mind, it seems obvious that we should design things in such a way that mistakes hurt as little as possible, and that means handling errors by default, not discarding them.
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.polish.md
================================================
# 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.
================================================
FILE: sections/errorhandling/catchunhandledpromiserejection.russian.md
================================================
# Перехватывайте необработанные отказы от обещаний
### Объяснение в один абзац
Как правило, большая часть современного кода приложения Node.js/Express выполняется в обещаниях - будь то в обработчике .then, обратном вызове функции или в блоке catch. Удивительно, но если разработчик не вспомнил о добавлении предложения .catch, ошибки, возникающие в этих местах, не обрабатываются обработчиком событий uncaughtException и исчезают. Недавние версии Node добавляли предупреждающее сообщение, когда появляется необработанный отказ, хотя это могло помочь заметить, когда что-то пойдет не так, но это явно не правильный метод обработки ошибок. Простое решение состоит в том, чтобы никогда не забывать добавлять предложения .catch в каждый вызов цепочки обещаний и перенаправлять их в централизованный обработчик ошибок. Однако построение вашей стратегии обработки ошибок только на основе дисциплины разработчика несколько хрупко. Следовательно, настоятельно рекомендуется использовать изящный запасной вариант и подписаться на `process.on('unhandledRejection', callback)` - это гарантирует, что любая ошибка обещания, если она не обрабатывается локально, будет обработана.
### Пример кода: эти ошибки не будут обнаружены никаким обработчиком ошибок (кроме unhandledRejection)
```javascript
DAL.getUserById(1).then((johnSnow) => {
// this error will just vanish
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
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);
});
```
### Цитата в блоге: "Если вы можете сделать ошибку, в какой-то момент вы это сделаете"
Из блога Джеймса Нельсона
> Давайте проверим ваше понимание. Что из следующего вы ожидаете увидеть как ошибку в консоли?
```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 не будет печатать ошибки ни для одной из них. Проблема с тем, чтобы быть человеком, состоит в том, что если вы можете ошибиться, в какой-то момент вы это сделаете. Имея это в виду, кажется очевидным, что мы должны проектировать вещи таким образом, чтобы ошибки причиняли как можно меньше вреда, а это означает, что по умолчанию ошибки обрабатывают, а не отбрасывают их.
================================================
FILE: sections/errorhandling/centralizedhandling.basque.md
================================================
# 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…
================================================
FILE: sections/errorhandling/centralizedhandling.brazilian-portuguese.md
================================================
# Lide com erros de forma centralizada. Não dentro de middlewares
### Explicação em um Parágrafo
Sem um objeto dedicado para o tratamento de erros, maiores são as chances de erros importantes se esconderem sob o radar devido a manuseio inadequado. O objeto manipulador de erros é responsável por tornar o erro visível, por exemplo, gravando em um logger bem formatado, enviando eventos para algum produto de monitoramento, como [Sentry](https://sentry.io/), [Rollbar](https://rollbar.com/), ou [Raygun](https://raygun.com/). A maioria dos frameworks web, como [Express](http://expressjs.com/en/guide/error-handling.html#writing-error-handlers), fornece um mecanismo de manipulação de erro através de um middleware. Um fluxo típico de manipulação de erros pode ser: Algum módulo lança um erro -> o roteador da API detecta o erro -> ele propaga o erro para o middleware (por exemplo, Express, KOA) que é responsável por detectar erros -> um manipulador de erro centralizado é chamado -> o middleware está sendo informado se erro é um erro não confiável (não operacional) para que ele possa reiniciar o aplicativo graciosamente. Note que é uma prática comum, mas errada, lidar com erros no middleware do Express - isso não cobre erros que são lançados em interfaces que não sejam da web.
### Exemplo de código - um fluxo de erro típico
```javascript
// camada de acesso a dados, não lidamos com erros aqui
DB.addDocument(newCustomer, (error, result) => {
if (error)
throw new Error("explicação melhor do erro aqui", other useful parameters)
});
// Código de rota da API, detectamos erros de sincronos e assíncronos e encaminhamos para o middleware
try {
customerService.addNew(req.body).then((result) => {
res.status(200).json(result);
}).catch((error) => {
next(error)
});
}
catch (error) {
next(error);
}
// Erro ao manipular o middleware, delegamos a manipulação ao manipulador de erro centralizado
app.use(async (err, req, res, next) => {
const isOperationalError = await errorHandler.handleError(err);
if (!isOperationalError) {
next(err);
}
});
```
### Exemplo de código - manipulando erros dentro de um objeto dedicado
```javascript
module.exports.handler = new errorHandler();
function errorHandler() {
this.handleError = async function(err) {
await logger.logError(err);
await sendMailToAdminIfCritical;
await saveInOpsQueueIfCritical;
await determineIfOperationalError;
};
}
```
### Exemplo de código - Anti-padrão: manipulando erros dentro do middleware
```javascript
// middleware lida com o erro diretamente, quem vai lidar com tarefas Cron e erros de teste?
app.use((err, req, res, next) => {
logger.logError(err);
if (err.severity == errors.high) {
mailer.sendMail(configuration.adminMail, 'Erro crítico ocorreu', err);
}
if (!err.isOperational) {
next(err);
}
});
```
### Citação de Blog: "Às vezes, níveis mais baixos não podem fazer nada útil, exceto propagar o erro para quem o chamou"
Do blog Joyent, classificado como 1 para as palavras-chave “Node.js error handling”
> …Você pode acabar lidando com o mesmo erro em vários níveis do stack. Isso acontece quando os níveis mais baixos não podem fazer nada útil, exceto propagar o erro para quem o chamou, o qual propaga o erro para quem o chamou e assim por diante. Geralmente, somente quem chama sabe qual é a resposta apropriada, seja para repetir a operação, relatar um erro ao usuário ou outra coisa. Mas isso não significa que você deve tentar reportar todos os erros para uma única callback de nível superior, porque a própria callback não pode saber em que contexto o erro ocorreu…
### Citação de Blog: "Lidar com cada erro individualmente resultaria em uma enorme duplicação"
Do blog JS Recipes classificado como 17 para as palavras-chave “Node.js error handling”
> ……Apenas no controlador do api.js da Hackathon Starter, existem mais de 79 ocorrências de objetos de erro. Lidar com cada erro individualmente resultaria em uma enorme quantidade de duplicação de código. A próxima melhor opção que você tem é delegar toda a lógica de tratamento de erros para um middleware do Express…
### Citação de Blog: "Erros de HTTP não têm lugar na sua base de código"
Do blog Daily JS classificado como 14 para as palavras-chave “Node.js error handling”
> ……Você deve definir propriedades úteis em objetos de erro, mas use essas propriedades de forma consistente. E não cruze os fluxos: Erros de HTTP não têm lugar na sua base de código. Ou para desenvolvedores de navegador, os erros do Ajax têm um lugar no código que fala com o servidor, mas não no código que processa os templates Mustache…
================================================
FILE: sections/errorhandling/centralizedhandling.chinese.md
================================================
# 集中处理错误,通过但不是在中间件里处理错误
### 一段解释
如果没有一个专用的错误处理对象,那么由于操作不当,在雷达下重要错误被隐藏的可能性就会更大。错误处理对象负责使错误可见,例如通过写入一个格式化良好的logger,通过电子邮件将事件发送到某个监控产品或管理员。一个典型的错误处理流程可能是:一些模块抛出一个错误 -> API路由器捕获错误 -> 它传播错误给负责捕获错误的中间件(如Express,KOA)-> 集中式错误处理程序被调用 -> 中间件正在被告之这个错误是否是一个不可信的错误(不是操作型错误),这样可以优雅的重新启动应用程序。注意,在Express中间件中处理错误是一种常见但又错误的做法,这样做不会覆盖在非Web接口中抛出的错误。
### 代码示例 – 一个典型错误流
```javascript
//DAL层, 在这里我们不处理错误
DB.addDocument(newCustomer, (error, result) => {
if (error)
throw new Error("Great error explanation comes here", other useful parameters)
});
//API路由代码, 我们同时捕获异步和同步错误,并转到中间件
try {
customerService.addNew(req.body).then(function (result) {
res.status(200).json(result);
}).catch((error) => {
next(error)
});
}
catch (error) {
next(error);
}
//错误处理中间件,我们委托集中式错误处理程序处理错误
app.use(function (err, req, res, next) {
errorHandler.handleError(err).then((isOperationalError) => {
if (!isOperationalError)
next(err);
});
});
```
### 代码示例 – 在一个专门的对象里面处理错误
```javascript
module.exports.handler = new errorHandler();
function errorHandler() {
this.handleError = function (err) {
return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
}
}
```
### 代码示例 – 反模式:在中间件内处理错误
```javascript
//中间件直接处理错误,那谁将处理Cron任务和测试错误呢?
app.use(function (err, req, res, next) {
logger.logError(err);
if(err.severity == errors.high)
mailer.sendMail(configuration.adminMail, "Critical error occured", err);
if(!err.isOperational)
next(err);
});
```
### 博客引用: "有时较低的级别不能做任何有用的事情, 除非将错误传播给他们的调用者"
摘自博客 Joyent, 对应关键字 “Node.JS error handling” 排名第一
> …您可能会在stack的多个级别上处理相同的错误。这发生在当较低级别不能执行任何有用的操作,除了将错误传播给它们的调用方, 从而将错误传播到其调用方, 等等。通常, 只有top-level调用方知道适当的响应是什么, 无论是重试操作、向用户报告错误还是其他事情。但这并不意味着您应该尝试将所有错误报告给单个top-level回调, 因为该回调本身无法知道错误发生在什么上下文中…
### 博客引用: "单独处理每个错误将导致大量的重复"
摘自博客 JS Recipes, 对应关键字 “Node.JS error handling” 排名17
> ……仅仅在Hackathon启动api.js控制器中, 有超过79处重复的错误对象。单独处理每个错误将导致大量的代码重复。您可以做的下一个最好的事情是将所有错误处理逻辑委派给一个express中间件…
### 博客引用: "HTTP错误不会在数据库代码中出现"
摘自博客 Daily JS, 对应关键字 “Node.JS error handling” 排名14
> ……您应该在error对象中设置有用的属性, 但使用此类属性时应保持一致。而且, 不要越过流: HTTP错误不会在数据库代码中出现。或者对于浏览器开发人员来说, Ajax 错误在与服务器交互的代码中有一席之地, 而不是处理Mustache模板的代码…
================================================
FILE: sections/errorhandling/centralizedhandling.french.md
================================================
# 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…
================================================
FILE: sections/errorhandling/centralizedhandling.japanese.md
================================================
# エラー処理を一元化し、ミドウェア内で処理をしない
### 一段落説明
エラー処理専用のオブジェクトがないと、不適切な処理が原因となって重要なエラーが発見されない可能性が高くなります。エラー処理オブジェクトは、エラーを可視化する責任をもちます。例えば、整形されたロガーに書き込んだり、[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 テンプレートを処理するコードの中には無いのです。…
================================================
FILE: sections/errorhandling/centralizedhandling.korean.md
================================================
# 에러를 미들웨어에서 처리하지 말고 한군데에서 집중적으로 처리해라
### 한문단 설명
에러 처리를 위한 전용 객체가 없으면 잘못된 처리로 인해 중요한 에러가 숨어있을 가능성이 더 커진다. 예를 들어, 에러 처리 객체는 [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 미들웨어 내에서 오류를 처리하는 것이 일반적이지만 잘못된 관습이다 – 이렇게 하면 웹 이외의 인터페이스에 발생하는 에러를 해결 할 수 없다.
### 코드 예시 – 일반적인 에러 흐름
```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);
}
});
```
### 코드 예시 – 전용 객체에서 에러 처리
```javascript
module.exports.handler = new errorHandler();
function errorHandler() {
this.handleError = async function(err) {
await logger.logError(err);
await sendMailToAdminIfCritical;
await saveInOpsQueueIfCritical;
await determineIfOperationalError;
};
}
```
### 코드 예시 – 좋지않은 패턴: 미들웨어에서 에러 처리
```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);
}
});
```
### 블로그 인용: "때로 하위 레벨은 호출자에게 전달하는 것 외에 쓸모있는 일을 할 수 없다"
Joyent 블로그에서 "Node.js 에러 처리" 키워드 1위에 위치했다
> …스택의 여러 레벨에서 동일한 오류를 처리할 수 있다. 이는 하위 레벨 수준에서 에러를 호출자에게 전달하는 것 외에는 쓸모있는 작업을 수행 할 수 없을 때 발생한다. 종종, 최상위 레벨 호출자만이 적절한 응답, 작업을 재시도할지, 사용자에게 에러를 보고할지, 또는 다른 작업을 수행할지를 알 수 있다. 그러나 모든 에러를 최상위 레벨에 보고해야 한다는 의미는 아니다, 왜냐하면 콜백 자체는 어떤 맥락에서 에러가 발생했는지 알 수 없기 때문이다…
### 블로그 인용: "각 에러를 개별적으로 처리하면 엄청난 중복이 발생할 수 있다"
JS Recipes 블로그에서 "Node.js 에러 처리" 키워드 17위에 위치했다
> ……Hackathon Starter api.js 컨트롤러에서만 79개 이상의 오류 객체가 있다. 각 에러를 개별적으로 처리하면 엄청난 중복이 발생할 수 있다. 다음으로 가장 좋은 방법은 모든 에러 처리 로직을 Express 미들웨어에 위임하는 것이다…
### 블로그 인용: "HTTP 에러는 데이터베이스 코드에 포함되지 않는다"
Daily JS 블로그에서 "Node.js 에러 처리" 키워드 14위에 위치했다
> ……에러 객체에 유용한 속성을 설정해야 하지만, 이런 속성은 일관되게 사용해야 한다. 그리고, 스트림을 넘지 마라: HTTP 에러는 데이터베이스 코드에 포함되지 않는다. 또한 브라우저 개발자의 경우, Ajax 에러는 서버와 통신하는 코드가 있지만, 머스테치(Mustache) 템플릿을 처리하는 코드는 아니다…
================================================
FILE: sections/errorhandling/centralizedhandling.md
================================================
# Handle errors centrally. Not within middlewares
### One Paragraph Explainer
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
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) => {
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);
});
```
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) => {
await errorHandler.handleError(err, res);
});
process.on("uncaughtException", (error:Error) => {
errorHandler.handleError(error);
});
process.on("unhandledRejection", (reason) => {
errorHandler.handleError(reason);
});
```
### Code example – handling errors within a dedicated object
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();
```
### Code Example – Anti Pattern: handling errors within the middleware
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);
}
});
```
### 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”
> …You may end up handling the same error at several levels of the stack. This happens when lower levels can’t do anything useful except propagate the error to their caller, which propagates the error to its caller, and so on. Often, only the top-level caller knows what the appropriate response is, whether that’s to retry the operation, report an error to the user, or something else. But that doesn’t mean you should try to report all errors to a single top-level callback, because that callback itself can’t know in what context the error occurred…
### Blog Quote: "Handling each err individually would result in tremendous duplication"
From the blog JS Recipes ranked 17 for the keywords “Node.js error handling”
> ……In Hackathon Starter api.js controller alone, there are over 79 occurrences of error objects. Handling each err individually would result in a tremendous amount of code duplication. The next best thing you can do is to delegate all error handling logic to an Express middleware…
### Blog Quote: "HTTP errors have no place in your database code"
From the blog Daily JS ranked 14 for the keywords “Node.js error handling”
> ……You should set useful properties in error objects, but use such properties consistently. And, don’t cross the streams: HTTP errors have no place in your database code. Or for browser developers, Ajax errors have a place in the code that talks to the server, but not code that processes Mustache templates…
================================================
FILE: sections/errorhandling/centralizedhandling.polish.md
================================================
# 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…
================================================
FILE: sections/errorhandling/centralizedhandling.russian.md
================================================
# Обрабатывайте ошибки централизованно. Не в промежуточных слоях
### Объяснение в один абзац
Без выделенного объекта для обработки ошибок есть больше шансов на то, что ошибки потеряются с радара из-за их неправильной обработки. Объект обработчика ошибок отвечает за отображение ошибки, например, путем записи в логгер, отправки событий в сервисы мониторинга, такие как [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-слой, мы не обрабатываем ошибки тут
DB.addDocument(newCustomer, (error, 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) => {
res.status(200).json(result);
}).catch((error) => {
next(error)
});
}
catch (error) {
next(error);
}
// Обработка ошибок в middleware, мы делегируем обработку централизованному обработчику ошибок
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-маршрутизатора, мы обрабатываем как 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 (err) {
await logger.logError(err);
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, обрабатывающий ошибки напрямую.
// А кто будет обрабатывать ошибки возникшие в 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
// 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"
> … Вы можете обработать одну и ту же ошибку на нескольких слоях. Это происходит, когда нижние слои не могут сделать ничего полезного, кроме как передать ошибку вызывающему слою, который передаст ошибку своему вызывающему слою, и так далее. Зачастую только самый верхний слой знает, что является подходящим действием на ошибку: попытка повторить операцию, сообщить пользователю об ошибке или что-то еще. Но это не значит, что вы должны пытаться сообщать обо всех ошибках в один верхний callback, потому что этот callback не может знать, в каком контексте произошла ошибка …
### Цитата из блога: "Обработка каждой ошибки по отдельности приведет к ужасному дублированию"
Из блога JS Recipes, занимающего 17 место по ключевым словам "Обработка ошибок Node.js"
> … Только в контроллере api.js Hackathon Starter имеется более 79 объектов ошибок. Обработка каждой ошибки в отдельности привела бы к ужасному дублированию кода. Следующее, что вы можете сделать, это делегировать всю логику обработки ошибок в middleware Express …
### Цитата из блога: "В коде вашей базы данных нет места ошибкам HTTP"
Из блога Daily JS, занимающем 14 место по ключевым словам "Обработка ошибок Node.js"
> … Вы должны добавлять полезные свойства в объекты ошибок, но использовать их согласовано. И не пересекайте логику: в коде вашей базы данных нет места ошибкам HTTP. Или, например, для frontend-разработчиков, ошибки Ajax имеют место в коде, который общается с сервером, но не в коде, который работает с шаблонами Mustache …
================================================
FILE: sections/errorhandling/documentingusingswagger.basque.md
================================================
# 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

================================================
FILE: sections/errorhandling/documentingusingswagger.brazilian-portuguese.md
================================================
# Documente erros de API usando o Swagger ou GraphQL
### Explicação em um Parágrafo
As APIs REST retornam resultados usando códigos de status HTTP. É absolutamente necessário que o usuário da API esteja ciente não apenas sobre o esquema da API, mas também sobre possíveis erros – o chamador pode, então, pegar um erro e, com muito tato, lidar com ele. Por exemplo, a documentação da API pode indicar antecipadamente que o status HTTP 409 é retornado quando o nome do cliente já existir (supondo que a API registre novos usuários) para que o responsável pela chamada possa renderizar a melhor esperiência de usuário para a situação determinada. O Swagger é um padrão que define o esquema da documentação da API, oferecendo um ecossistema de ferramentas que permitem criar documentação facilmente on-line, veja as telas de impressão abaixo.
Se você já adotou o GraphQL para seus endpoints da API, seu esquema já contém garantias estritas de quais erros devem ser parecidos ([descritos na especificação](https://facebook.github.io/graphql/June2018/#sec-Errors)) e como eles devem ser manipulados por suas ferramentas do lado do cliente. Além disso, você também pode complementá-los com documentação baseada em comentários.
### Exemplo de Erro no GraphQL
> Esse exemplo usa [SWAPI](https://graphql.org/swapi-graphql), o API de Star Wars.
```graphql
# deve falhar porque o id não é válido
{
film(id: "1ZmlsbXM6MQ==") {
title
}
}
```
```json
{
"errors": [
{
"message": "Nenhuma entrada no cache local para https://swapi.co/api/films/.../",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"film"
]
}
],
"data": {
"film": null
}
}
```
### Citação de Blog: "Você tem que dizer aos seus chamadores que erros podem acontecer"
Do blog Joyent, classificado como 1 para as palavras-chave “Node.js logging”
> Já falamos sobre como lidar com erros, mas quando você está escrevendo uma nova função, como você entrega erros ao código que chamou sua função? …Se você não sabe quais erros podem acontecer ou não sabe o que eles significam, seu programa não pode estar correto, exceto por acidente. Então, se você está escrevendo uma nova função, precisa dizer a seus chamadores quais erros podem acontecer e o que eles significam…
### Ferramenta Útil: Swagger Criação de Documentação Online

================================================
FILE: sections/errorhandling/documentingusingswagger.chinese.md
================================================
# 使用Swagger对API错误文档化
### 一段解释
REST API使用HTTP代码返回结果, API用户不仅绝对需要了解API schema, 而且还要注意潜在错误 – 调用方可能会捕获错误并巧妙地处理它。例如, 您的api文档可能提前指出, 当客户名称已经存在时, HTTP状态409将返回 (假设api注册新用户), 因此调用方可以相应地呈现给定情况下的最佳UX。Swagger是一个标准, 它定义了 API 文档的schema, 提供了一个生态系统的工具, 允许在线轻松创建文档, 请参阅下面的打印屏幕。
### 博客引用: "您必须告诉您的调用者什么错误可能发生"
摘自博客 Joyent, 对于关键字 “Node.JS logging” , 排名第一
> 我们已经讨论了如何处理错误, 但是在编写新函数时, 如何将错误传递给调用您的函数的代码?
...如果你不知道会发生什么错误或者不知道他们的意思, 那么你的程序就不可能是正确的, 除非是偶然的。所以, 如果你正在写一个新的函数, 你必须告诉你的调用者什么错误可以发生, 它们的意思是什么…
### 有用的工具: Swagger 在线文档创建工具

================================================
FILE: sections/errorhandling/documentingusingswagger.french.md
================================================
# 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

================================================
FILE: sections/errorhandling/documentingusingswagger.japanese.md
================================================
# 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

================================================
FILE: sections/errorhandling/documentingusingswagger.korean.md
================================================
# Document API errors using 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
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.
### GraphQL Error Example
> This example uses [SWAPI](https://graphql.org/swapi-graphql), the Star Wars API.
```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
}
}
```
### Blog Quote: "You have to tell your callers what errors can happen"
From the blog Joyent, ranked 1 for the keywords “Node.js logging”
> We’ve talked about how to handle errors, but when you’re writing a new function, how do you deliver errors to the code that called your function? …If you don’t know what errors can happen or don’t know what they mean, then your program cannot be correct except by accident. So if you’re writing a new function, you have to tell your callers what errors can happen and what they mean…
### Useful Tool: Swagger Online Documentation Creator

================================================
FILE: sections/errorhandling/documentingusingswagger.md
================================================
# 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. 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.
### GraphQL Error Example
> This example uses [SWAPI](https://graphql.org/swapi-graphql), the Star Wars API.
```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
}
}
```
### Blog Quote: "You have to tell your callers what errors can happen"
From the blog Joyent, ranked 1 for the keywords “Node.js logging”
> We’ve talked about how to handle errors, but when you’re writing a new function, how do you deliver errors to the code that called your function? …If you don’t know what errors can happen or don’t know what they mean, then your program cannot be correct except by accident. So if you’re writing a new function, you have to tell your callers what errors can happen and what they mean…
### Useful Tool: Swagger Online Documentation Creator

================================================
FILE: sections/errorhandling/documentingusingswagger.polish.md
================================================
# 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

================================================
FILE: sections/errorhandling/documentingusingswagger.russian.md
================================================
# Документироваие ошибок API при использовании Swagger или GraphQL
### Объяснение в один абзац
API-интерфейсы REST возвращают результаты с использованием кодов состояния HTTP, поэтому пользователь API должен знать не только о схеме API, но и о возможных ошибках - вызывающий может затем поймать ошибку и тактично ее обработать. Например, в документации по API может быть заранее указано, что HTTP-статус 409 возвращается, когда имя клиента уже существует (при условии, что API регистрирует новых пользователей), поэтому вызывающая сторона может соответственно отобразить лучший UX для данной ситуации. Swagger - это стандарт, определяющий схему документации API, предлагающую эко-систему инструментов, позволяющую легко создавать документацию в Интернете, см. экраны печати ниже.
Если вы уже приняли GraphQL для своих конечных точек API, ваша схема уже содержит строгие гарантии того, как должны выглядеть ошибки ([описано в спецификации](https://facebook.github.io/graphql/June2018/#sec-Errors )) и как они должны обрабатываться вашими инструментами на стороне клиента. Кроме того, вы также можете дополнить их документацией на основе комментариев.
### Пример ошибки GraphQL
> В этом примере используется [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
}
}
```
### Цитата блога: "Вы должны сообщить своим абонентам, какие ошибки могут произойти"
Из блога Joyent, занял 1 место по ключевым словам "Node.js logging"
> Мы говорили о том, как обрабатывать ошибки, но когда вы пишете новую функцию, как вы доставляете ошибки в код, вызвавший вашу функцию? … Если вы не знаете, какие ошибки могут произойти, или не знаете, что они означают, то ваша программа может быть исправлена только случайно. Поэтому, если вы пишете новую функцию, вы должны сообщить своим абонентам, какие ошибки могут произойти и что они означают …
### Полезный инструмент: Swagger Online Documentation Creator

================================================
FILE: sections/errorhandling/failfast.basque.md
================================================
# 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
================================================
FILE: sections/errorhandling/failfast.brazilian-portuguese.md
================================================
# Falhe rápido, valide argumentos usando uma biblioteca dedicada
### Explicação em um Parágrafo
Nós todos sabemos como verificar argumentos e falhar rapidamente é importante para evitar bugs ocultos (veja exemplo de código antipadrão abaixo). Se não, leia sobre programação explícita e programação defensiva. Na realidade, tendemos a evitá-lo devido ao incômodo de codificá-lo (por exemplo, pensar em validar o objeto JSON hierárquico com campos como e-mail e datas) - bibliotecas como o Joi e o Validator tornam esta tediosa tarefa muito fácil.
### Wikipédia: Programação Defensiva
A programação defensiva é uma abordagem para melhorar o software e o código-fonte, em termos de qualidade geral - reduzindo o número de bugs e problemas de software. Tornando o código-fonte compreensível - o código-fonte deve ser legível e compreensível, de modo que seja aprovado em uma auditoria de código. Fazer com que o software se comporte de maneira previsível, apesar de entradas inesperadas ou ações do usuário.
### Exemplo de código: validando uma entrada JSON complexa usando "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) {
// afirmações vêm em primeiro lugar
Joi.assert(newMember, memberSchema); //lança se a validação falhar
// outra lógica aqui
}
```
### Anti-padrão: nenhuma validação gera erros desagradáveis
```javascript
// Se o desconto for positivo, vamos redirecionar o usuário para imprimir seus cupons de desconto
function redirectToPrintDiscount(httpResponse, member, discount) {
if (discount != 0) {
httpResponse.redirect(`/discountPrintView/${member.id}`);
}
}
redirectToPrintDiscount(httpResponse, someMember);
// esqueci de passar o desconto de parâmetro, por que diabos o usuário foi redirecionado para a tela de desconto?
```
### Citação de Blog: "Você deve lançar esses erros imediatamente"
Do blog: Joyent
> Um caso degenerado é quando alguém chama uma função assíncrona, mas não passa uma callback. Você deve lançar esses erros imediatamente, pois o programa está quebrado e a melhor chance de encontrar erros envolve obter pelo menos um rastreamento de stack e, idealmente, um arquivo principal no ponto do erro. Para fazer isso, recomendamos a validação dos tipos de todos os argumentos no início da função.
================================================
FILE: sections/errorhandling/failfast.chinese.md
================================================
# 快速报错,使用专用库验证参数
### 一段解释
我们都知道如何检查参数和快速报错对于避免隐藏的错误很重要(见下面的反模式代码示例)。如果没有,请阅读显式编程和防御性编程。在现实中,由于对其编码是件恼人的事情(比如考虑验证分层的JSON对象,它包含像email和日期这样的字段),我们倾向于避免做这样的事情 – 像Joi这样的库和验证器轻而易举的处理这个乏味的任务。
### 维基百科: 防御性编程
防御性编程是一种改进软件和源代码的方法, 在以下方面: 一般质量 – 减少软件 bug 和问题的数量。使源代码可理解 – 源代码应该是可读的和可理解的, 以便在代码审核中得到批准。尽管会有意外输入或用户操作, 但使软件的行为具有可预知的方式。
### 代码示例: 使用‘Joi’验证复杂的JSON输入
```javascript
var memberSchema = Joi.object().keys({
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
birthyear: Joi.number().integer().min(1900).max(2013),
email: Joi.string().email()
});
function addNewMember(newMember)
{
//assertions come first
Joi.assert(newMember, memberSchema); //throws if validation fails
//other logic here
}
```
### 反模式: 没有验证会产生令人讨厌的错误
```javascript
//假如折扣为正,重定向用户去打印他的折扣优惠劵
function redirectToPrintDiscount(httpResponse, member, discount)
{
if(discount != 0)
httpResponse.redirect(`/discountPrintView/${member.id}`);
}
redirectToPrintDiscount(httpResponse, someMember);
//忘记传递参数discount, 为什么用户被重定向到折扣页面?
```
### 博客引用: "您应该立即抛出这些错误"
摘自博客: Joyent
> 一个退化情况是有人调用一个异步函数但没有传递一个回调方法。你应该立即抛出这些错误, 因为程序有了错误, 最好的调试它的时机包括,获得至少一个stack trace, 和理想情况下,核心文件里错误的点。为此, 我们建议在函数开始时验证所有参数的类型。
================================================
FILE: sections/errorhandling/failfast.french.md
================================================
# É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.
================================================
FILE: sections/errorhandling/failfast.japanese.md
================================================
# 専用のライブラリを利用して引数の検証を高速に行う
### 一段落説明
隠れたバグを避けるためには、引数をチェックすること、そして高速に失敗することが重要であると誰もが知っています(下記のアンチパターンコード例を参照)。もし知らないのであれば、明示的プログラミングと防御的プログラミングについて読んでみてください。実際には、コーディングをするのが面倒なので避けがちですが(例えば、メールアドレスや日時のようなフィールドを持つ階層的な 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より
> 悪化したケースとして、非同期関数を呼び出したもののコールバックを渡さなかった場合があります。プログラムは壊れていますし、デバッグに最適なのは少なくともスタックトレースを取得、理想的にはエラーが発生した地点のコアファイルを取得することなので、このようなエラーは直ちに投げるべきです。これを行うために、関数の開始時にすべての引数の型を検証することをおすすめします。
================================================
FILE: sections/errorhandling/failfast.korean.md
================================================
# Fail fast, validate arguments using a dedicated library
### One Paragraph Explainer
We all know how checking arguments and failing fast is important to avoid hidden bugs (see anti-pattern code example below). If not, read about explicit programming and defensive programming. In reality, we tend to avoid it due to the annoyance of coding it (e.g. think of validating hierarchical JSON object with fields like email and dates) – libraries like Joi and Validator turn this tedious task into a breeze.
### Wikipedia: Defensive Programming
Defensive programming is an approach to improve software and source code, in terms of General quality – reducing the number of software bugs and problems. Making the source code comprehensible – the source code should be readable and understandable so it is approved in a code audit. Making the software behave in a predictable manner despite unexpected inputs or user actions.
### Code example: validating complex JSON input using ‘Joi’
```javascript
var memberSchema = Joi.object().keys({
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
birthyear: Joi.number().integer().min(1900).max(2013),
email: Joi.string().email()
});
function addNewMember(newMember) {
// assertions come first
Joi.assert(newMember, memberSchema); //throws if validation fails
// other logic here
}
```
### Anti-pattern: no validation yields nasty bugs
```javascript
// if the discount is positive let's then redirect the user to 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?
```
### Blog Quote: "You should throw these errors immediately"
From the blog: Joyent
> A degenerate case is where someone calls an asynchronous function but doesn’t pass a callback. You should throw these errors immediately since the program is broken and the best chance of debugging it involves getting at least a stack trace and ideally a core file at the point of the error. To do this, we recommend validating the types of all arguments at the start of the function.
================================================
FILE: sections/errorhandling/failfast.md
================================================
# Fail fast, validate arguments using a dedicated library
### One Paragraph Explainer
We all know how checking arguments and failing fast is important to avoid hidden bugs (see anti-pattern code example below). If not, read about explicit programming and defensive programming. In reality, we tend to avoid it due to the annoyance of coding it (e.g. think of validating hierarchical JSON object with fields like email and dates) – libraries like Joi and Validator turn this tedious task into a breeze.
### Wikipedia: Defensive Programming
Defensive programming is an approach to improve software and source code, in terms of General quality – reducing the number of software bugs and problems. Making the source code comprehensible – the source code should be readable and understandable so it is approved in a code audit. Making the software behave in a predictable manner despite unexpected inputs or user actions.
### Code example: validating complex JSON input using ‘Joi’
```javascript
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) {
// assertions come first
Joi.assert(newMember, memberSchema); //throws if validation fails
// other logic here
}
```
### Anti-pattern: no validation yields nasty bugs
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?
```
### Blog Quote: "You should throw these errors immediately"
From the blog: Joyent
> A degenerate case is where someone calls an asynchronous function but doesn’t pass a callback. You should throw these errors immediately since the program is broken and the best chance of debugging it involves getting at least a stack trace and ideally a core file at the point of the error. To do this, we recommend validating the types of all arguments at the start of the function.
================================================
FILE: sections/errorhandling/failfast.polish.md
================================================
# 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.
================================================
FILE: sections/errorhandling/failfast.russian.md
================================================
# Быстро проваливайтесь, проверяя аргументы, используя выделенную библиотеку
### Объяснение в один абзац
Мы все знаем, как важно проверять аргументы и быстро отказывать, чтобы избежать скрытых ошибок (см. пример кода анти-паттерна ниже). Если нет, прочитайте о явном программировании и защитном программировании. В действительности, мы склонны избегать этого из-за досадного кодирования (например, проверка правильности иерархического объекта JSON с полями, такими как электронная почта и даты) - библиотеки, такие как Joi и Validator, превращают эту утомительную задачу в бриз.
### Википедия: защитное программирование
Защитное программирование - это подход к улучшению программного обеспечения и исходного кода, с точки зрения общего качества - уменьшения количества программных ошибок и проблем. Делать исходный код понятным - исходный код должен быть читаемым и понятным, чтобы он был одобрен в ходе аудита кода. Заставить программное обеспечение вести себя предсказуемо, несмотря на неожиданные входные данные или действия пользователя.
### Пример кода: проверка сложного ввода JSON с помощью "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
}
```
### Анти-шаблон: проверка не приводит к неприятным ошибкам
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?
```
### Цитата блога: "Вы должны немедленно выбросить эти ошибки"
Из блога: Джойент
> Вырожденный случай - это когда кто-то вызывает асинхронную функцию, но не передает обратный вызов. Вы должны немедленно выбросить эти ошибки, так как программа не работает, и наилучшая возможность отладки заключается в получении как минимум трассировки стека и, в идеале, файла ядра в точке ошибки. Для этого мы рекомендуем проверять типы всех аргументов в начале функции.
================================================
FILE: sections/errorhandling/monitoring.chinese.md
================================================
# 监控
### 一段解释
> 在最基本的层面上,监控意味着您可以很*容易地识别出在生产环境中发生了什么不好的事情,例如,通过电子邮件或Slack通知。挑战在于选择合适的工具集来满足您的需求而不会破坏您的防护。我建议,从确定核心的指标集开始,这些指标必须被监控以确保一个健康的状态 – CPU,服务器的RAM,node进程RAM(小于1.4GB),在最后一分钟的错误量,进程重新启动的数量,平均响应时间。然后浏览一些你可能喜欢的高级功能并添加到你的愿望清单中。一些豪华的监控功能的例子:数据库分析,跨服务的测量(即测量业务交易),前端整合,暴露原始数据给自定义的BI clients,Slack通知及其他。
实现高级功能需要冗长的设置或购买商业产品如datadog,NewRelic和相似产品。不幸的是,即使是基本的实现也不像在公园散步那么简单,因为一些度量指标是硬件相关的(CPU),而其他的则在node进程内(内部错误),因此所有直接了当的工具都需要一些额外的设置。例如,云供应商监控解决方案(如AWS CloudWatch,谷歌Stackdriver)将立即告诉你关于硬件度量,但对内部应用程序的行为却无可奉告。在另一端,基于日志的解决方案如Elasticsearch默认情况下缺少hardware view。解决方案是用缺少的指标来增加您的选择,例如,一个流行的选择是将应用程序日志发送到Elastic stack,并配置一些额外的代理(如Beat)来共享与硬件相关的信息以获得完整的画面。
### 博客引用: "我们对于promise有一个问题"
摘自博客 pouchdb.com, 对于关键字“node promises”,排名11
> … 我们建议您为所有服务监视这些信号:
错误率:因为错误是面向用户的,并且会立即影响您的客户。
响应时间:因为延迟直接影响您的客户和业务。
吞吐量:流量有助于您了解错误率增加和延迟的上下文。
饱和度:它告诉您的服务负载多少。如果CPU使用率是90%,你的系统能处理更多的流量吗?
…
================================================
FILE: sections/errorhandling/monitoring.french.md
================================================
# 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 ?
…
================================================
FILE: sections/errorhandling/monitoring.japanese.md
================================================
# 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?
…
================================================
FILE: sections/errorhandling/monitoring.md
================================================
# 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?
…
================================================
FILE: sections/errorhandling/monitoring.russian.md
================================================
# Мониторинг
### Объяснение в один абзац
> На самом базовом уровне мониторинг означает, что вы можете *легко определить, когда на производстве происходят плохие вещи. Например, получая уведомления по электронной почте или Slack. Задача состоит в том, чтобы выбрать правильный набор инструментов, который удовлетворит ваши требования, не нарушая ваш банк. Позвольте мне начать с определения базового набора метрик, которые необходимо отслеживать для обеспечения работоспособного состояния - ЦП, ОЗУ сервера, ОЗУ процесса узла (менее 1,4 ГБ), количество ошибок в последнюю минуту, количество перезапусков процесса, среднее время ответа. Затем перейдите к некоторым дополнительным функциям, которые вам могут понравиться, и добавьте их в свой список пожеланий. Некоторые примеры функции мониторинга класса "люкс": профилирование БД, межсервисное измерение (то есть измерение бизнес-транзакций), интеграция с внешним интерфейсом, предоставление необработанных данных для пользовательских клиентов BI, уведомления Slack и многие другие.
Для реализации расширенных функций требуется длительная настройка или покупка коммерческого продукта, такого как Datadog, newrelic и тому подобное. К сожалению, достижение даже базовых знаний - это не прогулка в парке, поскольку некоторые метрики связаны с аппаратным обеспечением (ЦП), а другие живут в процессе узла (внутренние ошибки), поэтому все простые инструменты требуют некоторой дополнительной настройки. Например, решения для мониторинга поставщиков облачных вычислений (например, AWS CloudWatch, Google StackDriver) немедленно сообщат вам о метрике аппаратного обеспечения, но ничего не скажут о поведении внутреннего приложения. С другой стороны, в решениях на основе журналов, таких как ElasticSearch, по умолчанию отсутствует аппаратное представление. Решение состоит в том, чтобы дополнить ваш выбор отсутствующими метриками, например, популярным выбором является отправка журналов приложений в стек Elastic и настройка некоторого дополнительного агента (например, Beat) для обмена информацией, относящейся к оборудованию, для получения полной картины.
### Цитата из блога: "У нас проблема с обещаниями"
Из блога pouchdb.com, занимавший 11 место по ключевым словам "Узловые обещания"
> … Мы рекомендуем вам смотреть эти сигналы для всех ваших сервисов: Частота ошибок: потому что ошибки связаны с пользователем и сразу же влияют на ваших клиентов.
Время ответа: потому что задержка напрямую влияет на ваших клиентов и бизнес.
Пропускная способность: трафик помогает понять контекст повышенной частоты ошибок и задержки.
Нагрузка: говорит о том, насколько "полон" ваш сервис. Если загрузка процессора составляет 90%, может ли ваша система обрабатывать больше трафика?
…
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.basque.md
================================================
# 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.
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.brazilian-portuguese.md
================================================
# Diferencie erros operacionais vs erros de programação
### Explicação em um Parágrafo
Distinguir os dois tipos de erros a seguir minimizará o tempo de inatividade do seu aplicativo e ajudará a evitar bugs insanos: Erros operacionais referem-se a situações em que você entende o que aconteceu e o impacto disso – por exemplo, uma consulta a algum serviço HTTP falhou devido a um problema de conexão. Por outro lado, os erros do programador referem-se a casos em que você não tem idéia do motivo e, às vezes, de onde um erro ocorreu – Pode ser algum código que tentou ler um valor indefinido ou um conjunto de conexões de banco de dados que vaze memória. Erros operacionais são relativamente fáceis de lidar – geralmente registrar o erro é o suficiente. As coisas ficam complicadas quando um erro do programador aparece, o aplicativo pode estar em um estado inconsistente e não há nada melhor que você possa fazer do que reiniciar normalmente.
### Exemplo de código - marcando um erro como operacional (confiável)
```javascript
// marcando um objeto de erro como operacional
const myError = new Error("Como posso adicionar um novo produto quando nenhum valor é fornecido?");
myError.isOperational = true;
// ou se você estiver usando alguma fábrica centralizada de erros (veja outros exemplos no marcador "Use somente o objeto Error interno")
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, "Descreva aqui o que aconteceu", true);
```
### Citação de Blog: "Erros do programador são bugs no programa"
Do blog, Joyent classificado como 1 para as palavras-chave “Node.js error handling”
> …A melhor maneira de se recuperar de erros de programação é travar imediatamente. Você deve executar seus programas usando um restaurador que irá reiniciar automaticamente o programa em caso de falha. Com um reinicializador executando, reiniciar é a maneira mais rápida de restaurar o serviço confiável diante de um erro temporário do programador…
### Citação de Blog: "Não há maneira segura de sair sem criar algum estado frágil indefinido"
Da documentação oficial do Node.js
> …Pela própria natureza de como o throw funciona em JavaScript, quase nunca há como "continuar de onde você parou" com segurança, sem vazar referências, ou criar algum outro tipo de estado frágil indefinido. A maneira mais segura de responder a um erro é desligar o processo. É claro que, em um servidor web normal, você pode ter muitas conexões abertas, e não é razoável encerrá-las abruptamente porque um erro foi acionado por outra pessoa. A melhor abordagem é enviar uma resposta de erro à solicitação que acionou o erro, deixando as outras concluírem em seu tempo normal e parar de atender novas solicitações nesse processo..
### Citação de Blog: "Caso contrário, você arrisca o estado do seu aplicativo"
Do blog, debugable.com classificado como 3 para as palavras-chave “Node.js uncaught exception”
> …Então, a menos que você realmente saiba o que está fazendo, você deve executar um reinício do seu serviço depois de receber um“uncaughtException” evento de exceção. Caso contrário, você corre o risco de que o estado do seu aplicativo, ou de bibliotecas de terceiros, se torne inconsistente, levando a todos os tipos de bugs malucos…
### "Citação de Blog: Existem três escolas de pensamentos sobre tratamento de erros"
Do blog: JS Recipes
> …Existem basicamente três escolas de pensamento sobre tratamento de erros:
1. Deixar o aplicativo travar e reiniciá-lo.
2. Lidar com todos os erros possíveis e nunca travar.
3. Uma abordagem equilibrada entre os dois.
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.chinese.md
================================================
# 区分操作型错误和程序型错误
### 一段解释
区分以下两种错误类型将最大限度地减少应用程序停机时间并帮助避免出现荒唐的错误: 操作型错误指的是您了解发生了什么情况及其影响的情形 – 例如, 由于连接问题而导致对某些 HTTP 服务的查询失败问题。另一方面, 程序型错误指的是您不知道原因, 有时是错误不知道来自何处的情况 – 可能是一些代码试图读取未定义的值或 DB 连接池内存泄漏。操作型错误相对容易处理 – 通常记录错误就足够了。当程序型错误出现,事情变得难以应付, 应用程序可能处于不一致状态, 你可以做的,没有什么比优雅的重新启动更好了。
### 代码示例 – 将错误标记为可操作 (受信任)
```javascript
//将错误标记为可操作
var myError = new Error("How can I add new product when no value provided?");
myError.isOperational = true;
//或者, 如果您使用的是一些集中式错误工厂 (请参见项目符号中的示例"仅使用内置错误对象")
function appError(commonType, description, isOperational) {
Error.call(this);
Error.captureStackTrace(this);
this.commonType = commonType;
this.description = description;
this.isOperational = isOperational;
};
throw new appError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
```
### 博客引用: "程序型错误是程序中的 bug"
摘自博客 Joyent, 对于关键字“Node.JS error handling”排名第一
> …从程序型错误中恢复的最好方法是立即崩溃。您应该使用restarter运行程序, 以便在发生崩溃时自动重新启动程序。在一个使用了restarter的地方, 在面对一个瞬态程序型错误, 崩溃是最快的方式来恢复可靠的服务…
### 博客引用: "不伴随着创建一些未定义的脆性状态,没有安全的方式可以离开"
摘自Node.JS官方文档
> …从 JavaScript throw 的工作原理上讲, 几乎没有任何方法可以安全地“在你跌倒的地方重新爬起来”而不引发泄漏且不创建一些其他形式的未定义的脆性状态。响应(未定义的)抛出错误的最安全方法是关闭进程。当然, 通常 web 服务器可能会有许多连接正在通信, 由于某个人触发了错误而突然关闭那些连接是不合理的。更好的方法是让该工作进程向触发错误的请求发送错误响应, 同时保持其它请求正常进行直至完成, 并停止侦听的新的请求。(译者注:为优雅重启做准备)
### 博客引用: "否则,您置您应用的状态于风险之中"
摘自博客 debugable.com, 对于关键字“Node.JS uncaught exception”排名第3
> …所以, 除非你真的知道你在做什么, 否则你应该在收到一个"uncaughtException"异常事件之后, 对你的服务进行一次优雅的重新启动。否则, 您应用的状态, 或和第三方库的状态变得不一致, 都被置于风险之中,导致各种荒唐的错误…
### 博客引用: "对于错误处理,有三种学院派想法"
摘自博客: JS Recipes
> …对于错误处理,主要有三种学院派想法:
1. 让应用崩溃并重启.
2. 处理所有可能的错误,从不崩溃.
3. 两者之间的折中方案
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.french.md
================================================
# 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
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.japanese.md
================================================
# 操作上のエラーとプログラマーのエラーを区別する
### 一段落説明
操作上のエラーとプログラマーのエラーという 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 つをバランスよく取り入れたアプローチ
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.korean.md
================================================
# 동작상의 에러 vs 프로그래머 에러
### 한문단 설명
다음 두 가지의 에러 유형을 구별하면 앱 다운타임(downtime)을 최소화하고 심각한 버그를 방지하는데 도움이 될 것이다: 동작 오류는 발생한 일과 영향에 대해 어떤 상황인지 말한다 – 예를 들면, 연결 문제로 인한 일부 HTTP 서비스 쿼리 실패가 있다. 반면에, 프로그래머 에러는 어디에서 에러가 발생했는지 왜 발생했는지 모르는 경우를 말한다 – 이것은 정의되지 않은 값이나 메모리 누수되는 데이터베이스 연결 풀(connection pool)을 읽으려는 코드일 수 있다. 동작 상의 에러는 비교적 다루기 쉽다 – 보통은 에러를 기록하면 충분하다. 프로그래머 에러가 발생하면, 응용 프로그램이 일관된 상태가 아닐 수도 있으며 이 땐 다시 시작하는 것보다 더 좋은 방법은 없다
### 코드 예시 – 동작상의 에러 표시 (신뢰됨)
```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);
```
### 블로그 인용: "프로그램에서 프로그래머 에러는 버그다"
Joyent 블로그에서 "Node.js 에러 처리" 키워드 1위에 위치했다
> …프로그래머 에러를 복구하는 가장 좋은 방법은 즉시 충돌하는 것이다. 충돌 시 자동으로 프로그램을 다시 시작하는 리스타터(restarter)를 사용하여 프로그램을 실행해야 한다. 리스타터(restarter)를 사용하는 경우, 일시적인 프로그래머 오류에 직면하면 신뢰할 수 있는 서비스를 복구하는 가장 빠른 방법은 충돌이다…
### 블로그 인용: "정의되지 않은 취약 상태를 만들지 않고 떠나는 안전한 방법은 없다"
Node.js 공식문서에서
> …자바스크립트에서 던지기(throw) 방식의 특성상, 정의되지 않은 종류의 취약 상태를 만들거나 참조 누수 없이는, 안전하게 "중단한 곳에서 픽업(pick up)" 할 수 있는 방법은 거의 없다. 던져진 에러를 처리하는 가장 안전한 방법은 프로세스를 종료하는 것이다. 물론, 일반적인 웹 서버에서는 많은 연결이 열려 있을 수 있으며, 다른 누군가에 의해 오류가 발생했을 수도 있기 때문에 갑자기 연결을 종료하는 것은 적절하지 않다. 더 나은 방법은 다른 사람들이 정상적인 시간에 완료할 수 있도록 하면서 에러를 발생시킨 요청에 대한 에러 응답을 보내고, 새 요청에 대한 응답을 중지하는 것이다.
### 블로그 인용: "그렇지 않으면 당신의 애플리케이션 상태가 위험해질 수 있음"
debugable.com 블로그에서 "Node.js 예상치 못한 예외 처리" 키워드 3위에 위치했다
> …그래서, 당신이 정말로 무엇을 하고 있는 지 모른다면, "예상치 못한 예외 처리(uncaughtException)" 예외 이벤트를 받은 후 서비스를 다시 시작해야한다. 그렇지 않으면, 애플리케이션 상태나 제 3자 라이브러리의 상태가 일관되지 않아 모든 종류의 심각한 버그가 발생할 위험이 있다…
### 블로그 인용: "에러 처리에는 주로 세 가지 방법이 있다"
JS Recipes 블로그에서
> …에러 처리에는 주로 세 가지 방법이 있다:
1. 애플리케이션을 중지하고 다시 시작하기.
2. 가능한 모든 에러를 처리하고 충돌하지 않게 하기.
3. 이 두가지 사이의 균형잡힌 접근
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.md
================================================
# Distinguish operational vs programmer errors
### One Paragraph Explainer
Distinguishing the following two error types will minimize your app downtime and helps avoid crazy bugs: Operational errors refer to situations where you understand what happened and the impact of it – for example, a query to some HTTP service failed due to connection problem. On the other hand, programmer errors refer to cases where you have no idea why and sometimes where an error came from – it might be some code that tried to read an undefined value or DB connection pool that leaks memory. Operational errors are relatively easy to handle – usually logging the error is enough. Things become hairy when a programmer error pops up, the application might be in an inconsistent state and there’s nothing better you can do than to restart gracefully
### Code Example – marking an error as operational (trusted)
Javascript
```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);
```
### Blog Quote: "Programmer errors are bugs in the program"
From the blog, Joyent ranked 1 for the keywords “Node.js error handling”
> …The best way to recover from programmer errors is to crash immediately. You should run your programs using a restarter that will automatically restart the program in the event of a crash. With a restarter in place, crashing is the fastest way to restore reliable service in the face of a transient programmer error…
### Blog Quote: "No safe way to leave without creating some undefined brittle state"
From Node.js official documentation
> …By the very nature of how throw works in JavaScript, there is almost never any way to safely “pick up where you left off”, without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error while letting the others finish in their normal time, and stop listening for new requests in that worker.
### Blog Quote: "Otherwise you risk the state of your application"
From the blog, debugable.com ranked 3 for the keywords “Node.js uncaught exception”
> …So, unless you really know what you are doing, you should perform a graceful restart of your service after receiving an “uncaughtException” exception event. Otherwise, you risk the state of your application, or that of 3rd party libraries to become inconsistent, leading to all kinds of crazy bugs…
### Blog Quote: "There are three schools of thoughts on error handling"
From the blog: JS Recipes
> …There are primarily three schools of thoughts on error handling:
>1. Let the application crash and restart it.
>2. Handle all possible errors and never crash.
>3. A balanced approach between the two
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.polish.md
================================================
# 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
================================================
FILE: sections/errorhandling/operationalvsprogrammererror.russian.md
================================================
# Различайте операционные ошибки и ошибки программиста
### Объяснение в один абзац
Разделение ошибок на эти два типа минимизирует время простоя вашего приложения и помогает избежать сумасшедших ошибок: операционные ошибки относятся к ситуациям, когда вы понимаете происходящее и влияние ошибки на программу. Например, запрос к какой-нибудь службе HTTP не выполнен из-за проблемы с подключением. С другой стороны, ошибки программиста относятся к случаям, когда вы не знаете, почему, а иногда и откуда возникла ошибка - это может быть какой-то код, который пытался прочитать undefined-значение или код, который использует пул соединений с БД и приводит к утечке памяти. Операционные ошибки относительно легко обрабатываются - обычно достаточно логирования ошибки. Хуже становиться, когда появляется ошибка программиста, приложение может быть в несогласованном состоянии, и все, что вы можете сделать - перезапустить приложение.
### Пример кода - помечаем ошибку как операционную (доверенную)
Javascript
```javascript
// помечаем объект ошибки, как операционный
const myError = new Error('Как мы можем добавить продукт, если значение не задано?');
myError.isOperational = true;
// или, если вы используете централизированную фабрику ошибок (смотрите другие примеры в статье "Используйте только встроенный объект 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, 'Описываем, что произошло', 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"
> … Лучший способ исправить ошибки программиста - это сразу же аварийно завершить работу. Вы должны запускать свои программы, используя сервис перезапуска, который автоматически будет перезапускать программу в случае сбоя. Сервис перезапуска является самым простым способом надежного восстановления сервиса при возникновении временной ошибки программиста…
### Цитата из блога: "Нет безопасного способа продолжить без возникновения хрупкого undefined-состояния системы"
Из официальной документации Node.js
> …По самой природе того, как throw работает в JavaScript, почти всегда нет способа безопасно "начать оттуда, где мы остановились", без утечки ссылок или создания другого undefined-состояния. Самый безопасный способ отреагировать на возникшую ошибку - завершить процесс. Конечно, на обычном веб-сервере у вас может быть открыто много подключений, и нет смысла внезапно закрывать все, потому что кто-то другой выбросил ошибку. Лучший вариант - отправить ответ об ошибке на запрос, который ее вызвал, позволяя остальным завершить работу в удобное время, и после прекратить прослушивание новых запросов в воркере, в котором возникла ошибка.
### Цитата блога: "В противном случае вы рискуете состоянием вашего приложения"
Из блога debugable.com, занявшего 3 место по ключевым словам "Node.js uncaught exception"
> …Итак, если вы действительно не знаете, что делаете, вам следует выполнить постепенный перезапуск службы после получения события исключения "uncaughtException". В противном случае вы рискуете привести к несогласованности состояния вашего приложения или сторонних библиотек, что приведет к всевозможным сумасшедшим ошибкам…
### Цитата блога: "Есть три школы мысли об обработке ошибок"
Из блога: JS Recipes
> …Существует три основных направления работы с ошибками:
1. Дайте приложению упасть и перезапустите его.
2. Обрабатывайте все возможные ошибоки и никогда не роняйте сервис.
3. Сбалансированный подход между двумя предыдущими.
================================================
FILE: sections/errorhandling/returningpromises.basque.md
================================================
# 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
)
================================================
FILE: sections/errorhandling/returningpromises.french.md
================================================
# 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
)
================================================
FILE: sections/errorhandling/returningpromises.md
================================================
# 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
)
================================================
FILE: sections/errorhandling/returningpromises.russian.md
================================================
# Возвращение промисов
### Короткое объяснение
У 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 ([...])
```
### Как правильно: return await `promise`
Javascript
```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 ([...])
```
### Анти-паттерн №2: синхронная функция возвращающая промис
Javascript
```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
)
================================================
FILE: sections/errorhandling/shuttingtheprocess.basque.md
================================================
# 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
================================================
FILE: sections/errorhandling/shuttingtheprocess.brazilian-portuguese.md
================================================
# Finalize o processo quando um estranho chegar
### Explicação em um Parágrafo
Em algum lugar dentro do seu código, um objeto manipulador de erro é responsável por decidir como proceder quando um erro é lançado – se o erro for confiável (por exemplo, erro operacional, consulte mais explicações na melhor prática #3), a gravação no arquivo de log poderá ser suficiente. As coisas ficam complicadas se o erro não for familiar - isso significa que algum componente pode estar em um estado defeituoso e todas as solicitações futuras estão sujeitas a falhas. Por exemplo, suponha um serviço de emissor de token único e com estado, que lançou uma exceção e perdeu seu estado - a partir de agora ele pode se comportar de maneira inesperada e fazer com que todas as solicitações falhem. Neste cenário, mate o processo e use uma "ferramenta de reinicialização" (como Forever, PM2, etc) para começar de novo com um estado limpo.
### Exemplo de código: decidindo se vai travar
```javascript
// Supondo que os desenvolvedores marquem erros operacionais conhecidos com error.isOperational = true, leia as melhores práticas #3
process.on('uncaughtException', function(error) {
errorManagement.handler.handleError(error);
if(!errorManagement.handler.isTrustedError(error))
process.exit(1)
});
// manipulador de erro centralizado encapsula lógica relacionada à manipulação de erros
function errorHandler() {
this.handleError = function (error) {
return logger.logError(err)
.then(sendMailToAdminIfCritical)
.then(saveInOpsQueueIfCritical)
.then(determineIfOperationalError);
}
this.isTrustedError = function (error) {
return error.isOperational;
}
}
```
### Citação de Blog: "A melhor maneira é travar"
Do blog Joyent
> …A melhor maneira de se recuperar de erros de programação é travar imediatamente. Você deve executar seus programas usando um restaurador que irá reiniciar automaticamente o programa em caso de falha. Com um reinicializador executando, o travamento é a maneira mais rápida de restaurar um serviço confiável diante de um erro temporário do programador…
### "Citação de Blog: Existem três escolas de pensamentos sobre tratamento de erros"
Do blog: JS Recipes
> …Existem basicamente três escolas de pensamento sobre tratamento de erros:
1. Deixar o aplicativo travar e reiniciá-lo.
2. Lidar com todos os erros possíveis e nunca travar.
3. Uma abordagem equilibrada entre os dois.
### Citação de Blog: "Não há maneira segura de sair sem criar algum estado frágil indefinido"
Da documentação oficial do Node.js
> …Pela própria natureza de como o throw funciona em JavaScript, quase nunca há como "continuar de onde você parou" com segurança, sem vazar referências, ou criar algum outro tipo de estado frágil indefinido. A maneira mais segura de responder a um erro é desligar o processo. É claro que, em um servidor web normal, você pode ter muitas conexões abertas, e não é razoável encerrá-las abruptamente porque um erro foi acionado por outra pessoa. A melhor abordagem é enviar uma resposta de erro à solicitação que acionou o erro, deixando as outras concluírem em seu tempo normal e parar de atender novas solicitações nesse processo..
================================================
FILE: sections/errorhandling/shuttingtheprocess.chinese.md
================================================
# 特殊情况产生时,优雅地退出服务
### 一段解释
在您的代码的某个地方,当一个错误抛出的时候,错误处理对象负责决定如何进行时 – 如果错误是可信的(即操作型错误,在最佳实践#3了解进一步的解释),写入日志文件可能是足够的。如果错误不熟悉,事情就变得棘手了 – 这意味着某些组件可能处于故障状态,所有将来的请求都可能失败。例如,假设一个单例(singleton)的,有状态的令牌发行者服务抛出异常并失去它的状态 — 从现在起,它可能会出现意外行为并导致所有请求失败。在这种情况下,杀进程,使用“重启”的工具(像Forever,PM2,等等)重新开始。
### 代码实例: 决定是否退出
```javascript
//收到未捕获的异常时,决定是否要崩溃
//如果开发人员标记已知的操作型错误使用:error.isOperational=true, 查看最佳实践 #3
process.on('uncaughtException', function(error) {
errorManagement.handler.handleError(error);
if(!errorManagement.handler.isTrustedError(error))
process.exit(1)
});
//封装错误处理相关逻辑在集中的错误处理中
function errorHandler(){
this.handleError = function (error) {
return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
}
this.isTrustedError = function(error)
{
return error.isOperational;
}
```
### 博客引用: "最好的方式是立即崩溃"
摘自 博客:Joyent
> …从程序型错误中恢复过来的最好方法是立即崩溃。你应该使用一个重启助手来运行您的程序,它会在崩溃的情况下自动启动程序。当使用重启助手,崩溃是面对临时性的程序型错误时,恢复可靠的服务的最快的方法…
### 博客引用: "错误处理有三种流派"
摘自 博客:JS Recipes
> …错误处理主要有三种流派:
1. 让应用崩溃,并重启。
2. 处理所有的错误,从不崩溃。
3. 介于两者之间。
### 博客引用: "不伴随着创建一些易碎的状态,是没有保险的方式退出"
摘自 Node.JS 官方文档
> …就throw工作在JavaScript的本质而言,几乎没有任何方法可以安全地“在您丢下的地方捡起”,而不会泄漏引用,或者创建其他类型的未定义的易碎性状态。对抛出的错误作出响应的最安全的方法是关闭进程。当然,在一个普通的Web服务器中,可能有很多连接打开了,因为其他人触发了一个错误,所以突然关闭这些连接是不合理的。更好的方法是将错误响应发送给触发错误的请求,同时让其他人在正常时间内完成,并停止侦听该工作者的新请求。
================================================
FILE: sections/errorhandling/shuttingtheprocess.french.md
================================================
# 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.
================================================
FILE: sections/errorhandling/shuttingtheprocess.japanese.md
================================================
# 見ず知らずの事象が起きたら潔くプロセスを終了する
### 一段落説明
コード内のどこかで、エラーハンドラオブジェクトがエラー発生時にどのように処理するかを決定することに責任を負っているとき ー エラーが信頼されている場合は(すなわち、操作上のエラーのことです。ベストプラクティス 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 の挙動の性質上、参照をリークさせたり、不明瞭で不安定な状態を作り出したりすることなく、安全に「中断したところから再開する」方法はほぼありません。投げられたエラーに対応する最も安全な方法は、プロセスをシャットダウンすることです。もちろん、通常のウェブサーバーでは、多くのコネクションがオープン状態になっているかもしれず、エラーが他の誰かによって引き起こされたからといって、それらを急にシャットダウンすることは合理的ではありません。より良いアプローチは、エラーの引き金となったリクエストにエラーレスポンスを送り、他のリクエストは通常の時間内に終了するようにして、そのワーカーにおいて新しいリクエストの受信を停止することです。
================================================
FILE: sections/errorhandling/shuttingtheprocess.korean.md
================================================
# Exit the process gracefully when a stranger comes to town
### One Paragraph Explainer
Somewhere within your code, an error handler object is responsible for deciding how to proceed when an error is thrown – if the error is trusted (i.e. operational error, see further explanation within best practice #3) then writing to log file might be enough. Things get hairy if the error is not familiar – this means that some component might be in a faulty state and all future requests are subject to failure. For example, assuming a singleton, stateful token issuer service that threw an exception and lost its state – from now it might behave unexpectedly and cause all requests to fail. Under this scenario, kill the process and use a ‘Restarter tool’ (like Forever, PM2, etc) to start over with a clean state.
### Code example: deciding whether to crash
```javascript
// Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
process.on('uncaughtException', function(error) {
errorManagement.handler.handleError(error);
if(!errorManagement.handler.isTrustedError(error))
process.exit(1)
});
// centralized error handler encapsulates error-handling related logic
function errorHandler() {
this.handleError = function (error) {
return logger.logError(err)
.then(sendMailToAdminIfCritical)
.then(saveInOpsQueueIfCritical)
.then(determineIfOperationalError);
}
this.isTrustedError = function (error) {
return error.isOperational;
}
}
```
### Blog Quote: "The best way is to crash"
From the blog Joyent
> …The best way to recover from programmer errors is to crash immediately. You should run your programs using a restarter that will automatically restart the program in the event of a crash. With a restarter in place, crashing is the fastest way to restore reliable service in the face of a transient programmer error…
### Blog Quote: "There are three schools of thoughts on error handling"
From the blog: JS Recipes
> …There are primarily three schools of thoughts on error handling:
1. Let the application crash and restart it.
2. Handle all possible errors and never crash.
3. A balanced approach between the two
### Blog Quote: "No safe way to leave without creating some undefined brittle state"
From Node.js official documentation
> …By the very nature of how throw works in JavaScript, there is almost never any way to safely “pick up where you left off”, without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error while letting the others finish in their normal time, and stop listening for new requests in that worker.
================================================
FILE: sections/errorhandling/shuttingtheprocess.md
================================================
# Exit the process gracefully when a stranger comes to town
### One Paragraph Explainer
Somewhere within your code, an error handler object is responsible for deciding how to proceed when an error is thrown – if the error is trusted (i.e. operational error, see further explanation within best practice #3) then writing to log file might be enough. Things get hairy if the error is not familiar – this means that some component might be in a faulty state and all future requests are subject to failure. For example, assuming a singleton, stateful token issuer service that threw an exception and lost its state – from now it might behave unexpectedly and cause all requests to fail. Under this scenario, kill the process and use a ‘Restarter tool’ (like Forever, PM2, etc) to start over with a clean state.
### Code example: deciding whether to crash
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();
```
### Blog Quote: "The best way is to crash"
From the blog Joyent
> …The best way to recover from programmer errors is to crash immediately. You should run your programs using a restarter that will automatically restart the program in the event of a crash. With a restarter in place, crashing is the fastest way to restore reliable service in the face of a transient programmer error…
### Blog Quote: "There are three schools of thoughts on error handling"
From the blog: JS Recipes
> …There are primarily three schools of thoughts on error handling:
>1. Let the application crash and restart it.
>2. Handle all possible errors and never crash.
>3. A balanced approach between the two
### Blog Quote: "No safe way to leave without creating some undefined brittle state"
From Node.js official documentation
> …By the very nature of how throw works in JavaScript, there is almost never any way to safely “pick up where you left off”, without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error while letting the others finish in their normal time, and stop listening for new requests in that worker.
================================================
FILE: sections/errorhandling/shuttingtheprocess.polish.md
================================================
# 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.
================================================
FILE: sections/errorhandling/shuttingtheprocess.russian.md
================================================
# Изящно выходите из процесса, когда неизвестное случается
### Объяснение в один абзац
Где-то в вашем коде объект-обработчик ошибок отвечает за принятие решения о том, как действовать при возникновении ошибки - если ошибка является доверенной (т.е. операционная ошибка, см. дальнейшее объяснение в этих практиках № 3), тогда записи в файл журнала может быть достаточно. Ситуация становится неясной, если ошибка незнакома - это означает, что какой-то компонент может быть в неисправном состоянии, и все будущие запросы могут быть сбойными. Например, если предположить, что единственная служба выдачи токенов с состоянием, которая вызвала исключение и потеряла свое состояние, отныне может вести себя неожиданно и вызывать сбой всех запросов. В этом сценарии завершите процесс и используйте "инструмент перезапуска" (например, Forever, PM2 и т.д.), Чтобы начать заново с чистым состоянием.
### Пример кода: решение о сбое
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();
```
### Цитата из блога: "Лучший способ - это рухнуть"
Из блога Джойент
> … Лучший способ исправить ошибки программиста - это сразу же аварийно завершить работу. Вы должны запустить свои программы, используя перезапуск, который автоматически перезапустит программу в случае сбоя. С перезапуском на месте сбой является самым быстрым способом восстановления надежного сервиса перед лицом временной ошибки программиста …
### Цитата блога: "Есть три школы мысли об обработке ошибок"
Из блога: JS Recipes
> … Существует три основных направления работы с ошибками:
1. Дайте приложению упасть и перезапустите его.
2. Обрабатывайте все возможные ошибоки и никогда не роняйте.
3. Сбалансированный подход между двумя предыдущими.
### Цитата из блога: "Нет безопасного способа уйти, не создав неопределенного хрупкого состояния"
Из официальной документации Node.js
> … По самой природе того, как throw работает в JavaScript, почти никогда не существует способа безопасно "выбрать то, на чем остановился", без утечки ссылок или создания какого-либо другого неопределенного хрупкого состояния. Самый безопасный способ отреагировать на возникшую ошибку - завершить процесс. Конечно, на обычном веб-сервере у вас может быть открыто много подключений, и нет смысла внезапно закрывать их, потому что кто-то еще вызвал ошибку. Лучший подход - отправить ответ об ошибке на запрос, который вызвал ошибку, позволяя остальным завершить работу в обычное время, и прекратить прослушивание новых запросов этого работника.
================================================
FILE: sections/errorhandling/testingerrorflows.basque.md
================================================
# 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);
}
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.brazilian-portuguese.md
================================================
# Fluxos de testes de erros usando seu framework favorito
### Explicação em um Parágrafo
Testar caminhos "felizes" não é melhor do que testar falhas. Uma boa cobertura de código de teste exige testar caminhos excepcionais. Caso contrário, não há confiança de que as exceções sejam realmente tratadas corretamente. Cada estrutura de testes unitários, como o [Mocha](https://mochajs.org/) e [Chai](http://chaijs.com/), suporta testes de exceção (exemplos de código abaixo). Se você achar tedioso testar todas as funções internas e exceções, você pode resolver testando apenas erros HTTP da API REST.
### Exemplo de código: garantindo que a exceção correta seja lançada usando Mocha & Chai
```javascript
describe("Bate-papo do Facebook", () => {
it("Notifica em nova mensagem de bate-papo", () => {
var chatService = new chatService();
chatService.participants = getDisconnectedParticipants();
expect(chatService.sendMessage.bind({ message: "Oi" })).to.throw(ConnectionError);
});
});
```
### Exemplo de código: garantindo que a API retorne o código de erro HTTP correto
```javascript
it("Cria um novo grupo no Facebook", function (done) {
var invalidGroupInfo = {};
httpRequest({
method: 'POST',
uri: "facebook.com/api/groups",
resolveWithFullResponse: true,
body: invalidGroupInfo,
json: true
}).then((response) => {
// se fôssemos executar o código neste bloco, nenhum erro foi lançado na operação acima
}).catch(function (response) {
expect(400).to.equal(response.statusCode);
done();
});
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.chinese.md
================================================
# 使用您喜欢的测试框架测试错误流
### 一段解释
测试‘正确’路径并不比测试失败更好。良好的测试代码覆盖率要求测试异常路径。否则,异常确实被处理正确是不可信的。每个单元测试框架,如[Mocha](https://mochajs.org/) & [Chai](http://chaijs.com/),都支持异常测试(请看下面的代码示例)。如果您觉得测试每个内部函数和异常都很乏味,那么您可以只测试REST API HTTP错误。
### 代码示例: 使用 Mocha & Chai 确保正确的异常被抛出
```javascript
describe("Facebook chat", () => {
it("Notifies on new chat message", () => {
var chatService = new chatService();
chatService.participants = getDisconnectedParticipants();
expect(chatService.sendMessage.bind({message: "Hi"})).to.throw(ConnectionError);
});
});
```
### 代码示例: 确保 API 返回正确的 HTTP 错误码
```javascript
it("Creates new Facebook group", function (done) {
var invalidGroupInfo = {};
httpRequest({method: 'POST', uri: "facebook.com/api/groups", resolveWithFullResponse: true, body: invalidGroupInfo, json: true
}).then((response) => {
//oh no if we reached here than no exception was thrown
}).catch(function (response) {
expect(400).to.equal(response.statusCode);
done();
});
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.french.md
================================================
# 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);
}
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.japanese.md
================================================
# お気に入りのテストフレームワークを使用してエラーフローをテストする
### 一段落説明
「ハッピー」パスをテストすることは、失敗をテストすることも同然です。良いテストコードカバレッジは、例外パスをテストすることを要求します。さもなければ、例外が実際に正しく処理されるという信用はありません。[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);
}
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.korean.md
================================================
# Test error flows using your favorite test framework
### One Paragraph Explainer
Testing ‘happy’ paths is no better than testing failures. Good testing code coverage demands to test exceptional paths. Otherwise, there is no trust that exceptions are indeed handled correctly. Every unit testing framework, like [Mocha](https://mochajs.org/) & [Chai](http://chaijs.com/), supports exception testing (code examples below). If you find it tedious to test every inner function and exception you may settle with testing only REST API HTTP errors.
### Code example: ensuring the right exception is thrown using Mocha & Chai
```javascript
describe("Facebook chat", () => {
it("Notifies on new chat message", () => {
var chatService = new chatService();
chatService.participants = getDisconnectedParticipants();
expect(chatService.sendMessage.bind({ message: "Hi" })).to.throw(ConnectionError);
});
});
```
### Code example: ensuring API returns the right HTTP error code
```javascript
it("Creates new Facebook group", function (done) {
var invalidGroupInfo = {};
httpRequest({
method: 'POST',
uri: "facebook.com/api/groups",
resolveWithFullResponse: true,
body: invalidGroupInfo,
json: true
}).then((response) => {
// if we were to execute the code in this block, no error was thrown in the operation above
}).catch(function (response) {
expect(400).to.equal(response.statusCode);
done();
});
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.md
================================================
# Test error flows using your favorite test framework
### One Paragraph Explainer
Testing ‘happy’ paths is no better than testing failures. Good testing code coverage demands to test exceptional paths. Otherwise, there is no trust that exceptions are indeed handled correctly. Every unit testing framework, like [Mocha](https://mochajs.org/) & [Chai](http://chaijs.com/), supports exception testing (code examples below). If you find it tedious to test every inner function and exception you may settle with testing only REST API HTTP errors.
### Code example: ensuring the right exception is thrown using Mocha & Chai
Javascript
```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);
});
});
```
### Code example: ensuring API returns the right HTTP error code and log properly
Javascript
```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 that are uncaught exceptions are handled as well
Javascript
```javascript
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 😳");
//Act
process.emit("uncaughtException", errorToThrow);
// Assert
expect(loggerDouble.calledWith(errorToThrow));
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.polish.md
================================================
# 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);
}
});
```
================================================
FILE: sections/errorhandling/testingerrorflows.russian.md
================================================
# Тестируйте потоки ошибок с использованием вашей любимой тестовой среды
### Объяснение в один абзац
Тестирование "счастливых" путей не лучше, чем тестирование неудач. Хорошее тестирование покрытия кода требует тестирования исключительных путей. В противном случае, нет уверенности, что исключения действительно обрабатываются правильно. Каждая инфраструктура модульного тестирования, например [Mocha](https://mochajs.org/) и [Chai](http://chaijs.com/), поддерживает тестирование исключений (примеры кода ниже). Если вам кажется утомительным тестировать каждую внутреннюю функцию и исключение, вы можете согласиться с тестированием только ошибок HTTP REST API.
### Пример кода: обеспечение правильного исключения с помощью 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
})
// 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);
}
});
```
================================================
FILE: sections/errorhandling/usematurelogger.basque.md
================================================
# 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
================================================
FILE: sections/errorhandling/usematurelogger.brazilian-portuguese.md
================================================
# Use um agente de log maduro para aumentar a visibilidade de erros
### Explicação em um Parágrafo
Todos nós amamos console.log, mas obviamente, um logger respeitável e persistente como [Winston][winston] (altamente popular) ou [pino][pino] (o novato que está focado no desempenho) é obrigatório para projetos sérios. Um conjunto de práticas e ferramentas ajudará a entender os erros muito mais rapidamente - (1) logar freqüentemente usando diferentes níveis (depuração, informação, erro), (2) ao registrar, fornecer informações contextuais como objetos JSON, ver exemplo abaixo, (3) observe e filtre os logs usando uma API de consulta de log (incorporada na maioria dos registradores) ou um software de visualização de logs, (4) Expor e selecionar a declaração de log para a equipe de operação usando ferramentas de inteligência operacional como o Splunk.
[winston]: https://www.npmjs.com/package/winston
[bunyan]: https://www.npmjs.com/package/bunyan
[pino]: https://www.npmjs.com/package/pino
### Exemplo de Código – Registrador Winston em ação
```javascript
// seu objeto registrador centralizado
var logger = new winston.Logger({
level: 'info',
transports: [
new (winston.transports.Console)()
]
});
// código personalizado em algum lugar usando o registrador
logger.log('info', 'Mensagem de Log de Teste com algum parâmetro %s', 'algum parâmetro', { anything: 'Este é um metadado' });
```
### Exemplo de código - Consultando a pasta de log (procurando por entradas)
```javascript
var options = {
from: new Date - 24 * 60 * 60 * 1000,
until: new Date,
limit: 10,
start: 0,
order: 'desc',
fields: ['message']
};
// Encontrar itens registrados entre hoje e ontem.
winston.query(options, function (err, results) {
// executar callback com os resultados
});
```
### Citação de Blog: "Requisitos do Registrador"
Do blog Strong Loop
> Vamos identificar alguns requisitos (para um registrador):
1. Carimbo de data / hora de cada linha de log. Este é bastante auto-explicativo - você deve ser capaz de dizer quando cada entrada de log ocorreu.
2. Formato de registro deve ser facilmente entendido tanto por seres humanos, quanto para máquinas.
3. Permite múltiplos fluxos de destino configuráveis. Por exemplo, você pode estar gravando logs de rastreio em um arquivo, mas quando um erro é encontrado, grava no mesmo arquivo, depois no arquivo de erro e envia um email ao mesmo tempo…
================================================
FILE: sections/errorhandling/usematurelogger.chinese.md
================================================
# 使用成熟的logger提高错误可见性
### 一段解释
我们都特别喜欢(loovve)console.log,但显而易见地,对于严肃的项目, 有信誉和持久的Logger是必需的,比如[Winston][winston] (非常流行) or [Pino][pino](专注于性能的新库)。一套实践和工具将有助于更快速地解释错误 – (1)使用不同的级别(debug, info, error)频繁地log;(2)在记录日志时, 以 JSON 对象的方式提供上下文信息, 请参见下面的示例;(3)使用日志查询API(在大多数logger中内置)或日志查看程序软件监视和筛选日志;(4)使用操作智能工具(如 Splunk)为操作团队公开和管理日志语句。
[winston]: https://www.npmjs.com/package/winston
[bunyan]: https://www.npmjs.com/package/bunyan
[pino]: https://www.npmjs.com/package/pino
### 代码示例 – 使用Winston Logger
```javascript
//您的集中式logger对象
var logger = new winston.Logger({
level: 'info',
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)({ filename: 'somefile.log' })
]
});
//在某个地方使用logger的自定义代码
logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
```
### 代码示例 – 查询日志文件夹 (搜索条目)
```javascript
var options = {
from: new Date - 24 * 60 * 60 * 1000,
until: new Date,
limit: 10,
start: 0,
order: 'desc',
fields: ['message']
};
// 查找在今天和昨天之间记录的项目
winston.query(options, function (err, results) {
//对于结果的回调处理
});
```
### 博客引用: "Logger要求"
摘自博客 Strong Loop
> 让我们确定一些要求 (对于logger):
1. 为每条日志添加时间戳。这条很好自我解释-你应该能够告知每个日志条目发生在什么时候。
2. 日志格式应易于被人类和机器理解。
3. 允许多个可配置的目标流。例如, 您可能正在将trace log写入到一个文件中, 但遇到错误时, 请写入同一文件, 然后写入到错误日志文件,并同时发送电子邮件…
================================================
FILE: sections/errorhandling/usematurelogger.french.md
================================================
# 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
================================================
FILE: sections/errorhandling/usematurelogger.japanese.md
================================================
# エラーの可視性を高めるために成熟したロガーを使用する
### 一段落説明
私たちはみな 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 メールを送信するかもしれません。
================================================
FILE: sections/errorhandling/usematurelogger.korean.md
================================================
# Use a mature logger to increase errors visibility
### One Paragraph Explainer
We all love console.log but obviously, a reputable and persistent logger like [Winston][winston] (highly popular) or [Pino][pino] (the new kid in town which is focused on performance) is mandatory for serious projects. A set of practices and tools will help to reason about errors much quicker – (1) log frequently using different levels (debug, info, error), (2) when logging, provide contextual information as JSON objects, see example below. (3) watch and filter logs using a log querying API (built-in in most loggers) or a log viewer software
(4) Expose and curate log statement for the operation team using operational intelligence tools like Splunk
[winston]: https://www.npmjs.com/package/winston
[bunyan]: https://www.npmjs.com/package/bunyan
[pino]: https://www.npmjs.com/package/pino
### Code Example – Winston Logger in action
```javascript
// your centralized logger object
var logger = new winston.Logger({
level: 'info',
transports: [
new (winston.transports.Console)()
]
});
// custom code somewhere using the logger
logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
```
### Code Example – Querying the log folder (searching for entries)
```javascript
var options = {
from: new Date - 24 * 60 * 60 * 1000,
until: new Date,
limit: 10,
start: 0,
order: 'desc',
fields: ['message']
};
// Find items logged between today and yesterday.
winston.query(options, function (err, results) {
// execute callback with results
});
```
### Blog Quote: "Logger Requirements"
From the blog Strong Loop
> Lets identify a few requirements (for a logger):
1. Timestamp each log line. This one is pretty self-explanatory – you should be able to tell when each log entry occurred.
2. Logging format should be easily digestible by humans as well as machines.
3. Allows for multiple configurable destination streams. For example, you might be writing trace logs to one file but when an error is encountered, write to the same file, then into error file and send an email at the same time…
================================================
FILE: sections/errorhandling/usematurelogger.md
================================================
# Use a mature logger to increase error visibility
### One Paragraph Explainer
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].
[pino]: https://www.npmjs.com/package/pino
[splunk]: https://www.splunk.com/
### Code Example
```JavaScript
const pino = require('pino');
// your centralized logger object
const logger = pino();
// custom code somewhere using the logger
logger.info({ anything: 'This is metadata' }, 'Test Log Message with some parameter %s', 'some parameter');
```
### Blog Quote: "Logger Requirements"
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
================================================
FILE: sections/errorhandling/usematurelogger.polish.md
================================================
# 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…
================================================
FILE: sections/errorhandling/usematurelogger.russian.md
================================================
# Используйте проверенный логгер, чтобы увеличить видимость ошибок
### Объяснение в один абзац
Мы все любим console.log, но, очевидно, авторитетный и постоянный регистратор, такой как [Winston][winston] (очень популярный) или [Pino][pino] (новый парень на районе, который ориентирован на производительность) является обязательным для серьезных проектов. Набор методов и инструментов поможет гораздо быстрее рассуждать об ошибках - (1) часто регистрировать с использованием разных уровней (отладка, информация, ошибка); (2) при ведении журнала, предоставлять контекстную информацию в виде объектов JSON, см. пример ниже; (3) просматривать и фильтровать журналы, используя API запросов журналов (встроенный в большинство регистраторов) или программу просмотра журналов; (4) разворачивать и составлять отчет для рабочей группы, используя инструменты предоставления оперативной информации, такие как Splunk.
[winston]: https://www.npmjs.com/package/winston
[pino]: https://www.npmjs.com/package/pino
### Пример кода - Winston Logger в действии
```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' });
```
### Пример кода - Запрос к папке журнала (поиск записей)
```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
});
```
### Цитата блога: "Требования к логгеру"
Из блога Strong Loop
> Давайте определим несколько требований (для регистратора):
1. Отметка времени каждой строки журнала. Это довольно очевидно - вы должны быть в состоянии сказать, когда произошла каждая запись в журнале.
2. Формат записей должен быть легко усваиваемым людьми, а также машинами.
3. Возможность для нескольких настраиваемых потоков назначения. Например, вы можете записывать журналы трассировки в один файл, но при возникновении ошибки запишите в тот же файл, затем в файл ошибок и отправьте электронное письмо одновременно …
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.basque.md
================================================
# 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…
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.brazilian-portuguese.md
================================================
# Utilize apenas o objeto interno Error
### Explicação em um Parágrafo
A natureza permissiva do JS junto com sua variedade de opções de fluxo de código (por exemplo, EventEmitter, Callbacks, Promises, etc) cria uma grande variação em como os desenvolvedores lidam com erros – alguns usam strings, outros definem os próprios tipos customizados. Usar o objeto interno Error do Node.js ajuda a manter a uniformidade dentro do seu código e com bibliotecas de terceiros, também preserva informações significativas como o rastreamento de stack. Ao gerar a exceção, geralmente é uma boa prática preenchê-la com propriedades contextuais adicionais, como o nome do erro e o código de erro HTTP associado. Para obter essa uniformidade e práticas, considere estender o objeto de erro com propriedades adicionais, consulte o exemplo de código abaixo
### Exemplo de código - fazendo certo
```javascript
// jogando um Error de uma função típica, seja síncrona ou assíncrona
if(!productToAdd)
throw new Error("Como posso adicionar um novo produto quando nenhum valor é fornecido?");
// 'jogando' um Error de um EventEmitter
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// 'jogando' um Error de uma Promise
const addProduct = async (productToAdd) => {
try {
const existingProduct = await DAL.getProduct(productToAdd.id);
if (existingProduct !== null) {
throw new Error("O produto já existe!");
}
} catch (err) {
// ...
}
}
```
### Exemplo de código – Anti padrão
```javascript
// lançar uma string não possui informações de rastreamento de stack e outras propriedades de dados importantes
if(!productToAdd)
throw ("Como posso adicionar um novo produto quando nenhum valor é fornecido?");
```
### Exemplo de código - fazendo isso ainda melhor
```javascript
// Objeto de erro centralizado que deriva do Error do Node
function AppError(name, httpCode, description, isOperational) {
Error.call(this);
Error.captureStackTrace(this);
this.name = name;
//...outras propriedades atribuídas aqui
};
AppError.prototype = Object.create(Error.prototype);
AppError.prototype.constructor = AppError;
module.exports.AppError = AppError;
// cliente jogando uma exceção
if(user == null)
throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "mais explicações", true)
```
### Citação de Blog: "Não vejo o valor em ter vários tipos diferentes"
Do blog, Ben Nadel classificado como 5 para as palavras-chave “Node.js error object”
>…”Pessoalmente, não vejo o valor em ter vários tipos diferentes de objetos de erro – JavaScript, como uma linguagem, não parece atender à captura de erros baseada em construtor. Como tal, diferenciar em uma propriedade de objeto parece muito mais fácil do que diferenciar em um tipo Construtor…
### Citação de Blog: "Uma string não é um erro"
Do blog, devthought.com classificado como 6 para as palavras-chave “Node.js error object”
> …passar uma string em vez de um erro resulta em interoperabilidade reduzida entre os módulos. Isso quebra relações com APIs que podem estar realizando checagens `instanceof` Error, ou que querem saber mais sobre o erro. Objetos Error, como veremos, têm propriedades muito interessantes em mecanismos modernos de JavaScript, além de manter a mensagem transmitida ao construtor…
### Citação de Blog: "Herdar de Error não adiciona muito valor"
Do blog machadogj
> …Um problema que eu tenho com a classe Error é que não é tão simples estendê-la. Claro, você pode herdar a classe e criar suas próprias classes Error como HttpError, DbError, etc. No entanto, isso leva tempo e não acrescenta muito valor, a menos que você esteja fazendo algo com tipos. Às vezes, você só quer adicionar uma mensagem e manter o erro interno, e às vezes você pode querer estender o erro com parâmetros, e tal…
### Citação do Blog: "Todos os erros do sistema e do JavaScript levantados pelo Node.js herdam de Error"
Da documentação oficial do Node.js
> …Todos os erros de JavaScript e do sistema gerados pelo Node.js herdam ou são instâncias da classe padrão Error do JavaScript e têm a garantia de fornecer pelo menos as propriedades disponíveis nessa classe. Um objeto genérico Erro de JavaScript que não denota nenhuma circunstância específica de por que o erro ocorreu. Objetos Error capturam um "rastreamento de stack" detalhando o ponto no código no qual o Erro foi instanciado e podem fornecer uma descrição do erro em texto. Todos os erros gerados pelo Node.js, incluindo todos os erros de sistema e JavaScript, serão instâncias ou herdarão da classe Error…
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.chinese.md
================================================
# 仅使用内建的错误对象
### 一段解释
JS天生的宽容性及其多变的代码流选项(例如 EventEmitter, Callbacks, Promises等等)使得开发者有太多引发错误的方式 – 有些人使用字符串,有些人使用自定义的类型。使用Node.js的内置错误对象有助于在你的代码和第三方库之间保持一致性,它还保留了重要信息,比如StackTrace。当引发异常时,给异常附加上下文属性(如错误名称和相关的HTTP错误代码)通常是一个好的习惯。要实现这种一致性和实践,请考虑使用附加属性扩展错误对象,见下面的代码示例。
### 代码示例 – 正确做法
```javascript
//从典型函数抛出错误, 无论是同步还是异步
if(!productToAdd)
throw new Error("How can I add new product when no value provided?");
//从EventEmitter抛出错误
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
//从promise抛出错误
return new promise(function (resolve, reject) {
Return DAL.getProduct(productToAdd.id).then((existingProduct) => {
if(existingProduct != null)
reject(new Error("Why fooling us and trying to add an existing product?"));
```
### 代码示例 – 反例
```javascript
//抛出字符串错误缺少任何stack trace信息和其他重要属性
if(!productToAdd)
throw ("How can I add new product when no value provided?");
```
### 代码示例 – 更好做法
```javascript
//从node错误派生的集中错误对象
function appError(name, httpCode, description, isOperational) {
Error.call(this);
Error.captureStackTrace(this);
this.name = name;
//...在这赋值其它属性
};
appError.prototype = 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)
```
### 博客引用:“I don’t see the value in having lots of different types”
摘自博客Ben Nadel, 对于关键字“Node.JS错误对象”,排名第五
> … 就我个人而言,我没看到弄很多不同类型的错误对象的价值 – JavaScript作为一种语言,似乎不适合基于构造函数的错误捕获。因此,区分对象属性似乎比区分构造函数类型容易得多…
### 博客引用: "字符串不是错误"
摘自博客 devthought.com, 对于关键字 “Node.JS error object” 排名第6
> … 传递字符串而不是错误会导致模块间协作性降低。它打破了和API的约定,可能在执行`instanceof`这样的错误检查,或想了解更多关于错误的信息。正如我们将看到的,错误对象在现代JavaScript引擎中拥有非常有趣的属性,同时保留传递给构造函数的消息…
### 博客引用: "从Error对象继承不会增加太多的价值"
摘自博客 machadogj
> … 我对Error类的一个问题是不太容易扩展。当然, 您可以继承该类并创建自己的Error类, 如HttpError、DbError等。然而, 这需要时间, 并且不会增加太多的价值, 除非你是在做一些关于类型的事情。有时, 您只想添加一条消息, 并保留内部错误, 有时您可能希望使用参数扩展该错误, 等等…
### 博客引用: "Node.js引发的所有JavaScript和系统错误都继承自Error"
摘自 Node.JS 官方文档
> … Node.js引发的所有JavaScript和系统错误继承自,或是JavaScript标准错误类的实例, 这保证至少提供了该类的可用属性。一个通用的JavaScript错误对象, 它不表示错误为什么发生的任何特定环境。错误对象捕获一个"stack trace", 详细说明了错误被实例化时在代码中的点, 并可能提供错误的文本描述。由Node.js生成的所有错误, 包括所有的系统和JavaScript错误, 都将是Error类的实例, 或继承自Error类 …
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.french.md
================================================
# 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…
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.japanese.md
================================================
# 組み込みのエラーオブジェクトのみを使用する
### 一段落説明
多くのコードフローの選択肢(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 クラスのインスタンスであるか、クラスを継承したものとなるでしょう…
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.korean.md
================================================
# 내장된 Error 객체만 사용하라
### 한문단 설명
다양한 코드 흐름 옵션(예:EventEmitter, Callbacks, Promises 등)과 함께 JS의 허용 가능한 특성은 개발자가 오류를 발생시키는 방법에 큰 차이를 둔다. – 일부 개발자들은 문자열을 사용하고, 일부는 그들만의 커스텀 타입을 정의한다. Node.js 내장 Error 객체를 사용하면 당신의 코드와 제 3자 라이브러리의 균일성을 유지할 수 있도록 도와주며, 또한 스택정보(StrackTrace)와 같은 중요한 정보도 보존할 수 있다. 예외가 발생할 때, 일반적으로 오류 이름이나 관련 HTTP 오류 코드같은 상황별로 추가적인 속성으로 채우는 것이 좋은 방법이다. 이 균일성과 관행을 얻을려면, Error 객체를 추가 속성으로 확장하라, 아래 코드 예 참조
### 코드 예시 – 제대로 하기
```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) {
// ...
}
}
```
### 코드 예시 - 좋지않은 패턴
```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?");
```
### 코드 예시 - 훨씬 더 좋다
```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)
```
### 블로그 인용: "여러 가지 유형이 있다는 것은 가치가 없다고 본다"
Ben Nadel 블로그에서 "Node.js error 객체" 키워드 5위에 위치했다.
>…”개인적으로, 여러 가지 유형이 있다는 것은 가치가 없다고 본다 – 언어로서의 자바스크립트는 생성자 기반의 오류 파악에 적합하지 않은 것 같다. 따라서, 객체 속성에서 구별하는 것이 생성자 유형에서 구분하는 것보다 훨씬 쉬운 것 같다…
### 블로그 인용: "문자열은 오류가 아니다"
devthought.com 블로그에서 "Node.js error 객체" 키워드 6위에 위치했다.
> …오류 대신 문자열을 전달함으로써 모듈 간의 상호운용성이 줄어들었다. 문자열을 사용하면 `instanceof` 에러로 검사하는 API 계약을 깨뜨리는 데다가 오류의 자세한 정보도 알기 어렵다. 뒤에서 설명하겠지만, 최신 자바스크립트 엔진의 Error 객체에는 유용한 속성을 많이 있으며 생성자에 전달된 메시지도 포함된다…
### 블로그 인용: "에러로 부터 상속해도 많은 값을 추가하지 않는다"
machadogj 블로그에서
> …Error 클래스와 관련된 한 가지 문제는 확장하기가 그리 간단하지 않다는 것이다. 물론 클래스를 상속하고 HttpError, DbError 등 자신만의 에러 클래스를 만들 수 있다. 그러나, 당신이 타입으로 무엇인가를 하지 않는 한 이것은 시간이 걸리며 많은 값을 추가하지 않는다. 때로 당신은 메시지 추가와 내부 에러를 유지하길 원하고 때로는 매개 변수를 사용하여 에러를 확장하길 원할 것이다, 등등…
### 블로그 인용: "모든 자바스크립트와 시스템 에러들은 node.js이 상속한 에러로 부터 발생한다"
Node.js 공식문서에서
> …Node.js에 의해 발생된 모든 자바스크립트 및 시스템 에러는 표준 자바스크립트 에러 클래스에서 상속되거나 표준 자바스크립트 에러 클래스의 인스턴스이며 최소한 그 클래스에서 사용할 수 있는 속성을 제공할 수 있도록 보장된다. 에러가 발생한 이유에 대한 특정 상황을 나타내지 않는 일반 자바스크립트 에러 객체. 에러 객체는 에러가 인스턴스화된 코드에서 포인트를 자세히 설명하는 "스택 추적"을 캡처(capture)하며, 에러에 대한 텍스트 설명을 제공할 수도 있다. 모든 시스템과 자바스크립트 에러를 포함한 Node.js에 의해, 생성된 모든 에러는, 에러 클래스의 인스턴스이거나, 상속 받은 것이다.…
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.md
================================================
# Use only the built-in Error object
### 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, 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
```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) {
// ...
}
}
```
### Code example – Anti Pattern
```javascript
// throwing a string lacks any stack trace information and other important data properties
if(!productToAdd)
throw ('How can I add new product when no value provided?');
```
### Code example – doing it even better
Javascript
```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)
```
*Explanation about the `Object.setPrototypeOf` in Typescript: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget*
### Blog Quote: "I don’t see the value in having lots of different types"
From the blog, Ben Nadel ranked 5 for the keywords “Node.js error object”
>…”Personally, I don’t see the value in having lots of different types of error objects [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"
From the blog, devthought.com ranked 6 for the keywords “Node.js error object”
> …passing a string instead of an error results in reduced interoperability between modules. It breaks contracts with APIs that might be performing `instanceof` Error checks, or that want to know more about the error. Error objects, as we’ll see, have very interesting properties in modern JavaScript engines besides holding the message passed to the constructor…
### Blog Quote: "Inheriting from Error doesn’t add too much value"
From the blog machadogj
> …One problem that I have with the Error class is that is not so simple to extend. Of course, you can inherit the class and create your own Error classes like HttpError, DbError, etc. However, that takes time and doesn’t add too much value [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"
From Node.js official documentation
> …All JavaScript and System errors raised by Node.js inherit from, or are instances of, the standard JavaScript Error class and are guaranteed to provide at least the properties available on that class. A generic JavaScript Error object that does not denote any specific circumstance of why the error occurred. Error objects capture a “stack trace” detailing the point in the code at which the Error was instantiated, and may provide a text description of the error. All errors generated by Node.js, including all System and JavaScript errors, will either be instances of or inherit from, the Error class…
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.polish.md
================================================
# 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…
================================================
FILE: sections/errorhandling/useonlythebuiltinerror.russian.md
================================================
# Используйте только встроенный объект Error
### Объяснение в один абзац
Гибкая природа JavaScript наряду с его разнообразием вариантов потока кода (например, EventEmitter, Callbacks, Promises и т.д.) приводит к значительному расхождению в том, как разработчики выдают ошибки - некоторые используют строки, другие определяют свои собственные пользовательские типы. Использование встроенного объекта Error в Node.js помогает сохранить единообразие в вашем коде, а с помощью сторонних библиотек он также сохраняет важную информацию, такую как StackTrace. При возникновении исключения обычно рекомендуется заполнить его дополнительными контекстными свойствами, такими как имя ошибки и связанный код ошибки HTTP. Чтобы добиться этого единообразия и практики, рассмотрите возможность расширения объекта Error дополнительными свойствами, см. пример кода ниже.
### Пример кода - делай все правильно
```javascript
// пробрасываем Error из типичной async или sync функции
if(!productToAdd)
throw new Error('How can I add new product when no value provided?');
// пробрасываем Error из EventEmitter
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// пробрасываем Error из 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
// пробрасывая строку, теряем информацию о stack trace и другие важные параметры
if(!productToAdd)
throw ('How can I add new product when no value provided?');
```
### Пример кода - делаем еще лучше
Javascript
```javascript
// главные объект ошибки производный от нодовского Error
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
// главные объект ошибки производный от нодовского 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 …
### Цитата блога: "Строка не является ошибкой"
Из блога devthought.com, занял 6 место по ключевым словам "Объект ошибки Node.js"
> … передача строки вместо ошибки приводит к снижению совместимости между модулями. Это нарушает контракты с API, которые могут выполнять проверки ошибок с помощью instanceof или хотят узнать больше об ошибке. Объекты ошибок, как мы увидим, обладают очень интересными свойствами в современных механизмах JavaScript, помимо хранения сообщения, переданного конструктору …
### Цитата из блога: "Наследование от ошибки не увеличивает их ценность"
Из блога Machadogj
> … Одна проблема, которую я имею с классом Error, заключается в том, что его не так просто расширить. Конечно, вы можете наследовать класс и создавать свои собственные классы ошибок, такие как HttpError, DbError и т.д. Однако это занимает время и не добавляет слишком много значения, если вы не делаете что-то с типами. Иногда вам просто нужно добавить сообщение и сохранить внутреннюю ошибку, а иногда вам может понадобиться расширить ошибку с помощью параметров, и так далее …
### Цитата из блога: "Все ошибки JavaScript и системы, возникающие в Node.js, наследуются от Error"
Из официальной документации Node.js
> … Все ошибки JavaScript и System, возникающие в Node.js, наследуются или являются экземплярами стандартного класса JavaScript Error и гарантированно предоставляют как минимум свойства, доступные в этом классе. Общий объект JavaScript Error, который не обозначает каких-либо конкретных обстоятельств, по которым произошла ошибка. Объекты ошибок фиксируют "трассировку стека", детализирующую точку в коде, в которой был создан экземпляр ошибки, и могут предоставлять текстовое описание ошибки. Все ошибки, сгенерированные Node.js, включая все системные ошибки и ошибки JavaScript, будут либо экземплярами класса Error, либо наследоваться от него …
================================================
FILE: sections/examples/dockerfile/.dockerignore
================================================
node_modules/
.git
README.md
LICENSE
.vscode
.idea
npm-debug.log
coverage
.env
.editorconfig
.aws
dist
.npmrc
================================================
FILE: sections/examples/dockerfile/.npmrc
================================================
================================================
FILE: sections/examples/dockerfile/Dockerfile
================================================
# 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" ]
================================================
FILE: sections/examples/dockerfile/package.json
================================================
{
"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"
}
}
================================================
FILE: sections/examples/dockerfile/src/app.ts
================================================
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');
});
================================================
FILE: sections/performance/block-loop.basque.md
================================================
# 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)
================================================
FILE: sections/performance/block-loop.french.md
================================================
# 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)
================================================
FILE: sections/performance/block-loop.japanese.md
================================================
# イベントループをブロックしない
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)
================================================
FILE: sections/performance/block-loop.md
================================================
# 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)
================================================
FILE: sections/performance/block-loop.polish.md
================================================
# 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)
================================================
FILE: sections/performance/block-loop.russian.md
================================================
# Не блокируйте цикл событий
Node обрабатывает цикл событий в основном в одном потоке, вращающемся через несколько очередей. Операции с высокой сложностью, большой анализ json, применение логики к огромным массивам, небезопасные запросы регулярных выражений и большие операции ввода-вывода - вот некоторые из операций, которые могут привести к остановке цикла обработки событий. Передавайте такие нагрузки ресурсоемких задач в выделенную службу (например, сервер заданий) или разбивайте длинные задачи на маленькие шаги, а затем используйте рабочий пул - вот некоторые примеры того, как избежать блокировки цикла обработки событий.
### 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('/', (req, res, next) => {
sleep(30)
res.send({})
next()
})
```
И когда мы тестируем это приложение, мы начинаем видеть задержку, вызванную длительным
while loop.
### Запуск теста тест
`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 работает быстро, когда работа, связанная с каждым клиентом в любой момент времени, "мала".
>[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)
================================================
FILE: sections/performance/nativeoverutil.basque.md
================================================
# 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.
================================================
FILE: sections/performance/nativeoverutil.brazilian-portuguese.md
================================================
# Prefira métodos nativos ao invés de utilitários do usuário como Lodash
### Explicação em um Parágrafo
Às vezes, usar métodos nativos é melhor do que requerir `lodash` ou `underscore`, porque isso não levará a um aumento de desempenho e usará mais espaço do que o necessário.
O desempenho usando métodos nativos resulta em um [ganho geral de 50%](https://github.com/Berkmann18/NativeVsUtils/blob/master/analysis.xlsx) que inclui os seguintes métodos: `Array.concat`, `Array.fill`, `Array.filter`, `Array.map`, `(Array|String).indexOf`, `Object.find`, ...
### Exemplo: comparação de benchmark - Lodash vs V8 (Nativo)
O gráfico abaixo mostra a [média dos benchmarks para uma variedade de métodos do Lodash](https://github.com/Berkmann18/NativeVsUtils/blob/master/nativeVsLodash.ods), Isso mostra que os métodos Lodash levam em média 146,23% mais tempo para completar as mesmas tarefas que os métodos V8.

### Exemplo de código – teste de Benchmark com `_.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 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 });
```
Que retornará isso:

Você pode encontrar uma lista maior de benchmarks [aqui](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.txt) ou alternativamente [executar isso](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.js) que mostraria o mesmo porém com cores.
### Citação de Blog: "Você (talvez) não precisa de Lodash/Underscore"
Do [repositório sobre esse assunto que foca em Lodash e Underscore](https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore).
> 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).
A maneira de configurá-lo é adicionando o plugin `eslint-plugin-you-dont-need-lodash-underscore` no seu arquivo de configuração do ESLint:
```json
{
"extends": [
"plugin:you-dont-need-lodash-underscore/compatible"
]
}
```
### Exemplo: detectando uso de utilidades não nativas do v8 usando um linter
Considere o arquivo abaixo:
```js
const _ = require('lodash');
// O ESLint sinalizará a linha acima com uma sugestão
console.log(_.map([0, 1, 2, 4, 8, 16], x => `d${x}`));
```
Aqui está o que o ESLint produziria ao usar o plugin YDNLU.

Naturalmente, o exemplo acima não parece realista, considerando o que bases de código reais teriam, mas você entendeu a idéia.
================================================
FILE: sections/performance/nativeoverutil.french.md
================================================
# 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.
================================================
FILE: sections/performance/nativeoverutil.japanese.md
================================================
# Lodash のようなユーザーランドのユーティリティよりも、ネイティブの JS メソッドを選ぶ
### 一段落説明
_lodash_ や _underscore_ を require するよりもネイティブメソッドを使う方が良い場合もあります。なぜなら、これらのライブラリは、パフォーマンスの低下や必要以上にスペースを占有する可能性があるからです。
以下のメソッドを含む、ネイティブメソッドを使用した場合のパフォーマンスは、 [全体的に ~50% 向上](https://github.com/Berkmann18/NativeVsUtils/blob/master/analysis.xlsx) になります: `Array.concat`, `Array.fill`, `Array.filter`, `Array.map`, `(Array|String).indexOf`, `Object.find`, ...
### 例: ベンチマーク比較 - Lodash vs V8 (Native)
下のグラフは、[様々な Lodash メソッドのベンチマークの平均](https://github.com/Berkmann18/NativeVsUtils/blob/master/nativeVsLodash.ods) を示しています。このグラフから、Lodash メソッドは V8 メソッドと同じタスクを完了するのに平均146.23%も時間がかかることがわかります。

### コード例 – `_.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 });
```
これは以下のような結果になります:

ベンチマークの大きなリストは[ここ](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.txt) にあります。あるいは、同じように色をつけて表示される [run this](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.js) にもあります。
### ブログ引用: "You don't (may not) need Lodash/Underscore ( Lodash / Underscore は必要ありません(必要ないかもしれません)。)"
[repo on this matter which focuses on Lodash and Underscore(Lodash と Underscore を中心としたこの件についてのリポジトリ)](https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore) より
> Lodash や Underscore は素晴らしいモダンな JavaScript ユーティリティライブラリであり、フロントエンド開発者に広く利用されています。しかし、最新のブラウザをターゲットにしている場合、ECMAScript5 [ES5] や ECMAScript2015 [ES6] のおかげで、すでにネイティブでサポートされているメソッドがたくさんあることに気づくかもしれません。プロジェクトに必要な依存関係を少なくしたく、ターゲットブラウザを明確に理解している場合は、Lodash/Underscore は必要ないかもしれません。
### 例: 非ネイティブメソッドの使用法に対応した Lint
ライブラリを使っているが必要のない場所を検知して、提案付きで警告してくれる[ ESLint プラグイン](https://www.npmjs.com/package/eslint-plugin-you-dont-need-lodash-underscore)というものがあります。(下の例を参照)
設定方法は、ESLint の設定ファイルに `eslint-plugin-you-dont-need-lodash-underscore` プラグインを追加することです:
```json
{
"extends": [
"plugin:you-dont-need-lodash-underscore/compatible"
]
}
```
### 例: linter を使用した非 v8 ユーティリティの使用状況の検出
以下のファイルのようにすることを検討してみてください:
```js
const _ = require('lodash');
// ESLint は上の行に提案のフラグを立てます。
console.log(_.map([0, 1, 2, 4, 8, 16], x => `d${x}`));
```
YDNLU プラグインを使った場合の ESLint の出力は以下の通りです。

もちろん、上の例は、実際のコードベースがどのようなものであるかを考えると、現実的ではないように思えますが、アイデアを得ることはできます。
================================================
FILE: sections/performance/nativeoverutil.md
================================================
# 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.
================================================
FILE: sections/performance/nativeoverutil.polish.md
================================================
# 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ł.
================================================
FILE: sections/performance/nativeoverutil.russian.md
================================================
# Предпочитайте нативные методы JS над пользовательскими утилитами, такими как Lodash
### Объяснение в один абзац
Иногда использовать нативные методы лучше, чем привязывать `lodash` или `underscore`, потому что это не приведет к повышению производительности и использованию большего пространства, чем необходимо.
Результативность с использованием собственных методов приводит к [общему увеличению ~ 50%](https://github.com/Berkmann18/NativeVsUtils/blob/master/analysis.xlsx), который включает следующие методы: `Array.concat`, `Array.fill`, `Array.filter`, `Array.map`, `(Array|String).indexOf`, `Object.find`, ...
### Пример: сравнение производительности - Lodash vs V8 (Native)
На приведенном ниже графике показано [среднее из эталонных показателей для различных методов Lodash](https://github.com/Berkmann18/NativeVsUtils/blob/master/nativeVsLodash.ods), это показывает, что методы Lodash занимают в среднем на 146,23% больше время для выполнения тех же задач, что и методы V8.

### Пример кода - бенчмарк-тест для `_.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 });
```
Который возвращает это:

Вы можете найти больший список тестов [здесь](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.txt) или альтернативно [запустить это](https://github.com/Berkmann18/NativeVsUtils/blob/master/index.js), который показывает то же самое, но в цвете.
### Цитата блога: "Вам не нужно (не нужно) Lodash/Underscore"
Из [репо по этому вопросу, в котором основное внимание уделяется Lodash и Underscore](https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore).
> 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-plugin-you-dont-need-lodash-underscore` в файл конфигурации ESLint:
```json
{
"extends": [
"plugin:you-dont-need-lodash-underscore/compatible"
]
}
```
### Пример: обнаружение использования утилит не-v8 с использованием линтера
Рассмотрим файл ниже:
```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}`));
```
Вот что ESLint будет выводить при использовании плагина YDNLU.

Конечно, приведенный выше пример не выглядит реалистичным, если учесть, какие будут исходные кодовые базы, но вы поняли идею.
================================================
FILE: sections/production/LTSrelease.basque.md
================================================
# 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.
================================================
FILE: sections/production/LTSrelease.brazilian-portuguese.md
================================================
# Use uma versão LTS do Node.js em produção
### Explicação em um Parágrafo
Verifique se você está usando uma versão LTS (Long Term Support) do Node.js em produção para receber correções de bugs críticos, atualizações de segurança e melhorias de desempenho.
As versões LTS do Node.js são suportadas por pelo menos 18 meses e são indicadas por números de versão pares (por exemplo, 4, 6, 8). Eles são melhores para produção, já que a linha de lançamento LTS é focada em estabilidade e segurança, enquanto a linha de lançamento 'Atual' tem uma vida útil mais curta e atualizações mais frequentes no código. As alterações nas versões LTS estão limitadas a correções de bugs para estabilidade, atualizações de segurança, possíveis atualizações npm, atualizações de documentação e certos aprimoramentos de desempenho que podem ser demonstrados para não interromper aplicações. existentes.
### Leia em
🔗 [Definições de lançamento do Node.js](https://nodejs.org/en/about/releases/)
🔗 [Agenda de lançamento do Node.js](https://github.com/nodejs/Release)
🔗 [Etapas Essenciais: Suporte de Longo Prazo para o Node.js por Rod Vagg](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
> ...o cronograma de lançamentos incrementais dentro de cada um deles será impulsionado pela disponibilidade de correções de bugs, correções de segurança e outras pequenas, mas importantes, alterações. O foco será na estabilidade, mas a estabilidade também inclui a minimização do número de bugs conhecidos e a manutenção das preocupações de segurança à medida que elas surgem.
================================================
FILE: sections/production/LTSrelease.chinese.md
================================================
# 使用 Node.js 的 LTS 版本
### 一段解释
确保您在正式环境中使用的是LTS(长期支持)版本的Node.js来获取关键错误的修复、安全更新和性能改进.
LTS版本的Node.js至少支持18个月,并由偶数版本号(例如 4、6、8)表示。它们最适合生产环境,因为LTS的发行线专注于稳定性和安全性,而“Current”版本发布寿命较短,代码更新更加频繁。LTS版本的更改仅限于稳定性错误修复、安全更新、合理的npm更新、文档更新和某些可以证明不会破坏现有应用程序的性能改进。
### 继续读下去
🔗 [ 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)
> ...每个增量发布计划将由错误修复、安全修复和其他小但重要的更改的可用性来驱动。重点将放在稳定性上,但稳定性还包括最大程度地减少已知错误的数量,和持续关注重大的安全问题。
================================================
FILE: sections/production/LTSrelease.french.md
================================================
# 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.
================================================
FILE: sections/production/LTSrelease.japanese.md
================================================
# Node.js の LTS リリースをプロダクションで使用する
### 一段落説明
重要なバグ修正、セキュリティアップデート、パフォーマンスの改善を受けるために、本番環境で Node.js の LTS(Long Term Support) バージョンを使用していることを確認してください。
Node.js の LTS バージョンは少なくとも18ヶ月間サポートされており、偶数のバージョン番号(例えば4, 6, 8)で示されています。LTS のリリースラインは安定性とセキュリティに焦点を当てているので、運用には最適ですが、「Current」 のリリースラインは寿命が短く、コードの更新がより頻繁に行われます。LTS のバージョンへの変更は、安定性のためのバグ修正、セキュリティ更新、可能な npm の更新、ドキュメントの更新、既存のアプリケーションを壊さないことが証明できる特定のパフォーマンスの改善に限定されます。
### 続きを読む
🔗 [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)
> ...これらの中での増分リリースのスケジュールは、バグ修正、セキュリティ修正、その他の小さいが重要な変更の有無によって決定されます。安定性に重点が置かれますが、安定性には既知のバグの数を最小限に抑え、セキュリティ上の懸念事項が発生した場合には、それを常に把握しておくことも含まれます。
================================================
FILE: sections/production/LTSrelease.korean.md
================================================
# Use an LTS release of Node.js in production
### One Paragraph Explainer
Ensure you are using an LTS(Long Term Support) version of Node.js in production to receive critical bug fixes, security updates and performance improvements.
LTS versions of Node.js are supported for at least 18 months and are indicated by even version numbers (e.g. 4, 6, 8). They're best for production since the LTS release line is focussed on stability and security, whereas the 'Current' release line has a shorter lifespan and more frequent updates to the code. Changes to LTS versions are limited to bug fixes for stability, security updates, possible npm updates, documentation updates and certain performance improvements that can be demonstrated to not break existing applications.
### Read on
🔗 [Node.js release definitions](https://nodejs.org/en/about/releases/)
🔗 [Node.js release schedule](https://github.com/nodejs/Release)
🔗 [Essential Steps: Long Term Support for Node.js by Rod Vagg](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
> ...the schedule of incremental releases within each of these will be driven by the availability of bug fixes, security fixes, and other small but important changes. The focus will be on stability, but stability also includes minimizing the number of known bugs and staying on top of security concerns as they arise.
================================================
FILE: sections/production/LTSrelease.md
================================================
# Use an LTS release of Node.js in production
### One Paragraph Explainer
Ensure you are using an LTS(Long Term Support) version of Node.js in production to receive critical bug fixes, security updates and performance improvements.
LTS versions of Node.js are supported for at least 18 months and are indicated by even version numbers (e.g. 4, 6, 8). They're best for production since the LTS release line is focussed on stability and security, whereas the 'Current' release line has a shorter lifespan and more frequent updates to the code. Changes to LTS versions are limited to bug fixes for stability, security updates, possible npm updates, documentation updates and certain performance improvements that can be demonstrated to not break existing applications.
### Read on
🔗 [Node.js release definitions](https://nodejs.org/en/about/releases/)
🔗 [Node.js release schedule](https://github.com/nodejs/Release)
🔗 [Essential Steps: Long Term Support for Node.js by Rod Vagg](https://medium.com/@nodesource/essential-steps-long-term-support-for-node-js-8ecf7514dbd)
> ...the schedule of incremental releases within each of these will be driven by the availability of bug fixes, security fixes, and other small but important changes. The focus will be on stability, but stability also includes minimizing the number of known bugs and staying on top of security concerns as they arise.
================================================
FILE: sections/production/LTSrelease.polish.md
================================================
# 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.
================================================
FILE: sections/production/LTSrelease.russian.md
================================================
# Используйте LTS-релиз Node.js в производстве
### Объяснение в один абзац
Убедитесь, что вы используете LTS (Long Term Support) версию Node.js в работе, чтобы получать критические исправления ошибок, обновления безопасности и улучшения производительности.
LTS-версии Node.js поддерживаются в течение не менее 18 месяцев и обозначаются четными номерами версий (например, 4, 6, 8). Они лучше всего подходят для производства, поскольку линия выпуска LTS ориентирована на стабильность и безопасность, тогда как линия выпуска "текущий" имеет более короткий срок службы и более частые обновления кода. Изменения в версиях LTS ограничены исправлениями ошибок для стабильности, обновлениями безопасности, возможными обновлениями npm, обновлениями документации и некоторыми улучшениями производительности, которые можно продемонстрировать, чтобы не сломать существующие приложения.
### Читать еще
🔗 [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)
> ... график дополнительных выпусков в каждом из них будет зависеть от наличия исправлений ошибок, исправлений безопасности и других небольших, но важных изменений. Основное внимание будет уделяться стабильности, но стабильность также включает в себя минимизацию количества известных ошибок и устранение проблем безопасности по мере их возникновения.
================================================
FILE: sections/production/apmproducts.basque.md
================================================
# Erabiltzaile esperientzia segurua APM produktuekin
### 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

================================================
FILE: sections/production/apmproducts.brazilian-portuguese.md
================================================
# Descubra erros e tempo de inatividade usando produtos APM
### Explicação em um Parágrafo
O APM (monitoramento de desempenho de aplicação) refere-se a uma família de produtos que visa monitorar o desempenho da aplicação de ponta a ponta, também da perspectiva do cliente. Enquanto as soluções de monitoramento tradicionais se concentram em exceções e métricas técnicas autônomas (por exemplo, rastreamento de erros, pontos de extremidade de servidor lentos etc.), no mundo real nossa aplicação sem exceções de código pode criar usuários decepcionados, por exemplo, se algum serviço de middleware for executado muito lentamente. Os produtos APM medem a experiência do usuário de ponta a ponta, por exemplo, dado um sistema que engloba a UI frontend e vários serviços distribuídos - alguns produtos APM podem dizer quão rápido dura uma transação que abrange vários níveis. Pode dizer se a experiência do usuário é sólida e apontar para o problema. Essa oferta atrativa vem com um preço relativamente alto, portanto, é recomendada para produtos complexos e em larga escala que exigem ir além do monitoramento direto.
### 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

================================================
FILE: sections/production/apmproducts.chinese.md
================================================
# 使用APM产品确保用户体验
### 一段解释
APM(应用程序性能监视)指的是一个产品系列, 目的是从端到端,也从客户的角度监控应用程序的性能。虽然传统的监控解决方案侧重于异常和独立的技术指标 (例如错误跟踪、检测慢速服务器节点等), 在现实世界中, 我们的应用程序可能会在没有任何代码异常的情况下让用户使用起来感到失望, 例如, 如果某些中间件服务执行得非常慢。APM 产品从端到端检测用户体验, 例如, 给定一个包含前端 UI 和多个分布式服务的系统 – 一些 APM 产品可以告诉您, 一个跨过多个层的事务的速度有多快。它可以判断用户体验是否可靠, 并指出问题所在。这种诱人的产品通常有一个相对较高的价格标签, 因此, 对于需要超越一般的监测的,大规模的和复杂的产品, 它们是值得推荐的。
### APM 示例 – 一种可视化显示跨服务应用性能的商业产品

### APM 示例 – 一种强调用户体验评分的商业产品

### APM 示例 – 一种突出显示慢速代码路径的商业产品

================================================
FILE: sections/production/apmproducts.french.md
================================================
# 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

================================================
FILE: sections/production/apmproducts.japanese.md
================================================
# APM 製品の確かなユーザー体験
### 一段落説明
APM(アプリケーション・パフォーマンス・モニタリング)とは、エンド・ツー・エンド、また顧客の視点からアプリケーションのパフォーマンスを監視することを目的とした製品群のことです。従来のモニタリングソリューションでは、例外やスタンドアローンの技術的なメトリクス(エラー追跡、遅いサーバーエンドポイントなど)に焦点を当てていましたが、現実の世界では、例えば、あるミドルウェアサービスが実際に遅い動作をしていた場合など、コードの例外がなくても、私たちのアプリがユーザーを失望させる可能性があります。APM 製品は、例えばフロントエンドの UI と複数の分散サービスを含むシステムを想定して、エンド・ツー・エンドまでのユーザーエクスペリエンスを測定します。 – APM 製品の中には、複数の階層にまたがるトランザクションがどのくらいの速さで最後まで実行されるかを伝えることができるものがあります。ユーザー体験がしっかりしているかどうかが分かり、問題点を指摘してくれます。この魅力的な製品は比較的高い価格帯で提供されているため、単純なモニタリングの域を超えた大規模で複雑なプロダクトにお勧めです。
### APM の例 – サービス間のアプリパフォーマンスを可視化する商用製品

### APM の例 – ユーザーエクスペリエンススコアを重視した市販品

### APM の例 – 遅いコードパスをハイライトする商用製品

================================================
FILE: sections/production/apmproducts.korean.md
================================================
# Sure user experience with APM products
### One Paragraph Explainer
APM (application performance monitoring) refers to a family of products that aims to monitor application performance from end to end, also from the customer perspective. While traditional monitoring solutions focus on Exceptions and standalone technical metrics (e.g. error tracking, slow server endpoints, etc), in the real world our app might create disappointed users without any code exceptions, for example, if some middleware service performed real slow. APM products measure the user experience from end to end, for example, given a system that encompasses frontend UI and multiple distributed services – some APM products can tell how fast a transaction that spans multiple tiers last. It can tell whether the user experience is solid and point to the problem. This attractive offering comes with a relatively high price tag hence it’s recommended for large-scale and complex products that require going beyond straightforward monitoring.
### APM example – a commercial product that visualizes cross-service app performance

### APM example – a commercial product that emphasizes the user experience score

### APM example – a commercial product that highlights slow code paths

================================================
FILE: sections/production/apmproducts.md
================================================
# Sure user experience with APM products
### One Paragraph Explainer
APM (application performance monitoring) refers to a family of products that aims to monitor application performance from end to end, also from the customer perspective. While traditional monitoring solutions focus on Exceptions and standalone technical metrics (e.g. error tracking, slow server endpoints, etc), in the real world our app might create disappointed users without any code exceptions, for example, if some middleware service performed real slow. APM products measure the user experience from end to end, for example, given a system that encompasses frontend UI and multiple distributed services – some APM products can tell how fast a transaction that spans multiple tiers last. It can tell whether the user experience is solid and point to the problem. This attractive offering comes with a relatively high price tag hence it’s recommended for large-scale and complex products that require going beyond straightforward monitoring.
### APM example – a commercial product that visualizes cross-service app performance

### APM example – a commercial product that emphasizes the user experience score

### APM example – a commercial product that highlights slow code paths

================================================
FILE: sections/production/apmproducts.polish.md
================================================
# 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

================================================
FILE: sections/production/apmproducts.russian.md
================================================
# Уверенный пользовательский опыт с продуктами APM
### Объяснение в один абзац
APM (мониторинг производительности приложений) относится к семейству продуктов, целью которых является мониторинг производительности приложений от конца до конца, в том числе с точки зрения клиента. В то время как традиционные решения мониторинга ориентированы на исключения и автономные технические метрики (например, отслеживание ошибок, медленные конечные точки сервера и т.д.), В реальном мире наше приложение может создавать разочарованных пользователей без каких-либо исключений кода, например, если какая-то служба промежуточного программного обеспечения работает очень медленно. Продукты APM измеряют пользовательский опыт от начала до конца, например, с учетом системы, которая включает интерфейсный интерфейс пользователя и несколько распределенных сервисов - некоторые продукты APM могут определить, как быстро выполняется транзакция, охватывающая несколько уровней. Это может сказать, является ли пользовательский опыт твердым и указывает на проблему. Это привлекательное предложение имеет относительно высокую цену, поэтому оно рекомендуется для крупномасштабных и сложных продуктов, которые требуют выхода за рамки простого мониторинга.
### Пример APM - коммерческий продукт, который визуализирует производительность кросс-сервисного приложения

### Пример APM - коммерческий продукт, который подчеркивает оценку пользовательского опыта

### Пример APM - коммерческий продукт, который выделяет медленные пути кода

================================================
FILE: sections/production/assigntransactionid.basque.md
================================================
# 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")}`);
}
}
```
================================================
FILE: sections/production/assigntransactionid.brazilian-portuguese.md
================================================
# Atribua‘TransactionId’ para cada declaração de log
### Explicação em um Parágrafo
Um log típico é um armazém de entradas de todos os componentes e requisições. Após a detecção de alguma linha ou erro suspeito, torna-se difícil combinar outras linhas que pertencem ao mesmo fluxo específico (por exemplo, o usuário "João" tentou comprar algo). Isso se torna ainda mais crítico e desafiador em um ambiente de microsserviço quando uma requisição/transação pode se estender por vários computadores. Aborde isso atribuindo um valor de identificador de transação exclusivo a todas as entradas da mesma solicitação, para que, ao detectar uma linha, você possa copiar o id e pesquisar por todas as linhas que possuam ID de transação semelhante. No entanto, alcançar isso no Node não é simples, pois um único thread é usado para atender a todas as solicitações - considere o uso de uma biblioteca que possa agrupar dados no nível de requisições - veja o exemplo de código no próximo slide. Ao chamar outro microsserviço, passe o Id da transação usando um cabeçalho HTTP como "x-transaction-id" para manter o mesmo contexto.
### Exemplo de código: configuração típica do Express
```javascript
// ao receber um novo pedido, inicie um novo contexto isolado e defina um ID de transação. O exemplo a seguir está usando a continuação da biblioteca npm-local-storage para isolar solicitações
const { createNamespace } = require('continuation-local-storage');
var session = createNamespace('minha sessão');
router.get('/:id', (req, res, next) => {
session.set('transactionId', 'algum GUID único');
someService.getById(req.params.id);
logger.info('Começando agora para obter algo por Id');
});
// Agora, qualquer outro serviço ou componente pode ter acesso aos dados contextuais, por requisição
class someService {
getById(id) {
logger.info(“Starting to get something by Id”);
// outra lógica vem aqui
}
}
// O logger agora pode anexar o ID da transação a cada entrada para que as entradas da mesma requisição tenham o mesmo valor
class logger {
info (message)
{console.log(`${message} ${session.get('transactionId')}`);}
}
```
================================================
FILE: sections/production/assigntransactionid.chinese.md
================================================
# 在每一个log语句指定‘TransactionId’
### 一段解释
一个典型的日志是来自所有组件和请求的条目的仓库。当检测到一些可疑行或错误时,为了与其他属于同一特定流程的行(如用户“约翰”试图购买某物)相匹配,就会变得难以应付。特别在微服务环境下,当一个请求/交易可能跨越多个计算机,这变得更加重要和具有挑战性。解决这个问题,可以通过指定一个唯一的事务标识符给从相同的请求过来的所有条目,这样当检测到一行,可以复制这个id,并搜索包含这个transaction id的每一行。但是,在node中实现这个不是那么直截了当的,这是由于它的单线程被用来服务所有的请求 – 考虑使用一个库,它可以在请求层对数据进行分组 – 在下一张幻灯片查看示例代码。当调用其它微服务,使用HTTP头“x-transaction-id”传递transaction id去保持相同的上下文。
### 代码示例: 典型的nginx配置
```javascript
//当接收到一个新的要求,开始一个新的隔离的上下文和设置一个事务transaction id。下面的例子是使用NPM库continuation-local-storage去隔离请求
const { createNamespace } = require('continuation-local-storage');
var session = createNamespace('my session');
router.get('/:id', (req, res, next) => {
session.set('transactionId', 'some unique GUID');
someService.getById(req.params.id);
logger.info('Starting now to get something by Id');
});
//现在, 任何其他服务或组件都可以访问上下文、每个请求、数据
class someService {
getById(id) {
logger.info(“Starting now to get something by Id”);
//其它逻辑
}
}
//Logger现在可以将事务 id 追加到每个条目, 以便同一请求中的项将具有相同的值
class logger{
info (message)
{console.log(`${message} ${session.get('transactionId')}`);}
}
```
================================================
FILE: sections/production/assigntransactionid.french.md
================================================
# 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.
================================================
FILE: sections/production/assigntransactionid.japanese.md
================================================
# 各ログ文に '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')}`);
}
}
```
================================================
FILE: sections/production/assigntransactionid.korean.md
================================================
# Assign ‘TransactionId’ to each log statement
### One Paragraph Explainer
A typical log is a warehouse of entries from all components and requests. Upon detection of some suspicious line or error, it becomes hairy to match other lines that belong to the same specific flow (e.g. the user “John” tried to buy something). This becomes even more critical and challenging in a microservice environment when a request/transaction might span across multiple computers. Address this by assigning a unique transaction identifier value to all the entries from the same request so when detecting one line one can copy the id and search for every line that has similar transaction Id. However, achieving this In Node is not straightforward as a single thread is used to serve all requests –consider using a library that that can group data on the request level – see code example on the next slide. When calling other microservice, pass the transaction Id using an HTTP header like “x-transaction-id” to keep the same context.
### Code example: typical Express configuration
```javascript
// when receiving a new request, start a new isolated context and set a transaction Id. The following example is using the npm library continuation-local-storage to isolate requests
const { createNamespace } = require('continuation-local-storage');
var session = createNamespace('my session');
router.get('/:id', (req, res, next) => {
session.set('transactionId', 'some unique GUID');
someService.getById(req.params.id);
logger.info('Starting now to get something by Id');
});
// Now any other service or components can have access to the contextual, per-request, data
class someService {
getById(id) {
logger.info(“Starting to get something by Id”);
// other logic comes here
}
}
// The logger can now append the transaction-id to each entry so that entries from the same request will have the same value
class logger {
info (message)
{console.log(`${message} ${session.get('transactionId')}`);}
}
```
================================================
FILE: sections/production/assigntransactionid.md
================================================
# Assign ‘TransactionId’ to each log statement
### One Paragraph Explainer
A typical log is a warehouse of entries from all components and requests. Upon detection of some suspicious line or error, it becomes hairy to match other lines that belong to the same specific flow (e.g. the user “John” tried to buy something). This becomes even more critical and challenging in a microservice environment when a request/transaction might span across multiple computers. Address this by assigning a unique transaction identifier value to all the entries from the same request so when detecting one line one can copy the id and search for every line that has similar transaction id. However, achieving this In Node is not straightforward as a single thread is used to serve all requests –consider using a library that that can group data on the request level – see code example on the next slide. When calling other 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());
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
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')}`);
}
}
```
### 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.
================================================
FILE: sections/production/assigntransactionid.polish.md
================================================
# 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')}`);
}
}
```
================================================
FILE: sections/production/assigntransactionid.russian.md
================================================
# Назначьте "TransactionId" для каждого вхождения журнала логирования
### Объяснение в один абзац
Типичный журнал - это хранилище записей всех компонентов и запросов. При обнаружении какой-либо подозрительной линии или ошибки становится трудно сопоставить другие строки, принадлежащие к тому же конкретному потоку (например, пользователь "Джон" пытался что-то купить). Это становится еще более критическим и сложным в микросервисной среде, когда запрос/транзакция может охватывать несколько компьютеров. Чтобы решить эту проблему, присвойте уникальное значение идентификатора транзакции всем записям одного и того же запроса, чтобы при обнаружении одной строки можно было копировать идентификатор и искать каждую строку, имеющую аналогичный идентификатор транзакции. Однако добиться этого в узле непросто, так как для обслуживания всех запросов используется один поток - рассмотрите возможность использования библиотеки, которая может группировать данные на уровне запроса - см. Пример кода на следующем слайде. При вызове другого микросервиса передайте идентификатор транзакции, используя заголовок HTTP, например "x-transaction-id", чтобы сохранить тот же контекст.
### Пример кода: типичная экспресс-конфигурация
```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')}`);
}
}
```
================================================
FILE: sections/production/bestateless.basque.md
================================================
# 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...
================================================
FILE: sections/production/bestateless.brazilian-portuguese.md
================================================
# Seja stateless, mate seus Servidores quase todos os dias
### Explicação em um Parágrafo
Você já encontrou um problema de produção grave no qual um servidor estava com alguma configuração ou dados em falta? Isso provavelmente se deve a alguma dependência desnecessária de algum ativo local que não faz parte da implantação. Muitos produtos de sucesso tratam servidores como um pássaro fênix - ele morre e renasce periodicamente sem nenhum dano. Em outras palavras, um servidor é apenas uma peça de hardware que executa seu código por algum tempo e é substituído depois disso.
Essa abordagem
- permite dimensionamento adicionando e removendo servidores dinamicamente sem efeitos colaterais.
- simplifica a manutenção, pois libera nossa mente de avaliar cada estado do servidor.
### Exemplo de código: anti-padrões
```javascript
// Erro típico 1: salvar arquivos enviados, localmente em um servidor
var multer = require('multer'); // middleware express para lidar com uploads de várias partes
var upload = multer({ dest: 'uploads/' });
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {});
// Erro típico 2: armazenar sessões de autenticação (passport) em um arquivo local ou memória
var FileStore = require('session-file-store')(session);
app.use(session({
store: new FileStore(options),
secret: 'keyboard cat'
}));
// Erro típico 3: armazenar informações no objeto global
Global.someCacheLike.result = { somedata };
```
### O que Outros Blogueiros Dizem
Do blog [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
> ...Um dia tive essa fantasia de iniciar um serviço de certificação para operações. A avaliação da certificação consistiria em um colega e eu aparecendo no data center corporativo e atacar os servidores de produção críticos com um taco de beisebol, uma motosserra e uma pistola de água. A avaliação seria baseada em quanto tempo levaria para a equipe de operações colocar todas as aplicações em funcionamento novamente. Esta pode ser uma fantasia idiota, mas há um pouco de sabedoria aqui. Enquanto você não deve usar os bastões de beisebol, é uma boa idéia queimar seus servidores em intervalos regulares. Um servidor deve ser como uma fênix, subindo regularmente das cinzas...
================================================
FILE: sections/production/bestateless.chinese.md
================================================
# 保存无状态,几乎每天停掉服务器
### 一段解释
你曾经有没有遇到一类严重的线上问题,比如一个服务器丢失了一些配置或数据?这可能是由于对于不属于部署部分的本地资源的一些不必要的依赖。许多成功的产品对待服务器就像凤凰鸟–它周期性地死亡和重生不带来任何损伤。换句话说,服务器只是一个硬件,执行你的代码一段时间后,可以更换。
这个方法:
- 允许动态添加和删除服务器,无任何负面影响;
- 简化了维护,因为它使我们不必费精力对每个服务器状态进行评估。
### 代码示例: 反模式
```javascript
//典型错误1: 保存上传文件在本地服务器上
var multer = require('multer') // 处理multipart上传的express中间件
var upload = multer({ dest: 'uploads/' })
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {})
//典型错误2: 在本地文件或者内存中,保存授权会话(密码)
var FileStore = require('session-file-store')(session);
app.use(session({
store: new FileStore(options),
secret: 'keyboard cat'
}));
//典型错误3: 在全局对象中保存信息
Global.someCacheLike.result = {somedata}
```
### 其他博客作者说什么
摘自博客 [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
> ...某天,我有了启动一个对操作的认证服务的幻想。认证评估将由我和一位同事出现在企业数据中心,并通过一个棒球棒,一个电锯和一把水枪设置关键生产服务器。评估将基于操作团队需要多长时间才能重新运行所有应用程序。这可能是一个愚蠢的幻想,但有一个真正的智慧在这里。而你应该放弃棒球棒,去定期的几乎烧毁你的服务器,这是一个好的做法。服务器应该像凤凰,经常从灰烬中升起...
================================================
FILE: sections/production/bestateless.french.md
================================================
# 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...
================================================
FILE: sections/production/bestateless.japanese.md
================================================
# ステートレスのままで、ほぼ毎日サーバーを停止させる
### 一段落説明
1台のサーバーに設定やデータの一部が欠落しているという深刻な運用上の問題に遭遇したことはありませんか? これはおそらく、デプロイメントの一部ではないローカルアセットへの不必要な依存が原因であると思われます。多くの成功しているプロダクトが不死鳥のようにサーバーを扱います – それは何のダメージも受けずに死んで定期的に生まれ変わります。言い換えれば、サーバーとは、コードをしばらくの間実行して、その後に入れ替わるハードウェアの一部に過ぎません。
このアプローチは、
- サーバを動的に追加したり削除したりすることで、副作用のないスケーリングを可能にします。
- 各サーバの状態を評価することから解放されるので、メンテナンスが簡単になります。
### コード例: アンチパターン
```javascript
// 典型的な間違い 1: アップロードファイルのローカル保存
const multer = require('multer'); // マルチパートアップロード処理用高速ミドルウェア
const upload = multer({ dest: 'uploads/' });
app.post('/photos/upload', upload.array('photos', 12), (req, res, next) => {});
// 典型的な間違い 2: 認証セッション(パスポート)をローカルファイルまたはメモリに保存する
const FileStore = require('session-file-store')(session);
app.use(session({
store: new FileStore(options),
secret: 'keyboard cat'
}));
// 典型的な間違い 3: グローバルオブジェクトの情報を格納
Global.someCacheLike.result = { somedata };
```
### 他のブロガーが言っていること
ブログ [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html) より:
> ...ある日、私は運用のための認証サービスを始めたいという妄想を抱いた。認定審査は、同僚と私が会社のデータセンターに出向き、野球のバット、チェーンソー、水鉄砲を持って、重要な本番用サーバーを見て回るというものでした。評価は、運用チームがすべてのアプリケーションを再稼働させるまでにどれくらいの時間がかかるかに基づいて行われます。くだらない妄想かもしれませんが、ここには名言のヒントがあります。野球のバットは見送るべきですが、定期的にサーバーを仮想的に焼き尽くすのは良いアイデアです。サーバーは不死鳥のように灰の中から定期的に立ち上がるべきです...
================================================
FILE: sections/production/bestateless.korean.md
================================================
# Be stateless, kill your Servers almost every day
### One Paragraph Explainer
Have you ever encountered a severe production issue where one server was missing some piece of configuration or data? That is probably due to some unnecessary dependency on some local asset that is not part of the deployment. Many successful products treat servers like a phoenix bird – it dies and is reborn periodically without any damage. In other words, a server is just a piece of hardware that executes your code for some time and is replaced after that.
This approach
- allows scaling by adding and removing servers dynamically without any side-effects.
- simplifies the maintenance as it frees our mind from evaluating each server state.
### Code example: anti-patterns
```javascript
// Typical mistake 1: saving uploaded files locally on a server
var multer = require('multer'); // express middleware for handling multipart uploads
var upload = multer({ dest: 'uploads/' });
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {});
// Typical mistake 2: storing authentication sessions (passport) in a local file or memory
var FileStore = require('session-file-store')(session);
app.use(session({
store: new FileStore(options),
secret: 'keyboard cat'
}));
// Typical mistake 3: storing information on the global object
Global.someCacheLike.result = { somedata };
```
### What Other Bloggers Say
From the blog [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
> ...One day I had this fantasy of starting a certification service for operations. The certification assessment would consist of a colleague and I turning up at the corporate data center and setting about critical production servers with a baseball bat, a chainsaw, and a water pistol. The assessment would be based on how long it would take for the operations team to get all the applications up and running again. This may be a daft fantasy, but there’s a nugget of wisdom here. While you should forego the baseball bats, it is a good idea to virtually burn down your servers at regular intervals. A server should be like a phoenix, regularly rising from the ashes...
================================================
FILE: sections/production/bestateless.md
================================================
# Be stateless, kill your Servers almost every day
### One Paragraph Explainer
Have you ever encountered a severe production issue where one server was missing some piece of configuration or data? That is probably due to some unnecessary dependency on some local asset that is not part of the deployment. Many successful products treat servers like a phoenix bird – it dies and is reborn periodically without any damage. In other words, a server is just a piece of hardware that executes your code for some time and is replaced after that.
This approach
- allows scaling by adding and removing servers dynamically without any side-effects.
- simplifies the maintenance as it frees our mind from evaluating each server state.
### Code example: anti-patterns
```javascript
// Typical mistake 1: saving uploaded files locally on a server
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 };
```
### What Other Bloggers Say
From the blog [Martin Fowler](https://martinfowler.com/bliki/PhoenixServer.html):
> ...One day I had this fantasy of starting a certification service for operations. The certification assessment would consist of a colleague and I turning up at the corporate data center and setting about critical production servers with a baseball bat, a chainsaw, and a water pistol. The assessment would be based on how long it would take for the operations team to get all the applications up and running again. This may be a daft fantasy, but there’s a nugget of wisdom here. While you should forego the baseball bats, it is a good idea to virtually burn down your servers at regular intervals. A server should be like a phoenix, regularly rising from the ashes...
================================================
FILE: sections/production/bestateless.polish.md
================================================
# 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...
================================================
FILE: sections/production/bestateless.russian.md
================================================
# Не прописывайтесь на постоянку, убивайте свои серверы почти каждый день
### Объяснение в один абзац
Сталкивались ли вы когда-нибудь с серьезной производственной проблемой, когда на одном сервере отсутствовала какая-то часть конфигурации или данных? Вероятно, это связано с некоторой ненужной зависимостью от локального актива, который не является частью развертывания. Многие успешные продукты относятся к серверам как к птице фениксу - она умирает и периодически перерождается без какого-либо ущерба. Другими словами, сервер - это просто аппаратное обеспечение, которое некоторое время выполняет ваш код и заменяется после этого.
Этот подход
- позволяет масштабировать, динамически добавляя и удаляя серверы без каких-либо побочных эффектов.
- упрощает обслуживание, поскольку освобождает наш разум от оценки состояния каждого сервера.
### Пример кода: антипаттерны
```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), function (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 };
```
### Что говорят другие блоггеры
Из блога [Мартин Фаулер](https://martinfowler.com/bliki/PhoenixServer.html):
> ... Однажды у меня появилась эта фантазия о запуске службы сертификации для операций. Оценка сертификации будет состоять из того, что мы с коллегой поедем в корпоративный центр обработки данных и расскажем о важнейших производственных серверах с бейсбольной битой, бензопилой и водяным пистолетом. Оценка будет основываться на том, сколько времени потребуется оперативной группе для того, чтобы все приложения снова заработали и снова заработали. Это может быть глупой фантазией, но здесь есть кусочек мудрости. В то время как вы должны отказаться от бейсбольных бит, это хорошая идея, чтобы виртуально сжигать ваши серверы через регулярные промежутки времени. Сервер должен быть как феникс, регулярно восстающий из пепла ...
================================================
FILE: sections/production/createmaintenanceendpoint.basque.md
================================================
# 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.
### Kode adibidea: kodearen bidez pilaketa sorta sortzea
```javascript
const heapdump = require("heapdump");
// Egiaztatu ia eskaera baimendua den
function baimenaDu(req) {
// ...
}
router.get("/ops/heapdump", (req, res, next) => {
if (!baimenaDu(req)) {
return res.status(403).send("Ez duzu baimenik!");
}
logger.info("heapdump-a generatzen");
heapdump.writeSnapshot((err, fitxategiarenIzena) => {
console.log(
"heapdump fitxategia prest dago eskariari bidaltzeko",
fitxategiarenIzena
);
fs.readFile(fitxategiarenIzena, "utf-8", (err, data) => {
res.end(data);
});
});
});
```
### 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)

================================================
FILE: sections/production/createmaintenanceendpoint.brazilian-portuguese.md
================================================
# Crie um ‘endpoint de manutenção’
### Explicação em um Parágrafo
Um endpoint de manutenção é uma API HTTP altamente seguro que faz parte do código da aplicação e sua finalidade é ser usado pela equipe de operação/produção para monitorar e expor a funcionalidade de manutenção. Por exemplo, ele pode retornar um dump de heap (instantâneo de memória) do processo, relatar se há algum vazamento de memória e até mesmo permitir executar comandos REPL diretamente. Esse endpoint é necessário onde as ferramentas DevOps convencionais (produtos de monitoramento, logs, etc) não conseguem reunir algum tipo específico de informações ou você escolhe não comprar/instalar tais ferramentas. A regra de ouro é usar ferramentas profissionais e externas para monitorar e manter a produção, que geralmente são mais robustas e precisas. Dito isso, é provável que haja casos em que as ferramentas genéricas não conseguirão extrair informações específicas do Node ou da aplicação - por exemplo, caso você deseje gerar uma snapshot da memória no momento em que o GC concluiu um ciclo - algumas bibliotecas npm executarão isso para você, mas ferramentas de monitoramento populares provavelmente perderão essa funcionalidade. É importante manter esse endpoint privado e acessível apenas por administradores, pois ele pode se tornar um alvo de um ataque DDOS.
### Exemplo de código: gerando um despejo de heap via código
```javascript
const heapdump = require('heapdump');
// Verifique se o pedido está autorizado
function isAuthorized(req) {
// ...
}
router.get('/ops/heapdump', (req, res, next) => {
if (!isAuthorized(req)) {
return res.status(403).send('You are not authorized!');
}
logger.info('Prestes a gerar o heapdump');
heapdump.writeSnapshot((err, filename) => {
console.log('arquivo heapdump está pronto para ser enviado para o chamador', filename);
fs.readFile(filename, "utf-8", (err, data) => {
res.end(data);
});
});
});
```
### Recursos Recomendados
[Preparando sua aplicação Node.js para produção (Slides)](http://naugtur.pl/pres3/node2prod)
▶ [Preparando sua aplicação Node.js para produção (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)

================================================
FILE: sections/production/createmaintenanceendpoint.chinese.md
================================================
# 创建维护端点
### 一段解释
维护端点是一个简单的安全的HTTP API, 它是应用程序代码的一部分, 它的用途是让ops/生产团队用来监视和公开维护功能。例如, 它可以返回进程的head dump (内存快照), 报告是否存在内存泄漏, 甚至允许直接执行 REPL 命令。在常规的 devops 工具 (监视产品、日志等) 无法收集特定类型的信息或您选择不购买/安装此类工具时, 需要使用此端点。黄金法则是使用专业的和外部的工具来监控和维护生产环境, 它们通常更加健壮和准确的。这就意味着, 一般的工具可能无法提取特定于node或应用程序的信息 – 例如, 如果您希望在 GC 完成一个周期时生成内存快照 – 很少有 npm 库会很乐意为您执行这个, 但流行的监控工具很可能会错过这个功能。
### 代码示例: 使用代码生产head dump
```javascript
var heapdump = require('heapdump');
router.get('/ops/headump', (req, res, next) => {
logger.info(`About to generate headump`);
heapdump.writeSnapshot(function (err, filename) {
console.log('headump file is ready to be sent to the caller', filename);
fs.readFile(filename, "utf-8", function (err, data) {
res.end(data);
});
});
});
```
### 推荐资源
[Getting your Node.js app production ready (Slides)](http://naugtur.pl/pres3/node2prod)
▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)

================================================
FILE: sections/production/createmaintenanceendpoint.french.md
================================================
# 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)

================================================
FILE: sections/production/createmaintenanceendpoint.japanese.md
================================================
# メンテナンスエンドポイントの作成
### 一段落説明
メンテナンスエンドポイントは、アプリのコードの一部であり、その目的は、ops/プロダクションチームがメンテナンス機能を監視し、公開するために使用する高度に安全な HTTP API です。 例えば、プロセスのヒープダンプ(メモリスナップショット)を返したり、メモリリークがあるかどうかを報告したり、REPL コマンドを直接実行したりすることができます。このエンドポイントは、従来の DevOps ツール(監視製品、ログなど)では特定の情報を収集できない場合や、そのようなツールを購入/インストールしないことを選択した場合に必要となります。黄金律は、生産の監視と維持のために専門的な外部ツールを使用することですが、これらは通常、より堅牢で正確です。とはいえ、一般的なツールでは、Node やアプリに固有の情報を抽出できない場合もあるでしょう。– 例えば、GC がサイクルを完了した瞬間にメモリスナップショットを生成したい場合は、以下のようになります – いくつかの npm ライブラリは喜んでこの機能を実行してくれますが、一般的なモニタリングツールはこの機能を見逃してしまう可能性があります。DDOS 攻撃の標的になる可能性があるため、このエンドポイントを非公開にし、管理者のみがアクセスできるようにしておくことが重要です。
### コード例: コードによるヒープダンプの生成
```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)

================================================
FILE: sections/production/createmaintenanceendpoint.korean.md
================================================
# Create a maintenance endpoint
### One Paragraph Explainer
A maintenance endpoint is a highly secure HTTP API that is part of the app code and its purpose is to be used by the ops/production team to monitor and expose maintenance functionality. For example, it can return a heap dump (memory snapshot) of the process, report whether there are some memory leaks and even allow to execute REPL commands directly. This endpoint is needed where the conventional DevOps tools (monitoring products, logs, etc) fail to gather some specific type of information or you choose not to buy/install such tools. The golden rule is using professional and external tools for monitoring and maintaining the production, these are usually more robust and accurate. That said, there are likely to be cases where the generic tools will fail to extract information that is specific to Node or to your app – for example, should you wish to generate a memory snapshot at the moment GC completed a cycle – few npm libraries will be glad to perform this for you but popular monitoring tools will likely miss this functionality. It is important to keep this endpoint private and accessibly only by admins because it can become a target of a DDOS attack.
### Code example: generating a heap dump via code
```javascript
const heapdump = require('heapdump');
// Check if request is authorized
function isAuthorized(req) {
// ...
}
router.get('/ops/heapdump', (req, res, next) => {
if (!isAuthorized(req)) {
return res.status(403).send('You are not authorized!');
}
logger.info('About to generate heapdump');
heapdump.writeSnapshot((err, filename) => {
console.log('heapdump file is ready to be sent to the caller', filename);
fs.readFile(filename, "utf-8", (err, data) => {
res.end(data);
});
});
});
```
### Recommended Resources
[Getting your Node.js app production ready (Slides)](http://naugtur.pl/pres3/node2prod)
▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)

================================================
FILE: sections/production/createmaintenanceendpoint.md
================================================
# Create a maintenance endpoint
### One Paragraph Explainer
A maintenance endpoint is a highly secure HTTP API that is part of the app code and its purpose is to be used by the ops/production team to monitor and expose maintenance functionality. For example, it can return a heap dump (memory snapshot) of the process, report whether there are some memory leaks and even allow to execute REPL commands directly. This endpoint is needed where the conventional DevOps tools (monitoring products, logs, etc) fail to gather some specific type of information or you choose not to buy/install such tools. The golden rule is using professional and external tools for monitoring and maintaining the production, these are usually more robust and accurate. That said, there are likely to be cases where the generic tools will fail to extract information that is specific to Node or to your app – for example, should you wish to generate a memory snapshot at the moment GC completed a cycle – few npm libraries will be glad to perform this for you but popular monitoring tools will likely miss this functionality. It is important to keep this endpoint private and accessibly only by admins because it can become a target of a DDOS attack.
### Code example: generating a heap dump via code
```javascript
const heapdump = require('heapdump');
// Check if request is authorized
function isAuthorized(req) {
// ...
}
router.get('/ops/heapdump', (req, res, next) => {
if (!isAuthorized(req)) {
return res.status(403).send('You are not authorized!');
}
logger.info('About to generate heapdump');
heapdump.writeSnapshot((err, filename) => {
console.log('heapdump file is ready to be sent to the caller', filename);
fs.readFile(filename, 'utf-8', (err, data) => {
res.end(data);
});
});
});
```
### Recommended Resources
[Getting your Node.js app production ready (Slides)](http://naugtur.pl/pres3/node2prod)
▶ [Getting your Node.js app production ready (Video)](https://www.youtube.com/watch?v=lUsNne-_VIk)

================================================
FILE: sections/production/createmaintenanceendpoint.polish.md
================================================
# 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)

================================================
FILE: sections/production/createmaintenanceendpoint.russian.md
================================================
# Создавайте конечную точку обслуживания
### Объяснение в один абзац
Конечная точка обслуживания - это высокозащищенный HTTP API, который является частью кода приложения, и его назначение - использовать команду ops/production для мониторинга и предоставления функциональных возможностей обслуживания. Например, он может вернуть дамп кучи (моментальный снимок памяти) процесса, сообщить о наличии утечек памяти и даже разрешить выполнение команд REPL напрямую. Эта конечная точка необходима, когда обычные инструменты DevOps (продукты мониторинга, журналы и т.д.) не в состоянии собрать какой-то конкретный тип информации или вы решили не покупать/устанавливать такие инструменты. Золотое правило заключается в использовании профессиональных и внешних инструментов для мониторинга и обслуживания производства, обычно они более надежны и точны. Тем не менее, могут быть случаи, когда универсальные инструменты не смогут извлечь информацию, относящуюся к Node или вашему приложению - например, если вы захотите сгенерировать снимок памяти в момент завершения цикла GC - несколько библиотек npm буду рады сделать это за вас, но популярные инструменты мониторинга, скорее всего, упустят эту функцию. Важно сохранять эту конечную точку частной и доступной только для администраторов, поскольку она может стать целью атаки DDOS.
### Пример кода: создание дампа кучи с помощью кода
```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);
});
});
});
```
### Рекомендуемые ресурсы
[Подготовка вашего приложения Node.js к производственому запуску (слайды)](http://naugtur.pl/pres3/node2prod)
▶ [Подготовка вашего приложения Node.js к производственому запуску (видео)](https://www.youtube.com/watch?v=lUsNne-_VIk)

================================================
FILE: sections/production/delegatetoproxy.basque.md
================================================
# 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.
### Nginx konfigurazio adibidea: erabili nginx zerbitzariaren erantzunak konprimatzeko
```nginx
# konfiguratu gzip konprimatzea
gzip on;
gzip_comp_level 6;
gzip_vary on;
# konfiguratu upstream
upstream nireAplikazioa {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
# web zebitzaria zehaztu
server {
# konfiguratu zerbitzaria ssl-arekin eta errore orriekin
listen 80;
listen 443 ssl;
ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
error_page 502 /errors/502.html;
# eduki estatikoa kudeatu
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;
}
```
### 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**…
================================================
FILE: sections/production/delegatetoproxy.brazilian-portuguese.md
================================================
# Delegue tudo o que for possível (por exemplo, gzip, SSL) a um proxy reverso
### Explicação em um Parágrafo
É muito tentador carregar o Express e usar suas várias opções de middleware para tarefas relacionadas à rede, como servir arquivos estáticos, codificação gzip, solicitações de limitação, terminação SSL etc. Isso é uma perda de desempenho devido ao seu modelo de thread único que manterá a CPU ocupada por longos períodos (Lembre-se, o modelo de execução do Node é otimizado para tarefas curtas ou tarefas relacionadas a IO assíncrono). Uma abordagem melhor é usar uma ferramenta especializada em tarefas de rede - os mais populares são o nginx e o HAproxy, que também são usados pelos maiores fornecedores de nuvem para aliviar a carga recebida nos processos node.js.
### Exemplo de configuração do Nginx - usando o nginx para compactar as respostas do servidor
```nginx
# configurar compactação gzip
gzip on;
gzip_comp_level 6;
gzip_vary on;
# configurar upstream
upstream myApplication {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
#definindo servidor da web
server {
# configurar servidor com páginas ssl e de erro
listen 80;
listen 443 ssl;
ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
error_page 502 /errors/502.html;
# lidando com conteúdo estático
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;
}
```
### O que Outros Blogueiros Dizem
* Do blog [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
> …É muito fácil cair nessa armadilha - Você vê um pacote como o Express e pensa “Incrível! Vamos começar ”- você codifica e tem uma aplicação que faz o que você deseja. Isso é excelente e, para ser honesto, você ganhou muito da batalha. No entanto, você perderá a guerra se fizer o upload do seu aplicativo em um servidor e escutá-lo na porta HTTP, porque esqueceu uma coisa muito importante: o Node não é um servidor da web. **Assim que qualquer volume de tráfego começar a bater em sua aplicação, você perceberá que as coisas começam a dar errado: as conexões são interrompidas, os recursos deixam de ser exibidos ou, no pior dos casos, o servidor falha. O que você está fazendo é tentar fazer com que o Node lide com todas as coisas complicadas que um servidor da Web comprovado faz muito bem. Por que reinventar a roda?**
> **Isto é apenas para um pedido, para uma imagem e tendo em conta que esta é a memória que a sua aplicação poderia ser usada para coisas importantes como ler uma base de dados ou lidar com lógica complicada; por que você prejudicaria sua aplicação apenas por conveniência?**
* Do blog [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
> Embora o express.js tenha manipulação interna de arquivos estáticos através de algum middleware de conexão, você nunca deve usá-lo. **O Nginx pode fazer um trabalho muito melhor ao lidar com arquivos estáticos e pode impedir que solicitações de conteúdo não dinâmico obstruam nossos processos do Node**…
================================================
FILE: sections/production/delegatetoproxy.chinese.md
================================================
# 委托任何可能的 (例如静态内容,gzip) 到反向代理
### 一段解释
过度使用Express,及其丰富的中间件去提供网络相关的任务,如服务静态文件,gzip 编码,throttling requests,SSL termination等,是非常诱人的。由于Node.js的单线程模型,这将使CPU长时间处于忙碌状态 (请记住,node的执行模型针对短任务或异步IO相关任务进行了优化),因此这是一个性能消耗。一个更好的方法是使用专注于处理网络任务的工具 – 最流行的是nginx和HAproxy,它们也被最大的云供应商使用,以减轻在Node.js进程上所面临的负载问题。
### 代码示例 – 使用 nginx 压缩服务器响应
```
# 配置 gzip 压缩
gzip on;
gzip_comp_level 6;
gzip_vary on;
# 配置 upstream
upstream myApplication {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
#定义 web server
server {
# configure server with ssl and error pages
listen 80;
listen 443 ssl;
ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
error_page 502 /errors/502.html;
# handling static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### 其他博客作者说什么
* 摘自博客 [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
> …很容易落入这个陷阱 – 你看到一个包比如Express,并认为 "真棒!让我们开始吧" – 你编写了代码,你实现了一个应用程序,做你想要的。这很好,老实说,你已经完成了大部分的事情。但是,如果您将应用程序上传到服务器并让它侦听 HTTP 端口,您将搞砸这个应用,因为您忘记了一个非常关键的事情: node不是 web 服务器。**一旦任何流量开始访问你的应用程序, 你会发现事情开始出错: 连接被丢弃,资源停止服务,或在最坏的情况下,你的服务器崩溃。你正在做的是试图让node处理所有复杂的事情,而这些事情让一个已验证过了的 web 服务器来处理,再好也不会过。为什么要重新造轮子?It**
> **这只是为了一个请求,为了一个图像,并铭记在脑海中,您的应用程序可以用于重要的东西,如读取数据库或处理复杂的逻辑; 为了方便起见,你为什么要削弱你的应用?**
* 摘自博客 [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
> 虽然 express.js 通过一些connect中间件处理静态文件,但你不应该使用它。**Nginx 可以更好地处理静态文件,并可以防止请求动态内容堵塞我们的node进程**…
================================================
FILE: sections/production/delegatetoproxy.french.md
================================================
# 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**…
================================================
FILE: sections/production/delegatetoproxy.japanese.md
================================================
# 可能な限りのこと全て(静的コンテンツや gzip など)をリバースプロキシに委譲する
### 一段落説明
Express を過剰に利用し、静的ファイルの提供、gzip エンコーディング、リクエストのスロットリング、SSL の終了などのネットワーク関連のタスクを提供してくれる、そのリッチなミドルウェアを使用することは非常に魅力的です。これは、CPU を長時間ビジー状態に保つシングルスレッドモデルのため、パフォーマンスを低下させます( Node の実行モデルは短いタスクや非同期 IO 関連のタスクに最適化されていることを覚えておいてください)。より良いアプローチは、ネットワーク作業の専門知識を持つツールを使用することです – 最も人気のあるのは nginx と HAproxy で、これらは最大手のクラウドベンダーも Node.js プロセスへの負荷を軽減するために使用しています。
### nginx 設定例 – nginx を使ってサーバのレスポンスを圧縮する
```nginx
# gzip 圧縮を設定する
gzip on;
gzip_comp_level 6;
gzip_vary on;
# アップストリームを設定する
upstream myApplication {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
# ウェブサーバーを定義する
server {
# サーバに ssl とエラーページを設定する
listen 80;
listen 443 ssl;
ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
error_page 502 /errors/502.html;
# 静的コンテンツをハンドリングする
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### 他のブロガーが言っていること
* ブログ [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications) より:
> ...このトラップに陥るのは非常に簡単です - あなたは Express のようなパッケージを見て、「素晴らしい!さっそく始めよう」と思ってしまうのです。– あなたがコードを書くことで、あなたが望むアプリケーションを手に入れることができます。これは秀逸だし、正直言ってかなりの勝利を収めていますね。しかし、アプリをサーバーにアップロードして HTTP ポートでリッスンすると、戦争に負けることになります。なぜなら、あなたは非常に重要なことを忘れているからです: Node はウェブサーバーではありません。**トラフィックのボリュームがアプリケーションにヒットし始めると、すぐに物事がうまくいかなくなることに気づくでしょう: 接続が切断されたり、アセットが提供されなくなったり、最悪の場合はサーバーがクラッシュしたりします。あなたがやっていることは、実績のあるウェブサーバが本当によくやっている複雑なことのすべてを Node に処理させようとしていることです。なぜ車輪を再発明するのでしょうか?**
> **これは、1つの画像のため、1つのリクエストのためのものであり、アプリケーションがデータベースを読んだり複雑なロジックを処理したりするような重要なものに使用できるメモリであることを念頭に置いてください; なぜ都合のいいようにアプリを廃人にするのでしょうか?**
* ブログ [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load) より:
> express.js にはいくつかの接続ミドルウェアを介した静的ファイル処理が組み込まれていますが、絶対に使ってはいけません。**Nginx は静的ファイルの処理をより良く行うことができ、動的ではないコンテンツへのリクエストがノードプロセスを詰まらせるのを防ぐことができます。**…
================================================
FILE: sections/production/delegatetoproxy.korean.md
================================================
# Delegate anything possible (e.g. static content, gzip) to a reverse proxy
### One Paragraph Explainer
It’s very tempting to cargo-cult Express and use its rich middleware offering for networking related tasks like serving static files, gzip encoding, throttling requests, SSL termination, etc. This is a performance kill due to its single threaded model which will keep the CPU busy for long periods (Remember, Node’s execution model is optimized for short tasks or async IO related tasks). A better approach is to use a tool that expertise in networking tasks – the most popular are nginx and HAproxy which are also used by the biggest cloud vendors to lighten the incoming load on node.js processes.
### Nginx Config Example – Using nginx to compress server responses
```nginx
# configure gzip compression
gzip on;
gzip_comp_level 6;
gzip_vary on;
# configure upstream
upstream myApplication {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
#defining web server
server {
# configure server with ssl and error pages
listen 80;
listen 443 ssl;
ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
error_page 502 /errors/502.html;
# handling static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### What Other Bloggers Say
* From the blog [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
> …It’s very easy to fall into this trap – You see a package like Express and think “Awesome! Let’s get started” – you code away and you’ve got an application that does what you want. This is excellent and, to be honest, you’ve won a lot of the battle. However, you will lose the war if you upload your app to a server and have it listen on your HTTP port because you’ve forgotten a very crucial thing: Node is not a web server. **As soon as any volume of traffic starts to hit your application, you’ll notice that things start to go wrong: connections are dropped, assets stop being served or, at the very worst, your server crashes. What you’re doing is attempting to have Node deal with all of the complicated things that a proven web server does really well. Why reinvent the wheel?**
> **This is just for one request, for one image and bearing in mind this is the memory that your application could be used for important stuff like reading a database or handling complicated logic; why would you cripple your application for the sake of convenience?**
* From the blog [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
> Although express.js has built-in static file handling through some connect middleware, you should never use it. **Nginx can do a much better job of handling static files and can prevent requests for non-dynamic content from clogging our node processes**…
================================================
FILE: sections/production/delegatetoproxy.md
================================================
# Delegate anything possible (e.g. static content, gzip) to a reverse proxy
### One Paragraph Explainer
It’s very tempting to cargo-cult Express and use its rich middleware offering for networking related tasks like serving static files, gzip encoding, throttling requests, SSL termination, etc. This is a performance kill due to its single threaded model which will keep the CPU busy for long periods (Remember, Node’s execution model is optimized for short tasks or async IO related tasks). A better approach is to use a tool that expertise in networking tasks – the most popular are nginx and HAproxy which are also used by the biggest cloud vendors to lighten the incoming load on node.js processes.
### Nginx Config Example – Using nginx to compress server responses
```nginx
# configure gzip compression
gzip on;
gzip_comp_level 6;
gzip_vary on;
# configure upstream
upstream myApplication {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
#defining web server
server {
# configure server with ssl and error pages
listen 80;
listen 443 ssl;
ssl_certificate /some/location/sillyfacesociety.com.bundle.crt;
error_page 502 /errors/502.html;
# handling static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### What Other Bloggers Say
* From the blog [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
> …It’s very easy to fall into this trap – You see a package like Express and think “Awesome! Let’s get started” – you code away and you’ve got an application that does what you want. This is excellent and, to be honest, you’ve won a lot of the battle. However, you will lose the war if you upload your app to a server and have it listen on your HTTP port because you’ve forgotten a very crucial thing: Node is not a web server. **As soon as any volume of traffic starts to hit your application, you’ll notice that things start to go wrong: connections are dropped, assets stop being served or, at the very worst, your server crashes. What you’re doing is attempting to have Node deal with all of the complicated things that a proven web server does really well. Why reinvent the wheel?**
> **This is just for one request, for one image and bearing in mind this is the memory that your application could be used for important stuff like reading a database or handling complicated logic; why would you cripple your application for the sake of convenience?**
* From the blog [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
> Although express.js has built-in static file handling through some connect middleware, you should never use it. **Nginx can do a much better job of handling static files and can prevent requests for non-dynamic content from clogging our node processes**…
================================================
FILE: sections/production/delegatetoproxy.polish.md
================================================
# Deleguj wszystko, co możliwe (np. zawartość statyczną, gzip) do odwrotnego proxy
### 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**…
================================================
FILE: sections/production/delegatetoproxy.russian.md
================================================
# Делегируйте все возможное (например, gzip, SSL) обратному прокси
### Объяснение в один абзац
Это очень заманчиво для карго-культа Express и использования его богатого промежуточного программного обеспечения для задач, связанных с сетью, таких как обслуживание статических файлов, кодирование gzip, запросы регулирования, завершение SSL и т.д. Это снижение производительности из-за его однопоточной модели, которая сохранит процессор занят для длительных периодов (помните, что модель выполнения Node оптимизирована для коротких задач или задач, связанных с асинхронным вводом-выводом). Лучшим подходом является использование инструмента, обладающего опытом в сетевых задачах. Наиболее популярными являются nginx и HAproxy, которые также используются крупнейшими поставщиками облачных технологий для снижения нагрузки на входящие процессы Node.js.
### Пример конфигурации nginx - Использование nginx для сжатия ответов сервера
```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;
}
```
### Что говорят другие блоггеры
* Из блога [Mubaloo](http://mubaloo.com/best-practices-deploying-node-js-applications):
> … Попасть в эту ловушку очень легко - вы видите пакет типа "Экспресс" и думаете: "Круто! Давайте начнем", - вы кодируете, и у вас есть приложение, которое делает то, что вы хотите. Это отлично, и, честно говоря, вы выиграли много битвы. Однако вы проиграете войну, если загрузите свое приложение на сервер и прослушаете его на своем HTTP-порте, потому что вы забыли очень важную вещь: Node не является веб-сервером. **Как только любой объем трафика начнет попадать в ваше приложение, вы заметите, что что-то начинает работать неправильно: соединения теряются, ресурсы перестают обслуживаться, или, в худшем случае, происходит сбой вашего сервера. То, что вы делаете, это пытаетесь заставить Node справиться со всеми сложными вещами, которые проверенный веб-сервер делает действительно хорошо. Зачем изобретать велосипед?**
> **Это только для одного запроса, для одного изображения и с учетом того, что это память, которую ваше приложение может использовать для важных вещей, таких как чтение базы данных или обработка сложной логики; зачем вам калечить ваше приложение ради удобства?**
* Из блога [Argteam](http://blog.argteam.com/coding/hardening-node-js-for-production-part-2-using-nginx-to-avoid-node-js-load):
> Несмотря на то, что в express.js есть встроенная статическая обработка файлов через некоторое промежуточное ПО для подключения, вы никогда не должны его использовать. **Nginx может гораздо лучше справляться со статическими файлами и предотвращать засорение запросов на не динамический контент нашими процессами узлов** …
================================================
FILE: sections/production/detectvulnerabilities.basque.md
================================================
# 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...
================================================
FILE: sections/production/detectvulnerabilities.brazilian-portuguese.md
================================================
# Utilize ferramentas que detectam vulnerabilidades automaticamente
### Explicação em um Parágrafo
As aplicações modernas de Node possuem dezenas e algumas vezes centenas de dependências. Se alguma das dependências que você usa tiver uma vulnerabilidade de segurança conhecida, seu aplicativo também estará vulnerável.
As ferramentas a seguir verificam automaticamente vulnerabilidades de segurança conhecidas em suas dependências:
- [npm audit](https://docs.npmjs.com/cli/audit) - npm audit
- [snyk](https://snyk.io/) - Encontre e corrija continuamente vulnerabilidades em suas dependências
### O que Outros Blogueiros dizem
Do blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/):
> ...Usá-lo para gerenciar as dependências da sua aplicação é poderoso e conveniente. Mas os pacotes que você usa podem conter vulnerabilidades críticas de segurança que também podem afetar sua aplicação. A segurança da sua aplicação é tão forte quanto o "elo mais fraco" em suas dependências. Felizmente, existem duas ferramentas úteis que você pode usar para garantir os pacotes de terceiros que você usa: nsp e requireSafe. Estas duas ferramentas fazem basicamente a mesma coisa, então usar ambos pode ser um exagero, mas “melhor prevenir do que remediar” são palavras para se viver quando se trata de segurança ...
================================================
FILE: sections/production/detectvulnerabilities.chinese.md
================================================
# 使用工具自动检测有漏洞的依赖项
### 一段解释
现代node应用有数十个, 有时是数以百计的依赖。如果您使用的任何依赖项存在已知的安全漏洞, 您的应用也很容易受到攻击。
下列工具自动检查依赖项中的已知安全漏洞:
[npm audit](https://docs.npmjs.com/cli/audit) - Node 安全工程
[snyk](https://snyk.io/) - 持续查找和修复依赖中的漏洞
### 其他博主说什么
摘自博客 [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) :
> ...被用来管理您应用的依赖是强大且方便的。但是, 您使用的依赖包可能存在严重的安全漏洞, 也会影响您的应用。您的应用的安全性仅仅与您的依赖组件中的 "最薄弱的一环" 一样严重。幸运的是, 您可以使用两种有用的工具来确保您使用的第三方库: ** 和 requireSafe。这两种工具在很大程度上都是一样的, 所以使用两种方法都可能过于夸张, 但 "安全比抱歉" 更安全...
================================================
FILE: sections/production/detectvulnerabilities.french.md
================================================
# 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é...
================================================
FILE: sections/production/detectvulnerabilities.japanese.md
================================================
# 脆弱な依存関係を自動的に検出するツールを使用する
### 一段落説明
最近の Node アプリケーションは、数十、時には数百の依存関係を持っています。使用している依存関係のいずれかに既知のセキュリティ脆弱性がある場合、あなたのアプリも同様に脆弱です。
以下のツールは、依存関係にある既知のセキュリティ脆弱性を自動的にチェックします。:
- [npm audit](https://docs.npmjs.com/cli/audit) - npm 監査
- [snyk](https://snyk.io/) - 依存関係にある脆弱性を継続的に発見し、修正する
### 他のブロガーが言っていること
ブログ [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) より:
> ...アプリケーションの依存関係を管理するために使用することは、強力で便利です。しかし、使用しているパッケージには重要なセキュリティ上の脆弱性が含まれている可能性があり、アプリケーションにも影響を与える可能性があります。アプリのセキュリティは、依存関係の「最も弱いリンク」と同じくらい強力です。幸いなことに、使用するサードパーティ製パッケージのセキュリティを確保するために使用できる 2 つの便利なツールがあります: nsp と requireSafe です。この2つのツールは大体同じことをするので、両方を使うのはやりすぎかもしれませんが、セキュリティに関しては「後悔するよりも安全な方がいい」という言葉が生きてくるでしょう。...
================================================
FILE: sections/production/detectvulnerabilities.korean.md
================================================
# Use tools that automatically detect vulnerable dependencies
### One Paragraph Explainer
Modern Node applications have tens and sometimes hundreds of dependencies. If any of the dependencies
you use has a known security vulnerability your app is vulnerable as well.
The following tools automatically check for known security vulnerabilities in your dependencies:
- [npm audit](https://docs.npmjs.com/cli/audit) - npm audit
- [snyk](https://snyk.io/) - Continuously find & fix vulnerabilities in your dependencies
### What Other Bloggers Say
From the [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) blog:
> ...Using to manage your application’s dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the “weakest link” in your dependencies. Fortunately, there are two helpful tools you can use to ensure the third-party packages you use: 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...
================================================
FILE: sections/production/detectvulnerabilities.md
================================================
# Use tools that automatically detect vulnerable dependencies
### One Paragraph Explainer
Modern Node applications have tens and sometimes hundreds of dependencies. If any of the dependencies
you use has a known security vulnerability your app is vulnerable as well.
The following tools automatically check for known security vulnerabilities in your dependencies:
- [npm audit](https://docs.npmjs.com/cli/audit) - npm audit
- [snyk](https://snyk.io/) - Continuously find & fix vulnerabilities in your dependencies
### What Other Bloggers Say
From the [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/) blog:
> ...Using to manage your application’s dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the “weakest link” in your dependencies. Fortunately, there are two helpful tools you can use to ensure the third-party packages you use: 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...
================================================
FILE: sections/production/detectvulnerabilities.polish.md
================================================
# 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...
================================================
FILE: sections/production/detectvulnerabilities.russian.md
================================================
# Используйте инструменты, которые автоматически обнаруживают уязвимые зависимости
### Объяснение в один абзац
Современные Node-приложения имеют десятки, а иногда и сотни зависимостей. Если какая-либо из них в зависимостях
у вас есть известная уязвимость в безопасности вашего приложения.
Следующие инструменты автоматически проверяют наличие известных уязвимостей в ваших зависимостях:
- [npm audit](https://docs.npmjs.com/cli/audit) - аудит npm
- [snyk](https://snyk.io/) - постоянно находите и исправляйте уязвимости в ваших зависимостях
### Что говорят другие блоггеры
Из блога [StrongLoop] (https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/):
> ... Использование для управления зависимостями вашего приложения является мощным и удобным. Но используемые вами пакеты могут содержать критические уязвимости безопасности, которые также могут повлиять на ваше приложение. Безопасность вашего приложения так же сильна, как "самая слабая ссылка" в ваших зависимостях. К счастью, есть два полезных инструмента, которые вы можете использовать для обеспечения сторонних пакетов, которые вы используете: nsp и requireSafe. Эти два инструмента в основном делают одно и то же, поэтому использование обоих может оказаться излишним, но "лучше, чем потом сожалеть" - это слова, которые нужно соблюдать, когда речь заходит о безопасности ...
================================================
FILE: sections/production/frontendout.basque.md
================================================
# 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.
### Ezarpen adibidea: nginxen ohiko ezarpena fitxategi estatikoak zerbitzatzeko
```nginx
# konfiguratu gzip konprimatzea
gzip on;
keepalive 64;
# web zerbitzaria zehaztu
server {
listen 80;
listen 443 ssl;
# eduki estatikoa kudeatu
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;
}
```
### 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”…
================================================
FILE: sections/production/frontendout.brazilian-portuguese.md
================================================
# Deixe seus recursos de frontend fora do Node
### Explicação em um Parágrafo
Em uma aplicação web clássica, o back-end serve o front-end/gráficos para o navegador, uma abordagem muito comum no mundo do Node é usar o middleware estático do Express para enviar arquivos estáticos para o cliente. MAS - O Node não é um aplicativo Web típico, pois utiliza um único thread que não é otimizado para servir muitos arquivos de uma só vez. Em vez disso, considere o uso de um proxy reverso (por exemplo, nginx, HAProxy), armazenamento em nuvem ou CDN (por exemplo, AWS S3, Armazenamento de Blobs do Azure etc.) que utiliza muitas otimizações para essa tarefa e obtém uma taxa de transferência muito melhor. Por exemplo, um middleware especializado como o nginx incorpora ganchos diretos entre o sistema de arquivos e a placa de rede e usa uma abordagem multi-thread para minimizar a intervenção entre várias solicitações.
Sua solução ideal pode usar um dos seguintes formulários:
1. Usando um proxy reverso - seus arquivos estáticos estarão localizados próximos ao seu aplicativo Node, somente os pedidos para a pasta de arquivos estáticos serão servidos por um proxy que fica na frente do seu aplicativo Node, como o nginx. Usando essa abordagem, seu aplicativo Node é responsável por implantar os arquivos estáticos, mas não para atendê-los. O colega do seu frontend vai adorar esta abordagem, pois evita solicitações de origem cruzada do frontend.
2. Armazenamento em nuvem - seus arquivos estáticos NÃO farão parte do conteúdo do aplicativo Node, eles serão carregados em serviços como o AWS S3, o Azure BlobStorage ou outros serviços semelhantes que nasceram para essa missão. Usando essa abordagem, seu aplicativo Node não é responsável por implantar os arquivos estáticos nem para atendê-los, portanto, um desacoplamento completo é desenhado entre o Node e o Frontend, que é, de qualquer maneira, manipulado por equipes diferentes.
### Exemplo de configuração: configuração típica do nginx para servir arquivos estáticos
```nginx
# configurar compactação gzip
gzip on;
keepalive 64;
# definindo servidor da web
server {
listen 80;
listen 443 ssl;
# lidar com conteúdo estático
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;
}
```
### O que Outros Blogueiros Dizem
Do blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
>…Em desenvolvimento, você pode usar [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) para servir arquivos estáticos. Mas não faça isso em produção, porque essa função precisa ser lida no sistema de arquivos para cada solicitação de arquivo. Por isso, ela terá latência significativa e afetará o desempenho geral do aplicativo. Note que res.sendFile() não é implementado com a chamada do sistema sendfile, o que tornaria muito mais eficiente. Em vez disso, use o middleware static-service (ou algo equivalente), que é otimizado para servir arquivos para aplicativos Express. Uma opção ainda melhor é usar um proxy reverso para servir arquivos estáticos; consulte Usar um proxy reverso para obter mais informações…
================================================
FILE: sections/production/frontendout.chinese.md
================================================
# 在node外处理您的前端资产
### 一段解释
在一个经典的 web 应用中,后端返回前端资源/图片给浏览器, 在node的世界,一个非常常见的方法是使用 Express 静态中间件, 以数据流的形式把静态文件返回到客户端。但是, node并不是一个典型的 web应用, 因为它使用单个线程,对于同时服务多个文件,未经过任何优化。相反, 考虑使用反向代理、云存储或 CDN (例如Nginx, AWS S3, Azure Blob 存储等), 对于这项任务, 它们做了很多优化,并获得更好的吞吐量。例如, 像 nginx 这样的专业中间件在文件系统和网卡之间的直接挂钩, 并使用多线程方法来减少多个请求之间的干预。
您的最佳解决方案可能是以下形式之一:
1. 反向代理 – 您的静态文件将位于您的node应用的旁边, 只有对静态文件文件夹的请求才会由位于您的node应用前面的代理 (如 nginx) 提供服务。使用这种方法, 您的node应用负责部署静态文件, 而不是为它们提供服务。你的前端的同事会喜欢这种方法, 因为它可以防止 cross-origin-requests 的前端请求。
2. 云存储 – 您的静态文件将不会是您的node应用内容的一部分, 他们将被上传到服务, 如 AWS S3, Azure BlobStorage, 或其他类似的服务, 这些服务为这个任务而生。使用这种方法, 您的node应用即不负责部署静态文件, 也不为它们服务, 因此, 在node和前端资源之间完全解耦, 这是由不同的团队处理。
### 代码示例: 对于静态文件,典型的nginx配置
```
# configure gzip compression
gzip on;
keepalive 64;
# defining web server
server {
listen 80;
listen 443 ssl;
# handle static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### 其它博主说了什么
摘自博客 [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
>…开发模式下, 您可以使用 [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) 服务静态文件. 但是不要在生产中这样做, 因为这个函数为了每个文件请求,必须从文件系统中读取, 因此它会遇到很大的延迟, 并影响应用程序的整体性能。请注意, res.sendFile() 没有用系统调用 sendFile 实现, 这将使它更高效。相反, 使用serve-static中间件 (或类似的东西), 在express应用中服务文件,这是优化了的。更佳的选择是使用反向代理来服务静态文件; 有关详细信息, 请参阅使用反向代理…
================================================
FILE: sections/production/frontendout.french.md
================================================
# 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…
================================================
FILE: sections/production/frontendout.japanese.md
================================================
# フロントエンドの資産を Node から取り出す
### 一段落説明
古典的なウェブアプリケーションでは、バックエンドはフロントエンドやグラフィックをブラウザに提供します。Node の世界で非常に一般的なアプローチは、クライアントへの静的ファイルのストリーム化のために Express の静的ミドルウェアを使用することです。しかし – Node は、一度に多くのファイルを提供するために最適化されていないシングルスレッドを利用しているため、典型的なウェブアプリではありません。代わりに、リバースプロキシ(nginx、HAProxyなど)、クラウドストレージや CDN(AWS S3、Azure Blob Storage など)を使用して、このタスクのために多くの最適化を利用し、はるかに優れたスループットを得ることを検討してください。例えば、nginx のような特殊なミドルウェアは、ファイルシステムとネットワークカード間のダイレクトフックを具現化し、複数のリクエスト間の介入を最小限に抑えるためにマルチスレッドアプローチを使用しています。
最適なソリューションは、以下のフォームのいずれかに従っている可能性があります:
1. リバースプロキシの使用 – 静的ファイルは Node アプリケーションのすぐ隣に配置され、静的ファイルフォルダへのリクエストだけが nginx のような Node アプリケーションの前にあるプロキシによって提供されます。このアプローチを使用すると、Node アプリは静的ファイルをデプロイする責任がありますが、それらを提供する責任はありません。フロントエンドからのクロスオリジンリクエストを防ぐことができるので、フロントエンドの同僚はこのアプローチを気に入るでしょう。
2. クラウドストレージ – 静的ファイルは Node アプリのコンテンツの一部ではなく、AWS S3、Azure BlobStorage、またはこのミッションのために生まれた他の類似のサービスにアップロードされます。このアプローチを使用すると、Node アプリは静的ファイルをデプロイする責任がなく、静的ファイルを提供する責任もありません。そのため、Node とフロントエンドの間は完全に分離され、異なるチームによって処理されます。
### 設定例: 静的ファイルを提供するための典型的な nginx の設定
```nginx
# gzip 圧縮を設定する
gzip on;
keepalive 64;
# ウェブサーバを定義する
server {
listen 80;
listen 443 ssl;
# 静的コンテンツを扱う
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### 他のブロガーが言っていること
ブログ [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/) より:
>…開発では、[res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) を使用して静的ファイルを提供することができます。この関数はファイル要求ごとにファイルシステムから読み込まなければならず、大幅な待ち時間が発生し、アプリの全体的なパフォーマンスに影響を与えることになるため、本番環境では行わないでください。res.sendFile() は、より効率的になる sendfile システムコールでは実装されていないことに注意してください。代わりに、Express アプリ用にファイルを提供するために最適化された serve-static ミドルウェア (または同等のもの) を使用してください。さらに良い方法は、静的ファイルを提供するリバースプロキシを使うことです。; 詳細については、リバースプロキシの使用を参照してください。…
================================================
FILE: sections/production/frontendout.korean.md
================================================
# Get your frontend assets out of Node
### One Paragraph Explainer
In a classic web app the backend serves the frontend/graphics to the browser, a very common approach in the Node’s world is to use Express static middleware for streamlining static files to the client. BUT – Node is not a typical webapp as it utilizes a single thread that is not optimized to serve many files at once. Instead, consider using a reverse proxy (e.g. nginx, HAProxy), cloud storage or CDN (e.g. AWS S3, Azure Blob Storage, etc) that utilizes many optimizations for this task and gain much better throughput. For example, specialized middleware like nginx embodies direct hooks between the file system and the network card and uses a multi-threaded approach to minimize intervention among multiple requests.
Your optimal solution might wear one of the following forms:
1. Using a reverse proxy – your static files will be located right next to your Node application, only requests to the static files folder will be served by a proxy that sits in front of your Node app such as nginx. Using this approach, your Node app is responsible deploying the static files but not to serve them. Your frontend’s colleague will love this approach as it prevents cross-origin-requests from the frontend.
2. Cloud storage – your static files will NOT be part of your Node app content, they will be uploaded to services like AWS S3, Azure BlobStorage, or other similar services that were born for this mission. Using this approach, your Node app is not responsible deploying the static files neither to serve them, hence a complete decoupling is drawn between Node and the Frontend which is anyway handled by different teams.
### Configuration example: typical nginx configuration for serving static files
```nginx
# configure gzip compression
gzip on;
keepalive 64;
# defining web server
server {
listen 80;
listen 443 ssl;
# handle static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### What Other Bloggers Say
From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
>…In development, you can use [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) to serve static files. But don’t do this in production, because this function has to read from the file system for every file request, so it will encounter significant latency and affect the overall performance of the app. Note that res.sendFile() is not implemented with the sendfile system call, which would make it far more efficient. Instead, use serve-static middleware (or something equivalent), that is optimized for serving files for Express apps. An even better option is to use a reverse proxy to serve static files; see Use a reverse proxy for more information…
================================================
FILE: sections/production/frontendout.md
================================================
# Get your frontend assets out of Node
### One Paragraph Explainer
In a classic web app the backend serves the frontend/graphics to the browser, a very common approach in the Node’s world is to use Express static middleware for streamlining static files to the client. BUT – Node is not a typical webapp as it utilizes a single thread that is not optimized to serve many files at once. Instead, consider using a reverse proxy (e.g. nginx, HAProxy), cloud storage or CDN (e.g. AWS S3, Azure Blob Storage, etc) that utilizes many optimizations for this task and gain much better throughput. For example, specialized middleware like nginx embodies direct hooks between the file system and the network card and uses a multi-threaded approach to minimize intervention among multiple requests.
Your optimal solution might wear one of the following forms:
1. Using a reverse proxy – your static files will be located right next to your Node application, only requests to the static files folder will be served by a proxy that sits in front of your Node app such as nginx. Using this approach, your Node app is responsible deploying the static files but not to serve them. Your frontend’s colleague will love this approach as it prevents cross-origin-requests from the frontend.
2. Cloud storage – your static files will NOT be part of your Node app content, they will be uploaded to services like AWS S3, Azure BlobStorage, or other similar services that were born for this mission. Using this approach, your Node app is not responsible deploying the static files neither to serve them, hence a complete decoupling is drawn between Node and the Frontend which is anyway handled by different teams.
### Configuration example: typical nginx configuration for serving static files
```nginx
# configure gzip compression
gzip on;
keepalive 64;
# defining web server
server {
listen 80;
listen 443 ssl;
# handle static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### What Other Bloggers Say
From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
>…In development, you can use [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) to serve static files. But don’t do this in production, because this function has to read from the file system for every file request, so it will encounter significant latency and affect the overall performance of the app. Note that res.sendFile() is not implemented with the sendfile system call, which would make it far more efficient. Instead, use serve-static middleware (or something equivalent), that is optimized for serving files for Express apps. An even better option is to use a reverse proxy to serve static files; see Use a reverse proxy for more information…
================================================
FILE: sections/production/frontendout.polish.md
================================================
# 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.
### Przykład konfiguracji: typowa konfiguracja nginx do obsługi plików statycznych
```nginx
# configure gzip compression
gzip on;
keepalive 64;
# defining web server
server {
listen 80;
listen 443 ssl;
# handle static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### 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…
================================================
FILE: sections/production/frontendout.russian.md
================================================
# Получайте ваши внешние ресурсы вне Node
### Объяснение в один абзац
В классическом веб-приложении серверная часть предоставляет интерфейс/графику браузеру. Очень распространенным подходом в мире Node является использование статического промежуточного программного обеспечения Express для оптимизации статических файлов для клиента. НО - Node не является типичным веб-приложением, поскольку использует один поток, который не оптимизирован для одновременного обслуживания нескольких файлов. Вместо этого рассмотрите возможность использования обратного прокси-сервера (например, nginx, HAProxy), облачного хранилища или CDN (например, AWS S3, хранилища BLOB-объектов Azure и т.д.), который использует множество оптимизаций для этой задачи и обеспечивает гораздо лучшую пропускную способность. Например, специализированное промежуточное программное обеспечение, такое как nginx, воплощает прямые перехватчики между файловой системой и сетевой картой и использует многопоточный подход, чтобы минимизировать вмешательство в множественные запросы.
Ваше оптимальное решение может носить одну из следующих форм:
1. Используя обратный прокси-сервер - ваши статические файлы будут расположены прямо рядом с вашим приложением Node, только запросы к папке со статическими файлами будут обрабатываться прокси-сервером, который находится перед вашим приложением Node, таким как nginx. Используя этот подход, ваше Node-приложение отвечает за развертывание статических файлов, но не за их обслуживание. Коллеге вашего внешнего интерфейса понравится этот подход, поскольку он предотвращает запросы внешнего происхождения от внешнего интерфейса.
2. Облачное хранилище - ваши статические файлы НЕ будут частью содержимого приложения Node, они будут загружены в такие сервисы, как AWS S3, Azure BlobStorage или другие подобные сервисы, созданные для этой миссии. Используя этот подход, ваше Node-приложение не несет ответственности за развертывание статических файлов и за их обслуживание, поэтому между Node и Frontend проводится полная развязка, которая в любом случае обрабатывается различными командами.
### Пример конфигурации: типичная конфигурация nginx для обслуживания статических файлов
```nginx
# configure gzip compression
gzip on;
keepalive 64;
# defining web server
server {
listen 80;
listen 443 ssl;
# handle static content
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /usr/local/silly_face_society/node/public;
access_log off;
expires max;
}
```
### Что говорят другие блоггеры
Из блога [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
> … В процессе разработки вы можете использовать [res.sendFile()](http://expressjs.com/4x/api.html#res.sendFile) для обслуживания статических файлов. Но не делайте этого в производственном процессе, потому что эта функция должна считывать данные из файловой системы для каждого запроса файла, поэтому она сталкивается со значительной задержкой и влияет на общую производительность приложения. Обратите внимание, что res.sendFile() не реализован с системным вызовом sendfile, что сделает его гораздо более эффективным. Вместо этого используйте статическое промежуточное программное обеспечение (или что-то подобное), оптимизированное для обслуживания файлов для приложений Express. Еще лучшим вариантом является использование обратного прокси-сервера для обслуживания статических файлов; см. Использование обратного прокси-сервера для получения дополнительной информации ...
================================================
FILE: sections/production/guardprocess.basque.md
================================================
# 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.
================================================
FILE: sections/production/guardprocess.brazilian-portuguese.md
================================================
# Poupe tempo de atividade do processo usando a ferramenta certa
### 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)), [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.
### O que Outros Blogueiros Dizem
* De [Boas Práticas em Produção do Express](https://expressjs.com/en/advanced/best-practice-performance.html):
> ... Em desenvolvimento, você iniciou sua aplicação simplesmente a partir da linha de comando com o node server.js ou algo semelhante. **Mas fazer isso na produção é uma receita para o desastre. Se o aplicativo falhar, ficará off-line** até que você reinicie. Para garantir que sua aplicação seja reiniciada se ela falhar, use um gerenciador de processos. Um gerenciador de processos é um “contêiner” para aplicativos que facilitam a implementação, fornece alta disponibilidade e permite gerenciar o aplicativo em tempo de execução.
* De um post no blog Medium [Understanding Node Clustering](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
> ... Entendendo o Cluster de Node.js no Docker “Os contêineres do Docker são ambientes virtuais simplificados e leves, projetados para simplificar os processos ao mínimo necessário. Processos que gerenciam e coordenam seus próprios recursos não são mais valiosos. **Em vez disso, as empresas de gerenciamento, como Kubernetes, Mesos e Gado, popularizaram o conceito de que esses recursos devem ser gerenciados em toda a infraestrutura.** Os recursos de CPU e memória são alocados por "agendadores" e os recursos de rede são gerenciados por balanceadores de carga fornecidos pelo stack.
================================================
FILE: sections/production/guardprocess.chinese.md
================================================
# 保护和重启你的失败进程(用正确的工具)
### 一段解释
在基本级别,必须保护Node进程并在出现故障时重新启动。简单地说, 对于那些小应用和不使用容器的应用 – 像这样的工具 [PM2](https://www.npmjs.com/package/pm2-docker) 是完美的,因为它们带来简单性,重启能力以及与Node的丰富集成。其他具有强大Linux技能的人可能会使用systemd并将Node作为服务运行。对于使用Docker或任何容器技术的应用程序来说,事情会变得更加有趣,因为集群管理和协调工具(比如[AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html),[Kubernetes](https://kubernetes.io/)等)会完成部署,监视和保持容器健康的功能。拥有所有丰富的集群管理功能(包括容器重启),为什么还要与其他工具(如PM2)混为一谈?这里并没有可靠的答案。将PM2保留在容器(主要是其容器特定版本[pm2-docker](https://www.npmjs.com/package/pm2-docker))中作为第一个守护层是有充分的理由的 - 在主机容器要求正常重启时,重新启动更快,并提供特定于node的功能比如向代码发送信号。其他选择可能会避免不必要的层。总而言之,没有一个解决方案适合所有人,但了解这些选择是最重要的。
### 其它博主说了什么
* 来自[Express 生成最佳实践](https://expressjs.com/en/advanced/best-practice-performance.html):
> ... 在开发中,您只需从命令行使用node.js或类似的东西启动您的应用程序。**但是在生产中这样做是一种灾难。 如果应用程序崩溃,它将掉线**,直到您重新启动它。要确保应用程序在崩溃时重新启动,请使用进程管理器。流程管理器是便于部署的应用程序的“容器”,提供高可用性,并使您能够在运行时管理应用程序。
* 摘自 the Medium blog post [了解节点集群](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
> ...了解Docker-Land中的NodeJS集群“Docker容器”是流线型的轻量级虚拟环境,旨在将流程简化为最低限度。管理和协调自己资源的流程不再有价值。**相反,像Kubernetes,Mesos和Cattle这样的管理层已经普及了这些资源应该在整个基础设施范围进行管理的概念**。CPU和内存资源由“调度器”分配,网络资源由堆栈提供的负载均衡器管理。
================================================
FILE: sections/production/guardprocess.french.md
================================================
# 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.
================================================
FILE: sections/production/guardprocess.japanese.md
================================================
# 障害が発生した場合は、プロセスを保護して再起動します(適切なツールを使用します)
### 一段落説明
基本的なレベルとして、ノードプロセスはガードされ、障害が発生したときに再起動されなければなりません。簡単に言うと、小さなアプリやコンテナを使わない人向けに – [PM2](https://www.npmjs.com/package/pm2-docker) のようなツールは、シンプルさ、再起動機能、そして Node との豊富な統合をもたらすので完璧です。Linux に強い人は systemd を使って Node をサービスとして動かすかもしれません。Docker やコンテナ技術を使用しているアプリケーションでは、クラスタ管理やコンテナのデプロイ、監視、修復を行うことができるオーケストレーションツールを使用するのが一般的なので、状況はさらに面白くなります。(例:[AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html)、[Kubernetes](https://kubernetes.io/) など) コンテナの再起動を含む、すべての豊富なクラスタ管理機能を持つのに、なぜ PM2 のような他のツールに干渉してしまうのでしょうか? 心配のない答えはありません。コンテナ内で PM2 を最初のガード層として維持するには十分な理由があります (主にコンテナ固有のバージョン [pm2-docker](https://www.npmjs.com/package/pm2-docker) ) – それは、プロセスを再起動する方がはるかに高速で、ホスティングコンテナが再起動を要求したときにコードにフラグを立てるなどの Node 固有の機能を提供します。不要なレイヤーを避けるために選ぶ人がいるかもしれません。この記事の結論としては、どのソリューションもそれらすべてに適しておらず、オプションを知ることが重要なことです。
### 他のブロガーが言っていること
* [Express 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やメモリのリソースは「スケジューラ」によって割り当てられ、ネットワークリソースはスタック提供のロードバランサによって管理されます。
================================================
FILE: sections/production/guardprocess.korean.md
================================================
# Guard and restart your process upon failure (using the right tool)
### One Paragraph Explainer
At the base level, Node processes must be guarded and restarted upon failures. Simply put, for small apps and those who don’t use containers – tools like [PM2](https://www.npmjs.com/package/pm2-docker) are perfect as they bring simplicity, restarting capabilities and also rich integration with Node. Others with strong Linux skills might use systemd and run Node as a service. Things get more interesting for apps that use Docker or any container technology since those are usually accompanied by cluster management and orchestration tools (e.g. [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/), etc) that deploy, monitor and heal containers. Having all those rich cluster management features including container restart, why mess up with other tools like PM2? There’s no bulletproof answer. There are good reasons to keep PM2 within containers (mostly its containers specific version [pm2-docker](https://www.npmjs.com/package/pm2-docker)) as the first guarding tier – it’s much faster to restart a process and provide Node-specific features like flagging to the code when the hosting container asks to gracefully restart. Other might choose to avoid unnecessary layers. To conclude this write-up, no solution suits them all and getting to know the options is the important thing
### What Other Bloggers Say
* From the [Express Production Best Practices](https://expressjs.com/en/advanced/best-practice-performance.html):
> ... In development, you started your app simply from the command line with node server.js or something similar. **But doing this in production is a recipe for disaster. If the app crashes, it will be offline** until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a “container” for applications that facilitate deployment, provides high availability, and enables you to manage the application at runtime.
* From the Medium blog post [Understanding Node Clustering](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
> ... Understanding Node.js Clustering in Docker-Land “Docker containers are streamlined, lightweight virtual environments, designed to simplify processes to their bare minimum. Processes that manage and coordinate their own resources are no longer as valuable. **Instead, management stacks like Kubernetes, Mesos, and Cattle have popularized the concept that these resources should be managed infrastructure-wide**. CPU and memory resources are allocated by “schedulers”, and network resources are managed by stack-provided load balancers.
================================================
FILE: sections/production/guardprocess.md
================================================
# Guard and restart your process upon failure (using the right tool)
### One Paragraph Explainer
At the base level, Node processes must be guarded and restarted upon failures. Simply put, for small apps and those who don’t use containers – tools like [PM2](https://www.npmjs.com/package/pm2) are perfect as they bring simplicity, restarting capabilities and also rich integration with Node. Others with strong Linux skills might use systemd and run Node as a service. Things get more interesting for apps that use Docker or any container technology since those are usually accompanied by cluster management and orchestration tools (e.g. [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/), etc) that deploy, monitor and heal containers. Having all those rich cluster management features including container restart, why mess up with other tools like PM2? There’s no bulletproof answer. There are good reasons to keep PM2 within containers (mostly its containers specific version [pm2-docker](https://www.npmjs.com/package/pm2-docker)) as the first guarding tier – it’s much faster to restart a process and provide Node-specific features like flagging to the code when the hosting container asks to gracefully restart. Other might choose to avoid unnecessary layers. To conclude this write-up, no solution suits them all and getting to know the options is the important thing
### What Other Bloggers Say
* From the [Express Production Best Practices](https://expressjs.com/en/advanced/best-practice-performance.html):
> ... In development, you started your app simply from the command line with node server.js or something similar. **But doing this in production is a recipe for disaster. If the app crashes, it will be offline** until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a “container” for applications that facilitate deployment, provides high availability, and enables you to manage the application at runtime.
* From the Medium blog post [Understanding Node Clustering](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
> ... Understanding Node.js Clustering in Docker-Land “Docker containers are streamlined, lightweight virtual environments, designed to simplify processes to their bare minimum. Processes that manage and coordinate their own resources are no longer as valuable. **Instead, management stacks like Kubernetes, Mesos, and Cattle have popularized the concept that these resources should be managed infrastructure-wide**. CPU and memory resources are allocated by “schedulers”, and network resources are managed by stack-provided load balancers.
================================================
FILE: sections/production/guardprocess.polish.md
================================================
# 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.
================================================
FILE: sections/production/guardprocess.russian.md
================================================
# Защищайте и перезапускайте свой процесс в случае неудачи (используя правильный инструмент)
### Объяснение в один абзац
На базовом уровне процессы Node должны быть защищены и перезапущены при сбоях. Проще говоря, для небольших приложений и тех, кто не использует контейнеры, такие инструменты, как [PM2](https://www.npmjs.com/package/pm2-docker), являются идеальными, поскольку они обеспечивают простоту, перезапускающие возможности, а также богатую интеграцию с узлом. Другие с сильными навыками Linux могут использовать systemd и запускать Node в качестве службы. Вещи становятся более интересными для приложений, использующих Docker или любую контейнерную технологию, поскольку они обычно сопровождаются инструментами управления кластером и оркестровки (например, [AWS ECS](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html), [Kubernetes](https://kubernetes.io/) и т.д.), которые разворачивают, контролируют и восстанавливают контейнеры. Имея все эти богатые функции управления кластером, включая перезапуск контейнера, зачем связываться с другими инструментами, такими как PM2? Там нет пуленепробиваемого ответа. Существуют веские причины держать PM2 в контейнерах (в основном это специфичная для контейнеров версия [pm2-docker](https://www.npmjs.com/package/pm2-docker)) в качестве первого уровня защиты - гораздо быстрее перезапустить обрабатывать и предоставлять специфичные для узла функции, такие как пометка кода, когда хост-контейнер запрашивает корректный перезапуск. Другие могут избежать ненужных слоев. В завершение этой статьи ни одно решение не подходит им всем, и важно знать варианты.
### Что говорят другие блоггеры
* Из [Express Production Best Practices](https://expressjs.com/en/advanced/best-practice-performance.html):
> ... В процессе разработки вы запускали свое приложение просто из командной строки с помощью узла server.js или чего-то подобного. **Но делать это на производстве - это путь к катастрофе. В случае сбоя приложения оно будет отключено** до тех пор, пока вы его не перезапустите. Чтобы приложение перезагружалось в случае сбоя, используйте диспетчер процессов. Диспетчер процессов - это "контейнер" для приложений, который облегчает развертывание, обеспечивает высокую доступность и позволяет управлять приложением во время выполнения.
* Из сообщения в Medium [Understanding Node Clustering](https://medium.com/@CodeAndBiscuits/understanding-nodejs-clustering-in-docker-land-64ce2306afef#.cssigr5z3):
> ... Понимание кластеризации Node.js в мире Docker: "Контейнеры Docker представляют собой упрощенные, легкие виртуальные среды, предназначенные для упрощения процессов до минимума. Процессы, которые управляют и координируют свои собственные ресурсы, уже не так ценны. **Вместо этого, стеки управления, такие как Kubernetes, Mesos и Cattle, популяризировали концепцию управления этими ресурсами во всей инфраструктуре**. Ресурсы ЦП и памяти распределяются "планировщиками", а сетевые ресурсы управляются балансировщиками нагрузки, предоставляемыми стеком".
================================================
FILE: sections/production/installpackageswithnpmci.basque.md
================================================
# 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.
================================================
FILE: sections/production/installpackageswithnpmci.french.md
================================================
# 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.
================================================
FILE: sections/production/installpackageswithnpmci.japanese.md
================================================
# 本番環境に npm ci を使ってパッケージをインストールする
### 一段落説明
[**依存関係をロックする**](./lockdependencies.japanese.md) に従って依存関係をロックしましたが、本番環境で使用されているパッケージのバージョンが正確であることを確認する必要があります。
パッケージのインストールに `npm ci` を使うと、まさにそれ以上のことができます。
* `package.json` と `package-lock.json` が一致していない (一致しているはずの) 場合や、ロックファイルがない場合は失敗します。
* もし `node_modules` フォルダが存在する場合は、インストールする前に自動的に削除される
* より速くなります! [リリースブログ記事](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable) によると、2倍近く速くなっています。
### これはどんな時に役立つのでしょうか?
CI 環境や QA が、後に本番環境に送るものと全く同じパッケージバージョンでソフトウェアをテストすることが保証されています。
また、何らかの理由で cli コマンドではなく、直接 package.json を編集して手動で package.json を変更した場合、package.json と package-lock.json の間にギャップが生じてエラーが発生します。
### npm が言っていること
[npm ci ドキュメント](https://docs.npmjs.com/cli/ci.html) より
> このコマンドは npm-install と似ていますが、テストプラットフォームや継続的インテグレーション、デプロイメントなどの自動化された環境や、依存関係をクリーンインストールしていることを確認したい状況で使用することを目的としています。
[ `ci` コマンドのリリースを発表しているブログポスト](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)
> このコマンドは、継続的インテグレーション/継続的デプロイメントプロセスのためのビルドのパフォーマンスと信頼性を大幅に改善し、ワークフローで CI/CD を使用している開発者に一貫性のある高速な体験を提供します。
[npmjs: dependencies と devDepencies](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file)
> "dependencies": 本番環境のアプリケーションに必要なパッケージ
> "devDependencies": ローカルでの開発やテストにのみ必要なパッケージ
================================================
FILE: sections/production/installpackageswithnpmci.md
================================================
# 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.
================================================
FILE: sections/production/lockdependencies.basque.md
================================================
# Blokeatu menpekotasunak
### 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
```
### Kode adibidea: shrinkwrap.json fitxategia, menpekotasun zuhaitz zehatza osatzen duena
```json
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### Kode adibidea: npm 5 menpekotasunak blokeatzeko fitxategia - 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="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.brazilian-portuguese.md
================================================
# Bloqueio de dependências
### Explicação de um Parágrafo
Seu código depende de muitos pacotes externos, digamos que ele "requeira" e use momentjs-2.1.4. Depois, por padrão, quando você implanta para produção, o npm pode buscar momentjs 2.1.5, o que infelizmente traz alguns novos bugs à aplicação. Usando os arquivos de configuração do npm e o argumento ```–save-exact = true``` instrui o npm a se referir à *exata* versão que foi instalada, então da próxima vez que você executar ```npm install``` (em produção ou dentro de um contêiner Docker que você planeja enviar para a frente para testes), a mesma versão dependente será buscada. Uma abordagem alternativa e popular é usar um arquivo `.shrinkwrap` (gerado facilmente usando npm) que indica exatamente quais pacotes e versões devem ser instalados para que nenhum ambiente seja tentado a buscar versões mais novas do que o esperado.
* **Atualização:** a partir do npm 5, as dependências são bloqueadas automaticamente usando .shrinkwrap. O Yarn, um gerenciador de pacotes emergente, também bloqueia dependências por padrão.
### Exemplo de código: arquivo .npmrc que instrui o npm a usar as versões exatas
```npmrc
// salve isso como arquivo .npmrc no diretório do projeto
save-exact:true
```
### Exemplo de código: arquivo shrinkwrap.json que destila a árvore de dependência exata
```json
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### Exemplo de código: npm 5 arquivo de bloqueio de dependências - package.json
```json
{
"name": "package-name",
"version": "1.0.0",
"lockfileVersion": 1,
"dependencies": {
"cacache": {
"version": "9.2.6",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
"integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
},
"duplexify": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
"integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
"dependencies": {
"end-of-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
"integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.chinese.md
================================================
# 锁定依赖版本
### 一段解释
您的代码依赖于许多外部包,假设它“需要”和使用momentjs-2.1.4,默认情况下,当布署到生产中时,npm可能会获得momentjs 2.1.5,但不幸的是,这将带来一些新的bug。使用npm配置文件和设置 ```–save-exact=true``` 指示npm去完成安装,以便下次运行 ```npm install```(在生产或在Docker容器中,您计划将其用于测试)时,将获取相同的依赖版本。另一种可选择受欢迎的方法是使用一个shrinkwrap文件(很容易使用npm生成)指出应该安装哪些包和版本,这样就不需要环境来获取新版本了。
* **更新:** 在npm5中,使用.shrinkwrap依赖项会被自动锁定。Yarn,一个新兴的包管理器,默认情况下也会锁定依赖项。
### 代码示例: .npmrc文件指示npm使用精确的版本
```
// 在项目目录上保存这个为.npmrc 文件
save-exact:true
```
### 代码示例: shirnkwrap.json文件获取准确的依赖关系树
```javascript
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### 代码示例: npm5依赖锁文件 - package.json
```javascript
{
"name": "package-name",
"version": "1.0.0",
"lockfileVersion": 1,
"dependencies": {
"cacache": {
"version": "9.2.6",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
"integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
},
"duplexify": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
"integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
"dependencies": {
"end-of-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
"integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.french.md
================================================
# Verrouillez les dépendances
### 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
```
### Exemple de code : fichier shrinkwrap.json qui extrait l'arbre exact des dépendances
```json
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### Exemple de code : fichier de verrouillage des dépendances 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="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.japanese.md
================================================
# 依存関係をロックする
### 一段落説明
あなたのコードは多くの外部パッケージに依存しています。例えば、'require' して momentjs-2.1.4 を使用しているとします。デフォルトでは、本番環境にデプロイするときに npm が momentjs 2.1.5 をフェッチすることがありますが、これは残念ながらテーブルにいくつかの新しいバグをもたらすことになります。npm の設定ファイルと引数 ```-save-exact=true``` を使うことで、インストールされた*正確な*同じバージョンを参照するように npm に指示します。そのため、次に ```npm install``` を実行したとき(本番環境やテスト用に出荷する予定の Docker コンテナ内で)、同じ依存バージョンが取得されます。別のポピュラーな方法としては、`.shrinkwrap` ファイル ( npm を使って簡単に生成されます) を使って、どのパッケージとバージョンをインストールすべきかを正確に記述することで、環境が期待以上に新しいバージョンを取得したくなることがないようにする方法があります。
* **更新:** npm 5 の時点で、依存関係は .shrinkwrap を使って自動的にロックされます。新興のパッケージマネージャである Yarn も、デフォルトで依存関係をロックしています。
### コード例: 正確なバージョンを使用するように npm に指示する .npmrc ファイル
```npmrc
// これをプロジェクトディレクトリに .npmrc ファイルとして保存します
save-exact:true
```
### コード例: 依存関係ツリーを正確に蒸留した shrinkwrap.json ファイル
```json
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### コード例: 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="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.korean.md
================================================
# Lock dependencies
### One Paragraph Explainer
Your code depends on many external packages, let’s say it ‘requires’ and use momentjs-2.1.4, then by default when you deploy to production npm might fetch momentjs 2.1.5 which unfortunately brings some new bugs to the table. Using npm config files and the argument ```–save-exact=true``` instructs npm to refer to the *exact* same version that was installed so the next time you run ```npm install``` (in production or within a Docker container you plan to ship forward for testing) the same dependent version will be fetched. An alternative and popular approach is using a `.shrinkwrap` file (easily generated using npm) that states exactly which packages and versions should be installed so no environment can get tempted to fetch newer versions than expected.
* **Update:** as of npm 5, dependencies are locked automatically using .shrinkwrap. Yarn, an emerging package manager, also locks down dependencies by default.
### Code example: .npmrc file that instructs npm to use exact versions
```npmrc
// save this as .npmrc file on the project directory
save-exact:true
```
### Code example: shrinkwrap.json file that distills the exact dependency tree
```json
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### Code example: npm 5 dependencies lock file – package.json
```json
{
"name": "package-name",
"version": "1.0.0",
"lockfileVersion": 1,
"dependencies": {
"cacache": {
"version": "9.2.6",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
"integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
},
"duplexify": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
"integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
"dependencies": {
"end-of-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
"integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.md
================================================
# Lock dependencies
### One Paragraph Explainer
Your code depends on many external packages, let’s say it ‘requires’ and use momentjs-2.1.4, then by default when you deploy to production npm might fetch momentjs 2.1.5 which unfortunately brings some new bugs to the table. Using npm config files and the argument `–save-exact=true` instructs npm to refer to the _exact_ same version that was installed so the next time you run `npm install` (in production or within a Docker container you plan to ship forward for testing) the same dependent version will be fetched. 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
### Code example: .npmrc file that instructs npm to use exact versions
```npmrc
// save this as .npmrc file on the project directory
save-exact:true
```
### Code example: npm 5 dependencies lock file – 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="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.polish.md
================================================
# Zablokuj zależności
### 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
```
### Przykład kodu: plik shrinkwrap.json, który destyluje dokładne drzewo zależności
```json
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### Przykład kodu: plik blokady zależności npm 5 – package.json
```json
{
"name": "package-name",
"version": "1.0.0",
"lockfileVersion": 1,
"dependencies": {
"cacache": {
"version": "9.2.6",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
"integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
},
"duplexify": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
"integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
"dependencies": {
"end-of-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
"integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
}
}
}
}
}
```
================================================
FILE: sections/production/lockdependencies.russian.md
================================================
# Блокируйте зависимости
### Объяснение в один абзац
Ваш код зависит от многих внешних пакетов, допустим, что он "требует" и использует momentjs-2.1.4, тогда по умолчанию при развертывании в рабочей среде npm может получить momentjs-2.1.5, что, к сожалению, приводит к появлению новых ошибок. Использование файлов конфигурации npm и параметра ```-save-correct = true``` указывает npm ссылаться на *точную* версию, которая была установлена, поэтому при следующем запуске ```npm install``` (в работе или в контейнере Docker, который вы планируете отправить для тестирования) будет выбрана та же версия зависимости. Альтернативный и популярный подход заключается в использовании файла `.shrinkwrap` (легко генерируемого с помощью npm), в котором указывается, какие именно пакеты и версии следует установить, чтобы ни у одной среды не было соблазна получить более новые версии, чем ожидалось.
* **Обновление:** начиная с npm 5, зависимости блокируются автоматически с помощью .shrinkwrap. Yarn, еще один менеджер пакетов, также блокирует зависимости по умолчанию.
### Пример кода: файл .npmrc, который указывает npm использовать точные версии
```npmrc
// save this as .npmrc file on the project directory
save-exact:true
```
### Пример кода: файл shrinkwrap.json, в котором определяется точное дерево зависимостей
```json
{
"name": "A",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.1.0"
}
}
}
}
}
```
### Пример кода: файл блокировки зависимостей npm 5 - package.json
```json
{
"name": "package-name",
"version": "1.0.0",
"lockfileVersion": 1,
"dependencies": {
"cacache": {
"version": "9.2.6",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
"integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
},
"duplexify": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz",
"integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=",
"dependencies": {
"end-of-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
"integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4="
}
}
}
}
}
```
================================================
FILE: sections/production/logrouting.basque.md
================================================
# Aplikazioaren kodeak ez luke erregistroen bideraketa kudeatu beharko
### 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

================================================
FILE: sections/production/logrouting.brazilian-portuguese.md
================================================
# Não direcione logs dentro do aplicativo
### Explicação em um Parágrafo
O código da aplicação não deve manipular o roteamento de log, mas deve usar um utilitário de logger para gravar em `stdout/stderr`. "Roteamento de log" significa selecionar e enviar logs para um local diferente da aplicação ou processo da aplicação, por exemplo, gravar os logs em um arquivo, banco de dados etc. A razão para isso é principalmente dupla: 1) separação de interesses e 2) [Melhores práticas de 12 fatores para aplicações modernas](https://12factor.net/logs).
Muitas vezes pensamos em "separação de interesses" em termos de pedaços de código entre serviços e entre os próprios serviços, mas isso se aplica também aos componentes mais "infra-estruturais". Seu código da aplicação não deve manipular algo que deve ser tratado pela infraestrutura/ambiente de execução (na maioria das vezes nos dias de hoje, contêineres). O que acontece se você definir os locais de log em sua aplicação, mas depois precisar alterar esse local? Isso resulta em uma alteração e implementação de código. Ao trabalhar com plataformas baseadas em contêiner/nuvem, os contêineres podem delegar e desligar ao escalar para demandas de desempenho, portanto, não podemos ter certeza de onde um arquivo de log terminará. O ambiente de execução (container) deve decidir para onde os arquivos de log serão roteados. O aplicativo deve apenas registrar o que precisa para `stdout`/`stderr`, e o ambiente de execução deve ser configurado para pegar o fluxo de log a partir de lá e roteá-lo para onde ele precisa ir. Além disso, aqueles na equipe que precisam especificar e/ou alterar os destinos de log geralmente não são desenvolvedores de aplicações, mas fazem parte do DevOps e podem não ter familiaridade com o código da aplicação. Isso impede que eles façam alterações facilmente.
### Exemplo de código - Anti-padrão: roteamento de log bem acoplado ao aplicativo
```javascript
const { createLogger, transports, winston } = require('winston');
const winston-mongodb = require('winston-mongodb');
// log para dois arquivos diferentes, que o aplicativo agora deve estar preocupado com
const logger = createLogger({
transports: [
new transports.File({ filename: 'combined.log' }),
],
exceptionHandlers: [
new transports.File({ filename: 'exceptions.log' })
]
});
// log para MongoDB, que o aplicativo agora deve estar preocupado com
winston.add(winston.transports.MongoDB, options);
```
Fazendo isso dessa maneira, a aplicação agora lida com lógica de aplicativo/lógica de negócios e lógica de roteamento de log!
### Exemplo de código - melhor tratamento de logs + exemplo do Docker
In the application:
```javascript
const logger = new winston.Logger({
level: 'info',
transports: [
new (winston.transports.Console)()
]
});
logger.log('info', 'Mensagem de Log de Teste com algum parâmetro %s', 'algum parâmetro', { anything: 'Este é um metadado' });
```
Then, in the docker container `daemon.json`:
```javascript
{
"log-driver": "splunk", // usando apenas o Splunk como exemplo, poderia ser outro tipo de armazenamento
"log-opts": {
"splunk-token": "",
"splunk-url": "",
...
}
}
```
Então este exemplo acaba ficando como `log -> stdout -> Docker container -> Splunk`
### Citação de Blog: "O'Reilly"
Do [blog O'Reilly](https://www.oreilly.com/ideas/a-cloud-native-approach-to-logs),
> Quando você tem um número fixo de instâncias em um número fixo de servidores, o armazenamento de logs no disco parece fazer sentido. No entanto, quando sua aplicação pode ir dinamicamente de 1 instância em execução para 100 e você não tem ideia de onde essas instâncias estão sendo executadas, é necessário que seu provedor de nuvem lide com a agregação desses logs em seu nome.
### Citação: "12-Factor"
Do [guia de boas práticas 12-Factor](https://12factor.net/logs),
> Uma aplicação de doze fatores nunca se preocupa com o roteamento ou armazenamento de seu fluxo de saída. Não se deve tentar gravar ou gerenciar arquivos de log. Em vez disso, cada processo em execução grava seu fluxo de eventos, sem buffer, em stdout.
> Nas implantações de teste ou de produção, o fluxo de cada processo será capturado pelo ambiente de execução, agrupado com todos os outros fluxos da aplicação e roteado para um ou mais destinos finais para visualização e arquivamento de longo prazo. Esses destinos de arquivamento não são visíveis ou configuráveis pela aplicação e, em vez disso, são completamente gerenciados pelo ambiente de execução.
### Exemplo: Visão geral da arquitetura usando o Docker e o Splunk como exemplo

================================================
FILE: sections/production/logrouting.french.md
================================================
# 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

================================================
FILE: sections/production/logrouting.japanese.md
================================================
# アプリケーションコードでログのルーティングを処理してはいけません
### 一段落説明
アプリケーションコードはログルーティングを扱うべきではなく、代わりにロガーユーティリティを使用して `stdout/stderr` に書き込むべきです。「ログルーティング」とは、ログを拾ってアプリケーションやアプリケーションプロセスとは別の場所にプッシュすること、例えば、ファイルやデータベースなどにログを書き込むことを意味します。その理由は主に2つあります: 1)懸念事項の分離と、2) [12-Factor best practices for modern applications(現代のアプリケーションのための12ファクターのベストプラクティス)](https://12factor.net/logs)。
私たちはしばしば、サービス間やサービス自体の間のコードの断片という意味で「懸念の分離」を考えますが、これはより「インフラストラクチャ的」なコンポーネントにも適用されます。あなたのアプリケーションコードは、インフラストラクチャ/実行環境(最近ではコンテナが多い)で処理すべきものを処理すべきではありません。アプリケーションでログの場所を定義していて、後でその場所を変更する必要がある場合はどうなるでしょう? その結果、コードの変更とデプロイが必要になります。コンテナベース/クラウドベースのプラットフォームで作業する場合、パフォーマンスの要求に合わせてスケーリングする際にコンテナがスピンアップしたり、シャットダウンしたりすることがあるので、ログファイルがどこで終わるかわからないのです。そのため、ログファイルの行き先は実行環境 (コンテナ) が決めるべきです。アプリケーションは必要なものを `stdout` / `stderr` にログを記録し、実行環境はそこからログストリームを拾い、必要な場所にルートするように設定する必要があります。また、ログの送信先を指定したり変更したりする必要があるチームの人々は、アプリケーション開発者ではなく DevOps の一員であることが多く、アプリケーションのコードに精通していない可能性があります。このため、彼らが簡単に変更を行うことができません。
### コード例 – アンチパターン: アプリケーションと密接に結合されたログルーティング
```javascript
const { createLogger, transports, winston } = require('winston');
/**
* `winston-mongodb` を require すると
* `winston.transports.MongoDB` が公開されます。
*/
require('winston-mongodb');
// ログを2つの異なるファイルに保存します。これはアプリケーションが考慮する必要があります。
const logger = createLogger({
transports: [
new transports.File({ filename: 'combined.log' }),
],
exceptionHandlers: [
new transports.File({ filename: 'exceptions.log' })
]
});
// ログをMongoDBに保存します。これはアプリケーションが考慮する必要があります。
winston.add(winston.transports.MongoDB, options);
```
このようにして、アプリケーションはアプリケーション/ビジネスロジックとログルーティングロジックの両方を処理するようになりました。
### コード例 – より良いログ処理 + Docker の例
アプリケーション内部:
```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' });
```
そして、dockerコンテナの `daemon.json` で:
```json5
{
"log-driver": "splunk", // Splunk を例に挙げていますが、別のストレージタイプを入力する可能性があります。
"log-opts": {
"splunk-token": "",
"splunk-url": "",
//...
}
}
```
そのため、この例では `log -> stdout -> Docker container -> Splunk` のようになります。
### ブログ引用: 「オライリー・ジャパン
[オライリーブログ](https://www.oreilly.com/ideas/a-cloud-native-approach-to-logs) より、
> 一定数のサーバ上に一定数のインスタンスがある場合、ディスク上にログを保存することは理にかなっているように思えます。しかし、アプリケーションが実行中の1つのインスタンスから100のインスタンスへと動的に変化し、それらのインスタンスがどこで実行されているのか分からない場合は、クラウドプロバイダーにログの集計を代行してもらう必要があります。
### 引用: 「12ファクター」
[12-Factor best practices for logging(ロギングのための12ファクターのベストプラクティス)](https://12factor.net/logs) より、
> 12 ファクターのアプリは、出力ストリームのルーティングやストレージには決して関心を持ちません。ログファイルへの書き込みや管理を試みるべきではありません。その代わり、各実行中のプロセスは、バッファリングされていないイベントストリームを標準出力に書き込みます。
> ステージングまたは本番環境では、各プロセスのストリームは実行環境によってキャプチャされ、アプリからの他のすべてのストリームと照合され、1つまたはそれ以上の最終目的地にルーティングされて、表示および長期間アーカイブされます。これらのアーカイブ先は、アプリからは見えませんし、アプリで設定することもできず、代わりに実行環境によって完全に管理されます。
### 例: Docker と Splunk を例にしたアーキテクチャの概要

================================================
FILE: sections/production/logrouting.md
================================================
# Your application code should not handle log routing
### One Paragraph Explainer
Application code should not handle log routing, but instead should use a logger utility to write to `stdout/stderr`. “Log routing” means picking up and pushing logs to a some other location than your application or application process, for example, writing the logs to a file, database, etc. The reason for this is mostly two-fold: 1) separation of concerns and 2) [12-Factor best practices for modern applications](https://12factor.net/logs).
We often think of "separation of concerns" in terms of pieces of code between services and between services themselves, but this applies to the more “infrastructural” components as well. Your application code should not handle something that should be handled by infrastructure/the execution environment (most often these days, containers). What happens if you define the log locations in your application, but later you need to change that location? That results in a code change and deployment. When working with container-based/cloud-based platforms, containers can spin up and shut down when scaling to performance demands, so we can't be sure where a logfile will end up. The execution environment (container) should decide where the log files get routed to instead. The application should just log what it needs to to `stdout` / `stderr`, and the execution environment should be configured to pick up the log stream from there and route it to where it needs to go. Also, those on the team who need to specify and/or change the log destinations are often not application developers but are part of DevOps, and they might not have familiarity with the application code. This prevents them from easily making changes.
### Code Example – Anti-pattern: Log routing tightly coupled to application
```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);
```
Doing it this way, the application now handles both application/business logic AND log routing logic!
### Code Example – Better log handling + Docker example
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", // just using Splunk as an example, it could be another storage type
"log-opts": {
"splunk-token": "",
"splunk-url": "",
//...
}
}
```
So this example ends up looking like `log -> stdout -> Docker container -> Splunk`
### Blog Quote: "O'Reilly"
From the [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.
### Quote: "12-Factor"
From the [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.
### Example: Architecture overview using Docker and Splunk as an example

================================================
FILE: sections/production/logrouting.polish.md
================================================
# 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

================================================
FILE: sections/production/logrouting.russian.md
================================================
# Код вашего приложения не должен обрабатывать журналы маршрутизации
### Объяснение в один абзац
Код приложения не должен обрабатывать маршрутизацию журналов, вместо этого должен использовать утилиту ведения журнала для записи в `stdout/stderr`. "Маршрутизация журналов" означает сбор и отправку журналов в другое место, отличное от вашего приложения или процесса приложения, например, запись журналов в файл, базу данных и т.д. Причина этого в основном двоякая: 1) разделение проблемы и 2) [12-фактор лучших методов для современных приложений](https://12factor.net/logs).
Мы часто думаем о "разделении интересов" в части кода между сервисами и между самими сервисами, но это относится и к более "инфраструктурным" компонентам. Код вашего приложения не должен обрабатывать то, что должно обрабатываться инфраструктурой/средой исполнения (чаще всего в наши дни, контейнерами). Что произойдет, если вы определите местоположения журналов в своем приложении, но позже вам нужно будет изменить это местоположение? Это приводит к изменению кода и развертыванию. При работе с контейнерными/облачными платформами контейнеры могут раскручиваться и закрываться при масштабировании в соответствии с требованиями к производительности, поэтому мы не можем быть уверены, где будет находиться файл журнала. Среда выполнения (контейнер) должна решить, куда вместо этого будут направлены файлы журнала. Приложение должно просто записывать то, что ему нужно, в `stdout`/`stderr`, а среда выполнения должна быть настроена так, чтобы он брал поток журналов оттуда и направлял его туда, куда он должен идти. Кроме того, те члены команды, которым необходимо указать и/или изменить места назначения журналов, часто не являются разработчиками приложений, но являются частью DevOps и могут не иметь представления о коде приложения. Это мешает им легко вносить изменения.
### Пример кода - антипаттерн: журнал маршрутизации тесно связан с приложением
```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);
```
Делая это таким образом, приложение теперь обрабатывает как логику приложения/бизнес, так и логику маршрутизации журнала!
### Пример кода - Улучшенная обработка журнала + пример Docker
В приложении:
```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' });
```
Затем в Docker-контейнере `daemon.json`:
```json5
{
"log-driver": "splunk", // just using Splunk as an example, it could be another storage type
"log-opts": {
"splunk-token": "",
"splunk-url": "",
//...
}
}
```
Таким образом, этот пример выглядит как `log -> stdout -> Docker container -> Splunk`
### Блог "O'Reilly"
Из блога [O'Reilly](https://www.oreilly.com/ideas/a-cloud-native-approach-to-logs),
> Когда у вас есть фиксированное количество экземпляров на фиксированном количестве серверов, кажется, что хранение журналов на диске имеет смысл. Однако, когда ваше приложение может динамически переходить от 1 запущенного экземпляра к 100, и вы не знаете, где запущены эти экземпляры, вам необходимо, чтобы ваш облачный провайдер занимался агрегированием этих журналов от вашего имени.
### Цитата из "12-Factor"
Из [12-Factor best practices for logging](https://12factor.net/logs),
> Двенадцатикратное приложение никогда не занимается маршрутизацией или хранением своего выходного потока. Оно не должено пытаться писать или управлять лог-файлами. Вместо этого каждый запущенный процесс записывает свой поток событий, без буферизации, в стандартный вывод.
> При промежуточном или производственном развертывании поток каждого процесса будет захвачен средой выполнения, сопоставлен со всеми другими потоками из приложения и направлен в одно или несколько конечных мест назначения для просмотра и долгосрочного архивирования. Эти архивные пункты назначения не видны и не могут быть изменены приложением, а полностью управляются средой выполнения.
### Пример: обзор архитектуры с использованием Docker и Splunk в качестве примера

================================================
FILE: sections/production/measurememory.basque.md
================================================
# 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".
================================================
FILE: sections/production/measurememory.brazilian-portuguese.md
================================================
# Meça e proteja o uso de memória
### Explicação em um Parágrafo
Em um mundo perfeito, um desenvolvedor Web não deve lidar com vazamentos de memória. Na realidade, os problemas de memória são uma pegadinha conhecida do Node. Acima de tudo, o uso da memória deve ser monitorado constantemente. Nos sites de desenvolvimento e produção pequena, você pode avaliar manualmente usando comandos do Linux ou ferramentas npm e bibliotecas como node-inspector e memwatch. A principal desvantagem dessas atividades manuais é que elas exigem que um ser humano monitore ativamente - para locais de produção sérios, é absolutamente vital usar ferramentas robustas de monitoramento, por exemplo. (AWS CloudWatch, DataDog ou qualquer sistema proativo semelhante) que alertam quando ocorre um vazamento. Existem também algumas diretrizes de desenvolvimento para evitar vazamentos: evite armazenar dados no nível global, use fluxos para dados com tamanho dinâmico, limite o escopo de variáveis usando let e const.
### O que Outros Blogueiros Dizem
* 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):
> ... “Embora este exemplo leve a resultados óbvios, o processo é sempre o mesmo:
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 [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 ”
“Por que a coleta de lixo é cara? O mecanismo JavaScript V8 emprega um mecanismo de coletor de lixo pare-o-mundo. Na prática, isso significa que o programa interrompe a execução enquanto a coleta de lixo está em andamento.”
================================================
FILE: sections/production/measurememory.chinese.md
================================================
# 测量和防范内存使用情况
### 一段解释
在一个完美的开发过程中, Web开发人员不应该处理内存泄漏问题。 实际上,内存问题是一个必须了解的Node已知的问题。首先,内存使用必须不断监视.在开发和小型生产站点上,您可以使用Linux命令或NPM工具和库(如node-inspector和memwatch)来手动测量。 这个人工操作的主要缺点是它们需要一个人进行积极的监控 - 对于正规的生产站点来说,使用鲁棒性监控工具是非常重要的,例如(AWS CloudWatch,DataDog或任何类似的主动系统),当泄漏发生时提醒。 防止泄漏的开发指南也很少:避免将数据存储在全局级别,使用动态大小的流数据,使用let和const限制变量范围。
### 其他博客说了什么
* 摘自博客 [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,以找出正在增长的内存泄露。”
* 摘自博客 [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 ”
“为什么垃圾收集代价很高? V8 JavaScript 使用了 stop-the-world (STW)的垃圾回收机制。 事实上,这意味着程序在进行垃圾回收时停止执行。”
================================================
FILE: sections/production/measurememory.french.md
================================================
# 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. »
================================================
FILE: sections/production/measurememory.japanese.md
================================================
# メモリ使用量を測定してガードする
### 一段落説明
完璧な世界では、ウェブ開発者はメモリリークに対処すべきではありません。実際には、メモリの問題は既知の Node の問題であり、気をつけなければなりません。何よりも、メモリ使用量を常に監視する必要があります。開発現場や小規模なプロダクションサイトでは、Linux コマンドや node-inspector や memwatch のような npm ツールやライブラリを使って手動で測定することもあります。このマニュアル活動の最大の欠点は、人間が積極的に監視する必要があることです。– 深刻なプロダクションサイトでは、( AWS CloudWatch、DataDog、または同様のプロアクティブシステム)などの堅牢な監視ツールを使用して、リークが発生した場合に警告を出すことが絶対的に重要です。漏洩を防ぐための開発ガイドラインもいくつかあります: グローバルレベルでのデータの保存を避ける、動的なサイズのデータにはストリームを使用する、let や const を使用して変数のスコープを制限する。
### 他のブロガーが言っていること
* ブログ [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 ガベージコレクタ機構を採用しています。これは実際には、ガベージコレクションの実行中にプログラムの実行を停止することを意味します。”
================================================
FILE: sections/production/measurememory.korean.md
================================================
# Measure and guard the memory usage
### One Paragraph Explainer
In a perfect world, a web developer shouldn’t deal with memory leaks. In reality, memory issues are a known Node’s gotcha one must be aware of. Above all, memory usage must be monitored constantly. In the development and small production sites, you may gauge manually using Linux commands or npm tools and libraries like node-inspector and memwatch. The main drawback of this manual activities is that they require a human being actively monitoring – for serious production sites, it’s absolutely vital to use robust monitoring tools e.g. (AWS CloudWatch, DataDog or any similar proactive system) that alerts when a leak happens. There are also few development guidelines to prevent leaks: avoid storing data on the global level, use streams for data with dynamic size, limit variables scope using let and const.
### What Other Bloggers Say
* From the blog [Dyntrace](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):
> ... “Although this example leads to obvious results the process is always the same:
Create heap dumps with some time and a fair amount of memory allocation in between
Compare a few dumps to find out what’s growing”
* From the blog [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.”
================================================
FILE: sections/production/measurememory.md
================================================
# Measure and guard the memory usage
### One Paragraph Explainer
In a perfect world, a web developer shouldn’t deal with memory leaks. In reality, memory issues are a known Node’s gotcha one must be aware of. Above all, memory usage must be monitored constantly. In the development and small production sites, you may gauge manually using Linux commands or npm tools and libraries like node-inspector and memwatch. The main drawback of this manual activities is that they require a human being actively monitoring – for serious production sites, it’s absolutely vital to use robust monitoring tools e.g. (AWS CloudWatch, DataDog or any similar proactive system) that alerts when a leak happens. There are also few development guidelines to prevent leaks: avoid storing data on the global level, use streams for data with dynamic size, limit variables scope using let and const.
### What Other Bloggers Say
* From the blog [Dyntrace](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):
> ... “Although this example leads to obvious results the process is always the same:
Create heap dumps with some time and a fair amount of memory allocation in between
Compare a few dumps to find out what’s growing”
* From the blog [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.”
================================================
FILE: sections/production/measurememory.polish.md
================================================
# 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.”
================================================
FILE: sections/production/measurememory.russian.md
================================================
# Измеряйте и защищайте использование памяти
### Объяснение в один абзац
В идеальном мире веб-разработчик не должен иметь дело с утечками памяти. На самом деле проблемы с памятью - это известная проблема Node, о которой нужно знать. Прежде всего, использование памяти должно постоянно контролироваться. На сайтах в стадии разработки или небольшого производства вы можете измерить это вручную, используя команды Linux или инструменты и библиотеки npm, такие как node-inspector и memwatch. Основным недостатком этих ручных действий является то, что они требуют активного участия человека для мониторинга - для серьезных производственных площадок абсолютно необходимо использовать надежные инструменты мониторинга, например, (AWS CloudWatch, DataDog или любая аналогичная проактивная система), которая предупреждает, когда происходит утечка. Существует также несколько рекомендаций по разработке для предотвращения утечек: избегайте хранения данных на глобальном уровне, используйте потоки для данных с динамическим размером, ограничивайте область видимости переменных с помощью let и const.
### Что говорят другие блоггеры
* Из блога [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ГБ памяти, которая должна быть ограничена при работе в системах с меньшим объемом памяти. Это ожидаемое поведение, поскольку сборка мусора является очень дорогостоящей операцией.
Решением для этого было добавление дополнительного параметра в процесс Node.js:
node –max_old_space_size=400 server.js –production"
"Почему сбор мусора стоит дорого? Движок V8 JavaScript использует механизм сборки мусора, который останавливает мир. На практике это означает, что программа останавливает выполнение, пока идет сбор мусора".
================================================
FILE: sections/production/monitoring.basque.md
================================================
# 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? …
================================================
FILE: sections/production/monitoring.brazilian-portuguese.md
================================================
# Monitoramento!
### Explicação em um Parágrafo
No nível básico, monitoramento significa que você pode *facilmente* identificar quando coisas ruins acontecem na produção. Por exemplo, ao ser notificado por email ou Slack. O desafio é escolher o conjunto certo de ferramentas que satisfarão suas necessidades sem quebrar seu banco. Posso sugerir, comece definindo o conjunto principal de métricas que devem ser observadas para garantir um estado íntegro - CPU, RAM do servidor, RAM do processo do Node (menos de 1,4 GB), o número de erros no último minuto, o número de reinícios do processo, tempo médio de resposta. Em seguida, analise alguns recursos avançados que você pode gostar e adicione-os à sua lista de desejos. Alguns exemplos de um recurso de monitoramento de luxo: criação de perfil de banco de dados, medição de serviço cruzado (isto é, medição de transação comercial), integração front-end, expor dados brutos a clientes de BI personalizados, notificações do Slack e muitos outros.
Atingir os recursos avançados exige uma configuração demorada ou a compra de um produto comercial como Datadog, NewRelic e similares. Infelizmente, alcançar até mesmo o básico não é um passeio no parque, pois algumas métricas são relacionadas ao hardware (CPU) e outras vivem dentro do processo do Node (erros internos), portanto, todas as ferramentas simples requerem alguma configuração adicional. Por exemplo, soluções de monitoramento de fornecedores de nuvem (por exemplo, [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) informarão imediatamente sobre as métricas de hardware, mas não sobre o comportamento interno da aplicação. Por outro lado, soluções baseadas em log, como o ElasticSearch, não possuem a visualização de hardware por padrão. A solução é aumentar sua escolha com métricas ausentes, por exemplo, uma opção popular é enviar logs de aplicativos para o [Elastic stack](https://www.elastic.co/products) e configurar alguns agentes adicionais (por exemplo, [Beat](https://www.elastic.co/products)) para compartilhar informações relacionadas ao hardware para obter a imagem completa.
### 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](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.
> Tempo de resposta: porque a latência afeta diretamente seus clientes e negócios.
> Taxa de transferência: o tráfego ajuda você a entender o contexto de taxas de erro aumentadas e a latência também.
> Saturação: Diz quão “completo” é o seu serviço. Se o uso da CPU for de 90%, seu sistema pode lidar com mais tráfego? …
================================================
FILE: sections/production/monitoring.chinese.md
================================================
# 监控!
### 一段解释
基本来说,当在生产环境中发生意外时,监控意味着你能够很*容易*识别它们。比如,通过电子邮件或Slack获得通知。挑战在于选择既能满足你的需求又不会破坏防护的合适工具集。我建议, 首先定义一组核心的度量标准, 这些指标必须被监视, 以确保健康状态 – CPU, 服务器RAM, Node进程RAM(小于1.4GB),最后一分钟的错误数量,进程重启次数,平均响应时间。然后去看看你可能喜欢的一些高级功能,并添加到你的愿望清单。一些高级监控功能的例子:DB分析,跨服务测量(即测量业务事务),前端集成,将原始数据展示给自定义BI客户端,Slack 通知等等。
要实现高级功能需要冗长的设置或购买诸如Datadog,Newrelic之类的商业产品。不幸的是,实现基本功能也并不容易,因为一些测量标准是与硬件相关的(CPU),而其它则在node进程内(内部错误),因此所有简单的工具都需要一些额外的设置。例如,云供应商监控解决方案(例如[AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/))能立即告诉您硬件度量标准,但不涉及内部应用程序行为。另一方面,基于日志的解决方案(如ElasticSearch)默认缺少硬件视图。解决方案是通过缺少的指标来增加您的选择,例如,一个流行的选择是将应用程序日志发送到[Elastic stack](https://www.elastic.co/products)并配置一些额外的代理(例如[Beat](https://www.elastic.co/products))来共享硬件相关信息以获得完整的展现。
### 监控示例:AWS cloudwatch默认仪表板。很难提取应用内指标

### 监控示例:StackDriver默认仪表板。很难提取应用内指标

### 监控示例:Grafana作为可视化原始数据的UI层

### 其他博主说了什么
摘自博客 [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/):
> ...我们建议您为所有服务监听这些信号:
> 错误率:因为错误是用户面对的,并立即会影响您的客户。
> 响应时间:因为延迟会直接影响您的客户和业务。
> 吞吐量:流量可帮助您了解增加的错误率和延迟的上下文。
> 饱和度:饱和度告诉你你的服务有多“满”。如果CPU使用率是90%,您的系统可以处理更多的流量吗?...
================================================
FILE: sections/production/monitoring.french.md
================================================
# 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](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 ? …
================================================
FILE: sections/production/monitoring.japanese.md
================================================
# モニタリング!
### 一段落説明
非常に基本的なレベルでは、モニタリングは、プロダクションで悪いことが起こったときに*簡単に*識別できることを意味します。例えば、メールやSlackで通知を受けることで識別します。課題は、あなたの銀行口座を枯渇させることなく、あなたの要件を満たすための適切なツールのセットを選択することです。提案しますが、健全な状態を確保するために監視しなければならないメトリクスのコアセットを定義することから始めましょう - CPU、サーバー RAM、ノードプロセス RAM(1.4GB未満)、最後の1分間のエラーの数、プロセスの再起動の数、平均応答時間。その後、あなたが好きそうないくつかの高度な機能を確認し、あなたの希望のリストに追加してください。豪華なモニタリング機能の例をいくつか紹介します: DB プロファイリング、クロスサービス測定(ビジネストランザクションの測定など)、フロントエンド統合、カスタム BI クライアントへの生データの公開、Slack通知など。
高度な機能を実現するためには、セットアップに時間がかかるか、Datadog や NewRelic などの商用製品を購入する必要があります。残念ながら、いくつかのメトリクスはハードウェア関連( CPU)であり、他のメトリクスはノードプロセス内に存在する(内部エラー)ため、すべての簡単なツールは追加のセットアップが必要であり、基本的なことでさえも達成することは簡単ではありません。例えば、クラウドベンダーの監視ソリューション(例:[AWS CloudWatch](https://aws.amazon.com/cloudwatch/)、[Google StackDriver](https://cloud.google.com/stackdriver/))は、ハードウェアのメトリクスについてはすぐに教えてくれますが、内部のアプリの動作については教えてくれません。一方、ElasticSearch のようなログベースのソリューションは、デフォルトでハードウェアビューがありません。解決策は、欠落しているメトリクスを補強することです。例えば、一般的な選択肢は、アプリケーションログを [Elastic stack](https://www.elastic.co/products) に送信し、ハードウェア関連の情報を共有して全体像を把握するために、いくつかの追加エージェント(例えば [Beat](https://www.elastic.co/products) )を設定することです。
### モニタリング例: AWS cloudwatch のデフォルトダッシュボード。アプリ内メトリクスの抽出が難しい

### モニタリング例: StackDriver のデフォルトダッシュボード。アプリ内メトリクスの抽出が難しい

### モニタリング例: 生データを可視化するUIレイヤーとしての Grafana

### 他のブロガーが言っていること
[Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/) のブログより:
> ...すべてのサービスのために、これらの信号を見ることをお勧めします:
> エラー率: なぜなら、エラーはユーザーが直面するものであり、すぐに顧客に影響を与えるからです。
> 応答時間: 待ち時間が直接顧客やビジネスに影響を与えるからです。
> スループット: トラフィックは、エラー率と遅延の増加のコンテキストを理解するのに役立ちます。
> 飽和: サービスがどの程度「フル」であるかを示します。CPU 使用率が 90% の場合、システムはより多くのトラフィックを処理できますか?…
================================================
FILE: sections/production/monitoring.korean.md
================================================
# Monitoring!
### One Paragraph Explainer
At the very basic level, monitoring means you can *easily* identify when bad things happen at production. For example, by getting notified by email or Slack. The challenge is to choose the right set of tools that will satisfy your requirements without breaking your bank. May I suggest, start with defining the core set of metrics that must be watched to ensure a healthy state – CPU, server RAM, Node process RAM (less than 1.4GB), the number of errors in the last minute, number of process restarts, average response time. Then go over some advanced features you might fancy and add to your wish list. Some examples of a luxury monitoring feature: DB profiling, cross-service measuring (i.e. measure business transaction), front-end integration, expose raw data to custom BI clients, Slack notifications and many others.
Achieving the advanced features demands lengthy setup or buying a commercial product such as Datadog, NewRelic and alike. Unfortunately, achieving even the basics is not a walk in the park as some metrics are hardware-related (CPU) and others live within the node process (internal errors) thus all the straightforward tools require some additional setup. For example, cloud vendor monitoring solutions (e.g. [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) will tell you immediately about the hardware metrics but not about the internal app behavior. On the other end, Log-based solutions such as ElasticSearch lack the hardware view by default. The solution is to augment your choice with missing metrics, for example, a popular choice is sending application logs to [Elastic stack](https://www.elastic.co/products) and configure some additional agent (e.g. [Beat](https://www.elastic.co/products)) to share hardware-related information to get the full picture.
### Monitoring example: AWS cloudwatch default dashboard. Hard to extract in-app metrics

### 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](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? …
================================================
FILE: sections/production/monitoring.md
================================================
# Monitoring!
### One Paragraph Explainer
At the very basic level, monitoring means you can *easily* identify when bad things happen at production. For example, by getting notified by email or Slack. The challenge is to choose the right set of tools that will satisfy your requirements without breaking your bank. May I suggest, start with defining the core set of metrics that must be watched to ensure a healthy state – CPU, server RAM, Node process RAM (less than 1.4GB), the number of errors in the last minute, number of process restarts, average response time. Then go over some advanced features you might fancy and add to your wish list. Some examples of a luxury monitoring feature: DB profiling, cross-service measuring (i.e. measure business transaction), front-end integration, expose raw data to custom BI clients, Slack notifications and many others.
Achieving the advanced features demands lengthy setup or buying a commercial product such as Datadog, NewRelic and alike. Unfortunately, achieving even the basics is not a walk in the park as some metrics are hardware-related (CPU) and others live within the node process (internal errors) thus all the straightforward tools require some additional setup. For example, cloud vendor monitoring solutions (e.g. [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) will tell you immediately about the hardware metrics but not about the internal app behavior. On the other end, Log-based solutions such as ElasticSearch lack the hardware view by default. The solution is to augment your choice with missing metrics, for example, a popular choice is sending application logs to [Elastic stack](https://www.elastic.co/products) and configure some additional agent (e.g. [Beat](https://www.elastic.co/products)) to share hardware-related information to get the full picture.
### Monitoring example: AWS cloudwatch default dashboard. Hard to extract in-app metrics

### 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](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? …
================================================
FILE: sections/production/monitoring.polish.md
================================================
# 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? …
================================================
FILE: sections/production/monitoring.russian.md
================================================
# Мониторинг!
### Объяснение в один абзац
На самом базовом уровне мониторинг означает, что вы можете *легко* определить, когда на производстве происходят плохие вещи. Например, получая уведомления по электронной почте или Slack. Задача состоит в том, чтобы выбрать правильный набор инструментов, который удовлетворит ваши требования, не нарушая ваш банк. Позвольте мне начать с определения базового набора метрик, которые необходимо отслеживать для обеспечения работоспособного состояния - ЦП, ОЗУ сервера, ОЗУ процесса узла (менее 1,4ГБ), количество ошибок в последнюю минуту, количество перезапусков процесса, среднее время ответа. Затем перейдите к некоторым дополнительным функциям, которые вам могут понравиться, и добавьте их в свой список пожеланий. Некоторые примеры функции мониторинга класса "люкс": профилирование БД, межсервисное измерение (то есть измерение бизнес-транзакций), интеграция с внешним интерфейсом, предоставление необработанных данных для пользовательских клиентов BI, уведомления Slack и многие другие.
Для реализации расширенных функций требуется длительная настройка или покупка коммерческого продукта, такого как Datadog, NewRelic и тому подобное. К сожалению, достижение даже базовых знаний - это не прогулка в парке, поскольку некоторые метрики связаны с аппаратным обеспечением (ЦП), а другие живут в процессе узла (внутренние ошибки), поэтому все простые инструменты требуют некоторой дополнительной настройки. Например, решения мониторинга облачных поставщиков (например, [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Google StackDriver](https://cloud.google.com/stackdriver/)) скажут вам непосредственно о метриках оборудования, но не о внутреннем поведении приложения. С другой стороны, решениям на основе журнала, таким как ElasticSearch, по умолчанию не хватает аппаратного представления. Решение состоит в том, чтобы дополнить ваш выбор отсутствующими метриками, например, популярным выбором является отправка журналов приложений в [Elastic stack](https://www.elastic.co/products) и настройка некоторого дополнительного агента (например, [Beat]( https://www.elastic.co/products)) для обмена информацией об оборудовании, чтобы получить полную картину.
### Пример мониторинга: панель инструментов AWS cloudwatch по умолчанию. Трудно извлечь метрики в приложении

### Пример мониторинга: панель мониторинга по умолчанию для StackDriver. Трудно извлечь метрики в приложении

### Пример мониторинга: Grafana как слой пользовательского интерфейса, который визуализирует необработанные данные

### Что говорят другие блоггеры
Из блога [Rising Stack](https://blog.risingstack.com/node-js-performance-monitoring-with-prometheus/):
> … Мы рекомендуем вам смотреть эти сигналы для всех ваших услуг:
> Частота ошибок: потому что ошибки связаны с пользователем и сразу же влияют на ваших клиентов.
> Время отклика: потому что задержка напрямую влияет на ваших клиентов и бизнес.
> Пропускная способность: трафик помогает вам понять контекст повышенной частоты ошибок и задержки.
> Нагрузка: говорит о том, насколько "нагружен" ваш сервис. Если загрузка процессора составляет 90%, может ли ваша система обрабатывать больше трафика? ...
================================================
FILE: sections/production/productioncode.basque.md
================================================
# 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/)
================================================
FILE: sections/production/productioncode.brazilian-portuguese.md
================================================
# Deixe seu código pronto para produção
### Explicação em um Parágrafo
A seguir, uma lista de dicas de desenvolvimento que afetam significativamente a manutenção e a estabilidade da produção:
* O guia de doze fatores - Familiarize-se com o guia [Doze fatores](https://12factor.net/)
* Seja sem estado - Não salve dados localmente em um servidor Web específico (veja o marcador separado - "Seja sem estado")
* Cache - Utilize o cache intensamente, mas nunca falhe por causa da incompatibilidade de cache
* Teste de memória - calibre o uso de memória e vazamentos como parte do seu fluxo de desenvolvimento, ferramentas como "memwatch" podem facilitar muito essa tarefa
* Funções de nome - Minimize o uso de funções anônimas (ou seja, callbacks em linha), pois um perfilador de memória típico fornecerá uso de memória por nome de função
* Use ferramentas CI - Use ferramentas CI para detectar falhas antes de enviar para produção. Por exemplo, use o ESLint para detectar erros de referência e variáveis indefinidas. Use –trace-sync-io para identificar o código que usa APIs síncronas (em vez da versão assíncrona)
* Registre sabiamente - Inclua em cada informação contextual da declaração de log, esperançosamente no formato JSON, para que as ferramentas de agregadores de log, como o Elastic, possam pesquisar nessas propriedades (veja o marcador separado - "Aumentar a visibilidade usando logs inteligentes"). Além disso, inclua o ID da transação que identifica cada solicitação e permite correlacionar linhas que descrevem a mesma transação (veja o marcador separado - "Incluir ID da transação")
* Gerenciamento de erros - O tratamento de erros é o calcanhar de Aquiles dos sites de produção do Node.js - muitos processos do Node estão travando devido a pequenos erros, enquanto outros persistem em um estado defeituoso em vez de travar. Definir a sua estratégia de tratamento de erros é absolutamente essencial, leia aqui as minhas [práticas recomendadas de tratamento de erros](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
================================================
FILE: sections/production/productioncode.chinese.md
================================================
# 代码生产环境的准备
### 一段解释
以下是一个开发技巧的列表,它极大地影响了产品的维护和稳定性:
* 十二因素指南 — 熟悉[12因素](https://12factor.net/)指南
* 无状态 — 在一个特定的web服务器上不保存本地数据(请参阅相关条目 - “Be Stateless”)
* 高速缓存 — 大量使用缓存,但不会因为缓存不匹配而产生错误
* 测试内存 — 测量内存的使用和泄漏,是作为开发流程的一部分,诸如“memwatch”之类的工具可以极大地促进这一任务
* 命名函数 — 将匿名函数(例如,内联callbabk)的使用最小化,因为一个典型的内存分析器为每个方法名提供内存使用情况
* 使用CI工具 — 在发送到生产前使用CI工具检测故障。例如,使用ESLint来检测引用错误和未定义的变量。使用–trace-sync-io来识别用了同步api的代码(而不是异步版本)
* 明确的日志 — 包括在每个日志语句中希望用json格式记录上下文信息,以便于日志聚合工具,如Elastic可以在这些属性上搜索(请参阅相关条目 – “Increase visibility using smart logs”)。此外,还包括标识每个请求的事务id,并允许将描述相同事务的行关联起来(请参阅 — “Include Transaction-ID”)
* 错误管理 — 错误处理是Node.js生产站点的致命弱点 – 许多Node进程由于小错误而崩溃,然而其他Node进程则会在错误的状态下存活,而不是崩溃。设置你的错误处理策略绝对是至关重要的, 在这里阅读我的(错误处理的最佳实践)(http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
================================================
FILE: sections/production/productioncode.french.md
================================================
# 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/)
================================================
FILE: sections/production/productioncode.japanese.md
================================================
# コードを本番に即したものにする
### 一段落説明
以下は、プロダクションのメンテナンスと安定性に大きく影響する開発のヒントのリストです。:
* 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/) を読んでください。
================================================
FILE: sections/production/productioncode.korean.md
================================================
# Make your code production-ready
### One Paragraph Explainer
Following is a list of development tips that greatly affect the production maintenance and stability:
* The twelve-factor guide – Get familiar with the [Twelve factors](https://12factor.net/) guide
* Be stateless – Save no data locally on a specific web server (see separate bullet – ‘Be Stateless’)
* Cache – Utilize cache heavily, yet never fail because of cache mismatch
* Test memory – gauge memory usage and leaks as part your development flow, tools such as ‘memwatch’ can greatly facilitate this task
* Name functions – Minimize the usage of anonymous functions (i.e. inline callback) as a typical memory profiler will provide memory usage per method name
* Use CI tools – Use CI tool to detect failures before sending to production. For example, use ESLint to detect reference errors and undefined variables. Use –trace-sync-io to identify code that uses synchronous APIs (instead of the async version)
* Log wisely – Include in each log statement contextual information, hopefully in JSON format so log aggregators tools such as Elastic can search upon those properties (see separate bullet – ‘Increase visibility using smart logs’). Also, include transaction-id that identifies each request and allows to correlate lines that describe the same transaction (see separate bullet – ‘Include Transaction-ID’)
* Error management – Error handling is the Achilles’ heel of Node.js production sites – many Node processes are crashing because of minor errors while others hang on alive in a faulty state instead of crashing. Setting your error handling strategy is absolutely critical, read here my [error handling best practices](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
================================================
FILE: sections/production/productioncode.md
================================================
# Make your code production-ready
### One Paragraph Explainer
Following is a list of development tips that greatly affect the production maintenance and stability:
- The twelve-factor guide – Get familiar with the [Twelve factors](https://12factor.net/) guide
- Be stateless – Save no data locally on a specific web server (see separate bullet – ‘Be Stateless’)
- Cache – Utilize cache heavily, yet never fail because of cache mismatch
- Test memory – gauge memory usage and leaks as part your development flow, tools such as ‘memwatch’ can greatly facilitate this task
- Name functions – Minimize the usage of anonymous functions (i.e. inline callback) as a typical memory profiler will provide memory usage per method name
- Use CI tools – Use CI tool to detect failures before sending to production. For example, use ESLint to detect reference errors and undefined variables. Use –trace-sync-io to identify code that uses synchronous APIs (instead of the async version)
- Log wisely – Include in each log statement contextual information, hopefully in JSON format so log aggregators tools such as Elastic can search upon those properties (see separate bullet – ‘Increase visibility using smart logs’). Also, include transaction-id that identifies each request and allows to correlate lines that describe the same transaction (see separate bullet – ‘Include Transaction-ID’)
- 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/)
================================================
FILE: sections/production/productioncode.polish.md
================================================
# 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/)
================================================
FILE: sections/production/productioncode.russian.md
================================================
# Делайте ваш код готовым к работе
### Объяснение в один абзац
Ниже приведен список советов по разработке, которые сильно влияют на обслуживание и стабильность производства:
* Руководство по двенадцати факторам - ознакомьтесь с руководством [Twelve factors](https://12factor.net/)
* Будьте вне сохранения состояния - не сохраняйте данные локально на определенном веб-сервере (см. отдельную рекомендацию - "Будьте без сохранения")
* Кэш - интенсивно используйте кэш, но никогда не выходите из строя из-за несоответствия кеша
* Проверка памяти - измеряйте использование памяти и утечки как часть процесса разработки, такие инструменты, как "memwatch", могут значительно облегчить эту задачу
* Имя функции - Минимизируйте использование анонимных функций (т.е. встроенный обратный вызов), поскольку типичный профилировщик памяти обеспечит использование памяти для имени метода
* Используйте инструменты CI - используйте инструмент CI для обнаружения сбоев перед отправкой в производство. Например, используйте ESLint для обнаружения ошибок ссылок и неопределенных переменных. Используйте –trace-sync-io для определения кода, который использует синхронные API (вместо асинхронной версии)
* Разумно логируйте - включайте в каждый оператор журнала контекстную информацию, возможно, в формате JSON, чтобы средства агрегирования журналов, такие как Elastic, могли осуществлять поиск по этим свойствам (см. отдельную рекомендацию - "Увеличьте видимость с помощью умных журналов"). Кроме того, включите идентификатор транзакции, который идентифицирует каждый запрос и позволяет сопоставить строки, описывающие одну и ту же транзакцию (см. отдельную рекомендацию - "Включить идентификатор транзакции")
* Управление ошибками - обработка ошибок - это ахиллесова пята реальных сайтов Node.js - многие процессы Node завершаются сбоем из-за незначительных ошибок, в то время как другие зависают в аварийном состоянии вместо сбоя. Настройка вашей стратегии обработки ошибок является абсолютно критической, прочитайте здесь мои [error handling best practices](http://goldbergyoni.com/checklist-best-practices-of-node-js-error-handling/)
================================================
FILE: sections/production/setnodeenv.basque.md
================================================
# 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._

================================================
FILE: sections/production/setnodeenv.brazilian-portuguese.md
================================================
# Defina NODE_ENV = production
### Explicação em um Parágrafo
Variáveis de ambiente de processo são um conjunto de pares de valores-chave disponibilizados para qualquer programa em execução, geralmente para propósitos de configuração. Embora quaisquer variáveis possam ser usadas, o Node incentiva a convenção de usar uma variável chamada NODE_ENV para sinalizar se estamos em produção no momento. Essa determinação permite que os componentes forneçam diagnósticos melhores durante o desenvolvimento, por exemplo, desativando o armazenamento em cache ou emitindo instruções de log detalhadas. Qualquer ferramenta de implantação moderna - Chef, Puppet, CloudFormation, outros - suporta a configuração de variáveis de ambiente durante a implantação.
### Exemplo de código: definindo e lendo a variável de ambiente NODE_ENV
```javascript
// Configurando variáveis de ambiente no bash antes de iniciar o processo do Node
$ NODE_ENV=development
$ node
// Lendo a Variável de Ambiente Usando Código
if (process.env.NODE_ENV === “production”)
useCaching = true;
```
### O que Outros Blogueiros Dizem
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!*

================================================
FILE: sections/production/setnodeenv.chinese.md
================================================
# 配置环境变量 NODE_ENV = production
### 一段解释
进程的环境变量是一组键值对,可用于任何运行程序,通常用于配置。虽然可以使用其他任何变量,但Node鼓励使用一个名为NODE_ENV的变量来标记我们是否正在开发。这一决定允许组件在开发过程中能提供更好的诊断,例如禁用缓存或发出冗长的日志语句。任何现代部署工具 — Chef、Puppet、CloudFormation等 — 在部署时都支持设置环境变量。
### 代码实例:配置和读取NODE_ENV环境变量
```javascript
//在启动node进程前,在bash中设置环境变量
$ NODE_ENV=development
$ node
//使用代码读取环境变量
If(process.env.NODE_ENV === “production”)
useCaching = true;
```
### 其他博主说了什么
摘自这篇博客[dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
> ...在node.js中有一个约定, 它使用名为NODE_ENV的变量来设置当前工作模式。我们看到它实际上是读取NODE_ENV,如果它没有设置,则默认为“development”。我们清楚的看到,通过设置NODE_ENV为production,node.js可以处理请求的数量可以提高大约三分之二,而CPU的使用率会略有下降。 *让我强调一下:设置NODE_ENV为production可以让你的应用程序快3倍!*

================================================
FILE: sections/production/setnodeenv.french.md
================================================
# 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 !*

================================================
FILE: sections/production/setnodeenv.japanese.md
================================================
# NODE_ENV = production を設定する
### 一段落説明
プロセス環境変数は、実行中のプログラムで利用できるキーと値のペアのセットで、通常は設定の目的で利用できます。任意の変数を使うことができますが、Node は NODE_ENV と呼ばれる変数を使って、現在本番環境であるかどうかのフラグを立てる慣習を推奨しています。この決定により、コンポーネントは開発中にキャッシングを無効にしたり、冗長なログ文を出力したりするなど、より良い診断を提供することができます。Chef、Puppet、CloudFormation、その他の最新のデプロイツールは、デプロイ時に環境変数を設定することをサポートしています。
### コード例: 環境変数 NODE_ENV の設定と読み込み
```shell script
// ノードプロセスを起動する前に bash で環境変数を設定する
$ NODE_ENV=development
$ node
```
```javascript
// コードを使って環境変数を読み込む
if (process.env.NODE_ENV === 'production')
useCaching = true;
```
### 他のブロガーが言っていること
ブログ [dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) より:
> ...Node.js では、現在のモードを設定するために node_env という変数を使用する慣習があります。実際には NODE_ENV を読み込んで、設定されていない場合は「development」にデフォルトで設定されていることがわかります。NODE_ENV を本番環境に設定することで、Node.js が処理できるリクエスト数が約3分の2に跳ね上がり、CPU の使用率はわずかに低下することが明らかになっています。*これだけは強調しておきます: NODE_ENV を本番環境に設定すると、アプリケーションが3倍速くなります!*

================================================
FILE: sections/production/setnodeenv.korean.md
================================================
# Set NODE_ENV = production
### One Paragraph Explainer
Process environment variables is a set of key-value pairs made available to any running program, usually for configuration purposes. Though any variables can be used, Node encourages the convention of using a variable called NODE_ENV to flag whether we’re in production right now. This determination allows components to provide better diagnostics during development, for example by disabling caching or emitting verbose log statements. Any modern deployment tool – Chef, Puppet, CloudFormation, others – support setting environment variables during deployment
### Code example: Setting and reading the NODE_ENV environment variable
```javascript
// Setting environment variables in bash before starting the node process
$ NODE_ENV=development
$ node
// Reading the environment variable using code
if (process.env.NODE_ENV === “production”)
useCaching = true;
```
### What Other Bloggers Say
From the blog [dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
> ...In Node.js there is a convention to use a variable called NODE_ENV to set the current mode. We see that it, in fact, reads NODE_ENV and defaults to ‘development’ if it isn’t set. We clearly see that by setting NODE_ENV to production the number of requests Node.js can handle jumps by around two-thirds while the CPU usage even drops slightly. *Let me emphasize this: Setting NODE_ENV to production makes your application 3 times faster!*

================================================
FILE: sections/production/setnodeenv.md
================================================
# Set NODE_ENV = production
### One Paragraph Explainer
Process environment variables is a set of key-value pairs made available to any running program, usually for configuration purposes. Though any variables can be used, Node encourages the convention of using a variable called NODE_ENV to flag whether we’re in production right now. This determination allows components to provide better diagnostics during development, for example by disabling caching or emitting verbose log statements. Any modern deployment tool – Chef, Puppet, CloudFormation, others – support setting environment variables during deployment
### Code example: Setting and reading the NODE_ENV environment variable
```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;
```
### What Other Bloggers Say
From the blog [dynatrace](https://www.dynatrace.com/blog/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/):
> ...In Node.js there is a convention to use a variable called NODE_ENV to set the current mode. We see that it, in fact, reads NODE_ENV and defaults to ‘development’ if it isn’t set. We clearly see that by setting NODE_ENV to production the number of requests Node.js can handle jumps by around two-thirds while the CPU usage even drops slightly. *Let me emphasize this: Setting NODE_ENV to production makes your application 3 times faster!*

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.
================================================
FILE: sections/production/setnodeenv.polish.md
================================================
# 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!*

================================================
FILE: sections/production/setnodeenv.russian.md
================================================
# Установите NODE_ENV = production
### Объяснение в один абзац
Переменные среды - это набор пар ключ-значение, предоставляемых любой работающей программе, обычно для целей конфигурации. Хотя могут использоваться любые переменные, Node поощряет соглашение об использовании переменной с именем NODE_ENV, чтобы указать, находимся ли мы в данный момент в производстве. Это определение позволяет компонентам обеспечивать лучшую диагностику во время разработки, например, путем отключения кэширования или выдачи подробных операторов журнала. Любой современный инструмент развертывания - Chef, Puppet, CloudFormation и другие - поддерживает настройку переменных среды во время развертывания.
### Пример кода: установка и чтение переменной среды 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;
```
### Что говорят другие блоггеры
Из блога [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 раза быстрее!*

================================================
FILE: sections/production/smartlogging.basque.md
================================================
# 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 ...
================================================
FILE: sections/production/smartlogging.brazilian-portuguese.md
================================================
# Aumente a transparência usando smart logging
### Explicação em um Parágrafo
Já que você imprime declarações de log de qualquer maneira e obviamente precisa de alguma interface que envolva informações de produção nas quais possa rastrear erros e métricas principais (por exemplo, quantos erros ocorrem a cada hora e qual é o ponto final da API mais lento) por que não investir algum esforço em uma estrutura de registro robusta que satisfará todos requisitos? Conseguir isso requer uma decisão ponderada em três etapas:
**1. logging inteligente** – no mínimo, você precisa usar uma biblioteca de registro respeitável como [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) e escreva informações significativas em cada início e fim de transação. Considere também formatar instruções de log como JSON e fornecer todas as propriedades contextuais (por exemplo, ID de usuário, tipo de operação, etc.) para que a equipe de operações possa atuar nesses campos. Inclua também um ID de transação exclusivo em cada linha de registro. Para obter mais informações, consulte o marcador abaixo "Escrever ID de transação para registrar". Um último ponto a considerar também é incluir um agente que registre os recursos do sistema, como memória e CPU, por exemplo o Elastic Beat.
**2. agregação inteligente** – depois de obter informações abrangentes sobre o sistema de arquivos dos servidores, é hora de enviá-las periodicamente para um sistema que agrega, facilita e visualiza esses dados. O stack Elastic, por exemplo, é uma escolha popular e gratuita que oferece todos os componentes para agregar e visualizar dados. Muitos produtos comerciais fornecem funcionalidade semelhante apenas reduzem significativamente o tempo de configuração e não requerem hospedagem.
**3. visualização inteligente** – agora as informações são agregadas e pesquisáveis, uma pessoa pode ficar satisfeita apenas com o poder de pesquisar facilmente os logs, mas isso pode ir muito além sem codificar ou gastar muito esforço. Agora, podemos mostrar métricas operacionais importantes, como taxa de erros, CPU média ao longo do dia, quantos novos usuários optaram por participar na última hora e qualquer outra métrica que ajude a gerenciar e melhorar nossa aplicação.
### 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

### Citações de Blog: Requisitos do Logger
Do blog [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
> Vamos identificar alguns requisitos (para um logger):
> 1. Carimbo de data/hora de cada linha de log. Este é bastante auto-explicativo - você deve ser capaz de dizer quando cada entrada de log ocorreu.
> 2. Formato de registro deve ser facilmente entendido por seres humanos, bem como máquinas.
> 3. Permite múltiplos fluxos de destino configuráveis. Por exemplo, você pode estar gravando logs de rastreio em um arquivo, mas quando um erro é encontrado, grava no mesmo arquivo, depois no arquivo de erro e envia um email ao mesmo tempo…
================================================
FILE: sections/production/smartlogging.chinese.md
================================================
# 使用智能日志使你的应用程序变得清晰
### 一段解释
无论如何,您要打印日志,而且需要一些可以在其中跟踪错误和核心指标的接口来展示生产环境信息(例如,每小时发生了多少错误,最慢的API节点是哪一个)为什么不在健壮的日志框架中进行一些适度的尝试呢? 要实现这一目标,需要在三个步骤上做出深思熟虑的决定:
**1. 智能日志** – 在最基本的情况下,您需要使用像[Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan)这样有信誉的日志库,在每个事务开始和结束时输出有意义的信息。还可以考虑将日志语句格式化为JSON,并提供所有上下文属性(如用户id、操作类型等)。这样运维团队就可以在这些字段上操作。在每个日志行中包含一个唯一的transaction ID,更多的信息查阅条款 “Write transaction-id to log”。最后要考虑的一点还包括一个代理,它记录系统资源,如内存和CPU,比如Elastic Beat。
**2. 智能聚合** – 一旦您在服务器文件系统中有了全面的信息,就应该定期将这些信息推送到一个可以聚合、处理和可视化数据的系统中。例如,Elastic stack是一种流行的、自由的选择,它提供所有组件去聚合和产生可视化数据。许多商业产品提供了类似的功能,只是它们大大减少了安装时间,不需要主机托管。
**3. 智能可视化** – 现在的信息是聚合和可搜索的, 一个可以满足仅仅方便地搜索日志的能力, 可以走得更远, 没有编码或花费太多的努力。我们现在可以显示一些重要的操作指标, 如错误率、平均一天CPU使用, 在过去一小时内有多少新用户选择, 以及任何其他有助于管理和改进我们应用程序的指标。
### 可视化示例: Kibana(Elastic stack的一部分)促进了对日志内容的高级搜索

### 可视化示例: Kibana(Elastic stack的一部分)基于日志来可视化数据

### 博客应用: Logger的需求
摘自博客 [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
> 让我们识别一些需求(对于一个日志记录器来说):
> 1. 每条日志对应一个时间戳。这个很好解释 – 您应该能够判断每个日志条目出现的时间。
> 2. 日志格式应该很容易被人和机器消化理解。
> 3. 允许多个可配置的目标流。例如,您可能在一个文件中写入trace日志,但是当遇到错误时,将其写入相同的文件,然后写入错误日志文件并同时发送电子邮件...
================================================
FILE: sections/production/smartlogging.french.md
================================================
# 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…
================================================
FILE: sections/production/smartlogging.japanese.md
================================================
# スマートログを使ってアプリを透明にする
### 一段落説明
どちらにしろログステートメントを出力しているのだから、エラーやコアメトリクスをトレースできるような本番環境の情報をラップアップするインタフェースが必要なのは明らかです (例えば、毎時何個のエラーが発生しているか、最も遅いAPIエンドポイントはどれかなど)。すべてのボックスをチェックする堅牢なロギングフレームワークに適度な努力を投資してはどうでしょうか? これを実現するためには、3つのステップについて熟考した上での決断が必要です。
**1. スマートロギング** – 最低限、[Winston](https://github.com/winstonjs/winston)、[Bunyan](https://github.com/trentm/node-bunyan) のような評判の良いロギングライブラリを使用し、各トランザクションの開始と終了時に意味のある情報を書く必要があります。また、ログステートメントを JSON としてフォーマットし、すべてのコンテキストプロパティ(ユーザーID、操作タイプなど)を提供して、運用チームがそれらのフィールドを操作できるようにすることを検討してください。また、各ログ行に一意のトランザクションIDを含めてください。詳細については、以下の「トランザクションIDをログに書き込む」を参照してください。最後に考慮すべき点として、Elastic Beat のようにメモリや CPU のようなシステムリソースをログに記録するエージェントも含まれています。
**2. スマートアグリゲーション** – サーバーのファイルシステムに関する包括的な情報を入手したら、定期的にこれらのデータを集約し、容易にし、可視化するシステムにプッシュしてください。 例えば、Elastic stack は、データを集約して可視化するためのすべてのコンポーネントを提供する、人気のある無料の選択肢です。多くの商用製品が同様の機能を提供していますが、それらはセットアップ時間を大幅に削減し、ホスティングを必要としません。
**3. スマートビジュアライゼーション** – 情報が集約され、検索可能になった今、ログを簡単に検索できる力だけで満足することができますが、これはコーディングや労力をかけずにはるかに先に進むことができます。 エラー率、1日の平均 CPU、最後の1時間にオプトインした新規ユーザーの数など、重要な運用上の指標を表示することができ、アプリの管理と改善に役立つその他の指標を表示することができます。
### 可視化の例: Kibana (Elastic stack の一部) はログコンテンツの高度な検索を容易にします

### 可視化の例: Kibana (Elastic stack の一部) はログに基づいてデータを可視化します

### ブログ引用: ロガーの要件
ブログ [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/) より:
> いくつかの(ロガーのための)要件を確認してみましょう:
> 1. 各ログ行にタイムスタンプを付けます。これは非常にわかりやすいものです - 各ログエントリがいつ発生したかがわかるはずです。
> 2. ロギングのフォーマットは、機械だけでなく人間にも分かりやすいものでなければなりません。
> 3. 複数の設定可能な送信先ストリームを許可します。例えば、トレースログを一つのファイルに書き込んでいるが、エラーが発生したときに同じファイルに書き込んで、次にエラーファイルに書き込んで、同時に電子メールを送信する...といった具合です。
================================================
FILE: sections/production/smartlogging.korean.md
================================================
# Make your app transparent using smart logs
### One Paragraph Explainer
Since you print out log statements anyway and you're obviously in a need of some interface that wraps up production information where you can trace errors and core metrics (e.g. how many errors happen every hour and which is your slowest API end-point) why not invest some moderate effort in a robust logging framework that will tick all boxes? Achieving that requires a thoughtful decision on three steps:
**1. smart logging** – at the bare minimum you need to use a reputable logging library like [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) and write meaningful information at each transaction start and end. Consider to also format log statements as JSON and provide all the contextual properties (e.g. user id, operation type, etc) so that the operations team can act on those fields. Include also a unique transaction ID at each log line, for more information refer to the bullet below “Write transaction-id to log”. One last point to consider is also including an agent that logs the system resource like memory and CPU like Elastic Beat.
**2. smart aggregation** – once you have comprehensive information on your servers file system, it’s time to periodically push these to a system that aggregates, facilities and visualizes this data. The Elastic stack, for example, is a popular and free choice that offers all the components to aggregate and visualize data. Many commercial products provide similar functionality only they greatly cut down the setup time and require no hosting.
**3. smart visualization** – now the information is aggregated and searchable, one can be satisfied only with the power of easily searching the logs but this can go much further without coding or spending much effort. We can now show important operational metrics like error rate, average CPU throughout the day, how many new users opted-in in the last hour and any other metric that helps to govern and improve our app
### Visualization Example: Kibana (part of the Elastic stack) facilitates advanced searching on log content

### Visualization Example: Kibana (part of the Elastic stack) visualizes data based on logs

### Blog Quote: Logger Requirements
From the blog [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
> Lets identify a few requirements (for a logger):
> 1. Timestamp each log line. This one is pretty self-explanatory – you should be able to tell when each log entry occurred.
> 2. Logging format should be easily digestible by humans as well as machines.
> 3. Allows for multiple configurable destination streams. For example, you might be writing trace logs to one file but when an error is encountered, write to the same file, then into error file and send an email at the same time…
================================================
FILE: sections/production/smartlogging.md
================================================
# Make your app transparent using smart logs
### One Paragraph Explainer
Since you print out log statements anyway and you're obviously in a need of some interface that wraps up production information where you can trace errors and core metrics (e.g. how many errors happen every hour and which is your slowest API end-point) why not invest some moderate effort in a robust logging framework that will tick all boxes? Achieving that requires a thoughtful decision on three steps:
**1. smart logging** – at the bare minimum you need to use a reputable logging library like [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan) and write meaningful information at each transaction start and end. Consider to also format log statements as JSON and provide all the contextual properties (e.g. user id, operation type, etc) so that the operations team can act on those fields. Include also a unique transaction ID at each log line, for more information refer to the bullet below “Write transaction-id to log”. One last point to consider is also including an agent that logs the system resource like memory and CPU like Elastic Beat.
**2. smart aggregation** – once you have comprehensive information on your 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.
### 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

### Blog Quote: Logger Requirements
From the blog [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
> Lets identify a few requirements (for a logger):
> 1. Timestamp each log line. This one is pretty self-explanatory – you should be able to tell when each log entry occurred.
> 2. Logging format should be easily digestible by humans as well as machines.
> 3. Allows for multiple configurable destination streams. For example, you might be writing trace logs to one file but when an error is encountered, write to the same file, then into error file and send an email at the same time…
================================================
FILE: sections/production/smartlogging.polish.md
================================================
# 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…
================================================
FILE: sections/production/smartlogging.russian.md
================================================
# Сделайте ваше приложение прозрачным, используя умные логи
### Объяснение в один абзац
Так как вы все равно выводите записи журнала, и вам, очевидно, нужен какой-то интерфейс, который объединяет производственную информацию, где вы можете отслеживать ошибки и основные показатели (например, сколько ошибок происходит каждый час и какая ваша самая медленная конечная точка API), почему бы не вкладывать умеренные усилия в надежную систему ведения журналов, которая помечает все флажки? Достижение этого требует вдумчивого решения в три этапа:
**1. умное ведение журналов** - как минимум, вам необходимо использовать авторитетную библиотеку журналов, такую как [Winston](https://github.com/winstonjs/winston), [Bunyan](https://github.com/trentm/node-bunyan), и записывать значимую информацию в начале и конце каждой транзакции. Также следует отформатировать операторы журнала в формате JSON и предоставить все контекстные свойства (например, идентификатор пользователя, тип операции и т.д.), Чтобы операционная группа могла работать с этими полями. Включите также уникальный идентификатор транзакции в каждой строке журнала, для получения дополнительной информации обратитесь к пункту ниже "Записать идентификатор транзакции в журнал". И последнее, на что следует обратить внимание, это также включение агента, который регистрирует системные ресурсы, такие как память, и процессор, такие как Elastic Beat.
**2. умное агрегирование** - когда у вас есть исчерпывающая информация о файловой системе ваших серверов, пора периодически отправлять ее в систему, которая собирает, обрабатывает и визуализирует эти данные. Стек Elastic, например, является популярным и бесплатным выбором, который предлагает все компоненты для агрегирования и визуализации данных. Многие коммерческие продукты предоставляют аналогичные функции, только они значительно сокращают время установки и не требуют хостинга.
**3. умная визуализация** - теперь информация агрегируется и доступна для поиска, которая вполне удовлетворительная, но только с помощью возможности простого поиска в журналах, хотя это может пойти гораздо дальше без необходимости кодирования или больших затрат. Теперь мы можем показывать важные операционные показатели, такие как частота ошибок, средняя загрузка ЦП в течение дня, количество новых пользователей, подключенных за последний час, и любые другие показатели, которые помогают управлять и улучшать наше приложение.
### Пример визуализации: Kibana (часть стека Elastic) облегчает расширенный поиск по содержимому журнала

### Пример визуализации: Kibana (часть стека Elastic) визуализирует данные на основе журналов

### Цитата блога. Требования к логгеру
Из блога [Strong Loop](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/):
> Давайте определим несколько требований (для регистратора):
> 1. Отметка времени каждой строки журнала. Это довольно очевидно - вы должны быть в состоянии сказать, когда произошла каждая запись в журнале.
> 2. Формат регистрации должен быть легко усваиваемым людьми и машинами.
> 3. Позволяет использовать несколько настраиваемых целевых потоков. Например, вы можете записывать журналы трассировки в один файл, но при возникновении ошибки запишите в тот же файл, затем в файл ошибок и отправьте электронное письмо одновременно ...
================================================
FILE: sections/production/utilizecpu.basque.md
================================================
# 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 ...
================================================
FILE: sections/production/utilizecpu.brazilian-portuguese.md
================================================
# Utilize todos os núcleos do processador
### Explicação em um Parágrafo
Pode não ser uma surpresa que, em sua forma básica, o Node seja executado em um único thread = um único processo = um único CPU. Pagando por hardwares pesados com 4 ou 8 CPUs e utilizando apenas um parece loucura, certo? A solução mais rápida para aplicações de tamanho médio é o uso do módulo Node’s Cluster, que em 10 linhas de código gera um processo para cada núcleo lógico e encaminha solicitações entre os processos em um estilo round-robin. Melhor ainda, use o PM2, que adoça o módulo de clustering com uma interface simples e interface de monitoramento legal. Embora essa solução funcione bem para aplicações tradicionais, ela pode ser insuficiente para aplicações que exigem desempenho de alto nível e fluxo de DevOps robusto. Para esses casos de uso avançado, considere a replicação do processo NODE usando o script de implantação e o balanceamento personalizados usando uma ferramenta especializada, como o nginx, ou use um mecanismo de contêiner como o AWS ECS ou Kubernetees que tenha recursos avançados para implantação e replicação de processos.
### Comparação: balanceamento usando o cluster do Node versus o nginx

### O que Outros Blogueiros Dizem
* Da [documentação do Node.js](https://nodejs.org/api/cluster.html#cluster_how_it_works):
> ... A segunda abordagem, os clusters do Node, deve, em teoria, oferecer o melhor desempenho. Na prática, no entanto, a distribuição tende a ser muito desequilibrada devido aos caprichos do planejador do sistema operacional. Cargas foram observadas onde mais de 70% de todas as conexões acabaram em apenas dois processos, de um total de oito ...
* Do blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
> ... O clustering é possível com o módulo de cluster do Node. Isso permite que um processo mestre crie processos de trabalho e distribua conexões de entrada entre os trabalhadores. No entanto, em vez de usar este módulo diretamente, é muito melhor usar uma das muitas ferramentas que fazem isso por você automaticamente. por exemplo, node-pm ou cluster-service ...
* Do post no Medium [Desempenho do balanceamento de carga do processo Node.js: comparando módulo de cluster, iptables e Nginx](https://medium.com/@fermads/node-js-process-load-balancing-comparing-cluster-iptables-and-nginx-6746aaf38272)
> ... O cluster do Node é simples de implementar e configurar, as coisas são mantidas dentro do reino do Node sem depender de outro software. Lembre-se de que seu processo mestre funcionará quase tanto quanto os processos de trabalho e com uma taxa de solicitação um pouco menor do que as outras soluções. ...
================================================
FILE: sections/production/utilizecpu.chinese.md
================================================
# 利用所有的CPU内核
### 一段解释
这应该不会让人感到意外, 在其基本形式上,Node运行在单进程,单线程,单个CPU上。购买了一个强大的包含4个或8个CPU的硬件,只使用一个听起来是不可思议的,对吗?适合中型应用最快的解决方案是使用Node的Cluster模块,它在10行代码中为每个逻辑核心和路由请求产生一个进程,进程之间以round-robin的形式存在。更好的是使用PM2,它通过一个简单的接口和一个很酷的监视UI来给cluster模块裹上糖衣。虽然这个解决方案对传统应用程序很有效,但它可能无法满足需要顶级性能和健壮的devops流的应用。对于那些高级的用例,考虑使用自定义部署脚本复制NODE进程,并使用像nginx
这样的专门的工具进行负载均衡,或者使用像AWS ECS或Kubernetees这样的容器引擎,这些工具具有部署和复制进程的高级特性。
### 比较:使用Node的clustre vs nginx做负载均衡

### 其他博主说什么
* 摘自[Node.JS documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
> ... 理论上第二种方法, Node clusters,应该是性能最佳的。然而, 在实践中, 由于操作系统调度程序的反复无常, 分布往往非常不平衡。观察负载, 所有连接中,超过70%在两个进程中处理, 而总共有八个进程...
* 摘自博客[StrongLoop](From the blog StrongLoop):
> ...通过Node的cluster模块实现集群化。这使一个主进程能够产生工作进程,并在工作进程间分配进入的连接。然而,与其直接使用这个模块,更好的选择是使用其中的许多工具之一, 它为您自动处理它; 例如,node-pm或cluster-service...
* 摘自the Medium post[node.js进程负载平衡性能:比较cluster moudlle、iptables和Nginx](https://medium.com/@fermads/node-js-process-load-balancing- iptabls -and- Nginx -6746aaf38272)
> ... Node cluster易于实施和配置,不依赖于其他软件就可以在Node的领域内进行。请记住,你的主进程将会工作几乎和你的工作进程一样多,比较于其他的解决方案,少一点请求率...
================================================
FILE: sections/production/utilizecpu.french.md
================================================
# 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. ...
================================================
FILE: sections/production/utilizecpu.japanese.md
================================================
# すべての CPU コアを利用する
### 一段落説明
意外ではないかもしれませんが、基本的な形として、Node は単一のスレッド、単一のプロセス、単一の CPU 上で動作します。4もしくは8個のCPUがある頑丈なハードにお金を払っておいて、1つだけを利用するのはバカバカしく聞こえるのではないでしょうか? 中規模なアプリケーションに適用する最速のソリューションは、10行のコードで各論理コアのためにプロセスを生成し、ラウンドロビン形式でプロセス間のリクエストをルーティングする、Node クラスターを使うことです。さらに良いのは、シンプルなインタフェースとクールなモニタリング UI でクラスタリングモジュールの体裁を整えている PM2 を使用することです。このソリューションは従来のアプリケーションには適していますが、一流のパフォーマンスと堅牢な DevOps フローを必要とするアプリケーションには不向きかもしれません。これらの高度なユースケースでは、カスタムデプロイスクリプトを使用して NODE プロセスをレプリケートし、nginx などの専用ツールを使用してバランシングを行うか、デプロイとプロセスのレプリケーションのための高度な機能を持つ AWS ECS や Kubernetees などのコンテナエンジンを使用することを検討してみてはいかがでしょうか。
### 比較: 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 クラスタは実装と設定が簡単で、他のソフトウェアに依存することなくノードの領域内に保持されます。マスタープロセスは、他のソリューションに比べてリクエスト率が若干低くても、作業者のプロセスとほぼ同等に機能することを覚えておいてください。 ...
================================================
FILE: sections/production/utilizecpu.korean.md
================================================
# Utilize all CPU cores
### One Paragraph Explainer
It might not come as a surprise that in its basic form, Node runs over a single thread=single process=single CPU. Paying for beefy hardware with 4 or 8 CPU and utilizing only one sounds crazy, right? The quickest solution which fits medium sized apps is using Node’s Cluster module which in 10 lines of code spawns a process for each logical core and route requests between the processes in a round-robin style. Even better, use PM2 which sugarcoats the clustering module with a simple interface and cool monitoring UI. While this solution works well for traditional applications, it might fall short for applications that require top-notch performance and robust DevOps flow. For those advanced use cases, consider replicating the NODE process using custom deployment script and balancing using a specialized tool such as nginx or use a container engine such as AWS ECS or Kubernetees that have advanced features for deployment and replication of processes.
### Comparison: Balancing using Node’s cluster vs nginx

### What Other Bloggers Say
* From the [Node.js documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
> ... The second approach, Node clusters, should, in theory, give the best performance. In practice, however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight ...
* From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
> ... Clustering is made possible with Node’s cluster module. This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it’s far better to use one of the many tools out there that do it for you automatically; for example node-pm or cluster-service ...
* From the Medium post [Node.js process load balance performance: comparing cluster module, iptables, and Nginx](https://medium.com/@fermads/node-js-process-load-balancing-comparing-cluster-iptables-and-nginx-6746aaf38272)
> ... Node cluster is simple to implement and configure, things are kept inside Node’s realm without depending on other software. Just remember your master process will work almost as much as your worker processes and with a little less request rate than the other solutions ...
================================================
FILE: sections/production/utilizecpu.md
================================================
# Utilize all CPU cores
### One Paragraph Explainer
It might not come as a surprise that in its basic form, Node runs over a single thread=single process=single CPU. Paying for beefy hardware with 4 or 8 CPU and utilizing only one sounds crazy, right? The quickest solution which fits medium sized apps is using Node’s Cluster module which in 10 lines of code spawns a process for each logical core and route requests between the processes in a round-robin style. Even better, use PM2 which sugarcoats the clustering module with a simple interface and cool monitoring UI. While this solution works well for traditional applications, it might fall short for applications that require top-notch performance and robust DevOps flow. For those advanced use cases, consider replicating the NODE process using custom deployment script and balancing using a specialized tool such as nginx or use a container engine such as AWS ECS or Kubernetees that have advanced features for deployment and replication of processes.
### Comparison: Balancing using Node’s cluster vs nginx

### What Other Bloggers Say
* From the [Node.js documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
> ... The second approach, Node clusters, should, in theory, give the best performance. In practice, however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight ...
* From the blog [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
> ... Clustering is made possible with Node’s cluster module. This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it’s far better to use one of the many tools out there that do it for you automatically; for example node-pm or cluster-service ...
* From the Medium post [Node.js process load balance performance: comparing cluster module, iptables, and Nginx](https://medium.com/@fermads/node-js-process-load-balancing-comparing-cluster-iptables-and-nginx-6746aaf38272)
> ... Node cluster is simple to implement and configure, things are kept inside Node’s realm without depending on other software. Just remember your master process will work almost as much as your worker processes and with a little less request rate than the other solutions ...
================================================
FILE: sections/production/utilizecpu.polish.md
================================================
# 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 ...
================================================
FILE: sections/production/utilizecpu.russian.md
================================================
# Используйте все ядра процессора
### Объяснение в один абзац
Неудивительно, что в своей базовой форме Node работает над одним потоком = один процесс = один процессор. Плата за мощное оборудование с 4 или 8 процессорами и использование только одного звучит безумно, верно? Самое быстрое решение, которое подходит для приложений среднего размера, - это использование кластерного модуля Node, который из 10 строк кода порождает процесс для каждого логического ядра и направляет запросы между процессами в стиле циклического перебора. Более того, используйте PM2, который приукрашивает модуль кластеризации простым интерфейсом и отличным интерфейсом мониторинга. Хотя это решение хорошо работает для традиционных приложений, оно может не подходить для приложений, требующих первоклассной производительности и надежного потока DevOps. Для этих расширенных вариантов использования рассмотрите возможность репликации процесса NODE с использованием пользовательского сценария развертывания и балансировки с помощью специализированного инструмента, такого как nginx, или используйте механизм контейнеров, такой как AWS ECS или Kubernetees, которые имеют расширенные функции для развертывания и репликации процессов.
### Сравнение: балансировка с использованием кластера Node против nginx

### Что говорят другие блоггеры
* Из документации [Node.js documentation](https://nodejs.org/api/cluster.html#cluster_how_it_works):
> ... Второй подход, кластеры Node, должен, теоретически, дать лучшую производительность. На практике, однако, распределение имеет тенденцию быть очень несбалансированным из-за капризов планировщика операционной системы. Нагрузки наблюдались, когда более 70% всех соединений заканчивались всего двумя процессами из восьми ...
* Из блога [StrongLoop](https://strongloop.com/strongblog/best-practices-for-express-in-production-part-two-performance-and-reliability/):
> ... Кластеризация возможна с помощью кластерного модуля Node. Это позволяет главному процессу порождать рабочие процессы и распределять входящие соединения среди рабочих. Однако вместо того, чтобы использовать этот модуль напрямую, гораздо лучше использовать один из множества инструментов, которые делают это автоматически; например node-pm или cluster-service ...
* Из поста на 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 прост в реализации и настройке, все хранится в сфере Node, не завися от другого программного обеспечения. Просто помните, что ваш основной процесс будет работать почти так же, как ваши рабочие процессы, и с меньшей частотой запросов, чем другие решения ...
================================================
FILE: sections/projectstructre/breakintcomponents.basque.md
================================================
# 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

================================================
FILE: sections/projectstructre/breakintcomponents.brazilian-portuguese.md
================================================
# Estruture sua solução por componentes
### Explicação em um Parágrafo
Para aplicações de tamanho médio e acima, os monólitos são muito ruins - ter um grande software com muitas dependências é difícil de avaliar e, muitas vezes, leva ao código de espaguete. Mesmo arquitetos inteligentes - aqueles que são habilidosos o suficiente para domar a fera e "modulá-la" - gastam muito esforço mental no projeto, e cada mudança requer uma avaliação cuidadosa do impacto em outros objetos dependentes. A solução final é desenvolver um software pequeno: dividir a pilha inteira em componentes independentes que não compartilham arquivos com outros, cada um constituindo poucos arquivos (por exemplo, API, serviço, acesso a dados, teste, etc.), de modo que é muito fácil de entender. Alguns podem chamar isso de arquitetura de 'microserviços' - é importante entender que os microsserviços não são uma especificação que você deve seguir, mas sim um conjunto de princípios. Você pode adotar muitos princípios em uma arquitetura completa de microsserviços ou adotar apenas alguns. Ambos são bons, desde que você mantenha baixa a complexidade do software. O mínimo que você deve fazer é criar bordas básicas entre os componentes, atribuir uma pasta na raiz do projeto para cada componente de negócios e torná-lo independente - outros componentes podem consumir sua funcionalidade somente por meio de sua interface pública ou API. Esta é a base para manter seus componentes simples, evitar o inferno de dependências e preparar o caminho para microsserviços completos no futuro, assim que seu aplicativo crescer.
### Citação de Blog: "O escalonamento requer escalonamento de todo o aplicativo"
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.
### Citação de Blog: "Então, o que a arquitetura do seu aplicativo grita?"
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.
Então, o que a arquitetura da sua aplicação grita? Quando você olha para a estrutura de diretório de nível superior e os arquivos de origem no pacote de nível mais alto; Eles gritam: sistema de saúde ou sistema de contabilidade ou sistema de gerenciamento de estoque? Ou eles gritam: Rails, ou Spring/Hibernate, ou ASP?.
### Bom: estruture sua solução por componentes independentes

### Ruim: Agrupe seus arquivos por papel técnico

================================================
FILE: sections/projectstructre/breakintcomponents.chinese.md
================================================
# 组件式构建你的解决方案
### 一段解释
对于中等规模的应用程序及以上,一个代码库是非常糟糕的 - 一个包含很多依赖的大型软件很难理解,往往导致代码混乱。即使是那些擅长解决复杂问题和 "模块化" 的聪明架构师 - 在设计上花费了很大的脑力, 每一个变化都需要仔细评估对其他依赖对象的影响。最终的解决方案是开发小型软件:将整个堆栈划分为独立的组件,这些组件不与其他组件共享文件,每个组件由很少的文件构成(例如API、服务、数据访问、测试等),因此很容易理解它。有些人可能称之为 "microservices" 架构 - 重要的是要理解 microservices 不是一个你必须遵循的规范,而是一套原则。您可以将许多原则引入到成熟的 microservices 体系结构中, 或者只采用少数几个。只要您保持软件的复杂性低, 两者都是好的。最起码应该做的是在组件之间创建一个基本边界, 为每个业务组件在项目根目录中分配一个文件夹, 并使其自包含-其他组件只能通过其公共接口或 API 使用其功能。这是保持您的组件简单的基础,在未来, 一旦您的应用程序增长,避免依赖性地狱,为全面的 microservices 架构铺平了道路.
### 博客引用: "伸缩需要对整个应用程序进行伸缩设计"
摘自博客 [MartinFowler.com](https://martinfowler.com/articles/microservices.html)
> 单个应用程序可以成功, 但越来越多的人对它们感到失望 - 尤其是随着更多的应用程序被部署到云中。更改周期被捆绑在一起 - 对应用程序的一小部分进行更改, 需要重建和部署整个整体。随着时间的推移, 通常很难保持一个良好的模块化结构, 这使得更改哪怕只会影响该模块中的一个模块变得更加困难。伸缩设计需要扩展整个应用程序, 而不是它的部分,这往往需要更多资源。
### 博客引用: "那么, 你的应用程序的架构声明了什么?"
摘自博客 [uncle-bob](https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html)
> ...如果你正在寻找一个图书馆的建筑架构, 你可能会看到一个盛大的入口, 一个 check-in-out 的文员, 阅读区, 小会议室, 画廊, 画廊后面容纳了装载所有图书馆书籍的书架。建筑会声明: 图书馆.
那么, 应用程序的体系架构会声明什么呢? 当您查看顶级目录结构和最高级别包中的源文件时; 他们声明: 医疗保健系统, 或会计系统, 或库存管理系统? 或者他们声明: Rails, 或Spring/Hibernate, 或 ASP?.
### 推荐: 通过独立组件构建解决方案

### 避免: 按技术角色对文件进行分组

================================================
FILE: sections/projectstructre/breakintcomponents.french.md
================================================
# 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

================================================
FILE: sections/projectstructre/breakintcomponents.japanese.md
================================================
# コンポーネントによりソリューションを構築する
### 一段落説明
中規模以上のアプリでは、モノリスは本当に良くありません - 1つの大きなソフトウェアに多くの依存関係を持たせることにより、推論が難しくなり、スパゲッティコードになってしまうことが多いからです。賢いアーキテクト — 獣を飼いならして「モジュール化」するのに十分なスキルを持った人 — であっても、設計には多大な精神的な努力を費やし、変更ごとに他の従属オブジェクトへの影響を慎重に評価する必要があります。究極の解決策は、小さなソフトウェアを開発することです: スタック全体が、他の人とファイルを共有しない自己完結型のコンポーネントに分割されており、それぞれが非常に少ないファイル (例えば、API、サービス、データアクセス、テストなど) で構成されているので、それらについての推論が非常に簡単になります。これを「マイクロサービス」アーキテクチャと呼ぶ人もいるかもしれませんが、マイクロサービスは従わなければならない仕様ではなく、一連の原則であることを理解することが重要です。多くの原則を採用して本格的なマイクロサービスアーキテクチャを構築することもできますし、いくつかの原則だけを採用することもできます。ソフトウェアの複雑さを低く抑えていれば、どちらも良いでしょう。最低限すべきことは、コンポーネント間に基本的な境界線を作り、プロジェクトのルートに各ビジネスコンポーネント用のフォルダを割り当て、それを自己完結型にすることです - 他のコンポーネントは、パブリックインタフェースまたは API を介してのみ、その機能を使用することができます。 これは、コンポーネントをシンプルに保ち、依存関係の地獄を回避し、アプリが成長すれば、将来的に本格的なマイクロサービスへの道を開くための基礎となります。
### ブログ引用: "Scaling requires scaling of the entire application" (スケーリングにはアプリケーション全体のスケーリングが必要)
ブログ [MartinFowler.com](https://martinfowler.com/articles/microservices.html) より
> モノリシック・アプリケーションは成功を収めることができますが、人々はモノリシック・アプリケーションに不満を感じるようになってきています - 特に多くのアプリケーションがクラウドにデプロイされるようになってきているためです。変更サイクル同士は連動しています - アプリケーションのごく一部に変更を加えると、モノリス全体を再構築してデプロイする必要があります。時間が経つにつれて、良いモジュール構造を維持することが難しくなり、そのモジュール内の1つのモジュールだけに影響するように変更を維持することが難しくなります。スケーリングでは、アプリケーションの一部だけでなく、アプリケーション全体を拡張する必要があり、多くの場合、より多くのリソースを必要とします。
### ブログ引用: "So what does the architecture of your application scream?" (では、アプリケーションのアーキテクチャは何を叫んでいるのでしょうか?)
ブログ [uncle-bob](https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html) より
> ...図書館の建築を眺めていると、あなたはおそらく壮大な入り口、図書館員のためのエリア、読書エリア、小さな会議室、そしてギャラリーの奥には図書館の本をすべて収納した棚があるのが見えるだろう。その建築は悲鳴を上げるだろう。図書館と。
では、アプリケーションのアーキテクチャはどんな悲鳴を上げているのでしょうか? 最上位のディレクトリ構造と最上位のパッケージのソースファイルを見たとき、ヘルスケアシステム、会計システム、在庫管理システム などと叫んでいませんか? それとも、次のように叫んでいるでしょうか。Rails、Spring/Hibernate、ASP ?
### 良い: 自己完結型のコンポーネントでソリューションを構築する

### 悪い: 技術的な役割ごとにファイルをグループ化

================================================
FILE: sections/projectstructre/breakintcomponents.korean.md
================================================
# 컴포넌트 기반으로 설계하라
### 한문단 설명
중소규모 이상의 앱부터는 단일암체 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라는 감이 오는가?.
### 좋은예: 자족적인 컴포넌트 기반으로 설계하라

### 나쁜예: 파일을 기술적인 역할별로 모아라

================================================
FILE: sections/projectstructre/breakintcomponents.md
================================================
# Structure your solution by components
### One Paragraph Explainer
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](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.
### Blog Quote: "So what does the architecture of your application scream?"
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.
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
```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
```
================================================
FILE: sections/projectstructre/breakintcomponents.polish.md
================================================
# 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

================================================
FILE: sections/projectstructre/breakintcomponents.russian.md
================================================
# Структурируйте свое решение по компонентам
### Объяснение в один абзац
Для приложений среднего размера и выше монолиты действительно плохи - иметь одно большое программное обеспечение с множеством зависимостей просто сложно, и это часто приводит к спагетти-коду. Даже умные архитекторы - те, кто достаточно опытен, чтобы приручить зверя и "модулизируя" его - тратят большие умственные усилия на проектирование, и каждое изменение требует тщательной оценки воздействия на другие зависимые объекты. Конечным решением является разработка небольшого программного обеспечения: разделите весь стек на отдельные компоненты, которые не делятся файлами с другими, каждый из которых содержит очень мало файлов (например, 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?
### Хорошо: структурируйте свое решение по отдельным компонентам

### Плохо: сгруппируйте файлы по техническим ролям

================================================
FILE: sections/projectstructre/choose-framework.md
================================================
# 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
================================================
FILE: sections/projectstructre/configguide.basque.md
================================================
# 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,
},
},
}
```
================================================
FILE: sections/projectstructre/configguide.brazilian-portuguese.md
================================================
# Use configuração consciente, segura e hierárquica do ambiente
### Explicação em um Parágrafo
Ao lidar com dados de configuração, muitas coisas podem simplesmente incomodar e desacelerar:
1. A configuração de todas as chaves usando variáveis de ambiente de processo torna-se muito entediante quando é necessário injetar 100 chaves (em vez de apenas cometer aquelas em um arquivo de configuração), no entanto, ao lidar com arquivos, os administradores do DevOps não podem alterar o comportamento sem alterar o código. Uma solução de configuração confiável deve combinar os dois arquivos de configuração + substituições das variáveis de processo.
2. Ao especificar todas as chaves em um JSON simples, é frustrante encontrar e modificar entradas quando a lista ficar maior. Um arquivo JSON hierárquico que é agrupado em seções pode superar esse problema + poucas bibliotecas de configuração permitem armazenar a configuração em vários arquivos e tomar cuidado para unir todas em tempo de execução. Veja o exemplo abaixo.
3. O armazenamento de informações confidenciais, como a senha do banco de dados, obviamente não é recomendado, mas não existe uma solução rápida e prática para esse desafio. Algumas bibliotecas de configuração permitem criptografar arquivos, outras criptografam essas entradas durante as confirmações do GIT ou simplesmente não armazenam valores reais para essas entradas e especificam o valor real durante a implementação por meio de variáveis de ambiente.
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), [config](https://www.npmjs.com/package/config) e [convict](https://www.npmjs.com/package/convict) que satisfazem muitos desses requisitos.
### Exemplo de código - configuração hierárquica ajuda a encontrar entradas e manter arquivos de configuração enormes
```js
{
// Configurações do módulo do cliente
"Customer": {
"dbConfig": {
"host": "localhost",
"port": 5984,
"dbName": "customers"
},
"credit": {
"initialLimit": 100,
// Definir baixo para desenvolvimento
"initialDays": 1
}
}
}
```
================================================
FILE: sections/projectstructre/configguide.chinese.md
================================================
# 使用环境感知,安全,分层的配置
### 一段解释
当我们处理配置参数时,常常会很慢并且很烦躁:(1)当需要注入100个keys(而不是只在配置文件中提交它们)时,使用进程环境变量设置所有的keys变得非常繁琐,但是当处理只有devops管理权限的文件时,不改变代码行为就不不会变。一个可靠的配置解决方案必须结合配置文件和进程变量覆盖。(2)枚举一个普通JSON的所有keys时,当目录变得非常庞杂的时候,查找修改条目困难。几乎没有配置库允许将配置存储在多个文件中,运行时将所有文件联合起来。分成几个部分的分层JSON文件能够克服这个问题。请参照下面示例。(3)不推荐存储像密码数据这样的敏感信息,但是又没有快速便捷的方法解决这个难题。一些配置库允许文件加密,其他库在Git提交时加密目录,或者不存储这些目录的真实值,在通过环境变量部署期间枚举真实值。(4)一些高级配置场景需要通过命令行(vargs)注入配置值,或者像Redis一样通过集中缓存同步配置信息,所以不同的服务器不会保存不同的数据。
一些配置库可以免费提供这些功能的大部分功能,请查看NPM库([nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config) 和 [convict](https://www.npmjs.com/package/convict))这些库可以满足这些要求中的许多要求。
### 代码示例 – 分层配置有助于查找条目和维护庞大的配置文件
```javascript
{
// Customer module configs
"Customer": {
"dbConfig": {
"host": "localhost",
"port": 5984,
"dbName": "customers"
},
"credit": {
"initialLimit": 100,
// Set low for development
"initialDays": 1
}
}
}
```
================================================
FILE: sections/projectstructre/configguide.french.md
================================================
# 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
}
}
}
```
================================================
FILE: sections/projectstructre/configguide.japanese.md
================================================
# 環境を意識したセキュアで階層的な設定を使用する
### 一段落説明
設定データを扱う場合、多くのことはただ単に迷惑であったり、遅くしたりするだけです。
1. 100個のキーを注入する必要がある場合(設定ファイルでコミットするだけではなく)、プロセス環境変数を使ってすべてのキーを設定するのは面倒になります。しかし、ファイルのみで作業する場合は、devops 管理者はコードを変更しないと挙動を変更することができません。信頼性の高い設定に関する解決策は、両方の設定ファイルとプロセス変数からのオーバーライドを組み合わせる必要があります。
2. フラットな JSON ですべてのキーを指定する場合、リストが大きくなったときにエントリを見つけて修正するのはイライラします。セクションにグループ化された階層的な JSON ファイルは、この問題を克服することができます + いくつかの設定ライブラリでは、複数のファイルに設定を保存し、実行時にすべてを結合するように注意を払うことができます。以下の例を見てください。
3. DB パスワードのような機密情報を保存することは明らかに推奨されていませんが、この課題に対する迅速で便利なソリューションは存在しません。設定ライブラリによっては、ファイルの暗号化を許可しているものもあれば、Git コミット時にそれらのエントリを暗号化しているものもありますし、単にそれらのエントリの実値を保存せず、デプロイ時に環境変数で実際の値を指定しているだけのものもあります。
4. いくつかの高度な設定シナリオでは、コマンドライン ( vargs ) から設定値を注入したり、Redis のような集中化されたキャッシュを介して設定情報を同期させたりして、複数のサーバが同じ設定データを使用するように要求しています。
5. アプリケーションは、起動時に必要な環境変数が存在しない場合には、可能な限り迅速に失敗し、即座にフィードバックを提供しなければなりません。これは、設定を検証するために [convict](https://www.npmjs.com/package/convict) を使用することで実現できます。
設定ライブラリの中には、これらの機能のほとんどを無料で提供できるものもありますので、[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) のような、これらの要件を多く満たしている npm ライブラリを見てみてください。
### コード例 – 階層化された設定は、エントリの検索や巨大な設定ファイルの管理に役立ちます
```json5
{
// Customer module configs
"Customer": {
"dbConfig": {
"host": "localhost",
"port": 5984,
"dbName": "customers"
},
"credit": {
"initialLimit": 100,
// Set low for development
"initialDays": 1
}
}
}
```
================================================
FILE: sections/projectstructre/configguide.korean.md
================================================
# Use environment aware, secure and hierarchical config
### One Paragraph Explainer
When dealing with configuration data, many things can just annoy and slow down:
1. setting all the keys using process environment variables becomes very tedious when in need to inject 100 keys (instead of just committing those in a config file), however when dealing with files only the DevOps admins cannot alter the behavior without changing the code. A reliable config solution must combine both configuration files + overrides from the process variables
2. when specifying all keys in a flat JSON, it becomes frustrating to find and modify entries when the list grows bigger. A hierarchical JSON file that is grouped into sections can overcome this issue + few config libraries allow to store the configuration in multiple files and take care to union all at runtime. See example below
3. storing sensitive information like DB password is obviously not recommended but no quick and handy solution exists for this challenge. Some configuration libraries allow to encrypt files, others encrypt those entries during GIT commits or simply don't store real values for those entries and specify the actual value during deployment via environment variables.
4. some advanced configuration scenarios demand to inject configuration values via command line (vargs) or sync configuration info via a centralized cache like Redis so multiple servers will use the same configuration data.
Some configuration libraries can provide most of these features for free, have a look at npm libraries like [rc](https://www.npmjs.com/package/rc), [nconf](https://www.npmjs.com/package/nconf), [config](https://www.npmjs.com/package/config), and [convict](https://www.npmjs.com/package/convict) which tick many of these requirements.
### Code Example – hierarchical config helps to find entries and maintain huge config files
```js
{
// Customer module configs
"Customer": {
"dbConfig": {
"host": "localhost",
"port": 5984,
"dbName": "customers"
},
"credit": {
"initialLimit": 100,
// Set low for development
"initialDays": 1
}
}
}
```
================================================
FILE: sections/projectstructre/configguide.md
================================================
# Use environment aware, secure and hierarchical config
### One Paragraph Explainer
When dealing with configuration data, many things can just annoy and slow down:
1. setting all the keys using process environment variables becomes very tedious when in need to inject 100 keys (instead of just committing those in a config file), however when dealing with files only the DevOps admins cannot alter the behavior without changing the code. A reliable config solution must combine both configuration files + overrides from the process variables
2. when specifying all keys in a flat JSON, it becomes frustrating to find and modify entries when the list grows bigger. A hierarchical JSON file that is grouped into sections can overcome this issue + few config libraries allow to store the configuration in multiple files and take care to union all at runtime. See example below
3. storing sensitive information like DB password is obviously not recommended but no quick and handy solution exists for this challenge. Some configuration libraries allow to encrypt files, others encrypt those entries during GIT commits or simply don't store real values for those entries and specify the actual value during deployment via environment variables.
4. some advanced configuration scenarios demand to inject configuration values via command line (vargs) or sync configuration info via a centralized cache like Redis so multiple servers will use the same configuration data.
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), [config](https://www.npmjs.com/package/config), and [convict](https://www.npmjs.com/package/convict) which tick many of these requirements.
### Code Example – hierarchical config helps to find entries and maintain huge config files
```json5
{
// Customer module configs
"Customer": {
"dbConfig": {
"host": "localhost",
"port": 5984,
"dbName": "customers"
},
"credit": {
"initialLimit": 100,
// Set low for development
"initialDays": 1
}
}
}
```
================================================
FILE: sections/projectstructre/configguide.polish.md
================================================
# 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
}
}
}
```
================================================
FILE: sections/projectstructre/configguide.russian.md
================================================
# Используйте конфигурацию с учетом среды, безопасную и иерархическую конфигурацию
### Объяснение в один абзац
При работе с данными конфигурации многие вещи могут просто раздражать и замедлять:
1. Установка всех ключей с использованием переменных среды становится очень утомительной, когда необходимо ввести 100 ключей (вместо того, чтобы просто фиксировать их в файле конфигурации), однако при работе с файлами только администраторы DevOps не могут изменить поведение без изменения кода. Надежное конфигурационное решение должно объединять оба файла конфигурации + переопределения из переменных процесса
2. При указании всех ключей в плоском JSON становится сложно найти и изменить записи, когда список увеличивается. Эту проблему можно решить с помощью иерархического файла JSON, сгруппированного по разделам. + Несколько библиотек конфигурации позволяют хранить конфигурацию в нескольких файлах и объединять их во время выполнения. См пример ниже
3. Хранение конфиденциальной информации, такой как пароль БД, явно не рекомендуется, но быстрого и удобного решения для этой задачи не существует. Некоторые библиотеки конфигурации позволяют шифровать файлы, другие шифруют эти записи во время коммитов GIT или просто не сохраняют реальные значения для этих записей и указывают фактическое значение во время развертывания через переменные среды.
4. Некоторые расширенные сценарии конфигурации требуют ввода значений конфигурации через командную строку (vargs) или синхронизируют информацию о конфигурации через централизованный кеш, такой как Redis, чтобы несколько серверов использовали одни и те же данные конфигурации.
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) и [convict](https://www.npmjs.com/package/convict), которые отмечают многие из этих требований.
### Пример кода - иерархическая конфигурация помогает находить записи и поддерживать огромные конфигурационные файлы
```json5
{
// Customer module configs
"Customer": {
"dbConfig": {
"host": "localhost",
"port": 5984,
"dbName": "customers"
},
"credit": {
"initialLimit": 100,
// Set low for development
"initialDays": 1
}
}
}
```
================================================
FILE: sections/projectstructre/createlayers.basque.md
================================================
# 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

================================================
FILE: sections/projectstructre/createlayers.brazilian-portuguese.md
================================================
# Coloque seus Componentes em Camadas, mantenha o Express dentro de seus limites
### Separe o código do componente em camadas: web, serviços e DAL

### Explicação em 1 minuto: A desvantagem de misturar camadas

================================================
FILE: sections/projectstructre/createlayers.chinese.md
================================================
# 应用程序分层,保持Express在其边界内
### 将组件代码分成web, services, DAL层

### 1分钟说明:混合层的缺点

================================================
FILE: sections/projectstructre/createlayers.french.md
================================================
# 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

================================================
FILE: sections/projectstructre/createlayers.japanese.md
================================================
# アプリケーションを階層化し、 Express を境界内に収める
### コンポーネントコードをウェブ、サービス、DAL のレイヤーに分ける

### 1分解説: レイヤーを混ぜることのデメリット

================================================
FILE: sections/projectstructre/createlayers.korean.md
================================================
# 컴포넌트를 계층화(layer)하고, Express를 그 경계 안에 둬라
### 컴포넌트 코드를 웹, 서비스, 데이터 접근 언어(DAL) 계층으로 나누어라

### 1분 설명: 계층을 섞으면 불리한 점

================================================
FILE: sections/projectstructre/createlayers.md
================================================
# Layer your app, keep Express within its boundaries
### 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
```
**- 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
================================================
FILE: sections/projectstructre/createlayers.polish.md
================================================
# 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

================================================
FILE: sections/projectstructre/createlayers.russian.md
================================================
# Выделяйте ваши компоненты в отдельный слой, держите Express в его границах
### Разделить код компонента на слои: веб, сервисы и DAL

### 1 минутное объяснение: обратная сторона смешения слоев

================================================
FILE: sections/projectstructre/separateexpress.basque.md
================================================
# 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;
});
```
================================================
FILE: sections/projectstructre/separateexpress.brazilian-portuguese.md
================================================
# Separe 'app' e 'server' no Express
### Explicação em um Parágrafo
O gerador mais recente do Express vem com uma ótima prática que vale a pena manter - a declaração da API é separada da configuração relacionada à rede (porta, protocolo, etc). Isso permite testar a API durante o processo, sem realizar chamadas de rede, com todos os benefícios que ela traz para a mesa: execução rápida de testes e obtenção de métricas de cobertura do código. Ele também permite implantar a mesma API em condições de rede flexíveis e diferentes. Bônus: melhor separação de preocupações e código mais limpo.
### Exemplo de código: declaração de API, deve residir em app.js
```javascript
var app = express();
app.use(bodyParser.json());
app.use("/api/events", events.API);
app.use("/api/forms", forms);
```
### Exemplo de código: declaração de rede do servidor, deve residir em /bin/www
```javascript
var app = require('../app');
var http = require('http');
/**
* Obtenha porta do ambiente e armazene no Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Crie um servidor HTTP.
*/
var server = http.createServer(app);
```
### Exemplo: teste sua API em processo usando o superteste (pacote de teste popular)
```javascript
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'tobi' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
````
================================================
FILE: sections/projectstructre/separateexpress.chinese.md
================================================
# Express的 '应用' 和 '服务' 分离
### 一段解释
最新的Express生成器有一个值得保留的伟大实践--API声明与网络相关配置(端口、协议等)是分开的。这样就可以在不执行网络调用的情况下对API进行在线测试,它所带来的好处是:快速执行测试操作和获取代码覆盖率。它还允许在灵活多样的网络条件下部署相同的API。额外好处:更好的关注点分离和更清晰的代码结构。
### 代码示例:API声明应该在 app.js 文件里面
```javascript
var app = express();
app.use(bodyParser.json());
app.use("/api/events", events.API);
app.use("/api/forms", forms);
```
### 代码示例: 服务器网络声明,应该在 /bin/www 文件里面
```javascript
var app = require('../app');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
```
### 示例代码: 使用超快的流行的测试包在线测试你的代码
```javascript
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'tobi' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
````
================================================
FILE: sections/projectstructre/separateexpress.french.md
================================================
# 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;
});
```
================================================
FILE: sections/projectstructre/separateexpress.japanese.md
================================================
# 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;
});
```
================================================
FILE: sections/projectstructre/separateexpress.korean.md
================================================
# Separate Express 'app' and 'server'
### One Paragraph Explainer
The latest Express generator comes with a great practice that is worth to keep - the API declaration is separated from the network related configuration (port, protocol, etc). This allows testing the API in-process, without performing network calls, with all the benefits that it brings to the table: fast testing execution and getting coverage metrics of the code. It also allows deploying the same API under flexible and different network conditions. Bonus: better separation of concerns and cleaner code
### Code example: API declaration, should reside in app.js
```javascript
var app = express();
app.use(bodyParser.json());
app.use("/api/events", events.API);
app.use("/api/forms", forms);
```
### Code example: Server network declaration, should reside in /bin/www
```javascript
var app = require('../app');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
```
### Example: test your API in-process using supertest (popular testing package)
```javascript
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'tobi' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
````
================================================
FILE: sections/projectstructre/separateexpress.polish.md
================================================
# 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;
});
```
================================================
FILE: sections/projectstructre/separateexpress.russian.md
================================================
# Разделяйте 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);
```
### Пример: протестируйте свой API в процессе, используя supertest (популярный пакет тестирования)
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;
});
```
================================================
FILE: sections/projectstructre/thincomponents.chinese.md
================================================
# 用组件来构造你的解决方案
### 一段解释
对于中型应用以上来说,按部就班的写在一起真是太糟糕了-当一个有很多依赖的大型的软件会导致我们理解起来非常困难并且导致我们的代码杂乱不堪。甚至像那些能够熟练地驯服野兽的聪明的设计师一样,他们在设计上花费大量的精力用来"模块化"代码,每一次改动都需要仔细的评估对于其他依赖对象的影响。构建小型项目的最终方法是:将整体的项目分享一个个不与其他组件共享文件的独立组件,每个组件由很少的文件组成(例如API、服务、数据访问、测试等),所以这是比较容易理解的。一些被称为"microservices"的架构,去理解"microservices"不是你必须遵守的规范而是一套原则是非常重要的。你可以将许多原则应用到一个成熟的微服务体系结构中,或者只采用少数几个原则。只要你把软件的复杂性保持在低水平,两者都是好的。您至少应该做的是在组件之间创建一个基本的边界,在项目根中为每个业务组件分配一个文件夹,并让它自己做到其他组件只允许通过它的公共接口或API来实现它的功能。这是让你的组件保持简单的基础,避免依赖关系,在你的应用程序成长后,为将来成熟的微服务铺平道路。
### 引用博客: "扩展需要整个应用的扩展"
摘自博客 MartinFowler.com
> 单片应用程序可以成功,但是越来越多的人对它们感到失望——特别是当越来越多的应用程序被部署到云上时。变更周期是绑定在一起的——对应用程序的一小部分进行了更改,需要重新构建和部署整个庞然大物。随着时间的推移,保持良好的模块结构通常很难,这使得更改只会影响自己内部的模块变得更加困难。扩展需要扩展整个应用程序,而不是需要更大的资源的部分。
### 推荐: 通过自包含的组件来构造解决方案

### 避免: 通过技术角色对文件进行分组

================================================
FILE: sections/projectstructre/thincomponents.french.md
================================================
# 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

================================================
FILE: sections/projectstructre/thincomponents.japanese.md
================================================
# 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

================================================
FILE: sections/projectstructre/thincomponents.md
================================================
# 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

================================================
FILE: sections/projectstructre/thincomponents.russian.md
================================================
# Структурируйте свое решение по компонентам
### Объяснение в один абзац
Для приложений среднего размера и выше монолиты действительно плохи - об одном большом программном обеспечении с множеством зависимостей просто сложно рассуждать, и оно часто приводит к спагетти кода. Даже те умные архитекторы, которые умеют укротить зверя и «его модульно» - тратят огромные умственные усилия на дизайн, и каждое изменение требует тщательной оценки воздействия на другие зависимые объекты. Конечным решением является разработка небольшого программного обеспечения: разделите весь стек на автономные компоненты, которые не обмениваются файлами с другими, каждый из которых содержит очень мало файлов (например, API, сервис, доступ к данным, тестирование и т.д.), Так что это очень легко рассуждать об этом. Некоторые могут назвать эту архитектуру «микросервисов» - важно понимать, что микросервисы - это не спецификация, которой вы должны следовать, а скорее набор принципов. Вы можете принять многие принципы в полноценную архитектуру микросервисов или принять только несколько. Оба хороши, если вы сохраняете сложность программного обеспечения на низком уровне. Самое меньшее, что вы должны сделать, это создать базовые границы между компонентами, назначить папку в корне вашего проекта для каждого бизнес-компонента и сделать его автономным - другим компонентам разрешено использовать его функциональные возможности только через открытый интерфейс или API. Это основа для того, чтобы ваши компоненты были простыми, избежать адских зависимостей и проложить путь к полноценным микросервисам в будущем, когда ваше приложение будет расти
### Цитата из блога: "Масштабирование требует масштабирования всего приложения"
Из блога MartinFowler.com
> Монолитные приложения могут быть успешными, но люди все чаще испытывают разочарование в связи с ними, особенно когда в облаке развертывается все больше приложений. Циклы изменений связаны друг с другом - изменение, внесенное в небольшую часть приложения, требует перестройки и развертывания всего монолита. Со временем зачастую трудно сохранить хорошую модульную структуру, что усложняет сохранение изменений, которые должны затрагивать только один модуль в этом модуле. Масштабирование требует масштабирования всего приложения, а не его частей, которые требуют больших ресурсов.
### Хорошо: структурируйте свое решение по отдельным компонентам

### Плохо: сгруппируйте файлы по техническим ролям

================================================
FILE: sections/projectstructre/typescript-considerations.md
================================================
# 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"
================================================
FILE: sections/projectstructre/wraputilities.basque.md
================================================
# 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

================================================
FILE: sections/projectstructre/wraputilities.brazilian-portuguese.md
================================================
# Envolva os utilitários comuns como pacotes npm
### Explicação em um Parágrafo
Quando você começa a crescer e tem componentes diferentes em servidores diferentes que consomem utilitários semelhantes, você deve começar a gerenciar as dependências - como você pode manter uma cópia do código do utilitário e permitir que vários componentes do consumidor a usem e implantem? Bem, existe uma ferramenta para isso, ele é chamado npm ... Comece por encapsular pacotes de utilitários de terceiros com seu próprio código para torná-los facilmente substituíveis no futuro e publicar seu próprio código como pacote npm privado. Agora, toda a sua base de código pode importar esse código e se beneficiar da ferramenta gratuita de gerenciamento de dependências. É possível publicar pacotes npm para seu uso privado sem compartilhá-lo publicamente usando [módulos privados](https://docs.npmjs.com/private-modules/intro), [registros privados](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) ou [pacotes npm locais](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
### Compartilhando seus próprios utilitários comuns em ambientes e componentes

================================================
FILE: sections/projectstructre/wraputilities.chinese.md
================================================
# 将公用实用工具封装成 npm 包
### 一段解释
一旦你开始在不同的服务器上增加不同的组件并使用不同的服务器,这些服务器会消耗类似的工具,那么你应该开始管理依赖关系 - 你如何保留实用工具代码的一个副本,并让多个使用组件者使用和部署? 好吧,有一个这样的框架,它被称为npm ...首先用自己的代码包装第三方实用工具包,以便将来可以轻松替换,并发布自己的代码作为私人npm包。 现在,您所有的代码库都可以导入该代码并受益于免费的依赖管理框架。 您可以发布npm包供您自己的私人使用,而无需公开分享 [私人模块](https://docs.npmjs.com/private-modules/intro), [私人注册表](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) or [本地 npm 包](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
### 在环境和组件中共享你自己的公用实用工具

================================================
FILE: sections/projectstructre/wraputilities.french.md
================================================
# 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

================================================
FILE: sections/projectstructre/wraputilities.japanese.md
================================================
# 一般的なユーティリティを npm パッケージとしてラップする
### 一段落説明
成長を始めて、似たようなユーティリティを使用する異なるサーバ上の異なるコンポーネントを持つようになったら、依存関係の管理を始めなければなりません。- ユーティリティコードのコピーを1つにして、複数のコンシューマコンポーネントに使用させてデプロイするにはどうすれば良いでしょう? そのためのツールとして、npm と呼ばれるものがあります。サードパーティのユーティリティパッケージを独自のコードでラップして、将来的に簡単に置き換えられるようにし、独自のコードをプライベートな npm パッケージとして公開することから始めましょう。そうすることで、あなたのすべてのコードベースは、コードをインポートすることができ、無料の依存関係管理ツールの恩恵を受けることができます。[private modules](https://docs.npmjs.com/private-modules/intro) や [private registry](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html)、[local npm packages](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc) を使うことで、自分だけのプライベートな利用だけのために npm パッケージを公開することができます。
### 環境やコンポーネント横断で独自の共通ユーティリティを共有する

================================================
FILE: sections/projectstructre/wraputilities.korean.md
================================================
# 공유 유틸리티들은 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 패키지를 공개적으로 공유하지 않고도 자용으로 쓸 수 있게 출판할 수 있다.
### 당신만의 공유 유틸리티들을 환경과 컴포넌츠에 공유하기

================================================
FILE: sections/projectstructre/wraputilities.md
================================================
# Wrap common utilities as npm packages
### One Paragraph Explainer
Once you start growing and have different components on different servers which consumes similar utilities, you should start managing the dependencies - how can you keep 1 copy of your utility code and let multiple consumer components use and deploy it? well, there is a tool for that, it's called npm... Start by wrapping 3rd party utility packages with your own code to make it easily replaceable in the future and publish your own code as private npm package. Now, all your code base can import that code and benefit free dependency management tool. It's possible to publish npm packages for your own private use without sharing it publicly using [private modules](https://docs.npmjs.com/private-modules/intro), [private registry](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) or [local npm packages](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
### Sharing your own common utilities across environments and components

================================================
FILE: sections/projectstructre/wraputilities.polish.md
================================================
# 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

================================================
FILE: sections/projectstructre/wraputilities.russian.md
================================================
# Оборачивайте общие утилиты в пакеты npm
### Объяснение в один абзац
Как только вы начнете расти и иметь разные компоненты на разных серверах, которые используют одинаковые утилиты, вы должны начать управлять зависимостями - как вы можете сохранить 1 копию своего кода утилиты и позволить нескольким потребительским компонентам использовать и развертывать ее? ну, есть инструмент для этого, он называется npm ... Начните с упаковки сторонних пакетов утилит с вашим собственным кодом, чтобы в будущем его можно было легко заменить, и опубликуйте свой собственный код как частный пакет npm. Теперь вся ваша кодовая база может импортировать этот код и использовать бесплатный инструмент управления зависимостями. Можно публиковать пакеты npm для личного использования, не публикуя их публично, используя [private modules](https://docs.npmjs.com/private-modules/intro), [private registry](https://npme.npmjs.com/docs/tutorials/npm-enterprise-with-nexus.html) или [local npm packages](https://medium.com/@arnaudrinquin/build-modular-application-with-npm-local-modules-dfc5ff047bcc)
### Совместное использование собственных общих утилит в средах и компонентах

================================================
FILE: sections/security/avoid_publishing_secrets.basque.md
================================================
# 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.
================================================
FILE: sections/security/avoid_publishing_secrets.brazilian-portuguese.md
================================================
# Evite publicar segredos no registro do npm
### Explicação em um Parágrafo
Precauções devem ser tomadas para evitar o risco de publicação acidental de segredos nos registros públicos do npm. Um arquivo `.npmignore` pode ser usado para colocar arquivos ou pastas específicos em uma blacklist, ou a lista `files` no `package.json` pode atuar como uma whitelist.
Para obter uma visão do que o npm publish realmente publicará no registro, o sinalizador `--dry-run` pode ser adicionado ao comando npm publish para fornecer uma visão detalhada do pacote tarbell criado.
É importante notar que se um projeto estiver utilizando os arquivos `.npmignore` e` .gitignore`, tudo o que não estiver em `.npmignore` será publicado no registro (isto é, o arquivo` .npmignore` substitui o `. gitignore`). Esta condição é uma fonte comum de confusão e é um problema que pode levar ao vazamento de segredos. Os desenvolvedores podem acabar atualizando o arquivo `.gitignore`, mas esquecem de atualizar` .npmignore` também, o que pode levar a que um arquivo potencialmente sensível não seja empurrado para o controle de origem, mas ainda seja incluído no pacote npm.
### Exemplo de Código
Exemplo de arquivo .npmignore
```
# Tests
test
coverage
# Build tools
.travis.yml
.jenkins.yml
# Environment
.env
.config
```
Exemplo uso de uma lista de arquivos no package.json
```json
{
"files" : [
"dist/moment.js",
"dist/moment.min.js"
]
}
```
### O que Outros Blogueiros Dizem
Do blog de [Liran Tal & Juan Picado em Snyk](https://snyk.io/blog/ten-npm-security-best-practices/):
> ... Outra boa prática a adotar é utilizar a propriedade files em package.json, que funciona como whitelist e especifica a matriz de arquivos a serem incluídos no pacote a ser criado e instalado (enquanto o arquivo ignore funciona como uma lista negra). A propriedade files e um arquivo ignore podem ser usados juntos para determinar quais arquivos devem ser incluídos explicitamente, assim como excluídos, do pacote. Ao usar ambos, o primeiro a propriedade files em package.json tem precedência sobre o arquivo ignore.
Do [blog do npm](https://blog.npmjs.org/post/165769683050/publishing-what-you-mean-to-publish)
> ... Quando você executa npm publish, o npm agrupa todos os arquivos no diretório atual. Ele toma algumas decisões sobre o que incluir e o que ignorar. Para tomar essas decisões, ele usa o conteúdo de vários arquivos no diretório do projeto. Esses arquivos incluem .gitignore, .npmignore e a matriz de arquivos no pacote.json. Também inclui sempre certos arquivos e ignora outros.
================================================
FILE: sections/security/avoid_publishing_secrets.french.md
================================================
# É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.
================================================
FILE: sections/security/avoid_publishing_secrets.japanese.md
================================================
# 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 配列が含まれます。また、それは常に特定のファイルを含め、他のものを無視します。
================================================
FILE: sections/security/avoid_publishing_secrets.md
================================================
# Avoid publishing secrets to the npm registry
### One Paragraph Explainer
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.
To gain a view of what npm publish will really publish to the registry, the `--dry-run` flag can be added the npm publish command to provide a verbose view of the tarbell package created.
It is important to note that if a project is utilising both `.npmignore` and `.gitignore` files, everything which isn't in `.npmignore` is published to the registry(i.e. the `.npmignore` file overrides the `.gitignore`). This condition is a common source of confusion and is a problem that can lead to leaking secrets. Developers may end up updating the `.gitignore` file, but forget to update `.npmignore` as well, which can lead to a potentially sensitive file not being pushed to source control, but still being included in the npm package.
### Code example
Example .npmignore file
```
# Tests
test
coverage
# Build tools
.travis.yml
.jenkins.yml
# Environment
.env
.config
```
Example use of files array in package.json
```json
{
"files" : [
"dist/moment.js",
"dist/moment.min.js"
]
}
```
### What other bloggers say
From the blog by [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.
From the [npm blog](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.
================================================
FILE: sections/security/avoid_publishing_secrets.polish.md
================================================
# 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.
================================================
FILE: sections/security/avoid_publishing_secrets.russian.md
================================================
# Избегайте публикации секретов в реестре npm
### Объяснение в один абзац
Следует принять меры предосторожности, чтобы избежать риска случайной публикации секретов в публичных реестрах npm. Файл `.npmignore` может использоваться для внесения в черный список определенных файлов или папок, или массив `files` в `package.json` может выступать в качестве белого списка.
Чтобы получить представление о том, что npm publish действительно будет публиковать в реестре, можно добавить флаг `--dry-run`, добавив команду npm publish, чтобы обеспечить подробное представление созданного пакета tarbell.
Важно отметить, что если в проекте используются файлы `.npmignore` и `.gitignore`, все, чего нет в `.npmignore`, публикуется в реестре (то есть файл `.npmignore` переопределяет `. gitignore`). Это условие является распространенным источником путаницы и является проблемой, которая может привести к утечке секретов. Разработчики могут в конечном итоге обновить файл `.gitignore`, но не забудьте также обновить `.npmignore`, иначе это может привести к тому, что потенциально конфиденциальный файл не будет передан в систему контроля версий, но все же будет включен в пакет npm.
### Пример кода
Example .npmignore file
```
# Tests
test
coverage
# Build tools
.travis.yml
.jenkins.yml
# Environment
.env
.config
```
Пример использования массива файлов в package.json
```json
{
"files" : [
"dist/moment.js",
"dist/moment.min.js"
]
}
```
### Что говорят другие блогеры
Из блога [Liran Tal & Juan Picado at Snyk](https://snyk.io/blog/ten-npm-security-best-practices/):
> ... Еще одна полезная практика - использование свойства files в package.json, который работает в качестве белого списка и определяет массив файлов, которые должны быть включены в пакет, который должен быть создан и установлен (в то время как файл игнорирования функционирует как черный список). Свойство files и файл ignore можно использовать вместе, чтобы определить, какие файлы должны быть явно включены, а также исключены из пакета. При использовании обоих, первое свойство files в package.json имеет приоритет над файлом игнорирования.
Из [npm блога](https://blog.npmjs.org/post/165769683050/publishing-what-you-mean-to-publish)
> ... Когда вы запускаете npm publish, npm объединяет все файлы в текущем каталоге. Он принимает несколько решений о том, что включать и что игнорировать. Чтобы принять эти решения, он использует содержимое нескольких файлов в каталоге вашего проекта. Эти файлы включают в себя .gitignore, .npmignore и массив файлов в пакете.json. Он также всегда включает определенные файлы и игнорирует другие.
================================================
FILE: sections/security/avoideval.basque.md
================================================
# 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.
================================================
FILE: sections/security/avoideval.brazilian-portuguese.md
================================================
# Evite instruções eval do JavaScript
### Explicação em um Parágrafo
`eval()`, `setTimeout()`, `setInterval()`, e `new Function()` são funções globais, geralmente usadas no Node.js, que aceitam um parâmetro de string que representa uma expressão, instrução ou sequência de instruções JavaScript. A preocupação de segurança de usar essas funções é a possibilidade de que uma entrada de usuário não confiável possa entrar na execução do código, levando ao comprometimento do servidor, já que avaliar o código do usuário essencialmente permite que um invasor execute qualquer ação possível. Sugere-se refatorar código para não depender do uso dessas funções em que a entrada do usuário pode ser passada para a função e executada.
### Exemplo de Código
```javascript
// exemplo de código malicioso que um invasor conseguiu inserir
userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
// código malicioso executado
eval(userInput);
```
### O que Outros Blogueiros Dizem
Do livro Essential Node.js Security por [Liran Tal](https://leanpub.com/nodejssecurity):
> A função eval() é talvez a mais desaprovada dentro do JavaScript em uma perspectiva de segurança. Ela analisa uma string JavaScript como texto e a executa como se fosse um código JavaScript.
Misturar isso com entradas não confiáveis do usuário que podem encontrar o caminho para eval() é uma receita para o desastre que
pode acabar comprometendo o servidor.
================================================
FILE: sections/security/avoideval.chinese.md
================================================
# 避免JS eval语法
### 一段解释
`eval()`,`setTimeout()`和`setInterval()`是全局方法,经常在Node.js中被使用,它接收一个字符串参数,代表一个JavaScript表达式,语句,或者语句序列。使用这些函数的安全问题是, 不受信任的用户输入可能会发现进入代码执行的方式,从而导致危害服务器,因为评估用户代码实质上允许攻击者执行任何他可以的操作。对于这些用户输入可以传递给函数并执行的方法,建议重构代码,而不依赖于它们的使用。
### 代码示例
```javascript
// 攻击者可能输入的恶意代码示例
const userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
// 恶意代码被执行
eval(userInput);
```
### 其他博客作者的说法
摘自[Liran Tal](https://leanpub.com/nodejssecurity)的书籍Essential Node.js Security:
> 从安全的角度出发,在JavaScript语法中,eval()可能是最让人不悦的函数。
它将javascript字符串解析为文本,并将其作为javascript代码执行。
和不受信任的用户输入掺和在一起,可能会发现使用eval()是一个导致灾难的方式,最终服务器遭受破坏。
================================================
FILE: sections/security/avoideval.french.md
================================================
# É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.
================================================
FILE: sections/security/avoideval.japanese.md
================================================
# 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() へ渡されることが分かっているかもしれない信頼されていないユーザー入力と混ぜることは、サーバーを危険にさらすことになる、崩壊へのレシピといえるでしょう。
================================================
FILE: sections/security/avoideval.md
================================================
# Avoid JS eval statements
### One Paragraph Explainer
`eval()`, `setTimeout()`, `setInterval()`, and `new Function()` are global functions, often used in Node.js, which accept a string parameter representing a JavaScript expression, statement, or sequence of statements. The security concern of using these functions is the possibility that untrusted user input might find its way into code execution leading to server compromise, as evaluating user code essentially allows an attacker to perform any actions that you can. It is suggested to refactor code to not rely on the usage of these functions where user input could be passed to the function and executed.
### Code example
```javascript
// example of malicious code which an attacker was able to input
const userInput = "require('child_process').spawn('rm', ['-rf', '/'])";
// malicious code executed
eval(userInput);
```
### What other bloggers say
From the Essential Node.js Security book by [Liran Tal](https://leanpub.com/nodejssecurity):
> The eval() function is perhaps of the most frowned upon JavaScript pieces from a security
perspective. It parses a JavaScript string as text, and executes it as if it were a JavaScript code.
Mixing that with untrusted user input that might find it’s way to eval() is a recipe for disaster that
can end up with server compromise.
================================================
FILE: sections/security/avoideval.polish.md
================================================
# 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.
================================================
FILE: sections/security/avoideval.russian.md
================================================
# Избегайте JavaScript eval утверждений
### Объяснение в один абзац
`eval()`, `setTimeout()`, `setInterval()` и `new Function()` являются глобальными функциями, часто используемыми в Node.js, которые принимают строковый параметр, представляющий выражение, инструкцию или последовательность JavaScript инструкций. Забота о безопасности при использовании этих функций - это вероятность того, что ненадежный пользовательский ввод может найти свое место в выполнении кода, что приведет к компрометации сервера, поскольку оценка пользовательского кода, по сути, позволяет злоумышленнику выполнять любые действия, которые вы можете. Рекомендуется реорганизовать код, чтобы не полагаться на использование этих функций, когда пользовательский ввод может быть передан в функцию и выполнен.
### Пример кода
```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);
```
### Что говорят другие блогеры
Из книги Essential Node.js Security [Liran Tal](https://leanpub.com/nodejssecurity):
> Функция eval(), пожалуй, самая неодобрительная с точки зрения безопасности с точки зрения JavaScript. Он анализирует строку JavaScript как текст и выполняет ее, как если бы это был код JavaScript.
Сочетание этого с ненадежным пользовательским вводом, который может найти путь к eval(), - это рецепт катастрофы, которая может привести к компрометации сервера
================================================
FILE: sections/security/bcryptpasswords.brazilian-portuguese.md
================================================
# Evite usar a biblioteca de criptografia do Node.js para manipular senhas, use Bcrypt
### Explicação em um Parágrafo
Ao armazenar senhas de usuários, use um algoritmo hash adaptativo como o bcrypt, oferecido pelo [módulo bcrypt npm](https://www.npmjs.com/package/bcrypt) é recomendado em vez de usar o módulo de criptografia Node.js nativo. `Math.random ()` também nunca deve ser usado como parte de qualquer senha ou geração de token devido à sua previsibilidade.
O módulo `bcrypt` ou similar deve ser usado ao contrário da implementação JavaScript, pois quando se usa `bcrypt`, um número de 'rounds' pode ser especificado para fornecer um hash seguro. Isso define o fator de trabalho ou o número de 'rounds' pelos quais os dados são processados, e mais rounds de hash levam a hash mais seguro (embora isso custe tempo de CPU). A introdução de hash rounds significa que o fator de força bruta é reduzido significativamente, pois os crackers de senha são retardados, aumentando o tempo necessário para gerar uma tentativa.
### Exemplo de Código
```javascript
// gerando uma senha segura assincronamente usando 10 rodadas de hash
bcrypt.hash('myPassword', 10, function(err, hash) {
// Armazenar hash segura no registro do usuário
});
// comparar uma entrada de senha fornecida com o hash salvo
bcrypt.compare('somePassword', hash, function(err, match) {
if(match) {
// Senhas conferem
} else {
// Senhas não conferem
}
});
```
### O que Outros Blogueiros Dizem
Do blog de [Max McCarty](https://dzone.com/articles/nodejs-and-password-storage-with-bcrypt):
> ... não é só usar apenas o algoritmo hash correto. Falei extensivamente sobre como a ferramenta certa também inclui o ingrediente necessário de "tempo" como parte do algoritmo de hash de senha e o que significa para o invasor que está tentando decifrar senhas por meio de força bruta.
================================================
FILE: sections/security/bcryptpasswords.chinese.md
================================================
# 对于密码,避免使用Node.js的Crypto库,使用Bcrypt
### 一段解释
当存储用户密码的时候,建议使用[bcrypt npm module](https://www.npmjs.com/package/bcrypt)提供的自适应哈希算法bcrypt,而不是使用Node.js的crypto模块。由于`Math.random()`的可预测性,它也不应该作为密码或者令牌生成的一部分。
相较于JavaScript实现,`bcrypt`或者类似的模块应该被使用。当使用`bcrypt`时,可以指定相应数量的回合数(rounds),以提供安全的哈希。这将设置work factor或者用于数据处理的回合次数,而更多的哈希回合次数导致更安全的哈希值(尽管这是CPU耗时的代价)。哈希回合(hashing rounds)的引入意味着蛮力因子会显著降低, 因此密码破解会减慢, 从而增加产生一次尝试所需的时间。
### 代码示例
```javascript
// 使用10个哈希回合异步生成安全密码
bcrypt.hash('myPassword', 10, function(err, hash) {
// 在用户记录中存储安全哈希
});
// 将提供的密码输入与已保存的哈希进行比较
bcrypt.compare('somePassword', hash, function(err, match) {
if(match) {
// 密码匹配
} else {
// 密码不匹配
}
});
```
### 其他博客作者的说法
摘自博客[Max McCarty](https://dzone.com/articles/nodejs-and-password-storage-with-bcrypt):
> ... 它不只是使用正确的哈希算法。我已经广泛讨论了正确的工具,包括必要的成分"时间",如何作为密码哈希算法的一部分, 以及它对于试图通过蛮力破解密码的攻击者,意味着什么。
================================================
FILE: sections/security/bcryptpasswords.japanese.md
================================================
# パスワードの処理に 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) のブログより:
> ... 正しいハッシュアルゴリズムを使うだけではありません。正しいツールがパスワードハッシュアルゴリズムの一部として 「時間」という必要不可欠な要素を含んでいることと、それがブルートフォースでパスワードを解読しようとしている攻撃者にとって何を意味するのかについて、広範囲にわたって話してきました。
================================================
FILE: sections/security/bcryptpasswords.polish.md
================================================
# 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.
================================================
FILE: sections/security/bcryptpasswords.russian.md
================================================
# Не используйте криптографическую библиотеку Node.js для паролей, используйте Bcrypt
### Объяснение в один абзац
При хранении паролей пользователей рекомендуется использовать адаптивный алгоритм хеширования, такой как bcrypt, предлагаемый [bcrypt npm module](https://www.npmjs.com/package/bcrypt), а не использовать собственный криптографический модуль Node.js. , `Math.random()` также никогда не следует использовать как часть генерации пароля или токена из-за его предсказуемости.
Модуль `bcrypt` или аналогичный ему следует использовать в отличие от реализации JavaScript, так как при использовании `bcrypt` можно указать несколько "раундов" для обеспечения безопасного хэша. Это устанавливает коэффициент работы или количество "раундов", для которых обрабатываются данные, и большее количество циклов хеширования приводит к более безопасному хэшированию (хотя это и происходит за счет процессорного времени). Введение циклов хеширования означает, что коэффициент грубой силы значительно уменьшается, поскольку взломщики паролей замедляются, увеличивая время, необходимое для генерации одной попытки.
### Пример кода
```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.')
}
```
### Что говорят другие блогеры
Из блога [Max McCarty](https://dzone.com/articles/nodejs-and-password-storage-with-bcrypt):
> ... это не просто использование правильного алгоритма хеширования. Я много говорил о том, что правильный инструмент также включает в себя необходимый компонент "время" как часть алгоритма хеширования паролей и что это значит для злоумышленника, который пытается взломать пароли с помощью грубой силы.
================================================
FILE: sections/security/childprocesses.basque.md
================================================
# 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.
================================================
FILE: sections/security/childprocesses.brazilian-portuguese.md
================================================
# Tome cuidado extra ao trabalhar com processos filhos
### Explicação em um Parágrafo
Por melhores que sejam os processos filhos, eles devem ser usados com cautela. A transmissão da entrada do usuário deve ser higienizada, se não completamente evitada.
Os perigos de entradas não analisadas executando em nível de lógica de sistema são ilimitados, alcançando desde a execução remota de código até a exposição de dados confidenciais do sistema e até mesmo perda de dados. Uma lista de verificação de preparações pode ser algo do tipo:
- evite a entrada do usuário em todos os casos, senão, valide e limpe-a
- limitar os privilégios dos processos pai e filhos usando identidades de usuário/grupo
- execute o seu processo dentro de um ambiente isolado para evitar efeitos colaterais indesejados se as outras preparações falharem
### Exemplo de código: perigos de execuções de processos de filho não-analizados
```javascript
const { exec } = require('child_process');
...
// por exemplo, pegue um script que receba dois argumentos, um deles é uma entrada do usuário não-analizada
exec('"/path/to/test file/someScript.sh" --someOption ' + input);
// -> imagine o que poderia acontecer se o usuário simplesmente inserisse algo como '&& rm -rf --no-preserve-root /'
// você teria uma surpresa indesejada
```
### Recursos Adicionais
Da [documentation](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback) do Node.js sobre processos filhos:
> Nunca passe a entrada de usuário não-analizada para esta função. Qualquer entrada contendo metacaracteres de shell pode ser usada para disparar a execução arbitrária de comandos.
================================================
FILE: sections/security/childprocesses.chinese.md
================================================
# 处理子进程时要谨慎
### 一段解释
尽管子进程非常棒, 但使用它们应该谨慎。如果无法避免传递用户输入,就必须经过脱敏处理。
未经脱敏处理的输入执行系统级逻辑的危险是无限的, 从远程代码执行到暴露敏感的系统数据, 甚至数据丢失。准备工作的检查清单可能是这样的
- 避免在每一种情况下的用户输入, 否则验证和脱敏处理
- 使用user/group标识限制父进程和子进程的权限
- 在隔离环境中运行进程, 以防止在其他准备工作失败时产生不必要的副作用
### 代码示例: 未脱敏处理子进程的危害
```javascript
const { exec } = require('child_process');
...
// 例如, 以一个脚本为例, 它采用两个参数, 其中一个参数是未经脱敏处理的用户输入
exec('"/path/to/test file/someScript.sh" --someOption ' + input);
// -> 想象一下, 如果用户只是输入'&& rm -rf --no-preserve-root /'类似的东西, 会发生什么
// 你会得到一个不想要的结果
```
### 额外资源
摘自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):
> 切勿将未经脱敏处理的用户输入传递给此函数。任何包含shell元字符(metacharacters)的输入都可用于触发任意命令的执行。
================================================
FILE: sections/security/childprocesses.french.md
================================================
# 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
================================================
FILE: sections/security/childprocesses.japanese.md
================================================
# 子プロセスで処理を行う場合は注意する
### 一段落説明
子プロセスは素晴らしいものですが、注意して使用する必要があります。ユーザー入力の受け渡しは、利用しないのでなければ、サニタイズされていなければなりません。サニタイズされていない入力がシステムレベルのロジックを実行する危険性は無限にあり、リモートコードの実行からセンシティブなシステムデータの漏洩、そしてデータ損失にまで及びます。準備のためのチェックリストは以下のようになります。
- すべての場合でユーザー入力を避け、そうでない場合は検証とサニタイズを行う
- ユーザー/グループアイデンティを利用して、親プロセスと子プロセスの権限を制限する
- 上記が機能しなかった場合の望まない副作用を防ぐために、プロセスを隔離された環境で実行する
### コード例: サニタイズされていない子プロセス実行の危険性
```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) より:
> サニタイズされていないユーザー入力をこの関数に決して渡さないでください。シェルのメタ文字を含んでいるどんな入力も、任意のコマンド実行を引き起こすために利用される可能性があります。
================================================
FILE: sections/security/childprocesses.md
================================================
# Be cautious when working with child processes
### One Paragraph Explainer
As great as child processes are, they should be used with caution. Passing in user input must be sanitized, if not avoided at all.
The dangers of unsanitized input executing system-level logic are unlimited, reaching from remote code execution to the exposure of
sensitive system data and even data loss. A check list of preparations could look like this
- avoid user input in every case, otherwise validate and sanitize it
- limit the privileges of the parent and child processes using user/group identities
- run your process inside of an isolated environment to prevent unwanted side-effects if the other preparations fail
### Code example: Dangers of unsanitized child process executions
```javascript
const { exec } = require('child_process');
...
// as an example, take a script that takes two arguments, one of them is unsanitized user input
exec('"/path/to/test file/someScript.sh" --someOption ' + input);
// -> imagine what could happen if the user simply enters something like '&& rm -rf --no-preserve-root /'
// you'd be in for an unwanted surprise
```
### Additional resources
From the Node.js child process [documentation](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback):
> Never pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.
================================================
FILE: sections/security/childprocesses.polish.md
================================================
# 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.
================================================
FILE: sections/security/childprocesses.russian.md
================================================
# Будьте осторожны при работе с дочерними процессами
### Объяснение в один абзац
Как бы ни были хороши дочерние процессы, их следует использовать с осторожностью. Передача пользовательского ввода должна быть очищена, если не предотвращена вообще.
Опасности несанкционированного ввода, выполняющего системную логику, безграничны, начиная от удаленного выполнения кода и заканчивая раскрытием конфиденциальных системных данных и даже потерей данных. Контрольный список препаратов может выглядеть так
- избегайте ввода пользователя в каждом случае, в противном случае проверьте и очистите его
- ограничьте права родительского и дочернего процессов, используя идентификаторы пользователя/группы
- запустить процесс внутри изолированной среды, чтобы предотвратить нежелательные побочные эффекты, если другие препараты не сработают
### Пример кода: опасность выполнения несанированных дочерних процессов
```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
```
### Дополнительные ресурсы
Из Node.js [документации](https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback):
> Никогда не передавайте необработанный пользовательский ввод в эту функцию. Любой ввод, содержащий метасимволы оболочки, может использоваться для запуска выполнения произвольной команды.
================================================
FILE: sections/security/commonsecuritybestpractices.basque.md
================================================
[✔]: ../../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)
================================================
FILE: sections/security/commonsecuritybestpractices.brazilian-portuguese.md
================================================
[✔]: ../../assets/images/checkbox-small-blue.png
# Coleção genérica de boas práticas de segurança
A seção de boas práticas comuns de segurança contém as práticas recomendadas que são padronizadas em muitos frameworks e convenções. Por exemplo, a execução de um aplicativo com SSL/TLS deve ser uma diretriz e uma convenção comuns em todas as configurações para obter grandes benefícios de segurança.
## ![✔] Use SSL/TLS para criptografar a conexão cliente-servidor
**TL;DR:** Nos tempode de [certificados SSL/TLS gratuitos](https://letsencrypt.org/) e fácil configuração desses, você não precisa mais pesar vantagens e desvantagens de usar um servidor seguro porque as vantagens como segurança, suporte à tecnologia moderna e confiança superam claramente as desvantagens, como sobrecarga mínima em comparação com o HTTP puro.
**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**](./secureserver.brazilian-portuguese.md)
## ![✔] Comparando valores secretos e hashes com segurança
**TL;DR:** Ao comparar valores secretos ou hashes como digestões do HMAC, você deve usar a função [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) que o Node fornece por padrão desde o Node.js v6.6.0. Este método compara dois objetos e continua comparando, mesmo que os dados não correspondam. Os métodos de comparação de igualdade padrão simplesmente retornariam após uma incompatibilidade de caracteres, permitindo ataques de tempo com base no comprimento da operação.
**Caso contrário:** Usando operadores de comparação de igualdade padrão, você pode expor informações críticas com base no tempo gasto para comparar dois objetos.
## ![✔] 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/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.
Em seguida, abaixo, listamos alguns conselhos importantes do projeto OWASP.
## ![✔] OWASP A2: Autenticação Quebrada
- Requisite MFA/2FA (autenticação de múltiplos fatores) para serviços e contas importantes
- Troque senhas e chaves de acesso com freqüência, incluindo chaves SSH
- Aplique diretivas de senha forte, tanto para operadores quanto para gerenciamento de usuários no aplicativo ([🔗 OWASP recomendações para senhas](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
- Não envie ou implemente sua aplicação com nenhuma credencial padrão, principalmente para usuários administradores ou serviços externos dos quais você depende
- Use apenas métodos de autenticação padrão, como OAuth, OpenID, etc. - **evite** autenticação básica
- Limitação da taxa de autenticação: Não permitir mais de _X_ tentativas de login (incluindo recuperação de senha, etc.) em um período _Y_
- Na falha de login, não deixe o usuário saber se a verificação de nome de usuário ou senha falhou, apenas retorne um erro de autenticação comum
- Considere o uso de um sistema centralizado de gerenciamento de usuários para evitar o gerenciamento de várias contas por funcionário (por exemplo, GitHub, AWS, Jenkins, etc) e para se beneficiar de um sistema de gerenciamento de usuários testado em batalha.
## ![✔] OWASP A5: Controle de acesso quebrado
- Respeite o [princípio do menor privilégio](https://en.wikipedia.org/wiki/Principle_of_least_privilege) - cada componente e DevOps deve ter acesso apenas às informações e recursos necessários
- **Nunca** trabalhar com a conta console/root (privilégio completo), exceto para gerenciamento de contas
- Executar todas as instâncias/contêineres com uma conta de função/serviço
- Atribuir permissões a grupos e não a usuários. Isso deve tornar o gerenciamento de permissões mais fácil e transparente para a maioria dos casos
## ![✔] OWASP A6: Configurações de Segurança
- O acesso ao interior do ambiente de produção é feito somente através da rede interna, use SSH ou outras formas, mas _nunca_ exponha serviços internos
- Restringir o acesso à rede interna - defina explicitamente qual recurso pode acessar outros recursos (por exemplo, política de rede ou sub-redes)
- Se estiver usando cookies, configure-o para o modo "seguro", no qual ele está sendo enviado apenas por SSL
- Se estiver usando cookies, configure-o apenas para "mesmo site", para que apenas solicitações do mesmo domínio recebam os cookies designados
- Se estiver usando cookies, prefira a configuração "HttpOnly" que impede que o código JavaScript do lado do cliente acesse os cookies
- Proteja cada VPC com regras de acesso restritas e restritivas
- Priorize ameaças usando qualquer modelagem padrão de ameaça à segurança como STRIDE ou DREAD
- Protege contra ataques DDoS usando balanceadores de carga HTTP(S) e TCP
- Realize testes periódicos de penetração por agências especializadas
## ![✔] OWASP A3: Exposição de dados sensíveis
- Aceite apenas conexões SSL/TLS, imponha Strict-Transport-Security usando cabeçalhos
- Separe a rede em segmentos (ou seja, sub-redes) e garanta que cada nó tenha o mínimo necessário de permissões de acesso de rede
- Agrupar todos os serviços/instâncias que não precisam de acesso à Internet e explicitamente desautorizar qualquer conexão de saída (também uma sub-rede privada)
- Armazene todos os segredos em serviços de cofre, como o AWS KMS, o HashiCorp Vault ou o Google Cloud KMS
- Bloqueie instâncias de metadados confidenciais usando metadados
- Criptografe dados em trânsito quando deixa um limite físico
- Não inclua segredos em instruções de log
- Evite mostrar senhas simples no frontend, tome as medidas necessárias no backend e nunca armazene informações confidenciais em texto simples
## ![✔] OWASP A9: Usando componentes com vulnerabilidades de segurança conhecidas
- Digitalize imagens do docker para vulnerabilidades conhecidas (usando o Docker e outros fornecedores oferecem serviços de digitalização)
- Ativar atualizações e patches automáticos de instâncias (máquinas) para evitar a execução de versões antigas do sistema operacional que não possuem patches de segurança
- Forneça ao usuário os tokens 'id', 'access' e 'refresh' para que o token de acesso seja de curta duração e renovado com o token de atualização
- Registrar e auditar cada chamada de API para serviços de nuvem e gerenciamento (por exemplo, quem excluiu o bucket do S3?) Usando serviços como o AWS CloudTrail
- Execute o verificador de segurança do seu provedor de nuvem (por exemplo, consultor de confiança de segurança da AWS)
## ![✔] OWASP A10: Registro e monitoramento insuficientes
- Alerte em eventos de auditoria notáveis ou suspeitos, como login de usuário, criação de novo usuário, alteração de permissão, etc.
- Alerte sobre quantidade irregular de falhas de login (ou ações equivalentes como senha esquecida)
- Inclua o horário e o nome de usuário que iniciaram a atualização em cada registro de banco de dados
## ![✔] OWASP A7: Cross-Site-Scripting (XSS)
- Use mecanismos de template ou frameworks que escapem automaticamente do XSS por design, como EJS, Pug, React ou Angular. Aprenda as limitações de cada mecanismo de proteção XSS e lidar adequadamente com os casos de uso que não são cobertos
- O escape de dados de solicitação HTTP não confiáveis com base no contexto na saída HTML (corpo, atributo, JavaScript, CSS ou URL) resolverá as vulnerabilidades de XSS refletido e armazenado
- Aplicar codificação sensível ao contexto quando modificar o documento do navegador no lado do cliente atua em relação ao DOM XSS
- Ativar uma Política de Segurança de Conteúdo (CSP) como um controle de mitigação de defesa em profundidade contra o XSS
================================================
FILE: sections/security/commonsecuritybestpractices.french.md
================================================
[✔]: ../../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)
================================================
FILE: sections/security/commonsecuritybestpractices.japanese.md
================================================
[✔]: ../../assets/images/checkbox-small-blue.png
# 一般的な Node.js セキュリティベストプラクティス
この一般的なセキュリティガイドラインのセクションには、多くのフレームワークや慣習において標準となっているベストプラクティスが含まれています。例えば、SSL/TLS を使用してアプリケーションを実行するということは、優れたセキュリティ上の利点を享受するためにあらゆる環境において従われる、よくあるガイドラインや慣習です。
## ![✔] クライアント/サーバー間の通信を暗号化するために SSL/TLS を使用する
**TL;DR:** [無料の SSL/TLS 証明書](https://letsencrypt.org/) が提供されそれらが簡単に設定できる時代には、セキュアなサーバーを使用することの利点と欠点を比較する必要はもはやありません。なぜなら、セキュリティやモダンなテクノロジーのサポート、そして信頼性といった利点は、明らかにHTTPと比べてオーバーヘッドが大きいといったような欠点を上回るためです。
**さもないと:** 接続が暗号化されていない場合には、攻撃者は中間者攻撃を行い、ユーザーの行動を監視し、さらに悪質なアクションを行ってくる可能性があります。
🔗 [**さらに読む: セキュアな Node.js サーバーを実行する**](./secureserver.japanese.md)
## ![✔] シークレット値とハッシュ値をセキュアに比較する
**TL;DR:** シークレット値や HMAC ダイジェストのようなハッシュを比較する場合は、Node.js v6.6.0 以降に Node が提供している [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) 関数を使用するべきです。このメソッドは 2 つの与えられたオブジェクトを比較し、データが一致しない場合でも比較を続けます。デフォルトの等値比較メソッドは、文字の不一致だった場合には単純にリターンするだけなので、操作の長さに基づいたタイミング攻撃を可能にします。
**さもないと:** デフォルトの等値比較演算子を使用すると、2 つのオブジェクトを比較するのにかかった時間に基づいて、重要な情報を漏出してしまうかもしれません。
## ![✔] Node.js を用いてランダムな文字列を生成する
**TL;DR:** トークンやその他のセキュリティ上重要なユースケースを対象として、擬似ランダム文字列を生成する独自のカスタムビルド関数を使用すると、実際には思ったほどランダムではなく、アプリケーションが暗号攻撃に対して脆弱になる可能性があります。安全なランダム文字列を生成する必要がある場合は、システムが提供するエントロピーを用いた [`crypto.RandomBytes(size, [callback])`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_randombytes_size_callback) 関数を使用してください。
**さもないと:** 暗号学的に安全な方法を使わずに擬似ランダム文字列を生成すると、攻撃者が生成結果を予測して再現し、アプリケーションを安全ではないものにしてしまう可能性があります。
続けて以下に、OWASP プロジェクトから重要なアドバイスをいくつか挙げてみました。
## ![✔] OWASP A2: 壊れた認証
- 重要なサービスやアカウントは MFA/2FA を要求する
- SSH キーも含め、パスワードやアクセスキーは頻繁に変更する
- 運用とアプリケーション内両方のユーザー管理おいて、強力なパスワードポリシーを適用する([🔗 OWASP パスワードの推奨事項](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
- デフォルトのクレデンシャル情報を使用してアプリケーションを出荷またはデプロイしない(特に管理者ユーザーや外部サービスに依存している場合)
- OAuth や OpenID のような標準的な認証方法のみを使用する - ベーシック認証の使用は **避ける**
- 認証レートリミット: 期間 _Y_ における _X_ 回を超えるログインを拒否する
- ログインに失敗した場合は、ユーザ名とパスワードのどちらの確認に失敗したかをユーザに知らせることなく、一般的な認証エラーを返す
- 従業員ごとに複数のアカウント(例えば、GitHub、AWS、Jenkinsなど)を管理することを避け、歴戦のユーザー管理システムの恩恵を受けるために、一元化されたユーザー管理システムの利用を検討する
## ![✔] OWASP A5: 壊れたアクセスコントロール
- [最小権限の原則](https://en.wikipedia.org/wiki/Principle_of_least_privilege)を尊重する - すべてのコンポーネントと DevOps 担当者は、必要最低限の情報とリソースにのみアクセスできるようにする
- アカウント管理以外では、ルート(フル権限)アカウントでの作業は **絶対に** 行わない
- ロール/サービスアカウントに代わって、すべてのインスタンス/コンテナを実行する
- ユーザーではなくグループに権限を割り当てる。これにより、ほとんどの場合、権限管理がより簡単で透明性の高いものになるはずである
## ![✔] OWASP A6: セキュリティの設定ミス
- 本番環境内部へのアクセスは内部ネットワークを介してのみ行い、SSH または他の手段を利用する。 _絶対に_ 内部サービスは外部に公開しない
- 内部ネットワークアクセスを制限する - どのリソースが他のリソースにアクセスできるかを明示的に設定する(例えば、ネットワークポリシーやサブネットなど)
- Cookie(cookies)を利用している場合は、クライアントサイドの JavaScript がCookieにアクセスすることを防ぐために「HttpOnly」の設定を優先的に行う
- Cookieを利用している場合は、「same site」を設定し、同ドメインからのリクエストのみ指定されたCookieを取得できるようにする
- 各 VPC を厳格で性異言されたアクセスルールで保護する
- STRIDE や DREAD のような標準的なセキュリティ脅威モデルを利用して脅威に優先順位を付ける
- HTTP(S) と TCP ロードバランサーを使用して DDoS 攻撃に対して保護をする
- 専門機関による定期的なペネトレーションテストを実施する
## ![✔] OWASP A3: センシティブなデータの露出
- SSL/TLS 接続のみを受け付け、ヘッダーを利用して String-Transport-Security を強制する
- ネットワークをセグメント(サブネットなど)に分割し、各ノードが必要最低限のネットワークアクセス権限を持っていることを確認する
- インターネットアクセスを必要としない全てのサービス/インスタンスをグループ化し、外向きの接続を明示的に禁止する(プライベートサブネット)
- AWS KMS、HachiCorp Vault または Google Cloud KMS のような vault 製品にシークレットを保存する
- メタデータを使用して、機密性の高いインスタンスメタデータを隔離する
- データが物理的な境界線を超える際は、運んでいるデータを暗号化する
- シークレットをログ情報の中に含まない
- フロントエンドでは平文のパスワードを表示しないようにし、バックエンドでは必要な対策を講じて決して機密情報を平文で保存しないようにする
## ![✔] OWASP A9: 既知のセキュリティ脆弱性を持つコンポーネントの使用
- docker イメージをスキャンして既知の脆弱性を探す(Docker や他のベンダーのスキャンサービスを利用する)
- インスタンス(マシン)の自動パッチ適用とアップグレードを有効にして、セキュリティパッチが不足している古いバージョンの OS を実行しないようにする
- ユーザに「id」「access」「refresh」といったトークンを提供することで、アクセストークンの期限を短くして、refresh トークンで更新されるようにする
- AWS CloudTrail のようなサービスを利用して、クラウドや管理サービスに対する API コール(例えば、誰がS3バケットを削除したのか?)のログを残し、監査を行う
- クラウドプロバイダー(AWS Trusted Advisor など)のセキュリティチェッカーを実行する
## ![✔] OWASP A10: ロギングとモニタリングの不足
- ユーザーログイン、新規ユーザー作成、権限変更といった操作において、目立った、または疑わしい監査対象イベントが発生したらアラートする
- 異常な回数のログインの失敗(もしくはパスワードを忘れた、などの同様のアクション)が発生した場合にはアラートする
- 各 DB レコードにおいて更新を行った時刻とユーザー名を含める
## ![✔] OWASP A7: クロスサイトスクリプティング(XSS)
- EJS、Pug、React、Angular など、設計によって自動的に XSS 回避するテンプレートエンジンやフレームワークを使用する。XSS 対策のそれぞれのメカニズムの限界を知り、対象外のユースケースに適切に対処する
- HTML 出力のコンテキスト(body、属性、JavaScript、CSS、URL など)に基づいて、信頼できない HTTP リクエストデータをエスケープすることで、反射型および格納型の XSS 脆弱性を解決する
- クライアントサイドでブラウザの document を変更する際に context-sensitive エンコーディングを適用して DOM XSS 対策する
- XSS を緩和する多層防御(defense-in-depth)として Content-Security Policy (CSP) を有効化する
## ![✔] 個人識別可能な情報(PIIデータ)の保護
- 個人情報(PII)とは、特定の個人を識別できるデータのことである
- アプリケーションでは個人情報は暗号化して保護する
- その地域におけるデータプライバシーに関する法律に従う
参考となる法律:
- 欧州連合(EU): GDPR - https://ec.europa.eu/info/law/law-topic/data-protection_en
- インド: https://meity.gov.in/writereaddata/files/Personal_Data_Protection_Bill,2018.pdf
- シンガポール: https://www.pdpc.gov.sg/Legislation-and-Guidelines/Personal-Data-Protection-Act-Overview
## ![✔] security.txt ファイルを配置する[プロダクション]
**TL;DR:** 本番環境において、 Web サイトや Web アプリケーションの ```/.well-known``` ディレクトリ(/.well-known/security.txt)またはルートディレクトリ(/security.txt)配下に ```security.txt``` というテキストファイルを置いてください。```security.txt``` ファイルは、セキュリティリサーチャーが脆弱性を報告するための詳細と、報告の送り先となる責任者および組織の連絡先の詳細(E メール、電話番号)を含む必要があります。
**さもないと:** 脆弱性についての報告を受けられない可能性があります。脆弱性への対応をすぐに行う機会を逃すことになります。
🔗 [**さらに読む: security.txt**](https://securitytxt.org/)
## ![✔] SECURITY.md ファイルを配置する[オープンソース]
**TL;DR:** プロジェクトのセキュリティ脆弱性を責任を持って報告するための方法を示すために、 SECURITY.md ファイルを、リポジトリのルートディレクトリ、docs ディレクトリ、もしくは .github ディレクトリの中に置いてください。SECURITY.md ファイルは、セキュリティリサーチャーが脆弱性を報告するための詳細と、報告の送り先となる責任者および組織の連絡先の詳細(E メール、電話番号)を含む必要があります。
**さもないと:** 脆弱性についての報告を受けられない可能性があります。脆弱性への対応をすぐに行う機会を逃すことになります。
🔗 [**さらに読む: SECURITY.md**](https://help.github.com/en/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository)
================================================
FILE: sections/security/commonsecuritybestpractices.md
================================================
[✔]: ../../assets/images/checkbox-small-blue.png
# Common Node.js security best practices
The common security guidelines section contains best practices that are standardized in many frameworks and conventions, running an application with SSL/TLS, for example, should be a common guideline and convention followed in every setup to achieve great security benefits.
## ![✔] Use SSL/TLS to encrypt the client-server connection
**TL;DR:** In the times of [free SSL/TLS certificates](https://letsencrypt.org/) and easy configuration of those, you do no longer have to weigh advantages and disadvantages of using a secure server because the advantages such as security, support of modern technology and trust clearly outweigh the disadvantages like minimal overhead compared to pure HTTP.
**Otherwise:** Attackers could perform man-in-the-middle attacks, spy on your users' behaviour and perform even more malicious actions when the connection is unencrypted
🔗 [**Read More: Running a secure Node.js server**](./secureserver.md)
## ![✔] Comparing secret values and hashes securely
**TL;DR:** When comparing secret values or hashes like HMAC digests, you should use the [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) function Node provides out of the box since Node.js v6.6.0. This method compares two given objects and keeps comparing even if data does not match. The default equality comparison methods would simply return after a character mismatch, allowing timing attacks based on the operation length.
**Otherwise:** Using default equality comparison operators you might expose critical information based on the time taken to compare two objects
## ![✔] Generating random strings using Node.js
**TL;DR:** Using a custom-built function generating pseudo-random strings for tokens and other security-sensitive use cases might actually not be as random as you think, rendering your application vulnerable to cryptographic attacks. When you have to generate secure random strings, use the [`crypto.randomBytes(size, [callback])`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) function using available entropy provided by the system.
**Otherwise:** When generating pseudo-random strings without cryptographically secure methods, attackers might predict and reproduce the generated results, rendering your application insecure
Going on, below we've listed some important bits of advice from the OWASP project.
## ![✔] OWASP A2: Broken Authentication
- Require MFA/2FA for important services and accounts
- Rotate passwords and access keys frequently, including SSH keys
- Apply strong password policies, both for ops and in-application user management ([🔗 OWASP password recommendation](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
- Do not ship or deploy your application with any default credentials, particularly for admin users or external services you depend on
- Use only standard authentication methods like OAuth, OpenID, etc. - **avoid** basic authentication
- Auth rate limiting: Disallow more than _X_ login attempts (including password recovery, etc.) in a period of _Y_
- On login failure, don't let the user know whether the username or password verification failed, just return a common auth error
- Consider using a centralized user management system to avoid managing multiple accounts per employee (e.g. GitHub, AWS, Jenkins, etc) and to benefit from a battle-tested user management system
## ![✔] OWASP A5: Broken access control
- Respect the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) - every component and DevOps person should only have access to the necessary information and resources
- **Never** work with the console/root (full-privilege) account except for account management
- Run all instances/containers on behalf of a role/service account
- Assign permissions to groups and not to users. This should make permission management easier and more transparent for most cases
## ![✔] OWASP A6: Security Misconfiguration
- Access to production environment internals is done through the internal network only, use SSH or other ways, but _never_ expose internal services
- Restrict internal network access - explicitly set which resource can access other resources (e.g. network policy or subnets)
- If using cookies, configure it to "secured" mode where it's being sent over SSL only
- If using cookies, configure it for "same site" only so only requests from same domain will get back the designated cookies
- If using cookies, prefer "HttpOnly" configuration that prevent client-side JavaScript code from accessing the cookies
- Protect each VPC with strict and restrictive access rules
- Prioritize threats using any standard security threat modeling like STRIDE or DREAD
- Protect against DDoS attacks using HTTP(S) and TCP load balancers
- Perform periodic penetration tests by specialized agencies
## ![✔] OWASP A3: Sensitive Data Exposure
- Only accept SSL/TLS connections, enforce Strict-Transport-Security using headers
- Separate the network into segments (i.e. subnets) and ensure each node has the least necessary networking access permissions
- Group all services/instances that need no internet access and explicitly disallow any outgoing connection (a.k.a private subnet)
- Store all secrets in a vault products like AWS KMS, HashiCorp Vault or Google Cloud KMS
- Lockdown sensitive instance metadata using metadata
- Encrypt data in transit when it leaves a physical boundary
- Don't include secrets in log statements
- Avoid showing plain passwords in the frontend, take necessary measures in the backend and never store sensitive information in plaintext
## ![✔] OWASP A9: Using Components With Known Security Vulneraibilities
- Scan docker images for known vulnerabilities (using Docker's and other vendors' scanning services)
- Enable automatic instance (machine) patching and upgrades to avoid running old OS versions that lack security patches
- Provide the user with both 'id', 'access' and 'refresh' token so the access token is short-lived and renewed with the refresh token
- Log and audit each API call to cloud and management services (e.g who deleted the S3 bucket?) using services like AWS CloudTrail
- Run the security checker of your cloud provider (e.g. AWS security trust advisor)
## ![✔] OWASP A10: Insufficient Logging & Monitoring
- Alert on remarkable or suspicious auditing events like user login, new user creation, permission change, etc
- Alert on irregular amount of login failures (or equivelant actions like forgot password)
- Include the time and username that initiated the update in each DB record
## ![✔] OWASP A7: Cross-Site-Scripting (XSS)
- Use templating engines or frameworks that automatically escape XSS by design, such as EJS, Pug, React, or Angular. Learn the limitations of each mechanisms XSS protection and appropriately handle the use cases which are not covered
- Escaping untrusted HTTP request data based on the context in the HTML output (body, attribute, JavaScript, CSS, or URL) will resolve Reflected and Stored XSS vulnerabilities
- 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)
================================================
FILE: sections/security/commonsecuritybestpractices.polish.md
================================================
[✔]: ../../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
================================================
FILE: sections/security/commonsecuritybestpractices.russian.md
================================================
[✔]: ../../assets/images/checkbox-small-blue.png
# Общие рекомендации по безопасности Node.js
Раздел общих рекомендаций по безопасности содержит рекомендации, которые стандартизированы во многих платформах и соглашениях, например, запуск приложения с SSL/TLS должен быть общим руководством и соглашением, которое следует соблюдать при каждой настройке для достижения значительных преимуществ безопасности.
## ![✔] Используйте SSL/TLS для шифрования соединения клиент-сервер
**TL;DR:** Во времена [бесплатных SSL/TLS-сертификатов](https://letsencrypt.org/) и их простой настройки вам больше не нужно взвешивать преимущества и недостатки использования безопасного сервера, потому что такие преимущества, как безопасность, поддержка современных технологий и доверие, явно перевешивают такие недостатки, как минимальные издержки по сравнению с чистым HTTP.
**Иначе:** Злоумышленники могут выполнять атаки "человек посередине", следить за поведением ваших пользователей и совершать еще более злонамеренные действия, когда соединение не зашифровано.
🔗 [**Read More: Запуск безопасного Node.js сервера**](./secureserver.russian.md)
## ![✔] Безопасное сравнение секретных значений и хэшей
**TL;DR:** При сравнении секретных значений или хэшей, таких как код HMAC, вы должны использовать [`crypto.timingSafeEqual(a, b)`](https://nodejs.org/dist/latest-v9.x/docs/api/crypto.html#crypto_crypto_timingsafeequal_a_b) функция Node обеспечивает готовую работу, начиная с Node.js v6.6.0. Этот метод сравнивает два заданных объекта и продолжает сравнивать, даже если данные не совпадают. Методы сравнения равенства по умолчанию просто возвращались бы после несоответствия символов, позволяя рассчитывать время атаки на основе длины операции.
**Иначе:** Используя операторы сравнения равенства по умолчанию, вы можете предоставить критическую информацию, основываясь на времени, затраченном на сравнение двух объектов.
## ![✔] Генерация случайных строк с использованием Node.js
**TL;DR:** Использование специально созданной функции, генерирующей псевдослучайные строки для токенов и других чувствительных к безопасности случаев использования, на самом деле может быть не таким случайным, как вы думаете, что делает ваше приложение уязвимым для криптографических атак. Когда вам нужно создать безопасные случайные строки, используйте [`crypto.randomBytes(size, [callback])`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback), используя доступную энтропию, предоставляемую системой.
**Иначе:** При создании псевдослучайных строк без криптографически безопасных методов злоумышленники могут прогнозировать и воспроизводить сгенерированные результаты, делая ваше приложение небезопасным
Далее мы перечислили несколько важных советов от проекта OWASP.
## ![✔] OWASP A2: сломанная аутентификация
- Требуйте MFA/2FA для важных услуг и учетных записей
- Чаще меняйте пароли и ключи доступа, включая ключи SSH.
- Применяйте политики надежных паролей как для операций, так и для управления пользователями внутри приложения ([🔗 OWASP password recommendation](https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Implement_Proper_Password_Strength_Controls.22))
- Не отправляйте и не развертывайте свое приложение с какими-либо учетными данными по умолчанию, особенно для пользователей-администраторов или внешних служб, от которых вы зависите
- Используйте только стандартные методы аутентификации, такие как OAuth, OpenID и т.д. - **избегайте** базовой аутентификации
- Ограничивайте скорость авторизации: запрещать более _X_ попыток входа в систему (включая восстановление пароля и т.д.) в период _Y_
- При неудачном входе в систему не сообщайте пользователю, прошла ли проверка имени пользователя или пароля, просто верните общую ошибку аутентификации
- Рассмотрите возможность использования централизованной системы управления пользователями, чтобы избежать управления несколькими учетными записями на одного сотрудника (например, GitHub, AWS, Jenkins и т.д.) и воспользоваться проверенной в бою системой управления пользователями
## ![✔] OWASP A5: нарушен контроль доступа
- Уважайте [Принцип минимальных привилегий](https://ru.wikipedia.org/wiki/Принцип_минимальных_привилегий) - каждый компонент и сотрудник DevOps должны иметь доступ только к необходимой информации и ресурсам
- **Никогда** не работаю с консольной/корневой (полной привилегией) учетной записью, за исключением управления учетными записями
- Запустите все экземпляры/контейнеры от имени роли/учетной записи службы.
- Назначьте разрешения для групп, а не для пользователей. Это должно сделать управление разрешениями проще и прозрачнее для большинства случаев
## ![✔] OWASP A6: неправильная настройка безопасности
- Доступ к внутренним компонентам производственной среды осуществляется только через внутреннюю сеть, с использованием SSH или других способов, но _никогда_ не предоставляйте внутренние службы
- Ограничьте доступ к внутренней сети - явно указывайте, какой ресурс может получить доступ к другим ресурсам (например, политика сети или подсети).
- При использовании файлов cookie настройте его в "защищенный" режим, когда он отправляется только по SSL
- При использовании файлов cookie настройте его только для "одного сайта", чтобы только запросы с одного домена возвращали указанные файлы cookie.
- При использовании файлов cookie, предпочитайте конфигурацию "HttpOnly", которая не позволяет клиентскому JavaScript-коду получить доступ к файлам cookie.
- Защитите каждый VPC с помощью строгих и ограничительных правил доступа.
- Расставляйте приоритеты угроз, используя любое стандартное моделирование угроз безопасности, такое как STRIDE или DREAD
- Защищайтесь от DDoS-атак с использованием балансировщиков нагрузки HTTP(S) и TCP.
- Проводите периодические тесты на проникновение специализированными агентствами.
##! [✔] OWASP A3: раскрытие конфиденциальных данных
- Принимайте только соединения SSL/TLS, применяйте Strict-Transport-Security с использованием заголовков.
- Разделите сеть на сегменты (то есть подсети) и убедитесь, что у каждого узла есть наименее необходимые разрешения на доступ к сети.
- Сгруппируйте все службы/экземпляры, которым не нужен доступ в Интернет, и явно запретите любое исходящее соединение (a.k.a частная подсеть)
- Храните все секреты в таких хранилищах, как AWS KMS, HashiCorp Vault или Google Cloud KMS.
- Блокируйте чувствительные метаданные экземпляра с использованием метаданных
- Шифруйте данные при передаче, когда они покидают физическую границу
- Не включайте секреты в записи журнала
- Избегайте показа простых паролей во внешнем интерфейсе, примите необходимые меры в бэкэнде и никогда не храните конфиденциальную информацию в открытом виде
## ![✔] OWASP A9: использование компонентов с известными уязвимостями безопасности
- Сканируйте образы докеров на наличие известных уязвимостей (с помощью Docker и других поставщиков, предлагающих услуги сканирования)
- Включите автоматическое исправление и обновление экземпляра (компьютера), чтобы избежать запуска старых версий ОС, в которых отсутствуют исправления безопасности.
- Предоставьте пользователю токены "id", "access" и "refresh", чтобы токен доступа был недолговечным и обновлялся токеном обновления
- Регистрируйте и проверяйте каждый вызов API для облачных сервисов и служб управления (например, кто удалил корзину S3?), Используя такие сервисы, как AWS CloudTrail.
- Запустите проверку безопасности вашего облачного провайдера (например, советник по безопасности AWS)
## ![✔] OWASP A10: недостаточная регистрация и мониторинг
- Оповещайте о значительных или подозрительных событиях аудита, таких как вход пользователя в систему, создание нового пользователя, изменение разрешения и т.д.
- Оповещайте о нерегулярном количестве неудачных попыток входа в систему (или эквилантировании действий, таких как забытый пароль)
- Включайте в лог время и имя пользователя, который инициировал обновление в каждой записи БД
## ![✔] OWASP A7: межсайтовый скриптинг (XSS)
- Используйте шаблоны или фреймворки, которые автоматически выходят из XSS, такие как EJS, Pug, React или Angular. Изучите ограничения каждого механизма защиты XSS и соответствующим образом обработайте случаи использования, которые не охвачены
- Экранируйте ненадежные данные HTTP-запроса на основе контекста в выводе HTML (тело, атрибут, JavaScript, CSS или URL), который устранит уязвимости отраженного и хранимого XSS
- Применение контекстно-зависимых кодировок при изменении документа браузера на стороне клиента действует против DOM XSS
- Включайте политики защиты контента (CSP) в качестве средства защиты от XSS для смягчения защиты.
================================================
FILE: sections/security/dependencysecurity.basque.md
================================================
# 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)
================================================
FILE: sections/security/dependencysecurity.brazilian-portuguese.md
================================================
# Inspecione constante e automaticamente por dependências vulneráveis
### Explicação em um Parágrafo
A maioria das aplicações Node.js depende muito de um grande número de módulos de terceiros do npm ou do Yarn, ambos registros de pacotes populares, devido à facilidade e velocidade de desenvolvimento. No entanto, a desvantagem desse benefício são os riscos de segurança de incluir vulnerabilidades desconhecidas em seu aplicativo, que é um risco reconhecido por seu lugar na lista de riscos de segurança de aplicações web mais importante do OWASP.
Há várias ferramentas disponíveis para ajudar a identificar pacotes de terceiros em aplicativos Node.js que foram identificados como vulneráveis pela comunidade para reduzir o risco de introduzi-los em seu projeto. Eles podem ser usados periodicamente em ferramentas CLI ou incluídos como parte do processo de criação da sua aplicação.
### Índice
- [NPM audit](#npm-audit)
- [Snyk](#snyk)
- [Greenkeeper](#greenkeeper)
### NPM Audit
`npm audit` é uma nova ferramenta cli introduzida no NPM@6.
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)
### Snyk
O Snyk oferece uma CLI rica em recursos, bem como integração com o GitHub. O Snyk vai além disso e, além de notificar vulnerabilidades, também cria automaticamente novas solicitações de pull, corrigindo vulnerabilidades, à medida que os patches são liberados para vulnerabilidades conhecidas.
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/)
🔗 [Leia em: Ferramenta on-line Synk para verificar pacotes npm e módulos do GitHub](https://snyk.io/test)
### Greenkeeper
O Greenkeeper é um serviço que oferece atualizações de dependência em tempo real, o que mantém um aplicativo mais seguro, sempre usando as versões das dependêcias mais atualizadas e corrigidas.
O Greenkeeper observa as dependências npm especificadas no arquivo `package.json` de um repositório e cria automaticamente uma ramificação com cada atualização de dependência. O conjunto de Integração Contínua (IC) do repositório é então executado para revelar quaisquer alterações significativas para a versão de dependência atualizada no aplicativo. Se o IC falhar devido à atualização de dependência, um problema claro e conciso será criado no repositório para ser analisado, destacando as versões do pacote atual e atualizado, juntamente com informações e histórico de confirmações da versão atualizada.
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
🔗 [Rising Stack Blog: riscos de dependências Node.js](https://blog.risingstack.com/controlling-node-js-security-risk-npm-dependencies/)
🔗 [NodeSource Blog: Melhorando a segurança do npm](https://nodesource.com/blog/how-to-reduce-risk-and-improve-security-around-npm)
================================================
FILE: sections/security/dependencysecurity.french.md
================================================
# 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)
================================================
FILE: sections/security/dependencysecurity.japanese.md
================================================
# 定期的に、そして自動的に脆弱性のある依存関係を検査する
### 一段落説明
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)
================================================
FILE: sections/security/dependencysecurity.md
================================================
# Constantly and automatically inspect for vulnerable dependencies
### One Paragraph Explainer
The majority of Node.js applications rely heavily on a large number of third party modules from npm or Yarn, both popular package registries, due to ease and speed of development. However, the downside to this benefit is the security risks of including unknown vulnerabilities into your application, which is a risk recognised by its place in the OWASP top critical web application security risks list.
There is a number of tools available to help identify third-party packages in Node.js applications which have been identified as vulnerable by the community to mitigate the risk of introducing them into your project. These can be used periodically from CLI tools or included as part of your application's build process.
### Table of Contents
- [NPM audit](#npm-audit)
- [Snyk](#snyk)
- [Greenkeeper](#greenkeeper)
- [Additional Resources](#additional-resources)
### NPM Audit
`npm audit` is a new cli tool introduced with NPM@6.
Running `npm audit` will produce a report of security vulnerabilities with the affected package name, vulnerability severity and description, path, and other information, and, if available, commands to apply patches to resolve vulnerabilities.

🔗 [Read on: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
### Snyk
Snyk offers a feature-rich CLI, as well as GitHub integration. Snyk goes further with this and in addition to notifying vulnerabilities, also automatically creates new pull requests fixing vulnerabilities as patches are released for known vulnerabilities.
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 Snyk GitHub integration automatically created pull request:

🔗 [Read on: Snyk website](https://snyk.io/)
🔗 [Read on: Synk online tool to check npm packages and GitHub modules](https://snyk.io/test)
### Greenkeeper
Greenkeeper is a service which offers real-time dependency updates, which keeps an application more secure by always using the most 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
🔗 [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)
================================================
FILE: sections/security/dependencysecurity.polish.md
================================================
# 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)
================================================
FILE: sections/security/dependencysecurity.russian.md
================================================
# Постоянно и автоматически проверяйте наличие уязвимых зависимостей
### Объяснение в один абзац
Из-за простоты и скорости разработки большинство приложений Node.js в значительной степени зависят от большого количества сторонних модулей из npm или Yarn, обоих популярных реестров пакетов. Однако недостатком этого преимущества являются риски безопасности, связанные с включением неизвестных уязвимостей в ваше приложение, что является риском, признанным по его месту в списке важнейших угроз безопасности веб-приложения OWASP.
Существует ряд инструментов, помогающих идентифицировать сторонние пакеты в приложениях Node.js, которые были определены сообществом как уязвимые, чтобы снизить риск их внедрения в ваш проект. Они могут периодически использоваться из инструментов CLI или включаться как часть процесса сборки вашего приложения.
### Оглавление
- [NPM audit](#npm-audit)
- [Snyk](#snyk)
- [Greenkeeper](#greenkeeper)
- [Дополнительные ресурсы](#дополнительные-ресурсы)
### NPM audit
`npm audit` - это новый инструмент CLI, представленный в NPM@6.
Запуск `npm audit` выдаст отчет об уязвимостях безопасности с указанием имени уязвимого пакета, серьезности и описания уязвимости, пути и другой информации, а также, если доступно, команд для применения исправлений для устранения уязвимостей.

🔗 [Читайте еще: NPM blog](https://docs.npmjs.com/getting-started/running-a-security-audit)
### Snyk
Snyk предлагает многофункциональный интерфейс командной строки, а также интеграцию с GitHub. Snyk идет дальше с этим и в дополнение к уведомлению об уязвимостях также автоматически создает новые запросы извлечения, исправляющие уязвимости, по мере выпуска исправлений для известных уязвимостей.
Многофункциональный веб-сайт Snyk также позволяет проводить специальную оценку зависимостей, когда предоставляется GitHub-репозиторий или URL-адрес модуля npm. Вы также можете искать пакеты 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 следит за зависимостями npm, указанными в файле `package.json` репозитория, и автоматически создает рабочую ветку с каждым обновлением зависимостей. Затем запускается пакет CI репозитория, чтобы выявить любые критические изменения для обновленной версии зависимости в приложении. Если CI завершается неудачно из-за обновления зависимостей, в хранилище, которое будет выставлено на аукцион, создается ясная и краткая проблема, в которой указаны текущие и обновленные версии пакета, а также информация и история изменений обновленной версии.
Пример вывода интеграции 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)
================================================
FILE: sections/security/escape-output.basque.md
================================================
# 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 ``. Isso pode ser mitigado instruindo o navegador a tratar qualquer parte de dados não confiáveis apenas como conteúdo e nunca interpretá-los - essa técnica é chamada de escape. Muitas bibliotecas npm e mecanismos de templates HTML fornecem recursos de escape (example: [escape-html](https://github.com/component/escape-html), [node-esapi](https://github.com/ESAPI/node-esapi)). Não só o conteúdo HTML deve ser escapado, mas também CSS e JavaScript
### Exemplo de código: não coloque dados não confiáveis no seu HTML
```html
direto em um script
dentro de um comentário HTML
em um nome de atributo
no nome de uma tag
direto no CSS
```
### Exemplo de código - Conteúdo mal-intencionado que pode ser injetado em um banco de dados
```html
A pseudo comment to the a post
```
### Citação de Blog: "Quando não queremos que os caracteres sejam interpretados"
Do Blog [benramsey.com](https://benramsey.com/articles/escape-output/)
> Os dados podem deixar sua aplicação na forma de HTML enviado para um navegador da Web, SQL enviado para um banco de dados, XML enviado para um leitor de RSS, WML enviado para um dispositivo sem fio, etc. As possibilidades são ilimitadas. Cada um deles tem seu próprio conjunto de caracteres especiais que são interpretados de maneira diferente do resto do texto simples recebido. Às vezes queremos enviar esses caracteres especiais para que eles sejam interpretados (tags HTML enviadas para um navegador da Web, por exemplo), enquanto outras vezes (no caso de entrada de usuários ou alguma outra fonte), não queremos que os caracteres para ser interpretado, então precisamos escapar eles.
> Escaping também é conhecido como codificação. Em suma, é o processo de representar dados de maneira que não sejam executados ou interpretados. Por exemplo, o HTML renderizará o texto a seguir em um navegador da Web como texto em negrito, porque as marcações `` têm um significado especial:
> ```html
> Isso é um texto em negrito.
> ```
### Citação de Blog: "OWASP recomenda usar uma biblioteca de codificação focada em segurança"
Do blog OWASP [Folha de Dicas de Prevenção de XSS (Cross Site Scripting)](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
> "Escrever esses codificadores não é tremendamente difícil, mas existem algumas armadilhas ocultas. Por exemplo, você pode se sentir tentado a usar alguns dos atalhos de escape, como "\" em JavaScript. No entanto, esses valores são perigosos e podem ser mal interpretados pelos analisadores aninhados no navegador. Você também pode esquecer de escapar do caracter de escape, que os atacantes podem usar para neutralizar suas tentativas de segurança.**OWASP recomenda o uso de uma biblioteca de codificação focada em segurança para garantir que essas regras sejam implementadas corretamente**."
### Citação de Blog: "Você DEVE usar a sintaxe de escape para a parte do HTML"
Do blog OWASP [Folha de Dicas de Prevenção de XSS (Cross Site Scripting)](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
> "Mas a codificação de entidade HTML não funciona se você estiver colocando dados não confiáveis dentro de uma tag ``. 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 `` といったように。これを緩和するには、ブラウザに対して、信頼されていないデータのかたまりをコンテンツとしてのみ扱い、決して解釈しないように指示することが有効です - このテクニックはエスケープと呼ばれます。多くの npm ライブラリや HTML テンプレートエンジンがエスケープ機能を提供しています (例: [escape-html](https://github.com/component/escape-html)、[node-esapi](https://github.com/ESAPI/node-esapi))。HTMLコンテンツだけでなく、CSS や JavaScript もエスケープする必要があります。
### コード例 - 信頼されていないデータを HTML に挿入しない
```html
script タグの中に直接挿入する
HTML コメントアウトの中に挿入する
属性名として挿入する
<ここに信頼されていないデータを挿入しないでください... href="/test" /> 要素名として挿入する
CSS に直接挿入する
```
### コード例 - DB に注入される可能性のある悪質なコンテンツ
```html
A pseudo comment to the a post
```
### ブログ引用: "When we don’t want the characters to be interpreted"(文字を解釈させたくない場合)
ブログ [benramsey.com](https://benramsey.com/articles/escape-output/) より
> データは、Webブラウザに送信される HTML、データベースに送信される SQL、RSS リーダーに送信される XML、ワイヤレスデバイスに送信される WML などの形でアプリケーションを離れる可能性があります。そのような可能性は至るところにあります。これらそれぞれのケースには、プレーンテキストとは異なる解釈をされる特殊文字のセットが存在します。時にこれらの特殊文字が解釈されるように送信したい場合もありますが(例えば Web ブラウザに送信される HTML タグなど)、他の場合においては(ユーザや他のソースからの入力の場合)、そういった文字を解釈されたくないので、エスケープする必要があります。
> エスケープは、エンコードと呼ばれることもあります。つまり、それはデータを、実行されたり解釈されたりしない形で表現するプロセスのことを指すのです。例えば、HTML において `` は特別な意味を持つので、ブラウザでは以下のようなテキストを太字テキストとして表示します:
> `これは太字のテキストです`
> ところで、ブラウザにタグを解釈させずに、タグそのものを表示させたい場合はどうすれば良いでしょうか。その場合は、HTML において特別な意味を持つ角括弧をエスケープする必要があります。以下はエスケープされた HTML を表します:
> `<strong>これは太字のテキストです</strong>`
### ブログ引用: "OWASP recommends using a security-focused encoding library"(OWASP はセキュリティに重点を置いたエンコードライブラリの利用を推奨します)
OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) より
> これらのエンコーダを書くことはそれほど難しいことではありませんが、いくつか落とし穴が隠れています。例えば、JavaScript の " のような、エスケープショートカットを使いたくなるかもしれません。しかしながら、このような値は危険であり、ブラウザのネストされたパーサーによって誤って解釈される可能性があります。また、エスケープ文字のエスケープを忘れる可能性もあり、これは攻撃者によって、安全化の試みを無効化するために利用されます。 **OWASP はこれらのルールが適切に実装されていることを確かにするために、セキュリティに重点を置いたエンコードライブラリの利用を推奨します。**
### ブログ引用: "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) より
> しかし、信頼されていないデータを、``. 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 ` `. 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 ``. Это может быть смягчено путем указания браузеру обрабатывать любой кусок ненадежных данных только как контент и никогда не интерпретировать его - этот метод называется экранированием. Многие библиотеки npm и движки шаблонов HTML предоставляют возможности экранирования (пример: [escape-html](https://github.com/component/escape-html), [node-esapi](https://github.com/ESAPI/узел-esapi)). Не только HTML-контент должен быть экранирован, но также CSS и JavaScript
### Пример кода - не помещайте ненадежные данные в ваш HTML
```html
directly in a script
inside an HTML comment
in an attribute name
in a tag name
directly in CSS
```
### Пример кода - вредоносный контент, который может быть введен в БД
```html
A pseudo comment to the a post
```
### Цитата из блога: "Когда мы не хотим, чтобы символы интерпретировались"
Из блога [benramsey.com](https://benramsey.com/articles/escape-output/)
> Данные могут оставить ваше приложение в виде HTML, отправленного в веб-браузер, SQL, отправленного в базу данных, XML, отправленного в программу чтения RSS, WML, отправленного на беспроводное устройство, и т.д. Возможности безграничны. Каждый из них имеет свой собственный набор специальных символов, которые интерпретируются иначе, чем остальная часть полученного простого текста. Иногда мы хотим отправить эти специальные символы так, чтобы они интерпретировались (например, HTML-теги, отправляемые в веб-браузер), в то время как в других случаях (в случае ввода от пользователей или какого-либо другого источника) нам не нужно интерпретировать символы, поэтому мы должны экранировать их.
> Экранирование также иногда называют "кодированием". Короче говоря, это процесс представления данных таким образом, что они не будут выполнены или интерпретированы. Например, HTML будет отображать следующий текст в веб-браузере как текст, выделенный жирным шрифтом, поскольку теги `` имеют особое значение:
This is bold text.
Но, предположим, я хочу отобразить теги в браузере и избежать их интерпретации. Затем мне нужно избежать угловых скобок, которые имеют особое значение в HTML. Следующее иллюстрирует экранированный HTML:
`<strong>This is bold text.</strong>`
### Цитата из блога: "OWASP рекомендует использовать библиотеку кодирования, ориентированную на безопасность"
Из блога OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
> "Написание этих кодировщиков не так уж сложно, но есть немало скрытых ловушек. Например, у вас может возникнуть соблазн использовать некоторые из таких ярлыков, как `\"`, в JavaScript. Однако эти значения опасны и могут быть неправильно истолкованы вложенными анализаторами в браузере. Вы также можете забыть избежать парсинга, который злоумышленники могут использовать для нейтрализации ваших попыток быть в безопасности. **OWASP рекомендует использовать ориентированную на безопасность библиотеку кодирования, чтобы обеспечить правильное выполнение этих правил**."
### Цитата из блога: "Вы ДОЛЖНЫ использовать синтаксис escape для части HTML"
Из блога OWASP [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
> "Но кодирование сущностей HTML не работает, если вы помещаете ненадежные данные в тег `