From 703d66f70dabb5c4244b82fde65fd52205baff6e Mon Sep 17 00:00:00 2001 From: Claudio W Date: Tue, 24 Oct 2023 13:00:09 +0200 Subject: [PATCH] meta: remove translated files and removed languages without traction (#6028) * meta: remove translated files and removed languages without traction * meta: adjusted pages and styles * fix: types and css * chore: replace transid * chore: add other languages back * chore: copy changes * Update pages/en/about/index.md Signed-off-by: Brian Muenzenmeyer * Update pages/en/about/governance.md Signed-off-by: Claudio W * chore: updated footer --------- Signed-off-by: Brian Muenzenmeyer Signed-off-by: Claudio W Co-authored-by: Brian Muenzenmeyer --- components/Footer.tsx | 13 +- crowdin.yml | 8 +- i18n/config.json | 72 +- i18n/locales/ar.json | 89 +- i18n/locales/ca.json | 39 - i18n/locales/de.json | 97 +- i18n/locales/en.json | 12 +- i18n/locales/es.json | 85 +- i18n/locales/fa.json | 39 - i18n/locales/fr.json | 97 +- i18n/locales/gl.json | 39 - i18n/locales/id.json | 103 +- i18n/locales/index.mjs | 10 - i18n/locales/it.json | 73 +- i18n/locales/ja.json | 75 +- i18n/locales/ka.json | 93 +- i18n/locales/ko.json | 85 +- i18n/locales/nl.json | 39 - i18n/locales/pt-br.json | 77 +- i18n/locales/ro.json | 39 - i18n/locales/ru.json | 85 +- i18n/locales/tr.json | 99 +- i18n/locales/uk.json | 81 +- i18n/locales/zh-cn.json | 105 +- i18n/locales/zh-tw.json | 83 +- layouts/DownloadReleasesLayout.tsx | 36 +- layouts/IndexLayout.tsx | 5 +- navigation.json | 22 +- pages/ar/404.md | 9 - pages/ar/about/governance.md | 32 - pages/ar/about/index.md | 42 - pages/ar/docs/es6.md | 40 - pages/ar/docs/guides/abi-stability.md | 50 - .../guides/anatomy-of-an-http-transaction.md | 426 -------- .../docs/guides/debugging-getting-started.md | 221 ---- pages/ar/docs/guides/getting-started-guide.md | 27 - pages/ar/docs/guides/index.md | 30 - .../ar/docs/guides/publishing-napi-modules.md | 44 - pages/ar/docs/index.mdx | 38 - pages/ar/download/current.md | 34 - pages/ar/download/index.md | 33 - pages/ar/download/package-manager.md | 297 ------ pages/ar/download/releases.md | 11 - pages/ar/get-involved/collab-summit.md | 18 - pages/ar/get-involved/contribute.md | 47 - pages/ar/get-involved/index.md | 31 - pages/ar/index.md | 18 - pages/be/404.md | 9 - pages/be/about/governance.md | 30 - pages/be/about/index.md | 45 - .../diagnostics/live-debugging/index.md | 25 - .../guides/event-loop-timers-and-nexttick.md | 344 ------- pages/be/download/current.md | 34 - pages/be/download/index.md | 34 - pages/be/download/releases.md | 11 - pages/be/index.md | 18 - pages/ca/404.md | 9 - pages/ca/about/index.md | 45 - pages/ca/docs/index.mdx | 42 - pages/ca/download/current.md | 34 - pages/ca/download/index.md | 34 - pages/ca/get-involved/index.md | 30 - pages/ca/index.md | 18 - pages/de/404.md | 9 - pages/de/about/governance.md | 31 - pages/de/about/index.md | 45 - pages/de/docs/index.mdx | 47 - pages/de/download/current.md | 34 - pages/de/download/index.md | 34 - pages/de/index.md | 18 - pages/en/about/governance.md | 8 +- pages/en/about/index.md | 13 +- pages/en/about/previous-releases.md | 20 + pages/en/about/security-reporting.md | 74 ++ pages/en/download/releases.md | 11 - pages/es/404.md | 9 - pages/es/about/governance.md | 24 - pages/es/about/index.md | 41 - pages/es/docs/es6.md | 40 - pages/es/docs/index.mdx | 38 - pages/es/download/current.md | 34 - pages/es/download/index.md | 34 - pages/es/download/package-manager.md | 293 ------ pages/es/download/releases.md | 11 - pages/es/get-involved/collab-summit.md | 18 - pages/es/get-involved/contribute.md | 47 - pages/es/get-involved/index.md | 32 - pages/es/index.md | 18 - pages/fa/404.md | 9 - pages/fa/about/index.md | 43 - pages/fa/index.md | 18 - pages/fr/404.md | 9 - pages/fr/about/governance.md | 28 - pages/fr/about/index.md | 38 - pages/fr/docs/es6.md | 40 - pages/fr/docs/guides/abi-stability.md | 40 - pages/fr/docs/index.mdx | 38 - pages/fr/download/current.md | 34 - pages/fr/download/index.md | 34 - pages/fr/download/package-manager.md | 293 ------ pages/fr/download/releases.md | 11 - pages/fr/get-involved/collab-summit.md | 18 - pages/fr/get-involved/contribute.md | 47 - pages/fr/get-involved/index.md | 25 - pages/fr/index.md | 18 - pages/gl/404.md | 9 - pages/gl/index.md | 18 - pages/id/404.md | 9 - pages/id/about/governance.md | 31 - pages/id/about/index.md | 45 - pages/id/docs/es6.md | 40 - pages/id/docs/guides/abi-stability.md | 41 - .../guides/anatomy-of-an-http-transaction.md | 365 ------- .../docs/guides/backpressuring-in-streams.md | 512 ---------- .../docs/guides/blocking-vs-non-blocking.md | 102 -- .../guides/buffer-constructor-deprecation.md | 214 ---- .../docs/guides/debugging-getting-started.md | 187 ---- .../id/docs/guides/diagnostics-flamegraph.md | 121 --- pages/id/docs/guides/diagnostics/index.md | 18 - .../diagnostics/live-debugging/index.md | 25 - .../live-debugging/using-inspector.md | 12 - .../docs/guides/diagnostics/memory/index.md | 52 - .../diagnostics/memory/using-gc-traces.md | 366 ------- .../diagnostics/memory/using-heap-profiler.md | 96 -- .../diagnostics/memory/using-heap-snapshot.md | 137 --- .../diagnostics/poor-performance/index.md | 30 - .../poor-performance/using-linux-perf.md | 76 -- pages/id/docs/guides/domain-postmortem.md | 365 ------- .../docs/guides/dont-block-the-event-loop.md | 414 -------- .../guides/event-loop-timers-and-nexttick.md | 343 ------- pages/id/docs/guides/getting-started-guide.md | 29 - pages/id/docs/guides/index.md | 34 - pages/id/docs/guides/nodejs-docker-webapp.md | 251 ----- .../id/docs/guides/publishing-napi-modules.md | 39 - pages/id/docs/guides/security/index.md | 322 ------ pages/id/docs/guides/simple-profiling.md | 230 ----- pages/id/docs/guides/timers-in-node.md | 125 --- .../working-with-different-filesystems.md | 90 -- pages/id/docs/index.mdx | 43 - pages/id/download/current.md | 34 - pages/id/download/index.md | 34 - pages/id/download/package-manager.md | 393 ------- pages/id/download/releases.md | 11 - pages/id/get-involved/collab-summit.md | 18 - pages/id/get-involved/contribute.md | 47 - pages/id/get-involved/index.md | 25 - pages/id/index.md | 18 - pages/it/404.md | 9 - pages/it/about/index.md | 45 - pages/it/get-involved/collab-summit.md | 18 - pages/it/get-involved/index.md | 31 - pages/it/index.md | 18 - pages/ja/404.md | 9 - pages/ja/about/index.md | 45 - pages/ja/docs/es6.md | 40 - .../docs/guides/blocking-vs-non-blocking.md | 297 ------ .../guides/buffer-constructor-deprecation.md | 396 ------- .../docs/guides/debugging-getting-started.md | 522 ---------- .../ja/docs/guides/diagnostics-flamegraph.md | 281 ----- pages/ja/docs/guides/getting-started-guide.md | 35 - pages/ja/docs/guides/index.md | 67 -- pages/ja/docs/guides/nodejs-docker-webapp.md | 566 ---------- pages/ja/docs/guides/simple-profiling.md | 455 --------- pages/ja/docs/guides/timers-in-node.md | 405 -------- pages/ja/docs/index.mdx | 37 - pages/ja/download/current.md | 34 - pages/ja/download/index.md | 34 - pages/ja/download/package-manager.md | 278 ----- pages/ja/download/releases.md | 11 - pages/ja/get-involved/collab-summit.md | 61 -- pages/ja/get-involved/contribute.md | 105 -- pages/ja/get-involved/index.md | 66 -- pages/ja/index.md | 18 - pages/ka/404.md | 9 - pages/ka/about/governance.md | 32 - pages/ka/about/index.md | 45 - pages/ka/docs/es6.md | 40 - .../docs/guides/debugging-getting-started.md | 189 ---- pages/ka/docs/guides/getting-started-guide.md | 29 - pages/ka/docs/guides/index.md | 33 - pages/ka/docs/index.mdx | 38 - pages/ka/download/index.md | 34 - pages/ka/get-involved/index.md | 25 - pages/ka/index.md | 18 - pages/ko/404.md | 9 - pages/ko/about/governance.md | 259 ----- pages/ko/about/index.md | 121 --- pages/ko/docs/es6.md | 104 -- .../guides/anatomy-of-an-http-transaction.md | 891 ---------------- .../docs/guides/blocking-vs-non-blocking.md | 281 ----- .../docs/guides/debugging-getting-started.md | 466 --------- .../diagnostics/live-debugging/index.md | 25 - .../live-debugging/using-inspector.md | 12 - .../docs/guides/diagnostics/memory/index.md | 52 - pages/ko/docs/guides/domain-postmortem.md | 879 ---------------- .../docs/guides/dont-block-the-event-loop.md | 515 ---------- .../guides/event-loop-timers-and-nexttick.md | 963 ------------------ pages/ko/docs/guides/getting-started-guide.md | 35 - pages/ko/docs/guides/index.md | 31 - pages/ko/docs/guides/nodejs-docker-webapp.md | 558 ---------- pages/ko/docs/guides/simple-profiling.md | 560 ---------- pages/ko/docs/guides/timers-in-node.md | 376 ------- .../working-with-different-filesystems.md | 424 -------- pages/ko/docs/index.mdx | 42 - pages/ko/download/current.md | 34 - pages/ko/download/index.md | 34 - pages/ko/download/package-manager.md | 586 ----------- pages/ko/download/releases.md | 18 - pages/ko/get-involved/contribute.md | 47 - pages/ko/get-involved/index.md | 25 - pages/ko/index.md | 18 - pages/nl/404.md | 9 - pages/nl/about/governance.md | 32 - pages/nl/about/index.md | 45 - pages/nl/docs/index.mdx | 38 - pages/nl/download/current.md | 34 - pages/nl/download/index.md | 34 - pages/nl/download/package-manager.md | 395 ------- pages/nl/download/releases.md | 11 - pages/nl/index.md | 18 - pages/pt-br/404.md | 9 - pages/pt-br/about/governance.md | 31 - pages/pt-br/about/index.md | 45 - pages/pt-br/docs/es6.md | 40 - pages/pt-br/docs/guides/abi-stability.md | 204 ---- .../docs/guides/blocking-vs-non-blocking.md | 218 ---- .../docs/guides/debugging-getting-started.md | 330 ------ .../docs/guides/diagnostics-flamegraph.md | 187 ---- .../docs/guides/dont-block-the-event-loop.md | 517 ---------- pages/pt-br/docs/index.mdx | 38 - pages/pt-br/download/current.md | 34 - pages/pt-br/download/index.md | 34 - pages/pt-br/download/package-manager.md | 285 ------ pages/pt-br/download/releases.md | 11 - pages/pt-br/get-involved/collab-summit.md | 18 - pages/pt-br/get-involved/contribute.md | 67 -- pages/pt-br/get-involved/index.md | 30 - pages/pt-br/index.md | 18 - pages/ro/404.md | 9 - pages/ro/about/governance.md | 24 - pages/ro/about/index.md | 38 - pages/ro/docs/index.mdx | 38 - pages/ro/download/current.md | 34 - pages/ro/download/index.md | 34 - pages/ro/download/package-manager.md | 293 ------ pages/ro/download/releases.md | 11 - pages/ro/get-involved/collab-summit.md | 18 - pages/ro/get-involved/contribute.md | 47 - pages/ro/get-involved/index.md | 30 - pages/ro/index.md | 18 - pages/ru/404.md | 9 - pages/ru/about/governance.md | 24 - pages/ru/about/index.md | 43 - pages/ru/docs/es6.md | 59 -- .../docs/guides/blocking-vs-non-blocking.md | 104 -- .../docs/guides/debugging-getting-started.md | 249 ----- .../ru/docs/guides/diagnostics-flamegraph.md | 121 --- pages/ru/docs/guides/getting-started-guide.md | 28 - pages/ru/docs/guides/index.md | 31 - pages/ru/docs/guides/nodejs-docker-webapp.md | 279 ----- pages/ru/docs/guides/simple-profiling.md | 288 ------ pages/ru/docs/guides/timers-in-node.md | 176 ---- pages/ru/docs/index.mdx | 43 - pages/ru/download/current.md | 34 - pages/ru/download/index.md | 34 - pages/ru/download/package-manager.md | 287 ------ pages/ru/download/releases.md | 11 - pages/ru/get-involved/collab-summit.md | 18 - pages/ru/get-involved/contribute.md | 47 - pages/ru/get-involved/index.md | 33 - pages/ru/index.md | 18 - pages/tr/404.md | 9 - pages/tr/about/governance.md | 32 - pages/tr/about/index.md | 45 - pages/tr/docs/es6.md | 40 - pages/tr/docs/guides/diagnostics/index.md | 18 - .../diagnostics/live-debugging/index.md | 25 - .../live-debugging/using-inspector.md | 12 - .../docs/guides/diagnostics/memory/index.md | 52 - pages/tr/docs/guides/getting-started-guide.md | 29 - pages/tr/docs/index.mdx | 38 - pages/tr/download/current.md | 34 - pages/tr/download/index.md | 34 - pages/tr/get-involved/collab-summit.md | 18 - pages/tr/get-involved/contribute.md | 47 - pages/tr/get-involved/index.md | 25 - pages/tr/index.md | 18 - pages/uk/404.md | 9 - pages/uk/about/governance.md | 24 - pages/uk/about/index.md | 45 - pages/uk/docs/es6.md | 40 - .../diagnostics/live-debugging/index.md | 25 - .../live-debugging/using-inspector.md | 12 - pages/uk/docs/index.mdx | 43 - pages/uk/download/current.md | 34 - pages/uk/download/index.md | 34 - pages/uk/download/releases.md | 11 - pages/uk/get-involved/collab-summit.md | 18 - pages/uk/get-involved/contribute.md | 47 - pages/uk/get-involved/index.md | 29 - pages/uk/index.md | 18 - pages/zh-cn/404.md | 9 - pages/zh-cn/about/governance.md | 31 - pages/zh-cn/about/index.md | 45 - pages/zh-cn/docs/es6.md | 40 - pages/zh-cn/docs/guides/abi-stability.md | 41 - .../guides/anatomy-of-an-http-transaction.md | 365 ------- .../docs/guides/backpressuring-in-streams.md | 513 ---------- .../docs/guides/blocking-vs-non-blocking.md | 102 -- .../guides/buffer-constructor-deprecation.md | 214 ---- .../docs/guides/debugging-getting-started.md | 187 ---- .../docs/guides/diagnostics-flamegraph.md | 123 --- pages/zh-cn/docs/guides/diagnostics/index.md | 18 - .../diagnostics/live-debugging/index.md | 25 - .../live-debugging/using-inspector.md | 12 - .../docs/guides/diagnostics/memory/index.md | 52 - .../diagnostics/memory/using-gc-traces.md | 352 ------- .../diagnostics/memory/using-heap-profiler.md | 96 -- .../diagnostics/memory/using-heap-snapshot.md | 137 --- .../diagnostics/poor-performance/index.md | 30 - .../poor-performance/using-linux-perf.md | 76 -- pages/zh-cn/docs/guides/domain-postmortem.md | 368 ------- .../docs/guides/dont-block-the-event-loop.md | 414 -------- .../guides/event-loop-timers-and-nexttick.md | 343 ------- .../docs/guides/getting-started-guide.md | 29 - pages/zh-cn/docs/guides/index.md | 34 - .../zh-cn/docs/guides/nodejs-docker-webapp.md | 250 ----- .../docs/guides/publishing-napi-modules.md | 39 - pages/zh-cn/docs/guides/security/index.md | 322 ------ pages/zh-cn/docs/guides/simple-profiling.md | 230 ----- pages/zh-cn/docs/guides/timers-in-node.md | 125 --- .../working-with-different-filesystems.md | 90 -- pages/zh-cn/docs/index.mdx | 43 - pages/zh-cn/download/current.md | 34 - pages/zh-cn/download/index.md | 34 - pages/zh-cn/download/package-manager.md | 396 ------- pages/zh-cn/download/releases.md | 11 - pages/zh-cn/get-involved/collab-summit.md | 18 - pages/zh-cn/get-involved/contribute.md | 47 - pages/zh-cn/get-involved/index.md | 25 - pages/zh-cn/index.md | 18 - pages/zh-tw/404.md | 9 - pages/zh-tw/about/governance.md | 32 - pages/zh-tw/about/index.md | 43 - pages/zh-tw/docs/index.mdx | 38 - pages/zh-tw/download/current.md | 34 - pages/zh-tw/download/index.md | 34 - pages/zh-tw/download/package-manager.md | 297 ------ pages/zh-tw/download/releases.md | 11 - pages/zh-tw/get-involved/collab-summit.md | 18 - pages/zh-tw/get-involved/contribute.md | 47 - pages/zh-tw/get-involved/index.md | 25 - pages/zh-tw/index.md | 18 - redirects.json | 16 +- styles/old/base.css | 4 + styles/old/page-modules/anchorLinks.css | 1 + styles/old/page-modules/header.css | 1 - types/navigation.ts | 2 - 358 files changed, 1063 insertions(+), 33779 deletions(-) delete mode 100644 i18n/locales/ca.json delete mode 100644 i18n/locales/fa.json delete mode 100644 i18n/locales/gl.json delete mode 100644 i18n/locales/nl.json delete mode 100644 i18n/locales/ro.json delete mode 100644 pages/ar/404.md delete mode 100644 pages/ar/about/governance.md delete mode 100644 pages/ar/about/index.md delete mode 100644 pages/ar/docs/es6.md delete mode 100644 pages/ar/docs/guides/abi-stability.md delete mode 100644 pages/ar/docs/guides/anatomy-of-an-http-transaction.md delete mode 100644 pages/ar/docs/guides/debugging-getting-started.md delete mode 100644 pages/ar/docs/guides/getting-started-guide.md delete mode 100644 pages/ar/docs/guides/index.md delete mode 100644 pages/ar/docs/guides/publishing-napi-modules.md delete mode 100644 pages/ar/docs/index.mdx delete mode 100644 pages/ar/download/current.md delete mode 100644 pages/ar/download/index.md delete mode 100644 pages/ar/download/package-manager.md delete mode 100644 pages/ar/download/releases.md delete mode 100644 pages/ar/get-involved/collab-summit.md delete mode 100644 pages/ar/get-involved/contribute.md delete mode 100644 pages/ar/get-involved/index.md delete mode 100644 pages/ar/index.md delete mode 100644 pages/be/404.md delete mode 100644 pages/be/about/governance.md delete mode 100644 pages/be/about/index.md delete mode 100644 pages/be/docs/guides/diagnostics/live-debugging/index.md delete mode 100644 pages/be/docs/guides/event-loop-timers-and-nexttick.md delete mode 100644 pages/be/download/current.md delete mode 100644 pages/be/download/index.md delete mode 100644 pages/be/download/releases.md delete mode 100644 pages/be/index.md delete mode 100644 pages/ca/404.md delete mode 100644 pages/ca/about/index.md delete mode 100644 pages/ca/docs/index.mdx delete mode 100644 pages/ca/download/current.md delete mode 100644 pages/ca/download/index.md delete mode 100644 pages/ca/get-involved/index.md delete mode 100644 pages/ca/index.md delete mode 100644 pages/de/404.md delete mode 100644 pages/de/about/governance.md delete mode 100644 pages/de/about/index.md delete mode 100644 pages/de/docs/index.mdx delete mode 100644 pages/de/download/current.md delete mode 100644 pages/de/download/index.md delete mode 100644 pages/de/index.md create mode 100644 pages/en/about/previous-releases.md create mode 100644 pages/en/about/security-reporting.md delete mode 100644 pages/en/download/releases.md delete mode 100644 pages/es/404.md delete mode 100644 pages/es/about/governance.md delete mode 100644 pages/es/about/index.md delete mode 100644 pages/es/docs/es6.md delete mode 100644 pages/es/docs/index.mdx delete mode 100644 pages/es/download/current.md delete mode 100644 pages/es/download/index.md delete mode 100644 pages/es/download/package-manager.md delete mode 100644 pages/es/download/releases.md delete mode 100644 pages/es/get-involved/collab-summit.md delete mode 100644 pages/es/get-involved/contribute.md delete mode 100644 pages/es/get-involved/index.md delete mode 100644 pages/es/index.md delete mode 100644 pages/fa/404.md delete mode 100644 pages/fa/about/index.md delete mode 100644 pages/fa/index.md delete mode 100644 pages/fr/404.md delete mode 100644 pages/fr/about/governance.md delete mode 100644 pages/fr/about/index.md delete mode 100644 pages/fr/docs/es6.md delete mode 100644 pages/fr/docs/guides/abi-stability.md delete mode 100644 pages/fr/docs/index.mdx delete mode 100644 pages/fr/download/current.md delete mode 100644 pages/fr/download/index.md delete mode 100644 pages/fr/download/package-manager.md delete mode 100644 pages/fr/download/releases.md delete mode 100644 pages/fr/get-involved/collab-summit.md delete mode 100644 pages/fr/get-involved/contribute.md delete mode 100644 pages/fr/get-involved/index.md delete mode 100644 pages/fr/index.md delete mode 100644 pages/gl/404.md delete mode 100644 pages/gl/index.md delete mode 100644 pages/id/404.md delete mode 100644 pages/id/about/governance.md delete mode 100644 pages/id/about/index.md delete mode 100644 pages/id/docs/es6.md delete mode 100644 pages/id/docs/guides/abi-stability.md delete mode 100644 pages/id/docs/guides/anatomy-of-an-http-transaction.md delete mode 100644 pages/id/docs/guides/backpressuring-in-streams.md delete mode 100644 pages/id/docs/guides/blocking-vs-non-blocking.md delete mode 100644 pages/id/docs/guides/buffer-constructor-deprecation.md delete mode 100644 pages/id/docs/guides/debugging-getting-started.md delete mode 100644 pages/id/docs/guides/diagnostics-flamegraph.md delete mode 100644 pages/id/docs/guides/diagnostics/index.md delete mode 100644 pages/id/docs/guides/diagnostics/live-debugging/index.md delete mode 100644 pages/id/docs/guides/diagnostics/live-debugging/using-inspector.md delete mode 100644 pages/id/docs/guides/diagnostics/memory/index.md delete mode 100644 pages/id/docs/guides/diagnostics/memory/using-gc-traces.md delete mode 100644 pages/id/docs/guides/diagnostics/memory/using-heap-profiler.md delete mode 100644 pages/id/docs/guides/diagnostics/memory/using-heap-snapshot.md delete mode 100644 pages/id/docs/guides/diagnostics/poor-performance/index.md delete mode 100644 pages/id/docs/guides/diagnostics/poor-performance/using-linux-perf.md delete mode 100644 pages/id/docs/guides/domain-postmortem.md delete mode 100644 pages/id/docs/guides/dont-block-the-event-loop.md delete mode 100644 pages/id/docs/guides/event-loop-timers-and-nexttick.md delete mode 100644 pages/id/docs/guides/getting-started-guide.md delete mode 100644 pages/id/docs/guides/index.md delete mode 100644 pages/id/docs/guides/nodejs-docker-webapp.md delete mode 100644 pages/id/docs/guides/publishing-napi-modules.md delete mode 100644 pages/id/docs/guides/security/index.md delete mode 100644 pages/id/docs/guides/simple-profiling.md delete mode 100644 pages/id/docs/guides/timers-in-node.md delete mode 100644 pages/id/docs/guides/working-with-different-filesystems.md delete mode 100644 pages/id/docs/index.mdx delete mode 100644 pages/id/download/current.md delete mode 100644 pages/id/download/index.md delete mode 100644 pages/id/download/package-manager.md delete mode 100644 pages/id/download/releases.md delete mode 100644 pages/id/get-involved/collab-summit.md delete mode 100644 pages/id/get-involved/contribute.md delete mode 100644 pages/id/get-involved/index.md delete mode 100644 pages/id/index.md delete mode 100644 pages/it/404.md delete mode 100644 pages/it/about/index.md delete mode 100644 pages/it/get-involved/collab-summit.md delete mode 100644 pages/it/get-involved/index.md delete mode 100644 pages/it/index.md delete mode 100644 pages/ja/404.md delete mode 100644 pages/ja/about/index.md delete mode 100644 pages/ja/docs/es6.md delete mode 100644 pages/ja/docs/guides/blocking-vs-non-blocking.md delete mode 100644 pages/ja/docs/guides/buffer-constructor-deprecation.md delete mode 100644 pages/ja/docs/guides/debugging-getting-started.md delete mode 100644 pages/ja/docs/guides/diagnostics-flamegraph.md delete mode 100644 pages/ja/docs/guides/getting-started-guide.md delete mode 100644 pages/ja/docs/guides/index.md delete mode 100644 pages/ja/docs/guides/nodejs-docker-webapp.md delete mode 100644 pages/ja/docs/guides/simple-profiling.md delete mode 100644 pages/ja/docs/guides/timers-in-node.md delete mode 100644 pages/ja/docs/index.mdx delete mode 100644 pages/ja/download/current.md delete mode 100644 pages/ja/download/index.md delete mode 100644 pages/ja/download/package-manager.md delete mode 100644 pages/ja/download/releases.md delete mode 100644 pages/ja/get-involved/collab-summit.md delete mode 100644 pages/ja/get-involved/contribute.md delete mode 100644 pages/ja/get-involved/index.md delete mode 100644 pages/ja/index.md delete mode 100644 pages/ka/404.md delete mode 100644 pages/ka/about/governance.md delete mode 100644 pages/ka/about/index.md delete mode 100644 pages/ka/docs/es6.md delete mode 100644 pages/ka/docs/guides/debugging-getting-started.md delete mode 100644 pages/ka/docs/guides/getting-started-guide.md delete mode 100644 pages/ka/docs/guides/index.md delete mode 100644 pages/ka/docs/index.mdx delete mode 100644 pages/ka/download/index.md delete mode 100644 pages/ka/get-involved/index.md delete mode 100644 pages/ka/index.md delete mode 100644 pages/ko/404.md delete mode 100644 pages/ko/about/governance.md delete mode 100644 pages/ko/about/index.md delete mode 100644 pages/ko/docs/es6.md delete mode 100644 pages/ko/docs/guides/anatomy-of-an-http-transaction.md delete mode 100644 pages/ko/docs/guides/blocking-vs-non-blocking.md delete mode 100644 pages/ko/docs/guides/debugging-getting-started.md delete mode 100644 pages/ko/docs/guides/diagnostics/live-debugging/index.md delete mode 100644 pages/ko/docs/guides/diagnostics/live-debugging/using-inspector.md delete mode 100644 pages/ko/docs/guides/diagnostics/memory/index.md delete mode 100644 pages/ko/docs/guides/domain-postmortem.md delete mode 100644 pages/ko/docs/guides/dont-block-the-event-loop.md delete mode 100644 pages/ko/docs/guides/event-loop-timers-and-nexttick.md delete mode 100644 pages/ko/docs/guides/getting-started-guide.md delete mode 100644 pages/ko/docs/guides/index.md delete mode 100644 pages/ko/docs/guides/nodejs-docker-webapp.md delete mode 100644 pages/ko/docs/guides/simple-profiling.md delete mode 100644 pages/ko/docs/guides/timers-in-node.md delete mode 100644 pages/ko/docs/guides/working-with-different-filesystems.md delete mode 100644 pages/ko/docs/index.mdx delete mode 100644 pages/ko/download/current.md delete mode 100644 pages/ko/download/index.md delete mode 100644 pages/ko/download/package-manager.md delete mode 100644 pages/ko/download/releases.md delete mode 100644 pages/ko/get-involved/contribute.md delete mode 100644 pages/ko/get-involved/index.md delete mode 100644 pages/ko/index.md delete mode 100644 pages/nl/404.md delete mode 100644 pages/nl/about/governance.md delete mode 100644 pages/nl/about/index.md delete mode 100644 pages/nl/docs/index.mdx delete mode 100644 pages/nl/download/current.md delete mode 100644 pages/nl/download/index.md delete mode 100644 pages/nl/download/package-manager.md delete mode 100644 pages/nl/download/releases.md delete mode 100644 pages/nl/index.md delete mode 100644 pages/pt-br/404.md delete mode 100644 pages/pt-br/about/governance.md delete mode 100644 pages/pt-br/about/index.md delete mode 100644 pages/pt-br/docs/es6.md delete mode 100755 pages/pt-br/docs/guides/abi-stability.md delete mode 100755 pages/pt-br/docs/guides/blocking-vs-non-blocking.md delete mode 100755 pages/pt-br/docs/guides/debugging-getting-started.md delete mode 100755 pages/pt-br/docs/guides/diagnostics-flamegraph.md delete mode 100644 pages/pt-br/docs/guides/dont-block-the-event-loop.md delete mode 100644 pages/pt-br/docs/index.mdx delete mode 100644 pages/pt-br/download/current.md delete mode 100644 pages/pt-br/download/index.md delete mode 100644 pages/pt-br/download/package-manager.md delete mode 100644 pages/pt-br/download/releases.md delete mode 100644 pages/pt-br/get-involved/collab-summit.md delete mode 100644 pages/pt-br/get-involved/contribute.md delete mode 100644 pages/pt-br/get-involved/index.md delete mode 100644 pages/pt-br/index.md delete mode 100644 pages/ro/404.md delete mode 100644 pages/ro/about/governance.md delete mode 100644 pages/ro/about/index.md delete mode 100644 pages/ro/docs/index.mdx delete mode 100644 pages/ro/download/current.md delete mode 100644 pages/ro/download/index.md delete mode 100644 pages/ro/download/package-manager.md delete mode 100644 pages/ro/download/releases.md delete mode 100644 pages/ro/get-involved/collab-summit.md delete mode 100644 pages/ro/get-involved/contribute.md delete mode 100644 pages/ro/get-involved/index.md delete mode 100644 pages/ro/index.md delete mode 100644 pages/ru/404.md delete mode 100644 pages/ru/about/governance.md delete mode 100644 pages/ru/about/index.md delete mode 100644 pages/ru/docs/es6.md delete mode 100644 pages/ru/docs/guides/blocking-vs-non-blocking.md delete mode 100644 pages/ru/docs/guides/debugging-getting-started.md delete mode 100644 pages/ru/docs/guides/diagnostics-flamegraph.md delete mode 100644 pages/ru/docs/guides/getting-started-guide.md delete mode 100644 pages/ru/docs/guides/index.md delete mode 100644 pages/ru/docs/guides/nodejs-docker-webapp.md delete mode 100644 pages/ru/docs/guides/simple-profiling.md delete mode 100644 pages/ru/docs/guides/timers-in-node.md delete mode 100644 pages/ru/docs/index.mdx delete mode 100644 pages/ru/download/current.md delete mode 100644 pages/ru/download/index.md delete mode 100644 pages/ru/download/package-manager.md delete mode 100644 pages/ru/download/releases.md delete mode 100644 pages/ru/get-involved/collab-summit.md delete mode 100644 pages/ru/get-involved/contribute.md delete mode 100644 pages/ru/get-involved/index.md delete mode 100644 pages/ru/index.md delete mode 100644 pages/tr/404.md delete mode 100644 pages/tr/about/governance.md delete mode 100644 pages/tr/about/index.md delete mode 100644 pages/tr/docs/es6.md delete mode 100644 pages/tr/docs/guides/diagnostics/index.md delete mode 100644 pages/tr/docs/guides/diagnostics/live-debugging/index.md delete mode 100644 pages/tr/docs/guides/diagnostics/live-debugging/using-inspector.md delete mode 100644 pages/tr/docs/guides/diagnostics/memory/index.md delete mode 100644 pages/tr/docs/guides/getting-started-guide.md delete mode 100644 pages/tr/docs/index.mdx delete mode 100644 pages/tr/download/current.md delete mode 100644 pages/tr/download/index.md delete mode 100644 pages/tr/get-involved/collab-summit.md delete mode 100644 pages/tr/get-involved/contribute.md delete mode 100644 pages/tr/get-involved/index.md delete mode 100644 pages/tr/index.md delete mode 100644 pages/uk/404.md delete mode 100644 pages/uk/about/governance.md delete mode 100644 pages/uk/about/index.md delete mode 100644 pages/uk/docs/es6.md delete mode 100644 pages/uk/docs/guides/diagnostics/live-debugging/index.md delete mode 100644 pages/uk/docs/guides/diagnostics/live-debugging/using-inspector.md delete mode 100644 pages/uk/docs/index.mdx delete mode 100644 pages/uk/download/current.md delete mode 100644 pages/uk/download/index.md delete mode 100644 pages/uk/download/releases.md delete mode 100644 pages/uk/get-involved/collab-summit.md delete mode 100644 pages/uk/get-involved/contribute.md delete mode 100644 pages/uk/get-involved/index.md delete mode 100644 pages/uk/index.md delete mode 100644 pages/zh-cn/404.md delete mode 100644 pages/zh-cn/about/governance.md delete mode 100644 pages/zh-cn/about/index.md delete mode 100644 pages/zh-cn/docs/es6.md delete mode 100644 pages/zh-cn/docs/guides/abi-stability.md delete mode 100644 pages/zh-cn/docs/guides/anatomy-of-an-http-transaction.md delete mode 100644 pages/zh-cn/docs/guides/backpressuring-in-streams.md delete mode 100644 pages/zh-cn/docs/guides/blocking-vs-non-blocking.md delete mode 100644 pages/zh-cn/docs/guides/buffer-constructor-deprecation.md delete mode 100644 pages/zh-cn/docs/guides/debugging-getting-started.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics-flamegraph.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/index.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/live-debugging/index.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/live-debugging/using-inspector.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/memory/index.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/memory/using-gc-traces.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/memory/using-heap-profiler.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/memory/using-heap-snapshot.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/poor-performance/index.md delete mode 100644 pages/zh-cn/docs/guides/diagnostics/poor-performance/using-linux-perf.md delete mode 100644 pages/zh-cn/docs/guides/domain-postmortem.md delete mode 100644 pages/zh-cn/docs/guides/dont-block-the-event-loop.md delete mode 100644 pages/zh-cn/docs/guides/event-loop-timers-and-nexttick.md delete mode 100644 pages/zh-cn/docs/guides/getting-started-guide.md delete mode 100644 pages/zh-cn/docs/guides/index.md delete mode 100644 pages/zh-cn/docs/guides/nodejs-docker-webapp.md delete mode 100644 pages/zh-cn/docs/guides/publishing-napi-modules.md delete mode 100644 pages/zh-cn/docs/guides/security/index.md delete mode 100644 pages/zh-cn/docs/guides/simple-profiling.md delete mode 100644 pages/zh-cn/docs/guides/timers-in-node.md delete mode 100644 pages/zh-cn/docs/guides/working-with-different-filesystems.md delete mode 100644 pages/zh-cn/docs/index.mdx delete mode 100644 pages/zh-cn/download/current.md delete mode 100644 pages/zh-cn/download/index.md delete mode 100644 pages/zh-cn/download/package-manager.md delete mode 100644 pages/zh-cn/download/releases.md delete mode 100644 pages/zh-cn/get-involved/collab-summit.md delete mode 100644 pages/zh-cn/get-involved/contribute.md delete mode 100644 pages/zh-cn/get-involved/index.md delete mode 100644 pages/zh-cn/index.md delete mode 100644 pages/zh-tw/404.md delete mode 100644 pages/zh-tw/about/governance.md delete mode 100644 pages/zh-tw/about/index.md delete mode 100644 pages/zh-tw/docs/index.mdx delete mode 100644 pages/zh-tw/download/current.md delete mode 100644 pages/zh-tw/download/index.md delete mode 100644 pages/zh-tw/download/package-manager.md delete mode 100644 pages/zh-tw/download/releases.md delete mode 100644 pages/zh-tw/get-involved/collab-summit.md delete mode 100644 pages/zh-tw/get-involved/contribute.md delete mode 100644 pages/zh-tw/get-involved/index.md delete mode 100644 pages/zh-tw/index.md diff --git a/components/Footer.tsx b/components/Footer.tsx index f3b501488ad01..ad234112e7777 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -1,6 +1,8 @@ import type { FC } from 'react'; import { FormattedMessage } from 'react-intl'; +import LocalizedLink from './LocalizedLink'; + type FooterProps = { className?: string }; // Note.: We don't expect to translate these items as we're going to replace with `nodejs/nodejs.dev` footer @@ -33,18 +35,15 @@ const Footer: FC = ({ className }) => (

The OpenJS Foundation  |  - Terms of Use + Trademark Policy  |  Privacy Policy  |  - Bylaws |  Code of Conduct  |  - Trademark Policy -  |  - Trademark List -  |  - Cookie Policy + + Security Reporting +

diff --git a/crowdin.yml b/crowdin.yml index 7dcd9f2a6d346..f434861ccf39e 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -8,28 +8,30 @@ files: content_segmentation: 0 ignore: - /pages/en/blog/**/*.md + - /pages/en/docs/**/*.md languages_mapping: two_letters_code: + es-ES: es pt-BR: pt-br zh-CN: zh-cn zh-TW: zh-tw - es-ES: es - source: /pages/en/**/*.mdx translation: /pages/%two_letters_code%/**/%original_file_name% content_segmentation: 0 ignore: - /pages/en/blog/**/*.mdx + - /pages/en/docs/**/*.mdx languages_mapping: two_letters_code: + es-ES: es pt-BR: pt-br zh-CN: zh-cn zh-TW: zh-tw - es-ES: es - source: /i18n/locales/en.json translation: /i18n/locales/%two_letters_code%.json languages_mapping: two_letters_code: + es-ES: es pt-BR: pt-br zh-CN: zh-cn zh-TW: zh-tw - es-ES: es diff --git a/i18n/config.json b/i18n/config.json index 1b682d7654944..af4c41c6df998 100644 --- a/i18n/config.json +++ b/i18n/config.json @@ -6,16 +6,8 @@ "langDir": "rtl", "dateFormat": "YYYY.MM.DD", "hrefLang": "ar", - "enabled": true - }, - { - "code": "ca", - "localName": "Catalan", - "name": "Catalan", - "langDir": "ltr", - "dateFormat": "DD.MM.YYYY", - "hrefLang": "ca", - "enabled": true + "enabled": false, + "default": false }, { "code": "de", @@ -24,7 +16,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "de", - "enabled": true + "enabled": false, + "default": false }, { "code": "en", @@ -43,16 +36,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "es-ES", - "enabled": true - }, - { - "code": "fa", - "localName": "زبان فارسی", - "name": "Persian", - "langDir": "rtl", - "dateFormat": "YYYY.MM.DD", - "hrefLang": "fa", - "enabled": true + "enabled": false, + "default": false }, { "code": "fr", @@ -61,7 +46,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "fr", - "enabled": true + "enabled": false, + "default": false }, { "code": "id", @@ -70,7 +56,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "id", - "enabled": true + "enabled": false, + "default": false }, { "code": "it", @@ -79,7 +66,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "it", - "enabled": true + "enabled": false, + "default": false }, { "code": "ja", @@ -88,7 +76,8 @@ "langDir": "ltr", "dateFormat": "YYYY.MM.DD", "hrefLang": "ja", - "enabled": true + "enabled": false, + "default": false }, { "code": "ka", @@ -97,7 +86,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "ka", - "enabled": true + "enabled": false, + "default": false }, { "code": "ko", @@ -106,7 +96,8 @@ "langDir": "ltr", "dateFormat": "YYYY.MM.DD", "hrefLang": "ko", - "enabled": true + "enabled": false, + "default": false }, { "code": "pt-br", @@ -115,16 +106,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "", - "enabled": true - }, - { - "code": "ro", - "localName": "limba română", - "name": "Romanian", - "langDir": "ltr", - "dateFormat": "DD.MM.YYYY", - "hrefLang": "ro", - "enabled": true + "enabled": false, + "default": false }, { "code": "ru", @@ -133,7 +116,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "ru", - "enabled": true + "enabled": false, + "default": false }, { "code": "tr", @@ -142,7 +126,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "tr", - "enabled": true + "enabled": false, + "default": false }, { "code": "uk", @@ -151,7 +136,8 @@ "langDir": "ltr", "dateFormat": "DD.MM.YYYY", "hrefLang": "uk", - "enabled": true + "enabled": false, + "default": false }, { "code": "zh-cn", @@ -160,7 +146,8 @@ "langDir": "ltr", "dateFormat": "YYYY/MM/DD", "hrefLang": "zh-Hans", - "enabled": true + "enabled": false, + "default": false }, { "code": "zh-tw", @@ -169,6 +156,7 @@ "langDir": "ltr", "dateFormat": "YYYY/MM/DD", "hrefLang": "zh-Hant", - "enabled": true + "enabled": false, + "default": false } ] diff --git a/i18n/locales/ar.json b/i18n/locales/ar.json index 6c019f198cab0..61cac039e0aaf 100644 --- a/i18n/locales/ar.json +++ b/i18n/locales/ar.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "إنتقل إلى الأعلى", - "components.header.links.home": "الرئيسية", - "components.header.links.about": "عن الموقع", - "components.header.links.download": "تنزيلات", - "components.header.links.docs": "التوثيق", - "components.header.links.getInvolved": "إنضم إلينا", - "components.header.links.security": "أمن", - "components.header.links.certification": "شهادة", - "components.header.links.blog": "المدونة", - "components.navigation.about.links.governance": "الحوكمة", - "components.navigation.docs.links.es6": "ES6 وما بعدها", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "إرشادات", - "components.navigation.docs.links.dependencies": "تبعيات", - "components.navigation.getInvolved.links.collabSummit": "القمة التعاونية", - "components.navigation.getInvolved.links.contribute": "مساهمة", - "components.navigation.getInvolved.links.codeOfConduct": "القواعد السلوكية", - "components.downloadList.links.previousReleases": "الاصدارات السابقة", - "components.downloadList.links.packageManager": "تحميل Node.js عن طريق نظام إدارة الحزم الافتراضي", - "components.downloadList.links.shaSums": "وثائق الاصدارات مختومة SHASUMS", - "components.downloadList.links.shaSums.howToVerify": " (كيفية التحقق)", - "components.downloadList.links.allDownloads": "تحميل جميع النسخ", - "components.downloadList.links.nightlyReleases": "إصدارات ليلية", - "components.downloadList.links.unofficialBuilds": "بُنْيَات غير رسمية", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "تثبيت Node.js باستعمال أرشيف ثنائي على لينكس", - "components.downloadList.links.installingOnWsl": "التثبيت على ويندوز في النظام الفرعي لينكس (WSL)", - "components.downloadReleasesTable.changelog": "سجل التغييرات", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "التوثيق", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "التالي | ", - "components.pagination.previous": "السابق", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/ca.json b/i18n/locales/ca.json deleted file mode 100644 index c1c574cedb3c3..0000000000000 --- a/i18n/locales/ca.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "components.footer.scrollToTop.button": "Torna al començament", - "components.header.links.home": "Inici", - "components.header.links.about": "Quant a", - "components.header.links.download": "Descàrregues", - "components.header.links.docs": "Documentació", - "components.header.links.getInvolved": "Participa", - "components.header.links.security": "Seguretat", - "components.header.links.certification": "Certification", - "components.header.links.blog": "Notícies", - "components.navigation.about.links.governance": "Govern", - "components.navigation.docs.links.es6": "ES6 i més enllà", - "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", - "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Guies", - "components.navigation.docs.links.dependencies": "Dependències", - "components.navigation.getInvolved.links.collabSummit": "Col·labora en el Summit", - "components.navigation.getInvolved.links.contribute": "Contribueix", - "components.navigation.getInvolved.links.codeOfConduct": "Codi de Conducta", - "components.downloadList.links.previousReleases": "Descarrègues", - "components.downloadList.links.packageManager": "Instal·lar Node.js mitjançant un gestor de paquets", - "components.downloadList.links.shaSums": "Signatures SHASUMS per arxius de versions", - "components.downloadList.links.shaSums.howToVerify": " (Com verificar-ho)", - "components.downloadList.links.allDownloads": "Totes les opcions de descàrrega", - "components.downloadList.links.nightlyReleases": "Versions Nightly", - "components.downloadList.links.unofficialBuilds": "Unofficial builds", - "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", - "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Registre de Canvis", - "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Documentació", - "components.header.buttons.toggleLanguage": "Toggle Language", - "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Següent | ", - "components.pagination.previous": "Anterior", - "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" -} diff --git a/i18n/locales/de.json b/i18n/locales/de.json index 8694496e07c5f..61cac039e0aaf 100644 --- a/i18n/locales/de.json +++ b/i18n/locales/de.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "Zum Seitenanfang", - "components.header.links.home": "Startseite", - "components.header.links.about": "Über Node.js", - "components.header.links.download": "Herunterladen", - "components.header.links.docs": "Dokumentation", - "components.header.links.getInvolved": "Mitmachen", - "components.header.links.security": "Sicherheit", - "components.header.links.certification": "Zertifizierung", - "components.header.links.blog": "Neuigkeiten", - "components.navigation.about.links.governance": "Governance", - "components.navigation.docs.links.es6": "ES6 und darüber hinaus", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Anleitungen", - "components.navigation.docs.links.dependencies": "Abhängigkeiten", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", "components.navigation.getInvolved.links.collabSummit": "Collab Summit", - "components.navigation.getInvolved.links.contribute": "Mitwirken", - "components.navigation.getInvolved.links.codeOfConduct": "Verhaltenskodex", - "components.downloadList.links.previousReleases": "Alle Versionen", - "components.downloadList.links.packageManager": "Node.js mit Paketmanagern installieren", - "components.downloadList.links.shaSums": "Signierte SHASUMS für die Versionsdateien", - "components.downloadList.links.shaSums.howToVerify": " (wie Überprüfen?)", - "components.downloadList.links.allDownloads": "Alle Download-Optionen", - "components.downloadList.links.nightlyReleases": "Nightly Builds", - "components.downloadList.links.unofficialBuilds": "Inoffizielle Builds", - "components.downloadList.links.buildingFromSource": "Erstellen von Node.js aus dem Quellcode auf unterstützten Plattformen", - "components.downloadList.links.installingOnLinux": "Installieren von Node.js über ein Binärarchiv", - "components.downloadList.links.installingOnWsl": "Auf Windows-Subsystem für Linux (WSL) installieren", - "components.downloadReleasesTable.changelog": "Änderungsprotokoll", - "components.downloadReleasesTable.releases": "Veröffentlichungen", - "components.downloadReleasesTable.docs": "Dokumentation", - "components.header.buttons.toggleLanguage": "Sprache umschalten", - "components.header.buttons.toggleDarkMode": "Dunkel-/Hell Modus umschalten", - "components.pagination.next": "Neuere | ", - "components.pagination.previous": "Ältere", - "layouts.blogPost.author.byLine": "{author, select, null {} other {Von {author}, }}", - "layouts.blogIndex.currentYear": "Neuigkeiten von {year}" + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", + "components.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/en.json b/i18n/locales/en.json index e47aba26f1252..61cac039e0aaf 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -1,8 +1,7 @@ { "components.footer.scrollToTop.button": "Scroll to top", - "components.header.links.home": "Home", - "components.header.links.about": "About", - "components.header.links.download": "Downloads", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", "components.header.links.docs": "Docs", "components.header.links.getInvolved": "Get Involved", "components.header.links.security": "Security", @@ -11,9 +10,11 @@ "components.footer.links.trademarkPolicy": "Trademark Policy", "components.footer.links.privacyPolicy": "Privacy Policy", "components.footer.links.codeOfConduct": "Code of Conduct", - "components.footer.links.security": "Security", + "components.footer.links.security": "Security Policy", "components.footer.links.openJS": "OpenJS Foundation", - "components.navigation.about.links.governance": "Governance", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", @@ -22,7 +23,6 @@ "components.navigation.getInvolved.links.collabSummit": "Collab Summit", "components.navigation.getInvolved.links.contribute": "Contribute", "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", - "components.downloadList.links.previousReleases": "Previous Releases", "components.downloadList.links.packageManager": "Installing Node.js via package manager", "components.downloadList.links.shaSums": "Signed SHASUMS for release files", "components.downloadList.links.shaSums.howToVerify": " (How to verify)", diff --git a/i18n/locales/es.json b/i18n/locales/es.json index 261a095549676..61cac039e0aaf 100644 --- a/i18n/locales/es.json +++ b/i18n/locales/es.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "Vuelve arriba", - "components.header.links.home": "Inicio", - "components.header.links.about": "Acerca", - "components.header.links.download": "Descargas", - "components.header.links.docs": "Documentación", - "components.header.links.getInvolved": "Participe", - "components.header.links.security": "Seguridad", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "Noticias", - "components.navigation.about.links.governance": "Dirección", - "components.navigation.docs.links.es6": "ES6 y más allá", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Guías", - "components.navigation.docs.links.dependencies": "Dependencias", - "components.navigation.getInvolved.links.collabSummit": "Colabore en el Summit", - "components.navigation.getInvolved.links.contribute": "Contribuya", - "components.navigation.getInvolved.links.codeOfConduct": "Código de Conducta", - "components.downloadList.links.previousReleases": "Versiones anteriores", - "components.downloadList.links.packageManager": "Instale Node.js mediante un gestor de paquetes", - "components.downloadList.links.shaSums": "Firmas SHASUMS de los archivos de versiones", - "components.downloadList.links.shaSums.howToVerify": " (Cómo verificarlo)", - "components.downloadList.links.allDownloads": "Todas las opciones de descarga", - "components.downloadList.links.nightlyReleases": "Versiones Nightly", - "components.downloadList.links.unofficialBuilds": "Construcciones no oficiales", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Instalación de Node.js a través del archivo binario", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Registro de Cambios", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Documentación", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Siguiente | ", - "components.pagination.previous": "Anterior", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/fa.json b/i18n/locales/fa.json deleted file mode 100644 index c4ea7b173e3ed..0000000000000 --- a/i18n/locales/fa.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "components.footer.scrollToTop.button": "رفتن به بالا", - "components.header.links.home": "خانه", - "components.header.links.about": "درباره", - "components.header.links.download": "دانلود‌ها", - "components.header.links.docs": "اسناد", - "components.header.links.getInvolved": "مشارکت جستن", - "components.header.links.security": "امنیت", - "components.header.links.certification": "Certification", - "components.header.links.blog": "بلاگ", - "components.navigation.about.links.governance": "مدیریت", - "components.navigation.docs.links.es6": "ES6 و فراتر", - "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", - "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "راهنمایی‌ها", - "components.navigation.docs.links.dependencies": "وابستگی‌ها", - "components.navigation.getInvolved.links.collabSummit": "نشت مشارکت کنندگان", - "components.navigation.getInvolved.links.contribute": "مشارکت", - "components.navigation.getInvolved.links.codeOfConduct": "شیوه تعامل برای مشارکت", - "components.downloadList.links.previousReleases": "انتشارهای پیشین", - "components.downloadList.links.packageManager": "نصب نودجی‌اس با package manager", - "components.downloadList.links.shaSums": "Signed SHASUMS for release files", - "components.downloadList.links.shaSums.howToVerify": " (چگونه راستی‌آزمایی کنیم؟)", - "components.downloadList.links.allDownloads": "تمام گزینه‌ها برای دانلود", - "components.downloadList.links.nightlyReleases": "ساخت‌های شبانه", - "components.downloadList.links.unofficialBuilds": "Unofficial builds", - "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", - "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "تغییرات", - "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "اسناد", - "components.header.buttons.toggleLanguage": "Toggle Language", - "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "بعدی | ", - "components.pagination.previous": "قبلی", - "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" -} diff --git a/i18n/locales/fr.json b/i18n/locales/fr.json index 564c05b0141f1..61cac039e0aaf 100644 --- a/i18n/locales/fr.json +++ b/i18n/locales/fr.json @@ -1,45 +1,68 @@ { - "components.footer.scrollToTop.button": "Faire défiler en haut", - "components.header.links.home": "Accueil", - "components.header.links.about": "À propos", - "components.header.links.download": "Téléchargements", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", "components.header.links.docs": "Docs", - "components.header.links.getInvolved": "S’impliquer", - "components.header.links.security": "Securité", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "Actualités", - "components.navigation.about.links.governance": "Gouvernance", - "components.navigation.docs.links.es6": "ES6 et au-delà", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", "components.navigation.docs.links.guides": "Guides", - "components.navigation.docs.links.dependencies": "Dépendances", - "components.navigation.getInvolved.links.collabSummit": "Sommet de collaboration", - "components.navigation.getInvolved.links.contribute": "Contribuer", - "components.navigation.getInvolved.links.codeOfConduct": "Code de conduite", - "components.downloadList.links.previousReleases": "Versions précédentes", - "components.downloadList.links.packageManager": "Installer Node.js via le gestionnaire de paquets", - "components.downloadList.links.shaSums": "SHASUMS signés pour les fichiers des versions", - "components.downloadList.links.shaSums.howToVerify": " (Comment vérifier)", - "components.downloadList.links.allDownloads": "Toutes les options de téléchargement", - "components.downloadList.links.nightlyReleases": "Versions quotidiennes", - "components.downloadList.links.unofficialBuilds": "Constructions non officielles", - "components.downloadList.links.buildingFromSource": "Compiler Node.js à partir du code source sur les systèmes d'exploitation maintenus", - "components.downloadList.links.installingOnLinux": "Installation de Node.js via une archive binaire", - "components.downloadList.links.installingOnWsl": "Installation sur le sous-système Windows pour Linux (WSL)", - "components.downloadReleasesTable.changelog": "Journal des modifications", - "components.downloadReleasesTable.releases": "Distributions", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", "components.downloadReleasesTable.docs": "Docs", - "components.header.buttons.toggleLanguage": "Changer la langue", - "components.header.buttons.toggleDarkMode": "Basculer le mode sombre/clair", - "components.pagination.next": "Plus récent ", - "components.pagination.previous": "Plus anciens", - "components.common.crossLink.previous": "Précédent", - "components.common.crossLink.next": "Suivant", - "layouts.blogPost.author.byLine": "{author, select, null {} other {Par {author}, }}", - "layouts.blogIndex.currentYear": "Actualités de {year}", - "components.api.jsonLink.title": "Afficher en JSON", - "components.api.sourceLink": "Code Source :", - "pages.404.title": "404 : Page introuvable", - "pages.404.description": "ENOENT : fichier ou répertoire introuvable" + "components.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/gl.json b/i18n/locales/gl.json deleted file mode 100644 index 90589c897c616..0000000000000 --- a/i18n/locales/gl.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "components.footer.scrollToTop.button": "Volta ao principio", - "components.header.links.home": "Inicio", - "components.header.links.about": "Acerca de", - "components.header.links.download": "Descargas", - "components.header.links.docs": "Documentación", - "components.header.links.getInvolved": "Participa", - "components.header.links.security": "Seguridade", - "components.header.links.certification": "Certification", - "components.header.links.blog": "Noticias", - "components.navigation.about.links.governance": "Goberno", - "components.navigation.docs.links.es6": "ES6 e máis aló", - "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", - "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Guías", - "components.navigation.docs.links.dependencies": "Dependencies", - "components.navigation.getInvolved.links.collabSummit": "Collab Summit", - "components.navigation.getInvolved.links.contribute": "Contribúe", - "components.navigation.getInvolved.links.codeOfConduct": "Comportamento", - "components.downloadList.links.previousReleases": "Versións anteriores", - "components.downloadList.links.packageManager": "Instalar Node.js usando un xestor de paquetes", - "components.downloadList.links.shaSums": "Firmas SHASUMS para os arquivos de versións", - "components.downloadList.links.shaSums.howToVerify": " (How to verify)", - "components.downloadList.links.allDownloads": "Todas as opcións de descarga", - "components.downloadList.links.nightlyReleases": "Versións Nightly", - "components.downloadList.links.unofficialBuilds": "Unofficial builds", - "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", - "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Cambios", - "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Documentación", - "components.header.buttons.toggleLanguage": "Toggle Language", - "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Seguinte | ", - "components.pagination.previous": "Anterior", - "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" -} diff --git a/i18n/locales/id.json b/i18n/locales/id.json index 7b1d056ed0ba3..61cac039e0aaf 100644 --- a/i18n/locales/id.json +++ b/i18n/locales/id.json @@ -1,43 +1,68 @@ { - "components.footer.scrollToTop.button": "Gulir ke atas", - "components.header.links.home": "Beranda", - "components.header.links.about": "Tentang", - "components.header.links.download": "Unduh", - "components.header.links.docs": "Dokumen", - "components.header.links.getInvolved": "Berkontribusi", - "components.header.links.security": "Keamanan", - "components.header.links.certification": "Sertifikasi", - "components.header.links.blog": "Berita", - "components.navigation.about.links.governance": "Tata Kerja", - "components.navigation.docs.links.es6": "ES6 dan seterusnya", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Panduan", - "components.navigation.docs.links.dependencies": "Dependensi", - "components.navigation.getInvolved.links.collabSummit": "KKT Kolaborasi", - "components.navigation.getInvolved.links.contribute": "Kontribusi", - "components.navigation.getInvolved.links.codeOfConduct": "Kode etik", - "components.downloadList.links.previousReleases": "Rilisan sebelumnya", - "components.downloadList.links.packageManager": "Menginstal Node.js melalui manajer paket", - "components.downloadList.links.shaSums": "SHASUMS yang ditandatangani untuk file rilisan", - "components.downloadList.links.shaSums.howToVerify": " (Cara melakukan verifikasi)", - "components.downloadList.links.allDownloads": "Semua opsi unduhan", - "components.downloadList.links.nightlyReleases": "Build Harian", - "components.downloadList.links.unofficialBuilds": "Build tidak resmi", - "components.downloadList.links.buildingFromSource": "Membangun Node.js dari sumber pada platform yang didukung", - "components.downloadList.links.installingOnLinux": "Menginstal Node.js melalui arsip biner", - "components.downloadList.links.installingOnWsl": "Menginstal melalui Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Log Perubahan", - "components.downloadReleasesTable.releases": "Rilisan", - "components.downloadReleasesTable.docs": "Dokumen", - "components.header.buttons.toggleLanguage": "Beralih Bahasa", - "components.header.buttons.toggleDarkMode": "Alihkan mode gelap/terang", - "components.pagination.next": "Terbaru | ", - "components.pagination.previous": "Lama", - "layouts.blogPost.author.byLine": "{author, select, null {} other {Oleh {author}, }}", - "layouts.blogIndex.currentYear": "Berita dari {year}", - "components.api.jsonLink.title": "Tampilkan sebagai JSON", - "components.api.sourceLink": "Kode Sumber:", - "pages.404.title": "404: Halaman tidak dapat ditemukan", - "pages.404.description": "ENOENT: tidak ada file atau direktori" + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", + "components.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/index.mjs b/i18n/locales/index.mjs index 30f6e52a8dc5c..570c91f316d75 100644 --- a/i18n/locales/index.mjs +++ b/i18n/locales/index.mjs @@ -4,21 +4,16 @@ // and import it below. import ar from './ar.json' assert { type: 'json' }; -import ca from './ca.json' assert { type: 'json' }; import de from './de.json' assert { type: 'json' }; import en from './en.json' assert { type: 'json' }; import es from './es.json' assert { type: 'json' }; -import fa from './fa.json' assert { type: 'json' }; import fr from './fr.json' assert { type: 'json' }; -import gl from './gl.json' assert { type: 'json' }; import id from './id.json' assert { type: 'json' }; import it from './it.json' assert { type: 'json' }; import ja from './ja.json' assert { type: 'json' }; import ka from './ka.json' assert { type: 'json' }; import ko from './ko.json' assert { type: 'json' }; -import nl from './nl.json' assert { type: 'json' }; import ptBr from './pt-br.json' assert { type: 'json' }; -import ro from './ro.json' assert { type: 'json' }; import ru from './ru.json' assert { type: 'json' }; import tr from './tr.json' assert { type: 'json' }; import uk from './uk.json' assert { type: 'json' }; @@ -29,21 +24,16 @@ import zhTw from './zh-tw.json' assert { type: 'json' }; // eslint-disable-next-line import/no-anonymous-default-export export default { ar, - ca, de, en, es, - fa, fr, - gl, id, it, ja, ka, ko, - nl, 'pt-br': ptBr, - ro, ru, tr, uk, diff --git a/i18n/locales/it.json b/i18n/locales/it.json index 52620965c7a69..61cac039e0aaf 100644 --- a/i18n/locales/it.json +++ b/i18n/locales/it.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "Portami all'inizio", - "components.header.links.home": "Home", - "components.header.links.about": "Informazioni", - "components.header.links.download": "Downloads", - "components.header.links.docs": "Documentazione", - "components.header.links.getInvolved": "Come partecipare", - "components.header.links.security": "Sicurezza", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "Blog", - "components.navigation.about.links.governance": "Gestione", - "components.navigation.docs.links.es6": "ES6 e oltre", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Guide", + "components.navigation.docs.links.guides": "Guides", "components.navigation.docs.links.dependencies": "Dependencies", "components.navigation.getInvolved.links.collabSummit": "Collab Summit", - "components.navigation.getInvolved.links.contribute": "Contribuire", - "components.navigation.getInvolved.links.codeOfConduct": "Condotta", - "components.downloadList.links.previousReleases": "Rilasci Precedenti", - "components.downloadList.links.packageManager": "Installa Node.js con un gestore di pacchetti", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", "components.downloadList.links.shaSums": "Signed SHASUMS for release files", "components.downloadList.links.shaSums.howToVerify": " (How to verify)", - "components.downloadList.links.allDownloads": "Tutti i download", - "components.downloadList.links.nightlyReleases": "Build notturne", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Registro modifiche", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Documentazione", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Successiva | ", - "components.pagination.previous": "Precedente", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/ja.json b/i18n/locales/ja.json index 5f8f1ba9793ae..61cac039e0aaf 100644 --- a/i18n/locales/ja.json +++ b/i18n/locales/ja.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "上部へスクロールする", - "components.header.links.home": "ホーム", - "components.header.links.about": "Node.js とは", - "components.header.links.download": "ダウンロード", - "components.header.links.docs": "ドキュメント", - "components.header.links.getInvolved": "参加する", - "components.header.links.security": "セキュリティ", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "ニュース", - "components.navigation.about.links.governance": "委員会", - "components.navigation.docs.links.es6": "ES6 について", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "ガイド", - "components.navigation.docs.links.dependencies": "依存関係", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", "components.navigation.getInvolved.links.collabSummit": "Collab Summit", - "components.navigation.getInvolved.links.contribute": "貢献する", - "components.navigation.getInvolved.links.codeOfConduct": "行動規範", - "components.downloadList.links.previousReleases": "バージョンの一覧", - "components.downloadList.links.packageManager": "Iパッケージマネージャを使用したダウンロード", - "components.downloadList.links.shaSums": "リリースファイルのための SHASUM 署名", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", "components.downloadList.links.shaSums.howToVerify": " (How to verify)", "components.downloadList.links.allDownloads": "All download options", "components.downloadList.links.nightlyReleases": "Nightly builds", - "components.downloadList.links.unofficialBuilds": "非公式のビルド版", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "変更履歴", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "ドキュメント", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "次 | ", - "components.pagination.previous": "前", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/ka.json b/i18n/locales/ka.json index e1b1797b00644..61cac039e0aaf 100644 --- a/i18n/locales/ka.json +++ b/i18n/locales/ka.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "ზემოთ", - "components.header.links.home": "მთავარი", - "components.header.links.about": "შესახებ", - "components.header.links.download": "ჩამოტვირთვა", - "components.header.links.docs": "დოკუმენტაცია", - "components.header.links.getInvolved": "შემოგვიერთდით", - "components.header.links.security": "უსაფრთხოება", - "components.header.links.certification": "სერტიფიკაცია", - "components.header.links.blog": "სიახლეები", - "components.navigation.about.links.governance": "მმართველობა", - "components.navigation.docs.links.es6": "ES6 და მის ფარგლებს მიღმა", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "სახელმძღვანელოები", - "components.navigation.docs.links.dependencies": "დაქვემდებარებულები (Dependencies)", - "components.navigation.getInvolved.links.collabSummit": "თანამშრომლობის სამიტი", - "components.navigation.getInvolved.links.contribute": "ხელშეწყობა", - "components.navigation.getInvolved.links.codeOfConduct": "ყოფაქცევის კოდექსი", - "components.downloadList.links.previousReleases": "უწინდელი ვერსიები", - "components.downloadList.links.packageManager": "Node.js-ის ინსტალაცია პაკეტის მენეჯერის გამოყენებით", - "components.downloadList.links.shaSums": "ხელმოწერილი SHASUMS გამოშვების (release) ფაილებისათვის", - "components.downloadList.links.shaSums.howToVerify": " (როგორ გადავამოწმოთ)", - "components.downloadList.links.allDownloads": "ჩამოტვირთვის ყველა ვარიანტი", - "components.downloadList.links.nightlyReleases": "ღამის ვერსიები", - "components.downloadList.links.unofficialBuilds": "არაოფიციალური ვერსიები", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Node.js-ის ინსტალაცია ბინარული (binary) არქივის გამოყენებით", - "components.downloadList.links.installingOnWsl": "ინსტალაცია Windows-ის Linux-ქვესისტემისათვის (WSL)", - "components.downloadReleasesTable.changelog": "ცვლილებათა ჩამონათვალი", - "components.downloadReleasesTable.releases": "უწინდელი ვერსიები", - "components.downloadReleasesTable.docs": "დოკუმენტაცია", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", - "components.header.buttons.toggleDarkMode": "გადართვა მუქ/ნათელ რეჟიმზე", - "components.pagination.next": "შემდეგი | ", - "components.pagination.previous": "წინა", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/ko.json b/i18n/locales/ko.json index a582789464260..61cac039e0aaf 100644 --- a/i18n/locales/ko.json +++ b/i18n/locales/ko.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "맨 위로", - "components.header.links.home": "홈", - "components.header.links.about": "About", - "components.header.links.download": "다운로드", - "components.header.links.docs": "문서", - "components.header.links.getInvolved": "참여하기", - "components.header.links.security": "보안", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "뉴스", - "components.navigation.about.links.governance": "거버넌스", - "components.navigation.docs.links.es6": "ES6와 그 이후", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "안내", - "components.navigation.docs.links.dependencies": "의존성", - "components.navigation.getInvolved.links.collabSummit": "협업자 서밋", - "components.navigation.getInvolved.links.contribute": "기여하기", - "components.navigation.getInvolved.links.codeOfConduct": "행동강령", - "components.downloadList.links.previousReleases": "이전 릴리스", - "components.downloadList.links.packageManager": "패키지 관리자를 통한 Node.js 설치", - "components.downloadList.links.shaSums": "릴리스 파일에 서명된 SHASUMS", - "components.downloadList.links.shaSums.howToVerify": " (검증 방법)", - "components.downloadList.links.allDownloads": "모든 다운로드 보기", - "components.downloadList.links.nightlyReleases": "나이틀리 빌드", - "components.downloadList.links.unofficialBuilds": "비공식 빌드", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Linux에서 바이너리 아카이브를 통해 Node.js 설치하기", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "변경사항", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "문서", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "다음 | ", - "components.pagination.previous": "이전", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/nl.json b/i18n/locales/nl.json deleted file mode 100644 index bf2f17011d92e..0000000000000 --- a/i18n/locales/nl.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "components.footer.scrollToTop.button": "Scroll naar boven", - "components.header.links.home": "Home", - "components.header.links.about": "Over Node.js", - "components.header.links.download": "Downloads", - "components.header.links.docs": "Documentatie", - "components.header.links.getInvolved": "Raak Betrokken", - "components.header.links.security": "Security", - "components.header.links.certification": "Certificering", - "components.header.links.blog": "Nieuws", - "components.navigation.about.links.governance": "Bestuur", - "components.navigation.docs.links.es6": "ES6 en meer", - "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", - "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Handleidingen", - "components.navigation.docs.links.dependencies": "Dependencies", - "components.navigation.getInvolved.links.collabSummit": "Collab Summit", - "components.navigation.getInvolved.links.contribute": "Bijdragen", - "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", - "components.downloadList.links.previousReleases": "Vorige Versies", - "components.downloadList.links.packageManager": "Installeer Node.js via package manager", - "components.downloadList.links.shaSums": "Ondertekende SHASUMS voor release bestanden", - "components.downloadList.links.shaSums.howToVerify": " (Hoe verifiëren?)", - "components.downloadList.links.allDownloads": "Alle download opties", - "components.downloadList.links.nightlyReleases": "Nightly builds", - "components.downloadList.links.unofficialBuilds": "Onofficiële builds", - "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Installeer Node.js via binary archive", - "components.downloadList.links.installingOnWsl": "Installeer op Windows Subsystem voor Linux (WSL)", - "components.downloadReleasesTable.changelog": "Changelog", - "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Documentatie", - "components.header.buttons.toggleLanguage": "Toggle Language", - "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Volgende | ", - "components.pagination.previous": "Vorige", - "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" -} diff --git a/i18n/locales/pt-br.json b/i18n/locales/pt-br.json index 1475f76f1aea4..61cac039e0aaf 100644 --- a/i18n/locales/pt-br.json +++ b/i18n/locales/pt-br.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "Retorne ao começo", - "components.header.links.home": "Início", - "components.header.links.about": "Sobre", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", "components.header.links.download": "Download", - "components.header.links.docs": "Documentação", - "components.header.links.getInvolved": "Participe", - "components.header.links.security": "Segurança", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "Novidades", - "components.navigation.about.links.governance": "Governança do Projeto", - "components.navigation.docs.links.es6": "ES6 e além", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Guias", - "components.navigation.docs.links.dependencies": "Dependências", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", "components.navigation.getInvolved.links.collabSummit": "Collab Summit", - "components.navigation.getInvolved.links.contribute": "Contribua", - "components.navigation.getInvolved.links.codeOfConduct": "Código de Conduta", - "components.downloadList.links.previousReleases": "Versões Anteriores", - "components.downloadList.links.packageManager": "Instale Node.js usando gerenciador de pacotes.", - "components.downloadList.links.shaSums": "SHASUMS assinados para arquivos de versões", - "components.downloadList.links.shaSums.howToVerify": " (Como verificar)", - "components.downloadList.links.allDownloads": "Todas as opções de download", - "components.downloadList.links.nightlyReleases": "Versões Nightly", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Instalando Node.js via arquivo binário.", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Documentação", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Próximo | ", - "components.pagination.previous": "Anterior", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/ro.json b/i18n/locales/ro.json deleted file mode 100644 index 0f671085c8d58..0000000000000 --- a/i18n/locales/ro.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "components.footer.scrollToTop.button": "Scroll to top", - "components.header.links.home": "Home", - "components.header.links.about": "About", - "components.header.links.download": "Downloads", - "components.header.links.docs": "Docs", - "components.header.links.getInvolved": "Get Involved", - "components.header.links.security": "Security", - "components.header.links.certification": "Certification", - "components.header.links.blog": "News", - "components.navigation.about.links.governance": "Governance", - "components.navigation.docs.links.es6": "ES6 and beyond", - "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", - "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Guides", - "components.navigation.docs.links.dependencies": "Dependencies", - "components.navigation.getInvolved.links.collabSummit": "Collab Summit", - "components.navigation.getInvolved.links.contribute": "Contribute", - "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", - "components.downloadList.links.previousReleases": "Previous Releases", - "components.downloadList.links.packageManager": "Installing Node.js via package manager", - "components.downloadList.links.shaSums": "Signed SHASUMS for release files", - "components.downloadList.links.shaSums.howToVerify": " (How to verify)", - "components.downloadList.links.allDownloads": "All download options", - "components.downloadList.links.nightlyReleases": "Nightly builds", - "components.downloadList.links.unofficialBuilds": "Unofficial builds", - "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", - "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Changelog", - "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Docs", - "components.header.buttons.toggleLanguage": "Toggle Language", - "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Newer | ", - "components.pagination.previous": "Older", - "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" -} diff --git a/i18n/locales/ru.json b/i18n/locales/ru.json index 558d177412467..61cac039e0aaf 100644 --- a/i18n/locales/ru.json +++ b/i18n/locales/ru.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "Вверх", - "components.header.links.home": "Главная", - "components.header.links.about": "О проекте", - "components.header.links.download": "Загрузка", - "components.header.links.docs": "Документация", - "components.header.links.getInvolved": "Присоединиться", - "components.header.links.security": "Безопасность", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "Новости", - "components.navigation.about.links.governance": "Управление", - "components.navigation.docs.links.es6": "ES6 и выше", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Руководства", - "components.navigation.docs.links.dependencies": "Зависимости", - "components.navigation.getInvolved.links.collabSummit": "Саммит сотрудников", - "components.navigation.getInvolved.links.contribute": "Участие", - "components.navigation.getInvolved.links.codeOfConduct": "Правила", - "components.downloadList.links.previousReleases": "Предыдущие релизы", - "components.downloadList.links.packageManager": "Установка Node.js с помощью пакетного менеджера", - "components.downloadList.links.shaSums": "Подписанные SHASUMS для файлов релиза", - "components.downloadList.links.shaSums.howToVerify": " (Как проверить)", - "components.downloadList.links.allDownloads": "Все варианты загрузки", - "components.downloadList.links.nightlyReleases": "Ночные сборки", - "components.downloadList.links.unofficialBuilds": "Неофициальные сборки", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "Установка Node.js через бинарный архив в Linux", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Список изменений", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Документация", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Следующий | ", - "components.pagination.previous": "Предыдущий", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/tr.json b/i18n/locales/tr.json index 81994747bc8b6..61cac039e0aaf 100644 --- a/i18n/locales/tr.json +++ b/i18n/locales/tr.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "En üste kaydır", - "components.header.links.home": "Anasayfa", - "components.header.links.about": "Hakkında", - "components.header.links.download": "İndir", - "components.header.links.docs": "Belgeler", - "components.header.links.getInvolved": "Dahil Olun", - "components.header.links.security": "Güvenlik", - "components.header.links.certification": "Sertifikasyon", - "components.header.links.blog": "Haberler", - "components.navigation.about.links.governance": "Yönetim Şekli", - "components.navigation.docs.links.es6": "ES6 ve sonrası", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Rehberler", - "components.navigation.docs.links.dependencies": "Kullanılan Kütüphaneler", - "components.navigation.getInvolved.links.collabSummit": "İşbirliği Zirvesi", - "components.navigation.getInvolved.links.contribute": "Katkıda bulunun", - "components.navigation.getInvolved.links.codeOfConduct": "Davranış Kuralları", - "components.downloadList.links.previousReleases": "Önceki Sürümler", - "components.downloadList.links.packageManager": "Node.js'i paket yöneticisi ile kurmak", - "components.downloadList.links.shaSums": "Sürüm dosyaları için imzalı SHASUMS", - "components.downloadList.links.shaSums.howToVerify": " (Nasıl doğrulanır)", - "components.downloadList.links.allDownloads": "Tüm indirme seçenekleri", - "components.downloadList.links.nightlyReleases": "Günlük Yayımlanan Sürümler", - "components.downloadList.links.unofficialBuilds": "Resmi olmayan sürümler", - "components.downloadList.links.buildingFromSource": "Desteklenen platformlarda Node.js'in kaynak kodundan derlenmesi", - "components.downloadList.links.installingOnLinux": "Binary arşiv yoluyla Node.js kurulumu", - "components.downloadList.links.installingOnWsl": "Linux için Windows Subsystem'a (WSL) kurun", - "components.downloadReleasesTable.changelog": "Değişiklikler", - "components.downloadReleasesTable.releases": "Sürümler", - "components.downloadReleasesTable.docs": "Dokümantasyon", - "components.header.buttons.toggleLanguage": "Dili Değiştir", - "components.header.buttons.toggleDarkMode": "Karanlık/aydınlık modunu değiştir", - "components.pagination.next": "Daha Yeni | ", - "components.pagination.previous": "Daha Eski", - "layouts.blogPost.author.byLine": "{author, select, null {} other {{author} tarafından }}", - "layouts.blogIndex.currentYear": "{year} yılından haberler" + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", + "components.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/uk.json b/i18n/locales/uk.json index ca1f69103c700..61cac039e0aaf 100644 --- a/i18n/locales/uk.json +++ b/i18n/locales/uk.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "Вгору", - "components.header.links.home": "Головна", - "components.header.links.about": "Про проект", - "components.header.links.download": "Завантаження", - "components.header.links.docs": "Документація", - "components.header.links.getInvolved": "Приєднатись", - "components.header.links.security": "Безпека", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", "components.header.links.certification": "Certification", - "components.header.links.blog": "Новини", - "components.navigation.about.links.governance": "Управління", - "components.navigation.docs.links.es6": "ES6 і вище", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "Керівництва", - "components.navigation.docs.links.dependencies": "Залежності", - "components.navigation.getInvolved.links.collabSummit": "Саміт співпраці", - "components.navigation.getInvolved.links.contribute": "Сприяння", - "components.navigation.getInvolved.links.codeOfConduct": "Правила", - "components.downloadList.links.previousReleases": "Попередні Релізи", - "components.downloadList.links.packageManager": "Встановлення Node.js через пакетний менеджер", - "components.downloadList.links.shaSums": "Підписані SHASUMS для файлів релізу", - "components.downloadList.links.shaSums.howToVerify": " (Як перевірити)", - "components.downloadList.links.allDownloads": "Всі варіанти завантажень", - "components.downloadList.links.nightlyReleases": "Нічні збірки", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "Список змін", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "Документація", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "Далі | ", - "components.pagination.previous": "Попередній", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/zh-cn.json b/i18n/locales/zh-cn.json index 9cd623221ee95..61cac039e0aaf 100644 --- a/i18n/locales/zh-cn.json +++ b/i18n/locales/zh-cn.json @@ -1,45 +1,68 @@ { - "components.footer.scrollToTop.button": "回到页顶", - "components.header.links.home": "首页", - "components.header.links.about": "关于", - "components.header.links.download": "下载", - "components.header.links.docs": "文档", - "components.header.links.getInvolved": "加入我们", - "components.header.links.security": "汇报安全漏洞", - "components.header.links.certification": "相关认证", - "components.header.links.blog": "新闻事件", - "components.navigation.about.links.governance": "管理规则", - "components.navigation.docs.links.es6": "ES6 及更高版本", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "指南", - "components.navigation.docs.links.dependencies": "依赖项", - "components.navigation.getInvolved.links.collabSummit": "协作者峰会", - "components.navigation.getInvolved.links.contribute": "贡献", - "components.navigation.getInvolved.links.codeOfConduct": "管理", - "components.downloadList.links.previousReleases": "先前所有已发布版本", - "components.downloadList.links.packageManager": "使用包管理器安装 Node.js", - "components.downloadList.links.shaSums": "查看发布文件的 SHASUM 签名", - "components.downloadList.links.shaSums.howToVerify": " (如何校验?)", - "components.downloadList.links.allDownloads": "所有下载选项", - "components.downloadList.links.nightlyReleases": "日构建版(仅供实验尝鲜用)", - "components.downloadList.links.unofficialBuilds": "非官方构建版", - "components.downloadList.links.buildingFromSource": "在已支持平台上通过编译 Node.js 源码得到可执行文件的步骤", - "components.downloadList.links.installingOnLinux": "在 Linux 上,通过二进制文件安装 Node.js", - "components.downloadList.links.installingOnWsl": "在适用于 Linux 的 Windows 子系统(WSL)上安装 Node.js", - "components.downloadReleasesTable.changelog": "更新日志", - "components.downloadReleasesTable.releases": "查看与下载", - "components.downloadReleasesTable.docs": "文档", - "components.header.buttons.toggleLanguage": "切换语言", - "components.header.buttons.toggleDarkMode": "明亮/暗黑模式切换", - "components.pagination.next": "较新的新闻事件 | ", - "components.pagination.previous": "更早的新闻事件", - "components.common.crossLink.previous": "上一页", - "components.common.crossLink.next": "下一页", - "layouts.blogPost.author.byLine": "{author, select, null {} other {由 {author} }}", - "layouts.blogIndex.currentYear": "{year} 年的所有新闻事件", - "components.api.jsonLink.title": "以 JSON 格式查看", - "components.api.sourceLink": "源代码:", - "pages.404.title": "404:您访问的页面不存在", - "pages.404.description": "ENOENT:无此文件或目录" + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", + "components.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/i18n/locales/zh-tw.json b/i18n/locales/zh-tw.json index cc5632a00f516..61cac039e0aaf 100644 --- a/i18n/locales/zh-tw.json +++ b/i18n/locales/zh-tw.json @@ -1,39 +1,68 @@ { - "components.footer.scrollToTop.button": "回到頁首", - "components.header.links.home": "首頁", - "components.header.links.about": "關於我們", - "components.header.links.download": "下載", - "components.header.links.docs": "文件", - "components.header.links.getInvolved": "加入我們", - "components.header.links.security": "安全", - "components.header.links.certification": "相關認證", - "components.header.links.blog": "部落格", - "components.navigation.about.links.governance": "管理規則", - "components.navigation.docs.links.es6": "ES6 相關", + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.about": "About Node.js®", + "components.header.links.download": "Download", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.footer.links.trademarkPolicy": "Trademark Policy", + "components.footer.links.privacyPolicy": "Privacy Policy", + "components.footer.links.codeOfConduct": "Code of Conduct", + "components.footer.links.security": "Security Policy", + "components.footer.links.openJS": "OpenJS Foundation", + "components.navigation.about.links.governance": "Project Governance", + "components.navigation.about.links.releases": "Releases", + "components.navigation.about.links.security": "Security Reporting", + "components.navigation.docs.links.es6": "ES6 and beyond", "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", - "components.navigation.docs.links.guides": "技術指南", + "components.navigation.docs.links.guides": "Guides", "components.navigation.docs.links.dependencies": "Dependencies", - "components.navigation.getInvolved.links.collabSummit": "協作者峰會", - "components.navigation.getInvolved.links.contribute": "貢獻", - "components.navigation.getInvolved.links.codeOfConduct": "管理", - "components.downloadList.links.previousReleases": "舊版", - "components.downloadList.links.packageManager": "I使用套件管理器安裝 Node.js", - "components.downloadList.links.shaSums": "發佈檔案的 SHASUM 簽名", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", "components.downloadList.links.shaSums.howToVerify": " (How to verify)", - "components.downloadList.links.allDownloads": "所有下載選項", - "components.downloadList.links.nightlyReleases": "每日建置版本", - "components.downloadList.links.unofficialBuilds": "非官方建置版本", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", - "components.downloadList.links.installingOnLinux": "在 Linux 上使用二進位檔案安裝 Node.js", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", - "components.downloadReleasesTable.changelog": "更新紀錄", + "components.downloadReleasesTable.changelog": "Changelog", "components.downloadReleasesTable.releases": "Releases", - "components.downloadReleasesTable.docs": "文件", + "components.downloadReleasesTable.docs": "Docs", "components.header.buttons.toggleLanguage": "Toggle Language", "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", - "components.pagination.next": "下一個 | ", - "components.pagination.previous": "上一個", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "components.common.breadcrumbs.navigateToHome": "Navigate to Home", + "components.common.crossLink.previous": "Prev", + "components.common.crossLink.next": "Next", + "components.common.codebox.copied": "Copied to clipboard!", + "components.metabar.lastUpdated": "Last Updated", + "components.metabar.readingTime": "Reading Time", + "components.metabar.addedIn": "Added In", + "components.metabar.author": "Author", + "components.metabar.authors": "Authors", + "components.metabar.contribute": "Contribute", + "components.metabar.contributeText": "Edit this page", + "components.metabar.viewAs": "View as", + "components.metabar.tableOfContents": "Table of Contents", "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", - "layouts.blogIndex.currentYear": "News from {year}" + "layouts.blogIndex.currentYear": "News from {year}", + "components.api.jsonLink.title": "View as JSON", + "components.api.sourceLink": "Source Code:", + "pages.404.title": "404: Page could not be found", + "pages.404.description": "ENOENT: no such file or directory", + "components.common.pagination.prev": "Previous", + "components.common.pagination.prevAriaLabel": "Previous page", + "components.common.pagination.next": "Next", + "components.common.pagination.nextAriaLabel": "Next page", + "components.common.pagination.defaultLabel": "Pagination", + "components.common.pagination.pageLabel": "Go to page {pageNumber}", + "components.common.languageDropdown.label": "Choose Language" } diff --git a/layouts/DownloadReleasesLayout.tsx b/layouts/DownloadReleasesLayout.tsx index c66a1f3a15362..4f97e076adb5f 100644 --- a/layouts/DownloadReleasesLayout.tsx +++ b/layouts/DownloadReleasesLayout.tsx @@ -5,12 +5,12 @@ import DownloadReleasesTable from '@/components/Downloads/DownloadReleasesTable' import { useLayoutContext } from '@/hooks/useLayoutContext'; import type { LegacyDownloadsReleasesFrontMatter } from '@/types'; -import BaseLayout from './BaseLayout'; +import AboutLayout from './AboutLayout'; const DownloadReleasesLayout: FC = ({ children }) => { const { frontMatter } = useLayoutContext(); - const { modules, title } = frontMatter as LegacyDownloadsReleasesFrontMatter; + const { modules } = frontMatter as LegacyDownloadsReleasesFrontMatter; // @TODO: Remove this once we migrate to `nodejs/nodejs.dev` codebase as this is unsafe // And completely not recommended @@ -20,25 +20,19 @@ const DownloadReleasesLayout: FC = ({ children }) => { ); return ( - -
-
-

{title}

- -
{children}
- -
- -

- -

-
-
-
-
+ + {children} + +
+ +

+ +

+
+
); }; diff --git a/layouts/IndexLayout.tsx b/layouts/IndexLayout.tsx index 5fa28e93b3e40..f92d6d50d8588 100644 --- a/layouts/IndexLayout.tsx +++ b/layouts/IndexLayout.tsx @@ -2,6 +2,7 @@ import type { FC, PropsWithChildren } from 'react'; import Banner from '@/components/Home/Banner'; import HomeDownloadButton from '@/components/Home/HomeDownloadButton'; +import LocalizedLink from '@/components/LocalizedLink'; import { useDetectOS } from '@/hooks/useDetectOS'; import { useLayoutContext } from '@/hooks/useLayoutContext'; import { WithNodeRelease } from '@/providers/withNodeRelease'; @@ -57,9 +58,9 @@ const IndexLayout: FC = ({ children }) => {

{labels?.['version-schedule-prompt']}{' '} - + {labels?.['version-schedule-prompt-link-text']} - + .

diff --git a/navigation.json b/navigation.json index a78e9835dbeaa..7987739fae938 100644 --- a/navigation.json +++ b/navigation.json @@ -1,9 +1,4 @@ { - "home": { - "link": "/", - "translationId": "components.header.links.home", - "items": {} - }, "about": { "link": "/about", "translationId": "components.header.links.about", @@ -11,6 +6,14 @@ "governance": { "link": "/about/governance", "translationId": "components.navigation.about.links.governance" + }, + "releases": { + "link": "/about/previous-releases", + "translationId": "components.navigation.about.links.releases" + }, + "security": { + "link": "/about/security-reporting", + "translationId": "components.navigation.about.links.security" } } }, @@ -30,10 +33,6 @@ "link": "/download/package-manager", "translationId": "components.downloadList.links.packageManager" }, - "previousReleases": { - "link": "/download/releases", - "translationId": "components.downloadList.links.previousReleases" - }, "nightlyReleases": { "link": "https://nodejs.org/download/nightly/", "translationId": "components.downloadList.links.nightlyReleases" @@ -100,11 +99,6 @@ } } }, - "security": { - "link": "https://github.com/nodejs/node/security/policy#security", - "translationId": "components.header.links.security", - "items": {} - }, "certification": { "link": "https://openjsf.org/certification", "translationId": "components.header.links.certification", diff --git a/pages/ar/404.md b/pages/ar/404.md deleted file mode 100644 index 9156292c3bff7..0000000000000 --- a/pages/ar/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: صفحة غير موجودة - -### ENOENT: لا يوجد ملف أو مسار بهذا الإسم diff --git a/pages/ar/about/governance.md b/pages/ar/about/governance.md deleted file mode 100644 index bde056aa1bcce..0000000000000 --- a/pages/ar/about/governance.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: حوكمة المشروع -layout: about.hbs ---- - -# حوكمة المشروع - -## منهج الإجماع في إتخاذ القرارات - -يتبع النود جي اس نموذج [منهج الإجماع في إتخاذ القرارات][]. - -## المساهمون - -تتم صيانة المستودع الرئيسي [nodejs/node][] من طرف مجموعة من المساهمين الذين تتم إضافتهم من قبل [لجنة التوجيه التقني][] بصفة مستمرة - -يعتبر الاشخاص الذين يساهمون مساهمة قيمة و ملحوظة مساهمين فعليين، و يمنحون حق اجراء تغييرات إلى المشروع مباشرة، و يتم تحديد هؤلاء الأشخاص من قبل لجنة التوجيه التقني، كما تتم مناقشة تسميتهم مع المساهمين الحاليين. - -للاطلاع على قائمة المساهمين الحالية، انظر ملف [README.md][] الخاص بالمشروع - -يجدر الإشارة أيضا إلى أن هناك دليلا يخص المساهمين و تتم مراجعته دوريا في ملف [collaborator-guide.md][] - -## اللجان العليا - -يتم قيادة المشروع بشكل مشترك من قبل كل من [لجنة التوجيه التقني (TSC)][] المسؤولة عن القيادة العليا للمشروع و [لجنة المجتمع (CommComm)][] المسؤولة عن توسيع مجتمع النود جي اس. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[لجنة المجتمع (CommComm)]: https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md -[منهج الإجماع في إتخاذ القرارات]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[لجنة التوجيه التقني (TSC)]: https://github.com/nodejs/TSC/blob/master/TSC-Charter.md -[لجنة التوجيه التقني]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/ar/about/index.md b/pages/ar/about/index.md deleted file mode 100644 index eb34d9e8b400f..0000000000000 --- a/pages/ar/about/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: about.hbs -title: عن النود جي اس -trademark: العلامة التجارية ---- - -# عن الـ Node.js ® - -كونه بيئة تشغيل جافاسكريبت غير متزامنة و مدفوعة بالاحداث، فإن Node.js صمم لبناء تطبيقات للشبكات قابلة للتطوير. في المثال الأتي، يمكن التحكم في عدة اتصالات معا في وقت واحد و مع كل اتصال يتم تشغيل دالة مستدعاة، وعندما لن يكون هناك عمل لاتمامه، سيقف النود جي اس عن العمل مؤقتا. - -```javascript -const http = require('http'); -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -هذا على النقيض من نموذج التزامن الأكثر شيوعا اليوم أين يتم استخدام الخيوط الخاصة بالنظام - -إن شبكة مبنية على الخيوط تعتبر غير فعالة نسبيا، و صعبة الاستخدام. و إضافة إلى ذلك فإن مستخدمي Node.js لن يكون لديهم قلق حول اغلاق العملية بما أنه ليس هنالك اقفال. تقريبا، ليس هنالك من دالة في Node.js تعمل مباشرة على مستوى الادخال و الاخراج لذلك لا تتوقف اي عملية، لذلك فإن بناء انظمة قابلة للتطوير بNode.js يعد امرا محببا و منطقيا. اذا كانت الفقرة السابقة تحتوي على مصطلحات مبهمة بالنسبة إليك تفضل بقراءة هذا المقال للتعمق (باللغة الانجليزية) [Blocking vs Non-Blocking][]. - ---- - -تعتبر النود جي اس شبيهة في تصميمها بمكتبات و أنظمة مثل [Event Machine][] الخاصة بالروبي و [Twisted][] الخاصة بالبايثون. - -تأخذ Node.js نموذج الاحداث (event model) ابعد قليلا فتمثل الحلقة التكرارية الخاصة بالاحداث ([event loop][]) كمكون اساسي في وقت التشغيل (runtime construct) وليس كمكتبة في انظمة أخرى، حيث ان هنالك دائما استدعاء متزامن (blocking call) للبدء في حلقة الاحداث. مبدئيا، يتم تحديد السلوك عبر دالة مستدعاة في بداية السكريبت في نهايتها تقوم بتشغيل خادم (server) عبر استدعاءٍ غير متزامن (blocking call) مثل `EventMachine::run()`، ولكن في Node.js لا يوجد شيء من هذا القبيل. تقوم Node.js بكل بساطة بدخول حلقة الاحداث بعد تنفيذها لسكريبت الادخال و تخرج من الحلقة السالفة الذكر عندما لا يكون هنالك اي دوال مستدعاة اخرى تستوجب التنفيذ. هذا النمط يشبه JavaScript الخاصة بالمتصفح اين يتم اخفاء حلقة الاحداث عن المستخدم. - -يعتبر بروتوكول الـHTTP مهما في Node.js. حيث انه تم أخذ اعتبار بث و تقليل وقت التأخير و هذا ما يجعل النود ممتازة لبناء مكتبات و إطارات عمل خاصة بالويب. - -[Blocking vs Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[event loop]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/ar/docs/es6.md b/pages/ar/docs/es6.md deleted file mode 100644 index a5ae9276e2238..0000000000000 --- a/pages/ar/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) و ما بعدها -layout: docs.hbs ---- - -# نسخة ECMAScript 2015 (ES6) و ما بعدها - -تم بناء الـ Node.js باستعمال نسخ حديثة من الـ [V8](https://v8.dev/docs/profile)، وهذا يضمن إتاحة آخر المميزات الخاصة بالجافاسكريبت والموافقة لـ [مواصفات JavaScript ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm) للمطورين في الوقت المناسب، إضافة إلى التحسينات المستمرة في الأداء والثبات. - -تقسم مميزات الـ ECMAScript 2015 (ES6) إلى ثلاثة مجموعات: **المميزات التي تم شحنها** و**المميزات التي سيتم شحنها** و**المميزات قيد التقدم** حيث: - -- أن كافة **المميزات التي تم شحنها**، والتي يعتبرها الـ V8 ثابتة **يتم تشغيلها تلقائيا على الـ Node.js** ولا تتطلب أي نوع من الإعلام في وقت التشغيل. -- أن **المميزات التي سيتم شحنها** والتي هي مميزات مكتملة تقريبا ولكنها لا تعتبر ثابتة حسب فريق تطوير الـ V8 تتطلب علما في وقت التشغيل لاستعمالها: `--harmony` -- أن **المميزات قيد التقدم** يمكن تشغيلها فرديا عبر العلم الخاص بها، رغم أن هذا الأمر منصوح بشدة تجنبه إلا لأغراض الاختبار. ملاحظة: هذه الأعلام معرفة من قبل الـ V8 ومن الممكن لها أن تتغير دون إشعار بذلك. - -## أي من المميزات تشحن مع أي نسخة من الـ Node.js افتراضيا ؟ - -يوفر موقع [node.green](https://node.green/) نظرة عامة ممتازة حول مميزات الـ ECMAScript المدعومة في مختلف نسخ الـ Node.js بناء على جدول كانغاكس. - -## أي من المميزات هي قيد التقدم ؟ - -تتم إضافة مميزات جديدة للـ V8 دوريا، وعموما يتوقع وصول هذه المميزات إلى الـ Node.js على الرغم من أن التوقيت يبقى غير معلوم. - -يمكنك الاطلاع على هذه المميزات التي هي **قيد التقدم** في كل نسخة من نسخ الـ Node.js عبر استعمال الأمر `grep` مع `--v8-options` وتجدر الأشارة إلى أن هذه المميزات غير مكتملة وقد تتعطل، لذلك فإن استعمالها يقع على مسؤوليتك الخاصة: - -```bash -node --v8-options | grep "in progress" -``` - -## لقد قمت بإعداد بنيتي التحتية للاستفادة من علم `--harmony`. هل يجب علي إلغاء ذلك؟ - -إن السلوك الحالي لعلم `--harmony` هو تمكين **المميزات التي سيتم شحنها** فقط. ففي نهاية المطاف هي تعتبر مرادفاً لـ `--es_staging`، وكما ذكر مسبقا فإن هذه الميزات تعتبر كاملة ولكن غير ثابتة بعد. إذا أردت أن يتم ذلك بأمان، خصوصا في بيئة إنتاجية فيجب عليك أن تأخذ بعين الاعتبار حذف هذا العلم حتى يتم شحن تلك الميزات افتراضيا مع الـ V8، ومن ثم مع الـ Node.js. إذا أبقيت على هذه الميزات مفعلة، فيجب أن تتوقع تَوَقُف شيفرتك عن العمل في ترقيات قادمة من الـ Node.js إذا غير الـ V8 من مسمياتهم لاتباع المعايير أكثر. - -## كيف يمكنني معرفة أي نسخة من الـ V8 يتم تضمينها مع نسخة معينة من الـ Node.js ؟ - -يوفر الـ Node.js طريقة سهلة لسرد كافة الاعتمادات والنسخ التي يتم تضمينها مع ملف ثنائي محدد عبر الكائن العام `process`. في حالة محرك الـ V8، بكتابة الأمر التالي في الطرفية لمعرفة نسخته: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/ar/docs/guides/abi-stability.md b/pages/ar/docs/guides/abi-stability.md deleted file mode 100644 index a647cdadb5bff..0000000000000 --- a/pages/ar/docs/guides/abi-stability.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: الواجهة الثنائية للتطبيق -layout: docs.hbs ---- - -# ثبات الواجهة الثنائية للتطبيق - -## مقدمة - -تعتبر الواجهة الثنائية للتطبيق طريقة يمكن للبرامج من خلالها أن تستدعي دوال و تستعمل هياكل بيانات من برامج مفسرة أخرى. -فهي تعتبر النسخة المفسرة لواجهة برمجة تطبيق الخاصة برنامج ما. بعبارة أخرى، هي ترويسات الملفات التي تصف المصنفات و الدوال -و هياكل البيانات و التعدادات إضافة إلى الثوابت التي تسمح لتطبيق بأن ينفذ مهمة مرغوبة استجابة لطريقة تفسير مجموعة من العناوين و قيم الإعدادات المتوقعة سلفاُ -إضافة إلى احجام هياكل الذاكرة و الأنساق التي بواسطتها تم تفسير مزود الواجهة الثنائية للتطبيق. - -يجب على التطبيق الذي يستعمل الواجهة الثنائية للتطبيق أن يُفسر بطريقة تجعل العناوين و الإعدادات المتوقعة و أحجام هياكل الذاكرة و الأنساق متوافقة مع -تلك التي تم بواسطتها تفسير مزود الواجهة الثنئاية للتطبيق، ويتم تحقيق هذا عادة عبر التفسير باستخدام الترويس التي تم توفيرها من طرف مزود الواجهة الثنائية للتطبيق. - -بما أن مزود الواجهة الثنائية للتطبيق و مستخدم الواجهة الثنائية للتطبيق قد يتم تفسيرهما في أوقات مختلفة باستعمال نسخ مفسرات مختلفة، فإن القطعة المسؤولة عن -عن ضمان توافق الواجهة الثنائية للتطبيق تكون داخل المفسر. يجب على النسخ المختلفة من المفسرات التي قد يتم توفيرها من طرف بائعين مختلفين أن تنتج نفس النسخة من -الواجهة الثنائية للتطبيق انطلاقا من ملف ترويسة ذو محتوى محدد، كما يجب عليها ان تنتج شيفرة خاصة بالتطبيق باستعمال الواجهة الثنائية للتطبيق التي يمكنها الوصول إلى الواجهة البرمجية -للتطبيق و التي تم وصفها في ترويسة معطاة استنادا إلى الناتج المتفق عليه للواجهة الثنائية للتطبيق الناتجة عن الوصف المتوفر في الترويسة. إن المفسرات الحديثة تمتلك سجل تتبع جيداُ فيما يخص -تحقيق التوافق بين الواجهات الثنائية للتطبيقات التي تنتجها. - -تقع المسؤولية الباقية فيما يخص ضمان توافق الواجهة الثنائية للتطبيق على عاتق الفرق المسؤول عن صيانة ملفات الترويس التي توفر واجهة برمجية للتطبيق التي بدورها تنتج -عن تفسير الواجهة الثنائية للتطبيق التي تبقى ثابتة. يمكن إجراء تغييرات على على ملفات الترويس، لكن يجب تتبع طبيعة هذه التغييرات بدقة لضمان أنه بعد تفسير الواجه الثنائية للتطبيق، -ﻻ تتغير بطريقة تؤدي إلى الإخلال بتوافق الواجهات الثنائية للتطبيقات الخاصة بالمستخدمين الحاليين مع النسخ الجديدة. - -## ثبات الواجهة البرمجية للتطبيقات في الـ Node.js - -توفر الـ Node.js ملفات ترويس يتم صيانتها من طرف عدة فرق تقنية مستقلة. على سبيل المثال، ملفات الترويس مثل `node.h` و `node_buffer.h` يتم صيانتها من طرف فريق الـ Node.js، بينما يتم صيانة ملف `v8.h` من طرف فريق الـ V8، الذي هو مستقل و يمتلك اجندته و أولوياته الخاصة رغم تعاونه الوثيق مع فريق الـ Node.js. مع ذلك، ليس لفريق الـ Node.js سوى تحكم جزئي على التغييرات التي يتم طرحها في ملفات الترويس التي يوفرها المشروع. نتيجة لما سبق، فإن مشروع الـ Node.js تبنى سياسة [الترميز الدلالي](https://semver.org/) ليضمن أن الواجهة البرمجية للتطبيق الموفرة من المشروع تنتج واجهة ثنائية ثابتة لجميع نسخ الـ Node.js الصغرى و الإصلاحية التي تم إطلاقها تحت نسخة رئيسية واحدة، وهذا يعني أن مشروع الـ Node.js يلزم نفسه بضمان أن الإضافات الأصلية للـ Node.js التي تم تفسيرها بواسطة نسخة رئيسية من الـ Node.js تعمل بنجاح عند تشغيلها من طرف أي نسخة ثانوية أو نسخة اصلاحية للـ Node.js تنتمي للنسخة الرئيسية التي تم تفسيرها اساسا بها. - -## N-API - -لقد تزايد الطلب لتزويد الـ Node.js بواجهة تطبيقات برمجية تنتج واجهة تطبيقات ثنائية تكون ثابتة على عدة نسخ رئيسية من الـ Node.js، و ما حفزنا لإنشاء واجهة برمجية مشابهة هو ما يلي: - -- بقاء لغة الجافاسكريبت متوافقة مع ذاتها من أيامها الأولى، بينما تتغير الواجهة الثنائية للتطبيق الخاصة بالمحرك الذي ينفذ الجافاسكريبت مع كل نسخة رئيسية للـ Node.js و هذا يعني أن أي تطبيق كُتب تماما بالجافاسكريبت لا يحتاج ﻹعادة تفسيره أو تثبيته أو نشره لأن النسخة الرئيسية الجديدة من الـ Node.js قد تم التخلي عنها في البيئة الانتاجية التي يشتغل عليها التطبيق. هذا التفاوت بين حزم الـ Node.js التي تحتوي على إضافات أصلية و تلك المكتوبة كليا بالجافاسكريبت قد أُضيف لعبئ صيانة الأنظمة الانتاجية التي تعتمد على الإضافات الأصلية. - -- وجود مشاريع أخرى بدأت في إنتاج واجهات الجافاسكريبت التي تعتبر بدائل للـ Node.js. بما أن هذه المشاريع قد تم بناؤها اعتمادا على محركات جافاسكريبت مختلفة عن الـ V8، فإن اضافاتها الأصلية تنطوي بالضرورة على هيكلية مختلفة و تستعمل واجهة برمجية مختلفة، و رغم ذلك، فإن استعمال واجهة برمجية واحدة خاصة بإضافة أصلية في عدة نسخ لواجهة الجافاسكريبت البرمجية الخاصة بالـ Node.js سيسمح لهذه المشاريع بأن تستعمل مميزات النظام البيئي لحزم الجافاسكريبت التي تتمحور حول الـ Node.js -- قد يحتوي الـ Node.js على محركات جافاسكريبت مختلفة مستقبلا، و هذا يعني أن جميع واجهات الـ Node.js ستبقى نفسها خارجيا، لكن سيعني أيضا أن ملفات الترويس الخاصة بالـ V8 ستكون غائبة. - مثل هذه الخطوة ستؤدي إلى اختلال النظام البيئي للـ Node.js عموماً و النظام البيئي الخاص بالإضافات خصوصاً إذا كانت الواجهة البرمجية للإضافة التي لا تستعمل محرك جافاسكريبت ليست موفرة من قبل الـ Node.js و غير متبناة من طرف الإضافات الأصلية. - -لهذه الأطراف، تم طرح الـ N-API في النسخة 8.6.0 و تم تمييزه كميزة مستقرة في النسخة 8.12.0. هذه الواجهة البرمجية معرفة في ملفات الترويس [`node_api.h`][] و [`node_api_types.h`][] و تضمن توافقا متقدما على مستوى عدة نسخ رئيسية من الـ Node.js كما يلي: -**تتوفر نسخة معينة _n_ من الـ N-API في النسخة الرئيسية من الـ Node.js التي نشرت فيها، و في كافة نسخ الـ Node.js اللاحقة بما فيها النسخ الرئيسية منها.** - -يمكن لمطوري الإضافات الأصلية إستغلال التوافق المتقدم الذي يضمنه الـ N-API عبر ضمان أن الإضافة تستعمل الواجهات البرمجية المحددة في في ملف ترويس `node_api.h` فقط مع هياكل البيانات و الثوابت المحدد في ملف `node_api_types.h`. بالقيام بذلك، يسهل المطورون تبني إضافاتهم عبر تنبيه المستخدمين في مرحلة الإنتاج إلى أن عبء صيانة تطبيقاتهم لن يزيد بتغيير الإضافات الأصلية في مشاريعهم بل بإضافة حزم مكتوبة كليا بالجافاسكريبت. - -ينطوي الـ N-API على نسخ عدة لكون أن هناك واجهات برمجية جديدة تضاف من وقت ﻵخر، وعكس الترميز الدلالي، فإن تنسيخ الـ N-API هو تراكمي، أي أن كل نسخة منه تمثل نفس المعنى للنسخ الثانوية في نظام الترميز الدلالي و بالتالي فإن كل التغييرات التي يتم إجراؤها على الـ N-API تكون متوافقة مع النسخ الأقدم. إضافة إلى ما سبق، فإن هناك نسخ جديدة من الـ N-API تضاف تحت بند "تجريبي" لإعطاء المجتمع الفرصة لفحصها في بيئة إنتاجية. تعني الحالة التجريبية أنه على الرغم من ان هناك اهتماماً لضمان أن ﻻ يجب تعديل الواجهات البرمجية الجديدة بطريقة تلغي توافق الواجهات الثنائية للتطبيقات مستقبلا، فإنه لم يتم الموافقة على كونها صحيحة و مفيدة بشكل كافٍ في الانتاج كما تم تصميمها، وعليه فيمكنها ان تنطوي على تغييرات غير متوافقة مع الواجهات الثنائية للتطبيق قبل أن يتم دمجها أخيراً مع نسخة قادمة من الـ N-API. بمعنى آخر، فإن نسخة تجريبية من الـ N-API لا يُضمن ان تحقق توافقا متقدما. - -[`node_api.h`]: https://github.com/nodejs/node/blob/main/src/node_api.h -[`node_api_types.h`]: https://github.com/nodejs/node/blob/main/src/node_api_types.h diff --git a/pages/ar/docs/guides/anatomy-of-an-http-transaction.md b/pages/ar/docs/guides/anatomy-of-an-http-transaction.md deleted file mode 100644 index 97be558463a19..0000000000000 --- a/pages/ar/docs/guides/anatomy-of-an-http-transaction.md +++ /dev/null @@ -1,426 +0,0 @@ ---- -title: التركيبة البنيوية لمُعَامَلَة HTTP -layout: docs.hbs ---- - -# التركيبة البنيوية لمُعَامَلَة HTTP - -الغاية من هذا الدليل هو مَنَح معارف قوية لعمل Node.js في معالجة HTTP. لنفرض أنك تعرف -بشكل عام كيف تعمل طلبات HTTP بغض النظر عن اللغة أو بيئة البرمجة وسنفرض أيضا على دِرَايَة -بقليلا من Node.js [`EventEmitters`][] و [`Streams`][]. إذا لم تكن فِعْلاً على دِرَايَة بهم وإنه -الجَدِير قيام بقراءة سريعة من خلال توثيقات واجهة برمجة التطبيقات (API) لكل منهم. - -## إنشاء الخادم - -أي تطبيق خادم الويب node وفي نقطة ما لإنشاء كائن خادم الويب، يتم ذلك -بإستعمال [`createServer`][]. - -```javascript -const http = require('http'); - -const server = http.createServer((request, response) => { - // السحر يحدث هنا! -}); -``` - -هذه الدالة تمرر داخل [`createServer`][] وهذا يدعى واحدة لكل طلب HTTP وهذا ما يجعله -مُقَابِلَ هذا الخادم ولذا يدعى معالج الطالب، في الحقيقة كائن الخادم [`Server`][] مرجع -بواسطة [`createServer`][] هو مُصدِر الحدث [`EventEmitter`][] و ما لدينا هنا فقط إختزال -لإنشاء كائن الخادم `server` وبعدها إضافة المستمع لاحقا. - -```javascript -const server = http.createServer(); -server.on('request', (request, response) => { - // نفس النوع من السحر يحدث هنا! -}); -``` - -عندما طلب HTTP يضرب الخادم، node يستدعي دالة معالجة الطالب مع القليل من الكائنات -المتاحة لتعامل مع المُدَاوَلَةٌ الطلب `request` و الجواب `response`، سوف نجلبهم قَرِيباً. - -في التقدم الفعلي لطلب الخادم، طريقة الإستماع [`listen`][] تحتاج لإستدعاء كائن الخادم -`server` في أغلب الحالات، كل ماتحتاج لتمريره للمستمع `listen` هو رقم المنفذ "port" الذي -تريد الخادم الإستماع إليه، يوجد بعض الخيارات الاخرى أيضا لذا راجع المرجع [API reference][]. - -## طريقة 'Method' و رابط 'URL' و رؤوس 'Headers' - -عند معالجة الطلب أول حاجَة ربما تود القيام بها هي تفقد الطرق و الرابط URL، لذا -هذه الإجراءات المُلاَئِمة يمكن إتخاذها. Node جعل هذه متعبة نسبيا بوضع خَواصُّ المعالجة داخل -كائن الطلب `request`. - -```javascript -const { method, url } = request; -``` - -> **ملاحظة:** كائن الطلب `request` هو مثيل لرسالة القادمة [`IncomingMessage`][]. - -الطريقة `method` هنا ستكون دائما HTTP method/verb عاديا و `url` هو الرابط بدون خادم و -البروتوكول أو المنفذ. لرابط نموذجي هذا يعني أن كل شئ بعد و مُتَضَمّن الخط مائلة للأمام "/" الثالث. - -الرؤوس هي أيضا ليست بعيدة جدا، هم يملكون كائن في الطلب `request` يدعى الرؤوس `headers`. - -```javascript -const { headers } = request; -const userAgent = headers['user-agent']; -``` - -من المهم أن نذكر هنا أن جميع الرؤوس تًظهر الأحرف الصغيرة فقط وبِغَضّ النّظَرِ عن كيف ما -أرسلها العميل. هذا يسهل عملية تحليل الرؤوس لأي غرض محتمل. - -إذا تم تكرار بعض الرؤوس وبعدها هذه القيم إعادة الكتابة عليها أو سلاسل مَوْصُولة بفاصلة -إسْتِنَاداً إلى الرأس، في بعض الحالات يمكن أن يكون مشكل لذا الروؤس الخام [`rawHeaders`][] -هي أيضا متاحة. - -## طلب الجسم (Request Body) - -عند تلقي طلب من `POST` أو `PUT`، جسم الطلب ربما يكون مهماً لتطبيقك. -للحصول على بيانات الجسم هو يَتَضَمّن أكثر من الوصول لطلبات الروؤس، -كائن الـ`request` تمرر داخل أدوات المعالجة لواجهة الـ[`ReadableStream`][]. -هذا التدفق يمكن الإستماع له أو نقله كأي تدفق أخر. يمكنك أخذ البيانات مباشرة -من التدفق عن طريق الإستماع إلى أحداث التدفقات `'data'` و `'end'`. - -الأجزاء الباعثة في كل `'data'` والحدث هو [`Buffer`][]. إذا كنت تعرف أنها -ستكون سِلْسِلَة من البيانات، أفضل شئ تفعله هو تجميع البيانات في مصفوفة -وبعدها في `'end'`، الرصفهم وتحويلهم إلى نصوص. - -```javascript -let body = []; -request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // في هذه النقطة، `body` عنده كامل طلب الجسم مخزن فيه على شكل سلسلة نصية - }); -``` - -> **ملاحظة:** قد يبدو هذا صبيانيا ومملا، وفي كثير من الحالات هو كذلك و لحسن الحظ -> هناك وحدات مثل [`concat-stream`][] و [`body`][] في [`npm`][] والتي يمكن أن تساعد -> في إخفاء بعضاً من هذا المنطق. من المهم أن تفهم جيدا ماذا يحدث قبل الخوض في هذا -> الطريق ولهذا السبب أنت هنا! - -## حاجَة سريعة حول الأخطاء - -بِما أَنَّ كائن `request` هو [`ReadableStream`][] إنه أيضًا [`EventEmitter`][] -و يتصرف كما أن خطأً قد حدث. - -أي خطأ في تدفق `request` يقدم نفسه ببعث لحدث `'error'` في التدفق. **إذا لم يكن -لديك مستمع لهذا الحدث، فالخطأ س*يلقي*، والتي سيحبط برنامج Node.js الخاص بك.** -ولذا يجب عليك إضافة مستمع لـ`'error'` على طلب تدفقاتك، حتى وإن سجلته فقط و -أكملت في طريقك.(ولو أنه من الأفضل لإرسال مشابه لخطأ جواب HTTP. المزيد على ذلك لاحقًا.) - -```javascript -request.on('error', err => { - // هذا يطبع رسالة الخطأ و أثره مكدس في `stderr`. - console.error(err.stack); -}); -``` - -هنالك طرق أخرى لمعالجة الأخطاء [handling these errors][] مثل بعض ملخصات و -الأدوات لكن كن دائمًا على دراية بأن الأخطاء يمكن أن تحدث وستحدث و ستقوم -بالتعامل معهم. - -## على ماذا حصلت لِحَدّ الآن - -في هذه النقطة لقد غطينا إنشاء خادم و إنْتِزاع الطرق و الروابط الروؤس و الجسم من -الطلبات. عندما نضع كل ذلك معا رُبّمَا ستظهر كما هذه: - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // في هذه النقطة، لدينا الرؤوس و الطريقة و الرابط و الجسم ويمكن الآن - // القيام بما نحتاج إليه في أمر للجواب لهذا الطلب - }); - }) - .listen(8080); // تنشيط الخادم و الاستماع على منفذ 8080. -``` - -إذا شغلنا هذا المثال سنكون قادرين على _تلقي_ الطلبات، لكن لا _نرد_ عليهم، -في حَقِيقَةِ الأمْر إذا عَرَض هذا في المتصفح، طلبك سيكون خارج المهلة ولاشئ يعاد -.إرساله للعميل - -حتى الآن نحن لم نلمس كائن الجواب `response` كلياً. أَيّما في ما ذاك لـ[`ServerResponse`][] -و مِمّ هو [`WritableStream`][]. أنه يحتوي على العديد من الطرق المفيدة لإرسال البيانات -الراجعة لعميل و سنقوم بتغطية ذلك لاحقا. - -## رمز الحالة HTTP - -إذا كنت لا تُبالي في إعداده، رمز الحالة لـHTTP سيكون دائما في الروؤس 200، -طبعاً ليس في كل جواب يعلمك به و في بعض النقاط حتما ستريد إرسال رمز حالة -مختلف، للقيام بهذا يمكنك تعيين خاصية `statusCode`. - -```javascript -response.statusCode = 404; // أخبر العميل أنه لم يتم العثور على المصدر. -``` - -هناك بعض الاختصارات الأخرى لهذا ، كما سنرى قريبًا. - -## إعداد جواب رؤوس - -يتم تعيين الرؤوس من خلال طريقة مناسبة تسمى [`setHeader`][]. - -```javascript -response.setHeader('Content-Type', 'application/json'); -response.setHeader('X-Powered-By', 'bacon'); -``` - -عند ضبط الرؤوس على الجواب، في الحالة التي تكون غير مدرك لأسمائهم. -إذا عينت الروؤس بشكل متكرر القيمة الأخيرة التي هي القيمة التي ترسل. - -## مُرفق إرسال بيانات الرأس - -الطرق لضبط الروؤس و رمز الحالة والتي سبق أن تناقشنا بإعتبرك أنك تستخدم "الروؤس المضمنة" -"implicit headers". هذا يعني أنك مُعْتَمِد على node للإرسال الروؤس لك في الوقت الحالي قبل البدء -في إرسال بيانات الجسم. - -إذا أردت يمكنك _تصريح_ بكتابة الروؤس لتدفق الجواب، للقيام بهذا يوجد طريقة تدعى [`writeHead`][] -التي تكتب رمز الحالة و الروؤس إلى التدفق. - -```javascript -response.writeHead(200, { - 'Content-Type': 'application/json', - 'X-Powered-By': 'bacon', -}); -``` - -بمجرد تعيينك الروؤس (سواء ضمنيًا أو صريحًا)، أنت مستعد للبدء في إرسال بيانات الجواب. - -## إرسال جواب الجسم - -بِما أَنَّ كائن الجواب `response` هو تدفق قابل للكتابة [`WritableStream`][]، كتابة جسم الجواب -خارجيا للعميل هي فقط مَسْألَة للإستخدام طرق التدفق الإعتيادية. - -```javascript -response.write(''); -response.write(''); -response.write('

Hello, World!

'); -response.write(''); -response.write(''); -response.end(); -``` - -دالة النهاية `end` في التدفقات يمكن ان تأخذ في بعض البيانات الإختيارية لإرسالها -كأخر حرف من البيانات في التدفقات لذا يمكن تبسيطها في المثال الأعلى. - -```javascript -response.end('

Hello, World!

'); -``` - -> **ملاحظة:** من المهم تعيين الحالة و الروؤس _قبل_ البدء بكتابة أقسام من البيانات -> للجسم وهذا يبدو منطقيا. منذ متى تأتي النص قبل الرؤوس في جوابات HTTP. - -## حاجَة أخرى سريعة حول الأخطاء - -تدفق الجواب `response` يمكن أن يبعث حالة الأخطاء `'error'` و بعض النقاط ستتعامل معه أيضا. -جميع النصائح لتدفق أخطاء الطلب `request` لاتزال تطبق هنا. - -## لنضعهم جميعا مع بعض - -الآن بعد أن تعلمنا عن عمل جوابات HTTP، لنقم بوضعهم كلهم معاً. -بناء على المثال السابق سنقوم بإنشاء خادم يعيد إرسال جميع البيانات التي إرسلها -إلينا من قِبل المستخدم وسنقوم بتنسيق البيانات على شكل JSON بإستعمال `JSON.stringify`. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // بداية الاشياء الجديدة - - response.on('error', err => { - console.error(err); - }); - - response.statusCode = 200; - response.setHeader('Content-Type', 'application/json'); - // ملاحظة: السطرين في الأعلى يمكن إستبداله بالسطر التالي. - // response.writeHead(200, {'Content-Type': 'application/json'}) - - const responseBody = { headers, method, url, body }; - - response.write(JSON.stringify(responseBody)); - response.end(); - // ملاحظة: السطرين في الأعلى يمكن إستبداله بالسطر التالي. - // response.end(JSON.stringify(responseBody)) - - // نهاية الاشياء الجديدة - }); - }) - .listen(8080); -``` - -## مثال لتردد خادم - -لنسهل المثال السابق لإنشاء خادم ترددي بسيط، أَيّ يرسل مهما كانت البيانات فقط والتي أستلمت -من توا من الجواب. كل ما نريد فعله هو أخذ طلب التدفق و كتابة البيانات في جواب التدفق وهو -مماثل ما فعلنا في السابق. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - }) - .listen(8080); -``` - -الآن لنقم تطويع هذه، نريد إرسال فقط تردد وفقا لشروط لمتبعة: - -- طريقة الطلب هي POST. -- الرابط 'URL' هو `/echo` - -في حالة أخرى نحن نريد تبسيط الرد مع 404. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -> **ملاحظة:** عند التحقق من الرابط URL بهذه الطريقة، نحن نقوم بشكل من التوجيه "routing". -> ويوجد أشكال أخرى للتوجيه بسيطة مثل دالة `بَدَّالَةٌ` `switch` أو معقدة كما في أدوات مثل -> [`express`][]. إذا كنت نبحث على شئ يقوم بالتوجيه ولاشئ أخر جرب [`router`][]. - -رائع! الآن نستقر على تبسيط هذا وتذكر كائنات الطلب `request` هي تدقف قابل للقراءة -[`ReadableStream`][] و كائنات الجواب `response` هي تدفق قابل للكتابة [`WritableStream`][]. -وهذا يعني أنه يمكننا إستخدام [`pipe`][] لتوجيه البيانات من واحدة لأخرى. وهذا تماما مانريده -من خادم إرتدادي! - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -أجل التدفقات! - -نحن لم ننتهي بعد على الرغم كما ذكرنا في عدة مرات في هذا الدليل، الأخطاء واردة -و نحتاج التعامل معها. - -لتعامل مع الأخطاء في طلب التدقف، وكذا مخرج الخطأ في `stderr` و إرسال رمز الحالة 404 -تدل على أن طلب سيء `Bad Request` ليس كما التطبيق في الحقيقي على أية حال، نود تفحص -الخطأ لمعرفة ماهو رمز الحالة الصحيح وما ستكون الرسالة كالعادة في الأخطاء،يجب عليك مراجعة -توثيقة `الخطأ` [`Error` documentation][]. - -في الجواب، سنسجل الخطأ فقط في`stderr`. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - request.on('error', err => { - console.error(err); - response.statusCode = 400; - response.end(); - }); - response.on('error', err => { - console.error(err); - }); - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -لقد قمنا الآن بتغطية أغلب الأساسيات مُعَالَجَة طالبات HTTP وفي هذه المرحلة من المفترض -تقدر على: - -تجسيد HTTP مع دالة معالجة الطلب و لإستماع للمنفذ. -الحصول على الرؤوس و الرابط 'URL' و طرق و بيانات الجسم من كائنات `request`. -صنع قرارات التوجيه إستنادا إلى الرابط و / أو بيانات أخرى في كائنات `request`. -إرسال الرؤوس و رموز حالات HTTP و بيانات الجسم بواسطة كائنات `request`. -نقل البيانات من كائنات `request` وإلى كائنات `response`. -تعامل مع أخطاء التدفق في حالتي تدقفات `request` و `response`. -من هذه الأساسيات، خوادم Node.js HTTP في العديد من حالات نَوْعِيّة يمكن إنشاؤه. يوجد -الكثير مثل هذه الأشياء مزودة بـAPIs لذا تأكد من قرأة التوثيقات الAPI منها -[`EventEmitters`][] و [`Streams`][] و [`HTTP`][]. - -[`EventEmitters`]: https://nodejs.org/api/events.html -[`Streams`]: https://nodejs.org/api/stream.html -[`createServer`]: https://nodejs.org/api/http.html#http_http_createserver_requestlistener -[`Server`]: https://nodejs.org/api/http.html#http_class_http_server -[`listen`]: https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback -[API reference]: https://nodejs.org/api/http.html -[`IncomingMessage`]: https://nodejs.org/api/http.html#http_class_http_incomingmessage -[`ReadableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_readable -[`rawHeaders`]: https://nodejs.org/api/http.html#http_message_rawheaders -[`Buffer`]: https://nodejs.org/api/buffer.html -[`concat-stream`]: https://www.npmjs.com/package/concat-stream -[`body`]: https://www.npmjs.com/package/body -[`npm`]: https://www.npmjs.com -[`EventEmitter`]: https://nodejs.org/api/events.html#events_class_eventemitter -[handling these errors]: https://nodejs.org/api/errors.html -[`ServerResponse`]: https://nodejs.org/api/http.html#http_class_http_serverresponse -[`setHeader`]: https://nodejs.org/api/http.html#http_response_setheader_name_value -[`WritableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_writable -[`writeHead`]: https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers -[`express`]: https://www.npmjs.com/package/express -[`router`]: https://www.npmjs.com/package/router -[`pipe`]: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options -[`Error` documentation]: https://nodejs.org/api/errors.html -[`HTTP`]: https://nodejs.org/api/http.html diff --git a/pages/ar/docs/guides/debugging-getting-started.md b/pages/ar/docs/guides/debugging-getting-started.md deleted file mode 100644 index efedba8d9f011..0000000000000 --- a/pages/ar/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: تصحيح الأخطاء - دليل البدء -layout: docs.hbs ---- - -# دليل التصحيح - -سيساعدك هذا الدليل للبدء في تصحيح سكريبتات و تطبيقات الـ Node.js الخاصة بك. - -## تمكين المدقق - -عند بدء الـ Node.js مع تمكين `--inspect`، يتم الانصات إلى عملية تصحيح، و افتراضيا، يتم هذا الانصات عبر المضيف و المنفذ 127.0.0.1:9229. -يتم إعطاء كل عملية إنصات رقم [UUID][] حصري. - -يجب على عميل التدقيق معرفة و تحديد عنوان المضيف و رقم المنفذ، إضافة إلى الـUUID حتى يتم الاتصال. -سيبدو العنوان كاملا كما يلي: -`ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e` - -ستستمع الـ Node.js إلى رسائل التصحيح إذا تلقت إشارة `SIGUSR1` (`SIGUSR1` غير متوفر على ويندوز)، حيث انه -في الـ Node.js 7 و ما قبله، ينشط إستقبال هذه الإشارة واجهة برمجة التطبيقات القديمة الخاصة بالتصحيح، -أما في الـ Node.js 8 و ما بعده، فذلك ينشط واجهة برمجة التطبيقات الخاصة بالمدقق - ---- - -## تأثيرات أمنية - -بما أن لدى مصحح الأخطاء وصولاً كاملاً إلى بيئة تنفيذ الـ Node.js، قد يمكن لبرمجية ضارة متصلة بهذا المنفذ أن تنفذ -شيفرات عشوائية من خلال عملية الـ Node، ولذلك فإنه من المهم فهم التأثيرات الأمنية المحتملة التي تنتج عن إتاحة -المنفذ الخاص بمصحح الأخطاء في الشبكات العامة و الخاصة. - -## إتاحة المنفذ الخاص بالتصحيح للعامة غير آمن - -إذا كان لمصحح الأخطاء عنوان عام، او كان عنوانه هو 0.0.0.0، فيمكن لأي عميل قادر على الوصول لعنوان الانترنت -الخاص بك أن يتواصل مع مصحح الأخطاء بدون أية قيود، و سيتمكن من تنفيذ برمجيات عشوائية. - -إفتراضيا، تأخذ العملية `node --inspect` العنوان 127.0.0.1، ويجب عليك تحديد العنوان العام لها صراحة سواء كان -0.0.0.0 أو غيره من العناوين إذا كنت تنوي ان تسمح بإتصالات خارجية لمصحح الأخطاء، ولكن فعل هذا قد يعرضك لمخاطر -أمنية جمة. تأكد من توظيف الجدران النارية و صلاحيات الوصول المناسبة لمنع أي تهديد أمني. - -إقرأ القسم المعنون بـ [سيناريوهات تمكين تصحيح الأخطاء عن بعد](#سيناريوهات-تمكين-تصحيح-الأخطاء-عن-بعد) للحصول -على بعض النصائح حول كيفية تمكين الاتصالات عن بعد بمصحح الأخطاء بشكل آمن. - -## التطبيقات المحلية تمتلك الوصول الكامل للمدقق - -حتى لو قمت بربط منقذ المدقق بالعنوان 127.0.0.1 (الإفتراضي)، فإن أي تطبيقات محلية ستحصل على صلاحية الوصول الكاملة -له. لقد تم تصميم ذلك حتى يتسنى لمصححات الأخطاء المحلية أن ترتبط به بالشكل المناسب. - -## المتصفحات و مآخذ الويب و سياسة نفس الأصل - -يمكن لمواقع الانترنت المفتوحة من متصفح أن تجري طلبات HTTP و webSockets تحت النموذج الأمني الخاص بالمتصفح، و يعد ضروريا -إجراء اتصال HTTP مبدئي لأجل الحصول على معرف حصري خاص بجلسة تصحيح الأخطاء. تمنع سياسة نفس الأصل المواقع من إجراء هذا الإتصال -وكتأمين من هجمات الـ [DNS rebinding](https://en.wikipedia.org/wiki/DNS_rebinding)، يقوم الـ Node.js بالتحقق من أن الرؤوس الخاصة -بالمضيف و الخاصة بالاتصال إما تحدد عنوانا أو `localhost` أو `localhost6` بدقة. - -تمنع سياسات التأمين هذه الإتصال عن طريق تحديد إسم المضيف بخادم لتصحيح الأخطاء عن بعد، لكن يمكنك إيجاد طريقة للالتفاف حول هذا بتحديد عنوان -بروتوكول الانترنت أو باستعمال نفق ssh كما هو موصوف اسفله. - -## برامج التدقيق - -هناك عدة أدوات مفتوحة المصدر يمكنها الإتصال بالدقق الخاص بالـ Node.js و ما يلي هي معلومات مبدئية عنها: - -### [node-inspect](https://github.com/nodejs/node-inspect) - -- مصحح أخطاء في سطر الأوامر مدعوم من مؤسسة الـ Node.js و يستعمل البروتوكول المسمى [Inspector Protocol][]. -- تشحن نسخة منه مع الـ Node و يمكن استعماله بواسطة الأمر `node inspect myscript.js`. -- يمكن تثبيت آخر نسخة منه بشكل مستقل (`npm install -g node-inspect` على سبيل المثال) و يمكن استعمالها بواسطة الأمر `node inspect myscript.js`. - -### [Chrome DevTools](https://github.com/ChromeDevTools/devtools-frontend) 55+ - -- **الطريقة الأولى**: قم بفتح العنوان `chrome://inspect` في أي متصفح مبني على Chromium. قم بالضغط على زر Configure و تأكد - من أن المضيف و المنفذ في القائمة. -- **الطريقة الثانية**: قم بنسخ `devtoolsFrontendUrl` من الناتج عن `/json/list` (أنظر أعلاه) أو النص التلميحي الناتج عن --inspect - و قم بلصقه في Chrome. - -### [Visual Studio Code](https://github.com/microsoft/vscode) 1.10+ - -- في قائمة تصحيح الأخطاء، إضغط على ايقونة الإعدادات لفتح `.vscode/launch.json`. - قم باختيار "Node.js" للتثبيت الأولي. - -### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- قم باختيار "Debug > Start Debugging" من القائمة أو قم بالضغط على F5. -- [خطوات تفصيلية بالإنجليزية](https://github.com/Microsoft/nodejstools/wiki/Debugging) - -### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) 2017.1+ و منتجات JetBrains الأخرى - -- قم بإنشاء إعدادات تصحيح جديدة خاصة بالـ Node.js و اضغط على Debug. سيتم استعمال `--inspect` افتراضياً بالنسبة للنسخ 7 فما فوق. - لإلغاء ذلك، قم بإلغاء تمكين `js.debugger.node.use.inspect` في السجل الخاص بالبرنامج. - -### [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - -- مكتبة تسهل التواصل بأطراف اتصال بروتوكول التدقيق. - -### [Gitpod](https://www.gitpod.io) - -- قم بإنشاء إعدادات تصحيح الأخطاء الخاصة بالـ Node.js من `Debug` أو قم بالضغط على F5. هنا [خطوات تفصيلية بالإنجليزية](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1) - -### [Eclipse IDE](https://eclipse.org/eclipseide) مع إضافة إكليبس الشاملة لتطوير الويب - -- من ملف .js، اختر "Debug As... > Node program", او -- إنشاء اعدادات المنقح لكي يتمكن من تشغيل تطبيق Node (بدأ بـ `--inspect`). - ---- - -## خيارات سطر الأوامر - -يبين الجدول الآتي تأثير كل تخصيص خاص بوقت التشغيل على تصحيح الأخطاء: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
التخصيصالمعنى
--inspect -
    -
  • يقوم بتمكين عميل التدقيق
  • -
  • يشتغل إفتراضيا على العنوان و المنفذ (127.0.0.1:9229)
  • -
-
--inspect=[host:port] -
    -
  • يقوم بتمكين عميل التدقيق
  • -
  • يحدد عنوانا أو إسم مضيف host (افتراضيا: 127.0.0.1)
  • -
  • يشتغل على المنفذ port (افتراضيا: 9229)
  • -
-
--inspect-brk -
    -
  • يقوم بتمكين عميل التدقيق
  • -
  • يشتغل على العنوان و المنفذ الافتراضيين (127.0.0.1:9229)
  • -
  • يتوقف قبل بدء تنفيذ شيفرة المستخدم
  • -
-
--inspect-brk=[host:port] -
    -
  • يقوم بتمكين عميل التدقيق
  • -
  • يحدد عنوانا قيمته host (افتراضيا: 127.0.0.1)
  • -
  • يشتغل على المنفذ port (افتراضيا: 9229)
  • -
  • يتوقف قبل بدء تنفيذ شيفرة المستخدم
  • -
-
node inspect script.js -
    -
  • يخبر العمليات الفرعية بتنفيذ السكربت الخاص بالمستخدم تحت علم --inspect مع استعمال العملية الرئيسية لتشغيل مصحح الأخطاء من سطر الأوامر.
  • -
-
node inspect --port=xxxx script.js -
    -
  • يخبر العمليات الفرعية بتنفيذ السكربت الخاص بالمستخدم تحت علم --inspect مع استعمال العملية الرئيسية لتشغيل مصحح الأخطاء من سطر الأوامر.
  • -
  • يشتغل عبر المنفذ port (افتراضيا: 9229)
  • -
-
- ---- - -## سيناريوهات تمكين تصحيح الأخطاء عن بعد - -نوصي دائما بعدم تشغيل مصحح الأخطاء على عنوان انترنت عام. إذا أردت تمكين تصحيح الأخطاء عن بعد، فننصح بإستعمال قنوات الـ ssh بدلا من ذلك. -المثال الآتي لأغراض توضيحية فقط. يجب عليك فهم المخاطر الأمنية المحتملة عند السماح بالوصول عن بعد لخدمة ذات امتيازات قبل أن تمضي قدما. - -فلنفترض أنك قمت بتشغيل الـ Node في حاسوب بعيد، remote.example.com على سبيل المثال، و تريد ان تتمكن من تصحيح الأخطاء فيها. -في ذلك الحاسوب البعيد، عليك بدء عملية node مع جعل المدقق يستمع على المضيف المحلي فقط (وهو الافتراضي). - -```bash -node --inspect server.js -``` - -الآن، و على حاسوبك المحلي الذي تريد من خلاله إنشاء اتصال بعميل تصحيح الأخطاء، يمكنك إنشاء قناة ssh: - -```bash -ssh -L 9221:localhost:9229 user@remote.example.com -``` - -يقوم هذا الأمر بإنشاء جلسة لقناة ssh حيث يتم إعادة توجيه الإتصال من المنفذ 9221 على جهازك المحلي إلى المنفذ 9221 على النطاق remote.example.com. -يمكنك الآن ربط مصحح أخطاء مثل Chrome DevTools أو Visual Studio Code بالعنوان localhost:9221 -مما يعني أنه قادر على بدء تصحيح الأخطاء كما لو أن تطبيق الـ Node.js يشتغل محليا. - ---- - -## مصحح الأخطاء القديم - -\*\*لقد تم اعتبار مصحح الأخطاء القديم قديماً ابتداء من نسخة الـ Node 7.7.0. قم باستعمال --inspect -أو المدقق بدلا منه. - -عند تشغيل مصحح الأخطاء القديم مع **--debug** أو **--debug-brk** في النسخة 7 -و ما قبلها، تستمع الـ Node.js إلى تعليمات التصحيح المعرفة من قبل بروتوكول التصحيح الخاص بالـ V8 الذي تم ايقاف تطويره و ذلك على منفذ TCP -`5858` افتراضياً. يستطيع أي عميل تصحيح يستخدم هذا البروتوكول أن يتصل و يصحح العملية الجاري تنفيذها، و من أشهرها ما سيُذكر أسفله. - -إن بروتوكول التصحيح الخاص بالـ V8 لم تعد يتم صيانته أو توثيقه دوريا. - -### [مصحح الأخطاء المبني ضمنيا](https://nodejs.org/dist/latest/docs/api/debugger.html) - -قم بتنفيذ الأمر `node debug script_name.js` لبدء النص البرمجي الخاص بك عن طريق مصحح الأخطاء المبني ضمنيا في Node. -يمكن للنص البرمجي الخاص بك أن يبدأ في عملية Node اخرى باستعمال `--debug-brk` كما تشغل عملية Node -المبدئية الملف `_debugger.js` و توصلك بوجهتك. - -### [node-inspector](https://github.com/node-inspector/node-inspector) - -قم بتصحيح الأخطاء في تطبيق Node.js الخاص بواسطة الـ Chrome DevTools و ذلك باستعمال عملية وسيطة تقوم بتحويل -بروتوكول المدقق المستعمل في Chromium إلى بروتوكول تصحيح الأخطاء في الـ V8 المستعمل في الـ Node.js - - - -[Inspector Protocol]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/ar/docs/guides/getting-started-guide.md b/pages/ar/docs/guides/getting-started-guide.md deleted file mode 100644 index ef11ed81c827c..0000000000000 --- a/pages/ar/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: دليل البدء -layout: docs.hbs ---- - -# كيف أبدأ باستعمال الـ Node.js بعد أن قمت بتثبيته؟ - -بعد تثبيتك للـ Node، دعنا نجرب كيفية بناء أول خادوم ويب باستعماله. -قم بإنشاء ملف بإسم "app.js" و ألصق داخله الشفرة الآتية: - -```javascript -const http = require('http'); -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -بعد ذلك، قم بتشغيل هذا الخادوم باستعمال الأمر `node app.js`، و قم بزيارة الرابط `http://localhost:3000` لترى رسالة مفادها 'Hello World'. diff --git a/pages/ar/docs/guides/index.md b/pages/ar/docs/guides/index.md deleted file mode 100644 index 793ee8c4d8412..0000000000000 --- a/pages/ar/docs/guides/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: الإرشادات -layout: docs.hbs ---- - -# الإرشادات - -## عام - -- [دليل البدء](/ar/docs/guides/getting-started-guide/) -- [التنقيح - البدء](/ar/docs/guides/debugging-getting-started/) -- [سهل التنميط من أجل تطبيقات Node.js](/en/docs/guides/simple-profiling/) -- [عمل دوكر على تطبيق ويب Node.js](/en/docs/guides/nodejs-docker-webapp/) -- [ترحيل إلى منشئات Buffer آمنة](/en/docs/guides/buffer-constructor-deprecation/) - -## المفاهيم الأساسية في الـ Node.js - -- [مقارنة عامة بين Blocking و Non-Blocking](/en/docs/guides/blocking-vs-non-blocking/) -- [الـ Node.js حلقة التكرارية، المؤقتات و process.nextTick()](/en/docs/guides/event-loop-timers-and-nexttick/) -- [لا تعرقل الحلقة التكرارية (أو يحشد العمل)](/en/docs/guides/dont-block-the-event-loop/) -- [مؤقتات في Node.js](/en/docs/guides/timers-in-node/) - -## الأدلة لوحدة المتعلقة - -- [التشريح لمعاملات HTTP](/ar/docs/guides/anatomy-of-an-http-transaction/) -- [العمل مع مختلف أنظمة الملفات](/en/docs/guides/working-with-different-filesystems/) -- [الضغط الخلفي في القنوات](/en/docs/guides/backpressuring-in-streams/) -- [مِقْيَاسُ مَجَال تحليل](/en/docs/guides/domain-postmortem/) -- [كيفية نشر حزمة N-API](/ar/docs/guides/publishing-napi-modules/) -- [استقرارية ABI](/ar/docs/guides/abi-stability/) diff --git a/pages/ar/docs/guides/publishing-napi-modules.md b/pages/ar/docs/guides/publishing-napi-modules.md deleted file mode 100644 index 89c65c154dd05..0000000000000 --- a/pages/ar/docs/guides/publishing-napi-modules.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: كيفية نشر حزمة N-API -layout: docs.hbs ---- - -# نشر نسخة N-API لحزمة موازية مع نسخة غير خاصة بـ N-API - -يتم توضيح الخطوات الآتية بإستعمال حزمة `iotivity-node`: - -- كخطوة أولى، قم بنشر النسخة الغير خاصة بالـ N-API من الحزمة. - - قم بتحديث النسخة في ملف `package.json`. بالنسبة لـ `iotivity-node` فإن النسخة ستصبح `1.2.0-2` - - قم بتفحص قائمة التأكيدات الخاصة بالإصدارات (تأكد من ان test/demos/docs على ما يرام) - - `npm publish` -- بعد ذلك، قم بنشر النسخة الخاصة بالـ N-API: - - قم بتحديث النسخة في ملفة `package.json`. في حالة `iotivity-node`، فإن النسخة ستصبح `1.2.0-3`. عند وضع أرقام النسخ، ننصحك بإتباع الطريقة الآتية لوضع نسخ قبلية: - [semver.org](https://semver.org/#spec-item-9). `1.2.0-napi` كمثال. - - قم بتفحص قائمة التأكيدات الخاصة بالإصدارات (تأكد من ان test/demos/docs على ما يرام) - - `npm publish --tag n-api` - -في هذا المثال، فإن وسم الحزمة بالوسم `n-api` سيضمن ذلك، رغم أن النسخة 1.2.0-3 احدث من آخر نسخة غير خاصة بالـ N-API تم نشرها (1.2.0-2). لن يتم تثبيت الحزمة إذا قام احدهم بفعل ذلك عن طريق الأمر -`npm install iotivity-node` ، بل سيتم تثبيت نسخة غير خاصة بالـ N-API افتراضيا. -حتى يتمكن المستخدم من تثبيت نسخة خاصة بالـ N-API، يجب عليه تنفيذ الأمر `npm install iotivity-node@n-api`. -لمزيد من المعلومات حول كيفية استعمال الوسوم مع مدير حزم النود، قم بزيارة ["Using dist-tags"][]. - -## كيفية تقديم اعتماد في نسخة لحزمة خاصة بـ N-API - -لإضافة نسخة خاصة بالـ N-API من حزمة `iotivity-node` كإعتماد ، يجب على ملف `package.json` أن يبدو كما يلي: - -```json -"dependencies": { - "iotivity-node": "n-api" -} -``` - -**ملاحظة** مثل ما تم شرحه في ["Using dist-tags"][]، و على النقيض من النسخ العادية، فإن النسخ الموسومة لا يمكن ان يُشار إليها باستعمال "مدى النسخ" مثل `"^2.0.0"` داخل ملف `package.json`، وسبب ذلك هو أن الوسم يشير لنسخة واحدة فقط لذلك، إذا اختار الشخص المسؤول عن الحزمة أن يسم نسخة احدث من الحزمة باستعمال نفس الوسم، فإن الأمر `npm update` سيستقبل آخر نسخة، و هذا عادي نظرا لكون الـ N-API ما يزال اختباريا. -لاستعمال اعتماد خاص بنسخة تدعم N-API عدا عن آخر نسخة تم نشرها، يجب ان يشار في ملف `package.json` إلى النسخ بالتحديد كما يلي: - -```json -"dependencies": { - "iotivity-node": "1.2.0-3" -} -``` - -["Using dist-tags"]: https://docs.npmjs.com/getting-started/using-tags diff --git a/pages/ar/docs/index.mdx b/pages/ar/docs/index.mdx deleted file mode 100644 index 1700141c6a024..0000000000000 --- a/pages/ar/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: التوثيق -layout: docs.hbs -labels: - lts: LTS ---- - -# عن التوثيق - -تتوفر عدة توثيقات على هذا الموقع: - -- التوثيق الخاص بمرجع واجهة برمجة التطبيق (API) -- مميزات ES6 -- الإرشادات - -## التوثيق الخاص بمرجع واجهة برمجة التطبيق (API) - -يوفر [التوثيق الخاص بمرجع واجهة برمجة التطبيق](https://nodejs.org/api/) معلومات مفصلة حول أي دالة أو كائن في الـ Node.js، حيث يبين هذا التطبيق أيا من المعطيات تقبلها دالة معينة، والقيمة التي ترجعها تلك الدالة إضافة إلى الأخطاء التي لها علاقة بتلك الدالة، كما يبين التوثيق أيضاً أي دوال متوفرة في النسخ المختلفة من الـ Node.js. - -يصف هذا التوثيق الوحدات المضمنة في الـ Node.js، وهو لا يوثق للوحدات المتوفرة عن طريق المجتمع. - -
- -### تبحث عن توثيق لنسخة سابقة؟ - - - -[كافة النسخ](https://nodejs.org/docs/) - -
- -## خصائص الـ ES6 - -يصف [قسم الـ ES6](/ar/docs/es6/) مجموعات الميزات الثلاثة الخاصة بالـ ES6، ويتحدث بالتفصيل عن المميزات المفعلة افتراضيا منها في الـ Node.js مع توفير روابط للشرح، كما يبين أي نسخة من الـ V8 يتم استعمالها مع إصدار محدد من الـ Node.js - -## الإرشادات - -يحتوي [قسم الإرشادات](/ar/docs/guides/) على مقالات مطولة ومعمقة حول القدرات والمميزات التقنية للـ Node.js diff --git a/pages/ar/download/current.md b/pages/ar/download/current.md deleted file mode 100644 index b93cca06e4860..0000000000000 --- a/pages/ar/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: التنزيلات -download: تنزيل -downloads: - headline: التنزيلات - lts: مستقر - current: الحالي - tagline-current: يحتوي على آخر الميزات - tagline-lts: موصى به لأغلب المستخدمين - display-hint: عرض التنزيلات لـ - intro: > - قم بتنزيل الكود المصدري للنود جي اس أو مثبت مبني لمنصتك و ابدأ التطوير اليوم. - currentVersion: آخر نسخة مستقرة - buildInstructions: بناء Node.js من المصدر على منصات مدعومة - WindowsInstaller: مثبت للويندوز - WindowsBinary: ملف ثنائي للويندوز - MacOSInstaller: مثبت للماك - MacOSBinary: ملف ثنائي للماك - LinuxBinaries: ملف ثنائي للينكس - SourceCode: الكود المصدري -additional: - headline: منصات إضافية - intro: > - يقوم أعضاء من مجتمع Node.js بالاشراف على نسخ غير رسمية من Node.js لمنصات أخرى. يجب التذكير أن هذه النسخ غير مدعومة من الفريق الأساسي للنود جي اس و قد لا تكون على نفس مستوى التطوير الخاص بالاصدارات الحالية للنود جي اس. - platform: منصة - provider: مزود - SmartOSBinaries: ملف ثنائي لـSmartOS - DockerImage: اسطوانة دوكر - officialDockerImage: اسطوانة نود جي اس الرسمية الخاصة بالدوكر - LinuxPowerSystems: لينكس على Power LE Systems - LinuxSystemZ: لينكس على System z - AIXPowerSystems: AIX على Power Systems ---- diff --git a/pages/ar/download/index.md b/pages/ar/download/index.md deleted file mode 100644 index 69d6c33fe4d5b..0000000000000 --- a/pages/ar/download/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -layout: download.hbs -title: التنزيلات -download: تنزيل -downloads: - headline: التنزيلات - lts: مستقر - current: الحالي - tagline-current: يحتوي على آخر الميزات - tagline-lts: موصى به لأغلب المستخدمين - display-hint: عرض التنزيلات لـ - intro: > - قم بتنزيل الكود المصدري للنود جي اس أو مثبت مبني لمنصتك و ابدأ التطوير اليوم. - currentVersion: آخر نسخة مستقرة - buildInstructions: بناء Node.js من المصدر على منصات مدعومة - WindowsInstaller: مثبت للويندوز - WindowsBinary: ملف ثنائي للويندوز - MacOSInstaller: مثبت للماك - MacOSBinary: ملف ثنائي للماك - LinuxBinaries: ملف ثنائي للينكس - SourceCode: الكود المصدري -additional: - headline: منصات إضافية - intro: > - platform: منصة - provider: مزود - SmartOSBinaries: ملف ثنائي لـSmartOS - DockerImage: اسطوانة دوكر - officialDockerImage: اسطوانة نود جي اس الرسمية الخاصة بالدوكر - LinuxPowerSystems: لينكس على Power LE Systems - LinuxSystemZ: لينكس على System z - AIXPowerSystems: AIX على Power Systems ---- diff --git a/pages/ar/download/package-manager.md b/pages/ar/download/package-manager.md deleted file mode 100644 index 30224818a93c3..0000000000000 --- a/pages/ar/download/package-manager.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -layout: page.hbs -title: تثبيت Node.js عن طريق مدير الحزم ---- - -# تثبيت النود جي اس عبر مدير حزم - -**_ملاحظة_** إن صيانة و دعم الحزم المذكورة في هذه الصفحة تتم عبر المشرفين على مديري الحزم، و **ليس** فريق النود جي اس الأساسي. تفضل بإبلاغ أية مشكلة إلى المشرفين على الحزم و إذا كانت مشكلتك عبارة عن خطأ في النود جي اس بحد ذاتها فسيبلغ المشرف عن هذه المشكلة صعودا. - ---- - -- [آندرويد](#android) -- [Arch Linux](#arch-linux) -- [التوزيعات المبنية على ديبيان أو اوبنتو، لينكس للمؤسسات / فيدورا و حزم سناب](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE و SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS و illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows1) - ---- - -## آندرويد - -لا يزال دعم النود جي اس على الاندرويد قيد التجربة، لذلك فإن الملفات الثنائية المنتجة قبلا لا تزال غير متوفرة من قبل مطوري النود جي اس. - -رغم ذلك، هناك بعض الحلول الموفرة من طرف ثالث، فمثلا يوفر مجتمع [Termux](https://termux.com/) محاكي طرفية و بيئة لينكس للأندرويد، إضافة إلى مدير حزم خاص و [مجموعة واسعة](https://github.com/termux/termux-packages) من العديد من التطبيقات المنتجة قبلا. -الأمر التالي سيثبت آخر نسخة متوفرة من النود جي اس: - -```bash -pkg install nodejs -``` - -حاليا، النسخ الثنائية الخاصة بـ Termux و هي مربوطة بـ `system-icu` (تعتمد على حزمة `libicu`). - -## Arch Linux - -تتوفر حزم النود جي اس و الـ npm على مستوى مستودعات المجتمع. - -```bash -pacman -S nodejs npm -``` - -## التوزيعات المبنية على ديبيان أو اوبنتو، لينكس للمؤسسات / فيدورا و حزم سناب - -يتم توفير [الملف الثنائي الرسمي للنود جي اس](https://github.com/nodesource/distributions) من قبل NodeSource. - -## FreeBSD - -آخر إصدارات النود جي اس متوفرة عبر [www/node](https://www.freshports.org/www/node) - -يمكنك تثبيت حزمة ثنائية عبر [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): - -```bash -pkg install node -``` - -او يمكنك انتاجها باستعمال الـ[ports](https://www.freebsd.org/cgi/man.cgi?ports) الخاص بك: - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -النود جي اس متوفر عبر portage tree. - -```bash -emerge nodejs -``` - -## IBM i - -نسخ LTS لـNode.js متوفرة من IBM و متوفرة عبر [مدير الحزمة الـ'yum'](https://ibm.biz/ibmi-rpms). إسم الحزمة هو `nodejs` متبوعا برقم الإصدار الرائد (مثلا، `nodejs8`، `nodejs10`، `nodejs12`، إلخ - -لتثبيت Node.js 12.x باستخدام سطر الأوامر، شغل الامر التالي كمستخدم مع سلطة \*ALLOBJ الخاصة : - -```bash -yum install nodejs12 -``` - -يمكن أيضًا تثبيت Node.js مع منتج IBM i الخاص بحلول وصول العملاء. انظر [وثيقة الدعم هذه](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) لتفاصيل أكثر - -## NetBSD - -النود جي اس متوفر في pkgsrc tree: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -أو يمكنك تثبيت حزمة ثنائية (إذا كانت متوفرة لمنصتك) باستعمال pkgin: - -```bash -pkgin -y install nodejs -``` - -## nvm - -مدير نسخ النود هو عبارة عن سكريبت خاص بالباش يستخدم لإدارة عدة نسخ من النود جي اس، حيث يسمح لك بالقيام بعمليات مختلفة كتثبيت و إلغاء تثبيت و تبديل نسخة معينة و اكثر من ذلك. -لتثبيت مدير نسخ النود استعمل [سكريبت التثبيت](https://github.com/nvm-sh/nvm#install--update-script). - -على انظمة يونيكس و OS X، يمكن تثبيت نسخة من النود جي اس تم بنائها من المصدر عبر [مدير نسخ النود (nvm)](https://github.com/creationix/nvm) عبر تثبيتها في المسار الذي يتوقعه مدير نسخ النود: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -بعد قيامك بهذه الخطوة، يمكنك استعمال مدير نسخ النود للتبديل بين النسخ المحررة و النسخ المبنية من المصدر. -على سبيل المثال ، اذا كانت نسخة النود جي اس الحالية هي v8.0.0-pre: - -```bash -nvm use 8 -``` - -حالما يتم إطلاق نسخة رسمية، قم بإلغاء تثبيت النسخة المبنية من المصدر: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -The `nvs` version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems - -To install `nvs` on Windows go to the [release page](https://github.com/jasongin/nvs/releases) here and download the MSI installer file of the latest release. - -You can also use `chocolatey` to install it: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -You can find the documentation regarding the installation steps of `nvs` in macOS/Unix-like systems [here](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Usage - -After this you can use `nvs` to switch between different versions of node. - -To add the latest version of node: - -```bash -nvs add latest -``` - -Or to add the latest LTS version of node: - -```bash -nvs add lts -``` - -Then run the `nvs use` command to add a version of node to your `PATH` for the current shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -To add it to `PATH` permanently, use `nvs link`: - -```bash -nvs link lts -``` - -## OpenBSD - -يتوفر النود جي اس حاليا عبر نظام البوابات. - -```bash -/usr/ports/lang/node -``` - -باستعمال [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) على OpenBSD: - -```bash -pkg_add node -``` - -## openSUSE و SLE - -يتوفر النود جي اس في المستودعات الرئيسية تحت الحزم الاتية: - -- **openSUSE Leap 42.2**: `nodejs4` -- **openSUSE Leap 42.3**: `nodejs4`, `nodejs6` -- **openSUSE Tumbleweed**: `nodejs4`, `nodejs6`, `nodejs8` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs4`, `nodejs6` - (يجب إضافة الـ "موديل الويب و البرمجة" [قبل التثبيت](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html)) - -على سبيل المثال، لتثبيت النود جي اس 4.x على openSUSE Leap 42.2 قم بتنفيذ ما يلي كجذر: - -```bash -zypper install nodejs4 -``` - -## macOS - -بكل بساطة، قم بتنزيل [مثبت الماك او اس](https://nodejs.org/ar/#home-downloadhead) مباشرة من موقع [nodejs.org](https://nodejs.org/). - -_إذا كنت تريد تنزيل الحزمة باستعمال الباش:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### البدائل - -باستعمال **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -باستعمال **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# على سبيل المثال -port install nodejs7 -``` - -باستعمال **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -تثبيت الحزمة الثنائية: - -```bash -pkgin -y install nodejs -``` - -من أو قم ببنائها يدويا من pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## SmartOS و illumos - -تأتي اسطوانة SmartOS مثبتة افتراضيا مع pkgsrc. على توزيعات أخرى من illumos، قم بتثبيت **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)** أولا و عندها يمكنك تثبيت الحزمة الثنائية اعتياديا: - -```bash -pkgin -y install nodejs -``` - -او قم ببنائها يدويا من pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -توفر Solus النود جي اس في مستودعها الرئيسي. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -يوفر Void Linux نسخة مستقرة من النود جي اس في المستودع الرئيسي. - -```bash -xbps-install -Sy nodejs -``` - -## ويندوز - -قم بتحميل [المثبت الخاص بويندوز](https://nodejs.org/ar/#home-downloadhead) مباشرة من موقع [nodejs.org](https://nodejs.org/). - -### البدائل - -باستعمال **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# أو للتثبيت الكامل بواسطة npm -cinst nodejs.install -``` - -باستعمال **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -``` diff --git a/pages/ar/download/releases.md b/pages/ar/download/releases.md deleted file mode 100644 index d78d04ace0b13..0000000000000 --- a/pages/ar/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: النسخ سابقة -modules: 'يشير NODE_MODULE_VERSION إلى رقم نسخة Node.js الخاص بالواجهة الثنائية (ABI) للتطبيق، وهو يستعمل لتحديد أي من نسخ Node.js المنتجة كملفات ثنائية خاصة بالسي ++ يمكنها ان تحمل بدون الحاجة إلى إعادة انتاجها. في وقت سابق، كان يتم تخزينها على شكل قيم ستة عشرية (hex) اما الآن فهي تمثل على شكل ارقام صحيحة' ---- - -### io.js و Node.js - -لقد كانت الاصدارات من 1.x إلى 3.x تسمى "io.js" و كانت جزء من فرع io.js، اما بالنسبة للنود جي اس 4.0.0، فإن اسطر النسخ السابقة من io.js تلاقت مع Node.js 0.12.x في نسخ موحدة - -### هل تبحث عن آخر اصدار من فرع محدد؟ diff --git a/pages/ar/get-involved/collab-summit.md b/pages/ar/get-involved/collab-summit.md deleted file mode 100644 index 9305bb9eed758..0000000000000 --- a/pages/ar/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: القمة التعاونية -layout: contribute.hbs ---- - -# القمة التعاونية - -القمة التعاونية هي مؤتمر غايته جمع المساهمين الحاليين مع المساهمين المحتملين للنقاش حول الـ Node.js وذلك بتعاون وتعليم حيين، و بمشاركة المعارف . تجتمع اللجان و مجموعات العمل مرتين في السنة للاتخاذ قرارات مهمة مع القدرة على العمل على بعض الجهود الشيقة التي يريدون دعمها شخصيا. - -## من يستطيع الحضور ؟ - -جميع الأشخاص مرحب بهم لحضور قمة تعاونية. ، خلال القمة، سيساعد القادة المتعاونين على الانخراط في المجموعات التي يودون المساعدة فيها و ذلك لدمجهم في ورشات العمل. -. -هذه فرصتك لتعلم ما يحدث داخل المجتمع، حتى تساهم فيه بالمهارات التي تمتلكها و تريد صقلها. - -ستضع مجموعات العمل رزنامات معاً حتى يتسنى للأشخاص ان يعتادوا عليها قبل الإنطلاق، و ذلك بإجراء الأحاديث العامة بين المتعاونين، و من ثم التعمق في الورشات. - -سوف يسرنا أن نراك في قمة تعاونية! قم بزيارة مستودع [Summit repo](https://github.com/nodejs/summit) لمعرفة القمم التعاونية القادمة و التي انقضت، و ألقِ نظرة على [المشاكل المطروحة](https://github.com/nodejs/summit/issues) التي تحتوي على ما تتطلع اللجان و مجموعات العمل لمناقشته شخصيا. diff --git a/pages/ar/get-involved/contribute.md b/pages/ar/get-involved/contribute.md deleted file mode 100644 index d351d1b967d1a..0000000000000 --- a/pages/ar/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: المساهمة -layout: contribute.hbs ---- - -# المساهمة - -شكراً لاهتمامك بالمساهمة في الـ Node.js! هنالك عدة طرق و أماكن يمكنك المساهمة فيها، و نحن هنا لتسهيل ذلك. - -## طلب مساعدة عامة - -الأسئلة المتعلقة بأي مساعدة عامة توجه إلى [مستودع المساعدة للـ Node.js](https://github.com/nodejs/help/issues) و ذلك لأن مستودع `nodejs/node` نشيط جدا. - -## الإبلاغ عن مشكلة - -إذا وجدت أي شيء تعتقد انه مشكلة في الـ Node.js، لا تتردد في في فتح مشكلة على المشروع في الـ GitHub. عند طرح مشكلتك، احرص على ان تعبر عنها بفحوصات قابلة للاعادة، كما يجب على تلك الفحوصات ألا تستعين بأي مكتبات خارجية. بشكل أوضح، يجب على تلك الفحوصات ان تكون قابلة للتنفيذ اعتماداً على الـ Node.js لا أكثر. - -عند التبليغ عن مشكل، نحتاج اكبر قدر ممكن من المعلومات حول بيئة التشغيل التي تستعملها. لا ندري أي معلومة لها صلة وثيقة بالمشكلة عند محاولة حصر المشكلة، قم بتضمين المعلومات التالية على الأقل: - -- إصدار الـ Node.js -- منصة التشغيل التي تعمل عليها (macOS, SmartOS, Linux, Windows) -- بنية حاسوبك (32 بت أو 64 بت و x86 أو ARM) - -حاليا، يتم تسيير مشروع الـ Node.js على عدد من المستودعات في الـ GitHub، ولكل واحد منها قاعدة بيانات مستقلة للمشكلات الخاصة بها. إذا أمكن، قم بطرح المشكلة التي تنوي الإبلاغ عنها في المستودع المناسب و لكن لا تقلق إذا وضعتها في المكان الخطأ، فمجتمع المساهمين سيكون سعيدا بتوجيهك إلى المستودع الملائم. - -- لإبلاغ عن مشكلة خاصة بالـ Node.js ، الرجاء إستخدام [nodejs/node](https://github.com/nodejs/node) -- لإبلاغ عن مشكلة خاصة بالموقع،الرجاء إستخدام [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## المساهمات في الشفرة المصدرية - -إذا أردت المساهمة في إصلاح أخطاء برمجية، إو إضافة ميزات للـ Node.js، تأكد من إطلاعك على [دليل المساهمة في الـ Node.js](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). ستجد شرحاً عن عمليات المراجعة من قبل المساهمين الحاليين في جميع المستودعات الخاصة بالمشروع. - -إذا كنت تتسائل حول كيفية البدء، يمكنك الإطلاع على [Node Todo](https://www.nodetodo.org/)، حيث يمكن له أن يريك كيفية القيام بمساهمتك الأولى. - -## كيف تصبح مساهماً - -عندما تصبح مساهما، تمتلك تأثيراً أكبر على المشروع. يمكن للمساهمين مساعدة بعضهم عبر مراجعة مساهماتهم، و تقصي المشكلات، و حتى تشكيل مستقبل المشروع، كما يمكن للأفراد الذين تحددهم لجنة التوجيه التقني بأنهم يقدمون مساهمات نوعية أن يتم ترقيتهم لمتعاونين، و يتم منحهم حق الكتابة في المشروع، حيث تمثل الأنشطة التي يتم أخذها بعين الاعتبار (ولكنها غير محدودة بها) نوعية: - -- المساهمة في الشفرة المصدرية و طلبات السحب -- المساهمة في التوثيق و طلبات السحب -- التعليقات على المشاكل و طلبات السحب -- المساهمات في موقع الـ Node.js -- المساعدة المقدمة للمستخدمين النهائيين و المساهمين الجدد -- المشاركة في مجموعات العمل -- المشاركات الأخرى في مجتمع الـ Node.js بصفة عامة. - -إذا كان هناك فرد يقوم بمساهمات قيمة ولا يريد ان يمنح حق الكتابة، يمكن له ان [يطرح مشكلة](https://github.com/nodejs/TSC/issues) او يتواصل مع [أحد أعضاء لجنة التوجيه التقني](https://github.com/nodejs/TSC#current-members). diff --git a/pages/ar/get-involved/index.md b/pages/ar/get-involved/index.md deleted file mode 100644 index 4f7e36334f324..0000000000000 --- a/pages/ar/get-involved/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: الإنخراط -layout: contribute.hbs ---- - -# الإنخراط - -## نقاش المجتمع - -- تعتبر [قائمة المشكلات على GitHub](https://github.com/nodejs/node/issues) المكان المخصص للنقاشات حول المميزات الأساسية للـ Node.js. -- الحساب الرسمي للـ Node.js على تويتر هو [nodejs](https://twitter.com/nodejs) -- [رزنامة مؤسسة الـ Node.js](https://nodejs.org/calendar) تحتوي على تواريخ لقاءات جميع الفرق العامة. - -## التعلم - -- [التوثيق الرسمي لواجهة برمجة التطبيق](https://nodejs.org/api/) يتحدث بالتفصيل على وجاهة برمجة التطبيق الخاصة بالـ Node.js -- [دلائل الـ Node.js](https://nodejs.dev) يرشدك إلى أساسيات تطوير تطبيقات باستعمال الـ Node.js. -- [NodeSchool.io](https://nodeschool.io/) سيعلمك مفاهيم الـ Node.js باستعمال العاب سطر اوامر تفاعلية. -- [التاق الخاص بالـ Node.js على Stack Overflow](https://stackoverflow.com/questions/tagged/node.js) يجمع معلومات جديدة كل يوم. -- [التاق الخاص بمجتمع مطوري الـ Node.js](https://dev.to/t/node) يمثل مكانا لمشاركة مشاريع الـ Node.js و المقالات و الدروس المتعلقة به إضافة إلى بدء النقاشات و طلب الآراء عن المواضيع المتعلقة بالـ Node.js. إن جميع المطورين من كافة المستويات مرحب بها هنا. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) هو مجتمع داعم لمطوري الجهة الخلفية للـ Node.js الذين يدعمون بعضهم على منصة Discord. - -## مواقع و مشاريع المجتمع دولي - -- [مجموعة الفيسبوك للـ Node.js بالعربية](https://www.facebook.com/groups/node.ar) -- [مجتمع Node.js الصيني](https://cnodejs.org/) -- [المجتمع المجري (المجرية)](https://nodehun.blogspot.com/) -- [مجموعة المستخدمين اليابانية](https://nodejs.jp/) -- [مجموعة الفيسبوك باللغة الأسبانية للـ Node.js](https://www.facebook.com/groups/node.es/) -- [مجتمع Node.js الفيتنامي](https://www.facebook.com/nodejs.vn/) -- [المجموعة الأوزبكستانية لـ Node.js](https://t.me/nodejs_uz) diff --git a/pages/ar/index.md b/pages/ar/index.md deleted file mode 100644 index d38d3be315ef1..0000000000000 --- a/pages/ar/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: الإصدار الحالي - download: تحميل - download-for: تحميل النسخة الخاصة بـ - other-downloads: تحميل نسخ أخرى - current: النسخة الحالية - lts: LTS - tagline-current: آخر المستجدات - tagline-lts: موصى به لجميع المستخدمين - changelog: سجل التغييرات - api: API Docs - version-schedule-prompt: أو انظر إلى - version-schedule-prompt-link-text: أجندة LTS ---- - -Node.js® هو إطار عمل مبني على محرك [Chrome V8](https://v8.dev/). diff --git a/pages/be/404.md b/pages/be/404.md deleted file mode 100644 index b27632fdd42d2..0000000000000 --- a/pages/be/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Старонка не знойдзена - -### ENOENT: няма такога файла або каталога diff --git a/pages/be/about/governance.md b/pages/be/about/governance.md deleted file mode 100644 index 7794be3c2c534..0000000000000 --- a/pages/be/about/governance.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Кіраванне праектам -layout: about.hbs ---- - -# Кіраванне праектам - -## Працэс пошуку кансэнсусу - -Праект Node.js прытрымліваецца мадэлі [пошуку кансэнсусу](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) ў прыняцці рашэнняў. - -## Суаўтары - -Рэпазіторый [nodejs/node][] на GitHub падтрымліваецца і развіваецца Суаўтарамі, якіх дадае Тэхнічны кіруючы камітэт ([TSC][]) на пастаяннай аснове. - -Людзі, якія ўносяць значны і каштоўны ўклад, становяцца Суаўтарамі і атрымліваюць доступ да праекта з дазволам на ўнясенне змяненняў. Гэтых людзей вызначае КТК (кіруючы тэхнічны камітэт), і іх вылучэнне абмяркоўваецца з існуючымі Суаўтарамі. - -Бягучы спіс Суаўтараў глядзіце ў [README.md][] праекта. - -Кіраўніцтва для Суаўтараў знаходзіцца ў [collaborator-guide.md][]. - -## Кіруючы тэхнічны камітэт - -Праект кіруецца [Кіруючым тэхнічным камітэтам (КТК)][] які адказвае за высокаўзроўневае кіраўніцтва праектам. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Кіруючым тэхнічным камітэтам (КТК)]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/be/about/index.md b/pages/be/about/index.md deleted file mode 100644 index 94acfa1ac82e1..0000000000000 --- a/pages/be/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Аб праекце -trademark: Гандлёвая марка ---- - -# Аб Node.js® - -Node.js — гэта падзейна-арыентаванае асінхроннае асяроддзе выканання JavaScript-кода, спраектаванае для стварэння маштабуемых сеткавых праграм. Ніжэй прыведзены прыклад "hello world", які можа адначасова апрацоўваць шмат злучэнняў. Для кожнага злучэння выклікаецца функцыя зваротнага выкліку, але калі злучэнняў няма, Node.js "засынае". - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Гэта адрозніваецца ад сённяшняй больш распаўсюджанай мадэлі паралелізму, у якой выкарыстоўваюцца патокі АС. Камунікацыя, заснаваная на патоках, з'яўляецца адносна неэфектыўнай і вельмі цяжкай у выкарыстанні. Больш за тое, карыстальнікі Node.js могуць не турбавацца аб блакіроўках працэсаў, паколькі іх не існуе. Амаль ніводная функцыя ў Node.js не працуе напрамую з уводам/вывадам, таму працэс ніколі не блакіруецца, за выключэннем выпадкаў, калі ўвод/вывад выконваецца з выкарыстаннем сінхронных метадаў стандартнай бібліятэкі Node.js. Такім чынам, паколькі нішто не блакіруецца, вельмі мэтазгодна распрацоўваць маштабуемыя сістэмы на Node.js. - -Больш падрабязна з гэтым падыходам можна азнаёміцца ў поўным артыкуле [Blocking vs. Non-Blocking][]. - ---- - -Node.js быў створаны пад уплывам такіх сістэм, як [Event Machine][] у Ruby і [Twisted][] у Python. Але пры гэтым падзейная сістэма ў ім выкарыстоўваецца значна шырэй: [цыкл падзей][] з'яўляецца часткай асяроддзя выканання, а не асобнай бібліятэкай. У іншых сістэмах заўсёды існуе блакіруючы выклік для запуску цыкла падзей. Звычайна, логіка праграмы вызначаецца праз зваротныя выклікі (callbacks) у пачатку скрыпта, а ў канцы праз блакіруючы выклік, напрыклад `EventMachine::run()`, запускаецца серверная частка. У Node.js няма нічога падобнага на выклік пачатку цыкла падзей. Node.js проста ўваходзіць у цыкл падзей пасля запуску скрыпта і выходзіць з цыкла, калі больш не застаецца зарэгістраваных функцый зваротнага выкліку. Гэта падобна на працу JavaScript у браўзеры, дзе цыкл падзей схаваны ад карыстальніка. - -HTTP — важны элемент Node.js, распрацаваны з улікам паточнасці і малой затрымкі. Гэта робіць Node.js добрай асновай для вэб-бібліятэкі ці фрэймворка. - -Тое, што Node.js спраектаваны без выкарыстання патокаў, зусім не азначае, што вы не зможаце скарыстацца перавагамі свайго шмат’ядзернага працоўнага асяроддзя. Даччыныя працэсы можна ствараць з дапамогай нашага API [`child_process.fork()`][]. Даччыныя працэсы спраектаваны так, каб з імі было лёгка ўзаемадзейнічаць. На аснове таго ж інтэрфейсу пабудаваны модуль [`cluster`][], які дазваляе размяркоўваць сокеты паміж працэсамі, каб збалансаваць нагрузку на ядры вашай сістэмы. - -[Blocking vs. Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[цыкл падзей]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/be/docs/guides/diagnostics/live-debugging/index.md b/pages/be/docs/guides/diagnostics/live-debugging/index.md deleted file mode 100644 index b35eca2c1e72a..0000000000000 --- a/pages/be/docs/guides/diagnostics/live-debugging/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Адладка ў рэальным часе -layout: docs.hbs ---- - -# Адладка ў рэальным часе - -- [Адладка ў рэальным часе](#live-debugging) - - [Мая праграма паводзіць сябе не так, як чакалася](#my-application-doesnt-behave-as-expected) - - [Сімптомы](#symptoms) - - [Адладка](#debugging) - -У гэтым дакуменце вы даведаецеся аб тым, як у рэальным часе адладжваць працэс Node.js. - -## Мая праграма паводзіць сябе не так, як чакалася - -### Сімптомы - -Карыстальнік можа заўважыць, што праграма не выдае чаканы вынік для пэўных уваходных даных, напрыклад, HTTP-сервер вяртае адказ JSON, у якім некаторыя палі пустыя. Падчас працы могуць адбыцца розныя памылкі, але ў дадзеным прыкладзе мы галоўным чынам засяродзімся на логіцы праграмы і яе правільнасці. - -### Адладка - -У гэтым прыкладзе карыстальнік жадаў бы зразумець паслядоўнасць выканання кода нашай праграмы для пэўнай падзеі, напрыклад, уваходнага HTTP-запыту. Ён таксама можа захацець паглядзець выкананне кода крок за крокам, а таксама праверыць, якія значэнні захоўваюць пераменныя. - -- [Выкарыстанне інспектара](/en/docs/guides/diagnostics/live-debugging/using-inspector) diff --git a/pages/be/docs/guides/event-loop-timers-and-nexttick.md b/pages/be/docs/guides/event-loop-timers-and-nexttick.md deleted file mode 100644 index 45fb3dc2a05da..0000000000000 --- a/pages/be/docs/guides/event-loop-timers-and-nexttick.md +++ /dev/null @@ -1,344 +0,0 @@ ---- -title: Цыкл падзей Node.js, таймеры і функцыя process.nextTick() -layout: docs.hbs ---- - -# Цыкл падзей Node.js, таймеры і функцыя `process.nextTick()` - -## Што такое Цыкл падзей? - -Цыкл падзей (Event Loop) — гэта тое, што дазваляе Node.js выконваць аперацыі ўводу-вываду без блакіроўкі (нягледзячы на тое, што JavaScript з'яўляецца аднапаточным), шляхам выгрузкі аперацый у ядро сістэмы, калі гэта магчыма. - -Большасць сучасных ядраў з'яўляюцца шматпаточнымі. Гэта значыць, што яны могуць апрацоўваць некалькі аперацый у фонавым рэжыме. Калі адна з гэтых аперацый завяршаецца, ядро паведамляе Node.js, што адпаведная callback-функцыя можа быць дададзена ў чаргу апытання (**poll**) для выканання. Мы разгледзім гэта больш падрабязна далей у артыкуле. - -## Падрабязней пра цыкл падзей - -Пры старце Node.js ініцыялізуе цыкл падзей (event loop). Пасля гэтага апрацоўваецца ўводны скрыпт (input script) (або працэс трапляе ў [REPL][], але гэта не разглядаецца ў гэтым артыкуле). Уводны скрыпт можа рабіць асінхронныя выклікі API, планаваць таймеры або выклікаць функцыю `process.nextTick()`. Пасля апрацоўкі ўводнага скрыпта пачынаецца апрацоўка цыкла падзей. - -На дыяграме ніжэй паказаны спрошчаны агляд паслядоўнасці аперацый цыкла падзей. - -``` - ┌───────────────────────────┐ -┌─>│ timers │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ pending callbacks │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ idle, prepare │ -│ └─────────────┬─────────────┘ ┌───────────────┐ -│ ┌─────────────┴─────────────┐ │ incoming: │ -│ │ poll │<─────┤ connections, │ -│ └─────────────┬─────────────┘ │ data, etc. │ -│ ┌─────────────┴─────────────┐ └───────────────┘ -│ │ check │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -└──┤ close callbacks │ - └───────────────────────────┘ -``` - -> Кожны блок дыяграмы далей будзе называецца "фазай" цыкла падзей. - -Кожная фаза мае FIFO чаргу callback-функцый для выканання. Хоць кожная фаза па-свойму асаблівая, але звычайна кожная фаза працуе па наступным алгарытме. Калі цыкл падзей пераходзіць на пэўную фазу, то спачатку будуць выкананы ўсе аперацыі, характэрныя для гэтай фазы, а затым будуць выкананы callback-функцыі з чаргі гэтай фазы. Callback-функцыі фазы будуць выконвацца пакуль чарга не будзе вычарпана або пакуль не будзе выканана максімальна дазволеная колькасць callback-функцый. Калі чарга вычарпана або дасягнуты ліміт на колькасць выкананых callback-функцый, цыкл падзей пяройдзе да наступнай фазы і гэтак далей. - -Паколькі любая з гэтых аперацый можа запланаваць _больш_ аперацый і новыя падзеі, якія апрацоўваюцца на фазе **poll**, дадаюцца ў чаргу ядром, падзеі для фазы poll могуць дадавацца ў чаргу падчас апрацоўкі падзей фазы poll. Такім чынам callback-функцыі, якія патрабуюць шмат часу на выкананне, могуць дазволіць фазе poll працаваць значна даўжэй, чым ліміт чакання дадзенага таймера. Больш падрабязную інфармацыю глядзіце ў раздзелах [**timers**](#timers) і [**poll**](#poll). - -> Існуе невялікае разыходжанне паміж рэалізацыяй Windows і Unix/Linux, але гэта не важна для гэтай дэманстрацыі. Тут будуць разгледжаны самыя важныя часткі. Фактычна існуе сем або восем этапаў, але тыя, якія нас цікавяць (тыя, якія насамрэч выкарыстоўвае Node.js) — прыведзены вышэй. - -## Агляд фаз - -- **timers**: на гэтай фазе выконваюцца callback-функцыі, якія былі запланаваны з дапамогай функцый `setTimeout()` і `setInterval()`. -- **pending callbacks**: выконваюцца callback-функцыі ўводу/вываду, якія былі адкладзены да наступнай ітэрацыі цыкла. -- **idle, prepare**: толькі для ўнутранага выкарыстання. -- **poll**: атрымліваюцца новыя падзеі ўводу-вываду; выконваюцца callback-функцыі звязаныя з уводам-вывадам (амаль усе, за выключэннем callback-функцый закрыцця і callback-функцый запланаваных таймерамі і функцыяй `setImmediate()`); Node будзе блакіраваць выкананне тут, калі гэта неабходна. -- **check**: выклікаюцца callback-функцыі, зарэгістраваныя функцыяй `setImmediate()`. -- **close callbacks**: выконваюцца некаторыя callback-функцыі закрыцця, напрыклад, `socket.on('close', ...)`. - -Паміж кожным запускам цыкла падзей Node.js правярае, ці чакаюцца якія-небудзь асінхронныя аперацыі ўводу/вываду або таймеры (timers). Калі нічога няма, то працэс Node.js завяршае сваю працу. - -## Падрабязны агляд фаз - -### timers (таймеры) - -Таймер вызначае **парогавае значэнне**, _пасля якога_ зададзеная callback-функцыя _можа быць выканана_, а не **дакладны** час, калі _яе трэба выканаць_. Callback-функцыі таймера будуць выкананы як толькі Node.js зможа запланаваць іх пасля заканчэння вызначанага часу чакання. Аднак планаванне аперацыйнай сістэмы або выкананне іншых callback-функцый можа затрымаць іх выкананне. - -> Тэхнічна, фаза [**poll**](#poll) кантралюе час, калі будуць выкананы таймеры. - -Напрыклад, вы запланавалі callback-функцыю, якая павінна быць выканана пасля 100мс чакання, пасля гэтага ваш скрыпт пачынае асінхроннае чытанне файла, якое займае 95мс: - -```js -const fs = require('fs'); - -function someAsyncOperation(callback) { - // Дапусцім, што гэта займе 95мс - fs.readFile('/path/to/file', callback); -} - -const timeoutScheduled = Date.now(); - -setTimeout(() => { - const delay = Date.now() - timeoutScheduled; - - console.log(`${delay}мс прайшло з таго часу, як я была запланавана`); -}, 100); - -// выканаем функцыю someAsyncOperation, якая займае 95 мс -someAsyncOperation(() => { - const startCallback = Date.now(); - - // зробім што-небудзь, што зойме 10 мс… - while (Date.now() - startCallback < 10) { - // нічога не рабіць - } -}); -``` - -Калі цыкл падзей пераходзіць у фазу **poll**, то яна мае пустую чаргу (функцыя `fs.readFile()` яшчэ не завершана), таму цыкл падзей будзе чакаць столькі мілісекунд, колькі засталося, да парогу чакання найбліжэйшага таймера. Пакуль ён чакае 95мс, функцыя `fs.readFile()` завяршае чытанне файла і callback-функцыя, выкананне якой займае 10мс, дадаецца ў чаргу фазы **poll**, а затым выконваецца. Калі callback-функцыя завершыцца, у чарзе больш не застанецца іншых callback-функцый, таму цыкл падзей убачыць, што парог чакання найбліжэйшага таймера дасягнуты, пасля чаго вернецца да фазы **timers**, каб выканаць callback-функцыі таймера. У гэтым прыкладзе вы ўбачыце, што агульная затрымка паміж запланаваным таймерам і выкананнем яго callback-функцыі складзе 105мс. - -> Каб прадухіліць фазу **poll** ад вычарпання цыкла падзей, [libuv][] (бібліятэка напісаная на мове C, якая рэалізуе цыкл падзей Node.js і ўсе асінхронныя паводзіны платформы) таксама мае жорсткі максімум (які залежыць ад сістэмы), пасля якога яна спыніць апытанне новых падзей. - -### pending callbacks (callback-функцыі ў чаканні) - -На гэтым этапе выконваюцца callback-функцыі для некаторых сістэмных аперацый, напрыклад, для памылак TCP. Некаторыя \*nix сістэмы чакаюць перад тым як паведаміць, што TCP-сокет атрымаў памылку `ECONNREFUSED` падчас спробы злучэння. Гэта падзея будзе дададзена ў чаргу для выканання ў фазе **pending callbacks**. - -### poll (апытанне) - -Фаза **poll** мае дзве асноўныя функцыі: - -1. Разлік таго, як доўга яна павінна блакіраваць і апытваць увод-вывад, а затым -2. Апрацоўка падзей у чарзе фазы **poll**. - -Калі цыкл падзей пераходзіць у фазу **poll** _і запланаваныя таймеры адсутнічаюць_, адбудзецца адно з двух: - -- _Калі чарга фазы **poll** — **не пустая**_, цыкл падзей будзе перабіраць чаргу callback-функцый, выконваючы іх сінхронна, пакуль чарга не будзе вычарпана або не будзе дасягнуты сістэмны жорсткі ліміт. - -- _Калі чарга фазы **poll** — **пустая**_, адбудзецца адно з двух: - - - Калі скрыпты былі запланаваны функцыяй `setImmediate()`, цыкл падзей скончыць фазу **poll** і пяройдзе да фазы **check**, каб выканаць гэтыя запланаваныя скрыпты. - - - Калі скрыпты **не былі** запланаваны з дапамогай функцыі `setImmediate()`, цыкл падзей будзе чакаць, пакуль callback-функцыі будуць дададзены ў чаргу, а затым неадкладна выканае іх. - -Пасля таго, як чарга для фазы **poll** апусцее, цыкл пачне правяраць таймеры ў якіх быў _дасягнуты парогавы час чакання_. Калі адзін або некалькі таймераў дасягнулі гэты парог, цыкл падзей вернецца да фазы **timers**, каб выканаць запланаваныя callback-функцыі гэтых таймераў. - -### check (этап агляду) - -Гэтая фаза дазваляе карыстальніку выконваць callback-функцыі адразу пасля завяршэння фазы **poll**. Калі фаза **poll** становіцца бяздзейнай і callback-функцыі былі пастаўлены ў чаргу з дапамогай функцыі `setImmediate()`, цыкл падзей можа перайсці да фазы **check** замест чакання. - -Функцыя `setImmediate()` на самай справе з'яўляецца спецыяльным таймерам, які працуе ў асобнай фазе цыкла падзей. Яна выкарыстоўвае API бібліятэкі libuv, якое плануе выкананне callback-функцый пасля завяршэння фазы **poll**. - -Як правіла, па меры выканання кода цыкл падзей трапляе ў фазу **poll**, дзе ён будзе чакаць уваходнага злучэння, запыту і г. д. Аднак, калі callback-функцыя была запланавана з дапамогай функцыі `setImmediate()` і фаза **poll** становіцца бяздзейнай, то гэта фаза завершыцца і цыкл падзей пяройдзе да фазы **check** замест чакання падзей для фазы **poll**. - -### close callbacks (callback-функцыі закрыцця) - -Калі сокет або дэскрыптар раптоўна закрываюцца (напрыклад, `socket.destroy()`), на гэтай фазе будзе сгенерыравана падзея `'close'`. Інакш яна будзе сгенерыравана праз функцыю `process.nextTick()`. - -## `setImmediate()` супраць `setTimeout()` - -Функцыі `setImmediate()` і `setTimeout()` падобныя, але паводзяць сябе па-рознаму ў залежнасці ад таго, калі яны былі выкліканы. - -- Функцыя `setImmediate()` прызначана для выканання скрыпта пасля завяршэння бягучай фазы **poll**. -- Функцыя `setTimeout()` плануе запуск скрыпта пасля таго, як скончыцца мінімальны парог чакання ў мілісекундах. - -Парадак выканання таймераў будзе мяняцца ў залежнасці ад кантэксту, у якім яны выклікаюцца. Калі абодва таймеры выклікаюцца з галоўнага модуля, то час, калі яны будуць выкананы, будзе залежаць ад прадукцыйнасці працэсу (на якую могуць уплываць іншыя праграмы, запушчаныя на машыне). - -Напрыклад, калі мы запусцім наступны скрыпт, які не знаходзіцца ўнутры цыкла ўводу-вываду (то-бок галоўнага модуля), парадак выканання двух таймераў не з'яўляецца дэтэрмінаваным, паколькі ён залежыць ад прадукцыйнасці працэсу: - -```js -// timeout_vs_immediate.js -setTimeout(() => { - console.log('timeout'); -}, 0); - -setImmediate(() => { - console.log('immediate'); -}); -``` - -``` -$ node timeout_vs_immediate.js -timeout -immediate - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -Аднак, калі вы перамесціце два выклікі ў цыкл уводу-вываду, неадкладная (immediate) callback-функцыя заўсёды будзе выконвацца першай: - -```js -// timeout_vs_immediate.js -const fs = require('fs'); - -fs.readFile(__filename, () => { - setTimeout(() => { - console.log('timeout'); - }, 0); - setImmediate(() => { - console.log('immediate'); - }); -}); -``` - -``` -$ node timeout_vs_immediate.js -immediate -timeout - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -Асноўная перавага выкарыстання функцыі `setImmediate()` над функцыяй `setTimeout()` заключаецца ў тым, што функцыя `setImmediate()` заўсёды будзе выконвацца перад таймерамі, калі яна запланавана ўнутры цыкла ўводу-вывыду, незалежна ад колькасці таймераў. - -## `Функцыя process.nextTick()` - -### Разуменне функцыі `process.nextTick()` - -Магчыма, вы заўважылі, што функцыя `process.nextTick()` не была адлюстравана на дыяграме, хаця яна і з'яўляецца часткай асінхроннага API. Гэта адбылося таму, што функцыя `process.nextTick()` тэхнічна не з'яўляецца часткай цыкла падзей. Замест гэтага, чарга функцыі (`nextTickQueue`) будзе апрацавана пасля завяршэння бягучай аперацыі, незалежна ад бягучай фазы цыкла падзей. _Аперацыя_ тут — гэта пераход кантролю ад асноўнага апрацоўшчыка C/C++, а таксама апрацоўка JavaScript, які неабходна выканаць. - -Гледзячы на нашу схему можна ўбачыць, што кожны раз, калі вы выклікаеце функцыю `process.nextTick()` у зададзенай фазе, усе callback-функцыі перададзеныя ў функцыю `process.nextTick()` будуць выкананы перад тым, як цыкл падзей працягне сваю працу. Гэта можа прывесці да непрыемных вынікаў, таму што **гэта дазваляе "вычарпаць" чаргу ўводу/вываду, зрабіўшы рэкурсіўныя выклікі функцыі `process.nextTick()`**, што не дасць цыклу падзей дасягнуць фазы **poll**. - -### Чаму гэта дазволена? - -Навошта дадаваць нешта падобнае ў Node.js? Часткова таму, што гэта філасофія дызайну, згодна з якой API заўсёды павінен быць асінхронным, нават калі гэта не патрэбна. Возьмем, напрыклад, гэты фрагмент кода: - -```js -function apiCall(arg, callback) { - if (typeof arg !== 'string') - return process.nextTick( - callback, - new TypeError('аргумент павінен мець тып string') - ); -} -``` - -У гэтым фрагменце кода адбываецца праверка аргумента, калі аргумент памылковы — у callback-функцыю будзе перададзена памылка. Даволі нядаўна API было абноўлена, каб дазволіць перадаваць аргументы ў функцыю `process.nextTick()`. Цяпер пасля callback-функцыі можна перадаць любую колькасць аргументаў і яны будуць перададзены ў callback-функцыю ў якасці яе аргументаў, такім чынам вам не трэбы ствараць укладзеныя функцыі. - -Мы перадаём памылку назад карыстальніку, але толькі _пасля_ таго, як астатняя частка карыстальніцкага кода будзе выканана. З дапамогай функцыі `process.nextTick()` мы гарантуем, што функцыя `apiCall()` заўсёды будзе запускаць свае callback-функцыі _пасля_ астатняй часткі карыстальніцкага кода і _да таго_, як цыклу падзей будзе дазволена працягваць сваё выкананне. Для гэтага стэк выклікаў JS дазволена раскруціць, а потым неадкладна выканаць дадзеную callback-функцыю. Гэта дазваляе карыстальніку рабіць рэкурсіўныя выклікі функцыі `process.nextTick()` не атрымліваючы `RangeError: Перавышаны максімальны памер стэка выкліку` ад v8. - -Гэтая філасофія можа прывесці да некаторых патэнцыйна праблемных сітуацый. Возьмем, напрыклад, гэты код: - -```js -let bar; - -// гэта функцыя мае асінхронную сігнатуру, але выклікае callback-функцыю сінхронна -function someAsyncApiCall(callback) { - callback(); -} - -// callback-функцыя выклікаецца да завяршэння `someAsyncApiCall`. -someAsyncApiCall(() => { - // паколькі функцыя someAsyncApiCall не была завершана, пераменнай bar - // не было прысвоена ніякае значэнне - console.log('bar', bar); // undefined -}); - -bar = 1; -``` - -Карыстальнік вызначае функцыю `someAsyncApiCall()` як функцыю з асінхроннай сігнатурай, але яна на самай справе працуе сінхронна. Калі яе выклікаюць, то callback-функцыя, перададзеная ў `someAsyncApiCall()`, выклікаецца ў той жа фазе цыкла падзей, таму што `someAsyncApiCall()` насамрэч не робіць нічога асінхроннага. У выніку callback-функцыя спрабуе спасылацца на пераменную `bar`, хоць такой пераменнай яшчэ можа не быць у вобласці бачнасці гэтай функцыі, таму што скрыпт магчыма яшчэ не дайшоў да канца. - -Калі мы памесцім callback-функцыю ў `process.nextTick()`, то скрыпт будзе выкананы да канца, і толькі пасля гэтага будзе выканана callback-функцыя, а значыць, што ў момант выканання callback-функцыі ўсе пераменныя, функцыі і г.д. ужо будуць ініцыялізаваныя. Перавага гэтага спосабу яшчэ і ў тым, што ён не дазваляе цыклу падзей працягваць сваё выкананне. Гэта можа быць карысна калі мы хочам папярэдзіць карыстальніка аб памылцы да таго, як цыкл падзей працягне сваю працу. Вось папярэдні прыклад з выкарыстаннем функцыі `process.nextTick()`: - -```js -let bar; - -function someAsyncApiCall(callback) { - process.nextTick(callback); -} - -someAsyncApiCall(() => { - console.log('bar', bar); // 1 -}); - -bar = 1; -``` - -Вось яшчэ адзін рэальны прыклад: - -```js -const server = net.createServer(() => {}).listen(8080); - -server.on('listening', () => {}); -``` - -Калі перадаецца толькі порт, то порт прывязваецца адразу ж. Такім чынам, callback-функцыю для падзеі `'listening'` можна неадкладна выклікаць. Праблема заключаецца ў тым, што callback-функцыя `.on('listening')` у гэты момант яшчэ не будзе зададзена. - -Каб абысці гэта, падзея `'listening'` ставіцца ў чаргу праз функцыю `nextTick()`, каб дазволіць скрыпту дайсці да канца. Гэта дазваляе карыстальніку дадаць любыя апрацоўшчыкі падзей. - -## `process.nextTick()` супраць `setImmediate()` - -У нас ёсць два функцыі, які выглядаюць падобнымі з пункту гледжання карыстальнікаў, але іх назвы могуць заблытаць. - -- Функцыя `process.nextTick()` запускаецца адразу ў той жа самай фазе -- Функцыя `setImmediate()` спрацоўвае на наступнай ітэрацыі або 'ціку' цыкла падзей - -Па сутнасці, імёны трэба памяняць месцамі. Функцыя `process.nextTick()` спрацоўвае хутчэй, чым функцыя `setImmediate()`, але гэта артэфакт мінулага, і вельмі малаверагодна, што гэта ўжо зменіцца. Гэта змена прывядзе да паломкі вялікага працэнта існуючых пакетаў у npm. Новыя модулі дадаюцца кожны дзень, таму з кожным днём чакання, колькасць патэнцыяльных праблем павялічваецца. І хоць назвы функцый прыводзяць да блытаніны, але яны не зменяцца. - -> Мы рэкамендуем распрацоўшчыкам выкарыстоўваць функцыю `setImmediate()`, таму што яе прасцей зразумець. - -## Навошта выкарыстоўваць функцыю `process.nextTick()`? - -На гэта ёсць дзве асноўныя прычыны: - -1. Дазволіць карыстальнікам апрацоўваць памылкі, ачышчаць усе непатрэбныя рэсурсы або, напрыклад, паўтарыць запыт, перш чым цыкл падзей працягне сваю працу. - -2. Часам неабходна дазволіць выкананне callback-функцыі пасля раскручвання стэка выклікаў, але перад тым, як цыкл падзей працягне сваю працу. - -Адзін з прыкладаў — адпавядаць чаканням карыстальніка. Просты прыклад: - -```js -const server = net.createServer(); -server.on('connection', conn => {}); - -server.listen(8080); -server.on('listening', () => {}); -``` - -Уявім, што функцыя `listen()` запускаецца ў пачатку цыкла падзей, але callback-функцыя, для падзеі 'listening' змяшчаецца ў функцыі `setImmediate()`. Акрамя выпадку калі імя хоста перададзена, прывязка да порта адбудзецца імгненна. Для працягу сваёй працы цыкл падзей павінен перайсці ў фазу **poll**, што азначае, што існуе шанец таго, што злучэнне магло быць атрымана. Гэта значыць, што падзея 'connection' была створана да падзеі 'listening'. - -Іншы прыклад — пашырэнне `EventEmitter` і стварэнне падзеі ў канструктары: - -```js -const EventEmitter = require('events'); - -class MyEmitter extends EventEmitter { - constructor() { - super(); - this.emit('event'); - } -} - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('адбылася падзея!'); -}); -``` - -Вы не можаце стварыць падзею наўпрост з канструктара, таму што скрыпт яшчэ не дойдзе да таго месца, дзе карыстальнік прызначае callback-функцыю для апрацоўкі гэтай падзеі. Таму ў самім канструктары вы можаце выкарыстоўваць функцыю `process.nextTick()`, і задаць ёй callback-функцыю, якая створыць падзею ўжо пасля завяршэння працы канструктара, што забяспечыць чаканыя вынікі: - -```js -const EventEmitter = require('events'); - -class MyEmitter extends EventEmitter { - constructor() { - super(); - - // выкарыстоўвайце nextTick, каб стварыць падзею, як толькі прызначаны апрацоўшчык - process.nextTick(() => { - this.emit('event'); - }); - } -} - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('адбылася падзея!'); -}); -``` - -[libuv]: https://libuv.org/ -[REPL]: https://nodejs.org/api/repl.html#repl_repl diff --git a/pages/be/download/current.md b/pages/be/download/current.md deleted file mode 100644 index 718cf26428690..0000000000000 --- a/pages/be/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Спампаваць -download: Спампаваць -downloads: - headline: Спампоўкі - lts: LTS - current: Бягучая - tagline-current: Найноўшыя функцыі - tagline-lts: Рэкамендавана для большасці - display-hint: Паказаць спампоўкі для - intro: > - Спампуйце зыходны код Node.js або ўсталёўшчык для вашай платформы і пачніце распрацоўку сёння. - currentVersion: Актуальная бягучая версія - buildInstructions: Зборка Node.js з зыходнага кода на платформах, што падтрымліваюцца - WindowsInstaller: Усталёўшчык для Windows - WindowsBinary: Двайковыя файлы для Windows - MacOSInstaller: Усталёўшчык для macOS - MacOSBinary: Двайковыя файлы для macOS - LinuxBinaries: Двайковыя файлы для Linux - SourceCode: Зыходны код -additional: - headline: Дадатковыя платформы - intro: > - Удзельнікі супольнасці Node.js падтрымліваюць неафіцыйныя зборкі Node.js для дадатковых платформ. Майце на ўвазе, што гэтыя зборкі не падтрымліваюцца асноўнай камандай Node.js і могуць не адпавядаць бягучым афіцыйным версіям Node.js. - platform: Платформа - provider: Пастаўшчык - SmartOSBinaries: Двайковыя файлы для SmartOS - DockerImage: Вобраз для Docker - officialDockerImage: Афіцыйны вобраз Node.js для Docker - LinuxPowerSystems: Linux на Power LE Systems - LinuxSystemZ: Linux на System z - AIXPowerSystems: AIX на Power Systems ---- diff --git a/pages/be/download/index.md b/pages/be/download/index.md deleted file mode 100644 index e74bb99e3b604..0000000000000 --- a/pages/be/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Спампаваць -download: Спампаваць -downloads: - headline: Спампоўкі - lts: LTS - current: Бягучая - tagline-current: Найноўшыя функцыі - tagline-lts: Рэкамендавана для большасці - display-hint: Паказаць спампоўкі для - intro: > - Спампуйце зыходны код Node.js або ўсталёўшчык для вашай платформы і пачніце распрацоўку сёння. - currentVersion: Актуальная LTS версія - buildInstructions: Зборка Node.js з зыходнага кода на платформах, што падтрымліваюцца - WindowsInstaller: Усталёўшчык для Windows - WindowsBinary: Двайковыя файлы для Windows - MacOSInstaller: Усталёўшчык для macOS - MacOSBinary: Двайковыя файлы для macOS - LinuxBinaries: Двайковыя файлы для Linux - SourceCode: Зыходны код -additional: - headline: Дадатковыя платформы - intro: > - Удзельнікі супольнасці Node.js падтрымліваюць неафіцыйныя зборкі Node.js для дадатковых платформ. Майце на ўвазе, што гэтыя зборкі не падтрымліваюцца асноўнай камандай Node.js і могуць не адпавядаць бягучым афіцыйным версіям Node.js. - platform: Платформа - provider: Пастаўшчык - SmartOSBinaries: Двайковыя файлы для SmartOS - DockerImage: Вобраз для Docker - officialDockerImage: Афіцыйны вобраз Node.js для Docker - LinuxPowerSystems: Linux на Power LE Systems - LinuxSystemZ: Linux на System z - AIXPowerSystems: AIX на Power Systems ---- diff --git a/pages/be/download/releases.md b/pages/be/download/releases.md deleted file mode 100644 index e8262ec63302a..0000000000000 --- a/pages/be/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Папярэднія рэлізы -modules: '<код>NODE_MODULE_VERSION адносіцца да нумара версіі ABI (двайковы інтэрфейс праграмы) Node.js, які выкарыстоўваецца для вызначэння таго, якія версіі двайковых файлаў C++ дапаўненняў, скампіляваных Node.js, можна загружаць без паўторнай кампіляцыі. Раней, у больш ранніх версіях, яно захоўвалася як шаснаццатковае значэнне, але цяпер прадстаўлена ў выглядзе цэлага ліку.' ---- - -### io.js і Node.js - -Рэлізы з 1.x па 3.x называліся "io.js", таму што яны былі часткай форка io.js. Пачынаючы з Node.js 4.0.0 io.js быў аб'яднаны з Node.js 0.12.x у агульны рэліз Node.js. - -### Шукаеце апошні рэліз пэўнай версіі? diff --git a/pages/be/index.md b/pages/be/index.md deleted file mode 100644 index 5b7dcd2ab5c93..0000000000000 --- a/pages/be/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Бягучая версія - download: Спампаваць - download-for: Спампаваць для - other-downloads: Іншыя спампоўкі - current: Бягучая - lts: LTS - tagline-current: Найноўшыя функцыі - tagline-lts: Рэкамендавана для большасці - changelog: Спіс змен - api: Дакументацыя API - version-schedule-prompt: Інфармацыю аб падтрымліваемых выпусках можна знайсці на - version-schedule-prompt-link-text: графік LTS ---- - -Node.js® — гэта кросплатформеннае асяроддзе выканання JavaScript з адкрытым зыходным кодам. diff --git a/pages/ca/404.md b/pages/ca/404.md deleted file mode 100644 index 4c86ad4ece44c..0000000000000 --- a/pages/ca/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Pàgina no trobada - -### ENOENT: L'arxiu o directori no existeix diff --git a/pages/ca/about/index.md b/pages/ca/about/index.md deleted file mode 100644 index 447d13de3a53a..0000000000000 --- a/pages/ca/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Sobre nosaltres -trademark: Trademark ---- - -# Sobre Node.js® - -Nascut com a un entorn d'execució de JavaScript orientat a esdeveniments asíncrons, Node.js està dissenyat per a crear aplicacions en xarxa de manera escalable. En la següent aplicació d'exemple "hola món", es pot manegar moltes connexions concurrents. Per a cada connexió el callback serà executat, no obstant si no hi hagués tasques pendents per a fer, Node.js romandrà adormit. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hola Món'); -}); - -server.listen(port, hostname, () => { - console.log(`El servidor s'està executant en http://${hostname}:${port}/`); -}); -``` - -Això contrasta amb el model de concurrència més comú d'avui dia, o es fan servir els fils del Sistema Operatiu. Les operacions en xarxes basades en fils són relativament ineficients i són molt més complicades de fer servir. A més a més, els usuaris de Node.js no han d'estar preocupats quant als bloquejos dels processos ja que són inexistents. Gairebé cap funció en Node.js realitza I/O directament, d'aquesta manera el procés mai és bloquejat. A raó de què no hi ha bloquejos, és més raonable desenvolupar sistemes escalables en Node.js. - -Si cap d'aquests termes no li és familiar, hi ha un article complet en [Blocking vs Non-Blocking][]. - ---- - -Node té un disseny similar i està influenciat per sistemes com [Event Machine][] de Ruby o [Twisted][] de Python. Node porta el model d'esdeveniments una mica més enllà, aquest presenta un [bucle d'esdeveniments][] com un entorn en comptes d'una llibreria. En altres sistemes sempre existeix una trucada que bloqueja per iniciar el bucle d'esdeveniments. El comportament és típicament definit a través de _callbacks_ a l'inici del script i al final s'inicia el servidor mitjançant una trucada de bloqueig com `EventMachine::run()`. En Node no existeix aquesta trucada. Node simplement ingressa el bucle d'esdeveniments després d'executar el script d'entrada. Node surt del bucle d'esdeveniments quan no hi ha més _callbacks_ que executar. s comporta d'una forma similar a JavaScript al navegador - el bucle d'esdeveniments està ocult a l'usuari. - -HTTP es ciutadà de primera classe en Node, disenyat amb operacions de streaming y baixa latència en ment. Això no fa a Node candidat per ser la base d'una llibrería o un framework web. - -Solament perquè Node està dissenyat sense fils, no significa que vostè no pot aprofitar els múltiples cores del seu sistema. Processos fills poden ser llençats usant la nostra API [`child_process.fork()`][], la qual està dissenyada per comunicar-se fàcilment amb el procés principal. Construïda sobre la mateixa interfície està el mòdul [`cluster`][], el qual permet compartir sockets entre processos per activar el balanceig de càrregues en els seus múltiples cores. - -[Blocking vs Non-Blocking]: https://nodejs.org/ca/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[bucle d'esdeveniments]: https://github.com/nodejs/node/blob/main/doc/topics/event-loop-timers-and-nexttick.md -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/ca/docs/index.mdx b/pages/ca/docs/index.mdx deleted file mode 100644 index 1e9b8750e6e84..0000000000000 --- a/pages/ca/docs/index.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Documentació -layout: docs.hbs -labels: - lts: LTS ---- - -# Sobre la documentació - -Existeixen tres tipus de documentació a l'abast en aquest lloc: - -- Referència de la API -- Característiques d'ES6 -- Preguntes freqüents - -## Referència de l'API - -La [Referència de l'API](https://nodejs.org/api/) proporciona informació detallada sobre una funció ó un objecte en Node.js. Aquesta -documentació indica quins arguments acepta un mètode, el valor que retorna aquest mètode i quins errors poden estar -relacionats al mateix. També indica quins mètodes són a l'abast per les diferents versions de Node.js - -També descriu els mòduls inclosos que proporciona Node.js, mes no documenta els mòduls que proporciona la comunitat. - -
- -### Buscant la referència de l'API per a una versió anterior? - - - -[Totes les versions](https://nodejs.org/docs/) - -
- -## Característiques d'ES6 - -La [secció d'ES6](/en/docs/es6/) descriu l'arbre dels grups de les característiques d'ES6, i detalla quines -característiques són activades per defecte en Node.js, juntament amb enllaços explicatius. També mostra com trobar -quina versió de V8 fa servir una versió particular de Node.js. - -## Guides - -The [Guides section](/en/docs/guides/) has long-form, in-depth articles about Node.js technical features and capabilities. diff --git a/pages/ca/download/current.md b/pages/ca/download/current.md deleted file mode 100644 index 396dd99cf232f..0000000000000 --- a/pages/ca/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Descàrrega -download: Descàrrega -downloads: - headline: Descàrregues - lts: LTS - current: Actual - tagline-current: Últimes característiques - tagline-lts: Recomanat per a la majoria - display-hint: Mostrar descàrregues per a - intro: > - Descarregui el codi font de Node.js o un instal·lador pre-compilat per a la seva plataforma, i comenci a desenvolupar avui. - currentVersion: Versió actual - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Plataformes addicionals - intro: > - Membres de la comunitat de Node.js proveeixen paquets pre-compilats de forma no oficial per a plataformes addicionals no suportades per l'equip central de Node.js que poden no estar al mateix nivell de les versions actuals oficials de Node.js. - platform: Plataforma - provider: Proveïdor - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ca/download/index.md b/pages/ca/download/index.md deleted file mode 100644 index b8ad11ff07c1a..0000000000000 --- a/pages/ca/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Descàrrega -download: Descàrrega -downloads: - headline: Descàrregues - lts: LTS - current: Actual - tagline-current: Últimes característiques - tagline-lts: Recomanat per a la majoria - display-hint: Mostrar descàrregues per a - intro: > - Descarregui el codi font de Node.js o un instal·lador pre-compilat per a la seva plataforma, i comenci a desenvolupar avui. - currentVersion: Versió LTS - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Plataformes addicionals - intro: > - Membres de la comunitat de Node.js proveeixen paquets pre-compilats de forma no oficial per a plataformes addicionals no suportades per l'equip central de Node.js que poden no estar al mateix nivell de les versions actuals oficials de Node.js. - platform: Plataforma - provider: Proveïdor - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ca/get-involved/index.md b/pages/ca/get-involved/index.md deleted file mode 100644 index d8d55af32831b..0000000000000 --- a/pages/ca/get-involved/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Participa -layout: contribute.hbs ---- - -# Participa - -## Discussió de la comunitat - -- La [llista d'incidències de GitHub](https://github.com/nodejs/node/issues) és el lloc per discutir les característiques del nucli de Node.js. -- El compte de Twitter oficial de Node.js és [nodejs](https://twitter.com/nodejs). -- The [Node.js Foundation calendar](https://nodejs.org/calendar) with all public team meetings. - -## Aprenentatge - -- La [Documentació oficial de l'API](https://nodejs.org/api/) detalla l'API de Node. -- [NodeSchool.io](https://nodeschool.io/) li ensenyarà conceptes de Node.js de forma interactiva mitjançant jocs utilitzant la línia de comandes. -- L'[etiqueta de Node.js en Stack Overflow](https://stackoverflow.com/questions/tagged/node.js) col·lecciona nova informació cada dia. -- L'[etiqueta de Node.js en la DEV Community](https://dev.to/t/node) és un lloc on compartir projectes de Node.js, articles i tutorials, així com iniciar debats i demanar realimentació sobre temes relacionats amb Node.js. Els desenvolupadors de tots els nivells d'experiència són benvinguts a participar. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) és una comunitat amigable de desenvolupadors de backend amb Node.js que es recolzen mútuament a Discord. - -## Llocs de la comunitat internacional i projectes - -- [Comunitat Xinesa de Node.js](https://cnodejs.org/) -- [Comunitat d'Hongria(Magyar)](https://nodehun.blogspot.com/) -- [Grup de Facebook israelià per Node.js](https://www.facebook.com/groups/node.il/) -- [Grup d'usuaris de Japó](https://nodejs.jp/) -- [Grup de Facebook en espanyol de Node.js](https://www.facebook.com/groups/node.es/) -- [Vietnamese Node.js community](https://www.facebook.com/nodejs.vn/) -- [Uzbekistan group for Node.js](https://t.me/nodejs_uz) diff --git a/pages/ca/index.md b/pages/ca/index.md deleted file mode 100644 index 93aa2634886b7..0000000000000 --- a/pages/ca/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Versió actual - download: Descarregar - download-for: Descarregar per - other-downloads: Altres Descàrregues - current: Actual - lts: LTS - tagline-current: Últimes característiques - tagline-lts: Recomanat per a la majoria - changelog: Canvis - api: Documentació de l'API - version-schedule-prompt: O revisi la - version-schedule-prompt-link-text: Agenda de LTS ---- - -Node.js® és un entorn d'execució per a JavaScript construït amb el [motor de JavaScript V8 de Chrome](https://v8.dev/). diff --git a/pages/de/404.md b/pages/de/404.md deleted file mode 100644 index 6f7c11b0d5174..0000000000000 --- a/pages/de/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Seite wurde nicht gefunden - -### ENOENT: Datei oder Ordner nicht gefunden diff --git a/pages/de/about/governance.md b/pages/de/about/governance.md deleted file mode 100644 index 7f634eeb6b75a..0000000000000 --- a/pages/de/about/governance.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Projektmanagment -layout: about.hbs ---- - -# Projektmanagment - -## Konsensus Suchprozess - -Das Node.js Projekt folgt dem [Konsensprinzip][]. - -## Mitwirkende - -Die [nodejs/node][] Kern-GitHub Repository wird von den Mitarbeitern verwaltet, die vom Technischen Lenkungsausschuss ([TSC][]) ständig hinzugefügt werden. - -Personen, die bedeutende und wertvolle Beiträge leisten, werden zu Mitarbeitern gezählt und erhalten Commit-Zugriff auf das Projekt. Diese Personen werden vom TSC identifiziert und ihre Nominierung wird mit den bestehenden Mitarbeitern abgesprochen. - -Die aktuelle Liste der Mitarbeiter finden Sie in der [README.md][] des Projekts. - -Ein Leitfaden für Mitarbeiter wird unter [collaborator-guide.md][] gepflegt. - -## Technischer Lenkungsausschuss - -Das Projekt wird vom [Technischen Lenkungsausschuss (TSC)][] geleitet, der für die Leitung des Projekts auf höchster Ebene verantwortlich ist. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[Konsensprinzip]: https://de.wikipedia.org/wiki/Konsensprinzip -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Technischen Lenkungsausschuss (TSC)]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/de/about/index.md b/pages/de/about/index.md deleted file mode 100644 index 82dbd8d249605..0000000000000 --- a/pages/de/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Über Node.js -trademark: Markenzeichen ---- - -# Über Node.js® - -Als asynchrone, Event-basierte Laufzeitumgebung wurde Node.js speziell für die Entwicklung von skalierbaren Netzwerkanwendungen entworfen. Im nachfolgenden "Hallo Welt"-Beispiel können viele Verbindungen gleichzeitig bearbeitet werden. Bei jeder neuen Anfrage wird die Callback-Funktion ausgeführt. Gibt es jedoch nichts zu tun, befindet sich Node.js im Ruhezustand. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hallo Welt'); -}); - -server.listen(port, hostname, () => { - console.log(`Server läuft unter http://${hostname}:${port}/`); -}); -``` - -Dies steht im Gegensatz zu den heutzutage üblichen Modellen für Nebenläufigkeit, bei denen Threads des Betriebssystems genutzt werden. Thread-basiertes Networking ist vergleichsweise ineffizient und sehr schwer umzusetzen. Zudem müssen sich Node-Nutzer nicht um Deadlocks im Prozess sorgen, da es keine Blockierung gibt. Fast keine Funktion in Node.js führt direkt I/O-Operationen aus, daher wird der Prozess nie blockiert. Da nichts blockiert, können mit Node.js sinnvoll skalierbare Systeme entwickelt werden. - -Wenn einige dieser Konzepte unbekannt sind, gibt es hier einen Artikel zum Thema [blockierend vs. blockierungsfrei][] (auf Englisch). - ---- - -Node.js ähnelt im Design und ist beeinflusst von Systemen wie Rubys "[Event Machine][]" oder Pythons "[Twisted][]". Node.js führt das Event-Modell noch etwas weiter. Die [Ereignisschleife][] ist ein Konstrukt direkt in der Laufzeitumgebung und wird nicht über eine Bibliothek eingebunden. In anderen Systemen ist immer ein blockierender Aufruf notwendig, um die Ereignisschleife zu starten. Üblicherweise wird das Verhalten in Callback-Funktionen am Anfang des Skripts definiert und am Ende wird mit einem blockierenden Aufruf wie `EventMachine::run()` ein Server gestartet. In Node.js gibt es keinen solchen Aufruf, um die Ereignisschleife zu starten. Node.js beginnt einfach mit der Ereignisschleife, nachdem das Eingabe-Skript ausgeführt wurde. Node.js verlässt die Ereignisschleife, wenn keine Callback-Funktionen mehr auszuführen sind. Dieses Verhalten ist wie bei Browser-JavaScript - die Ereignisschleife ist vor dem Nutzer versteckt. - -HTTP ist ein Basiselement in Node, entworfen mit Fokus auf Streaming und geringe Latenz. Dadurch ist Node.js sehr gut als Grundlage für Web-Bibliotheken oder Frameworks geeignet. - -Dass Node.js ohne Threads entworfen ist, bedeutet nicht, dass man die Vorteile von mehreren Kernen auf einer Maschine nicht ausnutzen kann. Untergeordnete Prozesse können mit der [`child_process.fork()`][] API gestartet werden und sie wurden so entworfen, dass man leicht mit ihnen kommunizieren kann. Auf der gleichen Schnittstelle setzt das [`Cluster`][] Modul auf, dass es Prozessen erlaubt Sockets gemeinsam zu nutzen, um Lastverteilung über Kerne hinweg zu ermöglichen. - -[blockierend vs. blockierungsfrei]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`Cluster`]: https://nodejs.org/api/cluster.html -[Ereignisschleife]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/de/docs/index.mdx b/pages/de/docs/index.mdx deleted file mode 100644 index bcfcb2a8cdb9a..0000000000000 --- a/pages/de/docs/index.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Dokumentation -layout: docs.hbs -labels: - lts: LTS ---- - -# Über die Dokumentationen - -Auf dieser Webseite gibt es verschiedene Arten von Dokumentationen: - -- API-Referenz -- ES6 Funktionalitäten -- Anleitungen - -## API-Referenz - -Die [API-Referenz](https://nodejs.org/api/) stellt detaillierte Informationen über Funktionen und -Objekte in Node.js bereit. Diese Dokumentation zeigt, welche Argumente die -Methoden erlauben, den Rückgabewert der Methode und welche Fehler im -Zusammenhang mit der Methode stehen. Die Dokumentation zeigt auch, welche -Methoden in den verschiedenen Node.js-Versionen verfügbar sind. - -Die API-Referenz beschreibt Module, die in Node.js integriert sind. Module, die -von der Community zur Verfügung gestellt werden, sind dort nicht dokumentiert. - -
- -### Du suchst nach API Referenzen für ältere Versionen? - - - -[Alle Versionen](https://nodejs.org/docs/) - -
- -## ES6 Funktionalitäten - -Der [ES6-Bereich](/en/docs/es6/) beschreibt die drei Gruppen von ES6-Funktionalitäten und gibt Detailinformation dazu, welche Funktionalitäten -standardmäßig in Node.js eingeschaltet sind. Zudem gibt es Links zu weiteren -Erklärungen. Dort finden sich auch Informationen, welche Version von V8 in -welcher Node.js-Version enthalten ist. - -## Anleitungen - -Unter Anleitungen finden sich ausführliche Artikel über technische -Funktionalitäten und Leistungsfähigkeit von Node.js. diff --git a/pages/de/download/current.md b/pages/de/download/current.md deleted file mode 100644 index 2b03dbe53c4a3..0000000000000 --- a/pages/de/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Herunterladen -download: Download -downloads: - headline: Downloads - lts: LTS - current: Aktuell - tagline-current: Neueste Funktionalitäten - tagline-lts: Für die meisten Nutzer empfohlen - display-hint: Downloads anzeigen für - intro: > - Lade den Node.js Quellcode oder ein bestehendes Installationsprogramm für deine Plattform herunter und beginne gleich mit der Entwicklung. - currentVersion: Aktuellste Version - buildInstructions: Erstellen von Node.js aus dem Quellcode auf unterstützten Plattformen - WindowsInstaller: Windows-Installationsprogramm - WindowsBinary: Windows Binärdatei - MacOSInstaller: macOS Installationsprogramm - MacOSBinary: macOS Binärdatei - LinuxBinaries: Linux Binärdateien - SourceCode: Quellcode -additional: - headline: Weitere Plattformen - intro: > - Mitglieder der Node.js Community pflegen inoffizielle, gebaute Versionen von Node.js für weitere Plattformen. Beachte, dass solche Versionen nicht vom Node.js-Kernteam unterstützt werden und daher eventuell noch nicht auf dem selben Level wie die aktuelle Node.js-Version sind. - platform: Plattform - provider: Anbieter - SmartOSBinaries: SmartOS Binärdateien - DockerImage: Docker Abbild - officialDockerImage: Offizielles Node.js Docker Abbild - LinuxPowerSystems: Linux auf Power LE Systemen - LinuxSystemZ: Linux auf System z - AIXPowerSystems: AIX auf Power Systems ---- diff --git a/pages/de/download/index.md b/pages/de/download/index.md deleted file mode 100644 index c09915ce95dd9..0000000000000 --- a/pages/de/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Download -download: Download -downloads: - headline: Downloads - lts: LTS - current: Aktuell - tagline-current: Neueste Funktionalitäten - tagline-lts: Für die meisten Nutzer empfohlen - display-hint: Downloads anzeigen für - intro: > - Lade den Node.js-Quellcode oder ein bestehendes Installationsprogramm für deine Plattform herunter und beginne gleich mit der Entwicklung. - currentVersion: Aktuellste LTS-Version - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Weitere Plattformen - intro: > - Mitglieder der Node.js Community pflegen inoffizielle, gebaute Versionen von Node.js für weitere Plattformen. Beachte, dass solche Versionen nicht vom Node.js-Kernteam unterstützt werden und daher eventuell noch nicht auf dem selben Level wie die aktuelle Node.js-Version sind. - platform: Plattform - provider: Anbieter - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/de/index.md b/pages/de/index.md deleted file mode 100644 index 45ecec50aee1d..0000000000000 --- a/pages/de/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Aktuelle Version - download: Herunterladen - download-for: Herunterladen für - other-downloads: Andere Downloads - current: Aktuell - lts: LTS - tagline-current: Neueste Funktionalitäten - tagline-lts: Für die meisten Nutzer empfohlen - changelog: Änderungshistorie - api: API Dokumentation - version-schedule-prompt: Oder wirf einen Blick auf den - version-schedule-prompt-link-text: LTS Release Plan ---- - -Node.js® ist eine JavaScript-Laufzeitumgebung, die auf [Chromes V8 JavaScript-Engine](https://v8.dev/) basiert. diff --git a/pages/en/about/governance.md b/pages/en/about/governance.md index fe758d1fd29a5..5d933d47cd5b1 100644 --- a/pages/en/about/governance.md +++ b/pages/en/about/governance.md @@ -27,9 +27,9 @@ A guide for Collaborators is maintained at [collaborator-guide.md][]. The project is governed by the [Technical Steering Committee (TSC)][] which is responsible for high-level guidance of the project. +[consensus seeking]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making +[readme.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members +[tsc]: https://github.com/nodejs/TSC +[technical steering committee (tsc)]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md [collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[Consensus Seeking]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Technical Steering Committee (TSC)]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC [nodejs/node]: https://github.com/nodejs/node diff --git a/pages/en/about/index.md b/pages/en/about/index.md index 456f5c4c819d6..6526bdf199df8 100644 --- a/pages/en/about/index.md +++ b/pages/en/about/index.md @@ -11,7 +11,7 @@ scalable network applications. In the following "hello world" example, many connections can be handled concurrently. Upon each connection, the callback is fired, but if there is no work to be done, Node.js will sleep. -```javascript +```js const http = require('http'); const hostname = '127.0.0.1'; @@ -43,7 +43,7 @@ If some of this language is unfamiliar, there is a full article on Node.js is similar in design to, and influenced by, systems like Ruby's [Event Machine][] and Python's [Twisted][]. Node.js takes the event model a bit -further. It presents an [event loop][] as a runtime construct instead of as a library. In other systems, +further. It presents an event loop as a runtime construct instead of as a library. In other systems, there is always a blocking call to start the event-loop. Typically, behavior is defined through callbacks at the beginning of a script, and at the end a server is started through a blocking call like `EventMachine::run()`. @@ -62,9 +62,8 @@ communicate with. Built upon that same interface is the [`cluster`][] module, which allows you to share sockets between processes to enable load balancing over your cores. -[Blocking vs. Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options +[blocking vs. non-blocking]: /learn/overview-of-blocking-vs-non-blocking/ +[`child_process.fork()`]: /api/child_process/ [`cluster`]: https://nodejs.org/api/cluster.html -[event loop]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ +[event machine]: https://github.com/eventmachine/eventmachine +[twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/en/about/previous-releases.md b/pages/en/about/previous-releases.md new file mode 100644 index 0000000000000..9ed530b3e4864 --- /dev/null +++ b/pages/en/about/previous-releases.md @@ -0,0 +1,20 @@ +--- +title: Releases +layout: download-releases.hbs +modules: 'NODE_MODULE_VERSION refers to the ABI (application binary interface) version number of Node.js, used to determine which versions of Node.js compiled C++ add-on binaries can be loaded in to without needing to be re-compiled. It used to be stored as hex value in earlier versions, but is now represented as an integer.' +--- + +# Releases + +Major Node.js versions enter _Current_ release status for six months, which gives library authors time to add support for them. +After six months, odd-numbered releases (9, 11, etc.) become unsupported, and even-numbered releases (10, 12, etc.) move to _Active LTS_ status and are ready for general use. +_LTS_ release status is "long-term support", which typically guarantees that critical bugs will be fixed for a total of 30 months. +Production applications should only use _Active LTS_ or _Maintenance LTS_ releases. + +### Release Schedule + +![Releases](https://raw.githubusercontent.com/nodejs/Release/main/schedule.svg?sanitize=true) + +Full details regarding Node.js release schedule are available [on GitHub](https://github.com/nodejs/release#release-schedule). + +### Looking for latest release of a version branch? diff --git a/pages/en/about/security-reporting.md b/pages/en/about/security-reporting.md new file mode 100644 index 0000000000000..1ac5b77800316 --- /dev/null +++ b/pages/en/about/security-reporting.md @@ -0,0 +1,74 @@ +--- +title: Security Reporting +layout: about.hbs +--- + +# Security Reporting + +For more details on active Security Policies, checkout [this page](https://github.com/nodejs/node/security/policy). + +## Reporting a bug in Node.js + +Report security bugs in Node.js via [HackerOne](https://hackerone.com/nodejs). + +Your report will be acknowledged within 5 days, and you'll receive a more +detailed response to your report within 10 days indicating the next steps in +handling your submission. + +After the initial reply to your report, the security team will endeavor to keep +you informed of the progress being made towards a fix and full announcement, +and may ask for additional information or guidance surrounding the reported +issue. + +### Node.js bug bounty program + +The Node.js project engages in an official bug bounty program for security +researchers and responsible public disclosures. The program is managed through +the HackerOne platform. See [https://hackerone.com/nodejs](https://hackerone.com/nodejs) for further details. + +## Reporting a bug in a third party module + +Security bugs in third party modules should be reported to their respective +maintainers. + +## Disclosure policy + +Here is the security disclosure policy for Node.js + +- The security report is received and is assigned a primary handler. This + person will coordinate the fix and release process. The problem is confirmed + and a list of all affected versions is determined. Code is audited to find + any potential similar problems. Fixes are prepared for all releases which are + still under maintenance. These fixes are not committed to the public + repository but rather held locally pending the announcement. + +- A suggested embargo date for this vulnerability is chosen and a CVE (Common + Vulnerabilities and Exposures (CVE®)) is requested for the vulnerability. + +- On the embargo date, the Node.js security mailing list is sent a copy of the + announcement. The changes are pushed to the public repository and new builds + are deployed to nodejs.org. Within 6 hours of the mailing list being + notified, a copy of the advisory will be published on the Node.js blog. + +- Typically the embargo date will be set 72 hours from the time the CVE is + issued. However, this may vary depending on the severity of the bug or + difficulty in applying a fix. + +- This process can take some time, especially when coordination is required + with maintainers of other projects. Every effort will be made to handle the + bug in as timely a manner as possible; however, it's important that we follow + the release process above to ensure that the disclosure is handled in a + consistent manner. + +## Receiving security updates + +Security notifications will be distributed via the following methods. + +- [https://groups.google.com/group/nodejs-sec](https://groups.google.com/group/nodejs-sec) +- [https://nodejs.org/en/blog/](https://nodejs.org/en/blog/) + +## Comments on this policy + +If you have suggestions on how this process could be improved please submit a +[pull request](https://github.com/nodejs/nodejs.org) or +[file an issue](https://github.com/nodejs/security-wg/issues/new) to discuss. diff --git a/pages/en/download/releases.md b/pages/en/download/releases.md deleted file mode 100644 index 72230649bb55b..0000000000000 --- a/pages/en/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Previous Releases -modules: 'NODE_MODULE_VERSION refers to the ABI (application binary interface) version number of Node.js, used to determine which versions of Node.js compiled C++ add-on binaries can be loaded in to without needing to be re-compiled. It used to be stored as hex value in earlier versions, but is now represented as an integer.' ---- - -### io.js & Node.js - -Releases 1.x through 3.x were called "io.js" as they were part of the io.js fork. As of Node.js 4.0.0 the former release lines of io.js converged with Node.js 0.12.x into unified Node.js releases. - -### Looking for latest release of a version branch? diff --git a/pages/es/404.md b/pages/es/404.md deleted file mode 100644 index 548d76cfb07ff..0000000000000 --- a/pages/es/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Página no encontrada - -### ENOENT: No existe el archivo o el directorio diff --git a/pages/es/about/governance.md b/pages/es/about/governance.md deleted file mode 100644 index 49ac7ad856ed5..0000000000000 --- a/pages/es/about/governance.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Dirección del Proyecto -layout: about.hbs ---- - -# Dirección del Proyecto - -## Proceso de búsqueda de consenso - -El proyecto Node.js sigue un modelo de [Búsqueda de Consenso](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) en la toma de decisiones. - -## Colaboradores - -El repositorio GitHub del core de [nodejs/node](https://github.com/nodejs/node) es mantenido por Colaboradores, los cuales son añadidos por el Comité Directivo Técnico ([TSC](https://github.com/nodejs/TSC)) de forma continua. - -Las personas que hacen contribuciones significativas y valiosas se convierten en Colaboradores y se les otorga permisos de escritura al proyecto. Estas personas son identificadas por el TSC y su nominación se discute con los Colaboradores existentes. - -Para ver la lista actual de Colaboradores, consulte el [README.md](https://github.com/nodejs/node/blob/main/README.md#current-project-team-members) del proyecto. - -Se mantiene una guía para Colaboradores en [collaborator-guide.md](https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md). - -## Comités de nivel superior - -El proyecto está dirigido conjuntamente por el [Comité de Dirección Técnica (TSC)](https://github.com/nodejs/TSC/blob/master/TSC-Charter.md), que es responsable de la orientación de alto nivel del proyecto, y el [Comité de la Comunidad (CommComm)](https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md) que es responsable de guiar y ampliar la comunidad Node.js. diff --git a/pages/es/about/index.md b/pages/es/about/index.md deleted file mode 100644 index 8c2e6e53ce473..0000000000000 --- a/pages/es/about/index.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -layout: about.hbs -title: Acerca -trademark: Trademark ---- - -# Acerca de Node.js® - -Ideado como un entorno de ejecución de JavaScript orientado a eventos asíncronos, Node.js está diseñado para crear aplicaciones network escalables. En el siguiente ejemplo de "hola mundo", pueden atenderse muchas conexiones simultáneamente. Por cada conexión, se activa la devolución de llamada o _callback_, pero si no hay trabajo que hacer, Node.js se dormirá. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hola Mundo'); -}); - -server.listen(port, hostname, () => { - console.log(`El servidor se está ejecutando en http://${hostname}:${port}/`); -}); -``` - -Esto contrasta con el modelo de concurrencia más común de hoy en día, en el que se emplean hilos del Sistema Operativo. Las redes basadas en hilos son relativamente ineficientes y muy difíciles de usar. Además, los usuarios de Node.js están libres de preocuparse por el bloqueo del proceso, ya que no existe. Casi ninguna función en Node.js realiza I/O directamente, por lo que el proceso nunca se bloquea. Por ello, es muy propicio desarrollar sistemas escalables en Node.js. - -Si alguno de estos términos no le es familiar, hay un artículo completo en [Blocking vs. Non-Blocking][]. - ---- - -Node.js es similar en diseño y está influenciado por sistemas como [Event Machine](https://github.com/eventmachine/eventmachine) de Ruby y [Twisted](https://twistedmatrix.com/trac/) de Python. Pero Node.js lleva el modelo de eventos un poco más allá. Incluye un [bucle de eventos][] como runtime de ejecución en lugar de una biblioteca. En otros sistemas siempre existe una llamada de bloqueo para iniciar el bucle de eventos. Por lo general, el comportamiento se define mediante devoluciones _callbacks_ de llamada al iniciarse un script y al final se inicia un servidor a través de una llamada de bloqueo como `EventMachine::run()`. En Node.js, no existe como tal la llamada de inicio del evento de bucle o _start-the-event-loop_. Node.js simplemente entra en el bucle de eventos después de ejecutar el script de entrada y sale cuando no hay más devoluciones _callbacks_ de llamada para realizar. Se comporta de una forma similar a JavaScript en el navegador - el bucle de eventos está oculto al usuario. - -HTTP es un elemento destacado en Node.js, diseñado teniendo en cuenta la transmisión de operaciones con streaming y baja latencia. Esto hace que Node.js sea muy adecuado para la base de una librería o un framework web. - -Que Node.js esté diseñado para trabajar sin hilos no significa que no pueda aprovechar múltiples núcleos en su entorno. Se pueden generar subprocesos o procesos hijos utilizando nuestra API [`child_process.fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options), la cual está diseñada para que la comunicación entre ellos sea fácil mediante su proceso principal. Desarrollada sobre esa misma interfaz está el módulo [`cluster`](https://nodejs.org/api/cluster.html), que le permite compartir sockets entre procesos para permitir el balanceo de carga entre sus múltiples núcleos. - -[Blocking vs. Non-Blocking]: /es/docs/guides/blocking-vs-non-blocking/ -[bucle de eventos]: /es/docs/guides/event-loop-timers-and-nexttick/ diff --git a/pages/es/docs/es6.md b/pages/es/docs/es6.md deleted file mode 100644 index a969dad83df43..0000000000000 --- a/pages/es/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) y más allá -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) y más allá - -Node.js está construido en base a versiones modernas de [V8](https://v8.dev/). Al mantenernos actualizados con las últimas versiones de este motor, aseguramos nuevas características del [La Especificación ECMA-262 de JavaScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm) que proporciona a los desarrolladores de Node.js, así como mejoras continuas en el rendimiento y la estabilidad. - -Todas las características de ECMAScript 2015 (ES6) se dividen en tres grupos **shipping**, **staged** y **in progress**: - -- Todas las funcionalidades en **shipping**, que V8 considera estable, se activan **de forma predeterminada en Node.js** y hacen que **NO** se requiera ninguna bandera o flag en tiempo de ejecución. -- Las funciones en **staged**, que son características casi completas que el equipo V8 no las considera estables, requieren un bandera o flag en tiempo de ejecución: `--harmony`. -- **In progress**, las características pueden ser activadas individualmente por su respectiva bandera o flag, aunque esto es altamente desaconsejado a menos que sea para propósitos de pruebas. Nota: estos indicadores están expuestos por V8 y potencialmente cambiarán sin previo aviso de desaprobación. - -## ¿Cuales de las características se incluyen con cada versión de Node.js por defecto? - -El sitio web [node.green](https://node.green/) proporciona una excelente visión general sobre las funciones compatibles de ECMAScript en varias versiones de Node.js, basadas en la tabla de compatibilidad de kangax. - -## ¿Cuales de las características están en progreso? - -Las nuevas características se agregan constantemente al motor V8. En términos generales, espere que lleguen en su futuro lanzamiento en Node.js, aunque se desconoce el momento. - -Puede detallar todas las funciones _in progress_ disponibles en cada versión de Node.js mediante el argumento `--v8-options`. Tenga en cuenta que estas son características incompletas y posiblemente rotas de V8, así que úselas bajo su propio riesgo: - -```bash -node --v8-options | grep "in progress" -``` - -## Tengo mi infraestructura configurada para aprovechar la bandera --harmony. ¿Debo eliminarlo? - -El comportamiento actual del indicador `--harmony` en Node.js es habilitar solo las funcionalidades en **staged**. Después de todo, ahora es sinónimo de `--es_staging`. Como se mencionó anteriormente, estas son características completas que aún no se han considerado estables. Si desea jugar de forma segura, especialmente en entornos de producción, considere eliminar este indicador de tiempo de ejecución hasta que se envíe de forma predeterminada en V8 y, en consecuencia, en Node.js. Si mantiene esto habilitado, debe estar preparado para futuras actualizaciones de Node.js que puedan romper su código si V8 cambia su semántica para seguir más de cerca el estándar. - -## ¿Cómo encuentro qué versión de V8 se envía con una versión de Node.js en particular? - -Node.js proporciona una manera simple de enumerar todas las dependencias y versiones que se envían con un binario específico a través del objeto global `process`. En el caso del motor V8, escriba lo siguiente en su terminal para recuperar su versión: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/es/docs/index.mdx b/pages/es/docs/index.mdx deleted file mode 100644 index f4e110e7e3a15..0000000000000 --- a/pages/es/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Documentación -layout: docs.hbs -labels: - lts: LTS ---- - -# Sobre la Documentación - -Existen diferentes tipos de documentación disponible en esta web: - -- Documentación de Referencia de la API -- Características de ES6 -- Guías - -## Documentación de Referencia de la API - -La [Documentación de Referencia de la API](https://nodejs.org/api/) proporciona información detallada sobre una función u objeto en Node.js. Esta documentación indica qué argumentos acepta un método, el valor de retorno de ese método y que errores pueden estar relacionados con ese método. También indica qué métodos están disponibles para diferentes versiones de Node.js. - -Esta documentación describe los módulos integrados proporcionados por Node.js. No documenta los módulos proporcionados por la comunidad. - -
- -### ¿Buscando la referencia de versiones anteriores de la API? - - - -[Todas las versiones](https://nodejs.org/docs/) - -
- -## Características de ES6 - -La [sección ES6](/en/docs/es6/) describe los tres grupos de funciones de ES6 y detalla qué funciones están habilitadas de forma predeterminada en Node.js, junto con enlaces explicativos. También muestra cómo encontrar qué versión de V8 se envió con una versión particular de Node.js. - -## Guías - -La [sección Guías](/en/docs/guides/) tiene artículos extensos y detallados sobre las características y capacidades técnicas de Node.js. diff --git a/pages/es/download/current.md b/pages/es/download/current.md deleted file mode 100644 index 745692c3b3efd..0000000000000 --- a/pages/es/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Descarga -download: Descarga -downloads: - headline: Descargas - lts: LTS - current: Actual - tagline-current: Últimas características - tagline-lts: Recomendado para la mayoría - display-hint: Mostrar descargas para - intro: > - Descargue el código fuente de Node.js o un instalador pre-compilado para su plataforma, y comience a desarrollar hoy. - currentVersion: Versión actual - buildInstructions: Compilando Node.js desde el código fuente en las plataformas soportadas - WindowsInstaller: Instalador Windows - WindowsBinary: Binario Windows - MacOSInstaller: Instalador macOS - MacOSBinary: Binario macOS - LinuxBinaries: Binario Linux - SourceCode: Código Fuente -additional: - headline: Plataformas adicionales - intro: > - Miembros de la comunidad de Node.js proveén paquetes pre-compilados de forma no oficial para plataformas adicionales no soportadas por el equipo central de Node.js que pueden no estar al mismo nivel de las versiones actuales oficiales de Node.js. - platform: Plataforma - provider: Proveedor - SmartOSBinaries: Binarios SmartOS - DockerImage: Imagen Docker - officialDockerImage: Imagen Docker Oficial Node.js - LinuxPowerSystems: Linux en Power LE Systems - LinuxSystemZ: Linux en System z - AIXPowerSystems: AIX en Power Systems ---- diff --git a/pages/es/download/index.md b/pages/es/download/index.md deleted file mode 100644 index 467a4672789e2..0000000000000 --- a/pages/es/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Descarga -download: Descarga -downloads: - headline: Descargas - lts: LTS - current: Actual - tagline-current: Últimas características - tagline-lts: Recomendado para la mayoría - display-hint: Mostrar descargas para - intro: > - Descargue el código fuente de Node.js o un instalador pre-compilado para su plataforma, y comience a desarrollar hoy. - currentVersion: Versión actual - buildInstructions: Compilando Node.js desde el código fuente en las plataformas soportadas - WindowsInstaller: Instalador Windows - WindowsBinary: Binario Windows - MacOSInstaller: Instalador macOS - MacOSBinary: Binario macOS - LinuxBinaries: Binario Linux - SourceCode: Código Fuente -additional: - headline: Plataformas adicionales - intro: > - Miembros de la comunidad de Node.js proveen paquetes pre-compilados de forma no oficial para plataformas adicionales no soportadas por el equipo central de Node.js que pueden no estar al mismo nivel de las versiones actuales oficiales de Node.js. - platform: Plataforma - provider: Proveedor - SmartOSBinaries: Binarios SmartOS - DockerImage: Imagen Docker - officialDockerImage: Imagen Docker Oficial Node.js - LinuxPowerSystems: Linux en Power LE Systems - LinuxSystemZ: Linux en System z - AIXPowerSystems: AIX en Power Systems ---- diff --git a/pages/es/download/package-manager.md b/pages/es/download/package-manager.md deleted file mode 100644 index 4b18a6da29010..0000000000000 --- a/pages/es/download/package-manager.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -layout: page.hbs -title: Instalando Node.js utilizando un gestor de paquetes ---- - -# Instalando Node.js utilizando un gestor de paquetes - -**_Nota:_** Los paquetes de esta página son mantenidos y soportados por sus respectivos responsables, **no** por el equipo central de Node.js. Por favor reporte cualquier problema que usted encuentre al responsable del paquete. Si su problema resulta ser un error en el mismo Node.js, la persona encargada reportará y escalará el error. - ---- - -- [Android](#android) -- [Arch Linux](#arch-linux) -- [Distribuciones de Linux basadas en Debian y Ubuntu, Enterprise Linux/Fedora y Snap](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE y SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS y illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) - ---- - -## Android - -El soporte para Android todavía es experimental en Node.js, por lo que los desarrolladores de Node.js aún no proporcionan los binarios precompilados. - -Sin embargo, hay algunas soluciones de terceros. Por ejemplo, la comunidad [Termux](https://termux.com/) que proporciona un emulador de terminal y un entorno Linux para Android, así como un administrador de paquetes propio y una [amplia colección](https://github.com/termux/termux-packages) de aplicaciones precompiladas. Este comando en la aplicación Termux instalará la última versión disponible de Node.js: - -```bash -pkg install nodejs -``` - -Actualmente, los binarios de Termux Node.js están vinculados contra `system-icu` (dependiendo del paquete `libicu`). - -## Arch Linux - -Los paquetes para Node.js y npm están disponibles en el repositorio de la Comunidad. - -```bash -pacman -S nodejs npm -``` - -## Distribuciones Linux basadas en Debian y Ubuntu, paquetes Enterprise Linux / Fedora y Snap - -[Las distribuciones de binarios oficiales de Node.js](https://github.com/nodesource/distributions) son proporcinados por NodeSource. - -## FreeBSD - -La release más reciente de Node.js está disponible desde el port [www/node](https://www.freshports.org/www/node). - -Instale el paquete binario a través de [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): - -```bash -pkg install node -``` - -O compílelo usted mismo utilizando [ports](https://www.freebsd.org/cgi/man.cgi?ports): - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js está disponible en portage. - -```bash -emerge nodejs -``` - -## IBM i - -Las versiones LTS de Node.js están disponibles en IBM, y están disponibles a través de [el administrador de paquetes 'yum'](https://ibm.biz/ibmi-rpms). El nombre del paquete es `nodejs` seguido del número de versión principal (por ejemplo, `nodejs8`, `nodejs10`, `nodejs12`, etc.) - -Para instalar Node.js 12.x desde la línea de comandos, ejecute lo siguiente como usuario con autoridad especial \*ALLOBJ: - -```bash -yum install nodejs12 -``` - -Node.js también se puede instalar con el producto IBM i Access Client Solutions. Consulte [este documento de soporte](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) para obtener más detalles. - -## NetBSD - -Node.js está disponible en pkgsrc: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -O instale un paquete binario (si está disponible para su plataforma) utilizando pkgin: - -```bash -pkgin -y install nodejs -``` - -## nvm - -Node Version Manager es un script bash utilizado para administrar múltiples versiones lanzadas de Node.js. Permite realizar operaciones como instalar, desinstalar, cambiar de versión, etc. Para instalar nvm, use este [script de instalación](https://github.com/nvm-sh/nvm#install--update-script). - -En los sistemas Unix / OS X, Node.js construido desde la fuente se puede instalar usando [nvm](https://github.com/creationix/nvm) instalándolo en la ubicación que nvm espera: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -Después de esto, puede utilizar `nvm` para cambiar entre las versiones publicadas y las versiones creadas desde la fuente. Por ejemplo, si la versión de Node.js es v8.0.0-pre: - -```bash -nvm use 8 -``` - -Once the official release is out you will want to uninstall the version built from source: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -The `nvs` version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems - -To install `nvs` on Windows go to the [release page](https://github.com/jasongin/nvs/releases) here and download the MSI installer file of the latest release. - -You can also use `chocolatey` to install it: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -You can find the documentation regarding the installation steps of `nvs` in macOS/Unix-like systems [here](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Usage - -After this you can use `nvs` to switch between different versions of node. - -To add the latest version of node: - -```bash -nvs add latest -``` - -Or to add the latest LTS version of node: - -```bash -nvs add lts -``` - -Then run the `nvs use` command to add a version of node to your `PATH` for the current shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -To add it to `PATH` permanently, use `nvs link`: - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js está disponible a través del sistema de puertos. - -```bash -/usr/ports/lang/node -``` - -Utilizando [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) en OpenBSD: - -```bash -pkg_add node -``` - -## openSUSE and SLE - -Node.js está disponible en los repositorios principales en los siguientes paquetes: - -- **openSUSE Leap 42.2**: `nodejs4` -- **openSUSE Leap 42.3**: `nodejs4`, `nodejs6` -- **openSUSE Tumbleweed**: `nodejs4`, `nodejs6`, `nodejs8` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs4`, `nodejs6` (The "Web and Scripting Module" must be [added before installing](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html).) - -Por ejemplo, para instalar Node.js 4.x en openSUSE Leap 42.2, ejecute lo siguiente como root: - -```bash -zypper install nodejs4 -``` - -## macOS - -Ó compílelo manualmente desde pkgsrc: - -_Si quieres descargar el paquete con bash:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### Alternativas - -Utilizando **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -Utilizando **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -Utilizando **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -Instale el paquete binario: - -```bash -pkgin -y install nodejs -``` - -O compílelo manualmente desde pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## SmartOS y illumos - -Las imágenes SmartOS vienen con pkgsrc preinstalado. En otras distribuciones de illumos, primero instale **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, y entonces podrá instalar el paquete binario de manera normal: - -```bash -pkgin -y install nodejs -``` - -O compílelo manualmente desde pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -Solus proporciona Node.js en su repositorio principal. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux incluye la versión estable de Node.js en el repositorio principal. - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -Simply download the [Windows Installer](https://nodejs.org/en/#home-downloadhead) directly from the [nodejs.org](https://nodejs.org/) web site. - -### Alternativas - -Utilizando **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -Utilizando **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -``` diff --git a/pages/es/download/releases.md b/pages/es/download/releases.md deleted file mode 100644 index a864c20b9cdeb..0000000000000 --- a/pages/es/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Versiones Anteriores -modules: 'NODE_MODULE_VERSION se refiere al número de versión ABI (interfaz binaria de la aplicación) de Node.js, que se utiliza para determinar qué versiones de binarios de complementos C++ compilados por Node.js se pueden cargar sin necesidad de volver a compilarlos. Solía almacenarse como valor hexadecimal en versiones anteriores, pero ahora se representa como un número entero.' ---- - -### io.js & Node.js - -Las versiones de la 1.x a 3.x se llamaron "io.js", ya que formaban parte del fork io.js. A partir de Node.js 4.0.0, las versiones de lanzamiento anteriores de io.js se convergieron con Node.js 0.12.x con lanzamientos unificados de Node.js. - -### ¿Buscando las últimas versiones de una rama específica? diff --git a/pages/es/get-involved/collab-summit.md b/pages/es/get-involved/collab-summit.md deleted file mode 100644 index d8c8f07256c28..0000000000000 --- a/pages/es/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Colabora en el Summit -layout: contribute.hbs ---- - -# Colabora en el Summit - -El Collaboration Summit es un evento de tipo no-conferencia para atraer actuales y potenciales colaboradores juntos para discutir Node.js con colaboración activa, educación e intercambio de conocimiento. Comités y grupos de trabajo se reúnen dos veces al año para tomar decisiones importantes mientras trabajan en algunos retos interesantes que subirán ellos mismos. - -## ¿Quién asiste? - -Todos son bienvenidos a asistir al Collab Summit. Durante el summit, los líderes ayudaran a los nuevos colaboradores a embarcarse en los grupos donde ellos deseen ayudar antes de integrarlos en las sesiones de trabajo. - -Esta es tu oportunidad de saber lo que está pasando en la comunidad, zambullirte y contribuir con las habilidades que ya tienes y aquellas que quisieras mejorar. - -Los grupos de trabajo establecerán un calendario para que la gente pueda familiarizarse antes de que inicie el evento, con discusiones generales de colaboradores, y luego entrar a sesiones de trabajo. - -Nos encantaría verte en el Collab Summit! Visita el [Summit repo](https://github.com/nodejs/summit) para saber de futuros y anteriores Collab Summits y echa un vistazo a [issues filed](https://github.com/nodejs/summit/issues) que comparte lo que los grupos de trabajo individuales y comités estan buscando discutir en persona. diff --git a/pages/es/get-involved/contribute.md b/pages/es/get-involved/contribute.md deleted file mode 100644 index a1bec5c82659c..0000000000000 --- a/pages/es/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Aportando -layout: contribute.hbs ---- - -# Aportando - -¡Gracias por su interés en aportar a Node.js! Hay varias formas y lugares en los que puede aportar, y estamos aquí para ayudar y facilitar. - -## Ayuda General - -Debido al alto nivel de actividad en el repositorio `nodejs/node`, las preguntas o solicitudes de ayuda general con Node.js deben dirigirse al [repositorio de ayuda de Node.js](https://github.com/nodejs/help/issues). - -## Reportando una Issue - -Si ha encontrado lo que cree que es un problema con Node.js, no dude en publicar un issue en el proyecto GitHub. Cuando publique su issue, asegúrese de expresar el problema con un caso de prueba reproducible, y ese caso de prueba no debe incluir ninguna dependencia externa. Es decir, que el caso de prueba se puede ejecutar sin nada más que Node.js mismo. - -Al informar con un issue, también necesitamos tanta información sobre su entorno como pueda incluir. Nunca sabemos qué información será pertinente cuando intentemos reducir el problema. Incluya, al menos ,la siguiente información: - -- Versión de Node.js -- Plataforma en la que está ejecutándose (macOS, SmartOS, Linux, Windows) -- Arquitectura en la que está funcionando (32bit or 64bit and x86 or ARM) - -El proyecto Node.js se gestiona actualmente en varios repositorios de GitHub separados, cada uno con su propia base de datos de problemas. Si es posible, dirija cualquier problema que esté informando al repositorio apropiado, pero no se preocupe si las cosas se ponen en el lugar equivocado, la comunidad de contribuyentes estará más que feliz de ayudarle a orientarse. - -- Para informar issues específicos de Node.js, utilice [nodejs/node](https://github.com/nodejs/node) -- Para informar de issues específicos de este sitio web, utilice [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## Aportaciones de Código - -Si desea corregir bugs fix o agregar una nueva funcionalidad a Node.js, asegúrese de consultar las [Pautas de contribución de Node.js](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). El proceso de revisión por parte de los colaboradores actuales para todas las aportaciones al proyecto se explica también en ese enlace. - -Si se pregunta cómo comenzar, consulte [Node Todo](https://www.nodetodo.org/), puede guiarle con su primera aportación. - -## Convertirse en colaborador - -Al convertirse en un colaborador, los contribuyentes pueden tener aún más impacto en el proyecto. Pueden ayudar a otros con la revisión de sus aportaciones, cuestiones de clasificación y tomar una parte aún mayor en la organización del proyecto. Las personas identificadas por el TSC que realizan aprotaciones significativas y valiosas en cualquier repositorio de Node.js pueden ser Colaboradores y tener acceso al proyecto. Las actividades tomadas en consideración incluyen (pero no se limitan a) en calidad de: - -- código de commits y pull requests -- documentación de commits y pull requests -- comentarios en issues y en pull requests -- contribuciones a la web Node.js -- asistencia a usuarios finales y contribuyentes novatos -- participación en los Working Groups -- otra participación en la Comunidad de Node.js - -Si las personas que realizan aportaciones valiosas no creen que se les haya considerado para comprometerse con el proyecto y acceder, pueden [registrar una issue](https://github.com/nodejs/TSC/issues) o [contactar a un miembro del TSC](https://github.com/nodejs/TSC#current-members) directamente. diff --git a/pages/es/get-involved/index.md b/pages/es/get-involved/index.md deleted file mode 100644 index 08a7399b5b31b..0000000000000 --- a/pages/es/get-involved/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Participe -layout: contribute.hbs ---- - -# Participe - -## Discusión de la Comunidad - -- La [lista de errores](https://github.com/nodejs/node/issues) es el lugar para discutir las características del núcleo de Node.js. -- La cuenta de Twitter oficial de Node.js es [nodejs](https://twitter.com/nodejs). -- El [calendario de la Fundación Node.js](https://nodejs.org/calendar) con todas las reuniones del equipo público. -- [Node Weekly](https://nodeweekly.com/) es una lista de correo que recopila los últimos eventos y noticias alrededor de la comunidad de Node.js. -- [Node Slackers](https://www.nodeslackers.com/) es una comunidad de Slack enfocada en Node.js. - -## Aprendizaje - -- La [Documentación oficial de la API](https://nodejs.org/api/) detalla la API de Node. -- [NodeSchool.io](https://nodeschool.io/) le enseñará conceptos de Node.js de forma interactiva mediante juegos utilizando la línea de comandos. -- La [etiqueta de Node.js en Stack Overflow](https://stackoverflow.com/questions/tagged/node.js) colecciona nueva información cada día. -- [La etiqueta DEV Community Node.js](https://dev.to/t/node) es un lugar para compartir proyectos, artículos y tutoriales de Node.js, así como para iniciar debates y pedir información sobre temas relacionados con Node.js. Desarrolladores de todos los niveles son bienvenidos a participar. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) es una comunidad amigable de desarrolladores back-end de Node.js que se apoyan mutuamente en Discord. - -## Sitios de comunidades internacionales y proyectos - -- [Comunidad China](https://cnodejs.org/) -- [Comunidad de Hungría (Magyar)](https://nodehun.blogspot.com/) -- [Comunidad en Facebook de usuarios Israelíes de Node.js](https://www.facebook.com/groups/node.il/) -- [Grupo de usuarios de Japón](https://nodejs.jp/) -- [Comunidad en Facebook de Español/Castellano](https://www.facebook.com/groups/node.es/) -- [Comunidad Vietnamita Node.js](https://www.facebook.com/nodejs.vn/) -- [Uzbekistan group for Node.js](https://t.me/nodejs_uz) diff --git a/pages/es/index.md b/pages/es/index.md deleted file mode 100644 index cf2a14f76b27a..0000000000000 --- a/pages/es/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Versión Actual - download: Descarga - download-for: Descargar para - other-downloads: Otras Descargas - current: Actual - lts: LTS - tagline-current: Últimas características - tagline-lts: Recomendado para la mayoría - changelog: Cambios - api: Documentación de la API - version-schedule-prompt: O eche un vistazo al - version-schedule-prompt-link-text: Programa de soporte a largo plazo (LTS) ---- - -Node.js® es un entorno de ejecución para JavaScript construido con [V8, motor de JavaScript de Chrome](https://v8.dev/). diff --git a/pages/fa/404.md b/pages/fa/404.md deleted file mode 100644 index b2f26c2b12080..0000000000000 --- a/pages/fa/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: صفحه مورد نظر شما یافت نشد. - -### ENOENT: فایل یا فولدر مورد نظر یافت نشد. diff --git a/pages/fa/about/index.md b/pages/fa/about/index.md deleted file mode 100644 index e679a69abe035..0000000000000 --- a/pages/fa/about/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -layout: about.hbs -title: درباره -trademark: نشان تجاری ---- - -# درباره Node.js® - -به عنوان یک اجرا کننده رویدادهای ناهماهنگ در جاوا اسکریپت، Node.js به شکلی طراحی شده است که بتوان با آن برنامه‌های تحت وب توسعه پذیر ساخت. در مثال "hello world" پایین، تعداد خیلی زیادی اتصال به صورت هم زمان انجام گیرد. پس از هر اتصال یه فراخوان (callback) اجرا خواهد شد، اما اگر کاری برای انجام نباشد نود می‌خوابد. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -این در مقایسه با مدل امروزی‌تر هم‌زمانی است، جایی که Theradهای سیستم عامل به کار گرفته می‌شوند. شبکه مبتنی بر Thread به نسب ناکارآمد و بسیار سخت کاربرد است. علاوه بر این کاربران Node.js از نگرانی قفل مرگبار فرایند‌ها آسوده هستند. از آن جایی که هیچ قفلی وجود ندارد، تقریبا هیچ فانکشنی در Node.js به صورت مستقیم با I/O انجام نمی‌دهد بنا بر این هیچ فرایند‌ای فقل نخواهد شد. به همین علت پیاده سازی سیستم‌های مقیاس‌پذیر بر روی Node.js بسیار منطقی است. - -اگر با این ادبیات ناآشنا هستید یک مقاله کامل در این رابطه وجود دارد. [Blocking vs Non-Blocking][]. - ---- - -Node.js در طراحی مشابه و تاثیر گرفته است از سیستم‌هایی ماننده Ruby's [Event Machine][] یا Python's [Twisted][]. Node.js مدل رویداد را کمی به جلوتر می‌برد و [event loop][] را به عنوان یک ساختار زمان‌بندی به جای یک کتابخانه ارائه می‌کند. - -در سیستم‌های دیگر همیشه یک تماس مسدود کننده برای شروع event-loop وجود دارد. - -به طور معمول رفتار از طریق callbackها در ابتدای اسکریپت تعریف می‌شود و در پایان یک سرور را از طریق یک تماس مسدود کننده مانند `EventMachine::run()` اجرا می‌کند. در Node.js چیزی به عنوان فراخوان برای شروع حلقه رویداد وجود ندارد. Node.js پس از اجرای اسکریپت ورودی به حلقه رویداد وارد می‌شود. این رفتار ماننده جاوااسکریپت در مرورگر است - حلقه رویداد از کاربر مخفی می‌ماند. - -[Blocking vs Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[event loop]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/fa/index.md b/pages/fa/index.md deleted file mode 100644 index 14acba4eebd37..0000000000000 --- a/pages/fa/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: نگارش کنونی - download: دانلود - download-for: دانلود برای - other-downloads: سایر دانلود‌ها - current: جاری - lts: پشتیبانی طولانی مدت - tagline-current: آخرین ویژگی‌ها - tagline-lts: پیشنهاد شده برای بیشتر کاربران - changelog: گزارش تغییرات - api: مستندات API - version-schedule-prompt: یا نگاهی بیاندازید به - version-schedule-prompt-link-text: زمان بندی پشتیبانی طولانی مدت ---- - -Node.js® چارچوبی است برای اجرای جاوااسکریپت ساخته شده بر روی [موتور جاوااسکریپت کروم](https://v8.dev/). diff --git a/pages/fr/404.md b/pages/fr/404.md deleted file mode 100644 index 070b7d6c36f57..0000000000000 --- a/pages/fr/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Page introuvable - -### ENOENT: aucun fichier ou répertoire trouvé diff --git a/pages/fr/about/governance.md b/pages/fr/about/governance.md deleted file mode 100644 index 7066c875f4384..0000000000000 --- a/pages/fr/about/governance.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Gouvernance du Projet -layout: about.hbs ---- - -# Gouvernance du Projet - -## Comité de Pilotage Technique - -Le projet est co-dirigé par un Comité de Pilotage Technique (Technical Steering Committee - TSC) qui est responsable de la gouvernance de haut-niveau du projet. - -## Collaborateurs - -Le TSC a toute autorité sur ce projet, y compris: - -Les invitations originelles à siéger au TSC ont été proposées à des contributeurs actifs qui avaient une expérience significative avec la gestion du projet. La participation à ce comité est susceptible d'évoluer dans le temps en rapport avec les besoins du projet. - -Pour obtenir la liste actuelle des collaborateurs, consultez le [README.md][]. - -Un guide pour les collaborateurs est disponible à l'adresse [collaborator-guide.md][]. - -## Comités de haut niveau - -Le projet est régi par le [Technical Steering Committee (TSC)][] qui est responsable de l'orientation à haut niveau du projet. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Technical Steering Committee (TSC)]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md diff --git a/pages/fr/about/index.md b/pages/fr/about/index.md deleted file mode 100644 index 4239891cdc248..0000000000000 --- a/pages/fr/about/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -layout: about.hbs -title: À propos -trademark: Marque déposée ---- - -# À propos de Node.js® - -En tant que moteur d'exécution JavaScript asynchrone piloté par les événements, Node.js est conçu pour construire des applications réseau évolutives. des applications réseau évolutives. Dans l'exemple suivant, "hello world", de nombreuses peuvent être gérées simultanément. À chaque connexion, le rappel est mais s'il n'y a pas de travail à faire, Node.js se met en veille. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Bonjour touts le mondes''); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Ceci contraste avec le modèle de concurrence plus commun dans lequel les processus sytème sont utilisés. La gestion réseau basée sur les processus est relativement inefficace et difficile à utiliser. De plus, les utilisateurs de Node.js n'ont pas à se soucier des problèmes d'interblocage des processus puisqu'il n'y a pas de verrouillage. Aucune fonction de Node.js ou presque n'effectue d'entrée/sortie, donc le processus ne se bloque pas. Et comme rien n'est bloquant, développer un système extensible est relativement aisé avec Node.js. - -Si une partie des termes utilisés ne vous sont pas familliers, voici un article complet (en anglais) [Bloquant vs Non-Bloquant](/en/docs/guides/blocking-vs-non-blocking/). - ---- - -Node.js est conçu de manière similaire et influencé par des librairies comme [Event Machine](https://github.com/eventmachine/eventmachine) (en) pour Ruby et [Twisted](https://twistedmatrix.com/trac/) (en) pour Python. Node.js pousse le modèle événementiel encore plus loin. Il instaure la [boucle événementielle](/en/docs/guides/event-loop-timers-and-nexttick/) (en) en tant que composant élémentaire de l'environnement d'exécution et non comme une librairie. Dans les autres systèmes, il y a toujours un appel bloquant pour démarrer la boucle événementielle. Le comportement est défini habituellement par des fonctions de rappel au début du script, et à la fin un serveur est démarré avec un appel bloquant comme `EventMachine::run()`. Dans Node.js, il n'y a pas d'appel pour démarrer la boucle. Node.js entre simplement dans la boucle après avoir exécuté le script d'entrée. Node.js sort de la boucle événementielle lorsqu'il n'y a plus de fonction de rappel à exécuter. Ce comportement est similaire à celui de JavaScript dans un navigateur - la boucle événementielle est cachée à l'utilisateur. - -HTTP a une place prépondérante dans Node.js, qui a été conçu pour le streaming et une faible latence. Ceci fait de Node.js une base toute désignée pour une librairie web ou un framework. - -Et si Node.js a été conçu sans processus multiples, vous pouvez tout de même profiter d'un environnement multi-coeur. Vous pouvez générer des processus enfant par le biais de l'API [`child_process.fork()`][] (en), avec lesquels vous pourrez communiquer facilement. Basé sur la même interface, le module [`cluster`][] (en) vous permettra de partager les sockets entre vos processus pour faire de la répartition de charge entre vos coeurs. diff --git a/pages/fr/docs/es6.md b/pages/fr/docs/es6.md deleted file mode 100644 index 97f90d96c834f..0000000000000 --- a/pages/fr/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) et au-delà -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) et au-delà - -Node.js est construit avec les versions modernes de [V8](https://v8.dev/). En se tenant au courant des dernières versions de ce moteur, nous nous assurons que de nouvelles fonctionnalités de la spécification [JavaScript ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm) sont apportées à Node. , les développeurs en temps opportun, ainsi que des améliorations continues des performances et de la stabilité. - -Toutes les fonctionnalités de l'ECMAScript 2015 (ES6) sont divisées en trois groupes pour les fonctionnalités de **livraison**, **mise en scène**et **en cours**: - -- Toutes les fonctionnalités **de livraison** que V8 considère comme stables sont activées **par défaut sur Node. s** et **PAS** ne requièrent aucune sorte d'indicateur de temps d'exécution. -- **Les** fonctionnalités stationnées, qui sont des fonctionnalités presque achevées qui ne sont pas considérées comme stables par l'équipe V8, nécessitent un drapeau d'exécution : `--harmonie`. -- **En cours** les fonctionnalités peuvent être activées individuellement par leur drapeau d'harmonie respectif, bien que cela soit fortement découragé à moins de procéder à des essais. Note : ces drapeaux sont exposés par V8 et peuvent être modifiés sans avis de dépréciation. - -## Quelles fonctionnalités sont fournies avec lesquelles la version de Node.js par défaut ? - -Le site web [node.green](https://node.green/) fournit un excellent aperçu des fonctionnalités de l'ECMAScript supportées dans diverses versions de Node.js, basé sur la table compat de kangax. - -## Quelles sont les fonctionnalités en cours ? - -De nouvelles fonctionnalités sont constamment ajoutées au moteur V8. En général, attendez-vous à ce qu'elles atterrissent sur une future version de Node.js, bien que le timing soit inconnu. - -Vous pouvez lister toutes les fonctionnalités de _en cours_ disponibles sur chaque noeud. s en utilisant l'argument `--v8-options` . Veuillez noter que ce sont des fonctionnalités incomplètes et éventuellement cassées de V8, donc utilisez-les à vos propres risques : - -```bash -node --v8-options | grep "in progress" -``` - -## J'ai mis en place mon infrastructure pour tirer parti du drapeau --harmonie. Dois-je le retirer ? - -Le comportement actuel du drapeau `--harmony` sur Node.js est d'activer les fonctionnalités **staged** uniquement. Après tout, c'est maintenant un synonyme de `--es_staging`. Comme mentionné ci-dessus, ces fonctionnalités sont complétées qui n'ont pas encore été considérées comme stables. Si vous voulez jouer en toute sécurité, en particulier dans les environnements de production, envisagez de supprimer ce drapeau d'exécution jusqu'à ce qu'il soit livré par défaut sur V8 et, par conséquent, sur Node.js. Si vous gardez cette option activée, vous devriez être préparé pour d'autres nœuds. s améliore pour casser votre code si V8 modifie leur sémantique pour suivre plus attentivement le standard. - -## Comment trouver quelle version de V8 est fournie avec une version particulière de Node.js ? - -Node.js fournit un moyen simple de lister toutes les dépendances et leurs versions respectives qui sont livrées avec un binaire spécifique grâce à l'objet global `process`. Dans le cas du moteur V8, tapez ce qui suit dans votre terminal pour récupérer sa version : - -```bash -node -p process.versions.v8 -``` diff --git a/pages/fr/docs/guides/abi-stability.md b/pages/fr/docs/guides/abi-stability.md deleted file mode 100644 index 011e30b36bb22..0000000000000 --- a/pages/fr/docs/guides/abi-stability.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Stabilité de l'ABI -layout: docs.hbs ---- - -# Stabilité de l'ABI - -## Introduction - -Une interface binaire d'application (ABI) permet aux programmes d'appeler des fonctions et d'utiliser des structures de données d'autres programmes compilés. et d'utiliser les structures de données d'autres programmes compilés. Il s'agit de la version compilée d'une interface de programmation d'application (API). En d'autres termes, les fichiers d'en-tête décrivant les classes, les fonctions, les structures de données, les énumérations et les constantes qui permettent à une application d'effectuer une tâche donnée correspondent, par le biais de la compilation, à un ensemble d'adresses et d'informations attendues. compilation à un ensemble d'adresses et de valeurs de paramètres attendues, ainsi qu'à des tailles et à des dispositions de structures de mémoire avec lesquelles l'application peut fonctionner. de taille et de disposition des structures de mémoire avec lesquelles le fournisseur de l'ABI a été compilé. - -L'application utilisant l'ABI doit être compilée de telle sorte que les adresses disponibles, les valeurs de paramètre attendues, et les tailles de la structure de mémoire et les mises en page sont d'accord avec celles avec lesquelles le fournisseur ABI a été compilé. Ceci est généralement accompli en compilant les en-têtes fournis par le fournisseur ABI. - -En raison de l'utilisation de l'ABI à différents moments avec différentes versions du compilateur, une partie de la responsabilité d'assurer la compatibilité de l'ABI incombe au compilateur. Différentes versions du compilateur, éventuellement fournies par différents vendeurs, doivent toutes produire la même ABI à partir d'un fichier d'en-tête ayant un certain contenu, et doivent produire un code pour l'application utilisant l'ABI qui accède à l'API décrite dans un en-tête donné conformément aux conventions de l'ABI résultant de la description dans l'en-tête. Les compilateurs modernes ont la réputation de ne pas rompre la compatibilité ABI des applications qu'ils compilent. - -La responsabilité restante de la compatibilité de l'ABI incombe à l'équipe chargée de la maintenance des fichiers d'en-tête qui fournissent l'API qui aboutit, lors de la compilation, à l'ABI qui doit rester stable. Des modifications peuvent être apportées aux fichiers d'en-tête, mais la nature des changements doit être suivie de près pour garantir que, lors de la compilation, l'ABI ne change pas d'une manière qui rendrait les utilisateurs existants de l'ABI incompatibles avec la nouvelle version. - -## Stabilité de l'ABI dans Node.js - -Node.js fournit des fichiers d'en-tête gérés par plusieurs équipes indépendantes. Par exemple, les fichiers d'en-tête tels que `node.h` et `node_buffer.h` sont gérés par l'équipe Node.js. `v8.h` est maintenu par l'équipe V8, qui, bien qu'en étroite collaboration avec l'équipe Node.js, est indépendante, et avec son propre calendrier et ses propres priorités. Ainsi, l'équipe Node.js n'a qu'un contrôle partiel sur les modifications introduites dans les en-têtes fournis par le projet. En conséquence, le projet Node.js a adopté la [version sémantique](https://semver.org/). Cela garantit que les API fournies par le projet se traduiront par une ABI stable pour toutes les versions mineures et correctives de Node.js publiées dans une version majeure. En pratique, cela signifie que le projet Node.js s'est engagé à garantir qu'un addon natif Node.js compilé avec une version majeure donnée de Node.js se chargera avec succès lorsqu'il sera chargé par n'importe quelle version mineure ou corrective de Node.js dans la version majeure. version avec laquelle il a été compilé. - -## N-API - -Il existe une demande pour doter Node.js d'une API qui permette d'obtenir une ABI stable sur plusieurs versions majeures de Node.js. La motivation pour créer une telle API est la suivante : - -- Le langage JavaScript est resté compatible avec lui-même depuis ses débuts, alors que l'ABI du moteur qui exécute le code JavaScript change avec chaque version majeure de Node.js. Cela signifie que les applications composées de paquets Node.js écrits entièrement en JavaScript n'ont pas besoin d'être recompilées, réinstallées ou redéployées lorsqu'une nouvelle version majeure de Node.js est introduite dans l'environnement de production dans lequel ces applications s'exécutent. En revanche, si une application dépend d'un paquetage contenant un addon natif, l'application doit être recompilée, réinstallée et redéployée chaque fois qu'une nouvelle version majeure de Node.js est introduite dans l'environnement de production. Cette disparité entre les paquets Node.js contenant des modules d'extension natifs et ceux qui sont entièrement écrits en JavaScript a alourdi la charge de maintenance des systèmes de production qui reposent sur des modules d'extension natifs. - -- D'autres projets ont commencé à produire des interfaces JavaScript qui sont essentiellement des implémentations alternatives de Node.js. Étant donné que ces projets reposent généralement sur un moteur JavaScript différent de celui de V8, leurs modules complémentaires natifs ont nécessairement une structure différente et utilisent une API différente. Néanmoins, l'utilisation d'une API unique pour un addon natif à travers différentes implémentations de l'API JavaScript de Node.js permettrait à ces projets de profiter de l'écosystème de paquets JavaScript qui s'est développé autour de Node.js. - -- Node.js pourrait contenir un moteur JavaScript différent à l'avenir. Cela signifie qu'extérieurement, toutes les interfaces de Node.js resteraient les mêmes, mais que le fichier d'en-tête V8 serait absent. Une telle mesure perturberait l'écosystème Node.js en général, et celui des modules d'extension natifs en particulier, si une API indépendante du moteur JavaScript n'est pas d'abord fournie par Node.js et adoptée par les modules d'extension natifs. - -À ces fins, Node.js a introduit N-API dans la version 8.6.0 et l'a marqué comme un composant stable du projet à partir de Node.js 8.12.0. L'API est définie dans les en-têtes [`node_api. h`][] et [`node_api_types.h`][], et fournit une garantie de compatibilité ascendante qui franchit la frontière de la version majeure de Node.js. La garantie peut être formulée comme suit : - -**Une version donnée _n_ de la N-API sera disponible dans la version majeure de Node.js dans laquelle elle a été publiée, ainsi que dans toutes les versions ultérieures de Node.js, y compris les versions majeures ultérieures.** - -Un auteur d'addon natif peut profiter de la garantie de compatibilité ascendante N-API en s'assurant que l'addon n'utilise que les API définies dans `node_api.h` et les structures de données et les constantes définies dans `node_api_types.h`. Ce faisant, l'auteur facilite l'adoption de son addon en indiquant aux utilisateurs en production que la charge de maintenance de leur application n'augmentera pas plus par l'ajout de l'addon natif à leur projet qu'elle ne le ferait par l'ajout d'un package écrit uniquement en JavaScript . - -La N-API est versionnée parce que de nouvelles API sont ajoutées de temps à autre. Contrairement au versionnement sémantique, le versionnement de la N-API est cumulatif. En d'autres termes, chaque version de la N-API a la même signification qu'une version mineure du système sémantique, ce qui signifie que toutes les modifications apportées à la N-API seront rétrocompatibles. En outre, les nouvelles N-API sont ajoutées sous un drapeau expérimental afin de donner à la communauté la possibilité de les tester dans un environnement de production. Le statut expérimental signifie que, bien que l'on ait veillé à ce que la nouvelle N-API ne doive pas être modifiée de manière incompatible avec l'ABI à l'avenir, elle n'a pas encore été suffisamment éprouvée en production pour être correcte et utile telle qu'elle a été conçue et, en tant que telle, elle peut subir des modifications incompatibles avec l'ABI avant d'être finalement incorporée dans une prochaine version de la N-API. En d'autres termes, une N-API expérimentale n'est pas encore couverte par la garantie de compatibilité future. - -[`node_api. h`]: https://github.com/nodejs/node/blob/main/src/node_api.h diff --git a/pages/fr/docs/index.mdx b/pages/fr/docs/index.mdx deleted file mode 100644 index d1c3584b8de6c..0000000000000 --- a/pages/fr/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Documentation -layout: docs.hbs -labels: - lts: LTS ---- - -# Au sujet de la documentation - -Plusieurs types de documentation sont disponibles sur ce site web : - -- Documentation de référence de l'API -- Caractéristiques de l'ES6 -- Guides - -## Documentation de référence de l'API - -La [documentation de référence de l'API] (https://nodejs.org/api/) fournit des informations détaillées sur une fonction ou un objet dans Node.js. Cette documentation indique quels arguments une méthode accepte, la valeur de retour de cette méthode et les erreurs qui peuvent être liées à cette méthode. Elle indique également quelles méthodes sont disponibles pour les différentes versions de Node.js. - -Cette documentation décrit les modules intégrés fournis par Node.js. Elle ne documente pas les modules fournis par la communauté. - -
- -### Vous recherchez les documents relatifs aux API des versions précédentes ? - - - -[All versions](https://nodejs.org/docs/) - -
- -## Caractéristiques ES6 - -La [section ES6](/fr/docs/es6/) décrit les trois groupes de fonctionnalités ES6 et précise quelles fonctionnalités sont activées par défaut dans Node.js, avec des liens explicatifs. Elle indique également comment trouver la version de V8 livrée avec une version particulière de Node.js. - -## Guides - -La section [Guides](/fr/docs/guides/) contient des articles détaillés sur les caractéristiques techniques et les capacités de Node.js. diff --git a/pages/fr/download/current.md b/pages/fr/download/current.md deleted file mode 100644 index 76e69763b37aa..0000000000000 --- a/pages/fr/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Téléchargements -download: Télécharger -downloads: - headline: Téléchargements - lts: LTS - current: Dernière - tagline-current: Dernières fonctionnalités - tagline-lts: Recommandé pour la plupart des utilisateurs - display-hint: Afficher les téléchargements pour Node - intro: > - Téléchargez le code source de Node.js pour votre système d'exploitation et commencez à développer dès aujourd'hui. - currentVersion: Dernière version Actuelle - buildInstructions: Compiler Node.js à partir du code source sur les systèmes d'exploitation maintenus - WindowsInstaller: Installateur Windows - WindowsBinary: Binaire Windows - MacOSInstaller: Installateur macOS - MacOSBinary: Binaire macOS - LinuxBinaries: Binaires Linux - SourceCode: Code Source -additional: - headline: Autres plate-formes - intro: > - Les membres de la communauté Node.js maintiennent des installateurs de Node.js pour d'autres plate-formes. Veuillez noter que ces téléchargements ne sont pas maintenus par l'équipe principale de Node.js et n'offrent pas forcément le même niveau de support que les téléchargements officiels. - platform: Image Docker de Node.js - provider: Plate-forme - SmartOSBinaries: Binaires SmartOS - DockerImage: Image Docker - officialDockerImage: Image Docker Officielle de Node.js - LinuxPowerSystems: Linux sur Power LE systems - LinuxSystemZ: Linux sur System z - AIXPowerSystems: AIX sur les systèmes de puissance ---- diff --git a/pages/fr/download/index.md b/pages/fr/download/index.md deleted file mode 100644 index e2ae32df7c52d..0000000000000 --- a/pages/fr/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Téléchargements -download: Télécharger -downloads: - headline: Téléchargements - lts: LTS - current: Dernière - tagline-current: Dernières fonctionnalités - tagline-lts: Recommandé pour la plupart des utilisateurs - display-hint: Afficher les téléchargements pour Node - intro: > - Téléchargez le code source de Node.js pour votre système d'exploitation et commencez à développer dès aujourd'hui. - currentVersion: Dernière version LTS - buildInstructions: Compiler Node.js à partir du code source sur les systèmes d'exploitation maintenus - WindowsInstaller: Installateur Windows - WindowsBinary: Binaire Windows - MacOSInstaller: Installateur macOS - MacOSBinary: Binaire macOS - LinuxBinaries: Binaires Linux - SourceCode: Code Source -additional: - headline: Autres plate-formes - intro: > - Les membres de la communauté Node.js maintiennent des installateurs de Node.js pour d'autres plate-formes. Veuillez noter que ces téléchargements ne sont pas maintenus par l'équipe principale de Node.js et n'offrent pas forcément le même niveau de support que les téléchargements officiels. - platform: Image Docker de Node.js - provider: Plate-forme - SmartOSBinaries: Fournisseur - DockerImage: Image Docker - officialDockerImage: Image Docker officielle de Node.js - LinuxPowerSystems: Linux sur Power LE Systems - LinuxSystemZ: Linux sur System z - AIXPowerSystems: AIX sur les systèmes de puissance ---- diff --git a/pages/fr/download/package-manager.md b/pages/fr/download/package-manager.md deleted file mode 100644 index 1ffcef1df1b19..0000000000000 --- a/pages/fr/download/package-manager.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -layout: page.hbs -title: Installation de Node.js via le gestionnaire de paquets ---- - -# Installation de Node.js via le gestionnaire de paquets - -**_Note:_** Les paquets sur cette page sont maintenus et supportés par leurs mainteneurs respectifs, **non pas** par l'équipe centrale de Node.js. Veuillez signaler tout problème que vous rencontrez au mainteneur du paquet. S'il s'avère que votre problème est un bogue dans Node.js lui-même, le mainteneur signalera le problème en amont. - ---- - -- [Android](#android) -- [Arch Linux](#arch-linux) -- [Distributions Linux dérivées de Debian et Ubuntu, Linux/Fedora Entreprise, et paquets Snap](#les-distributions-linux-basées-sur-debian-et-ubuntu-enterprise-linuxfedora-et-les-paquets-snap) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE and SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS and illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows) - ---- - -## Android - -Le support d'Android est encore expérimental dans Node.js, donc les binaires précompilés ne sont pas encore fournis par les développeurs de Node.js. - -Cependant, il existe quelques solutions tierces. Par exemple, la communauté [Termux](https://termux.com/) fournit un émulateur de terminal et un environnement Linux pour Android, ainsi que son propre gestionnaire de paquets et une [vaste collection](https://github.com/termux/termux-packages) de nombreuses applications précompilées. Cette commande dans l'application Termux installera la dernière version disponible de Node.js : - -```bash -pkg install nodejs -``` - -Currently, Termux Node.js binaries are linked against `system-icu` (depending on `libicu` package). - -## Arch Linux - -Node.js and npm packages are available in the Community Repository. - -```bash -pacman -S nodejs npm -``` - -## Les distributions Linux basées sur Debian et Ubuntu, Enterprise Linux/Fedora et les paquets Snap - -[Les distributions binaires Node.js](https://github.com/nodesource/distributions) sont disponibles sur NodeSource. - -## FreeBSD - -La version la plus récente de Node.js est disponible via le port [www/node](https://www.freshports.org/www/node). - -Installez un paquet binaire via [pkg](https://www.freebsd.org/cgi/man.cgi?pkg) : - -```bash -pkg install node -``` - -Ou compilez-le vous-même en utilisant [ports](https://www.freebsd.org/cgi/man.cgi?ports) : - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js est disponible dans l'arbre de portage. - -```bash -emerge nodejs -``` - -## IBM i - -Les versions LTS de Node.js sont disponibles auprès d'IBM, et sont disponibles via [le gestionnaire de paquets 'yum'] (https://ibm.biz/ibmi-rpms). Le nom du paquet est `nodejs` suivi du numéro de la version majeure (par exemple, `nodejs8`, `nodejs10`, `nodejs12`, etc). - -Pour installer Node.js 12.x à partir de la ligne de commande, exécutez la commande suivante en tant qu'utilisateur disposant de l'autorisation spéciale \*ALLOBJ : - -```bash -yum install nodejs12 -``` - -Node.js peut également être installé avec le produit IBM i Access Client Solutions. Voir [ce document de support] (http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) pour plus de détails. - -## NetBSD - -Node.js est disponible dans l'arbre pkgsrc : - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -Ou installez un paquet binaire (si disponible pour votre plateforme) en utilisant pkgin : - -```bash -pkgin -y install nodejs -``` - -## nvm - -Node Version Manager est un script bash utilisé pour gérer plusieurs versions de Node.js. Il vous permet d'effectuer des opérations comme l'installation, la désinstallation, le changement de version, etc. Pour installer nvm, utilisez ce [script d'installation](https://github.com/nvm-sh/nvm#install--update-script). - -Sur les systèmes Unix / OS X, Node.js construit à partir des sources peut être installé en utilisant [nvm](https://github.com/creationix/nvm) en l'installant à l'emplacement attendu par nvm : - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -Après cela, vous pouvez utiliser `nvm` pour basculer entre les versions publiées et les versions construites à partir des sources. Par exemple, si la version de Node.js est v8.0.0-pre : - -```bash -nvm use 8 -``` - -Une fois que la version officielle sera sortie, vous voudrez désinstaller la version construite à partir des sources : - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -Le gestionnaire de version `nvs` est multiplateforme et peut être utilisé sur Windows, macOS, et les systèmes Unix. - -Pour installer `nvs` sur Windows, allez sur la [release page](https://github.com/jasongin/nvs/releases) ici et téléchargez le fichier d'installation MSI de la dernière version. - -Vous pouvez également utiliser `chocolatey` pour l'installer : - -```bash -choco install nvs -``` - -#### macOS et tous les systèmes de type Unix - -Vous pouvez trouver la documentation concernant les étapes d'installation de `nvs` dans les systèmes macOS/Unix-like [ici](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Utilisation - -Après cela, vous pouvez utiliser `nvs` pour basculer entre les différentes versions de node. - -Pour ajouter la dernière version de node : - -```bash -nvs add latest -``` - -Ou pour ajouter la dernière version LTS de node : - -```bash -nvs add lts -``` - -Ensuite, lancez la commande `nvs use` pour ajouter une version de node à votre `PATH` pour le shell actuel : - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -Pour l'ajouter au `PATH` de façon permanente, utilisez `nvs link` : - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js est disponible via le système de ports. - -```bash -/usr/ports/lang/node -``` - -Utilisation de [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) sur OpenBSD : - -```bash -pkg_add node -``` - -## openSUSE et SLE - -Node.js est disponible dans les dépôts principaux sous les paquets suivants : - -- **openSUSE Leap 42.2** : `nodejs4` -- **openSUSE Leap 42.3** : `nodejs4`, `nodejs6` - **openSUSE Tumbleweed** : `nodejs4`, `nodejs6`, `nodejs8` - **SUSE Linux Enterprise Server (SLES) 12** : `nodejs4`, `nodejs6` (Le "Web and Scripting Module" doit être [ajouté avant l'installation](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html).) - -Par exemple, pour installer Node.js 4.x sur openSUSE Leap 42.2, exécutez ce qui suit en tant que root : - -```bash -zypper install nodejs4 -``` - -## macOS - -Téléchargez simplement le [macOS Installer](https://nodejs.org/en/#home-downloadhead) directement depuis le site Web [nodejs.org](https://nodejs.org/). - -_Si vous voulez télécharger le paquet avec bash:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### Alternatives - -Utilisation de **[Homebrew](https://brew.sh/)** : - -```bash -brew install node -``` - -Utilisation de **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -Utilisation de **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -Installez le paquet binaire : - -```bash -pkgin -y install nodejs -``` - -Ou compiler manuellement à partir de pkgsrc : - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## SmartOS et illumos - -Les images SmartOS sont livrées avec pkgsrc pré-installé. Sur les autres distributions illumos, installez d'abord **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, puis vous pouvez installer le paquet binaire normalement : - -```bash -pkgin -y install nodejs -``` - -Ou compiler manuellement à partir de pkgsrc : - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -Solus fournit Node.js dans son dépôt principal. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux fournit Node.js stable dans le dépôt principal. - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -Téléchargez simplement le [Windows Installer](https://nodejs.org/en/#home-downloadhead) directement depuis le site web [nodejs.org](https://nodejs.org/). - -### Alternatives - -En utilisant **[Chocolatey](https://chocolatey.org/)** : - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -En utilisant **[Scoop](https://scoop.sh/)** : - -```bash -scoop install nodejs -``` diff --git a/pages/fr/download/releases.md b/pages/fr/download/releases.md deleted file mode 100644 index 13c1738a45570..0000000000000 --- a/pages/fr/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Versions antérieures -modules: "NODE_MODULE_VERSION désigne le numéro de version ABI (application binary interface) de Node.js, utilisé pour déterminer les versions de Node.js.dans lesquelles les extensions C++ compilées en binaires peuvent être chargées dans devoir être recompilées. Il était stocké sous forme de valeur hexadécimale dans les versions antérieures, mais est désormais représenté sous forme d'un nombre entier." ---- - -### io.js & Node.js - -Les versions 1.x à 3.x étaient appelées "io.js" car elles faisaient partie du fork io.js. À partir de Node.js 4.0.0, les anciennes versions de io.js ont convergé avec Node.js 0.12.x en versions unifiées de Node.js. - -### Vous cherchez la dernière version d'une branche de version ? diff --git a/pages/fr/get-involved/collab-summit.md b/pages/fr/get-involved/collab-summit.md deleted file mode 100644 index 52c6011ab452f..0000000000000 --- a/pages/fr/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Sommet de collaboration -layout: contribute.hbs ---- - -# Sommet de collaboration - -Le Collaboration Summit est une non-conférence destinée à rassembler les contributeurs actuels et potentiels pour discuter de Node js dans le cadre d'une collaboration animée. contributeurs actuels et potentiels pour discuter de Node.js avec une collaboration animée, l'éducation et le partage des connaissances. Les comités et les groupes de travail se réunissent deux fois par an pour prendre des décisions importantes tout en étant en mesure de travailler sur des efforts passionnants qu'ils veulent faire avancer en personne. - -## Qui participe ? - -Tout le monde peut participer au Collab Summit. Pendant le sommet, les responsables aideront les nouveaux contributeurs à intégrer les groupes qu'ils aimeraient aider avant de les intégrer dans les sessions de travail. - -C'est l'occasion d'apprendre ce qui se passe au sein de la communauté, de participer et de contribuer avec les compétences que vous avez et que vous aimeriez perfectionner. - -Les groupes de travail établiront un calendrier afin que les gens puissent se familiariser avant d'arriver sur place, en organisant des discussions générales sur les collaborateurs, et avant de se plonger dans les sessions en petits groupes. - -We'd love to see you at Collab Summit! Check out the [Summit repo](https://github.com/nodejs/summit) for upcoming and past Collab Summits and have a look at the [issues filed](https://github.com/nodejs/summit/issues) that share what individual working groups and committees are looking to discuss in-person. diff --git a/pages/fr/get-involved/contribute.md b/pages/fr/get-involved/contribute.md deleted file mode 100644 index 7cb9f580d8a66..0000000000000 --- a/pages/fr/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Contribuer -layout: contribute.hbs ---- - -# Contribuer - -Merci de votre intérêt à contribuer à Node.js ! Il y a plusieurs façons et lieux que vous pouvez contribuer, et nous sommes là pour vous aider à faciliter cela. - -## Demander de l'aide générale - -Because the level of activity in the `nodejs/node` repository is so high, questions or requests for general help using Node.js should be directed at the [Node.js help repository](https://github.com/nodejs/help/issues). - -## Signaler un problème - -Si vous avez trouvé ce que vous pensez être un problème avec Node.js, n'hésitez pas à déposer un problème sur le projet GitHub. Lorsque vous déposez votre problème, assurez-vous que vous pouvez exprimer le problème avec un cas de test reproductible, et ce cas de test ne doit pas inclure de dépendances externes. En d'autres termes, le cas de test peut être exécuté sans rien d'autre que Node.js lui-même. - -Lorsque vous signalez un problème, nous avons également besoin d'un maximum d'informations sur votre environnement. Nous ne savons jamais quelles informations seront pertinentes lorsque nous essaierons de circonscrire le problème. Veuillez inclure au moins les informations suivantes : - -- Version de Node.js -- Plateforme sur laquelle vous utilisez (macOS, SmartOS, Linux, Windows) -- Architecture sur laquelle vous utilisez (32bit ou 64bit et x86 ou ARM) - -Le projet Node.js est actuellement géré par un certain nombre de dépôts GitHub distincts, chacun ayant sa propre base de données de problèmes. Dans la mesure du possible, veuillez diriger les problèmes que vous signalez vers le dépôt approprié, mais ne vous inquiétez pas si les choses se retrouvent au mauvais endroit, la communauté des contributeurs sera plus qu'heureuse de vous aider à vous orienter dans la bonne direction. - -- Pour signaler des problèmes spécifiques à Node.js, veuillez utiliser [nodejs/node](https://github.com/nodejs/node) -- Pour signaler des problèmes spécifiques à ce site web, veuillez utiliser [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## Contributions au code - -Si vous souhaitez corriger des bogues ou ajouter une nouvelle fonctionnalité à Node.js, veuillez consulter les [Conseils de contribution à Node.js](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). Le processus de révision par les collaborateurs existants pour toutes les contributions au projet y est également expliqué. - -Si vous vous demandez comment commencer, vous pouvez consulter [Node Todo](https://www.nodetodo.org/) qui vous guidera peut-être vers votre première contribution. - -## Devenir collaborateur - -En devenant collaborateur, les contributeurs peuvent avoir encore plus d'impact sur le projet. Ils peuvent aider d'autres contributeurs en examinant leurs contributions, trier les problèmes et jouer un rôle encore plus important dans l'élaboration de l'avenir du projet. Les personnes identifiées par le TSC comme apportant des contributions significatives et précieuses dans n'importe quel dépôt Node.js peuvent être nommées collaborateurs et se voir accorder un accès au projet. Les activités prises en compte incluent (mais ne sont pas limitées à) la qualité de : - -- les modifications de code et les demandes d'autorisation d'accès (pull requests) -- la documentation des commits et des pull requests -- les commentaires sur les problèmes et les demandes d'extraction -- contributions au site web Node.js -- l'assistance fournie aux utilisateurs finaux et aux contributeurs novices -- participation in Working Groups -- d'autres participations à la communauté Node.js au sens large - -Si des personnes apportant des contributions précieuses estiment qu'elles n'ont pas été prises en compte pour l'accès au commit, elles peuvent [enregistrer un problème](https://github.com/nodejs/TSC/issues) ou [contacter directement un membre du TSC](https://github.com/nodejs/node#tsc-technical-steering-committee). diff --git a/pages/fr/get-involved/index.md b/pages/fr/get-involved/index.md deleted file mode 100644 index 29e222ecbee0d..0000000000000 --- a/pages/fr/get-involved/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Comment s'impliquer ? -layout: contribute.hbs ---- - -# Comment s'impliquer ? - -## Discussions de la communauté - -- La [liste de problèmes GitHub](https://github.com/nodejs/node/issues) est le lieu de discussion des fonctionnalités de base de Node.js. -- Pour discuter en temps réel du développement de Node.js, utilisez l'une des plateformes suivantes - - Pour IRC, allez sur `irc.libera.chat` dans le `#node. s` canal avec un client [IRC](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients) ou connectez-vous dans votre navigateur web au canal en utilisant [un client web](https://kiwiirc.com/nextclient/) - - Pour Slack, il y a deux options : - - The [OpenJSF Slack](https://slack-invite.openjsf.org/) is a Foundation run Slack with several Node.js channels (channels prefixed by `#nodejs-` are related to the project). - - [Node Slackers](https://www.nodeslackers.com/) est une communauté Slack axée sur Node.js. -- Le compte officiel de Node.js Twitter est [nodejs](https://twitter.com/nodejs). -- Le calendrier du projet [Node.js](https://nodejs.org/calendar) avec toutes les réunions publiques de l'équipe. - -## Apprentissage - -- [Documentation de référence de l'API officielle](https://nodejs.org/api/) détaille l'API Node.js. -- [NodeSchool.io](https://nodeschool.io/) vous enseignera les concepts Node.js via des jeux interactifs en ligne de commande. -- [La balise Node.js de pile débordement de pile](https://stackoverflow.com/questions/tagged/node.js) recueille de nouvelles informations chaque jour. -- [La balise DEV Community Node.js](https://dev.to/t/node) est un endroit où partager un noeud. s projets, articles et tutoriaux ainsi que commencer les discussions et demander des commentaires sur Node. Les développeurs de tous les niveaux de compétences sont les bienvenus pour y participer. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) est une communauté amicale de développeurs de backend Node.js qui se supportent mutuellement sur Discord. diff --git a/pages/fr/index.md b/pages/fr/index.md deleted file mode 100644 index 6f63d870d2dc3..0000000000000 --- a/pages/fr/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Version actuelle - download: Téléchargements - download-for: Téléchargements pour - other-downloads: Autres téléchargements - current: Actuel - lts: LTS - tagline-current: Dernières fonctionnalités - tagline-lts: Recommandé pour la plupart des utilisateurs - changelog: Journal des modifications - api: Documentation API - version-schedule-prompt: Ou regardez le - version-schedule-prompt-link-text: Planning LTS ---- - -Node.js® est un environnement d’exécution JavaScript construit sur le [moteur JavaScript V8 de Chrome](https://v8.dev/). diff --git a/pages/gl/404.md b/pages/gl/404.md deleted file mode 100644 index fe41baa82c936..0000000000000 --- a/pages/gl/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Páxina non atopada - -### ENOENT: Non existe o arquivo ou directorio diff --git a/pages/gl/index.md b/pages/gl/index.md deleted file mode 100644 index 3f580eb4e3733..0000000000000 --- a/pages/gl/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Versión Actual - download: Descargar - download-for: Descargar para - other-downloads: Outras Descargas - current: Actual - lts: LTS - tagline-current: Últimas Características - tagline-lts: Recomendado para a maioría - changelog: Cambios - api: Documentación do API - version-schedule-prompt: Ou revise á - version-schedule-prompt-link-text: Axenda de LTS ---- - -Node.js® é un entorno de execución para JavaScript construído co [motor de JavaScript V8 de Chrome](https://v8.dev/). diff --git a/pages/id/404.md b/pages/id/404.md deleted file mode 100644 index 185a2f5e98afa..0000000000000 --- a/pages/id/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Halaman tidak dapat ditemukan - -### ENOENT: Tidak ada file atau direktori seperti itu diff --git a/pages/id/about/governance.md b/pages/id/about/governance.md deleted file mode 100644 index e0ff5288c4290..0000000000000 --- a/pages/id/about/governance.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Tata Kelola Proyek -layout: about.hbs ---- - -# Tata Kelola Proyek - -## Proses Pencarian Kesepakatan - -Proyek Node.js mengikuti model pengambilan keputusan [Pencarian Kesepakatan][]. - -## Kolaborator - -Repositori GitHub inti [nodejs/node][] dikelola oleh Kolaborator yang ditambahkan oleh Komite Pengarah Teknis ([TSC][]) secara berkesinambungan. - -Individu yang memberikan kontribusi signifikan dan berharga dijadikan Kolaborator dan diberikan akses-komit ke proyek. Orang-orang ini diidentifikasi oleh TSC dan nominasi mereka didiskusikan dengan Kolaborator yang ada. - -Untuk daftar Kolaborator saat ini, lihat [README.md][] proyek. - -Panduan untuk Kolaborator disimpan di [collaborator-guide.md][]. - -## Komite Pengarah Teknis - -Proyek ini diatur oleh [Komite Pengarah Teknis][] dalam bahasa inggris (Technical Steering Committee atau TSC) yang bertanggung jawab untuk bimbingan tingkat tinggi proyek. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[Pencarian Kesepakatan]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Komite Pengarah Teknis]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/id/about/index.md b/pages/id/about/index.md deleted file mode 100644 index dd7af9772db2a..0000000000000 --- a/pages/id/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Tentang -trademark: Merek dagang ---- - -# Tentang Node.js® - -Sebagai runtime JavaScript berbasis peristiwa asinkron, Node.js dirancang untuk membangun aplikasi jaringan yang dapat diskalakan. Dalam contoh "HELLO WORLD" berikut, banyak koneksi dapat ditangani secara bersamaan. Pada setiap koneksi, panggilan baliknya adalah dipecat, tetapi jika tidak ada pekerjaan yang harus dilakukan, Node.js akan tidur. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hai Dunia'); -}); - -server.listen(port, hostname, () => { - console.log(`Server berjalan di http://${hostname}:${port}/`); -}); -``` - -Ini berbeda dengan model konkurensi yang lebih umum saat ini, di mana utas OS dipekerjakan. Jaringan berbasis thread relatif tidak efisien dan sangat sulit untuk digunakan. Selain itu, pengguna Node.js bebas dari kekhawatiran dead-locking proses, karena tidak ada kunci. Hampir tidak ada fungsi di Node.js langsung melakukan I/O, jadi proses tidak pernah memblokir kecuali saat I/O dilakukan menggunakan metode sinkron dari pustaka standar Node.js. Karena tidak ada yang menghalangi, sistem yang dapat diskalakan sangat masuk akal untuk dikembangkan di Node.js. - -Jika beberapa bahasa ini tidak dikenal, ada artikel lengkap di [Pemblokiran vs. Non-Pemblokiran][]. - ---- - -Node.js mirip dalam desain, dan dipengaruhi oleh, sistem seperti Ruby [Event Machine][] dan [Twisted][] Python. Node.js mengambil model acara sedikit lebih jauh. Ini menyajikan [event loop][] sebagai konstruk runtime alih-alih sebagai perpustakaan. Dalam sistem lain, selalu ada panggilan pemblokiran untuk memulai acara-loop. Biasanya, perilaku didefinisikan melalui panggilan balik di awal skrip, dan pada akhirnya server dimulai melalui panggilan pemblokiran seperti `EventMachine::run()`. Di Node.js, tidak ada panggilan start-the-event-loop seperti itu. Node.js cukup memasuki loop acara setelah menjalankan skrip input. Node.js keluar dari loop acara ketika tidak ada lagi panggilan balik untuk dilakukan. Perilaku ini seperti JavaScript browser — loop acara disembunyikan dari pengguna. - -HTTP adalah warga negara kelas satu di Node.js, dirancang dengan streaming dan rendah latensi dalam pikiran. Ini membuat Node.js sangat cocok untuk fondasi web perpustakaan atau kerangka kerja. - -Node.js dirancang tanpa utas tidak berarti Anda tidak dapat mengambil keuntungan dari beberapa inti di lingkungan Anda. Proses anak dapat dimunculkan dengan menggunakan API [`child_process.fork()`][] kami, dan dirancang agar mudah berkomunikasi dengan. Dibangun di atas antarmuka yang sama adalah modul [`cluster`][], yang memungkinkan Anda untuk berbagi soket antar proses untuk mengaktifkan penyeimbangan beban atas inti Anda. - -[Pemblokiran vs. Non-Pemblokiran]: /id/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[event loop]: /id/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/id/docs/es6.md b/pages/id/docs/es6.md deleted file mode 100644 index 7ae03929ac26f..0000000000000 --- a/pages/id/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) dan seterusnya -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) dan seterusnya - -Node.js dibuat dengan versi modern [V8](https://v8.dev/). Dengan terus mengikuti rilis terbaru mesin ini, kami memastikan fitur baru dari [Spesifikasi JavaScript ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm) dibawa ke pengembang Node.js secara tepat waktu, serta peningkatan kinerja dan stabilitas yang berkelanjutan. - -Semua fitur ECMAScript 2015 (ES6) dibagi menjadi tiga grup untuk fitur **pengiriman**, **bertahap**, dan **sedang berlangsung**: - -- Semua fitur **pengiriman**, yang dianggap stabil oleh V8, diaktifkan **secara default di Node.js** dan **TIDAK** memerlukan tanda waktu proses apa pun. -- Fitur **Staged**, yang merupakan fitur yang hampir selesai dan tidak dianggap stabil oleh tim V8, memerlukan flag runtime: `--harmony`. -- **Dalam proses** fitur dapat diaktifkan satu per satu dengan bendera harmoni masing-masing, meskipun hal ini sangat tidak disarankan kecuali untuk tujuan pengujian. Catatan: tanda ini diekspos oleh V8 dan berpotensi berubah tanpa pemberitahuan penghentian. - -## Fitur mana yang dikirimkan dengan versi Node.js mana secara default? - -Situs web [node.green](https://node.green/) memberikan gambaran yang sangat baik tentang fitur ECMAScript yang didukung di berbagai versi Node.js, berdasarkan tabel kompatibilitas kangax. - -## Fitur mana yang sedang berlangsung? - -Fitur-fitur baru terus ditambahkan ke mesin V8. Secara umum, perkirakan mereka akan mendarat di rilis Node.js di masa mendatang, meskipun waktunya tidak diketahui. - -Anda dapat membuat daftar semua fitur _sedang berlangsung_ yang tersedia pada setiap rilis Node.js dengan memahami argumen `--v8-options`. Harap dicatat bahwa ini adalah fitur V8 yang tidak lengkap dan mungkin rusak, jadi gunakan dengan risiko Anda sendiri: - -```bash -node --v8-options | grep "in progress" -``` - -## Saya telah menyiapkan infrastruktur saya untuk memanfaatkan flag --harmony. Haruskah saya menghapusnya? - -Perilaku flag `--harmony` saat ini di Node.js adalah untuk mengaktifkan fitur **staged** saja. Lagi pula, sekarang menjadi sinonim dari `--es_staging`. Seperti disebutkan di atas, ini adalah fitur lengkap yang belum dianggap stabil. Jika Anda ingin bermain aman, terutama di lingkungan produksi, pertimbangkan untuk menghapus flag runtime ini hingga dikirimkan secara default pada V8 dan, akibatnya, pada Node.js. Jika Anda tetap mengaktifkan ini, Anda harus siap untuk peningkatan Node.js lebih lanjut untuk memecahkan kode Anda jika V8 mengubah semantiknya untuk lebih mengikuti standar. - -## Bagaimana cara menemukan versi V8 mana yang dikirimkan dengan versi Node.js tertentu? - -Node.js menyediakan cara sederhana untuk membuat daftar semua dependensi dan versi masing-masing yang dikirimkan dengan biner tertentu melalui objek global `process`. Dalam hal mesin V8, ketik berikut ini di terminal Anda untuk mengambil versinya: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/id/docs/guides/abi-stability.md b/pages/id/docs/guides/abi-stability.md deleted file mode 100644 index 74a2bc220e836..0000000000000 --- a/pages/id/docs/guides/abi-stability.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Stabilitas ABI -layout: docs.hbs ---- - -# Stabilitas ABI - -## Pengantar - -Application Binary Interface (ABI) adalah cara bagi program untuk memanggil fungsi dan menggunakan struktur data dari program terkompilasi lainnya. Ini adalah versi yang dikompilasi dari Antarmuka Pemrograman Aplikasi (Inggris: Application Programming Interface disingkat API). Dengan kata lain, file header menggambarkan kelas, fungsi, struktur data, enumerasi, dan konstanta yang memungkinkan aplikasi untuk melakukan tugas yang diinginkan sesuai dengan cara kompilasi ke satu set alamat dan nilai parameter dan memori yang diharapkan ukuran struktur dan tata letak yang dengannya penyedia ABI dikompilasi. - -Aplikasi yang menggunakan ABI harus dikompilasi sedemikian rupa sehingga tersedia alamat, nilai parameter yang diharapkan, dan ukuran dan tata letak struktur memori setuju dengan yang dengannya penyedia ABI dikompilasi. Ini biasanya dicapai dengan kompilasi terhadap header yang disediakan oleh penyedia ABI. - -Karena penyedia ABI dan pengguna ABI dapat dikompilasi di waktu yang berbeda dengan versi kompiler yang berbeda, sebagian dari tanggung jawab untuk memastikan kompatibilitas ABI terletak pada kompiler. Berbeda versi kompiler, mungkin disediakan oleh vendor yang berbeda, harus semuanya menghasilkan ABI yang sama dari file header dengan konten tertentu, dan harus menghasilkan kode untuk aplikasi yang menggunakan ABI yang mengakses API yang dijelaskan dalam a header yang diberikan sesuai dengan konvensi ABI yang dihasilkan dari deskripsi di header. Kompiler modern memiliki rekam jejak yang cukup baik tentang tidak melanggar kompatibilitas ABI dari aplikasi yang mereka kompilasi. - -Tanggung jawab yang tersisa untuk memastikan kompatibilitas ABI terletak pada tim memelihara file header yang menyediakan API yang dihasilkan, setelah kompilasi, di ABI agar tetap stabil. Perubahan pada file header dapat dibuat, tetapi sifat perubahan harus dilacak dengan cermat untuk memastikan bahwa, setelah kompilasi, ABI tidak berubah dengan cara yang akan merender pengguna ABI yang ada tidak kompatibel dengan versi baru. - -## Stabilitas ABI di Node.js - -Node.js menyediakan file header yang dikelola oleh beberapa tim independen. Untuk contoh, file header seperti `node.h` dan `node_buffer.h` dikelola oleh tim Node.js. `v8.h` dikelola oleh tim V8, yang meskipun berdekatan kerjasama dengan tim Node.js, independen, dan dengan jadwal sendiri dan prioritas. Dengan demikian, tim Node.js hanya memiliki sebagian kendali atas perubahan yang diperkenalkan di header yang disediakan proyek. Hasil dari, proyek Node.js telah mengadopsi [versi semantik](https://semver.org/). Ini memastikan bahwa API yang disediakan oleh proyek akan menghasilkan ABI yang stabil untuk semua versi minor dan patch dari Node.js yang dirilis dalam satu versi mayor. Dalam praktiknya, ini berarti bahwa proyek Node.js telah berkomitmen untuk memastikan bahwa addon asli Node.js dikompilasi terhadap versi utama tertentu dari Node.js akan berhasil dimuat saat dimuat oleh versi minor atau patch Node.js apa pun dalam versi utama yang dikompilasi. - -## N-API - -Permintaan telah muncul untuk melengkapi Node.js dengan API yang menghasilkan ABI yang tetap stabil di beberapa versi utama Node.js. motivasi untuk membuat API seperti itu adalah sebagai berikut: - -- Bahasa JavaScript tetap kompatibel dengan dirinya sendiri sejak sangat hari-hari awal, sedangkan ABI mesin yang mengeksekusi kode JavaScript berubah dengan setiap versi utama Node.js. Ini berarti bahwa aplikasi yang terdiri dari: Paket Node.js yang ditulis seluruhnya dalam JavaScript tidak perlu dikompilasi ulang, diinstal ulang, atau digunakan kembali sebagai versi utama baru dari Node.js dimasukkan ke dalam lingkungan produksi di mana aplikasi tersebut berjalan. Sebaliknya, jika aplikasi tergantung pada paket yang berisi addon asli, aplikasi harus dikompilasi ulang, diinstal ulang, dan digunakan kembali setiap kali versi utama baru dari Node.js diperkenalkan ke dalam lingkungan produksi. Disparitas ini antara paket Node.js yang berisi add-on asli dan yang ditulis sepenuhnya dalam JavaScript telah menambah beban pemeliharaan produksi sistem yang mengandalkan add-on asli. - -- Proyek lain sudah mulai menghasilkan antarmuka JavaScript yang pada dasarnya implementasi alternatif dari Node.js. Karena proyek-proyek ini adalah biasanya dibangun di atas mesin JavaScript yang berbeda dari V8, add-on asli mereka tentu mengambil struktur yang berbeda dan menggunakan API yang berbeda. Namun demikian, menggunakan satu API untuk addon asli di berbagai implementasi Node.js JavaScript API akan memungkinkan proyek ini memanfaatkan ekosistem paket JavaScript yang terkumpul di sekitar Node.js. - -- Node.js mungkin berisi mesin JavaScript yang berbeda di masa mendatang. Ini berarti bahwa, secara eksternal, semua antarmuka Node.js akan tetap sama, tetapi V8 file header tidak akan ada. Langkah tersebut akan menyebabkan terganggunya Ekosistem Node.js secara umum, dan addon asli pada khususnya, jika API yang agnostik mesin JavaScript tidak pertama kali disediakan oleh Node.js dan diadopsi oleh addon asli. - -Untuk tujuan ini Node.js telah memperkenalkan N-API di versi 8.6.0 dan menandainya sebagai komponen proyek yang stabil pada Node.js 8.12.0. API didefinisikan dalam header [`node_api.h`][] dan [`node_api_types.h`][], dan menyediakan forward- jaminan kompatibilitas yang melintasi batas versi utama Node.js. Itu jaminan dapat dinyatakan sebagai berikut: - -**Versi tertentu _n_ N-API akan tersedia dalam versi utama Node.js di mana ia diterbitkan, dan di semua versi Node.js berikutnya, termasuk versi utama berikutnya.** - -Penulis addon asli dapat memanfaatkan kompatibilitas ke depan N-API jaminan dengan memastikan bahwa addon hanya menggunakan API yang ditentukan dalam `node_api.h` serta struktur data dan konstanta yang didefinisikan dalam `node_api_types.h`. Dengan demikian, penulis memfasilitasi adopsi addon mereka dengan menunjukkan untuk pengguna produksi bahwa beban pemeliharaan untuk aplikasi mereka akan meningkat tidak lebih dengan menambahkan addon asli ke proyek mereka daripada dengan penambahan paket yang ditulis murni dalam JavaScript. - -N-API diversi karena API baru ditambahkan dari waktu ke waktu. Tidak seperti versi semantik, versi N-API bersifat kumulatif. Artinya, setiap versi dari N-API menyampaikan arti yang sama dengan versi minor dalam sistem semver, artinya bahwa semua perubahan yang dibuat pada N-API akan kompatibel ke belakang. Selain itu, baru N-API ditambahkan di bawah bendera eksperimental untuk memberi komunitas kesempatan untuk memeriksanya di lingkungan produksi. Status eksperimental berarti bahwa, meskipun perawatan telah diambil untuk memastikan bahwa API baru tidak harus dimodifikasi dengan cara yang tidak kompatibel dengan ABI di masa mendatang, itu belum cukup terbukti dalam produksi untuk menjadi benar dan berguna seperti yang dirancang dan, sebagai seperti itu, dapat mengalami perubahan yang tidak kompatibel dengan ABI sebelum akhirnya dimasukkan menjadi versi N-API yang akan datang. Artinya, N-API eksperimental belum dicakup oleh jaminan kompatibilitas ke depan. - -[`node_api.h`]: https://github.com/nodejs/node/blob/main/src/node_api.h -[`node_api_types.h`]: https://github.com/nodejs/node/blob/main/src/node_api_types.h diff --git a/pages/id/docs/guides/anatomy-of-an-http-transaction.md b/pages/id/docs/guides/anatomy-of-an-http-transaction.md deleted file mode 100644 index 793e9abbbc772..0000000000000 --- a/pages/id/docs/guides/anatomy-of-an-http-transaction.md +++ /dev/null @@ -1,365 +0,0 @@ ---- -title: Anatomi Transaksi HTTP -layout: docs.hbs ---- - -# Anatomi Transaksi HTTP - -Tujuan dari panduan ini adalah untuk memberikan pemahaman yang kuat tentang proses Penanganan HTTP Node.js. Kami akan berasumsi bahwa Anda tahu, secara umum, bagaimana HTTP permintaan bekerja, terlepas dari bahasa atau lingkungan pemrograman. Kami juga akan mengasumsikan sedikit keakraban dengan Node.js [`EventEmitters`][] dan [`Streams`][]. Jika Anda tidak cukup akrab dengan mereka, ada baiknya membaca cepat dokumen API untuk masing-masingnya. - -## Buat Server - -Setiap aplikasi server web node pada titik tertentu harus membuat server web obyek. Ini dilakukan dengan menggunakan [`createServer`][]. - -```javascript -const http = require('http'); - -const server = http.createServer((request, response) => { - // magic happens here! -}); -``` - -Fungsi yang diteruskan ke [`createServer`][] dipanggil sekali untuk setiap Permintaan HTTP yang dibuat terhadap server itu, jadi itu disebut permintaan pawang Sebenarnya, objek [`Server`][] yang dikembalikan oleh [`createServer`][] adalah sebuah [`EventEmitter`][], dan apa yang kita miliki di sini hanyalah singkatan untuk membuat objek `server` dan kemudian menambahkan pendengar nanti. - -```javascript -const server = http.createServer(); -server.on('request', (request, response) => { - // the same kind of magic happens here! -}); -``` - -Ketika permintaan HTTP mengenai server, node memanggil fungsi handler permintaan dengan beberapa objek praktis untuk menangani transaksi, `permintaan` dan `tanggapan`. Kami akan segera membahasnya. - -Untuk benar-benar melayani permintaan, metode [`listen`][] perlu dipanggil pada objek `server`. Dalam kebanyakan kasus, yang perlu Anda lakukan untuk `mendengarkan` adalah nomor port yang Anda inginkan untuk didengarkan oleh server. Ada beberapa pilihan lain juga, jadi lihat [referensi API][]. - -## Metode, URL, dan Header - -Saat menangani permintaan, hal pertama yang mungkin ingin Anda lakukan adalah melihat metode dan URL, sehingga tindakan yang tepat dapat diambil. Node.js membuat ini relatif tidak menyakitkan dengan meletakkan properti praktis ke objek `permintaan`. - -```javascript -const { method, url } = request; -``` - -> Objek `request` adalah turunan dari [`IncomingMessage`][]. - -`Metode` di sini akan selalu menjadi metode/kata kerja HTTP normal. `url` adalah URL lengkap tanpa server, protokol, atau port. Untuk URL biasa, ini berarti semuanya setelah dan termasuk garis miring ketiga. - -Header juga tidak jauh. Mereka berada di objek mereka sendiri pada `permintaan` yang disebut `headers`. - -```javascript -const { headers } = request; -const userAgent = headers['user-agent']; -``` - -Penting untuk dicatat di sini bahwa semua header hanya diwakili dalam huruf kecil, terlepas dari bagaimana klien sebenarnya mengirimnya. Ini menyederhanakan tugas parsing header untuk tujuan apa pun. - -Jika beberapa header diulang, maka nilainya akan ditimpa atau digabungkan bersama-sama sebagai string yang dipisahkan koma, tergantung pada header. Dalam beberapa kasus, ini bisa menjadi masalah, jadi [`rawHeaders`][] juga tersedia. - -## Badan Permintaan - -Saat menerima permintaan `POST` atau `PUT`, badan permintaan mungkin penting untuk aplikasi Anda. Mendapatkan data tubuh sedikit lebih terlibat daripada mengakses header permintaan. Objek `request` yang diteruskan ke handler mengimplementasikan antarmuka [`ReadableStream`][]. Aliran ini dapat didengarkan atau disalurkan ke tempat lain seperti aliran lainnya. Kami dapat mengambil data langsung dari stream dengan mendengarkan event `'data'` dan `'end'` stream. - -Potongan yang dipancarkan di setiap kejadian `'data'` adalah [`Buffer`][]. Jika Anda tahu itu akan menjadi data string, hal terbaik yang harus dilakukan adalah mengumpulkan data dalam array, lalu di `'end'`, gabungkan dan rangkum. - -```javascript -let body = []; -request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // at this point, `body` has the entire request body stored in it as a string - }); -``` - -> Ini mungkin tampak sedikit membosankan, dan dalam banyak kasus memang demikian. Untunglah, ada modul seperti [`concat-stream`][] dan [`body`][] pada [`npm`][] yang dapat membantu menyembunyikan sebagian dari logika ini. Penting untuk memiliki pemahaman yang baik tentang apa yang terjadi sebelum menempuh jalan itu, dan itulah mengapa Anda ada di sini! - -## Hal Singkat Tentang Kesalahan - -Karena objek `request` adalah [`ReadableStream`][], itu juga merupakan [`EventEmitter`][] dan berperilaku seperti saat terjadi kesalahan. - -Kesalahan dalam aliran `request` muncul dengan memancarkan peristiwa `'error'` di aliran. **Jika Anda tidak memiliki pendengar untuk acara itu, kesalahannya adalah _dilempar_, yang dapat merusak program Node.js Anda.** Oleh karena itu, Anda harus menambahkan pendengar `'error'` pada aliran permintaan Anda, meskipun Anda baru saja mencatatnya dan lanjutkan perjalananmu. (Meskipun mungkin yang terbaik untuk mengirim semacam kesalahan HTTP tanggapan. Lebih lanjut tentang itu nanti.) - -```javascript -request.on('error', err => { - // This prints the error message and stack trace to `stderr`. - console.error(err.stack); -}); -``` - -Ada cara lain untuk [menangani kesalahan ini][] seperti abstraksi dan alat lain, tetapi selalu waspadai bahwa kesalahan dapat dan memang terjadi, dan Anda harus berurusan dengan mereka. - -## Apa yang Kita Miliki Sejauh Ini - -Pada titik ini, kita telah membahas pembuatan server, dan mengambil metode, URL, header dan isi dari permintaan. Ketika kita menggabungkan semuanya, itu mungkin terlihat sesuatu seperti ini: - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // At this point, we have the headers, method, url and body, and can now - // do whatever we need to in order to respond to this request. - }); - }) - .listen(8080); // Activates this server, listening on port 8080. -``` - -Jika kita menjalankan contoh ini, kita akan dapat _menerima_ permintaan, tetapi tidak _merespon_ ke mereka. Sebenarnya, jika Anda menekan contoh ini di browser web, permintaan Anda akan waktu habis, karena tidak ada yang dikirim kembali ke klien. - -Sejauh ini kita belum menyentuh objek `response` sama sekali, yang merupakan sebuah instance dari [`ServerResponse`][], yang merupakan [`WritableStream`][]. Ini berisi banyak metode yang berguna untuk mengirim data kembali ke klien. Kami akan membahasnya selanjutnya. - -## Kode Status HTTP - -Jika Anda tidak repot mengaturnya, kode status HTTP pada respons akan selalu menjadi 200. Tentu saja, tidak setiap respons HTTP menjamin hal ini, dan pada titik tertentu Anda pasti ingin mengirim kode status yang berbeda. Untuk melakukan itu, Anda dapat mengatur properti `statusCode`. - -```javascript -response.statusCode = 404; // Tell the client that the resource wasn't found. -``` - -Ada beberapa jalan pintas lain untuk ini, seperti yang akan kita lihat segera. - -## Mengatur Header Respons - -Header diatur melalui metode praktis yang disebut [`setHeader`][]. - -```javascript -response.setHeader('Content-Type', 'application/json'); -response.setHeader('X-Powered-By', 'bacon'); -``` - -Saat menyetel header pada respons, nama mereka tidak peka huruf besar-kecil. Jika Anda mengatur header berulang kali, nilai terakhir yang Anda tetapkan adalah nilai yang didapat terkirim. - -## Mengirim Data Header Secara Eksplisit - -Metode pengaturan header dan kode status yang telah kita bahas asumsikan bahwa Anda menggunakan "header implisit". Ini berarti Anda mengandalkan simpul untuk mengirim header untuk Anda pada waktu yang tepat sebelum Anda mulai mengirim badan data. - -Jika mau, Anda dapat _secara eksplisit_ menulis header ke aliran respons. Untuk melakukan ini, ada metode yang disebut [`writeHead`][], yang menulis status kode dan header ke aliran. - -```javascript -response.writeHead(200, { - 'Content-Type': 'application/json', - 'X-Powered-By': 'bacon', -}); -``` - -Setelah Anda mengatur header (baik secara implisit atau eksplisit), Anda siap untuk mulai mengirim data respons. - -## Mengirim Badan Respon - -Karena objek `response` adalah [`WritableStream`][], menulis badan respons keluar ke klien hanya masalah menggunakan metode aliran biasa. - -```javascript -response.write(''); -response.write(''); -response.write('

Hello, World!

'); -response.write(''); -response.write(''); -response.end(); -``` - -Fungsi `akhir` pada aliran juga dapat mengambil beberapa data opsional untuk dikirim sebagai bit terakhir dari data pada aliran, sehingga kita dapat menyederhanakan contoh di atas sebagai berikut. - -```javascript -response.end('

Hello, World!

'); -``` - -> Penting untuk mengatur status dan header _sebelum_ Anda mulai menulis potongan data ke badan. Ini masuk akal, karena header datang sebelumnya isi dalam tanggapan HTTP. - -## Hal Cepat Lain Tentang Kesalahan - -Aliran `response` juga dapat memancarkan peristiwa `'error'`, dan pada titik tertentu Anda akan harus berurusan dengan itu juga. Semua saran untuk aliran `permintaan` kesalahan masih berlaku di sini. - -## Satukan Semuanya - -Sekarang kita telah belajar tentang membuat tanggapan HTTP, mari kita gabungkan semuanya. Berdasarkan contoh sebelumnya, kita akan membuat server yang mengirim kembali semua data yang dikirimkan kepada kami oleh pengguna. Kami akan memformat data itu sebagai JSON menggunakan `JSON.stringify`. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // BEGINNING OF NEW STUFF - - response.on('error', err => { - console.error(err); - }); - - response.statusCode = 200; - response.setHeader('Content-Type', 'application/json'); - // Note: the 2 lines above could be replaced with this next one: - // response.writeHead(200, {'Content-Type': 'application/json'}) - - const responseBody = { headers, method, url, body }; - - response.write(JSON.stringify(responseBody)); - response.end(); - // Note: the 2 lines above could be replaced with this next one: - // response.end(JSON.stringify(responseBody)) - - // END OF NEW STUFF - }); - }) - .listen(8080); -``` - -## Contoh Server Echo - -Mari kita sederhanakan contoh sebelumnya untuk membuat server echo sederhana, yang hanya mengirimkan data apa pun yang diterima dalam permintaan segera sebagai tanggapan. Semua yang perlu kita lakukan adalah mengambil data dari aliran permintaan dan menulis data itu ke aliran respons, mirip dengan apa yang kami lakukan sebelumnya. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - }) - .listen(8080); -``` - -Sekarang mari kita tweak ini. Kami hanya ingin mengirim echo di bawah ini kondisi: - -- Metode permintaan adalah POST. -- URL-nya adalah `/echo`. - -Dalam kasus lain, kami hanya ingin merespons dengan 404. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -> Dengan memeriksa URL dengan cara ini, kita sedang melakukan bentuk "perutean". Bentuk perutean lainnya bisa sesederhana pernyataan `switch` atau serumit seluruh kerangka kerja seperti [`express`][]. Jika Anda mencari sesuatu yang bisa perutean dan tidak ada yang lain, coba [`router`][]. - -Besar! Sekarang mari kita coba menyederhanakan ini. Ingat, objek `permintaan` adalah [`ReadableStream`][] dan objek `response` adalah [`WritableStream`][]. Itu berarti kita bisa menggunakan [`pipe`][] untuk mengarahkan data dari satu ke yang lain. itu persis seperti yang kita inginkan untuk server echo! - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -Yay Berjalan! - -Kami belum cukup selesai. Seperti disebutkan beberapa kali dalam panduan ini, kesalahan dapat dan memang terjadi, dan kita harus menghadapinya. - -Untuk menangani kesalahan pada aliran permintaan, kami akan mencatat kesalahan ke `stderr` dan mengirim kode status 400 untuk menunjukkan `Permintaan Buruk`. Dalam aplikasi dunia nyata, meskipun, kami ingin memeriksa kesalahan untuk mencari tahu apa kode status yang benar dan pesan akan. Seperti biasa dengan kesalahan, Anda harus berkonsultasi dengan [`Dokumentasi kesalahan`][]. - -Pada respons, kami hanya akan mencatat kesalahan ke `stderr`. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - request.on('error', err => { - console.error(err); - response.statusCode = 400; - response.end(); - }); - response.on('error', err => { - console.error(err); - }); - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -Kami sekarang telah membahas sebagian besar dasar-dasar penanganan permintaan HTTP. Pada saat ini, kamu harus bisa: - -- Instansiasi server HTTP dengan fungsi pengendali permintaan, dan dengarkan di sebuah pelabuhan. -- Dapatkan data header, URL, metode, dan isi dari objek `permintaan`. -- Membuat keputusan perutean berdasarkan URL dan/atau data lain di objek `permintaan`. -- Kirim header, kode status HTTP, dan data isi melalui objek `respons`. -- Pipa data dari objek `request` dan ke objek `response`. -- Menangani kesalahan aliran di aliran `permintaan` dan `tanggapan`. - -Dari dasar-dasar ini, server HTTP Node.js untuk banyak kasus penggunaan tipikal dapat: dibangun. Ada banyak hal lain yang disediakan oleh API ini, jadi pastikan untuk baca dokumen API untuk [`EventEmitters`][], [`Streams`][], dan [`HTTP`][]. - -[`EventEmitters`]: https://nodejs.org/api/events.html -[`Streams`]: https://nodejs.org/api/stream.html -[`createServer`]: https://nodejs.org/api/http.html#http_http_createserver_requestlistener -[`Server`]: https://nodejs.org/api/http.html#http_class_http_server -[`listen`]: https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback -[referensi API]: https://nodejs.org/api/http.html -[`IncomingMessage`]: https://nodejs.org/api/http.html#http_class_http_incomingmessage -[`ReadableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_readable -[`rawHeaders`]: https://nodejs.org/api/http.html#http_message_rawheaders -[`Buffer`]: https://nodejs.org/api/buffer.html -[`concat-stream`]: https://www.npmjs.com/package/concat-stream -[`body`]: https://www.npmjs.com/package/body -[`npm`]: https://www.npmjs.com -[`EventEmitter`]: https://nodejs.org/api/events.html#events_class_eventemitter -[menangani kesalahan ini]: https://nodejs.org/api/errors.html -[`ServerResponse`]: https://nodejs.org/api/http.html#http_class_http_serverresponse -[`setHeader`]: https://nodejs.org/api/http.html#http_response_setheader_name_value -[`WritableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_writable -[`writeHead`]: https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers -[`express`]: https://www.npmjs.com/package/express -[`router`]: https://www.npmjs.com/package/router -[`pipe`]: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options -[`Dokumentasi kesalahan`]: https://nodejs.org/api/errors.html -[`HTTP`]: https://nodejs.org/api/http.html diff --git a/pages/id/docs/guides/backpressuring-in-streams.md b/pages/id/docs/guides/backpressuring-in-streams.md deleted file mode 100644 index ec8f0f78a1901..0000000000000 --- a/pages/id/docs/guides/backpressuring-in-streams.md +++ /dev/null @@ -1,512 +0,0 @@ ---- -title: Backpressuring in Streams -layout: docs.hbs ---- - -# Backpressuring in Streams - -Ada masalah umum yang terjadi selama penanganan data yang disebut [`backpressure`][] yang menggambarkan penumpukan data di belakang buffer selama transfer data. Ketika penerima transfer memiliki operasi yang kompleks, atau lebih lambat karena alasan apa pun, ada kecenderungan bagi data dari sumber masuk untuk menumpuk, seperti penyumbatan. - -Untuk memecahkan masalah ini, harus ada sistem delegasi yang ada untuk memastikan aliran data yang lancar dari satu sumber ke sumber lain. Komunitas yang berbeda telah menyelesaikan masalah ini dengan cara yang unik untuk program mereka, pipa Unix dan soket TCP adalah contoh yang baik dari ini, dan sering kali disebut sebagai _flow control_. Dalam Node.js, streams telah menjadi solusi yang diadopsi. - -Tujuan panduan ini adalah untuk menjelaskan secara lebih rinci apa itu backpressure, dan bagaimana streams menanganinya secara tepat dalam kode sumber Node.js. Bagian kedua dari panduan akan memperkenalkan praktik terbaik yang disarankan untuk memastikan kode aplikasi Anda aman dan dioptimalkan saat mengimplementasikan streams. - -Kami berasumsi sedikit pengetahuan tentang definisi umum [`backpressure`][], [`Buffer`][], dan [`EventEmitters`][] dalam Node.js, serta beberapa pengalaman dengan [`Stream`][]. Jika Anda belum membaca dokumen tersebut, tidak ada salahnya untuk melihat dokumentasi API terlebih dahulu, karena ini akan membantu memperluas pemahaman Anda saat membaca panduan ini. - -## Masalah Penanganan Data - -Dalam sistem komputer, data ditransfer dari satu proses ke proses lain melalui pipa, soket, dan sinyal. Dalam Node.js, kami menemukan mekanisme serupa yang disebut [`Stream`][]. Streams sangat bagus! Mereka melakukan begitu banyak hal untuk Node.js dan hampir setiap bagian dari kode internal memanfaatkan modul tersebut. Sebagai pengembang, Anda lebih dari diharapkan untuk menggunakannya juga! - -```javascript -const readline = require('readline'); - -// process.stdin and process.stdout are both instances of Streams. -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, -}); - -rl.question('Why should you use streams? ', answer => { - console.log(`Maybe it's ${answer}, maybe it's because they are awesome! :)`); - - rl.close(); -}); -``` - -Contoh yang bagus tentang mengapa mekanisme backpressure yang diimplementasikan melalui streams adalah sebuah optimasi yang bagus dapat ditunjukkan dengan membandingkan alat sistem internal dari implementasi [`Stream`][] Node.js. - -Dalam satu skenario, kami akan mengambil file besar (sekitar \~9gb) dan memampatkannya menggunakan alat yang sudah dikenal [`zip(1)`][]. - -``` -zip The.Matrix.1080p.mkv -``` - -Meskipun itu akan memakan beberapa menit untuk menyelesaikannya, di shell lain kita dapat menjalankan skrip yang menggunakan modul Node.js [`zlib`][], yang membungkus alat kompresi lainnya, [`gzip(1)`][]. - -```javascript -const gzip = require('zlib').createGzip(); -const fs = require('fs'); - -const inp = fs.createReadStream('The.Matrix.1080p.mkv'); -const out = fs.createWriteStream('The.Matrix.1080p.mkv.gz'); - -inp.pipe(gzip).pipe(out); -``` - -Untuk menguji hasilnya, cobalah membuka setiap file yang terkompresi. File yang dikompresi oleh alat [`zip(1)`][] akan memberi tahu Anda bahwa file tersebut rusak, sedangkan kompresi yang selesai dengan menggunakan [`Stream`][] akan didekompresi tanpa kesalahan. - -> Dalam contoh ini, kita menggunakan `.pipe()` untuk mendapatkan sumber data dari satu ujung ke ujung yang lain. Namun, perhatikan bahwa tidak ada penangan kesalahan yang benar yang terpasang. Jika sepotong data gagal diterima dengan benar, sumber `Readable` atau stream `gzip` tidak akan dihancurkan. [`pump`][] adalah alat utilitas yang akan menghancurkan semua stream dalam pipeline secara tepat jika salah satunya gagal atau ditutup, dan harus dimiliki dalam kasus ini! - -[`pump`][] hanya diperlukan untuk Node.js 8.x atau versi sebelumnya, karena untuk Node.js 10.x atau versi yang lebih baru, [`pipeline`][] diperkenalkan untuk menggantikan [`pump`][]. Ini adalah metode modul untuk mengalirkan antara stream yang meneruskan kesalahan dan membersihkan dengan benar dan memberikan panggilan kembali ketika pipeline selesai. - -Berikut adalah contoh penggunaan pipeline: - -```javascript -const { pipeline } = require('stream'); -const fs = require('fs'); -const zlib = require('zlib'); - -// Gunakan API pipeline untuk dengan mudah mengalirkan serangkaian stream -// bersama-sama dan mendapatkan pemberitahuan ketika pipa sepenuhnya selesai. -// Pipa untuk mengompresi file video yang mungkin sangat besar secara efisien menggunakan gzip: - -pipeline( - fs.createReadStream('The.Matrix.1080p.mkv'), - zlib.createGzip(), - fs.createWriteStream('The.Matrix.1080p.mkv.gz'), - err => { - if (err) { - console.error('Pipeline failed', err); - } else { - console.log('Pipeline succeeded'); - } - } -); -``` - -Anda juga dapat memanggil [`promisify`][] pada pipeline untuk menggunakannya dengan `async` / `await`: - -```javascript -const stream = require('stream'); -const fs = require('fs'); -const zlib = require('zlib'); -const util = require('util'); - -const pipeline = util.promisify(stream.pipeline); - -async function run() { - try { - await pipeline( - fs.createReadStream('The.Matrix.1080p.mkv'), - zlib.createGzip(), - fs.createWriteStream('The.Matrix.1080p.mkv.gz') - ); - console.log('Pipeline succeeded'); - } catch (err) { - console.error('Pipeline failed', err); - } -} -``` - -## Terlalu Banyak Data, Terlalu Cepat - -Terlalu Banyak Data, Terlalu Cepat Terkadang sebuah stream [`Readable`][] memberikan data ke stream [`Writable`][] terlalu cepat - jauh lebih banyak daripada konsumen dapat tangani! - -Ketika hal itu terjadi, konsumen akan mulai memasukkan semua potongan data ke dalam antrian untuk dikonsumsi nanti. Antrian penulisan akan semakin panjang, dan karena itu lebih banyak data harus disimpan di memori sampai seluruh proses selesai. - -Menulis ke disk jauh lebih lambat daripada membaca dari disk, oleh karena itu, ketika kita mencoba mengompres file dan menuliskannya ke hard disk, backpressure akan terjadi karena disk tulis tidak akan mampu mengejar kecepatan dari pembacaan. - -```javascript -// Secara diam-diam, stream sedang mengatakan: "whoa, whoa! tunggu dulu, ini terlalu banyak!" -// Data akan mulai menumpuk di sisi pembacaan dari buffer data ketika -// write mencoba mengejar arus data yang masuk. -inp.pipe(gzip).pipe(outputFile); -``` - -Ini sebab mengapa mekanisme backpressure sangat penting. Jika sistem backpressure tidak ada, proses akan menggunakan memori sistem Anda, mengurangi kecepatan proses lain dan memonopoli sebagian besar sistem Anda sampai selesai. - -Hal ini mengakibatkan beberapa hal berikut: - -- Memperlambat semua proses saat ini -- Pemulung sampah yang sangat terbebani -- Kekurangan memori - -Pada contoh-contoh berikut kita akan menghapus [return value][] dari fungsi `.write()` dan mengubahnya menjadi `true`, yang secara efektif menonaktifkan dukungan backpressure di inti Node.js. Dalam setiap referensi ke binary yang dimodifikasi, kita berbicara tentang menjalankan binary `node` tanpa baris `return ret;`, dan sebagai gantinya dengan `return true;` yang diganti. - -## Beban Berlebih pada Pengumpulan Sampah - -Mari kita lihat benchmark singkat. Menggunakan contoh yang sama seperti di atas, kami melakukan beberapa percobaan waktu untuk mendapatkan waktu median untuk kedua binary. - -``` - trial (#) | `node` binary (ms) | modified `node` binary (ms) -================================================================= - 1 | 56924 | 55011 - 2 | 52686 | 55869 - 3 | 59479 | 54043 - 4 | 54473 | 55229 - 5 | 52933 | 59723 -================================================================= -average time: | 55299 | 55975 -``` - -Kedua proses tersebut memakan waktu sekitar satu menit untuk dijalankan, sehingga tidak terlalu banyak perbedaan antara keduanya, tetapi mari kita perhatikan lebih dekat untuk mengonfirmasi apakah kecurigaan kita benar. Kami menggunakan alat Linux [`dtrace`][] untuk mengevaluasi apa yang terjadi dengan pengumpul sampah V8. - -Waktu pengukuran GC (pengumpul sampah) menunjukkan interval dari siklus lengkap dari satu kali sapuan yang dilakukan oleh pengumpul sampah: - -``` -approx. time (ms) | GC (ms) | modified GC (ms) -================================================= - 0 | 0 | 0 - 1 | 0 | 0 - 40 | 0 | 2 - 170 | 3 | 1 - 300 | 3 | 1 - - * * * - * * * - * * * - - 39000 | 6 | 26 - 42000 | 6 | 21 - 47000 | 5 | 32 - 50000 | 8 | 28 - 54000 | 6 | 35 -``` - -Ketika kedua proses dimulai dengan sama dan tampaknya bekerja dengan GC pada tingkat yang sama, menjadi jelas bahwa setelah beberapa detik dengan sistem backpressure yang berfungsi dengan baik, beban GC disebar di selang waktu yang konsisten antara 4-8 milidetik hingga akhir transfer data. - -Namun, ketika sistem backpressure tidak ada, pengumpulan sampah V8 mulai menurun. Binary normal memanggil GC sekitar **75** kali dalam satu menit, sedangkan binary yang dimodifikasi hanya memanggil sebanyak **36** kali. - -Ini adalah utang yang lambat dan bertahap dari penggunaan memori yang semakin meningkat. Saat data ditransfer, tanpa adanya sistem backpressure, lebih banyak memori digunakan untuk setiap transfer chunk. - -Semakin banyak memori yang dialokasikan, semakin banyak GC yang harus diatasi dalam satu sapuan. Semakin besar sapuan, semakin banyak GC yang perlu memutuskan apa yang dapat dibebaskan, dan pemindaian untuk pointer terlepas di ruang memori yang lebih besar akan menghabiskan lebih banyak daya komputasi. - -## Kepenuhan Memori - -Untuk menentukan konsumsi memori dari setiap binary, kami menggunakan `/usr/bin/time -lp sudo ./node ./backpressure-example/zlib.js` pada masing-masing proses. - -Berikut adalah output dari binary normal: - -``` -Respecting the return value of .write() -============================================= -real 58.88 -user 56.79 -sys 8.79 - 87810048 maximum resident set size - 0 average shared memory size - 0 average unshared data size - 0 average unshared stack size - 19427 page reclaims - 3134 page faults - 0 swaps - 5 block input operations - 194 block output operations - 0 messages sent - 0 messages received - 1 signals received - 12 voluntary context switches - 666037 involuntary context switches -``` - -Ukuran byte maksimum yang ditempati oleh memori virtual ternyata sekitar 87,81 mb. - -Dan sekarang dengan mengubah [nilai kembali][] dari fungsi [`.write()`][], kami mendapatkan: - -``` -Without respecting the return value of .write(): -================================================== -real 54.48 -user 53.15 -sys 7.43 -1524965376 maximum resident set size - 0 average shared memory size - 0 average unshared data size - 0 average unshared stack size - 373617 page reclaims - 3139 page faults - 0 swaps - 18 block input operations - 199 block output operations - 0 messages sent - 0 messages received - 1 signals received - 25 voluntary context switches - 629566 involuntary context switches -``` - -Ukuran byte maksimum yang ditempati oleh memori virtual ternyata sekitar 1,52 gb. - -Tanpa adanya stream yang menerapkan backpressure, terdapat perbedaan besar pada jumlah ruang memori yang dialokasikan - perbedaan margin yang sangat besar antara dua proses yang sama! - -Eksperimen ini menunjukkan betapa mekanisme backpressure Node.js sangat dioptimalkan dan hemat biaya untuk sistem komputasi Anda. Sekarang, mari kita kupas bagaimana mekanisme ini bekerja! - -## Bagaimana Backpressure Menyelesaikan Masalah Ini? - -Ada berbagai fungsi untuk mentransfer data dari satu proses ke proses lainnya. Di Node.js, ada fungsi bawaan internal yang disebut [`.pipe()`][]. Ada juga [paket lainnya][] yang dapat Anda gunakan! Namun, pada level dasar dari proses ini, kita memiliki dua komponen terpisah: _sumber_ dari data dan _konsumer_. - -Ketika [`.pipe()`][] dipanggil dari sumber, ini memberi sinyal ke konsumer bahwa ada data yang harus ditransfer. Fungsi pipe membantu mengatur penutupan backpressure yang sesuai untuk trigger acara. - -Dalam Node.js, sumber datanya adalah aliran [`Readable`][] dan penerima datanya adalah aliran [`Writable`][] (keduanya dapat saling ditukar dengan aliran [`Duplex`][] atau aliran [`Transform`][], tetapi hal tersebut di luar cakupan panduan ini). - -Waktu terpicunya backpressure dapat diperinci tepat pada nilai kembalian dari fungsi [`.write()`][] pada aliran [`Writable`][]. Tentunya, nilai kembalian ini ditentukan oleh beberapa kondisi. - -Dalam setiap skenario di mana buffer data telah melebihi [`highWaterMark`][] atau antrian tulis sedang sibuk, [`.write()`][] akan mengembalikan `false`. - -Ketika nilai `false` dikembalikan, sistem backpressure akan berjalan. Ini akan menangguhkan [`readable`][] stream masuk dari mengirimkan data apa pun dan menunggu hingga konsumer siap kembali. Begitu buffer data dikosongkan, sebuah acara [`drain`][] akan dipancarkan dan melanjutkan aliran data yang masuk. - -Setelah antrian selesai, backpressure akan memungkinkan data dikirimkan lagi. Ruang di memori yang sedang digunakan akan membebaskan dirinya dan bersiap untuk batch data berikutnya. - -Ini efektif memungkinkan jumlah memori yang tetap digunakan pada saat tertentu untuk fungsi [`.pipe()`][]. Tidak akan ada kebocoran memori, buffering tak terbatas, dan garbage collector hanya harus menangani satu area di memori! - -Jadi, jika backpressure begitu penting, mengapa Anda (mungkin) belum pernah mendengarnya? Jawabannya sederhana: Node.js melakukan semua ini secara otomatis untuk Anda. - -Itu sangat bagus! Tetapi juga tidak begitu bagus ketika kita mencoba memahami cara mengimplementasikan stream kustom kami sendiri. - -> Pada kebanyakan mesin, ada ukuran byte yang menentukan kapan buffer penuh (yang akan berbeda-beda di mesin yang berbeda). Node.js memungkinkan Anda untuk menetapkan [`highWaterMark`][] kustom Anda sendiri, tetapi umumnya, nilai default diatur menjadi 16kb (16384, atau 16 untuk objectMode streams). Dalam situasi di mana Anda mungkin ingin menaikkan nilai tersebut, silakan lakukan dengan hati-hati! - -## Siklus Hidup `.pipe()` - -Untuk mencapai pemahaman yang lebih baik tentang backpressure, berikut adalah diagram alir tentang siklus aliran [`Readable`][] yang di-[pipe][] ke dalam aliran [`Writable`][]: - -``` - +===================+ - x--> Piping functions +--> src.pipe(dest) | - x are set up during |===================| - x the .pipe method. | Event callbacks | - +===============+ x |-------------------| - | Your Data | x They exist outside | .on('close', cb) | - +=======+=======+ x the data flow, but | .on('data', cb) | - | x importantly attach | .on('drain', cb) | - | x events, and their | .on('unpipe', cb) | -+---------v---------+ x respective callbacks. | .on('error', cb) | -| Readable Stream +----+ | .on('finish', cb) | -+-^-------^-------^-+ | | .on('end', cb) | - ^ | ^ | +-------------------+ - | | | | - | ^ | | - ^ ^ ^ | +-------------------+ +=================+ - ^ | ^ +----> Writable Stream +---------> .write(chunk) | - | | | +-------------------+ +=======+=========+ - | | | | - | ^ | +------------------v---------+ - ^ | +-> if (!chunk) | Is this chunk too big? | - ^ | | emit .end(); | Is the queue busy? | - | | +-> else +-------+----------------+---+ - | ^ | emit .write(); | | - | ^ ^ +--v---+ +---v---+ - | | ^-----------------------------------< No | | Yes | - ^ | +------+ +---v---+ - ^ | | - | ^ emit .pause(); +=================+ | - | ^---------------^-----------------------+ return false; <-----+---+ - | +=================+ | - | | - ^ when queue is empty +============+ | - ^------------^-----------------------< Buffering | | - | |============| | - +> emit .drain(); | ^Buffer^ | | - +> emit .resume(); +------------+ | - | ^Buffer^ | | - +------------+ add chunk to queue | - | <---^---------------------< - +============+ -``` - -> Jika Anda mengatur pipeline untuk menggabungkan beberapa stream untuk memanipulasi data Anda, kemungkinan besar Anda akan mengimplementasikan [`Transform`][] stream. - -Dalam hal ini, keluaran dari \[`Readable'][] stream akan masuk ke dalam [`Transform`][] stream dan akan dipipa ke dalam [`Writable\`]\[] stream. - -```javascript -Readable.pipe(Transformable).pipe(Writable); -``` - -Tekanan balik akan diterapkan secara otomatis, tetapi perlu diingat bahwa `highWaterMark` masuk dan keluar dari aliran [`Transform`][] dapat dimanipulasi dan akan mempengaruhi sistem tekanan balik. - -## Pedoman Tekanan Balik - -Sejak [Node.js v0.10][], kelas [`Stream`][] telah menawarkan kemampuan untuk memodifikasi perilaku [`.read()`][] atau [`.write()`][] dengan menggunakan versi garis bawah dari fungsi masing-masing ([`._read()`][] dan [`._write()`][]). - -Ada panduan yang terdokumentasi untuk [mengimplementasikan aliran Readable][] dan [mengimplementasikan aliran Writable][]. Kami akan mengasumsikan bahwa Anda telah membacanya, dan bagian selanjutnya akan membahas lebih dalam sedikit. - -## Aturan yang Harus Dipatuhi Saat Menerapkan Aliran Khusus - -Aturan emas dari aliran adalah **selalu menghormati tekanan balik**. Apa yang dianggap sebagai praktik terbaik adalah praktik non-inkonsisten. Selama Anda berhati-hati untuk menghindari perilaku yang bertentangan dengan dukungan tekanan balik internal, Anda dapat yakin bahwa Anda mengikuti praktik yang baik. - -Secara umum, - -1. Jangan pernah melakukan `.push()` jika Anda tidak diminta. -2. Jangan pernah memanggil `.write()` setelah mengembalikan nilai false tetapi tunggu 'drain' sebagai gantinya. -3. Aliran berubah antara versi Node.js yang berbeda, dan pustaka yang Anda gunakan. Berhati-hatilah dan uji segala sesuatu. - -> Dalam hal poin 3, paket yang sangat berguna untuk membangun aliran browser adalah [`readable-stream`][]. Rodd Vagg telah menulis [blog post yang bagus][] yang menjelaskan kegunaan pustaka ini. Singkatnya, ini menyediakan jenis penurunan tingkat yang terautomatisasi untuk aliran [`Readable`][] stream, dan mendukung versi browser dan Node.js yang lebih lama. - -## Aturan yang Khusus untuk Aliran Writable - -Sejauh ini, kita telah melihat bagaimana [`.write()`][] mempengaruhi backpressure dan telah berfokus pada stream [`Writable`][]. Karena fungsionalitas Node.js, secara teknis data mengalir dari hulu [`Readable`][] ke hilir [`Writable`][]. Namun, seperti yang dapat kita amati pada setiap transmisi data, materi, atau energi, sumber sama pentingnya dengan tujuan akhir dan stream [`Readable`][] sangat penting dalam bagaimana backpressure diatasi. - -Kedua proses ini saling bergantung untuk berkomunikasi dengan efektif. Jika stream [`Readable`][] mengabaikan permintaan stream [`Writable`][] untuk berhenti mengirimkan data, hal tersebut sama sulitnya dengan ketika nilai kembalian dari [`.write()`][] tidak benar. - -Oleh karena itu, selain menghormati nilai kembalian dari [`.write()`][], kita juga harus menghormati nilai kembalian dari [`.push()`][] yang digunakan dalam metode [`._read()`][]. Jika [`.push()`][] mengembalikan nilai `false`, maka stream akan berhenti membaca dari sumber. Jika tidak, stream akan berlanjut tanpa jeda. - -Selain itu, dari luar aliran kustom, ada risiko mengabaikan backpressure. Dalam contoh kebalikannya dari praktik baik, kode aplikasi memaksa data masuk setiap kali tersedia (ditandai oleh \['data' event]\[]): - -```javascript -// Ini masalah besar karena sepenuhnya mengabaikan nilai kembalian dari push -// yang mungkin menjadi sinyal backpressure dari aliran tujuan! -class MyReadable extends Readable { - _read(size) { - let chunk; - while (null !== (chunk = getNextChunk())) { - this.push(chunk); - } - } -} -``` - -Selain itu, dari luar aliran kustom, ada kesalahan dalam mengabaikan backpressure. Dalam contoh kontraposisi dari praktik yang baik, kode aplikasi memaksa data untuk dilewatkan setiap kali tersedia (diisyaratkan oleh peristiwa [`'data'`][]: - -```javascript -// Ini mengabaikan mekanisme backpressure yang telah ditetapkan oleh Node.js, -// dan tanpa syarat mendorong data, terlepas apakah -// aliran tujuan siap atau tidak. -readable.on('data', data => writable.write(data)); -``` - -Berikut adalah contoh penggunaan [`.push()`][] dengan sebuah Readable stream. - -```javascript -const { Readable } = require('stream'); - -// Membuat Readable stream kustom -const myReadableStream = new Readable({ - objectMode: true, - read(size) { - // Memasukkan beberapa data ke dalam stream - this.push({ message: 'Hello, world!' }); - this.push(null); // Menandai akhir dari stream - }, -}); - -// Mengkonsumsi stream -myReadableStream.on('data', chunk => { - console.log(chunk); -}); - -// Output: -// { message: 'Hello, world!' } -``` - -Dalam contoh ini, kita membuat sebuah Readable stream kustom yang memasukkan sebuah objek tunggal ke dalam stream menggunakan [`.push()`][]. Metode [`._read()`][] dipanggil ketika stream siap untuk mengkonsumsi data, dan dalam hal ini, kita langsung memasukkan beberapa data ke dalam stream dan menandai akhir dari stream dengan memasukkan null. - -Kami kemudian mengkonsumsi aliran dengan mendengarkan acara 'data' dan mencatat setiap potongan data yang didorong ke aliran. Dalam hal ini, kami hanya mendorong satu bagian data ke aliran, jadi kami hanya melihat satu pesan log. - -## Aturan khusus untuk Aliran yang Dapat Ditulis - -Ingatlah bahwa [`.write()`][] dapat mengembalikan nilai true atau false tergantung pada beberapa kondisi. Untungnya bagi kita, ketika membangun aliran [`Writable`][] sendiri, [`mesin keadaan aliran`][] akan menangani panggilan balik kita dan menentukan kapan harus menangani backpressure dan mengoptimalkan aliran data untuk kita. - -Namun, ketika kita ingin menggunakan sebuah [`Writable`][] secara langsung, kita harus menghormati nilai kembalian [`.write()`][] dan memperhatikan kondisi-kondisi ini dengan cermat: - -- Jika antrian tulis sedang sibuk, [`.write()`][] akan mengembalikan false. -- Jika potongan data terlalu besar, [`.write()`][] akan mengembalikan false (batasnya ditandai oleh variabel [`highWaterMark`][]). - - - -```javascript -// This writable is invalid because of the async nature of JavaScript callbacks. -// Without a return statement for each callback prior to the last, -// there is a great chance multiple callbacks will be called. -class MyWritable extends Writable { - _write(chunk, encoding, callback) { - if (chunk.toString().indexOf('a') >= 0) callback(); - else if (chunk.toString().indexOf('b') >= 0) callback(); - callback(); - } -} - -// The proper way to write this would be: -if (chunk.contains('a')) return callback(); -if (chunk.contains('b')) return callback(); -callback(); -``` - -Ada juga beberapa hal yang perlu diperhatikan saat mengimplementasikan [`._writev()`][]. Fungsi ini terkait dengan [`.cork()`][], tetapi ada kesalahan umum saat menulis: - -```javascript -// Menggunakan .uncork() dua kali di sini membuat dua panggilan pada lapisan C++, -// sehingga teknik cork/uncork menjadi tidak berguna. -ws.cork(); -ws.write('hello '); -ws.write('world '); -ws.uncork(); - -ws.cork(); -ws.write('from '); -ws.write('Matteo'); -ws.uncork(); - -// Cara yang benar untuk menulisnya adalah dengan menggunakan process.nextTick(), -// yang akan dipanggil pada event loop berikutnya. -ws.cork(); -ws.write('hello '); -ws.write('world '); -process.nextTick(doUncork, ws); - -ws.cork(); -ws.write('from '); -ws.write('Matteo'); -process.nextTick(doUncork, ws); - -// Sebagai fungsi global. -function doUncork(stream) { - stream.uncork(); -} -``` - -[`.cork()`][] dapat dipanggil sebanyak yang kita inginkan, kita hanya perlu berhati-hati untuk memanggil [`.uncork()`][] sebanyak jumlah yang sama untuk membuatnya mengalir kembali. - -## Kesimpulan - -Stream adalah modul yang sering digunakan di Node.js. Mereka penting untuk struktur internal, dan bagi pengembang, untuk memperluas dan menghubungkan antar ekosistem modul Node.js. - -Semoga sekarang Anda dapat menyelesaikan masalah, mengkodekan dengan aman aliran [`Writable`][] dan [`Readable`][] dengan memperhatikan tekanan balik, dan membagikan pengetahuan Anda dengan rekan kerja dan teman-teman. - -Pastikan untuk membaca lebih lanjut tentang [`Stream`][] untuk fungsi API lainnya yang dapat membantu meningkatkan kemampuan streaming Anda saat membangun aplikasi dengan Node.js. - -[`Stream`]: https://nodejs.org/api/stream.html -[`Buffer`]: https://nodejs.org/api/buffer.html -[`EventEmitters`]: https://nodejs.org/api/events.html -[`Writable`]: https://nodejs.org/api/stream.html#stream_writable_streams -[`Readable`]: https://nodejs.org/api/stream.html#stream_readable_streams -[`Duplex`]: https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams -[`Transform`]: https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams -[`zlib`]: https://nodejs.org/api/zlib.html -[`drain`]: https://nodejs.org/api/stream.html#stream_event_drain -[`'data'`]: https://nodejs.org/api/stream.html#stream_event_data -[`.read()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_read_size -[`.write()`]: https://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback -[`._read()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_read_size_1 -[`._write()`]: https://nodejs.org/docs/latest/api/stream.html#stream_writable_write_chunk_encoding_callback_1 -[`._writev()`]: https://nodejs.org/api/stream.html#stream_writable_writev_chunks_callback -[`.cork()`]: https://nodejs.org/api/stream.html#stream_writable_cork -[`.uncork()`]: https://nodejs.org/api/stream.html#stream_writable_uncork -[`.push()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_push_chunk_encoding -[mengimplementasikan aliran Writable]: https://nodejs.org/docs/latest/api/stream.html#stream_implementing_a_writable_stream -[mengimplementasikan aliran Readable]: https://nodejs.org/docs/latest/api/stream.html#stream_implementing_a_readable_stream -[paket lainnya]: https://github.com/sindresorhus/awesome-nodejs#streams -[`backpressure`]: https://en.wikipedia.org/wiki/Backpressure_routing -[Node.js v0.10]: https://nodejs.org/docs/v0.10.0/ -[`highWaterMark`]: https://nodejs.org/api/stream.html#stream_buffering -[return value]: https://github.com/nodejs/node/blob/55c42bc6e5602e5a47fb774009cfe9289cb88e71/lib/_stream_writable.js#L239 -[nilai kembali]: https://github.com/nodejs/node/blob/55c42bc6e5602e5a47fb774009cfe9289cb88e71/lib/_stream_writable.js#L239 -[`readable-stream`]: https://github.com/nodejs/readable-stream -[blog post yang bagus]: https://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html -[`dtrace`]: http://dtrace.org/blogs/about/ -[`zip(1)`]: https://linux.die.net/man/1/zip -[`gzip(1)`]: https://linux.die.net/man/1/gzip -[`mesin keadaan aliran`]: https://en.wikipedia.org/wiki/Finite-state_machine -[`.pipe()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_pipe_destination_options -[pipe]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_pipe_destination_options -[`pump`]: https://github.com/mafintosh/pump -[`pipeline`]: https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback -[`promisify`]: https://nodejs.org/api/util.html#util_util_promisify_original diff --git a/pages/id/docs/guides/blocking-vs-non-blocking.md b/pages/id/docs/guides/blocking-vs-non-blocking.md deleted file mode 100644 index 9cf7d2f00a1d3..0000000000000 --- a/pages/id/docs/guides/blocking-vs-non-blocking.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Pratinjau Pemblokiran vs Non-Pemblokiran -layout: docs.hbs ---- - -# Ikhtisar Pemblokiran vs Non-Pemblokiran - -Ikhtisar ini mencakup perbedaan antara **pemblokiran** dan **non-pemblokiran** panggilan di Node.js. Ikhtisar ini akan merujuk ke loop acara dan libuv tetapi tidak pengetahuan sebelumnya tentang topik-topik tersebut diperlukan. Pembaca diasumsikan memiliki pemahaman dasar tentang bahasa JavaScript dan Node.js [pola panggilan balik](/id/knowledge/getting-started/control-flow/what-are-callbacks/). - -> "I/O" terutama mengacu pada interaksi dengan disk sistem dan jaringan yang didukung oleh [libuv](https://libuv.org/). - -## Memblokir - -**Blocking** adalah saat eksekusi JavaScript tambahan di Node.js proses harus menunggu hingga operasi non-JavaScript selesai. Ini terjadi karena loop acara tidak dapat melanjutkan menjalankan JavaScript saat a Operasi **pemblokiran** sedang terjadi. - -Di Node.js, JavaScript yang menunjukkan kinerja buruk karena CPU intensif daripada menunggu operasi non-JavaScript, seperti I/O, biasanya tidak disebut sebagai **pemblokiran**. Metode sinkron di pustaka standar Node.js yang menggunakan libuv adalah operasi **pemblokiran** yang paling umum digunakan. Warga asli modul mungkin juga memiliki metode **pemblokiran**. - -Semua metode I/O di pustaka standar Node.js menyediakan asinkron versi, yang **non-blocking**, dan menerima fungsi callback. Beberapa metode juga memiliki rekanan **pemblokiran**, yang memiliki nama yang diakhiri dengan `Sinkron`. - -## Membandingkan Kode - -Metode **Blocking** mengeksekusi metode **synchronously** dan **non-blocking** jalankan **secara tidak sinkron**. - -Menggunakan modul Sistem File sebagai contoh, ini adalah file **sinkron** yang dibaca: - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // blocks here until file is read -``` - -Dan berikut ini adalah contoh **asynchronous** yang setara: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; -}); -``` - -Contoh pertama tampak lebih sederhana daripada yang kedua tetapi memiliki kelemahan: baris kedua **memblokir** eksekusi JavaScript tambahan apa pun hingga seluruh file dibaca. Perhatikan bahwa dalam versi sinkron jika terjadi kesalahan dilempar itu perlu ditangkap atau prosesnya akan macet. Dalam asinkron versi, terserah penulis untuk memutuskan apakah kesalahan harus dilemparkan sebagai ditampilkan. - -Mari kita sedikit memperluas contoh kita: - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // blocks here until file is read -console.log(data); -moreWork(); // will run after console.log -``` - -Dan ini adalah contoh asinkron yang serupa, tetapi tidak setara: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -moreWork(); // will run before console.log -``` - -Pada contoh pertama di atas, `console.log` akan dipanggil sebelum `moreWork()`. Di contoh kedua `fs.readFile()` adalah **non-blocking** jadi eksekusi JavaScript dapat melanjutkan dan `moreWork()` akan dipanggil terlebih dahulu. Kemampuan untuk berlari `moreWork()` tanpa menunggu file selesai dibaca adalah desain utama pilihan yang memungkinkan untuk throughput yang lebih tinggi. - -## Konkurensi dan Throughput - -Eksekusi JavaScript di Node.js adalah utas tunggal, jadi konkurensi mengacu pada kapasitas loop acara untuk menjalankan fungsi panggilan balik JavaScript setelah selesai pekerjaan lain. Kode apa pun yang diharapkan berjalan secara bersamaan harus mengizinkan loop acara untuk terus berjalan sebagai operasi non-JavaScript, seperti I/O, adalah terjadi. - -Sebagai contoh, mari kita pertimbangkan kasus di mana setiap permintaan ke server web mengambil 50ms untuk diselesaikan dan 45ms dari 50ms itu adalah database I/O yang dapat dilakukan secara tidak sinkron. Memilih **non-blocking** operasi asinkron membebaskan itu 45ms per permintaan untuk menangani permintaan lainnya. Ini adalah perbedaan yang signifikan dalam kapasitas hanya dengan memilih untuk menggunakan metode **non-blocking** daripada **memblokir** metode. - -Loop acara berbeda dari model dalam banyak bahasa lain di mana tambahan utas dapat dibuat untuk menangani pekerjaan bersamaan. - -## Bahaya Mencampur Blocking dan Non-Blocking Code - -Ada beberapa pola yang harus dihindari ketika berhadapan dengan I/O. Mari lihat pada contoh: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -fs.unlinkSync('/file.md'); -``` - -Dalam contoh di atas, `fs.unlinkSync()` kemungkinan akan dijalankan sebelumnya `fs.readFile()`, yang akan menghapus `file.md` sebelum benar-benar dibaca. SEBUAH cara yang lebih baik untuk menulis ini, yang sepenuhnya **non-blocking** dan dijamin mengeksekusi dalam urutan yang benar adalah: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (readFileErr, data) => { - if (readFileErr) throw readFileErr; - console.log(data); - fs.unlink('/file.md', unlinkErr => { - if (unlinkErr) throw unlinkErr; - }); -}); -``` - -Di atas menempatkan panggilan **non-blocking** ke `fs.unlink()` dalam callback dari `fs.readFile()` yang menjamin urutan operasi yang benar. - -## Sumber daya tambahan - -- [libuv](https://libuv.org/) diff --git a/pages/id/docs/guides/buffer-constructor-deprecation.md b/pages/id/docs/guides/buffer-constructor-deprecation.md deleted file mode 100644 index 369db061dc185..0000000000000 --- a/pages/id/docs/guides/buffer-constructor-deprecation.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -title: Porting ke API Buffer.from() / Buffer.alloc() -layout: docs.hbs ---- - -# Porting ke `Buffer.from()`/`Buffer.alloc()` API - -## Pratinjau - -Panduan ini menjelaskan cara bermigrasi ke metode konstruktor `Buffer` yang aman. Migrasi memperbaiki peringatan penghentian berikut: - -> Konstruktor Buffer() dan new Buffer() tidak direkomendasikan untuk digunakan karena masalah keamanan dan penggunaan. Mohon gunakan metode konstruksi Buffer.alloc(), Buffer.allocUnsafe(), atau Buffer.from() yang baru. - -- [Varian 1: Hilangkan dukungan untuk Node.js 4.4.x dan 5.0.0 — 5.9.x](#varian-1) (_direkomendasikan_) -- [Varian 2: Gunakan polyfill](#variant-2) -- [Varian 3: Deteksi manual, dengan pengaman](#variant-3) - -### Menemukan bit kode yang bermasalah menggunakan `grep` - -Jalankan saja `grep -nrE '[^a-zA-Z](Lambat)?Buffer\s*\(' --exclude-dir node_modules`. - -Ini akan menemukan semua tempat yang berpotensi tidak aman dalam kode Anda sendiri (dengan beberapa yang sangat tidak mungkin pengecualian). - -### Menemukan bit kode yang bermasalah menggunakan Node.js 8 - -Jika Anda menggunakan Node.js 8.0.0 (yang direkomendasikan), Node.js memperlihatkan beberapa opsi yang membantu menemukan potongan kode yang relevan: - -- `--trace-warnings` akan membuat Node.js menampilkan jejak tumpukan untuk peringatan ini dan peringatan lain yang dicetak oleh Node.js. -- `--trace-deprecation` melakukan hal yang sama, tetapi hanya untuk peringatan penghentian. -- `--pending-deprecation` akan menampilkan lebih banyak jenis peringatan penghentian. Secara khusus, ini akan menampilkan peringatan penghentian `Buffer()`, bahkan pada Node.js 8. - -Anda dapat mengatur flag ini menggunakan variabel lingkungan: - -```bash -$ export NODE_OPTIONS='--trace-warnings --pending-deprecation' -$ cat example.js -'use strict'; -const foo = new Buffer('foo'); -$ node example.js -(node:7147) [DEP0005] DeprecationWarning: The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead. - at showFlaggedDeprecation (buffer.js:127:13) - at new Buffer (buffer.js:148:3) - at Object. (/path/to/example.js:2:13) - [... more stack trace lines ...] -``` - -### Menemukan bit kode yang bermasalah menggunakan linter - -Aturan ESLint [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor) atau [node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) juga menemukan panggilan ke `Buffer()` API yang tidak digunakan lagi. Aturan-aturan itu termasuk dalam beberapa preset. - -Namun, ada kekurangannya, itu tidak selalu [bekerja dengan benar](https://github.com/chalker/safer-buffer#why-not-safe-buffer) saat `Buffer` ditimpa misalnya dengan polyfill, jadi disarankan adalah kombinasi dari ini dan beberapa metode lainnya dijelaskan di atas. - -## Varian 1: Hilangkan dukungan untuk Node.js 4.4.x dan 5.0.0 — 5.9.x - -Ini adalah solusi yang direkomendasikan saat ini yang hanya menyiratkan overhead minimal. - -Jalur rilis Node.js 5.x tidak didukung sejak Juli 2016, dan jalur rilis Node.js 4.x mencapai Akhir Masa Pakainya pada April 2018 (→ [Jadwal](https://github.com/nodejs/Release#Release_schedule)). Ini berarti bahwa versi Node.js ini _tidak_ akan menerima pembaruan apa pun, bahkan jika ada masalah keamanan, jadi penggunaan jalur rilis ini harus dihindari, jika memungkinkan. - -Apa yang akan Anda lakukan dalam kasus ini adalah mengonversi semua panggilan `New Buffer()` atau `Buffer()` untuk menggunakan `Buffer.alloc()` atau `Buffer.from()`, dengan cara berikut: - -- Untuk `Buffer(number) baru`, ganti dengan `Buffer.alloc(number)`. -- Untuk `New Buffer(string)` (atau `new Buffer(string, encoding)`), ganti dengan `Buffer.from(string)` (atau `Buffer.from(string, encoding)`). -- Untuk semua kombinasi argumen lainnya (ini jauh lebih jarang), ganti juga `new Buffer(...arguments)` dengan `Buffer.from(...arguments)`. - -Perhatikan bahwa `Buffer.alloc()` juga _lebih cepat_ pada versi Node.js saat ini daripada `new Buffer(size).fill(0)`, yang seharusnya Anda perlukan untuk memastikan zero-filling. - -Mengaktifkan aturan ESLint [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor) atau [node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) direkomendasikan untuk menghindari penggunaan `Buffer` API yang tidak aman secara tidak sengaja. - -Ada juga [JSCodeshift codemod](https://github.com/joyeecheung/node-dep-codemod#dep005) untuk memigrasikan konstruktor `Buffer` secara otomatis ke `Buffer.alloc()` atau `Buffer.from()`. Perhatikan bahwa saat ini hanya berfungsi dengan kasus di mana argumennya literal atau di mana konstruktor dipanggil dengan dua argumen. - -_Jika saat ini Anda mendukung versi Node.js yang lebih lama dan menghentikan dukungan untuk mereka tidak mungkin, atau jika Anda mendukung cabang paket Anda yang lebih lama, pertimbangkan untuk menggunakan [Varian 2](#varian-2) atau [Varian 3](#varian-3) di cabang lama, jadi orang yang menggunakan cabang lama itu juga akan menerima perbaikan. Dengan begitu, Anda akan menghilangkan potensi masalah yang disebabkan oleh penggunaan `Buffer` API yang tidak dijaga dan pengguna Anda tidak akan melihat peringatan penghentian runtime saat menjalankan kode Anda di Node.js 10._ - -## Variant 2: Gunakan polyfill - -Ada tiga polyfill berbeda yang tersedia: - -- **[safer-buffer](https://www.npmjs.com/package/safer-buffer)** adalah pengganti drop-in untuk seluruh `Buffer` API, yang akan _dilempar_ saat menggunakan `new Buffer()`. - - Anda akan mengambil langkah yang sama persis seperti pada [Varian 1](#varian-1), tetapi dengan polyfill `const Buffer = require('safer-buffer').Buffer` di semua file tempat Anda menggunakan `Buffer` API baru. - - Jangan gunakan API `new Buffer()` yang lama. Dalam file apa pun di mana baris di atas ditambahkan, menggunakan `new Buffer()` API lama akan _throw_. - -- **[buffer-from](https://www.npmjs.com/package/buffer-from) dan/atau [buffer-alloc](https://www.npmjs.com/package/buffer-alloc)** adalah [ponyfills](https://ponyfill.com/) untuk masing-masing bagian dari `Buffer` API. Anda hanya perlu untuk menambahkan paket yang sesuai dengan API yang Anda gunakan. - - Anda akan mengimpor modul yang diperlukan dengan nama yang sesuai, mis. `const bufferFrom = require('buffer-from')` lalu gunakan itu sebagai ganti panggilan ke `Buffer baru()`, mis. `new Buffer('test')` menjadi `bufferFrom('test')`. - - Kelemahan dengan pendekatan ini adalah sedikit lebih banyak perubahan kode untuk dimigrasikan (seperti yang akan Anda lakukan menggunakan misalnya `Buffer.from()` dengan nama yang berbeda). - -- **[safe-buffer](https://www.npmjs.com/package/safe-buffer)** juga merupakan pengganti drop-in untuk seluruh `Buffer` API, tetapi menggunakan `new Buffer()` akan tetap berfungsi seperti sebelumnya. - - Kelemahan dari pendekatan ini adalah Anda juga dapat menggunakan `new Buffer()` API . yang lebih lama dalam kode Anda, yang bermasalah karena dapat menyebabkan masalah dalam kode Anda, dan akan mulai memancarkan peringatan penghentian runtime dimulai dengan Node.js 10 ([baca selengkapnya di sini](https://github.com/chalker/safer-buffer#why-not-safe-buffer)). - -Perhatikan bahwa dalam kedua kasus tersebut, Anda juga harus menghapus semua panggilan ke `Buffer` . yang lama API secara manual — hanya memasukkan `safe-buffer` tidak memperbaiki masalah dengan sendirinya, itu hanya menyediakan polyfill untuk API baru. Saya telah melihat orang-orang melakukan kesalahan itu. - -Mengaktifkan aturan ESLint [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor) atau [node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) direkomendasikan. - -_Jangan lupa untuk menghentikan penggunaan polyfill setelah Anda menghentikan dukungan untuk Node.js <4.5.0._ - -## Varian 3 — Deteksi manual, dengan pengaman - -Ini berguna jika Anda membuat instance `Buffer` hanya di beberapa tempat (mis. pembungkus di sekitar mereka. - -### `Buffer(0)` - -Kasus khusus untuk membuat buffer kosong ini dapat diganti dengan aman dengan `Buffer.concat([])`, yang mengembalikan hasil yang sama hingga ke Node.js 0.8.x. - -### `Buffer(bukanNumber)` - -Sebelum: - -```js -const buf = new Buffer(notNumber, encoding); -``` - -Sesudah: - -```js -let buf; -if (Buffer.from && Buffer.from !== Uint8Array.from) { - buf = Buffer.from(notNumber, encoding); -} else { - if (typeof notNumber === 'number') { - throw new Error('The "size" argument must be not of type number.'); - } - buf = new Buffer(notNumber, encoding); -} -``` - -`encoding` adalah opsional. - -Perhatikan bahwa `typeof notNumber` sebelum `new Buffer()` diperlukan (untuk kasus ketika argumen `notNumber` tidak hard-coded) dan _tidak disebabkan oleh penghentian konstruktor `Buffer`_ — justru _why_ the Konstruktor `Buffer` tidak digunakan lagi. Paket ekosistem yang tidak memiliki jenis pemeriksaan ini menyebabkan banyak masalah keamanan — situasi ketika input pengguna yang tidak bersih dapat berakhir di `Buffer(arg)` create masalah mulai dari DoS hingga membocorkan informasi sensitif ke penyerang dari memori proses. - -Ketika argumen `notNumber` di-hardcode (misalnya literal `"abc"` atau `[0,1,2]`), pemeriksaan `typeof` dapat dihilangkan. - -Juga, perhatikan bahwa menggunakan TypeScript tidak memperbaiki masalah ini untuk Anda — ketika libs ditulis dalam `TypeScript` digunakan dari JS, atau ketika input pengguna berakhir di sana — ia berperilaku persis seperti JS murni, seperti semua jenis pemeriksaan hanya waktu terjemahan dan tidak ada dalam kode JS aktual yang TS mengkompilasi ke. - -### `Buffer(number)` - -Untuk dukungan Node.js 0.10.x (dan di bawah): - -```js -let buf; -if (Buffer.alloc) { - buf = Buffer.alloc(number); -} else { - buf = new Buffer(number); - buf.fill(0); -} -``` - -Jika tidak (Node.js 0.12.x): - -```js -const buf = Buffer.alloc ? Buffer.alloc(number) : new Buffer(number).fill(0); -``` - -## Tentang `Buffer.allocUnsafe()` - -Berhati-hatilah saat menggunakan `Buffer.allocUnsafe()`: - -- Jangan gunakan jika Anda tidak memiliki alasan yang baik untuk - - misalnya Anda mungkin tidak akan pernah melihat perbedaan kinerja untuk buffer kecil, pada kenyataannya, itu mungkin lebih cepat dengan `Buffer.alloc()`, - - jika kode Anda tidak berada di jalur kode panas — Anda mungkin juga tidak akan melihat perbedaan, - - perlu diingat bahwa pengisian nol meminimalkan potensi risiko. -- Jika Anda menggunakannya, pastikan Anda tidak pernah mengembalikan buffer dalam keadaan terisi sebagian, - - jika Anda menulisnya secara berurutan — selalu potong ke panjang tulisan yang sebenarnya - -Kesalahan dalam menangani buffer yang dialokasikan dengan `Buffer.allocUnsafe()` dapat mengakibatkan berbagai masalah, berkisar dari perilaku kode Anda yang tidak terdefinisi hingga data sensitif (input pengguna, kata sandi, sertifikat) bocor ke penyerang jarak jauh. - -_Perhatikan bahwa hal yang sama berlaku untuk penggunaan `new Buffer()` tanpa pengisian nol, tergantung pada Node.js versi (dan kurangnya pemeriksaan tipe juga menambahkan DoS ke daftar potensi masalah)._ - -## Pertanyaan Umum (FAQ) - -### Apa yang salah dengan konstruktor `Buffer`? - -Konstruktor `Buffer` dapat digunakan untuk membuat buffer dengan berbagai cara: - -- `New Buffer(42)` membuat `Buffer` sebesar 42 byte. Sebelum Node.js 8, buffer ini berisi _memori sewenang-wenang_ untuk alasan kinerja, yang dapat mencakup apa saja mulai dari kode sumber program untuk kata sandi dan kunci enkripsi. -- `new Buffer('abc')` membuat `Buffer` yang berisi versi UTF-8-encoded string '`'abc'`. Argumen kedua dapat menentukan pengkodean lain: misalnya,`new Buffer(string, 'base64')` dapat digunakan untuk mengonversi string Base64 menjadi yang asli urutan byte yang diwakilinya. -- Ada beberapa kombinasi argumen lainnya. - -Ini berarti bahwa dalam kode seperti `var buffer = new Buffer(foo);`, _tidak mungkin untuk mengetahuinya apa sebenarnya isi buffer yang dihasilkan_ tanpa mengetahui jenis `foo`. - -Terkadang, nilai `foo` berasal dari sumber eksternal. Misalnya, fungsi ini dapat diekspos sebagai layanan di server web, mengubah string UTF-8 menjadi bentuk Base64: - -```js -function stringToBase64(req, res) { - // The request body should have the format of `{ string: 'foobar' }`. - const rawBytes = new Buffer(req.body.string); - const encoded = rawBytes.toString('base64'); - res.end({ encoded }); -} -``` - -Perhatikan bahwa kode ini _tidak_ memvalidasi jenis `req.body.string`: - -- `req.body.string` diharapkan berupa string. Jika ini masalahnya, semuanya berjalan dengan baik. -- `req.body.string` dikendalikan oleh klien yang mengirimkan permintaan. -- Jika `req.body.string` adalah _number_ `50`, `rawBytes` akan menjadi `50` byte: - - Sebelum Node.js 8, konten tidak akan diinisialisasi - - Setelah Node.js 8, konten akan menjadi `50` byte dengan nilai `0` - -Karena pemeriksaan tipe yang hilang, penyerang dapat dengan sengaja mengirim nomor sebagai bagian dari permintaan. Dengan menggunakan ini, mereka dapat: - -- Baca memori yang tidak diinisialisasi. Ini **akan** membocorkan kata sandi, kunci enkripsi, dan lainnya jenis informasi sensitif. (Kebocoran informasi) -- Memaksa program untuk mengalokasikan sejumlah besar memori. Misalnya, saat menentukan `500000000` sebagai nilai input, setiap permintaan akan mengalokasikan 500MB memori. Ini dapat digunakan untuk menghabiskan memori yang tersedia dari suatu program sepenuhnya dan membuatnya crash, atau memperlambatnya secara signifikan. (Kegagalan layanan) - -Kedua skenario ini dianggap sebagai masalah keamanan yang serius di dunia nyata konteks server web. - -Saat menggunakan `Buffer.from(req.body.string)` sebagai gantinya, melewatkan nomor akan selalu melempar pengecualian sebagai gantinya, memberikan perilaku terkontrol yang selalu bisa ditangani oleh program. - -### Konstruktor `Buffer()` telah ditinggalkan untuk sementara waktu. Apakah ini benar-benar masalah? - -Survei kode di ekosistem `npm` telah menunjukkan bahwa konstruktor `Buffer()` masih banyak digunakan. Ini termasuk kode baru, dan penggunaan keseluruhan kode tersebut sebenarnya telah _increasing_. diff --git a/pages/id/docs/guides/debugging-getting-started.md b/pages/id/docs/guides/debugging-getting-started.md deleted file mode 100644 index 163ecf81470e4..0000000000000 --- a/pages/id/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: Memecahkan Masalah - Memulai -layout: docs.hbs ---- - -# Panduan Memecahkan Masalah - -Panduan ini akan membantu Anda memulai debugging aplikasi dan skrip Node.js Anda. - -## Aktifkan Inspektur - -Saat dimulai dengan sakelar `--inspect`, proses Node.js mendengarkan a klien debug. Secara default, ia akan mendengarkan di host dan port 127.0.0.1:9229. Setiap proses juga diberi [UUID][] yang unik. - -Klien pemeriksa harus mengetahui dan menentukan alamat host, port, dan UUID untuk terhubung. URL lengkap akan terlihat seperti `ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e`. - -Node.js juga akan mulai mendengarkan pesan debug jika menerima a Sinyal `SIGUSR1`. (`SIGUSR1` tidak tersedia di Windows.) Di Node.js 7 dan sebelumnya, ini mengaktifkan API Debugger lawas. Di Node.js 8 dan yang lebih baru, itu akan aktifkan API Inspektur. - ---- - -## Implikasi Keamanan - -Karena debugger memiliki akses penuh ke lingkungan eksekusi Node.js, a aktor jahat yang dapat terhubung ke port ini mungkin dapat mengeksekusi secara sewenang-wenang kode atas nama proses Node.js. Penting untuk memahami keamanan implikasi mengekspos port debugger pada jaringan publik dan pribadi. - -### Mengekspos port debug secara publik tidak aman - -Jika debugger terikat ke alamat IP publik, atau ke 0.0.0.0, setiap klien yang dapat mencapai alamat IP Anda akan dapat terhubung ke debugger tanpa pembatasan dan akan dapat menjalankan kode arbitrer. - -Secara default `node --inspect` mengikat ke 127.0.0.1. Anda secara eksplisit perlu memberikan alamat IP publik atau 0.0.0.0, dll., jika Anda ingin mengizinkan koneksi eksternal ke debuggernya. Melakukannya dapat membuat Anda terkena keamanan yang berpotensi signifikan ancaman. Kami menyarankan Anda memastikan firewall yang sesuai dan kontrol akses di tempat untuk mencegah paparan keamanan. - -Lihat bagian '[Mengaktifkan skenario debugging jarak jauh](#enabling-remote-debugging-scenarios)' pada beberapa saran tentang cara untuk memungkinkan klien debugger jarak jauh terhubung dengan aman. - -### Aplikasi lokal memiliki akses penuh ke inspektur - -Bahkan jika Anda mengikat port inspektur ke 127.0.0.1 (default), aplikasi apa pun berjalan secara lokal di mesin Anda akan memiliki akses tak terbatas. Ini adalah dengan desain untuk memungkinkan debugger lokal dapat melampirkan dengan nyaman. - -### Browser, WebSockets, dan kebijakan asal yang sama - -Situs web yang dibuka di browser web dapat membuat permintaan WebSocket dan HTTP di bawah model keamanan peramban. Koneksi HTTP awal diperlukan untuk mendapatkan id sesi debugger unik. Kebijakan asal yang sama mencegah situs web menjadi dapat membuat koneksi HTTP ini. Untuk keamanan tambahan terhadap [Serangan rebinding DNS](https://en.wikipedia.org/wiki/DNS_rebinding), Node.js memverifikasi bahwa tajuk 'Host' untuk koneksi juga tentukan alamat IP atau `localhost6` dengan tepat. - -Kebijakan keamanan ini melarang koneksi ke server debug jarak jauh dengan: menentukan nama host. Anda dapat mengatasi batasan ini dengan menentukan baik alamat IP atau dengan menggunakan terowongan ssh seperti yang dijelaskan di bawah ini. - -## Klien Inspektur - -Debugger CLI minimal tersedia dengan `node inspect myscript.js`. Beberapa alat komersial dan sumber terbuka juga dapat terhubung ke Inspektur Node.js. - -### [Chrome DevTools](https://github.com/ChromeDevTools/devtools-frontend) 55+, [Microsoft Edge](https://www.microsoftedgeinsider.com) - -- **Opsi 1**: Buka `chrome://inspect` dalam berbasis Chromium browser atau `edge://inspect` di Edge. Klik tombol Konfigurasi dan pastikan host dan port target Anda terdaftar. -- **Opsi 2**: Salin `devtoolsFrontendUrl` dari output `/json/list` (lihat di atas) atau teks petunjuk --inspect dan tempel ke Chrome. - -> Perhatikan bahwa Node.js dan Chrome harus dijalankan pada platform yang sama. - -### [Visual Studio code](https://github.com/microsoft/vscode) 1.10+ - -- Di panel Debug, klik ikon pengaturan untuk membuka `.vscode/launch.json`. Pilih "Node.js" untuk pengaturan awal. - -### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- Pilih "Debug > Start Debugging" dari menu atau tekan F5. -- [Petunjuk terperinci](https://github.com/Microsoft/nodejstools/wiki/Debugging). - -### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) dan IDE JetBrains lainnya - -- Buat konfigurasi debug Node.js baru dan tekan Debug. `--inspect` akan digunakan secara default untuk Node.js 7+. Untuk menonaktifkan hapus centang `js.debugger.node.use.inspect` di Registri IDE. Untuk mempelajari lebih lanjut tentang menjalankan dan men-debug Node.js di WebStorm dan IDE JetBrains lainnya, lihat [bantuan online WebStorm](https://www.jetbrains.com/help/webstorm/running-and-debugging-node-js.html). - -### [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - -- Perpustakaan untuk memudahkan koneksi ke [Protokol Inspektur][] titik akhir. - -### [Gitpod](https://www.gitpod.io) - -- Mulai konfigurasi debug Node.js dari tampilan `Debug` atau tekan `F5`. [Petunjuk terperinci](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1) - -### [Eclipse IDE](https://Eclipse.org/Eclipseide) dengan ekstensi Pengembang Web Liar Eclipse - -- Dari file .js, pilih "Debug As... > Node program", atau -- Buat Konfigurasi Debug untuk melampirkan debugger ke aplikasi Node.js yang sedang berjalan (sudah dimulai dengan `--inspect`). - ---- - -## Opsi baris perintah - -Tabel berikut mencantumkan dampak dari berbagai flag runtime pada debugging: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PenandaArti
--inspect -
    -
  • Mengaktifkan agen inspeksi
  • -
  • Mendengarkan di alamat dan port default (127.0.0.1:9229)
  • -
-
--inspect=[host:port] -
    -
  • Mengaktifkan agen inspeksi
  • -
  • Mengikat ke alamat atau nama host host (default: 127.0.0.1)
  • -
  • Mendengarkan pada port port (default: 9229)
  • -
-
--inspect-brk -
    -
  • Mengaktifkan agen inspeksi
  • -
  • Mendengarkan di alamat dan port default (127.0.0.1:9229)
  • -
  • Berhenti sebelum kode pengguna dimulai
  • -
-
--inspect-brk=[host:port] -
    -
  • Mengaktifkan agen inspeksi
  • -
  • Mengikat ke alamat atau nama host host (default: 127.0.0.1)
  • -
  • Mendengarkan pada port port (default: 9229)
  • -
  • Berhenti sebelum kode pengguna dimulai
  • -
-
node inspect script.js -
    -
  • Menjalankan proses anak untuk menjalankan skrip pengguna dengan flag --inspect; dan menggunakan proses utama untuk menjalankan debugger CLI.
  • -
-
node inspect --port=xxxx script.js -
    -
  • Menjalankan proses anak untuk menjalankan skrip pengguna dengan flag --inspect; dan menggunakan proses utama untuk menjalankan debugger CLI.
  • -
  • Mendengarkan pada port port (default: 9229)
  • -
-
- ---- - -## Mengaktifkan skenario debugging jarak jauh - -Kami menyarankan Anda tidak pernah mendengarkan debugger pada alamat IP publik. Jika Anda perlu mengizinkan koneksi debugging jarak jauh, kami merekomendasikan penggunaan ssh terowongan sebagai gantinya. Kami memberikan contoh berikut untuk tujuan ilustrasi saja. Harap pahami risiko keamanan dari mengizinkan akses jarak jauh ke hak istimewa layanan sebelum melanjutkan. - -Katakanlah Anda menjalankan Node.js pada mesin jarak jauh, remote.example.com, yang Anda ingin dapat men-debug. Di mesin itu, Anda harus memulai proses simpul dengan inspektur hanya mendengarkan localhost (default). - -```bash -node --inspect server.js -``` - -Sekarang, di mesin lokal Anda dari mana Anda ingin memulai klien debug koneksi, Anda dapat mengatur terowongan ssh: - -```bash -ssh -L 9221:localhost:9229 user@remote.example.com -``` - -Ini memulai sesi terowongan ssh di mana koneksi ke port 9221 di lokal Anda mesin akan diteruskan ke port 9229 di remote.example.com. Anda sekarang dapat melampirkan debugger seperti Chrome DevTools atau Visual Studio Code ke localhost:9221, yang seharusnya dapat melakukan debug seolah-olah aplikasi Node.js berjalan secara lokal. - ---- - -## Debugger Lama - -**Debugger lama tidak digunakan lagi sejak Node.js 7.7.0. Mohon gunakan `--inspect` dan Inspector sebagai gantinya.** - -Saat dimulai dengan sakelar **--debug** atau **--debug-brk** di versi 7 dan sebelumnya, Node.js mendengarkan perintah debugging yang ditentukan oleh yang dihentikan Protokol Debugging V8 pada port TCP, secara default `5858`. Setiap klien debugger yang berbicara bahwa protokol ini dapat terhubung dan men-debug proses yang sedang berjalan; sebuah pasangan yang populer tercantum di bawah ini. - -Protokol Debugging V8 tidak lagi dipertahankan atau didokumentasikan. - -### [Debugger Bawaan](https://nodejs.org/dist/latest/docs/api/debugger.html) - -Mulai `node debug script_name.js` untuk memulai skrip Anda di bawah bawaan debugger baris perintah. Skrip Anda dimulai dalam proses Node.js lain yang dimulai dengan opsi `--debug-brk`, dan proses Node.js awal menjalankan `_debugger.js` script dan menghubungkan ke target Anda. - -### [node-inspector](https://github.com/node-inspector/node-inspector) - -Debug aplikasi Node.js Anda dengan Chrome DevTools menggunakan proses perantara yang menerjemahkan [Protokol Inspektur][] yang digunakan di Chromium ke V8 Debugger protokol yang digunakan di Node.js. - - - -[Protokol Inspektur]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/id/docs/guides/diagnostics-flamegraph.md b/pages/id/docs/guides/diagnostics-flamegraph.md deleted file mode 100644 index e15026b74a233..0000000000000 --- a/pages/id/docs/guides/diagnostics-flamegraph.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Diagnostik - Flame Graph -layout: docs.hbs ---- - -# Flame Graph - -## Apa kegunaan flame graph? - -Flame graph adalah cara memvisualisasikan waktu CPU yang dihabiskan dalam fungsi. Mereka dapat membantu Anda menentukan di mana Anda menghabiskan terlalu banyak waktu untuk melakukan operasi sinkron. - -## Cara membuat flame graph - -Anda mungkin pernah mendengar membuat flame graph untuk Node.js itu sulit, tapi itu tidak benar (lagi). Solaris vms tidak lagi diperlukan untuk grafik nyala! - -Grafik nyala dihasilkan dari keluaran `perf`, yang bukan merupakan alat khusus simpul. Meskipun ini adalah cara paling ampuh untuk memvisualisasikan waktu CPU yang dihabiskan, ini mungkin memiliki masalah dengan bagaimana kode JavaScript dioptimalkan di Node.js 8 dan di atasnya. Lihat bagian [perf output issues](#perf-output-issues) di bawah ini. - -### Gunakan alat yang sudah dikemas sebelumnya - -Jika Anda menginginkan satu langkah yang menghasilkan grafik nyala secara lokal, coba [0x](https://www.npmjs.com/package/0x) - -Untuk mendiagnosis penerapan produksi, baca catatan berikut: [0x server produksi](https://github.com/davidmarkclements/0x/blob/master/docs/production-servers.md). - -### Buat grafik nyala dengan alat kinerja sistem - -Tujuan dari panduan ini adalah untuk menunjukkan langkah-langkah yang terlibat dalam membuat flame graph dan membuat Anda tetap mengendalikan setiap langkah. - -Jika Anda ingin memahami setiap langkah dengan lebih baik, lihat bagian berikut di mana kita akan membahas lebih detail. - -Sekarang mari kita mulai bekerja. - -1. Instal `perf` (biasanya tersedia melalui paket linux-tools-common jika belum diinstal) -2. coba jalankan `perf` - mungkin mengeluh tentang modul kernel yang hilang, instal juga -3. jalankan node dengan perf diaktifkan (lihat [masalah output perf](#perf-output-issues) untuk tips khusus untuk versi Node.js) - - ```bash - perf record -e cycles:u -g -- node --perf-basic-prof app.js - ``` - -4. mengabaikan peringatan kecuali mereka mengatakan Anda tidak dapat menjalankan perf karena paket yang hilang; Anda mungkin mendapatkan beberapa peringatan tentang tidak dapat mengakses sampel modul kernel yang sebenarnya tidak Anda cari. -5. Jalankan `perf script > perfs.out` untuk menghasilkan file data yang akan Anda visualisasikan dalam sekejap. Berguna untuk [menerapkan beberapa pembersihan](#filtering-out-node-js-internal-functions) untuk grafik yang lebih mudah dibaca -6. instal stackvis jika belum terinstal `npm i -g stackvis` -7. jalankan `stackvis perf < perfs.out > flamegraph.htm` - -Sekarang buka file flame graph di browser favorit Anda dan lihat itu terbakar. Ini diberi kode warna sehingga Anda dapat fokus pada batang oranye yang paling jenuh terlebih dahulu. Mereka cenderung mewakili fungsi berat CPU. - -Perlu disebutkan - jika Anda mengklik elemen flame graph, zoom-in dari sekelilingnya akan ditampilkan di atas grafik. - -### Menggunakan `perf` untuk mengambil sampel proses yang sedang berjalan - -Ini bagus untuk merekam data grafik nyala dari proses yang sudah berjalan yang tidak ingin Anda hentikan. Bayangkan sebuah proses produksi dengan masalah yang sulit untuk direproduksi. - -```bash -perf record -F99 -p `pgrep -n node` -g -- sleep 3 -``` - -Tunggu, untuk apa `tidur 3` itu? Itu ada untuk menjaga kinerja tetap berjalan - meskipun opsi `-p` menunjuk ke pid yang berbeda, perintah harus dieksekusi pada suatu proses dan diakhiri dengan itu. perf berjalan selama masa perintah yang Anda berikan padanya, terlepas dari apakah Anda benar-benar membuat profil perintah itu atau tidak. `sleep 3` memastikan kinerja berjalan selama 3 detik. - -Mengapa `-F` (frekuensi profil) diatur ke 99? Ini adalah default yang masuk akal. Anda dapat menyesuaikan jika Anda mau. `-F99` memberi tahu perf untuk mengambil 99 sampel per detik, untuk lebih presisi, tingkatkan nilainya. Nilai yang lebih rendah seharusnya menghasilkan keluaran yang lebih sedikit dengan hasil yang kurang tepat. Presisi yang Anda butuhkan tergantung pada berapa lama fungsi intensif CPU Anda benar-benar berjalan. Jika Anda mencari alasan perlambatan yang nyata, 99 frame per detik seharusnya sudah lebih dari cukup. - -Setelah Anda mendapatkan catatan perf 3 detik itu, lanjutkan dengan membuat grafik nyala dengan dua langkah terakhir dari atas. - -### Memfilter fungsi internal Node.js - -Biasanya Anda hanya ingin melihat kinerja panggilan Anda sendiri, jadi memfilter fungsi internal Node.js dan V8 dapat membuat grafik lebih mudah dibaca. Anda dapat membersihkan file perf Anda dengan: - -```bash -sed -i \ - -e "/( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)/d" \ - -e 's/ LazyCompile:[*~]\?/ /' \ - perfs.out -``` - -Jika Anda membaca grafik nyala Anda dan tampak aneh, seolah-olah ada sesuatu yang hilang dalam fungsi kunci yang memakan waktu paling lama, coba buat grafik nyala Anda tanpa filter - mungkin Anda mendapat kasus yang jarang terjadi tentang masalah dengan Node.js itu sendiri. - -### Opsi pembuatan profil Node.js - -`--perf-basic-prof-only-functions` dan `--perf-basic-prof` adalah dua yang berguna untuk men-debug kode JavaScript Anda. Opsi lain digunakan untuk membuat profil Node.js itu sendiri, yang berada di luar cakupan panduan ini. - -`--perf-basic-prof-only-functions` menghasilkan lebih sedikit output, jadi ini adalah opsi dengan overhead paling sedikit. - -### Mengapa saya membutuhkannya sama sekali? - -Nah, tanpa opsi ini Anda masih akan mendapatkan grafik nyala, tetapi dengan sebagian besar batang berlabel `v8::Function::Call`. - -## Masalah keluaran `perf` - -### Perubahan pipeline Node.js 8.x V8 - -Node.js 8.x dan yang lebih baru dikirimkan dengan optimasi baru ke pipa kompilasi JavaScript di mesin V8 yang terkadang membuat nama/referensi fungsi tidak dapat dijangkau untuk perf kadang-kadang. (Ini disebut Turbofan) - -Hasilnya adalah Anda mungkin tidak mendapatkan nama fungsi Anda tepat di grafik nyala. - -Anda akan melihat `ByteCodeHandler:` di mana Anda mengharapkan nama fungsi. - -[0x](https://www.npmjs.com/package/0x) memiliki beberapa mitigasi untuk itu. - -Untuk detail lihat: - -- https://github.com/nodejs/benchmarking/issues/168 -- https://github.com/nodejs/diagnostics/issues/148#issuecomment-369348961 - -### Node.js 10+ - -Node.js 10.x mengatasi masalah dengan Turbofan menggunakan flag `--interpreted-frames-native-stack`. - -Jalankan `node --interpreted-frames-native-stack --perf-basic-prof-only-functions` untuk mendapatkan nama fungsi dalam grafik nyala terlepas dari pipa V8 mana yang digunakan untuk mengompilasi JavaScript Anda. - -### Label rusak di flame graph - -Jika Anda melihat label seperti ini - -``` -node`_ZN2v88internal11interpreter17BytecodeGenerator15VisitStatementsEPNS0_8ZoneListIPNS0_9StatementEEE -``` - -itu berarti kinerja Linux yang Anda gunakan tidak dikompilasi dengan dukungan demangle, lihat https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 misalnya - -## Contoh - -Berlatih menangkap flame graph sendiri dengan [latihan flame graph](https://github.com/naugtur/node-example-flamegraph)! diff --git a/pages/id/docs/guides/diagnostics/index.md b/pages/id/docs/guides/diagnostics/index.md deleted file mode 100644 index 1ba72691f07ed..0000000000000 --- a/pages/id/docs/guides/diagnostics/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Panduan Diagnostik -layout: docs.hbs ---- - -# Panduan Diagnostik - -Panduan ini dibuat oleh [Kelompok Kerja Diagnostik][] dengan tujuan memberikan panduan saat mendiagnosis masalah pada aplikasi pengguna. - -Proyek dokumentasi ini diorganisir berdasarkan perjalanan pengguna. Perjalanan tersebut adalah serangkaian prosedur langkah-demi-langkah yang koheren yang dapat diikuti pengguna untuk menemukan akar masalah. - -Berikut ini adalah kumpulan panduan diagnostik yang tersedia: - -- [Memori](/en/docs/guides/diagnostics/memory) -- [Debug Langsung](/en/docs/guides/diagnostics/live-debugging) -- [Kinerja Buruk](/en/docs/guides/diagnostics/poor-performance) - -[Kelompok Kerja Diagnostik]: https://github.com/nodejs/diagnostics diff --git a/pages/id/docs/guides/diagnostics/live-debugging/index.md b/pages/id/docs/guides/diagnostics/live-debugging/index.md deleted file mode 100644 index 5a3936b387b79..0000000000000 --- a/pages/id/docs/guides/diagnostics/live-debugging/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Pemecahan Masalah Langsung -layout: docs.hbs ---- - -# Pemecahan Masalah Langsung - -- [Pemecahan Masalah Langsung](#live-debugging) - - [Aplikasi saya tidak berjalan seperti yang diharapkan](#my-application-doesnt-behave-as-expected) - - [Gejala](#symptoms) - - [Pemecahan Masalah](#debugging) - -Dalam dokumen ini, Anda dapat belajar tentang cara melakukan debug langsung pada proses Node.js. - -## Aplikasi saya tidak berjalan seperti yang diharapkan - -### Gejala - -Pengguna mungkin memperhatikan bahwa aplikasi tidak memberikan output yang diharapkan untuk beberapa input tertentu, misalnya, server HTTP mengembalikan respons JSON di mana beberapa field kosong. Berbagai hal dapat salah dalam proses tersebut, tetapi dalam kasus penggunaan ini, kami terutama fokus pada logika aplikasi dan kebenarannya. - -### Pemecahan Masalah - -Dalam kasus penggunaan ini, pengguna ingin memahami jalur kode yang dieksekusi oleh aplikasi kita untuk trigger tertentu seperti permintaan HTTP yang masuk. Mereka juga mungkin ingin melangkah melalui kode dan mengontrol eksekusi serta memeriksa nilai-nilai variabel yang ada di dalam memori. - -- [Menggunakan Inspeksi](/en/docs/guides/diagnostics/live-debugging/using-inspector) diff --git a/pages/id/docs/guides/diagnostics/live-debugging/using-inspector.md b/pages/id/docs/guides/diagnostics/live-debugging/using-inspector.md deleted file mode 100644 index eed54baddf9e8..0000000000000 --- a/pages/id/docs/guides/diagnostics/live-debugging/using-inspector.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Menggunakan Inspeksi -layout: docs.hbs ---- - -# Menggunakan Inspeksi - -Pada lingkungan lokal, biasanya kita berbicara tentang pemecahan masalah langsung di mana kita menempelkan debugger ke aplikasi kita dan menambahkan breakpoint untuk menghentikan eksekusi program. Kemudian kita melangkah melalui jalur kode dan memeriksa heap kita selama langkah-langkah yang berbeda. Menggunakan pemecah masalah langsung di produksi biasanya bukan pilihan karena kami memiliki akses terbatas ke mesin dan kami tidak dapat menghentikan eksekusi aplikasi karena menangani beban kerja yang kritis untuk bisnis. - -## Bagaimana Caranya - -https://nodejs.org/en/docs/guides/debugging-getting-started/ diff --git a/pages/id/docs/guides/diagnostics/memory/index.md b/pages/id/docs/guides/diagnostics/memory/index.md deleted file mode 100644 index 1cfc692be621b..0000000000000 --- a/pages/id/docs/guides/diagnostics/memory/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Diagnostik Memori -layout: docs.hbs ---- - -# Memori - -Dalam dokumen ini, Anda dapat belajar tentang cara memecahkan masalah yang berkaitan dengan memori. - -- [Memori](#memory) - - [Proses saya kehabisan memori](#my-process-runs-out-of-memory) - - [Gejala](#symptoms) - - [Efek Samping](#side-effects) - - [Proses saya menggunakan memori secara tidak efisien](#my-process-utilizes-memory-inefficiently) - - [Gejala](#symptoms-1) - - [Efek Samping](#side-effects-1) - - [Pemecahan Masalah](#debugging) - -## Proses saya kehabisan memori - -Node.js _(JavaScript)_ adalah bahasa yang dikumpulkan sampah, sehingga kebocoran memori mungkin terjadi melalui retainer. Karena aplikasi Node.js biasanya multi-penyewa, kritis untuk bisnis, dan berjalan lama, menyediakan cara yang mudah diakses dan efisien untuk menemukan kebocoran memori sangat penting. - -### Gejala - -Pengguna memperhatikan penggunaan memori yang terus meningkat _(dapat cepat atau lambat, selama beberapa hari atau bahkan minggu)_ kemudian melihat proses crash dan restart oleh manajer proses. Proses mungkin berjalan lebih lambat dari sebelumnya dan restart menyebabkan beberapa permintaan gagal _(load balancer merespons dengan 502)_. - -### Efek Samping - -- Restart proses karena kehabisan memori dan permintaan ditolakRestart proses karena kehabisan memori dan permintaan ditolak -- Aktivitas GC yang meningkat menyebabkan penggunaan CPU yang lebih tinggi dan waktu respons yang lebih lambat - - GC menghalangi Event Loop menyebabkan lambat -- Peningkatan swapping memori memperlambat proses (aktivitas GC) -- Mungkin tidak memiliki cukup memori yang tersedia untuk mendapatkan Heap Snapshot - -## Proses saya memanfaatkan memori secara tidak efisien - -### Gejala - -Aplikasi menggunakan jumlah memori yang tidak terduga dan / atau kami mengamati aktivitas kolektor sampah yang meningkat. - -### Efek Samping - -- Jumlah page fault yang tinggi -- Aktivitas GC yang lebih tinggi dan penggunaan CPU - -## Pemecahan Masalah - -Sebagian besar masalah memori dapat diatasi dengan menentukan berapa banyak ruang yang digunakan oleh objek tipe khusus kita dan variabel apa yang mencegah mereka dari dikumpulkan oleh sampah. Juga membantu untuk mengetahui pola alokasi program kita dari waktu ke waktu. - -- [Menggunakan Heap Profiler](/en/docs/guides/diagnostics/memory/using-heap-profiler/) -- [Menggunakan Heap Snapshot](/en/docs/guides/diagnostics/memory/using-heap-snapshot/) -- [GC Traces](/en/docs/guides/diagnostics/memory/using-gc-traces) diff --git a/pages/id/docs/guides/diagnostics/memory/using-gc-traces.md b/pages/id/docs/guides/diagnostics/memory/using-gc-traces.md deleted file mode 100644 index 6dfb470c73310..0000000000000 --- a/pages/id/docs/guides/diagnostics/memory/using-gc-traces.md +++ /dev/null @@ -1,366 +0,0 @@ ---- -title: Diagnostik Memori - Menggunakan Jejak GC -layout: docs.hbs ---- - -# Melacak pengumpulan sampah - -Panduan ini akan melalui dasar-dasar jejak pengumpulan sampah. - -Di akhir panduan ini, Anda akan dapat: - -- Aktifkan pelacakan di aplikasi Node.js Anda -- Menginterpretasikan jejak -- Identifikasi potensi masalah memori di aplikasi Node.js Anda - -Banyak hal yang perlu dipelajari tentang bagaimana garbage collector bekerja, tetapi jika Anda mempelajari satu hal saja, itu adalah bahwa saat GC berjalan, kode Anda tidak berjalan. - -Anda mungkin ingin mengetahui seberapa sering dan lama garbage collection berjalan, dan apa hasilnya. - -## Penyiapan - -Untuk proposal panduan ini, kita akan menggunakan skrip ini: - -```js -// script.mjs - -import os from 'os'; - -let len = 1_000_000; -const entries = new Set(); - -function addEntry() { - const entry = { - timestamp: Date.now(), - memory: os.freemem(), - totalMemory: os.totalmem(), - uptime: os.uptime(), - }; - - entries.add(entry); -} - -function summary() { - console.log(`Total: ${entries.size} entries`); -} - -// eksekusi -(() => { - while (len > 0) { - addEntry(); - process.stdout.write(`~~> ${len} entries to record\r`); - len--; - } - - summary(); -})(); -``` - -> Meskipun kebocoran terlihat jelas di sini, menemukan sumber kebocoran dapat menjadi merepotkan dalam konteks aplikasi dunia nyata. - -## Menjalankan dengan jejak garbage collection - -Anda dapat melihat jejak garbage collection pada keluaran konsol dari proses Anda dengan menggunakan flag `--trace-gc`. - -```console -$ node --trace-gc script.mjs -``` - -> Catatan: Anda dapat menemukan kode sumber dari [latihan][] ini di repositori Node.js Diagnostics. - -Ini akan menghasilkan output seperti ini: - -```bash -[39067:0x158008000] 2297 ms: Scavenge 117.5 (135.8) -> 102.2 (135.8) MB, 0.8 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2375 ms: Scavenge 120.0 (138.3) -> 104.7 (138.3) MB, 0.9 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2453 ms: Scavenge 122.4 (140.8) -> 107.1 (140.8) MB, 0.7 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2531 ms: Scavenge 124.9 (143.3) -> 109.6 (143.3) MB, 0.7 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2610 ms: Scavenge 127.1 (145.5) -> 111.8 (145.5) MB, 0.7 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2688 ms: Scavenge 129.6 (148.0) -> 114.2 (148.0) MB, 0.8 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2766 ms: Scavenge 132.0 (150.5) -> 116.7 (150.5) MB, 1.1 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -Total: 1000000 entries -``` - -Sulit untuk dibaca? Mungkin kita sebaiknya me-review beberapa konsep dan menjelaskan keluaran dari flag `--trace-gc`. - -### Memeriksa jejak dengan `--trace-gc` - -Flag `--trace-gc` (atau `--trace_gc`, keduanya sama saja) menghasilkan semua peristiwa garbage collection pada konsol. Komposisi setiap baris dapat dijelaskan sebagai berikut: - -```bash -[13973:0x110008000] 44 ms: Scavenge 2.4 (3.2) -> 2.0 (4.2) MB, 0.5 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure -``` - -| Token value | Interpretasi | -| ----------------------------------------------------- | --------------------------------------------------- | -| 13973 | PID (Process ID) dari proses yang sedang berjalan | -| 0x110008000 | Isolate (instance heap JS) | -| 44 ms | Waktu sejak proses dimulai dalam milidetik (ms) | -| Scavenge | Tipe / Fase dari GC | -| 2.4 | Heap yang digunakan sebelum GC dalam MB | -| (3.2) | Total heap sebelum GC dalam MB | -| 2.0 | Heap yang digunakan sesudah GC dalam MB | -| (4.2) | Total heap sesudah GC dalam MB | -| 0.5 / 0.0 ms (average mu = 1.000, current mu = 1.000) | Waktu yang dihabiskan dalam GC dalam milidetik (ms) | -| allocation failure | Alasan untuk GC | - -Kami hanya akan fokus pada dua peristiwa di sini: - -- Scavenge -- Mark-sweep - -Heap dibagi menjadi _ruang_. Di antara ini, ada ruang yang disebut "ruang baru" dan yang lain disebut "ruang lama". - -> 👉 Sebenarnya, struktur heap sedikit berbeda, tetapi kita akan tetap menggunakan versi yang lebih sederhana untuk artikel ini. Jika Anda ingin informasi lebih detail, kami mendorong Anda untuk melihat [presentasi Peter Marshall][] tentang Orinoco. - -### Scavenge - -Scavenge adalah nama algoritma yang akan melakukan pengumpulan sampah pada ruang baru. Ruang baru adalah tempat objek dibuat. Ruang baru dirancang untuk menjadi kecil dan cepat untuk pengumpulan sampah. - -Mari bayangkan sebuah skenario Scavenge: - -- we allocated `A`, `B`, `C` & `D`. - ```bash - | A | B | C | D | | - ``` -- kita ingin mengalokasikan `E` -- tidak cukup ruang, memori habis -- kemudian, koleksi (sampah) akan dipicu -- objek mati dikumpulkan -- objek yang hidup akan tetap -- dalam asumsi bahwa `B` dan `D` sudah mati - ```bash - | A | C | | - ``` -- sekarang kita dapat mengalokasikan `E` - ```bash - | A | C | E | | - ``` - -saat dua operasi Scavenge selesai, V8 akan memindahkan objek yang tidak dihapus ke old space. - -> 👉 Skenario Scavenge lengkap dapat ditemukan di [sini][] - -### Mark-sweep - -Mark-sweep digunakan untuk mengumpulkan objek dari old space. Old space adalah tempat objek yang selamat dari new space tinggal. - -Algoritma Mark-sweep terdiri dari dua fase: - -- **Mark**: Akan menandai objek yang masih hidup sebagai hitam dan objek lain sebagai putih. -- **Sweep**: Memindai objek-objek yang berwarna putih dan mengubahnya menjadi ruang yang kosong. - -> 👉 Sebenarnya langkah-langkah Mark dan Sweep sedikit lebih rumit. Silakan baca [dokumen][] ini untuk lebih detail. - -mark dan sweep algoritma - -## `--trace-gc` dalam aksi - -### Memory leak / Kebocoran memori - -Sekarang, jika Anda kembali ke jendela terminal sebelumnya: Anda akan melihat banyak peristiwa `Mark-sweep` di konsol. Kami juga melihat bahwa jumlah memori yang dikumpulkan setelah peristiwa tersebut tidak signifikan. - -Sekarang bahwa kita ahli dalam pengumpulan sampah! Apa yang bisa kita simpulkan? - -Kemungkinan kita memiliki kebocoran memori! Tapi bagaimana kita bisa yakin tentang hal itu? (Pengingat: Ini cukup jelas dalam contoh ini, tetapi bagaimana dengan aplikasi dunia nyata?) - -Tapi bagaimana kita bisa menemukan konteksnya? - -### Cara mendapatkan konteks alokasi buruk - -1. Anggaplah kita mengamati bahwa ruang tua terus meningkat. -2. Kurangi [`--max-old-space-size`][] sehingga total heap lebih dekat ke batas -3. Jalankan program sampai Anda mencapai out of memory. -4. Log yang dihasilkan menunjukkan konteks gagal. -5. Jika terjadi OOM, tingkatkan ukuran heap sekitar 10% dan ulangi beberapa kali. Jika pola yang sama diamati, itu menunjukkan kebocoran memori. -6. Jika tidak ada OOM, maka tetapkan ukuran heap menjadi nilai tersebut - Heap yang terkemas mengurangi jejak memori dan laten komputasi. - -Misalnya, cobalah jalankan `script.mjs` dengan perintah berikut: - -```bash -node --trace-gc --max-old-space-size=50 script.mjs -``` - -Anda seharusnya mengalami OOM: - -```bash -[...] -<--- Terakhir GCs yang dilakukan (dalam bentuk log) ---> -[40928:0x148008000] 509 ms: Mark-sweep 46.8 (65.8) -> 40.6 (77.3) MB, 6.4 / 0.0 ms (+ 1.4 ms in 11 steps since start of marking, biggest step 0.2 ms, walltime since start of marking 24 ms) (average mu = 0.977, current mu = 0.977) finalize incrementa[40928:0x148008000] 768 ms: Mark-sweep 56.3 (77.3) -> 47.1 (83.0) MB, 35.9 / 0.0 ms (average mu = 0.927, current mu = 0.861) allocation failure scavenge might not succeed -<--- Jejak tumpukan (stack trace) dalam JavaScript ---> -FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory [...] -``` - -Sekarang, coba jalankan perintah tersebut dengan ukuran 100mb: - -```bash -node --trace-gc --max-old-space-size=100 script.mjs -``` - -Anda seharusnya mengalami sesuatu yang serupa, satu-satunya perbedaan adalah jejak GC terakhir akan berisi ukuran heap yang lebih besar. - -```bash -<--- Last few GCs ---> -[40977:0x128008000] 2066 ms: Mark-sweep (reduce) 99.6 (102.5) -> 99.6 (102.5) MB, 46.7 / 0.0 ms (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 47 ms) (average mu = 0.154, current mu = 0.155) allocati[40977:0x128008000] 2123 ms: Mark-sweep (reduce) 99.6 (102.5) -> 99.6 (102.5) MB, 47.7 / 0.0 ms (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 48 ms) (average mu = 0.165, current mu = 0.175) allocati -``` - -> Catatan: Dalam konteks aplikasi yang sebenarnya, mungkin sulit untuk menemukan objek yang bocor di kode. Heap snapshot dapat membantu Anda menemukannya. Kunjungi [panduan yang didedikasikan untuk heap snapshot][] - -### Kelambatan - -Bagaimana cara memastikan apakah terlalu banyak koleksi sampah (garbage collections) terjadi atau menyebabkan overhead? - -1. Tinjau data jejak (trace data), khususnya waktu antara koleksi yang berurutan. -2. Tinjau data jejak, terutama sekitar waktu yang dihabiskan dalam GC. -3. Jika waktu antara dua GC lebih kecil dari waktu yang dihabiskan untuk GC, maka aplikasi tersebut mengalami kelaparan yang serius. -4. Jika waktu antara dua GC dan waktu yang dihabiskan dalam GC sangat tinggi, kemungkinan aplikasi dapat menggunakan heap yang lebih kecil. -5. Jika waktu antara dua GC jauh lebih besar dari waktu yang dihabiskan di dalam GC, maka aplikasi tersebut relatif sehat. - -## Perbaiki kebocoran - -Sekarang mari kita perbaiki kebocorannya. Alih-alih menggunakan objek untuk menyimpan entri kami, kami bisa menggunakan file. - -Mari kita ubah sedikit skrip kita: - -```js -// script-fix.mjs -import os from 'os'; -import fs from 'fs/promises'; - -let len = 1_000_000; -const fileName = `entries-${Date.now()}`; - -async function addEntry() { - const entry = { - timestamp: Date.now(), - memory: os.freemem(), - totalMemory: os.totalmem(), - uptime: os.uptime(), - }; - await fs.appendFile(fileName, JSON.stringify(entry) + '\n'); -} - -async function summary() { - const stats = await fs.lstat(fileName); - console.log(`File size ${stats.size} bytes`); -} - -// execution -(async () => { - await fs.writeFile(fileName, '----START---\n'); - while (len > 0) { - await addEntry(); - process.stdout.write(`~~> ${len} entries to record\r`); - len--; - } - - await summary(); -})(); -``` - -Menggunakan `Set` untuk menyimpan data bukanlah praktik yang buruk sama sekali; Anda hanya perlu memperhatikan jejak memori program Anda. - -> Catatan: Anda dapat menemukan kode sumber dari [latihan][] ini di repositori Diagnostik Node.js. - -Sekarang, mari kita jalankan skrip ini. - -``` -node --trace-gc script-fix.mjs -``` - -Anda harus mengamati dua hal: - -- Peristiwa mark-sweep lebih jarang muncul -- jejak memori tidak melebihi 25MB versus lebih dari 130MB dengan skrip pertama. - -Ini sangat masuk akal karena versi baru tidak terlalu menekan memori dari yang pertama. - -**Hasil**: Apa pendapat Anda tentang peningkatan skrip ini? Anda mungkin melihat bahwa versi skrip yang baru lambat. Bagaimana jika kita menggunakan `Set` lagi dan menulis isinya ke dalam a file hanya ketika memori mencapai ukuran tertentu? - -> [`getheapstatistics`][] API bisa membantu Anda. - -## Bonus: Lacak pengumpulan sampah secara terprogram - -### Menggunakan modul `v8` - -Anda mungkin ingin menghindari jejak dari seumur hidup proses Anda. Dalam hal ini, atur flag dari dalam proses. Modul `v8` memaparkan API untuk memasang flag dengan cepat. - -```js -import v8 from 'v8'; - -// mengaktifkan trace-gc -v8.setFlagsFromString('--trace-gc'); - -// menonaktifkan trace-gc -v8.setFlagsFromString('--notrace-gc'); -``` - -### Menggunakan kait kinerja - -Di Node.js, Anda dapat menggunakan [kait kinerja][] untuk melacak pengumpulan sampah. - -```js -const { PerformanceObserver } = require('perf_hooks'); - -// Buat pengamat kinerja -const obs = new PerformanceObserver(list => { - const entry = list.getEntries()[0]; - /* - Entri tersebut adalah turunan dari PerformanceEntry yang berisi - metrik dari satu peristiwa pengumpulan sampah. - Misalnya: - PerformanceEntry { - name: 'gc', - entryType: 'gc', - startTime: 2820.567669, - duration: 1.315709, - kind: 1 - } - */ -}); - -// Berlangganan notifikasi GC -obs.observe({ entryTypes: ['gc'] }); - -// Berhenti berlangganan -obs.disconnect(); -``` - -### Memeriksa jejak dengan kait kinerja - -Anda bisa mendapatkan statistik GC sebagai [PerformanceEntry][] dari callback di [PerformanceObserver][]. - -Misalnya: - -```ts -PerformanceEntry { - name: 'gc', - entryType: 'gc', - startTime: 2820.567669, - duration: 1.315709, - kind: 1 -} -``` - -| Properti | Interpretasi | -| --------- | ----------------------------------------------------------------------------------- | -| nama | Nama entri pertunjukan. | -| entryType | Jenis entri kinerja. | -| startTime | Stempel waktu milidetik beresolusi tinggi menandai waktu dimulainya Entri Performa. | -| duration | Jumlah total milidetik yang berlalu untuk entri ini. | -| kind | Jenis operasi pengumpulan sampah yang terjadi. | -| flags | Informasi tambahan tentang GC. | - -Untuk informasi lebih lanjut, Anda dapat merujuk ke [dokumentasi tentang performance hooks][performance hooks]. - -[PerformanceEntry]: https://nodejs.org/api/perf_hooks.html#perf_hooks_class_performanceentry -[PerformanceObserver]: https://nodejs.org/api/perf_hooks.html#perf_hooks_class_performanceobserver -[`--max-old-space-size`]: https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-megabytes -[kait kinerja]: https://nodejs.org/api/perf_hooks.html -[performance hooks]: https://nodejs.org/api/perf_hooks.html -[latihan]: https://github.com/nodejs/diagnostics/tree/main/documentation/memory/step3/exercise -[panduan yang didedikasikan untuk heap snapshot]: https://github.com/nodejs/nodejs.org/blob/main/locale/en/docs/guides/diagnostics/memory/using-heap-snapshot.md#how-to-find-a-memory-leak-with-heap-snapshots -[dokumen]: https://github.com/thlorenz/v8-perf/blob/master/gc.md#marking-state -[sini]: https://github.com/thlorenz/v8-perf/blob/master/gc.md#sample-scavenge-scenario -[presentasi Peter Marshall]: https://v8.dev/blog/trash-talk -[`getheapstatistics`]: https://nodejs.org/dist/latest-v16.x/docs/api/v8.html#v8getheapstatistics diff --git a/pages/id/docs/guides/diagnostics/memory/using-heap-profiler.md b/pages/id/docs/guides/diagnostics/memory/using-heap-profiler.md deleted file mode 100644 index 9f064c2566794..0000000000000 --- a/pages/id/docs/guides/diagnostics/memory/using-heap-profiler.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: Diagnostik Memori - Menggunakan Heap Profiler -layout: docs.hbs ---- - -# Menggunakan Heap Profiler - -Heap profiler berfungsi di atas V8 untuk menangkap alokasi seiring waktu. Dalam dokumen ini, kita akan membahas profil memori menggunakan: - -1. Timeline Alokasi -2. Sampling Heap Profiler - -Berbeda dengan heap dumps yang dibahas dalam panduan [Using Heap Snapshot][] ide menggunakan profil real-time adalah untuk memahami alokasi selama periode waktu tertentu. - -## Heap Profiler - Timeline Alokasi - -Heap Profiler mirip dengan Sampling Heap Profiler, kecuali ia akan melacak setiap alokasi. Ini memiliki overhead yang lebih tinggi daripada Sampling Heap Profiler sehingga tidak disarankan untuk digunakan di produksi. - -> Anda dapat menggunakan [@mmarchini/observe][] untuk memulai dan menghentikan profiler secara programatik. - -### Cara Menggunakan - -Memulai aplikasi: - -```console -node --inspect index.js -``` - -> `--inspect-brk` adalah pilihan yang lebih baik untuk skrip. - -Hubungkan ke instance dev-tools di Chrome dan kemudian: - -- Pilih tab `Memory`. -- Pilih `Allocation instrumentation timeline`. -- Mulai memprofil. - -![tutorial profiler heap langkah 1][3] - -Setelah profil heap berjalan, sangat disarankan untuk menjalankan sampel untuk mengidentifikasi masalah memori. Misalnya, jika kami melakukan profil heap pada aplikasi web, kami dapat menggunakan `Apache Benchmark` untuk memproduksi beban: - -```console -$ ab -n 1000 -c 5 http://localhost:3000 -``` - -Kemudian, tekan tombol stop saat beban selesai: - -![tutorial profiler heap langkah 2][4] - -Terakhir, lihat data snapshot: - -![tutorial profiler heap langkah 3][5] - -Periksa bagian [useful links](#useful-links) untuk informasi lebih lanjut tentang terminologi memori. - -## Sampling Heap Profiler - -Sampling Heap Profiler melacak pola alokasi memori dan ruang yang dipesan seiring waktu. Karena ini berbasis sampling, overheadnya cukup rendah untuk digunakan dalam sistem produksi. - -> Anda dapat menggunakan modul [`heap-profiler`][] untuk memulai dan menghentikan heap profiler secara programatik. - -### Cara Menggunakan - -Memuali aplikasi: - -```console -$ node --inspect index.js -``` - -> `--inspect-brk`adalah pilihan yang lebih baik untuk skrip. - -Hubungkan ke instance dev-tools dan kemudian: - -1. Pilih tab `Memory`. -2. Pilih `Allocation sampling`. -3. Mulai memprofil. - -![tutorial profiler heap 4][7] - -Buat beberapa beban dan hentikan profiler. Ini akan menghasilkan ringkasan dengan alokasi berdasarkan stacktrace mereka. Anda dapat fokus pada fungsi dengan alokasi heap yang lebih banyak, lihat contoh di bawah: - -![tutorial profiler heap 5][8] - -## Link Berguna - -- https://developer.chrome.com/docs/devtools/memory-problems/memory-101/ -- https://github.com/v8/sampling-heap-profiler -- https://developer.chrome.com/docs/devtools/memory-problems/allocation-profiler/ - -[Using Heap Snapshot]: /en/docs/guides/diagnostics/memory/using-heap-snapshot/ -[@mmarchini/observe]: https://www.npmjs.com/package/@mmarchini/observe -[3]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-1.png -[4]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-2.png -[5]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-3.png -[`heap-profiler`]: https://www.npmjs.com/package/heap-profile -[7]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-4.png -[8]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-5.png diff --git a/pages/id/docs/guides/diagnostics/memory/using-heap-snapshot.md b/pages/id/docs/guides/diagnostics/memory/using-heap-snapshot.md deleted file mode 100644 index cb68892ce0923..0000000000000 --- a/pages/id/docs/guides/diagnostics/memory/using-heap-snapshot.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: Diagnostik Memori - Menggunakan Snapshot Heap -layout: docs.hbs ---- - -# Menggunakan Snapshot Heap - -Anda dapat mengambil Snapshot Heap dari aplikasi yang sedang berjalan dan memuatnya ke [Chrome Developer Tools][] untuk memeriksa variabel tertentu atau memeriksa ukuran retainer. Anda juga dapat membandingkan beberapa snapshot untuk melihat perbedaan dari waktu ke waktu. - -## Peringatan - -Ketika membuat snapshot, semua pekerjaan lain dalam thread utama Anda akan dihentikan. Bergantung pada isi heap, ini bahkan bisa memakan waktu lebih dari satu menit. Snapshot dibangun di dalam memori, sehingga dapat menggandakan ukuran heap, sehingga mengisi seluruh memori dan kemudian menonaktifkan aplikasi. - -Jika Anda akan mengambil snapshot heap pada produksi, pastikan bahwa proses yang Anda ambil tidak akan berdampak pada ketersediaan aplikasi Anda. - -## Cara Melakukan - -### Dapatkan Snapshot Heap - -Ada beberapa cara untuk memperoleh snapshot heap: - -1. melalui inspector, -2. melalui sinyal eksternal dan flag baris perintah, -3. melalui panggilan `writeHeapSnapshot` dalam proses, -4. melalui protokol inspector. - -#### 1. Gunakan profil memori dalam inspector - -> Berfungsi di semua versi Node.js yang aktif dipelihara - -Jalankan node dengan flag`--inspect` dan buka inspector. ![buka inspector][2] - -Cara paling sederhana untuk mendapatkan Snapshot Heap adalah menghubungkan inspector ke proses Anda yang berjalan secara lokal. Kemudian pergi ke tab Memori dan ambil snapshot heap. - -![ambil snapshot memori heap][3] - -#### 2. Gunakan flag `--heapsnapshot-signal` - -> Berfungsi di v12.0.0 atau versi yang lebih baru - -Anda dapat memulai node dengan flag baris perintah yang memungkinkan bereaksi terhadap sinyal untuk membuat snapshot heap. - -``` -$ node --heapsnapshot-signal=SIGUSR2 index.js -``` - -``` -$ ps aux -USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND -node 1 5.5 6.1 787252 247004 ? Ssl 16:43 0:02 node --heapsnapshot-signal=SIGUSR2 index.js -$ kill -USR2 1 -$ ls -Heap.20190718.133405.15554.0.001.heapsnapshot -``` - -Untuk detailnya, lihat dokumentasi terbaru dari [flag heapsnapshot-signal][]. - -#### 3. Gunakan fungsi `writeHeapSnapshot` - -> Berfungsi di v11.13.0 atau versi yang lebih baru, dapat bekerja pada versi yang lebih lama dengan paket [heapdump][] - -Jika Anda membutuhkan snapshot dari proses yang sedang berjalan, seperti aplikasi yang berjalan pada server, Anda dapat mengimplementasikannya menggunakan: - -```js -require('v8').writeHeapSnapshot(); -``` - -Periksa [dokumen `writeHeapSnapshot`][] untuk opsi nama file. - -Anda perlu memiliki cara untuk memanggilnya tanpa menghentikan proses, jadi disarankan untuk memanggilnya dalam HTTP handler atau sebagai reaksi terhadap sinyal dari sistem operasi. Hati-hati untuk tidak mengekspos titik akhir HTTP yang memicu snapshot. Tidak boleh memungkinkan siapa pun untuk mengaksesnya. - -Untuk versi Node.js sebelum v11.13.0, Anda dapat menggunakan paket [heapdump][]. - -#### 4. Picu Heap Snapshot menggunakan protokol inspektor - -Protokol inspektor dapat digunakan untuk memicu Heap Snapshot dari luar proses. - -Tidak perlu menjalankan inspektor aktual dari Chromium untuk menggunakan API. - -Berikut contoh pemicu snapshot pada bash, menggunakan `websocat` dan `jq`: - -```bash -#!/bin/bash -set -e - -kill -USR1 "$1" -rm -f fifo out -mkfifo ./fifo -websocat -B 10000000000 "$(curl -s http://localhost:9229/json | jq -r '.[0].webSocketDebuggerUrl')" < ./fifo > ./out & -exec 3>./fifo -echo '{"method": "HeapProfiler.enable", "id": 1}' > ./fifo -echo '{"method": "HeapProfiler.takeHeapSnapshot", "id": 2}' > ./fifo -while jq -e "[.id != 2, .result != {}] | all" < <(tail -n 1 ./out); do - sleep 1s - echo "Capturing Heap Snapshot..." -done - -echo -n "" > ./out.heapsnapshot -while read -r line; do - f="$(echo "$line" | jq -r '.params.chunk')" - echo -n "$f" >> out.heapsnapshot - i=$((i+1)) -done < <(cat out | tail -n +2 | head -n -1) - -exec 3>&- -``` - -Berikut adalah daftar alat profil memori yang dapat digunakan dengan protokol inspector: - -- [OpenProfiling untuk Node.js][openprofiling] - -## Cara menemukan kebocoran memori dengan Heap Snapshots - -Anda dapat menemukan kebocoran memori dengan membandingkan dua snapshot heap. Penting untuk memastikan bahwa perbedaan snapshot tidak mengandung informasi yang tidak perlu. Langkah-langkah berikut harus menghasilkan perbedaan yang bersih antara snapshot. - -1. Biarkan proses memuat semua sumber dan selesai bootstrapping. Ini seharusnya hanya memakan waktu beberapa detik. -2. Mulai menggunakan fungsionalitas yang Anda curigai bocor memori. Kemungkinan besar ini membuat beberapa alokasi awal yang bukan bocoran. -3. Ambil satu snapshot heap. -4. Lanjutkan menggunakan fungsionalitas untuk sementara waktu, lebih baik tanpa menjalankan apa pun di antara. -5. Ambil snapshot heap lainnya. Perbedaan antara keduanya seharusnya sebagian besar berisi apa yang bocor. -6. Buka alat pengembang Chromium/Chrome dan pergi ke tab _Memory_ -7. Muat file snapshot lama terlebih dahulu, dan yang lebih baru satu detik. ![Muat tombol di alat][8] -8. Pilih snapshot yang lebih baru dan alihkan mode di dropdown di bagian atas dari _Ringkasan_ dengan _Perbandingan_. ![Comparison dropdown][9] -9. Cari delta positif besar dan jelajahi referensi yang menyebabkannya di panel bawah. - -Anda dapat berlatih menangkap snapshot heap dan menemukan kebocoran memori dengan [latihan snapshot heap ini][heapsnapshot exercise]. - -[Chrome Developer Tools]: https://developer.chrome.com/docs/devtools/ -[2]: /static/images/docs/guides/diagnostics/tools.png -[3]: /static/images/docs/guides/diagnostics/snapshot.png -[flag heapsnapshot-signal]: https://nodejs.org/api/cli.html#--heapsnapshot-signalsignal -[heapdump]: https://www.npmjs.com/package/heapdump -[dokumen `writeHeapSnapshot`]: https://nodejs.org/api/v8.html#v8_v8_writeheapsnapshot_filename -[openprofiling]: https://github.com/vmarchaud/openprofiling-node -[8]: /static/images/docs/guides/diagnostics/load-snapshot.png -[9]: /static/images/docs/guides/diagnostics/compare.png -[heapsnapshot exercise]: https://github.com/naugtur/node-example-heapdump diff --git a/pages/id/docs/guides/diagnostics/poor-performance/index.md b/pages/id/docs/guides/diagnostics/poor-performance/index.md deleted file mode 100644 index 7193506202bac..0000000000000 --- a/pages/id/docs/guides/diagnostics/poor-performance/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Kinerja Buruk - Diagnostik -layout: docs.hbs ---- - -# Kinerja Buruk - -Dalam dokumen ini Anda dapat mempelajari tentang cara memprofil proses Node.js. - -- [Kinerja Buruk](#poor-performance) - - [Aplikasi saya memiliki kinerja buruk](#my-application-has-a-poor-performance) - - [Gejala](#symptoms) - - [Debug](#debugging) - -## Aplikasi saya memiliki kinerja buruk - -### Gejala - -Latensi aplikasi saya tinggi dan saya sudah mengonfirmasi bahwa bottleneck bukanlah ketergantungan saya seperti database dan layanan downstream. Jadi saya curiga bahwa aplikasi saya menghabiskan waktu yang signifikan untuk menjalankan kode atau memproses informasi. - -Anda puas dengan kinerja aplikasi Anda secara umum tetapi ingin memahami bagian mana dari aplikasi Anda yang dapat ditingkatkan untuk berjalan lebih cepat atau lebih efisien. Ini dapat berguna ketika kita ingin meningkatkan pengalaman pengguna atau menghemat biaya komputasi. - -### Debug - -Dalam kasus penggunaan ini, kita tertarik dengan potongan kode yang menggunakan lebih banyak siklus CPU dari yang lain. Ketika kita melakukannya secara lokal, biasanya kita mencoba mengoptimalkan kode kita. - -Dokumen ini menyediakan dua cara sederhana untuk memprofil aplikasi Node.js: - -- [Menggunakan Profiler Sampling V8](https://nodejs.org/en/docs/guides/simple-profiling/) -- [Menggunakan Linux Perf](/en/docs/guides/diagnostics/poor-performance/using-linux-perf) diff --git a/pages/id/docs/guides/diagnostics/poor-performance/using-linux-perf.md b/pages/id/docs/guides/diagnostics/poor-performance/using-linux-perf.md deleted file mode 100644 index fc26484eeed8c..0000000000000 --- a/pages/id/docs/guides/diagnostics/poor-performance/using-linux-perf.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Kinerja Buruk - Menggunakan Linux Perf -layout: docs.hbs ---- - -# Menggunakan Linux Perf - -[Linux Perf](https://perf.wiki.kernel.org/index.php/Main_Page) menyediakan profil CPU level rendah dengan frame JavaScript, native, dan OS level. - -**Penting**: tutorial ini hanya tersedia di Linux. - -## Bagaimana Caranya - -Linux Perf biasanya tersedia melalui paket `linux-tools-common`. Melalui opsi `--perf-basic-prof` atau `--perf-basic-prof-only-functions` kita dapat memulai aplikasi Node.js dengan mendukung _perf_events_. - -`--perf-basic-prof` selalu akan menulis ke file (/tmp/perf-PID.map), yang dapat menyebabkan pertumbuhan disk yang tak terbatas. Jika itu menjadi masalah, gunakan modul: [linux-perf](https://www.npmjs.com/package/linux-perf) atau `--perf-basic-prof-only-functions`. - -Perbedaan utama antara keduanya adalah bahwa `--perf-basic-prof-only-functions` menghasilkan keluaran yang lebih sedikit, itu adalah opsi yang layak untuk profil produksi. - -```console -# Jalankan aplikasi dan dapatkan PID-nya -$ node --perf-basic-prof-only-functions index.js & -[1] 3870 -``` - -Kemudian record event berdasarkan frekuensi yang diinginkan: - -```console -$ sudo perf record -F 99 -p 3870 -g -``` - -Dalam fase ini, Anda mungkin ingin menggunakan tes beban pada aplikasi untuk menghasilkan lebih banyak rekaman untuk analisis yang dapat diandalkan. Ketika pekerjaan selesai, tutup proses perf dengan mengirimkan SIGINT (Ctrl-C) ke perintah. - -`perf` akan menghasilkan file di dalam folder `/tmp`, biasanya disebut `/tmp/perf-PID.map` (dalam contoh di atas: `/tmp/perf-3870.map`) yang berisi jejak untuk setiap fungsi yang dipanggil. - -Untuk menggabungkan hasil tersebut dalam file tertentu, jalankan: - -```console -$ sudo perf script > perfs.out -``` - -```console -$ cat ./perfs.out -node 3870 25147.878454: 1 cycles: - ffffffffb5878b06 native_write_msr+0x6 ([kernel.kallsyms]) - ffffffffb580d9d5 intel_tfa_pmu_enable_all+0x35 ([kernel.kallsyms]) - ffffffffb5807ac8 x86_pmu_enable+0x118 ([kernel.kallsyms]) - ffffffffb5a0a93d perf_pmu_enable.part.0+0xd ([kernel.kallsyms]) - ffffffffb5a10c06 __perf_event_task_sched_in+0x186 ([kernel.kallsyms]) - ffffffffb58d3e1d finish_task_switch+0xfd ([kernel.kallsyms]) - ffffffffb62d46fb __sched_text_start+0x2eb ([kernel.kallsyms]) - ffffffffb62d4b92 schedule+0x42 ([kernel.kallsyms]) - ffffffffb62d87a9 schedule_hrtimeout_range_clock+0xf9 ([kernel.kallsyms]) - ffffffffb62d87d3 schedule_hrtimeout_range+0x13 ([kernel.kallsyms]) - ffffffffb5b35980 ep_poll+0x400 ([kernel.kallsyms]) - ffffffffb5b35a88 do_epoll_wait+0xb8 ([kernel.kallsyms]) - ffffffffb5b35abe __x64_sys_epoll_wait+0x1e ([kernel.kallsyms]) - ffffffffb58044c7 do_syscall_64+0x57 ([kernel.kallsyms]) - ffffffffb640008c entry_SYSCALL_64_after_hwframe+0x44 ([kernel.kallsyms]) -.... -``` - -Output mentah dari perf mungkin agak sulit dipahami sehingga biasanya file mentah ini digunakan untuk menghasilkan flamegraph untuk visualisasi yang lebih baik. - -![Contoh nodejs grafik flame](https://user-images.githubusercontent.com/26234614/129488674-8fc80fd5-549e-4a80-8ce2-2ba6be20f8e8.png) - -Untuk menghasilkan flamegraph dari hasil ini, ikuti [tutorial ini](https://nodejs.org/en/docs/guides/diagnostics-flamegraph/#create-a-flame-graph-with-system-perf-tools) from step 6. - -Karena output dari `perf` bukan merupakan alat yang khusus untuk Node.js, maka mungkin ada masalah dengan cara kode JavaScript dioptimalkan di Node.js. Lihat [masalah output perf](https://nodejs.org/en/docs/guides/diagnostics-flamegraph/#perf-output-issues) untuk referensi lebih lanjut. - -## Tautan Berguna - -- https://nodejs.org/en/docs/guides/diagnostics-flamegraph/ -- https://www.brendangregg.com/blog/2014-09-17/node-flame-graphs-on-linux.html -- https://perf.wiki.kernel.org/index.php/Main_Page -- https://blog.rafaelgss.com.br/node-cpu-profiler diff --git a/pages/id/docs/guides/domain-postmortem.md b/pages/id/docs/guides/domain-postmortem.md deleted file mode 100644 index 6dbfdf32b7bf4..0000000000000 --- a/pages/id/docs/guides/domain-postmortem.md +++ /dev/null @@ -1,365 +0,0 @@ ---- -title: Postmortem Modul Domain -layout: docs.hbs ---- - -# Postmortem Modul Domain - -## Masalah Kegunaan - -### Perilaku Tersirat - -Mungkin bagi pengembang untuk membuat domain baru dan kemudian menjalankannya `domain.enter()`. Yang kemudian bertindak sebagai penangkap semua untuk pengecualian apa pun di masa depan yang tidak bisa diamati oleh pelempar. Mengizinkan penulis modul untuk mencegat pengecualian kode yang tidak terkait dalam modul yang berbeda. Mencegah pencetus kode dari mengetahui tentang pengecualiannya sendiri. - -Berikut adalah contoh bagaimana satu modul yang ditautkan secara tidak langsung dapat memengaruhi modul lainnya: - -```js -// module a.js -const b = require('./b'); -const c = require('./c'); - -// module b.js -const d = require('domain').create(); -d.on('error', () => { - /* silence everything */ -}); -d.enter(); - -// module c.js -const dep = require('some-dep'); -dep.method(); // Uh-oh! This method doesn't actually exist. -``` - -Karena modul `b` memasuki domain tetapi tidak pernah keluar, pengecualian yang tidak tertangkap akan ditelan. Meninggalkan modul `c` dalam kegelapan mengapa modul itu tidak berjalan secara keseluruhan naskah. Meninggalkan `module.exports` yang berpotensi terisi sebagian. Melakukan ini tidak sama dengan mendengarkan `'uncaughtException'`. Seperti yang terakhir adalah secara eksplisit dimaksudkan untuk menangkap kesalahan secara global. Masalah lainnya adalah bahwa domain adalah diproses sebelum penangan `'uncaughtException'`, dan mencegahnya dari berlari. - -Masalah lainnya adalah domain merutekan kesalahan secara otomatis jika tidak ada `'error'` handler diatur pada emitor acara. Tidak ada mekanisme keikutsertaan untuk ini, dan secara otomatis menyebar ke seluruh rantai asinkron. Ini mungkin tampak berguna pada awalnya, tetapi sekali panggilan asinkron adalah dua atau lebih modul yang dalam dan salah satunya tidak menyertakan penangan kesalahan yang akan dibuat oleh pembuat domain tiba-tiba menangkap pengecualian yang tidak terduga, dan pengecualian pelempar akan pergi tidak disadari oleh penulis. - -Berikut ini adalah contoh sederhana tentang bagaimana handler `'error'` yang hilang memungkinkan domain aktif untuk membajak kesalahan: - -```js -const domain = require('domain'); -const net = require('net'); -const d = domain.create(); -d.on('error', err => console.error(err.message)); - -d.run(() => - net - .createServer(c => { - c.end(); - c.write('bye'); - }) - .listen(8000) -); -``` - -Bahkan menghapus koneksi secara manual melalui `d.remove(c)` tidak mencegah kesalahan koneksi agar tidak disadap secara otomatis. - -Kegagalan yang mengganggu baik perutean kesalahan dan penanganan pengecualian adalah: inkonsistensi dalam bagaimana kesalahan digelembungkan. Berikut ini adalah contoh caranya domain bersarang akan dan tidak akan menggelembungkan pengecualian berdasarkan waktu terjadinya: - -```js -const domain = require('domain'); -const net = require('net'); -const d = domain.create(); -d.on('error', () => console.error('d intercepted an error')); - -d.run(() => { - const server = net - .createServer(c => { - const e = domain.create(); // No 'error' handler being set. - e.run(() => { - // This will not be caught by d's error handler. - setImmediate(() => { - throw new Error('thrown from setImmediate'); - }); - // Though this one will bubble to d's error handler. - throw new Error('immediately thrown'); - }); - }) - .listen(8080); -}); -``` - -Mungkin diharapkan bahwa domain bersarang selalu tetap bersarang, dan akan selalu menyebarkan pengecualian ke tumpukan domain. Atau pengecualian itu tidak akan pernah gelembung secara otomatis. Sayangnya kedua situasi ini terjadi, yang mengarah ke perilaku yang berpotensi membingungkan yang bahkan cenderung sulit untuk di-debug konflik waktu. - -### Kesenjangan API - -Sementara API berdasarkan penggunaan `EventEmitter` dapat menggunakan `bind()` dan gaya errback callback dapat menggunakan `intercept()`, API alternatif yang secara implisit mengikat ke domain aktif harus dieksekusi di dalam `run()`. Artinya jika penulis modul ingin mendukung domain menggunakan mekanisme alternatif dari yang disebutkan mereka harus secara manual mengimplementasikan dukungan domain itu sendiri. Alih-alih bisa memanfaatkan mekanisme implisit yang sudah ada. - -### Propagasi Kesalahan - -Menyebarkan kesalahan di seluruh domain bersarang tidak langsung, jika bahkan mungkin. Dokumentasi yang ada menunjukkan contoh sederhana tentang cara `close()` dan `http` server jika ada kesalahan pada handler permintaan. Apa yang tidak jelaskan adalah cara menutup server jika penangan permintaan membuat yang lain contoh domain untuk permintaan asinkron lainnya. Menggunakan yang berikut ini sebagai sederhana contoh kegagalan propagasi kesalahan: - -```js -const d1 = domain.create(); -d1.foo = true; // custom member to make more visible in console -d1.on('error', er => { - /* handle error */ -}); - -d1.run(() => - setTimeout(() => { - const d2 = domain.create(); - d2.bar = 43; - d2.on('error', er => console.error(er.message, domain._stack)); - d2.run(() => { - setTimeout(() => { - setTimeout(() => { - throw new Error('outer'); - }); - throw new Error('inner'); - }); - }); - }) -); -``` - -Bahkan jika instance domain digunakan untuk penyimpanan lokal, jadi akses ke sumber daya tersedia, masih tidak ada cara untuk mengizinkan kesalahan untuk melanjutkan propagasi dari `d2` kembali ke `d1`. Inspeksi cepat dapat memberi tahu kami yang hanya melempar dari domain `d2`'s handler `'error'` akan memungkinkan `d1` untuk kemudian tangkap pengecualian dan jalankan penangan kesalahannya sendiri. Padahal itu bukan kasus. Setelah memeriksa `domain._stack` Anda akan melihat bahwa hanya tumpukan berisi `d2`. - -Ini mungkin dianggap sebagai kegagalan API, tetapi meskipun itu beroperasi dalam hal ini cara masih ada masalah transmisi fakta bahwa cabang di eksekusi asinkron telah gagal, dan bahwa semua operasi lebih lanjut di dalamnya cabang harus dihentikan. Dalam contoh penangan permintaan http, jika kita mematikan beberapa permintaan asinkron dan masing-masing kemudian data `write()` kembali ke klien lebih banyak kesalahan akan muncul dari mencoba `write()` ke closed menangani. Lebih lanjut tentang ini di _Resource Cleanup on Exception_. - -### Pembersihan Sumber Daya pada Pengecualian - -Skrip berikut berisi contoh yang lebih kompleks dari pembersihan yang benar di pohon ketergantungan sumber daya kecil dalam kasus pengecualian terjadi di a koneksi yang diberikan atau salah satu dependensinya. Memecah skrip menjadi operasi dasar: - -```js -'use strict'; - -const domain = require('domain'); -const EE = require('events'); -const fs = require('fs'); -const net = require('net'); -const util = require('util'); -const print = process._rawDebug; - -const pipeList = []; -const FILENAME = '/tmp/tmp.tmp'; -const PIPENAME = '/tmp/node-domain-example-'; -const FILESIZE = 1024; -let uid = 0; - -// Setting up temporary resources -const buf = Buffer.alloc(FILESIZE); -for (let i = 0; i < buf.length; i++) buf[i] = ((Math.random() * 1e3) % 78) + 48; // Basic ASCII -fs.writeFileSync(FILENAME, buf); - -function ConnectionResource(c) { - EE.call(this); - this._connection = c; - this._alive = true; - this._domain = domain.create(); - this._id = Math.random().toString(32).substr(2).substr(0, 8) + ++uid; - - this._domain.add(c); - this._domain.on('error', () => { - this._alive = false; - }); -} -util.inherits(ConnectionResource, EE); - -ConnectionResource.prototype.end = function end(chunk) { - this._alive = false; - this._connection.end(chunk); - this.emit('end'); -}; - -ConnectionResource.prototype.isAlive = function isAlive() { - return this._alive; -}; - -ConnectionResource.prototype.id = function id() { - return this._id; -}; - -ConnectionResource.prototype.write = function write(chunk) { - this.emit('data', chunk); - return this._connection.write(chunk); -}; - -// Example begin -net - .createServer(c => { - const cr = new ConnectionResource(c); - - const d1 = domain.create(); - fs.open( - FILENAME, - 'r', - d1.intercept(fd => { - streamInParts(fd, cr, 0); - }) - ); - - pipeData(cr); - - c.on('close', () => cr.end()); - }) - .listen(8080); - -function streamInParts(fd, cr, pos) { - const d2 = domain.create(); - const alive = true; - d2.on('error', er => { - print('d2 error:', er.message); - cr.end(); - }); - fs.read( - fd, - Buffer.alloc(10), - 0, - 10, - pos, - d2.intercept((bRead, buf) => { - if (!cr.isAlive()) { - return fs.close(fd); - } - if (cr._connection.bytesWritten < FILESIZE) { - // Documentation says callback is optional, but doesn't mention that if - // the write fails an exception will be thrown. - const goodtogo = cr.write(buf); - if (goodtogo) { - setTimeout(() => streamInParts(fd, cr, pos + bRead), 1000); - } else { - cr._connection.once('drain', () => - streamInParts(fd, cr, pos + bRead) - ); - } - return; - } - cr.end(buf); - fs.close(fd); - }) - ); -} - -function pipeData(cr) { - const pname = PIPENAME + cr.id(); - const ps = net.createServer(); - const d3 = domain.create(); - const connectionList = []; - d3.on('error', er => { - print('d3 error:', er.message); - cr.end(); - }); - d3.add(ps); - ps.on('connection', conn => { - connectionList.push(conn); - conn.on('data', () => {}); // don't care about incoming data. - conn.on('close', () => { - connectionList.splice(connectionList.indexOf(conn), 1); - }); - }); - cr.on('data', chunk => { - for (let i = 0; i < connectionList.length; i++) { - connectionList[i].write(chunk); - } - }); - cr.on('end', () => { - for (let i = 0; i < connectionList.length; i++) { - connectionList[i].end(); - } - ps.close(); - }); - pipeList.push(pname); - ps.listen(pname); -} - -process.on('SIGINT', () => process.exit()); -process.on('exit', () => { - try { - for (let i = 0; i < pipeList.length; i++) { - fs.unlinkSync(pipeList[i]); - } - fs.unlinkSync(FILENAME); - } catch (e) {} -}); -``` - -- Ketika koneksi baru terjadi, secara bersamaan: - - Buka file di sistem file - - Buka Pipa ke soket unik -- Baca sepotong file secara tidak sinkron -- Tulis potongan ke koneksi TCP dan soket pendengar apa pun -- Jika salah satu dari sumber daya ini error, beri tahu semua sumber daya terlampir lainnya bahwa mereka perlu membersihkan dan mematikan - -Seperti yang dapat kita lihat dari contoh ini, lebih banyak yang harus dilakukan untuk membersihkan dengan benar sumber daya ketika sesuatu gagal daripada apa yang dapat dilakukan secara ketat melalui API domain. Semua yang ditawarkan domain adalah mekanisme agregasi pengecualian. Bahkan kemampuan yang berpotensi berguna untuk menyebarkan data dengan domain dengan mudah dilawan, dalam contoh ini, dengan melewatkan sumber daya yang dibutuhkan sebagai fungsi argumen. - -Satu domain masalah yang diabadikan adalah kesederhanaan yang seharusnya bisa melanjutkan eksekusi, bertentangan dengan apa yang dinyatakan dokumentasi, dari aplikasi meskipun pengecualian tak terduga. Contoh ini menunjukkan kekeliruan di balik gagasan itu. - -Mencoba pembersihan sumber daya yang tepat pada pengecualian tak terduga menjadi lebih kompleks sebagai aplikasi itu sendiri tumbuh dalam kompleksitas. Contoh ini hanya memiliki 3 dasar sumber daya dalam permainan, dan semuanya dengan jalur ketergantungan yang jelas. Jika aplikasi menggunakan sesuatu seperti sumber daya bersama atau sumber daya menggunakan kembali kemampuan untuk membersihkan, dan menguji dengan benar bahwa pembersihan telah dilakukan, tumbuh pesat. - -Pada akhirnya, dalam hal penanganan kesalahan, domain tidak lebih dari pengendali `'uncaughtException'` yang dimuliakan. Kecuali dengan lebih implisit dan perilaku yang tidak dapat diamati oleh pihak ketiga. - -### Propagasi Sumber Daya - -Kasus penggunaan lain untuk domain adalah menggunakannya untuk menyebarkan data di sepanjang asinkron jalur data. Satu hal yang bermasalah adalah ambiguitas kapan harus mengharapkan domain yang benar ketika ada beberapa di tumpukan (yang harus diasumsikan jika tumpukan async berfungsi dengan modul lain). Juga konflik antara makhluk dapat bergantung pada domain untuk penanganan kesalahan sementara juga tersedia untuk mengambil data yang diperlukan. - -Berikut ini adalah contoh yang terlibat yang menunjukkan kegagalan menggunakan domain untuk: menyebarkan data di sepanjang tumpukan asinkron: - -```js -const domain = require('domain'); -const net = require('net'); - -const server = net - .createServer(c => { - // Use a domain to propagate data across events within the - // connection so that we don't have to pass arguments - // everywhere. - const d = domain.create(); - d.data = { connection: c }; - d.add(c); - // Mock class that does some useless async data transformation - // for demonstration purposes. - const ds = new DataStream(dataTransformed); - c.on('data', chunk => ds.data(chunk)); - }) - .listen(8080, () => console.log('listening on 8080')); - -function dataTransformed(chunk) { - // FAIL! Because the DataStream instance also created a - // domain we have now lost the active domain we had - // hoped to use. - domain.active.data.connection.write(chunk); -} - -function DataStream(cb) { - this.cb = cb; - // DataStream wants to use domains for data propagation too! - // Unfortunately this will conflict with any domain that - // already exists. - this.domain = domain.create(); - this.domain.data = { inst: this }; -} - -DataStream.prototype.data = function data(chunk) { - // This code is self contained, but pretend it's a complex - // operation that crosses at least one other module. So - // passing along "this", etc., is not easy. - this.domain.run(() => { - // Simulate an async operation that does the data transform. - setImmediate(() => { - for (let i = 0; i < chunk.length; i++) - chunk[i] = ((chunk[i] + Math.random() * 100) % 96) + 33; - // Grab the instance from the active domain and use that - // to call the user's callback. - const self = domain.active.data.inst; - self.cb(chunk); - }); - }); -}; -``` - -Di atas menunjukkan bahwa sulit untuk memiliki lebih dari satu API asinkron mencoba menggunakan domain untuk menyebarkan data. Contoh ini mungkin bisa diperbaiki dengan menetapkan `parent: domain.active` di konstruktor `DataStream`. Kemudian memulihkannya melalui `domain.active = domain.active.data.parent` tepat sebelum panggilan balik pengguna dipanggil. Juga instantiasi `DataStream` di `'connection'` callback harus dijalankan di dalam `d.run()`, bukan hanya menggunakan `d.add(c)`, jika tidak, tidak akan ada domain aktif. - -Singkatnya, untuk memiliki doa penggunaan kesempatan ini harus benar-benar mematuhi seperangkat pedoman yang akan sulit untuk ditegakkan atau diuji. - -## Masalah perfoma - -Penghalang yang signifikan dari penggunaan domain adalah overhead. Menggunakan node's benchmark http bawaan, `http_simple.js`, tanpa domain yang dapat ditanganinya 22.000 permintaan/detik. Sedangkan jika dijalankan dengan `NODE_USE_DOMAINS=1` itu jumlahnya turun menjadi di bawah 17.000 permintaan/detik. Dalam hal ini hanya ada satu domain global. Jika kita mengedit benchmark maka http request callback membuat performa instans domain baru turun lebih jauh ke 15.000 permintaan/detik. - -Meskipun ini mungkin tidak akan memengaruhi server yang hanya melayani beberapa ratus atau bahkan seribu permintaan per detik, jumlah overhead berbanding lurus dengan jumlah permintaan asinkron yang dibuat. Jadi jika satu koneksi perlu terhubung ke beberapa layanan lain, semuanya akan berkontribusi pada keseluruhan latensi pengiriman produk akhir ke klien. - -Menggunakan `AsyncWrap` dan melacak berapa kali `init`/`pre`/`post`/`destroy` dipanggil dalam benchmark yang kami temukan bahwa jumlah semua peristiwa yang disebut lebih dari 170.000 kali per detik. Ini berarti bahkan menambahkan overhead 1 mikrodetik per panggilan untuk semua jenis pengaturan atau pembongkaran akan mengakibatkan hilangnya kinerja 17%. Memang, ini untuk yang dioptimalkan skenario tolok ukur, tetapi saya yakin ini menunjukkan perlunya a mekanisme seperti domain menjadi semurah mungkin untuk dijalankan. - -## Melihat ke depan - -Modul domain telah tidak digunakan lagi sejak Desember 2014, tetapi belum dihapus karena node tidak menawarkan fungsionalitas alternatif saat ini. Mulai dari tulisan ini ada pekerjaan yang sedang berlangsung membangun `AsyncWrap` API dan a proposal untuk Zona yang sedang disiapkan untuk TC39. Pada saat seperti itu ada yang cocok fungsi untuk menggantikan domain itu akan menjalani siklus penghentian penuh dan akhirnya akan dihapus dari inti. diff --git a/pages/id/docs/guides/dont-block-the-event-loop.md b/pages/id/docs/guides/dont-block-the-event-loop.md deleted file mode 100644 index 0e264f9cee239..0000000000000 --- a/pages/id/docs/guides/dont-block-the-event-loop.md +++ /dev/null @@ -1,414 +0,0 @@ ---- -title: Jangan Blokir Event Loop (atau Worker Pool) -layout: docs.hbs ---- - -# Jangan Blokir Event Loop (atau Worker Pool) - -## Haruskah Anda membaca panduan ini? - -Jika Anda menulis sesuatu yang lebih rumit daripada skrip baris perintah singkat, membaca ini akan membantu Anda menulis aplikasi dengan kinerja lebih tinggi dan lebih aman. - -Dokumen ini ditulis dengan mempertimbangkan server Node.js, tetapi konsepnya juga berlaku untuk aplikasi Node.js yang kompleks. Di mana detail spesifik OS bervariasi, dokumen ini berpusat pada Linux. - -## Ringkasan - -Node.js menjalankan kode JavaScript di Event Loop (inisialisasi dan callback), dan menawarkan Worker Pool untuk menangani tugas-tugas mahal seperti file I/O. Skala Node.js baik, terkadang lebih baik daripada pendekatan kelas berat seperti Apache. Rahasia skalabilitas Node.js adalah ia menggunakan sejumlah kecil utas untuk menangani banyak klien. Jika Node.js dapat bekerja dengan lebih sedikit utas, maka Node.js dapat menghabiskan lebih banyak waktu dan memori sistem Anda untuk bekerja pada klien daripada membayar overhead ruang dan waktu untuk utas (memori, pengalihan konteks). Tetapi karena Node.js hanya memiliki beberapa utas, Anda harus menyusun aplikasi Anda untuk menggunakannya dengan bijak. - -Berikut adalah aturan praktis yang baik untuk menjaga kecepatan server Node.js Anda: _Node.js cepat ketika pekerjaan yang terkait dengan setiap klien pada waktu tertentu adalah "kecil"_. - -Ini berlaku untuk callback di Event Loop dan tugas di Worker Pool. - -## Mengapa saya harus menghindari pemblokiran Event Loop dan Worker Pool? - -Node.js menggunakan sejumlah kecil utas untuk menangani banyak klien. Di Node.js ada dua jenis utas: satu Loop Peristiwa (alias loop utama, utas utama, utas acara, dll.), dan kumpulan `k` Pekerja di Kumpulan Pekerja (alias threadpool). - -Jika utas membutuhkan waktu lama untuk menjalankan panggilan balik (Loop Peristiwa) atau tugas (Pekerja), kami menyebutnya "diblokir". Sementara utas diblokir bekerja atas nama satu klien, itu tidak dapat menangani permintaan dari klien lain. Ini memberikan dua motivasi untuk memblokir baik Event Loop maupun Worker Pool: - -1. Kinerja: Jika Anda secara teratur melakukan aktivitas kelas berat pada kedua jenis utas, _throughput_ (permintaan/detik) server Anda akan terganggu. -2. Keamanan: Jika mungkin untuk input tertentu salah satu utas Anda mungkin diblokir, klien jahat dapat mengirimkan "masukan jahat" ini, membuat utas Anda diblokir, dan mencegahnya bekerja pada klien lain. Ini akan menjadi serangan [Denial of Service](https://en.wikipedia.org/wiki/Denial-of-service_attack). - -## Ulasan singkat tentang Node - -Node.js menggunakan Event-Driven Architecture: ia memiliki Event Loop untuk orkestrasi dan Worker Pool untuk tugas-tugas mahal. - -### Kode apa yang berjalan di Event Loop? - -Saat dimulai, aplikasi Node.js pertama-tama menyelesaikan fase inisialisasi, `memerlukan` modul dan mendaftarkan callback untuk event. Aplikasi Node.js kemudian masuk ke Event Loop, menanggapi permintaan klien yang masuk dengan mengeksekusi callback yang sesuai. Callback ini dijalankan secara sinkron, dan dapat mendaftarkan permintaan asinkron untuk melanjutkan pemrosesan setelah selesai. Callback untuk permintaan asinkron ini juga akan dijalankan di Event Loop. - -Loop Peristiwa juga akan memenuhi permintaan asinkron non-pemblokiran yang dibuat oleh panggilan baliknya, mis., I/O jaringan. - -Singkatnya, Event Loop mengeksekusi callback JavaScript yang terdaftar untuk event, dan juga bertanggung jawab untuk memenuhi permintaan asinkron yang tidak memblokir seperti I/O jaringan. - -### Kode apa yang berjalan di Worker Pool? - -Kumpulan Pekerja Node.js diimplementasikan di libuv ([docs](http://docs.libuv.org/en/v1.x/threadpool.html)), yang memperlihatkan API pengiriman tugas umum. - -Node.js menggunakan Worker Pool untuk menangani tugas-tugas "mahal". Ini termasuk I/O yang sistem operasinya tidak menyediakan versi non-pemblokiran, serta tugas-tugas yang secara khusus menggunakan CPU. - -Ini adalah API modul Node.js yang menggunakan Worker Pool ini: - -1. I/O-intensif - 1. [DNS](https://nodejs.org/api/dns.html): `dns.lookup()`, `dns.lookupService()`. - 2. [Sistem File](https://nodejs.org/api/fs.html#fs_threadpool_usage): Semua API sistem file kecuali `fs.FSWatcher()` dan yang secara eksplisit sinkron menggunakan threadpool libuv. -2. CPU-intensif - 1. [Crypto](https://nodejs.org/api/crypto.html): `crypto.pbkdf2()`, `crypto.scrypt()`, `crypto.randomBytes()`, `crypto.randomFill( )`, `crypto.generateKeyPair()`. - 2. [Zlib](https://nodejs.org/api/zlib.html#zlib_threadpool_usage): Semua zlib API kecuali yang secara eksplisit sinkron menggunakan threadpool libuv. - -Di banyak aplikasi Node.js, API ini adalah satu-satunya sumber tugas untuk Worker Pool. Aplikasi dan modul yang menggunakan [add-on C++](https://nodejs.org/api/addons.html) dapat mengirimkan tugas lain ke Worker Pool. - -Demi kelengkapan, kami mencatat bahwa ketika Anda memanggil salah satu API ini dari callback di Event Loop, Event Loop membayar beberapa biaya penyiapan kecil saat memasuki binding C++ Node.js untuk API tersebut dan mengirimkan tugas ke kolam pekerja. Biaya ini dapat diabaikan dibandingkan dengan biaya keseluruhan tugas, itulah sebabnya Event Loop membongkarnya. Saat mengirimkan salah satu tugas ini ke Worker Pool, Node.js memberikan pointer ke fungsi C++ yang sesuai di binding C++ Node.js. - -### Bagaimana Node.js memutuskan kode apa yang akan dijalankan selanjutnya? - -Secara abstrak, Event Loop dan Worker Pool masing-masing mempertahankan antrian untuk event yang tertunda dan tugas yang tertunda. - -Sebenarnya, Event Loop tidak benar-benar mempertahankan antrian. Sebaliknya, ia memiliki kumpulan deskriptor file yang meminta sistem operasi untuk memantau, menggunakan mekanisme seperti [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html) (Linux ), [kqueue](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/FSEvents_ProgGuide/KernelQueues/KernelQueues.html) (OSX), port peristiwa (Solaris), atau [IOCP](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx) (Windows). Deskriptor file ini sesuai dengan soket jaringan, file apa pun yang ditontonnya, dan sebagainya. Ketika sistem operasi mengatakan bahwa salah satu deskriptor file ini sudah siap, Loop Peristiwa menerjemahkannya ke peristiwa yang sesuai dan memanggil panggilan balik yang terkait dengan peristiwa itu. Anda dapat mempelajari lebih lanjut tentang proses ini [di sini](https://www.youtube.com/watch?v=P9csgxBgaZ8). - -Sebaliknya, Worker Pool menggunakan antrian nyata yang entrinya adalah tugas untuk diproses. Worker mengeluarkan tugas dari antrian ini dan mengerjakannya, dan ketika selesai Worker memunculkan acara "Setidaknya satu tugas selesai" untuk Event Loop. - -### Apa artinya ini bagi desain aplikasi? - -Dalam sistem satu utas per klien seperti Apache, setiap klien yang tertunda diberi utasnya sendiri. Jika utas menangani satu blok klien, sistem operasi akan menginterupsinya dan memberi klien lain giliran. Sistem operasi dengan demikian memastikan bahwa klien yang membutuhkan sedikit pekerjaan tidak dikenakan sanksi oleh klien yang membutuhkan lebih banyak pekerjaan. - -Karena Node.js menangani banyak klien dengan sedikit utas, jika utas memblokir menangani satu permintaan klien, maka permintaan klien yang tertunda mungkin tidak mendapat giliran sampai utas menyelesaikan panggilan balik atau tugasnya. _Perlakuan yang adil terhadap klien adalah tanggung jawab aplikasi Anda_. Ini berarti Anda tidak boleh melakukan terlalu banyak pekerjaan untuk klien mana pun dalam satu panggilan balik atau tugas. - -Ini adalah bagian dari mengapa Node.js dapat menskalakan dengan baik, tetapi ini juga berarti bahwa Anda bertanggung jawab untuk memastikan penjadwalan yang adil. Bagian selanjutnya berbicara tentang cara memastikan penjadwalan yang adil untuk Loop Peristiwa dan untuk Kelompok Pekerja. - -## Jangan blokir Event Loop - -Loop Peristiwa memperhatikan setiap koneksi klien baru dan mengatur pembuatan respons. Semua permintaan masuk dan tanggapan keluar melewati Event Loop. Ini berarti bahwa jika Loop Peristiwa menghabiskan waktu terlalu lama di titik mana pun, semua klien saat ini dan klien baru tidak akan mendapat giliran. - -Anda harus memastikan bahwa Anda tidak pernah memblokir Event Loop. Dengan kata lain, setiap callback JavaScript Anda harus selesai dengan cepat. Ini tentu saja juga berlaku untuk `await` Anda, `Promise.then` Anda, dan seterusnya. - -Cara yang baik untuk memastikan ini adalah dengan mempertimbangkan ["kompleksitas komputasi"](https://en.wikipedia.org/wiki/Time_complexity) dari panggilan balik Anda. Jika panggilan balik Anda mengambil jumlah langkah yang konstan, apa pun argumennya, maka Anda akan selalu memberikan giliran yang adil kepada setiap klien yang menunggu keputusan. Jika panggilan balik Anda mengambil jumlah langkah yang berbeda tergantung pada argumennya, maka Anda harus memikirkan berapa lama argumennya. - -Contoh 1: Panggilan balik waktu konstan. - -```javascript -app.get('/constant-time', (req, res) => { - res.sendStatus(200); -}); -``` - -Contoh 2: Panggilan balik `O(n)`. Callback ini akan berjalan cepat untuk `n` kecil dan lebih lambat untuk `n` besar. - -```javascript -app.get('/countToN', (req, res) => { - let n = req.query.n; - - // n iterations before giving someone else a turn - for (let i = 0; i < n; i++) { - console.log(`Iter ${i}`); - } - - res.sendStatus(200); -}); -``` - -Contoh 3: Panggilan balik `O(n^2)`. Callback ini akan tetap berjalan dengan cepat untuk `n` kecil, tetapi untuk `n` besar akan berjalan jauh lebih lambat daripada contoh `O(n)` sebelumnya. - -```javascript -app.get('/countToN2', (req, res) => { - let n = req.query.n; - - // n^2 iterations before giving someone else a turn - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - console.log(`Iter ${i}.${j}`); - } - } - - res.sendStatus(200); -}); -``` - -### Seberapa hati-hati Anda seharusnya? - -Node.js menggunakan mesin Google V8 untuk JavaScript, yang cukup cepat untuk banyak operasi umum. Pengecualian untuk aturan ini adalah operasi regexps dan JSON, yang dibahas di bawah ini. - -Namun, untuk tugas yang kompleks, Anda harus mempertimbangkan untuk membatasi input dan menolak input yang terlalu panjang. Dengan begitu, bahkan jika panggilan balik Anda memiliki kompleksitas yang besar, dengan membatasi input, Anda memastikan bahwa panggilan balik tidak dapat memakan waktu lebih dari waktu terburuk pada input terlama yang dapat diterima. Anda kemudian dapat mengevaluasi biaya kasus terburuk dari panggilan balik ini dan menentukan apakah waktu berjalannya dapat diterima dalam konteks Anda. - -### Memblokir Loop Acara: REDOS - -Salah satu cara umum untuk memblokir Loop Peristiwa secara fatal adalah dengan menggunakan [ekspresi reguler](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) yang "rentan". - -#### Menghindari ekspresi reguler yang rentan - -Ekspresi reguler (regexp) mencocokkan string input dengan pola. Kami biasanya menganggap kecocokan regexp membutuhkan satu lintasan melalui string input --- `O(n)` waktu di mana `n` adalah panjang string input. Dalam banyak kasus, satu pass memang diperlukan. Sayangnya, dalam beberapa kasus, pencocokan regexp mungkin memerlukan jumlah perjalanan eksponensial melalui string input --- waktu `O(2^n)`. Jumlah perjalanan eksponensial berarti bahwa jika mesin memerlukan perjalanan `x` untuk menentukan kecocokan, itu akan membutuhkan perjalanan `2*x` jika kita menambahkan hanya satu karakter lagi ke string input. Karena jumlah perjalanan berbanding lurus dengan waktu yang dibutuhkan, efek dari evaluasi ini adalah memblokir Loop Peristiwa. - -_Ekspresi reguler yang rentan_ adalah ekspresi yang mungkin memerlukan waktu eksponensial untuk mesin ekspresi reguler Anda, yang memaparkan Anda ke [REDOS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) pada "input jahat". Apakah pola ekspresi reguler Anda rentan atau tidak (yaitu mesin regexp mungkin membutuhkan waktu eksponensial) sebenarnya adalah pertanyaan yang sulit untuk dijawab, dan bervariasi tergantung pada apakah Anda menggunakan Perl, Python, Ruby, Java, JavaScript, dll., tetapi berikut adalah beberapa aturan praktis yang berlaku di semua bahasa ini: - -1. Hindari quantifier bersarang seperti `(a+)*`. Mesin regexp V8 dapat menangani beberapa di antaranya dengan cepat, tetapi yang lain rentan. -2. Hindari OR dengan klausa yang tumpang tindih, seperti `(a|a)*`. Sekali lagi, ini terkadang-cepat. -3. Hindari menggunakan referensi balik, seperti `(a.*) \1`. Tidak ada mesin regexp yang dapat menjamin evaluasi ini dalam waktu linier. -4. Jika Anda melakukan pencocokan string sederhana, gunakan `indexOf` atau yang setara dengan lokal. Ini akan lebih murah dan tidak akan pernah memakan waktu lebih dari `O(n)`. - -Jika Anda tidak yakin apakah ekspresi reguler Anda rentan, ingatlah bahwa Node.js umumnya tidak mengalami kesulitan untuk melaporkan _kecocokan_ bahkan untuk regexp yang rentan dan string input yang panjang. Perilaku eksponensial dipicu ketika ada ketidakcocokan tetapi Node.js tidak dapat memastikannya sampai mencoba banyak jalur melalui string input. - -#### Contoh REDOS - -Berikut adalah contoh regexp yang rentan mengekspos servernya ke REDOS: - -```javascript -app.get('/redos-me', (req, res) => { - let filePath = req.query.filePath; - - // REDOS - if (filePath.match(/(\/.+)+$/)) { - console.log('valid path'); - } else { - console.log('invalid path'); - } - - res.sendStatus(200); -}); -``` - -Regexp yang rentan dalam contoh ini adalah cara (buruk!) untuk memeriksa jalur yang valid di Linux. Ini cocok dengan string yang merupakan urutan nama yang dibatasi "/", seperti "/a/b/c". Ini berbahaya karena melanggar aturan 1: ia memiliki quantifier bersarang ganda. - -Jika klien bertanya dengan filePath `///.../\n` (100 / diikuti oleh karakter baris baru yang "." regexp tidak akan cocok), maka Loop Peristiwa akan berlangsung selamanya, memblokir Putaran Acara. Serangan REDOS klien ini menyebabkan semua klien lain tidak mendapatkan giliran sampai pencocokan regexp selesai. - -Untuk alasan ini, Anda harus waspada menggunakan ekspresi reguler yang kompleks untuk memvalidasi input pengguna. - -#### Sumber Daya Anti-REDOS - -Ada beberapa alat untuk memeriksa regexps Anda untuk keamanan, seperti - -- [safe-regex](https://github.com/davisjam/safe-regex) -- [rxxr2](http://www.cs.bham.ac.uk/~hxt/research/rxxr2/). Namun, tak satu pun dari ini akan menangkap semua regexps yang rentan. - -Pendekatan lain adalah dengan menggunakan mesin regexp yang berbeda. Anda dapat menggunakan modul [node-re2](https://github.com/uhop/node-re2), yang menggunakan mesin regexp [RE2](https://github.com/google/re2) yang sangat cepat dari Google. Namun berhati-hatilah, RE2 tidak 100% kompatibel dengan regexps V8, jadi periksa regresi jika Anda menukar modul node-re2 untuk menangani regexps Anda. Dan regexp yang sangat rumit tidak didukung oleh node-re2. - -Jika Anda mencoba mencocokkan sesuatu yang "jelas", seperti URL atau jalur file, temukan contoh di [perpustakaan regexp](http://www.regexlib.com) atau gunakan modul npm, mis. [ip-regex](https://www.npmjs.com/package/ip-regex). - -### Memblokir Loop Peristiwa: Modul inti Node.js - -Beberapa modul inti Node.js memiliki API mahal yang sinkron, termasuk: - -- [Enkripsi](https://nodejs.org/api/crypto.html) -- [Kompresi](https://nodejs.org/api/zlib.html) -- [Sistem file](https://nodejs.org/api/fs.html) -- [Proses turunan](https://nodejs.org/api/child_process.html) - -API ini mahal, karena melibatkan komputasi yang signifikan (enkripsi, kompresi), memerlukan I/O (file I/O), atau berpotensi keduanya (Child Process). API ini dimaksudkan untuk kenyamanan skrip, tetapi tidak dimaksudkan untuk digunakan dalam konteks server. Jika Anda menjalankannya di Event Loop, mereka akan membutuhkan waktu lebih lama untuk diselesaikan daripada instruksi JavaScript biasa, memblokir Event Loop. - -Di server, _Anda tidak boleh menggunakan API sinkron berikut dari modul ini_: - -- Enkripsi: - - `crypto.randomBytes` (versi sinkron) - - `crypto.randomFillSync` - - `crypto.pbkdf2Sync` - - Anda juga harus berhati-hati dalam memberikan masukan besar ke rutinitas enkripsi dan dekripsi. -- Kompresi: - - `zlib.inflateSync` - - `zlib.deflateSync` -- Berkas sistem: - - Jangan gunakan API sistem file sinkron. Misalnya, jika file yang Anda akses berada dalam [sistem file terdistribusi](https://en.wikipedia.org/wiki/Clustered_file_system#Distributed_file_systems) seperti [NFS](https://en.wikipedia.org/wiki/Network_File_System), waktu akses dapat sangat bervariasi. -- Child Process: - - `child_process.spawnSync` - - `child_process.execSync` - - `child_process.execFileSync` - -Daftar ini cukup lengkap pada Node.js v9. - -### Memblokir Loop Peristiwa: JSON DOS - -`JSON.parse` dan `JSON.stringify` adalah operasi lain yang berpotensi mahal. Meskipun ini adalah `O(n)` dalam panjang input, untuk `n` besar mereka bisa memakan waktu sangat lama. - -Jika server Anda memanipulasi objek JSON, terutama objek dari klien, Anda harus berhati-hati dengan ukuran objek atau string yang Anda gunakan di Event Loop. - -Contoh: pemblokiran JSON. Kami membuat objek `obj` dengan ukuran 2^21 dan `JSON.stringify`, menjalankan `indexOf` pada string, lalu JSON.parse. String `JSON.stringify`'d berukuran 50MB. Dibutuhkan 0,7 detik untuk merangkai objek, 0,03 detik untuk indexOf pada string 50MB, dan 1,3 detik untuk mengurai string. - -```javascript -var obj = { a: 1 }; -var niter = 20; - -var before, str, pos, res, took; - -for (var i = 0; i < niter; i++) { - obj = { obj1: obj, obj2: obj }; // Doubles in size each iter -} - -before = process.hrtime(); -str = JSON.stringify(obj); -took = process.hrtime(before); -console.log('JSON.stringify took ' + took); - -before = process.hrtime(); -pos = str.indexOf('nomatch'); -took = process.hrtime(before); -console.log('Pure indexof took ' + took); - -before = process.hrtime(); -res = JSON.parse(str); -took = process.hrtime(before); -console.log('JSON.parse took ' + took); -``` - -Ada modul npm yang menawarkan API JSON asinkron. Lihat misalnya: - -- [JSONStream](https://www.npmjs.com/package/JSONStream), yang memiliki API streaming. -- [JSON Ramah Besar](https://www.npmjs.com/package/bfj), yang memiliki API aliran serta versi asinkron dari API JSON standar menggunakan paradigma partisi-on-the-Event-Loop yang diuraikan di bawah. - -### Perhitungan rumit tanpa memblokir Event Loop - -Misalkan Anda ingin melakukan perhitungan kompleks dalam JavaScript tanpa memblokir Event Loop. Anda memiliki dua opsi: mempartisi atau membongkar. - -#### Partisi - -Anda dapat _mempartisi_ perhitungan Anda sehingga masing-masing berjalan pada Loop Peristiwa tetapi secara teratur menghasilkan (memberikan giliran ke) peristiwa tertunda lainnya. Dalam JavaScript, mudah untuk menyimpan status tugas yang sedang berlangsung dalam penutupan, seperti yang ditunjukkan pada contoh 2 di bawah ini. - -Sebagai contoh sederhana, misalkan Anda ingin menghitung rata-rata angka `1` hingga `n`. - -Contoh 1: Rata-rata yang tidak dipartisi, biaya `O(n)` - -```javascript -for (let i = 0; i < n; i++) sum += i; -let avg = sum / n; -console.log('avg: ' + avg); -``` - -Contoh 2: Rata-rata yang dipartisi, setiap langkah asinkron `n` berharga `O(1)`. - -```javascript -function asyncAvg(n, avgCB) { - // Save ongoing sum in JS closure. - var sum = 0; - function help(i, cb) { - sum += i; - if (i == n) { - cb(sum); - return; - } - - // "Asynchronous recursion". - // Schedule next operation asynchronously. - setImmediate(help.bind(null, i + 1, cb)); - } - - // Start the helper, with CB to call avgCB. - help(1, function (sum) { - var avg = sum / n; - avgCB(avg); - }); -} - -asyncAvg(n, function (avg) { - console.log('avg of 1-n: ' + avg); -}); -``` - -Anda dapat menerapkan prinsip ini pada iterasi array dan sebagainya. - -#### Menurunkan - -Jika Anda perlu melakukan sesuatu yang lebih kompleks, mempartisi bukanlah pilihan yang baik. Ini karena mempartisi hanya menggunakan Event Loop, dan Anda tidak akan mendapat manfaat dari banyak inti yang hampir pasti tersedia di mesin Anda. _Ingat, Event Loop harus mengatur permintaan klien, bukan memenuhinya sendiri._ Untuk tugas yang rumit, pindahkan pekerjaan dari Event Loop ke Worker Pool. - -##### Cara membongkar - -Anda memiliki dua opsi untuk Worker Pool tujuan yang akan digunakan untuk membongkar pekerjaan. - -1. Anda dapat menggunakan Node.js Worker Pool bawaan dengan mengembangkan [addon C++](https://nodejs.org/api/addons.html). Pada Node versi lama, buat addon C++ Anda menggunakan [NAN](https://github.com/nodejs/nan), dan pada versi yang lebih baru gunakan [N-API](https://nodejs.org/api/n-api.html). [node-webworker-threads](https://www.npmjs.com/package/webworker-threads) menawarkan cara khusus JavaScript untuk mengakses Kumpulan Pekerja Node.js. -2. Anda dapat membuat dan mengelola Worker Pool Anda sendiri yang didedikasikan untuk komputasi daripada Worker Pool bertema I/O Node.js. Cara paling mudah untuk melakukannya adalah menggunakan [Child Process](https://nodejs.org/api/child_process.html) atau [Cluster](https://nodejs.org/api/cluster.html). - -Anda seharusnya _tidak_ hanya membuat [Child Process](https://nodejs.org/api/child_process.html) untuk setiap klien. Anda dapat menerima permintaan klien lebih cepat daripada membuat dan mengelola turunan, dan server Anda mungkin menjadi [bom garpu](https://en.wikipedia.org/wiki/Fork_bomb). - -##### Kelemahan dari pembongkaran - -Kelemahan dari pendekatan pembongkaran adalah menimbulkan biaya overhead dalam bentuk _biaya komunikasi_. Hanya Event Loop yang diizinkan untuk melihat "namespace" (status JavaScript) aplikasi Anda. Dari Worker, Anda tidak bisa memanipulasi objek JavaScript di namespace Event Loop. Sebagai gantinya, Anda harus membuat serial dan deserialize objek apa pun yang ingin Anda bagikan. Kemudian Worker dapat mengoperasikan salinannya sendiri dari objek-objek ini dan mengembalikan objek yang dimodifikasi (atau "patch") ke Event Loop. - -Untuk masalah serialisasi, lihat bagian tentang JSON DOS. - -##### Beberapa saran untuk pembongkaran - -Anda mungkin ingin membedakan antara tugas-tugas CPU-intensif dan I/O-intensif karena mereka memiliki karakteristik yang sangat berbeda. - -Tugas intensif CPU hanya membuat kemajuan saat Worker-nya dijadwalkan, dan Worker harus dijadwalkan ke salah satu [logical core](https://nodejs.org/api/os.html#os_os_cpus) mesin Anda. Jika Anda memiliki 4 inti logis dan 5 Pekerja, salah satu Pekerja ini tidak dapat membuat kemajuan. Akibatnya, Anda membayar overhead (biaya memori dan penjadwalan) untuk Pekerja ini dan tidak mendapatkan pengembalian untuk itu. - -Tugas intensif I/O melibatkan permintaan dari penyedia layanan eksternal (DNS, sistem file, dll.) dan menunggu tanggapannya. Sementara seorang Pekerja dengan tugas intensif I/O sedang menunggu tanggapannya, tidak ada hal lain yang harus dilakukan dan dapat dibatalkan jadwalnya oleh sistem operasi, memberikan Pekerja lain kesempatan untuk mengajukan permintaan mereka. Dengan demikian, _tugas intensif I/O akan membuat kemajuan meskipun utas terkait tidak berjalan_. Penyedia layanan eksternal seperti database dan sistem file telah sangat dioptimalkan untuk menangani banyak permintaan yang tertunda secara bersamaan. Misalnya, sistem file akan memeriksa sekumpulan besar permintaan tulis dan baca yang tertunda untuk menggabungkan pembaruan yang bertentangan dan untuk mengambil file dalam urutan yang optimal (mis. lihat [slide ini](http://researcher.ibm.com/researcher/files/il-AVISHAY/01-block_io-v1.3.pdf)). - -Jika Anda hanya mengandalkan satu Kelompok Pekerja, mis. Node.js Worker Pool, maka karakteristik yang berbeda dari pekerjaan yang terikat CPU dan yang terikat I/O dapat membahayakan kinerja aplikasi Anda. - -Untuk alasan ini, Anda mungkin ingin mempertahankan Kumpulan Pekerja Komputasi yang terpisah. - -#### Membongkar: kesimpulan - -Untuk tugas-tugas sederhana, seperti mengulangi elemen-elemen array yang panjangnya sewenang-wenang, mempartisi mungkin merupakan pilihan yang baik. Jika komputasi Anda lebih kompleks, pembongkaran adalah pendekatan yang lebih baik: biaya komunikasi, yaitu overhead melewatkan objek serial antara Event Loop dan Worker Pool, diimbangi dengan manfaat menggunakan banyak inti. - -Namun, jika server Anda sangat bergantung pada perhitungan yang rumit, Anda harus memikirkan apakah Node.js benar-benar cocok. Node.js unggul untuk pekerjaan terikat I/O, tetapi untuk komputasi yang mahal, ini mungkin bukan pilihan terbaik. - -Jika Anda mengambil pendekatan pembongkaran, lihat bagian tentang tidak memblokir Kumpulan Pekerja. - -## Jangan blokir Kelompok Pekerja - -Node.js memiliki Worker Pool yang terdiri dari `k` Workers. Jika Anda menggunakan paradigma Pembongkaran yang dibahas di atas, Anda mungkin memiliki Kumpulan Pekerja Komputasi terpisah, yang menerapkan prinsip yang sama. Dalam kedua kasus tersebut, mari kita asumsikan bahwa `k` jauh lebih kecil daripada jumlah klien yang mungkin Anda tangani secara bersamaan. Ini sesuai dengan filosofi "satu utas untuk banyak klien" dari Node.js, rahasia skalabilitasnya. - -Seperti dibahas di atas, setiap Pekerja menyelesaikan Tugasnya saat ini sebelum melanjutkan ke yang berikutnya di antrian Kumpulan Pekerja. - -Sekarang, akan ada variasi dalam biaya Tugas yang diperlukan untuk menangani permintaan klien Anda. Beberapa Tugas dapat diselesaikan dengan cepat (misalnya membaca file pendek atau yang di-cache, atau menghasilkan sejumlah kecil byte acak), dan yang lain akan memakan waktu lebih lama (misalnya membaca file yang lebih besar atau tidak di-cache, atau menghasilkan lebih banyak byte acak). Tujuan Anda adalah untuk _meminimalkan variasi dalam waktu Tugas_, dan Anda harus menggunakan _Pembagian tugas_ untuk mencapainya. - -### Meminimalkan variasi waktu Tugas - -Jika Tugas Pekerja saat ini jauh lebih mahal daripada Tugas lainnya, maka tugas tersebut tidak akan tersedia untuk mengerjakan Tugas lain yang tertunda. Dengan kata lain, _setiap Tugas yang relatif panjang secara efektif mengurangi ukuran Kelompok Pekerja sebanyak satu hingga selesai_. Ini tidak diinginkan karena, sampai titik tertentu, semakin banyak Pekerja di Kumpulan Pekerja, semakin besar throughput Kumpulan Pekerja (tugas/detik) dan dengan demikian semakin besar throughput server (permintaan klien/detik). Satu klien dengan Tugas yang relatif mahal akan menurunkan throughput Worker Pool, yang pada gilirannya menurunkan throughput server. - -Untuk menghindari hal ini, Anda harus mencoba meminimalkan variasi panjang Tugas yang Anda kirimkan ke Kelompok Pekerja. Meskipun tepat untuk memperlakukan sistem eksternal yang diakses oleh permintaan I/O Anda (DB, FS, dll.) sebagai kotak hitam, Anda harus mengetahui biaya relatif dari permintaan I/O ini, dan harus menghindari pengiriman permintaan yang dapat Anda lakukan. berharap untuk menjadi sangat panjang. - -Dua contoh harus menggambarkan kemungkinan variasi dalam waktu tugas. - -#### Contoh variasi: Sistem file yang berjalan lama membaca - -Misalkan server Anda harus membaca file untuk menangani beberapa permintaan klien. Setelah berkonsultasi dengan API Node.js [File system](https://nodejs.org/api/fs.html), Anda memilih untuk menggunakan `fs.readFile()` untuk kesederhanaan. Namun, `fs.readFile()` adalah ([saat ini](https://github.com/nodejs/node/pull/17054)) tidak dipartisi: ia mengirimkan satu Tugas `fs.read()` yang mencakup seluruh mengajukan. Jika Anda membaca file yang lebih pendek untuk beberapa pengguna dan file yang lebih panjang untuk yang lain, `fs.readFile()` dapat menyebabkan variasi yang signifikan dalam panjang Tugas, sehingga merugikan throughput Kumpulan Pekerja. - -Untuk skenario terburuk, misalkan penyerang dapat meyakinkan server Anda untuk membaca file _arbitrary_ (ini adalah [kerentanan traversal direktori](https://www.owasp.org/index.php/Path_Traversal)). Jika server Anda menjalankan Linux, penyerang dapat memberi nama file yang sangat lambat: [`/dev/random`](http://man7.org/linux/man-pages/man4/random.4.html). Untuk semua tujuan praktis, `/dev/random` sangat lambat, dan setiap Pekerja yang diminta untuk membaca dari `/dev/random` tidak akan pernah menyelesaikan Tugas itu. Penyerang kemudian mengirimkan permintaan `k`, satu untuk setiap Pekerja, dan tidak ada permintaan klien lain yang menggunakan Kumpulan Pekerja yang akan membuat kemajuan. - -#### Contoh variasi: Operasi kripto yang berjalan lama - -Misalkan server Anda menghasilkan byte acak yang aman secara kriptografis menggunakan [`crypto.randomBytes()`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback). `crypto.randomBytes()` tidak dipartisi: ia membuat satu Tugas `randomBytes()` untuk menghasilkan byte sebanyak yang Anda minta. Jika Anda membuat lebih sedikit byte untuk beberapa pengguna dan lebih banyak byte untuk yang lain, `crypto.randomBytes()` adalah sumber variasi lain dalam panjang Tugas. - -### Pembagian tugas - -Tugas dengan biaya waktu variabel dapat merusak throughput Worker Pool. Untuk meminimalkan variasi dalam waktu Tugas, sejauh mungkin Anda harus _mempartisi_ setiap Tugas menjadi sub-Tugas dengan biaya yang sebanding. Ketika setiap sub-Tugas selesai, ia harus menyerahkan sub-Tugas berikutnya, dan ketika sub-Tugas terakhir selesai, ia harus memberi tahu pengirim. - -Untuk melanjutkan contoh `fs.readFile()`, Anda sebaiknya menggunakan `fs.read()` (partisi manual) atau `ReadStream` (dipartisi secara otomatis). - -Prinsip yang sama berlaku untuk tugas terikat CPU; contoh `asyncAvg` mungkin tidak sesuai untuk Loop Peristiwa, tetapi sangat cocok untuk Kumpulan Pekerja. - -Saat Anda mempartisi Tugas menjadi sub-Tugas, Tugas yang lebih pendek diperluas menjadi sejumlah kecil sub-Tugas, dan Tugas yang lebih panjang diperluas menjadi lebih banyak sub-Tugas. Di antara setiap sub-Tugas dari Tugas yang lebih panjang, Pekerja yang ditugaskan dapat mengerjakan sub-Tugas dari Tugas lain yang lebih pendek, sehingga meningkatkan keseluruhan throughput Tugas dari Kumpulan Pekerja. - -Perhatikan bahwa jumlah sub-Tugas yang diselesaikan bukanlah metrik yang berguna untuk throughput Worker Pool. Alih-alih, perhatikan jumlah _Tugas_ yang diselesaikan. - -### Menghindari pembagian tugas - -Ingatlah bahwa tujuan dari pembagian Tugas adalah untuk meminimalkan variasi dalam waktu Tugas. Jika Anda dapat membedakan antara Tugas yang lebih pendek dan Tugas yang lebih panjang (mis. menjumlahkan larik vs. mengurutkan larik), Anda dapat membuat satu Kumpulan Pekerja untuk setiap kelas Tugas. Merutekan Tugas yang lebih pendek dan Tugas yang lebih panjang untuk memisahkan Kumpulan Pekerja adalah cara lain untuk meminimalkan variasi waktu Tugas. - -Mendukung pendekatan ini, mempartisi Tugas menimbulkan overhead (biaya untuk membuat representasi Tugas Kumpulan Pekerja dan memanipulasi antrian Kumpulan Pekerja), dan menghindari pemartisian menghemat biaya perjalanan tambahan ke Kumpulan Pekerja. Ini juga mencegah Anda membuat kesalahan dalam mempartisi Tugas Anda. - -Kelemahan dari pendekatan ini adalah bahwa Pekerja di semua Kumpulan Pekerja ini akan dikenakan overhead ruang dan waktu dan akan bersaing satu sama lain untuk waktu CPU. Ingatlah bahwa setiap Tugas yang terikat CPU membuat kemajuan hanya saat dijadwalkan. Akibatnya, Anda hanya harus mempertimbangkan pendekatan ini setelah analisis yang cermat. - -### Kelompok Pekerja: kesimpulan - -Baik Anda hanya menggunakan Kumpulan Pekerja Node.js atau memelihara Kumpulan Pekerja yang terpisah, Anda harus mengoptimalkan throughput Tugas dari Kumpulan Anda. - -Untuk melakukannya, minimalkan variasi waktu tugas dengan menggunakan partisi tugas. - -## Risiko modul npm - -Sementara modul inti Node.js menawarkan blok bangunan untuk berbagai macam aplikasi, terkadang sesuatu yang lebih dibutuhkan. Pengembang Node.js sangat diuntungkan dari [ekosistem npm](https://www.npmjs.com/), dengan ratusan ribu modul yang menawarkan fungsionalitas untuk mempercepat proses pengembangan Anda. - -Namun, ingat bahwa sebagian besar modul ini ditulis oleh pengembang pihak ketiga dan umumnya dirilis hanya dengan jaminan upaya terbaik. Pengembang yang menggunakan modul npm harus memperhatikan dua hal, meskipun yang terakhir sering dilupakan. - -1. Apakah itu menghormati API-nya? -2. Mungkinkah API-nya memblokir Event Loop atau Worker? Banyak modul tidak berusaha menunjukkan biaya API mereka, sehingga merugikan komunitas. - -Untuk API sederhana, Anda dapat memperkirakan biaya API; biaya manipulasi string tidak sulit untuk dipahami. Namun dalam banyak kasus, tidak jelas berapa biaya API. - -_Jika Anda memanggil API yang mungkin melakukan sesuatu yang mahal, periksa kembali biayanya. Minta pengembang untuk mendokumentasikannya, atau periksa sendiri kode sumbernya (dan kirimkan PR yang mendokumentasikan biayanya)._ - -Ingat, meskipun API tidak sinkron, Anda tidak tahu berapa banyak waktu yang mungkin dihabiskan untuk Worker atau Event Loop di setiap partisinya. Misalnya, dalam contoh `asyncAvg` yang diberikan di atas, setiap panggilan ke fungsi helper dijumlahkan _setengah_ dari angka, bukan salah satunya. Maka fungsi ini akan tetap asinkron, tetapi biaya setiap partisi adalah `O(n)`, bukan `O(1)`, sehingga kurang aman digunakan untuk nilai `n` yang berubah-ubah. - -## Kesimpulan - -Node.js memiliki dua jenis utas: satu Loop Peristiwa dan Pekerja `k`. Event Loop bertanggung jawab atas callback JavaScript dan I/O non-pemblokiran, dan Worker menjalankan tugas yang terkait dengan kode C++ yang menyelesaikan permintaan asinkron, termasuk memblokir I/O dan pekerjaan intensif CPU. Kedua jenis utas bekerja pada tidak lebih dari satu aktivitas pada satu waktu. Jika ada panggilan balik atau tugas yang membutuhkan waktu lama, utas yang menjalankannya menjadi _diblokir_. Jika aplikasi Anda membuat panggilan balik atau tugas pemblokiran, ini dapat menyebabkan penurunan throughput (klien/detik) paling baik, dan penolakan layanan total paling buruk. - -Untuk menulis server web dengan throughput tinggi dan lebih tahan DoS, Anda harus memastikan bahwa pada input jinak dan berbahaya, Event Loop maupun Pekerja Anda tidak akan memblokir. diff --git a/pages/id/docs/guides/event-loop-timers-and-nexttick.md b/pages/id/docs/guides/event-loop-timers-and-nexttick.md deleted file mode 100644 index e4f7070ba4883..0000000000000 --- a/pages/id/docs/guides/event-loop-timers-and-nexttick.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: Loop Peristiwa Node.js, Pengatur Waktu, dan process.nextTick() -layout: docs.hbs ---- - -# Loop Peristiwa Node.js, Timer, dan `process.nextTick()` - -## Apa itu Loop Peristiwa? - -Loop peristiwa inilah yang memungkinkan Node.js melakukan I/O non-pemblokiran operasi — terlepas dari kenyataan bahwa JavaScript adalah single-threaded — oleh operasi pembongkaran ke kernel sistem bila memungkinkan. - -Karena kebanyakan kernel modern adalah multi-threaded, mereka dapat menangani multiple operasi yang dijalankan di latar belakang. Ketika salah satu dari operasi ini selesai, kernel memberi tahu Node.js sehingga panggilan balik yang sesuai dapat ditambahkan ke antrean **poll** untuk akhirnya dieksekusi. Kami akan menjelaskan ini secara lebih rinci nanti dalam topik ini. - -## Loop Peristiwa Dijelaskan - -Ketika Node.js dimulai, itu menginisialisasi loop acara, memproses skrip input yang disediakan (atau masuk ke [REPL][], yang tidak tercakup dalam dokumen ini) yang dapat membuat panggilan API asinkron, pengatur waktu jadwal, atau panggilan `process.nextTick()`, lalu mulai memproses loop peristiwa. - -Diagram berikut menunjukkan ikhtisar yang disederhanakan dari loop acara urutan operasi. - -``` - ┌───────────────────────────┐ -┌─>│ timers │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ pending callbacks │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ idle, prepare │ -│ └─────────────┬─────────────┘ ┌───────────────┐ -│ ┌─────────────┴─────────────┐ │ incoming: │ -│ │ poll │<─────┤ connections, │ -│ └─────────────┬─────────────┘ │ data, etc. │ -│ ┌─────────────┴─────────────┐ └───────────────┘ -│ │ check │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -└──┤ close callbacks │ - └───────────────────────────┘ -``` - -> Setiap kotak akan disebut sebagai "fase" dari loop peristiwa. - -Setiap fase memiliki antrian panggilan balik FIFO untuk dieksekusi. Sedangkan setiap fase adalah khusus dengan caranya sendiri, umumnya, ketika loop acara memasuki yang diberikan fase, itu akan melakukan operasi apa pun yang spesifik untuk fase itu, lalu jalankan panggilan balik dalam antrian fase itu sampai antrian selesai habis atau jumlah maksimum panggilan balik telah dieksekusi. Ketika antrian telah habis atau batas panggilan balik tercapai, acara loop akan pindah ke fase berikutnya, dan seterusnya. - -Karena salah satu dari operasi ini dapat dijadwalkan _lebih_ operasi dan baru peristiwa yang diproses dalam fase **poll** diantrekan oleh kernel, poll acara dapat diantrekan saat acara pemungutan suara sedang diproses. Sebagai hasilnya, panggilan balik yang berjalan lama dapat memungkinkan fase polling berjalan banyak lebih lama dari ambang timer. Lihat [**timers**](#timers) dan [**poll**](#poll) untuk detail selengkapnya. - -> Ada sedikit perbedaan antara Windows dan Implementasi Unix/Linux, tapi itu tidak penting untuk ini demonstrasi. Bagian terpenting ada di sini. Sebenarnya ada tujuh atau delapan langkah, tapi yang kami pedulikan — yang Node.js sebenarnya menggunakan - apakah yang di atas. - -## Ikhtisar Fase - -- **timer**: fase ini mengeksekusi callback yang dijadwalkan oleh `setTimeout()` dan `setInterval()`. -- **panggilan balik yang tertunda**: mengeksekusi panggilan balik I/O yang ditangguhkan ke loop berikutnya pengulangan. -- **idle, prepare**: hanya digunakan secara internal. -- **jajak pendapat**: mengambil peristiwa I/O baru; jalankan panggilan balik terkait I/O (hampir) semua dengan pengecualian close callback, yang dijadwalkan oleh timer, dan `setImmediate()`); node akan memblokir di sini bila perlu. -- **check**: callback `setImmediate()` dipanggil di sini. -- **close callback**: beberapa close callback, mis. `socket.on('tutup', ...)`. - -Di antara setiap putaran acara, Node.js memeriksa apakah itu menunggu setiap I/O atau penghitung waktu asinkron dan mati dengan bersih jika tidak ada setiap. - -## Fase secara Detail - -### pengatur waktu - -Timer menentukan **threshold** _setelah itu_ callback yang disediakan _mungkin dieksekusi_ daripada **waktu yang tepat** yang _diinginkan seseorang dieksekusi_. Panggilan balik pengatur waktu akan berjalan sedini mungkin dijadwalkan setelah jumlah waktu yang ditentukan telah berlalu; namun, Penjadwalan Sistem Operasi atau menjalankan panggilan balik lainnya mungkin tertunda mereka. - -> Secara teknis, [**poll** phase](#poll) mengontrol kapan timer dijalankan. - -Misalnya, Anda menjadwalkan waktu tunggu untuk dieksekusi setelah 100 ms ambang batas, maka skrip Anda mulai membaca file secara tidak sinkron yang membutuhkan waktu 95 ms: - -```js -const fs = require('fs'); - -function someAsyncOperation(callback) { - // Assume this takes 95ms to complete - fs.readFile('/path/to/file', callback); -} - -const timeoutScheduled = Date.now(); - -setTimeout(() => { - const delay = Date.now() - timeoutScheduled; - - console.log(`${delay}ms have passed since I was scheduled`); -}, 100); - -// do someAsyncOperation which takes 95 ms to complete -someAsyncOperation(() => { - const startCallback = Date.now(); - - // do something that will take 10ms... - while (Date.now() - startCallback < 10) { - // do nothing - } -}); -``` - -Saat loop peristiwa memasuki fase **poll**, antriannya kosong (`fs.readFile()` belum selesai), sehingga akan menunggu jumlah ms tersisa sampai ambang timer tercepat tercapai. Sementara itu menunggu 95 ms berlalu, `fs.readFile()` selesai membaca file dan nya panggilan balik yang membutuhkan waktu 10 md untuk diselesaikan ditambahkan ke antrean **jajak pendapat** dan dieksekusi. Saat panggilan balik selesai, tidak ada lagi panggilan balik di antrian, sehingga loop acara akan melihat bahwa ambang batas paling cepat timer telah tercapai lalu bungkus kembali ke fase **timers** untuk dieksekusi panggilan balik pengatur waktu. Dalam contoh ini, Anda akan melihat bahwa penundaan total antara pengatur waktu yang dijadwalkan dan panggilan baliknya yang dieksekusi akan menjadi 105ms. - -> Untuk mencegah fase **poll** kelaparan loop acara, [libuv][] (library C yang mengimplementasikan Node.js loop acara dan semua perilaku asinkron platform) juga memiliki hard maximum (tergantung sistem) sebelum berhenti polling untuk lebih banyak acara. - -### panggilan balik tertunda - -Fase ini mengeksekusi panggilan balik untuk beberapa operasi sistem seperti tipe dari kesalahan TCP. Misalnya jika soket TCP menerima `ECONNREFUSED` ketika mencoba menyambung, beberapa sistem \*nix ingin menunggu untuk melaporkan kesalahan. Ini akan diantrekan untuk dieksekusi dalam fase **panggilan balik tertunda**. - -### polling - -Fase **jajak pendapat** memiliki dua fungsi utama: - -1. Menghitung berapa lama harus memblokir dan polling untuk I/O, lalu -2. Memproses peristiwa dalam antrean **jajak pendapat**. - -Saat loop peristiwa memasuki fase **poll** _dan tidak ada timer dijadwalkan_, salah satu dari dua hal akan terjadi: - -- _Jika antrean **poll** **tidak kosong**_, loop peristiwa akan berulang melalui antrian panggilan baliknya yang mengeksekusinya secara sinkron sampai baik antrian telah habis, atau batas keras yang bergantung pada sistem tercapai. - -- _Jika antrean **jajak pendapat** **kosong**_, salah satu dari dua hal lagi akan terjadi: - - - Jika skrip telah dijadwalkan oleh `setImmediate()`, loop acara akan mengakhiri fase **poll** dan melanjutkan ke fase **check** ke jalankan skrip terjadwal tersebut. - - - Jika skrip **belum** dijadwalkan oleh `setImmediate()`, maka loop acara akan menunggu panggilan balik ditambahkan ke antrian, lalu mengeksekusi mereka segera. - -Setelah antrean **poll** kosong, loop acara akan memeriksa timer _yang batas waktunya telah tercapai_. Jika satu atau lebih pengatur waktu adalah siap, loop acara akan kembali ke fase **timers** untuk dieksekusi callback pengatur waktu itu. - -### memeriksa - -Fase ini memungkinkan seseorang untuk mengeksekusi panggilan balik segera setelah fase **jajak pendapat** telah selesai. Jika fase **jajak pendapat** menjadi tidak aktif dan skrip telah diantrekan dengan `setImmediate()`, loop acara mungkin lanjutkan ke fase **periksa** daripada menunggu. - -`setImmediate()` sebenarnya adalah timer khusus yang berjalan secara terpisah fase loop acara. Ini menggunakan API libuv yang menjadwalkan panggilan balik ke jalankan setelah fase **jajak pendapat** selesai. - -Umumnya, saat kode dieksekusi, loop acara pada akhirnya akan mengenai fase **jajak pendapat** di mana ia akan menunggu koneksi masuk, permintaan, dll. Namun, jika panggilan balik telah dijadwalkan dengan `setImmediate()` dan fase **poll** menjadi idle, akan berakhir dan berlanjut ke **periksa** fase daripada menunggu acara **jajak pendapat**. - -### tutup panggilan balik - -Jika soket atau pegangan ditutup tiba-tiba (misalnya `socket.destroy()`), Acara `'close'` akan dipancarkan dalam fase ini. Kalau tidak, itu akan menjadi dipancarkan melalui `process.nextTick()`. - -## `setImmediate()` vs `setTimeout()` - -`setImmediate()` dan `setTimeout()` serupa, tetapi berperilaku berbeda cara tergantung pada saat mereka dipanggil. - -- `setImmediate()` dirancang untuk mengeksekusi skrip setelah fase **jajak pendapat** saat ini selesai. -- `setTimeout()` menjadwalkan skrip untuk dijalankan setelah ambang batas minimum di ms telah berlalu. - -Urutan di mana penghitung waktu dijalankan akan bervariasi tergantung pada konteks di mana mereka dipanggil. Jika keduanya dipanggil dari dalam modul utama, maka waktu akan terikat oleh kinerja proses (yang dapat dipengaruhi oleh aplikasi lain yang berjalan di mesin). - -Misalnya, jika kita menjalankan skrip berikut yang tidak berada dalam I/O siklus (yaitu modul utama), urutan di mana dua timer adalah dieksekusi adalah non-deterministik, karena terikat oleh kinerja proses: - -```js -// timeout_vs_immediate.js -setTimeout(() => { - console.log('timeout'); -}, 0); - -setImmediate(() => { - console.log('immediate'); -}); -``` - -``` -$ node timeout_vs_immediate.js -timeout -immediate - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -Namun, jika Anda memindahkan dua panggilan tersebut dalam siklus I/O, panggilan balik segera selalu dieksekusi terlebih dahulu: - -```js -// timeout_vs_immediate.js -const fs = require('fs'); - -fs.readFile(__filename, () => { - setTimeout(() => { - console.log('timeout'); - }, 0); - setImmediate(() => { - console.log('immediate'); - }); -}); -``` - -``` -$ node timeout_vs_immediate.js -immediate -timeout - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -Keuntungan utama menggunakan `setImmediate()` daripada `setTimeout()` adalah `setImmediate()` akan selalu dieksekusi sebelum timer apa pun jika dijadwalkan dalam siklus I/O, terlepas dari berapa banyak timer yang ada. - -## `process.nextTick()` - -### Memahami `process.nextTick()` - -Anda mungkin telah memperhatikan bahwa `process.nextTick()` tidak ditampilkan di diagram, meskipun itu adalah bagian dari API asinkron. Hal ini karena `process.nextTick()` secara teknis bukan bagian dari loop peristiwa. Alih-alih, `nextTickQueue` akan diproses setelah operasi saat ini selesai, terlepas dari fase loop acara saat ini. Di Sini, sebuah _operasi_ didefinisikan sebagai transisi dari penangan C/C++ yang mendasarinya, dan penanganan JavaScript yang perlu dieksekusi. - -Melihat kembali diagram kita, setiap kali Anda memanggil `process.nextTick()` dalam sebuah fase tertentu, semua panggilan balik yang diteruskan ke `process.nextTick()` akan menjadi diselesaikan sebelum loop acara berlanjut. Ini bisa membuat beberapa hal buruk situasi karena ** memungkinkan Anda untuk "melaparkan" I/O Anda dengan membuat panggilan `process.nextTick()` rekursif\*** yang mencegah loop peristiwa dari mencapai fase **jajak pendapat**. - -### Mengapa itu diizinkan? - -Mengapa sesuatu seperti ini dimasukkan dalam Node.js? Sebagiannya adalah filosofi desain di mana API harus selalu asinkron bahkan di mana pun itu tidak harus. Ambil cuplikan kode ini misalnya: - -```js -function apiCall(arg, callback) { - if (typeof arg !== 'string') - return process.nextTick( - callback, - new TypeError('argument should be string') - ); -} -``` - -Cuplikan melakukan pemeriksaan argumen dan jika tidak benar, itu akan lolos kesalahan pada panggilan balik. API diperbarui cukup baru untuk memungkinkan meneruskan argumen ke `process.nextTick()` yang memungkinkannya mengambil apa pun argumen yang diteruskan setelah panggilan balik untuk disebarkan sebagai argumen untuk panggilan balik sehingga Anda tidak perlu menumpuk fungsi. - -Apa yang kami lakukan adalah meneruskan kesalahan kembali ke pengguna tetapi hanya _setelah_ kami telah mengizinkan sisa kode pengguna untuk dieksekusi. Dengan menggunakan `process.nextTick()` kami menjamin bahwa `apiCall()` selalu berjalan panggilan balik _setelah_ sisa kode pengguna dan _sebelum_ loop acara diperbolehkan untuk dilanjutkan. Untuk mencapai ini, tumpukan panggilan JS diizinkan untuk bersantai kemudian segera jalankan panggilan balik yang disediakan yang memungkinkan a orang untuk membuat panggilan rekursif ke `process.nextTick()` tanpa mencapai a `RangeError: Ukuran tumpukan panggilan maksimum terlampaui dari v8`. - -Filosofi ini dapat menyebabkan beberapa situasi yang berpotensi bermasalah. Ambil cuplikan ini misalnya: - -```js -let bar; - -// this has an asynchronous signature, but calls callback synchronously -function someAsyncApiCall(callback) { - callback(); -} - -// the callback is called before `someAsyncApiCall` completes. -someAsyncApiCall(() => { - // since someAsyncApiCall hasn't completed, bar hasn't been assigned any value - console.log('bar', bar); // undefined -}); - -bar = 1; -``` - -Pengguna mendefinisikan `someAsyncApiCall()` untuk memiliki tanda tangan asinkron, tetapi sebenarnya beroperasi secara sinkron. Saat dipanggil, panggilan balik disediakan untuk `someAsyncApiCall()` dipanggil dalam fase yang sama dari loop acara karena `someAsyncApiCall()` sebenarnya tidak melakukan apa-apa secara tidak sinkron. Akibatnya, callback mencoba mereferensikan `bar` even meskipun mungkin belum memiliki variabel itu dalam cakupannya, karena skripnya belum dapat berjalan sampai selesai. - -Dengan menempatkan callback dalam `process.nextTick()`, skrip masih memiliki kemampuan untuk menjalankan sampai selesai, memungkinkan semua variabel, fungsi, dll., untuk diinisialisasi sebelum panggilan balik dipanggil. Ini juga memiliki keuntungan dari tidak membiarkan loop acara berlanjut. Itu mungkin berguna bagi pengguna untuk diperingatkan akan kesalahan sebelum loop acara diperbolehkan untuk melanjutkan. Berikut adalah contoh sebelumnya menggunakan `process.nextTick()`: - -```js -let bar; - -function someAsyncApiCall(callback) { - process.nextTick(callback); -} - -someAsyncApiCall(() => { - console.log('bar', bar); // 1 -}); - -bar = 1; -``` - -Berikut contoh dunia nyata lainnya: - -```js -const server = net.createServer(() => {}).listen(8080); - -server.on('listening', () => {}); -``` - -Ketika hanya sebuah port yang dilewati, port tersebut langsung terikat. Sehingga `'mendengarkan'` panggilan balik dapat segera dipanggil. Masalahnya adalah bahwa `.on('listening')` panggilan balik tidak akan disetel pada saat itu. - -Untuk menyiasatinya, acara `'listening'` diantrekan di `nextTick()` untuk memungkinkan skrip berjalan hingga selesai. Ini memungkinkan pengguna untuk mengatur event handler yang mereka inginkan. - -## `process.nextTick()` vs `setImmediate()` - -Kami memiliki dua panggilan yang serupa sejauh menyangkut pengguna, tapi nama mereka membingungkan. - -- `process.nextTick()` langsung aktif pada fase yang sama -- `setImmediate()` diaktifkan pada iterasi berikut atau 'centang' dari lingkaran acara - -Intinya, nama harus ditukar. `process.nextTick()` mengaktifkan lebih banyak langsung dari `setImmediate()`, tetapi ini adalah artefak dari masa lalu yang tidak mungkin berubah. Membuat sakelar ini akan merusak banyak persentase paket di npm. Setiap hari lebih banyak modul baru sedang tambah, yang berarti setiap hari kita menunggu, lebih banyak potensi kerusakan terjadi. Meskipun membingungkan, namanya sendiri tidak akan berubah. - -> Kami menyarankan pengembang menggunakan `setImmediate()` dalam semua kasus karena ini lebih mudah untuk dipikirkan. - -## Mengapa menggunakan `process.nextTick()`? - -Ada dua alasan utama: - -1. Izinkan pengguna untuk menangani kesalahan, membersihkan sumber daya yang tidak diperlukan, atau mungkin coba permintaan lagi sebelum loop acara berlanjut. - -2. Kadang-kadang perlu untuk mengizinkan panggilan balik berjalan setelah panggilan stack telah dibatalkan tetapi sebelum loop acara berlanjut. - -Salah satu contohnya adalah agar sesuai dengan harapan pengguna. Contoh sederhana: - -```js -const server = net.createServer(); -server.on('connection', conn => {}); - -server.listen(8080); -server.on('listening', () => {}); -``` - -Katakan bahwa `listen()` dijalankan di awal loop acara, tetapi mendengarkan panggilan balik ditempatkan di `setImmediate()`. Kecuali a nama host dilewatkan, pengikatan ke port akan segera terjadi. Untuk loop acara untuk melanjutkan, itu harus mencapai fase **jajak pendapat**, yang berarti ada kemungkinan bukan nol bahwa koneksi dapat diterima memungkinkan acara koneksi dipecat sebelum acara mendengarkan. - -Contoh lain adalah mewarisi dari `EventEmitter` dan memancarkan acara dari dalam konstruktor: - -```js -const EventEmitter = require('events'); - -class MyEmitter extends EventEmitter { - constructor() { - super(); - this.emit('event'); - } -} - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('an event occurred!'); -}); -``` - -Anda tidak dapat langsung memancarkan acara dari konstruktor karena skrip tidak akan diproses ke titik di mana pengguna memberikan panggilan balik ke acara itu. Jadi, di dalam konstruktor itu sendiri, Anda dapat menggunakan `process.nextTick()` untuk menyetel panggilan balik untuk memancarkan acara setelah konstruktor selesai, yang memberikan hasil yang diharapkan: - -```js -const EventEmitter = require('events'); - -class MyEmitter extends EventEmitter { - constructor() { - super(); - - // use nextTick to emit the event once a handler is assigned - process.nextTick(() => { - this.emit('event'); - }); - } -} - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('an event occurred!'); -}); -``` - -[libuv]: https://libuv.org/ -[REPL]: https://nodejs.org/api/repl.html#repl_repl diff --git a/pages/id/docs/guides/getting-started-guide.md b/pages/id/docs/guides/getting-started-guide.md deleted file mode 100644 index 69f0f40476cb9..0000000000000 --- a/pages/id/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Panduan Memulai -layout: docs.hbs ---- - -# Bagaimana cara memulai dengan Node.js setelah saya menginstalnya? - -Setelah kita menginstal Node.js, mari kita buat server web pertama kita. Buat file bernama `app.js` yang berisi konten berikut: - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Halo Dunia'); -}); - -server.listen(port, hostname, () => { - console.log(`Server berjalan di http://${hostname}:${port}/`); -}); -``` - -Sekarang, jalankan server web Anda menggunakan `node app.js`. Kunjungi `http://localhost:3000` dan Anda akan melihat pesan yang mengatakan "Halo Dunia". - -Lihat [Pengantar Node.js](https://nodejs.dev/learn) untuk informasi lebih lanjut panduan komprehensif untuk memulai dengan Node.js. diff --git a/pages/id/docs/guides/index.md b/pages/id/docs/guides/index.md deleted file mode 100644 index 4d24b2867e3f6..0000000000000 --- a/pages/id/docs/guides/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Panduan -layout: docs.hbs ---- - -# Panduan - -## Umum - -- [Panduan Memulai](/en/docs/guides/getting-started-guide/) -- [Debugging - Memulai](/en/docs/guides/debugging-getting-started/) -- [Pembuatan profil mudah untuk Aplikasi Node.js](/en/docs/guides/simple-profiling/) -- [Diagnostik - Grafik Api](/en/docs/guides/diagnostics-flamegraph/) -- [Meng-docker aplikasi web Node.js](/en/docs/guides/nodejs-docker-webapp/) -- [Bermigrasi ke konstruktor Buffer yang aman](/en/docs/guides/buffer-constructor-deprecation/) -- [Diagnostika - Jurnal Pengguna](/en/docs/guides/diagnostics/) -- [Praktik Keamanan Terbaik](/en/docs/guides/security/) - -## Konsep inti Node.js - -- [Pengantar Node.js](https://nodejs.dev/en/learn/) -- [Ringkasan Pemblokiran vs Non-Pemblokiran](/en/docs/guides/blocking-vs-non-blocking/) -- [Loop Peristiwa Node.js, Timer, dan `process.nextTick()`](/en/docs/guides/event-loop-timers-and-nexttick/) -- [Jangan Blokir Event Loop (atau Worker Pool)](/en/docs/guides/dont-block-the-event-loop/) -- [Pengatur waktu di Node.js](/en/docs/guides/timers-in-node/) - -## Panduan terkait modul - -- [Anatomi Transaksi HTTP](/en/docs/guides/anatomy-of-an-http-transaction/) -- [Bekerja dengan Sistem File Berbeda](/en/docs/guides/working-with-different-filesystems/) -- [Tekanan Balik dalam Aliran](/en/docs/guides/backpressuring-in-streams/) -- [Postmortem Modul Domain](/en/docs/guides/domain-postmortem/) -- [Cara mempublikasikan paket N-API](/en/docs/guides/publishing-napi-modules/) -- [Stabilitas ABI](/en/docs/guides/abi-stability/) diff --git a/pages/id/docs/guides/nodejs-docker-webapp.md b/pages/id/docs/guides/nodejs-docker-webapp.md deleted file mode 100644 index 9f590416c2dc5..0000000000000 --- a/pages/id/docs/guides/nodejs-docker-webapp.md +++ /dev/null @@ -1,251 +0,0 @@ ---- -title: Meng-docker aplikasi web Node.js -layout: docs.hbs ---- - -# Meng-docker aplikasi web Node.js - -Tujuan dari contoh ini adalah untuk menunjukkan kepada Anda cara memasukkan aplikasi Node.js ke dalam Docker Container. Panduan ini ditujukan untuk pengembangan, dan _bukan_ untuk penerapan produksi. Panduan ini juga mengasumsikan Anda memiliki Panduan ini juga mengasumsikan Anda memiliki [Instalasi Docker](https://docs.docker.com/engine/installation/) yang berfungsi dan dasar pemahaman tentang bagaimana aplikasi Node.js terstruktur. - -Di bagian pertama panduan ini kita akan membuat aplikasi web sederhana di Node.js, lalu kita akan membangun image Docker untuk aplikasi itu, dan terakhir kita akan membuat instance container dari image itu. - -Docker memungkinkan Anda untuk mengemas aplikasi dengan lingkungannya dan semua dependensinya ke dalam "kotak", yang disebut container. Biasanya, container terdiri dari aplikasi yang berjalan dalam versi sistem operasi Linux yang dilucuti ke dasar. Image adalah cetak biru untuk container, container adalah instance image yang sedang berjalan. - -## Buat aplikasi Node.js - -Pertama, buat direktori baru tempat semua file akan hidup. Di direktori ini buat file `package.json` yang menjelaskan aplikasi Anda dan dependensinya: - -```json -{ - "name": "docker_web_app", - "version": "1.0.0", - "description": "Node.js on Docker", - "author": "First Last ", - "main": "server.js", - "scripts": { - "start": "node server.js" - }, - "dependencies": { - "express": "^4.18.2" - } -} -``` - -Dengan file `package.json` baru Anda, jalankan `npm install`. Jika Anda menggunakan `npm` versi 5 atau lebih baru, ini akan menghasilkan file `package-lock.json` yang akan disalin ke image Docker Anda. - -Kemudian, buat file `server.js` yang mendefinisikan aplikasi web menggunakan Kerangka kerja [Express.js](https://expressjs.com/): - -```javascript -'use strict'; - -const express = require('express'); - -// Constants -const PORT = 8080; -const HOST = '0.0.0.0'; - -// App -const app = express(); -app.get('/', (req, res) => { - res.send('Hello World'); -}); - -app.listen(PORT, HOST); -console.log(`Running on http://${HOST}:${PORT}`); -``` - -Pada langkah selanjutnya, kita akan melihat bagaimana Anda dapat menjalankan aplikasi ini di dalam Docker container menggunakan image Docker resmi. Pertama, Anda harus membangun Docker image pada aplikasi Anda. - -## Membuat Dockerfile - -Buat file kosong bernama `Dockerfile`: - -```markup -touch Dockerfile -``` - -Buka `Dockerfile` di editor teks favorit Anda - -Hal pertama yang perlu kita lakukan adalah menentukan dari gambar apa kita ingin membangun. Di sini kita akan menggunakan versi terbaru LTS (dukungan jangka panjang) `18` dari `node` tersedia dari [Docker Hub](https://hub.docker.com/_/node): - -```docker -FROM node:18 -``` - -Selanjutnya kita membuat direktori untuk menyimpan kode aplikasi di dalam image, ini akan menjadi direktori kerja untuk aplikasi Anda: - -```docker -# Create app directory -WORKDIR /usr/src/app -``` - -Image ini dilengkapi dengan Node.js dan NPM yang sudah terpasang, jadi hal berikutnya yang kami lakukan yang perlu dilakukan adalah menginstal dependensi aplikasi Anda menggunakan biner `npm`. Silahkan perhatikan bahwa jika Anda menggunakan `npm` versi 4 atau sebelumnya, `package-lock.json` file _tidak_ akan dihasilkan. - -```docker -# Menginstal dependensi aplikasi -# Wildcard digunakan untuk memastikan package.json DAN package-lock.json disalin -# jika tersedia (npm@5+) -COPY package*.json ./ - -RUN npm install -# Jika Anda membangun kode untuk produksi -# Jalankan npm ci --omit=dev -``` - -Perhatikan bahwa, daripada menyalin seluruh direktori kerja, kami hanya menyalin berkas `package.json`. Ini memungkinkan kami untuk memanfaatkan Docker yang di-cache lapisan. bitJudo memiliki penjelasan yang bagus tentang ini [di sini](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/). Selanjutnya, perintah `npm ci`, yang ditentukan dalam komentar, membantu menyediakan build yang lebih cepat, andal, dan dapat direproduksi untuk lingkungan produksi. Anda dapat membaca lebih lanjut tentang ini [di sini](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable). - -Untuk menggabungkan kode sumber aplikasi Anda di dalam Docker image, gunakan `COPY` petunjuk: - -```docker -# Bundle app source -COPY . . -``` - -Aplikasi Anda mengikat ke port `8080` sehingga Anda akan menggunakan instruksi `EXPOSE` untuk memetakannya oleh daemon `docker`: - -```docker -EXPOSE 8080 -``` - -Terakhir, tetapi tidak kalah penting, tentukan perintah untuk menjalankan aplikasi Anda menggunakan `CMD` yang mendefinisikan runtime Anda. Di sini kita akan menggunakan `node server.js` untuk memulai server Anda: - -```docker -CMD [ "node", "server.js" ] -``` - -`Dockerfile` Anda sekarang akan terlihat seperti ini: - -```docker -FROM node:18 - -# Buat direktori aplikasi -WORKDIR /usr/src/app - -# Instal dependensi aplikasi -# Wildcard digunakan untuk memastikan package.json DAN package-lock.json disalin -# jika tersedia (npm@5+) -COPY package*.json ./ - -RUN npm install -# Jika Anda membangun kode untuk produksi -# RUN npm ci --omit=dev - -# Bundle app source -COPY . . - -EXPOSE 8080 -CMD [ "node", "server.js" ] -``` - -## .dockerignore file - -Buat file `.dockerignore` di direktori yang sama dengan `Dockerfile` Anda dengan konten berikut: - -``` -node_modules -npm-debug.log -``` - -Ini akan mencegah modul lokal dan log debug Anda disalin ke Image Docker dan mungkin menimpa modul yang dipasang di dalam image Anda. - -## Membangun citra Anda - -Buka direktori yang memiliki `Dockerfile` Anda dan jalankan perintah berikut untuk membangun Docker image. Penanda `-t` memungkinkan Anda menandai image Anda sehingga lebih mudah untuk temukan nanti menggunakan perintah `docker images` berikut: - -```bash -docker build . -t /node-web-app -``` - -Image Anda sekarang akan terdaftar oleh Docker: - -```bash -$ docker images - -# Example -REPOSITORY TAG ID CREATED -node 18 78b037dbb659 2 weeks ago -/node-web-app latest d64d3505b0d2 1 minute ago -``` - -## Jalankan image - -Menjalankan image Anda dengan `-d` akan menjalankan container dalam mode terpisah, meninggalkan container berjalan di latar belakang. Penanda`-p` mengalihkan port publik ke port pribadi di dalam container. Jalankan image yang Anda buat sebelumnya: - -```bash -docker run -p 49160:8080 -d /node-web-app -``` - -Hasil output aplikasi Anda: - -```bash -# Get container ID -$ docker ps - -# Print app output -$ docker logs - -# Example -Running on http://localhost:8080 -``` - -Jika Anda perlu masuk ke dalam container, Anda dapat menggunakan perintah `exec`: - -```bash -# Enter the container -$ docker exec -it /bin/bash -``` - -## Uji - -Untuk menguji aplikasi Anda, dapatkan port aplikasi Anda yang dipetakan oleh Docker: - -```bash -$ docker ps - -# Example -ID IMAGE COMMAND ... PORTS -ecce33b30ebf /node-web-app:latest npm start ... 49160->8080 -``` - -Pada contoh di atas, Docker memetakan port `8080` di dalam container untuk port `49160` pada mesin Anda. - -Sekarang Anda dapat memanggil aplikasi Anda menggunakan `curl` (install diperlukan melalui: `sudo apt-get -install curl`): - -```bash -$ curl -i localhost:49160 - -HTTP/1.1 200 OK -X-Powered-By: Express -Content-Type: text/html; charset=utf-8 -Content-Length: 12 -ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0" -Date: Mon, 13 Nov 2017 20:53:59 GMT -Connection: keep-alive - -Hello world -``` - -## Matikan image - -Untuk mematikan aplikasi yang kami mulai, kami menjalankan perintah `kill`. Ini memerlukan ID container, sebagai contoh kami mendapatkan ID container:`ecce33b30ebf`. - -```bash -# Kill our running container -$ docker kill - - -# Confirm that the app has stopped -$ curl -i localhost:49160 -curl: (7) Failed to connect to localhost port 49160: Connection refused -``` - -Kami harap tutorial ini membantu Anda membuat dan menjalankan aplikasi Node.js sederhana di Docker. - -Anda dapat menemukan informasi lebih lanjut tentang Docker dan Node.js di Docker di tempat-tempat berikut: - -- [Docker image Node.js Resmi](https://hub.docker.com/_/node/) -- [Panduan Praktik Terbaik Docker Node.js](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md) -- [Dokumentasi Docker Resmi](https://docs.docker.com/get-started/nodejs/build-images/) -- [Tag Docker di Stack Overflow](https://stackoverflow.com/questions/tagged/docker) -- [Subreddit Docker](https://reddit.com/r/docker) diff --git a/pages/id/docs/guides/publishing-napi-modules.md b/pages/id/docs/guides/publishing-napi-modules.md deleted file mode 100644 index a5bc665ef8ac1..0000000000000 --- a/pages/id/docs/guides/publishing-napi-modules.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Cara mempublikasikan paket N-API -layout: docs.hbs ---- - -# Untuk mempublikasikan versi N-API dari sebuah paket bersama dengan versi non-N-API - -Langkah-langkah berikut diilustrasikan menggunakan paket `iotivity-node`: - -- Pertama, publikasikan versi non-N-API: - - Perbarui versi di `package.json`. Untuk `iotivity-node`, versi menjadi `1.2.0-2`. - - Periksa daftar periksa rilis (pastikan tes/demo/dokumen baik-baik saja) - - `npm publish` -- Kemudian, publikasikan versi N-API: - - Perbarui versi di `package.json`. Dalam kasus `iotivity-node`, versi menjadi `1.2.0-3`. Untuk versi, kami sarankan mengikuti skema versi pra-rilis seperti yang dijelaskan oleh [semver.org](https://semver.org/#spec-item-9) mis. `1.2.0-napi`. - - Periksa daftar periksa rilis (pastikan tes/demo/dokumen baik-baik saja) - - `npm publish --tag n-api` - -Dalam contoh ini, menandai rilis dengan `n-api` telah memastikan bahwa, meskipun versi 1.2.0-3 lebih lambat dari versi yang diterbitkan non-N-API (1.2.0-2), itu tidak akan diinstal jika seseorang memilih untuk menginstal `iotivity-node` hanya dengan menjalankan `npm install iotivity-node`. Ini akan menginstal versi non-N-API secara default. Pengguna harus menjalankan `npm install iotivity-node@n-api` untuk menerima versi N-API. Untuk informasi lebih lanjut tentang penggunaan tag dengan npm, periksa out ["Menggunakan dist-tags"][]. - -## Untuk memperkenalkan ketergantungan pada versi N-API dari sebuah paket - -Untuk menambahkan versi N-API dari `iotivity-node` sebagai dependensi, Maka `package.json` akan terlihat seperti ini: - -```json -"dependencies": { - "iotivity-node": "n-api" -} -``` - -> Seperti yang dijelaskan dalam ["Menggunakan dist-tags"][], tidak seperti versi biasa, versi yang diberi tag tidak boleh ditangani oleh rentang versi seperti `"^2.0.0"` di dalam `package.json`. Itu alasannya adalah karena tag merujuk ke satu versi. Jadi, jika pengelola paket memilih untuk menandai versi paket yang lebih baru menggunakan tag yang sama, `npm update` akan menerima versi yang lebih baru. Ini harus diterima mengingat sifat eksperimental N-API saat ini. Untuk bergantung pada N-API-enabled versi selain yang terbaru diterbitkan, ketergantungan `package.json` akan harus merujuk ke versi persis seperti berikut: - -```json -"dependencies": { - "iotivity-node": "1.2.0-3" -} -``` - -["Menggunakan dist-tags"]: https://docs.npmjs.com/getting-started/using-tags diff --git a/pages/id/docs/guides/security/index.md b/pages/id/docs/guides/security/index.md deleted file mode 100644 index e54c456030933..0000000000000 --- a/pages/id/docs/guides/security/index.md +++ /dev/null @@ -1,322 +0,0 @@ ---- -title: Praktik Terbaik Keamanan Node.js -layout: docs.hbs ---- - -# Praktik Terbaik Keamanan Node.js - -## Maksud - -Dokumen ini bermaksud untuk memperluas [model ancaman][] saat ini dan memberikan pedoman yang ekstensif tentang cara mengamankan aplikasi Node.js. - -## Isi Dokumen - -- Praktik terbaik: Cara ringkas dan mudah untuk melihat praktik terbaik. Kami dapat menggunakan [masalah ini][security guidance issue] atau [panduan ini][nodejs guideline] sebagai titik awal. Penting untuk dicatat bahwa dokumen ini khusus untuk Node.js, jika Anda mencari sesuatu yang luas, pertimbangkan [Praktik Terbaik OSSF][]. -- Enjelasan serangan: Menjelaskan dan mendokumentasikan dengan bahasa yang jelas dan contoh kode (jika memungkinkan) serangan yang disebutkan dalam model ancaman. -- Pustaka Pihak Ketiga: Mendefinisikan ancaman (serangan typo-squatting, paket berbahaya...) dan praktik terbaik sehubungan dengan dependensi modul node, dll... - -## Daftar Ancaman - -### Denial of Service dari server HTTP (CWE-400) - -Ini adalah serangan di mana aplikasi menjadi tidak tersedia untuk tujuan yang dirancang karena cara memproses permintaan HTTP yang masuk. Permintaan ini tidak perlu sengaja dibuat oleh pelaku jahat: klien yang dikonfigurasi atau bermasalah juga dapat mengirim pola permintaan ke server yang mengakibatkan penolakan layanan. - -Permintaan HTTP diterima oleh server HTTP Node.js dan diserahkan ke kode aplikasi melalui handler permintaan yang terdaftar. Server tidak mem-parsing isi dari badan permintaan. Oleh karena itu, setiap DoS yang disebabkan oleh isi dari badan permintaan setelah diserahkan ke handler permintaan bukanlah kerentanan dalam Node.js itu sendiri, karena tanggung jawab kode aplikasi untuk menanganinya dengan benar. - -Pastikan bahwa WebServer menangani kesalahan soket dengan benar, misalnya, ketika server dibuat tanpa penanganan kesalahan, maka akan rentan terhadap DoS - -```js -const net = require('net'); - -const server = net.createServer(function (socket) { - // socket.on('error', console.error) // ini mencegah server menjadi crash - socket.write('Echo server\r\n'); - socket.pipe(socket); -}); - -server.listen(5000, '0.0.0.0'); -``` - -Jika _permintaan buruk_ dilakukan, server dapat menjadi crash. - -Contoh serangan DoS yang tidak disebabkan oleh isi permintaan adalah [Slowloris][]. Pada serangan ini, permintaan HTTP dikirim secara perlahan-lahan dan terfragmentasi, satu fragmen pada satu waktu. Sampai permintaan lengkap diterima, server akan menahan sumber daya yang diperuntukkan untuk permintaan tersebut. Jika cukup banyak permintaan seperti ini dikirim pada waktu yang sama, jumlah koneksi simultan akan segera mencapai maksimumnya sehingga mengakibatkan serangan DoS. Inilah sebabnya mengapa serangan ini tidak bergantung pada isi permintaan, tetapi pada waktu dan pola permintaan yang dikirim ke server. - -**Pengendalian** - -- Gunakan reverse proxy untuk menerima dan meneruskan permintaan ke aplikasi Node.js. Reverse proxies dapat menyediakan caching, load balancing, IP blacklisting, dan sebagainya, yang mengurangi kemungkinan serangan DoS menjadi efektif. -- Konfigurasikan server timeouts dengan benar sehingga koneksi yang idle atau permintaan yang datang terlalu lambat dapat dijatuhkan. Lihat timeout yang berbeda pada [`http.Server`][], terutama `headersTimeout`, `requestTimeout`, `timeout`, dan `keepAliveTimeout`. -- Batasi jumlah soket terbuka per host dan secara keseluruhan. Lihat [dokumentasi http][], terutama `agent.maxSockets`, `agent.maxTotalSockets`, `agent.maxFreeSockets`, dan `server.maxRequestsPerSocket`. - -### Pengikatan Ulang DNS (CWE-346) - -Ini adalah serangan yang dapat menargetkan aplikasi Node.js yang dijalankan dengan inspektor debugging diaktifkan menggunakan [--inspect switch][]. - -Karena situs web yang dibuka di browser web dapat membuat permintaan WebSocket dan HTTP, mereka dapat menargetkan inspektor debugging yang berjalan secara lokal. Hal ini biasanya dicegah oleh [same-origin policy][] yang diterapkan oleh browser modern, yang melarang skrip dari mencapai sumber daya dari asal yang berbeda (yang berarti situs web jahat tidak dapat membaca data yang diminta dari alamat IP lokal). - -Namun, melalui DNS rebinding, penyerang dapat sementara mengendalikan asal untuk permintaan mereka sehingga mereka tampak berasal dari alamat IP lokal. Ini dilakukan dengan mengendalikan baik situs web maupun server DNS yang digunakan untuk menyelesaikan alamat IP-nya. Lihat [DNS Rebinding wiki][] untuk lebih detail. - -**Pengurangan Risiko** - -- Matikan inspektor pada sinyal _SIGUSR1_ dengan melekatkan pendengar `process.on('SIGUSR1',...)` kepadanya. -- Jangan jalankan protokol inspektor di produksi. - -### Pemaparan Informasi Sensitif kepada Pelaku yang Tidak Sah (CWE-552) - -Semua file dan folder yang terdapat pada direktori saat ini dimasukkan ke dalam registri npm selama publikasi paket. - -Terdapat beberapa mekanisme untuk mengontrol perilaku ini dengan menentukan daftar blokir dengan `.npmignore` dan `.gitignore` atau dengan menentukan daftar izin dalam `package.json` - -**Pengurangan Risiko** - -- Menggunakan `npm publish --dry-run` untuk melihat semua file yang akan dipublikasikan. Pastikan untuk meninjau kontennya sebelum menerbitkan paket. -- Juga penting untuk membuat dan menjaga file-file yang diabaikan seperti `.gitignore` dan `.npmignore`. Dalam file-file ini, Anda dapat menentukan file/folder mana yang tidak boleh dipublikasikan. [Properti file][] dalam `package.json` memungkinkan operasi sebaliknya -- allowed list. -- Jika terjadi pemaparan, pastikan untuk [membatalkan publikasi paket][]. - -### Pemalsuan Permintaan HTTP (CWE-444) - -Ini adalah serangan yang melibatkan dua server HTTP (biasanya proxy dan aplikasi Node.js). Klien mengirimkan permintaan HTTP yang pertama-tama melewati server front-end (proxy) dan kemudian diarahkan ke server back-end (aplikasi). Ketika front-end dan back-end menafsirkan permintaan HTTP yang ambigu dengan cara yang berbeda, maka ada potensi bagi penyerang untuk mengirimkan pesan berbahaya yang tidak akan terlihat oleh front-end tetapi akan terlihat oleh back-end, efektif "menyelundupkannya" melewati server proxy. - -Lihat [CWE-444][] untuk deskripsi yang lebih terperinci dan contoh-contohnya. - -Karena serangan ini tergantung pada Node.js menafsirkan permintaan HTTP secara berbeda dari server HTTP (acak) lainnya, serangan yang berhasil dapat disebabkan oleh kerentanan di Node.js, server front-end, atau keduanya. Jika cara permintaan diinterpretasikan oleh Node.js konsisten dengan spesifikasi HTTP (lihat [RFC7230][]), maka tidak dianggap sebagai kerentanan di Node.js. - -**Pengurangan Risiko** - -- Jangan gunakan opsi `insecureHTTPParser` saat membuat Server HTTP. -- Konfigurasikan server front-end untuk menormalkan permintaan yang ambigu. -- Terus memantau kerentanan penyelundupan permintaan HTTP baru di Node.js dan server front-end pilihan. -- Gunakan HTTP/2 ujung ke ujung dan nonaktifkan penurunan versi HTTP jika memungkinkan. - -### Paparan Informasi melalui Timing Attacks (CWE-208) - -Ini adalah serangan yang memungkinkan penyerang mempelajari informasi yang berpotensi sensitif dengan, misalnya, mengukur berapa lama waktu yang dibutuhkan aplikasi untuk merespons permintaan. Serangan ini tidak spesifik untuk Node.js dan dapat menargetkan hampir semua runtime. - -Serangan itu dimungkinkan setiap kali aplikasi menggunakan rahasia dalam operasi sensitif waktu (mis., Cabang). Pertimbangkan untuk menangani autentikasi dalam aplikasi tipikal. Di sini, metode autentikasi dasar menyertakan email dan kata sandi sebagai kredensial. Informasi pengguna diambil dari input yang disediakan pengguna dari DBMS idealnya. Setelah mengambil informasi pengguna, kata sandi dibandingkan dengan informasi pengguna yang diambil dari database. Menggunakan perbandingan string bawaan membutuhkan waktu lebih lama untuk nilai panjang yang sama. Perbandingan ini, ketika dijalankan untuk jumlah yang dapat diterima, dengan enggan meningkatkan waktu respons permintaan. Dengan membandingkan waktu respons permintaan, penyerang dapat menebak panjang dan nilai kata sandi dalam permintaan dalam jumlah besar. - -**Mitigasi** - -- Crypto API memperlihatkan fungsi `timingSafeEqual` untuk membandingkan nilai sensitif aktual dan yang diharapkan menggunakan algoritme waktu konstan. -- Untuk perbandingan kata sandi, Anda dapat menggunakan [scrypt][] yang tersedia juga di modul crypto asli. - -- Lebih umum, hindari penggunaan rahasia dalam operasi waktu variabel. Ini termasuk percabangan rahasia dan, ketika penyerang dapat ditempatkan bersama di infrastruktur yang sama (misalnya, mesin cloud yang sama), menggunakan rahasia sebagai indeks ke dalam memori. Menulis kode waktu konstan dalam JavaScript itu sulit (sebagian karena JIT). Untuk aplikasi kripto, gunakan API kripto atau WebAssembly bawaan (untuk algoritme yang tidak diterapkan secara asli). - -### Modul Pihak Ketiga Berbahaya (CWE-1357) - -Saat ini, di Node.js, paket apa pun dapat mengakses sumber daya yang kuat seperti akses jaringan. Selain itu, karena mereka juga memiliki akses ke sistem file, mereka dapat mengirimkan data apa saja ke mana saja. - -Semua kode yang berjalan ke proses node memiliki kemampuan untuk memuat dan menjalankan kode arbitrer tambahan dengan menggunakan `eval()`(atau yang setara). Semua kode dengan akses tulis sistem file dapat mencapai hal yang sama dengan menulis ke file baru atau yang sudah ada yang dimuat. - -Node.js memiliki [¹][experimental-features] [mekanisme kebijakan][] eksperimental untuk mendeklarasikan sumber daya yang dimuat sebagai tidak tepercaya atau tepercaya. Namun, kebijakan ini tidak diaktifkan secara default. Pastikan untuk menyematkan versi ketergantungan dan menjalankan pemeriksaan otomatis untuk kerentanan menggunakan alur kerja umum atau skrip npm. Sebelum menginstal paket, pastikan paket ini dipertahankan dan menyertakan semua konten yang Anda harapkan. Hati-hati, kode sumber Github tidak selalu sama dengan yang dipublikasikan, validasi di _node_modules_. - -#### Serangan rantai pasokan - -Serangan rantai suplai pada aplikasi Node.js terjadi ketika salah satu ketergantungannya (baik langsung atau transitif) terganggu. Hal ini dapat terjadi karena aplikasi terlalu lemah dalam spesifikasi dependensi (memungkinkan pembaruan yang tidak diinginkan) dan/atau kesalahan ketik umum dalam spesifikasi (rentan terhadap [typosquatting][]). - -Penyerang yang mengendalikan paket upstream dapat menerbitkan versi baru dengan kode berbahaya di dalamnya. Jika aplikasi Node.js bergantung pada paket itu tanpa ketat pada versi mana yang aman untuk digunakan, paket tersebut dapat diperbarui secara otomatis ke versi jahat terbaru, membahayakan aplikasi. - -Ketergantungan yang ditentukan dalam file `package.json` dapat memiliki nomor versi atau rentang yang tepat. Namun, saat menyematkan dependensi ke versi yang tepat, dependensi transitifnya tidak disematkan sendiri. Ini masih membuat aplikasi rentan terhadap pembaruan yang tidak diinginkan / tidak terduga. - -Vektor serangan yang mungkin terjadi: - -- Serangan salah ketik -- Keracunan Lockfile -- Pengelola yang dikompromikan -- Paket Berbahaya -- Kebingungan Ketergantungan - -**Mitigasi** - -- Cegah npm mengeksekusi skrip arbitrer dengan `--ignore-scripts` - - Selain itu, Anda dapat menonaktifkannya secara global dengan `npm config set quit-scripts true` -- Sematkan versi dependensi ke versi tetap tertentu, bukan versi yang merupakan rentang atau dari sumber yang dapat diubah. -- Gunakan lockfiles, yang menyematkan setiap ketergantungan (langsung dan transitif). - - Gunakan [Mitigasi untuk kerusakan lockfile][]. -- Otomatiskan pemeriksaan kerentanan baru menggunakan CI, dengan alat seperti [`npm-audit`][]. - - Alat seperti [`Socket`][] dapat digunakan untuk menganalisis paket dengan analisis statis untuk menemukan perilaku berisiko seperti akses jaringan atau sistem file. -- Gunakan [`npm ci`][] alih-alih ` instal npm`. Ini memaksa file kunci sehingga ketidakkonsistenan antara itu dan File _package.json_ menyebabkan kesalahan (alih-alih mengabaikan file kunci mendukung _package.json_). -- Periksa file _package.json_ dengan hati-hati untuk kesalahan/salah ketik pada nama dependencies. - -### Pelanggaran Akses Memori (CWE-284) - -Serangan berbasis memori atau berbasis tumpukan bergantung pada kombinasi kesalahan manajemen memori dan pengalokasi memori yang dapat dieksploitasi. Seperti semua runtime, Node.js rentan terhadap serangan ini jika proyek Anda berjalan di mesin bersama. Menggunakan heap yang aman berguna untuk mencegah kebocoran informasi sensitif karena pointer overruns dan underruns. - -Sayangnya, secure heap tidak tersedia di Windows. Informasi lebih lanjut dapat ditemukan di Node.js [dokumentasi secure-heap][]. - -**Mitigasi** - -- Gunakan `--secure-heap=n` bergantung pada aplikasi Anda di mana _n_ dialokasikan ukuran byte maksimum. -- Jangan menjalankan aplikasi produksi Anda di mesin bersama. - -### Penambalan Monyet (CWE-349) - -Penambalan monyet mengacu pada modifikasi properti dalam waktu proses yang bertujuan untuk mengubah perilaku yang ada. Contoh: - -```js -// eslint-disable-next-line no-extend-native -Array.prototype.push = function (item) { - // overriding the global [].push -}; -``` - -**Mitigasi** - -Bendera `--frozen-intrinsics` mengaktifkan intrinsik beku eksperimental[¹][experimental-features], yang berarti semua objek dan fungsi JavaScript bawaan dibekukan secara rekursif. Oleh karena itu, cuplikan berikut **tidak akan** menggantikan perilaku default `Array.prototype.push` - -```js -// eslint-disable-next-line no-extend-native -Array.prototype.push = function (item) { - // overriding the global [].push -}; - -// Uncaught: -// TypeError >>: -// Cannot assign to read only property 'push' of object '' -``` - -Namun, penting untuk disebutkan bahwa Anda masih dapat menentukan global baru dan mengganti global yang ada menggunakan `globalThis` - -```console -> globalThis.foo = 3; foo; // Anda masih bisa mendefinisikan global baru -3 -> globalIni.Array = 4; Himpunan; // Namun, Anda juga dapat mengganti global yang ada -4 -``` - -Oleh karena itu, `Object.freeze(globalThis)` dapat digunakan untuk menjamin tidak ada global yang akan diganti. - -### Prototipe Serangan Polusi (CWE-1321) - -Polusi prototipe mengacu pada kemungkinan untuk memodifikasi atau menyuntikkan properti ke item bahasa Javascript dengan menyalahgunakan penggunaan \_\_proto\__, \_constructor_, _prototype_, dan properti lain yang diwarisi dari prototipe bawaan. - - - -```js -const a = { a: 1, b: 2 }; -const data = JSON.parse('{"__proto__": { "polluted": true}}'); - -const c = Object.assign({}, a, data); -console.log(c.polluted); // true - -// Potential DoS -const data2 = JSON.parse('{"__proto__": null}'); -const d = Object.assign(a, data2); -d.hasOwnProperty('b'); // Uncaught TypeError: d.hasOwnProperty is not a function -``` - -Ini adalah kerentanan potensial yang diwarisi dari bahasa JavaScript. - -**Contoh**: - -- [CVE-2022-21824][] (Node.js) -- [CVE-2018-3721][] (Perpustakaan Pihak ke-3: Lodash) - -**Mitigasi** - -- Hindari [penggabungan rekursif tidak aman][], lihat [CVE-2018-16487][]. -- Terapkan validasi Skema JSON untuk permintaan eksternal/tidak tepercaya. -- Buat Objek tanpa prototipe dengan menggunakan `Object.create(null)`. -- Membekukan prototipe: `Object.freeze(MyObject.prototype)`. -- Nonaktifkan properti `Object.prototype.__proto__` menggunakan flag `--disable-proto`. -- Periksa apakah properti ada langsung pada objek, bukan dari prototipe menggunakan `Object.hasOwn(obj, keyFromObj)`. -- Hindari menggunakan metode dari `Object.prototype`. - -### Elemen Jalur Pencarian Tidak Terkontrol (CWE-427) - -Node.js memuat modul mengikuti [Module Resolution Algorithm][]. Oleh karena itu, ini mengasumsikan direktori di mana modul diminta (mengharuskan) dipercaya. - -Artinya, perilaku aplikasi berikut diharapkan. Dengan asumsi struktur direktori berikut: - -- _app/_ - - _server.js_ - - _auth.js_ - - _auth_ - -Jika server.js menggunakan `require('./auth')` ia akan mengikuti algoritme resolusi modul dan memuat _auth_ alih-alih _auth.js_. - -**Mitigasi** - -Menggunakan [¹][experimental-features] [mekanisme kebijakan dengan pemeriksaan integritas][] eksperimental dapat menghindari ancaman di atas. Untuk direktori yang dijelaskan di atas, seseorang dapat menggunakan `policy.json` berikut - -```json -{ - "resources": { - "./app/auth.js": { - "integrity": "sha256-iuGZ6SFVFpMuHUcJciQTIKpIyaQVigMZlvg9Lx66HV8=" - }, - "./app/server.js": { - "dependencies": { - "./auth": "./app/auth.js" - }, - "integrity": "sha256-NPtLCQ0ntPPWgfVEgX46ryTNpdvTWdQPoZO3kHo0bKI=" - } - } -} -``` - -Oleh karena itu, saat membutuhkan modul _auth_, sistem akan memvalidasi integritas dan menampilkan error jika tidak sesuai dengan yang diharapkan. - -```console -» node --experimental-policy=policy.json app/server.js -node:internal/policy/sri:65 - throw new ERR_SRI_PARSE(str, str[prevIndex], prevIndex); - ^ - -SyntaxError [ERR_SRI_PARSE]: Subresource Integrity string "sha256-iuGZ6SFVFpMuHUcJciQTIKpIyaQVigMZlvg9Lx66HV8=%" had an unexpected "%" at position 51 - at new NodeError (node:internal/errors:393:5) - at Object.parse (node:internal/policy/sri:65:13) - at processEntry (node:internal/policy/manifest:581:38) - at Manifest.assertIntegrity (node:internal/policy/manifest:588:32) - at Module._compile (node:internal/modules/cjs/loader:1119:21) - at Module._extensions..js (node:internal/modules/cjs/loader:1213:10) - at Module.load (node:internal/modules/cjs/loader:1037:32) - at Module._load (node:internal/modules/cjs/loader:878:12) - at Module.require (node:internal/modules/cjs/loader:1061:19) - at require (node:internal/modules/cjs/helpers:99:18) { - code: 'ERR_SRI_PARSE' -} -``` - -Perhatikan, selalu disarankan penggunaan `--policy-integrity` untuk menghindari mutasi kebijakan. - -## Fitur Eksperimental dalam Produksi - -Penggunaan fitur eksperimental dalam produksi tidak disarankan. Fitur eksperimental dapat mengalami perubahan besar jika diperlukan, dan fungsinya tidak stabil dengan aman. Meskipun, umpan balik sangat dihargai. - -## Alat OpenSSF - -[OpenSSF][] memimpin beberapa inisiatif yang bisa sangat berguna, terutama jika Anda berencana memublikasikan paket npm. Inisiatif tersebut meliputi: - -- [OpenSSF Scorecard][] Scorecard mengevaluasi project open source menggunakan serangkaian pemeriksaan risiko keamanan otomatis. Anda dapat menggunakannya untuk secara proaktif menilai kerentanan dan ketergantungan dalam basis kode Anda dan membuat keputusan yang matang tentang menerima kerentanan. -- [Program Badge Praktik Terbaik OpenSSF][] Project dapat secara sukarela melakukan sertifikasi mandiri dengan menjelaskan cara mereka mematuhi setiap praktik terbaik. Ini akan menghasilkan lencana yang dapat ditambahkan ke proyek. - -[model ancaman]: https://github.com/nodejs/node/security/policy#the-nodejs-threat-model -[security guidance issue]: https://github.com/nodejs/security-wg/issues/488 -[nodejs guideline]: https://github.com/goldbergyoni/nodebestpractices -[Praktik Terbaik OSSF]: https://github.com/ossf/wg-best-practices-os-developers -[Slowloris]: https://en.wikipedia.org/wiki/Slowloris_(computer_security) -[`http.Server`]: https://nodejs.org/api/http.html#class-httpserver -[dokumentasi http]: https://nodejs.org/api/http.html -[--inspect switch]: https://nodejs.org/en/docs/guides/debugging-getting-started/ -[same-origin policy]: https://nodejs.org/en/docs/guides/debugging-getting-started/ -[DNS Rebinding wiki]: https://en.wikipedia.org/wiki/DNS_rebinding -[Properti file]: https://docs.npmjs.com/cli/v8/configuring-npm/package-json#files -[membatalkan publikasi paket]: https://docs.npmjs.com/unpublishing-packages-from-the-registry -[CWE-444]: https://cwe.mitre.org/data/definitions/444.html -[RFC7230]: https://datatracker.ietf.org/doc/html/rfc7230#section-3 -[mekanisme kebijakan]: https://nodejs.org/api/permissions.html#policies -[typosquatting]: https://en.wikipedia.org/wiki/Typosquatting -[Mitigasi untuk kerusakan lockfile]: https://blog.ulisesgascon.com/lockfile-posioned -[`npm ci`]: https://docs.npmjs.com/cli/v8/commands/npm-ci -[dokumentasi secure-heap]: https://nodejs.org/dist/latest-v18.x/docs/api/cli.html#--secure-heapn -[CVE-2022-21824]: https://www.cvedetails.com/cve/CVE-2022-21824/ -[CVE-2018-3721]: https://www.cvedetails.com/cve/CVE-2018-3721/ -[penggabungan rekursif tidak aman]: https://gist.github.com/DaniAkash/b3d7159fddcff0a9ee035bd10e34b277#file-unsafe-merge-js -[CVE-2018-16487]: https://www.cve.org/CVERecord?id=CVE-2018-16487 -[scrypt]: https://nodejs.org/api/crypto.html#cryptoscryptpassword-salt-keylen-options-callback -[Module Resolution Algorithm]: https://nodejs.org/api/modules.html#modules_all_together -[mekanisme kebijakan dengan pemeriksaan integritas]: https://nodejs.org/api/permissions.html#integrity-checks -[experimental-features]: #experimental-features-in-production -[`Socket`]: https://socket.dev/ -[OpenSSF]: https://openssf.org/ -[OpenSSF Scorecard]: https://securityscorecards.dev/ -[Program Badge Praktik Terbaik OpenSSF]: https://bestpractices.coreinfrastructure.org/en diff --git a/pages/id/docs/guides/simple-profiling.md b/pages/id/docs/guides/simple-profiling.md deleted file mode 100644 index 5a0ee5923bb98..0000000000000 --- a/pages/id/docs/guides/simple-profiling.md +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: Pembuatan profil yang mudah untuk Aplikasi Node.js -layout: docs.hbs ---- - -# Pembuatan profil mudah untuk Aplikasi Node.js - -Ada banyak alat pihak ketiga yang tersedia untuk membuat profil aplikasi Node.js tetapi, dalam banyak kasus, opsi termudah adalah menggunakan profiler bawaan Node.js. Profiler bawaan menggunakan [profiler di dalam V8][] yang mengambil sampel tumpukan di interval reguler selama eksekusi program. Ini mencatat hasil ini sampel, bersama dengan peristiwa pengoptimalan penting seperti kompilasi jit, sebagai serangkaian kutu: - -``` -code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~ -code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~ -code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~ -code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub" -code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub" -``` - -Di masa lalu, Anda memerlukan kode sumber V8 untuk dapat menafsirkan kutu. Untungnya, alat telah diperkenalkan sejak Node.js 4.4.0 yang memfasilitasi konsumsi informasi ini tanpa membangun V8 secara terpisah dari sumbernya. Mari kita lihat bagaimana profiler bawaan dapat membantu memberikan wawasan tentang aplikasi pertunjukan. - -Untuk mengilustrasikan penggunaan profiler centang, kami akan bekerja dengan Express . sederhana aplikasi. Aplikasi kami akan memiliki dua penangan, satu untuk menambahkan pengguna baru ke sistem kami: - -```javascript -app.get('/newUser', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users[username]) { - return res.sendStatus(400); - } - - const salt = crypto.randomBytes(128).toString('base64'); - const hash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - users[username] = { salt, hash }; - - res.sendStatus(200); -}); -``` - -dan satu lagi untuk memvalidasi upaya otentikasi pengguna: - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || !users[username]) { - return res.sendStatus(400); - } - - const { salt, hash } = users[username]; - const encryptHash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - if (crypto.timingSafeEqual(hash, encryptHash)) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } -}); -``` - -_Harap dicatat bahwa ini BUKAN penangan yang disarankan untuk mengautentikasi pengguna di aplikasi Node.js Anda dan digunakan murni untuk tujuan ilustrasi. Anda tidak boleh mencoba merancang mekanisme otentikasi kriptografi Anda sendiri secara umum. Jauh lebih baik menggunakan solusi autentikasi yang sudah ada dan terbukti._ - -Sekarang asumsikan bahwa kami telah menerapkan aplikasi kami dan pengguna mengeluh tentang latensi tinggi pada permintaan. Kami dapat dengan mudah menjalankan aplikasi dengan profiler bawaan: - -``` -NODE_ENV=production node --prof app.js -``` - -dan letakkan beberapa beban di server menggunakan `ab` (ApacheBench): - -``` -curl -X GET "http://localhost:8080/newUser?username=matt&password=password" -ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password" -``` - -dan dapatkan output ab dari: - -``` -Concurrency Level: 20 -Time taken for tests: 46.932 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 5.33 [#/sec] (mean) -Time per request: 3754.556 [ms] (mean) -Time per request: 187.728 [ms] (mean, across all concurrent requests) -Transfer rate: 1.05 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 3755 - 66% 3804 - 75% 3818 - 80% 3825 - 90% 3845 - 95% 3858 - 98% 3874 - 99% 3875 - 100% 4225 (longest request) -``` - -Dari output ini, kami melihat bahwa kami hanya berhasil melayani sekitar 5 permintaan per detik dan rata-rata permintaan hanya membutuhkan waktu kurang dari 4 detik pulang pergi. Di sebuah contoh dunia nyata, kita bisa melakukan banyak pekerjaan di banyak fungsi atas nama dari permintaan pengguna tetapi bahkan dalam contoh sederhana kami, waktu kompilasi bisa hilang ekspresi reguler, menghasilkan garam acak, menghasilkan hash unik dari pengguna kata sandi, atau di dalam kerangka kerja Express itu sendiri. - -Karena kami menjalankan aplikasi kami menggunakan opsi `--prof`, file centang dibuat di direktori yang sama dengan aplikasi yang dijalankan secara lokal. Itu harus memiliki bentuk `isolate-0xnnnnnnnnnnnn-v8.log` (di mana `n` adalah digit). - -Untuk memahami file ini, kita perlu menggunakan prosesor centang yang dibundel dengan biner Node.js. Untuk menjalankan prosesor, gunakan flag `--prof-process`: - -``` -node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt -``` - -Membuka diproses.txt di editor teks favorit Anda akan memberi Anda beberapa perbedaan jenis informasi. File dipecah menjadi beberapa bagian yang rusak lagi sampai dengan bahasa. Pertama, kita melihat bagian ringkasan dan melihat: - -``` - [Summary]: - ticks total nonlib name - 79 0.2% 0.2% JavaScript - 36703 97.2% 99.2% C++ - 7 0.0% 0.0% GC - 767 2.0% Shared libraries - 215 0.6% Unaccounted -``` - -Ini memberitahu kita bahwa 97% dari semua sampel yang dikumpulkan terjadi dalam kode C++ dan itu saat melihat bagian lain dari output yang diproses, kita harus lebih memperhatikan untuk pekerjaan yang dilakukan di C++ (sebagai lawan dari JavaScript). Dengan mengingat hal ini, kita selanjutnya temukan bagian \[C++\] yang berisi informasi tentang fungsi C++ yang mana mengambil waktu CPU paling banyak dan lihat: - -``` - [C++]: - ticks total nonlib name - 19557 51.8% 52.9% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 4510 11.9% 12.2% _sha1_block_data_order - 3165 8.4% 8.6% _malloc_zone_malloc -``` - -Kami melihat bahwa 3 entri teratas menyumbang 72,1% dari waktu CPU yang diambil oleh program. Dari output ini, kita langsung melihat bahwa setidaknya 51,8% dari waktu CPU adalah diambil oleh fungsi yang disebut PBKDF2 yang sesuai dengan generasi hash kami dari kata sandi pengguna. Namun, mungkin tidak segera jelas bagaimana yang lebih rendah dua faktor entri ke dalam aplikasi kami (atau jika ya, kami akan berpura-pura sebaliknya demi contoh). Untuk lebih memahami hubungan antara ini fungsi, selanjutnya kita akan melihat bagian \[Profil bawah (berat)\] yang memberikan informasi tentang pemanggil utama dari setiap fungsi. Memeriksa ini bagian, kami menemukan: - -``` - ticks parent name - 19557 51.8% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 19557 100.0% v8::internal::Builtins::~Builtins() - 19557 100.0% LazyCompile: ~pbkdf2 crypto.js:557:16 - - 4510 11.9% _sha1_block_data_order - 4510 100.0% LazyCompile: *pbkdf2 crypto.js:557:16 - 4510 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 - - 3165 8.4% _malloc_zone_malloc - 3161 99.9% LazyCompile: *pbkdf2 crypto.js:557:16 - 3161 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 -``` - -Parsing bagian ini membutuhkan sedikit lebih banyak pekerjaan daripada jumlah centang mentah di atas. Dalam setiap "tumpukan panggilan" di atas, persentase di kolom induk memberi tahu Anda persentase sampel yang fungsinya pada baris di atas adalah dipanggil oleh fungsi di baris saat ini. Misalnya, di tengah "panggilan stack" di atas untuk \_sha1_block_data_order, kita melihat bahwa `_sha1_block_data_order` terjadi di 11,9% sampel, yang kami ketahui dari jumlah mentah di atas. Namun, di sini, kami juga dapat mengatakan bahwa itu selalu dipanggil oleh fungsi pbkdf2 di dalam Modul kripto Node.js. Kami melihat bahwa dengan cara yang sama, `_malloc_zone_malloc` dipanggil hampir secara eksklusif oleh fungsi pbkdf2 yang sama. Jadi, dengan menggunakan informasi dalam tampilan ini, kami dapat mengetahui bahwa perhitungan hash kami dari kata sandi pengguna menyumbang tidak hanya untuk 51,8% dari atas tetapi juga untuk semua waktu CPU di atas 3 fungsi yang paling banyak sampelnya sejak panggilan ke `_sha1_block_data_order` dan `_malloc_zone_malloc` dibuat atas nama fungsi pbkdf2. - -Pada titik ini, sangat jelas bahwa pembuatan hash berbasis kata sandi harus menjadi target optimasi kami. Untungnya, Anda telah sepenuhnya menginternalisasi [manfaat pemrograman asinkron][] dan Anda menyadari bahwa bekerja untuk menghasilkan hash dari kata sandi pengguna sedang dilakukan dengan cara yang sinkron dan sehingga mengikat loop acara. Ini mencegah kami untuk mengerjakan entri lain permintaan saat menghitung hash. - -Untuk mengatasi masalah ini, Anda membuat sedikit modifikasi pada penangan di atas untuk digunakan versi asinkron dari fungsi pbkdf2: - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || !users[username]) { - return res.sendStatus(400); - } - - crypto.pbkdf2( - password, - users[username].salt, - 10000, - 512, - 'sha512', - (err, hash) => { - if (users[username].hash.toString() === hash.toString()) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } - } - ); -}); -``` - -Benchmark ab yang baru dijalankan di atas dengan versi asinkron aplikasi Anda hasil: - -``` -Concurrency Level: 20 -Time taken for tests: 12.846 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 19.46 [#/sec] (mean) -Time per request: 1027.689 [ms] (mean) -Time per request: 51.384 [ms] (mean, across all concurrent requests) -Transfer rate: 3.82 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 1018 - 66% 1035 - 75% 1041 - 80% 1043 - 90% 1049 - 95% 1063 - 98% 1070 - 99% 1071 - 100% 1079 (longest request) -``` - -YEEEY! Aplikasi Anda sekarang melayani sekitar 20 permintaan per detik, kira-kira 4 kali lebih banyak dibandingkan dengan generasi hash sinkron. Selain itu, rata-rata latensi turun dari 4 detik sebelumnya menjadi lebih dari 1 detik. - -Semoga melalui investigasi kinerja ini (diakui dibikin) contoh, Anda telah melihat bagaimana prosesor tick V8 dapat membantu Anda mendapatkan yang lebih baik pemahaman tentang kinerja aplikasi Node.js Anda. - -Anda juga dapat menemukan [bagaimana untuk membuat grafik nyala][flamegraph diagnostik] bermanfaat. - -[profiler di dalam V8]: https://v8.dev/docs/profile -[manfaat pemrograman asinkron]: https://nodesource.com/blog/why-asynchronous -[flamegraph diagnostik]: /id/docs/guides/diagnostics-flamegraph/ diff --git a/pages/id/docs/guides/timers-in-node.md b/pages/id/docs/guides/timers-in-node.md deleted file mode 100644 index f7c12839bee7b..0000000000000 --- a/pages/id/docs/guides/timers-in-node.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Timer di Node.js -layout: docs.hbs ---- - -# Timer di Node.js dan seterusnya - -Modul Timer di Node.js berisi fungsi yang mengeksekusi kode setelah satu set periode waktu. Timer tidak perlu diimpor melalui `require()`, karena semua metode tersedia secara global untuk meniru browser JavaScript API. Untuk memahami sepenuhnya kapan fungsi pengatur waktu akan dijalankan, ada baiknya untuk baca di Node.js [Event Loop](/id/docs/guides/event-loop-timers-and-nexttick/). - -## Mengontrol Kontinuum Waktu dengan Node.js - -API Node.js menyediakan beberapa cara untuk mengeksekusi kode penjadwalan di beberapa titik setelah saat ini. Fungsi di bawah ini mungkin tampak familier, karena tersedia di sebagian besar browser, tetapi Node.js sebenarnya menyediakan implementasi sendiri dari metode ini. Pengatur waktu terintegrasi dengan sangat erat dengan sistem, dan terlepas dari kenyataan bahwa API mencerminkan browser API, ada beberapa perbedaan dalam implementasi. - -### Eksekusi "Ketika saya mengatakannya" ~ _`setTimeout()`_ - -`setTimeout()` dapat digunakan untuk menjadwalkan eksekusi kode setelah ditentukan jumlah milidetik. Fungsi ini mirip dengan [`window.setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) dari browser JavaScript API, namun string kode tidak dapat diteruskan Akan dieksekusi. - -`setTimeout()` menerima fungsi untuk dieksekusi sebagai argumen pertama dan penundaan milidetik didefinisikan sebagai angka sebagai argumen kedua. Tambahan argumen juga dapat disertakan dan ini akan diteruskan ke fungsi. Di Sini adalah contohnya: - -```js -function myFunc(arg) { - console.log(`arg was => ${arg}`); -} - -setTimeout(myFunc, 1500, 'funky'); -``` - -Fungsi di atas `myFunc()` akan dieksekusi mendekati 1500 milidetik (atau 1,5 detik) mungkin karena panggilan `setTimeout()`. - -Interval batas waktu yang diatur tidak dapat diandalkan untuk dieksekusi setelahnya jumlah milidetik yang _tepat_ itu. Ini karena kode pelaksana lain yang memblokir atau menahan loop acara akan mendorong eksekusi batas waktu kembali. _Satu-satunya_ jaminan adalah bahwa batas waktu tidak akan dijalankan _lebih cepat_ dari interval waktu habis yang dideklarasikan. - -`setTimeout()` mengembalikan objek `Timeout` yang dapat digunakan untuk mereferensikan batas waktu yang telah ditetapkan. Objek yang dikembalikan ini dapat digunakan untuk membatalkan batas waktu ( lihat `clearTimeout()` di bawah) serta ubah perilaku eksekusi (lihat `unref()` di bawah). - -### Eksekusi "Tepat setelah ini" ~ _`setImmediate()`_ - -`setImmediate()` akan mengeksekusi kode di akhir siklus loop peristiwa saat ini. Kode ini akan mengeksekusi _setelah_ setiap operasi I/O dalam loop peristiwa saat ini dan _sebelum_ setiap pengatur waktu yang dijadwalkan untuk loop acara berikutnya. Eksekusi kode ini dapat dianggap terjadi "tepat setelah ini", yang berarti kode apa pun mengikuti pemanggilan fungsi `setImmediate()` akan dijalankan sebelum `setImmediate()` argumen fungsi. - -Argumen pertama untuk `setImmediate()` akan menjadi fungsi yang akan dieksekusi. Setiap argumen berikutnya akan diteruskan ke fungsi saat dijalankan. Berikut ini contohnya: - -```js -console.log('sebelum langsung'); - -setImmediate(arg => { - console.log(`executing immediate: ${arg}`); -}, 'so immediate'); - -console.log('setelah segera'); -``` - -Fungsi di atas yang diteruskan ke `setImmediate()` akan dijalankan setelah semua dapat dijalankan kode telah dieksekusi, dan output konsol adalah: - -``` -sebelum segera -setelah segera -mengeksekusi segera: sangat segera -``` - -`setImmediate()` mengembalikan objek `Immediate`, yang dapat digunakan untuk membatalkan segera yang dijadwalkan (lihat `clearImmediate()` di bawah). - -> Jangan bingung `setImmediate()` dengan `process.nextTick()`. Ada beberapa cara utama mereka berbeda. Yang pertama adalah `process.nextTick()` akan berjalan _sebelum_ setiap `Immediate`s yang disetel serta sebelum I/O terjadwal. Yang kedua adalah bahwa `process.nextTick()` tidak dapat dihapus, artinya sekali kode telah dijadwalkan untuk dieksekusi dengan `process.nextTick()`, eksekusi tidak bisa dihentikan, sama seperti fungsi normal. [Lihat panduan](/id/docs/guides/event-loop-timers-and-nexttick/#process-nexttick) ini untuk lebih memahami pengoperasian `process.nextTick()`. - -### Eksekusi "Loop Tak Terbatas" ~ _`setInterval()`_ - -Jika ada blok kode yang harus dijalankan beberapa kali, `setInterval()` dapat digunakan untuk mengeksekusi kode tersebut. `setInterval()` mengambil fungsi argumen yang akan dijalankan berkali-kali dengan milidetik yang diberikan delay sebagai argumen kedua. Sama seperti `setTimeout()`, argumen tambahan dapat ditambahkan melampaui penundaan, dan ini akan diteruskan ke panggilan fungsi. Juga seperti `setTimeout()`, penundaan tidak dapat dijamin karena operasi yang mungkin berpegang pada loop acara, dan karena itu harus diperlakukan sebagai perkiraan penundaan. Lihat contoh di bawah ini: - -```js -function intervalFunc() { - console.log('Cant stop me now!'); -} - -setInterval(intervalFunc, 1500); -``` - -Dalam contoh di atas, `intervalFunc()` akan dieksekusi setiap 1500 milidetik, atau 1,5 detik, hingga berhenti (lihat di bawah). - -Sama seperti `setTimeout()`, `setInterval()` juga mengembalikan `Timeout` objek yang dapat digunakan untuk referensi dan memodifikasi interval yang telah ditetapkan. - -## Membersihkan Masa Depan - -Apa yang dapat dilakukan jika objek `Timeout` atau `Immediate` perlu dibatalkan? `setTimeout()`, `setImmediate()`, dan `setInterval()` mengembalikan objek pengatur waktu yang dapat digunakan untuk mereferensikan objek `Timeout` atau `Immediate` yang ditetapkan. Dengan meneruskan objek tersebut ke fungsi `clear` masing-masing, eksekusi objek itu akan dihentikan sama sekali. Fungsi masing-masing adalah `clearTimeout()`, `clearImmediate()`, dan `clearInterval()`. Lihat contohnya di bawah ini untuk contoh masing-masing: - -```js -const timeoutObj = setTimeout(() => { - console.log('Batas waktu melampaui waktu'); -}, 1500); - -const immediateObj = setImmediate(() => { - console.log('Segera mengeksekusi segera'); -}); - -const intervalObj = setInterval(() => { - console.log('Mewawancarai interval'); -}, 500); - -clearTimeout(timeoutObj); -clearImmediate(immediateObj); -clearInterval(intervalObj); -``` - -## Meninggalkan Timeout di Belakang - -Ingat bahwa objek `Timeout` dikembalikan oleh `setTimeout` dan `setInterval`. Objek `Timeout` menyediakan dua fungsi yang dimaksudkan untuk menambah `Timeout` perilaku dengan `unref()` dan `ref()`. Jika ada objek `Timeout` yang dijadwalkan menggunakan fungsi `set`, `unref()` dapat dipanggil pada objek tersebut. Ini akan berubah perilaku sedikit, dan tidak memanggil objek `Timeout` _ jika itu yang terakhir kode untuk dieksekusi_. Objek `Timeout` tidak akan membuat proses tetap hidup, menunggu untuk mengeksekusi. - -Dengan cara yang sama, objek `Timeout` yang memiliki `unref()` memanggilnya dapat menghapus perilaku itu dengan memanggil `ref()` pada objek `Timeout` yang sama, yang kemudian akan memastikan eksekusinya. Sadarilah, bagaimanapun, bahwa ini tidak tidak _tepat_ mengembalikan perilaku awal karena alasan kinerja. Melihat di bawah ini untuk contoh keduanya: - -```js -const timerObj = setTimeout(() => { - console.log('akan saya jalankan?'); -}); - -// jika dibiarkan saja, pernyataan ini akan mempertahankan yang di atas -// timeout dari berjalan, karena timeout akan menjadi satu-satunya -// hal yang mencegah program keluar -timerObj.unref(); - -// kita bisa menghidupkannya kembali dengan memanggil ref() di dalam -// segera -setImmediate(() => { - timerObj.ref(); -}); -``` - -## Lebih Jauh ke Bawah Loop Acara - -Ada lebih banyak lagi untuk Loop dan Timer Acara daripada panduan ini telah menutupi. Untuk mempelajari lebih lanjut tentang internal Node.js Loop Peristiwa dan bagaimana Pengatur Waktu beroperasi selama eksekusi, lihat panduan Node.js ini: [Loop Peristiwa Node.js, Pengatur Waktu, dan process.nextTick()](/id/docs/guides/event-loop-timers-and-nexttick/). diff --git a/pages/id/docs/guides/working-with-different-filesystems.md b/pages/id/docs/guides/working-with-different-filesystems.md deleted file mode 100644 index 76974879a99c8..0000000000000 --- a/pages/id/docs/guides/working-with-different-filesystems.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Bekerja dengan Sistem File Berbeda -layout: docs.hbs ---- - -# Bekerja dengan Sistem File Berbeda - -Node.js memperlihatkan banyak fitur dari sistem file. Tetapi tidak semua sistem file sama. Berikut ini adalah praktik terbaik yang disarankan untuk menjaga kode Anda tetap sederhana dan aman ketika bekerja dengan sistem file yang berbeda. - -## Perilaku Sistem File - -Sebelum Anda dapat bekerja dengan sistem file, Anda perlu tahu bagaimana perilakunya. Sistem file yang berbeda berperilaku berbeda dan memiliki lebih banyak atau lebih sedikit fitur daripada lainnya: sensitivitas kasus, ketidakpekaan kasus, pelestarian kasus, formulir Unicode pelestarian, resolusi cap waktu, atribut yang diperluas, inode, Unix izin, aliran data alternatif, dll. - -Berhati-hatilah dalam menyimpulkan perilaku sistem file dari `process.platform`. Sebagai contoh, jangan berasumsi bahwa karena program Anda berjalan di Darwin maka Anda oleh karena itu bekerja pada sistem file case-insensitive (HFS+), karena pengguna mungkin menggunakan sistem file case-sensitive (HFSX). Demikian pula, jangan berasumsi bahwa karena program Anda berjalan di Linux sehingga Anda bekerja pada sistem file yang mendukung izin dan inode Unix, seperti yang mungkin Anda alami drive eksternal, USB atau drive jaringan yang tidak. - -Sistem operasi mungkin tidak memudahkan untuk menyimpulkan perilaku sistem file, tetapi semuanya tidak hilang. Alih-alih menyimpan daftar setiap sistem file dan perilaku yang diketahui (yang selalu tidak lengkap), Anda dapat menyelidiki sistem file untuk melihat bagaimana sebenarnya ia berperilaku. Ada atau tidak adanya fitur tertentu yang mudah diselidiki, seringkali cukup untuk menyimpulkan perilaku fitur lain yang lebih sulit untuk diselidiki. - -Ingat bahwa beberapa pengguna mungkin memiliki sistem file berbeda yang dipasang di berbagai jalur di pohon kerja. - -## Hindari Pendekatan Common Denominator Terendah - -Anda mungkin tergoda untuk membuat program Anda bertindak seperti penyebut umum terendah sistem file, dengan menormalkan semua nama file menjadi huruf besar, menormalkan semua nama file ke bentuk NFC Unicode, dan menormalkan semua cap waktu file untuk mengatakan 1 detik resolusi. Ini akan menjadi pendekatan penyebut umum terendah. - -Jangan lakukan ini. Anda hanya akan dapat berinteraksi dengan aman dengan sistem file yang memiliki karakteristik penyebut umum terendah yang sama persis di setiap menghormati. Anda tidak akan dapat bekerja dengan sistem file yang lebih maju yang diharapkan pengguna, dan Anda akan mengalami tabrakan nama file atau stempel waktu. Anda pasti akan kehilangan dan merusak data pengguna melalui serangkaian rumit peristiwa dependen, dan Anda akan membuat bug yang akan sulit jika tidak mustahil untuk dipecahkan. - -Apa yang terjadi ketika Anda nanti perlu mendukung sistem file yang hanya memiliki 2 detik? atau resolusi stempel waktu 24 jam? Apa yang terjadi ketika standar Unicode maju untuk memasukkan algoritma normalisasi yang sedikit berbeda (seperti yang terjadi di masa lalu)? - -Pendekatan common denominator terendah akan cenderung mencoba membuat portabel program dengan hanya menggunakan panggilan sistem "portabel". Hal ini menyebabkan program-program yang bocor dan sebenarnya tidak portabel. - -## Mengadopsi Pendekatan Superset - -Manfaatkan sebaik-baiknya setiap platform yang Anda dukung dengan mengadopsi pendekatan superset. Misalnya, program pencadangan portabel harus menyinkronkan btimes (waktu yang dibuat untuk a file atau folder) dengan benar di antara sistem Windows, dan tidak boleh merusak atau mengubah btimes, meskipun btimes tidak didukung pada sistem Linux. Sama program cadangan portabel harus menyinkronkan izin Unix dengan benar di antara Linux sistem, dan tidak boleh merusak atau mengubah izin Unix, meskipun Unix izin tidak didukung pada sistem Windows. - -Tangani sistem file yang berbeda dengan membuat program Anda bertindak seperti yang lebih maju berkas sistem. Mendukung superset dari semua fitur yang mungkin: case-sensitivity, pelestarian kasus, sensitivitas bentuk Unicode, pelestarian bentuk Unicode, Unix izin, stempel waktu nanodetik resolusi tinggi, atribut yang diperluas, dll. - -Setelah Anda memiliki case-preservation dalam program Anda, Anda selalu dapat mengimplementasikan case-insensitivity jika Anda perlu berinteraksi dengan sistem file case-insensitive. Tetapi jika Anda mengabaikan pelestarian kasus dalam program Anda, Anda tidak dapat berinteraksi dengan aman dengan sistem file case-preserving. Hal yang sama berlaku untuk bentuk Unicode pelestarian dan pelestarian resolusi cap waktu. - -Jika sistem file memberi Anda nama file dalam campuran huruf kecil dan huruf besar, lalu simpan nama file dalam huruf besar yang diberikan. Jika sistem file memberi Anda nama file dalam bentuk Unicode campuran atau NFC atau NFD (atau NFKC atau NFKD), lalu simpan nama file dalam urutan byte yang tepat yang diberikan. Jika sistem file memberi Anda stempel waktu milidetik, lalu simpan stempel waktu di resolusi milidetik. - -Saat Anda bekerja dengan sistem file yang lebih rendah, Anda selalu dapat melakukan downsample dengan tepat, dengan fungsi perbandingan seperti yang dipersyaratkan oleh perilaku sistem file tempat program Anda sedang berjalan. Jika Anda tahu bahwa sistem file tidak mendukung Unix izin, maka Anda seharusnya tidak membaca izin Unix yang sama dengan Anda menulis. Jika Anda tahu bahwa sistem file tidak menyimpan huruf besar, maka Anda harus menjadisiap untuk melihat `ABC` dalam daftar direktori ketika program Anda membuat `abc`. Tetapi jika Anda tahu bahwa sistem file mempertahankan case, maka Anda harus mempertimbangkan `ABC` menjadi nama file yang berbeda dengan `abc`, saat mendeteksi penggantian nama file atau jika sistem file peka huruf besar-kecil. - -## Pelestarian Kasus - -Anda dapat membuat direktori bernama `test/abc` dan terkadang terkejut melihat bahwa `fs.readdir('test')` mengembalikan `['ABC']`. Ini bukan bug di Node.js. simpul mengembalikan nama file saat sistem file menyimpannya, dan tidak semua sistem file mendukung pelestarian kasus. Beberapa sistem file mengonversi semua nama file menjadi huruf besar (atau huruf kecil). - -## Pelestarian Formulir Unicode - -_Pelestarian kasus dan pelestarian bentuk Unicode adalah konsep yang serupa. Ke mengerti mengapa bentuk Unicode harus dipertahankan, pastikan Anda terlebih dahulu memahami mengapa kasus harus dipertahankan. Pelestarian bentuk Unicode juga sama sederhana bila dipahami dengan benar._ - -Unicode dapat menyandikan karakter yang sama menggunakan beberapa urutan byte yang berbeda. Beberapa string mungkin terlihat sama, tetapi memiliki urutan byte yang berbeda. Kapan bekerja dengan string UTF-8, berhati-hatilah agar harapan Anda sejalan bagaimana Unicode bekerja. Sama seperti Anda tidak mengharapkan semua karakter UTF-8 untuk dikodekan ke satu byte, Anda seharusnya tidak mengharapkan beberapa string UTF-8 yang terlihat sama ke mata manusia untuk memiliki representasi byte yang sama. Ini mungkin sebuah harapan yang dapat Anda miliki dari ASCII, tetapi bukan dari UTF-8. - -Anda dapat membuat direktori bernama `test/café` (NFC Unicode form dengan byte urutan `<63 61 66 c3 a9>` dan `string.length === 5`) dan terkejut melihat terkadang `fs.readdir('test')` mengembalikan `['café']` (bentuk Unicode NFD dengan urutan byte `<63 61 66 65 cc 81>` dan `string.length === 6`). Ini bukan kesalahan di Node. Node.js mengembalikan nama file saat sistem file menyimpannya, dan tidak semua sistem file mendukung pelestarian bentuk Unicode. - -HFS+, misalnya, akan menormalkan semua nama file ke bentuk yang hampir selalu sama sebagai bentuk NFD. Jangan berharap HFS+ berperilaku sama seperti NTFS atau EXT4 dan dan sebaliknya. Jangan mencoba mengubah data secara permanen melalui normalisasi sebagai a abstraksi bocor ke kertas di atas perbedaan Unicode antara sistem file. Ini akan menciptakan masalah tanpa memecahkan apapun. Alih-alih, pertahankan bentuk dan penggunaan Unicode normalisasi sebagai fungsi pembanding saja. - -## Ketidakpekaan Bentuk Unicode - -Ketidakpekaan bentuk Unicode dan pelestarian bentuk Unicode adalah dua perbedaan perilaku sistem file sering disalahartikan satu sama lain. Sama seperti ketidakpekaan huruf besar-kecil terkadang diimplementasikan secara tidak benar dengan menormalkan nama file secara permanen menjadi huruf besar saat menyimpan dan mengirimkan nama file, jadi bentuk Unicode ketidakpekaan kadang-kadang telah diterapkan secara tidak benar secara permanen menormalkan nama file ke bentuk Unicode tertentu (NFD dalam kasus HFS+) kapan menyimpan dan mengirimkan nama file. Itu mungkin dan jauh lebih baik untuk diterapkan Ketidakpekaan bentuk Unicode tanpa mengorbankan pelestarian bentuk Unicode, oleh menggunakan normalisasi Unicode untuk perbandingan saja. - -## Membandingkan Berbagai Bentuk Unicode - -Node.js menyediakan `string.normalize('NFC' / 'NFD')` yang dapat Anda gunakan untuk menormalkan string UTF-8 ke NFC atau NFD. Anda tidak boleh menyimpan output dari ini fungsi tetapi hanya menggunakannya sebagai bagian dari fungsi perbandingan untuk menguji apakah dua String UTF-8 akan terlihat sama bagi pengguna. - -Anda dapat menggunakan `string1.normalize('NFC') === string2.normalize('NFC')` atau `string1.normalize('NFD') === string2.normalize('NFD')` sebagai perbandingan Anda fungsi. Bentuk mana yang Anda gunakan tidak masalah. - -Normalisasi cepat tetapi Anda mungkin ingin menggunakan cache sebagai masukan untuk Anda fungsi perbandingan untuk menghindari normalisasi string yang sama berkali-kali. Jika string tidak ada di cache lalu normalkan dan cache. Hati-hati bukan untuk menyimpan atau mempertahankan cache, gunakan hanya sebagai cache. - -Perhatikan bahwa menggunakan `normalize()` mengharuskan versi Node.js Anda menyertakan ICU (jika tidak, `normalize()` hanya akan mengembalikan string asli). Jika Anda mengunduh versi terbaru Node.js dari situs web maka itu akan mencakup ICU. - -## Resolusi Stempel Waktu - -Anda dapat menyetel `mtime` (waktu yang diubah) dari file ke `1444291759414` (resolusi milidetik) dan terkadang terkejut melihat `fs.stat` itu mengembalikan mtime baru sebagai `1444291759000` (resolusi 1 detik) atau `1444291758000` (resolusi 2 detik). Ini bukan bug di Node. Node.js kembali cap waktu saat sistem file menyimpannya, dan tidak semua sistem file mendukung resolusi cap waktu nanodetik, milidetik, atau 1 detik. Bahkan beberapa sistem file memiliki resolusi yang sangat kasar untuk stempel waktu atime khususnya, mis. 24 jam untuk beberapa sistem file FAT. - -## Jangan Rusak Nama File dan Stempel Waktu Melalui Normalisasi - -Nama file dan cap waktu adalah data pengguna. Sama seperti Anda tidak akan pernah secara otomatis menulis ulang data file pengguna menjadi huruf besar pada data atau menormalkan `CRLF` menjadi `LF` akhir baris, jadi Anda tidak boleh mengubah, mengganggu, atau merusak nama file atau stempel waktu melalui case/bentuk Unicode/normalisasi stempel waktu. Normalisasi seharusnya hanya digunakan untuk perbandingan, tidak pernah untuk mengubah data. - -Normalisasi secara efektif adalah kode hash yang hilang. Anda dapat menggunakannya untuk menguji jenis kesetaraan tertentu (mis. Apakah beberapa string terlihat sama meskipun memiliki urutan byte yang berbeda) tetapi Anda tidak akan pernah dapat menggunakannya sebagai pengganti data aktual. Program Anda harus meneruskan data nama file dan stempel waktu apa adanya. - -Program Anda dapat membuat data baru di NFC (atau dalam kombinasi bentuk Unicode apa pun yang disukainya) atau dengan nama file huruf kecil atau besar, atau dengan stempel waktu resolusi 2 detik, tetapi program Anda tidak boleh merusak data pengguna yang ada dengan memaksakan huruf / Unicode bentuk / normalisasi cap waktu. Alih-alih, gunakan pendekatan superset dan pertahankan kasus, bentuk Unicode, dan resolusi stempel waktu dalam program Anda. Dengan begitu, Anda akan dapat berinteraksi dengan aman dengan sistem file yang melakukan hal yang sama. - -## Gunakan Fungsi Perbandingan Normalisasi dengan Tepat - -Make sure that you use case / Unicode form / timestamp comparison functions appropriately. Do not use a case-insensitive filename comparison function if you are working on a case-sensitive filesystem. Do not use a Unicode form insensitive comparison function if you are working on a Unicode form sensitive filesystem (e.g. NTFS and most Linux filesystems which preserve both NFC and NFD or mixed Unicode forms). Do not compare timestamps at 2-second resolution if you are working on a nanosecond timestamp resolution filesystem. - -## Bersiaplah untuk Sedikit Perbedaan dalam Fungsi Perbandingan - -Berhati-hatilah agar fungsi perbandingan Anda cocok dengan sistem file (atau selidiki sistem file jika memungkinkan untuk melihat bagaimana sebenarnya perbandingannya). Case-insensitivity misalnya lebih kompleks daripada `toLowerCase()` sederhana perbandingan. Faktanya, `toUpperCase()` biasanya lebih baik daripada `toLowerCase()` (karena menangani karakter bahasa asing tertentu secara berbeda). Tapi lebih baik masih akan menyelidiki sistem file karena setiap sistem file memiliki kasingnya sendiri tabel perbandingan dipanggang. - -Sebagai contoh, HFS+ dari Apple melakukan normalisasi pada nama file menjadi bentuk NFD, tetapi bentuk NFD tersebut sebenarnya adalah versi lama dari bentuk NFD yang saat ini digunakan, dan kadang-kadang mungkin sedikit berbeda dengan bentuk NFD terbaru yang ditetapkan oleh Unicode. Oleh karena itu, jangan berharap bahwa HFS+ NFD selalu sama persis dengan Unicode NFD. diff --git a/pages/id/docs/index.mdx b/pages/id/docs/index.mdx deleted file mode 100644 index 5e167b79b0f19..0000000000000 --- a/pages/id/docs/index.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Dokumentasi -layout: docs.hbs -labels: - lts: LTS ---- - -# Mengenai Dokumentasi - -Ada beberapa jenis dokumentasi yang tersedia di situs ini: - -- Dokumentasi Referensi API -- Fitur ES6 -- Panduan -- Dependensi - -## Dokumentasi Referensi API - -[Dokumentasi referensi API](https://nodejs.org/api/) memberikan informasi mendetail tentang fungsi atau objek di Node.js. Dokumentasi ini menunjukkan argumen apa yang diterima suatu metode, nilai kembalian dari metode itu, dan kesalahan apa yang mungkin terkait dengan metode itu. Ini juga menunjukkan metode mana yang tersedia untuk berbagai versi Node.js. - -Dokumentasi ini menjelaskan modul bawaan yang disediakan oleh Node.js. Itu tidak mendokumentasikan modul yang disediakan oleh komunitas. - -
- -### Mencari dokumen API dari rilis sebelumnya? - - - -[Semua versi](https://nodejs.org/docs/) - -
- -## Fitur ES6 - -[Bagian ES6](/id/docs/es6/) menjelaskan tiga grup fitur ES6, dan detail fitur mana yang diaktifkan secara default di Node.js, bersama tautan penjelasan. Ini juga menunjukkan cara menemukan versi V8 mana yang disertakan dengan rilis Node.js tertentu. - -## Panduan - -[Bagian Panduan](/id/docs/guides/) memiliki artikel panjang dan mendalam tentang fitur dan kemampuan teknis Node.js. - -## Dependensi - -Node.js bergantung pada komponen tambahan di luar kode Node.js itu sendiri. Sebuah [dependensi](https://github.com/nodejs/node/blob/main/doc/contributing/maintaining/maintaining-dependencies.md) menyediakan kode natif dan JavaScript dan dibangun bersama dengan kode yang ada di direktori src dan lib untuk membuat file biner Node.js. diff --git a/pages/id/download/current.md b/pages/id/download/current.md deleted file mode 100644 index 475603c908eb3..0000000000000 --- a/pages/id/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Unduh -download: Unduh -downloads: - headline: Unduhan - lts: LTS - current: Saat ini - tagline-current: Fitur Terbaru - tagline-lts: Direkomendasikan Untuk Sebagian Besar Pengguna - display-hint: Menampilkan unduhan untuk - intro: > - Unduh kode sumber Node.js atau penginstal bawaan untuk platform Anda, dan mulai mengembangkanya sekarang. - currentVersion: Versi LTS Terbaru - buildInstructions: Membangun Node.js dari sumber pada platform yang didukung - WindowsInstaller: Instalasi Windows - WindowsBinary: Windows Binary - MacOSInstaller: Instalasi macOS - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Kode Sumber -additional: - headline: Platform Tambahan - intro: > - Anggota komunitas Node.js memelihara versi tidak resmi dari Node.js untuk platform tambahan. Perhatikan bahwa build tersebut tidak didukung oleh tim inti Node.js dan mungkin belum berada pada level build yang sama dengan rilis Node.js saat ini. - platform: Platform - provider: Penyedia - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Docker Image untuk Node.js Resmi - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/id/download/index.md b/pages/id/download/index.md deleted file mode 100644 index f92e1782f80d3..0000000000000 --- a/pages/id/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Unduh -download: Unduh -downloads: - headline: Unduhan - lts: LTS - current: Saat ini - tagline-current: Fitur Terbaru - tagline-lts: Direkomendasikan Untuk Sebagian Besar Pengguna - display-hint: Menampilkan unduhan untuk - intro: > - Unduh kode sumber Node.js atau penginstal bawaan untuk platform Anda, dan mulai mengembangkanya sekarang. - currentVersion: Versi LTS Terbaru - buildInstructions: Membangun Node.js dari sumber pada platform yang didukung - WindowsInstaller: Instalasi Windows - WindowsBinary: Windows Binary - MacOSInstaller: Instalasi macOS - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Kode Sumber -additional: - headline: Platform Tambahan - intro: > - Anggota komunitas Node.js memelihara versi tidak resmi dari Node.js untuk platform tambahan. Perhatikan bahwa build tersebut tidak didukung oleh tim inti Node.js dan mungkin belum berada pada level build yang sama dengan rilis Node.js saat ini. - platform: Platform - provider: Penyedia - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Docker Image untuk Node.js Resmi - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/id/download/package-manager.md b/pages/id/download/package-manager.md deleted file mode 100644 index 11ec4dda4f490..0000000000000 --- a/pages/id/download/package-manager.md +++ /dev/null @@ -1,393 +0,0 @@ ---- -layout: page.hbs -title: Menginstal Node.js melalui manajer paket ---- - -# Menginstal Node.js melalui manajer paket - -**_Catatan:_** Paket-paket di halaman ini dikelola dan didukung oleh pembuat paketnya masing-masing, **bukan** tim inti Node.js. Harap laporkan masalah apa pun yang Anda temui ke pengelola paket. Jika ternyata masalah Anda adalah bug di Node.js itu sendiri, pengelola akan melaporkan masalah tersebut ke upstream. - ---- - -- [Alpine Linux](#alpine-linux) -- [Android](#android) -- [Arch Linux](#arch-linux) -- [CentOS, Fedora dan Red Hat Enterprise Linux](#centos-fedora-and-red-hat-enterprise-linux) -- [Distribusi Linux berbasis Debian dan Ubuntu](#debian-and-ubuntu-based-linux-distributions) -- [fnm](#fnm) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [macOS](#macos) -- [n](#n) -- [NetBSD](#netbsd) -- [Nodenv](#nodenv) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE and SLE](#opensuse-and-sle) -- [SmartOS and illumos](#smartos-and-illumos) -- [Snap](#snap) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) -- [z/OS](#zos) - ---- - -## Alpine Linux - -Paket Node.js LTS dan npm tersedia di Repositori Utama. - -```bash -apk add nodejs npm -``` - -Node.js Current dapat diinstal dari Repositori Komunitas. - -```bash -apk add nodejs-current -``` - -## Android - -Dukungan Android masih eksperimental di Node.js, jadi biner yang telah dikompilasi belum disediakan oleh pengembang Node.js. - -Namun, ada beberapa solusi pihak ketiga. Misalnya, komunitas [Termux](https://termux.com/) menyediakan emulator terminal dan lingkungan Linux untuk Android, serta pengelola paket sendiri dan [koleksi ekstensif](https://github.com/termux/termux-packages) dari banyak aplikasi yang telah dikompilasi. Perintah ini di aplikasi Termux akan menginstal versi Node.js terakhir yang tersedia: - -```bash -pkg install nodejs -``` - -Saat ini, binari Termux Node.js terhubung dengan `system-icu` (bergantung pada paket `libicu`). - -## Arch Linux - -Paket Node.js dan npm tersedia di Repositori Komunitas. - -```bash -pacman -S nodejs npm -``` - -## CentOS, Fedora dan Red Hat Enterprise Linux - -Node.js tersedia sebagai modul yang disebut `nodejs` di CentOS/RHEL 8 dan Fedora. - -```bash -dnf module install nodejs: -``` - -di mana `` sesuai dengan versi utama Node.js. Untuk melihat daftar aliran yang tersedia: - -```bash -dnf module list nodejs -``` - -Misalnya, untuk menginstal Node.js 18: - -```bash -dnf module install nodejs:18/common -``` - -### Alternatif - -Sumber daya ini menyediakan paket yang kompatibel dengan CentOS, Fedora, dan RHEL. - -- [Node.js snaps](#snap) dipertahankan dan didukung di https://github.com/nodejs/snap -- [Distribusi biner Node.js](#debian-and-ubuntu-based-linux-distributions) dikelola dan didukung oleh [NodeSource](https://github.com/nodesource/distributions) - -## Distribusi Linux berbasis Debian dan Ubuntu - -[Distribusi biner Node.js](https://github.com/nodesource/distributions/blob/master/README.md) tersedia dari NodeSource. - -### Alternatif - -Paket yang kompatibel dengan distribusi Linux berbasis Debian dan Ubuntu tersedia melalui [Node.js snaps](#snap). - -## fnm - -Pengelola versi Node.js yang cepat dan sederhana yang dibangun di Rust digunakan untuk mengelola beberapa versi Node.js yang dirilis. Ini memungkinkan Anda untuk melakukan operasi seperti menginstal, menghapus, mengganti versi Node secara otomatis berdasarkan direktori saat ini, dll. Untuk menginstal fnm, gunakan [instalasi skrip ini](https://github.com/Schniz/fnm#using-a-script-macoslinux). - -fnm memiliki dukungan lintas platform (macOS, Windows, Linux) & semua shell populer (Bash, Zsh, Fish, PowerShell, Windows Command Line Prompt). fnm dibangun dengan mengutamakan kecepatan dan dukungan kompatibilitas untuk file `.node-version` dan `.nvmrc`. - -## FreeBSD - -Rilis terbaru Node.js tersedia melalui port [www/node](https://www.freshports.org/www/node). - -Instal paket biner melalui [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): - -```bash -pkg install node -``` - -Atau kompilasi sendiri menggunakan [port](https://www.freebsd.org/cgi/man.cgi?ports): - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js tersedia di tree portage. - -```bash -emerge nodejs -``` - -## IBM i - -Versi LTS dari Node.js tersedia dari IBM, dan tersedia melalui [pengelola paket 'yum'](https://ibm.biz/ibmi-rpms). Nama paketnya adalah `nodejs` diikuti dengan nomor versi utama (misalnya, `nodejs12`, `nodejs14` dll) - -Untuk menginstal Node.js 14.x dari baris perintah, jalankan perintah berikut sebagai pengguna dengan otoritas khusus \*ALLOBJ: - -```bash -yum install nodejs14 -``` - -Node.js juga dapat diinstal dengan produk IBM i Access Client Solutions. Lihat [dokumen dukungan ini](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) untuk detail selengkapnya - -## macOS - -Unduh [Instalasi macOS](https://nodejs.org/en/#home-downloadhead) langsung dari situs web [nodejs.org](https://nodejs.org/). - -_Jika Anda ingin mengunduh paket dengan bash:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### Alternatif - -Menggunakan **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -Menggunakan **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -Menggunakan **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -Instal paket biner: - -```bash -pkgin -y install nodejs -``` - -Atau buat secara manual dari pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## n - -`n` adalah manajer versi Node.js yang mudah digunakan untuk Mac dan Linux. Tentukan versi target untuk menginstal menggunakan sintaks yang kaya, atau pilih dari menu versi yang diunduh sebelumnya. Versi diinstal di seluruh sistem atau di seluruh pengguna, dan untuk lebih banyak lagi penggunaan yang ditargetkan, Anda dapat menjalankan versi langsung dari unduhan yang di-cache. - -Lihat [Beranda](https://github.com/tj/n) untuk metode cara penginstalan (boostrap, npm, Homebrew, pihak ketiga), dan semua detail penggunaan. - -Jika Anda sudah memiliki `npm` kemudian menginstal `n` dan menggunakan versi `node` LTS terbaru dengan metode simpel berikut: - -``` -npm install -g n -n lts -``` - -## NetBSD - -Node.js tersedia di tree pkgsrc: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -Atau instal paket biner (jika tersedia untuk platform Anda) menggunakan pkgin: - -```bash -pkgin -y install nodejs -``` - -## Nodenv - -`nodenv` adalah manajer versi node ringan, mirip dengan `nvm`. Ini sederhana dan dapat diprediksi. Ekosistem plugin yang kaya memungkinkan Anda menyesuaikannya dengan kebutuhan Anda. Gunakan `nodenv` untuk memilih versi Node untuk aplikasi Anda dan menjamin bahwa lingkungan pengembangan Anda cocok dengan produksi. - -Instruksi instalasi Nodenv dipertahankan [di halaman Github](https://github.com/nodenv/nodenv#installation). Kunjungi halaman tersebut untuk memastikan Anda mengikuti versi terbaru dari langkah-langkah penginstalan. - -## nvm - -Node Version Manager adalah skrip bash yang digunakan untuk mengelola beberapa versi Node.js yang dirilis. Ini memungkinkan Anda untuk melakukan operasi seperti menginstal, menghapus, mengganti versi, dll. Untuk menginstal nvm, gunakan [instal skrip](https://github.com/nvm-sh/nvm#install--update-script). - -Pada sistem Unix / OS X Node.js yang dibangun dari sumber dapat diinstal menggunakan [nvm](https://github.com/creationix/nvm) dengan menginstal ke lokasi yang diharapkan nvm: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -Setelah ini, Anda dapat menggunakan `nvm` untuk beralih antara versi dan versi yang dirilis dibangun dari sumber. Misalnya, jika versi Node.js adalah v8.0.0-pre: - -```bash -nvm use 8 -``` - -Setelah perilisan resmi keluar, Anda akan menghapus versi yang dibuat dari sumber: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -Manajer versi `nvs` bersifat lintas platform dan dapat digunakan pada sistem Windows, macOS, dan seperti Unix - -Untuk menginstal `nvs` di Windows, buka [halaman rilis](https://github.com/jasongin/nvs/releases) di sini dan unduh file penginstal MSI dari rilis terbaru. - -Anda juga dapat menggunakan `chocolatey` untuk menginstalnya: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -Anda dapat menemukan dokumentasi mengenai langkah-langkah penginstalan `nvs` di sistem seperti macOS/Unix [di sini](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Penggunaan - -Setelah ini, Anda dapat menggunakan `nvs` untuk beralih di antara versi node yang berbeda. - -Bash untuk menambahkan versi terbaru dari simpul: - -```bash -nvs add latest -``` - -Atau pun bash untuk menambahkan node versi LTS terbaru: - -```bash -nvs add lts -``` - -Dan kemudian jalankan perintah `nvs use` untuk menambahkan versi node ke `PATH` Anda untuk shell saat ini: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -Untuk menambahkannya ke `PATH` secara permanen, gunakan bash `nvs link` berikut: - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js tersedia melalui sistem port. - -```bash -/usr/ports/lang/node -``` - -Cara menggunakan [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) di OpenBSD: - -```bash -pkg_add node -``` - -## openSUSE and SLE - -Node.js is available in the main repositories under the following packages: - -- **openSUSE Leap 15.2**: `nodejs10`, `nodejs12`, `nodejs14` -- **openSUSE Tumbleweed**: `nodejs16` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs10`, `nodejs12`, dan `nodejs14` ("Modul Web dan Scripting" harus [diaktifkan](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12-SP5/#intro-modulesExtensionsRelated).) -- **SUSE Linux Enterprise Server (SLES) 15 SP2**: `nodejs10`, `nodejs12`, dan `nodejs14` ("Modul Web dan Scripting" harus [diaktifkan](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/15/#Intro.Module).) - -Sebagai contoh, untuk menginstal Node.js 14.x pada openSUSE Leap 15.2, jalankan perintah berikut sebagai root: - -```bash -zypper install nodejs14 -``` - -Versi utama Node yang berbeda dapat diinstal dan digunakan secara bersamaan. - -## SmartOS dan ilumino - -SmartOS images hadir dengan pkgsrc yang sudah diinstal sebelumnya. Pada distribusi illumos lainnya, instal terlebih dahulu **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, lalu Anda dapat menginstal paket biner seperti biasa: - -```bash -pkgin -y install nodejs -``` - -Atau buat secara manual dari pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Snap - -[Node.js snaps](https://github.com/nodejs/snap) tersedia sebagai [`node`](https://snapcraft.io/node) di toko Snap. - -## Solus - -Solus menyediakan Node.js di repositori utamanya. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux mengirimkan Node.js stabil di repositori utama. - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -Unduh [Instalasi Windows](https://nodejs.org/en/#home-downloadhead) langsung dari situs web [nodejs.org](https://nodejs.org/). - -### Alternatif - -Menggunakan **[Winget](https://aka.ms/winget-cli)**: - -```bash -winget install OpenJS.NodeJS -# or for LTS -winget install OpenJS.NodeJS.LTS -``` - -Setelah menjalankan salah satu dari dua perintah di atas, mungkin perlu memulai ulang terminal emulator sebelum perintah `node` CLI tersedia. - -Menggunakan **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -Menggunakan **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -``` - -## z/OS - -IBM® SDK untuk Node.js - z/OS® tersedia dalam dua format instalasi, SMP/E dan PAX. Pilih format instalasi yang sesuai untuk Anda: - -- [Memasang dan mengonfigurasi Node.js edisi SMP/E di z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-smpe-edition) -- [Memasang dan mengonfigurasi Node.js edisi PAX di z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-pax-edition) diff --git a/pages/id/download/releases.md b/pages/id/download/releases.md deleted file mode 100644 index 6d25febce963e..0000000000000 --- a/pages/id/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Rilisan sebelumnya -modules: 'NODE_MODULE_VERSION> mengacu pada nomor versi ABI (application binary interface) dari Node.js, yang digunakan untuk menentukan versi mana dari binarly add-on C++ terkompilasi Node.js yang dapat dimuat tanpa perlu dikompilasi ulang. Di versi sebelumnya disimpan sebagai nilai hex, tetapi sekarang direpresentasikan sebagai bilangan bulat.' ---- - -### io.js & Node.js - -Rilis 1.x hingga 3.x disebut "io.js" karena merupakan bagian dari fork io.js. Pada Node.js 4.0.0, jalur rilis sebelumnya dari io.js menyatu dengan Node.js 0.12.x menjadi rilis Node.js terpadu. - -### Mencari rilis terbaru dari cabang versi? diff --git a/pages/id/get-involved/collab-summit.md b/pages/id/get-involved/collab-summit.md deleted file mode 100644 index 272db87dfeb44..0000000000000 --- a/pages/id/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: KTT Kolaborasi -layout: contribute.hbs ---- - -# KTT Kolaborasi - -Konferensi Tingkat Tinggi (KTT) Kolaborasi adalah un-konferensi untuk membawa saat ini dan kontributor potensial bersama untuk membahas Node.js dengan kolaborasi yang hidup, pendidikan, dan berbagi pengetahuan. Komite dan kelompok kerja berkumpul dua kali per tahun untuk membuat keputusan penting sementara juga dapat mengerjakan beberapa upaya menarik yang ingin mereka dorong secara langsung. - -## Siapa saja menghadiri? - -Siapapun boleh menghadiri KTT Kolaborasi. Selama KTT, para pemimpin akan membantu kontributor baru ke grup yang ingin mereka bantu sebelum mengintegrasikannya ke dalam sesi kerja. - -Ini adalah kesempatan Anda untuk mempelajari apa yang terjadi dalam komunitas untuk melompat dalam dan berkontribusi dengan keterampilan yang Anda miliki dan ingin diasah. - -Kelompok kerja akan menyusun jadwal sehingga orang dapat membiasakan diri sebelum orang-orang tiba di lokasi, memiliki kolaborator umum diskusi, dan kemudian masuk ke sesi breakout. - -Kami akan senang melihat mu di KTT Kolaborasi! Lihat [Repo KTT](https://github.com/nodejs/summit) untuk KTT Kolaborasi yang akan datang dan yang lalu dan lihat [masalah diajukan](https://github.com/nodejs/summit/issues) yang membagikan apa kelompok kerja individu dan komite ingin berdiskusi secara langsung. diff --git a/pages/id/get-involved/contribute.md b/pages/id/get-involved/contribute.md deleted file mode 100644 index be6fce457e8e4..0000000000000 --- a/pages/id/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Berkontribusi -layout: contribute.hbs ---- - -# Berkontribusi - -Terima kasih atas minat Anda untuk berkontribusi pada Node.js! Ada banyak cara dan tempat yang dapat Anda sumbangkan, dan kami siap membantu memfasilitasinya. - -## Meminta Bantuan Umum - -Karena tingkat aktivitas di repositori `nodejs/node` sangat tinggi, pertanyaan atau permintaan bantuan umum menggunakan Node.js harus diarahkan ke [Repositori bantuan Node.js](https://github.com/nodejs/help/issues). - -## Melaporkan Masalah - -Jika Anda telah menemukan apa yang Anda yakini sebagai masalah dengan Node.js, jangan ragu untuk mengajukan masalah pada proyek GitHub. Saat mengajukan masalah Anda, pastikan Anda dapat mengungkapkan masalah dengan kasus uji yang dapat direproduksi, dan kasus uji tersebut tidak boleh menyertakan dependensi eksternal apa pun. Artinya, test case dapat dieksekusi tanpa apa pun selain Node.js itu sendiri. - -Saat melaporkan masalah, kami juga membutuhkan sebanyak mungkin informasi tentang lingkungan Anda yang dapat Anda sertakan. Kita tidak pernah tahu informasi apa yang akan relevan ketika mencoba mempersempit masalah. Harap sertakan setidaknya informasi berikut: - -- Versi Node.js -- Platform yang Anda jalankan (macOS, SmartOS, Linux, Windows) -- Arsitektur yang Anda jalankan (32bit atau 64bit dan x86 atau ARM) - -Proyek Node.js saat ini dikelola di sejumlah repositori GitHub yang terpisah, masing-masing dengan database masalah mereka sendiri. Jika memungkinkan, harap arahkan masalah apa pun yang Anda laporkan ke repositori yang sesuai, tetapi jangan khawatir jika sesuatu terjadi di tempat yang salah, komunitas kontributor akan dengan senang hati membantu mengarahkan Anda ke arah yang benar. - -- Untuk melaporkan masalah khusus untuk Node.js, gunakan [nodejs/node](https://github.com/nodejs/node) -- Untuk melaporkan masalah khusus untuk situs web ini, gunakan [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## Kontribusi kode - -Jika Anda ingin memperbaiki bug atau menambahkan fitur baru ke Node.js, pastikan Anda membaca [Pedoman Kontribusi Node.js](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). Proses peninjauan oleh kolaborator yang ada untuk semua kontribusi pada proyek juga dijelaskan di sana. - -Jika kamu bertanya-tanya bagaimana memulainya, kamu dapat memeriksa [Node Todo](https://www.nodetodo.org/) yang dapat memandu mu menuju kontribusi pertama Anda. - -## Menjadi kolaborator - -Dengan menjadi kolaborator, kontributor dapat memberikan dampak yang lebih besar pada proyek. Mereka dapat membantu kontributor lain dengan meninjau kontribusi mereka, masalah triase dan mengambil bagian yang lebih besar dalam membentuk masa depan proyek. Individu yang diidentifikasi oleh TSC sebagai yang memberikan kontribusi signifikan dan berharga di semua repositori Node.js dapat dijadikan Kolaborator dan diberikan akses komit ke proyek. Kegiatan yang dipertimbangkan termasuk (tetapi tidak terbatas pada) kualitas: - -- dokumentasi melakukan dan menarik permintaan -- dokumentasi melakukan dan menarik permintaan -- komentar tentang masalah dan permintaan tarik -- kontribusi ke situs web Node.js -- bantuan yang diberikan kepada pengguna akhir dan kontributor pemula -- partisipasi dalam kelompok kerja -- partisipasi lain dalam komunitas Node.js yang lebih luas - -Jika individu yang memberikan kontribusi berharga tidak yakin bahwa mereka telah dipertimbangkan untuk akses komit, mereka dapat [mencatat masalah](https://github.com/nodejs/TSC/issues) atau [menghubungi anggota TSC](https://github.com/nodejs/node#tsc-technical-steering-committee) secara langsung. diff --git a/pages/id/get-involved/index.md b/pages/id/get-involved/index.md deleted file mode 100644 index 9874f6c7cb276..0000000000000 --- a/pages/id/get-involved/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Berkontribusi -layout: contribute.hbs ---- - -# Berkontribusi - -## Diskusi Komunitas - -- [Daftar masalah GitHub](https://github.com/nodejs/node/issues) adalah tempat untuk mendiskusikan fitur inti Node.js. -- Untuk obrolan waktu nyata tentang pengembangan Node.js, gunakan salah satu platform di bawah ini - - Untuk IRC, buka `irc.libera.chat` di saluran `#node.js` dengan [klien IRC](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients) atau sambungkan di browser web Anda ke saluran menggunakan [klien web](https://kiwiirc.com/nextclient/) - - Untuk Slack, ada dua opsi: - - [OpenJSF Slack](https://slack-invite.openjsf.org/) adalah Foundation run Slack dengan beberapa saluran Node.js (saluran yang diawali dengan `#nodejs-` terkait dengan proyek). - - [Node Slackers](https://www.nodeslackers.com/) adalah komunitas Slack yang berfokus pada Node.js. -- Akun Twitter resmi Node.js adalah [nodejs](https://twitter.com/nodejs). -- [Kalender Node.js Foundation](https://nodejs.org/calendar) dengan semua rapat tim publik. - -## Mempelajari - -- [Dokumentasi referensi API resmi](https://nodejs.org/api/) dokumen merinci API Node.js. -- [NodeSchool.io](https://nodeschool.io/) akan mengajari Anda konsep Node.js melalui game baris perintah interaktif. -- [Tag Stack Overflow Node.js](https://stackoverflow.com/questions/tagged/node.js) mengumpulkan informasi baru setiap hari. -- [Tag Node.js Komunitas DEV](https://dev.to/t/node) adalah tempat untuk berbagi proyek, artikel, dan tutorial Node.js serta memulai diskusi dan meminta umpan balik tentang Node.js- topik-topik yang berkaitan. Pengembang dari semua tingkat keahlian dipersilakan untuk ambil bagian. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) adalah komunitas ramah pengembang backend Node.js yang saling mendukung di Discord. diff --git a/pages/id/index.md b/pages/id/index.md deleted file mode 100644 index 4841e85ba6775..0000000000000 --- a/pages/id/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Versi Saat Ini - download: Unduh - download-for: Unduh untuk - other-downloads: Lihat lainnya - current: Saat ini - lts: LTS - tagline-current: Fitur Terbaru - tagline-lts: Disarankan untuk Banyak Orang - changelog: Log Perub. - api: Dokumentasi API - version-schedule-prompt: Untuk informasi tentang rilis yang didukung, lihat - version-schedule-prompt-link-text: jadwal rilis ---- - -Node.js® adalah lingkungan runtime JavaScript lintas platform sumber terbuka. diff --git a/pages/it/404.md b/pages/it/404.md deleted file mode 100644 index 41c3884868760..0000000000000 --- a/pages/it/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: La pagina non è stata trovata - -### ENOENT: Nessun file o cartella presente con questo nome diff --git a/pages/it/about/index.md b/pages/it/about/index.md deleted file mode 100644 index 390a8e8bbe374..0000000000000 --- a/pages/it/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: A propos -trademark: Trademark ---- - -# Informazioni su Node.js® - -Come runtime JavaScript guidato da eventi asincroni, Node.js è progettato per creare applicazioni di rete scalabili. Nel seguente esempio "Hello World", molte connessioni possono essere gestite contemporaneamente. Ad ogni connessione viene chiamata la callback, ma se non c'è nulla da fare, Node.js rimarrà inattivo. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Ciò è in contrasto con il modello di concorrenza più comune di oggi in cui vengono utilizzati i thread. Il networking basato su thread è relativamente inefficiente e molto difficile da utilizzare. Inoltre, gli utenti di Node.js sono liberi da preoccupazioni di blocco permanente del processo, poiché non ci sono blocchi. Quasi nessuna funzione in Node.js esegue direttamente I/O, quindi il processo non blocca mai. Dal momento che nulla si blocca, è molto facile sviluppare sistemi scalabili in Node.js - -Se alcuni dei termini utilizzati non ti sono familiari, ecco un articolo completo (in inglese) [Bloccante vs Non Bloccante][]. - ---- - -Node.js è influenzato da sistemi come la [Event Machine][] di Ruby o [Twisted][] di Python. Node.js porta il modello ad eventi un po' oltre. Node.js usa un [event loop][] come costrutto di runtime invece che come una libreria. In altri sistemi, c'è sempre una chiamata di blocco per avviare l'event-loop. In genere il comportamento è definito tramite callback all'inizio di uno script e alla fine avvia un server attraverso una chiamata di blocco come `EventMachine::run()`. In Node.js non esiste alcuna chiamata per avviare il ciclo. Node.js entra semplicemente nel ciclo degli eventi dopo aver eseguito lo script di input. Node.js esce dal ciclo di eventi quando non ci sono più callback da eseguire. Questo comportamento è simile a JavaScript in browser: il ciclo degli eventi è nascosto all'utente. - -HTTP ha un posto di rilievo in Node.js, che è stato progettato per lo streaming e bassa latenza. Ciò rende Node.js una base perfetta per una libreria o un framework web. - -Solo perché Node.js è progettato senza thread, non significa che non è possibile sfruttare i multi-core nel proprio ambiente. I processi figlio possono essere generati utilizzando la API [`child_process.fork()`][], con cui è possibile comunicare facilmente. Costruito sulla stessa interfaccia è il modulo [`cluster`][], che consente di condividere i socket tra i processi per consentire il bilanciamento del carico sui core. - -[Bloccante vs Non Bloccante]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[event loop]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: http://rubyeventmachine.com/ -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/it/get-involved/collab-summit.md b/pages/it/get-involved/collab-summit.md deleted file mode 100644 index 4340f948049f7..0000000000000 --- a/pages/it/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Collab Summit -layout: contribute.hbs ---- - -# Collab Summit - -Il Summit di collaborazione è simile a una conferenza e ha lo scopo di riunire i contributori attuali e potenziali per parlare di Node.js, collaborando, insegnando e condividendo informazioni. I comitati e gruppi di lavoro si riuniscono due volte all'anno per prendere decisioni importanti e allo stesso tempo per lavorare su alcuni parti del progetto che vogliono portare avanti di persona. - -## Chi partecipa? - -Chiunque è invitato a partecipare al Summit di Collaborazione. Durante il vertice, i leader, prima di iniziare le sessioni di lavoro, aiuteranno i nuovi contributori ad entrare nei gruppi che vorrebbero aiutare. - -Questa è l'occasione giusta per imparare cosa succede nella community per iniziare a contribuire con le tue conoscenze e con quelle che vorresti migliorare. - -I gruppi di lavoro faranno un programma in modo che le persone possono familiarizzare prima di recarsi sul posto, parlando con i collaboratori in maniera generica per poi immergersi nelle sessioni di lavoro successivamente. - -Ci piacerebbe vederti al Summit! Dai un'occhiata al [repository del Summit](https://github.com/nodejs/summit) per vedere gli eventi in arrivo e quelli passati e guarda anche le [issue archiviate](https://github.com/nodejs/summit/issues) che mostrano di cosa parlano i gruppi di lavoro individuali e i comitati. diff --git a/pages/it/get-involved/index.md b/pages/it/get-involved/index.md deleted file mode 100644 index e54907b3821a2..0000000000000 --- a/pages/it/get-involved/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Come partecipare -layout: contribute.hbs ---- - -# Come partecipare - -## Comunità - -- La [lista delle issues di GitHub](https://github.com/nodejs/node/issues) è il luogo in cui discutere delle funzionalità del core di Node.js. -- L'account Twitter ufficiale di Node.js é [nodejs](https://twitter.com/nodejs). -- Il [calendario della Node.js Foundation](https://nodejs.org/calendar) con tutti i meeting pubblici del team. -- [Node Slackers](https://www.nodeslackers.com/) è la comunità Slack di Node.js. - -## Impara - -- [Documentazione ufficiale delle API](https://nodejs.org/api/) contiene i dettagli delle API di Node.js. -- [NodeSchool.io](https://nodeschool.io/) insegna i concetti di Node.js attraverso giochi interattivi da linea di comando. -- [Il tag Node.js su Stack Overflow](https://stackoverflow.com/questions/tagged/node.js) colleziona molte informazioni ogni giorno. -- [Il tag Node.js nella comunità degli sviluppatori](https://dev.to/t/node) é il luogo dove condividere i progetti Node.js, articoli e tutorial come anche discussioni e per fare domande relative ad argomenti su Node.js. Sono benvenuti tutti gli sviluppatori di qualsiasi livello. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) é una comunità di sviluppatori backend di Node.js con supporto tramite Discord. - -## Siti e progetti delle comunità internazionali - -- [Comunità cinese](https://cnodejs.org/) -- [Comunità ungherese (Magyar)](https://nodehun.blogspot.com/) -- [Gruppo Facebook Node.js Israele](https://www.facebook.com/groups/node.il/) -- [Gruppo Giapponese](https://nodejs.jp/) -- [Gruppo Facebook Spagnolo Node.js](https://www.facebook.com/groups/node.es/) -- [Comunità Node.js Vietnamite](https://www.facebook.com/nodejs.vn/) -- [Uzbekistan group for Node.js](https://t.me/nodejs_uz) diff --git a/pages/it/index.md b/pages/it/index.md deleted file mode 100644 index 80f431c8c4a03..0000000000000 --- a/pages/it/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Versione corrente - download: Download - download-for: Download per - other-downloads: Altri download - current: Corrente - lts: LTS - tagline-current: Ultime funzionalità - tagline-lts: Consigliata - changelog: Changelog - api: Documentazione API - version-schedule-prompt: Dai un'occhiata alla - version-schedule-prompt-link-text: tabella di marcia LTS ---- - -Node.js® è un runtime JavaScript costruito sul [motore JavaScript V8 di Chrome](https://v8.dev/). diff --git a/pages/ja/404.md b/pages/ja/404.md deleted file mode 100644 index ba2f312b28747..0000000000000 --- a/pages/ja/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: ページが見つかりません - -### ENOENT: ファイルかディレクトリが存在しません diff --git a/pages/ja/about/index.md b/pages/ja/about/index.md deleted file mode 100644 index 885af2bf8a20d..0000000000000 --- a/pages/ja/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Node.jsとは -trademark: トレードマーク ---- - -# Node.js®とは - -Node.jsはスケールできるネットワークアプリケーションを構築するために、非同期でイベント駆動型のJavaScript実行環境として設計されています。次の「hello world」のサンプルコードは多くのネットワーク接続を並列に処理できます。それぞれのネットワーク接続ではコールバック処理が呼び出されますが、実行する処理がなければNode.jsはスリープします。 - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -これはOSのスレッドを採用した一般的な同時実行モデルとは対照的です。スレッドベースのネットワーキングは効率が悪く非常に使いにくいものです。さらにNode.jsにはロックがないため、ユーザーはプロセスのデッドロックの心配から解放されます。また、I/Oを直接実行する関数はほとんどないため、Node.jsの標準ライブラリーの同期メソッドを利用しない限りプロセスがブロックされることはありません。ブロックがないためスケーラブルなシステムをNode.jsで開発することは非常に合理的です。 - -もしこの説明が聞き慣れない場合は[Blocking vs. Non-Blocking][]の記事を参考にしてください。 - ---- - -Node.jsはRubyの[Event Machine][]やPythonの[Twisted][]に影響を受けておりそれらに似ています。Node.jsはさらにイベントモデルを進めています。Node.jsは[event loop][]をライブラリーとしてではなく実行環境の要素として扱っています。Node.js以外のシステムではイベントループを開始するために常にブロックの呼び出しが発生します。通常、この動作はスクリプトの開始時のコールバックを通して定義され、最終的に`EventMachine::run()`のようなブロックの呼び出しを通してサーバーが起動します。Node.jsにはこのようなイベントループを開始する呼び出しはありません。Node.jsは入力されたスクリプトを実行したあと、単純にイベントループに入ります。実行するコールバックがなくなるとイベントループを終了します。この動作はブラウザーのJavaScriptと似ていて、ユーザーからはイベントループは隠されています。 - -HTTPはNode.jsでは第一級オブジェクトであり、ストリーミングと低レイテンシーを意識して設計されています。このことからNode.jsはウェブのライブラリーやフレームワークの基盤に適したものになっています。 - -Node.jsはスレッドを使わず設計されていますが、マルチコアを利用できないわけではありません。子プロセスは[`child_process.fork()`][] APIを利用して作成することができ、簡単に通信できるように設計されています。同じインターフェイス上に[`cluster`][]モジュールが存在しており、プロセス間でソケットを共有しコアの負荷分散が可能になっています。 - -[Blocking vs. Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[event loop]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/ja/docs/es6.md b/pages/ja/docs/es6.md deleted file mode 100644 index 9a9b74acd0ada..0000000000000 --- a/pages/ja/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) とそれ以降のバージョン -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) とそれ以降のバージョン - -Node.js は [V8](https://v8.dev/) のモダンなバージョンに対して作られています。V8 を最新の状態に保つことで [JavaScript ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm) の新機能を開発者にすみやかに提供し、継続的なパフォーマンスと安定性の向上を保証しています。 - -すべての ECMAScript 2015 (ES6) の機能は **shipping(リリース済み)**、**staged(ステージング)** と **in progress(開発中)**の3つに分けられています: - -- V8 が安定しているとみなす **shipping(リリース済み)** の機能は Node.js では**標準で有効**になっているので、ランタイムフラグは**必要ありません**。 -- **staged(ステージング)**の機能は V8 チームによって安定しているとはみなされないほぼ完成した機能であり、ランタイムフラグを必要とします: `--harmony`。 -- **in progress(開発中)**の機能は、それぞれのハーモニーフラグによって個別に有効にすることができますが、テスト目的以外の使用は避けてください。注:これらのフラグは V8 によって公開されており、廃止予定の通知なしで変更される可能性があります。 - -## どの機能がどの Node.js のバージョンで標準で有効になってますか? - -[node.green](https://node.green/) は Kangax 氏の互換性テーブルに基づいて Node.js のさまざまなバージョンでサポートされている ECMAScript の機能に関する優れた概要を提供します。 - -## どの機能が開発中なのか? - -新しい機能は定期的に V8 に追加されています。一般的に、時期は未定ですが、将来の Node.js のリリースで有効になることを期待してください。 - -`--v8-options` を引数に指定した実行結果を `grep "in progress"` することで各 Node.js のリリースで利用可能なすべてのの **in progress(開発中)**の機能を列挙することができます。これらはV8の機能完全ではなく動かない可能性があるので、自己責任で使用してください: - -```bash -node --v8-options | grep "in progress" -``` - -## インフラ側で --harmony フラグを使うように設定しているんですが、フラグを除くべきですか? - -Node.js の --harmony フラグの現在の動作は **staged(ステージング)** 機能のみを有効にすることです。つまるところ `--es_staging` フラグと同じです。上記の通り、これらはまだ安定しているとは考えられていない完成した機能です。特に本番環境で安定して Node.js を使いたい場合は、このランタイムフラグが標準で V8 でリリースされ、その結果 Node.js でも標準になるまでランタイムフラグを削除することを検討してください。このフラグを継続的に利用する場合は Node.js のアップグレードの際に標準に準拠するために変更された V8 に挙動によってコードが動作しなくなる可能性を考慮して対策をする必要があります。 - -## 特定のバージョンの Node.js が組み込まれている V8 のバージョンを確認するにはどうすればよいですか? - -Node.js は `process` グローバルオブジェクトを通じて特定のバイナリに付属するすべての依存関係とそれぞれのバージョンを簡単に列挙する方法を提供します。 V8 エンジンの場合は、端末に次のように入力してバージョンを取得します: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/ja/docs/guides/blocking-vs-non-blocking.md b/pages/ja/docs/guides/blocking-vs-non-blocking.md deleted file mode 100644 index 43698b2bfe84d..0000000000000 --- a/pages/ja/docs/guides/blocking-vs-non-blocking.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -title: ブロッキングとノンブロッキングの概要 -layout: docs.hbs ---- - - - -# ブロッキングとノンブロッキングの概要 - -この概要では、Node.js における**ブロッキング**と**ノンブロッキング**呼び出しの違いについて説明します。 -この概要ではイベントループと libuv について説明しますが、 -これらのトピックに関する事前知識は必要ありません。 -読者は JavaScript 言語と Node.js コールバックパターンの基本的な知識を持っていることを前提としています。 - -> "I/O" とは、主に [libuv](https://libuv.org/) がサポートしている -> システムのディスクやネットワークとのやり取りを指します。 - - - -## ブロッキング - -**ブロッキング**は、Node.js プロセス内の追加の JavaScript の実行が、 -JavaScript 以外の操作が完了するまで待たなければならない場合です。 -これは、**ブロッキング**操作が行われている間は -イベントループが JavaScript の実行を継続できないために起こります。 - -Node.js では、 -I/O などの JavaScript 以外の操作を待機するのではなく、CPU に負荷がかかるためパフォーマンスが低下する JavaScript は通常、 -**ブロッキング**としては呼び出されません。 -Node.js 標準ライブラリの libuv を使用する同期メソッドは、最も一般的に使用されている**ブロッキング**操作です。 -ネイティブモジュールには**ブロッキング**メソッドもあります。 - -Node.js 標準ライブラリのすべての I/O メソッドは非同期バージョンを提供します。 -これらは**ノンブロッキング**で、コールバック関数を受け入れます。 -一部のメソッドには**ブロッキング**に対応したものもあり、 -その名前は `Sync` で終わります。 - - - -## コードを比較する - -**ブロッキング**メソッドは同期的に実行され、 -**ノンブロッキング**メソッドは非同期的に実行されます。 - -例としてファイルシステムモジュールを使用する場合、これは**同期的な**ファイルの読み取りです: - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // ファイルが読み込まれるまでここでブロック -``` - -そして、これは同等の**非同期的な**コードの例です: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; -}); -``` - -最初の例は2番目の例よりも単純に見えますが、 -2行目がファイル全体が読み取られるまで追加の JavaScript の実行を**ブロックする**という欠点があります。 -同期バージョンでは、エラーがスローされた場合はそれをキャッチする必要があるか、 -プロセスがクラッシュします。 -非同期バージョンでは、 -示されているようにエラーをスローするかどうかを決めるのは開発者次第です。 - -例を少しだけ拡張しましょう: - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // ファイルが読み込まれるまでここでブロック -console.log(data); -moreWork(); // console.log の後に実行されます -``` - -そして、これは似ていますが、同等ではない非同期の例です。 - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -moreWork(); // console.log の前に実行されます -``` - -上記の最初の例では、`console.log` が `moreWork()` の前に呼び出されます。 -2番目の例では、`fs.readFile()` は**ノンブロッキング**であるため、JavaScript の実行は続行でき、 -`moreWork()` が最初に呼び出されます。 -ファイルの読み込みが完了するのを待たずに `moreWork()` を実行する機能は、 -より高いスループットを可能にする重要な設計上の選択です。 - - - -## 並行性とスループット - -Node.js での JavaScript の実行はシングルスレッドであるため、 -同時実行性とは、他の作業が完了した後に JavaScript コールバック関数を実行するイベントループの能力のことです。 -同時に実行されることが予想されるコードでは、 -I/O などの JavaScript 以外の操作が発生しても、 -イベントループの実行を継続できる必要があります。 - -例として、Web サーバへの各リクエストが完了するのに 50 ミリ秒かかり、 -その 50 ミリ秒のうち 45 ミリ秒が非同期に実行できるデータベース入出力である場合を考えてみましょう。 -**ノンブロッキング**の非同期操作を選択すると、 -他のリクエストを処理するために 1 リクエストあたり 45 ミリ秒が解放されます。 -これは、**ブロッキング**メソッドの代わりに**ノンブロッキング**メソッドを使用することを選択しただけで、 -キャパシティが大きく異なることを意味します。 - -イベントループは、 -並行作業を処理するために追加のスレッドが作成される可能性がある他の多くの言語のモデルとは異なります。 - - - -## ブロッキングコードとノンブロッキングコードが混在する危険性 - -I/O を扱うときに避けるべきいくつかのパターンがあります。 -例を見てみましょう。 - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -fs.unlinkSync('/file.md'); -``` - -上記の例では、`fs.unlinkSync()` は -`fs.readFile()` の前に実行される可能性が高いため、 -`file.md` は実際に読み取られる前に削除されます。 -これを書くためのより良い方法は、 -完全に**ノンブロッキング**で正しい順序で実行されることが保証されていることです。 - -```js -const fs = require('fs'); -fs.readFile('/file.md', (readFileErr, data) => { - if (readFileErr) throw readFileErr; - console.log(data); - fs.unlink('/file.md', unlinkErr => { - if (unlinkErr) throw unlinkErr; - }); -}); -``` - -上記は、`fs.readFile()`のコールバック内で `fs.unlink()` への**ノンブロッキング**呼び出しを行います。 -これにより、正しい操作順序が保証されます。 - - - -## 追加のリソース - -- [libuv](https://libuv.org/) diff --git a/pages/ja/docs/guides/buffer-constructor-deprecation.md b/pages/ja/docs/guides/buffer-constructor-deprecation.md deleted file mode 100644 index 363bc70871bfe..0000000000000 --- a/pages/ja/docs/guides/buffer-constructor-deprecation.md +++ /dev/null @@ -1,396 +0,0 @@ ---- -title: Buffer.from()/Buffer.alloc() API への移植 -layout: docs.hbs ---- - -# `Buffer.from()`/`Buffer.alloc()` API への移植 - -## 概要 - -このガイドは安全な `Buffer` コンストラクタメソッドに移行する方法を説明します。マイグレーションにより、以下の非推奨警告が修正されました。 - -> The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead. - -- [Variant 1: Node.js ≤ 4.4.x および 5.0.0 — 5.9.x のサポートを終了](#variant-1) (_推奨_) -- [Variant 2: ポリフィルの使用](#variant-2) -- [Variant 3: セーフガード付きの手動検出](#variant-3) - - - -### `grep` を使って問題のあるコードを見つける - -`grep -nrE '[^a-zA-Z](Slow)?Buffer\s*\(' --exclude-dir node_modules` を実行するだけです。 - -それにより自身のコードの中ですべての潜在的に危険な箇所が分かるでしょう (とてもありそうにない例外を除いて)。 - -### Node.js 8 を使用して問題のあるコードを見つける - -Node.js ≥ 8.0.0 (これが推奨されています) を使用している場合、Node.js は関連するコードを見つけるのに役立つ複数のオプションを公開します。 - -- `--trace-warnings` は Node.js にこの警告と Node.js によって表示される他の警告のスタックトレースを表示させます -- `--trace-deprecation` でも同じことができますが、それは非推奨警告のためだけです -- `--pending-deprecation` はより多くの種類の非推奨警告を表示します。特に Node.js 8 でも、`Buffer()` の非推奨警告が表示されます - -環境変数を使用してこれらのフラグを設定できます。 - -```bash -$ export NODE_OPTIONS='--trace-warnings --pending-deprecation' -$ cat example.js -'use strict'; -const foo = new Buffer('foo'); -$ node example.js -(node:7147) [DEP0005] DeprecationWarning: The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead. - at showFlaggedDeprecation (buffer.js:127:13) - at new Buffer (buffer.js:148:3) - at Object. (/path/to/example.js:2:13) - [... more stack trace lines ...] -``` - - - -### リンターを使用して問題のあるコードを見つける - -ESLint の規則 [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor) -または -[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) にも、廃止予定の `Buffer()` API への呼び出しを検知する API があります。 -これらの規則はいくつかのプリセットに含まれています。 - -ただし、`Buffer` がオーバーライドされると -必ずしも[正しく動作する](https://github.com/chalker/safer-buffer#why-not-safe-buffer)とは限らないという欠点があります。 -ポリフィルでは、この方法と上記の他の方法を -組み合わせて使用することをお勧めします。 - -## Variant 1: Node.js ≤ 4.4.x および 5.0.0 — 5.9.x のサポートを終了 - -これは現在推奨されている解決策であり、最小限のオーバーヘッドしか意味しません。 - -Node.js 5.x リリースラインは 2016 年 7 月からサポートされていません。Node.js 4.x リリースラインは 2018 年 4 月にサポート終了となります (→ [Schedule](https://github.com/nodejs/Release#release-schedule))。つまり、セキュリティ上の問題が発生した場合でも、これらのバージョンの Node.js は更新を*受け取らない*ので、可能な限りこれらのリリースラインを使用しないでください。 - -この場合にすることは、すべての `new Buffer()` または `Buffer()` 呼び出しが `Buffer.alloc()` または `Buffer.from()` を使用するように変換することです。 - -- `new Buffer(number)` の場合は、`Buffer.alloc(number)` に置き換えます -- `new Buffer(string)` (または `new Buffer(string, encoding)`) の場合は、`Buffer.from(string)` (または `Buffer.from(string, encoding)`) に置き換えます -- 他のすべての引数の組み合わせ (これは滅多にありません)では、`new Buffer(...arguments)` を `Buffer.from(...arguments)` に置き換えます - -`Buffer.alloc()` は現在の Node.js バージョンにおいても -`new Buffer(size).fill(0)`と比べて _より速い_ ことに注意してください。 - -ESLint ルール [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor) -または -[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) を有効にすることは、 -誤った安全でない `Buffer` API の使用を避けるために推奨されます。 - -`Buffer` コンストラクタを自動的に `Buffer.alloc()` または `Buffer.from()` に移行するための -[JSCodeshift codemod](https://github.com/joyeecheung/node-dep-codemod#dep005) もあります。 -現在のところ、引数がリテラルである場合、 -またはコンストラクタが 2 つの引数で呼び出される場合にのみ機能することに注意してください。 - -_現在、古いバージョンの Node.js をサポートしていて、それらのサポートを削除することができない場合、または古いブランチをサポートしている場合は、 -[Variant 2](#variant-2) または [Variant 3](#variant-3) の使用を検討してください。また修正を受け取ります。 -そうすることで、無防備な `Buffer` API の使用によって引き起こされる潜在的な問題を根絶し、 -Node.js 10 でコードを実行するときにユーザは実行時廃止予定の警告を見ることはないでしょう。_ - -## Variant 2: ポリフィルの使用 - -利用可能な 3 つの異なるポリフィルがあります。 - -- **[safer-buffer](https://www.npmjs.com/package/safer-buffer)** は `Buffer` API 全体の代わりとなるドロップインであり、 - `new Buffer()` を使用すると _throw_ します。 - - [Variant 1](#variant-1)とまったく同じ手順を踏みますが、 - 新しい `Buffer` API を使うすべてのファイルにポリフィル `const Buffer = require('safer-buffer').Buffer` を入れます。 - - 古い `new Buffer()` API を使わないでください。上記の行が追加されているファイルでは、 - 古い `new Buffer()` API を使用すると _throw_ されます。 - -- **[buffer-from](https://www.npmjs.com/package/buffer-from) - または [buffer-alloc](https://www.npmjs.com/package/buffer-alloc)** あるいはその両方は - `Buffer` API のそれぞれの部分の [ポリフィル](https://ponyfill.com/) です。 - 使用している API に対応するパッケージを追加するだけです。 - - 必要なモジュールを適切な名前、例えば `const bufferFrom = require('buffer-from')` でインポートします。 - そして `new Buffer()` の呼び出しの代わりにそれを使います。 - `new Buffer('test')` は `bufferFrom('test')`になります。 - - このアプローチの欠点は、移行するためのコード変更 (たとえば、`Buffer.from()` を別の名前で使用しているような) が - 多少増えることです。 - -- **[safe-buffer](https://www.npmjs.com/package/safe-buffer)** も `Buffer` API 全体の代わりになるドロップインですが、 - `new Buffer()` を使用しても以前と同じように動作します。 - - このアプローチのマイナス面は、コード内で古い `new Buffer()` API を使用することも可能になることです。 - これは、コード内で問題を引き起こす可能性があり、 - Node.js 10 以降で実行時に非推奨の警告を発行し始めます - ([詳細はこちらをご覧ください](https://github.com/chalker/safer-buffer#why-not-safe-buffer))。 - -どちらの場合も、古い `Buffer` API へのすべての呼び出しを手動で削除することも重要です。 -`safe-buffer` を投入しただけでは問題が解決するわけではなく、新しい API にポリフィルを提供するだけです。 -その間違いをしている人を見かけます。 - -ESLint ルールの [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor) -または -[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) を有効にすることを -お勧めします。 - -_Node.js 4.5.0 以前のサポートを終了したら、必ず polyfill の使用をやめてください。_ - - - -## Variant 3 — セーフガード付きの手動検出 - -これは、少数の場所 (たとえば 1 か所) だけで `Buffer` インスタンスを作成する場合、 -またはそれらの周りに独自のラッパーがある場合に便利です。 - -### `Buffer(0)` - -空のバッファを作成するためのこの特別なケースは安全に `Buffer.concat([])` で置き換えることができます。 -これは Node.js 0.8.x までずっと同じ結果を返します。 - -### `Buffer(notNumber)` - -使用前: - -```js -const buf = new Buffer(notNumber, encoding); -``` - -使用後: - -```js -let buf; -if (Buffer.from && Buffer.from !== Uint8Array.from) { - buf = Buffer.from(notNumber, encoding); -} else { - if (typeof notNumber === 'number') { - throw new Error('The "size" argument must be not of type number.'); - } - buf = new Buffer(notNumber, encoding); -} -``` - -`encoding` は任意です。 - -`new Buffer()` の前の `typeof notNumber` は必須であり (`notNumber` 引数がハードコーディングされていない場合)、 -_`Buffer` コンストラクタの廃止が原因ではない_ ことに注意してください。 -`Buffer` コンストラクタが廃止されるのはそのためです。 -この型チェックに欠けているエコシステムパッケージは多くのセキュリティ問題を引き起こしました。 -悪意のあるユーザー入力が `Buffer(arg)` になって DoS からプロセスメモリから攻撃者への機密情報の漏洩に至る問題を引き起こすことです。 - -`notNumber` 引数がハードコードされている場合 (例: リテラル `"abc"` または `[0,1,2]`)、 -`typeof` チェックは省略できます。 - -また、TypeScript を使用してもこの問題は解決されないことに注意してください。 -`TypeScript` で記述されたライブラリが JS から使用される場合、またはユーザ入力がそこで終わる場合、 -すべての型チェックは変換時のみであり、 -TS がコンパイルする実際の JS コードには存在しません。 - -### `Buffer(number)` - -Node.js 0.10.x (およびそれ以下) をサポートする場合 - -```js -let buf; -if (Buffer.alloc) { - buf = Buffer.alloc(number); -} else { - buf = new Buffer(number); - buf.fill(0); -} -``` - -そうでない場合 (Node.js 0.12.x 以降): - -```js -const buf = Buffer.alloc ? Buffer.alloc(number) : new Buffer(number).fill(0); -``` - - - -## `Buffer.allocUnsafe()` について - -`Buffer.allocUnsafe()` を使用するときは特に注意してください: - -- 正当な理由がない場合は使用しないでください - - 例えば、おそらく小さなバッファのパフォーマンスの違いを見たことがない場合でしょう。 - 実際、それらは `Buffer.alloc()` でもっと速いかもしれません - - コードがホットコードパスにない場合 - おそらく違いに気付かないでしょう - - ゼロフィリングは潜在的なリスクを最小限に抑えることに留意してください -- 使用する場合は、決してバッファを部分的に満たした状態で返さないようにしてください - - 順番にそれを書いているならば - 常に実際に書かれた長さにそれを切り捨てます - -`Buffer.allocUnsafe()` で割り当てられたバッファの処理エラーは、 -コードの未定義の動作からリモートの攻撃者に漏洩する機密データ (ユーザ入力、パスワード、証明書) まで、 -さまざまな問題を引き起こす可能性があります。 - -_Node.js のバージョンによっては、ゼロフィリングなしに `new Buffer()` を使用する場合も同様です -(また、型チェックがないと、DoS が潜在的な問題のリストに追加されます)。_ - -## FAQ - -### `Buffer` コンストラクタの何が問題になっていますか。 - -`Buffer` コンストラクタは、さまざまな方法でバッファを作成するために使うことができます: - -- `new Buffer(42)` は 42 バイトの `Buffer` を作成します。 - Node.js 8 以前は、このバッファにはパフォーマンス上の理由から*任意のメモリ*が含まれていました。 - これには、プログラムのソースコードからパスワードや暗号化キーまで、さまざまなものが含まれます。 -- `new Buffer('abc')` は、文字列 `'abc'` の UTF-8 エンコードバージョンを含む `Buffer` を作成します。 - 2 番目の引数は別のエンコーディングを指定できます。 - たとえば、`new Buffer(string, 'base64')` を使用して、 - Base64 文字列をそれが表す元のバイトシーケンスに変換できます。 -- 引数には他にもいくつかの組み合わせがあります。 - -つまり、`var buffer = new Buffer(foo);`のようなコードでは、 -`foo` の型を知ることなしに、生成されたバッファの内容が正確に何であるかを知ることはできません。 - -時々、`foo` の値は外部の情報源から来ます。 -たとえば、この関数は Web サーバ上のサービスとして公開され、UTF-8 文字列を Base64 形式に変換します: - -```js -function stringToBase64(req, res) { - // リクエストボディは `{ string: 'foobar' }` のフォーマットを持つべきです。 - const rawBytes = new Buffer(req.body.string); - const encoded = rawBytes.toString('base64'); - res.end({ encoded }); -} -``` - -このコードは `req.body.string` の型を検証*しない*ことに注意してください: - -- `req.body.string` は文字列であることが期待されています。この場合、すべてうまくいきます。 -- `req.body.string` はリクエストを送信するクライアントによって制御されます。 -- `req.body.string` が _数値の_ `50` の場合、 `rawBytes` は `50` バイトになります。 - - Node.js 8 以前の場合、コンテンツは初期化されていませんでした。 - - Node.js 8 以降の場合、コンテンツは値が `0` の `50` バイトになります。 - -型チェックがないため、攻撃者は意図的にリクエストの一部として番号を送信する可能性があります。 -これを使用して、次のいずれかを実行する可能性があります: - -- 未初期化メモリを読み取ります。 - これにより、パスワード、暗号化キー、その他の機密情報が**漏洩します**。(情報漏洩) -- プログラムに大量のメモリーを割り当てさせます。 - たとえば、`500000000` を入力値として指定した場合、各リクエストは 500MB のメモリを割り当てます。 - これは、プログラムの利用可能なメモリを完全に使い果たしてクラッシュさせる、 - または大幅に遅くするために使用できます。(サービス拒否) - -これらのシナリオは両方とも、 -実際の Web サーバのコンテキストでは深刻なセキュリティ問題と見なされています。 - -代わりに `Buffer.from(req.body.string)` を使うと、 -数値を渡すと常に例外を投げ、 -常にプログラムによって処理されることができる制御された振る舞いを与えます。 - -### `Buffer()` コンストラクタはしばらくの間非推奨です。これは本当に問題なのでしょうか。 - -`npm` エコシステムのコードを調査したところ、`Buffer()` コンストラクターはまだ広く使用されていることがわかりました。 -これには新しいコードも含まれ、 -そのようなコードの全体的な使用量は実際には*増え続けています*。 diff --git a/pages/ja/docs/guides/debugging-getting-started.md b/pages/ja/docs/guides/debugging-getting-started.md deleted file mode 100644 index dd2bb5baf9644..0000000000000 --- a/pages/ja/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,522 +0,0 @@ ---- -title: デバッグ - 入門 -layout: docs.hbs ---- - -# デバッグガイド - -このガイドは、Node.js アプリケーションとスクリプトのデバッグを開始するのに役立ちます。 - - - -## インスペクタを有効にする - -`--inspect` スイッチを指定して起動すると、Node.js プロセスはデバッグクライアントを待機します。 -デフォルトでは、ホストとポート 127.0.0.1:9229 で待機します。 -各プロセスには固有の [UUID][] も割り当てられています。 - -インスペクタクライアントは、接続するホストアドレス、ポート、および UUID を認識して指定する必要があります。 -フル URL は、 -`ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e` のようになります。 - -Node.js は、`SIGUSR1` シグナルを受信した場合にもデバッグメッセージの受信を開始します -(`SIGUSR1` は Windows では使用できません)。 -Node.js 7 以前では、これにより古い Debugger API がアクティブになります。 -Node.js 8 以降では、Inspector API を起動します。 - ---- - - - -## セキュリティへの影響 - -デバッガは Node.js 実行環境にフルアクセスできるため、 -このポートに接続できる悪意のあるアクターが Node プロセスに代わって任意のコードを実行できる可能性があります。 -パブリックおよびプライベートネットワークでデバッガポートを公開することによる -セキュリティへの影響を理解することが重要です。 - - - -### デバッグポートを公開するのは危険です - -デバッガがパブリック IP アドレス、または 0.0.0.0 にバインドされている場合、 -自分の IP アドレスに到達できるクライアントは制限なしにデバッガに接続でき、 -任意のコードを実行できます。 - -デフォルトでは、`node --inspect` は 127.0.0.1 にバインドします。 -デバッガへの外部接続を許可する場合は、明示的にパブリック IP アドレスまたは 0.0.0.0 などを指定する必要があります。 -これを行うと、潜在的に重大なセキュリティ上の脅威にさらされる可能性があります。 -セキュリティ上の問題を防ぐために、適切なファイアウォールとアクセス制御を -適切に設定することをお勧めします。 - -リモートデバッガクライアントの接続を安全に許可する方法については、 -'[リモートデバッグシナリオの有効化](#enabling-remote-debugging-scenarios)'のセクションを参照してください。 - - - -### ローカルアプリケーションはインスペクタにフルアクセスできます - -インスペクタポートを 127.0.0.1 (デフォルト) にバインドしても、 -マシン上でローカルに実行されているすべてのアプリケーションに無制限のアクセス権が与えられます。 -これはローカルデバッガが便利にアタッチできるようにするための仕様です。 - - - -### ブラウザ、WebSocket、および同一生成元ポリシー - -Web ブラウザで開かれた Web サイトは、ブラウザセキュリティモデルの下で -WebSocket および HTTP リクエストを行うことができます。 -一意のデバッガセッション ID を取得するには、 -最初の HTTP 接続が必要です。 -同一生成元ポリシーは、Web サイトがこの HTTP 接続を確立できないようにします。 -[DNS リバインド攻撃](https://en.wikipedia.org/wiki/DNS_rebinding)に対するさらなるセキュリティのために、 -Node.js は接続のための 'Host' ヘッダが IP アドレスまたは `localhost` もしくは `localhost6` を正確に指定していることを検証します。 - -これらのセキュリティポリシーでは、ホスト名を指定してリモートデバッグサーバーに接続することを禁止しています。 -この制限を回避するには、IP アドレスを指定するか、 -または後述のように ssh トンネルを使用します。 - - - -## インスペクタクライアント - -一部の商用およびオープンソースのツールが Node の Inspector に接続できます。 -これらに関する基本的な情報は次のとおりです。 - - - -### [node-inspect](https://github.com/nodejs/node-inspect) - -- [Inspector プロトコル][]を使用する Node.js Foundation によってサポートされている CLI デバッガ -- バージョンは Node にバンドルされており、`node inspect myscript.js`と一緒に使うことができます -- 最新バージョンは独立してインストールすることもでき (例えば `npm install -g node-inspect`)、 `node-inspect myscript.js` と一緒に使うことができます - - - -### [Chrome DevTools](https://github.com/ChromeDevTools/devtools-frontend) 55+ - -- **オプション 1**: Chromium ベースのブラウザで `chrome://inspect` を開きます。設定ボタンをクリックして、ターゲットホストとポートが表示されていることを確認します。 -- **オプション 2**: `/json/list`の出力 (上記を参照) または --inspect ヒントテキストから `devtoolsFrontendUrl` をコピーして Chrome に貼り付けます - - - -### [Visual Studio Code](https://github.com/microsoft/vscode) 1.10+ - -- デバッグパネルで、設定アイコンをクリックして `.vscode/launch.json` を開きます。初期設定は "Node.js" を選択してください - - - -### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- メニューから "デバッグ > デバッグの開始" を選択するか、F5 を押します -- [詳しい説明](https://github.com/Microsoft/nodejstools/wiki/Debugging) - - - -### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) 2017.1+ と他の JetBrains IDE - -- 新しい Node.js デバッグ設定を作成して Debug をクリックします。Node.js 7 以降の場合、`--inspect` がデフォルトで使用されます。IDE レジストリで `js.debugger.node.use.inspect` のチェックを外します - - - -### [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - -- Inspector Protocol エンドポイントへの接続を容易にするためのライブラリ - - - -### [Gitpod](https://www.gitpod.io) - -- `Debug` ビュー から Node.js デバッグ設定を開始するか、`F5` を押します。[詳しい説明](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1) - ---- - - - -## コマンドラインオプション - -次の表は、デバッグ時のさまざまなランタイムフラグの影響を示しています。 - - - - - - - - - - - - - - - - - - - - - - - - - - - -
フラグ意味
--inspect -
    -
  • インスペクタエージェントを有効にする
  • -
  • デフォルトのアドレスとポートで待機する (127.0.0.1:9229)
  • -
-
--inspect=[host:port] -
    -
  • インスペクタエージェントを有効にする
  • -
  • アドレスまたはホスト名 host にバインド (デフォルト: 127.0.0.1)
  • -
  • port ポートで待ち受ける (デフォルト: 9229)
  • -
-
--inspect-brk -
    -
  • インスペクタエージェントを有効にする
  • -
  • デフォルトのアドレスとポートで待機する (127.0.0.1:9229)
  • -
  • ユーザーコードが始まる前に中断する
  • -
-
--inspect-brk=[host:port] -
    -
  • インスペクタエージェントを有効にする
  • -
  • アドレスまたはホスト名 host にバインド (デフォルト: 127.0.0.1)
  • -
  • port ポートで待ち受ける (デフォルト: 9229)
  • -
  • ユーザーコードが始まる前に中断する
  • -
-
node inspect script.js -
    -
  • --inspect フラグの下でユーザのスクリプトを実行するための子プロセスを生成します。そして CLI デバッガを動かすのに主要なプロセスを使用します
  • -
-
node inspect --port=xxxx script.js -
    -
  • --inspect フラグの下でユーザのスクリプトを実行するための子プロセスを生成します。そして CLI デバッガを動かすのに主要なプロセスを使用します
  • -
  • port ポートで待ち受ける (デフォルト: 9229)
  • -
-
- ---- - - - -## リモートデバッグシナリオを有効にする - -デバッガがパブリック IP アドレスを待ち受けないようにすることをお勧めします。 -リモートデバッグ接続を許可する必要がある場合は、代わりに ssh トンネルを使用することをお勧めします。 -以下の例は、説明のみを目的として提供されています。 -続行する前に特権サービスへのリモートアクセスを許可することの -セキュリティリスクを理解してください。 - -リモートマシン remote.example.com で Node を実行していて、デバッグできるようにしたいとしましょう。 -そのマシンでは、インスペクタが localhost (デフォルト) のみを監視して -ノードプロセスを開始する必要があります。 - -```bash -node --inspect server.js -``` - -これで、デバッグクライアント接続を開始したい場所から -ローカルマシンに SSH トンネルを設定できます。 - -```bash -ssh -L 9221:localhost:9229 user@remote.example.com -``` - -これにより、ローカルマシンの 9221 ポートへの接続が -remote.example.com の 9229 ポートに転送される ssh トンネルセッションが開始されます。 -これで、Chrome DevTools や Visual Studio Code などのデバッガを localhost:9221 にアタッチできます。 -Node.js アプリケーションがローカルで実行されているかのようにデバッグできるはずです。 - ---- - - - -## レガシーデバッガ - -**レガシーデバッガは Node 7.7.0 の時点で非推奨になりました。代わりに --inspect と Inspector を使ってください。** - -バージョン7以前の **--debug** または **--debug-brk** スイッチを指定して起動すると、 -Node.js は TCP ポートで廃止された V8 デバッグプロトコルで定義されている -デバッグコマンド (デフォルトでは `5858`) を待ち受けます。 -これで実行中のプロセスに接続してデバッグできます。 -いくつかのポピュラーなものは以下のとおりです。 - -V8 デバッグプロトコルは、もはや保守もドキュメンテーションもされていません。 - - - -### [組み込みデバッガ](https://nodejs.org/dist/latest/docs/api/debugger.html) - -Node の組み込みコマンドラインデバッガの下でスクリプトを起動するには、 -`node debug script_name.js` を起動します。 -スクリプトは `--debug-brk` オプションで開始された別のノードプロセスで開始され、 -最初のノードプロセスは `_debugger.js` スクリプトを実行してターゲットに接続します。 - - - -### [node-inspector](https://github.com/node-inspector/node-inspector) - -Chromium で使用されるインスペクタプロトコルを -Node.js で使用される V8 デバッガプロトコルに変換する中間プロセスを使用して、 -Chrome DevTools で Node.js アプリケーションをデバッグします。 - - - - - -[Inspector プロトコル]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/ja/docs/guides/diagnostics-flamegraph.md b/pages/ja/docs/guides/diagnostics-flamegraph.md deleted file mode 100644 index 7383fd440f4f1..0000000000000 --- a/pages/ja/docs/guides/diagnostics-flamegraph.md +++ /dev/null @@ -1,281 +0,0 @@ ---- -title: 診断 - フレームのグラフ -layout: docs.hbs ---- - - - -# フレームのグラフ - -## フレームグラフは何に役立ちますか? - -フレームグラフは、関数で費やされた CPU 時間を視覚化する方法です。同期処理に時間がかかりすぎる場所を特定するのに役立ちます。 - - - -## フレームグラフの作り方 - -Node.js のフレームグラフを作成するのは難しいと聞いたことがあるかもしれませんが、(もはや) そうではありません。 -Solaris vms はフレームグラフには不要です。 - -フレームグラフは `perf` 出力から生成されます。これは Node 固有のツールではありません。これは、費やされた CPU 時間を視覚化する最も強力な方法ですが、Node.js 8 以降で JavaScript コードが最適化される方法に問題がある可能性があります。下記の[perf 出力の問題](#perf-output-issues) のセクションを参照してください。 - - - -### あらかじめパッケージ化されたツールを使う - -部分的にフレームグラフを作成する単一のステップが必要な場合は、[0x](https://www.npmjs.com/package/0x) を試してください。 - -運用環境のデプロイメントを診断するために、[0x 運用サーバ][]という注意書きを読みましょう。 - - - -### システムパフォーマンスツールでフレームグラフを作成する - -このガイドの目的は、フレームグラフの作成に関連する手順を示し、各手順を管理し続けることです。 - -それぞれのステップをよりよく理解したいならば、続くセクションを見てください。 - -それでは作業に取り掛かりましょう。 - - - -1. `perf` をインストールします (まだインストールされていなければ、通常 linux-tools-common パッケージ経由で利用可能です) -2. `perf` を実行してみてください - カーネルモジュールが足りないと表示されるかもしれません、それらもインストールしてください -3. perf を有効にして node を実行します (Node.js のバージョンに固有のヒントについては [perf の出力の問題](#perf-output-issues) を参照してください) - - ```bash - perf record -e cycles:u -g -- node --perf-basic-prof app.js - ``` - -4. パッケージが足りないために perf を実行できないと表示されていない限り、警告を無視してください。カーネルモジュールのサンプルにアクセスできないという警告が表示されることがあります -5. `perf script > perfs.out` を実行して、すぐに視覚化できるデータファイルを生成します。読みやすいグラフに[クリーンアップを適用する](#filtering-out-node-internal-functions)と便利です -6. stackvis がインストールされていない場合は、`npm i -g stackvis`を実行して stackvis をインストールします -7. `stackvis perf < perfs.out > flamegraph.htm` を実行します - - - -お気に入りのブラウザでフレームグラフファイルを開いて、それが出力されるのを見てください。色分けされているので、最初に最も彩度の高いオレンジ色のバーに集中できます。それらは CPU を多用する機能を表している可能性があります。 - -言及する価値のあること - フレームグラフの要素をクリックするならば、その周囲のズームインはグラフの上に表示されるでしょう。 - - - -### `perf`を使って実行中のプロセスをサンプリングする - -これは、中断したくない、既に実行中のプロセスからフレームグラフデータを記録するのに最適です。再現が困難な問題を伴う製造プロセスを想像してください。 - -```bash -perf record -F99 -p `pgrep -n node` -g -- sleep 3 -``` - -ちょっと待ってください、何のための `sleep 3` でしょうか? それはperf を実行し続けるためにあります。`-p` オプションが異なる pid を指していますが、コマンドはプロセス上で実行され、そこで終了する必要があります。perf は、実際にそのコマンドをプロファイリングしているかどうかにかかわらず、渡したコマンドの存続期間にわたって実行されます。`sleep 3` は perf が 3 秒間実行されるようにします。 - -`-F` (プロファイリング頻度) が 99 に設定されているのはなぜですか? これは妥当なデフォルトの値です。必要に応じて調整できます。`-F99` はサンプルを毎秒 99 取るように perf に指示します。より正確にするには値を増やします。値が低いと出力が少なくなり、精度が低下します。必要な精度は、CPU に負荷がかかる機能が実際にどれくらいの時間実行されるかによって異なります。顕著な減速の理由を探しているなら、毎秒 99 フレームで十分すぎるはずです。 - -その 3 秒の perf レコードを取得したら、上に書いてある手順の最後の2つを実施してフレームグラフの生成に進みます。 - - - -### Node.js の内部関数を除外する - -通常、自身の呼び出しのパフォーマンスを見たいだけなので、Node.js と V8 の内部関数を除外することでグラフをもっと読みやすくすることができます。次のようにして perf ファイルをクリーンアップできます。 - -```bash -sed -i -r \ - -e "/( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)/d" \ - -e 's/ LazyCompile:[*~]?/ /' \ - perfs.out -``` - -フレームグラフを参照していて、何か時間がかかるキー関数が欠けているかのように不思議に思った場合は、フィルタなしでフレームグラフを生成してみてください。Node.js 自体に問題が発生することはまれです。 - - - -### Node.js のプロファイリングオプション - -`--perf-basic-prof-only-functions` と `--perf-basic-prof` は JavaScript コードをデバッグするのに便利です。Node.js 自体をプロファイリングするために他のオプションが使用されますが、これはこのガイドの範囲外です。 - -`--perf-basic-prof-only-functions` は出力が少なくなるので、オーバーヘッドが最も少ないオプションです。 - - - -### どうしてそれらを全く必要としないのですか? - -ええ、これらのオプションがなくてもフレームグラフが得られますが、ほとんどのバーには `v8::Function::Call` というラベルが付いています。 - - - -## `perf`出力の問題 - -### Node.js 8.x V8 パイプラインの変更 - -Node.js 8.x 以降には、V8 エンジンの JavaScript コンパイルパイプラインに対する新しい最適化が付属しているため、関数名/参照がperf にアクセスできない場合があります。(それはターボファンと呼ばれています) - -その結果、関数名がフレームグラフの中で正しく得られないかもしれません。 - -あなたは、関数名を期待するところで `ByteCodeHandler:` に気付くでしょう。 - -[0x](https://www.npmjs.com/package/0x) にはいくつかの緩和策が組み込まれています。 - -詳細: - -- https://github.com/nodejs/benchmarking/issues/168 -- https://github.com/nodejs/diagnostics/issues/148#issuecomment-369348961 - - - -### Node.js 10 以降 - -Node.js 10.x は Turbofan の問題に `--interpreted-frames-native-stack` フラグを使って対処します。 - -JavaScript をコンパイルするためにどの V8 パイプラインが使用されたかにかかわらず、フレームグラフの関数名を得るために `node --interpreted-frames-native-stack --perf-basic-prof-only-functions` を実行してください。 - - - -### フレームグラフのラベルが壊れている - -このようなラベルが表示されている場合 - -``` -node`_ZN2v88internal11interpreter17BytecodeGenerator15VisitStatementsEPNS0_8ZoneListIPNS0_9StatementEEE -``` - -それは使っている Linux の perf が demangle サポート付きでコンパイルされていないことを意味します。例は https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 を参照してください。 - - - -## 例 - -[フレームグラフ演習](https://github.com/naugtur/node-example-flamegraph)を使用してフレームグラフを自分でキャプチャする練習をしてください! - -[0x 運用サーバ]: https://github.com/davidmarkclements/0x/blob/master/docs/production-servers.md diff --git a/pages/ja/docs/guides/getting-started-guide.md b/pages/ja/docs/guides/getting-started-guide.md deleted file mode 100644 index 99d5d73008e76..0000000000000 --- a/pages/ja/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: 入門ガイド -layout: docs.hbs ---- - - - -# はじめての Web サーバー - - - -Node をインストールしたら、まずはじめに Web サーバーを構築してみましょう。 -"app.js" という名前のファイルを作成し、以下のコードをコピー&ペーストしましょう。 - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - - - -その後、 `node app.js` を使って Web サーバーを起動し、`http://localhost:3000` にアクセスすると、 'Hello World' というメッセージが表示されます。 diff --git a/pages/ja/docs/guides/index.md b/pages/ja/docs/guides/index.md deleted file mode 100644 index eb3644aee3789..0000000000000 --- a/pages/ja/docs/guides/index.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: ガイド -layout: docs.hbs ---- - - - -# ガイド - -## 一般 - -- [入門ガイド](/ja/docs/guides/getting-started-guide/) -- [デバッグ - 入門](/ja/docs/guides/debugging-getting-started/) -- [Node.js アプリケーションの簡単なプロファイリング](/ja/docs/guides/simple-profiling/) -- [診断 - フレームのグラフ](/ja/docs/guides/diagnostics-flamegraph/) -- [Node.js Web アプリケーションを Docker 化する](/ja/docs/guides/nodejs-docker-webapp/) -- [安全な Buffer コンストラクタへの移行](/ja/docs/guides/buffer-constructor-deprecation/) - - - -## Node.js コアコンセプト - -- [ブロッキングとノンブロッキングの概要](/ja/docs/guides/blocking-vs-non-blocking/) -- [Node.js イベントループ、タイマー、そして `process.nextTick()`](/ja/docs/guides/event-loop-timers-and-nexttick/) -- [イベントループ (またはワーカープール) をブロックしない](/ja/docs/guides/dont-block-the-event-loop/) -- [Node.js のタイマー](/ja/docs/guides/timers-in-node/) - - - -## モジュール関連ガイド - -- [HTTP トランザクションの構造](/ja/docs/guides/anatomy-of-an-http-transaction/) -- [異なるファイルシステムで作業する](/ja/docs/guides/working-with-different-filesystems/) -- [ストリーム内の背圧](/ja/docs/guides/backpressuring-in-streams/) -- [ドメインモジュールの事後分析](/ja/docs/guides/domain-postmortem/) -- [N-API パッケージを公開する方法](/ja/docs/guides/publishing-napi-modules/) -- [ABI の安定性](/ja/docs/guides/abi-stability/) diff --git a/pages/ja/docs/guides/nodejs-docker-webapp.md b/pages/ja/docs/guides/nodejs-docker-webapp.md deleted file mode 100644 index cfe6f0537d281..0000000000000 --- a/pages/ja/docs/guides/nodejs-docker-webapp.md +++ /dev/null @@ -1,566 +0,0 @@ ---- -title: Node.js Web アプリケーションを Docker 化する -layout: docs.hbs ---- - - - -# Node.js Web アプリケーションを Docker 化する - -この例の目的は、Node.js アプリケーションを Docker コンテナに取り込む方法を説明することです。 -このガイドは開発を目的としており、 -本番展開を目的と*していません*。 -このガイドでは、正常に [Docker がインストール](https://docs.docker.com/engine/installation/)され、 -Node.js アプリケーションがどのように構成されているかについての基本的な知識があることも前提としています。 - -このガイドの最初の部分では、Node.js で単純な Web アプリケーションを作成してから、 -そのアプリケーション用の Docker イメージを作成し、 -最後にそのイメージをコンテナとして実行します。 - -Docker を使用すると、ソフトウェア開発用に、コンテナと呼ばれる標準化された単位に -すべての依存関係を持つアプリケーションをパッケージ化できます。 -コンテナは、Linux オペレーティングシステムの基本バージョンを削除したものです。 -イメージはコンテナにロードするソフトウェアです。 - - - -## Node.js アプリケーションを作成する - -まず、すべてのファイルを配置する新しいディレクトリを作成します。 -このディレクトリにあなたのアプリケーションとその依存関係を記述する `package.json` ファイルを作成してください: - -```json -{ - "name": "docker_web_app", - "version": "1.0.0", - "description": "Node.js on Docker", - "author": "First Last ", - "main": "server.js", - "scripts": { - "start": "node server.js" - }, - "dependencies": { - "express": "^4.16.1" - } -} -``` - -新しい `package.json` ファイルを使って、`npm install` を実行してください。 -バージョン 5 以降の `npm` を使っているなら、 -これは Docker イメージにコピーされる `package-lock.json` ファイルを生成します。 - -それから、[Express.js](https://expressjs.com/) フレームワークを使って -Web アプリケーションを定義する `server.js` ファイルを作成します。 - -```javascript -'use strict'; - -const express = require('express'); - -// Constants -const PORT = 8080; -const HOST = '0.0.0.0'; - -// App -const app = express(); -app.get('/', (req, res) => { - res.send('Hello World'); -}); - -app.listen(PORT, HOST, () => { - console.log(`Running on http://${HOST}:${PORT}`); -}); -``` - -次のステップでは、公式の Docker イメージを使用して -Docker コンテナ内でこのアプリケーションを実行する方法を見ていきます。 -まず、アプリケーションの Docker イメージを作成する必要があります。 - - - -## Dockerfile を作成する - -`Dockerfile` という名前の空のファイルを作ります。 - -```markup -touch Dockerfile -``` - -お気に入りのテキストエディタで `Dockerfile` を開きます - -最初にしなければならないことは、どのイメージから構築したいかを定義することです。 -ここでは[Docker Hub](https://hub.docker.com/)から入手できる -`node` の最新の LTS (long term support) バージョン `12` を使います。 - -```docker -FROM node:12 -``` - -次に、イメージ内にアプリケーションコードを入れるディレクトリを作成します。 -アプリケーションの作業ディレクトリになります。 - -```docker -# アプリケーションディレクトリを作成する -WORKDIR /usr/src/app -``` - -このイメージには Node.js と NPM が既にインストールされていますので、 -次に必要な作業は `npm` バイナリを使ってアプリケーションの依存関係をインストールすることです。 -`npm` バージョン 4 以前を使用している場合、 -`package-lock.json` ファイルは*生成されない*ことに注意してください。 - -```docker -# アプリケーションの依存関係をインストールする -# ワイルドカードを使用して、package.json と package-lock.json の両方が確実にコピーされるようにします。 -# 可能であれば (npm@5+) -COPY package*.json ./ - -RUN npm install -# 本番用にコードを作成している場合 -# RUN npm install --only=production -``` - -作業ディレクトリ全体をコピーするのではなく、 -`package.json` ファイルだけをコピーしていることに注意してください。 -これにより、キャッシュされた Docker レイヤーを利用することができます。 -bitJudo は[このこと](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/)についてよく説明しています。 - -アプリケーションのソースコードを Docker イメージ内にバンドルするには、`COPY` -命令を使います。 - -```docker -# アプリケーションのソースをバンドルする -COPY . . -``` - -アプリケーションは `8080` ポートにバインドされているので `EXPOSE` 命令を使って -`docker` デーモンによってマッピングされるでしょう: - -```docker -EXPOSE 8080 -``` - -最後に重要なことを言い忘れましたが、ランタイムを定義する `CMD` を使ってアプリケーションを実行するためのコマンドを定義してください。 -ここでサーバを起動するために `node server.js` を実行する -基本的な `npm start` を使います: - -```docker -CMD [ "node", "server.js" ] -``` - -`Dockerfile` はこのようになっているはずです。 - -```docker -FROM node:12 - -# アプリケーションディレクトリを作成する -WORKDIR /usr/src/app - -# アプリケーションの依存関係をインストールする -# ワイルドカードを使用して、package.json と package-lock.json の両方が確実にコピーされるようにします。 -# 可能であれば (npm@5+) -COPY package*.json ./ - -RUN npm install -# 本番用にコードを作成している場合 -# RUN npm install --only=production - -# アプリケーションのソースをバンドルする -COPY . . - -EXPOSE 8080 -CMD [ "node", "server.js" ] -``` - - - -## .dockerignore ファイル - -以下の内容で `Dockerfile` と同じディレクトリに `.dockerignore` ファイルを -作成してください: - -``` -node_modules -npm-debug.log -``` - -これにより、ローカルモジュールとデバッグログが Docker イメージにコピーされたり、 -イメージ内にインストールされているモジュールが上書きされたりするのを防ぐことができます。 - - - -## 自分のイメージを構築する - -`Dockerfile` があるディレクトリに行き、次のコマンドを実行して Docker イメージを構築してください。 -`-t` フラグを使うとイメージにタグを付けることができるので、 -後で `docker images` コマンドを使って見つけやすくなります。 - -```bash -docker build . -t /node-web-app -``` - -あなたのイメージは Docker によって表示されます。 - -```bash -$ docker images - -# 例 -REPOSITORY TAG ID CREATED -node 12 1934b0b038d1 5 days ago -/node-web-app latest d64d3505b0d2 1 minute ago -``` - - - -## イメージの実行 - -イメージを `-d` で実行するとコンテナは分離モードで実行され、バックグラウンドで実行されたままになります。 -`-p` フラグはパブリックポートをコンテナ内のプライベートポートにリダイレクトします。 -以前に構築したイメージを実行します。 - -```bash -docker run -p 49160:8080 -d /node-web-app -``` - -アプリの出力をプリントします。 - -```bash -# コンテナ ID を取得する -$ docker ps - -# アプリ出力をプリントする -$ docker logs - -# 例 -Running on http://localhost:8080 -``` - -コンテナの中に入る必要があるなら、`exec` コマンドを使うことができます。 - -```bash -# コンテナに入る -$ docker exec -it /bin/bash -``` - - - -## テスト - -アプリケーションをテストするには、Docker がマッピングしたアプリケーションのポートを取得します。 - -```bash -$ docker ps - -# 例 -ID IMAGE COMMAND ... PORTS -ecce33b30ebf /node-web-app:latest npm start ... 49160->8080 -``` - -上の例では、Docker はコンテナの内側の `8080` ポートをマシンの `49160` ポートに -マッピングしました。 - -これで `curl` (必要ならばインストールしてください: `sudo apt-get -install curl`) を使ってアプリを呼び出すことができます: - -```bash -$ curl -i localhost:49160 - -HTTP/1.1 200 OK -X-Powered-By: Express -Content-Type: text/html; charset=utf-8 -Content-Length: 12 -ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0" -Date: Mon, 13 Nov 2017 20:53:59 GMT -Connection: keep-alive - -Hello world -``` - -このチュートリアルが、Docker 上で簡単な Node.js アプリケーションを立ち上げて実行するのに -役立つことを願います。 - -Docker および Docker 上の Node.js に関する詳細は、 -次の場所にあります。 - -- [公式 Node.js Docker イメージ](https://hub.docker.com/_/node/) -- [Node.js Docker ベストプラクティスガイド](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md) -- [公式 Docker ドキュメント](https://docs.docker.com/) -- [Docker Tag on Stack Overflow](https://stackoverflow.com/questions/tagged/docker) -- [Docker Subreddit](https://reddit.com/r/docker) diff --git a/pages/ja/docs/guides/simple-profiling.md b/pages/ja/docs/guides/simple-profiling.md deleted file mode 100644 index 521a67d3a7343..0000000000000 --- a/pages/ja/docs/guides/simple-profiling.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -title: Node.js アプリケーションの簡単なプロファイリング -layout: docs.hbs ---- - - - -# Node.js アプリケーションの簡単なプロファイリング - -Node.js アプリケーションのプロファイリングに使用できるサードパーティ製ツールは多数ありますが、 -多くの場合、最も簡単な方法はプロファイラに組み込まれている Node.js を使用することです。 -組み込みプロファイラは、プログラムの実行中に定期的にスタックをサンプリングする -[V8 内部のプロファイラ][] を使用します。 -これらのサンプルの結果と、jit コンパイルなどの重要な最適化イベントを -一連のティックとして記録します。 - -``` -code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~ -code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~ -code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~ -code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub" -code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub" -``` - - - -以前は、ティックを解釈するために V8 ソースコードが必要でした。 -幸いなことに、Node.js 4.4.0 以降、ソースとは別に V8 を構築することなく -容易にこの情報を利用できるツールが導入されました。 -組み込みのプロファイラーがアプリケーションのパフォーマンスに関する -洞察を提供するのに役立つ方法を見てみましょう。 - - - -ティックプロファイラーの使い方を説明するために、 -簡単な Express アプリケーションを使います。 -アプリケーションには、システムに新しいユーザを追加する2つのハンドラがあります。 - -```javascript -app.get('/newUser', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users.username) { - return res.sendStatus(400); - } - - const salt = crypto.randomBytes(128).toString('base64'); - const hash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - users[username] = { salt, hash }; - - res.sendStatus(200); -}); -``` - - - -ユーザ認証の試行を検証するためのものもあります。 - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || !users[username]) { - return res.sendStatus(400); - } - - const { salt, hash } = users[username]; - const encryptHash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - if (crypto.timingSafeEqual(hash, encryptHash)) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } -}); -``` - - - -_これらは、Node.js アプリケーションでユーザを認証する推奨のハンドラではなく、 -純粋に例を示す目的で使用されていることに注意してください。 -自身の暗号認証メカニズムを一般的に設計しようとしてはいけません。 -既存の実証済みの認証ソリューションを使用することをお勧めします。_ - - - -ここで、アプリケーションをデプロイし、ユーザがリクエストの待ち時間が長いことについて不満を言っているとします。 -内蔵のプロファイラーでアプリを簡単に実行できます。 - -``` -NODE_ENV=production node --prof app.js -``` - - - -`ab` (ApacheBench) を使用してサーバに負荷をかけます。 - -``` -curl -X GET "http://localhost:8080/newUser?username=matt&password=password" -ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password" -``` - - - -そして、次の ab 出力を取得します。 - -``` -Concurrency Level: 20 -Time taken for tests: 46.932 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 5.33 [#/sec] (mean) -Time per request: 3754.556 [ms] (mean) -Time per request: 187.728 [ms] (mean, across all concurrent requests) -Transfer rate: 1.05 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 3755 - 66% 3804 - 75% 3818 - 80% 3825 - 90% 3845 - 95% 3858 - 98% 3874 - 99% 3875 - 100% 4225 (longest request) -``` - - - -この出力から、1秒あたり約5つのリクエストを処理することに成功しているだけで、 -平均リクエストはラウンドトリップで4秒弱かかります。 -実際の例では、ユーザのリクエストに代わって -多くの機能で多くの作業を行っている可能性があります。 -しかし簡単な例でさえ、正規表現のコンパイル、ランダムソルトの生成、ユーザパスワードからの一意のハッシュの生成、 -または Express フレームワーク自体の内部では、時間が無駄になる可能性があります。 - - - -`--prof` オプションを使用してアプリケーションを実行したため、 -ティックファイルはローカルで実行しているアプリケーションと同じディレクトリに生成されました。 -形式は `isolate-0xnnnnnnnnnnnn-v8.log` (`n` は数字) です。 - - - -このファイルを理解するには、Node.js バイナリにバンドルされている tick プロセッサを使用する必要があります。 -プロセッサを実行するには `--prof-process` フラグを使用します。 - -``` -node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt -``` - - - -お気に入りのテキストエディタで processed.txt を開くと、情報が何種類か表示されます。 -ファイルはセクションに分割されており、セクションは言語ごとに分割されています。 -まず、要約セクションを見ると、このようになっています: - -``` - [Summary]: - ticks total nonlib name - 79 0.2% 0.2% JavaScript - 36703 97.2% 99.2% C++ - 7 0.0% 0.0% GC - 767 2.0% Shared libraries - 215 0.6% Unaccounted -``` - - - -これは、収集されたすべてのサンプルの 97% が C++ コードで発生しており、 -処理された出力の他のセクションを見るときは -(JavaScript ではなく) C++ で行われている作業に最も注意する必要があることを示しています。 -これを念頭に置いて、次にどの C++ 関数が最も CPU 時間を消費しているかについての情報を含む -\[C++\] セクションを見てみます。 - -``` - [C++]: - ticks total nonlib name - 19557 51.8% 52.9% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 4510 11.9% 12.2% _sha1_block_data_order - 3165 8.4% 8.6% _malloc_zone_malloc -``` - - - -上位 3 つのエントリが、プログラムで使用された CPU 時間の 72.1% を占めていることがわかります。 -この出力から、すぐにユーザのパスワードからのハッシュ生成に対応する PBKDF2 と呼ばれる機能によって -CPU 時間の少なくとも 51.8% が占められていることが分かります。 -ただし、下位2つのエントリがどのように私たちのアプリケーションに組み込まれるのか -(またはそうである場合は例のために別のふりをすることになる)、 -すぐには明らかにならないかもしれません。 -これらの関数間の関係をよりよく理解するために、 -次に各関数の主な呼び出し元に関する情報を提供する \[Bottom up (heavy) profile\] セクションを見ていきます。 -このセクションを調べると、次のことがわかります。 - -``` - ticks parent name - 19557 51.8% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 19557 100.0% v8::internal::Builtins::~Builtins() - 19557 100.0% LazyCompile: ~pbkdf2 crypto.js:557:16 - - 4510 11.9% _sha1_block_data_order - 4510 100.0% LazyCompile: *pbkdf2 crypto.js:557:16 - 4510 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 - - 3165 8.4% _malloc_zone_malloc - 3161 99.9% LazyCompile: *pbkdf2 crypto.js:557:16 - 3161 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 -``` - - - -このセクションを解析することは、 -上の生のティックカウントよりも少し多くの作業を要します。 -上記の各「コールスタック」内で、親列のパーセントは、 -上の行の関数が現在の行の関数によって呼び出されたサンプルの割合を示しています。 -たとえば、\_sha1_block_data_order の上の中央の "call stack" では、 -`_sha1_block_data_order` がサンプルの 11.9% で発生していることがわかります。 -これは、上記の raw カウントからわかりました。 -ただし、ここでは、Node.js 暗号モジュール内の pbkdf2 関数によって常に呼び出されたこともわかります。 -同様に、`_malloc_zone_malloc` はほとんど同じ pbkdf2 関数によって呼び出されています。 -したがって、このビューの情報を使用して、次のことがわかります。 -`_sha1_block_data_order` と `_malloc_zone_malloc` の呼び出しは pbkdf2 関数に代わって行われたため、 -ユーザのパスワードからのハッシュ計算は、上記の 51.8% だけでなく、 -上位 3 つのサンプル関数のすべての CPU 時間も占めています。 - - - -この時点で、パスワードベースのハッシュ生成が最適化の対象になるはずです。 -幸い、[非同期プログラミングの利点][] を完全に内部化したので、 -ユーザのパスワードからハッシュを生成する作業は同期的に行われ、 -イベントループが抑制されていることがわかりました。 -これにより、ハッシュを計算している間に -他の受信したリクエストを処理することができなくなります。 - - - -この問題を解決するには、非同期バージョンの pbkdf2 関数を使用するように -上記のハンドラを少し変更します。 - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users[username]) { - return res.sendStatus(400); - } - - crypto.pbkdf2( - password, - users[username].salt, - 10000, - 512, - 'sha512', - (err, hash) => { - if (users[username].hash.toString() === hash.toString()) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } - } - ); -}); -``` - - - -非同期バージョンのアプリを使って新しい上記の ab ベンチマークを実行すると、 -次のようになります。 - -``` -Concurrency Level: 20 -Time taken for tests: 12.846 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 19.46 [#/sec] (mean) -Time per request: 1027.689 [ms] (mean) -Time per request: 51.384 [ms] (mean, across all concurrent requests) -Transfer rate: 3.82 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 1018 - 66% 1035 - 75% 1041 - 80% 1043 - 90% 1049 - 95% 1063 - 98% 1070 - 99% 1071 - 100% 1079 (longest request) -``` - - - -やりました! アプリは現在、毎秒約20リクエストを処理しています。 -これは同期ハッシュ生成の場合の約4倍です。 -さらに、平均待ち時間は4秒弱から1秒強に減少しています。 - - - -うまくいけば、この (明らかに考案された) 例のパフォーマンス調査を通じて、 -V8 ティックプロセッサが Node.js アプリケーションのパフォーマンスの理解を深めるのに -役立つ方法を見ることがあるでしょう。 - - - -[V8 内部のプロファイラ]: https://v8.dev/docs/profile -[非同期プログラミングの利点]: https://nodesource.com/blog/why-asynchronous diff --git a/pages/ja/docs/guides/timers-in-node.md b/pages/ja/docs/guides/timers-in-node.md deleted file mode 100644 index ffb31a4691113..0000000000000 --- a/pages/ja/docs/guides/timers-in-node.md +++ /dev/null @@ -1,405 +0,0 @@ ---- -title: Node.js のタイマー -layout: docs.hbs ---- - - - -# Node.js のタイマーと仕組み - -Node.js のタイマーモジュールには、 -一定期間後にコードを実行する関数が含まれています。 -ブラウザの JavaScript API をエミュレートするためにすべてのメソッドがグローバルに利用可能であるため、 -`require()` を介してタイマーをインポートする必要はありません。 -タイマー関数がいつ実行されるかを完全に理解するためには、 -Node.js の[イベントループ](/ja/docs/guides/event-loop-timers-and-nexttick/)を読むことをお勧めします。 - - - -## Node.js を使って連続した時間を制御する - -Node.js APIには、現時点以降のある時点でコードを実行するように -スケジューリングする方法がいくつかあります。 -以下の関数はほとんどのブラウザで利用可能であるためおなじみのように思われるかもしれませんが、 -Node.js は実際にはこれらのメソッドの独自の実装を提供します。 -タイマーはシステムと非常に密接に統合されており、 -API がブラウザ API を反映しているという事実があるにもかかわらず、実装にはいくつかの違いがあります。 - - - -### "そう言うとき" 実行する ~ _`setTimeout()`_ - -`setTimeout()` を使用して、 -指定したミリ秒後に -コードの実行をスケジュールすることができます。 -この関数はブラウザの JavaScript API の [`window.setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout)に似ていますが、 -コードの文字列を渡して実行することはできません。 - -`setTimeout()` は、最初の引数として実行する関数と、 -2番目の引数として数値として定義されたミリ秒の遅延を受け入れます。 -追加の引数も含めることができ、これらは関数に渡されます。 -これはその一例です: - -```js -function myFunc(arg) { - console.log(`arg was => ${arg}`); -} - -setTimeout(myFunc, 1500, 'funky'); -``` - -上記の関数 `myFunc()` は、`setTimeout()` の呼び出しにより、 -可能な限り 1500 ミリ秒 (または 1.5 秒) くらいで実行されます。 - -設定されたタイムアウト間隔は、 -その*正確な*ミリ秒数の後に実行することに依存することはできません。 -これは、イベントループをブロックまたは保留している他の実行コードがタイムアウトの実行を遅らせるためです。 -*唯一*保証されているのは、 -タイムアウトが宣言されたタイムアウト間隔より早く実行されないということです。 - -`setTimeout()` は、設定されたタイムアウトを参照するために使用できる -`Timeout` オブジェクトを返します。 -この返されたオブジェクトを使用して、タイムアウトをキャンセル (下記の `clearTimeout()` を参照) し、 -実行動作を変更 (下記の`unref()` を参照) することができます。 - - - -### "この直後に" 実行する ~ _`setImmediate()`_ - -`setImmediate()` は現在のイベントループサイクルの終わりにコードを実行します。 -このコードは、現在のイベントループ内の I/O 操作の*後*、 -および次のイベントループのためにスケジュールされたタイマーの*前*に実行されます。 -このコードの実行は「この直後」に行われると考えることができます。 -つまり、`setImmediate()` 関数呼び出しに続くコードは、 -`setImmediate()`関数引数の前に実行されます。 - -`setImmediate()` の最初の引数は実行する関数になります。 -それ以降の引数は、実行時に関数に渡されます。これが例です: - -```js -console.log('before immediate'); - -setImmediate(arg => { - console.log(`executing immediate: ${arg}`); -}, 'so immediate'); - -console.log('after immediate'); -``` - -`setImmediate()` に渡された上記の関数は、すべての実行可能コードが実行された後に実行され、 -コンソール出力は次のようになります: - -``` -before immediate -after immediate -executing immediate: so immediate -``` - -`setImmediate()` は `Immediate` オブジェクトを返します。 -これを使用して、スケジュールされた Immediate をキャンセル (下記の `clearImmediate()` を参照) できます。 - -注意: `setImmediate()` を `process.nextTick()` と混同しないでください。 -いくつかの大きな違いがあります。 -1つ目は、`process.nextTick()` は、設定されている `Immediate` やスケジュールされている I/O の*前*に実行されるということです。 -2つ目は、`process.nextTick()` は消去不可能であるということです。 -つまり、一度 `process.nextTick()` でコードを実行するようにスケジュールされると、 -通常の関数のように実行を停止することはできません。 -`process.nextTick()` の操作をよく理解するために[このガイド](/ja/docs/guides/event-loop-timers-and-nexttick/#process-nexttick)を参照してください。 - - - -### "無限ループ" 実行 ~ _`setInterval()`_ - -複数回実行する必要があるコードブロックがある場合、 -`setInterval()` を使用してそのコードを実行できます。 -`setInterval()` は2番目の引数として指定されたミリ秒の遅れで無限回実行する関数の引数を取ります。 -`setTimeout()` と同じように、遅延を超えて追加の引数を追加することができ、 -それらは関数呼び出しに渡されます。 -`setTimeout()` と同様に、イベントループに耐えることができる操作のために遅延を保証することはできません。 -したがっておおよその遅延として扱われるべきです。 -以下の例を参照してください。 - -```js -function intervalFunc() { - console.log('Cant stop me now!'); -} - -setInterval(intervalFunc, 1500); -``` - -上の例では、`intervalFunc()` は停止されるまで -約 1500 ミリ秒 (1.5秒) ごとに実行されます(下記参照)。 - -`setTimeout()` と同様に、 -`setInterval()` もまた設定された間隔を参照したり修正したりするのに使用できる `Timeout` オブジェクトを返します。 - - - -## 未来をクリアする - -`Timeout` または `Immediate` オブジェクトをキャンセルする必要がある場合はどうすればいいですか? -`setTimeout()`、`setImmediate()`、および `setInterval()` は、 -set `Timeout`または `Immediate` オブジェクトを参照するために使用できるタイマーオブジェクトを返します。 -前述のオブジェクトをそれぞれの `clear` 関数に渡すことによって、 -そのオブジェクトの実行は完全に停止されます。 -それぞれの関数は `clearTimeout()`、`clearImmediate()`、そして `clearInterval()` です。 -それぞれの例については、以下の例を参照してください: - -```js -const timeoutObj = setTimeout(() => { - console.log('timeout beyond time'); -}, 1500); - -const immediateObj = setImmediate(() => { - console.log('immediately executing immediate'); -}); - -const intervalObj = setInterval(() => { - console.log('interviewing the interval'); -}, 500); - -clearTimeout(timeoutObj); -clearImmediate(immediateObj); -clearInterval(intervalObj); -``` - - - -## 後ろにタイムアウトを残す - -`Timeout` オブジェクトは `setTimeout` と `setInterval` によって返されることを忘れないでください。 -`Timeout` オブジェクトは `unref()` と `ref()` で `Timeout` の振る舞いを増強することを目的とした2つの関数を提供します。 -`set` 関数を使ってスケジュールされた `Timeout` オブジェクトがあれば、 -そのオブジェクトに対して `unref()` を呼び出すことができます。 -これはふるまいをわずかに変えます、 -そして*それが実行する最後のコードであるなら* `Timeout` オブジェクトを呼ばないでください。 -`Timeout` オブジェクトはプロセスを実行し続け、実行するのを待ちません。 - -同様に、`unref()` が呼び出された `Timeout` オブジェクトは、 -同じ `Timeout` オブジェクトに対して `ref()` を呼び出すことでその振る舞いを取り除くことができ、 -それによってその実行が保証されます。 -ただし、パフォーマンス上の理由から、これによって初期の動作が*正確*に復元されるわけではないことに注意してください。 -両方の例については、以下を参照してください。 - -```js -const timerObj = setTimeout(() => { - console.log('will i run?'); -}); - -// このままにしておくと、 -// タイムアウトがプログラムの終了を妨げる唯一のものになるので、 -// このステートメントで上記のタイムアウトを実行しないようにします。 -timerObj.unref(); - -// immediate 内で ref() を呼び出すことでそれを元の状態に -// 戻すことができます。 -setImmediate(() => { - timerObj.ref(); -}); -``` - - - -## イベントループのさらに下へ - -このガイドでカバーしてきた以上に -イベントループとタイマーにはもっとたくさんのものがあります。 -Node.js イベントループの内部と、 -実行中のタイマーの動作の詳細については、 -この Node.js ガイド [Node.js イベントループ、タイマー、および process.nextTick()](/ja/docs/guides/event-loop-timers-and-nexttick/) を参照してください。 diff --git a/pages/ja/docs/index.mdx b/pages/ja/docs/index.mdx deleted file mode 100644 index 0de2cde4afabf..0000000000000 --- a/pages/ja/docs/index.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: ドキュメント -layout: docs.hbs -labels: - lts: LTS ---- - -# ドキュメント - -ここには 3 種類のドキュメントがあります: - -- API リファレンス -- ES6 の機能 - -## API リファレンス - -[API リファレンス](https://nodejs.org/api/) では Node.js の関数やオブジェクトの詳細情報を提供しています。このドキュメントでは、メソッドで何の引数を取るのか、そのメソッドの返り値とそのメソッドに関連するエラーについても説明されています。また、異なる Node.js のバージョンでどのメソッドが使えるかについても説明されています。 - -このドキュメントでは Node.js によって提供された組み込みのモジュールについて説明しています。コアに組み込まれていないモジュールは含みません。 - -
- -### 以前のバージョンの API リファレンスをお探しですか? - - - -[すべてのバージョン](https://nodejs.org/docs/) - -
- -## ES6 の機能 - -[ES6 のセクション](/ja/docs/es6/) では、ES6 の 3 つの機能について説明しており、それぞれの機能ごとのリンクと一緒に Node.js の標準で有効化されているかについて書いてあります。また、リリースされた Node.js のバージョンごとに組み込まれている V8 のバージョンを知るのにも利用することができます。 - -## ガイド - -[ガイドのセクション](/ja/docs/guides)に Node.js の技術的な機能や能力について詳細な記事があります。 diff --git a/pages/ja/download/current.md b/pages/ja/download/current.md deleted file mode 100644 index c7928833a524c..0000000000000 --- a/pages/ja/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: ダウンロード -download: ダウンロード -downloads: - headline: ダウンロード - lts: LTS - current: 最新版 - tagline-current: 最新の機能 - tagline-lts: 推奨版 - display-hint: ダウンロード - intro: > - Node.js のソースコードをダウンロードするか、事前にビルドされたインストーラーを利用して、今日から開発を始めましょう。 - currentVersion: 最新のバージョン - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: その他のプラットフォーム - intro: > - その他のプラットフォームのための Node.js のビルドは、 Node.js コミュニティのメンバーによってメンテナンスされています。これらは Node.js のコアチームによってサポートされていません。また、最新の Node.js のリリースと同じ状態ではないかもしれないことにご注意ください。 - platform: Platform - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ja/download/index.md b/pages/ja/download/index.md deleted file mode 100644 index ca78ddd885903..0000000000000 --- a/pages/ja/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: ダウンロード -download: ダウンロード -downloads: - headline: ダウンロード - lts: LTS - current: 最新版 - tagline-current: 最新の機能 - tagline-lts: 推奨版 - display-hint: ダウンロード - intro: > - Node.js のソースコードをダウンロードするか、事前にビルドされたインストーラーを利用して、今日から開発を始めましょう。 - currentVersion: 最新のバージョン - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: その他のプラットフォーム - intro: > - その他のプラットフォームのための Node.js のビルドは、 Node.js コミュニティのメンバーによってメンテナンスされています。これらは Node.js のコアチームによってサポートされていません。また、最新の Node.js のリリースと同じ状態ではないかもしれないことにご注意ください。 - platform: Platform - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ja/download/package-manager.md b/pages/ja/download/package-manager.md deleted file mode 100644 index d7dc2091f3cbc..0000000000000 --- a/pages/ja/download/package-manager.md +++ /dev/null @@ -1,278 +0,0 @@ ---- -layout: page.hbs -title: パッケージマネージャを利用した Node.js のインストール ---- - -# パッケージマネージャを利用した Node.js のインストール - - - -**_注意:_** このページにあるパッケージはそれぞれのパッケージ管理者によってメンテナンスされています。Node.js コアチームによるものでは**ありません**。遭遇した問題はパッケージの管理者に報告してください。もしその問題が Node.js 自体のバグだと判明した場合は、管理者が報告をあげてくれます。 - ---- - -- [Android](#android) -- [Arch Linux](#arch-linux) -- [Debian と Ubuntu ベースの Linux ディストリビューション、エンタープライズ Linux/Fedora と Snap パッケージ](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD と OpenBSD](#freebsd-openbsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [NetBSD](#netbsd) -- [openSUSE と SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS と illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows) - ---- - -## Android - -Android support is still experimental in Node.js, so precompiled binaries are not yet provided by Node.js developers. - -However, there are some third-party solutions. For example, [Termux](https://termux.com/) community provides terminal emulator and Linux environment for Android, as well as own package manager and [extensive collection](https://github.com/termux/termux-packages) of many precompiled applications. This command in Termux app will install the last available Node.js version: - -```bash -pkg install nodejs -``` - -Currently, Termux Node.js binaries are linked against `system-icu` (depending on `libicu` package). - -## Arch Linux - - - -Node.js と npm のパッケージがコミュニティのリポジトリから利用可能です。 - -```bash -pacman -S nodejs npm -``` - -## Debian と Ubuntu ベースの Linux ディストリビューション、エンタープライズ Linux/Fedora と Snap パッケージ - - - -[Node.js 公式のバイナリディストリビューション](https://github.com/nodesource/distributions)が NodeSource によって提供されています。 - - - -## FreeBSD と OpenBSD - - - -Node.js は ports を使って利用可能です。 - -```bash -/usr/ports/www/node -``` - - - -開発バージョンも ports で利用可能です。 - -```bash -cd /usr/ports/www/node-devel/ && make install clean -``` - - - -または FreeBSD のパッケージ: - -```bash -pkg_add -r node-devel -``` - - - -FreeBSD の [pkg-ng](https://wiki.freebsd.org/pkgng) を使う: - -```bash -pkg install node -``` - - - -または、開発バージョン: - -```bash -pkg install node-devel -``` - -## Gentoo - - - -Node.js は Portageツリー で利用可能です。 - -```bash -emerge nodejs -``` - -## IBM i - - - -Node.js の LTS バージョンは IBM から ['yum' パッケージマネージャ](https://ibm.biz/ibmi-rpms) で利用可能です。パッケージの名前は `nodejs` の後にメジャーバージョンの数字が付きます(例えば `nodejs8`, `nodejs10`, `nodejs12`, など) - - - -Node.js 12.x をコマンドラインからインストールするには、以下のコマンドを \*ALLOBJ 権限のユーザで実行します - -```bash -yum install nodejs12 -``` - - - -Node.js は IBM i Access Client Solutions と一緒にインストールすることもできます。[こちらのサポートドキュメント(英語)](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619)に詳細があります。 - -## NetBSD - - - -Node.js は pkgsrcツリー で利用可能です。 - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - - - -または、(お使いのプラットフォームで利用可能なら) pkgin を使ってバイナリパッケージをインストール: - -```bash -pkgin -y install nodejs -``` - - - -## openSUSE と SLE - - - -[openSUSE one-click を利用して Node.js をダウンロード](http://software.opensuse.org/download.html?project=devel%3Alanguages%3Anodejs&package=nodejs)する。 - - - -RPM パッケージを利用可能なバージョン: openSUSE 11.4, 12.1, 12.2, 12.3, 13.1, Factory and Tumbleweed; SLE 11 (with SP1/SP2/SP3 variations). - - - -openSUSE 13.1 でのインストール例: - -```bash -sudo zypper ar \ - http://download.opensuse.org/repositories/devel:/languages:/nodejs/openSUSE_13.1/ \ - Node.js -sudo zypper in nodejs nodejs-devel -``` - -## macOS - - - -直接 [nodejs.org](https://nodejs.org/) のサイトから [macOS Installer](https://nodejs.org/ja/#home-downloadhead) をダウンロードしてください。 - - - -_bash でパッケージをダウンロードしたい場合:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### 代替手段 - -**[Homebrew](https://brew.sh/)** を使う: - -```bash -brew install node -``` - -**[MacPorts](https://www.macports.org/)** を使う: - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -**[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)** を使う: - - - -バイナリパッケージをインストール: - -```bash -pkgin -y install nodejs -``` - - - -または、pkgsrc から手動でビルド: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - - - -## SmartOS と illumos - - - -SmartOS のイメージには pkgsrc が付属しています。一方、illumos ディストリビューションの場合は、まず **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)** をインストールし、それから、通常通りバイナリパッケージをインストールすることが出来ます: - -```bash -pkgin -y install nodejs -``` - - - -または、pkgsrc から手動でビルド: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -Solus provides Node.js in its main repository. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - - - -Void Linux にはメインリポジトリに Node.js の安定版があります。 - -```bash -xbps-install -Sy nodejs -``` - -## Windows - - - -直接 [nodejs.org](https://nodejs.org/) のサイトから [Windows Installer](https://nodejs.org/ja/#home-downloadhead) をダウンロードしてください。 - -### 代替手段 - -**[Chocolatey](https://chocolatey.org/)** を使う: - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -**[Scoop](https://scoop.sh/)** を使う: - -```bash -scoop install nodejs -``` diff --git a/pages/ja/download/releases.md b/pages/ja/download/releases.md deleted file mode 100644 index fccc2608cdc53..0000000000000 --- a/pages/ja/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: リリース一覧 -modules: 'NODE_MODULE_VERSIONは、Node.jsのABI(アプリケーションバイナリインタフェース)のバージョン番号を指します。このバージョンは、再コンパイルすることなくC++アドオンのバイナリーをロード可能か確認するために使われます。' ---- - -### io.js & Node.js - -1.x から 3.x は、io.js のフォークにより、「io.js」と呼ばれていました。 Node.js 0.12.x と iojsの旧リリースラインは、Node.js 4.0.0 からリリースが統一されました。 - -### 最新のリリースバージョン用ブランチをお探しですか? diff --git a/pages/ja/get-involved/collab-summit.md b/pages/ja/get-involved/collab-summit.md deleted file mode 100644 index 1da95357f79ea..0000000000000 --- a/pages/ja/get-involved/collab-summit.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: コラボレーションサミット -layout: contribute.hbs ---- - - - -# コラボレーションサミット - -コラボレーションサミットは、活発なコラボレーション、教育、および知識の共有で Node.js について議論するために -現在および将来のコントリビュータを集めるためのアンカンファレンスです。 -委員会とワーキンググループは年に2回集まり、 -重要な決断を下すと同時に、 -直接推進したいというエキサイティングな取り組みに参加することもできます。 - - - -## 誰が参加しますか? - -コラボレーションサミットにはだれもが参加できます。 -サミット期間中、リーダーたちは、彼らをワーキングセッションに招き入れる前に、 -手助けしたいグループに新たなコントリビュータを参加させる手助けをします。 - -これはコミュニティ内で何が起こっているのかを学ぶ機会であり、 -あなたが持っていて磨きをかけたいスキルに貢献することです。 - -ワーキンググループは、人々が現場に着く前に一般のコラボレータのディスカッションをし、 -その後ブレイクアウトセッションに飛び込むことができるように -人々が彼ら自身に慣れることができるようにスケジュールをまとめます。 - -コラボレーションサミットでお会いしましょう! -次回および過去のコラボレーションサミットについては [Summit リポジトリ](https://github.com/nodejs/summit)をチェックし、 -個々のワーキンググループおよびコミッティーが直接話し合うことを検討しているものに関して -共有されている[問題](https://github.com/nodejs/summit/issues)を見てください。 diff --git a/pages/ja/get-involved/contribute.md b/pages/ja/get-involved/contribute.md deleted file mode 100644 index 7d4a0951462dd..0000000000000 --- a/pages/ja/get-involved/contribute.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: 貢献する -layout: contribute.hbs ---- - - - -# 貢献する - -Node.js への貢献に関心をお寄せいただきありがとうございます。貢献できる方法や場所は複数ありますが、それを促進するためにここにいます。 - - - -## 一般的な助けを求める - -`nodejs/node` リポジトリ内のアクティビティーのレベルは非常に高いため、Node.js を使用した一般的なヘルプについての質問または要求は、[Node.js ヘルプリポジトリ](https://github.com/nodejs/help/issues)に向けられるべきです。 - - - -## 問題を報告する - -Node.js の問題であると思われるものが見つかった場合は、GitHub プロジェクトに問題を報告することを躊躇わないでください。問題を提出するときは、再現可能なテストケースで問題を表現できることを確認してください。そのテストケースには外部の依存関係を含めないでください。つまり、テストケースは Node.js 以外のものがなくても実行できます。 - -問題を報告する際には、お客様の環境について含めることができる情報も必要です。問題を絞り込もうとしたときにどのような情報が適切になるかわかりません。少なくとも次の情報を含めてください。 - -- Node のバージョン -- 実行しているプラットフォーム (macOS, SmartOS, Linux, Windows) -- 実行しているアーキテクチャ (32 ビットまたは 64 ビット、および x86 または ARM) - -Node.js プロジェクトは現在、いくつかの GitHub リポジトリにまたがって管理されており、それぞれに独自の issue データベースがあります。可能であれば、あなたが報告している問題を適切なレポジトリに向けていただきたいですが、間違った場所にしたとしても心配しないでください。コントリビュータのコミュニティはあなたが正しい方向を指し示すのを手伝って喜ぶでしょう。 - -- Node.js 特有の問題を報告するには、[nodejs/node](https://github.com/nodejs/node) を使用してください。 -- この Web サイト特有の問題を報告するには、[nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) を使用してください。 - - - -## コードの貢献 - -Node.js にバグを修正したり、新しい機能を追加したい場合は、必ず [Node.js コントリビューションガイドライン](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests) を参照してください。 プロジェクトへのすべての貢献に対する既存のコラボレータによるレビュープロセスもここで説明されています。 - -どのように始めるべきか疑問に思っているなら、最初の貢献に向かってあなたを導くかもしれない [Node Todo](https://www.nodetodo.org/) をチェックすることができます。 - - - -## コラボレータになる - -コラボレータになることで、コントリビュータはプロジェクトにさらに大きな影響を与えることができます。彼らは貢献を見直すことによって問題を切り分けて他のコントリビュータを手助けすることができ、そしてプロジェクトの未来を形作ることにおいてさらに大きな役割を果たすことができます。TSC によって、Node.js リポジトリ全体にわたって重要かつ貴重な貢献をしていると識別された個人は、コントリビュータになり、プロジェクトへのコミットアクセス権を付与されることがあります。考慮される活動には、次のものの品質が含まれます (ただし、これらに限定されません)。 - -- コードのコミットとプルリクエスト -- ドキュメントのコミットとプルリクエスト -- 問題へのコメントとプルリクエスト -- Node.js Web サイトへの貢献 -- エンドユーザと初心者の貢献者に提供される支援 -- ワーキンググループへの参加 -- より広い Node.js コミュニティの他の参加 - -貴重な貢献をしている個人がコミットアクセスのために考慮されたと信じていないならば、彼らは[問題を記録する](https://github.com/nodejs/TSC/issues)か、または直接 [TSC メンバーに連絡する](https://github.com/nodejs/TSC#current-members) かもしれません。 diff --git a/pages/ja/get-involved/index.md b/pages/ja/get-involved/index.md deleted file mode 100644 index a65b6a7805e60..0000000000000 --- a/pages/ja/get-involved/index.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: 参加する -layout: contribute.hbs ---- - - - -# 参加する - -## コミュニティディスカッション - -- [GitHub issues リスト](https://github.com/nodejs/node/issues) は、Node.js のコア機能に関する議論の場です。 -- Node.js 公式 Twitter アカウントは [nodejs](https://twitter.com/nodejs) です。 -- [Node.js Foundation calendar](https://nodejs.org/calendar) とすべての公開チームミーティング。 - - - -## 学習 - -- [公式 API リファレンスドキュメント](https://nodejs.org/api/) は、Node.js API の詳細を説明しています。 -- [NodeSchool.io](https://nodeschool.io/) はインタラクティブなコマンドラインゲームを介して Node.js の概念を教えます。 -- [Stack Overflow Node.js tag](https://stackoverflow.com/questions/tagged/node.js) は、毎日新しい情報を収集します。 -- [The DEV Community Node.js tag](https://dev.to/t/node) は、Node.js プロジェクト、記事、チュートリアルを共有したり、ディスカッションを開始したり、Node.js 関連のトピックについてのフィードバックを求めたりする場所です。スキルレベルに関係なくすべての開発者が参加できます。 -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) は、Discord でお互いをサポートする Node.js バックエンド開発者のフレンドリーなコミュニティです。 - - - -## インターナショナルコミュニティサイトとプロジェクト - -- [中国コミュニティ](https://cnodejs.org/) -- [ハンガリー (マジャール) コミュニティ](https://nodehun.blogspot.com/) -- [Node.js のイスラエル Facebook グループ](https://www.facebook.com/groups/node.il/) -- [日本のユーザグループ](https://nodejs.jp/) -- [Node.js のスペイン語 Facebook グループ](https://www.facebook.com/groups/node.es/) -- [ベトナム Node.js コミュニティ](https://www.facebook.com/nodejs.vn/) -- [Uzbekistan group for Node.js](https://t.me/nodejs_uz) diff --git a/pages/ja/index.md b/pages/ja/index.md deleted file mode 100644 index a21e8124e0086..0000000000000 --- a/pages/ja/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: 最新のバージョン - download: ダウンロード - download-for: ダウンロード - other-downloads: 他のバージョン - current: 最新版 - lts: LTS - tagline-current: 最新の機能 - tagline-lts: 推奨版 - changelog: 変更履歴 - api: APIドキュメント - version-schedule-prompt: サポートされているバージョンに関する詳しい情報: - version-schedule-prompt-link-text: リリーススケジュール ---- - -Node.js®はクロスプラットフォームに対応したオープンソースのJavaScript実行環境です。 diff --git a/pages/ka/404.md b/pages/ka/404.md deleted file mode 100644 index 659c53297475a..0000000000000 --- a/pages/ka/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: გვერდი ვერ მოიძებნა - -### ENOENT: მსგავსი ფაილი ან კატალოგი არ არის diff --git a/pages/ka/about/governance.md b/pages/ka/about/governance.md deleted file mode 100644 index 824e4de35e9c3..0000000000000 --- a/pages/ka/about/governance.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: პროექტის მმართველობა -layout: about.hbs ---- - -# პროექტის მმართველობა - -## კონსენსუსის ძიების პროცესი - -პროექტი Node.js მიყვება გადაწყვეტილების მიღების მოდელს — [კონსენსუსის ძიება][]. - -## თანამშრომლები - -მთავარი GitHub-საცავის ([nodejs/node][]) შენახვაზე და განვითარებაზე მუშაობენ თანამშრომლები (კოლაბორატორები), რომელთა დამატებასაც უწყვეტ რეჟიმში ახორციელებს ხელმძღვანელი ტექნიკური კომიტეტი ([TSC][]). - -ადამიანები, რომლებსაც მნიშვნელოვანი და ღირებული წვლილი შეაქვთ პროექტში, ხდებიან თანამშრომლები (კოლაბორატორები) და იღებენ მუდმივ წვდომას პროექტზე (უშუალოდ შეუძლიათ ცვლილებების შეტანა). ასეთი პირების ამოცნობას (იდენტიფიცირებას) ახდენს TSC, ხოლო მათთვის წვდომის მიცემას განიხილავენ უკვე არსებული თანამშრომლები (კოლაბორატორები). - -თანამშრომელთა (კოლაბორატორთა) ამჟამინდელი სია შეგიძლიათ იხილოთ პროექტის [README.md][]-ში. - -იხილეთ თანამშრომელთათვის (კოლაბორატორთათვის) განკუთვნილი სახელმძღვანელო: [collaborator-guide.md][]. - -## უმაღლესი კომიტეტები - -პროექტის მართვაში ერთობლივად არის ჩართული [ხელმძღვანელი ტექნიკური კომიტეტი (TSC)][], რომელიც პასუხისმგებელია პროექტის მაღალი დონის (high-level) მმართველობაზე, და [საზოგადოების კომიტეტი (CommComm)][], რომელიც პასუხისმგებელია Node.js-ის საზოგადოების (community) ხელმძღვანელობაზე და გაფართოებაზე. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/master/doc/contributing/collaborator-guide.md -[საზოგადოების კომიტეტი (CommComm)]: https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md -[კონსენსუსის ძიება]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/master/README.md#current-project-team-members -[ხელმძღვანელი ტექნიკური კომიტეტი (TSC)]: https://github.com/nodejs/TSC/blob/master/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/ka/about/index.md b/pages/ka/about/index.md deleted file mode 100644 index e8b7f4f199e9e..0000000000000 --- a/pages/ka/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: პროექტის შესახებ -trademark: სავაჭრო ნიშანი ---- - -# Node.js®-ის შესახებ - -როგორც ასინქრონული, მოვლენებზე დაფუძნებული JavaScript-ის გამშვები გარემო, Node.js შექმნილია მასშტაბირებადი (გაფართოებადი) ქსელური აპლიკაციების შესაქმნელად. ქვემოთ მოცემულ ("hello world") მაგალითში, ერთდროულად მრავალი კავშირის დამუშავებაა შესაძლებელი. თითოეული კავშირისთვის მოხდება (callback) ფუნქციის გამოძახება, მაგრამ თუ გასაკეთებელი არაფერია, Node.js დარჩება უმოქმედოდ (დაიძინებს). - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -ეს მიდგომა განსხვავდება დღესდღეობით უფრო გავრცელებული პარალელიზმის მოდელისგან, რომელშიც გამოიყენება OS-ნაკადები (threads). ნაკადზე დაფუძნებული მიდგომა შედარებით არაეფექტურია და ძალიან რთულია გამოსაყენებლად. უფრო მეტიც, Node.js-ის მომხმარებლებს არ უწევთ, იდარდონ პროცესების ბლოკირებაზე, რადგან აქ არ არსებობს ბლოკირება. Node.js-ის თითქმის არც ერთი ფუნქცია არ ახორციელებს უშუალოდ შეტანა/გამოტანას, ამიტომ პროცესი არასოდეს იბლოკება გარდა იმ შემთხვევისა, როცა შეტანა/გამოტანა ხორციელდება Node.js-ის სტანდარტული ბიბლიოთეკის სინქრონული მეთოდების გამოყენებით. ყოველივე ამის გამო, Node.js-ის გამოყენება მასშტაბირებადი სისტემების შესაქმნელად ძალიან გონივრულია. - -თუ თქვენთვის ზემოთ მოხსენიებული ტერმინებიდან რომელიმე გაუგებარია, იხილეთ სრული სტატია: [ბლოკირება vs არა-ბლოკირება][]. - ---- - -Node.js დიზაინით მსგავსია, და იმყოფება გავლენის ქვეშ ისეთი სისტემებისა, როგორებიცაა: [Event Machine][] Ruby-ში და [Twisted][] Python-ში. თუმცა, მასში (Node.js-ში) მოვლენათა მოდელი ბევრად უფრო ფართოდ გამოიყენება. იგი [მოვლენათა ციკლს][] წარმოგვიდგენს როგორც გამშვები გარემოს კონსტრუქციას, ნაცვლად იმისა, რომ წარმოგვიდგინოს ბიბლიოთეკის სახით. სხვა სისტემებში, მოვლენათა ციკლის დასაწყებად ყოველთვის გვაქვს დამბლოკველი გამოძახება. როგორც წესი, ქცევა განისაზღვრება ფუნქციების მეშვეობით სკრიპტის დასაწყისში, ბოლოს კი — დამბლოკველი გამოძახების მეშვეობით, როგორიცაა `EventMachine::run()` — სერვერი ეშვება. Node.js-ში მოვლენათა ციკლის დასაწყებად მსგავსი გამოძახება არ გვაქვს: იგი (შემავალი) სკრიპტის გაშვების შემდეგ ავტომატურად შედის მოვლენათა ციკლში. როდესაც განსახორციელებელი ფუნქციები (callbacks) აღარ დარჩება, Node.js გამოდის მოვლენათა ციკლიდან. ეს ქცევა წააგავს JavaScript-ის ქცევას ბრაუზერში: მოვლენათა ციკლი დამალულია მომხმარებლისაგან. - -Node.js-ში განსაკუთრებული ადგილი უკავია HTTP-ს, რომელიც შექმნილია სტრიმინგისა და დაბალი შეყოვნების გათვალისწინებით. ეს Node.js-ს აქცევს იდეალურ საფუძვლად ვებ-ბიბლიოთეკის ან framework-ის დასაშენებლად. - -ის ფაქტი, რომ Node.js შექმნილია ნაკადების (threads) გარეშე, არ ნიშნავს იმას, რომ არ შეგიძლიათ, თქვენს გარემოში მრავალი ბირთვით ისარგებლოთ. შვილობილი პროცესების წარმოქმნა შეგიძლიათ [`child_process.fork()`][] API-ის გამოყენებით. ამავე ინტერფეისის საფუძველზეა აგებული [`cluster`][] მოდული, რომელიც საშუალებას გაძლევთ, დაყოთ სოკეტები პროცესებს შორის, რათა დატვირთვა გადანაწილდეს ბირთვებზე. - -[ბლოკირება vs არა-ბლოკირება]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[მოვლენათა ციკლს]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/ka/docs/es6.md b/pages/ka/docs/es6.md deleted file mode 100644 index 633407dc038e7..0000000000000 --- a/pages/ka/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) და მის ფარგლებს მიღმა -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) და მის ფარგლებს მიღმა - -Node.js შექმნილია [V8](https://v8.dev/)-ის უახლეს ვერსიებზე დაყრდნობით. ძრავის (V8) უახლესი ვერსიების პარალელურად [Node.js-ის] მუდმივი განახლებების საფუძველზე Node.js დეველოპერებს რეალურ დროში, გარანტირებულად ეძლევათ წვდომა [JavaScript ECMA-262 სპეციფიკაციის](http://www.ecma-international.org/publications/standards/Ecma-262.htm) ახალ მახასიათებლებზე. გარდა ამისა, მუდმივად უმჯობესდება წარმადობა და სტაბილურობა. - -ECMAScript 2015 (ES6) მახასიათებლები სამ ჯგუფად იყოფა: **მიწოდებული (shipping)**, **მზა (staged)** და **მოქმედი (in progress)**: - -- ყოველი **მიწოდებული (shipping)** მახასიათებელი, რომელსაც V8 სტაბილურად მიიჩნევს, **Node.js-ზე ნაგულისხმევად არის გააქტიურებული** და **არ** მოითხოვს რაიმე სახის [დამატებით] მითითებას გაშვების მომენტში. -- **მზა (staged)** მახასიათებლები, ანუ თითქმის დასრულებული მახასიათებლები, რომლებიც V8-ის გუნდის მიერ არ არის მიჩნეული სტაბილურად, გაშვების მომენტში მოითხოვს დამატებით არგუმენტს: `--harmony`. -- **მოქმედი (in progress)** მახასიათებლების გააქტიურება შესაძლებელია ინდივიდუალურად, მათთვის შესაბამისი თანაზომიერების (harmony) არგუმენტით, თუმცა ტესტირების გარდა რაიმე სხვა მიზნით ამის გაკეთება უკიდურესად არასასურველია. შენიშვნა: ეს არგუმენტები (flags) შემოღებულია V8-ის მიერ და შესაძლოა შეიცვალოს ყოველგვარი წინასწარი გაფრთხილების გარეშე. - -## Node.js-ის რომელ ვერსიას რომელი მახასიათებლები მოყვება ნაგულისხმევად? - -ვებსაიტი [node.green](https://node.green/) kangax-ის თავსებადობის ცხრილზე დაყრდნობით გვაწვდის შესანიშნავ მიმოხილვას Node.js-ის სხვადასხვა ვერსიაში მხარდაჭერილი ECMAScript-ის მახასიათებლების შესახებ. - -## რომელი მახასიათებლებია მოქმედი? - -V8 ძრავას მუდმივად ემატება ახალი მახასიათებლები. ზოგადად, ველით, რომ ისინი გამოჩნდებიან Node.js-ის მომავალ გამოშვებაში, თუმცა ზუსტი თარიღი უცნობია. - -თქვენ შეგიძლიათ იხილოთ Node.js-ის თითოეულ გამოშვებაში ხელმისაწვდომი _მოქმედი (in progress)_ მახასიათებლების სია `--v8-options` არგუმენტის გამოყენებით. გთხოვთ გაითვალისწინოთ, რომ ესენი V8-ის დაუმთავრებელი და პოტენციურად გაუმართავი მახასიათებლებია, ასე რომ, მათი გამოყენება რისკის შემცველია: - -```bash -node --v8-options | grep "in progress" -``` - -## ჩემი ინფრასტრუქტურა ისეა მოწყობილი, რომ სარგებლობს --harmony არგუმენტით. უნდა წავშალო? - -`--harmony` არგუმენტის მიმდინარე ქცევა Node.js-ზე მხოლოდ **მზა (staged)** მახასიათებელთა გააქტიურებაში გამოიხატება. ბოლოს და ბოლოს, ამჟამად იგი წარმოადგენს `--es_staging`-ის სინონიმს. როგორც ზემოთ აღინიშნა, ესენი (**მზა** მახასიათებლები) არის დასრულებული მახასიათებლები, რომლებიც ჯერჯერობით არ არის მიჩნეული სტაბილურად. თუკი თქვენთვის მნიშვნელოვანია უსაფრთხოება, განსაკუთრებით საწარმოო გარემოში, მოაშორეთ ეს პარამეტრი მანამ, სანამ [თქვენთვის] საჭირო მახასიათებლები არ გახდება „ნაგულისხმევი“ V8-ზე და, მაშასადამე, Node.js-ზე. თუ ამას არ იზამთ, მზად უნდა იყოთ იმისათვის, რომ Node.js-ის შემდგომი განახლებები (თუკი V8 შეცვლის სემანტიკას, რათა უფრო მჭიდროდ მიჰყვეს სტანდარტებს) გამოიწვევს თქვენი კოდის მუშაობის დარღვევას. - -## როგორ გავარკვიო, V8-ის რომელი ვერსია მოყვება Node.js-ის კონკრეტულ ვერსიას? - -Node.js უზრუნველყოფს მარტივ გზას, — გლობალური `process` ობიექტის მეშვეობით, — დაქვემდებარებათა (_dependencies_) და შესაბამის ვერსიათა, — რომლებიც მოყვება [Node.js-ის] კონკრეტულ გამოშვებას, — სიის [ეკრანზე] გამოსატანად. V8 ძრავის შემთხვევაში, მისი ვერსიის გასაგებად, ტერმინალში გაუშვით შემდეგი ბრძანება: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/ka/docs/guides/debugging-getting-started.md b/pages/ka/docs/guides/debugging-getting-started.md deleted file mode 100644 index 0bac04d19ec5f..0000000000000 --- a/pages/ka/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: შეცდომების აღმოჩენა/აღმოფხვრა - პირველი ნაბიჯები -layout: docs.hbs ---- - -# სახელმძღვანელო გამართვის (_Debugging_) შესახებ - -წინამდებარე სახელმძღვანელო დაგეხმარებათ შეისწავლოთ Node.js-აპლიკაციებისა და სკრიპტების გამართვა. - -## ინსპექტორის გააქტიურება - -როდესაც `--inspect` არგუმენტით ეშვება, Node.js-პროცესი უსმენს შეცდომათა აღმომჩენ (გამმართავ) კლიენტს. ნაგულისხმევად, იგი მოუსმენს შემდეგ ჰოსტზე (_მასპინძელზე_) და პორტზე: 127.0.0.1:9229. თითოეულ პროცესს ასევე ენიჭება უნიკალური [UUID][]. - -კავშირის დასამყარებლად ინსპექტორმა კლიენტებმა უნდა იცოდნენ და მიუთითონ ჰოსტის მისამართი, პორტი და UUID. სრული URL დაახლოებით ასე უნდა გამოიყურებოდეს: `ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e`. - -Node.js ასევე დაიწყებს გამართვის შეტყობინებათა მოსმენას, თუკი იგი მიიღებს `SIGUSR1` სიგნალს (`SIGUSR1` ხელმისაწვდომი არ არის Windows-ის გარემოში). Node.js-ის მე-7 და უფრო ძველ ვერსიებში ეს გაააქტიურებს მოძველებულ Debugger API-ს. Node.js-ის მე-8 და უფრო ახალ ვერსიებში Inspector API გააქტიურდება. - ---- - -## გავლენა უსაფრთხოების დონეზე - -რამდენადაც გამმართველს სრული წვდომა აქვს Node.js გამშვებ გარემოზე, ბოროტმოქმედს, რომელსაც შეუძლია ამ პორტთან დაკავშირება, შესაძლებლობა ეძლევა Node.js-პროცესის სახელით გაუშვას თვითნებური კოდი. აქედან გამომდინარე, მნიშვნელოვანია გვესმოდეს გამმართველის პორტის საჯარო ან კერძო ქსელში გამჟღავნების [უარყოფითი] გავლენა უსაფრთხოების დონეზე. - -### გამართვის (debug) პორტის გასაჯაროება სახიფათოა - -თუ გამმართველი მიბმულია საჯარო IP-მისამართთან ან 0.0.0.0-თან, ნებისმიერ კლიენტს, რომელსაც წვდომა აქვს თქვენს IP-მისამართთან, ყოველგვარი შეზღუდის გარეშე შეძლებს გამმართველთან დაკავშირებას და თვითნებური კოდის გაშვებას. - -ნაგულისხმევად, `node --inspect` ებმის 127.0.0.1-ს. გამმართველთან გარე კავშირების დასაშვებად, ცალსახად დაგჭირდებათ, უზრუნველყოთ საჯარო IP-მისამართი ან 0.0.0.0 და ა.შ. [თუმცა,] ამის გაკეთებამ, შესაძლოა პოტენციურად საყურადღებო უსაფრთხოების რისკების წინაშე დაგაყენოთ. ჩვენ გირჩევთ, უზრუნველყოთ სათანადო firewall-ებისა და წვდომის კონტროლის არსებობა, რათა თავიდან აიცილოთ მსგავსი საფრთხეები. - -იხილეთ განყოფილება „[დისტანციური გამართვის სცენართა გააქტიურება](#enabling-remote-debugging-scenarios)“, რომელშიც მოცემულია რამდენიმე რჩევა იმის შესახებ, თუ როგორ მივცეთ დისტანციურ გამმართველ კლიენტებს უსაფრთხოდ დაკავშირების ნებართვა. - -### ლოკალურ აპლიკაციებს აქვთ სრული წვდომა ინსპექტორზე - -მაშინაც კი, თუ თქვენ ინსპექტორის პორტს მიაბამთ 127.0.0.1-ს (ნაგულისხმევი), ლოკალურად, თქვენს მოწყობილობაზე გაშვებულ ნებისმიერ აპლიკაციას ექნება შეუზღუდავი წვდომა. ასე იმისათვის ხდება, რომ ლოკალურ გამმართველებს მიეცეთ ადვილად მიმაგრების საშუალება. - -### ბრაუზერები, WebSocket-ები და იგივე წარმოშობის (_same-origin_) პოლიტიკა - -ვებბრაუზერში გახსნილ ვებსაიტებს შეუძლიათ განახორციელონ WebSocket- და HTTP-მოთხოვნები ბრაუზერის უსაფრთხოების მოდელის მიხედვით. საწყისი HTTP კავშირი აუცილებელია გამმართველის სესიის უნიკალური id-ის მისაღებად. იგივე წარმოშობის პოლიტიკა (_same-origin-policy_) ხელს უშლის ვებსაიტებს ამ HTTP-კავშირის დამყარებაში. დამატებითი დაცვისათვის [DNS rebinding შეტევების](https://en.wikipedia.org/wiki/DNS_rebinding) წინააღმდეგ, Node.js ამოწმებს, ზუსტად არის თუ არა მითითებული კავშირის 'Host' სათაურებში (headers) IP-მისამართი, `localhost` ან `localhost6`. - -ეს უსაფრთხოების წესები კრძალავს დისტანციურ გამართვის სერვერთან დაკავშირებას ჰოსტის სახელის (_hostname_) მითითებით. ამ შეზღუდვისათვის გვერდის ავლა შეგიძლიათ IP-მისამართის მითითებით ან ssh-გვირაბების (_tunnels_) გამოყენებით, როგორც ეს ქვემოთ არის აღწერილი. - -## ინსპექტორი კლიენტები - -მინიმალისტური CLI-გამმართველი ხელმისაწვდომია ბრძანებით `node inspect myscript.js`. Node.js-ინსპექტორთან დაკავშირება ასევე შეუძლია რამდენიმე კომერციულ და ღიად ხელმისაწვდომ ინსტრუმენტს. - -### [Chrome დეველოპერის ინსტრუმენტები](https://github.com/ChromeDevTools/devtools-frontend) 55+, [Microsoft Edge](https://www.microsoftedgeinsider.com) - -- **ვარიანტი 1**: გახსენით `chrome://inspect` Chromium-ზე დაფუძნებულ ბრაუზერში ან `edge://inspect` — Edge-ში. დააწკაპუნეთ Configure ღილაკზე და დარწმუნდით, რომ სასურველი ჰოსტი და პორტი არის ჩამონათვალში. -- **ვარიანტი 2**: დააკოპირეთ `devtoolsFrontendUrl` მნიშვნელობა `/json/list`-დან (იხილეთ ზემოთ) ან --inspect მიმნიშნებელი ტექსტი და ჩასვით Chrome-ში. - -> გაითვალისწინეთ, რომ Node.js და Chrome ერთსა და იმავე პლატფორმაზე უნდა გაეშვას. - -### [Visual Studio Code](https://github.com/microsoft/vscode) 1.10+ - -- „გამართვის“ (_Debug_) პანელში დააწკაპუნეთ პარამეტრების ხატულაზე, რათა გახსნათ `.vscode/launch.json` [ფაილი]. აირჩიეთ „Node.js“ საწყისი მოწყობისათვის. - -### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- მენიუდან აირჩიეთ „Debug > Start Debugging“ ან დააჭირეთ `F5`-ს. -- [დეტალური ინსტრუქციები](https://github.com/Microsoft/nodejstools/wiki/Debugging). - -### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) და სხვა JetBrains IDE-ები - -- შექმენით ახალი Node.js გამართვის კონფიგურაცია და დააჭირეთ „Debug“ ღილაკს. `--inspect` ნაგულისხმევად იქნება გამოყენებული `Node.js 7+`-ისთვის. გამოსართავად, IDE-რეესტრში მოხსენით მონიშვნა (_uncheck_) `js.debugger.node.use.inspect`-ს. WebStorm-ში და სხვა JetBrains IDE-ებში Node.js-ის გაშვებასა და გამართვასთან დაკავშირებით დეტალური ინფორმაციისათვის იხილეთ [WebStorm ონლაინ დახმარება](https://www.jetbrains.com/help/webstorm/running-and-debugging-node-js.html). - -### [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - -- ბიბლიოთეკა, რომელიც ამარტივებს კავშირს [Inspector Protocol][]-ის (_ინსპექტორის პროტოკოლის_) endpoint-ებთან. - -### [Gitpod](https://www.gitpod.io) - -- გაუშვით Node.js გამართვის კონფიგურაცია `Debug` ხედიდან (_view_) ან დააჭირეთ `F5`-ს. [დეტალური ინსტრუქციები](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1). - -### [Eclipse IDE](https://eclipse.org/eclipseide) Eclipse Wild Web Developer დამატებით (_extension-ით_) - -- გახსენით .js [გაფართოების მქონე] ფაილი, აირჩიეთ „Debug As... > Node program“, ან -- შექმენით გამართვის კონფიგურაცია, რათა მიამაგროთ გამმართველი გაშვებულ Node.js-აპლიკაციას (უკვე დაიწყო `--inspect`-ით). - ---- - -## ბრძანებათა სტრიქონის არგუმენტები - -ქვემოთ მოცემულ ცხრილში ჩამოთვლილია სხვადასხვა არგუმენტების — რომელთა მითითებაც შესაძლებელია გაშვების მომენტში (_runtime_) — გავლენა გამმართველზე: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
არგუმენტი (*Flag*)მნიშვნელობა
--inspect -
    -
  • ინსპექტორის გააქტიურება
  • -
  • ნაგულისხმევი მისამართისა და პორტის მოსმენა (127.0.0.1:9229)
  • -
-
--inspect=[host:port] -
    -
  • ინსპექტორის გააქტიურება
  • -
  • მიმაგრება მისამართზე ან host ჰოსტის სახელზე (hostname) (ნაგულისხმევი: 127.0.0.1)
  • -
  • მოსმენა port პორტზე (ნაგულისხმევი: 9229)
  • -
-
--inspect-brk -
    -
  • ინსპექტორის გააქტიურება
  • -
  • ნაგულისხმევი მისამართისა და პორტის მოსმენა (127.0.0.1:9229)
  • -
  • [სკრიპტის შესრულების] შეწყვეტა მომხმარებლის კოდის [შესრულების] დაწყებამდე
  • -
-
--inspect-brk=[host:port] -
    -
  • ინსპექტორის გააქტიურება
  • -
  • მიმაგრება მისამართზე ან host ჰოსტის სახელზე (hostname) (ნაგულისხმევი: 127.0.0.1)
  • -
  • მოსმენა port პორტზე (ნაგულისხმევი: 9229)
  • -
  • [სკრიპტის შესრულების] შეწყვეტა მომხმარებლის კოდის [შესრულების] დაწყებამდე
  • -
-
node inspect script.js -
    -
  • შვილობილი პროცესის წარმოქმნა, რათა მომხმარებლის სკრიპტი გაეშვას --inspect არგუმენტით (flag); - მთავარი პროცესის გამოყენება CLI გამმართველის გასაშვებად.
  • -
-
node inspect --port=xxxx script.js -
    -
  • შვილობილი პროცესის წარმოქმნა, რათა მომხმარებლის სკრიპტი გაეშვას --inspect არგუმენტით (flag); - მთავარი პროცესის გამოყენება CLI გამმართველის გასაშვებად.
  • -
  • მოსმენა port პორტზე (ნაგულისხმევი: 9229)
  • -
-
- ---- - -## დისტანციური გამართვის სცენართა გააქტიურება - -ჩვენ გირჩევთ, არასოდეს დაუშვათ გამმართველის მოსმენა საჯარო IP-მისამართზე. თუ გჭირდებათ, რომ დაუშვათ დისტანციური კავშირები გამართვისათვის, გირჩევთ გამოიყენოთ ssh-გვირაბები. ქვემოთ მოცემული მაგალითი მიზნად ისახავს მხოლოდ განმარტებას. სანამ ამას იზამდეთ, მნიშვნელოვანია გესმოდეთ უსაფრთხოებასთან დაკავშირებით არსებული საფრთხეები, რომლებსაც ჰბადებს პრივილეგირებულ სერვისთან დისტანციური კავშირის დამყარების შესაძლებლობა. - -ვთქვათ, დისტანციურ მოწყობილობაზე, remote.example.com, გაშვებული გაქვთ Node.js-აპლიკაცია და გსურთ მისი გამართვა. ასეთ შემთხვევაში, ამ [დისტანციურ] მოწყობილობაზე უნდა გაუშვათ node-პროცესი ინსპექტორით, რომელიც უსმენს მხოლოდ localhost-ს (ნაგულისხმევი). - -```bash -node --inspect server.js -``` - -შემდგომ ამისა, ადგილობრივ (_ლოკალურ_) მოწყობილობაზე, საიდანაც გსურთ წამოიწყოთ გამმართველი კლიენტის კავშირი, შეგიძლიათ შექმნათ ssh-გვირაბი: - -```bash -ssh -L 9221:localhost:9229 user@remote.example.com -``` - -ეს შექმნის ssh-გვირაბის სესიას, რომელშიც კავშირი 9221 პორტთან თქვენს ადგილობრივ მოწყობილობაზე, გადამისამართდება remote.example.com-ის 9229 პორტზე. შემდგომ ამისა, თქვენ შეძლებთ გამმართველის, როგორიცაა Chrome DevTools ან Visual Studio Code, მიმაგრებას localhost:9221-ზე, და შეგეძლებათ გამართვა ისევე, როგორც იმ შემთხვევაში, როცა Node.js-აპლიკაცია გაშვებულია ადგილობრივად (_ლოკალურად_). - ---- - -## მოძველებული გამმართველი - -**მოძველებული გამმართველის გამოყენება მიზანშეწონილი აღარ არის Node.js 7.7.0 ვერსიიდან მოყოლებული. ნაცვლად ამისა, გამოიყენეთ ინსპექტორი (`--inspect`).** - -როცა მე-7 ან უფრო ადრინდელ ვერსიაში ეშვება **--debug** ან **--debug-brk** არგუმენტით, Node.js უსმენს გამართვის ბრძანებებს, რომლებიც განსაზღვრულია V8 გამართვის პროტოკოლით TCP პორტზე (ნაგულისხმევად `5858`). ნებისმიერ გამმართველ კლიენტს, რომელსაც ესმის ეს პროტოკოლი, შეუძლია მიმდინარე პროცესთან დაკავშირება და [მისი] გამართვა; ქვემოთ ჩამოთვლილია რამდენიმე პოპულარული კლიენტი. - -V8 გამართვის პროტოკოლი აღარ არის მხარდაჭერილი და მისი დოკუმენტირებაც აღარ ხორციელდება. - -### [ჩაშენებული გამმართველი](https://nodejs.org/dist/latest/docs/api/debugger.html) - -იმისათვის, რომ თქვენი სკრიპტი გაუშვათ ჩაშენებულ CLI-გამმართველთან ერთად, შეიყვანეთ ბრძანება `node debug script_name.js`. ამით, თქვენი სკრიპტი გაეშვება `--debug-brk` პარამეტრით სხვა Node-პროცესში, ხოლო საწყისი Node-პროცესი გაუშვებს `_debugger.js` სკრიპტს და დაუკავშირდება თქვენს სამიზნეს (_თქვენს სამიზნე სკრიპტს_). - -### [node-inspector](https://github.com/node-inspector/node-inspector) - -გამართეთ თქვენი Node.js-აპლიკაცია Chrome DevTools-ით შუამავალი პროცესის გამოყენებით, რომელიც Chromium-ში გამოყენებულ [Inspector Protocol][]-ს (_ინსპექტორის პროტოკოლს_) თარგმნის Node.js-ში გამოყენებულ V8 გამმართველ პროტოკოლად. - - - -[Inspector Protocol]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/ka/docs/guides/getting-started-guide.md b/pages/ka/docs/guides/getting-started-guide.md deleted file mode 100644 index 992519d3c782c..0000000000000 --- a/pages/ka/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: პირველი ნაბიჯები -layout: docs.hbs ---- - -# პირველი ნაბიჯები Node.js-ის ინსტალაციის შემდეგ - -Node.js-ის ინსტალაციის შემდეგ, მოდით შევქმნათ ჩვენი პირველი ვებსერვერი. შექმენით ფაილი სახელად `app.js` შემდეგი შიგთავსით: - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -ახლა გაუშვით თქვენი ვებსერვერი ბრძანებით `node app.js`. თქვენს ბრაუზერში გახსენით მისამართი `http://localhost:3000` და თქვენ იხილავთ შეტყობინებას „Hello World“. - -Node.js-ის საწყისებთან დაკავშირებით მეტად ამომწურავი ინფორმაციისათვის იხილეთ შემდეგი გზამკვლევი: [შესავალი Node.js-ში](https://nodejs.dev/en/learn/). diff --git a/pages/ka/docs/guides/index.md b/pages/ka/docs/guides/index.md deleted file mode 100644 index b28d263c8ce8d..0000000000000 --- a/pages/ka/docs/guides/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: სახელმძღვანელოები -layout: docs.hbs ---- - -# სახელმძღვანელოები - -## ზოგადი - -- [პირველი ნაბიჯები](/ka/docs/guides/getting-started-guide/) -- [გამართვა - პირველი ნაბიჯები](/ka/docs/guides/debugging-getting-started/) -- [Easy profiling for Node.js Applications](/en/docs/guides/simple-profiling/) -- [Diagnostics - Flame Graphs](/en/docs/guides/diagnostics-flamegraph/) -- [Dockerizing a Node.js web app](/en/docs/guides/nodejs-docker-webapp/) -- [Migrating to safe Buffer constructors](/en/docs/guides/buffer-constructor-deprecation/) -- [Diagnostics - User Journey](/en/docs/guides/diagnostics/) - -## Node.js-ის ძირითადი ცნებები - -- [შესავალი Node.js-ში](https://nodejs.dev/en/learn/) -- [Overview of Blocking vs Non-Blocking](/en/docs/guides/blocking-vs-non-blocking/) -- [The Node.js Event Loop, Timers, and `process.nextTick()`](/en/docs/guides/event-loop-timers-and-nexttick/) -- [Don't Block the Event Loop (or the Worker Pool)](/en/docs/guides/dont-block-the-event-loop/) -- [Timers in Node.js](/en/docs/guides/timers-in-node/) - -## მოდულთან დაკავშირებული სახელმძღვანელოები - -- [Anatomy of an HTTP Transaction](/en/docs/guides/anatomy-of-an-http-transaction/) -- [Working with Different Filesystems](/en/docs/guides/working-with-different-filesystems/) -- [Backpressuring in Streams](/en/docs/guides/backpressuring-in-streams/) -- [Domain Module Postmortem](/en/docs/guides/domain-postmortem/) -- [How to publish N-API package](/en/docs/guides/publishing-napi-modules/) -- [ABI Stability](/en/docs/guides/abi-stability/) diff --git a/pages/ka/docs/index.mdx b/pages/ka/docs/index.mdx deleted file mode 100644 index 1c5a8fbf230b6..0000000000000 --- a/pages/ka/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: დოკუმენტაცია -layout: docs.hbs -labels: - lts: LTS ---- - -# დოკუმენტაციის შესახებ - -წინამდებარე ვებსაიტზე ხელმისაწვდომია რამდენიმე ტიპის დოკუმენტაცია: - -- დოკუმენტაცია: API-სქოლიო -- ES6-ის მახასიათებლები -- სახელმძღვანელოები - -## დოკუმენტაცია: API-სქოლიო - -[API-სქოლიო](https://nodejs.org/api/) გვაწვდის დეტალურ ინფორმაციას Node.js-ში არსებული ფუნქციებისა და ობიექტების შესახებ. იგი შეიცავს ინფორმაციას იმის შესახებ, თუ რა არგუმენტებს იღებს ესა თუ ის მეთოდი, რას აბრუნებს იგი და რა შეცდომები შეიძლება უკავშირდებოდეს მას. გარდა ამისა, შეიცავს ინფორმაციას იმის შესახებ, თუ რომელი მეთოდებია ხელმისაწვდომი Node.js-ის ამა თუ იმ ვერსიაში. - -აღნიშნული დოკუმენტაცია აღწერს Node.js-ის მიერ უზრუნველყოფილ, ჩაშენებულ მოდულებს. მასში არ შედის საზოგადოების (community) მიერ უზრუნველყოფილი მოდულები. - -
- -### ეძებთ უწინდელი ვერსიებისათვის განკუთვნილ API-დოკუმენტაციას? - - - -[ყველა ვერსია](https://nodejs.org/docs/) - -
- -## ES6-ის მახასიათებლები - -[ამ განყოფილებაში](/ka/docs/es6/) აღწერილია ES6-ის მახასიათებლების სამი ჯგუფი და დეტალები იმის შესახებ, თუ რომელი მახასიათებლების გამოყენება არის Node.js-ში ნაგულისხმევად შესაძლებელი. ტექსტს ერთვის ბმულები დამატებითი განმარტებებისათვის. აღნიშნული განყოფილება ასევე გვიჩვენებს, როგორ გავარკვიოთ, თუ V8-ის რომელი ვერსია მოყვება Node.js-ის კონკრეტულ გამოშვებას (release). - -## სახელმძღვანელოები - -[სახელმძღვანელოთა განყოფილება](/ka/docs/guides/) შეიცავს ვრცელ სტატიებს, სადაც სიღრმისეულად არის განხილული Node.js-ის ტექნიკური შესაძლებლობები და მახასიათებლები. diff --git a/pages/ka/download/index.md b/pages/ka/download/index.md deleted file mode 100644 index a53bad24f29aa..0000000000000 --- a/pages/ka/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: ჩამოტვირთვა -download: ჩამოტვირთვა -downloads: - headline: ჩამოტვირთვები - lts: LTS - current: მიმდინარე - tagline-current: უახლესი შესაძლებლობები - tagline-lts: რეკომენდებულ­ია მომხმარებელთა უმეტესობისათვის - display-hint: ჩამოტვირთვების ჩვენება - - intro: > - ჩამოტვირთეთ Node.js-ის კოდი ან თქვენი პლატფორმისთვის შესაბამისი მზა საინსტალაციო და დაიწყეთ დეველოპმენტი დღესვე. - currentVersion: მიმდინარე გრძელვადიანად მხარდაჭერილი (LTS) ვერსია - buildInstructions: მხარდაჭერილ პლატფორმებზე Node.js-ის კოდიდან აგება (Building) - WindowsInstaller: Windows-საინსტალაციო - WindowsBinary: Windows Binary - MacOSInstaller: macOS-საინსტალაციო - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: კოდი (წყარო) -additional: - headline: დამატებითი პლატფორმები - intro: > - Node.js-ის საზოგადოების (community) წევრები თვალყურს ადევნებენ Node.js-ის დამატებითი პლატფორმებისათვის განკუთვნილ არაოფიციალურ ვერსიებს. გაითვალისწინეთ, რომ მსგავსი ვერსიები მხარდაჭერილი არ არის Node.js-ის მთავარი გუნდის მიერ, და შესაძლოა, არ იყოს აგებული Node.js-ის მიმდინარე ვერსიის დონეზე. - platform: პლატფორმა - provider: მომმარაგებელი (პროვაიდერი) - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker-გამოსახულება - officialDockerImage: Node.js-ის ოფიციალური Docker-გამოსახულება - LinuxPowerSystems: Linux — Power LE Systems-ზე - LinuxSystemZ: Linux — System z-ზე - AIXPowerSystems: AIX — Power Systems-ზე ---- diff --git a/pages/ka/get-involved/index.md b/pages/ka/get-involved/index.md deleted file mode 100644 index 594a19061d0c7..0000000000000 --- a/pages/ka/get-involved/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: შემოგვიერთდით -layout: contribute.hbs ---- - -# შემოგვიერთდით - -## საზოგადოების დისკუსია - -- [GitHub-ზე წარმოდგენილი პრობლემათა სია](https://github.com/nodejs/node/issues) არის Node.js-ის ძირითადი მახასიათებლების გარშემო დისკუსიისათვის განკუთვნილი სივრცე. -- Node.js development-ის შესახებ რეალურ დროში სასაუბროდ გამოიყენეთ ქვემოთ მოცემულთაგან რომელიმე პლატფორმა - - IRC-სთვის შედით `irc.libera.chat`-ის `#node.js` არხზე [IRC client](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients)-ის გამოყენებით ან დაუკავშირდით არხს თქვენს ბრაუზერში [web-კლიენტის](https://kiwiirc.com/nextclient/) გამოყენებით - - Slack-ისთვის არსებობს ორი ვარიანტი: - - [Node Slackers](https://www.nodeslackers.com/) არის Node.js-ზე ორიენტირებული Slack-საზოგადოება. ზოგიერთ ჯგუფს აქ აქვს სადისკუსიო არხები. - - [OpenJSF Slack](https://slack-invite.openjsf.org/)-ში არის რამდენიმე არხი Node.js-ის გარშემო სასაუბროდ (არხები, რომელთა დასახელებაც იწყება `#nodejs-`-ით). ზოგიერთ ჯგუფს აქ აქვს სადისკუსიო არხები. -- Node.js-ის ოფიციალური ანგარიში Twitter-ზე: [nodejs](https://twitter.com/nodejs). -- [Node.js ფონდის კალენდარი](https://nodejs.org/calendar) ყველა საჯარო შეხვედრით. - -## სწავლა - -- [ოფიციალური API-დოკუმენტაცია (სქოლიო)](https://nodejs.org/api/) აღწერს Node.js-ის API-ს. -- [NodeSchool.io](https://nodeschool.io/) შეგასწავლით Node.js-ის ცნებებს ინტერაქტიული (ბრძანებათა სტრიქონის) თამაშების საშუალებით. -- [Stack Overflow Node.js-ტეგით](https://stackoverflow.com/questions/tagged/node.js): აქ ყოველდღე უამრავი ახალი ინფორმაცია გროვდება. -- [DEV-საზოგადოება Node.js-ტეგით](https://dev.to/t/node) არის სივრცე Node.js-ის პროექტების, სტატიებისა და გაკვეთილების გასაზიარებლად, ისევე, როგორც სადისკუსიოდ და გამოხმაურების მისაღებად Node.js-თან დაკავშირებული თემების გარშემო. ნებისმიერი კვალიფიკაციის მქონე დეველოპერთა ჩართულობა მისასალმებელია. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) (Discord) არის Node.js backend-დეველოპერთა მეგობრული საზოგადოება, სადაც ერთმანეთს მხარში უდგანან. diff --git a/pages/ka/index.md b/pages/ka/index.md deleted file mode 100644 index 5a4442bb4ffda..0000000000000 --- a/pages/ka/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: მიმდინარე ვერსია - download: ჩამოტვირთვა - download-for: ჩამოტვირთვა - other-downloads: სხვა ჩამოტვირთვები - current: მიმდინარე - lts: LTS - tagline-current: უახლესი შესაძლებლობები - tagline-lts: რეკომენდებულ­ია მომხმარებელთა უმეტესობისათვის - changelog: ცვლილებათა ჩამონათვალი - api: API-დოკუმენტაცია - version-schedule-prompt: ან გადახედეთ - version-schedule-prompt-link-text: გრძელვადიანი მხარდაჭერის (LTS) განრიგს ---- - -Node.js® არის [Chrome-ის V8 ძრავზე](https://v8.dev/) დაფუძნებული JavaScript-ის გამშვები გარემო. diff --git a/pages/ko/404.md b/pages/ko/404.md deleted file mode 100644 index e621c06c812d7..0000000000000 --- a/pages/ko/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: 페이지를 찾을 수 없습니다 - -### ENOENT: 파일 또는 디렉터리가 없습니다 diff --git a/pages/ko/about/governance.md b/pages/ko/about/governance.md deleted file mode 100644 index 011612492846c..0000000000000 --- a/pages/ko/about/governance.md +++ /dev/null @@ -1,259 +0,0 @@ ---- -title: 프로젝트 거버넌스 -layout: about.hbs ---- - -# 프로젝트 거버넌스 - -## 기술 결정 위원회(TSC, Technical Steering Committee) - - - -프로젝트의 고수준 지침에 대한 책임이 있는 기술 결정 위원회(TSC)가 함께 프로젝트를 운영하고 있습니다. - -TSC는 다음을 포함해서 이 프로젝트의 최종 권한을 가집니다. - -- 기술적 방향 -- 프로젝트 거버넌스와 절차 (이 정책을 포함해서) -- 기여 정책 -- GitHub 저장소 호스팅 -- 행동 지침 -- 추가적인 협업자 목록의 관리 - - - -최초의 TSC 멤버십 초대는 활발한 기여자나 프로젝트 관리에 충분한 경험을 가진 사람들에게 주어졌습니다. -멤버십은 프로젝트의 요구사항에 따라 발전될 것입니다. - -현재 TSC 회원 목록은 프로젝트 -[README.md](https://github.com/nodejs/node/blob/main/README.md#tsc-technical-steering-committee)에서 -볼 수 있습니다. - - - -## 협업자 - -TSC와 TSC가 지속적으로 추가한 협업자들이 -[nodejs/node](https://github.com/nodejs/node) GitHub 저장소를 관리하고 있습니다. - -중요하고 가치 있는 기여를 하는 개인이 협업자가 되고 프로젝트의 커밋-접근 권한을 받습니다. 이러한 개인은 -TSC가 인정하고 주간 TSC 회의에서 협업자로 추가하는 것을 논의합니다. - - - -_Note:_ 중요한 기여를 했음에도 커밋 접근 권한을 얻지 못한다면 이슈를 남기거나 TSC 멤버에게 -직접 연락을 취하면 다음 TSC 회의 때 다루게 될 것입니다. - -nodejs/node 저장소 내용의 수정은 협업을 통해서 이뤄집니다. GitHub 계정을 가진 누구나 풀 리퀘스트로 -수정을 제안할 수 있고 프로젝트 협업자가 이를 검토할 것입니다. 모든 풀 리퀘스트는 반드시 리뷰를 -받아야 하고 변경사항에 대한 전체 책임을 지고 상당한 전문성을 가진 협업자가 이를 받아들일 것입니다. -기존의 협업자가 제안한 풀 리퀘스트는 다른 협업자가 승인해야 합니다. 다른 협업자가 관여해서 -특정 수정 부분에 대해서 동의하지 않는다면 합의가 이루어져야 합니다. 거버넌스의 합의 모델에 관한 -더 자세한 내용은 아래의 *합의점을 찾는 과정*을 보기 바랍니다. - - - -협업자는 TSC에서 논의하려고 풀 리퀘스트나 이슈에 **_tsc-agenda_** 태그를 할당함으로써 중요하거나 -논쟁이 되는 수정사항이나 합의점을 찾지 못한 수정사항을 개선하려고 할 수도 있습니다. -TSC는 필요한 경우 최종 중재자가 되어야 합니다. - -현재 협업자 목록은 프로젝트 -[README.md](https://github.com/nodejs/node/blob/main/README.md#current-project-team-members)에서 -볼 수 있습니다. - -협업자 가이드는 -[collaborator-guide.md](https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md)에서 -관리되어 있습니다. - - - -## TSC 멤버십 - -TSC 멤버십은 기간 제한이 없고 TSC에 인원 제한도 없습니다. 하지만, 전문성과 균형을 가진 채 -효율적인 결정을 하면서 중요한 영역을 충분히 다룰 수 있도록 6 ~ 12명 정도가 적당하다고 생각합니다. - -이 규칙을 뛰어넘는 TSC 멤버십의 요구사항이나 자격에 대한 특정 조건은 없습니다. - -TSC는 표준 TSC 발의를 통해 새로운 회원을 TSC에 추가할 것입니다. - - - -TSC 회원은 자발적인 사퇴나 표준 TSC 발의를 통해 TSC에서 제외될 수 있습니다. - -TSC 멤버십의 변경은 의제에 올라와야 하고 다른 의제로 제안될 수도 있습니다.(아래 "TSC 회의"를 보세요.) - -TSC 회원의 1/3 이상이 같은 고용주와 관련되면 안 됩니다. TSC 회원이 제외되거나 사퇴하거나 TSC 회원의 -고용상태가 바뀔 때 TSC 멤버십의 1/3 이상이 같은 고용주를 갖게 되는 상황이 만들어질 수 있습니다. -이 상황은 같은 고용주를 가진 1명 이상의 TSC 멤버가 사퇴하거나 제외됨으로써 즉시 해결되어야 합니다. - - - -## TSC 회의 - -TSC는 구글 행아웃으로 매주 만납니다. TSC가 승인해서 선정한 중재자가 회의를 주최합니다. -각 회의는 YouTube로 발행되어야 합니다. - -논쟁이 필요하거나 거버넌스, 기여 정책, TSC 멤버십, 릴리스 절차의 수정에 대한 주제가 -TSC 의제에 추가됩니다. - -이 의제의 의도는 모든 패치를 승인하거나 리뷰하는 것이 아닙니다. 이러한 승인이라 리뷰는 -GitHub에서 계속해서 이루어지고 더 큰 협업자 그룹에서 다뤄집니다. - - - -어떤 커뮤니티 회원이나 기여자도 GitHub에 이슈를 남김으로써 다음 미팅 일정에 무언가를 추가하도록 -요청할 수 있습니다. 어떤 협업자, TSC 회원, 중재자라도 이슈에 **_tsc-agenda_** 태그를 -추가해서 의제를 추가할 수 있습니다. - -각 TSC 회의 전에 중재자는 TSC 회원과 의제를 공유할 것입니다. TSC 회원은 각 회의를 시작할 때 -원하는 의제를 추가할 수 있습니다. 중재자와 TSC는 의제를 거부하거나 제거할 수 없습니다. - - - -TSC는 특정 프로젝트의 사람들이나 대표자가 투표권 없이 회의에 참여하도록 초대할 수 있습니다. 현재 이렇게 초대된 사람은 다음과 같습니다. - -- [build](https://github.com/node-forward/build) 프로젝트에서 선택된 대표자 - -중재자는 각 의제를 논의한 내용을 요약하고 미팅 후에 풀 리퀘스트로 보낼 책임이 있습니다. - - - -## 합의점을 찾는 과정 - -TSC는 [합의점 찾기](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) 의사결정 모델을 따릅니다. - -의제가 합의점을 찾았을 때 중재자는 합의점에 대한 반대의견을 받기 위한 마지막 요청으로 "반대하는 사람 있습니까?"라고 물을 것입니다. - -의제가 합의점에 이르지 못한다면 TSC 멤버는 투표를 종료하거나 다음 회의에 이슈를 올리도록 하는 투표를 요청할 수 있습니다. 투표요청은 반드시 TSC의 과반수가 동의해야 하고 그렇지 않으면 논의를 계속할 것입니다. 간단히 과반수가 이깁니다. diff --git a/pages/ko/about/index.md b/pages/ko/about/index.md deleted file mode 100644 index 32909b548344a..0000000000000 --- a/pages/ko/about/index.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -layout: about.hbs -title: About -trademark: 트레이드마크 ---- - -# Node.js®에 대해서 - - - -비동기 이벤트 주도 JavaScript 런타임으로써 Node.js 는 확장성 있는 네트워크 애플리케이션을 만들 수 있도록 -설계되었습니다. 다음 "hello world" 예제는 다수의 연결을 동시에 처리할 수 있습니다. -각 연결에서 콜백이 실행되는데 실행할 작업이 없다면 Node.js 는 대기합니다. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - - - -이는 오늘날 OS 스레드가 일반적으로 사용하는 동시성 모델과는 대조적입니다. 스레드 기반의 네트워크는 -상대적으로 비효율적이고 사용하기가 몹시 어렵습니다. 게다가 잠금이 없으므로 Node.js 의 사용자는 프로세스의 -교착상태에 대해서 걱정할 필요가 없습니다. Node.js 에서 I/O를 직접 수행하는 함수는 거의 없으므로 프로세스는 -결과 블로킹 되지 않습니다. 아무것도 블로킹 되지 않으므로 Node.js 에서는 확장성 있는 시스템을 개발하는 게 -아주 자연스럽습니다. - - - -여기서 나오는 용어가 익숙하지 않다면 [블로킹 대 논-블로킹][]에 대한 글을 읽어보세요. - ---- - - - -Node.js 는 Ruby의 [Event Machine][]이나 Python의 [Twisted][]같은 시스템과 설계상 유사하고 -영향을 받았습니다. Node.js 는 좀 더 발전된 이벤트 모델을 선택해서 라이브러리가 아닌 런타임 생성자로 -[이벤트 루프][]를 제공합니다. 다른 시스템에서는 이벤트 루프를 시작하는 블럭킹 호출이 항상 존재합니다. - -보통은 스크립트의 시작 부분에서 콜백을 통해서 동작을 정의하고 마지막에서 `EventMachine::run()`같은 -블로킹 호출로 서버를 시작합니다. Node.js 에서는 이와 같은 이벤트 루프를 시작하는 호출이 없습니다. Node.js 는 -입력 스크립트를 실행한 후에 이벤트 루프에 바로 진입합니다. 더이상 실행할 콜백이 없다면 Node.js 는 -이벤트 루프를 종료합니다. 이 동작은 브라우저 JavaScript과 같이 사용자에게서 이벤트 루프를 감춥니다. - - - -Node.js 에서 HTTP는 일급 객체(first class citizen)이고 스트리밍과 저지연을 염두에 두고 -설계되었습니다. 이는 Node.js 가 웹 라이브러리나 프레임워크의 기반으로 아주 적합하게 하였습니다. - -Node.js 는 스레드를 사용하지 않도록 설계되지만 멀티 코어 환경의 장점을 얻지 못한다는 의미는 아닙니다. -[`child_process.fork()`][] API를 사용해서 자식 프로세스를 생성할 수 있습니다. 같은 인터페이스로 -만들어진 [`cluster`][]을 사용하면 다수의 코어에 로드 밸런싱이 가능하도록 프로세스 간에 -소켓을 공유할 수 있습니다. - - - -[블로킹 대 논-블로킹]: /ko/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[이벤트 루프]: /ko/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/ko/docs/es6.md b/pages/ko/docs/es6.md deleted file mode 100644 index 3f4e688dc8953..0000000000000 --- a/pages/ko/docs/es6.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: ECMAScript 2015(ES6)와 그 다음 -layout: docs.hbs ---- - - - -# ECMAScript 2015(ES6)와 그 다음 - -Node.js는 [V8](https://v8.dev/)의 최신 버전으로 만들었습니다. -V8을 최신 릴리스로 유지하기 때문에 Node.js 개발자에게 -[JavaScript ECMA-262 명세](http://www.ecma-international.org/publications/standards/Ecma-262.htm)의 -새로운 기능을 제때에 지원하면서 성능과 안정성 개선도 할 수 있습니다. - -모든 ECMAScript 2015(ES6) 기능은 **shipping**, **staged**, **in progress**라는 -세 가지 그룹으로 나뉩니다. - -- 모든 **shipping** 기능은 V8이 안정적이라고 간주한 것으로 - **Node.js에서는 기본적으로 켜져 있으므로** 런타임 플래그가 전혀 **필요 없습니다**. -- **Staged** 기능은 거의 완성되었지만, V8 팀이 안정적이라고 간주하지 않은 기능으로 - `--harmony` 런타임 플래그가 필요합니다. -- **In progress** 기능은 각 하모니 플래그로 개별적으로 활성화할 수 있습니다. 테스트 목적이 - 아니라면 활성화하지 않기를 강력하게 권장합니다. 주의: 이 플래그는 V8에서 제공한 것으로 - 폐기 공지 없이 변경될 수 있습니다. - - - -## Node.js 버전에 어떤 기능이 기본적으로 포함되나요? - -[node.green](https://node.green/) 웹사이트에서 어떤 Node.js가 어떤 ECMAScript 기능을 -지원하는지 파악할 수 있습니다. 이는 kangax의 호환성 표를 기반으로 만들어졌습니다. - - - -## 어떤 기능이 진행 중입니까? - -V8 엔진에 계속해서 새로운 기능이 추가되고 있습니다. 정확한 시기는 알 수 없겠지만 -앞으로 릴리스 할 Node.js에는 V8에 추가된 새 기능이 대체로 포함될 것입니다. - -`--v8-options` 인자로 각 Node.js 릴리스에서 모든 _in progress_ 기능의 리스트를 볼 수 -있습니다. 이 기능들은 완성되지 않았고 V8에서 제대로 돌아가지 않을 수도 있으므로 이 기능을 사용할 때는 -위험을 감수해야 함을 명심하세요. - -```bash -node --v8-options | grep "in progress" -``` - - - -## --harmony 플래그를 사용하는 환경이 있습니다. 이를 제거해야 하나요? - -Node.js에서 `--harmony` 플래그의 현재 동작은 **staged** 기능만 활성화하는 것입니다. 결국, -이는 `--es_staging`과 같은 의미입니다. 앞에서 말했듯이 이 기능은 완성되었지만, 아직 안정적이라고 -볼 수는 없습니다. 프로덕션 환경 등에서 안전하게 운영하고 싶다면 V8과 Node.js에서 기본적으로 -제공할 때까지 이 런타임 플래그를 제거하는 것을 고려해 보세요. 이 기능을 활성화한다면 차후 Node.js를 -업그레이드 할 때 V8이 이 기능의 의미를 표준에 더 가깝게 변경한 경우 코드가 깨질 수 있으므로 -대비해야 합니다. - - - -## Node.js의 특정 버전에 포함된 V8의 버전을 어떻게 알 수 있나요? - -Node.js에서는 `process` 전역 객체를 통해 특정 바이너리에 포함된 모든 의존성과 각 버전의 목록을 -쉽게 볼 수 있습니다. V8 엔진의 경우 터미널에서 다음 명령어를 실행하면 V8 버전을 볼 수 있습니다. - -```bash -node -p process.versions.v8 -``` diff --git a/pages/ko/docs/guides/anatomy-of-an-http-transaction.md b/pages/ko/docs/guides/anatomy-of-an-http-transaction.md deleted file mode 100644 index 8a3c16f12fda7..0000000000000 --- a/pages/ko/docs/guides/anatomy-of-an-http-transaction.md +++ /dev/null @@ -1,891 +0,0 @@ ---- -title: HTTP 트랜잭션 해부 -layout: docs.hbs ---- - - - -# HTTP 트랜잭션 해부 - -이 문서의 목적은 Node.js HTTP 처리 과정을 잘 이해하게 하는 것입니다. 언어나 프로그래밍 환경과 -관계없이 상식선에서 HTTP 요청이 어떻게 동작하는지는 알고 있어야 합니다. Node.js의 -[`EventEmitters`][]와 [`Streams`][]에도 어느 정도 익숙해야 합니다. 익숙하지 않다면 -관련 API 문서를 미리 훑어보는 편이 좋습니다. - - - -## 서버 생성 - -모든 node 웹 서버 애플리케이션은 웹 서버 객체를 만들어야 합니다. -이 때 [`createServer`][]를 이용합니다. - -```javascript -const http = require('http'); - -const server = http.createServer((request, response) => { - // 여기서 작업이 진행됩니다! -}); -``` - - - -이 서버로 오는 HTTP 요청마다 [`createServer`][]에 전달된 함수가 한 번씩 호출됩니다. -사실 [`createServer`][]가 반환한 [`Server`][] 객체는 [`EventEmitter`][]이고 여기서는 -`server` 객체를 생성하고 리스너를 추가하는 축약 문법을 사용한 것입니다. - -```javascript -const server = http.createServer(); -server.on('request', (request, response) => { - // 여기서 작업이 진행됩니다! -}); -``` - - - -HTTP 요청이 서버에 오면 node가 트랜잭션을 다루려고 `request`와 `response` 객체를 전달하며 -요청 핸들러 함수를 호출합니다. 곧 이 객체를 사용해 볼 것입니다. - -요청을 실제로 처리하려면 [`listen`][] 메서드가 `server` 객체에서 호출되어야 합니다. -대부분은 서버가 사용하고자 하는 포트 번호를 `listen`에 전달하기만 하면 됩니다. -몇 가지 다른 옵션도 있으므로 [API 문서][]를 참고하세요. - - - -## 메서드, URL, 헤더 - -요청을 처리할 때, 우선은 메서드와 URL을 확인한 후 이와 관련된 적절한 작업을 실행하려고 할 것입니다. -Node가 `request` 객체에 유용한 프로퍼티를 넣어두었으므로 이 작업은 비교적 쉽게 할 수 있습니다. - -```javascript -const { method, url } = request; -``` - -> **주의:** `request` 객체는 [`IncomingMessage`][]의 인스턴스입니다. - - - -여기서 `method`는 항상 일반적인 HTTP 메서드/동사가 될 것입니다. `url`은 전체 URL에서 서버, -프로토콜, 포트를 제외한 것으로, 세 번째 슬래시 이후의 나머지 전부라고 볼 수 있습니다. - -헤더도 많이 다르지 않습니다. `request`에 `headers`라는 전용 객체가 있습니다. - -```javascript -const { headers } = request; -const userAgent = headers['user-agent']; -``` - - - -클라이언트가 어떻게 헤더를 설정했는지에 관계없이 모든 헤더는 소문자로만 표현된다는 것을 기억해야 합니다. -이는 어떤 목적이든 헤더를 파싱하는 작업을 간편하게 해줍니다. - -일부 헤더를 반복해서 설정한다면 이 값은 헤더에 따라 덮어씌워지거나 콤마로 구분된 문자열로 합쳐집니다. -이게 문제가 될 경우에는 [`rawHeaders`][]를 사용할 수도 있습니다. - - - -## 요청 바디 - -`POST`나 `PUT` 요청을 받을 때 애플리케이션에 요청 바디는 중요할 것입니다. 요청 헤더에 접근하는 -것보다 바디 데이터를 받는 것은 좀 더 어렵습니다. 핸들러에 전달된 `request` 객체는 -[`ReadableStream`][] 인터페이스를 구현하고 있습니다. 이 스트림에 이벤트 리스너를 등록하거나 -다른 스트림에 파이프로 연결할 수 있습니다. 스트림의 `'data'`와 `'end'` 이벤트에 이벤트 리스너를 -등록해서 데이터를 받을 수 있습니다. - -각 `'data'` 이벤트에서 발생시킨 청크는 [`Buffer`][]입니다. 이 청크가 문자열 데이터라는 것을 -알고 있다면 이 데이터를 배열에 수집한 다음 `'end'` 이벤트에서 이어 붙인 다음 문자열로 -만드는 것이 가장 좋습니다. - - - -```javascript -let body = []; -request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // 여기서 `body`에 전체 요청 바디가 문자열로 담겨있습니다. - }); -``` - -> **주의:** 이 코드가 약간 장황할 수도 있고 대부분은 실제로 그렇습니다. 다행히 [`npm`][]에 -> [`concat-stream`][]나 [`body`][] 같은 모듈로 이 로직을 감출 수 있습니다. 이어서 읽기 전에 -> 어떤 작업이 이뤄지는지 잘 이해하는 것이 중요합니다. 그래서 이 글을 읽고 있는 것입니다. - - - -## 오류에 대한 간단한 설명 - -`request` 객체가 [`ReadableStream`][]이므로 [`EventEmitter`][]이기도 하고 -오류가 발생했을 때 [`EventEmitter`][]처럼 동작합니다. - -`request` 스트림의 오류가 발생하면 스트림에서 `'error'` 이벤트가 발생하면서 오류를 전달합니다. -**이벤트에 리스너가 등록되어 있지 않다면 Node.js 프로그램을 종료시킬 수도 있는 오류를 _던질_ 것입니다.** -그러므로 단순히 오류를 로깅만 하더라도 요청 스트림에 `'error'` 리스너를 추가해야 합니다.(하지만 -HTTP 오류 응답을 보내는 것이 좋을 겁니다. 이에 대해는 뒤에서 더 자세히 살펴봅니다.) - - - -```javascript -request.on('error', err => { - // 여기서 `stderr`에 오류 메시지와 스택 트레이스를 출력합니다. - console.error(err.stack); -}); -``` - -별도의 추상화나 도구를 이용해서 [오류를 처리하는][] 다른 방법도 존재하지만, 항상 오류는 발생할 수 -있다는 것을 명심하고 오류를 처리해야 합니다. - - - -## 지금까지 살펴본 내용 - -지금까지 서버를 생성하고 요청의 메서드, UL, 헤더, 바디를 가져왔습니다. -이를 모두 사용하면 다음과 같이 될 것입니다. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // 여기서 헤더, 메서드, url, 바디를 가지게 되었고 - // 이 요청에 응답하는 데 필요한 어떤 일이라도 할 수 있게 되었습니다. - }); - }) - .listen(8080); // 이 서버를 활성화하고 8080 포트로 받습니다. -``` - - - -이 예제를 실행하면 요청을 _받을 수_ 있지만, 요청에 *응답*하지는 않습니다. 사실 웹 브라우저에서 -이 예제에 접근하면 클라이언트에 돌려보내는 것이 없으므로 요청이 타임아웃에 걸릴 것입니다. - -지금까지 `response` 객체는 전혀 건드리지 않았습니다. 이 객체는 [`ServerResponse`][]의 -인스턴스이면서 [`WritableStream`][]입니다. 여기에는 클라이언트에 데이터를 응답하기 위한 -여러 가지 유용한 메서드가 있습니다. 이제 이를 살펴볼 것입니다. - - - -## HTTP 상태 코드 - -따로 설정하지 않으면 응답의 HTTP 상태 코드는 항상 200입니다. 물론 모든 HTTP 응답이 이를 보장하는 -것은 아니고 어떤 경우에는 다른 상태 코드를 보내기를 원할 것입니다. -상태 코드를 변경하려면 `statusCode` 프로퍼티를 설정해야 합니다. - -```javascript -response.statusCode = 404; // 클라이언트에게 리소스를 찾을 수 없다고 알려줍니다. -``` - -이에 대한 단축 설정도 있는데 곧 살펴볼 것입니다. - - - -## 응답 헤더 설정 - -편리한 [`setHeader`][] 메서드로 헤더를 설정합니다. - -```javascript -response.setHeader('Content-Type', 'application/json'); -response.setHeader('X-Powered-By', 'bacon'); -``` - -응답에 헤더를 설정할 때 헤더 이름의 대소문자는 중요하지 않습니다. 헤더를 여러 번 설정한다면 마지막에 설정한 값을 보낼 것입니다. - - - -## 명시적인 헤더 데이터 전송 - -지금까지 설명한 헤더와 상태 코드를 설정하는 메서드는 "암묵적인 헤더"를 사용하고 있다고 가정합니다. 이는 -바디 데이터를 보내기 전 적절한 순간에 헤더를 보내는 일을 노드에 의존하고 있다는 의미입니다. - -원한다면 _명시적으로_ 응답 스트림에 헤더를 작성할 수 있습니다. 헤더를 작성하는 [`writeHead`][] -메서드가 있습니다. 이 메서드는 스트림에 상태 코드와 헤더를 작성합니다. - -```javascript -response.writeHead(200, { - 'Content-Type': 'application/json', - 'X-Powered-By': 'bacon', -}); -``` - -(암묵적이든 명시적이든) 일단 헤더를 설정하고 나면 응답 데이터를 전송할 준비가 된 것입니다. - - - -## 응답 바디 전송 - -`response` 객체는 [`WritableStream`][]이므로 클라이언트로 보내는 응답 바디는 일반적인 -스트림 메서드를 사용해서 작성합니다. - -```javascript -response.write(''); -response.write(''); -response.write('

Hello, World!

'); -response.write(''); -response.write(''); -response.end(); -``` - -스트림의 `end` 함수에 스트림에 보낼 데이터의 마지막 비트를 선택적으로 전달할 수 있으므로 -위의 예제는 다음과 같이 간단하게 작성할 수 있습니다. - -```javascript -response.end('

Hello, World!

'); -``` - -> **주의:** 바디에 데이터 청크를 _작성하기 전에_ 상태 코드와 헤더를 설정해야 합니다. -> HTTP 응답에서 바디 전에 헤더가 있으므로 이는 이치에 맞습니다. - - - -## 오류에 대한 추가 설명 - -`response` 스트림도 `'error'` 이벤트를 발생시킬 수 있고 때로는 이 오류도 처리해야 합니다. -`request` 스트림 오류에 대한 모든 설명이 여기서도 똑같이 적용됩니다. - - - -## 지금까지 배운 내용을 사용한 예제 - -HTTP 응답 만드는 방법을 배웠으니 이제 모든 것을 함께 사용해 보겠습니다. 이전에 본 예제에서 사용자가 -서버에 보낸 모든 데이터를 다시 보내는 서버를 만들 것입니다. `JSON.stringify`를 사용해서 데이터를 -JSON으로 포매팅할 것입니다. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // 여기서부터 새로운 부분입니다. - - response.on('error', err => { - console.error(err); - }); - - response.statusCode = 200; - response.setHeader('Content-Type', 'application/json'); - // 주의: 위 두 줄은 다음 한 줄로 대체할 수도 있습니다. - // response.writeHead(200, {'Content-Type': 'application/json'}) - - const responseBody = { headers, method, url, body }; - - response.write(JSON.stringify(responseBody)); - response.end(); - // 주의: 위 두 줄은 다음 한 줄로 대체할 수도 있습니다. - // response.end(JSON.stringify(responseBody)) - - // 새로운 부분이 끝났습니다. - }); - }) - .listen(8080); -``` - - - -## 에코 서버 예제 - -위의 예제를 간략하게 바꾸어 간단한 에코 서버를 만들어보겠습니다. 에코 서버는 요청받은 데이터를 -그대로 응답으로 돌려보내는 서버입니다. 앞에서 했던 것처럼 요청 스트림에서 데이터를 가져와 -응답 스트림에 쓰기만 하면 됩니다. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - }) - .listen(8080); -``` - - - -이제 약간 변경해보겠습니다. 다음의 조건에서만 에코 응답을 보내려고 합니다. - -- 요청 메서드가 POST인 경우 -- URL이 `/echo`인 경우 - -위 조건이 아닌 경우에는 404를 응답합니다. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - - - -> **주의:** 이 방법으로 URL을 검사함으로써 "라우팅"을 하고 있습니다. `switch` 문으로 간단히 -> 라우팅할 수도 있고 [`express`][]같은 프레임워크로 복잡한 라우팅을 할 수도 있습니다. -> 라우팅 처리를 하는 무언가를 찾고 있다면 [`router`][]를 사용해 보길 바랍니다. - -좋습니다! 이제 이를 간략화 해보겠습니다. `request` 객체는 [`ReadableStream`][]이고 -`response` 객체는 [`WritableStream`][]임을 명심하세요. 이 말은 데이터를 한 스트림에서 -다른 스트림으로 직접 연결하는 [`pipe`][]를 사용할 수 있음을 의미합니다. -에코 서버에서 하려는 것이 바로 이것입니다. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - - - -이게 스트림입니다! - -아직은 끝난 것이 아닙니다. 이 문서에서 여러 번 얘기했듯이 오류는 언제든 발생할 수 있고 -우리는 이를 처리해야 합니다. - -요청 스트림에서 오류를 처리하기 위해 오류를 `stderr`에 로깅하고 `Bad Request`를 의미하는 -400 상태 코드를 보낼 것입니다. 실제 애플리케이션에서는 적절한 상태 코드와 메시지가 무엇인지 찾아내기 -위해 오류를 검사하고자 할 것입니다. 언제나처럼 오류에 대해서는 [`Error` 문서][]를 살펴봐야 합니다. - -응답에서는 `stdout`에 오류를 로깅 할 것입니다. - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - request.on('error', err => { - console.error(err); - response.statusCode = 400; - response.end(); - }); - response.on('error', err => { - console.error(err); - }); - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - - - -지금까지 HTTP 요청을 다루는 기본 내용을 거의 다 다루었습니다. 이제 다음을 할 수 있어야 합니다. - -- 요청 핸들러 함수로 HTTP 서버의 인스턴스를 생성하고 특정 포트로 서버를 열 수 있습니다. -- `request` 객체에서 헤더, URL, 메서드, 바디 데이터를 가져올 수 있습니다. -- URL이나 `request` 객체의 데이터에 기반을 둬서 라우팅을 할 수 있습니다. -- `response` 객체로 헤더, HTTP 상태 코드, 바디 데이터를 보낼 수 있습니다. -- `request` 객체에서 `response` 객체로 데이터를 파이프로 연결할 수 있습니다. -- `request`와 `response` 스트림 모두에서 스트림 오류를 처리할 수 있습니다. - -이 기본 내용을 바탕으로 많은 사용 사례를 위한 Node.js HTTP 서버를 구축할 수 있습니다. -API가 제공하는 그 외 많은 기능이 있으므로 [`EventEmitters`][], [`Streams`][], -[`HTTP`][]의 API 문서를 꼭 읽어보세요. - - - -[`EventEmitters`]: https://nodejs.org/api/events.html -[`Streams`]: https://nodejs.org/api/stream.html -[`createServer`]: https://nodejs.org/api/http.html#http_http_createserver_requestlistener -[`Server`]: https://nodejs.org/api/http.html#http_class_http_server -[`listen`]: https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback -[API 문서]: https://nodejs.org/api/http.html -[`IncomingMessage`]: https://nodejs.org/api/http.html#http_class_http_incomingmessage -[`ReadableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_readable -[`rawHeaders`]: https://nodejs.org/api/http.html#http_message_rawheaders -[`Buffer`]: https://nodejs.org/api/buffer.html -[`concat-stream`]: https://www.npmjs.com/package/concat-stream -[`body`]: https://www.npmjs.com/package/body -[`npm`]: https://www.npmjs.com -[`EventEmitter`]: https://nodejs.org/api/events.html#events_class_eventemitter -[오류를 처리하는]: https://nodejs.org/api/errors.html -[`ServerResponse`]: https://nodejs.org/api/http.html#http_class_http_serverresponse -[`setHeader`]: https://nodejs.org/api/http.html#http_response_setheader_name_value -[`WritableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_writable -[`writeHead`]: https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers -[`express`]: https://www.npmjs.com/package/express -[`router`]: https://www.npmjs.com/package/router -[`pipe`]: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options -[`Error` 문서]: https://nodejs.org/api/errors.html -[`HTTP`]: https://nodejs.org/api/http.html diff --git a/pages/ko/docs/guides/blocking-vs-non-blocking.md b/pages/ko/docs/guides/blocking-vs-non-blocking.md deleted file mode 100644 index de366a1595fa5..0000000000000 --- a/pages/ko/docs/guides/blocking-vs-non-blocking.md +++ /dev/null @@ -1,281 +0,0 @@ ---- -title: 블록킹과 논블록킹 살펴보기 -layout: docs.hbs ---- - - - -# 블로킹과 논블로킹 살펴보기 - -이 글에서는 Node.js에서 **블로킹**과 **논블로킹** 호출의 차이점을 다룹니다. 이벤트 루프와 -libuv를 참조할 것이지만 사전 지식이 필요하지는 않습니다. 이 글을 읽는 사람은 JavaScript -언어와 Node.js 호출 패턴에 관해 기본적인 이해가 있다고 가정합니다. - -> "I/O"는 주로 [libuv](https://libuv.org/)가 지원하는 시스템 디스크나 네트워크와 -> 상호작용하는 것을 가리킵니다. - - - -## 블로킹 - -**블로킹**은 Node.js 프로세스에서 추가적인 JavaScript의 실행을 위해 JavaScript가 아닌 -작업이 완료될 때까지 기다려야만 하는 상황입니다. 이는 이벤트 루프가 **블로킹** 작업을 하는 -동안 JavaScript 실행을 계속할 수 없기 때문입니다. - -Node.js에서, I/O 등의 JavaScript가 아닌 작업을 기다리는 것보다 CPU 집약적인 작업 때문에 -나쁜 성능을 보여주는 JavaScript는 보통 **블로킹**이라고 부르지 않습니다. libuv를 사용하는 -Node.js 표준 라이브러리의 동기 메서드가 가장 대표적인 **블로킹** 작업입니다. -네이티브 모듈도 **블로킹** 메서드를 가질 수 있습니다. - -Node.js 표준 라이브러리의 모든 I/O 메서드는 **논블로킹**인 비동기 방식을 제공하고 -콜백 함수를 받습니다. 일부 메서드는 같은 작업을 하는 **블로킹** 메서드도 가지는데 이는 -이름 마지막에 `Sync`가 붙습니다. - - - -## 코드 비교 - -**블로킹** 메서드는 **동기**로 실행되고 **논블로킹** 메서드는 **비동기**로 실행됩니다. - -예시로 파일 시스템 모듈을 사용할 때 다음은 **동기**로 파일을 읽는 예제입니다. - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // 파일을 읽을 때까지 여기서 블로킹 됩니다. -``` - -다음은 같은 작업의 **비동기** 예제입니다. - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; -}); -``` - - - -첫 예제가 두 번째보다 간단해 보이지만 두 번째 줄에서 전체 파일을 읽을 때까지 다른 JavaScript -실행이 **블로킹**되는 단점이 있습니다. 동기 예제에서 오류가 발생하면 반드시 처리해주어야 하고 -그렇지 않으면 프로세스가 죽을 것입니다. 비동기 예제에서는 예제에 나왔듯이 에러를 던질지 아닐지는 -작성자에게 달려있습니다. - -예제를 좀 더 확장해 보겠습니다. - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // 파일을 읽을 때까지 여기서 블로킹됩니다. -console.log(data); -moreWork(); // console.log 이후 실행될 것입니다. -``` - -이를 비동기로 작성한 예제를 보겠습니다. - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -moreWork(); // console.log 이전에 실행될 것입니다. -``` - - - -위의 첫 예제에서 `console.log`는 `moreWork()` 전에 호출될 것입니다. 두 번째 -예제에서는 `fs.readFile()`가 **논블로킹**이므로 계속 JavaScript를 실행하고 -`moreWork()`가 먼저 호출될 것입니다. 파일 읽기가 완료되기를 기다리지 않고 `moreWork()`를 -실행할 수 있도록 한 것은 높은 스루풋을 가능하게 하는 핵심 디자인 선택입니다. - - - -## 동시성과 스루풋 - -Node.js에서 JavaScript 실행이 싱글 스레드이므로 동시성은 다른 작업이 완료된 후에 -JavaScript 콜백 함수를 실행하는 이벤트 루프의 능력을 의미합니다. 동시에 실행되어야 하는 -모든 코드는 I/O 등의 JavaScript가 아닌 작업이 일어나는 동안 이벤트 루프가 계속 -실행될 수 있도록 해야 합니다. - -예시로 웹서버로의 요청이 완료되기까지 50ms가 걸리고 50ms 중 45ms는 비동기로 -실행될 수 있는 데이터베이스 I/O인 상황을 생각해 보겠습니다. **논블로킹** 비동기 작업을 사용하면 -요청마다 45ms는 다른 요청을 처리할 수 있게 됩니다. 이는 **블로킹** 메서드 대신 -**논블로킹** 메서드를 사용함으로써 확연히 다른 성능 차이가 납니다. - -이벤트 루프는 동시 작업을 다루려고 부가적인 스레드를 만드는 다른 언어의 모델과는 다릅니다. - - - -## 블로킹과 논블로킹 코드를 섞을 때의 위험성 - -I/O를 다룰 때 피해야 하는 몇 가지 패턴이 있습니다. 예제를 보겠습니다. - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -fs.unlinkSync('/file.md'); -``` - - - -위 예제에서 `fs.unlinkSync()`가 `fs.readFile()`보다 먼저 실행될 수 있으므로 실제 -`file.md`를 읽기 전에 파일을 제거할 수 있습니다. 이 예제를 제대로 작성하려면 완전히 -**논블로킹**으로 작성해서 올바른 순서로 실행되도록 보장해야 합니다. - -```js -const fs = require('fs'); -fs.readFile('/file.md', (readFileErr, data) => { - if (readFileErr) throw readFileErr; - console.log(data); - fs.unlink('/file.md', unlinkErr => { - if (unlinkErr) throw unlinkErr; - }); -}); -``` - - - -여기서는 `fs.readFile()`의 콜백에서 `fs.unlink()`를 **논블로킹**으로 호출하도록 해서 작업 순서가 올바르도록 보장했습니다. - -## 추가 자료 - -- [libuv](https://libuv.org/) diff --git a/pages/ko/docs/guides/debugging-getting-started.md b/pages/ko/docs/guides/debugging-getting-started.md deleted file mode 100644 index 410514ba64752..0000000000000 --- a/pages/ko/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,466 +0,0 @@ ---- -title: 디버깅 - 시작하기 -layout: docs.hbs ---- - - - -# 디버깅 가이드 - -이 문서는 Node.js 앱과 스크립트의 디버깅을 도울 것입니다. - -## 인스펙터 활성화 - -`--inspect` 스위치로 시작하면 Node.js 프로세스가 디버깅 클라이언트에서 수신을 -시작하고 기본 호스트와 포트로 `127.0.0.1:9229`를 사용합니다. 각 프로세스는 -고유한 [UUID][]도 할당받습니다. - -인스펙터 클라이언트는 호스트 주소, 포트, UUID를 알아야 접속할 수 있습니다. 전체 -URL은 `ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e` 같은 형태가 -됩니다. - -Node.js가 `SIGUSR1` 신호를 받으면 디버깅 메시지도 수신하기 -시작합니다.(`SIGUSR1`은 Windows에서는 사용할 수 없습니다.) Node.js 7 이하 -버전에서는 레거시 Debugger API가 활성화되고 Node.js 8 이상에서는 Inspector API를 -활성화합니다. - ---- - - - -## 보안 관련 - -디버거가 Node.js 실행 환경에 완전히 액세스하기 때문에 이 포트에 연결할 수 있는 공격자가 노드 프로세스를 대신하여 임의의 코드를 실행할 수 있습니다. 디버거 포트를 공용 및 개인 네트워크에 노출하는 경우 보안에 미치는 영향을 이해하는 것은 중요합니다. - - - -### 디버그 포트를 공개적으로 노출하는 것은 안전하지 않습니다. - -디버거가 퍼블릭 IP 주소 또는 0.0.0.0에 바인딩 될 경우 IP 주소에 접근할 수 있는 어떤 클라이언트든 아무 제약 없이 디버거에 접속할 수 있고 임의의 코드를 실행할 수 있습니다. - -기본적으로 `node --inspect`는 127.0.0.1에 바인딩 합니다. 디버거에 외부 접속을 허용하려 할 경우 퍼블릭 IP 주소 또는 0.0.0.0 등을 명시적으로 제공해야 합니다. 이렇게 하면 잠재적으로 심각한 보안 위협에 노출될 수 있습니다. 보안 노출을 방지하기 위해 적절한 방화벽과 액세스 제어를 유지하는 것이 좋습니다. - -원격 디버거 클라이언트의 접근을 안전하게 허용하는 방법은 '[원격 디버깅 활성화 시나리오](#enabling-remote-debugging-scenarios)' 섹션을 참조하십시오. - - - -### 로컬 애플리케이션은 인스펙터에 완전히 액세스 할 수 있습니다. - -인스펙터 포트를 127.0.0.1(기본값)에 바인딩하더라도 시스템에서 로컬로 실행되는 애플리케이션들은 제한 없이 액세스 할 수 있습니다. 이것은 로컬 디버거를 편리하게 부착할 수 있도록 의도적으로 설계되었습니다. - - - -### 브라우저, 웹소켓, 동일 출처 정책 - -웹 브라우저에서 열리는 웹사이트는 브라우저 보안 모델에 따라 웹소켓과 HTTP 요청을 할 수 있습니다. 고유한 디버거 세션 ID를 얻으려면 초기 HTTP 연결이 필요합니다. 동일 출처 정책은 이 HTTP 연결을 만들 수 없도록 합니다. [DNS 리바인딩 공격](https://en.wikipedia.org/wiki/DNS_rebinding)에 대한 추가 보안을 위해 Node.js는 연결의 'Host' 헤더가 IP 주소나 `localhost` 또는 `localhost6`을 정확하게 지정하는지 검증합니다. - - - -이러한 보안 정책은 호스트 이름을 지정하여 원격 디버그 서버에 접속할 수 없도록 합니다. IP 주소를 지정하거나 아래에 설명된 것과 같이 ssh 터널을 사용하여 이 제한사항을 해결할 수 있습니다. - - - -## 인스펙터 클라이언트 - -Node 인스펙터에 접속할 수 있는 여러 상용 도구와 오픈소스 도구가 있습니다. -아래에 이러한 도구들을 간략하게 정리했습니다. - -### [node-inspect](https://github.com/nodejs/node-inspect) - -- Node.js 재단에서 지원하는 CLI 디버거로 [Inspector 프로토콜][]을 사용합니다. -- Node에 포함되어 있고 `node inspect myscript.js`로 사용할 수 있습니다. -- 최신 버전을 별도로 설치할 수 있고(예시: `npm install -g node-inspect`) - `node-inspect myscript.js`로 사용할 수 있습니다. - -### [Chrome DevTools](https://github.com/ChromeDevTools/devtools-frontend) 55+ - -- **방법 1**: 크로미움에 기반을 둔 브라우저에서 `chrome://inspect`를 엽니다. - Configure 버튼을 눌러서 대상 호스트와 포트 목록을 확인합니다. -- **방법 2**: `/json/list`(상단 참고)의 출력에서 `devtoolsFrontendUrl`을 - 복사하거나 --inspect가 알려준 텍스트에서 복사해서 크롬에 붙여넣기를 합니다. - - - -### [Visual Studio Code](https://github.com/microsoft/vscode) 1.10+ - -- Debug 패널에서 설정 아이콘을 클릭해서 `.vscode/launch.json`을 엽니다. - 초기 설정으로 "Node.js"를 선택하세요. - -### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- 메뉴에서 "Debug > Start Debugging"을 선택하거나 F5를 누르세요. -- [상세한 설명](https://github.com/Microsoft/nodejstools/wiki/Debugging) - -### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) 2017.1+와 다른 JetBrains IDE - -- 새로운 Node.js 디버그 설정을 생성하고 Debug를 누르세요. Node.js 7+에서는 - 기본적으로 `--inspect`를 사용할 것입니다. 비활성화하려면 IDE 레지스트리에서 - `js.debugger.node.use.inspect`의 체크를 해제하세요. - -### [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - -- 인스펙터 프로토콜 엔드포인트로의 연결을 쉽게 하는 라이브러리입니다. - -### [Gitpod](https://www.gitpod.io) - -- `Debug` 뷰에서 Node.js 디버그 설정을 실행하거나 `F5` 키를 누르세요. - [자세한 방법은 여기를 참고하세요.](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1) - -### [Eclipse IDE](https://eclipse.org/eclipseide)와 Eclipse Wild Web Developer 확장 프로그램 - -- .js 파일에서 "Debug As... > Node program"을 선택하거나, -- 실행 중인 (`--inspect`로 시작한) Node 애플리케이션에 디버거를 연결하는 디버그 설정을 생성하세요. - ---- - - - -## 명령행 옵션 - -다음 테이블은 디버깅용 여러 런타임 플래그의 기능을 보여줍니다. - - - - - - - - - - - - - - - - - - - - - - - - - - - -
플래그의미
--inspect -
    -
  • 인스펙터 에이전트 활성화
  • -
  • 기본 주소와 포트에서 수신(127.0.0.1:9229)
  • -
-
--inspect=[host:port] -
    -
  • 인스펙터 에이전트 활성화
  • -
  • 주소 또는 호스트 이름 host에 바인딩 (기본값: 127.0.0.1)
  • -
  • port 포트에서 수신 (기본값: 9229)
  • -
-
--inspect-brk -
    -
  • 인스펙터 에이전트 활성화
  • -
  • 기본 주소와 포트에서 수신(127.0.0.1:9229)
  • -
  • 사용자 코드 시작 전 멈춤
  • -
-
--inspect-brk=[host:port] -
    -
  • 인스펙터 에이전트 활성화
  • -
  • 주소 또는 호스트 이름 host에 바인딩 (기본값: 127.0.0.1)
  • -
  • port 포트에서 수신 (기본값: 9229)
  • -
  • 사용자 코드 시작 전 멈춤
  • -
-
node inspect script.js -
    -
  • 사용자의 스크립트를 --inspect 플래그로 실행하는 자식 프로세스를 생성하고 CLI 디버거 실행에 메인 프로세스를 사용합니다.
  • -
-
node inspect --port=xxxx script.js -
    -
  • 사용자의 스크립트를 --inspect 플래그로 실행하는 자식 프로세스를 생성하고 CLI 디버거 실행에 메인 프로세스를 사용합니다.
  • -
  • port 포트에서 수신 (기본값: 9229)
  • -
-
- ---- - -## 원격 디버깅 활성화 시나리오 - - - -디버거가 퍼블릭 IP 주소에서 수신하지 않는 것을 권장합니다. 만약 원격 디버깅 연결을 허용해야 하는 경우 ssh 터널링을 대신 사용할 것을 권장합니다. 설명을 위해 아래 예제를 제공합니다. 진행하기 전 권한을 가진 서비스에 원격 액세스를 허용할 경우 발생할 수 있는 보안 위험을 이해하시기 바랍니다. - - - -디버깅하기를 원하는 remote.example.com 원격 시스템에서 노드가 실행 중이라고 가정하겠습니다. 해당 시스템에서 localhost(기본값)만 수신하는 인스펙터로 노드 프로세스를 시작해야 합니다. - -```bash -node --inspect server.js -``` - - - -이제 디버그 클라이언트 연결을 시작하려는 로컬 시스템에서 ssh 터널을 설정할 수 있습니다. - -```bash -ssh -L 9221:localhost:9229 user@remote.example.com -``` - - - -그러면 로컬 시스템의 9221 포트에서 remote.example.com의 9229 포트로 전달되는 ssh 터널 세션이 시작됩니다. Chrome DevTools 또는 Visual Studio Code 등의 디버거로 localhost:9221에 연결 할 수 있으며 Node.js 애플리케이션이 로컬에서 실행 중인 것처럼 디버깅할 수 있습니다. - ---- - - - -## 레거시 디버거 - -**레거시 디버거는 Node 7.7.0부터 폐기되었습니다. 대신 --inspect와 인스펙터를 사용하세요.** - -버전 7 이하에서 **--debug**나 **--debug-brk** 스위치로 시작하면 Node.js는 -TCP 포트(기본 `5858`)로 지금은 중단된 V8 디버깅 프로토콜에서 정의한 디버깅 명령어를 받습니다. -이 프로토콜을 사용하는 모든 디버거 클라이언트는 실행된 프로세스에 접속하고 디버깅할 수 있습니다. -인기 있는 클라이언트의 목록이 아래 나와 있습니다. - -V8 디버깅 프로토콜은 더는 관리되지 않고 문서화도 되지 않습니다. - - - -### [내장 디버거](https://nodejs.org/dist/latest/docs/api/debugger.html) - -Node의 내장 명령형 디버거로 스크립트를 실행하려면 `node debug script_name.js`로 실행하세요. -스크립트가 다른 Node 프로세스에서 `--debug-brk` 옵션으로 시작되고 원래의 Node 프로세스는 -`_debugger.js`를 실행해서 대상에 접속합니다. - -### [node-inspector](https://github.com/node-inspector/node-inspector) - -크로미움에서 사용하는 인스펙터 프로토콜을 Node.js가 사용하는 V8 디버거 프로토콜로 변환하는 -중간 프로세스를 사용해서 크롬 개발자도구로 Node.js 애플리케이션을 디버깅합니다. - - - - - - - -[Inspector 프로토콜]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/ko/docs/guides/diagnostics/live-debugging/index.md b/pages/ko/docs/guides/diagnostics/live-debugging/index.md deleted file mode 100644 index 10c9ed8fce252..0000000000000 --- a/pages/ko/docs/guides/diagnostics/live-debugging/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 라이브 디버깅 -layout: docs.hbs ---- - -# 라이브 디버깅 - -- [라이브 디버깅](#live-debugging) - - [응용 프로그램이 예상대로 작동하지 않을 때](#my-application-doesnt-behave-as-expected) - - [증상](#symptoms) - - [디버깅](#debugging) - -이 문서를 통해 Node.js 프로세스를 라이브 디버그하는 방법을 배울 수 있습니다. - -## 응용 프로그램이 예상대로 작동하지 않을 때 - -### 증상 - -사용자는 응용 프로그램이 특정 인풋에 대해 예상되는 아웃풋을 제공하지 않는 것을 발견할 수 있습니다. 예를 들어, HTTP 서버가 특정 필드가 비어있는 JSON 응답을 리턴하는 것처럼요. 프로세스 중 많은 오류가 발생할 수 있지만 이 사용 사례에서 우리는 응용 프로그램 로직과 그 정확성을 중점적으로 다룹니다. - -### 디버깅 - -이 사용 사례에서, 사용자는 들어오는 HTTP 요청과 같은 특정한 트리거에 대해 응용 프로그램이 실행하는 코드 경로를 이해하고자 합니다. 또한 코드를 따라가며 메모리에 저장된 변수의 값을 검사할 뿐아니라 실행을 제어하길 원할 수도 있습니다. - -- [검사기 사용하기](/en/docs/guides/diagnostics/live-debugging/using-inspector) diff --git a/pages/ko/docs/guides/diagnostics/live-debugging/using-inspector.md b/pages/ko/docs/guides/diagnostics/live-debugging/using-inspector.md deleted file mode 100644 index 464357b2915a3..0000000000000 --- a/pages/ko/docs/guides/diagnostics/live-debugging/using-inspector.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: 검사기 사용하기 -layout: docs.hbs ---- - -# 검사기 사용하기 - -로컬 환경에서 우리는 일반적으로 디버거를 응용 프로그램에 연결하고 프로그램 실행을 일시 중지하기 위해 중단점을 추가하는 라이브 디버깅을 이야기합니다. 그 다음 코드 경로를 따라가고 여러 단계에서 힙을 검사합니다. 하지만 프로덕션에서는 보통 머신에의 접근이 제한되어 있고 비즈니스에 중요한 워크로드를 다루는 응용 프로그램의 실행을 방해할 수 없기 때문에 라이브 디버거를 사용하지 않습니다. - -## 사용 방법 - -https://nodejs.org/en/docs/guides/debugging-getting-started/ diff --git a/pages/ko/docs/guides/diagnostics/memory/index.md b/pages/ko/docs/guides/diagnostics/memory/index.md deleted file mode 100644 index 98c59a68016cb..0000000000000 --- a/pages/ko/docs/guides/diagnostics/memory/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 메모리 진단 -layout: docs.hbs ---- - -# 메모리 - -이 문서를 통해 메모리 관련 이슈를 디버그하는 방법을 배울 수 있습니다. - -- [메모리](#memory) - - [내 프로세스에 필요한 메모리가 부족할 때](#my-process-runs-out-of-memory) - - [증상](#symptoms) - - [부작용](#side-effects) - - [내 프로세스가 메모리를 비효율적으로 사용할 때](#my-process-utilizes-memory-inefficiently) - - [증상](#symptoms-1) - - [부작용](#side-effects-1) - - [디버깅](#debugging) - -## 내 프로세스에 필요한 메모리가 부족할 때 - -Node.js _(JavaScript)_ 는 가비지 컬렉션을 사용하는 언어이므로, 리테이너를 통해 메모리 누수가 발생할 수 있습니다. Node.js 응용 프로그램은 대부분 멀티-테넌트이고, 비즈니스에 중요하고, 오래 실행되므로 메모리 누수를 찾는 효율적이며 접근이 용이한 방법을 제공하는 것이 필수적입니다. - -### 증상 - -사용자는 메모리 사용량이 계속해서 늘어나다가 _(빠를 수도 느릴 수도 있고, 며칠 혹은 몇 주까지 걸쳐 일어난다)_ 프로세스가 고장 나고 프로세스 매니저에 의해 재실행되는 것을 발견할 수 있습니다. 프로세스가 이전보다 느리게 실행되고 재실행이 일부 요청의 실패를 불러올 수 있습니다. _(load balancer responds with 502)_ - -### 부작용 - -- 메모리 고갈로 인해 프로세스가 재시작되며 요청들이 버려짐 -- GC 활동의 증가는 CPU 사용량을 높이고 반응 시간을 늦춤 - - GC가 이벤트 루프를 막아 느려짐 -- 메모리 스와핑 증가로 인해 프로세스가 느려짐 (GC 사용) -- 힙 스냅숏을 가져오기에 메모리 여유가 부족할 수 있음 - -## 내 프로세스가 메모리를 비효율적으로 사용할 때 - -### 증상 - -응용 프로그램이 예상하지 못한 양의 메모리를 사용하고/하거나 높은 가비지 컬렉터 사용이 관찰됨 - -### 부작용 - -- 다수의 페이지 폴트 -- 더 높은 GC 활동 및 CPU 사용량 - -## 디버깅 - -대부분의 메모리 이슈는 특정 타입의 객체가 얼마나 많은 공간을 차지할지와 어떤 변수가 가비지 컬렉션되는 것을 방해하는지 결정하는 것으로 해결 가능합니다. 또한 프로그램의 시간에 따른 할당 패턴을 알고 있다면 도움이 됩니다. - -- [힙 프로파일러 사용하기](/en/docs/guides/diagnostics/memory/using-heap-profiler/) -- [힙 스냅샷 사용하기](/en/docs/guides/diagnostics/memory/using-heap-snapshot/) -- [GC 트레이스](/en/docs/guides/diagnostics/memory/using-gc-traces) diff --git a/pages/ko/docs/guides/domain-postmortem.md b/pages/ko/docs/guides/domain-postmortem.md deleted file mode 100644 index 1409f50cd62b6..0000000000000 --- a/pages/ko/docs/guides/domain-postmortem.md +++ /dev/null @@ -1,879 +0,0 @@ ---- -title: 도메인 모듈 포스트모템 -layout: docs.hbs ---- - - - -# 도메인 모듈 포스트모템 - -## 사용성 이슈 - -### 암묵적인 동작 - -개발자가 새로운 도메인을 만들고 `domain.enter()`를 실행할 수 있습니다. 이는 이후 모든 예외를 -잡는 것처럼 동작하므로 오류를 던진 쪽에서 관찰할 수 없게 했습니다. 이는 모듈 작성자가 다른 모듈의 -관련 없는 코드의 예외를 가로챌 수 있게 했고 코드의 작성자가 자신의 예외를 알지 못하게 했습니다. - -다음 예제는 간접적으로 연결된 모듈이 다른 모듈에 어떻게 영향을 끼칠 수 있는지를 보여줍니다. - - - -```js -// 모듈 a.js -const b = require('./b'); -const c = require('./c'); - -// 모듈 b.js -const d = require('domain').create(); -d.on('error', () => { - /* 모든 것을 무시합니다. */ -}); -d.enter(); - -// 모듈 c.js -const dep = require('some-dep'); -dep.method(); // 앗! 이 메서드는 실제로 존재하지 않습니다. -``` - -모듈 `b`가 도메인에 들어갔지만 나오지는 않았으므로 잡지 않은 모든 예외가 무시될 것입니다. 이는 -모듈 `c`가 왜 전체 스크립트를 실행하지 않는지를 알지 못하게 둡니다. 부분적으로 존재하는 -`module.exports`를 잠재적으로 둡니다. 이렇게 하는 것은 전역적으로 오류를 잡겠다고 명시적으로 -나타내는 `'uncaughtException'`을 사용하는 것과 다릅니다. 도메인이 -어떤 `'uncaughtException'` 핸들러보다도 먼저 처리되어 -`'uncaughtException'`이 실행되지 않도록 한다는 것은 또 다른 문제입니다. - - - -또 다른 문제는 도메인 라우트가 이벤트 이미터에 `'error'` 핸들러가 설정되어 있지 않다면 오류를 -발생시킨다는 것입니다. 이를 위한 옵트인 메커니즘은 존재하지 않고 전체 비동기 체인에 자동으로 전파됩니다. -처음에는 유용해 보이지만 비동기 호출이 두 개 이상의 모듈을 호출하고 이 중 하나가 오류 핸들러를 -작성하지 않았다면 도메인 생성자는 예상치 못한 예외를 갑자기 받을 것이고 오류가 발생한 곳의 -작성자는 알지 못할 것입니다. - -다음 예제는 빠진 `'error'` 핸들러 때문에 어떻게 활성화된 도메인이 오류를 가로채는지 보여줍니다. - -```js -const domain = require('domain'); -const net = require('net'); -const d = domain.create(); -d.on('error', err => console.error(err.message)); - -d.run(() => - net - .createServer(c => { - c.end(); - c.write('bye'); - }) - .listen(8000) -); -``` - - - -`d.remove(c)`를 통해 수동으로 연결을 제거하더라도 연결 오류가 자동으로 -가로채지는 것을 막지 못합니다. - -오류 라우팅과 예외처리를 모두 괴롭히는 실패는 오류를 버블링하는 방법의 불일치입니다. -다음은 중첩된 도메인이 언제 발생한 오류에 따라 어떻게 버블링하고 버블링하지 않는지를 보여줍니다. - -```js -const domain = require('domain'); -const net = require('net'); -const d = domain.create(); -d.on('error', () => console.error('d intercepted an error')); - -d.run(() => { - const server = net - .createServer(c => { - const e = domain.create(); // 'error' 핸들러가 설정되지 않았습니다. - e.run(() => { - // 이 오류는 d의 오류 핸들러가 잡지 못합니다. - setImmediate(() => { - throw new Error('thrown from setImmediate'); - }); - // 그런데도 이 오류는 d의 오류 핸들러에 버블링 될 것입니다. - throw new Error('immediately thrown'); - }); - }) - .listen(8080); -}); -``` - -중첩된 도메인은 항상 중첩된 상태로 남아있고 예외는 항상 도메인 스택으로 전파되기를 기대할 수 있습니다. -아니면 이 예외가 절대 자동으로 버블링되지 않기를 기대할 수 있습니다. 불행히도 두 가지 상황이 모두 -발생하고 이는 시점의 충돌을 디버깅하기 어렵게 만들기 쉬운 혼란스러운 동작입니다. - - - -### API 차이 - -`EventEmitter`에 기반을 둔 API는 `bind()`를 사용할 수 있고 에러를 다시 받는 형식의 콜백은 -`intercept()`를 사용할 수 있지만, 활성화된 도메인에 암묵적으로 바인딩 되는 다른 API는 -`run()` 안에서 실행되어야 합니다. 이는 모듈 작성자가 앞에서 말한 방식의 대안 메커니즘을 사용해서 -도메인을 지원하고자 하면 이미 적소에 있는 암묵적인 메커니즘을 이용하지 않고 직접 도메인 지원을 -구현해야 한다는 의미입니다. - - - -### 오류 전파 - -중첩된 도메인에 걸친 오류 전파는 직관적이지 않습니다. 기존의 문서는 요청 핸들러에 오류가 있다면 -`http` 서버를 어떻게 `close()`하는지 간단한 예제를 보여줍니다. 여기서 설명하지 않은 것은 -요청 핸들러가 또 다른 비동기 요청을 위한 다른 도메인 인스턴스를 생성한다면 어떻게 닫을 것인가입니다. -오류 전파의 실패를 보여주는 다음 예제를 보겠습니다. - -```js -const d1 = domain.create(); -d1.foo = true; // 콘솔에서 더 가시적으로 만드는 커스텀 멤버 -d1.on('error', er => { - /* 오류 처리 */ -}); - -d1.run(() => - setTimeout(() => { - const d2 = domain.create(); - d2.bar = 43; - d2.on('error', er => console.error(er.message, domain._stack)); - d2.run(() => { - setTimeout(() => { - setTimeout(() => { - throw new Error('outer'); - }); - throw new Error('inner'); - }); - }); - }) -); -``` - - - -도메인 인스턴스가 로컬 스토리지에 사용되어 자원에 대한 액세스가 가능해지더라도 여전히 오류가 `d2`에서 -`d1`으로 다시 계속 전파되도록 허용할 수 있는 방법이 없습니다. 빠른 검사는 `d2` 도메인의 -`'error'` 핸들러를 던지기만 하면 `d1`이 예외를 잡아서 자체 에러 핸들러를 실행할 수 있게 합니다. -지금은 이 경우가 아니지만 `domain._stack`을 검사하면 스택에 `d2`만 포함되어 있음을 알 수 있습니다. - -이것이 API의 실패라고 생각할 수 있습니다만 이러한 방식으로 동작하더라도 비동기 실행의 분기가 실패했다는 -사실을 전달하는 문제가 여전히 남아있고 이 분기의 추가작업은 중단되어야 합니다. http 요청 핸들러 -예제에서 다수의 비동기 요청을 보내고 각 요청에서 `write()`의 데이터를 다시 클라이언트에 보내면 -닫힌 핸들에 `write()`를 시도하면서 더 많은 오류가 발생합니다. -이것에 대한 자세한 내용은 *예외발생시 자원 정리*를 참고하세요. - - - -### 예외 발생 시 자원 정리 - -다음 스크립트는 해당 연결이나 의존성에서 예외가 발생한 경우 작은 자원 의존성 트리를 적절하게 -정리하는 꽤 복잡한 예제입니다. 기본 작업으로 스크립트를 나누었습니다. - -```js -'use strict'; - -const domain = require('domain'); -const EE = require('events'); -const fs = require('fs'); -const net = require('net'); -const util = require('util'); -const print = process._rawDebug; - -const pipeList = []; -const FILENAME = '/tmp/tmp.tmp'; -const PIPENAME = '/tmp/node-domain-example-'; -const FILESIZE = 1024; -let uid = 0; - -// 임시 자원을 설정합니다 -const buf = Buffer.alloc(FILESIZE); -for (let i = 0; i < buf.length; i++) buf[i] = ((Math.random() * 1e3) % 78) + 48; // Basic ASCII -fs.writeFileSync(FILENAME, buf); - -function ConnectionResource(c) { - EE.call(this); - this._connection = c; - this._alive = true; - this._domain = domain.create(); - this._id = Math.random().toString(32).substr(2).substr(0, 8) + ++uid; - - this._domain.add(c); - this._domain.on('error', () => { - this._alive = false; - }); -} -util.inherits(ConnectionResource, EE); - -ConnectionResource.prototype.end = function end(chunk) { - this._alive = false; - this._connection.end(chunk); - this.emit('end'); -}; - -ConnectionResource.prototype.isAlive = function isAlive() { - return this._alive; -}; - -ConnectionResource.prototype.id = function id() { - return this._id; -}; - -ConnectionResource.prototype.write = function write(chunk) { - this.emit('data', chunk); - return this._connection.write(chunk); -}; - -// 예제 시작 -net - .createServer(c => { - const cr = new ConnectionResource(c); - - const d1 = domain.create(); - fs.open( - FILENAME, - 'r', - d1.intercept(fd => { - streamInParts(fd, cr, 0); - }) - ); - - pipeData(cr); - - c.on('close', () => cr.end()); - }) - .listen(8080); - -function streamInParts(fd, cr, pos) { - const d2 = domain.create(); - const alive = true; - d2.on('error', er => { - print('d2 error:', er.message); - cr.end(); - }); - fs.read( - fd, - Buffer.alloc(10), - 0, - 10, - pos, - d2.intercept((bRead, buf) => { - if (!cr.isAlive()) { - return fs.close(fd); - } - if (cr._connection.bytesWritten < FILESIZE) { - // 문서에는 콜백이 선택사항으로 나와 있지만 - // 작성이 실패하면 예외가 던져진다고는 얘기하지 않았습니다. - const goodtogo = cr.write(buf); - if (goodtogo) { - setTimeout(() => streamInParts(fd, cr, pos + bRead), 1000); - } else { - cr._connection.once('drain', () => - streamInParts(fd, cr, pos + bRead) - ); - } - return; - } - cr.end(buf); - fs.close(fd); - }) - ); -} - -function pipeData(cr) { - const pname = PIPENAME + cr.id(); - const ps = net.createServer(); - const d3 = domain.create(); - const connectionList = []; - d3.on('error', er => { - print('d3 error:', er.message); - cr.end(); - }); - d3.add(ps); - ps.on('connection', conn => { - connectionList.push(conn); - conn.on('data', () => {}); // 들어오는 데이터는 무시합니다. - conn.on('close', () => { - connectionList.splice(connectionList.indexOf(conn), 1); - }); - }); - cr.on('data', chunk => { - for (let i = 0; i < connectionList.length; i++) { - connectionList[i].write(chunk); - } - }); - cr.on('end', () => { - for (let i = 0; i < connectionList.length; i++) { - connectionList[i].end(); - } - ps.close(); - }); - pipeList.push(pname); - ps.listen(pname); -} - -process.on('SIGINT', () => process.exit()); -process.on('exit', () => { - try { - for (let i = 0; i < pipeList.length; i++) { - fs.unlinkSync(pipeList[i]); - } - fs.unlinkSync(FILENAME); - } catch (e) {} -}); -``` - - - -- 새로운 연결이 이뤄지면 동시에 - - 파일시스템에서 파일을 엽니다. - - 유일한 소켓과 파이프를 연결합니다. -- 파일의 청크를 비동기로 읽습니다. -- TCP 연결과 리스닝 중인 모든 소켓에 청크를 작성합니다. -- 이러한 자원에서 오류가 발생하면 정리하고 종료해야 하는 모든 연결된 자원에 알립니다. - -이 예제에서 알 수 있듯이 도메인 API로 엄격하게 수행할 수 있는 것보다 실패했을 때 자원을 적절하게 -정리하려면 더 많은 작업을 해야 합니다. 도메인이 제공하는 모든 것은 예외를 수집하는 메커니즘입니다. -이 예제에서 함수의 인자로 필요한 자원을 전달해서 도메인으로 데이터를 전파할 수 있는 잠재적으로 -유용한 기능조차도 쉽게 대응할 수 있습니다. - -도메인이 유지되는 한 가지 문제는 문서에 나와 있는 것과는 달리 예기치 않은 예외에도 불구하고 -애플리케이션을 계속 실행할 수 있다는 단순한 생각이었습니다. -이 예제는 이 생각에 오류가 있다는 것을 보여줍니다. - - - -예기치 않은 예외가 발생했을 때 적절하게 자원 정리를 시도하면 애플리케이션 자체의 복잡도가 증가하므로 -더 복잡해집니다. 이 예제는 3가지의 기본적인 자원만 가지고 있고 이 자원는 모두 명확한 의존성 경로를 -가집니다. 애플리케이션이 공유된 자원이나 자원 재사용을 사용하는 경우 정리 기능과 정리가 -제대로 이뤄졌는지 확인하는 적절한 테스트는 복잡도가 더 증가합니다. - -결국, 오류처리 관점에서 도메인은 더 암묵적이고 서드파티가 관찰할 수 없는 동작이라는 점을 제외하면 -`'uncaughtException'` 핸들러와 별반 다르지 않습니다. - - - -### 자원 전파 - -도메인의 또 다른 사용방법은 비동기 데이터 경로를 따라 데이터를 전파하는 데 사용하는 것입니다. -한 가지 문제점은 스택에 여러 개가 있을 때(비동기 스택이 다른 모듈과 동작한다고 가정해야 한다면) -올바른 도메인을 기대하는 경우의 모호함입니다. 필요한 데이터를 얻는 데 사용하려고 도메인을 가지면서 -오류처리를 도메인에 의존하는 것에 충돌도 있습니다. - -비동기 스택을 따라 데이터를 전파하려고 도메인을 사용할 때의 실패를 다음 예제에서 보여줍니다. - -```js -const domain = require('domain'); -const net = require('net'); - -const server = net - .createServer(c => { - // 모든 곳에서 인자를 전달할 수 없으므로 - // 연결 내에서 이벤트 간에 데이터를 전파하려고 도메인을 사용합니다. - const d = domain.create(); - d.data = { connection: c }; - d.add(c); - // 데모용으로 쓸모없는 비동기 데이터 변환을 하는 Mock 클래스 - const ds = new DataStream(dataTransformed); - c.on('data', chunk => ds.data(chunk)); - }) - .listen(8080, () => console.log('listening on 8080')); - -function dataTransformed(chunk) { - // 실패! DataStream 인스턴스도 도메인을 생성했으므로 - // 사용하려고 했던 활성 도메인을 잃어버렸습니다. - domain.active.data.connection.write(chunk); -} - -function DataStream(cb) { - this.cb = cb; - // DataStream은 데이터 전파에도 도메인을 사용하려고 합니다! - // 불행히도 이는 이미 존재하는 다른 도메인과 충돌할 것입니다. - this.domain = domain.create(); - this.domain.data = { inst: this }; -} - -DataStream.prototype.data = function data(chunk) { - // 이 코드는 자기충족적이지만 최소한 하나의 다른 모듈과의 복잡한 작업인 척합니다. - // 그러므로 "this"를 함께 전달하기는 쉽지 않습니다. - this.domain.run(() => { - // 데이터를 변환하는 비동기 작업을 시뮬레이트합니다. - setImmediate(() => { - for (let i = 0; i < chunk.length; i++) - chunk[i] = ((chunk[i] + Math.random() * 100) % 96) + 33; - // 활성화된 도메인에서 인스턴스를 가져오고 사용자 콜백을 호출하는 데 사용합니다. - const self = domain.active.data.inst; - self.cb(chunk); - }); - }); -}; -``` - - - -위 예제는 데이터를 전파하려고 도메인을 사용하는 두 개 이상의 비동기 API를 가지기가 어렵다는 것을 -보여줍니다. 이 예제는 `DataStream` 생성자에서 `parent: domain.active`를 할당해서 -고칠 수 있습니다. 그런 다음 사용자의 콜백이 호출되기 직전에 -`domain.active = domain.active.data.parent`로 도메인을 복구합니다. -`'connection'` 콜백에서 `DataStream`의 인스턴스 생성은 단순히 `d.add(c)`를 사용하는 대신 -`d.run()` 안에서 실행되어야 합니다. 그렇지 않으면 활성화된 도메인이 없을 것입니다. - -간단히 말해, 이렇게 하려면 적용이나 테스트가 어려울 수 있는 일련의 가이드라인을 엄격하게 따라야 합니다. - - - -## 성능 문제 - -도메인을 사용할 때의 중요한 방해요소는 오버헤드입니다. 도메인 없이 node에 내장된 http 벤치마크 -`http_simple.js`를 사용하면 초당 22,000 요청 이상을 처리할 수 있습니다. 그에 비해 -`NODE_USE_DOMAINS=1`로 실행하면 초당 17,000 요청 이하로 떨어집니다. 이 경우에는 단 하나의 -전역 도메인만 있습니다. 벤치마크의 http 요청 콜백이 새로운 도메인 인스턴스를 생성하도록 수정하면 -성능은 초당 15,000 요청으로 떨어집니다. - -이 문제가 초당 수백, 수천 요청만 처리하는 서버에는 영향을 주지 않을 수 있지만, 오버헤드의 규모는 -비동기 요청 수에 비례합니다. 그러므로 하나의 연결에 다른 여러 서비스로의 연결이 필요하다면 -이 모든 요청은 클라이언트에게 전달하는 최종 제품의 전체 지연시간에 영향을 주게 됩니다. - -앞에서 얘기한 벤치마크에서 `AsyncWrap`을 사용하고 `init`/`pre`/`post`/`destroy`가 -호출된 횟수를 추적하자 호출된 모든 이벤트의 합이 초당 170,000번 이상이라는 것을 알 수 있었습니다. -이는 어떤 종류의 설정이나 정리를 위한 호출당 1마이크로초의 오버헤드가 추가되어 17%의 성능 저하가 -발생한다는 것을 의미합니다. 당연히 이는 벤치마크에 최적화된 시나리오이지만 도메인 같은 메커니즘은 -가능한 한 싸게 실행되어야 할 필요성을 보여준다고 생각합니다. - - - -## 앞을 내다 보며 - -도메인 모듈은 2014년 12월부터 소프트 폐기되었지만, 지금은 node가 대체 기능을 제공하지 않으므로 -아직 제거하지 않았습니다. 이 글을 쓰는 시점에 `AsyncWrap` API와 TC39를 위해 준비하고 있는 -Zone에 관한 제안을 만들고 있습니다. 도메인을 교체할 적당한 기능이 있을 때 전체 폐기 주기를 -진행할 것이고 결국 코어에서 제거할 것입니다. diff --git a/pages/ko/docs/guides/dont-block-the-event-loop.md b/pages/ko/docs/guides/dont-block-the-event-loop.md deleted file mode 100644 index 47a219602cc4b..0000000000000 --- a/pages/ko/docs/guides/dont-block-the-event-loop.md +++ /dev/null @@ -1,515 +0,0 @@ ---- -title: 이벤트 루프와 워커 풀을 막지 마세요! -layout: docs.hbs ---- - -# 이벤트 루프와 워커 풀을 막지 마세요! - -## 누가 이 문서를 읽어야 하나요? - -만약 당신이 간단한 스크립트보다 더 복잡한 코드를 작성하길 원하신다면, 해당 문서를 읽는 것은 당신의 애플리케이션의 성능을 더 좋게, 보안을 안전하게 하는데 도움을 줄 것입니다. - -해당 문서는 Node.js 서버를 기준으로 작성되었지만, 기본적인 개념은 복잡한 Node.js 애플리케이션에서도 적용됩니다. -OS마다 세부 내용은 달라질 수 있으며 해당 문서는 리눅스를 기준으로 작성되었습니다. - -## 요약 - -Node.js에서는 자바스크립트 코드를 이벤트 루프(초기화와 콜백)에서 실행시키고 파일 I/O와 같은 값비싼 작업은 워커 풀에게 위임합니다. -어떤 경우에는 더 많은 Apache와 같은 서버를 두는 것보다 Node.js가 좋을 정도로 Node.js의 확장성은 뛰어납니다. -Node.js 확장성의 핵심은 많은 수의 클라이언트를 단 몇 개의 스레드만으로 처리한다는 점입니다. -Node.js가 몇 개의 스레드만으로 잘 처리한다는 것은 곧 스레드를 생성하면서 발생하는 메모리 오버헤드와 컨텍스트 스위칭에서 발생하는 오버헤드를 클라이언트의 요청을 처리하는 데에 사용할 수 있다는 의미이기도 합니다. -반대로 말하면 당신은 애플리케이션이 몇 개의 스레드만으로 제대로 동작하도록 설계해야 한다는 뜻이기도 합니다. - -당신의 Node.js 서버가 빠르게 동작할 수 있는 단 하나의 경험칙이 있습니다. -_Node.js는 클라이언트에 관련된 일을 하는 시간이 "적으면 적을수록" 빠르다_. - -이 경험칙은 이벤트 루프의 콜백과 워커 풀의 태스크에 관련되어 있습니다. - -## 왜 이벤트 루프와 워커 풀을 막지 않아야 할까요? - -Node.js는 많은 수의 클라이언트를 단 몇 개의 스레드만으로 처리합니다. -Node.js에는 2종류의 스레드가 있습니다. 하나는 이벤트 루프(또는 메인 루프, 메인 스레드, 이벤트 스레드 등)이며 다른 하나는 워커 풀(또는 스레드풀)에 있는 `k`개의 워커들입니다. - -이벤트 루프에서 콜백을 실행하거나 워커에서 태스크를 실행할 때 오랜 시간이 걸린다면 우리는 그 스레드를 "막혔다"고 표현합니다. -스레드가 한 클라이언트를 위해 처리하는 동안에는 해당 스레드가 다른 클라이언트들의 요청을 처리할 수 없기 때문입니다. -이것은 우리에게 이벤트 루프나 워커 풀을 막지않아야 하는 2가지 이유를 설명해줍니다. - -1. 성능: 당신이 주기적으로 어떤 종류의 스레드에서든 처리 시간이 오래 걸리는 작업을 실행한다면 서버의 _처리량_ (요청/초)에 악영향을 끼칠 것입니다. -2. 보안: 만약 클라이언트에서의 특정한 인풋이 스레드 중 하나를 막는 것이 가능하다면, 악의적인 클라이언트가 해당 인풋을 요청하여 스레드를 의도적으로 막아 결과적으로 다른 클라이언트들의 요청을 처리하지 못하게 됩니다. 이는 [Denial of Service](https://en.wikipedia.org/wiki/Denial-of-service_attack) 공격으로 이어질 수 있습니다. - -## Node 빠르게 훑어보기 - -Node.js는 전체적으로 조율하기 위한 하나의 이벤트 루프와 값비싼 작업을 처리하는 하나의 워커풀로 구성된 Event-Driven Architecture로 설계되어있습니다. - -### 어떤 코드가 이벤트 루프에서 동작하나요? - -처음 실행될 때 Node.js 애플리케이션에서는 초기화 단계를 거칩니다. 해당 단계에서는 모듈들을 `require`하고 이벤트를 위한 콜백을 등록합니다. -그다음 Node.js 애플리케이션은 이벤트 루프에 진입하고 적절한 콜백을 실행하여 클라이언트의 요청에 응답합니다. -해당 콜백은 동기적으로 실행되며 해당 콜백이 완료되고 나서 비동기 요청들이 더 등록될 수 있습니다. -비동기 요청들을 처리하기 위한 콜백 또한 이벤트 루프에서 실행됩니다. - -이벤트 루프는 또한 네트워크 I/O처럼 콜백에 의해 계속 요청되는 논블로킹 비동기 요청들도 처리하게 됩니다. - -요약하자면 이벤트 루프에서는 이벤트를 위해 등록된 자바스크립트 콜백을 실행하고 네트워크 I/O와 같은 논블로킹 비동기 요청들 또한 처리할 수 있어야 합니다. - -### 어떤 코드가 워커 풀에서 동작하나요? - -Node.js에서 워커 풀은 libuv([docs](http://docs.libuv.org/en/v1.x/threadpool.html))로 구현되어 있으며 libuv는 일반적인 작업 요청 API를 노출하고 있습니다. - -Node.js는 워커 풀을 "값비싼" 작업을 처리하는 경우에 이용합니다. -해당 작업에는 CPU-intensive한 작업들뿐만 아니라 OS에서 논블로킹을 지원하지 않는 I/O의 경우도 포함됩니다. - -아래 목록은 워커 풀을 사용하게 하는 Node.js 모듈 API입니다. - -1. I/O-intensive - 1. [DNS](https://nodejs.org/api/dns.html): `dns.lookup()`, `dns.lookupService()`. - 2. [File System](https://nodejs.org/api/fs.html#fs_threadpool_usage): `fs.FSWatcher()`와 libuv의 스레드 풀을 명백하게 동기적으로 사용하는 경우를 제외한 모든 파일 시스템 API. -2. CPU-intensive - 1. [Crypto](https://nodejs.org/api/crypto.html): `crypto.pbkdf2()`, `crypto.scrypt()`, `crypto.randomBytes()`, `crypto.randomFill()`, `crypto.generateKeyPair()`. - 2. [Zlib](https://nodejs.org/api/zlib.html#zlib_threadpool_usage): libuv의 스레드 풀을 명백하게 동기적으로 사용하는 경우를 제외한 모든 zlib API. - -대부분의 Node.js 애플리케이션의 경우, 워커 풀을 사용하는 방법은 위의 API 목록이 유일합니다. -[C++ add-on](https://nodejs.org/api/addons.html)을 사용하는 애플리케이션이나 모듈의 경우 다른 작업을 워커 풀에서 처리할 수 있습니다. - -이벤트 루프의 콜백에 의해 위 목록 중 하나의 API가 호출되었을 때 이벤트 루프에서는 해당 API를 위해 Node.js C++ 바인딩에 들어가고 워커 풀에 작업을 요청하므로 셋업을 함에 있어 약간의 리소스가 사용될 수 있습니다. -하지만 이 리소스는 작업을 위한 전체 비용에 비하면 무시할 정도이며 이것이 이벤트 루프가 [offloading](https://en.wikipedia.org/wiki/Computation_offloading)한 이유입니다. -Node.js는 워커 풀에 이러한 작업을 요청할 때 Node.js C++ 바인딩에서 해당하는 C++ 함수에 대한 포인터를 함께 제공합니다. - -### Node.js에서는 다음에 실행될 코드를 어떻게 결정하나요? - -추상적으로 말하자면 이벤트 루프와 워커 풀에서는 각각 대기 중인 이벤트와 대기 중인 작업을 관리하기 위한 큐를 가지고 있습니다. - -하지만 실제로는 이벤트 루프는 큐를 가지고 있지 않습니다. -그 대신 이벤트 루프는 OS에게 모니터링을 요청하는 [File descriptor](https://en.wikipedia.org/wiki/File_descriptor)들의 콜렉션을 가지고 있으며 이는 [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html) (Linux), [kqueue](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/FSEvents_ProgGuide/KernelQueues/KernelQueues.html) (OSX), event ports (Solaris), [IOCP](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx) (Windows)와 같은 메커니즘으로 동작합니다. - -이 파일 디스크립터들은 그것이 모니터링하고 있는 모든 네트워크 소켓, 모니터링 중인 파일 등과 작용합니다. -OS에서 파일 디스크립터가 준비되었다고 알리면 이벤트 루프에서는 이를 적절한 이벤트로 번역 후에 해당 이벤트에 관련된 콜백을 호출합니다. 이 과정에 대해 더 자세히 알고 싶으시다면 [여기](https://www.youtube.com/watch?v=P9csgxBgaZ8)를 클릭하세요. - -이와 반대로 워커 풀에서는 진짜로 큐를 사용하여 처리할 작업의 입출입을 관리합니다. -하나의 워커는 하나의 작업을 해당 큐에서 pop해서 처리하며 작업이 완료되면 "최소한 하나의 작업은 끝났음" 이벤트를 이벤트 루프에 보냅니다. - -## 애플리케이션 디자인에서 어떤 의미를 가지나요? - -Apache와 같은 하나의 스레드에서 하나의 클라이언트를 처리하는 디자인에서는 각각의 대기 중인 클라이언트는 해당 스레드에 할당됩니다. -만약 하나의 스레드가 하나의 클라이언트에 의해 막히게 되면 OS에서 이를 중단시키고 다른 클라이언트가 사용할 수 있게 합니다. -OS는 적은 양의 작업이 필요한 클라이언트가 더 많은 양의 작업이 필요한 클라이언트에 의해 피해 보지 않도록 조처를 한다는 의미입니다. - -Node.js는 많은 클라이언트를 몇 개의 스레드로 처리해야 하므로 만약 스레드가 한 클라이언트의 요청에 의해 막힌다면 그 뒤에 대기 중인 클라이언트들의 요청은 스레드가 해당 콜백이나 작업을 끝낼 때까지 대기해야 합니다. -_클라이언트에 대한 공정한 처리는 당신의 애플리케이션의 책임입니다_. -이는 하나의 콜백이나 작업을 요청하는 클라이언트에 너무 많은 시간을 사용하지 않는 것이 좋다는 의미입니다. - -이것은 Node.js가 확장성이 좋은 이유 중 하나이지만 한편으로는 당신에게 공정한 스케줄링을 보장해야 한다는 책임이 주어진다는 의미이기도 합니다. -밑의 섹션들을 통해 이벤트 루프와 워커 풀에서 어떻게 공정한 스케줄링을 보장할 수 있는지 알아보겠습니다. - -## 이벤트 루프를 막지마세요 - -이벤트 루프는 새로운 클라이언트 연결을 모니터링하고 응답 생성을 조율합니다. -모든 들어오는 요청들과 나가는 응답들은 이벤트 루프를 거치게 됩니다. -만약 이벤트 루프가 특정 지점에서 지나치게 오래 있게 된다면 다른 모든 대기 중인 클라이언트와 들어오게 될 클라이언트가 순서를 보장받지 못할 수 있음을 의미합니다. - -당신은 이벤트 루프가 막히지 않는 것을 확실히 하는 것이 좋습니다. -다른 말로 하면, 당신의 자바스크립트 콜백은 빠른 시간 내에 완료되어야 합니다. -이는 `await`나 `Promise.then` 등에서도 통용됩니다. - -이벤트 루프가 막히지 않는 것을 보장하는 좋은 방법은 콜백의 ["시간 복잡도"](https://en.wikipedia.org/wiki/Time_complexity)를 유추해보는 것입니다. -만약 콜백이 인자를 얼마나 받는 것과 상관없이 상수의 시간이 소요된다면, 모든 대기 중인 클라이언트에게 공정하게 시간이 주어질 것입니다. -인자에 따라 다른 시간이 콜백에서 소요된다면 그것이 얼마나 길어질지 생각해보는 것이 좋습니다. - -예시 1: 상수 시간의 콜백. - -```javascript -app.get('/constant-time', (req, res) => { - res.sendStatus(200); -}); -``` - -예시 2: `O(n)` 콜백. `n`이 작다면 빠르게 동작하고 `n`이 커질수록 느리게 동작할 것입니다. - -```javascript -app.get('/countToN', (req, res) => { - let n = req.query.n; - - // 다른 클라이언트에게 순서가 주어지기 전에 n번 반복 - for (let i = 0; i < n; i++) { - console.log(`Iter ${i}`); - } - - res.sendStatus(200); -}); -``` - -예시 3: `O(n^2)` 콜백. `n`이 작다면 여전히 빠르게 동작하겠지만 `n`이 커질수록 앞의 `O(n)` 예시보다 훨씬 매우 느리게 동작할 것입니다. - -```javascript -app.get('/countToN2', (req, res) => { - let n = req.query.n; - - // 다른 클라이언트에게 순서가 주어지기 전에 n^2번 반복 - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - console.log(`Iter ${i}.${j}`); - } - } - - res.sendStatus(200); -}); -``` - -### 어느 정도로 조심해야 할까요? - -Node.js는 자바스크립트를 위해 구글의 V8 엔진을 사용하는데 이는 대부분의 연산에서 매우 빠르게 동작합니다. -(정규 표현식과 JSON 연산에서는 예외인데 이에 대해서는 밑에서 다루도록 하겠습니다.) - -그러나 복잡한 작업의 경우 인풋을 받고나서 너무 긴 인풋의 경우 거절하는 것을 고려하는 것이 좋습니다. -이렇게 한다면 아무리 콜백이 큰 복잡도를 가진다고 하더라도 당신이 설정한 최악의 시간 복잡도 이상은 받지 않는다는 것을 보장할 수 있습니다. -해당 콜백의 최악의 경우의 비용을 평가하고 그것이 당신의 기준에 들어오는지 계산할 수 있게 됩니다. - -### 이벤트 루프 블로킹: [REDOS](https://en.wikipedia.org/wiki/ReDoS) - -이벤트 루프를 심각할 정도로 피해를 입히는 가장 흔한 방법은 "취약한" [정규 표현식](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)을 이용하는 것입니다. - -#### 취약한 정규 표현식을 피할 것 - -정규 표현식은 인풋의 문자열에서 해당하는 패턴을 찾습니다. -우리는 보통 한 번의 문자열 인풋은 `O(n)` (n은 문자열의 길이)의 시간이 한 번만 발생될 것이라 생각합니다. -대부분의 경우는 정말 한 번만 발생하지만 어떤 정규 표현식 요청은 지수적인 증가 `O(2^n)`로 이어질 수 있습니다. -지수적으로 증가한다는 것은 `x`번만으로 끝날 수 있는 요청이 인풋 문자열에 단 하나의 문자를 더하는 것만으로 `2*x`의 요청으로 늘어날 수 있음을 의미합니다. -요청의 숫자는 소요되는 시간과 선형적인 관계가 있으므로 이는 이벤트 루프를 막는 결과로 이어질 것입니다. - -*취약한 정규 표현식*은 "악의적인 인풋"에 의해 지수 시간을 소요하게 되어 [REDOS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)로 이어지게 할 수 있습니다. -당신의 정규 표현식이 취약한지(지수 시간이 소요될 수 있는지)에 대한 답을 하는 것은 쉽지 않으며 어떤 언어(Perl, Python, Ruby, Java, JavaScript 등)를 사용하는지에 따라 달라집니다. 그렇지만 어떤 언어에서든 적용할 수 있는 몇 개의 경험칙이 있습니다. - -1. `(a+)*`와 같은 중첩된 한정자를 사용하는 것을 피하십시오. V8의 정규 표현식 엔진은 이들 중 몇 개는 빠르게 처리할 수 있으나 대부분에 취약합니다. -2. `(a|a)*`와 같이 공통 부분을 가지는 절간에 OR하는 것을 피하십시오. 1번에서처럼 어떤 경우에 한해 빠를 수 있습니다. -3. `(a.*) \1`처럼 역참조하는 것을 피하십시오. 정규 표현식 엔진이 이것을 선형 시간 내에 완료할 수 있을지 장담할 수 없습니다. -4. 만약 간단한 문자열간에 비교를 한다면 `indexOf`나 local equivalent를 사용하십시오. 더 저렴하며 어떤 경우에도 `O(n)`의 시간을 초과하지 않을 것입니다. - -당신의 정규 표현식이 취약한지 아닌지 확신할 수 없다면 Node.js는 일반적으로 취약한 정규 표현식이나 긴 문자열 인풋의 경우에도 문제 보고를 하지 않는다는 것을 기억하세요. -지수적으로 증가하는 문제는 불일치가 발생하였을 때 시작될 수 있지만 Node.js는 인풋 문자열에 대한 충분한 시도를 하기 전에 확신할 수 없습니다. - -#### REDOS 예시 - -취약한 정규 표현식이 서버에 어떻게 REDOS를 하는지에 대한 예시가 있습니다. - -```javascript -app.get('/redos-me', (req, res) => { - let filePath = req.query.filePath; - - // REDOS - if (filePath.match(/(\/.+)+$/)) { - console.log('valid path'); - } - else { - console.log('invalid path'); - } - - res.sendStatus(200); -}); -``` - -위의 취약한 정규 표현식 예시는 리눅스에서 유효한 경로인지 체크하는 (좋지않은) 방법입니다. -이는 "/a/b/c"와 같이 "/"로 시작하는 모든 문자열에 대해 패턴을 체크하게 되는데 이는 규칙 1(중첩된 한정자를 피하십시오.)을 위반하였으므로 위험합니다. - -만약 클라이언트가 파일경로 `///.../\n` (100개의 /와 \n으로 끝나 정규 표현식의 "."에 매치되지 않게 됨)를 요청하게 되면 이벤트 루프에서는 무한 루프에 빠지게 되면서 막히게 됩니다. -이러한 클라이언트의 REDOS 공격은 대기 중인 모든 클라이언트가 정규 표현식 처리가 끝날 때까지 기다리게 합니다. - -이러한 이유로, 유저의 인풋을 유효성 검사할때 복잡한 정규 표현식을 조심히 사용하는 것이 좋습니다. - -#### REDOS를 방어하는 방법 - -다음과 같은 당신의 정규 표현식이 안전한지 검사해주는 도구들이 있습니다. - -- [safe-regex](https://github.com/davisjam/safe-regex) -- [rxxr2](https://github.com/superhuman/rxxr2). - 하지만 이러한 도구가 모든 취약한 정규 표현식을 막아주는 것은 아닙니다. - -또다른 방법으로는 다른 정규 표현식 엔진을 사용하는 것이 있습니다. -구글의 겁나 빠른 [RE2](https://github.com/google/re2) 정규 표현식 엔진을 사용하는 [node-re2](https://github.com/uhop/node-re2)모듈을 사용할 수 있습니다. -그러나 조심하시길. RE2는 V8 정규 표현식과 100% 호환되는 것이 아니므로 node-re2 모듈로 변경하게 된다면 회귀 검사를 해야합니다. -특별하게 복잡한 정규 표현식들은 node-re2에 의해 지원되지 않습니다. - -만약 당신이 "명백한" 것들(URL이나 파일의 경로같은)에 정규 표현식을 사용하려 한다면 [regexp library](http://www.regexlib.com)에서 예시를 찾아서 사용하거나 [ip-regex](https://www.npmjs.com/package/ip-regex)같은 npm 모듈을 사용하십시오. - -### 이벤트 루프 블로킹: Node.js 코어 모듈 - -다음과 같은 몇 개의 Node.js 코어 모듈은 동기적으로 동작하는 값비싼 API를 가지고 있습니다. - -- [암호화](https://nodejs.org/api/crypto.html) -- [압축](https://nodejs.org/api/zlib.html) -- [파일 시스템](https://nodejs.org/api/fs.html) -- [자식 프로세스](https://nodejs.org/api/child_process.html) - -이 API들은 상당한 연산(암호화, 압축)이 필요하거나 I/O를 요구하거나(파일 I/O) 잠재적으로 둘 다 필요(자식 프로세스)할 수 있습니다. 이러한 API들은 스크립트의 편의를 위해 있는 것으로 서버 사이드에서 사용하도록 의도되지 않았기 때문입니다. 만약 당신이 이 API들을 이벤트 루프에서 실행한다면 이벤트 루프가 막히게 되면서 일반적인 자바스크립트 명령보다 훨씬 더 긴 시간을 소요할 것입니다. - -서버 사이드에서 _다음과 같은 동기적인 API를 사용하지 않는 것이 좋습니다_. - -- 암호화: - - `crypto.randomBytes` (동기적인 버전) - - `crypto.randomFillSync` - - `crypto.pbkdf2Sync` - - 이외에도 암호화 복호화 과정에 긴 인풋을 넣는 것에 대해 조심하는 것이 좋습니다. -- 압축: - - `zlib.inflateSync` - - `zlib.deflateSync` -- 파일 시스템: - - 동기적인 파일 시스템 API를 사용하지 마십시오. 예를 들어 당신이 접근하려고 하는 파일이 [NFS](https://en.wikipedia.org/wiki/Network_File_System)와 같은 [분산 파일 시스템](https://en.wikipedia.org/wiki/Clustered_file_system#Distributed_file_systems) 내에 있다면 접근 시간은 매우 편차가 클 수 있습니다. -- 자식 프로세스: - - `child_process.spawnSync` - - `child_process.execSync` - - `child_process.execFileSync` - -위 리스트는 Node.js v9에 오면서 거의 완성되었습니다. - -### 이벤트 루프 블로킹: JSON DOS - -`JSON.parse`와 `JSON.stringify`는 잠재적으로 매우 비싼 연산입니다. -인풋의 길이에 따른 `O(n)`의 시간 복잡도를 가지기에 큰 `n`에서는 놀랄 정도로 긴 시간이 소요됩니다. - -만약 서버가 JSON 객체를 다룬다면, 특히 클라이언트에서 온 객체라면, 이벤트 루프가 다루게 될 객체의 크기에 대해 염두해두어야 합니다. - -예시: JSON 블로킹. 2^21의 크기를 가지는 `obj` 객체를 생성하고 `JSON.stringify` 한 다음, 문자열의 `indexOf`를 실행하고 그것을 JSON.parse합니다. JSON.stringify된 문자열은 50MB입니다. 객체를 JSON.stringify하는데 0.7초가 소요되고 50MB의 문자열에 indexOf하는데 0.03초 소요되고 문자열을 JSON.parse하는데에 1.3초가 걸리게 됩니다. - -```javascript -var obj = { a: 1 }; -var niter = 20; - -var before, str, pos, res, took; - -for (var i = 0; i < niter; i++) { - obj = { obj1: obj, obj2: obj }; // Doubles in size each iter -} - -before = process.hrtime(); -str = JSON.stringify(obj); -took = process.hrtime(before); -console.log('JSON.stringify took ' + took); - -before = process.hrtime(); -pos = str.indexOf('nomatch'); -took = process.hrtime(before); -console.log('Pure indexof took ' + took); - -before = process.hrtime(); -res = JSON.parse(str); -took = process.hrtime(before); -console.log('JSON.parse took ' + took); -``` - -npm 모듈이 제공하는 비동기적 JSON API가 있습니다. 예를 들어, - -- [JSONStream](https://www.npmjs.com/package/JSONStream), 스트림 API를 가지고 있습니다. -- [Big-Friendly JSON](https://www.npmjs.com/package/bfj), 아래에 설명된 partitioning-on-the-Event-Loop 패러다임을 이용한 비동기 버전의 표준 JSON API와 스트림 API를 가지고 있습니다. - -### 이벤트 루프를 막지 않고 복잡한 계산하는 방법 - -자바스크립트에서 이벤트 루프를 막지 않고 복잡한 계산을 하는 것을 원한다고 가정해봅시다. -당신에게는 파티셔닝과 오프로딩, 2가지 옵션이 있습니다. - -#### 파티셔닝 - -*분할*하여 계산하게 되면 분할된 모든 작업을 이벤트 루프에서 실행하지만 다른 대기 중인 이벤트에 대한 소요시간을 평균으로 맞출 수 있습니다. -자바스크립트에서는 밑의 예시 2에서처럼 현재 진행 중인 작업의 상태를 클로저에 저장하는 것은 간단합니다. - -간단하게 예를 들어 숫자 `1`에서부터 `n`까지의 평균을 계산하고 싶다고 가정해봅시다. - -예시 1: 분할되지 않았을때 평균, `O(n)` 소요 - -```javascript -for (let i = 0; i < n; i++) - sum += i; -let avg = sum / n; -console.log('avg: ' + avg); -``` - -예시 2: 분할되었을때 평균, 비동기적으로 분할된 각각의 `n`은 `O(1)` 소요 - -```javascript -function asyncAvg(n, avgCB) { - // 현재 진행 중인 계산의 합을 JS 클로저에 저장. - var sum = 0; - function help(i, cb) { - sum += i; - if (i == n) { - cb(sum); - return; - } - - // "비동기적 재귀". - // 비동기적으로 다음 연산을 스케줄링. - setImmediate(help.bind(null, i + 1, cb)); - } - - // 헬퍼 함수를 시작. avgCB를 콜하는 CB. - help(1, function (sum) { - var avg = sum / n; - avgCB(avg); - }); -} - -asyncAvg(n, function (avg) { - console.log('avg of 1-n: ' + avg); -}); -``` - -이 방법은 배열 순회나 다른 방식에도 적용할 수 있습니다. - -#### 오프로딩 - -만약 이보다 더 복잡한 계산이 필요하다면 파티셔닝은 좋은 방법이 아닐 수 있습니다. -파티셔닝은 이벤트 루프만 이용하기에 (매우 높은 확률로 당신 컴퓨터에 있는) 여러 개의 코어를 이용하는 이점을 얻을 수 없습니다. -_언제나 명심하세요. 이벤트 루프는 클라이언트의 요청을 조율하는 역할이지 직접 실행하는 역할이 아님을_. -더 복잡한 작업을 하기 위해서는 이벤트 루프의 작업을 워커 풀로 옮겨야합니다. - -#### 어떻게 오프로드하나요? - -어떤 워커 풀에 작업을 오프로드할 것인지에 대한 2가지 옵션이 있습니다. - -1. [C++ addon](https://nodejs.org/api/addons.html)을 이용하여 설치되어 있는 Node.js의 워커 풀을 이용하는 방법이 있습니다. Node의 이전 버전에서는 [NAN](https://github.com/nodejs/nan)을 이용하여 C++ addon을 빌드하고 최신 버전에서는 [N-API](https://nodejs.org/api/n-api.html)을 이용합니다. [node-webworker-threads](https://www.npmjs.com/package/webworker-threads)는 자바스크립트로만 Node.js 워커 풀에 접근할 수 있는 방법을 제공합니다. -2. Node.js의 I/O 특화 워커 풀을 이용하기 보다 당신이 직접 계산에 특화된 워커 풀을 생성하고 관리할 수 있습니다. 가장 직관적인 방법은 [자식 프로세스](https://nodejs.org/api/child_process.html)나 [클러스터](https://nodejs.org/api/cluster.html)를 이용하는 것입니다. - -모든 클라이언트마다 [자식 프로세스](https://nodejs.org/api/child_process.html)를 전부 생성하지 _않는_ 것이 좋습니다. -자식을 생성하고 관리하는 것보다 클라이언트의 요청을 더 빨리 받게 되면서 서버가 [포크 폭탄](https://en.wikipedia.org/wiki/Fork_bomb)이 되어버릴 수 있습니다. - -##### 오프로딩의 부정적인 측면 - -오프로딩 방식의 단점은 *커뮤니케이션 비용*의 형태로 오버헤드 발생이 야기될 수 있다는 점입니다. -오직 이벤트 루프만이 애플리케이션의 "네임스페이스" (자바스크립트 상태)를 볼 수 있습니다. -이벤트 루프의 네임스페이스에 있는 자바스크립트 객체를 워커로부터 조작할 수 없습니다. -대신에 이를 위해서는 공유하고자 하는 객체를 직렬화, 역직렬화 과정을 통해 공유하게 됩니다. -그 후 워커는 복사된 객체를 이용하여 연산하고 변경한 객체 (또는 "패치")를 이벤트 루프에 반환합니다. - -직렬화 문제에 대해서는 JSON DOS 섹션을 확인해주세요. - -##### 오프로딩을 위한 몇 가지 제언 - -CPU-intensive 작업과 I/O-intensive 작업은 매우 다른 특성을 가지고 있으므로 당신은 이 둘을 구분하고 싶을 것입니다. - -CPU-intensive 작업은 처리를 위한 워커가 스케줄링되었을 때만 진행되어야 하며 워커는 반드시 컴퓨터의 [logical cores](https://nodejs.org/api/os.html#os_os_cpus) 중 하나에 스케줄링되어야 합니다. -만약 4개의 논리적 코어를 가지고 있을때 5개의 워커가 있다면 이 워커들 중 하나는 작동하지 않게 됩니다. -이는 해당 워커에 대한 메모리와 스케줄링에 대한 오버헤드가 발생하면서도 어떤 결과도 얻지 못 하는 결과로 이어집니다. - -I/O-intensive 작업에는 외부 서비스 제공자(DNS, 파일 시스템 등)에게 요청하는 것과 이에 대한 응답을 기다리는 것까지 포함됩니다. -I/O-intensive 작업을 하는 워커가 응답을 기다리는 동안에 해당 워커는 아무것도 할게 없으므로 OS에 의해 스케줄링에서 제거되어버리고 다른 워커에게 해당 요청을 넘기게 됩니다. -그러므로 _I/O-intensive 작업은 관련된 스레드가 작동 중이 아니더라도 진행 중인 상태여야 합니다_. -데이터베이스나 파일 시스템과 같은 외부 서비스 제공자들은 많은 수의 대기 중인 요청을 동시에 처리하는 것에 매우 특화되어 왔습니다. -예를 들어 파일 시스템은 머지하기 위해 충돌적으로 업데이트하고 파일을 읽으려고 하는 대기 중인 큰 크기의 쓰기와 읽기 요청을 최적화된 순서로 처리할 수 있습니다. (예시 [슬라이드](http://researcher.ibm.com/researcher/files/il-AVISHAY/01-block_io-v1.3.pdf)) - -만약 단 하나의 워커 풀(예를 들어 Node.js 워커 풀)에만 의존한다면 CPU 의존적인 작업과 I/O 의존적인 작업 간의 서로 다른 특징으로 인해 애플리케이션 성능의 손해가 생길 수 있습니다. - -이러한 이유로 당신은 분리된 계산 특화 워커 풀을 유지하는 것이 좋을 수 있습니다. - -#### 오프로딩: 결론 - -임의적으로 긴 배열의 요소를 순회해야하는 것과 같은 간단한 작업을 하는 경우에는 파티셔닝이 좋은 옵션이 될 수 있습니다. -계산이 이보다 더 복잡해진다면 오프로딩이 더 좋은 전략입니다. 이벤트 루프와 워커 풀 간에 직렬화된 객체를 주고받는 데에 발생하는 오버헤드와 같은 커뮤니케이션 비용은 다수의 코어를 사용하는 이득으로 상쇄될 수 있기 때문입니다. - -그러나 서버가 복잡한 계산에 매우 의존적이라면 Node.js를 사용하는 것 자체가 좋은 선택인지에 대해 다시 생각해보는 것이 좋을 수도 있습니다. Node.js는 I/O 의존적인 작업에 특화되어 있기에 값비싼 계산에 대해서는 최선의 선택이 아닐 수도 있습니다. - -오프로딩 전략을 선택하신다면 워커 풀을 막지마세요 섹션을 참고해주세요. - -## 워커 풀을 막지마세요 - -Node.js는 `k`개의 워커로 구성된 워커 풀을 가지고 있습니다. -만약 위에서 이야기한 오프로딩 전략을 사용 중이라면 분리된 계산 특화 워커 풀을 가지고 있을 것이고 같은 방법이 적용됩니다. -어떤 경우든간에, `k`의 수가 동시에 처리해야 하는 클라이언트의 수보다 훨씬 적다고 가정해봅시다. -Node.js의 확장성의 핵심인 "다수의 클라이언트를 처리하는 하나의 스레드" 철학은 여기에서도 지켜집니다. - -위에서 이야기한 것처럼, 각 워커는 워커 풀 큐의 다음 작업에 도달하기 위해서는 현재 작업을 먼저 완료해야 합니다. - -이번 경우에는 클라이언트 요청을 처리해야하는 작업의 비용간에 차이가 있다고 가정합니다. -어떤 작업(짧거나 캐싱된 파일을 읽거나 적은 수의 임의의 바이트를 생성하는 경우)은 빠르게 처리될 것이고 다른 작업들(크거나 캐싱되지 않은 파일을 읽거나 더 많은 임의의 바이트를 생성하는 경우)은 더 오래 걸릴 것입니다. -목표가 *작업 소요 시간간의 편차를 최소화하는 것*이라면 *작업 파티셔닝*을 이용하여 이를 달성할 수 있습니다. - -### 작업 소요 시간간의 편차를 최소화하기 - -한 워커의 현재 작업이 다른 작업들보다 훨씬 더 비싸다면 해당 워커는 다른 대기 중인 작업을 처리할 수 없을 것입니다. -다른 말로 하면, _상대적으로 긴 작업은 해당 작업이 끝날 때까지 워커 풀의 전체 크기를 줄이게 됩니다_. -이것은 바람직하지 않은 상황인데, 어느 정도까지는 워커 풀에 워커가 더 많이 있을수록 워커 풀의 처리량(작업/초)이 증가하므로 워커 풀에 워커가 더 많다는 것은 서버 처리량(클라이언트 요청/초)의 증가로 이어집니다. -한 클라이언트의 상대적으로 비싼 작업은 워커 풀의 처리량을 감소시키게 되고 이는 서버의 처리량 감소로 이어지게 됩니다. - -이를 피하기 위해선 워커 풀에 위임하는 작업 길이간의 편차를 최소화하는 것이 좋습니다. -외부 시스템 접근에 대한 I/O 요청(DB, 파일 시스템 등)은 블랙 박스로 다뤄지는 것이 적절하므로 당신은 이러한 I/O 요청의 상대적인 비용에 대해 인지하고 있어야 하며 특별히 길 것이라고 예상되는 요청을 피할 수 있어야 합니다. - -밑에서는 작업 시간에 있어 가능한 예시 두 가지를 설명합니다. - -#### 변형된 예시: 긴 시간이 소요되는 파일 시스템 읽기 - -어떤 클라이언트 요청을 처리하기 위해 서버에서는 반드시 파일을 정해진 순서대로 읽어야 한다고 가정해봅시다. -Node.js의 [File system](https://nodejs.org/api/fs.html) API를 훑어본 후에 당신은 간단하게 하기 위해 `fs.readFile()`를 선택했다고 합시다. -그러나 `fs.readFile()`는 ([현재 기준으로](https://github.com/nodejs/node/pull/17054)) 분할되어 있지 않아 하나의 `fs.read()` 작업을 통해 전체 파일을 순회하게 됩니다. -어떤 유저의 작업에는 짧은 파일을 읽고 다른 유저에서는 긴 파일을 읽는다면 `fs.readFile()`는 작업 길이간의 확연한 차이로 이어지게 되며 이는 곧 워커 풀의 처리량 감소로 이어지게 됩니다. - -최악의 경우에는 공격자가 서버를 임의의 파일을 읽게 할 수 있습니다([경로 순회 취약점](https://www.owasp.org/index.php/Path_Traversal)). -만약 서버가 리눅스라면 공격자는 극심하게 느린 파일([`/dev/random`](http://man7.org/linux/man-pages/man4/random.4.html))을 지정할 수 있습니다. -현실적인 수준에서 `/dev/random`은 무한에 가까울 정도로 느리며 `/dev/random`을 읽게 요청된 모든 워커는 해당 작업에서 절대 빠져나올 수 없습니다. -공격자는 `k`번의 요청(각 워커당 한 번씩)만 하면 어떤 다른 클라이언트의 요청도 워커 풀이 처리하지 못 하는 상황이 됩니다. - -#### 변형된 예시: 긴 시간이 소요되는 암호화 연산 - -서버에서 암호학적으로 안전한 임의의 바이트를 [`crypto.randomBytes()`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback)를 이용하여 생성한다고 가정해봅시다. -`crypto.randomBytes()`는 분할되어 있지 않으므로 이는 하나의 `randomBytes()` 작업을 이용하여 요청하는 만큼의 바이트를 생성하게 됩니다. -어떤 유저에게는 짧은 바이트를 생성하고 다른 유저에게는 긴 바이트를 생성한다면 `crypto.randomBytes()`는 위의 예시와 같은 경우가 생기게 됩니다. - -### 작업 파티셔닝 - -작업간의 소요 시간 편차는 워커 풀의 처리량의 감소로 이어질 수 있습니다. -작업 시간 편차를 최소화하기 위해 각 작업을 비슷한 비용이 들지만 가능한 한 작게 서브작업으로 분할해야 합니다. -각 서브작업이 완료되면 그 다음 서브작업을 요청하고 맨 마지막 서브작업이 끝나면 작업이 끝났음을 알려야 합니다. - -`fs.readFile()` 예시를 계속해서 들자면 `fs.read()`(수동 파티셔닝)가 아닌 `ReadStream`(자동 파티셔닝)을 사용해야 합니다. - -CPU 의존적인 작업에서도 같은 방식이 적용됩니다. `asyncAvg` 예시가 이벤트 루프에서 적절하지 않을 수 있으나 워커 풀에서는 훌륭하게 설명합니다. - -하나의 작업을 서브작업을 분할할때 짧은 작업은 적은 수의 서브작업으로 분리되고 긴 작업은 많은 수의 서브작업으로 분리되어야 합니다. -짧은 작업에 지정된 워커는 해당 작업을 끝내고 긴 작업의 서브 작업에 도와줄 수 있으므로 이는 워커 풀의 전체 처리량 증가로 이어지게 됩니다. - -완료된 서브작업의 수는 워커 풀의 처리량을 측정하기에 좋은 메트릭이 아니라는 것을 명심하세요. -대신에 완료된 *작업*의 수를 고려하세요. - -### 작업 파티셔닝을 하지 않아도 되는 경우 - -작업 분할의 목적은 작업 시간 편차를 최소화를 위한 것임을 상기시켜 봅시다. -만약 짧은 작업과 긴 작업(배열의 전체 합 vs 배열 정렬)임을 구분할 수 있다고 할 때, 작업의 클래스에 대한 워커 풀을 생성할 수 있습니다. -짧은 작업과 긴 작업을 각기 다른 워커 풀로 라우팅시키는 것은 작업 시간 편차를 최소화하는 또 다른 방법입니다. - -이 방식의 경우, 작업 분할에 의해 발생되는 오버헤드(워커 풀 작업 생성과 워커 풀 큐를 관리하는 비용)와 워커 풀에 접근하는 비용 등을 줄일 수 있습니다. -이는 또한 작업을 파티셔닝할 때 생길 수 있는 실수를 하지 않도록 유지합니다. - -이 방식의 단점은 모든 워커 풀의 워커가 공간, 시간 오버헤드를 발생시키며 CPU 시간을 경쟁적으로 사용하게 됩니다. -CPU 의존적인 작업은 스케줄링이 되었을 때만 진행된다는 것을 기억하세요. -결과적으로 심사숙고하여 분석한 이후에 이 방식을 적용하는 것이 좋습니다. - -### 워커 풀: 결론 - -Node.js 워커 풀만 사용하든 분리된 워커 풀을 유지하든, 당신은 워커 풀의 작업 처리량을 최적화해야 합니다. - -이것을 위해서 작업 파티셔닝을 통해 작업 시간 편차의 최소화합니다. - -## npm 모듈의 위험성 - -Node.js 코어 모듈이 넓은 범주의 애플리케이션을 구성하는데에 들어가지만 많은 경우 이보다 더 많은 것을 필요로 합니다. Node.js 개발자들은 개발 속도를 가속화해주는 기능을 제공하는 수 십만 개의 모듈이 있는 [npm ecosystem](https://www.npmjs.com/)에서 많은 도움을 받을 것입니다. - -그러나 이러한 모듈의 대부분은 서드 파티 개발자에 의해 작성되었고 일반적으로 어떠한 보장도 되지 않은체 배포된다는 점을 기억해야 합니다. npm 모듈을 사용하는 개발자는 2가지에 대해 생각해야 하지만 이 중 후자는 많은 경우 고려되지 않습니다. - -1. API대로 잘 동작하는가? -2. API가 이벤트 루프나 워커 루프를 막을 수 있는가? - 많은 모듈은 API의 비용에 대해 말하지 않으며 이는 커뮤니티 전체의 손해로 이어집니다. - -문자열 조작같은 간단한 API의 경우 비용을 측정하는 것은 어렵지 않습니다. -그러나 대부분의 경우 해당 API가 얼마나 비용이 드는지에 대해 분명히 작성하지 않습니다. - -_당신이 값비싼 API를 호출하려고 한다면 비용을 더블 체크하세요. 해당 API의 개발자에게 비용에 대해 문서화를 요청하거나 직접 소스 코드를 분석해서 비용에 대한 문서화를 PR할 수도 있습니다_. - -API가 비동기적으로 처리된다 하더라도 그것이 워커에서 혹은 이벤트 루프의 각 분할간에 얼마나 소요될지는 알 수 없다는 것을 기억하세요. -예를 들어 위의 `asyncAvg` 예시처럼, 각 헬퍼 함수의 호출 비용의 합은 한 번이 아닌 아닌 전체의 *절반*이었습니다. -이 함수는 여전히 비동기적이지만 각 분할에 대한 비용은 `O(1)`이 아닌 `O(n)`이므로 임의의 `n`을 사용하는 것에 대해 더 조심하게 됩니다. - -## 결론 - -Node.js는 이벤트 루프와 `k` 워커 2가지 종류의 스레드를 가지고 있습니다. -이벤트 루프는 자바스크립트 콜백과 논브로킹 I/O에 대한 책임이 있으며 워커는 C++ 코드로 해당 작업을 실행하여 블로킹 I/O와 CPU-intensive 작업을 포함하는 비동기 요청을 완료합니다. -두 종류의 스레드 모두 한 번에 한 작업보다 많은 일을 하지 않습니다. -만약 콜백이나 작업이 긴 시간이 소요된다면 해당 스레드는 _막히게 됩니다_. -애플리케이션이 막히는 콜백이나 작업을 생성한다면 이는 최소한 처리량(클라이언트/초)의 감소로 이어지고 최악의 경우 완전한 서비스 거부 상태에 빠지게 될 수 있습니다. - -높은 처리량을 내면서 Dos에 대해 보다 안전한 웹 서버를 작성하기 위해서는 양호한 인풋과 악성 인풋을 구분할줄 알아야 하고 이벤트 루프나 워커가 막히지 않게 해야 합니다. diff --git a/pages/ko/docs/guides/event-loop-timers-and-nexttick.md b/pages/ko/docs/guides/event-loop-timers-and-nexttick.md deleted file mode 100644 index 0ec271d5791f5..0000000000000 --- a/pages/ko/docs/guides/event-loop-timers-and-nexttick.md +++ /dev/null @@ -1,963 +0,0 @@ ---- -title: Node.js 이벤트 루프, 타이머, `process.nextTick()` -layout: docs.hbs ---- - - - -# Node.js 이벤트 루프, 타이머, `process.nextTick()` - -## 이벤트 루프란? - -이벤트 루프는 가능하다면 언제나 시스템 커널에 작업을 떠넘겨서 Node.js가 -논 블로킹 I/O 작업을 수행하도록 해줍니다.(JavaScript가 싱글 스레드임에도 불구하고) - -대부분의 현대 커널은 멀티 스레드이므로 백그라운드에서 다수의 작업을 실행할 수 있습니다. -이러한 작업 중 하나가 완료되면 커널이 Node.js에게 알려주어 적절한 콜백을 **poll** 큐에 -추가할 수 있게 하여 결국 실행되게 합니다. 이 글 후반부에서 더 자세한 내용을 설명할 것입니다. - - - -## 이벤트 루프 설명 - -Node.js를 시작할 때 이벤트 루프를 초기화하고 제공된 입력 스크립트(또는 이 문서에서는 -다루지 않는 [REPL][]에 입력한)를 처리합니다. 이때 이 스크립트는 비동기 API를 호출하거나 -스케줄링된 타이머를 사용하거나 `process.nextTick()`를 호출할 수 있습니다. -그다음 이벤트 루프 처리를 시작합니다. - -아래 다이어그램은 이벤트 루프의 작업 순서의 간단한 개요를 보여줍니다. - -``` - ┌───────────────────────────┐ -┌─>│ timers │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ pending callbacks │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ idle, prepare │ -│ └─────────────┬─────────────┘ ┌───────────────┐ -│ ┌─────────────┴─────────────┐ │ incoming: │ -│ │ poll │<─────┤ connections, │ -│ └─────────────┬─────────────┘ │ data, etc. │ -│ ┌─────────────┴─────────────┐ └───────────────┘ -│ │ check │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -└──┤ close callbacks │ - └───────────────────────────┘ -``` - -_note: 각 박스는 이벤트 루프의 "단계"를 의미합니다._ - - - -각 단계는 실행할 콜백의 FIFO 큐를 가집니다. 각 단계는 자신만의 방법에 제한적이므로 -보통 이벤트 루프가 해당 단계에 진입하면 해당 단계에 한정된 작업을 수행하고 큐를 모두 -소진하거나 콜백의 최대 개수를 실행할 때까지 해당 단계의 큐에서 콜백을 실행합니다. -큐를 모두 소진하거나 콜백 제한에 이르면 이벤트 루프는 다음 단계로 이동합니다. - -이러한 작업이 _또 다른_ 작업을 스케줄링하거나 **poll** 단계에서 처리된 새로운 이벤트가 -커널에 의해 큐에 추가될 수 있으므로 폴링 이벤트를 처리하면서 poll 이벤트를 큐에 추가할 수 있습니다. -그 결과 오래 실행되는 콜백은 poll 단계가 타이머의 한계 시점보다 훨씬 더 오래 -실행되도록 할 수 있습니다. 자세한 내용은 [**timers**](#timers)와 -[**poll**](#poll)을 참고하세요. - -_**NOTE:** 윈도우와 Unix/Linux 구현체간에 약간의 차이가 있지만 여기서는 중요치 -않습니다. 실제 7~8단계가 있지만 Node.js가 실제로 사용해서 신경 써야 하는 -가장 중요한 단계는 위의 단계입니다._ - - - -## 단계 개요 - -- **timers**: 이 단계는 `setTimeout()`과 `setInterval()`로 스케줄링한 - 콜백을 실행합니다. -- **pending callbacks**: 다음 루프 반복으로 연기된 I/O 콜백들을 실행합니다. -- **idle, prepare**: 내부용으로만 사용합니다. -- **poll**: 새로운 I/O 이벤트를 가져옵니다. I/O와 연관된 콜백(클로즈 콜백, 타이머로 스케줄링된 콜백, - `setImmediate()`를 제외한 거의 모든 콜백)을 실행합니다. 적절한 시기에 node는 여기서 블록 합니다. -- **check**: `setImmediate()` 콜백은 여기서 호출됩니다. -- **close callbacks**: 일부 close 콜백들, 예를 들어 `socket.on('close', ...)`. - -이벤트 루프가 실행하는 사이 Node.js는 다른 비동기 I/O나 타이머를 기다리고 있는지 -확인하고 기다리고 있는 것이 없다면 깔끔하게 종료합니다. - - - -## 각 단계의 자세한 설명 - -### timers - -타이머는 사람이 _실행하기를 원하는_ **정확한** 시간이 아니라 제공된 콜백이 -_일정 시간 후에 실행되어야 하는_ **기준시간**을 지정합니다. 타이머 콜백은 지정한 -시간이 지난 후에 스케줄링 될 수 있는 가장 이른 시간에 실행될 것입니다. 하지만 -운영체제 스케줄링이나 다른 콜백 실행 때문에 지연될 수 있습니다. - -_**Note**: 기술적으로는 [**poll** 단계](#poll)에서 타이머를 언제 실행할지 제어합니다._ - -예를 들어, 100ms 임계 값 이후에 실행되도록 만료시간을 지정하면 스크립트는 -95ms가 걸리는 파일 읽기를 비동기로 시작합니다. - - - -```js -const fs = require('fs'); - -function someAsyncOperation(callback) { - // 이 작업이 완료되는데 95ms가 걸린다고 가정합니다. - fs.readFile('/path/to/file', callback); -} - -const timeoutScheduled = Date.now(); - -setTimeout(() => { - const delay = Date.now() - timeoutScheduled; - - console.log(`${delay}ms have passed since I was scheduled`); -}, 100); - -// 완료하는데 95ms가 걸리는 someAsyncOperation를 실행합니다. -someAsyncOperation(() => { - const startCallback = Date.now(); - - // 10ms가 걸릴 어떤 작업을 합니다. - while (Date.now() - startCallback < 10) { - // 아무것도 하지 않습니다. - } -}); -``` - -이벤트 루프가 **poll** 단계에 진입했을 때 빈 큐를 가지고 있으므로(`fs.readFile()`이 -아직 완료되지 않았습니다.) 가장 빠른 타이머의 임계 값에 도달할 때까지 수 밀리 초 기다릴 -것입니다. 95ms가 지나기를 기다리는 동안 `fs.readFile()`이 파일 읽기를 끝마치고 완료하는데 -10ms가 걸리는 콜백이 **poll** 큐에 추가되어 실행됩니다. 콜백이 완료되었을 때 큐에 있는 -콜백이 없으므로 이벤트 루프는 가장 빠른 타이머의 임계 값에 도달했는지를 확인하고 타이머의 -콜백을 실행하려고 **timers** 단계에 되돌아갑니다. 이 예제에서 타이머가 스케줄링되고 -콜백이 실행되기까지의 전체 지연시간이 105ms가 되는 것을 볼 수 있습니다. - -Note: **poll** 단계가 이벤트 루프를 모두 차지하지 않게 하기 위해 [libuv][](Node.js -이벤트 루프와 플랫폼의 모든 비동기 동작을 구현한 C 라이브러리)도 더 많은 이벤트를 폴링하기를 -멈추는 하는 하드 최댓값(시스템에 따라 다릅니다.)도 가집니다. - - - -### pending 콜백 - -이 단계에서는 TCP 오류 같은 시스템 작업의 콜백을 실행합니다. 예를 들어 TCP 소켓이 -연결을 시도하다가 `ECONNREFUSED`를 받으면 일부 \*nix 시스템은 오류를 보고하기를 -기다리려고 합니다. 이는 **pending callbacks** 단계에서 실행되기 위해 큐에 추가될 것입니다. - - - -### poll - -**poll** 단계는 두 가지 주요 기능을 가집니다. - -1. I/O를 얼마나 오래 블록하고 폴링해야 하는지 계산합니다. 그 다음 -2. **poll** 큐에 있는 이벤트를 처리합니다. - -이벤트 루프가 **poll** 단계에 진입하고 _스케줄링된 타이머가 없을 때_ -두 가지 중 하나의 상황이 발생합니다. - -- _**poll** 큐가 **비어있지 않다면**_ 이벤트 루프가 콜백의 큐를 순회하면서 - 큐를 다 소진하거나 시스템 의존적인 하드 한계에 도달할 때까지 동기로 콜백을 실행합니다. - - - -- _**poll** 큐가 **비어있다면**_ 다음 중 하나의 상황이 발생합니다. - - - 스크립트가 `setImmediate()`로 스케줄링되었다면 이벤트 루프는 **poll** 단계를 - 종료하고 스케줄링된 스크립트를 실행하기 위해 **check** 단계로 넘어갑니다. - - - 스크립트가 `setImmediate()`로 스케줄링되지 않았다면 이벤트 루프는 콜백이 큐에 - 추가되기를 기다린 후 즉시 실행합니다. - -**poll** 큐가 일단 비게 되면 타이머가 _시간 임계점에 도달했는지_ 확인할 것입니다. -하나 이상의 타이머가 준비되었다면 이벤트 루프는 타이머의 콜백을 실행하기 위해 -**timers** 단계로 돌아갈 것입니다. - - - -### check - -이 단계는 **poll** 단계가 완료된 직후 사람이 콜백을 실행할 수 있게 합니다. **poll** -단계가 유휴상태가 되고 스크립트가 `setImmediate()`로 큐에 추가되었다면 이벤트 루프를 -기다리지 않고 **check** 단계를 계속할 것입니다. - -`setImmediate()`는 사실 이벤트 루프의 별도 단계에서 실행되는 특수한 타이머입니다. -`setImmediate()`는 **poll** 단계가 완료된 후 콜백 실행을 스케줄링하는데 -libuv API를 사용합니다. - -보통 코드가 실행되었으므로 이벤트 루프는 들어오는 연결, 요청 등을 기다리는 -**poll** 단계에 결국 다다르게 됩니다. 하지만 콜백이 `setImmediate()`로 -스케줄링되었고 **poll** 단계가 유휴상태가 되었다면 **poll** 이벤트를 기다리지 않고 -**check** 단계로 넘어가게 됩니다. - - - -### close 콜백 - -소켓이나 핸들이 갑자기 닫힌 경우(예: `socket.destroy()`) 이 단계에서 -`'close'` 이벤트가 발생할 것입니다. 그렇지 않으면 `process.nextTick()`으로 -실행될 것입니다. - - - -## `setImmediate()` 대 `setTimeout()` - -`setImmediate()`와 `setTimeout()`은 비슷하지만 호출된 시기에 따라 다르게 동작합니다. - -- `setImmediate()`는 현재 **poll** 단계가 완료되면 스크립트를 실행하도록 설계되었습니다. -- `setTimeout()`는 최소 임계 값(ms)이 지난 후 스크립트가 실행되도록 스케줄링합니다. - -타이머가 실행되는 순서는 어떤 컨텍스트에서 호출되었는지에 따라 다양합니다. 둘 다 메인 모듈 -내에서 호출된다면 프로세서의 성능에 따라 달라집니다.(머신에서 실행되는 다른 애플리케이션의 -영향을 받을 수 있습니다.) - -예를 들어 I/O 주기 내에 있지 않은 컨텍스트(예: 메인 모듈)에서 다음 스크립트를 실행한다면 -두 타이머의 순서는 프로세스 성능에 영향을 받으므로 결정적이지 않습니다. - - - -```js -// timeout_vs_immediate.js -setTimeout(() => { - console.log('timeout'); -}, 0); - -setImmediate(() => { - console.log('immediate'); -}); -``` - -``` -$ node timeout_vs_immediate.js -timeout -immediate - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -하지만 I/O 주기 안에서 둘을 호출한다면 immediate 콜백이 항상 먼저 실행됩니다. - -```js -// timeout_vs_immediate.js -const fs = require('fs'); - -fs.readFile(__filename, () => { - setTimeout(() => { - console.log('timeout'); - }, 0); - setImmediate(() => { - console.log('immediate'); - }); -}); -``` - -``` -$ node timeout_vs_immediate.js -immediate -timeout - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -`setTimeout()`보다 `setImmediate()`를 사용할 때 가장 큰 장점은 -`setImmediate()`가 얼마나 많은 타이머가 존재하냐에 상관없이 I/O 주기 내에서 -스케줄된 어떤 타이머보다 항상 먼저 실행된다는 것입니다. - - - -## `process.nextTick()` - -### `process.nextTick()` 이해하기 - -`process.nextTick()`이 비동기 API에 속해있지만, 다이어그램에는 표시되지 않은 것을 -눈치챘을 겁니다. 이는 `process.nextTick()`이 기술적으로는 이벤트 루프의 일부가 -아니기 때문입니다. 대신 `nextTickQueue`는 이벤트 루프의 현재 단계와 관계없이 -현재 작업이 완료된 후에 처리될 것입니다. 여기에서 *작업*이란 기저의 C/C++ -핸들러에서 전환하는 것, 또 실행되어야 하는 JavaScript를 처리하는 것을 말합니다. - -다이어그램을 다시 보겠습니다. 해당 단계에서 `process.nextTick()`을 호출하면 -`process.nextTick()`에 전달한 모든 콜백은 언제나 이벤트 루프를 계속 진행하기 -전에 처리될 것입니다. 이 동작 때문에 재귀로 `process.nextTick()`을 호출하면 -이벤트 루프가 **poll** 단계에 다다르는 것을 막아서 **I/O가 "굶주리게" 될 수 있으므로** -좋지 않은 상황을 만들 수 있습니다. - - - -### 왜 이러한 동작을 허용하나요? - -왜 이러한 기능이 Node.js에 포함되었는가? 이는 API는 그럴 필요가 없더라도 항상 비동기여야 한다는 -설계 철학 때문입니다. 예제로 다음 코드를 보겠습니다. - -```js -function apiCall(arg, callback) { - if (typeof arg !== 'string') - return process.nextTick( - callback, - new TypeError('argument should be string') - ); -} -``` - - - -위 코드는 인자를 확인한 뒤 제대로 된 인자가 아니면 콜백에 오류를 전달합니다. 최근에 갱신된 API에서는 -`process.nextTick()`에 인자를 전달할 수 있게 되어서 콜백뒤에 전달한 인자는 콜백에 대한 인자로 -전파되기 때문에 중첩된 함수를 작성할 필요가 없습니다. - -여기서는 사용자에게 오류를 다시 전달하고 있지만 _그 후에_ 사용자의 남은 코드를 실행할 수 있습니다. -`process.nextTick()`을 사용하면 사용자 코드의 나머지 부분 _이후_, 이벤트 루프가 진행되기 -*이전*에 항상 `apiCall()`이 콜백을 실행할 수 있게 보장합니다. 이를 위해 JS 호출 스택을 풀고 -바로 제공된 콜백을 실행하면서 개발자가 -`RangeError: Maximum call stack size exceeded from v8`에 도달하지 않으면서 -`process.nextTick()`을 재귀호출할 수 있게 합니다. - - - -이 철학은 잠재적인 문제 상황을 만들 수 있습니다. 다음 예제를 보겠습니다. - -```js -let bar; - -// 비동기 시그니처를 갖지만, 동기로 콜백을 호출합니다. -function someAsyncApiCall(callback) { - callback(); -} - -// `someAsyncApiCall`이 완료되면 콜백을 호출한다. -someAsyncApiCall(() => { - // someAsyncApiCall는 완료되었지만, bar에는 어떤 값도 할당되지 않았다. - console.log('bar', bar); // undefined -}); - -bar = 1; -``` - -개발자가 `someAsyncApiCall()`을 비동기 시그니처로 정의했지만 실제로는 동기로 동작합니다. -이 함수가 호출되었을 때 `someAsyncApiCall()`가 실제로 비동기로 아무것도 하지 않으므로 -`someAsyncApiCall()`에 전달된 콜백은 이벤트 루프의 같은 단계에서 호출됩니다. 그 결과 -이 스크립트는 완료까지 실행되지 않았으므로 이 범위에서는 `bar` 변수가 없을 수 있음에도 콜백이 -`bar`를 참조하려고 시도합니다. - -`process.nextTick()`에 콜백을 두면 모든 변수, 함수 등이 호출되는 콜백보다 먼저 초기화하면서 -스크립트를 완료까지 실행할 수 있습니다. 이는 이벤트 루프가 계속 진행되지 않도록 하는 장점도 있습니다. -이벤트 루프가 계속 진행되기 전에 사용자에게 오류 알림을 주는 것이 유용할 수 있습니다. -다음은 앞의 예제를 `process.nextTick()`으로 바꾼 것입니다. - - - -```js -let bar; - -function someAsyncApiCall(callback) { - process.nextTick(callback); -} - -someAsyncApiCall(() => { - console.log('bar', bar); // 1 -}); - -bar = 1; -``` - -다음은 또 다른 예제입니다. - -```js -const server = net.createServer(() => {}).listen(8080); - -server.on('listening', () => {}); -``` - -포트만 전달하면 포트가 바로 바인딩 됩니다. 그래서 `'listening'` 콜백이 바로 호출될 수 있습니다. -문제는 `.on('listening')` 콜백이 이때 설정되지 않는다는 것입니다. - -이를 피하려면 `'listening'` 이벤트를 `nextTick()`으로 큐에 넣어서 스크립트가 완료될 때까지 -실행되도록 할 수 있습니다. 이를 통해 어떤 이벤트 핸들러라도 설정하도록 할 수 있습니다. - - - -## `process.nextTick()` 대 `setImmediate()` - -개발자가 관심 가질 두 가지 유사한 호출이 있지만 이름은 혼란스럽습니다. - -- `process.nextTick()`은 같은 단계에서 바로 실행됩니다. -- `setImmediate()`는 이어진 순회나 이벤트 루프의 'tick'에서 실행됩니다. - -사실 이름은 서로 바뀌어야 합니다. `process.nextTick()`이 `setImmediate()`보다 더 즉시 -실행되지만, 이는 바뀔 가능성이 없는 과거의 유산입니다. 이 둘을 바꾼다면 수많은 npm 패키지가 깨질 -것입니다. 매일같이 새로운 모듈이 추가되고 있으므로 잠재적인 손상은 더 많이 발생할 것입니다. -이 둘은 혼란스럽지만 이름이 바뀌진 않을 것입니다. - -_`setImmediate()`가 예상하기 더 쉬우므로 모든 경우에 `setImmediate()`를 사용하기를 -권장합니다._ - - - -## 왜 `process.nextTick()`을 사용하는가? - -두 가지 이유가 있습니다. - -1. 사용자가 이벤트 루프를 계속하기 전에 오류를 처리하고 불필요한 자원을 정리하고 요청을 - 다시 시도할 수 있게 합니다. - -2. 호출 스택은 풀린 뒤에도 이벤트 루프를 계속 진행하기 전에 콜백을 실행해야 하는 경우가 있습니다. - -한 가지 예는 사용자의 기대를 맞추는 것입니다. 다음은 간단한 예제입니다. - -```js -const server = net.createServer(); -server.on('connection', conn => {}); - -server.listen(8080); -server.on('listening', () => {}); -``` - - - -`listen()`이 이벤트 루프 시작 부분에서 실행되었지만, listening 콜백은 `setImmediate()`에 -있습니다. 바인딩할 호스트네임을 전달하지 않는 한 포트는 즉시 적용될 것입니다. 이벤트 루프를 -진행하려면 **poll** 단계에 도달해야 하는데, 이 말은 listening 이벤트 전에 connection 이벤트가 -발생하도록 해서 연결을 받을 가능성이 있다는 것입니다. - -또 다른 예제는 `EventEmitter`를 상속받고 생성자 내에서 이벤트를 호출하고자 하는 -함수 생성자를 실행하는 것입니다. - -```js -const EventEmitter = require('events'); -const util = require('util'); - -function MyEmitter() { - EventEmitter.call(this); - this.emit('event'); -} -util.inherits(MyEmitter, EventEmitter); - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('an event occurred!'); -}); -``` - - - -사용자가 콜백을 이벤트에 할당한 시점에 스크립트가 실행되는 것이 아니므로 생성자에서 발생시킨 이벤트는 -즉시 실행되지 않습니다. 그러므로 기대하는 결과대로 생성자 안에서 생성자가 완료된 후 이벤트를 발생시키는 -콜백을 설정하려고 `process.nextTick()`을 사용할 수 있습니다. - -```js -const EventEmitter = require('events'); -const util = require('util'); - -function MyEmitter() { - EventEmitter.call(this); - - // 핸들러가 할당되면 이벤트를 발생시키려고 nextTick을 사용합니다. - process.nextTick(() => { - this.emit('event'); - }); -} -util.inherits(MyEmitter, EventEmitter); - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('an event occurred!'); -}); -``` - -[libuv]: https://libuv.org/ -[REPL]: https://nodejs.org/api/repl.html#repl_repl diff --git a/pages/ko/docs/guides/getting-started-guide.md b/pages/ko/docs/guides/getting-started-guide.md deleted file mode 100644 index 6e37d9386c5ca..0000000000000 --- a/pages/ko/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: 시작 가이드 -layout: docs.hbs ---- - - - -# Node.js를 설치한 후 어떻게 시작할 수 있을까요? - -Node를 설치했으면 우리의 첫 번째 웹 사이트를 구축해 봅시다. -"app.js"라는 이름의 파일을 만든 후 아래의 코드를 붙여넣으세요. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - - - -그런 다음 `node app.js`를 사용하여 웹 사이트를 실행한 후 `http://localhost:3000`을 방문하면 'Hello World'라는 메시지를 볼 수 있을 것입니다. diff --git a/pages/ko/docs/guides/index.md b/pages/ko/docs/guides/index.md deleted file mode 100644 index 7d0cc09bcc41b..0000000000000 --- a/pages/ko/docs/guides/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: 가이드 -layout: docs.hbs ---- - -# 가이드 - -## General - -- [시작 가이드](/ko/docs/guides/getting-started-guide/) -- [디버깅 - 시작하기](/ko/docs/guides/debugging-getting-started/) -- [Node.js 애플리케이션의 간단한 프로파일링](/ko/docs/guides/simple-profiling/) -- [Diagnostics - Flame Graphs](/ko/docs/guides/diagnostics-flamegraph/) -- [Node.js 웹 앱의 도커라이징](/ko/docs/guides/nodejs-docker-webapp/) -- [Migrating to safe Buffer constructors](/ko/docs/guides/buffer-constructor-deprecation/) - -## Node.js core concepts - -- [블록킹과 논블록킹 살펴보기](/ko/docs/guides/blocking-vs-non-blocking/) -- [Node.js 이벤트 루프, 타이머, `process.nextTick()`](/ko/docs/guides/event-loop-timers-and-nexttick/) -- [Don't Block the Event Loop (or the Worker Pool)](/ko/docs/guides/dont-block-the-event-loop/) -- [Node.js의 Timers](/ko/docs/guides/timers-in-node/) - -## Module related guides - -- [HTTP 트랜잭션 해부](/ko/docs/guides/anatomy-of-an-http-transaction/) -- [여러 파일 시스템에서 작업하기](/ko/docs/guides/working-with-different-filesystems/) -- [Backpressuring in Streams](/ko/docs/guides/backpressuring-in-streams/) -- [도메인 모듈 포스트모템](/ko/docs/guides/domain-postmortem/) -- [How to publish N-API package](/ko/docs/guides/publishing-napi-modules/) -- [ABI Stability](/ko/docs/guides/abi-stability/) diff --git a/pages/ko/docs/guides/nodejs-docker-webapp.md b/pages/ko/docs/guides/nodejs-docker-webapp.md deleted file mode 100644 index 9bd6096f711cc..0000000000000 --- a/pages/ko/docs/guides/nodejs-docker-webapp.md +++ /dev/null @@ -1,558 +0,0 @@ ---- -title: Node.js 웹 앱의 도커라이징 -layout: docs.hbs ---- - - - -# Node.js 웹 앱의 도커라이징 - -이 예제에서는 Node.js 애플리케이션을 Docker 컨테이너에 넣는 방법을 보여줍니다. 이 가이드는 -개발 목적이지 프로덕션 배포용이 _아닙니다_. -[Docker가 설치](https://docs.docker.com/engine/installation/)되어 있고 -Node.js 애플리케이션의 구조에 대한 기본적인 지식이 있어야 합니다. - -먼저 간단한 Node.js 웹 애플리케이션을 만든 후에 이 애플리케이션을 위한 Docker 이미지를 -만들어서 컨테이너로 실행할 것입니다. - -Docker를 사용하면 애플리케이션과 모든 의존성을 소프트웨어 개발에서 컨테이너라고 부르는 표준화된 -단위로 패키징할 수 있습니다. 컨테이너는 리눅스 운영체제의 간단 버전입니다. -이미지는 컨테이너에 로드하는 소프트웨어를 말합니다. - - - -## Node.js 앱 생성 - -우선, 모든 파일을 넣은 새로운 디렉터리를 만들겠습니다. 이 디렉터리 안에 애플리케이션과 의존성을 -알려주는 `package.json` 파일을 생성하겠습니다. - -```json -{ - "name": "docker_web_app", - "version": "1.0.0", - "description": "Node.js on Docker", - "author": "First Last ", - "main": "server.js", - "scripts": { - "start": "node server.js" - }, - "dependencies": { - "express": "^4.16.1" - } -} -``` - - - -`package.json` 파일을 만든 후, `npm install`을 실행하세요. 버전 5 이상의 `npm`을 -사용한다면, Docker 이미지에 복사할 `package-lock.json` 파일을 `npm`에서 생성할 것입니다. - -이제 [Express.js](https://expressjs.com/) 프레임워크로 웹앱을 정의하는 `server.js`를 만들겠습니다. - -```javascript -'use strict'; - -const express = require('express'); - -// 상수 -const PORT = 8080; -const HOST = '0.0.0.0'; - -// 앱 -const app = express(); -app.get('/', (req, res) => { - res.send('Hello World'); -}); - -app.listen(PORT, HOST, () => { - console.log(`Running on http://${HOST}:${PORT}`); -}); -``` - -다음 단계에서 공식 Docker 이미지를 사용해서 Docker 컨테이너 안에서 이 앱을 실행하는 방법을 -살펴보겠습니다. 먼저 앱의 Docker 이미지를 만들어야 합니다. - - - -## Dockerfile 생성 - -`Dockerfile`이라는 빈 파일을 생성합니다. - -```markup -touch Dockerfile -``` - -선호하는 텍스트 에디터로 `Dockerfile`을 엽니다. - -가장 먼저 해야 할 것은 어떤 이미지를 사용해서 빌드할 것인지를 정의하는 것입니다. 여기서는 -[Docker Hub](https://hub.docker.com/)에 있는 -`node`의 최신 LTS(장기 지원) 버전인 `16`을 사용할 것입니다. - -```docker -FROM node:16 -``` - - - -다음으로 이미지 안에 애플리케이션 코드를 넣기 위해 디렉터리를 생성할 것입니다. -이 디렉터리가 애플리케이션의 작업 디렉터리가 됩니다. - -```docker -# 앱 디렉터리 생성 -WORKDIR /usr/src/app -``` - -이 이미지에는 이미 Node.js와 NPM이 설치되어 있으므로 `npm` 바이너리로 -앱의 의존성을 설치하기만 하면 됩니다. 버전 4 이하의 `npm`은 `package-lock.json` -파일을 생성하지 _않을_ 것입니다. - -```docker -# 앱 의존성 설치 -# 가능한 경우(npm@5+) package.json과 package-lock.json을 모두 복사하기 위해 -# 와일드카드를 사용 -COPY package*.json ./ - -RUN npm install -# 프로덕션을 위한 코드를 빌드하는 경우 -# RUN npm ci --omit=dev -``` - - - -작업 디렉터리 전체가 아닌 `package.json` 파일만을 복사하고 있는데, 이는 캐시된 -Docker 레이어의 장점을 활용하기 위함입니다. bitJudo가 이에 대해 -[여기](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/)에 -잘 설명해 두었습니다. 추가로, 주석에 언급된 `npm ci` 커맨드는 프로덕션 환경을 -위한 더 빠르고, 신뢰할 수 있고, 재현 가능한 빌드를 제공합니다. 이에 대해 -[여기](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)에서 -자세히 알아볼 수 있습니다. - -Docker 이미지 안에 앱의 소스코드를 넣기 위해 `COPY` 지시어를 사용합니다. - -```docker -# 앱 소스 추가 -COPY . . -``` - -앱이 `8080`포트에 바인딩 되어 있으므로 `EXPOSE` 지시어를 사용해서 `docker` 데몬에 매핑합니다. - -```docker -EXPOSE 8080 -``` - - - -마지막으로 런타임을 정의하는 `CMD`로 앱을 실행하는 중요 명령어를 정의해야 합니다. -여기서는 서버를 구동하도록 `node server.js`을 실행하는 기본 `npm start`을 사용할 것입니다. - -```docker -CMD [ "node", "server.js" ] -``` - -`Dockerfile`은 다음과 같아야 합니다. - -```docker -FROM node:16 - -# 앱 디렉터리 생성 -WORKDIR /usr/src/app - -# 앱 의존성 설치 -# 가능한 경우(npm@5+) package.json과 package-lock.json을 모두 복사하기 위해 -# 와일드카드를 사용 -COPY package*.json ./ - -RUN npm install -# 프로덕션을 위한 코드를 빌드하는 경우 -# RUN npm ci --omit=dev - -# 앱 소스 추가 -COPY . . - -EXPOSE 8080 -CMD [ "node", "server.js" ] -``` - - - -## .dockerignore 파일 - -`Dockerfile`과 같은 디렉터리에 `.dockerignore` 파일을 다음 내용으로 만드세요. - -``` -node_modules -npm-debug.log -``` - -이는 Docker 이미지에 로컬 모듈과 디버깅 로그를 복사하는 것을 막아서 이미지 내에서 -설치한 모듈을 덮어쓰지 않게 합니다. - - - -## 이미지 빌드 - -작성한 `Dockerfile`이 있는 디렉터리로 가서 Docker 이미지를 빌드하는 다음 명령어를 실행하세요. -`-t` 플래그로 이미지에 태그를 추가할 수 있어 나중에 `docker images` 명령어로 -쉽게 찾을 수 있습니다. - -```bash -docker build . -t /node-web-app -``` - -Docker가 당신이 빌드한 이미지를 보여줄 것입니다. - -```bash -$ docker images - -# 예시 -REPOSITORY TAG ID CREATED -node 16 1934b0b038d1 5 days ago -/node-web-app latest d64d3505b0d2 1 minute ago -``` - - - -## 이미지 실행 - -`-d`로 이미지를 실행하면 분리 모드로 컨테이너를 실행해서 백그라운드에서 컨테이너가 돌아가도록 합니다. -`-p` 플래그는 공개 포트를 컨테이너 내의 비공개 포트로 리다이렉트합니다. 앞에서 만든 이미지를 실행하세요. - -```bash -docker run -p 49160:8080 -d /node-web-app -``` - -앱의 로그를 출력하세요. - -```bash -# 컨테이너 아이디를 확인합니다 -$ docker ps - -# 앱 로그를 출력합니다 -$ docker logs - -# 예시 -Running on http://localhost:8080 -``` - -컨테이너 안에 들어가 봐야 한다면 `exec` 명령어를 사용할 수 있습니다. - -```bash -# 컨테이너에 들어갑니다 -$ docker exec -it /bin/bash -``` - - - -## 테스트 - -앱을 테스트하려면 Docker 매핑된 앱 포트를 확인합니다. - -```bash -$ docker ps - -# 예시 -ID IMAGE COMMAND ... PORTS -ecce33b30ebf /node-web-app:latest npm start ... 49160->8080 -``` - -위 예시에서 Docker가 컨테이너 내의 `8080` 포트를 머신의 `49160` 포트로 매핑했습니다. - -이제 `curl`로 앱을 호출할 수 있습니다.(필요하다면 `sudo apt-get install curl`로 설치하세요.) - -```bash -$ curl -i localhost:49160 - -HTTP/1.1 200 OK -X-Powered-By: Express -Content-Type: text/html; charset=utf-8 -Content-Length: 12 -ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0" -Date: Mon, 13 Nov 2017 20:53:59 GMT -Connection: keep-alive - -Hello world -``` - - - -간단한 Node.js 애플리케이션을 Docker로 실행하는데 이 튜토리얼이 도움되었길 바랍니다. - -다음 링크에서 Docker와 Docker에서의 Node.js에 대한 정보를 더 자세히 볼 수 있습니다. - -- [공식 Node.js Docker 이미지](https://hub.docker.com/_/node/) -- [Node.js Docker 사용사례 문서](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md) -- [공식 Docker 문서](https://docs.docker.com/) -- [Stack Overflow에 Docker 태그로 올라온 질문](https://stackoverflow.com/questions/tagged/docker) -- [Docker 레딧](https://reddit.com/r/docker) diff --git a/pages/ko/docs/guides/simple-profiling.md b/pages/ko/docs/guides/simple-profiling.md deleted file mode 100644 index 7ba6d2d94f999..0000000000000 --- a/pages/ko/docs/guides/simple-profiling.md +++ /dev/null @@ -1,560 +0,0 @@ ---- -title: Node.js 애플리케이션의 간단한 프로파일링 -layout: docs.hbs ---- - - - -# Node.js 애플리케이션의 간단한 프로파일링 - -Node.js 애플리케이션을 프로파일링하는 서드파티 도구들이 많이 있지만, 대부분은 Node.js에 내장된 -프로파일러를 사용하는 것인 가장 쉬운 방법입니다. 내장된 프로파일러는 프로그램을 실행하는 동안 주기적으로 -스택을 샘플링하는 [V8 내의 프로파일러][]를 사용합니다. 이 샘플링 결과를 기록하면서 jit 컴파일이나 -tick 시리즈처럼 중요한 최적화 작업을 기록합니다. - -``` -code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~ -code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~ -code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~ -code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub" -code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub" -``` - - - -이전에는 tick을 해석하려면 V8 소스 코드가 필요했습니다. 다행히, 소스에서 V8 빌드를 따로 하지 않고 -이 정보를 사용할 수 있는 도구가 Node.js 4.4.0부터 도입되었습니다. 애플리케이션의 성능을 -볼 수 있는 내장된 프로파일러를 어떻게 사용하는지 살펴보겠습니다. - -tick 프로파일러의 사용방법을 설명하기 위해 간단한 Express 애플리케이션을 만들어 보겠습니다. -예제 애플리케이션은 2개의 핸들러를 가지고 있는데 하나는 새로운 사용자를 시스템에 추가할 것입니다. - - - -```javascript -app.get('/newUser', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users[username]) { - return res.sendStatus(400); - } - - const salt = crypto.randomBytes(128).toString('base64'); - const hash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - users[username] = { salt, hash }; - - res.sendStatus(200); -}); -``` - -다른 핸들러는 사용자 인증의 유효성을 검사합니다. - - - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || !users[username]) { - return res.sendStatus(400); - } - - const { salt, hash } = users[username]; - const encryptHash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - if (crypto.timingSafeEqual(hash, encryptHash)) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } -}); -``` - - - -_Node.js 애플리케이션에서 사용자 인증을 처리하는 핸들러는 추천하지 않는 방법이고 여기서는 예시를 -보여주기 위해서 사용한 것뿐입니다. 보통은 직접 만든 인증 메커니즘을 설계하지 말아야 합니다. -기존에 존재하는 입증된 인증솔루션을 사용하는 것이 훨씬 낫습니다._ - -배포한 애플리케이션에서 사용자가 요청에 지연이 발생한다고 불평한다고 가정해 보겠습니다. -내장된 프로파일러로 애플리케이션을 간단히 실행할 수 있습니다. - -``` -NODE_ENV=production node --prof app.js -``` - -`ab`(ApacheBench)로 서버에 부하를 줄 수 있습니다. - -``` -curl -X GET "http://localhost:8080/newUser?username=matt&password=password" -ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password" -``` - -다음과 같은 결과가 나올 것입니다. - - - -``` -Concurrency Level: 20 -Time taken for tests: 46.932 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 5.33 [#/sec] (mean) -Time per request: 3754.556 [ms] (mean) -Time per request: 187.728 [ms] (mean, across all concurrent requests) -Transfer rate: 1.05 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 3755 - 66% 3804 - 75% 3818 - 80% 3825 - 90% 3845 - 95% 3858 - 98% 3874 - 99% 3875 - 100% 4225 (longest request) -``` - - - -이 결과를 보면 초당 5건의 요청만 처리할 수 있고 한 요청당 4초 미만의 시간이 걸리는 것을 알 수 있습니다. -실제 애플리케이션에서는 요청을 처리할 때 많은 함수에서 다량의 작업이 일어날 수 있지만, 이 간단한 -예시에서도 정규표현식을 해석하고 임의의 솔트를 만들고 사용자 비밀번호에서 유일한 해시값을 만들고 -Express 프레임워크 내부 작업을 진행하기 위해 시간이 소비됩니다. - -`--prof` 옵션으로 애플리케이션을 실행했으므로 애플리케이션을 실행한 디렉터리에 tick 파일이 생성됩니다. -파일명은 `isolate-0xnnnnnnnnnnnn-v8.log`(여기서 `n`은 숫자입니다.) 같은 형식일 것입니다. - -이 파일을 이해하려면 Node.js 바이너리에 포함된 tick 프로세서를 사용해야 합니다. -`--prof-process` 플래그로 tick 프로세서를 실행할 수 있습니다. - -``` -node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt -``` - - - -사용하는 텍스트 에디터에서 processed.txt를 열면 몇 가지 정보를 볼 수 있습니다. -파일은 언어로 구분된 단위로 나누어져 있습니다. 우선 요약 부분을 보겠습니다. - -``` - [Summary]: - ticks total nonlib name - 79 0.2% 0.2% JavaScript - 36703 97.2% 99.2% C++ - 7 0.0% 0.0% GC - 767 2.0% Shared libraries - 215 0.6% Unaccounted -``` - - - -이 부분을 보면 C++ 코드에서 수집된 샘플이 97%를 차지하는 것을 볼 수 있으므로 처리된 결과에서 -다른 부분을 볼 때 C++에서 이뤄진 작업에 대부분의 관심을 기울여야 합니다.(JavaScript 대비) -그래서 C++ 함수가 대부분의 CPU 시간을 차지한 정보를 담고 있는 \[C++\] 부분을 찾아볼 것입니다. - -``` - [C++]: - ticks total nonlib name - 19557 51.8% 52.9% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 4510 11.9% 12.2% _sha1_block_data_order - 3165 8.4% 8.6% _malloc_zone_malloc -``` - - - -프로그램에서 72.1%의 CPU 시간을 차지한 3개의 작업을 보겠습니다. 이 결과를 보면 사용자 비밀번호에서 -해시를 생성하는 PBKDF2 함수 호출이 최소 51.8%의 CPU 시간을 차지한 것을 바로 눈치챌 수 있습니다. -하지만 더 낮은 비율을 가진 두 부분은 애플리케이션의 어떤 부분인지 바로 알 수 없습니다.(아니면 -예제를 위해서 그런 척 할 것입니다.) 이러한 함수 간의 관계를 더 이해하려면 각 함수의 주요 호출자 정보를 -제공하는 \[Bottom up (heavy) profile\] 부분을 봐야 합니다. -이 부분을 찾아보면 다음과 같이 나와 있습니다. - -``` - ticks parent name - 19557 51.8% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 19557 100.0% v8::internal::Builtins::~Builtins() - 19557 100.0% LazyCompile: ~pbkdf2 crypto.js:557:16 - - 4510 11.9% _sha1_block_data_order - 4510 100.0% LazyCompile: *pbkdf2 crypto.js:557:16 - 4510 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 - - 3165 8.4% _malloc_zone_malloc - 3161 99.9% LazyCompile: *pbkdf2 crypto.js:557:16 - 3161 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 -``` - - - -이 섹션을 분석하려면 위에 나온 tick 횟수보다는 약간 더 작업이 필요합니다. 위에 나온 각 -"호출 스택(call stacks)"에서 parent에 나온 퍼센티지는 현재 줄에 있는 함수가 호출한 -바로 윗 줄의 함수가 차지하는 비율을 알려줍니다. 예를 들어 중간에 있는 \_sha1_block_data_order의 -"호출 스택"에서 \_sha1_block_data_order가 샘플에서 11.9%를 차지한다는 것을 알 수 있고 -이는 횟수에서 나온 값이라는 것을 알 수 있습니다. 하지만 여기서 이 함수는 항상 Node.js crypto 모듈의 -pbkdf2 함수가 호출한다고도 할 수 있습니다. 비슷하게 \_malloc_zone_malloc도 같은 pbkdf2 함수가 -거의 전적으로 호출한다는 것을 알 수 있습니다. 그러므로 이 관점으로 얻은 정보를 사용하면 -\_sha1_block_data_order과 \_malloc_zone_malloc가 pbkdf2 함수에 의해서 호출되었으므로 -사용자 비밀번호의 해시 계산이 앞에서 본 51.8%뿐 아니라 상위 3개의 모든 CPU 시간을 -차지한다는 것을 알 수 있습니다. - -이 관점으로 보면 비밀번호에 기반을 둔 해시 생성이 최적화 대상이 되어야 한다는 것이 아주 명확합니다. -고맙게도 [비동기 프로그래밍의 장점][]을 완전히 이해하고 있고 사용자 비밀번호에서 해시를 생성하는 과정이 -동기로 진행된다는 것을 알 수 있으므로 이를 이벤트 루프로 바꾸면 됩니다. -이는 해시를 계산하는 동안 들어오는 다른 요청을 처리할 수 있게 합니다. - - - -이 이슈를 처리하려면 pdkdf2 함수의 비동기 버전을 사용하도록 핸들러를 수정하면 됩니다. - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users[username]) { - return res.sendStatus(400); - } - - crypto.pbkdf2(password, users[username].salt, 10000, 512, (err, hash) => { - if (users[username].hash.toString() === hash.toString()) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } - }); -}); -``` - - - -애플리케이션의 비동기 버전으로 앞에서 진행한 ab 벤치마크를 실행하면 다음과 같은 결과를 볼 수 있습니다. - -``` -Concurrency Level: 20 -Time taken for tests: 12.846 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 19.46 [#/sec] (mean) -Time per request: 1027.689 [ms] (mean) -Time per request: 51.384 [ms] (mean, across all concurrent requests) -Transfer rate: 3.82 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 1018 - 66% 1035 - 75% 1041 - 80% 1043 - 90% 1049 - 95% 1063 - 98% 1070 - 99% 1071 - 100% 1079 (longest request) -``` - - - -애플리케이션이 이제 초당 20개의 요청을 처리할 수 있게 되었습니다. 이는 동기 해시 생성을 사용한 것보다 -대략 4배가 빨라진 것입니다. 게다가 평균 지연시간이 이전의 4초에서 1초 정도로 줄어들었습니다. - -이 예시의 성능 분석을 통해 V8 tick 프로세서가 Node.js 애플리케이션 성능을 이해하는데 -어떻게 도움이 되는지 알기 바랍니다. - -[V8 내의 프로파일러]: https://v8.dev/docs/profile -[비동기 프로그래밍의 장점]: https://nodesource.com/blog/why-asynchronous diff --git a/pages/ko/docs/guides/timers-in-node.md b/pages/ko/docs/guides/timers-in-node.md deleted file mode 100644 index ac9ebd1cd4fbb..0000000000000 --- a/pages/ko/docs/guides/timers-in-node.md +++ /dev/null @@ -1,376 +0,0 @@ ---- -title: Node.js의 Timers -layout: docs.hbs ---- - - - -# Node.js의 Timers - -Node.js의 Timers 모듈에는 일정 시간 후에 코드를 실행하는 함수가 있습니다. Timers의 모든 메서드는 -브라우저 JavaScript API를 에뮬레이트하기 위해 전역으로 사용할 수 있으므로 `require()`로 임포트할 -필요가 없습니다. 타이머 함수가 언제 실행될지 완전히 이해하려면 Node.js -[Event Loop](/en/docs/guides/event-loop-timers-and-nexttick/)를 읽어보는 게 좋습니다. - - - -## Node.js 시간 연속체 제어하기 - -Node.js API는 현시점 이후 어떤 순간에 코드를 실행하도록 스케줄링하는 여러 가지 방법을 제공합니다. -아래의 함수는 대부분 브라우저에서 사용할 수 있으므로 아마 익숙할 테지만 Node.js는 실제로 이러한 -메서드의 Node.js 구현체를 제공합니다. Timers는 시스템과 매우 밀접하게 통합되어 있고 API가 -브라우저 API를 미러링하고 있음에도 구현에서는 약간의 차이점이 있습니다. - - - -### "지정한 시기에" 실행 ~ _`setTimeout()`_ - -`setTimeout()`은 지정한 밀리 초 이후 코드 실행을 스케줄링하는 데 사용할 수 있습니다. 이 함수는 -브라우저 JavaScript API의 -[`window.setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout)과 -비슷하지만, 코드의 문자열을 실행하려고 전달할 수 없습니다. - -`setTimeout()`은 첫 인자로 실행할 함수를 받고 두 번째 인자로 지연시킬 밀리 초를 숫자로 받습니다. -부가적인 인자를 더 전달할 수도 있는데 이는 함수로 전달될 것입니다. 다음은 그 예제입니다. - -```js -function myFunc(arg) { - console.log(`arg was => ${arg}`); -} - -setTimeout(myFunc, 1500, 'funky'); -``` - - - -위 함수 `myFunc()`는 `setTimeout()` 호출로 인해 약 1500밀리 초(1.5초) 정도에 -실행될 것입니다. - -설정한 타임아웃 간격은 _정확한_ 밀리 초 후 실행되도록 할 수 없습니다. 이벤트 루프를 블로킹하거나 -보유하고 있는 다른 실행 코드가 타임아웃의 실행을 다시 뒤로 밀기 때문입니다. 선언된 타임아웃 간격보다 -_더 빨리_ 실행되지는 않는다는 _것만_ 보장합니다. - -`setTimeout()`은 설정한 타임아웃을 참조하는 `Timeout` 객체를 반환합니다. 여기서 반환된 객체로 -실행 동작을 변경할 수도 있고(아래 `unref()`를 보세요.) 타임아웃을 -취소할 수 있습니다.(아래 `clearTimeout()`을 보세요.) - - - -### "바로 다음에" 실행 ~ _`setImmediate()`_ - -`setImmediate()`는 현재 이벤트 루프 주기 끝에 코드를 실행합니다. 이 코드는 현재 이벤트 루프의 -모든 I/O 작업 후 다음 이벤트 루프에 스케줄링 된 모든 타이머 이전에 실행됩니다. 이 코드 실행은 -`setImmediate()` 함수 호출 뒤에 오는 모든 코드는 `setImmediate()` 함수 인자 이전에 실행된다는 -의미로 "바로 다음에" 실행한다고 생각할 수 있습니다. - -`setImmediate()`의 첫 인자는 실행할 함수입니다. 그 뒤의 인자는 실행될 때 함수로 전달됩니다. -다음은 그 예제입니다. - -```js -console.log('before immediate'); - -setImmediate(arg => { - console.log(`executing immediate: ${arg}`); -}, 'so immediate'); - -console.log('after immediate'); -``` - - - -`setImmediate()`에 전달한 위 함수는 실행할 수 있는 코드를 모두 실행한 후에 실행하고 콘솔 출력은 다음과 같을 것입니다. - -``` -before immediate -after immediate -executing immediate: so immediate -``` - -`setImmediate()`는 바로 스케줄링 된 것을 취소할 수 있는 `Immediate` 객체를 -반환합니다.(아래 `clearImmediate()`를 보세요) - -Note: `setImmediate()`를 `process.nextTick()`와 혼동하지 마세요. 서로 다른 몇 가지 점이 -있습니다. 첫째로 `process.nextTick()`은 모든 스케줄링된 I/O 이전뿐만 아니라 설정한 모든 -`Immediate` _이전에_ 실행될 것입니다. 두 번째로 `process.nextTick()`은 취소할 수 없으므로 -일단 `process.nextTick()`으로 코드를 실행하도록 스케줄링하면 일반 함수처럼 실행을 멈출 수 없습니다. -`process.nextTick()`의 동작을 더 이해하려면 -[이 가이드 문서](/en/docs/guides/event-loop-timers-and-nexttick/#process-nexttick)를 -참고하세요. - - - -### "무한루프" 실행 ~ _`setInterval()`_ - -여러 번 실행해야 하는 코드 블록이 있다면 `setInterval()`을 사용할 수 있습니다. -`setInterval()`은 두 번째 인자로 지정한 밀리 초 단위의 지연시간으로 무한대로 실행할 함수를 -인자로 받습니다. `setTimeout()`처럼 지연시간 다음에 부가적인 인자를 지정할 수 있고 이는 함수 호출에 -전달될 것입니다. 또한 `setTimeout()`처럼 작업이 이벤트 루프에서 진행 중일 수 있으므로 지연시간이 -보장되지 않습니다. 그러므로 대략적인 지연시간으로 생각해야 합니다. 아래 예시를 보겠습니다. - -```js -function intervalFunc() { - console.log('Cant stop me now!'); -} - -setInterval(intervalFunc, 1500); -``` - -위 예제에서 `intervalFunc()`는 중단하기 전까지는(아래 참고) 1500밀리 초(1.5초)마다 실행될 것입니다. - -`setTimeout()`처럼 `setInterval()`도 설정한 인터벌을 참조하고 수정하는 데 사용할 수 있는 -`Timeout` 객체를 반환합니다. - - - -## 취소하기 - -`Timeout`이나 `Immediate` 객체를 취소하고 싶다면 어떻게 해야 할까요? `setTimeout()`, -`setImmediate()`, `setInterval()`은 설정한 `Timeout`이나 `Immediate` 객체를 참조하는 -타이머 객체를 반환합니다. 각각의 `clear` 함수에 이 객체들을 전달해서 해당 객체의 실행을 완전히 -중단할 수 있습니다. 각각의 함수는 `clearTimeout()`, `clearImmediate()`, -`clearInterval()`입니다. 각 예제는 아래에 나와 있습니다. - -```js -const timeoutObj = setTimeout(() => { - console.log('timeout beyond time'); -}, 1500); - -const immediateObj = setImmediate(() => { - console.log('immediately executing immediate'); -}); - -const intervalObj = setInterval(() => { - console.log('interviewing the interval'); -}, 500); - -clearTimeout(timeoutObj); -clearImmediate(immediateObj); -clearInterval(intervalObj); -``` - - - -## 타임아웃 감춰두기 - -여기서 `Timeout` 객체는 `setTimeout`과 `setInterval`이 반환했다는 점을 기억하길 바랍니다. -`Timeout` 객체는 `Timeout`의 동작을 강화하는 두 가지 함수 `unref()`와 `ref()`를 제공합니다. -`set` 함수로 스케줄링 된 `Timeout` 객체가 있다면 이 객체에서 `unref()`를 호출할 수 있습니다. -이는 동작을 다소 변경하는데 _실행할 코드가 이것밖에 남지 않았다면_ `Timeout` 객체를 호출하지 않습니다. -`Timeout` 객체는 프로세스를 유지하지 않고 실행을 기다립니다. - -비슷하게 `unref()`가 호출된 `Timeout` 객체에서 `ref()`를 호출하면 이 동작을 제거해서 -실행을 보장할 수 있습니다. 하지만 성능 문제로 초기 동작을 _완전히 똑같이_ 복구하는 것은 아닙니다. -아래의 예제를 보겠습니다. - -```js -const timerObj = setTimeout(() => { - console.log('will i run?'); -}); - -// 이 부분만 있다면 이 타임아웃이 프로그램을 종료되지 않게 하고 있으므로 -// 위 타임아웃이 실행되지 않도록 합니다. -timerObj.unref(); - -// immediate 안에서 ref()를 실행해서 다시 실행상태로 만들 수 있습니다 -setImmediate(() => { - timerObj.ref(); -}); -``` - - - -## 이벤트 루프 더 알아보기 - -이벤트 루프와 타이머에는 이 문서에서 다룬 것 이상의 많은 내용이 있습니다. Node.js 이벤트 루프의 -내부 구조와 실행할 때 타이머가 동작하는 방식을 알고 싶다면 -[Node.js 이벤트 루프, 타이머, process.nextTick()](/en/docs/guides/event-loop-timers-and-nexttick/) -문서를 참고하세요. diff --git a/pages/ko/docs/guides/working-with-different-filesystems.md b/pages/ko/docs/guides/working-with-different-filesystems.md deleted file mode 100644 index 0686ec8400f0c..0000000000000 --- a/pages/ko/docs/guides/working-with-different-filesystems.md +++ /dev/null @@ -1,424 +0,0 @@ ---- -title: 여러 파일 시스템에서 작업하기 -layout: docs.hbs ---- - - - -# 여러 파일 시스템에서 작업하기 - -Node는 파일 시스템에서 다양한 기능을 제공합니다. 하지만 모든 파일 시스템이 같은 것은 아닙니다. -여러 파일 시스템에서 동작할 때 코드를 간단하고 안전하게 유지하기 위한 모범 예제를 -아래에서 제시합니다. - - - -## 파일 시스템의 동작 - -파일 시스템을 사용하기 전에 파일 시스템이 어떻게 동작하는지 알아야 합니다. 다른 파일 시스템은 -다르게 동작하고 파일 시스템마다 기능이 더 많거나 적거나 합니다. 예를 들어 대소문자 구분/비구분, -대소문자 유지, 유니코드 형식 보존, 타임스탬프 처리방법, 속성 확장, 아이노드, 유닉스 권한, -데이터 스트림 대안 등이 있습니다. - -`process.platform`에서 파일 시스템의 동작을 추측하는 것을 주의해야 합니다. 예를 들어 사용자가 -대소문자를 구별하는 파일 시스템(HFSX)를 사용할 수도 있으므로 프로그램이 Darwin에서 동작하고 있다고 -대소문자를 구별하지 않는 파일 시스템(HFS+)을 사용한다고 가정해서는 안 됩니다. 유사하게 유닉스 권한이나 -아이노드를 지원하지 않는 외장 드라이브나 USB, 네트워크 드라이브를 사용할 수도 있으므로 Linux에서 -돌아가고 있다고 파일 시스템이 유닉스 권한이나 아이노드를 지원한다고 가정해서는 안 됩니다. - -운영체제로 파일 시스템의 동작을 쉽게 예상할 수 없지만 모두 필요 없는 것은 아닙니다. 알려진 모든 -파일 시스템과 동작의 목록을 관리하는 대신(절대 완료된 목록을 갖지 못할 것입니다.) 파일 시스템이 -실제로 어떻게 동작하는지 확인할 수 있습니다. 쉽게 확인할 수 있는 특정 기능의 존재 여부 만으로도 -확인하기 더 어려운 다른 기능의 동작을 예측하기에 대부분 충분합니다. - -일부 사용자는 워킹 트리의 다양한 경로에 여러 가지 파일 시스템을 마운트해서 -사용할 수도 있다는 것을 명심하세요. - - - -## 최소 공통분모 접근 피하기 - -모든 파일명을 대문자로 정규화하고 모든 파일명을 NFC 유니코드 형식으로 정규화하고 파일의 타임스탬프를 -1초 해상도로 정규화함으로써 파일 시스템의 최소 공통분모로 프로그램이 동작하게 하고 싶을 수도 있습니다. -이를 최소 공통분모 접근이라고 합니다. - -이렇게 하면 안 됩니다. 모든 부분에서 최소 공통분모의 특성과 정확히 같은 파일 시스템에서만 안전하게 -사용할 수 있을 것입니다. 더 향상된 파일 시스템에서는 사용자가 기대하는 방법으로 동작하지 않을 것이고 -파일 시스템이나 타임스탭프 충돌이 발생할 것입니다. 복잡하게 의존하는 이벤트 사이에서 사용자 데이터를 -잃어버리거나 훼손할 가능성이 아주 크고 해결할 수 없거나 어려운 버그를 만들 것입니다. - -2초나 24시간 타임스탬프 해상도만 가진 파일 시스템을 나중에 지원해야 한다면 어떻게 할 것입니까? -유니코드 표준이 정규화 알고리즘과 약간 다른 내용을 포함하게 된다면(이런 일은 과거에도 일어났습니다.) -어떻게 할 것입니까? - -최소 공통분모 접근은 "이식성 있는(portable)" 시스템 호출만 사용해서 이식성 있는 프로그램을 만들려고 -하는 경향이 있습니다. 이는 누출되기 쉽고 실제로는 이식성이 없는 프로그램이 됩니다. - - - -## 슈퍼셋 접근 도입 - -슈퍼셋 접근으로 지원하는 각 플랫폼을 최상으로 사용하게 하세요. 예를 들어, 이식성 있는 백업 프로그램은 -리눅스 시스템에서는 btimes을 지원하지 않더라도 윈도우 시스템에서 btimes(파일이나 폴더의 생성 시간)를 -제대로 동기화해야 하고 btimes를 없애거나 바꾸지 않아야 합니다. 같은 이식성 있는 백업 프로그램은 -리눅스 시스템에서 유닉스 권한을 제대로 동기화해야 하고 윈도우 시스템이 유닉스 권한을 지원하지 않더라도 -유닉스 권한을 없애거나 바꾸면 안 됩니다. - -더 진보된 파일 시스템처럼 동작하게 프로그램을 만들어서 여러 파일 시스템을 처리하세요. 대소문자 구별, -대소문자 유지, 유니코드 형식 구별, 유니코드 형식 보존, 유닉스 권한, 고행상도 나노초 타임스탬프, -확장 속성 등 가능한 모든 기능의 슈퍼셋을 지원하세요. - -프로그램이 대소문자를 보존하고 있다면 대소문자를 구별하지 않는 파일 시스템을 사용해야 할 때 항상 -대소문자를 구별하지 않도록 구현할 수 있습니다. 하지만 프로그램이 대소문자를 유지하지 않는다면 대소문자를 -유지하는 파일 시스템에서 안전하게 사용할 수 없을 것입니다. 유니코드 형식 보존과 타임스탬프 해상도 -보존에서도 마찬가지입니다. - -파일 시스템에 대소문자가 섞인 파일명을 준다면 받은 그대로의 파일명을 유지하세요. 파일 시스템이 -유니코드 형식이나 NFC, NFD(혹은 NFKC나 NFKD)가 섞인 파일명을 준다면 주어진 바이트 순서 -그대로의 파일명을 유지하세요. 파일 시스템이 밀리 초 단위의 타임스탬프를 준다면 밀리 초단위의 해상도로 -타임스탬프를 유지하세요. - -프로그램이 돌아가는 파일 시스템의 동작에서 필요로 하는 기능과 비교해서 기능이 더 부족한 파일 시스템에서 -동작할 때 언제나 적절하게 기능을 줄일 수 있습니다. 파일 시스템 유닉스 권한을 지원하지 않는 것을 알고 -있다면 작성한 유닉스 권한과 같은 권한을 읽으려고 하면 안 됩니다. 파일 시스템이 대소문자를 보존하지 -않는 것을 알고 있지만, 프로그램이 `ab`를 생성할 때 디렉터리 목록에서 `ABC`를 볼 대비를 해야 합니다. -하지만 파일 시스템이 대소문자를 유지하는 것을 알고 있다면 파일명 변경을 감지하거나 파일 시스템에 -대소문자를 구별 하는 경우 `ABC`와 `abc`를 다른 파일명으로 간주해야 합니다. - - - -## 대소문자 보존 - -`test/abc`라는 디렉터리를 생성한 뒤 `fs.readdir('test')`가 `['ABC']`를 반환할 때 놀랄 수도 -있습니다. 이는 Node의 버그가 아닙니다. Node는 파일 시스템이 저장한 파일명을 반환하고 모든 -파일 시스템이 대소문자를 보존하는 것은 아닙니다. 어떤 파일 시스템은 모든 파일명을 -대문자(혹은 소문자)로 바꿉니다. - - - -## 유니코드 형식 보존 - -_대소문자 보존과 유니코드 형식 보존은 비슷한 개념입니다. 유니코드 형식을 보존해야 하는 이유를 -이해하려면 먼저 왜 대소문자를 보존해야 하는지를 확실히 이해해야 합니다. 제대로 이해한다면 -유니코드 형식 보존은 아주 간단합니다._ - -유니코드는 여러 가지 다른 바이트 순서를 사용해서 같은 문자를 인코딩할 수 있습니다. 여러 가지 문자열이 -같아 보일 수 있지만 다른 바이트 순서를 가질 수 있습니다. UTF-8 문자열에서 줄과 관련해서 유니코드가 -동작하는 방식에 대해서 조심해야 합니다. 모든 UTF-8 문자를 하나의 바이트로 인코딩되기를 기대하면 -안 되듯이 사람 눈에는 같아 보이는 여러 가지 UTF-8 문자열이 같은 바이트 표현을 한다고 생각해서는 -안 됩니다. ASCII에서는 이런 기대를 해도 되지만 UTF-8에서는 안 됩니다. - -`test/café`라는 디렉터리(`<63 61 66 c3 a9>`의 바이트 순서와 `string.length === 5`를 가진 -NFC 유니코드 형식)를 만들고 `fs.readdir('test')`가 `['café']`(`<63 61 66 65 cc 81>`의 -바이트 순서와 `string.length === 6`를 가진 NFD 유니코드 형식)을 반환하면 놀랄 수도 있습니다. -이는 Node의 버그가 아닙니다. Node는 파일 시스템이 저장한 파일명을 반환하는데 모든 파일 시스템이 -유니코드 형식을 보존하는 것은 아닙니다. - -예를 들어 HFS+는 거의 항상 모든 파일명을 NFD 형식으로 정규화할 것입니다. HFS+가 NTFS나 EXT4처럼 -동작하기를 기대해도 안 되고 그 반대를 기대해도 안 됩니다. 파일 시스템마다 다른 유니코드를 감추려고 취약한 -추상화로 정규화함으로써 데이터를 항상 바꾸려고 하지 마세요. 이는 아무런 문제도 해결하지 못하고 문제를 -만들어 낼 것입니다. 대신 유니코드 형식을 보존하고 비교함수처럼 정규화만 사용하세요. - - - -## 유니코드 형식 비구별 - -유니코드 형식을 비구별과 유니코드 형식 보존은 종종 헷갈리는 파일 시스템의 다른 두 가지 동작입니다. -때로 대소문자 비구별을 파일명을 저장하고 전송할 때 항상 대문자로 정규화하게 잘못 구현하듯이 유니코드 -형식 비구별도 종종 파일명을 저장하고 전송할 때 파일명을 특정 유니코드 형식(HFS+의 경우 NFD)으로 -항상 정규화하도록 잘못 구현하곤 합니다. 비교할 때만 유니코드를 정규화함으로써 유니코드 형식은 -보존하면서도 유니코드 형식 비구별을 구현하는 것이 가능하고 이 방법이 훨씬 좋습니다. - - - -## 다른 유니코드 형식의 비교 - -Node는 UTF-8 문자열을 NFC나 NFD로 정규화하는 데 사용할 수 있는 -`string.normalize('NFC' / 'NFD')`를 제공합니다. 이 함수의 반환 값은 절대 저장하면 안 되고 -두 UTF-8 문자열이 사용자에게 같아 보이는지 확인하는 비교 함수에서만 사용해야 합니다. - -비교 함수로 `string1.normalize('NFC') === string2.normalize('NFC')`나 -`string1.normalize('NFD') === string2.normalize('NFD')`를 사용할 수 있습니다. -어느 방법을 사용하든 상관없습니다. - -정규화는 빠르지만 같은 문자열을 여러 번 정규화하는 것을 피하고자 비교함수의 입력값에 캐시를 -사용하려고 할 수 있습니다. 캐시에 문자열이 없다면 정규화하고 이를 저장합니다. 캐시를 저장하거나 -유지하지 않도록 조심하고 캐시로써만 사용해야 합니다. - -`normalize()`를 사용하려면 사용하는 Node 버전에 ICU를 포함해야 합니다.(그렇지 않으면 -`normalize()`가 원래의 문자열을 그냥 반환할 것입니다.) 웹사이트에서 최신 버전의 Node를 -다운로드 했다면 ICU가 포함되어 있습니다. - - - -## 타임스탬프 해상도 - -파일의 `mtime`(수정시간)을 `1444291759414`(밀리 초 해상도)로 설정했는데 `fs.stat`가 mtime을 -`1444291759000`(1초 해상도)나 `1444291758000`(2초 해상도)로 반환하는 것에 당황할 수도 -있습니다. 이는 Node의 버그가 아닙니다. Node는 파일 시스템이 저장한 타임스탬프를 반환하고 모든 -파일 시스템이 나노초, 밀리 초, 1초 타임스탬프 해상도를 지원하는 것은 아닙니다. 일부 파일 시스템은 -atime 타임스탬프에 아주 거친 해상도를 쓰기도 합니다.(예를 들어 일부 FAT 파일 시스템은 24시간입니다.) - - - -## 정규화로 파일명과 타임스탬프를 훼손시키지 마세요. - -파일명과 타임스탬프는 사용자 데이터입니다. 데이터를 대문자로 바꾸거나 `CRLF`나 `LF`같은 줄 끝 문자를 -정규화해서 사용자 파일 데이터를 자동으로 재작성하지 말아야 하듯이 대소문자 / 유니코드 형식 / 타임스탬프 -정규화로 파일명이나 타임스탬프를 절대 변경하거나 훼손시키지 않아야 합니다. 정규화는 비교할 때만 사용하고 -데이터를 바꾸면 안 됩니다. - -정규화는 효율적인 손실을 주는 해시 코드입니다. 어떤 종류든 동등한지 검사할 때 사용할 수 있지만(여러 -문자열이 다른 바이트 순서를 가지고 있더라도 같아 보이는지 등) 실제 데이터를 교체하는 데 사용할 수는 -없습니다. 프로그램은 있는 그대로의 파일명과 타임스탬프를 전달해야 합니다. - -프로그램이 NFC(또는 선호하는 어떤 유니코드 형식의 조합이더라도)에서, 혹은 소문자나 대문자 파일명으로, -혹은 2초 해상도 타임스탬프로 새로운 데이터를 만들 수 있지만, 대소문자 / 유니코드 형식 / 타임스탬프 -정규화를 적용해서 기존의 사용자 데이터를 훼손시키면 안됩니다. 대신 슈퍼셋 접근을 적용하고 프로그램에서 -대소문자, 유니코드 형식, 타임스탬프 해상도를 보존하세요. 이 방법을 적용하면 같은 동작을 하는 -파일 시스템을 안정하게 사용할 수 있습니다. - - - -## 정규화 비교 함수를 적절하게 사용하세요. - -대소문자 / 유니코드 형식 / 타임스탬프 비교 함수를 적절하게 사용하세요. 대소문자를 구별하는 -파일 시스템에서 동작한다면 대소문자를 구별하지 않는 파일명 비교 함수를 사용하지 말아야 합니다. 유니코드 -형식을 구별하는 파일 시스템에서 동작한다면(예를 들어 NFC와 NFD를 둘 다 보존하거나 혼합된 유니코드 -형식을 사용하는 NTFS와 대부분의 리눅스 파일 시스템) 유니코드 형식을 구별하지 않는 비교 함수를 -사용하지 마세요. 나노초 타임스탬프 해상도를 가진 파일 시스템에서 동작한다면 2초 해상도로 타임스탬프를 -비교하지 마세요. - - - -## 비교함수에 있는 약간의 차이점에 대비하세요. - -비교함수로 파일 시스템에서 일치 여부를 판단할 때는 주의해야 합니다.(또는 실제로 파일 시스템이 어떻게 -비교하는지 볼 수 있다면 파일 시스템을 탐구해야 합니다.) 예를 들어 대소문자 구분없이 비교하는 것은 단순한 -`toLowerCase()` 비교보다 훨씬 복잡합니다. 사실 `toUpperCase()`가 `toLowerCase()`보다 -보통 더 좋습니다.(`toLowerCase()`가 특정 외국어 문자를 다르게 다루기 때문입니다.) 하지만 모든 -파일 시스템은 자신만의 대소문자 비교 테이블을 가지고 있으므로 파일시스템을 탐구하는 것이 좋습니다. - -예를 들어, Apple의 HFS+는 파일 이름을 NFD 형식으로 정규화 하지만 실제 이 NFD 형식은 현재 NFD 형식의 -이전 버전이며 최신 유니코드 표준의 NFD 형식과는 조금 다를 수 있습니다. HFS+ NFD가 유니코드의 NFD와 항상 -같을 거라고 기대하면 안 됩니다. diff --git a/pages/ko/docs/index.mdx b/pages/ko/docs/index.mdx deleted file mode 100644 index de1bf3b782cbf..0000000000000 --- a/pages/ko/docs/index.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: 문서 -layout: docs.hbs -labels: - lts: LTS ---- - -# 문서에 관해서 - -이 웹사이트에는 여러 종류의 문서가 있습니다. - -- API 레퍼런스 문서 -- ES6 기능 -- 안내(가이드) - -## API 레퍼런스 문서 - -[API 레퍼런스 문서](https://nodejs.org/api/)에는 Node.js의 함수나 객체에 대한 자세한 정보가 있습니다. -이 문서에서 메서드가 어떤 인자를 받고 어떤 값을 반환하는지 해당 메서드와 관련된 에러에는 어떤 것이 -있는지를 알려줍니다. 다양한 Node.js에서 어떤 메서드를 사용할 수 있는지도 알려줍니다. - -이 문서는 Node.js가 제공하는 내장 모듈을 설명합니다. 커뮤니티에서 제공하는 모듈은 문서화하지 않습니다. - -
- -### 이전 버전에 대한 API 문서가 필요한가요? - - - -[모든 버전](https://nodejs.org/docs/) - -
- -## ES6 기능 - -[ES6 부분](/ko/docs/es6/)에서는 세 가지 ES6 기능 그룹을 설명하고 Node.js에서 어떤 기능이 -기본적으로 활성화되어있는지 설명하면서 추가 링크를 제공합니다. 특정 Node.js 릴리스 버전에 -어떤 V8 버전이 포함되었는지 찾는 방법도 알려줍니다. - -## 안내 - -Node.js의 기술적인 기능에 대한 길고 상세한 글입니다. diff --git a/pages/ko/download/current.md b/pages/ko/download/current.md deleted file mode 100644 index 6a70f391482f0..0000000000000 --- a/pages/ko/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: 다운로드 -download: 다운로드 -downloads: - headline: 다운로드 - lts: LTS - current: 현재 버전 - tagline-current: 최신 기능 - tagline-lts: 대다수 사용자에게 추천 - display-hint: '다음 버전을 표시:' - intro: > - 플랫폼에 맞게 미리 빌드된 Node.js 인스톨러나 소스코드를 다운받아서 바로 개발을 시작하세요. - currentVersion: 최신 현재 버전 - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: 그 밖의 플랫폼 - intro: > - Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release. - platform: 플랫폼 - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ko/download/index.md b/pages/ko/download/index.md deleted file mode 100644 index 72b7d72d0d8ee..0000000000000 --- a/pages/ko/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: 다운로드 -download: 다운로드 -downloads: - headline: 다운로드 - lts: LTS - current: 현재 버전 - tagline-current: 최신 기능 - tagline-lts: 대다수 사용자에게 추천 - display-hint: '다음 버전을 표시:' - intro: > - 플랫폼에 맞게 미리 빌드된 Node.js 인스톨러나 소스코드를 다운받아서 바로 개발을 시작하세요. - currentVersion: 최신 LTS 버전 - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: 그 밖의 플랫폼 - intro: > - Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release. - platform: 플랫폼 - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ko/download/package-manager.md b/pages/ko/download/package-manager.md deleted file mode 100644 index f69869aca850b..0000000000000 --- a/pages/ko/download/package-manager.md +++ /dev/null @@ -1,586 +0,0 @@ ---- -layout: page.hbs -title: 패키지 매니저로 Node.js 설치하기 ---- - - - -# 패키지 매니저로 Node.js 설치하기 - -**_Note:_** 이 페이지에 나오는 패키지는 각 패키지 관리자가 관리하고 Node.js 코어 팀이 -**관리하지 않습니다**. 이슈가 있다면 패키지 관리자에게 보고해 주세요. 해당 이슈가 Node.js 자체의 -버그라면 관리자가 이슈를 Node.js에 보고할 것입니다. - ---- - -- [안드로이드](#android) -- [Arch Linux](#arch-linux) -- [데비안과 우분투 기반 리눅스 배포판. 엔터프라이즈 리눅스/페도라와 Snap 패키지](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE 와 SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS 와 illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) - ---- - - - -## 안드로이드 - -Node.js의 안드로이드 지원은 현재 시험 단계에 있기 때문에 Node.js 개발자들이 제공하는 미리 컴파일된 바이너리가 아직 없습니다. - -하지만 몇 가지 서드파티는 존재합니다. 일례로 [Termux](https://termux.com/) 커뮤니티는 안드로이드를 위한 터미널 에뮬레이터와 리눅스 환경을 제공하는데, 고유한 패키지 매니저와 다수의 [미리 컴파일된 애플리케이션 패키지](https://github.com/termux/termux-packages)도 함께 제공하고 있습니다. Termux 앱에서 다음 명령어를 사용하면 최신 Node.js 버전을 설치합니다. - -```bash -pkg install nodejs -``` - -현재 Termux Node.js 바이너리는 `libicu` 패키지에 의존하는 `system-icu`에 링크되어 있습니다. - - - -## Arch Linux - -커뮤니티 저장소에서 Node.js와 npm을 이용할 수 있습니다. - -```bash -pacman -S nodejs npm -``` - - - -## 데비안과 우분투 기반 리눅스 배포판. 엔터프라이즈 리눅스/페도라와 Snap 패키지 - -[공식 Node.js 바이너리 배포판](https://github.com/nodesource/distributions)은 NodeSource가 제공합니다. - - - -## FreeBSD - -Node.js의 최신 릴리스는 [www/node](https://www.freshports.org/www/node) 포트를 통해 사용할 수 있습니다. - -바이너리 패키지는 다음과 같이 [pkg](https://www.freebsd.org/cgi/man.cgi?pkg)를 통해 설치할 수 있습니다. - -```bash -pkg install node -``` - -또는 다음과 같이 [ports](https://www.freebsd.org/cgi/man.cgi?ports)를 사용해 컴파일 할 수도 있습니다. - -```bash -cd /usr/ports/www/node && make install -``` - - - -## Gentoo - -Node.js는 portage를 사용할 수 있습니다. - -```bash -emerge nodejs -``` - - - -## IBM i - -IBM에서 ['yum' 패키지 매니저](https://ibm.biz/ibmi-rpms)를 통해 Node.js의 LTS 버전을 사용할 수 있습니다. -패키지 이름은 `nodejs` 뒤에 주 버전 숫자를 붙이면 됩니다(`nodejs8`, `nodejs10`, `nodejs12` 등). - -커맨드 라인에서 Node.js 12.x를 설치하려면 \*ALLOBJ 특수 권한을 가진 사용자로 다음 명령을 실행하세요. - -```bash -yum install nodejs12 -``` - -IBM i Access Client 솔루션 제품을 통해 Node.js를 설치할 수도 있습니다. -자세한 사항은 [지원 문서](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619)를 참조하세요. - - - -## NetBSD - -pkgsrc에서 Node.js를 설치할 수 있습니다. - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -사용하는 플랫폼에서 가능하다면 pkgin로 바이너리 패키지를 설치하는 방법도 있습니다. - -```bash -pkgin -y install nodejs -``` - - - -## nvm - -Node Version Manager는 Node.js의 다양한 릴리스 버전을 관리하는 bash 스크립트입니다. nvm으로 -설치, 제거, 버전 변경 같은 작업을 할 수 있습니다. nvm을 설치하려면 -[설치 스크립트](https://github.com/nvm-sh/nvm#install--update-script)를 사용하세요. - -Unix / OS X 시스템에서는 소스로 빌드된 Node.js를 -[nvm](https://github.com/creationix/nvm)으로 설치할 수 있습니다. -이는 nvm에 설정된 위치에 설치됩니다. - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -설치 후 `nvm`으로 릴리스 된 버전이나 소스에서 빌드한 버전 간에 변경할 수 있습니다. -예를 들어 Node.js 버전이 v8.0.0-pre라면 다음과 같이 실행합니다. - -```bash -nvm use 8 -``` - -공식적으로 릴리스 된 후 소스에서 빌드된 버전을 다음과 같이 제거할 수 있습니다. - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -The `nvs` version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems - -To install `nvs` on Windows go to the [release page](https://github.com/jasongin/nvs/releases) here and download the MSI installer file of the latest release. - -You can also use `chocolatey` to install it: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -You can find the documentation regarding the installation steps of `nvs` in macOS/Unix-like systems [here](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Usage - -After this you can use `nvs` to switch between different versions of node. - -To add the latest version of node: - -```bash -nvs add latest -``` - -Or to add the latest LTS version of node: - -```bash -nvs add lts -``` - -Then run the `nvs use` command to add a version of node to your `PATH` for the current shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -To add it to `PATH` permanently, use `nvs link`: - -```bash -nvs link lts -``` - - - -## OpenBSD - -다음과 같이 ports 시스템을 통해 Node.js를 사용할 수 있습니다. - -```bash -/usr/ports/lang/node -``` - -OpenBSD 환경에서 [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1)를 사용하는 방법도 있습니다. - -```bash -pkg_add node -``` - - - -## openSUSE와 SLE - -다음 패키지 아래 주 저장소에서 Node.js를 사용할 수 있습니다. - -- **openSUSE Leap 42.2**: `nodejs4` -- **openSUSE Leap 42.3**: `nodejs4`, `nodejs6` -- **openSUSE Tumbleweed**: `nodejs4`, `nodejs6`, `nodejs8` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs4`, `nodejs6` - ("웹과 스크립트 모듈"은 반드시 [설치 전에 추가](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html)해야 합니다.) - -예시로 openSUSE Leap 42.2에서 Node.js 4.x를 설치하려면 root 계정으로 다음 명령어를 실행해야 합니다. - -```bash -zypper install nodejs4 -``` - - - -## macOS - -[nodejs.org](https://nodejs.org/) 웹사이트에서 [매킨토시 인스톨러](https://nodejs.org/ko/#home-downloadhead)를 다운로드 받으세요. - -_bash에서 패키지를 다운로드 받고 싶다면 다음 명령어를 실행하세요._ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - - - -### 그 밖의 방법 - -**[Homebrew](https://brew.sh/)**를 사용할 수 있습니다. - -```bash -brew install node -``` - -**[MacPorts](https://www.macports.org/)**를 사용할 수 있습니다. - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -**[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**를 사용해서 -바이너리 패키지를 설치할 수 있습니다. - -```bash -pkgin -y install nodejs -``` - -pkgsrc에서 수동으로 빌드할 수도 있습니다. - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - - - -## SmartOS와 illumoss - -SmartOS 이미지에는 미리 설치된 pkgsrc가 포함되어 있습니다. illumos 배포판에서는 먼저 -**[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**를 설치하고 평소처럼 -바이너리 패키지를 설치하세요. - -```bash -pkgin -y install nodejs -``` - -pkgsrc에서 수동으로 빌드할 수도 있습니다. - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - - - -## Solus - -Solus는 메인 저장소에서 Node.js를 제공합니다. - -```bash -sudo eopkg install nodejs -``` - - - -## Void Linux - -Void Linux는 메인 저장소에서 Node.js 안정 버전을 제공합니다. - -```bash -xbps-install -Sy nodejs -``` - - - -## Windows - -[nodejs.org](https://nodejs.org/) 웹사이트에서 -[윈도우 인스톨러](https://nodejs.org/ko/#home-downloadhead)를 직접 다운로드 받으세요. - -### 그 밖의 방법 - -**[Chocolatey](https://chocolatey.org/)**를 사용할 수 있습니다. - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -**[Scoop](https://scoop.sh/)**를 사용할 수 있습니다. - -```bash -scoop install nodejs -``` diff --git a/pages/ko/download/releases.md b/pages/ko/download/releases.md deleted file mode 100644 index 6cb393b3e4097..0000000000000 --- a/pages/ko/download/releases.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: download-releases.hbs -title: 이전 릴리스 -modules: 'NODE_MODULE_VERSION은 Node.js의 ABI(application binary interface) 버전 번호를 가리키고 이 버전은 어떤 버전의 Node.js가 C++ 애드온 바이너리를 컴파일해서 다시 컴파일하지 않아도 불러올 수 있는지 결정하는데 사용합니다. 예전 버전에서는 hex 값으로 저장되었지만 지금은 정수를 사용하고 있습니다.' ---- - - - -### io.js와 Node.js - -1.x부터 3.x 릴리스는 "io.js"라고 부르는데 이때는 io.js로 포크했기 때문입니다. -Node.js 4.0.0에서 io.js의 이전 릴리스 라인과 Node.js 0.12.x가 합쳐져서 -하나의 Node.js 릴리스가 되었습니다. - -### 버전별 최신 릴리스를 찾고 있나요? diff --git a/pages/ko/get-involved/contribute.md b/pages/ko/get-involved/contribute.md deleted file mode 100644 index b9c894aaa80c0..0000000000000 --- a/pages/ko/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: 기여하기 -layout: contribute.hbs ---- - -# 기여하기 - -Node.JS에 기여하는데 관심을 가져주셔서 감사합니다! 당신이 기여할 수 있는 여러 방법과 장소가 있고 우리는 그것이 잘 이루어지도록 돕기위해 있습니다. - -## 일반적인 도움받기 - -`nodejs/node` 리포지토리에서의 활동 수준이 너무 높으므로 Node.js 사용에 대한 일반적인 질문이나 요청은 [Node.js 지원 리포지토리](https://github.com/nodejs/help/issues).를 이용하세요. - -## 문제/이슈 보고 - -Node.js의 문제로 보이는 것을 찾았다면 Github프로젝트에 작성하는 것을 망설이지 말아주세요. 이슈를 제기할 때는 재현가능한 테스트 케이스를 설명해주시고 이때 그 테스트 케이스는 외부 의존성을 포함하지 않아야 합니다. 즉, 테스트 케이스는 Node.js만을 가지고 실행이 되어야 합니다. - -이슈를 보고할 때, 설명할 수 있는 개발 환경 정보도 함께 가능한 많이 적어주세요. 해당 이슈의 원인을 좁혀가며 찾을 때 어떤 정보가 적절할 지 알 수 없습니다. 최소한 다음의 정보들은 적어주시기바랍니다. - -- Node.js 버전 -- Node.js를 사용하는 운영체제 (macOS, SmartOS, Linux, Windows) -- Node.js가 돌아가는 아키텍쳐 (32bit 또는 64bit, x86 또는 ARM인지) - -Node.js 프로젝트는 수많은 Github 리포지토리들을 통해 관리되고 있으며 각각의 리포지토리는 별도의 버그 데이터베이스가 있습니다. 가능하면 보고하고자 하는 문제를 적절한 리포지토리에서 보고해주세요. 잘못된 위치에 보고를 하셔도 괜찮습니다. 기여자 커뮤니티에서 적절한 위치로 안내해드릴겁니다. - -- Node.js와 관련된 이슈보고는 다음 리포지토리를 이용해주세요. [nodejs/node](https://github.com/nodejs/node) -- 이 페이지와 관련된 이슈보고는 다음 리포지토리를 이용해주세요. [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## 코드 기여 - -Node.js의 버그를 수정하거나 새로운 기능을 추가하고 싶다면 가이드 라인을 참고하세요 [Node.js 기여 가이드라인](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). 프로젝트 기여 검토절차도 위 링크에서 확인 할 수 있습니다. 검토는 협력자들에 의해 이루어집니다. - -만약 어떻게 시작할 지 모르겠다면, 첫 기여 방향을 제시해줄 다음 리포지토리를 참고하세요.[Node Todo](https://www.nodetodo.org/) - -## 협력자 되기 - -협력자가 됨으로써, 기여자들은 프로젝트에 더 큰 영향력을 행사할 수 있습니다. 다른 기여자들의 기여내용을 검토함으로써 도와줄 수도 있고, 이슈를 분류하고 프로젝트의 미래를 그리는데 더 큰 부분을 차지합니다. TSC에 의해 Node.js에 중요하고 가치있는 기여를 이룬 개개인들은 협업자가 되고 프로젝트에 커밋할 권한을 받을 수 있습니다. 고려되는 활동들로는 아래를 예시로 들 수 있습니다. (예시일뿐,저것만 되는 것은 아닙니다.) - -- 코드 commit과 pull request하기 -- 문서 commit과 pull request하기 -- 이슈에 의견을 남기고 pull request하기 -- Node.js 웹사이트에 기여하기 -- 최종사용자와 초보 기여자들에게 도움주기 -- 작업 그룹에 참여하기 -- 다른 더 넓은 Node.js 커뮤니티에 참여하기 - -만약 가치있는 기여를 한 개개인들이 커밋 권한이 없다면 직접 이슈를 남기거나 TSC멤버에게 연락할 수 있습니다.[이슈남기기](https://github.com/nodejs/TSC/issues), 또는 [TSC 멤버에게 연락하기](https://github.com/nodejs/node#tsc-technical-steering-committee) diff --git a/pages/ko/get-involved/index.md b/pages/ko/get-involved/index.md deleted file mode 100644 index e28506ecfd5f8..0000000000000 --- a/pages/ko/get-involved/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 참여하기 -layout: contribute.hbs ---- - -# 참여하기 - -## 커뮤니티 논의 - -- [GitHub 이슈 목록](https://github.com/nodejs/node/issues)에서 Node.js 핵심 기능에 대한 논의가 이루어집니다. -- Node.js의 실시간 채팅 개발을 위해서 아래의 플랫폼 중 하나를 사용하세요. - - IRC의 경우 [IRC 클라이언트](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients) 를 참고하여`irc.libera.chat` 의 `#node.js` 채널을 방문하세요. 또는 당신의 웹 브라우저를 [웹 클라이언트](https://kiwiirc.com/nextclient/) 를 사용하여 채널에 연결하세요. - - 슬랙의 경우, 두 가지 선택지가 있습니다. - - [OpenJSF Slack](https://slack-invite.openjsf.org/)은 여러 Node.js채널의 슬랙을 운영하는 단체입니다.( `#nodejs-`라고 되어있는 채널이 프로젝트와 관련있는 채널입니다.) - - [Node Slackers](https://www.nodeslackers.com/)는 Node.js에 초점을 맞춘 슬랙 커뮤니티입니다. -- Node.js공식 트위터는 [nodejs](https://twitter.com/nodejs)입니다. -- [Node.js 프로젝트 캘린더](https://nodejs.org/calendar)에 모든 팀 미팅 일정이 있습니다. - -## 알아보기 - -- [공식 API 레퍼런스 문서](https://nodejs.org/api/)는 Node.js API에 대해 설명합니다. -- [NodeSchool.io](https://nodeschool.io/)는 명령어로 상호작용하는 게임을 통해 Node.js 개념에 대해 알려줍니다. -- [Stack Overflow Node.js 태그](https://stackoverflow.com/questions/tagged/node.js)에는 매일 새로운 정보가 쌓입니다. -- [The DEV Community Node.js 태그](https://dev.to/t/node)는 Node.js와 관련된 주제에 대해 논의하거나 의견을 묻기에도 좋고, Node.js 프로젝트, 글, 튜토리얼을 공유하기에도 좋은 장소입니다. 개발자라면 모두 환영합니다. -- [Nodeiflux](https://discord.com/invite/vUsrbjd)는 Discord에서 서로를 지원하는 Node.js 백엔드 개발자 커뮤니티입니다. diff --git a/pages/ko/index.md b/pages/ko/index.md deleted file mode 100644 index 7ac6db2fa13c2..0000000000000 --- a/pages/ko/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: 현재 버전 - download: 다운로드 - download-for: 다운로드 - - other-downloads: 다른 운영 체제 - current: 현재 버전 - lts: LTS - tagline-current: 최신 기능 - tagline-lts: 안정적, 신뢰도 높음 - changelog: 변경사항 - api: API 문서 - version-schedule-prompt: LTS 일정은 - version-schedule-prompt-link-text: 여기서 확인하세요 ---- - -Node.js®는 [Chrome V8 JavaScript 엔진](https://v8.dev/)으로 빌드된 JavaScript 런타임입니다. diff --git a/pages/nl/404.md b/pages/nl/404.md deleted file mode 100644 index 49c58d60869cf..0000000000000 --- a/pages/nl/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Pagina niet gevonden - -### ENOENT: Bestand of folder bestaat niet diff --git a/pages/nl/about/governance.md b/pages/nl/about/governance.md deleted file mode 100644 index 75226c385ded1..0000000000000 --- a/pages/nl/about/governance.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Project Bestuur -layout: about.hbs ---- - -# Project Bestuur - -## Besluitvormingsproces - -Node.js volgt een [Consensus Seeking][] besluitvormingsmodel. - -## Medewerkers - -De [nodejs/node][] core GitHub-repository wordt onderhouden door medewerkers die op continue basis worden toegevoegd door de Technical Steering Commissie ([TSC][]). - -Individuen die significante bijdragen leveren worden toegevoegd als Medewerkers (Collaborators) en krijgen commit-toegang tot het project. Deze individuen worden geselecteerd door de TSC. - -De huidige lijst van Medewerkers van het project is beschikbaar op [README.md][]. - -Een handleiding voor Medewerkers is beschikbaar op [collaborator-guide.md][]. - -## Top Level Commissies - -Het project wordt gezamenlijk bestuurd door de [Technical Steering Committee (TSC)][], die verantwoordelijk is voor high-level bestuur van het project, en door de [Community Committee (CommComm)][], die verantwoordelijk is voor het begeleiden en uitbreiden van de Node.js-community. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[Community Committee (CommComm)]: https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md -[Consensus Seeking]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Technical Steering Committee (TSC)]: https://github.com/nodejs/TSC/blob/master/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/nl/about/index.md b/pages/nl/about/index.md deleted file mode 100644 index ac216be42c560..0000000000000 --- a/pages/nl/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Over Node.js -trademark: Trademark ---- - -# Over Node.js® - -Als een asynchrone event-driven JavaScript runtime is Node.js ontworpen om schaalbare netwerk applicaties te bouwen. In het volgende "hello world" voorbeeld zien we dat verschillende connecties gelijktijdig afgehandeld kunnen worden. Bij elke connectie wordt de callback functie opgeroepen, maar als er niets te doen is, dan gaat Node.js ook niet tussenkomen. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Dit is in contrast met het meer gangbare concurrency-model (gelijktijdigheidsmodel) van vandaag, waarin OS-threads gebruikt worden. Thread-based netwerken zijn relatief inefficiënt en moeilijk te gebruiken. Verder hoeven Node.js gebruikers zich geen zorgen te maken over het proces te dead-locken, omdat er geen locks aanwezig zijn. Er zijn bijna geen functies in Node.js die rechtstreeks I/O uitvoeren, dus het proces blokkeert nooit, behalve wanneer de I/O wordt uitgevoerd met synchrone methodes van de Node.js standard library. Omdat niets blokkeert, is Node.js perfect voor het ontwikkelen van schaalbare systemen. - -Als dit u niet bekend is, dan is hier een volledig artikel over [Blocking vs. Non-Blocking][]. - ---- - -Node.js is vergelijkbaar in design met, en beïnvloed door, systemen zoals Ruby's [Event Machine][] en Python's [Twisted][]. Node.js breid het event-model verder uit. Het biedt een [event loop][] aan als een runtime construct in plaats van als een library. Bij andere systemen is er altijd eerst een blocking-call om de event-loop te starten. Meestal wordt het gedrag gedefinieerd door callbacks aan het begin van een script, en wordt er vaak een server gestart aan het einde via een blocking-call zoals `EventMachine::run()`. Bij Node.js is dit niet zo, er is geen start-the-event-loop oproep. Node.js betreed simpelweg de even-loop na het uitvoeren van het input script, en verlaat de event-loop wanneer er geen callbacks meer zijn om uit te voeren. Dit gedrag is zoals bij browser JavaScript - de event-loop is verborgen voor de gebruiker. - -HTTP is een first-class citizen in Node.js, ontworpen met streaming en low-latency in het achterhoofd. Dit maakt Node.js zeer geschikt als basis voor een web library of framework. - -Omdat Node.js is ontworpen zonder threads betekent dit niet dat je geen gebruik kunt maken van multi-cores in uw omgeving. Child processen kunnen worden gespawend door gebruik te maken van onze [`child_process.fork()`][] API, en zijn ontworpen om makkelijk mee te kunnen communiceren. Gebouwd op dezelfde interface is de [`cluster`][] module, waarmee je sockets kunt delen tussen processen om load balancing mogelijk te maken over uw cores. - -[Blocking vs. Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[event loop]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/nl/docs/index.mdx b/pages/nl/docs/index.mdx deleted file mode 100644 index 9c69ae508430b..0000000000000 --- a/pages/nl/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Documentatie -layout: docs.hbs -labels: -lts: LTS ---- - -# Documentatie - -Er zijn verschillende soorten documentatie beschikbaar op onze website: - -- API-referentiedocumentatie -- ES6-features -- Handleiding - -## API-referentiedocumentatie - -De [API-referentiedocumentatie](https://nodejs.org/api/) biedt gedetailleerde informatie over functies en objecten in Node.js. Zij geeft aan welke argumenten geaccepteerd kunnen worden door een methode, de return-waarde van een methode en informatie over errors die gekoppeld zijn met deze methode. Ze geeft ook aan welke methoden beschikbaar zijn binnen de verschillende versies van Node.js. - -Deze documentatie behandelt enkel de ingebouwde modules van Node.js. Ze behandelt geen community-modules. - -
- -### Op zoek naar API-documentatie van vorige versies? - - - -[Alle versies](https://nodejs.org/docs/) - -
- -## ES6-features - -De [ES6-sectie](/en/docs/es6/) beschrijft de drie ES6-feature groepen en de standaard features binnen Node.js. Ze toont ook welke versie van V8 bij een bepaalde Node.js-versie hoort. - -## Handleiding - -De [Handleiding](/en/docs/guides/) bevat lange, diepgaande artikelen over de technische kenmerken en mogelijkheden van Node.js. diff --git a/pages/nl/download/current.md b/pages/nl/download/current.md deleted file mode 100644 index ffd9b133105b7..0000000000000 --- a/pages/nl/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Download -download: Download -downloads: - headline: Downloads - lts: LTS - current: Huidig - tagline-current: Laatste Features - tagline-lts: Aanbevolen Voor Meeste Gebruikers - display-hint: Downloads bekijken voor - intro: > - Download de Node.js source-code of een pre-built installer voor uw platform, en begin vandaag nog met ontwikkelen. - currentVersion: Huidige Versie - buildInstructions: Ontwikkel Node.js op ondersteunde platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Aanvullende Platformen - intro: > - Leden van de Node.js-community onderhouden onofficiële builds van Node.js voor aanvullende platformen. Houd er rekening mee dat deze builds niet worden ondersteund doot het Node.js-kernteam en mogelijk niet op hetzelfde buildniveau zijn als de huidige Node.js-release. - platform: Platform - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Officiële Node.js Docker Image - LinuxPowerSystems: Linux op Power LE Systemen - LinuxSystemZ: Linux op System z - AIXPowerSystems: AIX op Power Systemen ---- diff --git a/pages/nl/download/index.md b/pages/nl/download/index.md deleted file mode 100644 index 027eb8bf688c7..0000000000000 --- a/pages/nl/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Download -download: Download -downloads: - headline: Downloads - lts: LTS - current: Huidig - tagline-current: Laatste Features - tagline-lts: Aanbevolen Voor Meeste Gebruikers - display-hint: Downloads bekijken voor - intro: > - Download de Node.js source-code of een pre-built installer voor uw platform, en begin vandaag nog met ontwikkelen. - currentVersion: Laatste LTS Versie - buildInstructions: Ontwikkel Node.js op ondersteunde platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Aanvullende Platformen - intro: > - Leden van de Node.js-community onderhouden onofficiële builds van Node.js voor aanvullende platformen. Houd er rekening mee dat deze builds niet worden ondersteund doot het Node.js-kernteam en mogelijk niet op hetzelfde buildniveau zijn als de huidige Node.js-release. - platform: Platform - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Officiële Node.js Docker Image - LinuxPowerSystems: Linux op Power LE Systemen - LinuxSystemZ: Linux op System z - AIXPowerSystems: AIX op Power Systemen ---- diff --git a/pages/nl/download/package-manager.md b/pages/nl/download/package-manager.md deleted file mode 100644 index e26f855e16c88..0000000000000 --- a/pages/nl/download/package-manager.md +++ /dev/null @@ -1,395 +0,0 @@ ---- -layout: page.hbs -title: Installeer Node.js via package-manager ---- - -# Installeer Node.js via package-manager - -**_Opmerking:_** De packages op deze pagina worden onderhouden door hun makers, **niet** door het Node.js-kernteam. Meld eventuele problemen die u tegenkomt aan de pakketbeheerders. Als blijkt dat uw probleem een bug is die veroorzaakt wordt door Node.js, dan zullen de pakketbeheerders dit bij ons melden. - ---- - -- [Alpine Linux](#alpine-linux) -- [Android](#android) -- [Arch Linux](#arch-linux) -- [CentOS, Fedora en Red Hat Enterprise Linux](#centos-fedora-and-red-hat-enterprise-linux) -- [Debian en Ubuntu gebaseerde Linux-distributies](#debian-and-ubuntu-based-linux-distributions) -- [fnm](#fnm) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [macOS](#macos) -- [n](#n) -- [NetBSD](#netbsd) -- [Nodenv](#nodenv) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE en SLE](#opensuse-and-sle) -- [SmartOS en illumos](#smartos-and-illumos) -- [Snap](#snap) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) -- [z/OS](#zos) - ---- - -## Alpine Linux - -Node.js LTS en npm-packages zijn beschikbaar in de Main Repository. - -```bash -apk add nodejs npm -``` - -Node.js Current kan geïnstalleerd worden vanuit de Community Repository. - -```bash -apk add nodejs-current -``` - -## Android - -Android-ondersteuning is nog steeds experimenteel binnen Node.js, dus precompiled binaries zijn momenteel nog niet beschikbaar. - -Er zijn wel enkele third-party-oplossingen beschikbaar. Bijvoorbeeld: de [Termux](https://termux.com/) community, deze bieden een terminal-emulator en Linux-omgeving aan voor Android, daarnaast hebben ze ook een eigen package-manager en een [uitgebreide collectie](https://github.com/termux/termux-packages) van precompiled applicaties. Dit commando in de Termux-app installeert de laatst beschikbare Node.js-versie: - -```bash -pkg install nodejs -``` - -Momenteel worden Termux Node.js binaries gelinkt tegen `system-icu` (afhankelijk van `libicu` package). - -## Arch Linux - -Node.js en npm-packages zijn beschikbaar in de Community Repository. - -```bash -pacman -S nodejs npm -``` - -## CentOS, Fedora en Red Hat Enterprise Linux - -Node.js is beschikbaar als een module genaamd `nodejs` in CentOS/RHEL 8 en Fedora. - -```bash -dnf module install nodejs: -``` - -waar `` overeenkomt met de hoofdversie van Node.js. Voor een lijst met beschikbare streams: - -```bash -dnf module list nodejs -``` - -Bijvoorbeeld, om Node.js 12 te installeren: - -```bash -dnf module install nodejs:12 -``` - -### Alternatieven - -Deze bronnen bieden packages aan die compatibel zijn met CentOS, Fedora en RHEL. - -- [Node.js snaps](#snap) onderhouden en ondersteund op https://github.com/nodejs/snap -- [Node.js binary distributies](#debian-and-ubuntu-based-linux-distributions) onderhouden en ondersteund door [NodeSource](https://github.com/nodesource/distributions) - -## Debian en Ubuntu gebaseerde Linux-distributies - -[Node.js binary-distributies](https://github.com/nodesource/distributions) zijn beschikbaar bij NodeSource. - -### Alternatieven - -Packages die compatibel zijn met op Debian en Ubuntu gebaseerde Linux-distributies zijn beschikbaar op [Node.js snaps](#snap). - -## fnm - -Snelle en eenvoudige Node.js versiebeheerder geschreven in Rust, wordt gebruikt om meerdere uitgebrachte Node.js versies te beheren. Hiermee kunt u bewerkingen uitvoeren zoals: install, uninstall, switch Node versions, enz. Om fnm te installeren, kunt u dit [script](https://github.com/Schniz/fnm#using-a-script-macoslinux) gebruiken. - -fnm heeft cross-platform ondersteuning (macOS, Windows, Linux) & wordt ook ondersteund door alle populaire shells (Bash, Zsh, Fish, PowerShell, Windows Command Line Prompt). fnm is gebouwd met snelheid in het achterhoofd en met compatibiliteit voor `.node-version` en `.nvmrc` bestanden. - -## FreeBSD - -De meest recente release van Node.js is beschikbaar op de [www/node](https://www.freshports.org/www/node) poort. - -Installeer een binary-package via [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): - -```bash -pkg install node -``` - -Of compileer het zelf met behulp van [ports](https://www.freebsd.org/cgi/man.cgi?ports): - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js is beschikbaar in de portage-tree. - -```bash -emerge nodejs -``` - -## IBM i - -LTS-versies van Node.js (van IBM) zijn beschikbaar en verkrijgbaar via [de 'yum' package-manager](https://ibm.biz/ibmi-rpms). De package-name is `nodejs` gevolgd door het hoofdversienummer (bijvoorbeeld: `nodejs12`, `nodejs14`, enz.) - -Om Node.js 14.x vanuit de command-line te installeren, voert u het onderstaande commando uit met een gebruiker die \*ALLOBJ machtigingen heeft: - -```bash -yum install nodejs14 -``` - -Node.js kan ook worden geïnstalleerd met IBM i Access Client Solutions. Zie [dit support-document](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) voor meer informatie - -## macOS - -Download de [macOS-installer](https://nodejs.org/en/#home-downloadhead) op de [nodejs.org](https://nodejs.org/) website. - -_Als je het package met bash wilt downloaden:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### Alternatieven - -Met **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -Met **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -Met **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -Installeer de binary-package: - -```bash -pkgin -y install nodejs -``` - -Of bouw handmatig vanuit pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## n - -`n` is een eenvoudig te gebruiken Node.js versiebeheerder voor Mac en Linux. Met `n` kunt u een doelversie specifieren (met gebruik van een rich-syntax) om te downloaden, of kiezen uit een lijst van eerder gedownloade versies. De versies worden system-wide of user-wide geïnstalleerd, en voor meer gericht gebruik kunt u een versie direct vanuit de cached-downloads uitvoeren. - -Bezoek de [homepage](https://github.com/tj/n) voor installatiemethoden (bootstrap, npm, Homebrew, third-party), en alle gebruiksdetails. - -Als je `npm` al hebt geïnstalleerd dan is het installeren van `n` en de nieuwste LTS `node` versie zo simpel als: - -``` -npm install -g n -n lts -``` - -## NetBSD - -Node.js is beschikbaar in de pkgsrc-tree: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -Of installeer een binary-package (indien beschikbaar voor uw platform) met pkgin: - -```bash -pkgin -y install nodejs -``` - -## Nodenv - -`nodenv` is een lightweight node versiebeheerder, vergelijkbaar met `nvm`. Het is simpel, voorspelbaar en heeft een rijk ecosysteem aan plugins die u kunt aanpassen aan uw behoeften. Gebruik `nodenv` om een Node-versie te kiezen voor uw applicatie en te garanderen dat uw ontwikkel- en productieomgeving overeenkomen. - -Nodenv installatie-instructies zijn beschikbaar op [Github](https://github.com/nodenv/nodenv#installation). Bezoek a.u.b. de GitHub-pagina om er zeker van te zijn dat u de correcte installatiestappen volgt. - -## nvm - -Node Version Manager is een bash script dat gebruikt wordt om verschillende Node.js versies te beheren. Het laat u handelingen uitvoeren zoals: install, uninstall, switch version, enz. Gebruik dit [installatiescript](https://github.com/nvm-sh/nvm#install--update-script) om nvm te installeren. - -Op Unix / OS X systemen kan Node.js (vanuit broncode) geïnstalleerd worden met behulp van [nvm](https://github.com/creationix/nvm) door het te installeren op de locatie waar nvm dit verwacht: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -Hierna kan `nvm` gebruikt worden om te schakelen tussen uitgebrachte versies en versies gebouwd vanuit broncode. Bijvoorbeeld, als de versie van Node.js v8.0.0-pre is: - -```bash -nvm use 8 -``` - -Zodra de officiële versie uitgebracht is, kunt u de versie gebouwd vanuit broncode verwijderen: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -De `nvs` versiebeheerder is cross-platform en kan gebruikt worden op Windows, macOS en Unix-like systemen. - -Ga naar de [release-pagina](https://github.com/jasongin/nvs/releases) en download de MSI-installer van de laatste release. - -Het is ook mogelijk om `chocolatey` te gebruiken om `nvs` te installeren: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -[Hier](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) kunt de documentatie over de installatiestappen van `nvs` in macOS/Unix-like systemen terugvinden - -#### Gebruik - -Hierna kan `nvs` gebruiken om te wisselen tussen verschillende versies van node. - -Om de laatste versie van node toe te voegen: - -```bash -nvs add latest -``` - -Of om de laatste LTS-versie van node toe te voegen: - -```bash -nvs add lts -``` - -Voer hierna het `nvs use` commando uit om een versie van node toe te voegen aan je `PATH` voor de huidige shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -Gebruik `nvs link`, om het permanent aan `PATH` toe te voegen: - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js is beschikbaar via het ports-systeem. - -```bash -/usr/ports/lang/node -``` - -Met [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) op OpenBSD: - -```bash -pkg_add node -``` - -## openSUSE en SLE - -Node.js is beschikbaar in de main-repositories onder de volgende packages: - -- **openSUSE Leap 15.2**: `nodejs10`, `nodejs12`, `nodejs14` -- **openSUSE Tumbleweed**: `nodejs16` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs10`, `nodejs12`, and `nodejs14` (De module "Web and Scripting" moet [ingeschakeld](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12-SP5/#intro-modulesExtensionsRelated) zijn.) -- **SUSE Linux Enterprise Server (SLES) 15 SP2**: `nodejs10`, `nodejs12`, and `nodejs14` (De module "Web and Scripting" moet [ingeschakeld](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/15/#Intro.Module) zijn.) - -Om bijvoorbeeld Node.js 14.x op openSUSE Leap 15.2 te installeren, voert u het volgende commando uit als root: - -```bash -zypper install nodejs14 -``` - -Het is mogelijk om verschillende versies van Node te installeren en deze tegelijkertijd te gebruiken. - -## SmartOS en illumos - -SmartOS-images komen voorgeïnstalleerd met pkgsrc. Op andere illumos-distributies dient u eerst **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)** installeren, hierna kunt u de binary-package installeren. - -```bash -pkgin -y install nodejs -``` - -Of bouw handmatig vanuit pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Snap - -[Node.js snaps](https://github.com/nodejs/snap) zijn beschikbaar als [`node`](https://snapcraft.io/node) in de Snap-store. - -## Solus - -Solus biedt Node.js aan in zijn main-repository. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux levert Node.js in zijn main-repository. - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -Download de [Windows Installer](https://nodejs.org/en/#home-downloadhead) rechtstreeks op de [nodejs.org](https://nodejs.org/) website. - -### Alternatieven - -Met **[Winget](https://aka.ms/winget-cli)**: - -```bash -winget install OpenJS.NodeJS -# or for LTS -winget install OpenJS.NodeJS.LTS -``` - -Na het uitvoeren van een van de bovenstaande commando's kan het nodig zijn om uw terminal-emulator te herstarten voordat het `node` CLI commando beschikbaar wordt. - -Met **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -Met **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -# or for LTS -scoop install nodejs-lts -``` - -## z/OS - -IBM® SDK voor Node.js - z/OS® is beschikbaar in twee installatieformaten, SMP/E en PAX. Selecteer het installatieformaat dat voor u van toepassing is: - -- [Installatie en configuratie van de SMP/E-editie van Node.js op z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-smpe-edition) -- [Installatie en configuratie van de PAX-editie van Node.js op z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-pax-edition) diff --git a/pages/nl/download/releases.md b/pages/nl/download/releases.md deleted file mode 100644 index 7ce37e6f3afd1..0000000000000 --- a/pages/nl/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Vorige Releases -modules: 'NODE_MODULE_VERSION verwijst naar het ABI (application binary interface) versienummer van Node.js, wordt gebruikt om te bepalen welke versies van Node.js gecompileerde C++ add-on binaries kunnen worden geladen zonder te re-compilen. Het werd oorspronkelijk opgeslagen als hexadecimale waarde, maar wordt nu weergeven als een integer.' ---- - -### io.js & Node.js - -Releases van 1.x tot en met 3.x werden "io.js" genoemd, omdat ze deel uitmaakten van de io.js-fork. Vanaf Node.js 4.0.0 zijn de vormalige releases van io.js geconvergeerd met Node.js 0.12.x in uniforme Node.js-releases. - -### Op zoek naar de laatste release van een version branch? diff --git a/pages/nl/index.md b/pages/nl/index.md deleted file mode 100644 index 0198c5f350a9c..0000000000000 --- a/pages/nl/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Huidige Versie - download: Download - download-for: Download voor - other-downloads: Andere Downloads - current: Huidig - lts: LTS - tagline-current: Laatste Features - tagline-lts: Aanbevolen Voor Meeste Gebruikers - changelog: Changelog - api: API Documentatie - version-schedule-prompt: Of bekijk de - version-schedule-prompt-link-text: Long Term Support (LTS) schedule ---- - -Node.js® is een JavaScript runtime gebouwd op [Chrome's V8 JavaScript engine](https://v8.dev/). diff --git a/pages/pt-br/404.md b/pages/pt-br/404.md deleted file mode 100644 index 473d20b893144..0000000000000 --- a/pages/pt-br/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Página não encontrada - -### ENOENT: Arquivo ou diretório não encontrado diff --git a/pages/pt-br/about/governance.md b/pages/pt-br/about/governance.md deleted file mode 100644 index 66df258e29a1f..0000000000000 --- a/pages/pt-br/about/governance.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Governança do projeto -layout: about.hbs ---- - -# Governança do projeto - -## Processo de busca por consenso - -O projeto Node.js segue um modelo de [Busca por Consenso][] para a tomada de decisões. - -## Colaboradores - -O repositório principal [nodejs/node][] no GitHub é mantido por Colaboradores nomeados continuamente pelo Comitê Técnico de Direção ([TSC][]). - -Indivíduos que fazem contribuições significativas e valiosas se tornam Colaboradores e ganham acesso para realizar commits ao projeto. Essas pessoas são identificadas pelo Comitê e suas nomeações são discutidas com os colaboradores já existentes. - -Para conhecer a lista atual de Colaboradores, consulte o [README.md][] do projeto. - -Um guia para Colaboradores é mantido em [collaborator-guide.md][]. - -## Comitê Técnico de Direção - -O projeto é regido pelo [Comitê Técnico de Direção (TSC em inglês)][], responsável pela orientação de alto nível do projeto. - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[Busca por Consenso]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Comitê Técnico de Direção (TSC em inglês)]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/pt-br/about/index.md b/pages/pt-br/about/index.md deleted file mode 100644 index cabf4d4d83915..0000000000000 --- a/pages/pt-br/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Sobre -trademark: Marca registrada ---- - -# Sobre Node.js® - -Como um tempo de execução assíncrono conduzido por eventos de JavaScript, Node.js é projetado para construir aplicativos escaláveis e de rede. No exemplo "hello world" seguinte, muitas conexões podem ser tratadas simultaneamente. Em cada conexão, o callback é acionado, mas se não houver trabalho a ser feito, o Node.js ficará inativo. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Olá Mundo'); -}); - -server.listen(port, hostname, () => { - console.log(`Servidor executando em http://${hostname}:${port}/`); -}); -``` - -Observe que isso contrasta com o modelo de concorrência, muito comúm hoje em dia, no qual são usadas as threads do Sistema Operacional. Entretanto, uma rede baseada em threads se torna relativamente ineficiente e muito difícil de usar. Além disso, os usuários do Node.js não precisam se preocupar em bloquear processos, já que não existem bloqueios. Quase nenhuma função no Node.js executa diretamente operações I/O, e por isso, o processo nunca se bloqueia, exceto quando o I/O é realizado usando métodos síncronos de Node.js da biblioteca padrão. Como nada se bloqueia, é razóavel usar Node.js para desenvolver sistemas escaláveis. - -Se alguns destes termos não são familiares, há um artigo completo ao respeito: [Bloqueando vs. Não Bloqueando][]. - ---- - -Node.js é semelhante no design, e bastante influenciado, por sistemas como os de [Máquina de Eventos][] do Ruby ou como o [Twisted][]do Python. Porém, Node.js leva o modelo de eventos para um pouco mais além. De fato, o Node.js apresenta um [laço de eventos][] como uma construção de tempo de execução em vez de como uma biblioteca. Já em outros sistemas, sempre há uma chamada de bloqueio para iniciar o laço de eventos. Normalmente, o comportamento é definido através de callbacks no início de um script e, no final, um servidor é iniciado através de uma chamada de bloqueio como `EventMachine::run()`. Entretanto, em Node.js não existe essa chamada-inicial-para-o-começo-do-laço. De fato, o Node.js simplesmente entra no laço de eventos após executar o script de entrada. E, posteriormente, o Node.js sai do laço de eventos quando não há mais callbacks para executar. Esse comportamento é como o JavaScript do navegador: o laço de eventos é oculto para o usuário. - -O HTTP é um cidadão de primeira classe no Node.js, pois ele é desenhado com fluxo e baixa latência. Isso torna o Node.js bem adequado para a criação de uma biblioteca ‘web’ ou qualquer framework. - -O fato do Node.js ser desenhado sem threads não quer dizer que não podamos tirar proveito de um ambiente com múltiplos núcleos. Por exemplo, processos filho podem ser gerados usando nossa API [`child_process.fork()`][], pois foi desenhada para uma fácil comunicação. Por outro lado, o módulo [`cluster`][] foi construido com a mesma interfase. Este módulo permite compartilhar soquetes entre processos para abilitar o equilibro da carga entre os núcleos. - -[Bloqueando vs. Não Bloqueando]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[laço de eventos]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Máquina de Eventos]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/pt-br/docs/es6.md b/pages/pt-br/docs/es6.md deleted file mode 100644 index 9bbe1db24f4fc..0000000000000 --- a/pages/pt-br/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) e além -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) e além - -Node.js é construído contra novas versões do [V8](https://v8.dev/). Mantendo-se em dia com as últimas atualizações desse motor, nós garantimos que as novas funcionalidades da [especificação JavaScript ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm) são trazidas para os desenvolvedores de Node.js em tempo hábil, assim como as melhorias contínuas de performance e estabilidade. - -Todas as funcionalidades ECMAScript 2015 (ES6) são divididas em três grupos: **em produção**, em **homologação** e em **andamento**: - -- Todas as funcionalidades **em produção**, consideras estáveis pelo V8, tornam-se **ativadas por padrão em Node.js** e **NÃO** necessitam de nenhuma opção de tempo de execução. -- As funcionalidades em **homologação**, cujo são recursos quase concluídos, mas não são considerados estáveis pela equipe V8, requerem uma opção de tempo de execução: `--harmony`. -- Em **andamento**, seriam as funcionalidades que podem ser ativadas individualmente pela sua respectiva opção harmony, embora isso seja muito desencorajado a menos que seja para fins de teste. Nota: essas opções são expostas pelo V8 e potencialmente podem mudar sem qualquer aviso de descontinuidade. - -## Quais funcionalidades são enviadas com cada versão do Node.js por padrão? - -O site [node.green](https://node.green/) fornece uma excelente visão geral sobre funcionalidades ECMAScript suportados em várias versões de Node.js, baseadas na tabela de compatibilidades do kangax. - -## Quais funcionalidades estão em andamento? - -Novas funcionalidades estão sendo constantemente adicionadas ao motor do V8. É esperado que elas apareçam em alguma versão futura do Node.js, porém sem uma previsão precisa de quando isso irá acontecer. - -Você pode listar todas as funcionalidades _em andamento_ disponíveis em cada versão do Node.js utilizando o `grep` em conjunto com a opção `--v8-options`. É importante notar que essas funcionalidades podem estar incompletas ou quebradas no V8, portanto use-as por sua conta e risco: - -```bash -node --v8-options | grep "in progress" -``` - -## Eu tenho a minha infraestrutura configurada para suportar a flag --harmony. Eu devo remove-la? - -O comportamento atual da flag `--harmony` é habilitar somente funcionalidades **em homologação**. Além disso, ela agora é um sinônimo da flag `--es_staging`. Como mencionado anteriormente, estas funcionalidades estão completas, mas não foram consideradas estáveis ainda. Se você deseja rodar sua aplicação de forma segura, especialmente em ambientes de produção, considere remover esta flag até que ela seja lançada por padrão no V8 e, consequentemente, no Node.js. Se você deseja a manter habilitada, você deve estar preparado para atualizações futuras do Node.js que podem quebrar o seu código caso o V8 mude a sua semântica para seguir o padrão de maneira mais fiel. - -## Como eu encontro qual versão do V8 foi embarcada com uma versão particular do Node.js? - -O Node.js provê uma maneira simples de listar todas as dependências e suas respectivas versões que são lançadas com um binário específico através do objeto global `process`. No caso da engine do V8, digite o seguinte comando no seu terminal para recuperar a sua versão: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/pt-br/docs/guides/abi-stability.md b/pages/pt-br/docs/guides/abi-stability.md deleted file mode 100755 index a2267605a15d9..0000000000000 --- a/pages/pt-br/docs/guides/abi-stability.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Estabilidade ABI -layout: docs.hbs ---- - -# Estabilidade ABI - -## Introdução - - - -Uma Interface Binária de Aplicação (IBA, ou _Application Binary Interface (ABI)_ em inglês) -é uma forma que programas utilizam para chamar funções e utilizar estruturas de -dados de outros programas compilados. É a versão compilada de uma Interface -de Programação de Aplicações (API). Em outras palavras, os arquivos de -cabeçalho que descrevem as classes, funções, estruturas, enumeradores -e constante que permitem a aplicação performar uma tarefa desejada -correspondem, a nível de compilação, a um conjunto de endereços, valores de -parâmetros esperados, tamanhos de estruturas de memória e layouts com os quais -o provedor da ABI foi compilado. - - - -A aplicação que está usando o ABI deve ser compilada de tal maneira que -os endereços disponíveis, valores esperados de parâmetros, tamanhos de -estruturas de memória e layouts concordem com aqueles com os quais o -provedor da ABI foi compilado. Isto é normalmente feito compilando -a aplicação utilizando os headers providos pelo provedor da ABI. - - - -Já que o provedor da ABI e o usuário da ABI podem ser compilados em tempos -diferentes e com versões diferentes do compilador, uma porção da responsabilidade -de garantir a compatibilidade da ABI está no compilador. Diferentes versões -do compilador, talvez providas por diferentes fornecedores, devem todas -produzir a mesma ABI a partir de um arquivo de cabeçalho com um conteúdo -determinado, e devem produzir código para a aplicação utilizando a ABI -que acessa a API descrita em um dado cabeçalho de acordo com as convenções -da ABI resultantes das descrições no cabeçalho. Compiladores modernos tem um histórico -relativamente bom em não quebrar esta compatibilidade nas aplicações que -compilam. - - - -O resto da responsabilidade por garantir a compatibilidade da API está no -time que mantém os arquivos de cabeçalho que criam a API que, após compilada, -resulta na ABI que deve permanecer estável. Mudanças nesses arquivos de -cabeçalho podem ser feitas, porém a natureza destas mudanças deve ser -acompanhada de perto para garantir que, após a compilação, a ABI não mude -de forma que usuários existentes percam a compatibilidade com a nova versão. - -## Estabilidade da ABI no Node.js - - - -O Node.js possui diversos arquivos de cabeçalhos que são mantidos por diversos -times independentes, por exemplo, cabeçalhos como `node.h` e `node_buffer.h` são -mantidos pela equipe do Node.js. `v8.h` é mantido pela equipe do V8 que, mesmo -sendo muito próxima da equipe do Node.js, é ainda sim independente e possui suas -próprias agendas e prioridades. Portanto, o time do Node.js só possui controle -parcial sobre as mudanças que são introduzidas nos cabeçalhos que o projeto possui. -Como resultado, o projeto do Node.js adotou o [semantic versioning](https://semver.org/). -Isto garante que as APIs providas pelo projeto vão resultar em uma ABI estável -para todas as versões minor e patch do Node.js lançadas dentro de uma major. -Na prática, isso significa que o projeto como um todo se comprometeu a garantir -que um módulo nativo do Node.js que for compilado contra uma versão major do Node.js -vai carregar com sucesso em todas as versões minor ou patch dentro desta versão -major sobre a qual o addon foi compilado. - -## N-API - - - -Uma demanda para equipar o Node.js com uma API que resulta em uma ABI que permanece -estável dentre múltiplas versões major do Node.js acabou surgindo. A motivação para -criar tal API são as seguintes: - -- A linguagem JavaScript permaneceu compatível com ela mesma desde o seus - primeiros dias, enquanto a ABI do engine que executa o código JavaScript muda - com cada versão major do Node.js. Isso significa que aplicações que consistem - de pacotes do Node.js que são completamente escritos em JavaScript não precisam - ser recompilados, reinstalados ou sofrer um novo deploy uma vez que uma nova - versão major do Node.js é instalada no ambiente de produção onde tal aplicação - está sendo executada. Em contraste a isso, se uma aplicação depende de m pacote - que contém um módulo nativo, então a aplicação precisa ser recompilada, reinstalada - e reexecutada sempre que uma nova versão major do Node.js é introduzida em seu ambiente - de produção. Essa disparidade entre os pacotes que contém addons nativos e os que são - escritos com JavaScript em sua totalidade acabou por adicionar um peso a mais na - manutenção em sistemas que estão em produção e dependem de addons nativos. - -- Outros projetos começaram a produzir interfaces JavaScript que são, essencialmente, - alternativas às implementações do Node.js. Uma vez que estes projetos são, geralmente, - criados e construídos em um engine JavaScript diferente do V8, seus addons nativos - necessariamente tem uma estrutura diferente e usam uma API diferente. Mesmo assim, - utilizar uma única API para um módulo nativo entre diferentes implementações da - API JavaScript do Node.js permitiria que estes projetos tirassem vantagem do - ecossistema de pacotes JavaScript que já se acumulou ao redor do Node.js. -- O Node.js pode mudar para utilizar um engine JavaScript diferente do V8 no futuro. - Isto significa que, externamente, todas as interfaces do Node.js continuariam iguais, - porém o cabeçalho do V8 não existiria. Tal alteração causaria uma disrupção do - ecossistema do Node.js no geral, e também do ecossistema de addons nativos em particular, - se a API que é agnóstica do engine JavaScript que está sendo utilizado não for provida - pelo Node.js e adotada pelos addons nativos. - - - -Para estas finalidades o Node.js introduziu a N-API na versão 8.6.0 e a marcou como -um componente estável do projeto na versão 8.12.0. A API é definida pelos headers -[`node_api.h`][] e [`node_api_types.h`][], e provê uma garantia de compatibilidade -com versões posteriores que ultrapassam a limitação da versão major do Node.js. -Esta garantia pode ser descrita como o seguinte: - - - -**Uma versão _n_ da N-API estará disponível na versão major do Node.js na qual -ela foi primeiramente publicada, e em todas as versões subsequentes do Node.js, -incluindo versões major.** - - - -Um autor de um módulo nativo pode tirar proveito desta garantia de compatibilidade -da N-API para fazer com que seu módulo só utilize as APIs dispostas no `node_api.h` -e as estruturas de dados e constantes definidas em `node_api_types.h`. Fazendo isto, -o autor facilita a adoção do seu módulo indicando para seus usuários que este módulo -não acarretará em uma reinstalação ou um trabalho extra de manutenção se for instalado. -De forma que este módulo se comportaria da mesma forma que um pacote escrito completamente -em JavaScript. - - - -A N-API é versionada de porque novas APIs são adicionadas de tempos em tempos. -Diferentemente do semantic versioning, as versões do N-API são cumulativas. Isto é, -cada versão da N-API tem o mesmo significado de uma versão minor no sistema semver, -significando que todas as mudanças feitas na N-API são retrocompatíveis. Além disso, -novas N-APIs são adicionadas sob uma flag experimental para dar à comunidade a chance -de serem desligadas em ambientes produtivos. O status experimental significa que, mesmo -que todo o cuidado tenha sido tomado para garantir que a nova API não foi modificada de -forma que se tornasse incompatível com a ABI no futuro, ela ainda não foi suficientemente -testada em produção para ser dada como correta e útil e, por conta disso, pode sofrer -mudanças incompatíveis com a ABI antes de ser finalmente incorporada dentro da próxima -versão da N-API. Isto é, uma versão experimental da N-API ainda não está coberta pela -garantia de compatibilidade com versões posteriores que comentamos anteriormente. - -[`node_api.h`]: https://github.com/nodejs/node/blob/main/src/node_api.h -[`node_api_types.h`]: https://github.com/nodejs/node/blob/main/src/node_api_types.h diff --git a/pages/pt-br/docs/guides/blocking-vs-non-blocking.md b/pages/pt-br/docs/guides/blocking-vs-non-blocking.md deleted file mode 100755 index 18cb40b26d029..0000000000000 --- a/pages/pt-br/docs/guides/blocking-vs-non-blocking.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: Visão geral sobre operações bloqueantes e não bloqueantes -layout: docs.hbs ---- - - - -# Visão geral sobre operações bloqueantes e não-bloqueantes - - - -Esta visão geral cobre as **diferenças** entre chamadas **bloqueantes** e **não-bloqueantes** no Node.js. -Vamos nos referir ao event loop e à libuv, mas não é necessário nenhum conhecimento prévio sobre -estes tópicos. É esperado que o leitor tenha um conhecimento básico de padrões de callback no JavaScript e Node.js. - -> "I/O" se refere, principalmente, à interação com o disco do sistema -> e a rede suportada pela [libuv](http://libuv.org). - - - -## Chamadas bloqueantes - - - -Ser **bloqueante** é quando a execução do código do resto do código JavaScript no processo -do Node.js precisa esperar até que uma operação não-JavaScript seja completada. Isso acontece -porque o event loop é incapaz de continuar executando JavaScript enquanto uma operação -**bloqueante** está sendo executada. - - - -No Node.js, JavaScript que mostra uma performance ruim devido ao fato de que é um -processo que usa CPU intensivamente ao invés de esperar uma operação não-JavaScript, -como I/O, não é geralmente identificada como uma operação **bloqueante**. Métodos -síncronos na biblioteca padrão do Node.js que usam a libuv são as operações **bloqueantes** -mais utilizadas. Módulos nativos também podem conter métodos **bloqueantes**. - - - -Todos os métodos I/O na biblioteca padrão do Node.js tem uma versão assíncrona, -que, por definição, são **não-bloqueantes**, e aceitam funções de callback. Alguns métodos -também tem suas versões **bloqueantes**, que possuem o sufixo `Sync` no nome. - - - -## Comparando códigos - - - -Métodos **bloqueantes** executam de forma **síncrona** e métodos **não-bloqueantes** -executam de forma **assíncrona**. - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // a execução é bloqueada aqui até o arquivo ser lido -``` - - - -E aqui temos um exemplo equivalente usando um método **assíncrono**: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; -}); -``` - - - -O primeiro exemplo parece mais simples do que o segundo, mas ele possui o contra -de que, na segunda linha, temos um código **bloqueando** a execução de qualquer -JavaScript adicional até que todo o arquivo seja lido. Note que, na versão síncrona, -qualquer erro que houver na aplicação vai precisar ser tratado ou então o processo -vai sofrer um crash. Na versão assíncrona, é da decisão do programador se quer ou -não tratar os erros. - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // trava aqui até o arquivo ser lido -console.log(data); -maisProcessamento(); // roda depois de console.log -``` - - - -Um exemplo similar, mas não equivalente, no formato assíncrono: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -maisProcessamento(); // vai rodar antes do console.log -``` - - - -No primeiro exemplo acima, `console.log` vai ser chamado antes de `maisProcessamento()`. -No segundo exemplo, `fs.readFile()` é uma operação **não-bloqueante**, então a execução -de código JavaScript vai continuar e o método `maisProcessamento()` vai ser chamado -primeiro. A habilidade de executar `maisProcessamento()` sem ter de esperar o arquivo -ser completamente lido é um conceito chave de design que permite uma melhor escalabilidade -através de mais rendimento. - -## Concorrência e Rendimento - - - -A execução do JavaScript no Node.js é single threaded. Então a concorrência é -referente somente à capacidade do event loop de executar funções de callback -depois de completar qualquer outro processamento. Qualquer código que pode -rodar de maneira concorrente deve permitir que o event loop continue executando -enquanto uma operação não-JavaScript, como I/O, está sendo executada. - - - -Como um exemplo, vamos considerar o caso onde cada requisição de um servidor web -leva 50ms para ser completada e 45ms desses 50ms é I/O de banco de dados que pode -ser realizado de forma assíncrona. Escolhendo uma abordagen **não-bloqueante** -vamos liberar esses 45ms por request para que seja possível lidar com outras -requests. Isso é uma diferença bastante significante em capacidade só porque -decidimos utilizar um método **não-bloqueante** ao invés de sua variante -**bloqueante**. - - - -O event loop é diferente de outros modelos em muitas outras linguagens onde threads -adicionais podem ser criadas para lidar com processamento concorrente. - -## Perigos de misturar códigos bloqueantes e não-bloqueantes - - - -Existem alguns padrões que devem ser evitados quando lidamos com I/O. Vamos ver um -exemplo: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -fs.unlinkSync('/file.md'); -``` - - - -No exemplo acima, `fs.unlinkSync()` provavelmente vai rodar antes de `fs.readFile()`, -o que deletaria o arquivo `file.md` antes de que ele possa ser, de fato, lido. Uma forma -melhor de escrever esse código, de forma completamente **não-bloqueante** e garantida de -executar na ordem correta seria: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (readFileErr, data) => { - if (readFileErr) throw readFileErr; - console.log(data); - fs.unlink('/file.md', unlinkErr => { - if (unlinkErr) throw unlinkErr; - }); -}); -``` - - - -O exemplo acima coloca uma chamada **não-bloqueante** a `fs.unlink()` dentro do callback -de `fs.readFile()`, o que garante a ordem correta das operações. - -## Additional Resources - -- [libuv](http://libuv.org/) diff --git a/pages/pt-br/docs/guides/debugging-getting-started.md b/pages/pt-br/docs/guides/debugging-getting-started.md deleted file mode 100755 index b9f117950dcb6..0000000000000 --- a/pages/pt-br/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,330 +0,0 @@ ---- -title: Debugging - Getting Started -layout: docs.hbs ---- - -# Guia de debugging - - - -Este guia vai te ajudar a começar a debugar suas aplicações Node.js. - -## Ative o inspetor - - - -Quando uma aplicação Node.js for iniciada com a flag `--inspect`, o processo irá -esperar por um client de debugging. Por padrão, ele vai ouvir no host e porta -locais `127.0.0.1:9229`. Cada processo também possuirá um [UUID][] único. - - - -Clients do inspector devem saber e especificar o endereço do host, porta e UUID -para se conectarem. Uma URL completa é mais ou menos assim: -`ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e` - - - -O Node.js também irá ouvir mensagens de debugging se o processo receber um sinal do tipo -`SIGUSR1` (o `SIGUSR1` não está disponível no Windows). No Node.js 7 e anteriores, isto -ativa a API legada de debugging. Nas versões 8 para frente, isto vai ativar a API de -inspeção. - ---- - -## Implicações de segurança - - - -Uma vez que o debugger tem total acesso ao ambiente de execução do Node. Um ator -malicioso que tiver acesso a conexão por esta porta pode executar um código qualquer -em nome do processo que está sendo invadido. É importante notar e entender as implicações -de se expor a porta de debugging em redes públicas ou privadas. - -### Expor a porta de debugging publicamente é inseguro - - - -Se o debugger está conectado a um endereço de IP público, ou 0.0.0.0, qualquer client -que puder chegar neste endereço vai poder se conectar a ele sem nenhuma restrição e -vai ser capaz de rodar qualquer código. - - - -Por padrão `node --inspect` se liga a `127.0.0.1`. Você precisa explicitamente dar um -endereço de IP ou 0.0.0.0, etc. Se você deseja permitir conexões externas. Fazer isto -pode expor sua aplicação a uma falha de segurança potencialmente significante. Nós -sugerimos que você garante que todos os firewalls e controles de acesso existam e estejam -configurados de acordo para prevenir tal exposição. - - - - -Veja a seção sobre '[Ativando cenários de debugging remoto](#enabling-remote-debugging-scenarios)' para dicas de como permitir -de forma segura que outros clients se conectem. - -### Aplicações locais tem acesso total ao inspetor - - - -Mesmo que você conecte a porta do inspetor a 127.0.0.1 (o padrão), qualquer aplicação -que rode localmente na sua máquina vai ter acesso sem restrições ao mesmo. Isto foi -desenhado para ser assim para permitir que debuggers locais possam se conectar de forma -mais simples. - -### Browsers, websockets e políticas de mesma origem - - - -Sites abertos em um navegador podem fazer requisições via websockets e HTTP -desde que estejam dentro do modelo de segurança do browser. Uma conexão HTTP inicial -é necessária para obter um ID único para uma sessão de debugging. Para mais segurança -contra [ataques de rebinding de DNS](https://en.wikipedia.org/wiki/DNS_rebinding), -o Node.js verifica se o header `Host` para a conexão especificam ou um endereço de IP -que seja exatamente `localhost`. - - - -Estas políticas de segurança não permitem a conexão a um servidor de debug remoto -somente especificando o hostname. Você pode contornar essa restrição especificando -ou um IP ou usando um túnel SSH como descrito abaixo. - -## Clients de Inspetores - - - -Muitas ferramentas comerciais e open source podem se conectar ao inspetor do Node. Aqui -estão as informações básicas sobre eles: - -### [node-inspect](https://github.com/nodejs/node-inspect) - -- Um debugger de linha de comando que é mantido pela Node.js Foundation, utiliza o [Protocolo de Inspeção][] -- A última versão pode ser instalada de forma independente (usando `npm install -g node-inspect`) e utilizada com `node-inspect script.js` - -#### [Chrome DevTools](https://github.com/ChromeDevTools/devtools-frontend) 55+ - -- **Opção 1**: Abra uma nova aba em `chrome://inspect` em qualquer navegador baseado no Chromium. Clique no botão `configure` e tenha certeza que sua porta e host estão listados -- **Opção 2**: Copie o `devtoolsFrontendUrl` da saída do `/json/list` (veja acima) ou da flag --inspect e cole no Chrome -- **Opção 3**: Instale a extensão NIM (Node Inspector Manager): https://chrome.google.com/webstore/detail/nim-node-inspector-manage/gnhhdgbaldcilmgcpfddgdbkhjohddkj - -#### [Visual Studio Code](https://github.com/microsoft/vscode) 1.10+ - -- No painel "Debug", clique no icone de configurações para abrir `./vscode/launch.json` - Seleciona "Node.js" para o setup inicial - -#### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- Escolha "Debug > Start Debugging" no menu ou aperte F5 -- [Mais detalhes](https://github.com/Microsoft/nodejstools/wiki/Debugging). - -#### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) 2017.1+ e outros IDEs da JetBrains - -- Crie uma nova configuraçõ de debug para Node.js e aperte o botão "Debug". A flag `--inspect` será usada - por padrão para o Node.js 7 ou superior. Para desativar esse comportamento, desmarque `js.debugger.node.use.inspect` no registro da IDE. - -#### [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - - - -- Biblioteca para facilitar a conexão nos protocolos de inspeção - -#### [Gitpod](https://www.gitpod.io) - - - -- Crie uma nova configuração de debug para Node.js a partir da view `Debug` ou aperte `F5`. [Mais instruções aqui](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1) - ---- - -## Opções de linha de comando - - - -Abaixo temos a lista de todas as flags que impactam a linha de comando enquanto em debugging: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FlagSignificado
--inspect -
    -
  • Ative o agente do inspetor
  • -
  • Ouve no endereço e porta padrões (127.0.0.1:9229)
  • -
-
--inspect=[host:porta] -
    -
  • Ativa o agente do inspetor
  • -
  • Faz a conexão com o endereço ou hostname descrito em host (padrão: 127.0.0.1)
  • -
  • Ouve a porta descrita em porta (padrão: 9229)
  • -
-
--inspect-brk -
    -
  • Ativa o agente do inspetor
  • -
  • Ouve no endereço e porta padrões (127.0.0.1:9229)
  • -
  • Pausa antes do código do usuário iniciar
  • -
-
--inspect-brk=[host:port] -
    -
  • Ativa o agente do inspetor
  • -
  • Faz a conexão com o endereço ou hostname descrito em host (default: 127.0.0.1)
  • -
  • Ouve na porta descrita por porta (padrão: 9229)
  • -
  • Pausa antes do código do usuário iniciar
  • -
-
node inspect script.js -
    -
  • Inicia um child process para executar um script do usuário sob a flag --inspect; e usa o processo principal para executar o CLI do debugger.
  • -
-
node inspect --port=xxxx script.js -
    -
  • Inicia um child process para executar um script do usuário sob a flag --inspect; e usa o processo principal para executar o CLI do debugger.
  • -
  • Ouve na porta descrita por porta (padrão: 9229)
  • -
-
- ---- - -## Ativando cenários de debugging remoto - - - -Nós recomendamos que você nunca faça com que o debugger ouça um IP público. Se você -precisar permitir conexões de debug remotas, nós recomendamos que use um túnel SSH. -Os exemplos a seguir são apenas ilustrativos. Por favor entenda que existe um risco -grande de segurança ao permitir acesso a um serviço privilegiado antes de continuar. - - - -Digamos que você esteja executando o Node em uma máquina remota, com o endereço `remoto.exemplo.com`, que -você quer ser capaz de debugar. Nesta máquina, você deve iniciar o processo do node com o inspetor ouvindo -somente o `localhost` (o padrão) - -```bash -node --inspect server.js -``` - - - -Agora, na sua máquina local, de onde você quer iniciar uma conexão de debug, -crie um tunel SSH: - -```bash -ssh -L 9221:localhost:9229 user@remoto.exemplo.com -``` - - - -Isso inicia um tunel SSH onde a conexão para a porta 9221 na sua máquina local vai ser -direcionada para a porta 9229 no servidor remoto.exemplo.com. Agora você pode anexar -um debugger, como o Chrome DevTools ou o Visual Studio Code, ao `localhost:9221`, -que deve ser capaz de debugar como se a aplicação estivesse sendo executada localmente. - ---- - -## Debugger legado - - - -**O debugger legado foi depreciado na versão 7.7.0 do Node. Por favor utilize --inspect e -o inspetor ao invés dele** - - - -Quando iniciado com a flag **--debug** ou **--debug-brk** na versão 7 e anteriores, -o Node.js começa a ouvir por comandos de debug definidos pelo protocolo de debug do V8, -que já foi descontinuado, em uma porta TCP que, por padrão, é a `5858`. Qualquer client de debugging -que conversa com esse protocolo pode conectar a ele e debugar um processo sendo executado; abaixo temos -alguns dos mais populares. - -### [Debugger nativo](https://nodejs.org/dist/latest/docs/api/debugger.html) - - - -Rode como `node debug script.js` para iniciar seu script através do debugger nativo -de linha de comando. Seu script vai ser iniciado em um outro processo do node -que vai ser rodado com a flag `--debug-brk`, e o processo inicial do Node vai executar -o script `_debugger.js` e conectar à sua aplicação. - -### [node-inspector](https://github.com/node-inspector/node-inspector) - - - -Utiliza o Chrome DevTools para debugar sua aplicação Node.js através de um processo -intermediário que traduz o protocolo de inspeção utilizado no Chromium para a o -protocolo de debug do V8 utilizado no Node.js. - - - -[Protocolo de Inspeção]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/pt-br/docs/guides/diagnostics-flamegraph.md b/pages/pt-br/docs/guides/diagnostics-flamegraph.md deleted file mode 100755 index fea3db0a34e33..0000000000000 --- a/pages/pt-br/docs/guides/diagnostics-flamegraph.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: Diagnostics - Flame Graphs -layout: docs.hbs ---- - -# Flame Graphs - -## Para que serve um Flame Graph? - - - -Flame graphs são uma forma de visualizar o tempo de CPU gasto em funções. Eles podem ajudar você a identificar onde você pode estar gastando muito tempo fazendo processamento síncrono. - -## Como criar um Flame Graph - - - -Você deve ter ouvido que criar Flame Graphs pro Node.js era complicado, mas isso não é verdade (não mais). -VMs com Solaris não são mais necessárias para criação de Flame Graphs! - - - -Flame Graphs são gerados a partir da saída do `perf`, que não é uma ferramenta específica do Node. Enquanto ela é a forma mais poderosa de visualizar o tempo gasto em CPU, ela também pode ter problemas com como o código JavaScript é otimizado nas versões superiores à 8 do Node.js. Veja a seção [problemas de saída do perf](#problemas-de-saída-do-perf). - -### Usando uma ferramenta pré-empacotada - - - -Se você quiser uma ferramenta simples, de um único passo, que produz um Flame Graph rápido localmente, tente o [0x](https://www.npmjs.com/package/0x) - - - -Para diagnosticar problemas em produção, leia estas notas: [0x em servidores de produção][] - -### Criando um Flame Graph com as ferramentas `perf` do sistema - - - -O propósito deste guia é mostrar os passos envolvidos em criar um flame graph e te manter no controle de cada parte. - - - -Se você quiser entender melhor cada passo, dê uma olhada nas seções abaixo onde temos mais detalhes. - - - -Vamos começar! - -1. Instale o `perf` (geralmente disponível através do pacote `linux-tools-common` se já não tiver instalado) -2. tente rodar o comando `perf` - ele pode reclamar sobre alguns módulos não encontrados do kernel, então instale eles também -3. Execute o Node com o `perf` ativado (veja [problemas de saída do perf](#problemas-de-saída-do-perf) para dicas específicas de versões do Node) - - ```bash - perf record -e cycles:u -g -- node --perf-basic-prof app.js - ``` - -4. Ignore os avisos a não ser que eles digam que você não pode rodar o `perf` por conta de pacotes não encontrados; Você pode ter alguns avisos sobre não poder acessar as samples dos módulos do kernel, mas não estamos querendo acessar elas de qualquer forma. -5. Execute `perf script > perfs.out` para gerar o arquivo de dados que já vamos visualizar. É bom [fazer uma limpeza](#filtrando-funções-internas-do-node) para uma saída mais legível -6. Instale o stackvis se não tiver já instalado através de `npm i -g stackvis` -7. Execute `stackvis perf < perfs.out > flamegraph.htm` - - - -Agora abra o arquivo `htm` no seu browser preferido e veja o resultado. Ele tem um código de cores, de forma que você pode focar nas barras mais alaranjadas primeiro. Elas provavelmente representam funções que possuem alto uso de CPU. - - - -Vale mencionar que, ao clicar em um elemento do gráfico, um zoom será aplicado nas redondezas do mesmo e exibido no topo do gráfico. - -### Usando `perf` para visualizar um processo em andamento - - - -Isto é excelente para gravar dados para um flame graph a partir de um processo que já esteja rodando e você não quer interromper, por exemplo, um processo de produção com um problema difícil de reproduzir. - -```bash -perf record -F99 -p `pgrep -n node` -g -- sleep 3 -``` - - - -Mas o que é este `sleep 3`? Ele existe somente para manter o `perf` rodando - mesmo com o `-p` apontando para um PID diferente, o comando precisa ser executado com um processo e finalizado com ele. -O perf executa com o mesmo tempo de vida do comando que você passar para ele, esteja você debugando ou não aquele comando. `sleep 3` garante que o perf rode por 3 segundos. - - - -Porque o `-F` (frequencia de profiling) está em 99? É um default razoável que pode ser ajustado se você quiser. -O `-F99` diz ao perf para tirar 99 amostras por segundo, para mais precisão, aumente o valor. Valores melhores devem produzir menos saídas com resultados também menos precisos. A precisão que você precisa depende de quanto tempo suas funções que precisam de muita CPU demoram para rodar. Se você está procurando a razão de uma lentidão aparente, 99 frames por segundo devem ser mais do que suficientes. - - - -Depois de 3 segundos de gravação do perf, gere o flame graph com os últimos dois passos mostrados acima. - -### Filtrando funções internas do Node - - - -Geralmente só queremos olhar a performance do nosso próprio código, então é muito importante filtrarmos as funções internas do Node e do V8 para que o gráfico fique mais simples de ler. Você pode limpar o arquivo com o seguinte comando: - -```bash -sed -i -r \ - -e "/( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)/d" \ - -e 's/ LazyCompile:[*~]?/ /' \ - perfs.out -``` - - - -Se você ler o gráfico e ele parecer esquisito, como se houvesse algo faltando na função que está levando mais tempo, tente gerar o gráfico sem o filtro - as vezes você pode ter encontrado um problema com o Node.js em si. - -### Opções de profiling do Node.js - - - -A flag `--perf-basic-prof-only-functions` e `--perf-basic-prof` são duas das opções que são úteis para debugar seu código JavaScript. Outras opções são usadas para debugar o Node.js em si, o que está fora do escopo deste guia. - - - -`--perf-basic-prof-only-functions` produz menos saídas, então é a opção com menos overhead. - -### Por que eu preciso disso? - - - -Bom, sem essas opções você ainda tem o mesmo flame graph, mas com a maioria das barras com a label `v8::Function::Call` - -## Problemas de saída do `perf` - -### Mudanças na pipeline do V8 para o Node.js 8.x - - - -As versões 8.x e acima do Node.js possuem novas otimizações para a compilação do JavaScript no V8, que fazem com que as referências/nomes das funções ilegíveis para o perf algumas vezes. (O novo compilado é chamado TurboFan) - - - -Por conta disso os nomes das funções podem não estar corretos no gráfico. - - - -Você vai notar um `ByteCodeHandler:` onde deveria haver um nome de função. - - - -O [0x](https://www.npmjs.com/package/0x) tem algumas mitigações para isso já no próprio sistema. - - - -Para mais detalhes veja: - -- https://github.com/nodejs/benchmarking/issues/168 -- https://github.com/nodejs/diagnostics/issues/148#issuecomment-369348961 - -### Node.js 10+ - - - -A versão 10.x do Node.js trata o problema com o turboFan usando a flag `--interpreted-frames-native-stack`. - - - -Execute `node --interpreted-frames-native-stack --perf-basic-prof-only-functions` para obter os nomes das funções no gráfico independentemente de que tipo de pipeline o V8 usou para compilar seu código JavaScript. - -### Labels quebradas no gráfico - - - -Se você está vendo labels parecidas com essas: - -``` -node`_ZN2v88internal11interpreter17BytecodeGenerator15VisitStatementsEPNS0_8ZoneListIPNS0_9StatementEEE -``` - - - -Significa que a versão do perf que voc6e está usando no Linux não foi compilada com o support para o demangle, veja https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 para exemplos. - -## Exemplos - - - -Pratique capturando amostras e gerando flame graphs você mesmo com [este exercício](https://github.com/naugtur/node-example-flamegraph)! - -[0x em servidores de produção]: https://github.com/davidmarkclements/0x/blob/master/docs/production-servers.md diff --git a/pages/pt-br/docs/guides/dont-block-the-event-loop.md b/pages/pt-br/docs/guides/dont-block-the-event-loop.md deleted file mode 100644 index 6cdf9d62d5a2e..0000000000000 --- a/pages/pt-br/docs/guides/dont-block-the-event-loop.md +++ /dev/null @@ -1,517 +0,0 @@ ---- -title: Não bloqueie o Event Loop (ou a Worker Pool) -layout: docs.hbs ---- - -# Não bloqueie o Event Loop (ou a Worker Pool) - -## Você deve ler esse guia? - -Se você está escrevendo algo mais complicado que um breve script de linha de comando, ler este guia ajudará você a escrever aplicativos de maior desempenho e mais seguros. - -Este documento foi escrito com servidores Node em mente, mas os conceitos são aplicados para aplicações Node complexas também. -Onde detalhes específicos do sistema operacional variam, este documento é centrado no Linux. - -## Resumo - -O Node.js executa código JavaScript no Event Loop (inicialização e callbacks), e oferece uma Worker Pool para manipular tarefas custosas como I/O de arquivo. -Node escala bem, as vezes mais do que abordagens pesadas como Apache. -O segredo da escalabilidade do Node é que ele usa um pequeno número de threads para manipular muitos clientes. -Se o Node pode trabalhar com menos threads, ele poderá gastar mais tempo do seu sistema e memória trabalhando nos clientes em vez de desperdiçar recursos de espaço e tempo para as threads (memória e mudança de contexto). -Mas pelo fato do Node ter poucas threads, você precisa estruturar sua aplicação para usá-las com sabedoria. - -Aqui está um princípio básico para manter o servidor Node rápido: _Node é rápido quando o trabalho associado a cada cliente em um determinado momento é "pequeno"_. - -Isso se aplica a callbacks no Event Loop e tarefas na Worker Pool. - -## Por que eu devo evitar bloquear o Event Loop e a Worker Pool? - -O Node usa um pequeno número de threads para manipular muitos clientes. -No Node existem dois tipos de threads: um Event Loop (também conhecido como main loop, main thread, event thread, etc.), e uma pool de `k` Workers em uma Worker Pool (também conhecido como threadpool) - -Se uma thread está levando muito tempo para excutar um callback (Event Loop) ou uma tarefa (Worker), nós a chamamos de "bloqueada". -Enquanto uma thread está bloqueada trabalhando para um cliente, ela não pode lidar com requisições de outros clientes. -Isso fornece duas motivações para não bloquear o Event Loop nem a Worker Pool: - -1. Performance: Se você executar regularmente atividades pesadas em qualquer tipo de thread, o _throughput_ (requisições por segundo) do seu servidor sofrerá. -2. Segurança: Se for possível que para determinadas entradas uma de suas threads seja bloqueada, um cliente malicioso pode enviar esse "evil input", para fazer suas threads bloquearem, e mantê-las trabalhando para outros clientes. Isso seria um ataque de [Negação de Serviço](https://en.wikipedia.org/wiki/Denial-of-service_attack) - -## Uma rápida revisão do Node - -O Node usa a Arquitetura Orientada a Eventos: ele tem um Event Loop para orquestração e uma Worker Pool para tarefas custosas. - -### Que código é executado no Event Loop? - -Quando elas começam, aplicações Node primeiro concluem uma fase de inicialização, fazendo "`require`'ing" de módulos e registrando callbacks para eventos. -As Aplicações Node entram no Event Loop, respondendo requisições recebidas do cliente para executar o callback apropriado. -Esse callback executa de forma síncrona, e pode registrar requisições assíncronas para continuar o processamento após a conclusão. - -Os callbacks para essas requisições assíncronas também serão executadas no Event Loop. - -O Event Loop também atenderá às requisições assíncronas não-bloqueantes feitas por seus callbacks, por exemplo, I/O de rede. - -Em resumo, o Event Loop executa os callbacks JavaScript registrados por eventos, e também é responsável atender requisições assíncronas não-bloqueantes, como I/O de rede. - -### Que código é executado na Worker Pool? - -A Worker Pool do Node é implementado na libuv ([docs](http://docs.libuv.org/en/v1.x/threadpool.html)), que expõe uma API geral para envio de tarefas. - -O Node usa a Worker Pool para lidar com tarefas "custosas". -Isso inclui I/O para quais um sistem operacional não fornece uma versão não-bloqueante, bem como tarefas particularmente intensivas em CPU. - -Estas são os módulos de APIs do Node que fazem uso dessa Worker Pool: - -1. I/O intensivo - 1. [DNS](https://nodejs.org/api/dns.html): `dns.lookup()`, `dns.lookupService()`. - 2. [Sistema de arquivo](https://nodejs.org/api/fs.html#fs_threadpool_usage): Todas APIs do sistema de arquivo exceto `fs.FSWatcher()` e aquelas que são explicitamente síncronas usam a threadpool da libuv. -2. CPU intensivo - 1. [Crypto](https://nodejs.org/api/crypto.html): `crypto.pbkdf2()`, `crypto.scrypt()`, `crypto.randomBytes()`, `crypto.randomFill()`, `crypto.generateKeyPair()`. - 2. [Zlib](https://nodejs.org/api/zlib.html#zlib_threadpool_usage): Todas APIs do zlib exceto aquelas que são explicitamente síncronas usam a threadpool da libuv. - -Em muitas aplicações Node, essas APIs são as únicas fontes de tarefas para a Worker Pool. Aplicações e módulos que usam um [C++ add-on](https://nodejs.org/api/addons.html) podem enviar tarefas para a Worker Pool. - -Para cobrir todos os aspectos, observamos que quando você chama uma dessas APIs a partir de um callback no Event Loop, o Event Loop paga alguns custos menores de configuração, pois entra nas ligações do Node C++ para essa API e envia uma tarefa para ao Worker Pool. -Esses custos são insignificantes em comparação ao custo total da tarefa, e é por isso que o Event Loop está sendo menos usado. -Ao enviar uma dessas tarefas para a Worker Pool, o Node fornece um ponteiro para a função C++ correspondente nas ligações Node C++. - -### Como o Node decide qual código executar a seguir? - -De forma abstrata, o Event Loop e a Worker Pool mantêm filas para eventos e tarefas pendentes, respectivamente. - -Na verdade, o Event Loop não mantém realmente uma fila. -Em vez disso, ele possui uma coleção de descritores de arquivos que solicita ao sistema operacional para monitorar, usando um mecanismo como [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html) (Linux), [kqueue](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/FSEvents_ProgGuide/KernelQueues/KernelQueues.html) (OSX), event ports (Solaris), ou [IOCP](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx) (Windows). -Esses descritores de arquivos correspondem aos sockets de rede, aos arquivos que estão sendo monitorados e assim por diante. -Quando o sistema operacional diz que um desses descritores de arquivos está pronto, o Evente Loop o converte para o evento apropriado e chama os callbacks associados com esse evento. -Você pode aprender mais sobre esse processo [aqui](https://www.youtube.com/watch?v=P9csgxBgaZ8). - -Por outro lado, a Worker Pool usa uma fila real cujas entradas são tarefas a serem processadas. -Um Worker abre uma tarefa nesse fila e trabalha nela, e quando concluída, o Worker gera um evento "Pelo menos uma tarefa está concluída" para o Event Loop. - -### O que isso significa para o design da aplicação? - -Em um sistema uma-thread-por-cliente tipo Apache, cada cliente pendente recebe sua própria thread. -Se uma thread que manipula um cliente bloqueado, o sistema operacional irá interropé-lo e dará a vez para outro cliente. -O sistema operacional garante, assim, que os clientes que exigem uma pequena quantidade de trabalho não sejam prejudicados por clientes que exigem mais trabalho. - -Como o Node lida com muitos clientes com poucas threads, se uma thread bloqueia o processamento da requisição de um cliente, as requisições pendentes do cliente podem não ter uma volta até que a thread conclua seu callback ou tarefa. -_O tratamento justo dos clientes é, portanto, de responsabilidade de sua applicação_. -Isso significa que você não deve fazer muito trabalho para nenhum cliente em uma única tarefa ou callback. - -Isso faz parte do motivo pelo qual o Node escalar bem, mas também significa que você é responsável por garantir um scheduling justo. -As próximas seções falam sobre como garantir um agendamento justo para o Loop de Eventos e para a Worker Pool. - -## Não bloqueia o Event Loop - -O Event Loop percebe cada nova conexão do cliente e orquestra a geração de uma resposta. -Todas as solicitações recebidas e respostas enviadas passam pelo Event Loop. -Isso significa que, se o Event Loop passar muito tempo em algum ponto, todos os clientes atuais e novos não serão atendidos. - -Você nunca deve bloquear o Event Loop. -Em outras palavras, cada um de seus callbacks JavaScript devem ser concluídos rapidamente. -Isto, obviamente, também se aplica aos seus `wait`'s , seus `Promise.then`'s, e assim por diante. - -Uma boa maneira de garantir isso é estudar sobre a ["complexidade computacional"](https://en.wikipedia.org/wiki/Time_complexity) de seus callbacks. -Se o seu callback executar um número constante de etapas, independentemente de seus argumentos, você sempre dará a cada cliente pendente uma chance justa. -Se seu callback executa um número considerável de etapas, dependendo de seus argumentos, pense em quanto tempo os argumentos podem demorar. - -Exemplo 1: Um callback em tempo constante. - -```javascript -app.get('/constant-time', (req, res) => { - res.sendStatus(200); -}); -``` - -Exemplo 2: Um callback `O(n)`. Este callback será executado rapidamente para pequenos `n` e mais lentamente para grandes `n`. - -```javascript -app.get('/countToN', (req, res) => { - let n = req.query.n; - - // n iterations before giving someone else a turn - for (let i = 0; i < n; i++) { - console.log(`Iter ${i}`); - } - - res.sendStatus(200); -}); -``` - -Exemplo 3: Um callback `O(n^2)`. Este callback ainda será executado rapidamente para pequenos `n`, mas para grandes `n`, será executado muito mais lentamente que o exemplo anterior `O(n)`. - -```javascript -app.get('/countToN2', (req, res) => { - let n = req.query.n; - - // n^2 iterations before giving someone else a turn - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - console.log(`Iter ${i}.${j}`); - } - } - - res.sendStatus(200); -}); -``` - -### Quão cuidadoso você deve ser? - -O Node usa a engine V8 do Google para JavaScript, o que é bastante rápido para muitas operações comuns. -Exceções a esta regra são regexps e operações JSON, discutidas abaixo. - -No entanto, para tarefas complexas, considere limitar a entrada e rejeitar entradas muito longas. -Dessa forma, mesmo que seu callback tenha grande complexidade, limitando a entrada, você garante que o callback não pode demorar mais do que o pior caso na entrada aceitável mais longa. -Você pode avaliar o pior caso desse callback e determinar se o tempo de execução é aceitável no seu contexto. - -### Bloqueando o Event Loop: REDOS - -Uma maneira comum de bloquear desastrosamente o Event Loop é usar uma [expressão regular](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) "vulnerável". - -#### Evitando expressões regulares vulneráveis - -Uma expressão regular (regexp) corresponde a uma sequência de entrada diante de um padrão. -Geralmente pensamos em uma combinação regexp exigindo uma única passagem pela string de entrada --- tempo `O(n)` em que `n` é o comprimento da string de entrada. -Em muitos casos, basta uma única passegem. -Infelizmente, em alguns casos, a correspondência regexp pode exigir um número exponencial de viagens pela string de entrada --- tempo `O(2^n)`. -Um número exponencial de viagens significa que, se o mecanismo exigir `x` viagens para determinar uma correspondência, serão necessárias `2*x` viagens se adicionarmos apenas mais um caractere à string de entrada. -Como o número de viagens está linearmente relacionado ao tempo necessário, o efeito dessa avaliação será bloquear o Event Loop. - -Uma _expressão regular vulnerável_ é aquela em que seu mecanismo de expressão regular pode levar um tempo exponencial, expondo você a [REDOS](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) no "evil input". -Se o seu padrão de expressão regular é vulnerável (ou seja, o mecanismo regexp pode levar um tempo exponencial) é realmente uma pergunta difícil de responder e varia dependendo de você estar usando Perl, Python, Ruby, Java, JavaScript, etc., mas aqui estão algumas regras práticas que se aplicam a todas essas linguagens: - -1. Evite quantificadores aninhados como `(a+)*`. O mecanismo regexp do Node pode lidar com alguns deles rapidamente, mas outros são vulneráveis. -2. Evite OR's com cláusulas sobrepostas, como `(a|a)*`. Novamente, esses nem sempre são rápidos. -3. Evite usar referências anteriores, como `(a.*) \1`. Nenhum mecanismo regexp pode garantir a avaliação em tempo linear. -4. Se você estiver fazendo uma correspondência simples de string, use `indexOf` ou o equivalente local. Será mais barato e nunca levará mais que `O(n)`. - -Se você não tiver certeza se sua expressão regular é vulnerável, lembre-se de que o Node geralmente não tem problemas para relatar uma _correspondência_, mesmo para uma regexp vulnerável e uma longa string de entrada. -O comportamento exponencial é acionado quando há uma incompatibilidade, mas o Node não pode ter certeza até que tente muitos caminhos pela string de entrada. - -#### Um exemplo de REDOS - -Aqui está um exemplo de regexp vulnerável, expondo seu servidor ao REDOS: - -```javascript -app.get('/redos-me', (req, res) => { - let filePath = req.query.filePath; - - // REDOS - if (fileName.match(/(\/.+)+$/)) { - console.log('valid path'); - } else { - console.log('invalid path'); - } - - res.sendStatus(200); -}); -``` - -O regexp vulnerável neste exemplo é uma maneira (ruim!) de verificar um caminho válido no Linux. -Corresponde as strings que são uma sequência de nomes delimitados por "/", como "/a/b/c". -Isso é perigoso porque viola a regra 1: possui um quantificador duplamente aninhado. - -Se um cliente consulta com filePath `///.../\n` (100 /'s seguidos por um caractere de quebra de linha que o "." da regexp não corresponda), o Event Loop levará efetivamente para sempre, bloqueando o Event Loop. -O ataque REDOS deste cliente faz com que todos os outros clientes não tenham sua vez até que a correspondência de regexp termine. - -Por esse motivo, você deve desconfiar do uso de expressões regulares complexas para validar a entrada do usuário. - -#### Recursos anti-REDOS - -Existem algumas ferramentas para verificar a segurança de seus regexps, como - -- [safe-regex](https://github.com/davisjam/safe-regex) -- [rxxr2](https://github.com/superhuman/rxxr2). - -No entanto, nenhum deles capturará todos os regexps vulneráveis. - -Outra abordagem é usar um mecanismo diferente de regexp. -Você pode usar o módulo[node-re2](https://github.com/uhop/node-re2), que usa o mecanismo de regexp rápido [RE2](https://github.com/google/re2) do Google . -Mas esteja avisado, o RE2 não é 100% compatível com os regexps do Node, portanto, verifique as regressões se você trocar para o módulo node-re2 para manipular seus regexps. -E regexps particularmente complicados não são suportados pelo node-re2. - -Se você estiver tentando corresponder a algo "óbvio", como uma URL ou um caminho de arquivo, encontre um exemplo em uma [biblioteca regexp](http://www.regexlib.com) ou use um módulo npm, por exemplo [ip-regex](https://www.npmjs.com/package/ip-regex). - -### Bloqueando o Event Loop: módulos principais do Node - -Vários módulos principais do Node têm APIs síncronas custosas, incluindo: - -- [Encryption](https://nodejs.org/api/crypto.html) -- [Compression](https://nodejs.org/api/zlib.html) -- [File system](https://nodejs.org/api/fs.html) -- [Child process](https://nodejs.org/api/child_process.html) - -Essas APIs são custosas, porque envolvem computação significativa (criptografia, compactação), exigem I/O (I/O de arquivo) ou potencialmente ambas (child process). Essas APIs destinam-se à conveniência de script, mas não para uso no contexto de servidor. Se você executá-los no Event Loop, eles levarão muito mais tempo para serem concluídos do que uma instrução JavaScript típica, bloqueando o Event Loop. - -Em um servidor, _você não deve usar as seguintes APIs síncronas desses módulos_: - -- Criptografia: - - `crypto.randomBytes` (versão síncrona) - - `crypto.randomFillSync` - - `crypto.pbkdf2Sync` - - Você também deve ter cuidado ao fornecer uma entrada grande para as rotinas de criptografia e descriptografia. -- Compression: -- Compressão: - - `zlib.inflateSync` - - `zlib.deflateSync` -- Sistema de arquivo: - - Não use as APIs do sistema de arquivos síncronas. Por exemplo, se o arquivo que você acessar estiver em um [sistema de arquivos distribuído](https://en.wikipedia.org/wiki/Clustered_file_system#Distributed_file_systems) como [NFS](https://en.wikipedia.org/wiki/Network_File_System), os tempos de acesso podem variar bastante. -- Child process: - - `child_process.spawnSync` - - `child_process.execSync` - - `child_process.execFileSync` - -Esta lista está razoavelmente completa a partir do Node v9. - -### Bloqueando o Event Loop: JSON DOS - -`JSON.parse` e `JSON.stringify` são outras operações potencialmente custosas. -Embora estes sejam `O(n)` no comprimento da entrada, para grandes `n` eles podem demorar surpreendentemente. - -Se o servidor manipular objetos JSON, principalmente os de um cliente, você deve ter cuidado com o tamanho dos objetos ou strings com as quais trabalha no Event Loop. - -Exemplo: bloqueio de JSON. Criamos um objeto `obj` de tamanho 2^21 e `JSON.stringify`, rodamos `indexOf` na string e, em seguida, JSON.parse. A string `JSON.stringify`'d tem 50 MB. Demora 0,7 segundos para trasformar em string o objeto, 0,03 segundos para indexOf na string de 50 MB e 1,3 segundos para converter a string. - -```javascript -var obj = { a: 1 }; -var niter = 20; - -var before, str, pos, res, took; - -for (var i = 0; i < niter; i++) { - obj = { obj1: obj, obj2: obj }; // Doubles in size each iter -} - -before = process.hrtime(); -str = JSON.stringify(obj); -took = process.hrtime(before); -console.log('JSON.stringify took ' + took); - -before = process.hrtime(); -pos = str.indexOf('nomatch'); -took = process.hrtime(before); -console.log('Pure indexof took ' + took); - -before = process.hrtime(); -res = JSON.parse(str); -took = process.hrtime(before); -console.log('JSON.parse took ' + took); -``` - -Existem módulos npm que oferecem APIs JSON assíncronas. Veja alguns exemplo: - -- [JSONStream](https://www.npmjs.com/package/JSONStream), que possui APIs de stream. -- [Big-Friendly JSON](https://www.npmjs.com/package/bfj), que possui APIs de stream e versões assíncronas das APIs JSON padrão usando o paradigma de particionamento no Event Loop descrito abaixo. - -### Cálculos complexos sem bloquear o Event Loop - -Suponha que você queira fazer cálculos complexos em JavaScript sem bloquear o Event Loop. -Você tem duas opções: particionamento ou descarregamento. - -#### Particionamento - -Você pode _particionar_ seus cálculos para que cada um seja executado no Event Loop, mas produz regularmente (alterna) outros eventos pendentes. -Em JavaScript, é fácil salvar o estado de uma tarefa em andamento em um closure, como mostra o exemplo 2 abaixo. - -Para um exemplo simples, suponha que você queira calcular a média dos números `1` até `n`. - -Exemplo 1: Média não particionada, custos `O(n)` - -```javascript -for (let i = 0; i < n; i++) sum += i; -let avg = sum / n; -console.log('avg: ' + avg); -``` - -Exemplo 2: Média particionada, cada uma das etapas assíncronas `n` custa `O(1)`. - -```javascript -function asyncAvg(n, avgCB) { - // Save ongoing sum in JS closure. - var sum = 0; - function help(i, cb) { - sum += i; - if (i == n) { - cb(sum); - return; - } - - // "Asynchronous recursion". - // Schedule next operation asynchronously. - setImmediate(help.bind(null, i + 1, cb)); - } - - // Start the helper, with CB to call avgCB. - help(1, function (sum) { - var avg = sum / n; - avgCB(avg); - }); -} - -asyncAvg(n, function (avg) { - console.log('avg of 1-n: ' + avg); -}); -``` - -Você pode aplicar esse princípio a iterações de array e assim por diante. - -#### Offloading - -Se você precisar fazer algo mais complexo, o particionamento não é uma boa opção. -Isso ocorre porque o particionamento usa apenas o Event Loop e você não se beneficiará de vários núcleos quase certamente disponíveis em sua máquina. -_Lembre-se, o Event Loop deve orquestrar requisições de clientes, não atendê-las._ -Para uma tarefa complicada, mova o trabalho do Event Loop para uma Worker Pool. - -##### Como fazer offload - -Você tem duas opções para uma Work Pool de destino no qual descarregar o trabalho. - -1. Você pode usar a Worker Pool built-in do Node desenvolvendo um [addon C++](https://nodejs.org/api/addons.html). Nas versões mais antigas do Node, crie seu complemento C++ usando [NAN](https://github.com/nodejs/nan) e nas versões mais recentes use [N-API](https://nodejs.org/api/n-api.html). [node-webworker-threads](https://www.npmjs.com/package/webworker-threads) oferece uma maneira JavaScript-only para acessar a Worker Pool do Node. -2. Você pode criar e gerenciar sua própria Worker Pool dedicada à computação, em vez da Worker Pool de I/O do Node. As maneiras mais simples de fazer isso são usando [Child Process](https://nodejs.org/api/child_process.html) ou [Cluster](https://nodejs.org/api/cluster.html). - -Você _não_ deve simplesmente criar um [Child Process](https://nodejs.org/api/child_process.html) para cada cliente. -Você pode receber requisições de clientes mais rapidamente do que criar e gerenciar children, e seu servidor pode se tornar um [fork pump](https://en.wikipedia.org/wiki/Fork_bomb). - -##### Desvantagem do offloading - -A desvantagem da abordagem de offloading é que ela incorre em custos indiretos na forma de _custos de comunicação_. -Somente o Event Loop tem permissão para ver o "namespace" (estado JavaScript) do sua aplicação. -De um Worker, você não pode manipular um objeto JavaScript no namespace do Event Loop. -Em vez disso, você deve serializar e desserializar todos os objetos que deseja compartilhar. -Em seguida, o Worker pode operar em sua própria cópia desses objetos e retornar o objeto modificado (ou um "patch") ao Event Loop. - -Para questões de serialização, consulte a seção JSON DOS. - -##### Algumas sugestões para offloading - -Você pode fazer uma distinção entre tarefas intensivas em CPU e I/O, porque elas possuem características marcadamente diferentes. - -Uma tarefa com uso intenso de CPU só progride quando seu Worker está agendado e o Worker deve ser agendado em um dos [núcleos lógicos](https://nodejs.org/api/os.html#os_os_cpus) da sua máquina . -Se você tiver 4 núcleos lógicos e 5 Workers, um deles não poderá progredir. -Como resultado, você está pagando custos indiretos (memória e custos de agendamento) por este Worker e não recebe retorno por isso. - -As tarefas intensivas de I/O envolvem a consulta de um provedor de serviços externo (DNS, sistema de arquivos etc.) e a espera de sua resposta. -Enquanto um Worker com uma tarefa intensiva de I/O está aguardando sua resposta, ele não tem mais nada a fazer e pode ser descontinuado pelo sistema operacional, dando a outro Worker a chance de enviar sua requisição. -Portanto, _as tarefas intensivas em I/O farão progressos mesmo enquanto a thread associada não estiver em execução_. -Os provedores de serviços externos, como bancos de dados e sistemas de arquivos, foram altamente otimizados para lidar com muitas requisições pendentes simultaneamente. -Por exemplo, um sistema de arquivos examinará um grande conjunto de requisições de gravação e leitura pendentes para mesclar atualizações conflitantes e recuperar arquivos em uma ordem ideal (por exemplo, consulte [estes slides](http://researcher.ibm.com/researcher/files/il-AVISHAY/01-block_io-v1.3.pdf)). - -Se você confiar em apenas uma Worker Pool, por exemplo, a Worker Pool do Node, as diferentes características do trabalho vinculado à CPU e vinculado à I/O podem prejudicar o desempenho da aplicação. - -Por esse motivo, convém manter uma Computation Worker Pool separada. - -#### Offloading: concluções - -Para tarefas simples, como iterar sobre os elementos de um array arbitrariamente longa, o particionamento pode ser uma boa opção. -Se o seu cálculo for mais complexo, o offloading é uma abordagem melhor: os custos de comunicação, ou seja, a sobrecarga de passagem de objetos serializados entre o Event Loop e a Worker Pool, são compensados pelo benefício do uso de múltiplos núcleos. - -No entanto, se o seu servidor depende muito de cálculos complexos, você deve pensar se o Node é realmente boa escolha. O Node é excelente para trabalhos ligados a I/O, mas para cálculos custosos, pode não ser a melhor opção. - -Se você adotar a abordagem de offloading, consulte a seção sobre não bloquear a Worker Pool. - -## Não bloqueie o Worker Pool - -O Node possui uma Worker Pool composto por Workers `k`. -Se você estiver usando o paradigma de Offloading discutido acima, poderá ter uma Computational Worker Pool separado, ao qual os mesmos princípios se aplicam. -Em qualquer um dos casos, vamos supor que `k` seja muito menor do que o número de clientes que você pode estar lidando simultaneamente. -Isso está de acordo com a filosofia "uma thread para muitos clientes" do Node, o segredo de sua escalabilidade. - -Conforme discutido acima, cada Worker conclui sua Task atual antes de prosseguir para a próxima na fila da Worker Pool. - -Agora, haverá variação no custo das Tasks necessárias para lidar com as requisições dos seus clientes. -Algumas Tasks podem ser concluídas rapidamente (por exemplo, lendo arquivos curtos ou em cache ou produzindo um pequeno número de bytes aleatórios) e outras demoram mais (por exemplo, lendo arquivos maiores ou não em cache ou gerando mais bytes aleatórios). -Seu objetivo deve ser _minimizar a variação nos tempos de Task_ e você deve usar _Particionamento de Task_ para fazer isso. - -### Minimizando a variação no tempo das Tasks - -Se a Task atual de um Worker for muito mais custosa que outras Tasks, não estará disponível para trabalhar em outras Tasks pendentes. -Em outras palavras, _cada Task relativamente longa diminui efetivamente o tamanho do Worker Pool até que alguma seja concluída_. -Isso é indesejável porque, até certo ponto, quanto mais Workers na Worker Pool, maior a taxa de transferência da Worker Pool(tarefas/segundo) e, portanto, maior a taxa de transferência do servidor (requisição do cliente/segundo). -Um cliente com uma Task relativamente custosa diminuirá a taxa de transferência do Worker Pool, diminuindo a taxa de transferência do servidor. - -Para evitar isso, tente minimizar a variação no comprimento das Tasks enviadas ao Worker Pool. -Embora seja apropriado tratar os sistemas externos acessados por suas requisições de I/O (DB, FS, etc.) como caixas-pretas, você deve estar ciente do custo relativo dessas requisições de I/O, e evite enviar requisições que você espera que sejam particularmente longas. - -Dois exemplos devem ilustrar a possível variação nos tempos das tarefas. - -#### Exemplo de variação: leituras no sistema de arquivos de longa execução - -Suponha que seu servidor precise ler arquivos para lidar com algumas requisições do cliente. -Após consultar as APIs de [File system](https://nodejs.org/api/fs.html) do Node, você optou por usar o `fs.readFile()` para simplificar. -No entanto, `fs.readFile()` é ([atualmente](https://github.com/nodejs/node/pull/17054)) não particionado: ele envia uma única Task `fs.read()` abrangendo todo o arquivo. -Se você ler arquivos mais curtos para alguns usuários e arquivos mais longos para outros, `fs.readFile()` poderá introduzir variações significativas no tamanho das Tasks, em detrimento da taxa de transferência da Worker Pool. - -Para o pior cenário, suponha que um atacante possa convencer seu servidor para ler um arquivo _arbitrário_ (esta é uma [directory traversal vulnerability](https://www.owasp.org/index.php/Path_Traversal)). -Se o seu servidor estiver executando o Linux, o atacante poderá nomear um arquivo extremamente lento: [`/dev/random`](http://man7.org/linux/man-pages/man4/random.4.html). -Para todos os propósitos práticos, `/dev/random` é infinitamente lento, e todo Worker solicitado a ler em `/dev/random` nunca terminará essa tarefa. -Um atacante envia requisições `k`, uma para cada Work, e nenhuma outra requisição de cliente que use a Worker Pool fará progresso. - -#### Exemplo de variação: operações de criptografia de longa execução - -Suponha que seu servidor gere bytes aleatórios criptograficamente seguros usando [`crypto.randomBytes()`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback). -O `crypto.randomBytes()` não é particionado: ele cria uma única Task `randomBytes()` para gerar quantos bytes você solicitou. -Se você criar menos bytes para alguns usuários e mais bytes para outros, `crypto.randomBytes()` é outra fonte de variação no tamanho das Tasks. - -### Particionamento de Task - -Tasks com custos variáveis de tempo podem prejudicar a taxa de transferência da Worker Pool. -Para minimizar a variação no tempo das Tasks, na medida do possível, você deve _particionar_ cada Task em sub-Tasks com custo comparável. -Quando cada sub-Task for concluída, ela deverá enviar a próxima sub-Task e, quando a sub-Task final for concluída, deverá notificar o remetente. - -Para continuar o exemplo de `fs.readFile()`, você deve usar `fs.read()` (particionamento manual) ou `ReadStream` (particionado automaticamente). - -O mesmo princípio se aplica às tarefas ligadas à CPU; o exemplo `asyncAvg` pode ser inadequado para o Event Loop, mas é adequado para a Worker Pool. - -Quando você particiona uma Task em sub-Tasks, as Tasks mais curtas se expandam para um pequeno número de sub-Tasks, e as Tasks mais longas se expandem para um número maior de sub-Tasks. -Entre cada sub-Task de uma Task mais longa, o Worker ao qual foi designado pode trabalhar em uma sub-Task de outra Task mais curta, melhorando assim o rendimento geral da Task da Worker Pool. - -Observe que o número de sub-Tasks concluídas não é uma métrica útil para a taxa de transferência da Worker Pool. -Em vez disso, preocupe-se com o número de _Tasks_ concluídas. - -### Evitando o particionamento de Tasks - -Lembre-se de que o objetivo do particionamento de Tasks é minimizar a variação no tempo das Tasks. -Se você conseguir distinguir entre Tasks mais curtas e Tasks mais longas (por exemplo, somar um array versus ordenar um array), poderá criar uma Worker Pool para cada classe de Task. -O roteamento de Tasks mais curtas e tarefas mais longas para separar na Worker Pool é outra maneira de minimizar a variação do tempo da Task. - -Em favor dessa abordagem, o particionamento de Tasks incorre em sobrecarga (os custos de criação de uma representação de Task da Worker Pool e de manipulação de fila da Worker Pool) e evitar o particionamento economiza os custos de passagens adicionais na Worker Pool. -Também evita que você cometa erros ao particionar suas Tasks. - -A desvantagem dessa abordagem é que os Workers em todas essas Worker Pools sofrerão sobrecarga de espaço e tempo e competirão entre si pelo tempo de CPU. -Lembre-se de que cada Task vinculada à CPU só progride enquanto está agendada. -Como resultado, você só deve considerar essa abordagem após uma análise cuidadosa. - -### Worker Pool: conclusões - -Se você usa apenas a Worker Pool do Node ou mantém Worker Pools separadas, você deve otimizar a taxa de transferência de Task dos seus Pool(s). - -Para fazer isso, minimize a variação nos tempos da Task usando o particionamento de Tasks. - -## Os riscos dos módulos npm - -Enquanto os módulos principais do Node oferecem blocos de construção para uma ampla variedade de aplicações, às vezes é necessário algo mais. Os desenvolvedores de Node se beneficiam enormemente do [ecosistema npm](https://www.npmjs.com/), com centenas de milhares de módulos oferecendo funcionalidade para acelerar seu processo de desenvolvimento. - -Lembre-se, no entanto, que a maioria desses módulos é escrita por desenvolvedores de terceiros e geralmente é liberada com apenas com o minímo necessário para funcionar. Um desenvolvedor que usa um módulo npm deve se preocupar com duas coisas, embora este último seja frequentemente esquecido. - -1. Honra suas APIs? -2. Suas APIs podem bloquear o Event Loop ou um Worker? - -Muitos módulos não fazem nenhum esforço para indicar o custo de suas APIs, em detrimento da comunidade. - -Para APIs simples, você pode estimar seus custo; o custo da manipulação de string não é difícil de entender. -Mas, em muitos casos, não está claro quanto uma API pode custar. - -_Se você está chamando uma API que pode fazer algo pesado, verifique o custo. Peça aos desenvolvedores para documentá-lo ou examine você mesmo o código-fonte (e envie um PR documentando o custo)._ - -Lembre-se, mesmo que a API seja assíncrona, você não sabe quanto tempo ela passará em um Worker ou no Event Loop em cada uma de suas partições. -Por exemplo, suponha que no exemplo `asyncAvg` dado acima, cada chamada para a função auxiliar somasse _metade_ dos números em vez de um deles. -Então essa função ainda seria assíncrona, mas o custo de cada partição seria `O(n)`, não `O(1)`, tornando muito menos seguro o uso de valores arbitrários de `n`. - -## Conclusão - -O Node possui dois tipos de threads: um Event Loop e `k` Workers. -O Event Loop é responsável por callbacks JavaScript e I/O não bloqueante, e um Worker executa tarefas correspondentes ao código C++ que conclui uma requisição assíncrona, incluindo o bloqueio de I/O e usos intensivos da CPU. -Ambos os tipos de threads funcionam em não mais de uma atividade por vez. -Se qualquer callback ou tarefa demorar muito, a thread em execução será _bloqueada_. -Se o sua aplicacão efetuar callbacks ou tarefas bloqueantes, isso pode levar a uma taxa de transferência degradada (clientes/segundo) na melhor das hipóteses, e na negação de serviço completa na pior das hipóteses. - -Para escrever um servidor web com alta taxa de transferência, mais à prova de DoS, você deve garantir que nas entradas benignas e maliciosas, nem o Event Loop nem os Workers sejam bloqueados. diff --git a/pages/pt-br/docs/index.mdx b/pages/pt-br/docs/index.mdx deleted file mode 100644 index 0c1063018e273..0000000000000 --- a/pages/pt-br/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Docs -layout: docs.hbs -labels: - lts: LTS ---- - -# Sobre a Documentação - -Existem diversos tipos de documentação disponíveis neste site: - -- Documentação de referência de API -- Funcionalidades do ES6 -- Guias - -## Documentação de referência de API - -A [Documentação de referência de API](https://nodejs.org/api/) provê uma informação detalhada sobre uma função ou objeto no Node.js. Esta documentação indica quais argumentos um método aceita, o valor de retorno deste método e quais erros podem estar relacionados aquele método. Ela também indica quais métodos estão disponíveis para diferentes versões do Node.js. - -Esta documentação descreve os módulos embarcados (built-in) providos pelo Node.js. Ela não documenta os módulos providos pela comunidade. - -
- -### Procurando por documentações de API de versões antigas? - - - -[Todas as versões](https://nodejs.org/docs/) - -
- -## Funcionalidades do ES6 - -A [seção do ES6](/pt-br/docs/es6/) descreve os três grupos de funcionalidade e detalha quais funcionalidades estão habilitadas por padrão no Node.js, incluindo links com explicações. Ela também mostra como encontrar qual versão do V8 está embarcada em conjunto com uma versão particular do Node.js. - -## Guias - -A [seção de Guias](/pt-br/docs/guides/) têm uma longa lista de artigos que detalham as funcionalidades técnicas e capacidades do Node.js. diff --git a/pages/pt-br/download/current.md b/pages/pt-br/download/current.md deleted file mode 100644 index 46bdbeaef6f07..0000000000000 --- a/pages/pt-br/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Download -download: Download -downloads: - headline: Downloads - lts: LTS - current: Atual - tagline-current: Recursos Mais Recentes - tagline-lts: Recomendado Para a Maioria dos Usuários - display-hint: Mostrar downloads para - intro: > - Baixe o código fonte do Node.js ou um instalador pré-compilado para o seu sistema, e comece a desenvolver hoje. - currentVersion: Versão LTS Mais Recente - buildInstructions: Compile o Node.js pelo código nas plataformas suportadas - WindowsInstaller: Instalador Windows - WindowsBinary: Binário para Windows - MacOSInstaller: Instalador macOS - MacOSBinary: Binário para macOS - LinuxBinaries: Binários para Linux - SourceCode: Código fonte -additional: - headline: Plataformas adicionais - intro: > - Membros da comunidade Node.js mantêm compilados não oficiais do Node.js para plataformas adicionais. Note, tais compilados não são mantidos pela equipe oficial do Node.js e podem não estar no mesmo nível de compilação da versão atual do Node.js. - platform: Plataforma - provider: Provedor - SmartOSBinaries: Binários SmartOS - DockerImage: Imagem Docker - officialDockerImage: Imagem Docker Oficial do Node.js - LinuxPowerSystems: Linux no Power LE Systems - LinuxSystemZ: Linux no System z - AIXPowerSystems: AIX no Power Systems ---- diff --git a/pages/pt-br/download/index.md b/pages/pt-br/download/index.md deleted file mode 100644 index 2cb4765415f0b..0000000000000 --- a/pages/pt-br/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Download -download: Download -downloads: - headline: Downloads - lts: LTS - current: Atual - tagline-current: Recursos Mais Recentes - tagline-lts: Recomendado Para a Maioria dos Usuários - display-hint: Mostrar downloads para - intro: > - Baixe o código fonte do Node.js ou um instalador pré-compilado para o seu sistema, e comece a desenvolver hoje. - currentVersion: Versão LTS Mais Recente - buildInstructions: Compile o Node.js pelo código nas plataformas suportadas - WindowsInstaller: Instalador Windows - WindowsBinary: Binário para Windows - MacOSInstaller: Instalador macOS - MacOSBinary: Binário para macOS - LinuxBinaries: Binários para Linux - SourceCode: Código fonte -additional: - headline: Plataformas adicionais - intro: > - Membros da comunidade Node.js mantêm compilados não oficiais do Node.js para plataformas adicionais. Note, tais compilados não são mantidos pela equipe oficial do Node.js e podem não estar no mesmo nível de compilação da versão atual do Node.js. - platform: Plataforma - provider: Provedor - SmartOSBinaries: Binários SmartOS - DockerImage: Imagem Docker - officialDockerImage: Imagem Docker Oficial do Node.js - LinuxPowerSystems: Linux no Power LE Systems - LinuxSystemZ: Linux no System z - AIXPowerSystems: AIX no Power Systems ---- diff --git a/pages/pt-br/download/package-manager.md b/pages/pt-br/download/package-manager.md deleted file mode 100644 index 80c1e4a98ff79..0000000000000 --- a/pages/pt-br/download/package-manager.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -layout: page.hbs -title: Instalando Node.js via gerenciador pacotes ---- - -# Instalando Node.js via gerenciador pacotes - -**_Nota:_** Os pacotes nessa página são mantidos e suportados por seus respectivos empacotadores, **não** pela equipe principal do Node.js. Por favor, relate quaisquer problemas encontrados para o mantenedor do pacote. Se o problema for um bug no próprio Node.js, o mantenedor deve relatar para o issue upstream. - ---- - -- [Android](#android) -- [Arch Linux](#arch-linux) -- [Debian e Distribuições Linux baseadas em Ubuntu, Enterprise Linux/Fedora e pacotes Snap](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE e SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS e illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) - ---- - -## Android - -O suporte ao Android ainda é experimental no Node.js, portanto, os binários pré-compilados ainda não são fornecidos pelos desenvolvedores do Node.js - -Entretanto, existem algumas soluções de terceiros. Por exemplo, a comunidade [Termux](https://termux.com/) que fornece um emulador de terminal e ambiente Linux para Android, assim como seu próprio gerenciador de pacotes e [extensa coleção](https://github.com/termux/termux-packages) com muitas aplicações pré-compiladas. Esse comando vai instalar a última versão disponível do Node.js no Termux: - -```bash -pkg install nodejs -``` - -Atualmente, os binários do Node.js no Termux estão ligados ao `system-icu` (dependência do pacote `libicu`) - -## Arch Linux - -Os pacotes para o Node.js e o npm estão disponíveis no Repositório da Comunidade. - -```bash -pacman -S nodejs npm -``` - -## Debian e distribuições Linux basedas em Ubuntu, Enterprise Linux/Fedora e pacotes Snap - -[Distribuição dos binários oficiais do Node.js](https://github.com/nodesource/distributions) são fornecidos pelo NodeSource. - -## FreeBSD - -A versão mais recente do Node.js está disponível na porta [www/node](https://www.freshports.org/www/node). - -Instale um pacote binário via [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): - -```bash -pkg install node -``` - -Ou compile-o por conta própria usando [ports](https://www.freebsd.org/cgi/man.cgi?ports): - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -O Node.js está disponível no diretório portage. - -```bash -emerge nodejs -``` - -## NetBSD - -Node.js está disponível no diretório pkgsrc: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -Ou instale um pacote binário (se estiver disponível para sua plataforma) usando pkgin: - -```bash -pkgin -y install nodejs -``` - -## nvm - -Node Version Manager é um script bash utilizado para gerenciar múltiplas versões do Node.js. Ele Permite que você instale, desinstale, mude de versão e etc. Para instalar o nvm, use esse [script de instalação](https://github.com/nvm-sh/nvm#install--update-script). - -Em sistemas Unix / OS X o Node.js compilado a partir do código fonte pode ser instalado usando [nvm](https://github.com/creationix/nvm), instalando-o no -local em que o nvm espera: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -Despois disso, você pode usar o `nvm` para alternar entre versões lançadas e versões -compiladas a partir do código fonte. -Por exemplo, se a versão do Node.js é v8.0.0-pre: - -```bash -nvm use 8 -``` - -Uma vez que a versão oficial for lançada você pode querer desinstalar a versão compilada -a partir do código fonte: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -O gerenciador de versões `nvs` é multi-plataformal e pode ser utilizado no Windows, macOS e Sistemas baseadoes em UNIX - -Para instalar o `nvs` no Windows, visite a [página de versões](https://github.com/jasongin/nvs/releases) e baixe o instalador no formato MSI da última versão disponível. - -Você também pode usar `chocolatey` para instalar o `nvs`: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -Você pode encontrar a documentação sobre as etapas de instalação do `nvs` para macOS/Sistemas baseados em UNIX [nesta página](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Usage - -Após a instalação você pode utilizar o `nvs` para alternar entre diferentes versões do Node. - -Para adicionar a última versão do node: - -```bash -nvs add latest -``` - -Ou para adicionar a última versão LTS do node: - -```bash -nvs add lts -``` - -Após execute o comando `nvs use` para introduzir a versão instalada do node no seu `PATH` para a sessão atual do seu shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -Para adicionar-lo ao `PATH` de forma permanente, use `nvs link` - -```bash -nvs link lts -``` - -## OpenBSD - -O Node.js está disponível através das portas do sistema. - -```bash -/usr/ports/lang/node -``` - -Usando [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) no OpenBSD: - -```bash -pkg_add node -``` - -## openSUSE e SLE - -Node.js está disponível nos principais repositórios sob os seguintes pacotes: - -- **openSUSE Leap 42.2**: `nodejs4` -- **openSUSE Leap 42.3**: `nodejs4`, `nodejs6` -- **openSUSE Tumbleweed**: `nodejs4`, `nodejs6`, `nodejs8` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs4`, `nodejs6` - (O "Web and Scripting Module" deve ser [adicionado antes da instalação](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html).) - -Por exemplo, para instalar o Node.js 4.x no openSUSE 42.2, execute o seguinte como root: - -```bash -zypper install nodejs4 -``` - -## macOS - -Basta baixar o [macOS Installer](https://nodejs.org/pt-br/#home-downloadhead) diretamente do site [nodejs.org](https://nodejs.org/). - -_Se desejar baixar o pacote com bash:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### Alternativas - -Usando **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -Usando **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Exemplo -port install nodejs7 -``` - -Usando **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -Instale o pacote binário: - -```bash -pkgin -y install nodejs -``` - -Ou compile manualmente pelo pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## SmartOS e illumos - -Imagens do SmartOS vêm com o pkgsrc pré-instalado. Em outras distribuições illumos, primeiro instale **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, então você pode instalar o binário normalmente: - -```bash -pkgin -y install nodejs -``` - -Ou compile manualmente pelo pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -O Solus fornece o Node.js em seu repositório principal. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux possui versões estáveis de Node.js no seu repositório principal. - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -Baixe o [Windows Installer](https://nodejs.org/pt-br/#home-downloadhead) diretamente do site [nodejs.org](https://nodejs.org/). - -### Alternativas - -Usando **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# ou para a instalação completa com npm -cinst nodejs.install -``` - -Usando **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -``` diff --git a/pages/pt-br/download/releases.md b/pages/pt-br/download/releases.md deleted file mode 100644 index 678ea15c19e4b..0000000000000 --- a/pages/pt-br/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Versões Anteriores -modules: 'NODE_MODULE_VERSION Se refere ao número de versão de ABI (application binary interface) do Node.js, usado para determinar quais versões do Node.js que compilam binários de complemento do C++ que podem ser carregados sem precisarem ser re-compilados. Ele costumava ser armazenado como um valor hexadecimal em versões anteriores, mas agora é representado como um inteiro.' ---- - -### io.js & Node.js - -As versões 1.x até 3.x foram chamadas de "io.js", pois faziam parte do fork do io.js. A partir do Node.js 4.0.0 as antigas linhas de lançamento do io.js convergiram com o Node.js 0.12.x para as versões unificadas do Node.js. - -### Procurando pelo último lançamento de uma versão? diff --git a/pages/pt-br/get-involved/collab-summit.md b/pages/pt-br/get-involved/collab-summit.md deleted file mode 100644 index 6f603a299c010..0000000000000 --- a/pages/pt-br/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Collab Summit -layout: contribute.hbs ---- - -# Collab Summit - -O _Collaboration Summit_ é uma desconferência organizada para juntar contribuidores e potênciais contribuidores e discutir sobre Node.js com colaborações animadas, educação, e compartilhamento de conhecimento. Comitês e grupos de trabalho se reunem duas vezes por ano para tomar decisões importantes e trabalhar pessoalmente em alguns esforços que precisam de um empurrãozinho. - -## Quem pode participar? - -Todos são bem-vindos a participar do _Collab Summit_. Durante o evento, líderes irão ajudar a integrar novos contribuidores ao grupos em que estes gostariam de colaborar antes de levá-los as sessões de trabalho (_workinkg sessions_). - -Essa é uma oportunidade para você ficar a par do que está acontecendo na comunidade, embarcar e contribuir com as habilidades que possui e gostaria de aprimorar. - -Os grupos de trabalho irão fornecer um cronograma para que as pessoas possam se familiarizar antes de chegar ao local, participar das discussões gerais dos colaboradores e então mergulhar nas sessões específicas. - -Nós adoraríamos ver você no _Collab Summit_! Confira o [_Summit repo_](https://github.com/nodejs/summit) para verificar eventos futuros e passados. Também de uma olhada nos [tópicos reportados](https://github.com/nodejs/summit/issues) que compartilham o que grupos de trabalhos e comitês estão planejando discutir pessoalmente. diff --git a/pages/pt-br/get-involved/contribute.md b/pages/pt-br/get-involved/contribute.md deleted file mode 100644 index bfcccbe88a232..0000000000000 --- a/pages/pt-br/get-involved/contribute.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Contribuindo -layout: contribute.hbs ---- - -# Contribuindo - -Agradecemos seu interesse em contribuir com o Node.js! -Existem muitas maneiras e locais que você pode contribuir, e nós estamos aqui para ajudar a facilitar esse processo. - -## Pedindo ajuda (geral) - -A quantidade de atividade no repositório `nodejs/node` é tão alta que, questões e solicitações de ajuda sobre -a utilização do Node.js de forma geral devem ser direcionadas para o [repositório de ajuda do Node.js](https://github.com/nodejs/help/issues). - -## Reportando um problema - -Se você encontrou o que acredita ser um problema com o Node.js, por favor não hesite em reportá-lo no GitHub -do projeto. Quando for reportar um problema, certifique-se de descrevê-lo juntamente com um caso de teste. Este -caso de teste não deve incluir nenhuma dependência externa, isto é, devemos conseguir executar o teste com nada -mais nada menos que o próprio Node.js. - -Quando estiver reportando um problema, envie o máximo de informações possíveis sobre o ambiente em -que este ocorreu. Nós nunca sabemos qual informação será importante quando tentamos restringir as causas do problema. -Por favor, inclua ao menos as seguintes informações: - -- Versão do Node -- Plataforma em que está sendo executado (macOS, SmartOS, Linux, Windows) -- Arquitetura em que está sendo executado (32bit ou 64bit e x86 ou ARM) - -O projeto Node.js é atualmente gerênciando através de diversos repositórios separados no GitHub, cada -um com sua própria base de problemas. Se possível, direcione o problema que está sendo reportado ao -repositório apropriado, mas não se preocupe caso algo seja colocado no lugar errado. A comunidade de -contribuidores ficará mais do que contente em fornecer a ajuda necessária e apontar a direção correta. - -- Para reportar um problema específico do Node.js, utilize [nodejs/node](https://github.com/nodejs/node) -- Para reportar um porblema específico deste website, utilize [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## Contribuições de códigos - - - -Se você gostaria de corrigir _bugs_ ou adicionar novas funcionalidades ao Node.js, por favor consulte -o [Guia de Contribuições do Node.js](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). -O processo de revisão realizado pelo colaboradores para todas as contribuições ao projeto é explicado -neste documento também. - -Se você está se perguntando por onde começar, confira o [Node Todo](https://www.nodetodo.org/), que poderá -ajudar você na sua primeira contribuição. - -## Tornando-se um Colaborador - -Ao tornar-se um Colaborator, contribudores poderão impactar ainda mais o projeto. Colaboradores podem auxiliar outros contribuidores revisando suas contribuições, filtrando problemas e assumem um papel importante moldando o futuro do projeto. Indivíduos reconhecidos pelo TSC, por terem realizado contribuições significantes e valiosas em algum dos repositórios do Node.js podem tornar-se Colaboradores e a estes são concedidos permissões de _commit_ ao projeto. - -As atividade que são levadas em consideração incluem (mas não se limitam) a qualidade de: - -- _commits_ de código e _pull requests_ -- documentação dos _commits_ e _pull requests_ -- comentários em _issues_ e _pull requests_ -- contribuções ao website do Node.js -- ajuda fornecida a usuários e novos contribuidores -- participação em grupos de trabaho (_Working Groups_) -- outras participações na comunidade Node.js - -Se alguém, realizando contribuições valiosas acredita que não foi considerado para receber esse título, poderá [abrir um pedido](https://github.com/nodejs/TSC/issues) ou [contatar um membro do TSC](https://github.com/nodejs/TSC#current-members) diretamente. diff --git a/pages/pt-br/get-involved/index.md b/pages/pt-br/get-involved/index.md deleted file mode 100644 index e123ae0e56039..0000000000000 --- a/pages/pt-br/get-involved/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Participe -layout: contribute.hbs ---- - -# Participe - -## Discussões da Comunidade - -- A [lista de problemas do GitHub](https://github.com/nodejs/node/issues) é o lugar para discutir as principais funcionalidades do Node.js. -- A conta oficial do Node.js no Twitter é [nodejs](https://twitter.com/nodejs). -- O [calendário da Fundação Node.js](https://nodejs.org/calendar) contém todas as reuniões dos times públicos - -## Aprenda - -- [Documentação oficial da API](https://nodejs.org/api/) detalha a API do Node.js. -- [NodeSchool.io](https://nodeschool.io/) ensinará os conceitos do Node.js através de jogos interativos em linha de comando. -- [Tag Node.js no Stack Overflow](https://stackoverflow.com/questions/tagged/node.js) coleta novas informações todos os dias. -- [Tag Node.js na DEV Community](https://dev.to/t/node) é o lugar para compartilhar projetos, artigos e tutoriais, bem como iniciar discussões e solicitar _feedback_ sobre tópicos relacionados ao Node.js. Desenvolvedores de todos os níveis são bem-vindos a participar. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) é uma comunidade de desenvolvedores _backend_ que utilizam Node.js, auxiliando uns aos outros através do Discord. - -## Sites e projetos internacionais da comunidade - -- [Comunidade Chinesa](https://cnodejs.org/) -- [Comunidade Húngara(Magyar)](https://nodehun.blogspot.com/) -- [Grupo Node.js Israelense no Facebook](https://www.facebook.com/groups/node.il/) -- [Grupo de usuários Japoneses](https://nodejs.jp/) -- [Grupo Node.js em espanhol no Facebook](https://www.facebook.com/groups/node.es/) -- [Vietnamese Node.js community](https://www.facebook.com/nodejs.vn/) -- [Uzbekistan group for Node.js](https://t.me/nodejs_uz) diff --git a/pages/pt-br/index.md b/pages/pt-br/index.md deleted file mode 100644 index 1253bdad6d973..0000000000000 --- a/pages/pt-br/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Versão Atual - download: Baixar - download-for: Baixar para - other-downloads: Outros Downloads - current: Atual - lts: LTS - tagline-current: Últimas Funcionalidades - tagline-lts: Recomendado Para Maioria dos Usuários - changelog: Changelog - api: Documentação da API - version-schedule-prompt: Ou verifique o - version-schedule-prompt-link-text: Cronograma de versões LTS ---- - -Node.js® é um runtime JavaScript desenvolvido com o [Chrome's V8 JavaScript engine](https://v8.dev/). diff --git a/pages/ro/404.md b/pages/ro/404.md deleted file mode 100644 index f3e5a0fc4d15f..0000000000000 --- a/pages/ro/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Page could not be found - -### ENOENT: no such file or directory diff --git a/pages/ro/about/governance.md b/pages/ro/about/governance.md deleted file mode 100644 index 8d8410dba32c6..0000000000000 --- a/pages/ro/about/governance.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Project Governance -layout: about.hbs ---- - -# Project Governance - -## Consensus Seeking Process - -The Node.js project follows a [Consensus Seeking](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) decision making model. - -## Collaborators - -The [nodejs/node](https://github.com/nodejs/node) core GitHub repository is maintained by the Collaborators who are added by the Technical Steering Committee ([TSC](https://github.com/nodejs/TSC)) on an ongoing basis. - -Individuals making significant and valuable contributions are made Collaborators and given commit-access to the project. These individuals are identified by the TSC and their nomination is discussed with the existing Collaborators. - -For the current list of Collaborators, see the project's [README.md](https://github.com/nodejs/node/blob/main/README.md#current-project-team-members). - -A guide for Collaborators is maintained at [collaborator-guide.md](https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md). - -## Top Level Committees - -The project is governed jointly by the [Technical Steering Committee (TSC)](https://github.com/nodejs/TSC/blob/master/TSC-Charter.md) which is responsible for high-level guidance of the project, and the [Community Committee (CommComm)](https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md) which is responsible for guiding and extending the Node.js community. diff --git a/pages/ro/about/index.md b/pages/ro/about/index.md deleted file mode 100644 index e15184cf6741b..0000000000000 --- a/pages/ro/about/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -layout: about.hbs -title: About -trademark: Trademark ---- - -# About Node.js® - -As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications. In the following "hello world" example, many connections can be handled concurrently. Upon each connection, the callback is fired, but if there is no work to be done, Node.js will sleep. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -This is in contrast to today's more common concurrency model, in which OS threads are employed. Thread-based networking is relatively inefficient and very difficult to use. Furthermore, users of Node.js are free from worries of dead-locking the process, since there are no locks. Almost no function in Node.js directly performs I/O, so the process never blocks. Because nothing blocks, scalable systems are very reasonable to develop in Node.js. - -If some of this language is unfamiliar, there is a full article on [Blocking vs. Non-Blocking](/en/docs/guides/blocking-vs-non-blocking/). - ---- - -Node.js is similar in design to, and influenced by, systems like Ruby's [Event Machine](https://github.com/eventmachine/eventmachine) and Python's [Twisted](https://twistedmatrix.com/trac/). Node.js takes the event model a bit further. It presents an [event loop](/en/docs/guides/event-loop-timers-and-nexttick/) as a runtime construct instead of as a library. In other systems, there is always a blocking call to start the event-loop. Typically, behavior is defined through callbacks at the beginning of a script, and at the end a server is started through a blocking call like `EventMachine::run()`. In Node.js, there is no such start-the-event-loop call. Node.js simply enters the event loop after executing the input script. Node.js exits the event loop when there are no more callbacks to perform. This behavior is like browser JavaScript — the event loop is hidden from the user. - -HTTP is a first-class citizen in Node.js, designed with streaming and low latency in mind. This makes Node.js well suited for the foundation of a web library or framework. - -Node.js being designed without threads doesn't mean you can't take advantage of multiple cores in your environment. Child processes can be spawned by using our [`child_process.fork()`][] API, and are designed to be easy to communicate with. Built upon that same interface is the [`cluster`][] module, which allows you to share sockets between processes to enable load balancing over your cores. diff --git a/pages/ro/docs/index.mdx b/pages/ro/docs/index.mdx deleted file mode 100644 index 50fd4b3011001..0000000000000 --- a/pages/ro/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Docs -layout: docs.hbs -labels: - lts: LTS ---- - -# About Docs - -There are several types of documentation available on this website: - -- API reference documentation -- ES6 features -- Guides - -## API Reference Documentation - -The [API reference documentation](https://nodejs.org/api/) provides detailed information about a function or object in Node.js. This documentation indicates what arguments a method accepts, the return value of that method, and what errors may be related to that method. It also indicates which methods are available for different versions of Node.js. - -This documentation describes the built-in modules provided by Node.js. It does not document modules provided by the community. - -
- -### Looking for API docs of previous releases? - - - -[All versions](https://nodejs.org/docs/) - -
- -## ES6 Features - -The [ES6 section](/en/docs/es6/) describes the three ES6 feature groups, and details which features are enabled by default in Node.js, alongside explanatory links. It also shows how to find which version of V8 shipped with a particular Node.js release. - -## Guides - -The [Guides section](/en/docs/guides/) has long-form, in-depth articles about Node.js technical features and capabilities. diff --git a/pages/ro/download/current.md b/pages/ro/download/current.md deleted file mode 100644 index 5c8f320149341..0000000000000 --- a/pages/ro/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Download -download: Download -downloads: - headline: Downloads - lts: LTS - current: Current - tagline-current: Latest Features - tagline-lts: Recommended For Most Users - display-hint: Display downloads for - intro: > - Download the Node.js source code or a pre-built installer for your platform, and start developing today. - currentVersion: Latest Current Version - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Additional Platforms - intro: > - Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release. - platform: Platform - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ro/download/index.md b/pages/ro/download/index.md deleted file mode 100644 index d7456db80c410..0000000000000 --- a/pages/ro/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Download -download: Download -downloads: - headline: Downloads - lts: LTS - current: Current - tagline-current: Latest Features - tagline-lts: Recommended For Most Users - display-hint: Display downloads for - intro: > - Download the Node.js source code or a pre-built installer for your platform, and start developing today. - currentVersion: Latest LTS Version - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Additional Platforms - intro: > - Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release. - platform: Platform - provider: Provider - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/ro/download/package-manager.md b/pages/ro/download/package-manager.md deleted file mode 100644 index 10a5cd0a0703c..0000000000000 --- a/pages/ro/download/package-manager.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -layout: page.hbs -title: Installing Node.js via package manager ---- - -# Installing Node.js via package manager - -**_Note:_** The packages on this page are maintained and supported by their respective packagers, **not** the Node.js core team. Please report any issues you encounter to the package maintainer. If it turns out your issue is a bug in Node.js itself, the maintainer will report the issue upstream. - ---- - -- [Android](#android) -- [Arch Linux](#arch-linux) -- [Debian and Ubuntu based Linux distributions, Enterprise Linux/Fedora and Snap packages](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE and SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS and illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) - ---- - -## Android - -Android support is still experimental in Node.js, so precompiled binaries are not yet provided by Node.js developers. - -However, there are some third-party solutions. For example, [Termux](https://termux.com/) community provides terminal emulator and Linux environment for Android, as well as own package manager and [extensive collection](https://github.com/termux/termux-packages) of many precompiled applications. This command in Termux app will install the last available Node.js version: - -```bash -pkg install nodejs -``` - -Currently, Termux Node.js binaries are linked against `system-icu` (depending on `libicu` package). - -## Arch Linux - -Node.js and npm packages are available in the Community Repository. - -```bash -pacman -S nodejs npm -``` - -## Debian and Ubuntu based Linux distributions, Enterprise Linux/Fedora and Snap packages - -[Node.js binary distributions](https://github.com/nodesource/distributions) are available from NodeSource. - -## FreeBSD - -The most recent release of Node.js is available via the [www/node](https://www.freshports.org/www/node) port. - -Install a binary package via [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): - -```bash -pkg install node -``` - -Or compile it on your own using [ports](https://www.freebsd.org/cgi/man.cgi?ports): - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js is available in the portage tree. - -```bash -emerge nodejs -``` - -## IBM i - -LTS versions of Node.js are available from IBM, and are available via [the 'yum' package manager](https://ibm.biz/ibmi-rpms). The package name is `nodejs` followed by the major version number (for instance, `nodejs8`, `nodejs10`, `nodejs12`, etc) - -To install Node.js 12.x from the command line, run the following as a user with \*ALLOBJ special authority: - -```bash -yum install nodejs12 -``` - -Node.js can also be installed with the IBM i Access Client Solutions product. See [this support document](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) for more details - -## NetBSD - -Node.js is available in the pkgsrc tree: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -Or install a binary package (if available for your platform) using pkgin: - -```bash -pkgin -y install nodejs -``` - -## nvm - -Node Version Manager is a bash script used to manage multiple released Node.js versions. It allows you to perform operations like install, uninstall, switch version, etc. To install nvm, use this [install script](https://github.com/nvm-sh/nvm#install--update-script). - -On Unix / OS X systems Node.js built from source can be installed using [nvm](https://github.com/creationix/nvm) by installing into the location that nvm expects: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -After this you can use `nvm` to switch between released versions and versions built from source. For example, if the version of Node.js is v8.0.0-pre: - -```bash -nvm use 8 -``` - -Once the official release is out you will want to uninstall the version built from source: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -The `nvs` version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems - -To install `nvs` on Windows go to the [release page](https://github.com/jasongin/nvs/releases) here and download the MSI installer file of the latest release. - -You can also use `chocolatey` to install it: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -You can find the documentation regarding the installation steps of `nvs` in macOS/Unix-like systems [here](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Usage - -After this you can use `nvs` to switch between different versions of node. - -To add the latest version of node: - -```bash -nvs add latest -``` - -Or to add the latest LTS version of node: - -```bash -nvs add lts -``` - -Then run the `nvs use` command to add a version of node to your `PATH` for the current shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -To add it to `PATH` permanently, use `nvs link`: - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js is available through the ports system. - -```bash -/usr/ports/lang/node -``` - -Using [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) on OpenBSD: - -```bash -pkg_add node -``` - -## openSUSE and SLE - -Node.js is available in the main repositories under the following packages: - -- **openSUSE Leap 42.2**: `nodejs4` -- **openSUSE Leap 42.3**: `nodejs4`, `nodejs6` -- **openSUSE Tumbleweed**: `nodejs4`, `nodejs6`, `nodejs8` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs4`, `nodejs6` (The "Web and Scripting Module" must be [added before installing](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html).) - -For example, to install Node.js 4.x on openSUSE Leap 42.2, run the following as root: - -```bash -zypper install nodejs4 -``` - -## macOS - -Simply download the [macOS Installer](https://nodejs.org/en/#home-downloadhead) directly from the [nodejs.org](https://nodejs.org/) web site. - -_If you want to download the package with bash:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### Alternatives - -Using **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -Using **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -Using **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -Install the binary package: - -```bash -pkgin -y install nodejs -``` - -Or build manually from pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## SmartOS and illumos - -SmartOS images come with pkgsrc pre-installed. On other illumos distributions, first install **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, then you may install the binary package as normal: - -```bash -pkgin -y install nodejs -``` - -Or build manually from pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -Solus provides Node.js in its main repository. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux ships Node.js stable in the main repository. - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -Simply download the [Windows Installer](https://nodejs.org/en/#home-downloadhead) directly from the [nodejs.org](https://nodejs.org/) web site. - -### Alternatives - -Using **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -Using **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -``` diff --git a/pages/ro/download/releases.md b/pages/ro/download/releases.md deleted file mode 100644 index 72230649bb55b..0000000000000 --- a/pages/ro/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Previous Releases -modules: 'NODE_MODULE_VERSION refers to the ABI (application binary interface) version number of Node.js, used to determine which versions of Node.js compiled C++ add-on binaries can be loaded in to without needing to be re-compiled. It used to be stored as hex value in earlier versions, but is now represented as an integer.' ---- - -### io.js & Node.js - -Releases 1.x through 3.x were called "io.js" as they were part of the io.js fork. As of Node.js 4.0.0 the former release lines of io.js converged with Node.js 0.12.x into unified Node.js releases. - -### Looking for latest release of a version branch? diff --git a/pages/ro/get-involved/collab-summit.md b/pages/ro/get-involved/collab-summit.md deleted file mode 100644 index ea791185273ae..0000000000000 --- a/pages/ro/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Collab Summit -layout: contribute.hbs ---- - -# Collab Summit - -Collaboration Summit is an un-conference for bringing current and potential contributors together to discuss Node.js with lively collaboration, education, and knowledge sharing. Committees and working groups come together twice per year to make important decisions while also being able to work on some exciting efforts they want to push forward in-person. - -## Who attends? - -Anyone is welcome to attend Collab Summit. During the summit, leaders will help onboard new contributors to groups they'd love to help prior to integrating them into the working sessions. - -This is your opportunity to learn what is happening within the community to jump in and contribute with the skills you have and would like to hone. - -Working groups will put together a schedule so that people can familiarize themselves before folks get onsite, having the general collaborator discussions, and then dive into breakout sessions. - -We'd love to see you at Collab Summit! Check out the [Summit repo](https://github.com/nodejs/summit) for upcoming and past Collab Summits and have a look at the [issues filed](https://github.com/nodejs/summit/issues) that share what individual working groups and committees are looking to discuss in-person. diff --git a/pages/ro/get-involved/contribute.md b/pages/ro/get-involved/contribute.md deleted file mode 100644 index d72b180b6610a..0000000000000 --- a/pages/ro/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Contributing -layout: contribute.hbs ---- - -# Contributing - -Thank you for your interest in contributing to Node.js! There are multiple ways and places you can contribute, and we're here to help facilitate that. - -## Asking for General Help - -Because the level of activity in the `nodejs/node` repository is so high, questions or requests for general help using Node.js should be directed at the [Node.js help repository](https://github.com/nodejs/help/issues). - -## Reporting an Issue - -If you have found what you believe to be an issue with Node.js please do not hesitate to file an issue on the GitHub project. When filing your issue please make sure you can express the issue with a reproducible test case, and that test case should not include any external dependencies. That is to say, the test case can be executed without anything more than Node.js itself. - -When reporting an issue we also need as much information about your environment that you can include. We never know what information will be pertinent when trying narrow down the issue. Please include at least the following information: - -- Version of Node.js -- Platform you're running on (macOS, SmartOS, Linux, Windows) -- Architecture you're running on (32bit or 64bit and x86 or ARM) - -The Node.js project is currently managed across a number of separate GitHub repositories, each with their own separate issues database. If possible, please direct any issues you are reporting to the appropriate repository but don't worry if things happen to get put in the wrong place, the community of contributors will be more than happy to help get you pointed in the right direction. - -- To report issues specific to Node.js, please use [nodejs/node](https://github.com/nodejs/node) -- To report issues specific to this website, please use [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## Code contributions - -If you'd like to fix bugs or add a new feature to Node.js, please make sure you consult the [Node.js Contribution Guidelines](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). The review process by existing collaborators for all contributions to the project is explained there as well. - -If you are wondering how to start, you can check [Node Todo](https://www.nodetodo.org/) which may guide you towards your first contribution. - -## Becoming a collaborator - -By becoming a collaborator, contributors can have even more impact on the project. They can help other contributors by reviewing their contributions, triage issues and take an even bigger part in shaping the project's future. Individuals identified by the TSC as making significant and valuable contributions across any Node.js repository may be made Collaborators and given commit access to the project. Activities taken into consideration include (but are not limited to) the quality of: - -- code commits and pull requests -- documentation commits and pull requests -- comments on issues and pull requests -- contributions to the Node.js website -- assistance provided to end users and novice contributors -- participation in Working Groups -- other participation in the wider Node.js community - -If individuals making valuable contributions do not believe they have been considered for commit access, they may [log an issue](https://github.com/nodejs/TSC/issues) or [contact a TSC member](https://github.com/nodejs/TSC#current-members) directly. diff --git a/pages/ro/get-involved/index.md b/pages/ro/get-involved/index.md deleted file mode 100644 index 86cd56324b0f9..0000000000000 --- a/pages/ro/get-involved/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Get involved -layout: contribute.hbs ---- - -# Get Involved - -## Community Discussion - -- The [GitHub issues list](https://github.com/nodejs/node/issues) is the place for discussion of Node.js core features. -- The official Node.js Twitter account is [nodejs](https://twitter.com/nodejs). -- The [Node.js Foundation calendar](https://nodejs.org/calendar) with all public team meetings. -- [Node Slackers](https://www.nodeslackers.com/) is a Node.js-focused Slack community. - -## Learning - -- [Official API reference documentation](https://nodejs.org/api/) details the Node.js API. -- [NodeSchool.io](https://nodeschool.io/) will teach you Node.js concepts via interactive command-line games. -- [Stack Overflow Node.js tag](https://stackoverflow.com/questions/tagged/node.js) collects new information every day. -- [The DEV Community Node.js tag](https://dev.to/t/node) is a place to share Node.js projects, articles and tutorials as well as start discussions and ask for feedback on Node.js-related topics. Developers of all skill-levels are welcome to take part. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) is a friendly community of Node.js backend developers supporting each other on Discord. - -## International community sites and projects - -- [Chinese community](https://cnodejs.org/) -- [Hungarian (Magyar) community](https://nodehun.blogspot.com/) -- [Israeli Facebook group for Node.js](https://www.facebook.com/groups/node.il/) -- [Japanese user group](https://nodejs.jp/) -- [Spanish language Facebook group for Node.js](https://www.facebook.com/groups/node.es/) -- [Vietnamese Node.js community](https://www.facebook.com/nodejs.vn/) diff --git a/pages/ro/index.md b/pages/ro/index.md deleted file mode 100644 index c15ed38b3ee7f..0000000000000 --- a/pages/ro/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Current Version - download: Download - download-for: Download for - other-downloads: Other Downloads - current: Current - lts: LTS - tagline-current: Latest Features - tagline-lts: Recommended For Most Users - changelog: Changelog - api: API Docs - version-schedule-prompt: Or have a look at the - version-schedule-prompt-link-text: Long Term Support (LTS) schedule ---- - -Node.js® is a JavaScript runtime built on [Chrome's V8 JavaScript engine](https://v8.dev/). diff --git a/pages/ru/404.md b/pages/ru/404.md deleted file mode 100644 index 8b936807527a3..0000000000000 --- a/pages/ru/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Страница не найдена - -### ENOENT: нет такого файла или каталога diff --git a/pages/ru/about/governance.md b/pages/ru/about/governance.md deleted file mode 100644 index 3af986cacadbd..0000000000000 --- a/pages/ru/about/governance.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Управление проектом -layout: about.hbs ---- - -# Управление проектом - -## Процесс поиска консенсуса - -Проект Node.js следует модели [поиска консенсуса](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) для принятия решений. - -## Коллабораторы - -Репозиторий [nodejs/node](https://github.com/nodejs/node) на GitHub поддерживается и развивается за счет Коллабораторов, которые добавляются Техническим руководящим комитетом ([TSC](https://github.com/nodejs/TSC)) на постоянной основе. - -Люди, которые вносят значительный и ценный вклад, становятся Коллабораторами и получают постоянный доступ к проекту. Эти лица идентифицируются TSC, и их назначение обсуждается с существующими сотрудниками. - -Текущий список Коллабораторов можно найти в [README.md](https://github.com/nodejs/node/blob/main/README.md#current-project-team-members) проекта. - -Руководство для Коллабораторов находится по адресу [collaborator-guide.md](https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md). - -## Комитеты высшего уровня - -Проект управляется совместно [Техническим руководящим комитетом (TSC)](https://github.com/nodejs/TSC/blob/master/TSC-Charter.md), который отвечает за руководство проектом на высоком уровне, и [Комитетом сообщества (CommComm)](https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md), который отвечает за руководство и расширение Node.js сообщества. diff --git a/pages/ru/about/index.md b/pages/ru/about/index.md deleted file mode 100644 index b322c5cbd3276..0000000000000 --- a/pages/ru/about/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -layout: about.hbs -title: О проекте -trademark: Торговая марка ---- - -# О Node.js® - -Как асинхронное событийное JavaScript-окружение, Node.js спроектирован для построения масштабируемых сетевых приложений. Ниже приведен пример "hello world", который может одновременно обрабатывать много соединений. Для каждого соединения вызывается функция обратного вызова, однако, когда соединений нет Node.js засыпает. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World\n'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Этот подход контрастирует с более распространенной на сегодняшний день моделью параллелизма, в которой используются параллельные OS потоки. Такой подход является относительно неэффективным и очень сложным в использовании. Кроме того, пользователи Node.js могут не беспокоиться о блокировках процессов, поскольку их не существует. Почти ни одна из функций в Node.js не работает напрямую с I/O, поэтому поток никогда не блокируется. В следствии этого на Node.js легко разрабатывать масштабируемые системы. - -Для более детального знакомства с этим подходом, можно ознакомится с полной статьей [Blocking vs Non-Blocking][]. - ---- - -Node.js создан под влиянием таких систем как [Event Machine][] в Ruby или [Twisted][] в Python. Но при этом событийная модель, в нем, используется значительно шире, принимая [event loop][] за основу окружения, а не в качестве отдельной библиотеки. В других системах всегда происходят блокировки вызова, чтобы запустить цикл событий. - -Обычно, поведение определяется через функции обратного вызова (callback) в начале скрипта и дальнейшим его вызовом через блокирующий вызов, вроде `EventMachine::run()`. В Node.js нет ничего похожего на вызов начала цикла событий, он автоматически входит в него после запуска скрипта. Node.js выходит из событийного цикла тогда, когда не остается зарегистрированных функций обратного вызова. Такое поведение похоже на поведение браузерного JavaScript, где событийный цикл скрыт от пользователя. - -HTTP является объектом первого рода в Node.js, разработанным с поточностью и малой задержкой, что делает Node.js хорошей основой для веб-библиотеки или фреймворка. - -[Blocking vs Non-Blocking]: /ru/docs/guides/blocking-vs-non-blocking/ -[event loop]: /ru/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/ru/docs/es6.md b/pages/ru/docs/es6.md deleted file mode 100644 index ee4a8482fe50c..0000000000000 --- a/pages/ru/docs/es6.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) и выше -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) и выше - -Node.js строится на современных версиях [V8](https://v8.dev/). Базируясь на последних -выпусках этого движка, мы обеспечиваем поддержку новых функций из -[спецификации JavaScript ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm) -своевременно предоставляя их разработчикам Node.js, а также улучшая производительность и стабильность. - -Вся функциональность ECMAScript 2015 (ES6) разделена на три группы: **поставляемая (shipping)**, -**подготовленная (staged)** и **в процессе (in progress)**: - -- Вся **поставляемая** функциональность, которую V8 считает стабильной, включена **по умолчанию в Node.js** - и **НЕ** нуждается в дополнительных конфигурациях и флагах. -- **Подготовленная** функциональность, это список почти готовых внедрений, который еще не утвержден - командой V8 как стабильной, и требует дополнительный флаг `--harmony`. -- Функциональность под знаком **в процессе** может быть активирована индивидуально, с помощью соответствующего - флага гармонизации, хотя это крайне нежелательно, кроме как для целей тестирования. Примечание: - эти флаги доступны в V8 и могут измениться без уведомления об их устаревании. - -## Какие функции поставляются с какой версией Node.js по умолчанию? - -На сайте [node.green](https://node.green/) представлен отличный обзор поддерживаемой функциональности -ECMAScript в различных версиях Node.js на основе таблицы сравнения kangax. - -## Какие функции в процессе? - -Новые функции постоянно добавляются в движок V8. Вообще говоря, ожидайте, что они появятся -в будущем выпуске Node.js, хотя точных дат неизвестно. - -Вы можете узнать о функциональности _в процессе_, доступной в каждом выпуске Node.js, используя аргумент -`--v8-options`. Обратите внимание, что это неполные и, возможно, некорректные функции V8, поэтому -используйте их на свой страх и риск: - -```bash -node --v8-options | grep "in progress" -``` - -## Моя инфраструктура настроена с использованием флага --harmony. Должен ли я удалить его? - -Текущее поведение флага `--harmony` на Node.js состоит в том, чтобы включать только **подготовленную** функциональность. -В конце концов, теперь это синоним `--es_staging`. Как упомянуто выше, это законченные функции, которые еще не считаются -стабильными. Если вы беспокоитесь о безопасности использования таких функций, особенно в производственных средах, рассмотрите -возможность выключения этого флага до тех пор, пока требуемые функции не перейдут в стадию "по умолчанию" на V8 и, следовательно, -на Node.js. Если вы оставите его включенным, вы должны быть готовы к дальнейшим обновлениям Node.js, которые могут сломать ваш код, -если V8 изменит свою семантику, чтобы более точно следовать стандарту. - -## Как мне узнать, какая версия V8 поставляется с определенной версией Node.js? - -Node.js предоставляет простой способ перечисления всех зависимостей и соответствующих версий, которые поставляются -с конкретным бинарным файлом через глобальный объект `process`. В случае с движком V8 введите следующую команду в -терминале, чтобы узнать его версию: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/ru/docs/guides/blocking-vs-non-blocking.md b/pages/ru/docs/guides/blocking-vs-non-blocking.md deleted file mode 100644 index ea4102971475f..0000000000000 --- a/pages/ru/docs/guides/blocking-vs-non-blocking.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: Блокирующие и Неблокирующие Вызовы -layout: docs.hbs ---- - -# Обзор Блокирующих и Неблокирующих Вызовов - -Этот обзор рассматривает разницу между **блокирующими** и **неблокирующими** вызовами в Node.js. Он ссылается на цикл событий (event loop) и библиотеку libuv, однако предварительное знание этих тем не требуется. Предполагается, что читатели имеют базовое понимание JavaScript и паттерна обратных вызовов (callback) в Node.js. - -> Обозначение "I/O" (Ввод/Вывод) в первую очередь ссылается на взаимодействие с системным диском и сетью при поддержке [libuv](https://libuv.org/). - -## Блокирование - -О **блокировании** говорят, когда выполнение JS кода в Node.js приостановлено до тех пор, пока не завершится работа сторонней операции (например, чтение какого-нибудь файла). Так происходит потому, что цикл событий не может продолжить исполнение JavaScript, так как работает **блокирующая** операция. - -В Node.js медленно исполняемый JS код не принято называть **блокирующим**, если причиной тому высокая нагрузка кода на процессор, а не ожидание завершения сторонней операции. Синхронные методы в стандартной библиотеке Node.js, которые используют libuv — наиболее часто применяемые **блокирующие** операции. Нативные модули также могут иметь **блокирующие** методы. - -Все I/O методы в стандартной библиотеке Node.js предоставляют свои асинхронные версии, которые являются **неблокирующими** и принимают функции обратного вызова в качестве аргумента. Некоторые методы также имеют свои **блокирующие** аналоги. Названия таких методов заканчиваются на `Sync`. - -## Сравнение Кода - -**Блокирующие** методы исполняются **синхронно**, а **неблокирующие** методы исполняются **асинхронно**. - -Возьмем модуль File System для примера. Вот пример **синхронного** чтения файла: - -```js -const fs = require('fs'); -// исполнение кода заблокировано, пока файл не будет полностью считан -const data = fs.readFileSync('/file.md'); -``` - -А вот эквивалентный **асинхронный** пример: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; -}); -``` - -Первый пример выглядит проще чем второй, но он имеет один недостаток: вторая строка **блокирует** исполнение любого нижеследующего кода, до тех пор, пока весь file.md не будет считан. Обратите внимание, если синхронная версия кода сгенерирует исключение, его нужно обработать, иначе процесс Node.js "упадёт". В асинхронном варианте выбор — сгенерировать исключение или нет — оставлен на усмотрение программиста. - -Давайте немного расширим наш пример: - -```js -const fs = require('fs'); -// исполнение кода заблокировано, пока файл не будет полностью считан -const data = fs.readFileSync('/file.md'); -console.log(data); -moreWork(); // функция будет исполнена, после console.log -``` - -А вот похожий, но не эквивалентный асинхронный пример: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -moreWork(); // функция будет исполнена до console.log -``` - -В первом примере метод `console.log` будет вызван до срабатывания функции `moreWork()`. Во втором примере метод `fs.readFile()` является **неблокирующим**, поэтому исполнение JavaScript может продолжаться, не дожидаясь окончания его работы. Как следствие функция `moreWork()` сработает раньше `console.log`. Эта возможность — отсутствие необходимости дожидаться окончания чтения файла и других системных вызовов — ключевое инженерное решение, которое обеспечивает высокую пропускную способность Node.js. - -## Конкурентность и Пропускная Способность - -Исполнение JavaScript в Node.js является однопоточным. Поэтому, говоря о конкурентности (параллельности вычислений) в Node.js, подразумевают, что после того, как цикл событий обработал синхронный код, он способен обработать функции обратного вызова. Подобно сторонним операциям (таким как I/O), любой конкурентный код должен позволять циклу событий продолжать свою работу. - -В качестве примера возьмем запросы к веб-серверу. Допустим, обработка сервером одного запроса занимает 50мс. Из этих 50мс, 45мс уходит на операции чтения/записи в базу данных. С базой данных можно взаимодействовать и **асинхронно**. При таком подходе на каждый запрос к веб-серверу **неблокирующая** асинхронная операция высвободит 45мс для обработки других запросов, а это существенная разница. - -Обработка конкурентной (параллельной) работы при помощи цикла событий в Node.js отличается от подходов во многих других языках программирования, в которых могут создаваться дополнительные потоки. - -## Опасность смешивания Блокирующего и Неблокирующего Кода - -Существуют паттерны, которые следует избегать при работе с I/O. Взглянем на пример: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -fs.unlinkSync('/file.md'); -``` - -В вышеуказанном примере метод `fs.unlinkSync()` с высокой вероятностью будет исполнен до `fs.readFile()`. Это приведет к удалению файла до его прочтения. Лучше переписать этот код в **неблокирующем** виде, что гарантирует правильный порядок исполнения методов: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (readFileErr, data) => { - if (readFileErr) throw readFileErr; - console.log(data); - fs.unlink('/file.md', unlinkErr => { - if (unlinkErr) throw unlinkErr; - }); -}); -``` - -В последнем примере **неблокирующий** вызов метода `fs.unlink()` расположен внутри функции обратного вызова `fs.readFile()`. Такой подход гарантирует правильную последовательность операций. - -## Дополнительные ресурсы - -- [libuv](https://libuv.org/) diff --git a/pages/ru/docs/guides/debugging-getting-started.md b/pages/ru/docs/guides/debugging-getting-started.md deleted file mode 100644 index 6f6116aa7f0c7..0000000000000 --- a/pages/ru/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: Отладка - Начало Работы -layout: docs.hbs ---- - -# Руководство по отладке - -Это руководство поможет вам начать отладку ваших приложений и скриптов Node.js. - -## Активация инспектора - -При запуске с аргументом `--inspect` процесс Node.js прослушивает клиент отладки. -По умолчанию клиент прослушивается на хосте 127.0.0.1 с портом 9229. -Каждому процессу также назначается уникальный [UUID][]. - -Клиенты инспектора должны знать и указывать адрес хоста, порт и UUID для подключения. -Полный URL будет выглядеть примерно так: -`ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e`. - -Процесс Node.js также начнет прослушивать сообщения отладки, если он получит -сигнал `SIGUSR1`. (`SIGUSR1` не доступен в среде Windows.) В Node.js версии 7 -и ниже это активирует устаревший Debugger API. В Node.js версии 8 и выше будет -активирован Inspector API. - ---- - -## Последствия для безопасности - -Так как дебаггер имеет полный доступ к среде выполнения Node.js, злоумышленник, -способный подключиться к этому порту, сможет выполнить произвольный код от имени -процесса Node. Поэтому важно понимать последствия для безопасности при обличении -порта отладчика в публичных и частных сетях. - -### Публичное обличение порта отладки небезопасно - -Если отладчик привязан к какому-либо публичному IP-адресу, или к 0.0.0.0, любой клиент, -способный достичь вашего IP-адреса сможет подключиться к отладчику без каких-либо -ограничений и сможет запускать произвольный код. - -По умолчанию `node --inspect` привязывается к 127.0.0.1. Чтобы разрешить внешние подключения, -вы должны явно предоставить общедоступный IP-адрес или 0.0.0.0 и т.д. Однако это может -подвергнуть приложение потенциально значительной угрозе его безопасности. Мы предлагаем -вам обеспечить наличие файрволов и других соответствующих средств контроля доступа для -того, чтобы предотвратить такую угрозу. - -См. раздел '[Включение сценариев удаленной отладки](#enabling-remote-debugging-scenarios)', который -включает рекомендации о том, как безопасно подключить удаленные клиенты отладчика. - -### Локальные приложения имеют полный доступ к инспектору - -Даже если вы привязали порт инспектора к 127.0.0.1 (по умолчанию), любые приложения, -запущенные локально на вашем компьютере, будут иметь неограниченный доступ. -Это сделано для того, чтобы локальные отладчики могли легко подключаться. - -### Браузеры, WebSockets, same-origin policy - -Веб-сайты, открытые в веб-браузере, могут отправлять запросы WebSocket и HTTP -в соответствии с моделью безопасности браузера. Начальное HTTP-соединение необходимо -для получения уникального идентификатора сеанса отладчика. Правило ограничения домена -(Same Origin Policy) не позволяет веб-сайтам устанавливать это HTTP-соединение. -Для дополнительной защиты от [атак DNS rebinding](https://ru.wikipedia.org/wiki/DNS_rebinding) -Node.js проверяет, что заголовки 'Host' для соединения точно указывают IP-адрес, -localhost или localhost6. - -Эти политики безопасности запрещают подключение к удаленному серверу отладки c -указанием имени хоста. Вы можете обойти это ограничение, указав либо IP-адрес, -либо используя ssh-туннели, как описано ниже. - -## Клиенты инспектора - -Несколько коммерческих и открытых инструментов могут подключаться к инспектору Node.js. -Основная информация по ним: - -### [node-inspect](https://github.com/nodejs/node-inspect) - -- Отладчик CLI, поддерживаемый Фондом Node.js, который использует [Протокол Инспектора][]. -- Соответствующая версия собирается вместе с Node.js, - можно использовать с помощью команды `node inspect myscript.js`. -- Последняя версия также может быть установлена независимо (например, `npm install -g node-inspect`) - и использоваться через `node-inspect myscript.js`. - -### [Инструменты разработчика Chrome](https://github.com/ChromeDevTools/devtools-frontend) 55+, [Microsoft Edge](https://www.microsoftedgeinsider.com) - -- **Вариант 1**: Откройте `chrome://inspect` в браузере на основе Chromium - или `edge://inspect` в браузере Edge. Нажмите кнопку Configure и убедитесь, - что нужные вам хост и порт перечислены в списке. -- **Вариант 2**: Скопируйте значение `devtoolsFrontendUrl` из вывода `/json/list` - (`curl http://localhost:9229/json/list`) или текст подсказки --inspect и откройте его в Chrome. - -### [Visual Studio Code](https://github.com/microsoft/vscode) 1.10+ - -- На панели "Отладка" (Debug) щелкните значок настроек, чтобы открыть файл `.vscode/launch.json`. - Выберите "Node.js" для первоначальной настройки. - -### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- В меню выберите "Debug > Start Debugging" или нажмите `F5`. -- [Детальные инструкции](https://github.com/Microsoft/nodejstools/wiki/Debugging). - -### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) 2017.1+ и другие IDE JetBrains - -- Создайте новую конфигурацию отладки Node.js и нажмите кнопку "Debug" (`Shift+F9`). `--inspect` будет - использоваться по умолчанию для Node.js 7+. Чтобы отключить, снимите флажок - `js.debugger.node.use.inspect` в реестре IDE. - -### [chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - -- Библиотека для облегчения подключения к эндпоинтам Протокола Инспектора. - -### [Gitpod](https://www.gitpod.io) - -- Запустите конфигурацию отладки Node.js из представления `Debug` или нажмите `F5`. [Детальные инструкции](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1) - -### [Eclipse IDE](https://eclipse.org/eclipseide) c расширением Eclipse Wild Web Developer - -- Открыв файл .js, выберите "Debug As... > Node program", или -- Создайте конфигурацию отладки, чтобы присоединить отладчик к запущенному приложению Node (уже запущенному с `--inspect`). - ---- - -## Аргументы командной строки - -В следующей таблице перечислено влияние различных runtime флагов при отладке: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ФлагЗначение
--inspect -
    -
  • Включить инспектор
  • -
  • Прослушивать адрес и порт по умолчанию (127.0.0.1:9229)
  • -
-
--inspect=[host:port] -
    -
  • Включить инспектор
  • -
  • Прослушивать адрес host (по умолчанию: 127.0.0.1)
  • -
  • Прослушивать порт port (по умолчанию: 9229)
  • -
-
--inspect-brk -
    -
  • Включить инспектор
  • -
  • Прослушивать адрес и порт по умолчанию (127.0.0.1:9229)
  • -
  • Прервать выполнение сценария перед началом выполнения пользовательского кода
  • -
-
--inspect-brk=[host:port] -
    -
  • Включить инспектор
  • -
  • Прослушивать адрес host (по умолчанию: 127.0.0.1)
  • -
  • Прослушивать порт port (по умолчанию: 9229)
  • -
  • Прервать выполнение сценария перед началом выполнения пользовательского кода
  • -
-
node inspect script.js -
    -
  • Запустить дочерний процесс для выполнения пользовательского скрипта под флагом --inspect; - использовать основной процесс для запуска отладчика CLI.
  • -
-
node inspect --port=xxxx script.js -
    -
  • Запустить дочерний процесс для выполнения пользовательского скрипта под флагом --inspect; - использовать основной процесс для запуска отладчика CLI.
  • -
  • Прослушивать порт port (по умолчанию: 9229)
  • -
-
- ---- - -## Включение сценариев удаленной отладки - -Мы рекомендуем, чтобы отладчик никогда не прослушивал общедоступный IP-адрес. -Если вам необходимо разрешить удаленные подключения для отладки, мы рекомендуем -использовать SSH-тунелли. Следующий пример предоставляется только в целях -иллюстрации возможностей. Вы должны понимать все риски информационной безопасности, -связанные с предоставлением удаленного доступа к привилегированной службе. - -Допустим вы запускаете на удаленной машине, remote.example.com, приложение Node, -которое вы хотите отлаживать. На этой машине следует запустить процесс Node -с инспектором, прослушивающим только localhost (по умолчанию). - -```bash -node --inspect server.js -``` - -Теперь вы можете настроить ssh-туннель на локальном компьютере, с которого -вы хотите инициировать подключение клиента отладки. - -```bash -ssh -L 9221:localhost:9229 user@remote.example.com -``` - -Это запустит сессию ssh, в которой соединение с портом 9221 на вашем локальном -компьютере будет перенаправлено к порту 9229 на remote.example.com. Теперь вы -можете подключить к localhost:9221 отладчик, такой как Chrome DevTools или -Visual Studio Code, у которого будет возможность отладки так, как если бы приложение -Node.js работало локально. - ---- - -## Устаревший Debugger - -**Debugger API устарело начиная с Node.js версии 7.7.0. -Вместо него следует использовать Inspector API с флагом --inspect.** - -При запуске с флагом **--debug** или **--debug-brk** в версии 7 или ниже, -Node.js прослушивает команды отладки, определенные протоколом -отладки V8, на порту TCP (по умолчанию `5858`). Любой клиент отладки, который -понимает этот протокол, может подключиться и отладить работающий процесс; -пара популярных клиентов перечислены ниже. - -Протокол отладки V8 более не поддерживается и не документируется. - -### [Встроенный отладчик](https://nodejs.org/dist/latest/docs/api/debugger.html) - -Введите `node debug script_name.js` для запуска скрипта со встроенным CLI отладчиком. -Сам скрипт будет запущен с флагом `--debug-brk` в другом процессе Node, а первоначальный -процесс Node запускает скрипт `_debugger.js` и подключается к целевому скрипту. - -### [node-inspector](https://github.com/node-inspector/node-inspector) - -Отлаживайте приложение Node.js с помощью Chrome DevTools используя -промежуточный процесс, который переводит протокол инспектора, используемый в Chromium, -в протокол отладчика V8, используемый в Node.js. - - - -[Протокол Инспектора]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/ru/docs/guides/diagnostics-flamegraph.md b/pages/ru/docs/guides/diagnostics-flamegraph.md deleted file mode 100644 index b8fec73875dd4..0000000000000 --- a/pages/ru/docs/guides/diagnostics-flamegraph.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Диагностика - Flame Graphs -layout: docs.hbs ---- - -# Flame Graphs - -## Для чего нужен flame graph? - -Flame graphs - это способ визуализации процессорного времени потраченного на функции. Они могут помочь вам определить, какие синхронные операции выполняются дольше всего. - -## Как создать flame graph - -Возможно, вы слышали о том, что в Node.js трудно создать flame graph, но это больше не так. Виртуальные машины Solaris больше не нужны для flame graph'ов! - -Flame graph'ы генерируются из выходных данных `perf`, который не является специфичным Node.js инструментом. Хотя это наиболее эффективный способ визуализации затраченного процессорного времени, у него могут быть проблемы с оптимизацией кода JavaScript в Node.js 8 и выше. См. [проблемы вывода `perf`](#perf-output-issues) section below. - -### Используйте предварительно упакованный инструмент - -Если вы хотите в один ход получить flame graph, попробуйте [0x](https://www.npmjs.com/package/0x). - -Для диагностики production deployments, читайте эти записи: [0x production servers](https://github.com/davidmarkclements/0x/blob/master/docs/production-servers.md) - -### Создание flame graph'а с помощью системных инструментов - -Цель это руководства - показать шаги, связанные с созданием flame graph'а и держать вас в курсе каждого шага. - -Если вы хотите лучше понять каждый шаг, взгляните на следующие разделы, которые мы рассмотрим более подробно. - -Теперь давайте приступим к работе. - -1. установите `perf` (обычно доступен через пакет `linux-tools-common`, если он еще не установлен) -2. попробуйте запустить `perf` - он может пожаловаться на отсутствующие модули ядра, установить их тоже -3. запустите команду `node` с включенным `perf` (см. [проблемы вывода `perf`](#perf-output-issues) для подсказок, специфичных для разных версий Node.js) - - ```bash - perf record -e cycles:u -g -- node --perf-basic-prof app.js - ``` - -4. игнорируйте предупреждения до тех пор, пока они не скажут вам, что `perf` не может быть запущен из-за отсутствия пакетов; вы также можете получить некоторые предупреждения о невозможности доступа к примерам модулей ядра, которые вам не нужны в любом случае -5. запустите `perf script > perfs.out`, чтобы сгенерировать файл с данными, который вы вот-вот визуализируете. Также полезно [произвести некоторую чистку](#filtering-out-node-js-internal-functions) для того, чтобы получить более читабельный график -6. установите `stackvis` если еще не установлен `npm i -g stackvis` -7. запустите `stackvis perf < perfs.out > flamegraph.htm` - -Теперь откройте файл flame graph'а в вашем любимом браузером и наблюдайте, как он горит. Он имеет цветовую кодировку, поэтому вы можете сосредоточиться на самых насыщенных оранжевых столбцах в первую очередь. Скорее всего, они отображают самые ресурсоемкие функции процессора. - -Стоит упомянуть - если вы кликните по элементу flame graph'а, то над графиком отобразится увеличение его окружения. - -### Использование `perf` для замерки запущенного процесса - -Это отлично подходит для записи данных flame graph'а из уже запущенного процесса, который вы не хотите прерывать. Представьте себе продакшн процесс с трудновоспроизводимой проблемой. - -```bash -perf record -F99 -p `pgrep -n node` -g -- sleep 3 -``` - -Подождите, для чего нужна команда `sleep 3`? Она нужна для того, чтобы поддерживать работу `perf`. Несмотря на то, что параметр `-p` указывает на другой `pid`, команда должна быть выполнена в процессе и завершить его. `perf` выполняется столько, сколько выполняется команда, которую вы ему передаете, независимо от того, профилируете ли вы ее или нет. `sleep 3` гарантирует, что `perf` будет выполняться 3 секунды. - -Почему параметр `-F` (частота профилирования) установлен в 99? Это по умолчанию. Вы можете настроить его как хотите. `-F99` говорит `perf` делать 99 отчетов в секунду, увеличивайте значение для большой точности. Более низкие значения должны давать меньше результатов с менее точными результатами. Точность, которая вам нужна, зависит от того, как долго выполняются ваши ресурсоемкие функции. Если вы ищете причину заметного замедления, 99 кадров в секунду должно быть более чем достаточно. - -После того, как вы получите эту 3-секундную запись, приступайте к генерации flame graph'а, следуя двум последним пунктам сверху. - -### Фильтрация внутренних Node.js функций - -Обычно вы просто хотите увидеть производительность ваших собственных функций, поэтому фильтрация внутренних функций Node.js и V8 может значительно облегчить чтение графика. Вы можете почистить свой `perf` файл с помощью команды: - -```bash -sed -i -r \ - -e "/( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)/d" \ - -e 's/ LazyCompile:[*~]?/ /' \ - perfs.out -``` - -Если вы читаете свой flame graph, и он кажется странным, как будто чего-то не хватает в ключевой функции, занимающей большую часть времени, попробуйте сгенерировать свой flame graph без фильтров - возможно, у вас возник редкий случай проблемы с самим Node.js. - -### Опции профилирования Node.js - -`--perf-basic-prof-only-functions` и `--perf-basic-prof` это те две опции, которые полезны для отладки вашего JavaScript кода. Другие параметры используются для профилирования самого Node.js, что выходит за рамки данного руководства. - -Опция `--perf-basic-prof-only-functions` позволяет генерировать меньше вывода, поэтому это вариант с наименьшими издержками. - -### Зачем они мне нужны? - -Ну, без этих опций вы в любом случае получите flame graph, но большинство столбцов будет с надписью `v8::Function::Call`. - -## Проблемы вывода `perf` - -### Изменения в пайплайне Node.js 8.x V8 - -Node.js 8.x и выше поставляется с новыми оптимизациями для пайплайна компиляции JavaScript в движке V8, который иногда делает имена/ссылки на функции недоступными для `perf`. (Это называется Turbofan) - -В результате названия ваших функций может выглядеть неправильно на flame graph'е. - -Вы увидите что-то вроде `ByteCodeHandler:` там, где должны быть названия функций. - -В [0x](https://www.npmjs.com/package/0x) встроены некоторые меры пресечения этого. - -Подробнее см.: - -- https://github.com/nodejs/benchmarking/issues/168 -- https://github.com/nodejs/diagnostics/issues/148#issuecomment-369348961 - -### Node.js 10+ - -Node.js 10.x решает проблему с Turbofan с помощью флага `--interpreted-frames-native-stack`. - -Запустите `node --interpreted-frames-native-stack --perf-basic-prof-only-functions`, чтобы получить имена функций в flame graph'е независимо от того, какой пайплайн V8 использовался для компиляции вашего JavaScript кода. - -### Неправильные подписи на flame graph'е - -Если вы видите подписи, похожие на эту: - -``` -node`_ZN2v88internal11interpreter17BytecodeGenerator15VisitStatementsEPNS0_8ZoneListIPNS0_9StatementEEE -``` - -это означает, что используемая вами версия `perf` не была скомпилирована с поддержкой demangle, см. https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 для примера - -## Примеры - -Потренируйтесь создавать flame graph'ы самостоятельно с [этим заданием](https://github.com/naugtur/node-example-flamegraph)! diff --git a/pages/ru/docs/guides/getting-started-guide.md b/pages/ru/docs/guides/getting-started-guide.md deleted file mode 100644 index 13e4f50bab928..0000000000000 --- a/pages/ru/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Первые шаги -layout: docs.hbs ---- - -# С чего начать в Node.js после его установки? - -После того, как вы установили Node, давайте попробуем создать наш первый веб-сервер. -Создайте файл с именем "app.js" и скопируйте следующий код: - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Далее запустите ваш веб-сервер, используя команду `node app.js`, откройте `http://localhost:3000` в браузере и вы увидите сообщение 'Hello World'. diff --git a/pages/ru/docs/guides/index.md b/pages/ru/docs/guides/index.md deleted file mode 100644 index 8e3a3bdb385ce..0000000000000 --- a/pages/ru/docs/guides/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Руководства -layout: docs.hbs ---- - -# Руководства - -## Общее - -- [Первые шаги](/ru/docs/guides/getting-started-guide/) -- [Отладка - начало работы](/ru/docs/guides/debugging-getting-started/) -- [Простое профилирование Node.js приложений](/ru/docs/guides/simple-profiling/) -- [Диагностика - Flame Graphs](/ru/docs/guides/diagnostics-flamegraph/) -- [Докеризация веб-приложения Node.js](/ru/docs/guides/nodejs-docker-webapp/) -- [Migrating to safe Buffer constructors](/en/docs/guides/buffer-constructor-deprecation/) - -## Ключевые концепции Node.js - -- [Блокирующие и Неблокирующие Вызовы](/ru/docs/guides/blocking-vs-non-blocking/) -- [The Node.js Event Loop, Timers, and `process.nextTick()`](/en/docs/guides/event-loop-timers-and-nexttick/) -- [Don't Block the Event Loop (or the Worker Pool)](/en/docs/guides/dont-block-the-event-loop/) -- [Таймеры в Node.js](/ru/docs/guides/timers-in-node/) - -## Module-related guides - -- [Anatomy of an HTTP Transaction](/en/docs/guides/anatomy-of-an-http-transaction/) -- [Working with Different Filesystems](/en/docs/guides/working-with-different-filesystems/) -- [Backpressuring in Streams](/en/docs/guides/backpressuring-in-streams/) -- [Domain Module Postmortem](/en/docs/guides/domain-postmortem/) -- [How to publish N-API package](/en/docs/guides/publishing-napi-modules/) -- [ABI Stability](/en/docs/guides/abi-stability/) diff --git a/pages/ru/docs/guides/nodejs-docker-webapp.md b/pages/ru/docs/guides/nodejs-docker-webapp.md deleted file mode 100644 index 2428b394582d9..0000000000000 --- a/pages/ru/docs/guides/nodejs-docker-webapp.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -title: Докеризация веб-приложения Node.js -layout: docs.hbs ---- - -# Докеризация веб-приложения Node.js - -Цель этого примера — показать, как поместить приложение Node.js в Docker-контейнер. -Это руководство предназначено для разработки, но не для прямого использования в -продакшене. Мы также предполагаем, что вы успешно [установили Docker](https://docs.docker.com/install/) на свой ПК и -имеете базовое представление о структуре Node.js приложения. - -В первой части руководства мы создадим простое Node.js приложение, затем -мы сделаем для него docker-образ, и, наконец, инициализируем экземпляр контейнера -из этого образа. - -Docker позволяет вам упаковать приложение вместе с его окружением и всеми зависимостями в -"коробку", называемую контейнером. Обычно контейнер состоит из приложения, работающего в -упрощенной версии ОС Linux. Образ — это шаблон для контейнера, контейнер — это работающий -экземпляр образа. - -## Создание приложения Node.js - -Для начала создадим новую директорию, в которой будут находиться все файлы приложения. В этой директории -создайте файл `package.json`, в котором описано приложение и его зависимости: - -```json -{ - "name": "docker_web_app", - "version": "1.0.0", - "description": "node.js on docker", - "author": "first last ", - "main": "server.js", - "scripts": { - "start": "node server.js" - }, - "dependencies": { - "express": "^4.16.1" - } -} -``` - -После создания файла `package.json`, выполните команду `npm install`. Если вы используете `npm` -версии 5 или выше, это также создаст файл `package-lock.json`, который будет скопирован в ваш docker-образ. - -Далее создайте файл `server.js`, который определяет веб-приложение на основе -фреймворка [Express.js](https://expressjs.com/): - -```javascript -'use strict'; - -const express = require('express'); - -// константы -const port = 8080; -const host = '0.0.0.0'; - -// приложение -const app = express(); -app.get('/', (req, res) => { - res.send('Hello World'); -}); - -app.listen(PORT, HOST, () => { - console.log(`Running on http://${HOST}:${PORT}`); -}); -``` - -Далее мы рассмотрим, как можно запускать это приложение внутри Docker-контейнера, -используя официальный образ Docker'а. Сначала давайте создадим Docker-образ с нашим приложением. - -## Создание файла Dockerfile - -Создайте пустой файл с именем `Dockerfile`: - -```markup -touch Dockerfile -``` - -Откройте этот файл в вашем любимом текстовом редакторе. - -Первое, что нам надо сделать — определить базовый образ, -который будет взят за основу. Мы будем использовать образ `node` последней версии -LTS\* (версии с долгосрочной поддержкой) — `12`, -доступный на [Docker Hub](https://hub.docker.com/). - -\* Прим. переводчика: на момент написания статьи. - -```docker -FROM node:12 -``` - -Затем создадим директорию для кода приложения внутри образа. -Это будет рабочая папка для вашего приложения. - -```docker -# создание директории приложения -WORKDIR /usr/src/app -``` - -Образ, который мы используем, поставляется с уже предустановленным Node.js и NPM. -Поэтому мы можем просто установить зависимости приложения с помощью команд `npm`. -Обратите внимание, если вы используете `npm` 4 или ниже, файл `package-lock.json` -не будет сгенерирован. - -```docker -# установка зависимостей -# символ астериск ("*") используется для того чтобы по возможности -# скопировать оба файла: package.json и package-lock.json -COPY package*.json ./ - -RUN npm install -# Если вы создаете сборку для продакшн -# RUN npm ci --omit=dev -``` - -Обратите внимание, что вместо того, чтобы копировать весь рабочий каталог, -мы копируем только файл `package.json`. Это позволяет воспользоваться -кэшированием слоев в Docker. [Здесь](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/) -bitJudo дал хорошее объяснение того, как это работает. Более того, -команда `npm ci`, указанная в комментарии, позволяет создавать -более быстрые, надежные, воспроизводимые сборки для продакшена. -вы можете прочесть больше об этой команде [здесь](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable). - -Чтобы отправить исходный код вашего приложения внутрь Docker-образа, -используйте директиву `COPY`. - -```docker -# копируем исходный код -COPY . . -``` - -Сервер привязан к `8080` порту, поэтому мы будем использовать -инструкцию `EXPOSE`, чтобы проинформировать Docker о том, что в контейнере -имеется приложение, прослушивающее этот порт. - -```docker -EXPOSE 8080 -``` - -Последняя, но не менее важная команда `CMD` содержит все необходимые -переменные среды и инструкции для запуска приложения. -Здесь мы просто используем `node server.js` для запуска. - -```docker -CMD [ "node", "server.js" ] -``` - -Ваш `Dockerfile` теперь должен выглядеть примерно так: - -```docker -FROM node:12 - -# создание директории приложения -WORKDIR /usr/src/app - -# установка зависимостей -# символ астериск ("*") используется для того чтобы по возможности -# скопировать оба файла: package.json и package-lock.json -COPY package*.json ./ - -RUN npm install -# Если вы создаете сборку для продакшн -# RUN npm ci --omit=dev - -# копируем исходный код -COPY . . - -EXPOSE 8080 -CMD [ "node", "server.js" ] -``` - -## Файл .dockerignore - -Создайте файл `.dockerignore` в той же директории, что и `Dockerfile`, -со следующим содержимым: - -``` -node_modules -npm-debug.log -``` - -Это предотвратит копирование локально установленных модулей и дебаг-логов -в Docker-образ и возможную перезапись модулей установленных внутри образа. - -## Сборка образа - -Перейдите в директорию, в которой находится ваш `Dockerfile` и запустите -следующую команду, чтобы собрать Docker-образ. Флаг `-t` позволяет поставить -тэг к вашему образу, чтобы его позже было проще найти при помощи команды -`docker images`: - -```bash -docker build . -t /node-web-app -``` - -Созданный образ теперь будет отображаться в списке всех образов: - -```bash -$ docker images - -# пример вывода -repository tag id created -node 12 1934b0b038d1 5 days ago -/node-web-app latest d64d3505b0d2 1 minute ago -``` - -## Запуск образа - -Запуск образа с флагом `-d` позволяет контейнеру работать в фоновом режиме. -Флаг `-p` перенаправляет публичный порт на приватный порт внутри контейнера. -Запустите образ, который вы ранее создали: - -```bash -docker run -p 49160:8080 -d /node-web-app -``` - -Отобразите логи вашего приложения: - -```bash -# отобразить все контейнеры, чтобы получить id нужного нам -$ docker ps - -# отобразить логи -$ docker logs - -# пример логов -running on http://localhost:8080 -``` - -Если вам нужно попасть внутрь контейнера, используйте команду `exec`: - -```bash -# войти в контейнер в интерактивном режиме -$ docker exec -it /bin/bash -``` - -## Проверка - -Чтобы проверить ваше приложение, используйте публичный порт, к которому привязан контейнер: - -```bash -$ docker ps - -# пример вывода -id image command ... ports -ecce33b30ebf /node-web-app:latest npm start ... 49160->8080 -``` - -В примере выше docker связал порт `8080` внутри контейнера с портом `49160` -на вашем компьютере. - -Вы можете сделать запрос к вашему приложению с помощью утилиты `curl` -(установите ее, если требуется с помощью команды: `sudo apt-get install curl`): - -```bash -$ curl -i localhost:49160 - -http/1.1 200 ok -x-powered-by: express -content-type: text/html; charset=utf-8 -content-length: 12 -etag: w/"c-m6twob/y57lesdjquheb1p/qtv0" -date: mon, 13 nov 2017 20:53:59 gmt -connection: keep-alive - -hello world -``` - -Надеемся, что эта инструкция помогла вам настроить и запустить простое приложение -Node.js с помощью Docker. - -Вы можете найти больше информации о Docker и Node.js в docker по следующим ссылкам: - -- [Официальный docker-образ Node.js](https://hub.docker.com/_/node/) -- [Руководство по лучшим практикам Node.js в Docker](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md) -- [Официальная документация Docker](https://docs.docker.com/) -- [Тэг Docker на stack overflow](https://stackoverflow.com/questions/tagged/docker) -- [Канал Docker на reddit](https://reddit.com/r/docker) diff --git a/pages/ru/docs/guides/simple-profiling.md b/pages/ru/docs/guides/simple-profiling.md deleted file mode 100644 index d357bf0f3a14b..0000000000000 --- a/pages/ru/docs/guides/simple-profiling.md +++ /dev/null @@ -1,288 +0,0 @@ ---- -title: Простое профилирование Node.js приложений -layout: docs.hbs ---- - -# Простое профилирование Node.js приложений - -Для профилирования приложений Node.js доступно множество сторонних инструментов, -но во многих случаях проще всего использовать встроенный профайлер Node.js. -Встроенный профайлер использует [профайлер V8][], который делит стек -выполняющейся программы на фрагменты через равные промежутки времени. Профайлер -представляет результаты этих фрагментов с учетом оптимизаций, таких как -Jit-компиляция, в виде ряда тиков: - -``` -code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~ -code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~ -code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~ -code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub" -code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub" -``` - -В прошлом требовался бы исходный код V8, чтобы иметь возможность анализировать -тики. К счастью, начиная с Node.js 4.4.0 были представлены инструменты, которые -облегчают использование этой информации без отдельной сборки V8. Давайте посмотрим, -как встроенный профайлер дает представление о производительности приложений. - -Возьмем простое приложением Express, чтобы проиллюстрировать использование профайлера. -Приложение будет иметь два обработчика, один из которых будет использоваться для -добавления новых пользователей в систему: - -```javascript -app.get('/newUser', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users[username]) { - return res.sendStatus(400); - } - - const salt = crypto.randomBytes(128).toString('base64'); - const hash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - users[username] = { salt, hash }; - - res.sendStatus(200); -}); -``` - -а другой - для проверки аутентификации пользователей: - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || !users[username]) { - return res.sendStatus(400); - } - - const { salt, hash } = users[username]; - const encryptHash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - if (crypto.timingSafeEqual(hash, encryptHash)) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } -}); -``` - -_Обратите внимание, что это НЕ рекомендуемые обработчики для аутентификации -пользователей в приложениях Node.js. Они используются исключительно в качестве -примера. В целом, не следует пытаться разработать свои собственные механизмы -криптографической аутентификации. Гораздо лучше использовать готовые проверенные -решения._ - -Теперь предположим, что мы развернули наше приложение, и пользователи жалуются -на высокую задержку запросов. Мы можем легко запустить приложение с помощью -встроенного профайлера: - -``` -NODE_ENV=production node --prof app.js -``` - -и добавить нагрузку на сервер с помощью `ab` (ApacheBench): - -``` -curl -X GET "http://localhost:8080/newUser?username=matt&password=password" -ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password" -``` - -и получить на выходе: - -``` -Concurrency Level: 20 -Time taken for tests: 46.932 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 5.33 [#/sec] (mean) -Time per request: 3754.556 [ms] (mean) -Time per request: 187.728 [ms] (mean, across all concurrent requests) -Transfer rate: 1.05 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 3755 - 66% 3804 - 75% 3818 - 80% 3825 - 90% 3845 - 95% 3858 - 98% 3874 - 99% 3875 - 100% 4225 (longest request) -``` - -По выводу видно, что обрабатывается только около 5 запросов в секунду, и в среднем -занимает чуть менее 4 секунд в обе стороны. В реальной ситуации могло бы -последовать еще множество вычислений от имени пользовательского запроса, но даже -в нашем простом примере могут возникать временные потери как при компиляции -регулярных выражений, генерации случайных солей и хешей из паролей пользователей, -так и внутри самого фреймворка Express. - -Так как мы запустили приложение, используя опцию `--prof`, тиковый файл был -сгенерирован в том же каталоге, откуда приложение было запущено. Он должен быть -вида `isolate-0xnnnnnnnnnnnn-v8.log` (где `n` - цифра). - -Чтобы разобраться в этом файле, используйте тиковый процессор в комплекте с двоичным -файлом Node.js. Чтобы запустить процессор, используйте флаг `--prof-process`: - -``` -node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt -``` - -Открыв обработанный текст в вашем любимом текстовом редакторе, вы увидите различного -вида информацию. Файл разбит на секции, которые разбиты по языкам. Взглянем сначала -на итоговый раздел: - -``` - [Summary]: - ticks total nonlib name - 79 0.2% 0.2% JavaScript - 36703 97.2% 99.2% C++ - 7 0.0% 0.0% GC - 767 2.0% Shared libraries - 215 0.6% Unaccounted -``` - -Это говорит нам о том, что 97% всех собранных замеров происходили в коде C++, -и что при просмотре других разделов обработанного вывода мы должны уделять -больше внимания работе, выполняемой именно в C++ (а не, к примеру, JavaScript). -Имея это в виду, мы затем находим раздел \[C++\], который содержит информацию о том, -какие функции C++ отнимают больше всего процессорного времени, и видим: - -``` - [C++]: - ticks total nonlib name - 19557 51.8% 52.9% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 4510 11.9% 12.2% _sha1_block_data_order - 3165 8.4% 8.6% _malloc_zone_malloc -``` - -Мы видим, что на первые три записи приходится 72,1% процессорного времени, -используемого программой. Мы также сразу видим, что как минимум 51,8% -процессорного времени занято функцией PBKDF2, которая соответствует нашей -генерации хеш-кода из пароля пользователя. Тем не менее, может быть -не сразу очевидно, как две нижние записи влияют на наше приложение -(если же вы догадываетесь об этом, мы притворимся, что это не очевидно, в целях примера). -Чтобы лучше понять взаимосвязь между этими функциями, мы обратимся затем к -разделу \[Bottom up (heavy) profile\], который предоставляет информацию о том, -где чаще всего вызывается каждая функция. Исследуя этот раздел, мы находим: - -``` - ticks parent name - 19557 51.8% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 19557 100.0% v8::internal::Builtins::~Builtins() - 19557 100.0% LazyCompile: ~pbkdf2 crypto.js:557:16 - - 4510 11.9% _sha1_block_data_order - 4510 100.0% LazyCompile: *pbkdf2 crypto.js:557:16 - 4510 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 - - 3165 8.4% _malloc_zone_malloc - 3161 99.9% LazyCompile: *pbkdf2 crypto.js:557:16 - 3161 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 -``` - -Анализ этого раздела требует немного больше работы, чем простой подсчет тиков как выше. -В каждом из вышеприведенных стеков вызовов процент в родительском столбце показывает -процент выборок, для которых функция в строке выше была вызвана функцией в текущей строке. -Например, в среднем стеке для \_sha1_block_data_order мы видим, -что вызов `_sha1_block_data_order` встречался в 11,9% выборок, что мы и так знали -исходя из подсчетов выше. Однако теперь мы также можем сказать, -что он всегда вызывался функцией pbkdf2 внутри модуля crypto Node.js. Мы видим, -что аналогичным образом `_malloc_zone_malloc` вызывалась практически всегда -той же функцией pbkdf2. Таким образом, используя информацию в этом представлении, -мы можем сказать, что наше вычисление хеша из пароля пользователя составляет -не только указанные 51,8%, а все процессорное время в 3 самых часто вызываемых функциях, -так как вызовы `_sha1_block_data_order` и `_malloc_zone_malloc` были сделаны -от имени функции pbkdf2. - -Теперь становится ясно, что целью нашей оптимизации должна быть генерация хеша на основе пароля. -К счастью, вы полностью усвоили [преимущества асинхронного программирования][] -и понимаете, что работа по генерации хеша выполняется синхронно -и, таким образом, связывает цикл обработки событий. Это лишает нас возможности работать с -другими входящими запросами во время вычисления хеша. - -Чтобы устранить эту проблему, внесем небольшую модификацию в наши обработчики, -используя асинхронную версию функции pbkdf2: - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users[username]) { - return res.sendStatus(400); - } - - crypto.pbkdf2( - password, - users[username].salt, - 10000, - 512, - 'sha512', - (err, hash) => { - if (users[username].hash.toString() === hash.toString()) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } - } - ); -}); -``` - -В результате нового запуска теста ab для асинхронной версии приложения -получаем результат: - -``` -Concurrency Level: 20 -Time taken for tests: 12.846 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 19.46 [#/sec] (mean) -Time per request: 1027.689 [ms] (mean) -Time per request: 51.384 [ms] (mean, across all concurrent requests) -Transfer rate: 3.82 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 1018 - 66% 1035 - 75% 1041 - 80% 1043 - 90% 1049 - 95% 1063 - 98% 1070 - 99% 1071 - 100% 1079 (longest request) -``` - -Ура! Наше приложение теперь обрабатывает около 20 запросов в секунду, -что примерно в 4 раза больше, чем при синхронном генерировании хешей. -Кроме того, средняя задержка снизилась с 4 секунд -до чуть более 1 секунды. - -Надеемся, что благодаря разбору производительности этого -(заведомо надуманного) примера вы увидели, как тиковый процессор -V8 может дать вам лучшее понимание производительности ваших приложений Node.js. - -[профайлер V8]: https://v8.dev/docs/profile -[преимущества асинхронного программирования]: https://nodesource.com/blog/why-asynchronous diff --git a/pages/ru/docs/guides/timers-in-node.md b/pages/ru/docs/guides/timers-in-node.md deleted file mode 100644 index cff5bdf8d827b..0000000000000 --- a/pages/ru/docs/guides/timers-in-node.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: Таймеры в Node.js -layout: docs.hbs ---- - -# Таймеры в Node.js и за пределами - -Модуль таймеров в Node.js содержит функции, которые выполняют код по истечении -заданного периода времени. Таймеры не нужно импортировать через `require()`, так как -все методы доступны глобально для эмуляции браузерного JavaScript API. -Для того, чтобы полностью понять когда будут выполняться функции таймера, имеет смысл -прочитать об [Event Loop](/en/docs/guides/event-loop-timers-and-nexttick/) в Node.js. - -## Управление временным континуумом с Node.js - -API Node.js предоставляет несколько способов планирования кода, который нужно -выполнить, в какой-то момент в будущем. Приведенные ниже функции могут показатья знакомыми, так как -они доступны в большинстве браузеров, но Node.js на самом деле предоставляет -свою реализацию этих методов. Таймеры очень тесно интегрируются с системой, и, несмотря на то, -что API Node.js отражает API браузера, все равно имеются некоторые различия в реализации. - -### "Когда я скажу" Выполнение ~ _`setTimeout()`_ - -`setTimeout()` может использоваться для планирования выполнения кода после назначенного -количества миллисекунд. Эта функция аналогична [`window.setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) из JavaScript API браузера, однако строка кода не может передаваться -в качестве аргумента для выполнения. - -`setTimeout()` первым параметром принимает функцию, которую нужно выполнить, и задержку в миллисекундах, -как число, в качестве второго параметра. Также можно перечислить дополнительные аргументы и они -будут переданы функции. Вот пример этого: - -```js -function myFunc(arg) { - console.log(`arg was => ${arg}`); -} - -setTimeout(myFunc, 1500, 'funky'); -``` - -Функция `myFunc()` выполнится через время, максимально приближенное к -1500 миллисекундам (или 1.5 секунды), из-за вызова `setTimeout()`. - -Нельзя полагаться на то, что тайм-аут выполнится после этого _точного_ количества миллисекунд. -Это связано с тем, что другой исполняемый код, который блокирует или удерживает цикл событий, -отодвигает выполнение тайм-аута на задний план. _Единственной_ гарантией является то, что -тайм-аут не будет выполнен раньше, чем заданный интервал. - -`setTimeout()` возвращает объект `Timeout`, который можно использовать в качестве ссылки -на тайм-аут, который был установлен. Этот объект можно использовать для отмены тайм-аута (см. `clearTimeout()` ниже), а также для изменения поведения при выполнении (см. `unref()` ниже). - -### "Сразу после этого" Выполнение ~ _`setImmediate()`_ - -`setImmediate()` выполнит код в конце текущего цикла событий. -Этот код будет выполняться _после_ любых операций ввода-вывода в текущем цикле событий и -_перед_ любым запланированными таймерами для следующего цикла событий. Такое выполнение кода -можно рассматривать как "сразу после этого", то есть любой код, следующий за вызовом -функции `setImmediate()`, будет выполняться до аргумента функции `setImmediate()`. - -Первым аргументом `setImmediate()` будет функция, которую нужно выполнить. Все последующие -аргументы будут переданы функции при ее выполнении. Вот пример: - -```js -console.log('before immediate'); - -setImmediate(arg => { - console.log(`executing immediate: ${arg}`); -}, 'so immediate'); - -console.log('after immediate'); -``` - -Функция, переданная в `setImmediate()`, будет выполнена после того, -как будет выполнен весь исполняемый код, и в консоли мы увидим следующее: - -``` -before immediate -after immediate -executing immediate: so immediate -``` - -`setImmediate()` возвращает объект `Immediate`, который можно использовать для отмены -запланированного immediate (см. `clearImmediate()` ниже). - -Примечание: Не путайте `setImmediate()` и `process.nextTick()`. Между ними есть -несколько основных различий. Во-первых, `process.nextTick()` выполнится _перед_ любыми `Immediate`, -а также перед любыми запланированными операциями ввода/вывода. Во-вторых, `process.nextTick()` не подлежит -отмене, имеется в виду, что после того как вы запланировали выполнение кода с помощью `process.nextTick()`, -то его выполнение не может быть приостановлено, также как и с обычной функцией. Обратитесь к -[этому руководству](/en/docs/guides/event-loop-timers-and-nexttick/#process-nexttick), чтобы лучше понять -работу `process.nextTick()`. - -### "Бесконечный цикл" Выполнение ~ _`setInterval()`_ - -Если у вас есть код, который нужно выполнить несколько раз, то можно использовать -для этого `setInterval()`. `setInterval()` принимает параметром функцию, которая будет -выполняться бесконечное количество раз с заданным интервалом в миллисекундах, сам интервал передается -вторым параметром. Как и в случае с `setTimeout()` можно передавать дополнительные аргументы, -эти аргументы будут переданы функции при вызове. Также как и с `setTimeout()`, задержка не может -быть гарантирована из-за операций, которые могут удерживать цикл событий, следовательно, нужно -рассматривать эту задержку как приблизительную. Смотрите пример ниже: - -```js -function intervalFunc() { - console.log('Cant stop me now!'); -} - -setInterval(intervalFunc, 1500); -``` - -В примере выше `intervalFunc()` будет выполняться каждые 1500 миллисекунд -или 1.5 секунд, до тех пор, пока ее не остановят (см. ниже). - -`setInterval()`, также как и `setTimeout()` возвращает объект `Timeout`, который -можно использовать в качестве ссылки для изменения установленного интервала. - -## Отмена грядущего - -Что нужно сделать, чтобы отменить `Timeout` или `Immediate`? `setTimeout()`, `setImmediate()` и -`setInterval()` возвращают объект таймера, который можно использовать в качестве ссылки на установленные -`Timeout` и `Immediate` объекты. При передаче этого объекта в соответствующую функцию `clear` - выполнение -этого объекта будет полностью остановлено. `clearTimeout()`, `clearImmediate()` и `clearInterval()` - это те -самые специальные функции. Давайте посмотрим на пример ниже: - -```js -const timeoutObj = setTimeout(() => { - console.log('timeout beyond time'); -}, 1500); - -const immediateObj = setImmediate(() => { - console.log('immediately executing immediate'); -}); - -const intervalObj = setInterval(() => { - console.log('interviewing the interval'); -}, 500); - -clearTimeout(timeoutObj); -clearImmediate(immediateObj); -clearInterval(intervalObj); -``` - -## Оставляя тайм-ауты позади - -Помните, что `setTimeout` и `setInterval` возвращают объект `Timeout`. -У объекта `Timeout` есть два метода, чтобы расширить свое поведение, это -`unref()` и `ref()`. Если есть объект `Timeout`, запланированный с использованием функции `set`, -то для этого объекта может быть вызвана `unref()`. Это немного изменит поведение тем, что объект -`Timeout` не выполнит запланированный код, _если это последний код, который нужно выполнить_. Объект `Timeout` -не будет удерживать процесс в ожидании выполнения. - -Аналогичным образом, объект `Timeout`, на котором был вызван `unref()`, -может убрать это поведение, вызвав `ref()` на том же `Timeout` объекте, что затем -обеспечит его выполнение. Однако имейте в виду, что это не _точно_ восстанавливает -исходное поведение по причинам производительности. Давайте взглянем на примеры ниже: - -```js -const timerObj = setTimeout(() => { - console.log('will i run?'); -}); - -// если оставить без внимания, то это выражение -// не позволит выполниться тайм-ауту выше, так как сам тайм-аут -// будет единственным, что не позволит программе завершиться -timerObj.unref(); - -// мы можем вернуть его к жизни вызвав ref() внутри immediate -setImmediate(() => { - timerObj.ref(); -}); -``` - -## Далее по событийному циклу - -В событийном цикле и таймерах можно найти гораздо больше информации, чем в -этом руководстве. Чтобы узнать больше о внутренностях цикла событий Node.js и о том, -как работают таймеры во время выполнения - взгляните на это руководство: [The Node.js Event Loop, Timers, and process.nextTick()](/en/docs/guides/event-loop-timers-and-nexttick/). diff --git a/pages/ru/docs/index.mdx b/pages/ru/docs/index.mdx deleted file mode 100644 index 54a1720596400..0000000000000 --- a/pages/ru/docs/index.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Документация -layout: docs.hbs -labels: - lts: LTS ---- - -# О документации - -На этом сайте представлено несколько видов документаций: - -- Документация API -- Функциональность ES6 -- Руководства - -## Документация API - -[API документации](https://nodejs.org/api/) предоставляет подробную информацию о функциях и объектах в Node.js. -В ней содержится информация о принимаемых аргументах, возвращаемом значении и ошибках связанных -рассматриваемым методом. Также содержит информацию о доступных методах доступны для разных версий Node.js. - -В этой документации описываются встроенные модули, предоставляемые Node.js. Он не документирует модули, -предоставленные сообществом. - -
- -### Нужна документация API предыдущих версий? - - - -[Все версии](https://nodejs.org/docs/) - -
- -## Функциональность ES6 - -[Раздел ES6](/ru/docs/es6/) описывает три группы функциональности ES6 и подробную информацию о том, какие функции -включены по умолчанию в Node.js. Также рассматривается вопрос: как найти версию V8, поставляемую с конкретным -выпуском Node.js. - -## Руководства - -[Раздел руководств](/ru/docs/guides/) содержит подробные статьи о технических возможностях Node.js. diff --git a/pages/ru/download/current.md b/pages/ru/download/current.md deleted file mode 100644 index efc1b5b36db6c..0000000000000 --- a/pages/ru/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Загрузка -download: Загрузка -downloads: - headline: Загрузки - lts: LTS - current: Текущая - tagline-current: Последняя функциональность - tagline-lts: Рекомендованный для большинства - display-hint: Показать загрузки для - intro: > - Загрузите исходный код Node.js или готовый установщик для вашей платформы и начните разработку уже сегодня. - currentVersion: Последняя текущая версия - buildInstructions: Сборка Node.js из исходного кода на поддерживаемых платформах - WindowsInstaller: Установщик Windows - WindowsBinary: Бинарный Windows - MacOSInstaller: Установщик macOS - MacOSBinary: Бинарный macOS - LinuxBinaries: Бинарный Linux - SourceCode: Исходный код -additional: - headline: Дополнительные платформы - intro: > - Члены сообщества Node.js поддерживают неофициальные сборки Node.js для ряда других платформ. Обратите внимание, что такие сборки не поддерживаются основной командой Node.js и могут не содержать всей функциональности, что и текущая версия Node.js. - platform: Платформа - provider: Провайдер - SmartOSBinaries: Исходный код для SmartOS - DockerImage: Образ Docker - officialDockerImage: Официальный Docker-образ Node.js - LinuxPowerSystems: Linux на Power LE Systems - LinuxSystemZ: Linux на System z - AIXPowerSystems: AIX на Power Systems ---- diff --git a/pages/ru/download/index.md b/pages/ru/download/index.md deleted file mode 100644 index 91e98f289b88c..0000000000000 --- a/pages/ru/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Загрузка -download: Загрузка -downloads: - headline: Загрузки - lts: LTS - current: Текущая - tagline-current: Последняя функциональность - tagline-lts: Рекомендованный для большинства - display-hint: Показать загрузки для - intro: > - Загрузите исходный код Node.js или готовый установщик для вашей платформы и начните разработку уже сегодня. - currentVersion: Последняя текущая версия - buildInstructions: Сборка Node.js из исходного кода на поддерживаемых платформах - WindowsInstaller: Установщик Windows - WindowsBinary: Бинарный Windows - MacOSInstaller: Установщик macOS - MacOSBinary: Бинарный macOS - LinuxBinaries: Бинарный Linux - SourceCode: Исходный код -additional: - headline: Дополнительные платформы - intro: > - Члены сообщества Node.js поддерживают неофициальные сборки Node.js для ряда других платформ. Обратите внимание, что такие сборки не поддерживаются основной командой Node.js и могут не содержать всей функциональности, что и текущая версия Node.js. - platform: Платформа - provider: Провайдер - SmartOSBinaries: Исходный код для SmartOS - DockerImage: Образ Docker - officialDockerImage: Официальный Docker-образ Node.js - LinuxPowerSystems: Linux на Power LE Systems - LinuxSystemZ: Linux на System z - AIXPowerSystems: AIX на Power Systems ---- diff --git a/pages/ru/download/package-manager.md b/pages/ru/download/package-manager.md deleted file mode 100644 index 04e2d17c949d7..0000000000000 --- a/pages/ru/download/package-manager.md +++ /dev/null @@ -1,287 +0,0 @@ ---- -layout: page.hbs -title: Установка Node.js через пакетный менеджер ---- - -# Установка Node.js через пакетный менеджер - -**_Заметка:_** Пакеты, описанные на этой странице, разрабатываются и поддерживаются соответствующими упаковщиками, **а не** командой Node.js. Пожалуйста, сообщайте о любых проблемах, с которыми вы сталкиваетесь с конкретным пакетом. Если выяснится, что ваша проблема ― ошибка в самом Node.js, проблема будет передана выше. - ---- - -- [Android](#android) -- [Arch Linux](#arch-linux) -- [Дистрибутивы Linux на основе Debian и Ubuntu, пакеты Enterprise Linux/Fedora и Snap](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE и SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS и illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) - ---- - -## Android - -Поддержка Android все еще является экспериментальной в Node.js, поэтому предварительно скомпилированные -двоичные файлы еще не предоставлены в открытом доступе. - -Однако есть и сторонние решения. Например, сообщество [Termux](https://termux.com/) предоставляет эмулятор терминала и среду Linux для Android, а также собственный менеджер пакетов и [обширную коллекцию](https://github.com/termux/termux-packages) многих предварительно скомпилированных приложений. Эта команда в приложении Termux установит последнюю доступную версию Node.js: - -```bash -pkg install nodejs -``` - -В настоящее время двоичные файлы Termux Node.js связаны с `system-icu` (в зависимости от пакета `libicu`). - -## Arch Linux - -Пакеты Node.js и npm доступны в репозитории сообщества. - -```bash -pacman -S nodejs npm -``` - -## Дистрибутивы Linux на основе Debian и Ubuntu, пакеты Enterprise Linux/Fedora и Snap - -[Официальный Node.js бинарный дистрибутив](https://github.com/nodesource/distributions) предоставляемый NodeSource. - -## FreeBSD - -Самый последний выпуск Node.js доступен через порт [www/node](https://www.freshports.org/www/node). - -Установите бинарный пакет через [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): - -```bash -pkg install node -``` - -Или скомпилируйте свой используя [порты](https://www.freebsd.org/cgi/man.cgi?ports): - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js доступен в дереве портежей. - -```bash -emerge nodejs -``` - -## NetBSD - -Node.js доступен в дереве pkgsrc: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -Или установите бинарный пакет (если он доступен для вашей платформы) с помощью pkgin: - -```bash -pkgin -y install nodejs -``` - -## nvm - -Node Version Manager ― это bash-скрипт, используемый для управления несколькими выпущенными версиями Node.js. Он позволяет -выполнять такие операции, как установка, удаление, переключение версий и т.д.. -Чтобы установить nvm, используйте этот [скрипт установки](https://github.com/nvm-sh/nvm#install--update-script). - -В системах Unix/OS X Node.js, созданный из исходного кода, можно установить с помощью -[nvm](https://github.com/creationix/nvm) путем установки в папку по умолчанию nvm: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -После этого вы можете использовать `nvm` для переключения между выпущенными версиями и версиями -построенных из исходного кода. -Например, если версия Node.js v8.0.0-pre: - -```bash -nvm use 8 -``` - -После выхода официального релиза вы захотите удалить встроенную версию: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -The `nvs` version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems - -To install `nvs` on Windows go to the [release page](https://github.com/jasongin/nvs/releases) here and download the MSI installer file of the latest release. - -You can also use `chocolatey` to install it: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -You can find the documentation regarding the installation steps of `nvs` in macOS/Unix-like systems [here](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### Usage - -After this you can use `nvs` to switch between different versions of node. - -To add the latest version of node: - -```bash -nvs add latest -``` - -Or to add the latest LTS version of node: - -```bash -nvs add lts -``` - -Then run the `nvs use` command to add a version of node to your `PATH` for the current shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -To add it to `PATH` permanently, use `nvs link`: - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js доступен через систему портов. - -```bash -/usr/ports/lang/node -``` - -Использование [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) в OpenBSD: - -```bash -pkg_add node -``` - -## openSUSE и SLE - -Node.js доступен в основных репозиториях в следующих пакетах: - -- **openSUSE Leap 42.2**: `nodejs4` -- **openSUSE Leap 42.3**: `nodejs4`, `nodejs6` -- **openSUSE Tumbleweed**: `nodejs4`, `nodejs6`, `nodejs8` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs4`, `nodejs6` - ("Модуль Web и Scripting" должен быть [добавлен перед установкой](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html).) - -Например, чтобы установить Node.js 4.x в openSUSE Leap 42.2, запустите следующее от имени пользователя root: - -```bash -zypper install nodejs4 -``` - -## macOS - -Просто загрузите [установщик macOS](https://nodejs.org/ru/#home-downloadhead) прямо с веб-сайта [nodejs.org](https://nodejs.org/). - -_Если вы хотите скачать пакет с bash:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### Альтернативы - -Использование **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -Использование **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Пример -port install nodejs7 -``` - -Использование **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -Установка бинарных файлов: - -```bash -pkgin -y install nodejs -``` - -Или сборка с помощью pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## SmartOS и illumos - -Образы SmartOS поставляются с предустановленным pkgsrc. В других дистрибутивах Illumos сначала установите **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, затем вы сможете установить бинарный пакет как обычно: - -```bash -pkgin -y install nodejs -``` - -Или собрать с помощью pkgsrc: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -Solus предоставляет Node.js в своем основном репозитории. - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux поставляет стабильный файл Node.js в основном репозитории. - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -Просто загрузите [Установщик Windows](https://nodejs.org/ru/#home-downloadhead) прямо с веб-сайта [nodejs.org](https://nodejs.org/). - -### Альтернативы - -Использование **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# или полная установка с npm -cinst nodejs.install -``` - -Использование **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -``` diff --git a/pages/ru/download/releases.md b/pages/ru/download/releases.md deleted file mode 100644 index 4a3efec83cebe..0000000000000 --- a/pages/ru/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Предыдущие версии -modules: 'NODE_MODULE_VERSION относится к номеру версии Node.js ABI (двоичный интерфейс приложения), который используется для определения того, в какие версии скомпилированных двоичных файлов C++ Node.js можно загружать файлы без необходимости перекомпиляции. Раньше он хранился как шестнадцатеричное значение в более ранних версиях, но теперь представляется как целое число.' ---- - -### io.js & Node.js - -Релизы от 1.x до 3.x выходили под именем "io.js", так как они были частью форка io.js. Начиная с Node.js 4.0.0, предыдущие версии io.js перешли с Node.js 0.12.x в унифицированные версии Node.js. - -### Ищете последнюю версию ветки версии? diff --git a/pages/ru/get-involved/collab-summit.md b/pages/ru/get-involved/collab-summit.md deleted file mode 100644 index e6972115dc428..0000000000000 --- a/pages/ru/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Саммит сотрудников -layout: contribute.hbs ---- - -# Саммит сотрудников - -Саммит сотрудников (Collaboration Summit) ― это "анти"-конференция, на которую собираются нынешние и потенциальные участники, чтобы вживую обсудить Node.js, и поделится знаниями. Комитеты и рабочие группы собираются два раза в год для принятия важных решений, а также могут работать над некоторыми проектами, которые они хотят продвигать лично. - -## Кто приглашен? - -Любой желающий может посетить саммит сотрудников. Во время саммита лидеры будут помогать новым участникам внедрится в интересующие их группы, прежде чем добавить их в рабочие сессии. - -Это возможность узнать о том, что происходит в сообществе, прежде чем присоединиться и поделиться своими навыками, которые вы хотели бы отточить. - -Рабочие группы заранее составят график мероприятия, чтобы участники могли строить свои планы прежде, чем окажутся на месте. Проведут общие обсуждения с сотрудниками, а затем погрузятся в секционные заседания. - -Мы будем рады видеть вас на саммит сотрудников! Посмотрите [репозиторий саммита](https://github.com/nodejs/summit) для предстоящих и прошедших мероприятий и ознакомьтесь с [вопросами](https://github.com/nodejs/summit/issues) поставленными для дальнейшего живого обсуждения. diff --git a/pages/ru/get-involved/contribute.md b/pages/ru/get-involved/contribute.md deleted file mode 100644 index 109a1e8744d24..0000000000000 --- a/pages/ru/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Участие -layout: contribute.hbs ---- - -# Участие - -Благодарим за интерес к участию в Node.js! Есть несколько способов и сфер, где вы можете внести свой вклад, и мы здесь, чтобы помочь в этом. - -## Обращение за общей помощью - -Поскольку уровень активности в репозитории `nodejs/node` очень высок, вопросы или запросы об общей помощи в Node.js следует направлять в [репозиторий справки Node.js](https://github.com/nodejs/help/issues). - -## Сообщение о проблеме - -Если вы обнаружили проблему с Node.js, не стесняйтесь создать issue в проекте GitHub. При создании issue, пожалуйста, максимально четко опишите проблему и приложите самодостаточный и воспроизводимый пример, без внешних зависимостей. То есть пример должен работать на чистом Node.js. - -При рапорте проблемы, также требуется как можно больше информации о среде выполнения. Мы никогда не знаем, какая информация будет уместна при попытке идентифицировать проблему. Пожалуйста, включите по крайней мере следующую информацию: - -- Версия Node.js -- Платформа, на которой вы работаете (macOS, SmartOS, Linux, Windows) -- Архитектура, на которой вы работаете (32-битная или 64-битная и x86 или ARM) - -В настоящее время проектом Node.js управляют несколько отдельных репозиториев GitHub, каждый из которых имеет свою собственную базу данных issues. Если возможно, просьба направлять issue в соответствующий репозиторий, но не беспокойтесь, если что-то окажется не в том месте, сообщество участников с радостью помогут перенаправить вас. - -- Чтобы сообщить о проблеме, специфичных для Node.js, используйте [nodejs/node](https://github.com/nodejs/node) -- Чтобы сообщить о проблемах, характерных для этого веб-сайта, используйте [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## Написание кода - -Если вы хотите исправить ошибки или добавить новую функциональность в Node.js, обязательно ознакомьтесь с [правилами участия для Node.js](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). Там же объясняется процесс проверки существующими сотрудниками всех вкладов в проект. - -Если вам интересно, как начать, вы можете проверить [Node Todo](https://www.nodetodo.org/), который поможет найти ваш первый шаг в развитии Node.js сообщества. - -## Становление участником - -Став участником, пользователь может оказать еще большее влияние на проект. Он может помочь другим участникам, проверяя их работы и сортируя issues, а также принять еще большее участие в формировании будущего проекта. Сотрудники, которые определены TSC как вносящие значительный и ценный вклад в любой репозиторий Node.js, могут стать соавторами и получить доступ к проекту. Принимаемые во внимание действия (но это не полный список): - -- код фиксы и pull request'ы -- исправления документации и pull request'ы -- комментарии по вопросам и pull request'ы -- вклад в сайт Node.js -- помощь, предоставляемая конечным пользователям и начинающим участникам -- участие в рабочих группах -- другое участие в сообществе Node.js - -Если люди, делающие ценный вклад, не считают, что их рассматривали для доступа к коммитам, они могут [создать issue](https://github.com/nodejs/TSC/issues) или [связаться с членами TSC](https://github.com/nodejs/TSC#current-members) напрямую. diff --git a/pages/ru/get-involved/index.md b/pages/ru/get-involved/index.md deleted file mode 100644 index 277183b3e38a5..0000000000000 --- a/pages/ru/get-involved/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Присоединиться -layout: contribute.hbs ---- - -# Присоединиться - -## Обсуждение сообщества - -- [Список проблем на GitHub](https://github.com/nodejs/node/issues) это место для обсуждения возможностей ядра Node.js. -- Официальный аккаунт Node.js в Твиттере ― [nodejs](https://twitter.com/nodejs). -- [Календарь Фонда Node.js](https://nodejs.org/calendar) со всеми общественными встречами. - -## Обучение - -- [Официальная справочная документация по API](https://nodejs.org/api/) описывает API Node.js -- [NodeSchool.io](https://nodeschool.io/) научит вас концепциям Node.js через интерактивные игры командной строки. -- [Тег Node.js на Stack Overflow](https://stackoverflow.com/questions/tagged/node.js) собирает новую информацию каждый день. -- [Тег сообщества на DEV.js](https://dev.to/t/node) ― это место, где можно делиться проектами, статьями и учебными - пособиями по Node.js, а также начинать обсуждения и запрашивать отзывы по темам, связанным с Node.js. Разработчики - всех уровней квалификации могут принять участие. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd), является дружественным сообществом бекенд-разработчиков на Node.js, - поддерживающих друг друга на Discord. - -## Международные общественные сайты и проекты - -- [Китайское сообщество](https://cnodejs.org/) -- [Венгерское (мадьярское) сообщество](https://nodehun.blogspot.com/) -- [Израильская группа Facebook для Node.js](https://www.facebook.com/groups/node.il/) -- [Японская группа пользователей](https://nodejs.jp/) -- [Испанская языковая группа Facebook для Node.js](https://www.facebook.com/groups/node.es/) -- [Вьетнамское сообщество Node.js](https://www.facebook.com/nodejs.vn/) -- [Узбекская группа Node.js](https://t.me/nodejs_uz) diff --git a/pages/ru/index.md b/pages/ru/index.md deleted file mode 100644 index e916ab1576fdb..0000000000000 --- a/pages/ru/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Текущая версия - download: Загрузить - download-for: Загрузить для - other-downloads: Другие загрузки - current: Текущая - lts: LTS - tagline-current: Новые возможности - tagline-lts: Рекомендовано для большинства - changelog: Список изменений - api: Документация - version-schedule-prompt: Информацию о поддерживаемых выпусках можно найти на - version-schedule-prompt-link-text: графике выпусков ---- - -Node.js® — это кросс-платформенная среда выполнения JavaScript с открытым исходным кодом. diff --git a/pages/tr/404.md b/pages/tr/404.md deleted file mode 100644 index 771d7098640e0..0000000000000 --- a/pages/tr/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Sayfa bulunamadı - -### ENOENT: Böyle bir dosya ya da dizin bulunamadı diff --git a/pages/tr/about/governance.md b/pages/tr/about/governance.md deleted file mode 100644 index 17c99ed6b503a..0000000000000 --- a/pages/tr/about/governance.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Proje Yönetimi -layout: about.hbs ---- - -# Proje Yönetimi - -## Uzlaşma Arama Süreci - -Node.js projesi, [fikir birliği arayışı][] karar verme modelini uygular. - -## Destekleyenler - -[nodejs/node][] ana Github deposu, Teknik Yönlendirme Komitesi ([TSC][]) tarafından eklenen Destekleyen Ekip tarafından korunur. - -Önemli ve değerli katkılarda bulunan kişiler Destekleyen ekibe dahil edilir ve projeye erişim hakkı verilir. Bu kişiler TSC ve mevcut destekleyici ekip üyeleri tarafından aday gösterilir. - -Destekleyen ekibin mevcut üye listesi için projenin [README.md][] dosyasına göz atın. - -Destekleyen ekip kılavuzu için [collaborator-guide.md][] dosyasına göz atın. - -## Üst Düzey Komiteler - -Bu proje, proje düzeyinde rehberlikten sorumlu olan [Teknik Yönlendirme Komitesi (TSC)][] ve Node.js topluluğunu yönlendirmek ve genişletmekten sorumlu olan [Topluluk Komitesi (CommComm)][] tarafından ortak yönetilmektedir. - -[ collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[Topluluk Komitesi (CommComm)]: https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md -[ fikir birliği arayışı]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[Teknik Yönlendirme Komitesi (TSC)]: https://github.com/nodejs/TSC/blob/master/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/tr/about/index.md b/pages/tr/about/index.md deleted file mode 100644 index 858b2ac8a3565..0000000000000 --- a/pages/tr/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Hakkında -trademark: Trademark ---- - -# Node.js® Hakkında - -Asenkron, olay tabanlı JavaScript çalışma ortamı olan Node.js, ölçeklenebilir ağ uygulamaları oluşturmak için tasarlanmıştır. Aşağıdaki "hello world" örneğinde, birçok bağlantı aynı anda ele alınabilir. Her bağlantıda geri çağırım başlatılır, ancak yapılacak hiçbir iş yoksa Node.js uyuyacaktır. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Bu, işletim sistemi iş parçacıklarının(thread) kullanıldığı günümüzün yaygın eşzamanlılık modelinin aksinedir. İş parçacığı tabanlı ağ iletişimi nispeten yetersiz ve kullanmak için zor. Ayrıca, Node.js kullanıcıları işlemlerin kilitlenmesinden endişe duymaz, çünkü kilitler yoktur. Node.js'deki neredeyse hiçbir işlev doğrudan G/Ç gerçekleştirmez, bu yüzden işlem hiç bloklanmaz. Hiçbir şey engellemediğinden, ölçeklenebilir sistemlerin Node.js'de geliştirilmesi çok makul. - -Bu dilin bir kısmı alışılmadık geldiyse, [Blocking vs. Non-Blocking][] hakkında tam bir makale mevcut. - ---- - -Node.js, Ruby'nin [Event Machine][] ve Python'ın [Twisted][] gibi sistemlerine tasarım olarak benzer ve bunlardan etkilenmiştir. Node.js olay modelini biraz daha ileri götürür. [event loop][]'u bir kütüphane yerine çalışma ortamı yapısı olarak sunar. Diğer sistemlerde, genellikle event-loop'u başlatan bir blokeli çağırım vardır. Tipik olarak, davranış betiğin başlangıcındaki geri çağırımlar vasıtasıyla tanımlanmıştır ve sonunda bir sunucu `EventMachine::run()` gibi bir blokeli çağırım vasıtasıyla başlatılır. Node.js'de böyle bir olay-dongüsünü-başlat çağırımı yoktur. Node.js girdi betiğini yürüttükten sonra basitçe olay döngüsüne girer. Node.js yerine getirilecek daha fazla geri çağırım kalmadığı zaman olay döngüsünden çıkar. Bu davranış internet tarayıcısındaki JavaScript gibidir - olay döngüsü kullanıcıdan gizlenmiştir. - -HTTP, akış ve düşük gecikme süresi göz önünde bulundurularak tasarlanan Node.js'de birinci sınıf bir vatandaştır. Bu, Node.js'yi bir web kütüphanesinin veya çatının oluşturulması için çok uygun yapar. - -Node.js'nin iş parçacıkları olmadan tasarlanmış olması, ortamınızdaki birden çok çekirdeğin avantajlarından yararlanamayacağınız anlamına gelmez. Çocuk işlemler [`child_process.fork()`][] API'miz kullanılarak oluşturulabilirler ve birbirleriyle iletişim kurması kolay olacak şekilde tasarlanmışlardır. Aynı arayüz üzerine kurulu [`cluster`][] modülü, çekirdekleriniz üzerindeki yük dengelemesini sağlamak için işlemler arasında soketleri paylaşmanıza olanak tanır. - -[Blocking vs. Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[event loop]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/tr/docs/es6.md b/pages/tr/docs/es6.md deleted file mode 100644 index 7cb3f8810a18c..0000000000000 --- a/pages/tr/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) ve ilerisi -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) ve ilerisi - -Node.js [V8](https://v8.dev/)'in modern sürümlerine göre oluşturulmuştur. Bu motorun en son sürümlerini güncel tutarak, [JavaScript ECMA-262 spesifikasyonundaki](http://www.ecma-international.org/publications/standards/Ecma-262.htm) yeni özelliklerin zamanında Node.js geliştiricilerine ulaştırılmasının yanı sıra sürekli performans ve kararlılık iyileştirmeleri sağlıyoruz. - -Bütün ECMAScript 2015 (ES6) özellikleri **shipping**, **staged** ve **in progress** olarak üç gruba ayrılmıştır: - -- Tüm **shipping** özellikleri, V8'in kararlı olduğunu düşündüğü, **Node.js'de varsayılan olarak açıktır** ve herhangi bir çalışma zamanı işareti **GEREKTİRMEZ**. -- **Staged** özellikleri, neredeyse tamamlanmış fakat V8 takımı tarafından kararlı olduğu düşünülmeyen özellikler, bir çalışma zamanı işareti gerektirir: `--harmony`. -- **In progress** özellikleri kendi uyum işaretiyle ayrı ayrı olarak etkinleştirilebilir, test amaçlı olmadıkça bu kesinlikle önerilmez. Not: bu işaretler V8 tarafından sunulmuştur ve herhangi bir kullanımdan kaldırma bildirimi olmaksızın potansiyel olarak değişecektir. - -## Hangi özellikler hangi Node.js sürümüyle beraber gelir? - -[node.green](https://node.green/) web sitesi, kangax'ın uyum tablosuna dayalı, Node.js'nin çeşitli sürümlerinde desteklenen ECMAScript özelliklerine mükemmel bir genel bakış sağlar. - -## Hangi özelikler yapım aşamasında? - -V8 motoruna sürekli olarak yeni özellikler eklenmektedir. Genel olarak, zamanlama bilinmese de, gelecekteki bir Node.js sürümüne geçmelerini bekleyin. - -Her Node.js sürümünde mevcut olan tüm _in progress_ özelliklerini `--v8-options` argümanını kullanarak listeleyebilirsiniz. Lütfen bunların eksik ve muhtemelen bozuk V8 özellikleri olduğunu unutmayın, bu nedenle bunları kendi sorumluluğunuzda kullanın: - -```bash -node --v8-options | grep "in progress" -``` - -## --harmony kullanarak altyapımı oluşturdum. Kullanmayı bırakmalı mıyım? - -Node.js üzerindeki `--harmony` işaretinin şu anki davranışı yalnızca **staged** özellikleri etkinleştirmektir. Sonuçta, artık `--es_staging` ile eş anlamlıdır. Yukarıda bahsedildiği gibi, bunlar henüz kararlı olduğu düşünülmeyen tamamlanmış özelliklerdir. Eğer risk almak istemiyorsanız, özellikle üretim ortamlarında, V8'de ve dolayısıyla Node.js'de varsayılan olarak gönderilinceye kadar bu çalışma zamanı işaretini kaldırmayı düşünün. Bunu etkin tutarsanız, gelecekteki Node.js yükseltmelerinde, V8 standartı yakından takip etmek için onların anlamlarını değiştirirse kodunuzun bozulmasına hazır olmalısınız. - -## Hangi V8 sürümünün hangi Node.js sürümüyle birlikte geldiğini nasıl öğrenebilirim? - -Node.js, `process` global nesnesi aracılığıyla tüm bağımlılıkları ve ilgili sürümleri listelemek için basit bir yol sağlar. V8 motoru hakkında, versiyonunu almak için terminalinize aşağıdakileri yazın: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/tr/docs/guides/diagnostics/index.md b/pages/tr/docs/guides/diagnostics/index.md deleted file mode 100644 index 8758e61d71453..0000000000000 --- a/pages/tr/docs/guides/diagnostics/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Tanılama Rehberi -layout: docs.hbs ---- - -# Tanılama Rehberi - -Bu rehberler, bir kullanıcının uygulamasındaki sorunu teşhis ederken rehberlik sağlaması amacıyla [Tanılama Çalışma Grubu][] tarafından oluşturulmuştur. - -Dokümantasyon projesi, kullanıcı deneyimi akışına göre yapılandırılmıştır. Bu akış, kullanıcının sorunlarının temel nedenlerini belirleyip adım adım çözebileceği tutarlı prosedürlerden oluşur. - -Mevcut teşhis araçları için rehberler şunlardır: - -- [Bellek](/en/docs/guides/diagnostics/memory) -- [Canlı Hata Ayıklama](/en/docs/guides/diagnostics/live-debugging) -- [Düşük Performans](/en/docs/guides/diagnostics/poor-performance) - -[Tanılama Çalışma Grubu]: https://github.com/nodejs/diagnostics diff --git a/pages/tr/docs/guides/diagnostics/live-debugging/index.md b/pages/tr/docs/guides/diagnostics/live-debugging/index.md deleted file mode 100644 index 9f59b2d9ed36b..0000000000000 --- a/pages/tr/docs/guides/diagnostics/live-debugging/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Canlı Hata Ayıklama -layout: docs.hbs ---- - -# Canlı Hata Ayıklama - -- [Canlı Hata Ayıklama](#live-debugging) - - [Uygulamam beklenen şekilde davranmıyor](#my-application-doesnt-behave-as-expected) - - [Belirtiler](#symptoms) - - [Hata ayıklama](#debugging) - -Bu dokümanda bir Node.js işleminde canlı hata ayıklamanın nasıl yapılacağını öğrenebilirsiniz. - -## Uygulamam beklenen şekilde davranmıyor - -### Belirtiler - -Kullanıcı, uygulamanın belirli girdiler için beklenen çıktıyı vermediğini gözlemleyebilir; örneğin, bir HTTP sunucusu belirli alanların boş olduğu bir JSON yanıtı döndürür. Süreç sırasında çeşitli şeyler yanlış gidebilir, ancak bu kullanım için temel olarak uygulamanın çalışma mantığına ve doğruluğuna odaklanıyoruz. - -### Hata ayıklama - -Bu kullanımda kullanıcı, HTTP isteği gibi bir tetikleyici için uygulamamızın çalıştırdığı kodu görmek ister. Ayrıca kullanıcı, kodda adım adım ilerlemek ve kodun çalışma aşamasını kontrol etmenin yanı sıra değişkenlerin bellekte hangi değerleri tuttuğunu incelemek isteyebilir. - -- [Inspector Kullanımı](/en/docs/guides/diagnostics/live-debugging/using-inspector) diff --git a/pages/tr/docs/guides/diagnostics/live-debugging/using-inspector.md b/pages/tr/docs/guides/diagnostics/live-debugging/using-inspector.md deleted file mode 100644 index abb34046b0050..0000000000000 --- a/pages/tr/docs/guides/diagnostics/live-debugging/using-inspector.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Inspector Kullanımı -layout: docs.hbs ---- - -# Inspector Kullanımı - -Lokal geliştirme ortamında, canlı hata ayıklama işlemini genellikle uygulamamıza bir hata ayıklayıcı ekleyip, breakpointler ile çalışmayı durdurarak gerçekleştiririz. Sonra, kodun çalışmasını adım adım izler ve adımlar arasında belleği kontrol ederiz. Ancak, canlı ortamda bu yöntemi kullanmak genellikle mümkün değildir çünkü makineye erişimimiz sınırlıdır ve uygulama kritik bir iş yaparken çalışmasını engelleyemeyiz. - -## Nasıl Yapılır - -https://nodejs.org/en/docs/guides/debugging-getting-started/ diff --git a/pages/tr/docs/guides/diagnostics/memory/index.md b/pages/tr/docs/guides/diagnostics/memory/index.md deleted file mode 100644 index 8ee43174e8ceb..0000000000000 --- a/pages/tr/docs/guides/diagnostics/memory/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Bellek Hataları Teşhisi -layout: docs.hbs ---- - -# Bellek - -Bu dokümanda bellek ile ilgili hataların nasıl çözüleceğini öğrenebilirsin. - -- [Bellek](#memory) - - [Bellek yetersizliği](#my-process-runs-out-of-memory) - - [Belirtiler](#symptoms) - - [Yan Etkiler](#side-effects) - - [Belleğin verimsiz kullanılması](#my-process-utilizes-memory-inefficiently) - - [Belirtiler](#symptoms-1) - - [Yan Etkiler](#side-effects-1) - - [Hataları ayıklamak](#debugging) - -## Bellek yetersizliği - -Node.js*(JavaScript)* çöp toplayıcı bir dildir, yani saklayıcılar aracılığıyla bellek sızıntıları olması mümkündür. Node.js uygulamaları genellikle çok kiracılı, uzun süreli çalışan ve kritik işlerdir. Dolayısıyla bellek sızıntılarını bulmak için erişilebilir ve verimli bir yol sunmak önemlidir. - -### Belirtiler - -Kullanıcı, sürekli artan bellek kullanımını _(hızlı veya yavaş, günler hatta haftalar boyunca)_ gözlemliyor, ardından işlem yöneticisi tarafından işlemin çöküp yeniden başlatıldığını görüyorsa. Belki de işlem önceki haline göre daha yavaş çalışıyor ve yeniden başlatmalar bazı isteklerin başarısız olmasına sebep oluyorsa*(yük dengeleyici 502 koduyla cevap veriyorsa)*. - -### Yan Etkiler - -- Belleğin tükenmesi sebebiyle işlemin yeniden başlatılması ve isteklerin tamamlanamaması -- GC aktivitesinin artması sebebiyle oluşan daha fazla CPU kullanımı ve daha yavaş cevap süresi - - GC'nin Event Loop'u bloklaması ve yavaşlığa sebep olması -- Bellek takasının artışı sebebiyle işlemin yavaşlaması (GC aktivitesi) -- Heap Snapshot alabilmek için yeterli bellek alanının kalmaması - -## Belleğin verimsiz kullanılması - -### Belirtiler - -Uygulamanın beklenenin dışında belleği kullanması ve/veya garbage collector aktivitesinin artığını gözlemek. - -### Yan Etkiler - -- Artan sayıda sayfa hataları -- Yüksek GC aktivitesi ve CPU kullanımı - -## Hata ayıklamak - -Çoğu bellek sorunu, belirli nesne türlerimizin ne kadar yer kapladığını ve onların çöp toplamasını engelleyen değişkenlerin neler olduğunu belirleyerek çözülebilir. Programımızın zaman içindeki tahsis desenini bilmek de yardımcı olabilir. - -- [Heap Profiler kullanmak](/en/docs/guides/diagnostics/memory/using-heap-profiler/) -- [Heap Snapshot kullanmak](/en/docs/guides/diagnostics/memory/using-heap-snapshot/) -- [GC İzleri](/en/docs/guides/diagnostics/memory/using-gc-traces) diff --git a/pages/tr/docs/guides/getting-started-guide.md b/pages/tr/docs/guides/getting-started-guide.md deleted file mode 100644 index 7f5ce5430e9b5..0000000000000 --- a/pages/tr/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Başlangıç Kılavuzu -layout: docs.hbs ---- - -# Node.js kurulumunu tamamladıktan son nasıl başlarım? - -Node.js kurduktan sonra ilk web sunucumuzu kuralım. `app.js` adında bir dosya oluşturalım ve şu satırları ekleyelim: - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Şimdi web sunucunuzu `node app.js` komutu ile çalıştırabilirsiniz. Tarayıcınızdan `http://localhost:3000` adresini açtığınızda "Hello World" mesajını göreceksiniz. - -Node.js ile çalışmaya başlamak ve daha kapsamlı bilgi edinmek için [Node.js'e giriş](https://nodejs.dev/en/learn/) sayfasını inceleyebilirsiniz. diff --git a/pages/tr/docs/index.mdx b/pages/tr/docs/index.mdx deleted file mode 100644 index d64481c20af41..0000000000000 --- a/pages/tr/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Docs -layout: docs.hbs -labels: - lts: LTS ---- - -# Belgeler Hakkında - -Bu web sitesinde çeşitli dokümantasyon türleri bulunmaktadır: - -- API referans dokümantasyonu -- ES6 özellikleri -- Rehberler - -## API Referans Dokümantasyonu - -[API Referans Dokümantasyonu](https://nodejs.org/api/) Node.js içerisindeki fonksiyon ve nesneler hakkında detaylı bilgi sağlar. Bu dokümantasyon, bir metodun hangi argümanları kabul ettiğini o metodun dönüş değerini ve bu metotla ilgili hangi hataların olabileceğini gösterir. Ayrıca, Node.js'nin farklı sürümleri için hangi yöntemlerin kullanılabileceğini gösterir. - -Bu belgede, Node.js. tarafından sağlanan yerleşik modüller açıklanmaktadır. Topluluk tarafından sağlanan modülleri belgelendirmez. - -
- -### Önceki sürümler için API dokümanlarını mı arıyorsunuz? - - - -[Tüm versiyonlar](https://nodejs.org/docs/) - -
- -## ES6 Özellikleri - -[ES6 bölümü](/tr/docs/es6/), üç ES6 özellik grubunu ve açıklayıcı bağlantıların yanı sıra Node.js'de varsayılan olarak hangi özelliklerin etkin olduğunu açıklar. Ayrıca, belirli bir Node.js sürümüyle birlikte gönderilen V8 sürümünün nasıl bulunacağını da gösterir. - -## Rehberler - -[Rehber bölümü](/tr/docs/guides/)'nde Node.js teknik özellikleri ve yetenekleriyle ilgili uzun ve derinlemesine makaleler bulunmaktadır. diff --git a/pages/tr/download/current.md b/pages/tr/download/current.md deleted file mode 100644 index 3ae7b692d033b..0000000000000 --- a/pages/tr/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: İndir -download: İndir -downloads: - headline: İndir - lts: Uzun Süreli Destek (LTS) - current: Güncel - tagline-current: Yeni Özellikler - tagline-lts: Çoğu kullanıcı için önerilir - display-hint: 'İndirmeleri göster:' - intro: > - Node.js'in kaynak kodunu veya uygun dağıtımı indirin, ve bugün geliştirmeye başlayın. - currentVersion: Güncel Versiyon - buildInstructions: Node.js'i desteklenen sistemlerde derleyin - WindowsInstaller: Windows Yükleyicisi - WindowsBinary: Windows Dağıtımı - MacOSInstaller: macOS Yükleyicisi - MacOSBinary: macOS Dağıtımı - LinuxBinaries: Linux Dağıtımı - SourceCode: Kaynak Kodu -additional: - headline: Diğer Platformlar - intro: > - Node.js topluluğunun üyeleri, ek platformlar için resmi olmayan Node.js yapılarını korur. Bu tür derlemelerin Node.js çekirdek ekibi tarafından desteklenmediğini ve henüz mevcut Node.js sürümüyle aynı derleme düzeyinde olmayabileceğini unutmayın. - platform: Platform - provider: Sağlayıcı - SmartOSBinaries: SmartOS Dağıtımları - DockerImage: Docker İmajı - officialDockerImage: Resmi Node.js Docker İmajı - LinuxPowerSystems: Power LE sistemlerinde Linux - LinuxSystemZ: System Z üzerinde Linux - AIXPowerSystems: Power Systems üzerinde AIX ---- diff --git a/pages/tr/download/index.md b/pages/tr/download/index.md deleted file mode 100644 index afc003d0ef482..0000000000000 --- a/pages/tr/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: İndir -download: İndir -downloads: - headline: İndirmeler - lts: Uzun Süreli Destek (LTS) - current: Güncel - tagline-current: Yeni Özellikler - tagline-lts: Çoğu kullanıcı için önerilir - display-hint: 'İndirmeleri göster:' - intro: > - Node.js'in kaynak kodunu veya uygun dağıtımı indirin, ve bugün geliştirmeye başlayın. - currentVersion: Güncel LTS Sürümü - buildInstructions: Node.js'i desteklenen sistemlerde derleyin - WindowsInstaller: Windows Yükleyicisi - WindowsBinary: Windows Dağıtımı - MacOSInstaller: macOS Yükleyicisi - MacOSBinary: macOS Dağıtımı - LinuxBinaries: Linux Dağıtımı - SourceCode: Kaynak Kodu -additional: - headline: Diğer Platformlar - intro: > - Node.js topluluğunun üyeleri, ek platformlar için resmi olmayan Node.js yapılarını korur. Bu tür derlemelerin Node.js çekirdek ekibi tarafından desteklenmediğini ve henüz mevcut Node.js sürümüyle aynı derleme düzeyinde olmayabileceğini unutmayın. - platform: Platform - provider: Sağlayıcı - SmartOSBinaries: SmartOS Dağıtımları - DockerImage: Docker İmajı - officialDockerImage: Resmi Node.js Docker İmajı - LinuxPowerSystems: Power LE sistemlerinde Linux - LinuxSystemZ: System z üzerinde Linux - AIXPowerSystems: Power Systems üzerinde AIX ---- diff --git a/pages/tr/get-involved/collab-summit.md b/pages/tr/get-involved/collab-summit.md deleted file mode 100644 index e50b771881261..0000000000000 --- a/pages/tr/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: İşbirliği Zirvesi -layout: contribute.hbs ---- - -# İşbirliği Zirvesi - -İşbirliği Zirvesi, heyecan verici ortaklık, eğitim ve bilgi paylaşımı için varolan ve potansiyel katkıda bulunan geliştiricileri Node.js hakkında konuşmak için biraraya getiren konferans gibi bir buluşmadır. Komiteler ve gruplar önemli kararları verirken, aynı zamanda heyecan verici fikirleri ve öne sürmek istedikleri çalışmalar için yüz yüze görüşme fırsatı yakalayarak yılda iki kez biraraya gelir. - -## Kim katılır? - -İşbirliğe Zirvesi'ne isteyen herkes katılabilir. Zirve boyunca liderler, yeni katılımcıları çalışma oturumlarına dahil etmeden önce katkı sağlamayı istedikleri gruplara dahil etmeye yardımcı olur. - -Sahip olduğunuz ve geliştirmek istediğiniz becerilerle dahil olup katkıda bulunmak ve toplulukta neler olup bittiğini öğrenmek için yegane fırsattır. - -Çalışma oturumları bireyler konuma gelmeden, genel işbirlik konuşmaları ve dağılma oturumları öncesi insanların kendilerini alıştırabilmesi ve aşina olabilmesi için bir takvim belirler. - -Sizi İşbirliği Zirvesi'nde görmeyi çok isteriz! [Zirve reposunu](https://github.com/nodejs/summit) geçmişte olan ve gelecekte olacak olan İşbirliği Zirveleri için ve [issues kısmına](https://github.com/nodejs/summit/issues) farklı çalışma oturumlarının ve komitelerin neleri yüz yüze görüşmek istediklerini görmek için göz atın. diff --git a/pages/tr/get-involved/contribute.md b/pages/tr/get-involved/contribute.md deleted file mode 100644 index d7d4982e1f814..0000000000000 --- a/pages/tr/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Katkıda Bulun -layout: contribute.hbs ---- - -# Katkıda Bulun - -Node.js'e ilginiz için teşekkürler! Birçok şekilde katkı sağlayabilirsiniz. Bu konuda size yardımcı olmak için burdayız. - -## Genel konularda yardım istekleri - -`nodejs/node` reposundaki etkinlik seviyesinin yoğunluğundan, genel yardım soruları ve talepleri [Node.js yardım reposu](https://github.com/nodejs/help/issues)'na yönlendirilmelidir. - -## Sorun bildirme - -Eğer Node.js ile ilgili sorun olduğuna inandığınız bir şey bulduysanız, lütfen GitHub projesi üzerinden bir sorunu dosyalamaktan çekinmeyin. Sorununuzu dosyalarken, lütfen sorunu tekrarlanabilir bir test senaryosu ile ifade ettiğinizden emin olun, ayrıca bu test durumu harici herhangi bir bağımlılık içermemelidir. Test durumu, Node.js'in kendisinden başka bir bağımlılığı olmadan yerine getirilebiliyor olmalı. - -Bir sorunu bildirirken, ortamınız hakkında olabildiğince bilgiye ihtiyacımız var. Sorunu çözümlemeye çalışırken, hangi bilgilerin ilgili olabileceğini bilmeyiz. Bu sebeple lütfen asgari olarak aşağıdaki bilgileri ekleyin: - -- Node.js Sürümü -- Çalıştırdığınız platform (macOS, SmartOS, Linux, Windows) -- Üzerinde çalıştığınız yapı (32bit veya 64bit ve x86 veya ARM) - -Node.js projesi şu anda her birinin kendi ayrı sorunlar veri tabanı ile bir dizi ayrı GitHub reposunda yönetilmektedir. Mümkün olduğu kadar bildireceğiniz sorunları uygun olan depoya yönlendirin. Bildirimizini yanlış yere yapmanız halinde endişe etmeyin, topluluk içerisinde sizi memnuniyetle doğru yönlendirecek katılımcılar olacaktır. - -- Node.js'ye özgü sorunları bildirmek için, lütfen [nodejs/node](https://github.com/nodejs/node)'ı kullanın -- Bu websitesine özgü sorunları bildirmek için, lütfen [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues)'u kullanın - -## Kod katkıları - -Eğer hataları düzeltmek veya Node.js'e yeni bir özellik eklemek istiyorsanız, lütfen [Node.js Katkı Yönergeleri](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests)'ne başvurduğunuzdan emin olun. Projeye yapılan tüm katkıların mevcut katılımcılar tarafından gözden geçirme süreçleri burada açıklanmıştır. - -Nasıl başlayacağınızı merak ediyorsanız, ilk adımlarınızda size rehberlik edebilecek [Node Todo](https://www.nodetodo.org/) sayfasına göz atabilirsiniz. - -## Katılımcı olmak - -Katılımcı olarak, katkıda bulunanlar proje üzerinde daha da fazla etkiye sahip olabilirler. Yapılan katkılarını gözden geçirerek, aciliyetine göre sorunları sıralayarak diğer katkıda bulunanlara yardımcı olabilirler, hatta projenin geleceğinin şekillenmesinde büyük rol alırlar. TSC tarafından herhangi bir Node.js reposunda önemli ve değerli katkılarda bulunduğu belirlenen kişiler ortak çalışan yapılabilir ve projeye taahhütlü erişim verilebilir. Dikkate alınan faaliyetler aşağıdaki hususları içerir (ancak bunlarla sınırlı değildir): - -- kod teklifleri (code commits) ve değerlendirme istekleri (PR) -- kod teklifleri ve değerlendirme isteklerinin dokümantasyonu -- sorunlar ve değerlendirme istekleri üzerine yorumlar -- Node.js web sitesine katkılar -- son kullanıcı ve acemi katılımcılara destek sağlamış olmak -- çalışma gruplarına destek -- daha geniş Node.js topluluklarında katkı sağlamak - -Kişiler değerli katkılarının dikkate alınmadığını düşünürlerse, bunu [sorun olarak bildirebilir](https://github.com/nodejs/TSC/issues) veya bir [TSC üyesi](https://github.com/nodejs/node#tsc-technical-steering-committee) ile doğrudan iletişime geçebilir. diff --git a/pages/tr/get-involved/index.md b/pages/tr/get-involved/index.md deleted file mode 100644 index 1a07cc71aac02..0000000000000 --- a/pages/tr/get-involved/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Dahil olun -layout: contribute.hbs ---- - -# Dahil olun - -## Topluluk Tartışması - -- [GitHub sorunları listesi](https://github.com/nodejs/node/issues), Node.js temel özelliklerinin tartışıldığı alandır. -- Node.js geliştirme hakkında, canlı sohbet için aşağıdaki platformlardan birini kullanın - - IRC için, bir [IRC istemcisi](https//en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients) ile `#node.js` kanalındaki `irc.libera.chat` adresine gidin veya web tarayıcınızdan `freenode'un WebChat'ini` kullanarak kanala bağlanın - - Slack için iki seçenek vardır: - - [Node Slackers](https://www.nodeslackers.com/) bir Slack topluluğudur. Bazı çalışma grupları'nın bu toplulukta Node.js odaklı tartışma kanalları vardır. - - [OpenJSF Slack](https://slack-invite.openjsf.org/), birkaç Node.js kanalıyla (`#nodejs`- önekli kanallar projeyle ilgilidir) Foundation tarafından çalıştırılan bir Slack kanalıdır. -- Resmi Node.js Twitter hesabı [@nodejs](https://twitter.com/nodejs). -- Halka açık tüm takım toplantılarını içeren [Node.js Foundation takvimi](https://nodejs.org/calendar). - -## Bilgi edinme - -- [Resmi API referans dokümantasyonu](https://nodejs.org/api/) Node.js API hakkında bilgi verir. -- [NodeSchool.io](https://nodeschool.io/), etkileşimli komut-satırı oyunları aracılığıyla size Node.js kavramlarını öğretecektir. -- [Stack Overflow Node.js etiketi](https://stackoverflow.com/questions/tagged/node.js) her gün yeni bilgi toplar. -- [DEV Community Node.js etiketi](https://dev.to/t/node) Node.js projelerini, makalelerini ve öğreticilerini paylaşmanın yanı sıra tartışmaları başlatmak ve Node.js ile ilgili konularda geri bildirim istemek için bir yerdir. Her seviyeden geliştiriciler bu topluluğun bir parçası olmaya davetlidir. -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) Discord üzerinde birbirlerini dostane destekleyen Node.js backend geliştiricilerinin bir topluluğudur. diff --git a/pages/tr/index.md b/pages/tr/index.md deleted file mode 100644 index 55f5b1e711a14..0000000000000 --- a/pages/tr/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Güncel Versiyon - download: İndir - download-for: 'İndirin:' - other-downloads: Diğer İndirme Bağlantıları - current: Güncel - lts: Uzun Süreli Destek (LTS) - tagline-current: Yeni Özellikler - tagline-lts: Çoğu kullanıcı için önerilir - changelog: Değişiklikler - api: API - version-schedule-prompt: Desteklenen sürümler hakkında bilgi almak için - version-schedule-prompt-link-text: yayınlama takvimine bakın ---- - -Node.js® [Chrome'un V8 JavaScript motoru](https://v8.dev/) üzerine inşa edilmiş bir JavaScript çalışma ortamıdır. diff --git a/pages/uk/404.md b/pages/uk/404.md deleted file mode 100644 index a96093f1c544a..0000000000000 --- a/pages/uk/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Сторінку не знайдено - -### ENOENT: немає такого файлу чи каталогу diff --git a/pages/uk/about/governance.md b/pages/uk/about/governance.md deleted file mode 100644 index 50aa4c0937ab4..0000000000000 --- a/pages/uk/about/governance.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Управління проектом -layout: about.hbs ---- - -# Управління проектом - -## Технічний керівний комітет - -Цей проект спільно керується Технічним керівним комітетом (Technical Steering Committee (TSC)), що є відповідальним за найвищий рівень координування проектом. - -## Співавтори - -TSC має остаточне авторство над цим проектом, включаючи: - -В першу чергу запрошення на участь у TSC були дані тим особам, які були активними учасникам та мають значний досвід в управлінні проектом. Членство передбачає повну зайнятість, відповідно до потреб проекту. - -Поточний список учасників TSC можна знайти в [README.md](https://github.com/nodejs/node/blob/main/README.md#tsc-technical-steering-committee) проекту. - -GitHub–репозиторій [nodejs/node](https://github.com/nodejs/node) підтримується TSC та додатковими співавторами, що були додані TSC на постійній основі. - -## Членство в TSC - -Особи, що роблять значні та важливі внески стають співавторами та отримують доступ на запис (commit-access) у проект. Вони ідентифікуються через TSC і їх залучення як співавторів обговорюється протягом щотижневих зустрічей TSC. diff --git a/pages/uk/about/index.md b/pages/uk/about/index.md deleted file mode 100644 index a3f8844a44941..0000000000000 --- a/pages/uk/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: Про проєкт -trademark: Товарний знак ---- - -# Про Node.js® - -Як асинхронне подієво-орієнтоване середовище виконання JavaScript, Node.js призначений для створення масштабованих мережевих додатків. У наступному прикладі "Привіт, світе!" багато з'єднань можуть оброблятися одночасно. При кожному з'єднанні викликається зворотний виклик, але якщо немає роботи для виконання, Node.js буде перебувати у режимі сну. - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -Це контрастує з більш поширеною моделлю, в якій використовуються OS потоки. Мережеве програмування на основі потоків є відносно неефективним та дуже складним у використанні. Більше того, користувачі Node.js можуть не турбуватись про блокування процесів, оскільки вони відсутні. Майже жодна функція в Node.js не виконує безпосередніх операцій введення-виведення (I/O), тому процес ніколи не блокується, за винятком випадків, коли I/O виконується за допомогою синхронних методів стандартної бібліотеки Node.js. Оскільки нічого не блокується, розробка масштабованих систем на Node.js є дуже обґрунтованою. - -Якщо деякі з цих термінів незнайомі, то можете переглянути повну статтю на [Blocking vs Non-Blocking][]. - ---- - -Node.js схожий у своєму дизайні з такими системами, як Ruby's [Event Machine][] та Python's [Twisted][]. Node.js використовує подієву модель значно ширше, він представляє [цикл подій][] як конструкцію виконання часу роботи, а не як бібліотеку. В інших системах завжди є блокуючий виклик для запуску циклу подій. Зазвичай поведінка визначається через зворотні виклики в початку скрипта, а на кінці сервер запускається через блокуючий виклик, подібний до `EventMachine::run()`. У Node.js немає такого виклику для запуску циклу подій. Node.js просто входить у цикл подій після виконання вхідного скрипта. Node.js виходить з ціклу подій, коли немає більше зворотних викликів для виконання. Ця поведінка схожа на JavaScript у браузері: цикл подій прихований від користувача. - -HTTP є основним елементом у Node.js, розроблений з урахуванням потокового та низького часу затримки. Це робить Node.js хорошою основою для веббібліотек або фреймворку. - -Те, що Node.js, розроблений без використання потоків, не означає, що ви не можете скористатися перевагами багатоядерного середовища. Дочірні процеси можуть бути створені за допомогою нашого API [`child_process.fork()`][] і розроблені для зручного взаємодії. На основі цього ж інтерфейсу побудований модуль [`cluster`][], який дозволяє спільно використовувати сокети між процесами для розподілу навантаження на ваші ядра. - -[Blocking vs Non-Blocking]: /en/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[цикл подій]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/uk/docs/es6.md b/pages/uk/docs/es6.md deleted file mode 100644 index 8d8ef755da143..0000000000000 --- a/pages/uk/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) та вище -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) та вище - -Node.js побудований на сучасних версіях [V8](https://v8.dev/). Ми певні в тому, що новий функціонал зі [специфікації JavaScript ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm) постачається Node.js–розробникам поступово, для подальшого підвищення швидкодії та стабільності, оскільки використовуємо найсвіжіші релізи цього рушія. - -Весь ECMAScript 2015 (ES6) функціонал поділяється на три групи: **доставлені**, **підготовлені** та **у процесі**: - -- Весь **доставлений** функціонал, який вважається у V8 стабільним, **увімкнений у Node.js за замовчуванням** і **НЕ** потребує будь–якого флага для оточення. -- **Підготовлений** функціонал, що містить майже готові нововведення, що розглядаються командою V8 як нестабільні, потребують флагу: `--harmony`. -- Функціонал **у процесі** може вмикатись окремо через власні harmony–флаги, хоча це не рекомендується, за виключенням, якщо ви звісно не тестуєте цей функціонал. Зауважте: ці флаги визначаються V8 і можуть бути змінені без будь–якого попередження. - -## Який функціонал вже постачається з Node.js за замовчуванням? - -Сайт [node.green](https://node.green/) надає прекрасний огляд всіх нововведень ECMAScript, що підтримуються у різних версіях Node.js, та базується на таблицях сумісності kangax. - -## Який функціонал знаходиться у процесі підготовки? - -Новий функціонал постійно додається у рушій V8. Взагалі кажучи очікується, що вони всі будуть підтримуватись у майбутньому релізі Node.js, хоча терміни поки невідомі. - -Ви можете побачити список всього функціоналу, що знаходиться _у процесі_ в кожній версії Node.js через грепінг з аргументом `--v8-options`. Майте на увазі, що цей функціонал може бути незакінченим, або зламаним функціоналом V8, тому його використання - це ваш власний ризик: - -```bash -node --v8-options | grep "in progress" -``` - -## В мене є мої налаштування інфраструктури, що використовують флаг --harmony. Чи слід мені відмовитись від нього? - -Наразі флаг `--harmony` в Node.js вмикає лише **підготовлений** функціонал. Зрештою, тепер це синонім `--es_staging`. Як згадано вище, цей функціонал є завершеним, але ще не вважається стабільним. Якщо ви хочете використовувати його безпечно, особливо на production–середовищах, краще видалити цей флаг з оточення, поки від не буде постачатись з V8 і, відповідно, у Node.js за замовчування. Якщо ви залишите його увімкненим, вам слід бути готовими до можливих оновлень Node.js, що зламають ваш код, якщо зміни у V8, їхня семантика буде більш точно відповідати стандарту. - -## Як я можу дізнатись яка версія V8 постачається з певною версією Node.js? - -Node.js надає простий спосіб для отримання списку залежностей та їх версій, що постачаються з певним бінарником через глобальний об’єкт `process`. У випадку з рушієм V8, введіть це в терміналі і ви отримаєте його версію: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/uk/docs/guides/diagnostics/live-debugging/index.md b/pages/uk/docs/guides/diagnostics/live-debugging/index.md deleted file mode 100644 index 5a76c1e596bc2..0000000000000 --- a/pages/uk/docs/guides/diagnostics/live-debugging/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Налагодження в реальному часі -layout: docs.hbs ---- - -# Налагодження в реальному часі - -- [Налагодження в реальному часі](#live-debugging) - - [Моя програма не працює належним чином](#my-application-doesnt-behave-as-expected) - - [Симптоми](#symptoms) - - [Налагодження](#debugging) - -У цьому документі ви можете дізнатися, як виконувати налагодження в реальному часі процесу Node.js. - -## Моя програма не працює належним чином - -### Симптоми - -Користувач може спостерігати, що програма не дає очікуваного результату для певних вхідних даних, наприклад, HTTP-сервер повертає відповідь JSON, де певні поля є порожніми. У процесі можуть статися різні помилки, але ми головним чином зосереджені на логіці та правильності програми. - -### Налагодження - -У цьому випадку користувач хоче зрозуміти послідовність виконання коду нашої програми для певної події, наприклад, вхідного HTTP-запиту. Вони також можуть хотіти стежимо за виконанням коду крок за кроком, а також перевіряти значення змінних, що зберігаються у пам'яті. - -- [Використання інспектора](/en/docs/guides/diagnostics/live-debugging/using-inspector) diff --git a/pages/uk/docs/guides/diagnostics/live-debugging/using-inspector.md b/pages/uk/docs/guides/diagnostics/live-debugging/using-inspector.md deleted file mode 100644 index e1bdba25a1878..0000000000000 --- a/pages/uk/docs/guides/diagnostics/live-debugging/using-inspector.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Використання інспектора -layout: docs.hbs ---- - -# Використання інспектора - -У локальному середовищі розробки ми зазвичай виконуємо налагодження в реальному часі, приєднуючи налагоджувач до нашої програми та зупиняючи його роботу за допомогою точок зупину. Далі ми стежимо за виконанням коду крок за кроком і перевіряємо пам’ять між кроками. Однак використання цього методу в реальному середовищі зазвичай неможливо, оскільки у нас обмежений доступ до машини, і ми не можемо перервати виконання програми, оскільки вона обробляє критичні робочі завдання. - -## Інструкція - -https://nodejs.org/en/docs/guides/debugging-getting-started/ diff --git a/pages/uk/docs/index.mdx b/pages/uk/docs/index.mdx deleted file mode 100644 index c3339901266ec..0000000000000 --- a/pages/uk/docs/index.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Документація -layout: docs.hbs -labels: - lts: LTS ---- - -# Про документацію - -Є три типи документації, що доступні на цьому сайті: - -- довідкова документація про API; -- функціонал ES6; -- посібники; -- залежності. - -## Довідкова документація про API - -[Довідкова документація про API](https://nodejs.org/api/) надає детальну інформацію про функції та об’єкти у Node.js. Ця документація показує які аргументи приймають методи, які значення ці методи повертають та які помилки пов'язані з цими методами. Вона також показує які методи доступні для різних версій Node.js. - -Ця документація описує вбудовані модулі, які надаються Node.js. Вона не документує модулі, що надаються спільнотою. - -
- -### Шукаєте документацію про API для попередніх релізів? - - - -[всі версії](https://nodejs.org/docs/) - -
- -## Функціонал ES6 - -[Секція ES6](/en/docs/es6/) описує три групи функціоналу ES6 і описує, який функціонал наразі доступний у Node.js за замовчуванням разом з пояснювальними посиланнями. Вона також показує як дізнатись яка версія V8 постачається з певним релізом Node.js. - -## Посібники - -[Розділ посібників](/en/docs/guides/) містить розгорнуті та детальні статті про технічні функції та можливості Node.js. - -## Залежності - -Node.js залежить від додаткових компонентів, крім самого коду Node.js. Ці [dependencies](https://github.com/nodejs/node/blob/main/doc/contributing/maintaining/maintaining-dependencies.md) забезпечують як нативний код, так і код JavaScript, і створюються разом із кодом у каталогах `src ` і `lib` для створення двійкових файлів Node.js. diff --git a/pages/uk/download/current.md b/pages/uk/download/current.md deleted file mode 100644 index 70e5d5ac6907f..0000000000000 --- a/pages/uk/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: Завантажити -download: Завантажити -downloads: - headline: Завантаження - lts: LTS - current: Поточна - tagline-current: Найновіші можливості - tagline-lts: Рекомендовано для більшості - display-hint: Показати завантаження для - intro: > - Завантажте початковий код Node.js або інсталятор для вашої платформи та почніть розробку сьогодні. - currentVersion: Поточна версія - buildInstructions: Building Node.js from source on supported platforms - WindowsInstaller: Windows Installer - WindowsBinary: Windows Binary - MacOSInstaller: macOS Installer - MacOSBinary: macOS Binary - LinuxBinaries: Linux Binaries - SourceCode: Source Code -additional: - headline: Додаткові платформи - intro: > - Учасники спільноти Node.js підтримують неофіційні збірки Node.js для додаткових платформ. Майте на увазі, що ці збірки не підтримуються основною командою Node.js і можуть не мати того ж функціоналу що й поточний реліз Node.js. - platform: Платформа - provider: Провайдер - SmartOSBinaries: SmartOS Binaries - DockerImage: Docker Image - officialDockerImage: Official Node.js Docker Image - LinuxPowerSystems: Linux on Power LE Systems - LinuxSystemZ: Linux on System z - AIXPowerSystems: AIX on Power Systems ---- diff --git a/pages/uk/download/index.md b/pages/uk/download/index.md deleted file mode 100644 index 42db043a0558b..0000000000000 --- a/pages/uk/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: Завантажити -download: Завантажити -downloads: - headline: Завантаження - lts: LTS - current: Поточна - tagline-current: Найновіші можливості - tagline-lts: Рекомендовано для більшості - display-hint: Показати завантаження для - intro: > - Завантажте початковий код Node.js або інсталятор для вашої платформи та почніть розробку сьогодні. - currentVersion: Поточна версія - buildInstructions: Побудова Node.js з вихідного коду на платформах, що підтримуються - WindowsInstaller: Інсталятор для Windows - WindowsBinary: Бінарний файл для Windows - MacOSInstaller: Інсталятор для macOS - MacOSBinary: Бінарний файл для macOS - LinuxBinaries: Бінарні файли для Linux - SourceCode: Вихідний код -additional: - headline: Додаткові платформи - intro: > - Учасники спільноти Node.js підтримують неофіційні збірки Node.js для додаткових платформ. Майте на увазі, що ці збірки не підтримуються основною командою Node.js і можуть не мати тієї ж функціональності що й поточний реліз Node.js. - platform: Платформа - provider: Провайдер - SmartOSBinaries: Бінарні файли для SmartOS - DockerImage: Образ для Docker - officialDockerImage: Офіційний образ Node.js для Docker - LinuxPowerSystems: Linux на Power LE Systems - LinuxSystemZ: Linux на System z - AIXPowerSystems: AIX на Power Systems ---- diff --git a/pages/uk/download/releases.md b/pages/uk/download/releases.md deleted file mode 100644 index e88f8f1b83ed9..0000000000000 --- a/pages/uk/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: Previous Releases -modules: 'NODE_MODULE_VERSION refers to the ABI (application binary interface) version number of Node.js, used to determine which versions of Node.js compiled C++ add-on binaries can be loaded in to without needing to be re-compiled. It used to be stored as hex value in earlier versions, but is now represented as an integer.' ---- - -### io.js та Node.js - -Релізи від 1.x до 3.x називались "io.js", оскільки вони були частиною форку io.js. Node.js 4.0.0 є загальним релізом io.js об'єднаного з Node.js 0.12.x у спільні релізи Node.js. - -### Шукаєте останній реліз певної версії? diff --git a/pages/uk/get-involved/collab-summit.md b/pages/uk/get-involved/collab-summit.md deleted file mode 100644 index ce11795c6224e..0000000000000 --- a/pages/uk/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Саміт співробітників -layout: contribute.hbs ---- - -# Саміт співробітників - -Саміт співробітників (Collaboration Summit) ― це "анти"-конференція, на яку збираються нинішні та потенційні учасники, щоб наживо обговорити Node.js та поділитися знаннями. Комітети та робочі групи збираються двічі на рік для прийняття важливих рішень, а також можуть працювати над деякими проєктами, які вони хочуть просувати особисто. - -## Хто запрошений? - -Усі охочі можуть відвідати саміт співробітників. Під час саміту лідери допомагатимуть новим учасникам вступити до груп, що їх цікавлять, перш ніж додати їх до робочих сесій. - -Це можливість дізнатися про те, що відбувається в спільноті, перш ніж приєднатися та поділитися своїми навичками, які ви хотіли б відточити. - -Робочі групи заздалегідь складуть графік заходу, щоб учасники могли будувати свої плани, перш ніж опиняться на місці, проведуть загальні обговорення зі співробітниками, а потім поринуть у секційні засідання. - -Ми будемо раді бачити вас на саміті співробітників! Перегляньте [репозиторій саміту](https://github.com/nodejs/summit) для майбутніх та минулих заходів та ознайомтеся з [поставленими питаннями](https://github.com/nodejs/summit/issues) для подальшого живого обговорення. diff --git a/pages/uk/get-involved/contribute.md b/pages/uk/get-involved/contribute.md deleted file mode 100644 index 016080dd5858b..0000000000000 --- a/pages/uk/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Внесок -layout: contribute.hbs ---- - -# Внесок - -Дякуємо за інтерес до участі у Node.js! Є кілька способів і сфер, де ви можете зробити свій внесок, і ми тут, щоб допомогти в цьому. - -## Звернення за загальною допомогою - -Оскільки рівень активності в репозиторії `nodejs/node` дуже високий, питання або запити про спільну допомогу в Node.js слід надсилати до [репозиторію довідки Node.js](https://github.com/nodejs/help/issues). - -## Повідомлення про проблему - -Якщо ви виявили проблему з Node.js, не соромтеся створити відповідний запис у проєкті GitHub. При створенні запису переконайтеся, що ви можете описати проблему за допомогою відтворюваного тестового випадку, і цей тестовий випадок не повинен містити залежностей від зовнішніх компонентів. Іншими словами, тестовий випадок повинен виконуватися без будь-яких додаткових компонентів, окрім Node.js. - -При повідомленні про проблему нам також потрібно якомога більше інформації про ваше середовище, яку ви можете надати. Ми не знаємо, яка інформація буде доречною при спробі ідентифікувати проблему. Будь ласка, додайте принаймні наступну інформацію: - -- Версія Node.js -- Платформа, на якій ви працюєте (macOS, SmartOS, Linux, Windows) -- Архітектура, на якій ви працюєте (32-біт або 64-біт, x86 або ARM) - -Проєкт Node.js наразі керується через кілька окремих репозиторіїв GitHub, кожен зі своєю базою даних проблем. Якщо це можливо, будь ласка, спрямовуйте будь-які проблеми до відповідного репозиторію, але не хвилюйтеся, якщо вони потраплять не в те місце – спільнота учасників буде рада допомогти вам рухатися в правильному напрямку. - -- Щоб повідомити про проблему, пов'язану з Node.js, будь ласка, скористайтесь [nodejs/node](https://github.com/nodejs/node) -- Щоб повідомити про проблему, пов'язану з цим сайтом, будь ласка, скористайтесь [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## Написання коду - -Якщо ви бажаєте виправити помилки або додати новий функціонал до Node.js, будь ласка, переконайтеся, що ви ознайомилися з [правилами щодо внесення внесків до Node.js](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests). Там також пояснюється процес перевірки існуючими співробітниками всіх внесків у проєкт. - -Якщо ви думаєте, з чого почати, ви можете перевірити програму [Node Todo](https://www.nodetodo.org/), яка може спрямувати вас до вашого першого внеску. - -## Стати учасником - -Ставши учасником, користувач може ще більше вплинути на проєкт. Він може допомогти іншим учасникам, перевіряючи їх роботи та сортуючи проблеми, а також брати ще більшу участь у формуванні майбутнього проєкту. Особи, які TSC (Технічна Робоча Група) визнала значними і цінними учасниками будь-якого репозиторію Node.js, можуть стати співавторами та отримати доступ до проєкту. Дії та їх якість, що приймаються до уваги (але не обмежуються ними): - -- коміти коду та запити на об'єднання -- документація комітів та запитів на об'єднання -- коментарі до проблем і запитів на об'єднання -- внески у сайт Node.js -- надана допомога кінцевим користувачам і новачкам -- участь у робочих групах -- інша участь у більшій спільноті Node.js - -Якщо особи, які роблять цінні внески, не вважають, що їх розглядали для отримання доступу до коміту, вони можуть [зареєструвати проблему](https://github.com/nodejs/TSC/issues) або [звернутися безпосередньо до члена TSC](https://github.com/nodejs/node#tsc-technical-steering-committee). diff --git a/pages/uk/get-involved/index.md b/pages/uk/get-involved/index.md deleted file mode 100644 index 66e2f630844ac..0000000000000 --- a/pages/uk/get-involved/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Приєднатись -layout: contribute.hbs ---- - -# Приєднатись - -## Громадське обговорення - -- [Список іш’ю на GitHub](https://github.com/nodejs/node/issues) — це місце, де обговорюють ключовий функціонал Node.js. -- Офіційний аккаунт Node.js у Twitter [nodejs](https://twitter.com/nodejs). -- The [Node.js Foundation calendar](https://nodejs.org/calendar) with all public team meetings. -- [Node Weekly](https://nodeweekly.com/) це поштове розсилання, що збирає найсвіжіші події та новини довкола спільноти Node.js. - -## Навчання - -- [Офіційна довідкова документація по API](https://nodejs.org/api/) описує Node API. -- [NodeSchool.io](https://nodeschool.io/) навчить вас концепцій Node.js через інтерактивні консольні ігри. -- [Stack Overflow Node.js tag](https://stackoverflow.com/questions/tagged/node.js) щодня поповнюється новою інформацією. - -## Сайти міжнародних спільнот та проекти - -- [Chinese community](https://cnodejs.org/) -- [Hungarian (Magyar) community](https://nodehun.blogspot.com/) -- [Israeli Facebook group for Node.js](https://www.facebook.com/groups/node.il/) -- [Japanese user group](https://nodejs.jp/) -- [Spanish language Facebook group for Node.js](https://www.facebook.com/groups/node.es/) -- [Vietnamese Node.js community](https://www.facebook.com/nodejs.vn/) -- [Uzbekistan group for Node.js](https://t.me/nodejs_uz) diff --git a/pages/uk/index.md b/pages/uk/index.md deleted file mode 100644 index e6a5dbf6fae56..0000000000000 --- a/pages/uk/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: Поточна версія - download: Завантажити - download-for: Завантажити для - other-downloads: Інші завантаження - current: Поточна - lts: LTS - tagline-current: Найновіші можливості - tagline-lts: Рекомендовано для більшості - changelog: Список змін - api: Документація - version-schedule-prompt: Або подивіться на - version-schedule-prompt-link-text: графік LTS ---- - -Node.js® — це JavaScript–оточення побудоване на JavaScript–рушієві [Chrome V8](https://v8.dev/). diff --git a/pages/zh-cn/404.md b/pages/zh-cn/404.md deleted file mode 100644 index d3508f78cf519..0000000000000 --- a/pages/zh-cn/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: 页面未找到 - -### ENOENT: 找不到文件或目录 diff --git a/pages/zh-cn/about/governance.md b/pages/zh-cn/about/governance.md deleted file mode 100644 index b94df308fef3e..0000000000000 --- a/pages/zh-cn/about/governance.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: 项目管理 -layout: about.hbs ---- - -# 项目管理 - -## 追求一致协商 - -Node.js 项目遵循[一致协商][]的工作模式。 - -## 贡献者 - -[nodejs/node][] 托管于 GitHub 上核心存储库是由不断加入技术指导委员会([TSC][])的委员们一点一滴从基础开始慢慢维护的。 - -对项目作出重大或有价值贡献者们会被任命为贡献者,并授予访问项目的权限;这些个人被 TSC 识别且由现任的贡献者们讨论提名。 - -关于当前贡献者列表,请看项目中有关 [README.md][] 的说明。 - -关于贡献者指南在 [collaborator-guide.md][] 中维护。 - -## 技术委员会 - -本项目由[技术指导委员会(TSC)][]创建,这是一个对项目进行高层决策指导的团队。 - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[一致协商]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[技术指导委员会(TSC)]: https://github.com/nodejs/TSC/blob/main/TSC-Charter.md -[TSC]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/zh-cn/about/index.md b/pages/zh-cn/about/index.md deleted file mode 100644 index a080143d23ea6..0000000000000 --- a/pages/zh-cn/about/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -layout: about.hbs -title: 关于 Node.js -trademark: 商标 ---- - -# 关于 Node.js® - -作为一个异步事件驱动的 JavaScript 运行时,Node.js 被设计用来构建可扩展的网络应用。在下面的 “Hello World” 示例中,可以并发处理许多连接,每一个连接都会触发一个回调,而当没有可做的事情时,Node.js 就会进入休眠状态。 - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -这与当今比较常见的采用操作系统线程的并发模型形成了鲜明对比。基于线程的网络效率相对较低且更难以使用。此外,由于没有锁,Node.js 的用户不用担心进程死锁的问题。Node.js 中几乎没有函数直接执行 I/O 操作(除非你使用 Node.js 标准库中的同步函数版本),其进程从不会被阻塞,因此用 Node.js 来开发可扩展系统是非常合理的。 - -如果你对上面的描述有一些不理解地方,这里有一篇专门关于[阻塞对比非阻塞][]的文章供你参考。 - ---- - -Node.js 在设计上类似于 Ruby 的 [Event Machine][] 或 Python 的 [Twisted][] 之类的系统。但 Node.js 更深入地考虑了事件模型,它将[事件循环][]作为一个运行时结构而不是作为一个库来呈现。在其他系统中,总是有一个阻塞调用来启动事件循环。通常情况下,要执行的行为是通过脚本开始时的回调来定义的,然后通过 `EventMachine::run()` 这样的阻塞调用来启动服务器。而在 Node.js 中,没有这种启动事件循环的调用。Node.js 在执行输入脚本后直接进入事件循环,当没有更多的回调要执行时,Node.js 就会退出事件循环。这种行为就像浏览器的 JavaScript 一样 —— 事件循环对用户是隐藏的。 - -HTTP 是 Node.js 中的一等公民,设计时考虑到了流式和低延迟,这使得 Node.js 非常适合作为网络库或框架的基础。 - -Node.js 被设计成单线程运行,但这并不意味着你无法利用到 CPU 的多个核心。你可以通过 [`child_process.fork()`][] API 来生成子进程,并且它被设计成非常易于通信。而建立在同一个接口之上的 [`cluster`][] 模块允许你在进程之间共享套接字(sockets),以实现核心的负载均衡。 - -[阻塞对比非阻塞]: /zh-cn/docs/guides/blocking-vs-non-blocking/ -[`child_process.fork()`]: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options -[`cluster`]: https://nodejs.org/api/cluster.html -[事件循环]: /zh-cn/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/zh-cn/docs/es6.md b/pages/zh-cn/docs/es6.md deleted file mode 100644 index 1c6fde8e7d2e4..0000000000000 --- a/pages/zh-cn/docs/es6.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: ECMAScript 2015 (ES6) 以及未来展望 -layout: docs.hbs ---- - -# ECMAScript 2015 (ES6) 以及未来展望 - -Node.js 是针对 [V8](https://v8.dev/) 引擎构建的。通过与此引擎的最新版本保持同步,我们确保及时向 Node.js 开发人员提供 [JavaScript ECMA-262 specification](http://www.ecma-international.org/publications/standards/Ecma-262.htm) 中的新功能,以及持续的性能和稳定性改进。 - -所有的 ECMAScript 2015 (ES6) 功能将被分为三个部分 **shipping**,**staged** 和 **in progress**: - -- 所有 **shipping**:在 V8 引擎中认为是稳定的,转变成 **Node.js 默认**,并且 **不会** 需要任何运行时标记。 -- **Staged**:这些是将要完成的特性,并且在 V8 团队看来并不一定稳定,需要一个 `--harmony` 标记。 -- **In progress**:这些特性可以通过各自单独的 harmony 标记被激活使用。除非为了测试用途,否则绝不鼓励这样做。值得注意的是这些标记是借由 V8 引擎公开,将来或许会有潜在的变化而不会有任何免责声明或者协议。 - -## 默认情况下什么特性随着 Node.js 一起发布? - -[node.green](https://node.green/) 提供了非常完整、几乎涵盖了不同版本的 Node.js 中所支持的 ECMAScript 特性。它基于 kangax 的兼容性对照表构建。 - -## 有哪些特性在开发中? - -新特性源源不断地被加入 V8 引擎。一般说来,虽然具体的时间未知,但我们总希望他们将来在 Node.js 中有所体现。 - -在每个 Node.js 发布版中,你可以通过 greeping 配上 `--v8-options` 参数罗列出全部处于 _in progress_ 状态的特性功能。请注意:他们尚未完成,可能因为 V8 引擎自带的功能而夭折。所以使用这些特性时会冒风险。 - -```bash -node --v8-options | grep "in progress" -``` - -## 我有我自己的基本框架,可以利用 --harmony,所以我可以移除这个标记吗? - -目前来说,`--harmony` 在 Node.js 的作用是让 **staged** 特性起作用。它本质上等同于 `--es_staging`。如上所述,有些特性尚未完全确认是稳定的,所以如果你希望一个安全的环境(尤其是在发布环境),你应该考虑移除这个运行时的环境标记,直到它在 V8 中以默认形式发布,或者在 Node.js 中落地。如果你开启了这个开关,你应该有对未来 Node.js 升级而造成代码破坏(无法正常工作)的准备,比如 V8 引擎做了更改,它的语法变得更接近标准。 - -## 我怎么知道某个特定版本的 Node.js 发布是随着哪个版本的 V8 引擎呢? - -Node.js 提供了一个简单的方法以列出所有依赖项,以及通过 `process` 全局对象,借助特定的二进制包发布的不同版本。由于是 V8 引擎,在你的终端输入以下命令就可以获取相关版本号: - -```bash -node -p process.versions.v8 -``` diff --git a/pages/zh-cn/docs/guides/abi-stability.md b/pages/zh-cn/docs/guides/abi-stability.md deleted file mode 100644 index 39f2496a1315a..0000000000000 --- a/pages/zh-cn/docs/guides/abi-stability.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: ABI 的稳定性 -layout: docs.hbs ---- - -# ABI 的稳定性 - -## 简介 - -应用程序二进制接口(ABI)是程序通过调用函数使用其它编译程序中的数据结构的一种方式。它是应用程序接口(API)的编译版本。换句话说:描述类、函数、数据结构、枚举和常量的头文件,它们使应用程序能够执行所需的任务方法是编译到一组地址和预期的参数值和内存。编译 ABI 提供程序的结构大小和布局。 - -编译使用 ABI 的应用程序必须使得可用地址、预期参数值和内存结构大小和布局与 ABI 提供程序编译的那些协议一致。这通常是通过对 ABI 提供程序提供的标头进行编译来实现的。 - -由于 ABI 提供方和 ABI 用户可能会在不同时刻使用不同版本的编译器进行编译,因此确保 ABI 兼容性的部分责任在于编译器。不同版本的编译器(可能由不同的供应商提供)都必须从具有特定内容的头文件生成相同的 ABI,并且必须使用 ABI(根据约定使用给定头文件描述的 API)生成应用程序代码。现代编译器具有相当好的跟踪记录,不破坏它们编译的应用程序的 ABI 兼容性。 - -保持并确保 ABI 兼容性的责任在于维护标头文件的团队,后者提供 API;在编译后使得在 ABI 中保持稳定。对头文件进行更改是可以的,但必须密切跟踪更改的性质,以确保在编译时 ABI 不会更改,从而不会导致 ABI 的现有用户与新版本不兼容。 - -## ABI 在 Node.js 中的稳定性 - -Node.js 提供的一些头文件是由几个独立的团队维护的。举个例子,诸如 `node.h` 和 `node_buffer.h` 是通过 Node.js 团队维护,而 `v8.h` 由 V8 团队维护,尽管它们之间的关系非常紧密,但是仍然都是独立的,并且都有自己的计划和优先级别。因此,Node.js 团队对于这些项目提供的头文件中引入的变更只有部分控制权。因此 Node.js 项目已采用[语义版本控制](https://semver.org/)。这可确保项目提供的 ABI 将为所有次要版本和修补程序版本的 Node.js 发布一个稳定的 ABI。在实践中,这将意味着 Node.js 项目已承诺确保:针对给定的主要版本的 Node.js 加载时,Node.js 本地化插件编译将成功加载由任何 Node.js 次要或修补程序版本在其编译的主要版本中。 - -## N-API - -为 Node.js 装备了一个 API 而导致在多个 Node.js 主要版本之间保持稳定的 ABI 的需求已经出现。创建此类 API 的动机如下: - -- JavaScript 语言自其早期就一直与自身兼容,而执行 JavaScript 代码的引擎 ABI 则随 Node.js 的每个主要版本而变化。这意味着在 JavaScript 中完全写入 Node.js 包中所包含的应用程序不需要重新编译和重新安装,或者作为新的主要版本的 Node.js 被丢弃到运行此类应用程序的生产环境中。相比之下,如果应用程序依赖于包含本机插件的包,仅将 Node.js 的新主版本引入到生产环境中就必须重新编译、重安装和部署应用程序。这种差距在包含本机插件的 Node.js 包和完全写入 JavaScript 的 Node.js 之间,增加了依赖于本机插件的生产系统的维护负担。 - -- 其他项目已经开始产出 JavaScript 接口,这基本上是 Node.js 的替代实现。因为这些项目通常是建立在不同 JavaScript 引擎而不是 V8;他们的本机插件必须采取不同的结构和使用不同的 API。不过,在 Node.js 的 JavaScript API 的不同实现中,使用本机插件的单个 API 将允许这些项目利用 Node.js 包中累积的 JavaScript 软件包的生态系统。 - -- Node.js 可能在将来包含不同的 JavaScript 引擎。这意味着,对外所有 Node.js 接口将保持不变,但 V8 头文件将不存在。如果某个 API 没有首先被 Node.js 引擎提供,并且没有被本地插件采用。那么这一步将导致 Node.js 生态系统的中断——特别是本机插件的破坏。 - -对于这些收束,Node.js 已在版本 8.6.0 中引入了 N-API 并将其标记为项目的稳定组件——如 Node.js 8.12.0。这些 API 在头文件 [`node_api.h`][] 和 [`node_api_types.h`][]中定义,并提供跨越 Node.js 主要版本边界的前向兼容性保证。保证可以说明如下: - -**N-API 的指定版本 _N_ 将在其发布的 Node.js 的主要版本和所有后续版本的 Node.js 中提供,包括后续的主要版本。** - -本地插件开发者可以通过确保插件只使用 `node_api.h` 中定义的 API 以及在 `node_api_types.h` 中定义的数据结构和常量,利用 N-API 向前兼容性保证。由此方式,开发者通过向生产用户表明其应用程序的维护负担将增加,而不是通过添加一个纯粹由 JavaScript 编写的包,从而简化其插件的采用。 - -N-API 是版本化的,因为会不时添加新的 API;与语义版本控制不同,N-API 版本控制是累积性的。也就是说,N-API 的每个版本在 semver 系统中传达与次要版本相同的含义,这意味着对 N-API 所做的所有更改都将向后兼容。此外,新的 N-API 将添加到实验标志下,以使社区有机会在生产环境中对其进行审核。实验状态意味着,尽管已注意确保新 API 不会在将来以 ABI 不兼容的方式进行修改,但在生产中尚未充分证明它是正确和有用的。 因此,在最终并入即将推出的 N-API 版本之前可能会经历 ABI 不兼容的更改。也就是说,正向兼容性保证尚未涵盖实验性的 N-API。 - -[`node_api.h`]: https://github.com/nodejs/node/blob/main/src/node_api.h -[`node_api_types.h`]: https://github.com/nodejs/node/blob/main/src/node_api_types.h diff --git a/pages/zh-cn/docs/guides/anatomy-of-an-http-transaction.md b/pages/zh-cn/docs/guides/anatomy-of-an-http-transaction.md deleted file mode 100644 index b4a44d9e69a80..0000000000000 --- a/pages/zh-cn/docs/guides/anatomy-of-an-http-transaction.md +++ /dev/null @@ -1,365 +0,0 @@ ---- -title: HTTP 传输解析 -layout: docs.hbs ---- - -# 一次 HTTP 传输解析 - -本指南的宗旨将让你对 HTTP 传输处理有一个清晰完整的了解。在不考虑特定编程语言及开发环境下,我们假设你已经知道在一般情况下 HTTP 是如何进行工作的。我们同样假定你熟悉 Node.js 的 [`EventEmitters`][] 和 [`Streams`][]。当然,如果你确实不了解它们,我们强烈建议你把以上列出的内容快速而完整地阅读一遍。 - -## 创建一个后台服务 - -任何网络服务应用程序总是要先创建一个服务对象。这在 Node.js 中通常通过 [`createServer`][] 方法。 - -```javascript -const http = require('http'); - -const server = http.createServer((request, response) => { - // magic happens here! -}); -``` - -每当有 HTTP 请求到达服务器时,[`createServer`][] 中传入的函数就被自动执行。所以这个函数也被称为是请求处理函数。实际上,由 [`createServer`][] 构造函数返回的 [`Server`][] 对象是一个 [`EventEmitter`][],我们在这里仅是对创建 `server` 和对它添加监听事件进行了简化处理。 - -```javascript -const server = http.createServer(); -server.on('request', (request, response) => { - // the same kind of magic happens here! -}); -``` - -当一个 HTTP 到达服务端,node 调用 request 处理程序,并产生一些唾手可得的对象用以处理传输,这些对象就是 `request` 和 `response`。我们马上会讲到。 - -实际上,为了处理请求,[`listen`][] 方法需要在 `server` 对象上被显式调用。在大多数情况下,你只要把端口号作为参数传入 `listen` 方法中,作为监听端口即可。当然也有一些其它选项,具体可以参考 [API 参考文档][]。 - -## 方法、访问地址以及请求头 - -当处理一个请求时,第一件事你需要做的是看一下这个方法和其访问地址,以此决定你到底采取何种合理的行为。Node.js 通过把这些行为属性附加到 `request` 对象上,使得我们处理起来相对而言可以轻松一些。 - -```javascript -const { method, url } = request; -``` - -> **注意:** `request` 对象是 [`IncomingMessage`][] 的一个实例。 - -这里的 `method` 总是一个普通的 HTTP 方法动作行为 (verb),`url` 是指没有服务器协议和 端口号的完整访问地址。一个典型的访问地址通常意味着包括第三个斜杠以及后面的所有内容。 - -请求头也不是很难得到,它们也在 `request` 对象里,称为 `headers`。 - -```javascript -const { headers } = request; -const userAgent = headers['user-agent']; -``` - -非常重要的一点是:所有的请求头全是小写字母,而不管实际上它们是怎么进行传输的。所以在无论任何 情况下,解析请求头就得到了简化。 - -如果一些请求头出现重复,它们的值不是被覆盖,就是通过英文分号进行分割。究竟哪种方式取决于具体的信息头。在某些情况下这可能出现问题,所以我们还可以直接使用 [`rawHeaders`][]。 - -## 请求体 - -当接受到了一个 `POST` 或者 `PUT` 请求时,请求体对于你的应用程序非常重要。相对于访问请求 头而言,获取请求体有些麻烦。传入请求对象的 `request` 其实实现了 [`ReadableStream`][] 接口, 这个信息流可以被监听,或者与其它流进行对接。我们可以通过监听 `'data'` 和 `'end'` 事件从而把 数据给取出来。 - -每次在 `'data'` 事件中触发抓获的数据块是一个 [`Buffer`][]。如果你已知是一个字符串对象,那么 最好的方案就是把这些数据收集到一个数组中,然后在 `'end'` 事件中拼接并且把它转化为字符串。 - -```javascript -let body = []; -request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // at this point, `body` has the entire request body stored in it as a string - }); -``` - -> **注意:** 这看起来有些单调乏味,大多数情况下也确实是这样。 不过庆幸的是因为 [`npm`][] 上实在有太多的诸如 [`concat-stream`][] 和 [`body`][] 一类类库屏蔽了部分细节逻辑而替你做了这些事情。当然,对于你而言在使用这些类库前知道它们到底干了什么非常重要,这就是你为什么需要读这篇文章! - -## 一笔带过关于错误的一些信息 - -因为 `request` 是一个 [`ReadableStream`][] 对象,它同样也是 [`EventEmitter`][] 对象。所以当有错误发生时,表现的行为是很相像的。当有错误在 `request` 流上发生时,它会自动激发自身的 `'error'` 事件。**如果你不去处理监听这个事件,此错误将被*抛出*,这导致你的程序崩溃。** 你应该无论如何都要添加 `'error'` 事件去监听你的请求对象,哪怕你只是做一个日志或者用你自己的独有方式去处理(当然,最佳的处理方式是返回一些出错的信息,这已是后话了)。 - -在 `request`流中错误的表现便是通过激发(捕获)`'error'`事件。**如果你不捕获处理的话,程序一旦出错,异常立即被*抛出*,会让你的 Node.js 程序立马崩溃**。因此你务必要这样做——即便你啥都不处理,只是做一个日志也行(当然,最佳实践方法实发送某种 HTTP 出错消息给客(比如出错码等),这是后话)。 - -```javascript -request.on('error', err => { - // This prints the error message and stack trace to `stderr`. - console.error(err.stack); -}); -``` - -当然还有一些其它的方法来 [处理错误][]:诸如其它的抽象化概念和工具等。但是你总是要意识到错误的确会发生,所以你应当处理它们。 - -## 我们已经聊得那么多了 - -直到现在,我们已经谈到了如何创建一个对象,如果从请求中获取方法,请求地址,请求头和请求体。当我们把它们组合到一起,它就看上去是这个样子: - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // At this point, we have the headers, method, url and body, and can now - // do whatever we need to in order to respond to this request. - }); - }) - .listen(8080); // Activates this server, listening on port 8080. -``` - -如果我们运行这个示例代码,我们只能*接收*到请求但得不到*回应*。实际上,如果你在浏览器内运行这个示例,你的请求只会超时,因为服务器那边根本没有返回给客户端任何东西。 - -谈了那么久,我们都还没有说到 `response` 对象。它是一个[`ServerResponse`][],实例,而 ServerRespose 又是 [`WritableStream`][]。它包含了很多方法可以用以把数据返回给客户端。我们下面就将涉及到此议题。 - -## HTTP 状态码 - -如果你嫌麻烦不想设置它,返回客户端的默认状态码总是 200。当然,不是每个 HTTP 返回码必须都是 200,在某些情况下你一定希望返回一个不同的状态码,所以你应该设置 `statusCode` 属性。 - -```javascript -response.statusCode = 404; // Tell the client that the resource wasn't found. -``` - -我们同样也有其它捷径去做这件事,后面我们会很快看到。 - -## 设置响应头 - -响应头通过一个[`setHeader`][]的属性很方便地设置。 - -```javascript -response.setHeader('Content-Type', 'application/json'); -response.setHeader('X-Powered-By', 'bacon'); -``` - -设置响应头时,它们的名字是大小写敏感的。如果你重复设置响应头,最后一次设置的值也就是系统得到的值。 - -## 显示发送头数据 - -我们之前讨论的设置响应头以及状态码的方法建立在你使用“隐式设置”的方式,这意味着你在发送消息体之前依赖于 node 发送请求头。 - -如果你愿意,你可以*显式*为返回流重写响应头。为做到这点,你可以使用 [`writeHead`][],方法向消息流重写状态码和响应头。 - -```javascript -response.writeHead(200, { - 'Content-Type': 'application/json', - 'X-Powered-By': 'bacon', -}); -``` - -一旦设置了响应头(无论是隐式还是显式设置),你已经为发送返回数据做好了准备。 - -## 发送返回体 - -既然 `response` 对象是一个[`WritableStream`][],所以向客户端写入返回体只是一个普通的流方法的问题。 - -```javascript -response.write(''); -response.write(''); -response.write('

Hello, World!

'); -response.write(''); -response.write(''); -response.end(); -``` - -消息流上的 `end`方法同时还可以带入一些可选数据作为流上最后需要发送的一些数据,所以我们可以简单地把以上的代码做如下形式的简化: - -```javascript -response.end('

Hello, World!

'); -``` - -> 你只有在开始向返回体写数据 *之前*设置状态和响应头,这点很重要。因为响应头信息总是在消息体前到达。 - -## 另一件一笔带过关于错误的事 - -`response`返回流同样也会触发 `'error'`事件,某种程度上说你不得不自己去处理它。之前全部关于`request`消息流出错的处理方法在这里也同样适用。 - -## 把之前所学的全部整合到一起 - -现在既然我们已经学了如何处理 HTTP 返回信息,现在让我们把这些零碎东西组合到一起。基于先前的示例代码,我们将作出一个服务端,使它可以将从用户接受到的全部信息返回给用户。我们将通过`JSON.stringify`对消息数据进行格式化。 - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - const { headers, method, url } = request; - let body = []; - request - .on('error', err => { - console.error(err); - }) - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - // BEGINNING OF NEW STUFF - - response.on('error', err => { - console.error(err); - }); - - response.statusCode = 200; - response.setHeader('Content-Type', 'application/json'); - // Note: the 2 lines above could be replaced with this next one: - // response.writeHead(200, {'Content-Type': 'application/json'}) - - const responseBody = { headers, method, url, body }; - - response.write(JSON.stringify(responseBody)); - response.end(); - // Note: the 2 lines above could be replaced with this next one: - // response.end(JSON.stringify(responseBody)) - - // END OF NEW STUFF - }); - }) - .listen(8080); -``` - -## 服务器响应的示例代码 - -让我们简化之前的代码,做一个可以有响应的简单的服务端。它同样也可以把接受到的任何信息返回给客户端。我们所要做的就是从请求流中把请求数据取出,然后原样写回到返回流中即可。就如我们之前做的那么简单。 - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - }) - .listen(8080); -``` - -现在让我们调整一下,我们只对以下条件应答: - -- 请求方法是 POST 方式。 -- 访问路径是 `/echo`。 - -其它任何情况均返回 404。 - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - let body = []; - request - .on('data', chunk => { - body.push(chunk); - }) - .on('end', () => { - body = Buffer.concat(body).toString(); - response.end(body); - }); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -> **注意:** 为了检查请求路径,我们设计了一个路由格式。 其它形式的路由 `switch`,简单的可以通过 `switch` 的形式检查,复杂的诸如 [`express`][] 框架,如果你正在寻找路由而不需要做其它事情,简单用 [`router`][]。 - -太棒了!现在我们进一步简化它。记住,`request`是一个[`ReadableStream`][]对象,`response`对象是一个[`WritableStream`][]对象。那意味着我们可以使用 [`pipe`][]直接从一个流转到另外一个流。那的确是我们需要的: - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -就是这样! - -我们还尚未完全完成,如之前多次谈到,错误随时可能发生,所以我们需要处理它们。 - -为了处理请求流上的错误,我们把错误记录到`stderr`对象中,然后回发一个 400 的代码表示`Bad Request`。在现实生活中,我们想检查分析错误,了解它们正确的状态码以及具体出错信息。具体可以参考[`Error` documentation][]。 - -对于返回,我们把错误日志记录到 `stderr`中。 - -```javascript -const http = require('http'); - -http - .createServer((request, response) => { - request.on('error', err => { - console.error(err); - response.statusCode = 400; - response.end(); - }); - response.on('error', err => { - console.error(err); - }); - if (request.method === 'POST' && request.url === '/echo') { - request.pipe(response); - } else { - response.statusCode = 404; - response.end(); - } - }) - .listen(8080); -``` - -我们现在已经涉及到了大部分基本的 HTTP 请求知识,此时此刻,你应该已经具备了: - -- 实例化带有请求处理函数的 HTTP 服务器,并让它在端口上监听。 -- 从 `request` 对象中获取请求头部、URL、方法和请求体等数据。 -- 让路由决定依赖于访问路径,或者在 `request` 对象其它数据中。 -- 通过 `response` 对象发送响应头,HTTP 状态码以及消息体。 -- 通过 `request` 对象与 `response` 对象对接,传输数据。 -- 在 `request` 和 `response` 流中处理错误。 - -从这些简单示例中,我们已经可以构建针对众多特定情况下的 Node.js HTTP 服务器。这些 API 实际上还提供了其它的功能,故建议你最好通读 API 文档以便于更彻底地了解[`EventEmitters`][]、[`Streams`][]以及[`HTTP`][]。 - -[`EventEmitters`]: https://nodejs.org/api/events.html -[`Streams`]: https://nodejs.org/api/stream.html -[`createServer`]: https://nodejs.org/api/http.html#http_http_createserver_requestlistener -[`Server`]: https://nodejs.org/api/http.html#http_class_http_server -[`listen`]: https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback -[API 参考文档]: https://nodejs.org/api/http.html -[`IncomingMessage`]: https://nodejs.org/api/http.html#http_class_http_incomingmessage -[`ReadableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_readable -[`rawHeaders`]: https://nodejs.org/api/http.html#http_message_rawheaders -[`Buffer`]: https://nodejs.org/api/buffer.html -[`concat-stream`]: https://www.npmjs.com/package/concat-stream -[`body`]: https://www.npmjs.com/package/body -[`npm`]: https://www.npmjs.com -[`EventEmitter`]: https://nodejs.org/api/events.html#events_class_eventemitter -[处理错误]: https://nodejs.org/api/errors.html -[`ServerResponse`]: https://nodejs.org/api/http.html#http_class_http_serverresponse -[`setHeader`]: https://nodejs.org/api/http.html#http_response_setheader_name_value -[`WritableStream`]: https://nodejs.org/api/stream.html#stream_class_stream_writable -[`writeHead`]: https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers -[`express`]: https://www.npmjs.com/package/express -[`router`]: https://www.npmjs.com/package/router -[`pipe`]: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options -[`Error` documentation]: https://nodejs.org/api/errors.html -[`HTTP`]: https://nodejs.org/api/http.html diff --git a/pages/zh-cn/docs/guides/backpressuring-in-streams.md b/pages/zh-cn/docs/guides/backpressuring-in-streams.md deleted file mode 100644 index 7c6a436d650b5..0000000000000 --- a/pages/zh-cn/docs/guides/backpressuring-in-streams.md +++ /dev/null @@ -1,513 +0,0 @@ ---- -title: 数据流中的积压问题 -layout: docs.hbs ---- - -# 数据流中的积压问题 - -通常在数据处理的时候我们会遇到一个普遍的问题:[`背压`][],意思是在数据传输过程中有一大堆数据在缓存之后积压着。每次当数据到达结尾又遇到复杂的运算,又或者无论什么原因它比预期的慢,这样累积下来,从源头来的数据就会变得很庞大,像一个塞子一样堵塞住。 - -为解决这个问题,必须存在一种适当的代理机制,确保流从一个源流入另外一个的时候是平滑顺畅的。不同的社区组织针对他们各自的问题单独做了解决,好例子比如 Unix 的管道和 TCP 的 Socket。此问题经常与 _流控制_ 相关。在 Node.js 中,流已经是被采纳的解决方案。 - -此文的目的在于详细深入介绍什么是积压,并从代码角度详细解释在 Node.js 中,流是如何针对此问题进行处理的。本文的第二部分将给予你实现流的功能时最佳实践,以确保你的程序既安全又精简。 - -我们假定你对 Node.js 中的 [`背压`][],[`Buffer`][],[`EventEmitter`][] 和 [`Stream`][] 的基本概念有一点了解。如果你尚未完整阅读过 API 文档,那么最好是先看一下相关 API 说明,它也会有助于你扩展理解本文的主旨。 - -## 处理数据中遇到的问题 - -在一个计算机系统中,通过管道,socket 和信号量将数据从一个进程传到另外一个进程中。在 Node.js 中,我们发明了一个类似的机制,它称为 [`Stream`][]。流太棒了!它们为 Node.js 做了太多的事情,而且内部代码库的每个角落都用到了那个模块。作为一个开发者,你也应该鼓励自己多去使用这个模块! - -```javascript -const readline = require('readline'); - -// process.stdin and process.stdout are both instances of Streams. -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, -}); - -rl.question('Why should you use streams? ', answer => { - console.log(`Maybe it's ${answer}, maybe it's because they are awesome! :)`); - - rl.close(); -}); -``` - -通过流实现积压机制的一个很好的例子是通过比较内部系统工具可以证明一个很大的优化。它通过 Node.js 的 [`Stream`][]实现。 - -在以下场景中,我们将拿一个巨大的文件(大概有 9gb 那么大),然后用熟悉的 [`zip(1)`][] 的工具压缩。 - -``` -zip The.Matrix.1080p.mkv -``` - -当这个终端还需要等待一些时间来完成时,我们另起一个终端运行 Node.js 的模块: [`zlib`][],它对 [`gzip(1)`][] 进行了包装。 - -```javascript -const gzip = require('zlib').createGzip(); -const fs = require('fs'); - -const inp = fs.createReadStream('The.Matrix.1080p.mkv'); -const out = fs.createWriteStream('The.Matrix.1080p.mkv.gz'); - -inp.pipe(gzip).pipe(out); -``` - -现在尝试打开每个压缩的文件来测试结果。由 [`zip(1)`][] 压缩的文件会提醒你文件中断了,但通过 [`Stream`][] 的压缩在解压时无任何错误。 - -> 请注意:这个例子中我们使用 `.pipe()` 从一个数据源终端到另外一个终端得到了数据源,不过没有使用任何出错处理机制。如果一大堆数据出错了但是又要被接收, `Readable` 和 `gzip` 数据流不会被销毁。[`pump`][] 是一个工具类,如果有某个流发生错误或者关闭,它会自动销毁相关所有的流,在这个情况下是必须使用的! - -[`pump`][]对于 Node.js 8.x 以及先前版本是必须的。但对于 10.x 和之后的版本而言,我们引入了 [`pipeline`][]来取而代之。这是一个模块化函数,用于对接不同的数据流,可以处理异常错误并善后清理释放资源。它同时也提供了一个回调函数——当整个 pipeline 任务完成时将触发。 - -这里给出一个例子,告诉你如何使用 pipeline: - -```javascript -const { pipeline } = require('stream'); -const fs = require('fs'); -const zlib = require('zlib'); - -// Use the pipeline API to easily pipe a series of streams -// together and get notified when the pipeline is fully done. -// A pipeline to gzip a potentially huge video file efficiently: - -pipeline( - fs.createReadStream('The.Matrix.1080p.mkv'), - zlib.createGzip(), - fs.createWriteStream('The.Matrix.1080p.mkv.gz'), - err => { - if (err) { - console.error('Pipeline failed', err); - } else { - console.log('Pipeline succeeded'); - } - } -); -``` - -你也可以使用[`promisify`][]包装 pipeline,配合`async` / `await`进行使用: - -```javascript -const stream = require('stream'); -const fs = require('fs'); -const zlib = require('zlib'); -const util = require('util'); - -const pipeline = util.promisify(stream.pipeline); - -async function run() { - try { - await pipeline( - fs.createReadStream('The.Matrix.1080p.mkv'), - zlib.createGzip(), - fs.createWriteStream('The.Matrix.1080p.mkv.gz') - ); - console.log('Pipeline succeeded'); - } catch (err) { - console.error('Pipeline failed', err); - } -} -``` - -## 数据太多,速度太快 - -有太多的例子证明有时[`Readable`][]传输给[`Writable`][]的速度远大于它接受和处理的速度! - -如果发生了这种情况,消费者开始为后面的消费而将数据列队形式积压起来。写入队列的时间越来越长,也正因为如此,更多的数据不得不保存在内存中直到整个流程全部处理完毕。 - -写入磁盘的速度远比从磁盘读取数据慢得多,因此,当我们试图压缩一个文件并写入磁盘时,积压的问题也就出现了。因为写磁盘的速度不能跟上读磁盘的速度。 - -```javascript -// Secretly the stream is saying: "whoa, whoa! hang on, this is way too much!" -// Data will begin to build up on the read-side of the data buffer as -// `write` tries to keep up with the incoming data flow. -inp.pipe(gzip).pipe(outputFile); -``` - -这就是为什么说积压机制很重要——如果积压机制不存在,进程将用完你全部的系统内存,从而对其它进程产生显著影响,它独占系统大量资源直到任务完成为止。 - -这最终导致一些问题: - -- 明显使得其它进程处理变慢 -- 太多繁重的垃圾回收 -- 内存耗尽 - -以下例子中我们把`.write()`函数的[返回值][]取出,改成 `true`,这样明显地禁止了 Node.js 核心的积压的支持。在任何引用了 'modified' 二进制库的地方,我们探讨在不适用`return ret;`的情况下运行`node`二进制代码,并用 `return true;`取代它。 - -## 过度的垃圾收集 - -让我们来看一个快速的基准。使用上面的同一个例子,我们进行两次试验以获得两个二进制文件的中位时间。 - -``` - trial (#) | `node` binary (ms) | modified `node` binary (ms) -================================================================= - 1 | 56924 | 55011 - 2 | 52686 | 55869 - 3 | 59479 | 54043 - 4 | 54473 | 55229 - 5 | 52933 | 59723 -================================================================= -average time: | 55299 | 55975 -``` - -两者都跑一分钟,所以几乎没有什么区别。但让我们仔细看看我们的猜测是否正确。我们使用 Linux 工具[`dtrace`][]来评估 V8 垃圾回收机制发生了什么。 - -GC(垃圾回收器)测量表明一个完整的周期间隔一个由垃圾回收器进行扫描: - -``` -approx. time (ms) | GC (ms) | modified GC (ms) -================================================= - 0 | 0 | 0 - 1 | 0 | 0 - 40 | 0 | 2 - 170 | 3 | 1 - 300 | 3 | 1 - - * * * - * * * - * * * - - 39000 | 6 | 26 - 42000 | 6 | 21 - 47000 | 5 | 32 - 50000 | 8 | 28 - 54000 | 6 | 35 -``` - -当两个进程同时运行,并似乎以同样的效率开始工作,在若干秒随着适当的积压开始变得有效率起来。它将 GC 负载扩展到每隔一定的 4-8 毫秒的间隔,直到数据传输结束。 - -但是,当积压机制处理不恰当,V8 垃圾回收机制开始变慢。一般情况下 GC 一分钟内进行 75 次回收,但是修改过的二进制库仅 36 次。 - -随着内存占用越来越多,缓慢和渐进的欠债也不断积累。随着数据的传输,在没有积压系统的情况下,每个块传输都使用更多的内存。 - -内存分配使用越多,GC 就越要照顾内存交换。内存交换得越多,GC 就需要考虑决定哪些内存可以被释放,并且要一直在大块内存中扫描独立区块,而这又要消耗更多的计算功率。 - -## 内存耗尽 - -为判断每个程序内存消耗,我们使用 `/usr/bin/time -lp sudo ./node ./backpressure-example/zlib.js` 单独计算每个进程所用时间。 - -这是普通程序输出结果: - -``` -Respecting the return value of .write() -============================================= -real 58.88 -user 56.79 -sys 8.79 - 87810048 maximum resident set size - 0 average shared memory size - 0 average unshared data size - 0 average unshared stack size - 19427 page reclaims - 3134 page faults - 0 swaps - 5 block input operations - 194 block output operations - 0 messages sent - 0 messages received - 1 signals received - 12 voluntary context switches - 666037 involuntary context switches -``` - -虚拟内存占用的最大字节块消耗了 87.81 mb。 - -现在改变 - -``` -Without respecting the return value of .write(): - ================================================== - real 54.48 - user 53.15 - sys 7.43 - 1524965376 maximum resident set size - 0 average shared memory size - 0 average unshared data size - 0 average unshared stack size - 373617 page reclaims - 3139 page faults - 0 swaps - 18 block input operations - 199 block output operations - 0 messages sent - 0 messages received - 1 signals received - 25 voluntary context switches - 629566 involuntary context switches -``` - -.write()`方法的返回值,我们得到以下结果: - -虚拟内存占用的最大的字节块达到了 1.52 gb。 - -没有合适的流来处理积压,就会产生一个内存占用的震级顺序——与同样的进程处理有着天壤之别! - -## 积压是怎么处理这些问题的? - -这个实验展示了如何精简以对你的计算系统进行精简,以及有效的资源消耗。现在,我们故意弄出一个故障看看它又是怎么工作的。 - -我们有不同的函数将数据从一个进程传入另外一个进程。在 Node.js 中,有一个内置函数称为[`.pipe()`][],同样地,你们也可以使用[其它工具包][]。最终,在这个进程的基本层面上我们有二个互不相关的组件:数据的*源头*和*消费者*。 - -当 [`.pipe()`][]被源调用之后,它通知消费者有数据需要传输。管道函数为事件触发建立了合适的积压封装。 - -在 Node.js 中,源头是一个[`Readable`][]的流,消费者是[`Writable`][]流(它们两者可能通过 [`Duplex`][]或[`Transform`][]进行交互)。只不过这超出我们本文讨论范围了。 - -当积压被触发的一刹那,它可以被缩略成[Writable`的`.write()][]方法。返回函数值当然是根据一些条件所决定的。 - -在数据缓存超出了 [`highWaterMark`][]或者写入的列队处于繁忙状态,[`.write()`][]会返回 `false`。 - -当`false`返回之后,积压系统介入了。它将暂停从任何发送数据的数据流中进入的[`Readable`][]。一旦数据流清空了,[`'drain'`][]事件将被触发,消耗进来的数据流。 - -一旦队列全部处理完毕,积压机制将允许允许数据再次发送。在使用中的内存空间将自我释放,同时准备接收下一次的批量数据。 - -这个有效的举措允许一大堆锁住的内存可以为[`.pipe()`][]函数随时使用而并没有内存泄露、无限扩张的内存缓冲。同时垃圾回收器仅需要处理一处地方。 - -所以,积压既然如此重要,为什么还有理由说你没有听说过呢?显然答案很明显:Node.js 为你做了一切。 - -> 对于大部分机器而言,一个字节的大小就足以决定一个缓存是否已经满了(不同机器此值有变化)。Node.js 将允许你设置你自己的[`highWaterMark`][]。但是通常来说,默认是设置为 16kb(16384,对于对象模型流而言是 16)。在某些实例中你或许想提高那个值,尽管去提高吧,但是也要小心使用! - -## `.pipe()` 的生命周期 - -这太好了!不过当我们试图去理解如何实现我们自己的积压流,这却并不太好。 - -``` - +===================+ - x--> Piping functions +--> src.pipe(dest) | - x are set up during |===================| - x the .pipe method. | Event callbacks | - +===============+ x |-------------------| - | Your Data | x They exist outside | .on('close', cb) | - +=======+=======+ x the data flow, but | .on('data', cb) | - | x importantly attach | .on('drain', cb) | - | x events, and their | .on('unpipe', cb) | -+---------v---------+ x respective callbacks. | .on('error', cb) | -| Readable Stream +----+ | .on('finish', cb) | -+-^-------^-------^-+ | | .on('end', cb) | - ^ | ^ | +-------------------+ - | | | | - | ^ | | - ^ ^ ^ | +-------------------+ +=================+ - ^ | ^ +----> Writable Stream +---------> .write(chunk) | - | | | +-------------------+ +=======+=========+ - | | | | - | ^ | +------------------v---------+ - ^ | +-> if (!chunk) | Is this chunk too big? | - ^ | | emit .end(); | Is the queue busy? | - | | +-> else +-------+----------------+---+ - | ^ | emit .write(); | | - | ^ ^ +--v---+ +---v---+ - | | ^-----------------------------------< No | | Yes | - ^ | +------+ +---v---+ - ^ | | - | ^ emit .pause(); +=================+ | - | ^---------------^-----------------------+ return false; <-----+---+ - | +=================+ | - | | - ^ when queue is empty +============+ | - ^------------^-----------------------< Buffering | | - | |============| | - +> emit .drain(); | ^Buffer^ | | - +> emit .resume(); +------------+ | - | ^Buffer^ | | - +------------+ add chunk to queue | - | <---^---------------------< - +============+ -``` - -> 注意:如果你创建一些管道准备把一些流串联起来从而操纵数据,你应该实现 [`Transform`][]流。 - -为了对积压有一个更好的理解,这里有一[`Readable`][]流正通过 [piped管道][]进入[`Writable`][]的整个生命周期图: - -```javascript -Readable.pipe(Transformable).pipe(Writable); -``` - -在这种情况下,从[`Readable`][]流中的输出进[`Transform`][],并且会被管道输送进入[`Writable`][]。 - -## 积压行为的准则 - -积压将被自动应用,但是同时请注意输入、输出[传输的][]`highWaterMark` 可以手动控制,并且会影响到积压系统。 - -从[Node.js v0.10][]开始, [`Stream`][]类借助带有下划线一些相关函数[`.read()`][]和[`.write()`][],并提供了访问他们的能力。 - -## 实现用户自定义流须知 - -这里有一些准则文档可供参考:[实现可读的流][]和[实现可写的流][]。我们假设你可以把这些文章已经读过了,下个章节将做稍许的深入讲解。 - -积压将被自动应用,但是同时请注意输入和输出 [`Transform`][] 的 `水准值` 可以手动控制,并且会影响到积压系统。 - -1. 没有特殊要求下,绝对不要用 `.push()`。 -2. 在流返回 `false` 后不要调用 `.write()` 方法,而是等待 'drain'。 -3. 流在不同的 Node.js 版本和库中是有变化的。小心你的测试。 - -> 关于第三点,构建浏览器流的一个难以置信的方法是使用 [`readable-stream`][]。Rodd Vagg 曾经写过一篇[大作][]来详细描述如何使用这个工具库。简而言之,它为 [`Readable`][]流提供了自动可销毁降解的类型,并且支持旧版的 Node.js 和浏览器。 - -## 对于可读流的规则 - -可以理解为: - -迄今为止,我们已经看了[`.write()`][] 方法对于积压的影响,并且过多关注在[`Writable`][]流上,因为 Node.js 的功能,数据从[`Readable`][]流到[`Writable`][]。但是正如我们在数据流传输过程中我们观察到的一样:源和目标一样重要,[`Readable`][]流对于积压是如何处理的至关重要。 - -这两个过程相互依赖地进行有效沟通,如果 [`Readable`][]流在[`Writable`][]流需要它停止发送数据的时候忽略了,那么当[`.write()`][]方法返回时,会产生问题。 - -所以,除了谨慎对待[`.write()`][] [方法,我们同样要小心在 <3>`._read()`][]使用 [`.push()`][] 方法的返回值。如果[`.push()`][] 方法返回一个`false` ,流就会停止从源读数据。否则,它就不会停止而继续读下去。 - -```javascript -// This is problematic as it completely ignores return value from push -// which may be a signal for backpressure from the destination stream! -class MyReadable extends Readable { - _read(size) { - let chunk; - while (null !== (chunk = getNextChunk())) { - this.push(chunk); - } - } -} -``` - -这里有个糟糕的使用 [`.push()`][]的例子: - -```javascript -// This ignores the backpressure mechanisms Node.js has set in place, -// and unconditionally pushes through data, regardless if the -// destination stream is ready for it or not. -readable.on('data', data => writable.write(data)); -``` - -从定制流之外忽略积压简直可笑至极。在以下反例中,代码仅关注数据是否到达(通过[`'data'` event][]订阅): - -```javascript -const { Readable } = require('stream'); - -// Create a custom Readable stream -const myReadableStream = new Readable({ - objectMode: true, - read(size) { - // Push some data onto the stream - this.push({ message: 'Hello, world!' }); - this.push(null); // Mark the end of the stream - }, -}); - -// Consume the stream -myReadableStream.on('data', chunk => { - console.log(chunk); -}); - -// Output: -// { message: 'Hello, world!' } -``` - -下面是一个使用 [`.push()`][]带有Readable的例子。 - -在这个示例中,我们创建了一个自定义的可读流,通过 [`.push()`][]方法将单个对象 推到流中。 [`._read()`][] 方法在流准备好消费数据时被调用,在这种情况下, 我们立即将一些数据推送到流中,并通过推送空标志流的结束。 - -## 关于可写流的规则 - -然后我们通过监听“数据”事件、记录每块推送到流的数据量。 在这种情况下,我们只把一块数据推到流中,所以我们只看到一个日志消息。 - -重新调用[`.write()`][]方法根据一些条件可能返回 true 或者 false。幸运地是,当我们构建属于自己的 [`Writable`][]流的时候,[`数据流状态机`][]会处理我们的回调,并且决定什么时候处理积压并且为我们简化数据流。 - -- 如果写队列确实繁忙,[`.write()`][] 方法将返回 false。 -- 如果数据块太大, [`.write()`][] 方法将返回 false(限定通过 [`highWaterMark`][] 决定)。 - - - -```javascript -// This writable is invalid because of the async nature of JavaScript callbacks. -// Without a return statement for each callback prior to the last, -// there is a great chance multiple callbacks will be called. -class MyWritable extends Writable { - _write(chunk, encoding, callback) { - if (chunk.toString().indexOf('a') >= 0) callback(); - else if (chunk.toString().indexOf('b') >= 0) callback(); - callback(); - } -} - -// The proper way to write this would be: -if (chunk.contains('a')) return callback(); -if (chunk.contains('b')) return callback(); -callback(); -``` - -但是当我们需要直接使用[`Writable`][]流时,我们必须考虑 [`.write()`][] 方法返回的值,并且注意到以下一些情况: - -```javascript -// Using .uncork() twice here makes two calls on the C++ layer, rendering the -// cork/uncork technique useless. -ws.cork(); -ws.write('hello '); -ws.write('world '); -ws.uncork(); - -ws.cork(); -ws.write('from '); -ws.write('Matteo'); -ws.uncork(); - -// The correct way to write this is to utilize process.nextTick(), which fires -// on the next event loop. -ws.cork(); -ws.write('hello '); -ws.write('world '); -process.nextTick(doUncork, ws); - -ws.cork(); -ws.write('from '); -ws.write('Matteo'); -process.nextTick(doUncork, ws); - -// As a global function. -function doUncork(stream) { - stream.uncork(); -} -``` - -在实现[`._writev()`][]方法时还有其它一些东西值得考虑。此函数与[`.cork()`][] 耦合,但是编写代码的时有一个容易犯的错误: - -## 总结 - -[`.cork()`][]方法可以调用任意多次,但同时也要记得调用 [`.uncork()`][]方法同样的次数,使得它可以正常流入。 - -流经常作为一个模块用于 Node.js 中,对于内部的系统结构而言非常重要。对于开发者而言,可以通过 Node.js 扩展连接应答系统。 - -现在我们希望你有能力进行故障排除,记住了是如何为你的 [`Writable`][]和[`Readable`][]流编写积压处理的。并且你还可以把这些知识分享给你的同事和朋友们。 - -[`Stream`]: https://nodejs.org/api/stream.html -[`Buffer`]: https://nodejs.org/api/buffer.html -[`EventEmitter`]: https://nodejs.org/api/events.html -[`Writable`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_pipe_destination_options -[Writable`的`.write()]: https://nodejs.org/api/stream.html#stream_writable_streams -[`Readable`]: https://nodejs.org/api/stream.html#stream_readable_streams -[`Duplex`]: https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams -[`Transform`]: https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams -[传输的]: https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams -[`zlib`]: https://nodejs.org/api/zlib.html -[`'drain'`]: https://nodejs.org/api/stream.html#stream_event_drain -[`'data'` event]: https://nodejs.org/api/stream.html#stream_event_data -[`.read()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_read_size -[`.write()`]: https://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback -[方法,我们同样要小心在 <3>`._read()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_read_size_1 -[`._read()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_read_size_1 -[`._writev()`]: https://nodejs.org/api/stream.html#stream_writable_writev_chunks_callback -[`.cork()`]: https://nodejs.org/api/stream.html#stream_writable_cork -[`.uncork()`]: https://nodejs.org/api/stream.html#stream_writable_uncork -[`.push()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_push_chunk_encoding -[实现可写的流]: https://nodejs.org/docs/latest/api/stream.html#stream_implementing_a_writable_stream -[实现可读的流]: https://nodejs.org/docs/latest/api/stream.html#stream_implementing_a_readable_stream -[其它工具包]: https://github.com/sindresorhus/awesome-nodejs#streams -[`背压`]: https://en.wikipedia.org/wiki/Backpressure_routing -[Node.js v0.10]: https://nodejs.org/docs/v0.10.0/ -[`highWaterMark`]: https://nodejs.org/api/stream.html#stream_buffering -[返回值]: https://github.com/nodejs/node/blob/55c42bc6e5602e5a47fb774009cfe9289cb88e71/lib/_stream_writable.js#L239 -[`readable-stream`]: https://github.com/nodejs/readable-stream -[大作]: https://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html -[`dtrace`]: http://dtrace.org/blogs/about/ -[`zip(1)`]: https://linux.die.net/man/1/zip -[`gzip(1)`]: https://linux.die.net/man/1/gzip -[`数据流状态机`]: https://en.wikipedia.org/wiki/Finite-state_machine -[`.pipe()`]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_pipe_destination_options -[piped管道]: https://nodejs.org/docs/latest/api/stream.html#stream_readable_pipe_destination_options -[`pump`]: https://github.com/mafintosh/pump -[`pipeline`]: https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback -[`promisify`]: https://nodejs.org/api/util.html#util_util_promisify_original diff --git a/pages/zh-cn/docs/guides/blocking-vs-non-blocking.md b/pages/zh-cn/docs/guides/blocking-vs-non-blocking.md deleted file mode 100644 index d80c9516caad3..0000000000000 --- a/pages/zh-cn/docs/guides/blocking-vs-non-blocking.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: 阻塞对比非阻塞一览 -layout: docs.hbs ---- - -# 阻塞对比非阻塞一览 - -本文介绍了在 Node.js 中 **阻塞** 和 **非阻塞** 调用的区别。本文涉及事件循环和 libuv ,但不必对其有事先了解。我们假定读者对于 JavaScript 语言和 Node.js 的回调机制有一个基本的了解。 - -> "I/O" 主要指由[libuv](https://libuv.org/)支持的,与系统磁盘和网络之间的交互。 - -## 阻塞 - -**阻塞** 是指在 Node.js 程序中,其它 JavaScript 语句的执行,必须等待一个非 JavaScript 操作完成。这是因为当 **阻塞** 发生时,事件循环无法继续运行 JavaScript。 - -在 Node.js 中,JavaScript 由于执行 CPU 密集型操作,而不是等待一个非 JavaScript 操作(例如 I/O)而表现不佳,通常不被称为 **阻塞**。在 Node.js 标准库中使用 libuv 的同步方法是最常用的 **阻塞** 操作。原生模块中也有 **阻塞** 方法。 - -在 Node.js 标准库中的所有 I/O 方法都提供异步版本,**非阻塞**,并且接受回调函数。某些方法也有对应的 **阻塞** 版本,名字以 `Sync` 结尾。 - -## 代码比较 - -**阻塞** 方法 **同步** 执行,**非阻塞** 方法 **异步** 执行。 - -使用文件系统模块做例子,这是一个 **同步** 文件读取: - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // blocks here until file is read -``` - -这是一个等同的 **异步** 示例: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; -}); -``` - -第一个示例看上去比第二个简单些,但是有一个缺陷:第二行语句会 **阻塞** 其它 JavaScript 语句的执行直到整个文件全部读取完毕。注意在同步版本中,如果错误被抛出,它需要被捕获否则整个程序都会崩溃。在异步版本中,由作者来决定错误是否如上所示抛出。 - -让我们稍微扩展一下我们的例子: - -```js -const fs = require('fs'); -const data = fs.readFileSync('/file.md'); // blocks here until file is read -console.log(data); -moreWork(); // will run after console.log -``` - -这是一个类似但不等同的异步示例: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -moreWork(); // will run before console.log -``` - -在上述第一个例子中, `console.log` 将在 `moreWork()` 之前被调用。在第二个例子中, `fs.readFile()` 是 **非阻塞** 的,所以 JavaScript 执行可以继续, `moreWork()` 将被首先调用。在不等待文件读取完成的情况下运行 `moreWork()` 的能力是一个可以提高吞吐量的关键设计选择。 - -## 并发和吞吐量 - -在 Node.js 中 JavaScript 的执行是单线程的,因此并发性是指事件循环在完成其他工作后执行 JavaScript 回调函数的能力。任何预期以并行方式运行的代码必须让事件循环能够在非 JavaScript 操作(比如 I/O )执行的同时继续运行。 - -例如,让我们思考这样一种情况:每个对 Web 服务器的请求需要 50 毫秒完成,而那 50 毫秒中的 45 毫秒是可以异步执行的数据库 I/O。选择 **非阻塞** 异步操作可以释放每个请求的 45 毫秒来处理其它请求。仅仅是选择使用 **非阻塞** 方法而不是 **阻塞** 方法,就能造成并发的显著差异。 - -事件循环不同于许多其他语言的模型,其它语言创建额外线程来处理并发工作。 - -## 混合阻塞和非阻塞代码的危险 - -处理 I/O 时应该避免一些模式。我们来看一个例子: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (err, data) => { - if (err) throw err; - console.log(data); -}); -fs.unlinkSync('/file.md'); -``` - -在以上的例子中, `fs.unlinkSync()` 极有可能在 `fs.readFile()` 之前执行,它会在实际读取之前删除 `file.md` 。更好的写法是完全 **非阻塞** 并保证按正确顺序执行: - -```js -const fs = require('fs'); -fs.readFile('/file.md', (readFileErr, data) => { - if (readFileErr) throw readFileErr; - console.log(data); - fs.unlink('/file.md', unlinkErr => { - if (unlinkErr) throw unlinkErr; - }); -}); -``` - -以上代码在 `fs.readFile()` 的回调中对 `fs.unlink()` 进行了 **非阻塞** 调用,这保证了正确的操作顺序。 - -## 其它资源 - -- [libuv](https://libuv.org/) diff --git a/pages/zh-cn/docs/guides/buffer-constructor-deprecation.md b/pages/zh-cn/docs/guides/buffer-constructor-deprecation.md deleted file mode 100644 index 80f1625c7af47..0000000000000 --- a/pages/zh-cn/docs/guides/buffer-constructor-deprecation.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -title: 请使用 Buffer.from()/Buffer.alloc() -layout: docs.hbs ---- - -# 请使用 `Buffer.from()`/`Buffer.alloc()` - -## 概括 - -本教程将向你介绍如果迁移到安全的 `Buffer` 构造函数方法。此合并将消除以下已废除的警告: - -> Buffer() 和 new Buffer() 构造函数对于有安全顾虑的人而言是不推荐使用的。请使用新的方法 Buffer.alloc(),Buffer.allocUnsafe() 或者是 Buffer.from() 构造函数。 - -- [变化 1: 在 Node.js ≤ 4.4.x 和 5.0.0 — 5.9.x 版本中不支持](#variant-1) (_推荐_) -- [变化 2: 使用 polyfill 库](#variant-2) -- [变化 3: 带安全守护的手动检测](#variant-3) - -### 在使用 `grep` 的代码中找出一些问题 - -运行 `grep -nrE '[^a-zA-Z](Slow)?Buffer\s*\(' --exclude-dir node_modules`. - -此代码将从你的代码中找出潜在的不安全的代码(包括一些潜在地,没有考虑周到的异常)。 - -### 在使用 `Node 8` 的代码中找出一些问题 - -如果你使用的 Node.js 版本大于等于 8.0.0,Node.js 提供了一些选项帮助你在代码中寻找相关问题: - -- `--trace-warnings` 通过 Node.js 向您展示堆栈信息跟踪,打印出此警告和其它警告信息。 -- `--trace-deprecation` 和上面差不多,不过只打印废弃警告。 -- `--pending-deprecation` 将对废弃警告给出更多的类型。尤其它会展示 `Buffer()` 的废弃警告,即便在 Node.js 8 也是如此。 - -你可以使用环境变量设置这些开关: - -```bash -$ export NODE_OPTIONS='--trace-warnings --pending-deprecation' -$ cat example.js -'use strict'; -const foo = new Buffer('foo'); -$ node example.js -(node:7147) [DEP0005] DeprecationWarning: The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead. - at showFlaggedDeprecation (buffer.js:127:13) - at new Buffer (buffer.js:148:3) - at Object. (/path/to/example.js:2:13) - [... more stack trace lines ...] -``` - -### 在使用 `linter` 的代码中找出一些问题 - -ESLint 规则[不使用缓存构造函数](https://eslint.org/docs/rules/no-buffer-constructor)或 [node/ 未废除的 Api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) 也会寻找到使用 `Buffer()` 废弃的函数。 这些规则预先已经包含了。 - -不过这存在一个劣势,举个例子,当 `Buffer` 被 polyfill 重写的时候,它不保证一直[正常工作](https://github.com/chalker/safer-buffer#why-not-safe-buffer)。所以推荐使用此方法和其它如上描述的方法在一起使用。 - -## 变化 1: 在 Node.js ≤ 4.4.x 和 5.0.0 — 5.9.x 版本中不支持 - -这是现在的一个推荐的解决方案,暗示仅有极小的成本。 - -Node.js 5.x 发行自 2016 年就不再支持,而 4.x 版本发行线支持到 2018 年 4 月就寿终正寝了(→ [计划表](https://github.com/nodejs/Release#release-schedule))。这意味着这些版本 _不会_ 接受任何更新,即便有安全问题也不会被修复,所以如果可能,我们不应使用这些版本。 - -在这种情况下,你应该把全部的 `new Buffer()` 或 `Buffer()` 更改为 `Buffer.alloc()` 或 `Buffer.from()`,规则如下: - -- 对于 `new Buffer(number)`, 请用 `Buffer.alloc(number)` 替换。 -- 对于 `new Buffer(string)` (或 `new Buffer(string, encoding)`),请用对应的 `Buffer.from(string)` (或 `Buffer.from(string, encoding)`)进行替换。 -- 对于其它情况(一般极为罕见)中使用了 `new Buffer(...arguments)` 的,请用 `Buffer.from(...arguments)` 进行替换。 - -注意:`Buffer.alloc()` 在当前的 Node.js 版本上 _快于_ `new Buffer(size).fill(0)`,后者是当你确认需要用 0 对整个缓存进行初始化。 - -启用 ESLint 检查规则[不使用缓存构造函数](https://eslint.org/docs/rules/no-buffer-constructor)或 [node/ 未废除的 Api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) 时,也会建议避免使用不安全的 `Buffer` 函数。 - -同样我们还有 [JSCodeshift codemod](https://github.com/joyeecheung/node-dep-codemod#dep005),它可以把 `Buffer` 构造函数的地方自动替换成 `Buffer.alloc()` 或 `Buffer.from()`。注意目前它只会工作在参数是文本型,或者带有两个参数的构造函数的情况下。 - -_如果你目前支持那些旧版本的 Node.js,并且抛弃对它们的支持又不可能的情况下,或者你需要支持你包中的旧版本情况下,请考虑使用[版本 2](#variant-2),或者[版本 3](#variant-3)。这样人们可以在使用这些旧版本情况下照样修复这些安全问题。那样的话,这些由不安全的 `Buffer` 所引发的问题会被你彻底根除,你的用户也不用在你运行 Node.js 10 的时候观察你的运行时废弃警告。_ - -## 变化 2: 使用替换库 - -存在着三种替换库: - -- **[更安全的缓存](https://www.npmjs.com/package/safer-buffer)** 是整个用来替换 `Buffer` 函数的方法。当你在使用 `new Buffer()` 的时候,将会 _抛出_ 异常。 - - 和[变化 1](#变化-1-在-nodejs-≤-44x-和-500--59x-版本中不支持) 中一样,你会得到详细同样的步骤。不过请用 `const Buffer = require('safer-buffer').Buffer` 在你所有文件中对 `Buffer` 函数进行替换。 - - 请不要使用旧版本的 _new Buffer()_ 函数,在添加上面的行的任何文件中,使用 <1>new Buffer() 会 _抛出_ 异常。 - -- **[buffer-from](https://www.npmjs.com/package/buffer-from) 或 [buffer-alloc](https://www.npmjs.com/package/buffer-alloc)** 都是 [ponyfills](https://ponyfill.com/) `Buffer` 可接受的方案。 你所要做的就是针对你自己的 API 添加所需的包。 - - 你需要用一个合适的名字为这些调入的模块重命名,例如 `const bufferFrom = require('buffer-from')`。并且使用它们取代你的 `new Buffer()`。例如 `new Buffer('test')` 变成了 `bufferFrom('test')`。 - - 这种方法的缺点是稍微改变代码以迁移它们(如您所希望的那样)。例如在不同的名称下使用 `Buffer.from()`。 - -- **[安全的缓存](https://www.npmjs.com/package/safe-buffer)** 同样也是替换整个 `Buffer` 的方案,但是用 `new Buffer()` 也可以像以前一样正常工作。 - - 欲达此目的而降阶到此,可以让你在代码中使用稍旧一些的 `new Buffer()` 函数,它会引发代码一些问题,并在 Node.js 10 ([阅读更多详情](https://github.com/chalker/safer-buffer#why-not-safe-buffer)) 激发对于运行时废弃函数的警告检查。 - -注意,在任意一种情况下,手动移除你代码中所有关于 `Buffer` 的调用非常重要——仅在 `safe-buffer` 中抛出警告不解决问题,它只是为新的 API 提供了一种替换而已。我亲眼见过人们犯过这类错误。 - -启用 ESLint 规则[不使用缓存构造函数](https://eslint.org/docs/rules/no-buffer-constructor) 或是 [node/ 未废除的 Api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md) 是推荐的。 - -_如果你抛弃了对 Node.js 版本小于 4.5.0 的支持,请不要忘记把替代库也一起去掉。_ - -## 变化 3 — 带安全守护的手动检测 - -在某些情况下这对于你创建 `Buffer` 实例是有帮助的(例如:只需要一个实例的情况下)。或者你有你自己的包装围绕在它们身边。 - -### `Buffer(0)` - -创建空缓存这个特殊的例子可以用 `Buffer.concat([])` 来代替,对于 Node.js 0.8.x 版本而言返回同样的结果。 - -### `Buffer(notNumber)` - -Before: - -```js -const buf = new Buffer(notNumber, encoding); -``` - -After: - -```js -let buf; -if (Buffer.from && Buffer.from !== Uint8Array.from) { - buf = Buffer.from(notNumber, encoding); -} else { - if (typeof notNumber === 'number') { - throw new Error('The "size" argument must be not of type number.'); - } - buf = new Buffer(notNumber, encoding); -} -``` - -`encoding` 为可选参数。 - -注意在 `new Buffer()` 前的 `typeof notNumber` 检测必不可少(对于 `notNumber` 参数不是硬编码的情况下),并且 _不会引发 `Buffer` 构造函数废弃的警报_——这就是 _为什么_ 说 `Buffer` 构造函数被废弃的原因。缺少此类型检测的生态系统引发过不计其数的安全事故——如脏用户的某些输入,在 `Buffer(arg)` 可能会意外终止,这会导致从 DoS 攻击到从进程内存向攻击者泄露敏感信息范围内一系列问题。 - -当 `notNumber` 被硬编码(如文本型 `"abc"` 或者 `[0,1,2]`), `typeof` 类型检查可以被忽略。 - -当然,注意使用 TypeScript 也不解决问题——用 `TypeScript` 写的库从 JS 方引用,或者用户的输入停在那边——它表现得就和原生态的 JS 一模一样,因为所有类型检查仅仅在翻译解析阶段,在 TS 编译成真实的 JS 代码时却不存在了。 - -### `Buffer(number)` - -对于 Node.js 0.10.x (和之后的版本)支持: - -```js -let buf; -if (Buffer.alloc) { - buf = Buffer.alloc(number); -} else { - buf = new Buffer(number); - buf.fill(0); -} -``` - -其余版本(Node.js ≥ 0.12.x): - -```js -const buf = Buffer.alloc ? Buffer.alloc(number) : new Buffer(number).fill(0); -``` - -## 关于 `Buffer.allocUnsafe()` - -使用 `Buffer.allocUnsafe()` 须格外谨慎几点: - -- 如果没有一个很好的理由,请不要使用它: - - 对于小缓存,你或许不想看到性能上的差别。实际上,用 `Buffer.alloc()` 甚至更快。 - - 如果你的代码不是在热代码路径中——你也不希望看到有差别,记住用零填充将把潜在的风险降到最低。 - - 请务必记住:“零填充”的方式会尽最大可能降低风险。 -- 如果你使用它,请务必保证你从不会返回只填充了一部分的缓存, - - 如果你按顺序写入此缓存——总是截取此缓存到你写入缓存的实际长度。 - -处理与 `Buffer.allocUnsafe()` 相关的缓存错误可能会引发各种各样的问题,从你代码的不确定行为表现到敏感数据(如用户输入,密码,相关证书等)被泄露给远程的攻击者等。 - -_注意,当你不用 0 去填充缓存,此问题同样发生在 `new Buffer()` 上。这依赖于 Node.js 版本(缺少类型检查也会额外增加 DoS 攻击)。_ - -## 常见问题 - -### `Buffer` 构造函数有什么问题? - -`Buffer` 构造函数可以用不同方式创建缓存: - -- `new Buffer(42)`创建一个 42 个字节的`缓存` 。在 Node.js 8 之前,该缓存考虑性能,它包含 \_随机内存,而这可能包括任何数据,从编码的源码到密码,以及加密秘钥等。

-- `new Buffer('abc')` 创建一个 UTF-8 编码的字符串`abc`。第二个参数可以指定用何种编码:举一个例子,`new Buffer(string, 'base64')`可用于将 Base64 字符串转换为原始字符串表示的字节序列。 -- 还有其他几种不同的论点。 - -这意味着在代码中诸如 `var buffer = new Buffer(foo);`,当你不知道 `foo` 是什么类型,想要知道生成的缓存里边到底存了什么内容几乎是不可能的。 - -有时,`foo` 的值来源于外部源头。举一个例子,以下函数作为服务器上的一个函数公开,把 UTF-8 的编码字符串转换成 Base64 形式: - -```js -function stringToBase64(req, res) { - // The request body should have the format of `{ string: 'foobar' }`. - const rawBytes = new Buffer(req.body.string); - const encoded = rawBytes.toString('base64'); - res.end({ encoded }); -} -``` - -注意这个代码 _不会_ 验证 `req.body.string` 的类型: - -- `req.body.string` 期望的类型是字符串型。如果是这种情况一切正常。 -- `req.body.string` 受客户端发送请求所控制。 -- 如果 `req.body.string` 是 _数字_ `50`,`rawBytes` 将变成 `50` 个字节: - - 在 Node.js 8 之前,内容是未经初始化的。 - - 在 Node.js 8 之后,内容是 50 个 0。 - -因为缺少类型检查,攻击者可以别有用心地发送一个数字作为请求的一部分,借助它,他们可以: - -- 读取未初始化的内存数据。 这显然**会**导致密码、秘钥和其它敏感数据的泄露(信息泄露)。 -- 强迫程序开辟一个超大内存区域。举一个例子,当指定`500000000`作为输入数据时,每个请求将开辟 500MB 内存区。这不是会耗尽内存使得程序崩溃,就会导致明显的程序性能下降(服务拒绝攻击)。 - -这些情况在现实的网络服务中都被认为是非常严重的安全问题。 - -当使用 `Buffer.from(req.body.string)` 的时候,如果传入一个数字总是抛出异常,给程序提供了一个总是可以自我处理的机会。 - -### `Buffer()` 构造函数废弃有一阵了,它有问题吗? - -检测 `npm` 生态系统的代码,表明 `Buffer()` 仍然广泛被使用。这包含新提交的代码,以及这类代码的使用仍然在 _增长中_。 diff --git a/pages/zh-cn/docs/guides/debugging-getting-started.md b/pages/zh-cn/docs/guides/debugging-getting-started.md deleted file mode 100644 index 17cdc091a6b6b..0000000000000 --- a/pages/zh-cn/docs/guides/debugging-getting-started.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: 调试 - 入门指南 -layout: docs.hbs ---- - -# 调试指南 - -本指南将帮助你开始学习调试 Node.js 程序和脚本。 - -## 启用检查器 - -当使用 `--inspect` 开关符启动检查器时,一个 Node.js 进程开始侦听调试客户端。默认情况下侦听 127.0.0.1:9229 的域名和端口号;每个进程都有一个唯一的 [UUID][] 标示符。 - -检查器的客户端必须知晓并制定连接的域名地址、端口号以及 UUID。一个完整的 URL 看上去如:`ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e`。 - -如果收到了 `SIGUSR1` 信号 (`SIGUSR1` 在 Windows 下不可用),Node.js 同样会开始侦听调试信息;在 Node.js 7 以及先前的版本中,这将激活旧版本的调试 API(legacy Debugger API);在 Node.js 8 和后续版本中,将激活检查器 API(Inspector API)。 - ---- - -## 安全隐患 - -由于调试器对 Node.js 执行环境具有完全访问权限,能够连接到此端口的恶意行为者能够代替 Node.js 进程执行任意代码。理解将调试器端口暴露在公共和专用网络上所受影响的安全性是很重要的。 - -### 把调试端口暴露在公共网络是不安全的 - -如果调试器与一个公共的 IP 地址绑定,或者与 0.0.0.0 绑定,任何可以访问你 IP 地址的客户端都可以在不受限的情况下连接调试器,然后随意运行代码。 - -默认情况下,`node --inspect` 绑定 127.0.0.1。如果打算允许外部连接到调试器,则明确需要提供公共 IP 地址或 0.0.0.0 等。这样做可能会使您面临潜在的重大安全威胁。我们建议您在适当的位置确保适当的防火墙和访问控制,以防止安全隐患。 - -查看 '[启用远程调试情形](#enabling-remote-debugging-scenarios)' 章节部分,以了解如何安全地允许远程调试器连接调试。 - -### 本地应用有足够的权限访问监视器 - -即便你把监视器绑定到 127.0.0.1(默认),任何在你本地机器上运行的应用程序仍然毫无限制地可以访问。这是因为在设计上我们允许本地调试器可以轻松方便地进行连接。 - -### 浏览器,网络套接字和同源政策 - -网站的开放是通过一个可以让网络套接字和 HTTP 请求在浏览器安全模式下进行的。一个初始化的 HTTP 连接必须先获得一个唯一的调试会话 ID。同源政策能够阻止这个网站与 HTTP 连接。对于其它额外的安全防范[DNS 重新绑定攻击](https://en.wikipedia.org/wiki/DNS_rebinding),Node.js 会先精确验证‘宿主’头连接不是一个一个指定的 IP 地址,就是 `localhost`,又或者是 `localhost6`。 - -这些安全政策不允许通过指定主机名的方式直接进行远程连接。你不是通过指定 IP 地址,就是使用 ssh 管道的方式(下面将会有所陈述)绕开此限制。 - -## 监视器客户端 - -一些商业和开源工具可以连接到 Node 的监视器上,关于它们基本信息如下: - -### [Chrome 开发工具](https://github.com/ChromeDevTools/devtools-frontend) 55+, [Microsoft Edge](https://www.microsoftedgeinsider.com) - -- **方法1:**在基于 Chromium 内核的浏览器下打开`chrome://inspect`,或在Edge浏览器下打开 `edge://inspect` ,点击配置按钮确保你的目标宿主和端口号列入其 -- **方法 2:**从 `/json/list` 的输出中复制 `devtoolsFrontendUrl` (见上文)或 --inspect 提示文本并粘贴到 Chrome。 - -> 请注意:Node.js 和 Chrome 必须在同一个平台上运行。 - -### [Visual Studio Code](https://github.com/microsoft/vscode) 1.10+ - -- 在 Debug 面板中,点击“设置图标”,打开 `.vscode/launch.json`,选择 "Node.js" 进行初始化构建。 - -### [Visual Studio](https://github.com/Microsoft/nodejstools) 2017+ - -- 从菜单中或者单击 F5, "Debug > Start Debugging"。 -- [详细说明](https://github.com/Microsoft/nodejstools/wiki/Debugging)。 - -### [JetBrains WebStorm](https://www.jetbrains.com/webstorm/) 以及其它版本 - -- 创建一个新的 Node.js 调试配置,点击调试。在 Node.js 7 版本上默认会加上 `--inspect`开关。欲禁用 的话,在 IDE 注册表中请取消对 `js.debugger.node.use.inspect`的勾选。想了解更多关于WebStorm和其它JetBrains产品的调试方法,可以参考 - -### [chrome 远程接口](https://github.com/cyrus-and/chrome-remote-interface) - -- 简化对[检查器协议终端][]连接的库。 - -### [Gitpod](https://github.com/cyrus-and/chrome-remote-interface) - -- 你可以通过`Debug`视图开启调试配置,或者按下`F5`也行。[此处是详细教程](https://medium.com/gitpod/debugging-node-js-applications-in-theia-76c94c76f0a1)。 - -### [Eclipse IDE](https://eclipse.org/eclipseide) 带有 Eclipse 万维网开发扩展的开发 - -- 从某个后缀为 js 文件,选择 “以……方式调试(Debug As...) > Node 程序 (Node program)”,或者 -- 创建一个调试配置,它把调试器挂接到一个正在运行的 Node 程序上(并且该调试已经使用`--inspect`参数)。 - ---- - -## 命令行选项 - -WebStorm在线帮助/a>。 - - - - - - - - - - - - - - - - - - - - - - - - - - - -
标示符含义
--inspect -
    -
  • 启用监视器代理
  • -
  • 在默认地址和端口上监听(127.0.0.1:9229)
  • -
-
--inspect=[host:port] -
    -
  • 启用监视器代理
  • -
  • 绑定地址或主机名宿主 (默认:127.0.0.1)
  • -
  • 监听端口 (默认:9229)
  • -
-
--inspect-brk -
    -
  • 启用监视器代理
  • -
  • 监听默认地址和端口(127.0.0.1:9229)
  • -
  • 在用户代码启动前终止
  • -
-
--inspect-brk=[host:port] -
    -
  • 启用监视器代理
  • -
  • 绑定地址和主机名宿主(默认:127.0.0.1)
  • -
  • 监听端口(默认:9229)
  • -
  • 在用户代码启动前终止
  • -
-
Node 监视script.js -
    -
  • 通过 --inspect 标志生成一个新的子进程,使用主进程运行 CLI 调试器。
  • -
-
node inspect --port=xxxx script.js -
    -
  • 通过 --inspect 标志生成一个新的子进程,使用主进程运行 CLI 调试器。
  • -
  • 监听端口(默认:9229)
  • -
-
- ---- - -## 启用远程调试的情形 - -以下命令表列出了在调试状态下不同标示符的影响: - -我们推荐你千万不要使用调试器监听公共的 IP 地址。如果你真需要允许远程调试连接,那么就请使用 SSH 代替。以下我们提供你例子仅是为解释目的。请在开始前理解允许远程访问特权的安全风险。 - -```bash -node --inspect server.js -``` - -让我们假定你在一台远程机器上运行 Node,譬如 remote.example.com。你想进行调试。在那台机器上你应该启动 node 进程,让监视器仅监听本地(默认)。 - -```bash -ssh -L 9221:localhost:9229 user@remote.example.com -``` - -现在,在你本地机器上,从你初始化一个调试客户端连接开始,你创建了一个 SSH 管道: - ---- - -## 遗留的调试器 - -**遗留的调试器自 Node 7.7.0 已被弃用。请使用 --inspect 代替。** - -在版本 7 以及更早的版本使用 **--debug** 或 **--debug-brk** 开关启动调试时,Node.js 侦听由中断定义的调试命令,TCP 端口上的 V8 调试协议,默认为 `5858`。任何遵守此协议的调试客户端都可以连接并调试运行这个进程,下面有一些热门的说明。 - -在版本 7 以及更早的版本使用 **--debug** 或 **--debug-brk** 开关启动调试时,Node.js 侦听由中断定义的调试命令,TCP 端口上的 V8 调试协议,默认为 `5858`。任何遵守此协议的调试客户端都可以连接并调试运行这个进程,下面有一些热门的说明。 - -### [内置调试器](https://nodejs.org/dist/latest/docs/api/debugger.html) - -V8 调试协议再也不维护或是归档了。 - -### [node 监视器](https://nodejs.org/dist/latest/docs/api/debugger.html) - -在 Node.js 内置命令行调试器中用 `node debug script_name.js` 启动你的脚本。你的脚本就在 Node 另外一个进程中随着 `--debug-brk` 启动了起来,并且初始化的 Node 进程运行 `_debugger.js` 脚本连接上你的目标。 - - - -[检查器协议终端]: https://chromedevtools.github.io/debugger-protocol-viewer/v8/ -[UUID]: https://tools.ietf.org/html/rfc4122 diff --git a/pages/zh-cn/docs/guides/diagnostics-flamegraph.md b/pages/zh-cn/docs/guides/diagnostics-flamegraph.md deleted file mode 100644 index bc1c6f021f29a..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics-flamegraph.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: 诊断 - 火焰图 -layout: docs.hbs ---- - -# 火焰图 - -## 火焰图起什么作用? - -“火焰图” 是专门用于分析 CPU 在函数中所消耗的时间。他们可以协助你定位哪些同步方法过于消耗时间。 - -## 如何创建一个火焰图? - -或许你已经听说对于 Node.js,创建火焰图不是非常容易,但是那并不是真的(永远不会)。我们再也不需要 Solaris vms 创建火焰图了! - -火焰图通过 `perf` 输出,这并不是一个 node 所指定的工具。即便它是把 CPU 耗时可视化的最佳工具,它仍然存在一些问题 —— 如在 Node.js 8 和之后版本中 JavaScript 编码是如何优化的。欲了解详情可以看[perf 输出的问题](#perf-output-issues)这部分。 - -### 使用预包装工具 - -如果你想在本地开始单一输出火焰图,请尝试 [0x](https://www.npmjs.com/package/0x) - -如果你想诊断发布的生产环境,请阅读[在生产环境中的 0x][]。 - -### 用系统工具 pref 创建火焰图 - -本教程的目的在于给你展示如何创建火焰图的具体步骤,这样让你可以对每一步都有掌控。 - -如果你更好地想理解每一个步骤,请仔细看这些步骤,我们将详细阐述。 - -现在让我们开始吧: - -1. 安装 `perf`(如果你没有安装,那么通常通过 linux-tools-common 安装包进行安装) -2. 尝试运行 `perf` - 或许会告诉你缺少内核模块,请同样安装他们。 -3. 启用 pref 并运行 node(具体参考 [perf 输出的问题](#perf-output-issues)以此了解针对不同 Node.js 版本的建议) - - ```bash - perf recording -e cycles:u -g -- node --perf-basic-prof app.js - ``` - -4. 忽略一些警告,除非它告诉你因为缺少必要的安装包而无法运行 pref,你可能会得到一些警告,告诉你不能访问内核模块的样本等。 -5. 运行命令 `perf script > perfs.out` 生成稍后你看到的可视化的数据文件。对于一个易读的火焰图而言,[应用清理](#filtering-out-node-js-internal-functions)是有作用的。 -6. 如果没有安装 stackvis,请运行 `npm i -g stackvis` -7. 最后运行 `stackvis perf < perfs.out > flamegraph.htm` - -现在你可以使用你最喜爱的浏览器打开火焰图文件,然后观察其燃烧状况。此图是带色编码的,因此你首先应该关注饱和度最深的橘色条。这些最有可能意味着你的 CPU 运行复杂函数消耗的状况。 - -值得一提的是:如果你点击火焰图的一个元素,它周围相关的元素将被放大,并将显示在图形的上方。 - -### 使用 `perf` 对一个运行的进程采样 - -`pref` 对于一个从已经运行、且不想被随意中断的进程中录制火焰图无疑是相当不错的。设想一下现在你有一个非常难重现问题的生产环境上的进程: - -```bash -perf record -F99 -p `pgrep -n node` -g -- sleep 3 -``` - -先停一下,这里 `sleep 3` 是干什么的?它的目的是为了让 pref 持续运行 —— 尽管 `-p` 参数选项是让你指定一个不同的进程 ID(pid),此命令仍然需要在一个进程上执行,并随着它终止。perf 运行的是传递给它的命令的生存期,不管你是否实际分析该命令。`sleep 3` 确保此命令运行 3 秒。 - -为什么 `-F`(采样频率)要被设置成 99?这是有默认原因的,当然你如果愿意可以任意设置。`-F99` 告诉 pref 每秒采样 99 个样本,目的是为了更精确地提高数值。越是低的数值意味着产出越是低的输出,相伴的也就是越是低精度的结果。你需要的精度取决于你的 CPU 运行多长时间的密集型函数。如果你正在寻找一个明显的减速的原因,那么 99 帧每秒应该是足够的。 - -当你得到了那 3 秒 pref 生成的记录,请用以上步骤的最后 2 步处理生成火焰图。 - -### 过滤掉 Node.js 的内置函数 - -通常你只希望看到你自定义函数的调用性能如何,因此把 Node.js 和 V8 内置函数过滤掉,可以让你的图变得简单又容易看懂。你可以这样做: - -```bash -sed -i -r \ - -e "/( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)/d" - -e 's/ LazyCompile:[*~]? /' \ - amouns.out -``` - -如果你现在读火焰图,就会觉得它看上去很怪 —— 花费了多数时间的主要函数就像丢了什么一样,你可以尝试不使用过滤参数,那么你也许得到一个罕见的情况下 Node.js 自身的问题。 - -### Node 的分析选项 - -`--perf-basic-prof-only-functions` 和 `--perf-basic-prof`:此二者函数对你的 JavaScript 调试有帮助,其余选项则用于分析 Node.js 自身,这已经超出了本章的范畴。 - -`--perf-basic-prof-only-functions`:因为输出少,所以使用此参数选项开销也少。 - -### 为什么我需要这些参数? - -当然,如果没有这些参数的话,你照样可以得到火焰图。不过大部分的条状都将被标记为 `v8::Function::Call`。 - -## `perf` 输出的一些问题 - -### Node.js 8.x V8 管道上的变化 - -Node.js 8.x 及以上版本使用了 V8 引擎,采用了新的优化 JavaScript 编译管道模式。这使得一些函数的名字、引用有时候无法被 perf 捕获到(这也被成为“Turbofan”)。 - -导致的结果也就是在火焰图中你无法正确地得到一些函数名字。 - -你或许会注意到 `ByteCodeHandler:`,在那儿可以得到你期盼得到的函数名字。 - -[0x](https://www.npmjs.com/package/0x) 有一些对于此类情况的内置缓解措施。 - -欲知详情,请了解以下内容: - -- https://github.com/nodejs/benchmarking/issues/168 -- https://github.com/nodejs/diagnostics/issues/148#issuecomment-369348961 - -### Node.js 10+ - -Node.js 10.x 使用 `--interpreted-frames-native-stack` 标志解决了“Turbofan”的问题。 - -运行 `node --interpreted-frames-native-stack --perf-basic-prof-only-functions`,你就可以在火焰图中得到函数的名字,无论过去 V8 引擎使用那个管道编译你的 JavaScript。 - -### 火焰图中受损的标签 - -如果你看到诸如以下的标签: - -``` -node`_ZN2v88internal11interpretter17BytecodeGenerator15VisitStatementsEPNS0_8ZoneListIPNS0_9StatementEE -``` - -这意味着你正在运行的 Linux 的 perf 没有用 demangle 支持方法编译,请以 https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 作为示例参考。 - -## 示例部分 - -请通过[火焰图练习](https://github.com/naugtur/node-example-flamegraph)来练习捕获你的火焰图吧! - -[在生产环境中的 0x]: https://github.com/davidmarkclements/0x/blob/master/docs/production-servers.md diff --git a/pages/zh-cn/docs/guides/diagnostics/index.md b/pages/zh-cn/docs/guides/diagnostics/index.md deleted file mode 100644 index 142b5e47ce5f7..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 诊断指南 -layout: docs.hbs ---- - -# 诊断指南 - -这些指南在[诊断工作小组][]中得以创建,其目的旨在诊断一个程序中的相关问题时能给予相应的指导。 - -本文档基于用户亲身经历组织而成。这些历程是一系列互相关联、一步步的措施。用户应当遵从他们,以便于根据用户上报的事件锁定问题。 - -这是可用的诊断指南: - -- [内存诊断相关](/zh-cn/docs/guides/diagnostics/memory) -- [在线调试](/zh-cn/docs/guides/diagnostics/live-debugging) -- [低效率运行](/zh-cn/docs/guides/diagnostics/poor-performance) - -[诊断工作小组]: https://github.com/nodejs/diagnostics diff --git a/pages/zh-cn/docs/guides/diagnostics/live-debugging/index.md b/pages/zh-cn/docs/guides/diagnostics/live-debugging/index.md deleted file mode 100644 index 9e651e4c6cf30..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/live-debugging/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 在线调试 -layout: docs.hbs ---- - -# 在线调试 - -- [在线调试](#在线调试) - - [我的程序没有以预期方式工作](#我的程序没有以预期方式工作) - - [表现症状](#表现症状) - - [如何调试](#如何调试) - -你将在本文中学到如何在线调试 Node.js 进程。 - -## 我的程序没有以预期方式工作 - -### 表现症状 - -用户或许已经观察到对于特定的输入,程序无法输出预期值。举个例子:一个 HTTP 服务以 JSON 格式返回数据,但某些字段却是空的。许多错误的原因皆可导致此问题的发生,不过在本示例中,我们 着重关注程序的逻辑以及如何修复。 - -### 如何调试 - -在本示例中,用户需要理解“程序路径”:它表示为响应一个特定的触发,应用程序所执行的路径(例如:HTTP 请求路径)。同时用户也希望通过“走单步”的方式贯穿整个代码,顺便控制代码的执行流程,以及观察 内存中变量中到底存储了什么数据。预知详情,可以点击下面的链接: - -- [使用内存检查器](/zh-cn/docs/guides/diagnostics/live-debugging/using-inspector) diff --git a/pages/zh-cn/docs/guides/diagnostics/live-debugging/using-inspector.md b/pages/zh-cn/docs/guides/diagnostics/live-debugging/using-inspector.md deleted file mode 100644 index a295cd9ac49b5..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/live-debugging/using-inspector.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: 使用内存检查器 -layout: docs.hbs ---- - -# 使用内存检查器 - -在本地环境中,当我们谈到“在线调试”时,这意味着把我们的程序附加到调试器上,然后在代码里加 若干断点从而挂起正常的程序执行。然后我们单步调试完整个代码路径,观察不同单步时堆的变化。 不过在生产环境中使用调试器于我们而言并不是一个可选项,因为我们限制了该机器的访问权限,同时 我们也无法打断正常的工作执行流。道理很简单:因为它正在处理与公司业务逻辑相关的重要任务。 - -## 如何使用? - -https://nodejs.org/zh-cn/docs/guides/debugging-getting-started/ diff --git a/pages/zh-cn/docs/guides/diagnostics/memory/index.md b/pages/zh-cn/docs/guides/diagnostics/memory/index.md deleted file mode 100644 index 52550804f9390..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/memory/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 内存诊断相关 -layout: docs.hbs ---- - -# 内存诊断相关 - -在本文档中,你讲学到如何调试与内存相关的一系列问题。 - -- [内存诊断相关](#内存诊断相关) - - [内存耗尽](#内存耗尽) - - [相关症状](#内存耗尽的相关症状) - - [副作用](#内存耗尽的副作用) - - [低效率内存使用](低效率内存使用) - - [相关症状](#低效率内存使用的相关症状) - - [副作用](#低效率内存使用的副作用) - - [调试](#调试) - -## 内存耗尽 - -Node.js _(基于 JavaScript)_ 是一个带垃圾回收功能的语言,故内存泄露是可能是 大量占用引起。通常 Node.js 的应用程序都是多终端、关键业务,以及长时间运行。因 此如能提供一个行之有效的找出内存泄露原因的方法是必须的。 - -### 内存耗尽的相关症状 - -用户观察到内存占用持续增长 _(或快活慢,持续数天乃至数周不等)_,然后发现进程崩溃并 通过进程管理器重启进程。进程或许比之前运行得慢,重启也使得一些特定的请求失败 _(负载均衡返回 502)_。 - -### 内存耗尽的副作用 - -- 由于内存耗尽,进程被迫重新启动,请求无法得到响应。 -- 持续增长的 GC 活动导致 CPU 占用率更高,响应时间更长。 - - GC 把事件循环机制阻塞住导致了速度变慢。 -- 增长的内存交换(由 GC 活动引起)使得进程变慢。 -- 没有足够的内存空间来存储一个堆快照。 - -## 低效率内存使用 - -### 低效率内存使用的相关症状 - -应用程序占用的内存与我们的预期不符,我们观察到垃圾回收器的活动有所提升。 - -### 低效率内存使用的副作用 - -- 分页错误数持续增长。 -- 较高的 GC 活动以及 CPU 使用率。 - -## 调试 - -调试一个内存泄露的问题,我们需要看特定的对象占用了多少内存空间,以及什么变量占有了 他们从而使得垃圾回收。为了使我们有效地调试,我们同时也需要了解变量随时间的分配模式。 - -- [使用堆剖析器](/zh-cn/docs/guides/diagnostics/memory/using-heap-profiler/) -- [使用堆快照](/zh-cn/docs/guides/diagnostics/memory/using-heap-snapshot/) -- [GC 跟踪](/zh-cn/docs/guides/diagnostics/memory/using-gc-traces) diff --git a/pages/zh-cn/docs/guides/diagnostics/memory/using-gc-traces.md b/pages/zh-cn/docs/guides/diagnostics/memory/using-gc-traces.md deleted file mode 100644 index f03875a0be184..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/memory/using-gc-traces.md +++ /dev/null @@ -1,352 +0,0 @@ ---- -title: 内存诊断——使用 GC 跟踪 -layout: docs.hbs ---- - -# 追踪垃圾回收 - -本指南将贯穿所有关于垃圾回收跟踪机制的基础部分。 - -当你完成本章节阅读之后,你将会了解: - -- 如何在 Node.js 应用程序中启用跟踪 -- 解析跟踪信息 -- 识别可能潜在 Node.js 应用程序内与内存相关的问题 - -垃圾回收是如何工作的,实在有太多的东西需要学习。但有一点必须清楚:那便是当 GC 运行 的时候,你的代码是不工作的。 - -或许你想知道垃圾回收运行的频率,以及需要运行多久,以及结果是什么。 - -## 脚本构建 - -为本章讲解之目的,我们将使用以下脚本: - -```js -// script.mjs -import os from 'os'; -let len = 1_000_000; -const entries = new Set(); -function addEntry() { - const entry = { - timestamp: Date.now(), - memory: os.freemem(), - totalMemory: os.totalmem(), - uptime: os.uptime(), - }; - entries.add(entry); -} -function summary() { - console.log(`Total: ${entries.size} entries`); -} -// execution -(() => { - while (len > 0) { - addEntry(); - process.stdout.write(`~~> ${len} entries to record\r`); - len--; - } - summary(); -})(); -``` - -> 在此即便内存泄露是明显的,但若想找出泄露的源头,在实际的应用程序 环境中仍然是非常复杂的。 - -## 如何运行垃圾回收追踪 - -你可以借助 `--trace-gc` 在控制台输出中看到垃圾回收追踪的信息情况。 - -```console -$ node --trace-gc script.mjs -``` - -> 注意:你可以在 Node.js 症状分析的[练习][]中找到相关源码。 - -运行之后,输出如下效果: - -```bash -[39067:0x158008000] 2297 ms: Scavenge 117.5 (135.8) -> 102.2 (135.8) MB, 0.8 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2375 ms: Scavenge 120.0 (138.3) -> 104.7 (138.3) MB, 0.9 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2453 ms: Scavenge 122.4 (140.8) -> 107.1 (140.8) MB, 0.7 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2531 ms: Scavenge 124.9 (143.3) -> 109.6 (143.3) MB, 0.7 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2610 ms: Scavenge 127.1 (145.5) -> 111.8 (145.5) MB, 0.7 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2688 ms: Scavenge 129.6 (148.0) -> 114.2 (148.0) MB, 0.8 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -[39067:0x158008000] 2766 ms: Scavenge 132.0 (150.5) -> 116.7 (150.5) MB, 1.1 / 0.0 ms (average mu = 0.994, current mu = 0.994) allocation failure -Total: 1000000 entries -``` - -是否感到不太容易读?我们应该对一些基本的概念有所了解,并使用 `--trace-gc` 进 行解析。 - -### 使用 `--trace-gc` 检查追踪 - -`--trace-gc`( `--trace_gc` 也可) 将把所有和垃圾回收事件相关的信息在控制台上如数输出。 每一行的构成部分可作如下解释: - -```bash -[13973:0x110008000] 44 ms: Scavenge 2.4 (3.2) -> 2.0 (4.2) MB, 0.5 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure -``` - -| 值 | 解析说明 | -| ----------------------------------------------------- | -------------------------- | -| 13973 | 运行中进程的编号 | -| 0x110008000 | 独立内存地址 (JS 堆实例) | -| 44 ms | 自开始运行的时间(毫秒) | -| Scavenge | 类型 / GC 阶段 | -| 2.4 | GC 运行前占有内存(MiB) | -| (3.2) | GC 运行前总占有内存(MiB) | -| 2.0 | GC 运行后占有内存(MiB) | -| (4.2) | GC 运行后总占有内存(MiB) | -| 0.5 / 0.0 ms (average mu = 1.000, current mu = 1.000) | GC 花费的时间(ms) | -| allocation failure | GC 内存分配失败的具体原因 | - -在此我们只需关注两件事: - -- Scavenge -- 标记—清除 - -内存堆被分割成了若干 _区间_ 块。在这些区间块里边,我们有“新”区间,还有“旧”区间。 - -> 👉 实际上,堆的结构本文表述有差异,但我们为了简化期间而故意为之。 如果你想了解更多的细节,我们建议你看 [talk of Peter Marshall][]。 - -### Scavenge - -“Scavenge” 是一种算法的名称,它将执行垃圾回收,并把无用空间转化成可用的新空间。 新空间就是新对象存放的地方。新空间被设计成又小又快的样子,以便于垃圾回收。 - -我们假设以下使用了 Scavenge 的场景: - -- 我们分配了 `A`, `B`, `C` 和 `D` 四块内存变量 - ```bash - | A | B | C | D | | - ``` -- 我们继续想要分配 `E` -- 可用空间不够,内存耗尽了 -- 然后垃圾回收机制被触发 -- 无用的对象被回收了 -- 可用对象仍然得到保留 -- 假设 `B` 和 `D` 是无用对象,那么回收后如下所示 - ```bash - | A | C | | - ``` -- 现在我们可以分配 `E` - ```bash - | A | C | E | | - ``` - -v8 会提升对象,因此对无用空间进行两次 Scavenge 操作之后不再进行垃圾收集。 - -> 👉 参考这里完整的 [Scavenge 情形][]。 - -### 标记—清除 - -“标记—清除”用于从旧空间收集对象,“旧空间”指新空间中幸存下来的物体居住的地方。 - -该算法分成两个阶段: - -- **标记**: 把“可用对象”(活对象)标记成黑,其余则为白。 -- **清除**: 扫描收集所有白色区域,并回收它们转换成为可用空间。 - -> 👉 实际上,“标记—清除”仍然有一些东西值得说道。请阅读此[文档][]以便于了解更多详情。 - -标记和扫描算法 - -## `--trace-gc` 参数实际作用 - -### 内存泄露 - -现在我们是垃圾收集方面的专家了!我们可以得出什么推论? - -我们或许有内存泄露问题,但我们如何确定呢(友情提示:这个示例中很明显,但对于一个现实世界里 的程序呢)? - -同时我们又如何观察上下文? - -打个比方。请使用如下的命令运行 `script.mjs` : - -### 如何捕获糟糕的内存分配上下文? - -1. 假设我们观察到旧内存持续不断地增长 -2. 反复使用 [`--max-old-space-size`][],直到堆内存接近于极限值 -3. 运行程序,直到触发“内存耗尽”的提示。 -4. 这将记录下内存获取失败的上下文信息 -5. 如果触发了“内存耗尽”,不断提高堆的大小(每次10%),尝试数次之后如仍观察到此现象的发生,这意味着内存存在泄露。 -6. 如果无法触发“内存耗尽”,保持你的堆栈大小固定成那个值——因为一个被压缩的堆减少了内存空间量,以及计算过程中的延迟。 - -你应该会遇到如下信息的“内存耗尽”: - -```bash -node --trace-gc --max-old-space-size=50 script.mjs -``` - -现在请调整堆大小至 100mb: - -```bash -[...] -<--- Last few GCs ---> -[40928:0x148008000] 509 ms: Mark-sweep 46.8 (65.8) -> 40.6 (77.3) MB, 6.4 / 0.0 ms (+ 1.4 ms in 11 steps since start of marking, biggest step 0.2 ms, walltime since start of marking 24 ms) (average mu = 0.977, current mu = 0.977) finalize incrementa[40928:0x148008000] 768 ms: Mark-sweep 56.3 (77.3) -> 47.1 (83.0) MB, 35.9 / 0.0 ms (average mu = 0.927, current mu = 0.861) allocation failure scavenge might not succeed -<--- JS stacktrace ---> -FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory [...] -``` - -你应该遇到相似的情况,只不过最后的 GC 跟踪记录包含一个较大的堆空间。 - -```bash -node --trace-gc --max-old-space-size=100 script.mjs -``` - -如何确定你的内存回收次数太多,亦或者导致性能损耗? - -```bash -<--- Last few GCs ---> -[40977:0x128008000] 2066 ms: Mark-sweep (reduce) 99.6 (102.5) -> 99.6 (102.5) MB, 46.7 / 0.0 ms (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 47 ms) (average mu = 0.154, current mu = 0.155) allocati[40977:0x128008000] 2123 ms: Mark-sweep (reduce) 99.6 (102.5) -> 99.6 (102.5) MB, 47.7 / 0.0 ms (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 48 ms) (average mu = 0.165, current mu = 0.175) allocati -``` - -> 请注意:在实际应用程序的上下文中,通过代码寻找泄露对象非常困难。不过“堆捕获”可以帮助到你,详情请看[堆捕获相关指南][]。 - -### 速度慢 - -现在让我们修复这个问题吧。我们将用一个文件,而不是一个对象来存储相关信息。 - -1. 观察跟踪的数据,尤其是在连续不断的内存回收之间的时间。 -2. 观察跟踪的数据,尤其是在 GC 发生前后的时间。 -3. 如果两次 GC 间的时间小于执行一次 GC 所用时间,说明该程序内存严重不足。 -4. 如果两次 GC 间的时间和执行一次 GC 所用时间都异常高,说明该程序使用的内存小了些。 -5. 如果两次 GC 间的时间远大于执行一次 GC 所用时间,程序就相对来说很健康。 - -## 如何修复内存泄露 - -我们对脚本做一点如下的修改: - -使用一个 `Set` 来存储数据在实践中并不坏。你应该关心你程序所留下的内存相关信息。 - -```js -// script-fix.mjs -import os from 'os'; -import fs from 'fs/promises'; -let len = 1_000_000; -const fileName = `entries-${Date.now()}`; -async function addEntry() { - const entry = { - timestamp: Date.now(), - memory: os.freemem(), - totalMemory: os.totalmem(), - uptime: os.uptime(), - }; - await fs.appendFile(fileName, JSON.stringify(entry) + '\n'); -} -async function summary() { - const stats = await fs.lstat(fileName); - console.log(`File size ${stats.size} bytes`); -} -// execution -(async () => { - await fs.writeFile(fileName, '----START---\n'); - while (len > 0) { - await addEntry(); - process.stdout.write(`~~> ${len} entries to record\r`); - len--; - } - await summary(); -})(); -``` - -现在则是我们执行该脚本的时候: - -> 注意:你可以在 Node.js 症状分析的[练习][]中找到相关源码。 - -你应该观察到两件事情: - -``` -node --trace-gc script-fix.mjs -``` - -相对于第一个脚本而言,新版本的脚本在内存上施加的压力更小,自然更容易甄别出。 - -- “标记—清除” 事件频率减少 -- 与之前(第一个脚本)相比内存占用超过 130MB 而言,本次内存相关记录显示不超过 25MB。 - -**拓展**: 你如何考虑提升这个脚本?或许你已经注意到这个新版本的脚本太慢了。 如果我们再次使用 `Set` ,仅当内存占用达到某个程度大小的时候再把内容一次性地写入文件? - -或许你并不像跟踪整个程序完整的信息。如果是这样的话,在程序中设置你的标记即可。 `v8` 模块公开了一个 API 可以让你立即设置参数: - -> 使用 [`getheapstatistics`][] API 或许可以帮到你 - -## 加分项: 通过代码跟踪垃圾收集 - -### 使用 `v8` 模块 - -Node.js 里你还可以使用 [性能钩子][] 来追踪垃圾回收信息。 - -```js -import v8 from 'v8'; -// enabling trace-gc -v8.setFlagsFromString('--trace-gc'); -// disabling trace-gc -v8.setFlagsFromString('--notrace-gc'); -``` - -### 使用“性能钩子” - -在 Node.js 中,你可以使用[性能钩子][]来跟踪垃圾回收的具体情况。 - -```js -const { PerformanceObserver } = require('perf_hooks'); - -// Create a performance observer -const obs = new PerformanceObserver(list => { - const entry = list.getEntries()[0]; - /* - The entry is an instance of PerformanceEntry containing - metrics of a single garbage collection event. - For example: - PerformanceEntry { - name: 'gc', - entryType: 'gc', - startTime: 2820.567669, - duration: 1.315709, - kind: 1 - } - */ -}); - -// Subscribe to notifications of GCs -obs.observe({ entryTypes: ['gc'] }); - -// Stop subscription -obs.disconnect(); -``` - -### 使用“性能钩子”检查一个跟踪信息 - -你可以通过[PerformanceObserver][],从回调函数中得到一个诸如[PerformanceEntry][]一样的 GC 静态数据信息 - -举个例子: - -```ts -PerformanceEntry { - name: 'gc', - entryType: 'gc', - startTime: 2820.567669, - duration: 1.315709, - kind: 1 -} -``` - -| 属性名 | 解释 | -| --------- | -------------------------------------- | -| name | 性能名称 | -| entryType | 性能类型 | -| startTime | 回收开始时间(单位:高精度毫秒时间戳) | -| duration | 本次回收总时间(单位:毫秒) | -| kind | 本次垃圾收集的类型 | -| flags | 垃圾回收的其余信息 | - -欲了解更多信息,您可以参考 [关于性能钩子的文档][performance hooks]。 - -[PerformanceEntry]: https://nodejs.org/api/perf_hooks.html#perf_hooks_class_performanceentry -[PerformanceObserver]: https://nodejs.org/api/perf_hooks.html#perf_hooks_class_performanceobserver -[`--max-old-space-size`]: https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-megabytes -[性能钩子]: https://nodejs.org/api/perf_hooks.html -[performance hooks]: https://nodejs.org/api/perf_hooks.html -[练习]: https://github.com/nodejs/diagnostics/tree/main/documentation/memory/step3/exercise -[堆捕获相关指南]: https://github.com/nodejs/nodejs.org/blob/main/locale/en/docs/guides/diagnostics/memory/using-heap-snapshot.md#how-to-find-a-memory-leak-with-heap-snapshots -[文档]: https://github.com/thlorenz/v8-perf/blob/master/gc.md#marking-state -[Scavenge 情形]: https://github.com/thlorenz/v8-perf/blob/master/gc.md#sample-scavenge-scenario -[talk of Peter Marshall]: https://v8.dev/blog/trash-talk -[`getheapstatistics`]: https://nodejs.org/dist/latest-v16.x/docs/api/v8.html#v8getheapstatistics diff --git a/pages/zh-cn/docs/guides/diagnostics/memory/using-heap-profiler.md b/pages/zh-cn/docs/guides/diagnostics/memory/using-heap-profiler.md deleted file mode 100644 index fd111a2cd3cba..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/memory/using-heap-profiler.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: 内存诊断——使用 Heap 剖析器 -layout: docs.hbs ---- - -# 使用内存堆剖析器 - -内存堆剖析器处于 V8 的顶部,能持续对内存分配进行快照。在这篇文章里我们将设计到内存的 剖析,将使用: - -1. 时间轴的分配 -2. 采样内存堆剖析器信息 - -不同于[使用堆快照][]中所涉及到的内容,使用实时堆剖析意在了解一段特定时间下内存分配 情况。 - -## 堆剖析器 - 时间轴的分配 - -堆剖析器与堆采样分析器相似,不同处在于它会跟踪每次的内存分配状况,它的开销也就 高于堆采样分析器,所以不建议在生产环境中使用。 - -> 你可借助 [@mmarchini/observe][] 通过编码方式来启动和停止剖析器。 - -### 怎么用堆剖析器? - -启动应用程序: - -```console -node --inspect index.js -``` - -> `--inspect-brk` 对于脚本而言是较好的选项。 - -在 Chrome 中连接开发工具实例,然后: - -- 选择 `memory` 选项卡 -- 选择 `Allocation instrumentation timeline` -- 开始剖析 - -![堆剖析器步骤 1][3] - -堆剖析一旦开始运行,我们强烈建议您运行示例,这样便于确认内存相关的问题。 举个例子:如果我们对一个 Web 应用程序进行堆剖析,`Apache Benchmark` 可以用来产出(模拟)应用程序中的负载。 - -```console -$ ab -n 1000 -c 5 http://localhost:3000 -``` - -当负载全部请求完毕之后,请按“停止”按钮。 - -![堆剖析器步骤 2][4] - -最后针对内存分配情况看一下快照。 - -![堆剖析器步骤 3][5] - -请查阅下列有助于你了解关于更多内存相关术语的[链接部分](#useful-links) 。 - -## 堆剖析的采样 - -对堆剖析器的采样是在一定时间内持续跟踪内存份分配状况和后备内存。由于采样基于低 开销进行,所以它可以用在生产环境。 - -> 在这个示例中,我们假定堆剖析基于 Web 应用程序。 - -### 如何对堆剖析进行采样? - -启动应用程序: - -```console -$ node --inspect index.js -``` - -> 你可以借助 [`heap-profiler`][] 模块,通过编程方式控制堆内存剖析的开与关。 - -在 Chrome 中连接开发工具的实例,然后: - -1. 选择 `memory` 选项卡 -2. 选择 `Allocation sampling` -3. 开始剖析 - -![堆剖析器步骤 4][7] - -在负载产生后停止剖析器,它会自动生成一个基于堆栈跟踪的内存分配总结。你可以关注 函数的内存堆分配状况,可以参照下面的例子: - -![堆剖析器步骤 5][8] - -## 有帮助的相关链接: - -- https://developer.chrome.com/docs/devtools/memory-problems/memory-101/ -- https://github.com/v8/sampling-heap-profiler -- https://developer.chrome.com/docs/devtools/memory-problems/allocation-profiler/ - -[使用堆快照]: /zh-cn/docs/guides/diagnostics/memory/using-heap-snapshot/ -[@mmarchini/observe]: https://www.npmjs.com/package/@mmarchini/observe -[3]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-1.png -[4]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-2.png -[5]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-3.png -[`heap-profiler`]: https://www.npmjs.com/package/heap-profile -[7]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-4.png -[8]: /static/images/docs/guides/diagnostics/heap-profiler-tutorial-5.png diff --git a/pages/zh-cn/docs/guides/diagnostics/memory/using-heap-snapshot.md b/pages/zh-cn/docs/guides/diagnostics/memory/using-heap-snapshot.md deleted file mode 100644 index 9fd7aa1029694..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/memory/using-heap-snapshot.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: 内存诊断——使用 Heap 快照 -layout: docs.hbs ---- - -# 使用内存堆快照 - -你可以在程序运行的同时为程序生成一个内存堆快照,然后把它加载到 [Chrome 开发工具][]中 检查特定的变量,或者是占用内存的大小。你也可以持续性地比较多个快照来观察他们之间的不同。 - -## 警告! - -在创建快照的同时其它主线程中的工作都会停止。根据堆的上下文情况,有可能这种快照将持续超 过一分钟之久。内存快照在内存中创建,所以可能占用两倍的内存,导致整个内存都被填满而使得 应用程序崩溃。 - -如果你想在生产环境生成内存快照,请确认被快照的那个进程崩溃不会对你程序的应用产生影响。 - -## 如何生成快照? - -### 获取内存快照 - -使用 `--inspect` 命令符运行 node 程序并打开检查器。 - -1. 通过检查器 -2. 通过外部信号以及命令行命令符 -3. 通过在进程内部调用 writeHeapSnapshot 函数 -4. 通过检查协议 - -#### 1. 在检查器中使用内存剖析工具 - -> 该方法适用于所有维护活跃版本的 Node.js - -最简便获取堆快照的方法就是把检查器和你本地正在运行的进程进行连接,切换到“内存”标签页, 选择采集内存快照。 ![打开查看器][2] - -获取Heap 快照的最简单方式是将视察员连接到您的 进程本地运行。 然后转到内存标签页并拍摄堆快照。 - -![拍一张堆快照。][3] - -#### 2. 使用 `--heapsnapshot-signal` 命令符 - -> 此方法在 Node.js v12.0.0 或之后版本使用 - -预知详情,请查阅最新关于[内存快照信号量标志符][]的文档。 - -``` -$ node --heapsnapshot-signal=SIGUSR2 index.js -``` - -``` -$ ps aux -USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND -node 1 5.5 6.1 787252 247004 ? Ssl 16:43 0:02 node --heapsnapshot-signal=SIGUSR2 index.js -$ kill -USR2 1 -$ ls -Heap.20190718.133405.15554.0.001.heapsnapshot -``` - -如果你想从一个正在运行的进程里提取快照,这如同在服务器上运行的程序一样,你可以这样做: - -#### 3. 使用 `writeHeapSnapshot` 函数 - -> Node.js 版本至少是 v11.13.0 或之后 对于旧版本的 Node.js,可以借助 [heapdump 包][] 来使用 - -请查阅 [`writeHeapSnapshot` 文档][] 了解文件名的可用选项。 - -```js -require('v8').writeHeapSnapshot(); -``` - -在不停掉进程的前提下你需要有一个方式来生成快照,建议在 HTTP Handler 里调用,亦或是从操作 系统中对某个信号量做出反应。但你需小心一点:不要暴漏触发生成快照的 Http 终端地址,它不应该 被其他人直接访问。 - -对于 v11.13.0 之前的 Node.js 版本,请借助 [heapdump 包][]来实现。 - -“检查器协议” 可被用来从进程外部触发生成内存堆快照。 - -#### 4. 借助检查器协议触发内存堆快照 - -通过 Chromium 运行实际的检查器调用 API 并不是必要的方式。 - -以 bash 方式,借助 `websocat` 和 `jq`,给出触发内存快照的方式: - -这里提供一份与检查器协议一起使用的内存分析工具的详尽列表: - -```bash -#!/bin/bash -set -e - -kill -USR1 "$1" -rm -f fifo out -mkfifo ./fifo -websocat -B 10000000000 "$(curl -s http://localhost:9229/json | jq -r '.[0].webSocketDebuggerUrl')" < ./fifo > ./out & -exec 3>./fifo -echo '{"method": "HeapProfiler.enable", "id": 1}' > ./fifo -echo '{"method": "HeapProfiler.takeHeapSnapshot", "id": 2}' > ./fifo -while jq -e "[.id != 2, .result != {}] | all" < <(tail -n 1 ./out); do - sleep 1s - echo "Capturing Heap Snapshot..." -done - -echo -n "" > ./out.heapsnapshot -while read -r line; do - f="$(echo "$line" | jq -r '.params.chunk')" - echo -n "$f" >> out.heapsnapshot - i=$((i+1)) -done < <(cat out | tail -n +2 | head -n -1) - -exec 3>&- -``` - -为找到内存泄露,必须先对比两个快照。但必须先确保这些快照之间的区别未包含不需要的信息。 遵循下列步骤,你就可以创建一个干净的快照。 - -- [适用于 Node.js 的 OpenProfiling][openprofiling] - -## 如何借助内存堆快照发现内存泄露? - -为找到内存泄露,必须先对比两个快照。但必须先确保这些快照之间的区别未包含不需要的信息。 遵循下列步骤,你就可以创建一个干净的快照。 - -1. 让进程加载所有资源并完成引导。最多需要几秒即可完成。 -2. 开始使用您怀疑会泄漏内存的功能。它很可能是进行一些初始分配,而不是泄漏的分配。 -3. 拍一张堆快照。 -4. 继续使用该功能一段时间,最好不要运行 其他内容。 -5. 再拍一张堆快照。两者之间的差额大多应该包含 泄漏的内容。 -6. 打开 Chromium/Chrome 开发工具并转到 _Memory_ 标签 -7. 首先加载旧的快照文件,紧接着再加载新的。 ![在工具中加载按钮][8] -8. 在顶部下拉菜单中选择较新的快照,并切换模式从 _Summary_ 到 _Comparison_ ![比较下拉列表][9] -9. 在最底部的面板中寻找他们之间较大的差异部分,浏览那些导致形成这些原因的相关引用。 - -你可以通过[此内存堆快照练习][heapsnapshot exercise]来锻炼你捕获快照以及寻找内存泄露的能力。 - -[Chrome 开发工具]: https://developer.chrome.com/docs/devtools/ -[2]: /static/images/docs/guides/diagnostics/tools.png -[3]: /static/images/docs/guides/diagnostics/snapshot.png -[内存快照信号量标志符]: https://nodejs.org/api/cli.html#--heapsnapshot-signalsignal -[heapdump 包]: https://www.npmjs.com/package/heapdump -[`writeHeapSnapshot` 文档]: https://nodejs.org/api/v8.html#v8_v8_writeheapsnapshot_filename -[openprofiling]: https://github.com/vmarchaud/openprofiling-node -[8]: /static/images/docs/guides/diagnostics/load-snapshot.png -[9]: /static/images/docs/guides/diagnostics/compare.png -[heapsnapshot exercise]: https://github.com/naugtur/node-example-heapdump diff --git a/pages/zh-cn/docs/guides/diagnostics/poor-performance/index.md b/pages/zh-cn/docs/guides/diagnostics/poor-performance/index.md deleted file mode 100644 index fb0cecbbac7f8..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/poor-performance/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 低性能和效率—如何诊断 -layout: docs.hbs ---- - -# 低效率运行 - -本文档将告知你如何分析一个 Node.js 进程。 - -- [低性能和效率](#低效率运行) - - [我的程序执行效率太低了!](#我的程序执行效率太低了) - - [症状](#症状) - - [调试](#调试) - -## 我的程序执行效率太低了! - -### 症状 - -我的程序非常缓慢,我肯定瓶颈并非出在数据库和下游服务方面的依赖。我怀疑我的程序 在执行代码和处理方面花费了太久的时间。 - -或许你对你的程序运行效率尚满意,但总想了解一下哪一部分还有改进的余地以便让程序 运行的更快且效率更高。当我们想提高用户体验,或者节省计算机开销的时候,了解如何分析 是很有作用的。 - -### 调试 - -在本用户案例中,我们仅对造成 CPU 过多运行的代码片段该兴趣深入研究,不讨论其它代码。 我们在研究的同时也会尽量优化精简代码。 - -本文将提供你两种方式分析一个 Node.js 应用程序的效率: - -- [如何使用 V8 采样分析器](/zh-cn/docs/guides/simple-profiling/) -- [如何使用 Linux 的 Perf 工具](/zh-cn/docs/guides/diagnostics/poor-performance/using-linux-perf) diff --git a/pages/zh-cn/docs/guides/diagnostics/poor-performance/using-linux-perf.md b/pages/zh-cn/docs/guides/diagnostics/poor-performance/using-linux-perf.md deleted file mode 100644 index 8ef5fcafd06f0..0000000000000 --- a/pages/zh-cn/docs/guides/diagnostics/poor-performance/using-linux-perf.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: 低性能和效率—如何使用 Linux 的 Perf 工具 -layout: docs.hbs ---- - -# 使用 Linux Perf 工具分析 - -[Linux Perf](https://perf.wiki.kernel.org/index.php/Main_Page) 借助 JavaScript 提供您低级别程度的 CPU 分析, 本地分析以及操作系统级别的帧分析。 - -**重要**:此教程仅在 Linux 上可用。 - -## 我该怎么做? - -Linux Perf 工具通常随着 `linux-tools-common` 工具包一起发布。借助 `--perf-basic-prof` 或 `--perf-basic-prof-only-functions` 命令,我们可以启动一个带有支持 _perf_events_ 的 Node.js 程序。 - -`--perf-basic-prof` :总是把结果写入一个文件(通常是 /tmp/perf-PID.map),这样做的结果便是该文件的大小会 不停地增长。如果你对此感到担心的话,可以使用 [linux-perf](https://www.npmjs.com/package/linux-perf) 或 `--perf-basic-prof-only-functions`。 - -以上二者的主要区别在于 `--perf-basic-prof-only-functions` 的输出量更少,显然这对于生产环境下的性能分析 是可行性方案。 - -```console -# Launch the application an get the PID -$ node --perf-basic-prof-only-functions index.js & -[1] 3870 -``` - -然后根据预想的采集频率记录所有发生过的事件: - -```console -$ sudo perf record -F 99 -p 3870 -g -``` - -在本阶段你还可以加载一个负载测试,以便于生成更多的可靠的信息便于诊断和分析。当完成这一切之后,使用 SIGINT(Ctrl-C) 强制关闭性能分析工具即可。 - -`perf` 工具会在 `/tmp` 路径下生成一个文件,通常是 `/tmp/perf-PID.map` (上面的例子是 `/tmp/perf-3870.map`), 其中包含着每个函数调用的跟踪堆栈情况。 - -如想汇总这些数据到一起形成一个文件,请执行以下命令: - -```console -$ sudo perf script > perfs.out -``` - -```console -$ cat ./perfs.out -node 3870 25147.878454: 1 cycles: - ffffffffb5878b06 native_write_msr+0x6 ([kernel.kallsyms]) - ffffffffb580d9d5 intel_tfa_pmu_enable_all+0x35 ([kernel.kallsyms]) - ffffffffb5807ac8 x86_pmu_enable+0x118 ([kernel.kallsyms]) - ffffffffb5a0a93d perf_pmu_enable.part.0+0xd ([kernel.kallsyms]) - ffffffffb5a10c06 __perf_event_task_sched_in+0x186 ([kernel.kallsyms]) - ffffffffb58d3e1d finish_task_switch+0xfd ([kernel.kallsyms]) - ffffffffb62d46fb __sched_text_start+0x2eb ([kernel.kallsyms]) - ffffffffb62d4b92 schedule+0x42 ([kernel.kallsyms]) - ffffffffb62d87a9 schedule_hrtimeout_range_clock+0xf9 ([kernel.kallsyms]) - ffffffffb62d87d3 schedule_hrtimeout_range+0x13 ([kernel.kallsyms]) - ffffffffb5b35980 ep_poll+0x400 ([kernel.kallsyms]) - ffffffffb5b35a88 do_epoll_wait+0xb8 ([kernel.kallsyms]) - ffffffffb5b35abe __x64_sys_epoll_wait+0x1e ([kernel.kallsyms]) - ffffffffb58044c7 do_syscall_64+0x57 ([kernel.kallsyms]) - ffffffffb640008c entry_SYSCALL_64_after_hwframe+0x44 ([kernel.kallsyms]) -.... -``` - -原始的输出有一些难以理解,所以通常而言,该文件被用于生成火焰图以方便查看。 - -![Example nodejs flamegraph](https://user-images.githubusercontent.com/26234614/129488674-8fc80fd5-549e-4a80-8ce2-2ba6be20f8e8.png) - -为了生成火焰图,请参考[生成火焰图教程](https://nodejs.org/zh-cn/docs/guides/diagnostics-flamegraph/#create-a-flame-graph-with-system-perf-tools),从第六步开始。 - -`perf` 并不是单为 Node.js 量身定制的分析工具,因此对于如何优化 JavaScript 代码上可能存在缺陷。 预知详情可以参考[`perf` 输出的一些问题](https://nodejs.org/zh-cn/docs/guides/diagnostics-flamegraph/#perf-output-issues)。 - -## 其它相关的一些有用的链接帮助 - -- https://nodejs.org/en/docs/guides/diagnostics-flamegraph/ -- https://www.brendangregg.com/blog/2014-09-17/node-flame-graphs-on-linux.html -- https://perf.wiki.kernel.org/index.php/Main_Page -- https://blog.rafaelgss.com.br/node-cpu-profiler diff --git a/pages/zh-cn/docs/guides/domain-postmortem.md b/pages/zh-cn/docs/guides/domain-postmortem.md deleted file mode 100644 index d273808523053..0000000000000 --- a/pages/zh-cn/docs/guides/domain-postmortem.md +++ /dev/null @@ -1,368 +0,0 @@ ---- -title: 域模块已死 -layout: docs.hbs ---- - -# 域模块已死 - -## 使用中的问题 - -### 隐式行为 - -对于一个开发者而言,创建一个新的域然后简单地通过 `domain.enter()` 运行起来,然后在将来它就可以捕获全部抛出异常者无法观察到的异常。允许模块作者截取不同模块中无关代码的异常而不让原来的代码知道它的自身异常。 - -下面是一个间接链接模块如何影响另一个模块的例子: - -```js -// module a.js -const b = require('./b'); -const c = require('./c'); - -// module b.js -const d = require('domain').create(); -d.on('error', () => { - /* silence everything */ -}); -d.enter(); - -// module c.js -const dep = require('some-dep'); -dep.method(); // Uh-oh! This method doesn't actually exist. -``` - -因为模块 `b` 进入了域中且从未退出,任何未捕获的异常将被吞掉。茫茫然地留下模块 `c` 而为什么它没有运行整个脚本?留下一个可能部分填充的模块 `module.exports`。这么做与监听 `'uncaughtException'`是不同的。后者明显指全局捕获异常错误,另外一个问题是域在任何 `'uncaughtException'` 处理程序之前进行处理,并阻止它们继续执行。 - -另一个问题是如果在事件激发者上没有相关 `'错误'` 控制,域自动路由错误。这种选择机制对你而言没的选择,它会在整个异步链上自动传播。这个或许一开始看起来有用,但是一旦异步调用是两个或多个模块,其中有一个不包含域的创建者的错误处理程序突然遇到了意想不到的例外,抛出异常的也就不会被作者注意到。 - -下面是一个简单的例子,说明丢失的 `'错误'` 处理程序是如何允许的主动域劫持错误的: - -```js -const domain = require('domain'); -const net = require('net'); -const d = domain.create(); -d.on('error', err => console.error(err.message)); - -d.run(() => - net - .createServer(c => { - c.end(); - c.write('bye'); - }) - .listen(8000) -); -``` - -即便通过 `d.remove(c)` 手动移除连接也不会阻止连接错误不会自动捕获。 - -困扰错误路由和异常处理的故障是不一致的错误如何冒泡。下面是一个例子说明嵌套域怎样在异常发生时向上冒泡异常: - -```js -const domain = require('domain'); -const net = require('net'); -const d = domain.create(); -d.on('error', () => console.error('d intercepted an error')); - -d.run(() => { - const server = net - .createServer(c => { - const e = domain.create(); // No 'error' handler being set. - e.run(() => { - // This will not be caught by d's error handler. - setImmediate(() => { - throw new Error('thrown from setImmediate'); - }); - // Though this one will bubble to d's error handler. - throw new Error('immediately thrown'); - }); - }) - .listen(8080); -}); -``` - -可以预期嵌套域始终保持嵌套,并且总是将异常传播到域堆栈上。或者那些例外不会自动发生冒泡。不幸的是,这两种情况都会发生,导致可能混淆的行为,甚至可能很难调试时序冲突。 - -### API 缺陷 - -虽然基于 `EventEmitter` 的 API 可以使用 `bind()` ,而错误回调风格的回调可以使用 `intercept()`,但是隐式绑定到活动域的替代 API 必须在 `run()` 中执行。这意思是,如果模块作者想用一种机制来支持域,那么就可以使用必须手动实现域自身的支持机制。而不是能够利用已经存在的隐含机制。 - -### 错误传递 - -如果可能的话,跨嵌套域传播错误不是直截了当的。现有文档显示了在请求处理程序中出现错误时如何使用 `close()` 方法关闭 `http` 服务器的简单示例。它没有解释的是,如果请求处理程序为另一个异步请求创建另一个域实例,则如何关闭服务器。以下作为错误传播失败的简单例子: - -```js -const d1 = domain.create(); -d1.foo = true; // custom member to make more visible in console -d1.on('error', er => { - /* handle error */ -}); - -d1.run(() => - setTimeout(() => { - const d2 = domain.create(); - d2.bar = 43; - d2.on('error', er => console.error(er.message, domain._stack)); - d2.run(() => { - setTimeout(() => { - setTimeout(() => { - throw new Error('outer'); - }); - throw new Error('inner'); - }); - }); - }) -); -``` - -即使在域实例被用于本地存储的情况下,使得对资源的访问仍可用,仍然没有办法允许错误从 `d2` 继续传播到 `d1`。快速检查可以告诉我们简单地从 `d2` 域 `'错误'` 处理程序中抛出将允许 `d1` 捕获异常并执行它自己的错误处理程序。虽然不是这种情况。在检查 `domain._stack` 时,您会看到堆栈只包含 `d2` 。 - -这可能被认为是 API 的一个失败,但即使确定它在这方面可以运行,还有一个问题,就是当异步执行中的某个分支发生了失败,那么所有进一步的操作都必须终止。在 http 请求处理程序的示例中,如果我们发起几个异步请求,然后每个 `write()` 方法数据返回到客户端,试图对一个已经关闭的处理调用 `write()` 方法时会出现更多的错误。关于 _异常的资源清理_ 中对此进行了更多的讨论。 - -### 异常的资源清理 - -下面的脚本包含一个更复杂的示例。它是关于在一个小的资源依赖树中正确资源清理,在一个给定的连接或其任何依赖关系中发生异常的情况下,将脚本分解为基本操作: - -```js -'use strict'; - -const domain = require('domain'); -const EventEmitter = require('events'); -const fs = require('fs'); -const net = require('net'); -const print = process._rawDebug; - -const pipeList = []; -const FILENAME = '/tmp/tmp.tmp'; -const PIPENAME = '/tmp/node-domain-example-'; -const FILESIZE = 1024; -let uid = 0; - -// Setting up temporary resources -const buf = Buffer.alloc(FILESIZE); -for (let i = 0; i < buf.length; i++) buf[i] = ((Math.random() * 1e3) % 78) + 48; // Basic ASCII -fs.writeFileSync(FILENAME, buf); - -class ConnectionResource extends EventEmitter { - constructor(c) { - super(); - - this._connection = c; - this._alive = true; - this._domain = domain.create(); - this._id = Math.random().toString(32).substr(2).substr(0, 8) + ++uid; - - this._domain.add(c); - this._domain.on('error', () => { - this._alive = false; - }); - } - - end(chunk) { - this._alive = false; - this._connection.end(chunk); - this.emit('end'); - } - - isAlive() { - return this._alive; - } - - id() { - return this._id; - } - - write(chunk) { - this.emit('data', chunk); - return this._connection.write(chunk); - } -} - -// Example begin -net - .createServer(c => { - const cr = new ConnectionResource(c); - - const d1 = domain.create(); - fs.open( - FILENAME, - 'r', - d1.intercept(fd => { - streamInParts(fd, cr, 0); - }) - ); - - pipeData(cr); - - c.on('close', () => cr.end()); - }) - .listen(8080); - -function streamInParts(fd, cr, pos) { - const d2 = domain.create(); - const alive = true; - d2.on('error', er => { - print('d2 error:', er.message); - cr.end(); - }); - fs.read( - fd, - Buffer.alloc(10), - 0, - 10, - pos, - d2.intercept((bRead, buf) => { - if (!cr.isAlive()) { - return fs.close(fd); - } - if (cr._connection.bytesWritten < FILESIZE) { - // Documentation says callback is optional, but doesn't mention that if - // the write fails an exception will be thrown. - const goodtogo = cr.write(buf); - if (goodtogo) { - setTimeout(() => streamInParts(fd, cr, pos + bRead), 1000); - } else { - cr._connection.once('drain', () => - streamInParts(fd, cr, pos + bRead) - ); - } - return; - } - cr.end(buf); - fs.close(fd); - }) - ); -} - -function pipeData(cr) { - const pname = PIPENAME + cr.id(); - const ps = net.createServer(); - const d3 = domain.create(); - const connectionList = []; - d3.on('error', er => { - print('d3 error:', er.message); - cr.end(); - }); - d3.add(ps); - ps.on('connection', conn => { - connectionList.push(conn); - conn.on('data', () => {}); // don't care about incoming data. - conn.on('close', () => { - connectionList.splice(connectionList.indexOf(conn), 1); - }); - }); - cr.on('data', chunk => { - for (let i = 0; i < connectionList.length; i++) { - connectionList[i].write(chunk); - } - }); - cr.on('end', () => { - for (let i = 0; i < connectionList.length; i++) { - connectionList[i].end(); - } - ps.close(); - }); - pipeList.push(pname); - ps.listen(pname); -} - -process.on('SIGINT', () => process.exit()); -process.on('exit', () => { - try { - for (let i = 0; i < pipeList.length; i++) { - fs.unlinkSync(pipeList[i]); - } - fs.unlinkSync(FILENAME); - } catch (e) {} -}); -``` - -- 当一个新的连接发生时,同时也发生: - - 打开文件系统上的文件 - - 针对唯一的套接字打开文件管道 -- 异步读取文件块 -- 将块写入 TCP 连接和任何监听套接字中 -- 如果这些资源中的任何一个出错,则通知其它需要清理和关闭的附加资源 - -正如我们从这个例子中看到的那样,当某些事情发生故障时必须做正确的清理。所有域提供的是异常聚合机制。在这个例子中,即使通过域传递数据的潜在有用能力也很容易通过将需要的资源作为函数参数传递。 - -一个问题是把域持久化。它是对能够继续执行的简单假设,与文档所述的相反,尽管有一个意外的例外。这个例子说明了这个想法背后的谬误。 - -当应用程序本身的复杂性增加时,尝试对意外异常进行适当的资源清理变得更加复杂。此示例只有三个基本资源在应用中,并且它们都具有明确的依赖路径。如果应用程序使用诸如共享资源或资源重用之类的东西,清理和测试该清理的能力已经大大提高。 - -最后,在处理错误方面,域不仅仅是一个值得骄傲的 `'uncaughtException'` 处理程序。除第三方更隐秘和不可观察的行为以外。 - -### 资源传播 - -域的另一个用例是使用它来沿着异步数据路径传播数据。一个问题是当在堆栈中有多个时,期望何时得到正确的域的模糊性(必须假定)。异步堆栈与其它模块一起工作。还可以依赖于域进行错误处理,同时也有可能用于检索必要的数据。 - -下面是一个示例,演示了使用域沿着异步堆栈传输数据的失败情况: - -```js -const domain = require('domain'); -const net = require('net'); - -const server = net - .createServer(c => { - // Use a domain to propagate data across events within the - // connection so that we don't have to pass arguments - // everywhere. - const d = domain.create(); - d.data = { connection: c }; - d.add(c); - // Mock class that does some useless async data transformation - // for demonstration purposes. - const ds = new DataStream(dataTransformed); - c.on('data', chunk => ds.data(chunk)); - }) - .listen(8080, () => console.log('listening on 8080')); - -function dataTransformed(chunk) { - // FAIL! Because the DataStream instance also created a - // domain we have now lost the active domain we had - // hoped to use. - domain.active.data.connection.write(chunk); -} - -class DataStream { - constructor(cb) { - this.cb = cb; - // DataStream wants to use domains for data propagation too! - // Unfortunately this will conflict with any domain that - // already exists. - this.domain = domain.create(); - this.domain.data = { inst: this }; - } - - data(chunk) { - // This code is self contained, but pretend it's a complex - // operation that crosses at least one other module. So - // passing along "this", etc., is not easy. - this.domain.run(() => { - // Simulate an async operation that does the data transform. - setImmediate(() => { - for (let i = 0; i < chunk.length; i++) - chunk[i] = ((chunk[i] + Math.random() * 100) % 96) + 33; - // Grab the instance from the active domain and use that - // to call the user's callback. - const self = domain.active.data.inst; - self.cb(chunk); - }); - }); - } -} -``` - -以上表明,尝试使用一个以上的异步 API 借助域来传播数据是困难的。这个例子是固定假设通过在 `DataStream` 构造函数中赋值 `parent: domain.active`。然后通过 `domain.active = domain.active.data.parent` 在用户的回调函数被调用前恢复它。 `DataStream` 的实例化`'连接'`回调必须在 `d.run()` 中运行,而不是简单地使用 `d.add(c)`,否则将没有活动域。 - -简而言之,倘若要祈祷有机会运用这样的方式处理问题,需要严格遵守一组很难实施或测试的指导方针。 - -## 性能问题 - -使用域名的显著威慑是开销。使用节点内置的 http 基准,`http_simple.js`,没有域,它可以处理超 22000 个请求/秒。而如果它运行的是 `NODE_USE_DOMAINS=1`,则该数字下降到 17000个请求/秒以下。在这种情况下只有一个全局域。如果我们编辑基准,那么 http 请求回调会创建一个新的域实例,性能进一步下降到 15000 个请求/秒。 - -虽然这可能不会影响每秒只有几百甚至一千个请求的服务器,但开销的数量与异步请求的数量成正比。因此,如果单个连接需要连接到其它几个服务,所有这些都将对最终交付给客户机的等待时间产生影响。 - -使用 `AsyncWrap` 并跟踪次数 `init`/`pre`/`post`/`destroy` 在以上基准中所提及,我们发现所有事件的总和超过每秒 170000 次。这意味着即使为每种类型的设置增加 1 微秒的开销,任何类型的安装或拆除都会导致 17% 的性能损失。当然,这是针对基准的优化方案,但我相信这证明了一种机制,如域尽可能简单方便地运行的必要性。 - -## 展望未来 - -自从 2014 年 12 月以来,域模块已经被软弃用,但由于节点目前暂时没有替代功能,所以还没有彻底被移除。在撰写本文时,`AsyncWrap` 的 API 的工作正在进行,以及为 TC39 准备的区域的建议。在这种时候,如有合适的功能来替换域,它将经历完整的弃用周期而最终从核心移除。 diff --git a/pages/zh-cn/docs/guides/dont-block-the-event-loop.md b/pages/zh-cn/docs/guides/dont-block-the-event-loop.md deleted file mode 100644 index d66350247dd30..0000000000000 --- a/pages/zh-cn/docs/guides/dont-block-the-event-loop.md +++ /dev/null @@ -1,414 +0,0 @@ ---- -title: 不要阻塞你的事件循环(或是工作线程池) -layout: docs.hbs ---- - -# 不要阻塞你的事件循环(或是工作线程池) - -## 你是否应该读这篇指南? - -如果你写出的代码并不是一行命令调用那么简单,那么阅读本篇指南可以帮助你写出高性能、更安全的程序。 - -此文档是从 Node.js 服务器开发的角度编写的,但这些概念也同样适用于复杂的 Node.js 应用程序。 文章中如有涉及到不同操作系统的细节,仅以 Linux 系统为代表。 - -## 概述 - -Node.js 通过事件循环机制(初始化和回调)的方式运行 JavaScript 代码,并且提供了一个线程池处理诸如文件 I/O 等高成本的任务。 Node 的伸缩性非常好,某些场景下它甚至比类似 Apache 等更重量级的解决方案表现更优异。 Node 可伸缩性的秘诀在于它仅使用了极少数的线程就可以处理大量客户端连接。 如果 Node.js 只需占用很少的线程,那么它就可以将更多的系统 CPU 时间和内存花费在客户端任务而不是线程的空间和时间消耗上(内存,上下文切换)。 但是同样由于 Node.js 只有少量线程,你必须非常小心的组织你的应用程序以便合理的使用它们。 - -这里有一个很好的经验法则,能使您的 Node.js 服务器变快: _在任何时候,当分配到每个客户端的任务是“少量”的情况下,Node.js 是非常快的。_ - -这条法则可以应用于事件轮询中的回调任务,以及在工作线程池上的任务。 - -## 为什么不要阻塞你的事件轮询(或是工作线程池)? - -Node.js 是用很少量的线程来处理大量客户端请求的。 在 Node.js 中,有两种类型的线程:一个事件循环线程(也被称为主循环,主线程,事件线程等)。另外一个是在工作线程池里的 `k` 个工作线程(也被称为线程池)。 - -如果一个线程执行一个回调函数(事件轮询线程)或者任务(工作线程)需要耗费很长时间,我们称之为“阻塞”。 当一个线程在处理某一个客户端请求时被阻塞了,它就无法处理其它客户端的请求了。 这里给出两个不能阻塞事件轮询线程和工作线程的理由: - -1. 性能:如果你在任意类型的线程上频繁处理繁重的任务,那么你的服务器的 _吞吐量_(请求/秒)将面临严峻考验。 -2. 安全性:如果对于特定的输入,你的某种类型的线程可能会被阻塞,那么恶意攻击者可以通过构造类似这样的“恶意输入”,故意让你的线程阻塞,然后使其它客户端请求得不到处理。这就是[拒绝服务攻击](https://en.wikipedia.org/wiki/Denial-of-service_attack)。 - -## 对 Node.js 的快速回顾 - -Node.js 使用事件驱动机制:它有一个事件轮询线程负责任务编排,和一个专门处理繁重任务的工作线程池。 - -### 哪种代码运行在事件轮询线程上? - -当 Node.js 程序运行时,程序首先完成初始化部分,即处理 `require` 加载的模块和注册事件回调。 然后,Node.js 应用程序进入事件循环阶段,通过执行对应回调函数来对客户端请求做出回应。 此回调将同步执行,并且可能在完成之后继续注册新的异步请求。 这些异步请求的回调也会在事件轮询线程中被处理。 - -事件循环中同样也包含很多非阻塞异步请求的回调,如网络 I/O。 - -总体来说,事件轮询线程执行事件的回调函数,并且负责对处理类似网络 I/O 的非阻塞异步请求。 - -### 哪种代码运行在工作线程池? - -Node.js 的工作线程池是通过 libuv([相关文档](http://docs.libuv.org/en/v1.x/threadpool.html))来实现的,它对外提供了一个通用的任务处理 API。 - -Node.js 使用工作线程池来处理“高成本”的任务。 这包括一些操作系统并没有提供非阻塞版本的 I/O 操作,以及一些 CPU 密集型的任务。 - -Node.js 模块中有如下这些 API 用到了工作线程池: - -1. I/O 密集型任务: - 1. [DNS](https://nodejs.org/api/dns.html):`dns.lookup()`,`dns.lookupService()`。 - 2. [文件系统](https://nodejs.org/api/fs.html#fs_threadpool_usage):所有的文件系统 API。除 `fs.FSWatcher()` 和那些显式同步调用的 API 之外,都使用 libuv 的线程池。 -2. CPU 密集型任务: - 1. [Crypto](https://nodejs.org/api/crypto.html):`crypto.pbkdf2()`、`crypto.scrypt()`、`crypto.randomBytes()`、`crypto.randomFill()`、`crypto.generateKeyPair()`。 - 2. [Zlib](https://nodejs.org/api/zlib.html#zlib_threadpool_usage):所有 Zlib 相关函数,除那些显式同步调用的 API 之外,都适用 libuv 的线程池。 - -在许多 Node.js 应用程序中,这些 API 是工作线程池任务的唯一来源。此外应用程序和模块可以使用 [C++ 插件](https://nodejs.org/api/addons.html) 向工作线程池提交其它任务。 - -为了完整性考虑,我们必须要说明,当你在事件轮询线程的一个回调中调用这些 API 时,事件轮询线程将不得不为此花费少量的额外开销,因为它必须要进入对应 API 与 C++ 桥接通讯的 Node.js C++ binding 中,从而向工作线程池提交一个任务。 和整个任务的成本相比,这些开销微不足道。这就是为什么事件循环线程总是将这些任务转交给工作线程池。 当向工作线程池中提交了某个任务,Node.js 会在 C++ binding 中为对应的 C++ 函数提供一个指针。 - -### Node 怎么决定下一步该运行哪些代码? - -抽象来说,事件轮询线程和工作池线程分别为等待中的事件回调和等待中的任务维护一个队列。 - -而事实上,事件轮询线程本身并不维护队列,它持有一堆要求操作系统使用诸如 [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html) (Linux),[kqueue](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/FSEvents_ProgGuide/KernelQueues/KernelQueues.html) (OSX),event ports (Solaris) 或者 [IOCP](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx) (Windows) 等机制去监听的文件描述符。 这些文件描述符可能代表一个网络套接字,一个监听的文件等等。 当操作系统确定某个文件的描述符发生变化,事件轮询线程将把它转换成合适的事件,然后触发与该事件对应的回调函数。 你可以通过[这里](https://www.youtube.com/watch?v=P9csgxBgaZ8)学习到更多有关这个过程的知识。 - -相对而言,工作线程池则使用一个真实的队列,里边装的都是要被处理的任务。 一个工作线程从这个队列中取出一个任务,开始处理它。当完成之后这个工作线程向事件循环线程中发出一个“至少有一个任务完成了”的消息。 - -### 对于应用设计而言,这意味着什么? - -在类似 Apache 这种“一个客户端连接一个线程”的系统中,每个处理中的客户端都被分配了一个独立的线程。 如果处理某个客户端的线程阻塞了,操作系统会中断它,并给予下一个客户端请求执行的机会。 操作系统必须确保一个只需要少量开销的客户端请求不会被其他需要大量开销的客户端请求影响。 - -因为 Node.js 用少量的线程处理许多客户端连接,如果在处理某个客户端的时候阻塞了,在该客户端请求的回调或任务完成之前,其他等待中的任务可能都不会得到执行机会。 _因此,保证每个客户端请求得到公平的执行机会变成了应用程序的责任。_ 这意味着,对于任意一个客户端,你不应该在一个回调或任务中做太多的事情。 - -这既是 Node.js 服务能够保持良好伸缩性的原因,同时也意味应用程序必须自己确保公平调度。 下一部分将探讨如何确保事件循环线程和工作线程池的公平调度。 - -## 不要阻塞你的事件轮询线程 - -事件轮询线程关注着每个新的客户端连接,协调产生一个回应。 所有这些进入的请求和输出的应答都要通过事件轮询线程。 这意味着如果你的事件轮询线程在某个地方花费太多的时间,所有当前和未来新的客户端请求都得不到处理机会了。 - -因此,你应该保证永远不要阻塞事件轮询线程。 换句话说,每个 JavaScript 回调应该快速完成。 这些当然对于 `await`,`Promise.then` 也同样适用。 - -一个能确保做到这一点的方法是分析关于你回调代码的 ["计算复杂度"](https://en.wikipedia.org/wiki/Time_complexity)。 如果你的回调函数在任意的参数输入下执行步骤数量都相同,那么你总能保证每个等待中的请求得到一个公平的执行机会。 如果回调根据其参数不同所需要的执行步骤数量也不同, 则应深入考虑参数复杂度增长的情况下请求的可能执行时间增长情况。 - -例子 1:固定执行时间的回调。 - -```javascript -app.get('/constant-time', (req, res) => { - res.sendStatus(200); -}); -``` - -例子 2:一个 `O(n)` 回调。该回调对于小的输入 `n` 执行很快,但是 `n` 如果很大,会执行得很慢。 - -```javascript -app.get('/countToN', (req, res) => { - let n = req.query.n; - - // n iterations before giving someone else a turn - for (let i = 0; i < n; i++) { - console.log(`Iter ${i}`); - } - - res.sendStatus(200); -}); -``` - -例子 3:一个 `O(n^2)` 函数回调。 该回调对于小的输入 `n` 同样执行很快, 但是 `n` 如果很大,会比之前 `O(n)` 那个例子慢得多。 - -```javascript -app.get('/countToN2', (req, res) => { - let n = req.query.n; - - // n^2 iterations before giving someone else a turn - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - console.log(`Iter ${i}.${j}`); - } - } - - res.sendStatus(200); -}); -``` - -### 你应当注意些什么呢? - -Node.js 使用谷歌的 V8 引擎处理 JavaScript,对于大部分操作确实很快。但有个例外是正则表达式以及 JSON 的处理,下面会讨论。 - -但是,对于复杂的任务你应当考虑限定输入范围,拒绝会导致太长执行时间的输入。 那样的话,即便你的输入相当长而且复杂,因为你限定了输入范围,你也可以确保回调函数的执行时间在你预估的最差情况范围之内。 然后你可以评估此回调函数的最糟糕执行时间,根据你的业务场景决定此运行时间是否可以接受。 - -### 阻塞事件轮询:REDOS - -一个灾难性地阻塞事件轮询的常见错误是使用“有漏洞”的[正则表达式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)。 - -#### 避免易受攻击的正则表达式 - -一个正则表达式是一定的规则去尝试匹配一个输入的字符串。 我们通常认为正则表达式的匹配需要扫描一次输入字符串—— `O(n)` 时间,其中 `n` 是输入字符串的长度。 在大部分情况下,一次扫描的确足够。 不幸的是,在某些情况下,正则表达式匹配扫描随着输入字符串呈指数增长——时间是 `O(2^n)`。 指数级的扫描时间消耗意味着如果引擎需要 `x` 时间来确定匹配;我们的输入仅仅只增加一个字符,它将需要 `2 * x` 的时间。 由于扫描的消耗与所需时间呈线性关系,因此,这种正则匹配将阻塞事件循环。 - -_易受攻击的正则表达式_ 是指执行时间随输入指数级增长的情况, 它使您的应用程序在“恶意输入”的情况下面临 [REDOS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) (正则表达式拒绝服务攻击)的风险。 一个正则表达式是否易受攻击的(例如,正则表达式引擎需要指数级的时间复杂度来执行),这实际上是一个很难回答的问题。并且根据您是用 Perl、Python、Ruby、Java、JavaScript 等不同的语言情况也有所不同,但这里有在一些在所有语言里都适用的一些经验法则: - -1. 避免嵌套量词,如 `(a+)*`。Node.js 的正则表达式引擎可能可以快速处理某些例子,但某些则可能是易受攻击的。 -2. 避免带有“或”的重叠情况,如 `(a|a)*`。同样,Node.js 只能保证某些场景下可以快速匹配。 -3. 避免使用回溯,如 `(a.*) \1`。没有正则表达式引擎可以保证在线性时间内执行这种匹配。 -4. 如果您只需要做简单的字符串匹配,请使用 `indexOf` 或其他等价 API。这些是更好的选择,它们永远不会超过 `O(n)` 的时间。 - -如果您不确定正则表达式是否易受攻击,请记住:即使对于一个易受攻击的正则表达式和长输入字符串,Node.js 通常也仍然可以确保结果正确匹配。 而指数爆炸的场景是出现在用户输入并不匹配正则特征,但是 Node.js 必须要尝试去执行非常多次的扫描才能最终得出结论。 - -#### 一个 REDOS 例子 - -下面是一个给服务器带来 REDOS 风险的示例示例: - -```javascript -app.get('/redos-me', (req, res) => { - let filePath = req.query.filePath; - - // REDOS - if (filePath.match(/(\/.+)+$/)) { - console.log('valid path'); - } else { - console.log('invalid path'); - } - - res.sendStatus(200); -}); -``` - -这个有漏洞的正则例子是一个(糟糕的!)检查 Linux 上合法路径的例子。 它匹配的字符串是以 "/" 分隔的名称序列,如 "/a/b/c"。 这是非常危险的,因为它违反了规则 1:它有一个双重嵌套的量词。 - -假设客户端查询的是路径 `///.../\n` (100个“/”后跟一个正则表达式的“.”不匹配的换行符),则事件循环线程将持续执行且无法停止,从而阻止事件循环。 这类客户端发起的 REDOS 攻击会导致所有其它客户端在此正则表达式匹配完成之前得不到任何执行机会。 - -因此,您应该警惕使用复杂的正则表达式来验证用户输入的场景。 - -#### 关于如何抵制 REDOS 的资源 - -这里提供了你一些工具帮助你检查你的正则表达式是否安全,像: - -- [安全正则表达式](https://github.com/davisjam/safe-regex) -- [rxxr2](https://github.com/superhuman/rxxr2) - -但是上述模块都无法保证能够捕获全部的正则表达式漏洞。 - -另一个方案是使用一个不同的正则表达式引擎。 你可以使用 [node-re2](https://github.com/uhop/node-re2) 模块,它使用谷歌的超快正则表达式引擎 [RE2](https://github.com/google/re2)。 但注意,RE2 对 Node.js 正则表达式不是 100% 兼容,所以如果你想用 node-re2 模块来处理你的正则表达式的话,请检仔细查你的表达式。 这里尤其值得提醒的是,一些特殊的复杂正则表达式不被 node-re2 支持。 - -### 阻塞事件轮询:Node.js 的核心模块 - -一些Node.js核心模块有同步昂贵的API,其中包括: - -- [加密](https://nodejs.org/api/crypto.html) -- [压缩](https://nodejs.org/api/zlib.html) -- [文件系统](https://nodejs.org/api/fs.html) -- [子进程](https://nodejs.org/api/child_process.html) - -这些 API 是高开销的,因为它们包括了非常巨大的计算(如加密、压缩上),需要 I/O(如文件 I/O),或者两者都有潜在包含(如子进程处理)。这些 API 是为脚本提供方便,并非让你在服务器上下文中使用。如果你在事件循环中使用它们,则需要花费比一般的 JavaScript 更长的执行时间从而可能导致阻塞事件轮询。 - -对于一个服务器而言,_你不应当使用以下同步的 API 函数_: - -- 加密: - - `crypto.randomBytes`(同步版本) - - `crypto.randomFillSync` - - `crypto.pbkdf2Sync` - - 同时你应当非常小心对加密和解密给予大数据输入的情况。 -- 压缩: - - `zlib.inflateSync` - - `zlib.deflateSync` -- 文件系统: - - 不能使用同步文件系统方法 API 函数。举个例子,如果你的程序运行于一个[分布式文件系统](https://en.wikipedia.org/wiki/Clustered_file_system#Distributed_file_systems),像 [NFS](https://en.wikipedia.org/wiki/Network_File_System),则访问时间会发生很大变化。 -- 子进程: - - `child_process.spawnSync` - - `child_process.execSync` - - `child_process.execFileSync` - -此列表对于 Node.js 9 都是有效的。 - -### 阻塞事件循环:JSON DOS - -`JSON.parse` 以及 `JSON.stringify` 是其它潜在高开销的操作。 这些操作的复杂度是 `O(n)` ,对于大型的 `n` 输入,消耗的时间可能惊人的长。 - -如果您的服务器操纵JSON对象,特别是来自客户端的对象, 您应该谨慎对待您在事件循环上工作的对象或字符串的大小。 - -关于 JSON 阻止事件循环的示例:我们创建一个大小为 2^21 的 JSON 的对象,然后用 `JSON.stringify` 序列化它;在此字符串上运行 `indexOf` 函数,然后使用 JSON.parse 解析它。 `JSON.stringify` 字符串为 50MB。字符串化对象耗时 0.7 秒,对这个 50MB 的字符串使用 indexOf 函数耗时 0.03 秒,用了 1.3 秒解析字符串。 - -```javascript -var obj = { a: 1 }; -var niter = 20; - -var before, str, pos, res, took; - -for (var i = 0; i < niter; i++) { - obj = { obj1: obj, obj2: obj }; // Doubles in size each iter -} - -before = process.hrtime(); -str = JSON.stringify(obj); -took = process.hrtime(before); -console.log('JSON.stringify took ' + took); - -before = process.hrtime(); -pos = str.indexOf('nomatch'); -took = process.hrtime(before); -console.log('Pure indexof took ' + took); - -before = process.hrtime(); -res = JSON.parse(str); -took = process.hrtime(before); -console.log('JSON.parse took ' + took); -``` - -有 npm 模块提供异步JSON API。例如: - -- [JSONStream](https://www.npmjs.com/package/JSONStream),有流式操作的 API。 -- [Big-Friendly JSON](https://www.npmjs.com/package/bfj),有流式 API 和使用下文所概述的任务拆分思想的异步 JSON 标准 API。 - -### 不要让复杂的计算阻塞事件循环 - -有一些 npm 的模块提供了异步的 JSON API 函数,参考: - -#### 任务拆分 - -你可以把你的复杂计算 _拆分开_,然后让每个计算分别运行在事件循环中,不过你要定期地让其它一些等待的事件执行就会。 在 JavaScript 中,用闭包很容易实现保存执行的上下文,请看如下的 2 个例子。 - -举个例子,假设你想计算 `1` 到 `n` 的平均值。 - -例子1:不分区算平均数,开销是 `O(n)` - -```javascript -for (let i = 0; i < n; i++) sum += i; -let avg = sum / n; -console.log('avg: ' + avg); -``` - -例子2:分区算平均值,每个 `n` 的异步步骤开销为 `O(1)`。 - -```javascript -function asyncAvg(n, avgCB) { - // Save ongoing sum in JS closure. - var sum = 0; - function help(i, cb) { - sum += i; - if (i == n) { - cb(sum); - return; - } - - // "Asynchronous recursion". - // Schedule next operation asynchronously. - setImmediate(help.bind(null, i + 1, cb)); - } - - // Start the helper, with CB to call avgCB. - help(1, function (sum) { - var avg = sum / n; - avgCB(avg); - }); -} - -asyncAvg(n, function (avg) { - console.log('avg of 1-n: ' + avg); -}); -``` - -这个原则也可以应用到数组迭代和其它类似场景。 - -#### 任务分流 - -如果你需要做更复杂的任务,拆分可能也不是一个好选项。这是因为拆分之后任务仍然在事件循环线程中执行,并且你无法利用机器的多核硬件能力。_ 请记住,事件循环线程只负责协调客户端的请求,而不是独自执行完所有任务。 对一个复杂的任务,最好把它从事件循环线程转移到工作线程池上_。 - -##### 如何进行任务分流? - -你有两种方式将任务转移到工作线程池执行: - -1. 你可以通过开发 [C++ 插件](https://nodejs.org/api/addons.html) 的方式使用内置的 Node.js 工作池。稍早之前的 Node.js 版本,通过使用 [NAN](https://github.com/nodejs/nan) 的方式编译你的 C++ 插件,在新版的 Node.js 上使用 [N-API](https://nodejs.org/api/n-api.html)。 [node-webworker-threads](https://www.npmjs.com/package/webworker-threads) 提供了一个仅用 JavaScript 就可以访问 Node.js 的工作池的方式。 -2. 您可以创建和管理自己专用于计算的工作线程池,而不是使用 Node.js 自带的负责的 I/O 的工作线程池。最直接的方法就是使用 [Child Process](https://nodejs.org/api/child_process.html) 或者是 [cluster](https://nodejs.org/api/cluster.html)。 - -你 *不应该*直接为每个请求都创建一个[子进程](https://nodejs.org/api/child_process.html)。 因为客户端请求的频率可能远远高于你的服务器能创建和管理子进程的频率,这种情况你的服务器就变成了一个[Fork 炸弹](https://en.wikipedia.org/wiki/Fork_bomb)。 - -##### 转移到工作线程池的缺陷 - -这种方法的缺点是它增大了 _通信开销_ 。 因为 Node. js 仅允许事件循环线程去查访问应用程序的“命名空间”(保存着 JavaScript 状态)。 在工作线程中是无法操作事件循环线程的命名空间中的 JavaScript 对象的。 因此,您必须序列化和反序列化任何要在线程间共享的对象。 然后,工作线程可以对属于自己的这些对象的副本进行操作,并将修改后的对象(或“补丁”) 返回到事件循环线程。 - -有关序列化问题,请参阅 JSON 文档部分。 - -##### 一些关于分流的建议 - -您可能希望区分 CPU 密集型和 I/O 密集型任务,因为它们具有明显不同的特性。 - -CPU 密集型任务只有在该 Worker 线程被调度到时候才得到执行机会,并且必须将该任务分配到机器的某一个[逻辑核心](https://nodejs.org/api/os.html#os_os_cpus)中。如果你的机器有 4 个逻辑核心和 5 个工作线程,那这些工作线程中的某一个则无法得到执行。 因此,您实质上只是在为该工作线程白白支付开销(内存和调度开销),却无法得到任何返回。 - -I/O 密集型任务通常包括查询外部服务提供程序(DNS、文件系统等)并等待其响应。 当 I/O 密集型任务的工作线程正在等待其响应时,它没有其它工作可做,并且可以被操作系统重新调度,从而使另一个 Worker 有机会提交它的任务。 因此,_即使关联的线程并没有被保持,I/O 密集型任务也可以持续运行_。 像数据库和文件系统这样的外部服务提供程序已经经过高度优化,可以同时处理许多并发的请求。 例如,文件系统会检查一大组并发等待的写入和读取请求,以合并冲突更新并以最佳顺序读取文件(请参阅[这些幻灯片](http://researcher.ibm.com/researcher/files/il-AVISHAY/01-block_io-v1.3.pdf))。 - -如果只依赖一个工作线程池(例如 Node.js 工作池),则 CPU 密集和 I/O 密集的任务的不同特效性可能会损害应用程序的性能。 - -因此,您可能希望一个维护单独的计算工作线程池。 - -#### 分流:总结 - -对于简单的任务:比如遍历任意长数组的元素,拆分可能是一个很好的选择。 如果计算更加复杂,则分流是一种更好的方法:通信成本(即在事件循环线程和工作线程之间传递序列化对象的开销)被使用多个物理内核的好处抵消。 - -但是,如果你的服务器严重依赖复杂的计算,则应该重新考虑 Node.js 是否真的很适合该场景?Node.js 擅长于 I/O 密集型任务,但对于昂贵的计算,它可能不是最好的选择。 - -如果采用分流方法,请参阅“不阻塞工作线程池”一节。 - -## 不要阻塞你的工作线程池 - -Node.js有一个工人池,由 `k` 工人组成。 如果您正在使用上文讨论的卸载模式,您可能会有一个单独的计算工人池,适用同样的原则。 在任何情况下, 让我们假定 `k` 比您同时处理的客户数目要小得多。 这符合Node.js的“许多客户端的一个线程”哲学,这是其可扩展性的秘密。 - -正如在上文中讨论的,每个工作线程必须完成其当前任务,才能继续执行工作线程池队列中的下一项。 - -那么,处理客户请求所需的任务成本将会在不同的客户端输入场景下发生很大变化。 有些任务可以快速完成(例如读取小文件或缓存文档,或者生成少量的随机字节),而另一些则需要更长的时间(例如读取较大或未缓存的文件,或生成更多的随机字节)。 您的目标应该是使用 *任务拆分*来*尽量缩小不同请求任务执行时间的动态变化*, - -### 最小化任务时间的变化 - -如果工作线程的当前任务比其它任务开销大很多,则他无法处理其它等待中任务。 换言之,每个相对长的任务会直接减少了工作线程池的可用线程数量,直到它的任务完成。 这是不可取的。因为从某种程度上说,工作池中的工作线程越多,工作池吞吐量(任务/秒)就越大,因此服务器吞吐量(客户端请求/秒)就越大。 一个具有相对昂贵开销任务的客户端请求将减少工作线程池整体的吞吐量,从而降低服务器的吞吐量。 - -为避免这种情况,应尽量减少提交给工作池的不同任务在执行时间上的变化。 虽然将 I/O 请求(DB、FS 等)访问的外部系统视为黑盒在某种角度是适当的;但您应该知道这些 I/O 请求的相对成本,并应避免提交您预估可能特别耗时的任务。 - -下面的两个示例应该能说明任务时间可能发生的变化: - -#### 动态执行时间示例: 长时间运行的文件系统读取 - -假设您的服务器必须读取文件来处理某些客户端请求。 在了解 Node.js 的[文件系统](https://nodejs.org/api/fs.html)的 API 之后,您选择使用 `fs.readFile()` 进行简单操作。 但是,`fs.readFile()` 是([当前](https://github.com/nodejs/node/pull/17054))未拆分任务的:它提交一个 `fs.read()` 任务来读取整个文件。 如果您为某些用户读取较短的文件,并为其它人读取较长的文件,`fs.readFile()` 可能会在任务长度上引入显著的变化,从而损害工作线程池吞吐量。 - -对于最坏的情况,假设攻击者可以促使您的服务器读取 _任意_ 文件(这是一个[目录遍历漏洞](https://www.owasp.org/index.php/Path_Traversal))。 如果您的服务器运行的是 Linux,攻击者可以命名一个非常慢的文件:[`/dev/random`](http://man7.org/linux/man-pages/man4/random.4.html)。 对于所有实际的目的,`/dev/random` 是无限缓慢的;每个工作线程都被要求读取 `/dev/random`,这样下去将永远不会完成这项任务。 然后,攻击者提交 `k` 个请求,每一个被分配给一个工作线程,则其它需要使用工作线程的客户端请求将得不到执行机会。 - -#### 动态执行时间示例: 长时间运行的加密操作 - -假设您的服务器使用 [`crypto.randomBytes()`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) 来生成密码学上安全的随机字节。`crypto.randomBytes()` 是不拆分任务的:它创建单个 `randomBytes()` 任务,以生成您请求的字节数。 如果为某些用户创建的字节数较少,并且其它请求创建字节数较多;则 `crypto.randomBytes()` 是任务长度变化的另一个来源。 - -### 任务拆分 - -具有可变时间成本的任务可能会损害工作池的吞吐量。 为了尽量减少任务时间的变化,应尽可能将每个任务 _划分_ 为开销接近一致的子任务。 当每个子任务完成时,它应该提交下一个子任务;并且当最终的子任务完成时,它应该通知提交者。 - -继续使用 `fs.readFile()` 的示例,更好的方案是使用 `fs.read()`(手动拆分)或 `ReadStream`(自动拆分)。 - -同样的原理也适用于 CPU 密集型任务; `asyncAvg` 示例可能不适用于事件循环,但它非常适用于工作线程池。 - -将任务拆分为子任务时,较短的任务将拆分为少量的子任务,而更长的任务将拆分为更多的子任务。 在较长任务的每个子任务之间,分配给它的工作线程可以调度执行另一个更短的任务拆分出来的子任务,从而提高工作池的总体任务吞吐量。 - -请注意:完成的子任务数对于工作线程池的吞吐量不是一个有用的度量指标。相反,请关注完成的 _任务_ 数。 - -### 避免任务拆分 - -我们需要明确任务拆分的目的是尽量减少任务执行时间的动态变化。 但是如果你可以人工区分较短的任务和较长的任务(例如,对数组求和或排序),则可以手动为每个类型的任务创建一个工作池。 将较短的任务和更长的任务分别路由到各自的工作线程池,也是减少任务时间动态变化的另一种方法。 - -建议这种方案的原因是,做任务拆分会导致额外的开销(创建工作线程,表示和操作线程池任务队列),而避免拆分会为您节省这些外成本,同时也会避免你在拆分任务的时候犯错误。 - -这种方案的缺点是:所有这些工作池中的工作线程都将消耗空间和时间开销,并将相互竞争 CPU 时间片。 请记住:每个 CPU 密集任务只在它被调度到的时候才会得到执行。 因此,您应该再仔细分析后才考虑此方案。 - -### 工作线程池:总结 - -无论您只使用 Node.js 工作线程池还是维护单独的工作线程池,都应着力优化线程池的任务吞吐量。 - -为此,请使用任务拆分最小化任务执行时间的动态变化范围。 - -## 使用 npm 模块的风险 - -虽然 Node.js 核心模块为各种需求提供了基础支持,但有时还需要更多的功能。Node.js 的开发人员从 [npm 生态系统](https://www.npmjs.com/) 中获益良多,有成百上千个模块可以为你的应用开发提效。 - -但是,请记住,这些模块中的大多数是由第三方开发人员编写的;它们通常只能保证尽力做到很好。使用 npm 模块的开发人员应该关注如下两件事,尽管后者经常被遗忘。 - -1. 它是否拥有优秀的 API 设计? -2. 它的 API 可能会阻塞事件循环线程或工作线程吗? 许多模块都没有计算考虑他们的成本,这对社区非常不利。 - -对于简单的 API,您可以估计 API 的成本;如字符串操作的成本并不难预估。 但在许多情况下却很难预估 API 可能的开销。 - -_如果您正在调用 API 做一些复杂繁琐的事情,请仔细检查开销。 让相关的开发者记录下来,或检查你自己的源代码(并提交一个PR,记录此成本)。_ - -请记住:即使 API 是异步的,您也可能无法预估它的每个拆分的子任务需要在工作线程或事件循环线程上花费多少时间。 例如,假设在上面给出的 `asyncAvg` 示例中,每个对 helper 函数的调用都累加一半的数字而不只是其中的一个。 那么这个函数仍然是异步的,但每个子任务的成本将是 `O(n)` 而不是 `O(1)`, 就使得对于任意的输入 `n` 不再那么安全。 - -## 总结 - -Node.js有两种线程:一个事件循环和 `k` 工作者。 事件循环负责JavaScript 回调和非屏蔽I/O, 和一个工人执行对 C++ 代码的任务,完成异步请求,包括阻止I/O 和 CPU密集工作。 两种类型的线程每次只能在一个活动上工作。 如果任何回调或任务需要很长时间,运行的线程会被屏蔽 \*\* 如果您的应用程序阻止回调或任务,这最多可能导致通过量化(客户/秒),最坏情况下完全拒绝服务。 - -要写入一个高吞吐量,更多地预防 DoS 服务攻击的服务,您必须确保在良性和恶意输入中, 你的事件循环和你的 Worker 始终不会屏蔽。 diff --git a/pages/zh-cn/docs/guides/event-loop-timers-and-nexttick.md b/pages/zh-cn/docs/guides/event-loop-timers-and-nexttick.md deleted file mode 100644 index bb4de42612f21..0000000000000 --- a/pages/zh-cn/docs/guides/event-loop-timers-and-nexttick.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: Node.js 事件循环,定时器和 process.nextTick() -layout: docs.hbs ---- - -# Node.js 事件循环,定时器和 `process.nextTick()` - -## 什么是事件循环? - -事件循环是 Node.js 处理非阻塞 I/O 操作的机制——尽管 JavaScript 是单线程处理的——当有可能的时候,它们会把操作转移到系统内核中去。 - -因为目前大多数内核都是多线程的,所以它们可以在后台处理多种操作。当其中的一个操作完成的时候,内核通知 Node.js 将适合的回调函数添加到 _轮询_ 队列中等待时机执行。我们在本文后面会进行详细介绍。 - -## 事件循环机制解析 - -当 Node.js 启动后,它会初始化事件循环,处理已提供的输入脚本(或丢入 [REPL][],本文不涉及到),它可能会调用一些异步的 API、调度定时器,或者调用 `process.nextTick()`,然后开始处理事件循环。 - -下面的图表展示了事件循环操作顺序的简化概览。 - -``` - ┌───────────────────────────┐ -┌─>│ timers │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ pending callbacks │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -│ │ idle, prepare │ -│ └─────────────┬─────────────┘ ┌───────────────┐ -│ ┌─────────────┴─────────────┐ │ incoming: │ -│ │ poll │<─────┤ connections, │ -│ └─────────────┬─────────────┘ │ data, etc. │ -│ ┌─────────────┴─────────────┐ └───────────────┘ -│ │ check │ -│ └─────────────┬─────────────┘ -│ ┌─────────────┴─────────────┐ -└──┤ close callbacks │ - └───────────────────────────┘ -``` - -> 注意:每个框被称为事件循环机制的一个阶段。 - -每个阶段都有一个 FIFO 队列来执行回调。虽然每个阶段都是特殊的,但通常情况下,当事件循环进入给定的阶段时,它将执行特定于该阶段的任何操作,然后执行该阶段队列中的回调,直到队列用尽或最大回调数已执行。当该队列已用尽或达到回调限制,事件循环将移动到下一阶段,等等。 - -由于这些操作中的任何一个都可能调度 _更多的_ 操作和由内核排列在**轮询**阶段被处理的新事件, 且在处理轮询中的事件时,轮询事件可以排队。因此,长时间运行的回调可以允许轮询阶段运行长于计时器的阈值时间。有关详细信息,请参阅 [**计时器**](#timers) 和 [**轮询**](#poll) 部分。 - -> 注意: 在 Windows 和 Unix/Linux 实现之间存在细微的差异,但这对演示来说并不重要。最重要的部分在这里。实际上有七或八个步骤,但我们关心的是 Node.js 实际上使用以上的某些步骤。 - -## 阶段概述 - -- **timers**: 此阶段执行由 `setTimeout()` 和 `setInterval()` 排序。 -- **pending callbacks**: 执行 I/O 回调推迟到下一个循环 迭代。 -- **idle, prepare**: 仅在内部使用。 -- **poll**: 检索新的 I/O 事件; 执行与 I/O 相关的几乎任何回调(由“计时器”或 “`setImmediate()`”所设的紧邻回调除外); node 将在适当时机在此处暂停。 -- **check**: `setImmediate()` 回调在此处被调用。 -- **close callbacks**:一些关闭的回调函数,如:`socket.on('close', ...)`。 - -由于这些操作中的任何一个都可能调度 _更多的_ 操作并且在 **轮询(poll)** 阶段被处理的新事件会被内核排列, 并且在处理轮询中的事件时,轮询事件可以排队。因此,长时间运行的回调可以允许轮询阶段运行长于计时器的 **阈值(threshold)**。有关详细信息,请参阅 [**计时器**](#timers) 和 [**轮询**](#poll) 部分。 - -## 阶段的详细概述 - -### 定时器 - -计时器指定 **阈值** _之后_ 一个提供的回调 _可以执行_ 而不是 **准确** 一个人 *想执行 的时间*计时器调用将尽早运行,因为它们可以在指定时间过后 排定; 然而,操作系统计划或运行其他回调可能会延迟。 - -> 从技术上讲, [**轮询** 阶段](#poll) 控制执行计时器的时间。 - -在每次运行的事件循环之间,Node.js 检查它是否在等待任何异步 I/O 或计时器,如果没有的话,则完全关闭。 - -```js -const fs = require('fs'); - -function someAsyncOperation(callback) { - // Assume this takes 95ms to complete - fs.readFile('/path/to/file', callback); -} - -const timeoutScheduled = Date.now(); - -setTimeout(() => { - const delay = Date.now() - timeoutScheduled; - - console.log(`${delay}ms have passed since I was scheduled`); -}, 100); - -// do someAsyncOperation which takes 95 ms to complete -someAsyncOperation(() => { - const startCallback = Date.now(); - - // do something that will take 10ms... - while (Date.now() - startCallback < 10) { - // do nothing - } -}); -``` - -计时器可以 _在回调后面_ 指定 **阈值**,而不是用户希望回调执行的确切时间。因为在经过指定的一段时间间隔后, 计时器回调将被尽可能早地运行。但是,操作系统调度或其它正在运行的回调可能会延迟它们。 - -> 注意:为了防止 **轮询** 阶段挤占事件循环的执行,[libuv][](实现 Node.js 事件循环和平台上所有异步行为的 C 函数库)还设有一个最大硬性限制(取决于系统),以避免继续轮询更多事件。 - -### 挂起的回调函数 - -此阶段对某些系统操作(如 TCP 错误类型)执行回调。例如,如果 TCP 套接字在尝试连接时接收到 `ECONNREFUSED`,则某些 \*nix 的系统希望等待报告错误。这将被排队以在 **挂起的回调** 阶段执行。 - -### 轮询 - -例如,您调度了一个在 100 毫秒后执行回调的定时器,并且您的脚本开始异步读取文件,这会耗费 95 毫秒: - -1. 计算应该阻塞和轮询 I/O 的时间。 -2. 然后处理 **轮询** 队列里的事件。 - -当事件循环进入 **轮询(poll)** 阶段时,它有一个空队列(此时 `fs.readFile()` 尚未完成),因此它将等待剩下的毫秒数,直到达到最快的一个计时器阈值为止。当它等待 95 毫秒过后,`fs.readFile()` 完成读取文件,它的那个需要 10 毫秒才能完成的回调将被添加到 **轮询** 队列中并执行。当回调完成时,队列中不再有回调,此时事件循环机制将发现计时器最快的阈值(100ms)的已经达到,然后将回到 **计时器** 阶段,以执行定时器的回调。在本示例中,您将看到调度计时器到它的回调被执行之间的总延迟将为 105 毫秒。 - -- _如果 **轮询** 队列 **不是空的**_ ,事件循环将循环访问回调队列并同步执行它们,直到队列已用尽,或者达到了与系统相关的硬性限制。 - -- _如果 **轮询** 队列 **是空的**_ ,还有两件事发生: - - - 如果脚本被 `setImmediate()` 调度,则事件循环将结束 **轮询** 阶段,并继续 **检查** 阶段以执行那些被调度的脚本。 - - - 如果脚本 **未被** `setImmediate()`调度,则事件循环将等待回调被添加到队列中,然后立即执行。 - -注意:为了防止 **轮询** 阶段事件循环陷入吃不饱的状态,[libuv][](实现 Node.js 事件循环和平台的所有异步行为的 C 函数库)在停止轮询以获得更多事件之前,还有一个硬性的最大值(依赖于系统)。 - -### 检查阶段 - -此阶段对某些系统操作(如 TCP 错误类型)执行回调。例如,如果 TCP 套接字在尝试连接时接收到 `ECONNREFUSED`,则某些 \*nix 的系统希望等待报告错误。这将被排队以在 **挂起的回调** 阶段执行。 - -**轮询** 阶段有两个重要的功能: - -当事件循环进入 **轮询** 阶段且 _没有被调度的计时器时_ ,将发生以下两种情况之一: - -### 关闭的回调函数 - -一旦 **轮询** 队列为空,事件循环将检查 _已达到时间阈值的计时器_。如果一个或多个计时器已准备就绪,则事件循环将绕回计时器阶段以执行这些计时器的回调。 - -## `setImmediate()` 对比 `setTimeout()` - -此阶段允许人员在 **轮询** 阶段完成后立即执行回调。如果轮询阶段变为空闲状态,并且脚本使用 `setImmediate()` 后被排列在队列中,则事件循环可能继续到 **检查** 阶段而不是等待。 - -- ` setImmediate()` 是为了在 当前 **所有检测** 阶段完成后执行脚本。 -- `setTimeout()` 安排一个脚本,在已过期的最小阈值后运行。 - -`setImmediate()` 实际上是一个在事件循环的单独阶段运行的特殊计时器。它使用一个 libuv API 来安排回调在 **轮询** 阶段完成后执行。 - -通常,在执行代码时,事件循环最终会进入轮询阶段,在该阶段它将等待传入连接、请求等。但是,如果回调已使用 `setImmediate()`调度过,并且轮询阶段变为空闲状态,则它将结束此阶段,并继续到检查阶段而不是继续等待轮询事件。 - -```js -// timeout_vs_immediate.js -setTimeout(() => { - console.log('timeout'); -}, 0); - -setImmediate(() => { - console.log('immediate'); -}); -``` - -``` -$ node timeout_vs_immediate.js -timeout -immediate - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -如果套接字或处理函数突然关闭(例如 `socket.destroy()`),则`'close'` 事件将在这个阶段发出。否则它将通过 `process.nextTick()` 发出。 - -```js -// timeout_vs_immediate.js -const fs = require('fs'); - -fs.readFile(__filename, () => { - setTimeout(() => { - console.log('timeout'); - }, 0); - setImmediate(() => { - console.log('immediate'); - }); -}); -``` - -``` -$ node timeout_vs_immediate.js -immediate -timeout - -$ node timeout_vs_immediate.js -immediate -timeout -``` - -`setImmediate()` 和 `setTimeout()` 很类似,但是基于被调用的时机,他们也有不同表现。 - -## `process.nextTick()` - -### 理解 `process.nextTick()` - -您可能已经注意到`process.nextTick()` 在图示中没有显示,即使它是异步 API 的一部分。这是因为 `process.nextTick()`从技术上讲不是事件循环的一部分。相反,它都将在当前操作完成后处理`nextTickQueue`, 而不管事件循环的当前阶段如何。这里所谓的*操作*被定义为来自底层 C/C++ 处理器的转换,和需要处理的 JavaScript 代码的执行。 - -回顾我们的图示,任何时候在给定的阶段中调用 `process.nextTick()`,所有传递到 `process.nextTick()` 的回调将在事件循环继续之前解析。这可能会造成一些糟糕的情况,因为**它允许您通过递归 `process.nextTick()`调用来“饿死”您的 I/O**,阻止事件循环到达 **轮询** 阶段。 - -### 为什么会允许这样? - -为什么这样的事情会包含在 Node.js 中?一部分因为它是一个设计理念,即尽管不是必需的情况下, API 应该始终是异步的。以此代码段为例: - -```js -function apiCall(arg, callback) { - if (typeof arg !== 'string') - return process.nextTick( - callback, - new TypeError('argument should be string') - ); -} -``` - -代码段进行参数检查。如果不正确,则会将错误传递给回调函数。最近对 API 进行了更新,允许传递参数给 `process.nextTick()`,这将允许它接受任何在回调函数位置之后的参数,并将参数传递给回调函数作为回调函数的参数,这样您就不必嵌套函数了。 - -我们正在做的是将错误传回给用户,但仅在执行用户的其余代码之后。通过使用`process.nextTick()`,我们保证 `apiCall()` 始终在用户代码的其余部分*之后*和在让事件循环继续进行*之前*,执行其回调函数。为了实现这一点,JS 调用栈被允许展开,然后立即执行提供的回调,允许进行递归调用 `process.nextTick()`,而不触碰 `RangeError: 超过 V8 的最大调用堆栈大小` 限制。 - -这种设计原理可能会导致一些潜在的问题。 以此代码段为例: - -```js -let bar; - -// this has an asynchronous signature, but calls callback synchronously -function someAsyncApiCall(callback) { - callback(); -} - -// the callback is called before `someAsyncApiCall` completes. -someAsyncApiCall(() => { - // since someAsyncApiCall has completed, bar hasn't been assigned any value - console.log('bar', bar); // undefined -}); - -bar = 1; -``` - -用户将 `someAsyncApiCall()` 定义为具有异步签名,但实际上它是同步运行的。当调用它时,提供给 `someAsyncApiCall()` 的回调是在事件循环的同一阶段内被调用,因为 `someAsyncApiCall()` 实际上并没有异步执行任何事情。结果,回调函数在尝试引用 `bar`,但作用域中可能还没有该变量,因为脚本尚未运行完成。 - -通过将回调置于 `process.nextTick()` 中,脚本仍具有运行完成的能力,允许在调用回调之前初始化所有的变量、函数等。它还具有不让事件循环继续的优点,适用于让事件循环继续之前,警告用户发生错误的情况。下面是上一个使用 `process.nextTick()` 的示例: - -```js -let bar; - -function someAsyncApiCall(callback) { - process.nextTick(callback); -} - -someAsyncApiCall(() => { - console.log('bar', bar); // 1 -}); - -bar = 1; -``` - -这又是另外一个真实的例子: - -```js -const server = net.createServer(() => {}).listen(8080); - -server.on('listening', () => {}); -``` - -这种设计原理可能会导致一些潜在的问题。 以此代码段为例: - -为了绕过这个问题,`'listening'` 事件被排在 `nextTick()` 中,以允许脚本运行完成。这让用户设置所想设置的任何事件处理器。 - -## `process.nextTick()` 对比 `setImmediate()` - -就用户而言,我们有两个类似的调用,但它们的名称令人费解。 - -- `process.nextTick()` 在同一个阶段立即执行。 -- `setImmediate()` 在事件循环的接下来的迭代或 'tick' 上触发。 - -实质上,这两个名称应该交换,因为 `process.nextTick()` 比 `setImmediate()` 触发得更快,但这是过去遗留问题,因此不太可能改变。如果贸然进行名称交换,将破坏 npm 上的大部分软件包。每天都有更多新的模块在增加,这意味着我们要多等待每一天,则更多潜在破坏会发生。尽管这些名称使人感到困惑,但它们本身名字不会改变。 - -> 我们建议开发人员在所有情况下都使用 `setImmediate()`,因为它更容易理解。 - -## 为什么要使用 `process.nextTick()`? - -只有传递端口时,端口才会立即被绑定。因此,可以立即调用 `'listening'` 回调。问题是 `.on('listening')` 的回调在那个时间点尚未被设置。 - -1. 允许用户处理错误,清理任何不需要的资源,或者在事件循环继续之前重试请求。 - -2. 有时有让回调在栈展开后,但在事件循环继续之前运行的必要。 - -为了绕过这个问题,`'listening'` 事件被排在 `nextTick()` 中,以允许脚本运行完成。这让用户设置所想设置的任何事件处理器。 - -```js -const server = net.createServer(); -server.on('connection', conn => {}); - -server.listen(8080); -server.on('listening', () => {}); -``` - -假设 `listen()` 在事件循环开始时运行,但监听的回调被放置在 `setImmediate()` 中。除非传递过主机名,才会立即绑定到端口。为使事件循环继续进行,它必须命中 **轮询** 阶段,这意味着有可能已经接收了一个连接,并在侦听事件之前触发了连接事件。 - -另一个例子是扩展 `EventEmitter`, 并在构造器内释放一个事件: - -```js -const EventEmitter = require('events'); - -class MyEmitter extends EventEmitter { - constructor() { - super(); - this.emit('event'); - } -} - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('an event occurred!'); -}); -``` - -你不能立即从构造函数中触发事件,因为脚本尚未处理到用户为该事件分配回调函数的地方。因此,在构造函数本身中可以使用 `process.nextTick()` 来设置回调,以便在构造函数完成后发出该事件,这是预期的结果: - -```js -const EventEmitter = require('events'); - -class MyEmitter extends EventEmitter { - constructor() { - super(); - - // use nextTick to emit the event once a handler is assigned - process.nextTick(() => { - this.emit('event'); - }); - } -} - -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => { - console.log('an event occurred!'); -}); -``` - -[libuv]: https://libuv.org/ -[REPL]: https://nodejs.org/api/repl.html#repl_repl diff --git a/pages/zh-cn/docs/guides/getting-started-guide.md b/pages/zh-cn/docs/guides/getting-started-guide.md deleted file mode 100644 index 25b42b6e1a8c0..0000000000000 --- a/pages/zh-cn/docs/guides/getting-started-guide.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: 入门指南 -layout: docs.hbs ---- - -# 在安装了 Node.js 之后,我怎么开始呢? - -一旦你已经安装了 Node,让我们尝试构建第一个 Web 服务器。 请创建一个“app.js”文件,粘贴以下代码: - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -然后使用 `node app.js` 运行程序,访问 `http://localhost:3000`,你就会看到一个消息,写着“Hello World”。 - -请查阅 [Node.js 介绍](https://nodejs.dev/en/learn/),这是一个对于 Node.js 起步完整的指南。 diff --git a/pages/zh-cn/docs/guides/index.md b/pages/zh-cn/docs/guides/index.md deleted file mode 100644 index 764e20bd9a9eb..0000000000000 --- a/pages/zh-cn/docs/guides/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: 指南 -layout: docs.hbs ---- - -# 指南 - -## 常规 - -- [入门指南](/zh-cn/docs/guides/getting-started-guide/) -- [调试入门](/zh-cn/docs/guides/debugging-getting-started/) -- [Node.js 应用一窥](/zh-cn/docs/guides/simple-profiling/) -- [诊断 - 火焰图](/zh-cn/docs/guides/diagnostics-flamegraph/) -- [将 Node.js 网络应用安装到 Docker 中](/zh-cn/docs/guides/nodejs-docker-webapp/) -- [迁移到安全的 Buffer 构造函数中](/zh-cn/docs/guides/buffer-constructor-deprecation/) -- [诊断 —— 用户亲历](/zh-cn/docs/guides/diagnostics/) -- [处理安全性问题的最佳实践做法](/zh-cn/docs/guides/security/) - -## Node.js 核心概念 - -- [Node.js 的介绍](https://nodejs.dev/zh-cn/learn/) -- [阻塞对比非阻塞一览](/zh-cn/docs/guides/blocking-vs-non-blocking/) -- [Node.js 事件轮询,定时器和 `process.nextTick()`](/zh-cn/docs/guides/event-loop-timers-and-nexttick/) -- [不要阻塞你的事件轮询(或是工作池)](/zh-cn/docs/guides/dont-block-the-event-loop/) -- [Node.js 中的定时器](/zh-cn/docs/guides/timers-in-node/) - -## 与模块相关的指南 - -- [HTTP 传输解析](/zh-cn/docs/guides/anatomy-of-an-http-transaction/) -- [搭配不同的文件系统工作](/zh-cn/docs/guides/working-with-different-filesystems/) -- [流的背压](/zh-cn/docs/guides/backpressuring-in-streams/) -- [Postmortem 中的主要模块](/zh-cn/docs/guides/domain-postmortem/) -- [如何发布 N-API 包](/zh-cn/docs/guides/publishing-napi-modules/) -- [ABI 的稳定性](/zh-cn/docs/guides/abi-stability/) diff --git a/pages/zh-cn/docs/guides/nodejs-docker-webapp.md b/pages/zh-cn/docs/guides/nodejs-docker-webapp.md deleted file mode 100644 index a5f492ae46fab..0000000000000 --- a/pages/zh-cn/docs/guides/nodejs-docker-webapp.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -title: 把一个 Node.js web 应用程序给 Docker 化 -layout: docs.hbs ---- - -# 把一个 Node.js web 应用程序给 Docker 化 - -本示例的目标是给你演示如何将一个 Node.js 的应用装入到 Docker 容器中。本教程旨在针对于开发人员,而 _非_ 产品发布人员。此教程同样假定你有一个可以正常工作的 [Docker 安装](https://docs.docker.com/engine/installation/),并且对于 Node.js 的应用程序是如何组织的有一个大致的基本了解。 - -在本教程的第一部分我们在 Node.js 中创建一个 Web 的应用程序,然后我们为那个应用构建一个 Docker 镜像;最后我们将把那个镜像作为容器运行之。 - -Docker 允许你以应用程序所有的依赖全部打包成一个标准化的单元,这被称为一个容器。对于应用开发而言,一个容器就是一个蜕化到最基础的 Linux 操作系统。一个镜像是你加载到容器中的软件。 - -## 创建 Node.js 应用 - -首先,创建一个新文件夹以便于容纳需要的所有文件,并且在此其中创建一个 `package.json` 文件,描述你应用程序以及需要的依赖: - -```json -{ - "name": "docker_web_app", - "version": "1.0.0", - "description": "Node.js on Docker", - "author": "First Last ", - "main": "server.js", - "scripts": { - "start": "node server.js" - }, - "dependencies": { - "express": "^4.18.2" - } -} -``` - -配合着你的 `package.json` 请运行 `npm install`。如果你使用的 `npm` 是版本 5 或者之后的版本,这会自动生成一个 `package-lock.json` 文件,它将一起被拷贝进入你的 Docker 镜像中。 - -然后,创建一个 `server.js` 文件,使用 [Express.js](https://expressjs.com/) 框架定义一个 Web 应用: - -```javascript -'use strict'; - -const express = require('express'); - -// Constants -const PORT = 8080; -const HOST = '0.0.0.0'; - -// App -const app = express(); -app.get('/', (req, res) => { - res.send('Hello World'); -}); - -app.listen(PORT, HOST, () => { - console.log(`Running on http://${HOST}:${PORT}`); -}); -``` - -在稍后的步骤中我们将看一下借助使用官方的 Docker 镜像,你如何在 Docker 镜像中运行这个应用。首先,你需要一个构建一个应用程序的 Docker 应用。 - -## 创建一个名称为 `Dockerfile` 的文件 - -创建一个空文件,命名为 `Dockerfile`: - -```markup -touch Dockerfile -``` - -用你最喜欢的文本编辑器打开这个 `Dockerfile`。 - -我们要做的第一件事是定义我们需要从哪个镜像进行构建。这里我们将使用最新的 LTS(长期服务器支持版,比如 `Node 18`),你可以从 [Docker 站点](https://hub.docker.com/) 获取相关镜像: - -```docker -FROM node:18 -``` - -下一步在镜像中创建一个文件夹存放应用程序代码,这将是你的应用程序工作目录: - -```docker -# Create app directory -WORKDIR /usr/src/app -``` - -此镜像中 Node.js 和 NPM 都已经安装,所以下一件事对于我们而言是使用 `npm` 安装你的应用程序的所有依赖。请注意,如果你的 `npm` 的版本是 4 或者更早的版本,`package-lock.json` 文件将不会自动生成。 - -```docker -# Install app dependencies -# A wildcard is used to ensure both package.json AND package-lock.json are copied -# where available (npm@5+) -COPY package*.json ./ - -RUN npm install -# If you are building your code for production -# RUN npm ci --omit=dev -``` - -请注意,我们只是拷贝了 `package.json` 文件而非整个工作目录。这允许我们利用缓存 Docker 层的优势。bitJudo 对此有一个很好的解释,请[见此](http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/)。 进一步说,对于生产环境而言,注释中提及的 `npm ci` 命令协助提供了一个更快、可靠、可再生的构建环境。欲知详情,可以参考[此处](https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable)。 - -在 Docker 镜像中使用 `COPY` 命令绑定你的应用程序: - -```docker -# Bundle app source -COPY . . -``` - -你的应用程序绑定的端口为 `8080`,所以你可以使用 `EXPOSE` 命令使它与 `docker` 的镜像做映射: - -```docker -EXPOSE 8080 -``` - -最后但同样重要的事是,使用定义运行时的 `CMD` 定义命令来运行应用程序。这里我们使用 `node server.js` 来启动你的服务器: - -```docker -CMD [ "node", "server.js" ] -``` - -你的 `Dockerfile` 现在看上去是这个样子: - -```docker -FROM node:18 - -# Create app directory -WORKDIR /usr/src/app - -# Install app dependencies -# A wildcard is used to ensure both package.json AND package-lock.json are copied -# where available (npm@5+) -COPY package*.json ./ - -RUN npm install -# If you are building your code for production -# RUN npm ci --omit=dev - -# Bundle app source -COPY . . - -EXPOSE 8080 -CMD [ "node", "server.js" ] -``` - -## .dockerignore 文件 - -在 `Dockerfile` 的同一个文件夹中创建一个 `.dockerignore` 文件,带有以下内容: - -``` -node_modules -npm-debug.log -``` - -这将避免你的本地模块以及调试日志被拷贝进入到你的 Docker 镜像中,以至于把你镜像原有安装的模块给覆盖了。 - -## 构建你的镜像 - -进入到 `Dockerfile` 所在的那个目录中,运行以下命令构建 Docker 镜像。开关符 `-t` 让你标记你的镜像,以至于让你以后很容易地用 `docker images` 找到它。 - -```bash -docker build . -t /node-web-app -``` - -Docker 现在将给出你的镜像列表: - -```bash -$ docker images - -# Example -REPOSITORY TAG ID CREATED -node 18 78b037dbb659 2 weeks ago -/node-web-app latest d64d3505b0d2 1 minute ago -``` - -## 运行镜像 - -使用 `-d` 模式运行镜像将以分离模式运行 Docker 容器,使得容器在后台自助运行。开关符 `-p` 在容器中把一个公共端口导向到私有的端口,请用以下命令运行你之前构建的镜像: - -```bash -docker run -p 49160:8080 -d /node-web-app -``` - -把你应用程序的输出打印出来: - -```bash -# Get container ID -$ docker ps - -# Print app output -$ docker logs - -# Example -Running on http://localhost:8080 -``` - -如果你需要进入容器中,请运行 `exec` 命令: - -```bash -# Enter the container -$ docker exec -it /bin/bash -``` - -## 测试 - -为测试你的应用程序,给出与 Docker 映射过的端口号: - -```bash -$ docker ps - -# Example -ID IMAGE COMMAND ... PORTS -ecce33b30ebf /node-web-app:latest npm start ... 49160->8080 -``` - -在上面的例子中,在容器中 Docker 把端口号 `8080` 映射到你机器上的 `49160` 。 - -现在你可以使用 `curl`(如果需要的话请通过 `sudo apt-get install curl` 安装)调用你的程序了: - -```bash -$ curl -i localhost:49160 - -HTTP/1.1 200 OK -X-Powered-By: Express -Content-Type: text/html; charset=utf-8 -Content-Length: 12 -ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0" -Date: Mon, 13 Nov 2017 20:53:59 GMT -Connection: keep-alive - -Hello world -``` - -## 关闭镜像 - -我们可以通过使用 `kill` 命令来关闭我们已经开启的镜像。这里使用到了容器的 ID, 在本示例代码中是 `ecce33b30ebf`。 - -```bash -# Kill our running container -$ docker kill - -# Confirm that the app has stopped -$ curl -i localhost:49160 -curl: (7) Failed to connect to localhost port 49160: Connection refused -``` - -我们希望本教程能够帮助你起步,在 Docker 中运行一个简单的 Node.js 应用程序。 - -你也可以在以下一些地方寻觅到更多有关于 Docker 和基于 Docker 的 Node.js 相关内容: - -- [官方 Node.js 的 Docker 镜像](https://hub.docker.com/_/node/) -- [Node.js 基于 Docker 使用的最佳经验](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md) -- [官方 Docker 文档](https://docs.docker.com/get-started/nodejs/build-images/) -- [在 StackOverFlow 上有关 Docker 标记内容](https://stackoverflow.com/questions/tagged/docker) -- [Docker 版块](https://reddit.com/r/docker) diff --git a/pages/zh-cn/docs/guides/publishing-napi-modules.md b/pages/zh-cn/docs/guides/publishing-napi-modules.md deleted file mode 100644 index d24736db74213..0000000000000 --- a/pages/zh-cn/docs/guides/publishing-napi-modules.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: 如何发布 N-API 包 -layout: docs.hbs ---- - -# 发布混合了 N-API 和 non-N-API 包 - -以下步骤基于 `iotivity-node` 进行说明: - -- 首先,发布非 N-API 版本: - - 在 `package.json`中更新版本。关于 `iotivity-node`, 版本变成 `1.2.0-2` - - 通过发布清单(确保测试/演示/文档是正确的) - - `$ npm publish` -- 其次,发布 N-API 版本: - - 更新 `package.json` 版本。 在这种情况下,`iotivity-node` 的版本变成了 `1.2.0-3`。 版本审查, 我们推荐以下预发布的版本架构,由 [semver.org](https://semver.org/#spec-item-9)提供。如: `1.2.0-napi`。 - - 通览所有的清单(确保测试/示例/文档都正常)。 - - `$ npm publish --tag n-api` - -在这个例子中,标记为 `n-api` 的发布版已经确保尽管其版本 1.2.0-3 比 non-N-API 的版本号要延后一些,但如果有人简单通过运行 `npm install iotivity-node` 安装 `iotivity-node`,它不会被安装而只会默认安装 non-N-API。此人应该运行 `npm install iotivity-node@n-api` 得到 N-API 的版本号,有关使用标签的更多详情请查阅 ["使用目标标签"][]。 - -## 在某个版本的 N-API 包中引入特定的依赖 - -为了将 `iotivity-node` 的 N-API 版本作为依赖进行添加安装,`package.json` 应如下形式呈现: - -```json -"dependencies": { - "iotivity-node": "n-api" -} -``` - -> **注意:** 如 ["使用目标标签"](https://docs.npmjs.com/getting-started/using-tags) 的解释,不同于一般的版本号,标记的版本号不能在 `package.json` 中通过版本范围(诸如 `"^2.0.0"` 的形式)进行追踪。所以,版本维护者使用相同的标签但选择了一个稍晚一些的版本, `npm update` 将收到稍晚的版本。这在当前试验环境下的 N-API 是可以接受的。为了依赖于一个 N-API 特定版本而不是最新的发布版,`package.json` 依赖不得不引用具体的版本范围,如下所示: - -```json -"dependencies": { - "iotivity-node": "n-api" -} -``` - -["使用目标标签"]: https://docs.npmjs.com/getting-started/using-tags diff --git a/pages/zh-cn/docs/guides/security/index.md b/pages/zh-cn/docs/guides/security/index.md deleted file mode 100644 index 972022fd1acc0..0000000000000 --- a/pages/zh-cn/docs/guides/security/index.md +++ /dev/null @@ -1,322 +0,0 @@ ---- -title: Node.js 中处理安全性问题的最佳实践做法 -layout: docs.hbs ---- - -# Node.js 中处理安全性问题的最佳实践 - -## 本文目的 - -本文旨在对目前既有的[威胁示例][]进行扩展,并且提供一些扩展的例子教导如何让你的 Node.js 应用安全性得到保障。 - -## 本文内容 - -- 最佳实践做法:这是一个针对 Node.js 应用的安全性问题的最佳实践做法的精简压缩版。我们可以使用[安全指南讨论议题][安全指南讨论议题]或者是[nodejs 使用指南][nodejs 使用指南]作为我们的开始。值得注意的是:本文特定针对的是 Node.js,如果你正在寻找其它更通用的教程,可以参考[OSSF 最佳实践做法][]。 -- 安全性攻击解释:用最通俗易懂的语言,根据需要配上一些代码,来解释在我们在威胁示例中提到的攻击方式。 -- 第三方库中的潜在攻击方式(诸如“误植”式攻击,含有恶意代码的包库……),以及关于 node 模块依赖等问题的一系列最佳实践。 - -## 威胁列表 - -### HTTP 拒绝服务式攻击(CWE-400) - -这种攻击会导致应用程序变得无法响应请求而拒绝服务,其攻击原理是依据处理 HTTP 请求的方式导致的。这些攻击性请求并非一定是经过精心策划,甚至连一台错误配置,又或者有缺陷的客户端也 会发送大量请求到服务端,导致拒绝式服务。 - -HTTP 请求通过 Node.js 的 HTTP 服务器得以接受,并传递给已注册的相关程序代码进行处理。因为服务本身并不解析请求数据的实际内容,因此对于任何一个试图通过文本内容发起 HTTP 拒绝服务式攻击,接受这些请求的处理模块本身并不存在缺陷,因为这是处理模块中代码的职责,它应该准确地处理这些问题。 - -请务必确保服务器能够处理服务端的错误,否则服务器在处理请求时发生了错误,恰好又没有处理异常的相关代码,那么就可能存在拒绝服务式攻击的潜在威胁。 - -```js -const net = require('net'); - -const server = net.createServer(function (socket) { - // socket.on('error', console.error) // this prevents the server to crash - socket.write('Echo server\r\n'); - socket.pipe(socket); -}); - -server.listen(5000, '0.0.0.0'); -``` - -此处如果接受一个 _非法请求_ ,服务器就可能崩溃了。 - -另一个案例 [Slowloris][] 并非是通过请求的内容发动拒绝式服务攻击。在这个攻击中,HTTP请求发送既慢又散,每次就发送一点点内容,这样就会导致服务器为等待完整的请求不得不一直保留大量的资源。设想一下:如果这种请求足够的多,连接数很快会达到最大值,然后就发生拒绝式服务的问题。这就是不通过发送文本的内容,而是借助消耗时间,以及发送大量碎片化请求的方式进行攻击的。 - -**缓解措施** - -- 使用一个反向代理来接受、转发 Node.js 应用程序请求,反向代理可以提供诸如缓存、负载均衡、IP 黑名单等方式尽可能减少服务式拒绝攻击发生的可能性。 -- 正确地配置服务器超时时间(timeout),这样凡是龟速响应请求以及一直原地不动的连接请求就会被直接抛弃。请了解超时配置的区别,并查看 [`http.Server`][] 部分,尤其是 `headersTimeout`,`requestTimeout`, `timeout` 和 `keepAliveTimeout`。 -- 在每台主机上限制开放端口的总数。请查看 [http 文档][],尤其是 `agent.maxSockets`,`agent.maxTotalSockets`,`agent.maxFreeSockets` 和 `server.maxRequestsPerSocket`。 - -### DNS 重绑定(CWE-346) - -这种攻击方式针对正在运行中的,并且使用 [--inspect switch][] 参数开启了调试观察器的 Node.js 应用程序。 - -在一个网页浏览器里边可以发起 WebSocket 和 HTTP 两种请求方式,他们可以对本地的调试观察器同时作用。通常而言,这是被主流浏览器的[同源协议][]所禁止,它不允许执行来自不同的源的脚本(这也同时意味着一个恶意的网站不能读取来自本地 IP 地址的内容)。 - -然而通过 DNS 重绑定的方法攻击者可以为了他们的恶意请求而临时控制发送源,使得请求看上去就像是从本地发出的一样。这种方法通过同时控制网站以及处理 IP 地址的 DNS 服务器来实现。请查看 [DNS 重绑定维基百科][]了解更多细节。 - -**缓解措施** - -- 通过挂上`process.on(‘SIGUSR1’, …)`的监听器方式禁止调试观察器 SIGUSR1 的信号。 -- 不要在生产环境中使用调试观察器。 - -### 向不明身份者暴露敏感信息(CWE-552) - -在当前目录下所有的文件、文件夹都会通过打包发布的方式推送致 npm 的注册服务器上。 - -有一些机制可以避免这种行为:诸如通过定义`.npmignore`和`.gitignore` ,或者在 `package.json`中定义白名单列表。 - -**缓解措施** - -- 使用 `npm publish --dry-run` 开列所有将要被发布的文件,并在发布前请确保这些文件都被审核过是可以发布的。 -- 创建和维护诸如 `.gitignore` 和`.npmignore` 之类的文件,避免发布不必要的文件。 在这些文件中你可以指定哪些文件(文件夹)不应该被发布。`package.json` 中的[文件属性][]允许你进行反操作(哪些文件是可以发布的)。 -- 万一发布了不应该发布的内容,请参考 [如何撤消已有的发布][] 撤消你的发布。 - -### HTTP 请求夹带私货(CWE-444) - -这种攻击方式涉及到两个 HTTP 服务端(通常一个是代理,一个是 Node.js 应用)。客户端 发送一个 HTTP 请求首先到代理服务器,代理服务器将请求转发到后台服务(也就是 Node.js 应用)。 当前端和后端对于这个请求的解析产生歧义时,攻击者就可能发送一个恶意信息,并且该信息不会被 前端所发现,却会被后台所处理。这就是有效的“夹带私货”式透过代理服务器发动攻击。 - -预知详情,请查看 [CWE-444][] 中相关信息和例子。 - -基于这样一个事实:即攻击依赖于 Node.js 解析 HTTP 请求的方式与任何一个 HTTP 前端服务器 所不同,那么该 Node.js 存在可能被攻击的缺陷,这可以是前端,也可能前后端都存在。 如果 Node.js 解析请求的方式与 HTTP 特性文档中描述的一致(具体参考 [RFC7230][]),那么 这个 Node.js 应用就不会被认为是存在缺陷的。 - -**缓解措施** - -- 当创建一个 HTTP 服务时,请不要使用 `insecureHTTPParser` 选项 -- 前端做适当的配置,使得带有歧义的请求能够正常化 -- 对 HTTP 发出的新“私货”请求请持续在 Node.js 端以及前端都保持留意 -- 使用第二代的 HTTP 协议(HTTP/2),并不允许降级 - -### 根据耗时的多少猜测敏感信息导致信息暴露(CWE-208) - -该攻击方式是攻击者根据发起请求后服务器需要多久才给出一个回复所用的耗时,不知不觉地猜测出一些敏感的信息。该攻击方式不仅是针对 Node.js,几乎所有的应用都会受到这种攻击方式的影响。 - -该攻击方式容易发生在一个需要一定时间进行某保护性的操作中(例如)。 设想一下我们是如何处理身份验证的:身份验证最基础 的方法便是“电子邮件”+“密码”的组合。 系统从用户的输入得到了登陆信息,再从数据库里边得到已有信息。在从客户输入那边获取信息之时, 程序将把用户输入的密码与数据库中的密码进行比对。使用系统内置的字符串比较, 对于一定程度相同的字符串是需要消耗一定时间的。在不断地反复比较, 直到达到一定的次数和响应时间之后,通过比较响应请求时间,攻击者就可能猜测出密码的长度, 甚至是密码内容。 - -**缓解措施** - -- 请使用`timingSafeEqual`函数来比较敏感信息的内容,因为它的耗时是一个固定值。 -- 在进行密码比较的过程中,请使用 [scrypt][]。 - -- 更一般地说,我们应当避免在可变时间操作中使用保护性措施。 这包括分支保护,以及当攻击者可能位于同一基础架构(例如,同一台云计算机)上时,使用保护性措施作为内存索引。在 JavaScript 中写入固定耗时的代码极其困难(部分因为 JIT 的缘故)。对于那些加密的应用而言,使用内置的加密 API 函数或者是 WebAssembly 为好(因为 WebAssembly 的算法并非本地实现)。 - -### 含有恶意攻击的第三方库 (CWE-1357) - -目前为止,Node.js 中任何一个包都有强大的能力去访问其它资源:例如网络资源等。更进一步地说,Node.js 中的包可以访问本地文件系统,并且把数据发送到任何地方。 - -在 node 里可以通过`eval()`(或者其它类似的方式)加载、运行任何代码。所有与文件系统相关,拥有写权限的代码也能通过写入一个新文件,或者已有文件,当他们被加载执行时,就能达到一样的目的。 - -Node.js 携带一个尝鲜版本的[¹][experimental-features][规则机制][]来声明所加载的资源是否是可被新信任的。请务必确定所有的依赖包版本号, 以及借助公共工作流或 npm 的脚本来自动检测这些包里可能潜在的缺陷。 在安装依赖包时,请务必确认这些包都是被正常维护的,并包含你预期的内容。 请务必小心!GitHub 的源代码不总是和发布版本保持一致,请在*node_modules* 里仔细验证。 - -#### 供应链式攻击 - -Node.js 中 “供应链式攻击”通常发生在某个(些)依赖(无论是直接依赖还是间接依赖)已经被攻陷的情况下。究其原因便是这类应用的特定依赖审核太过于松散(甚至允许根本不需要的更新进入), 或者是常规的拼写错误导致的误认(请参考[typosquatting][])。 - -一个控制上游更新端的攻击者完全可以发布一个新的,携带恶意代码的更新包。如果 Node.js 应用没经过检验或者不确定哪个包是安全的,那么这个包就有潜在更新成为携带恶意代码的包的可能性,随之攻陷你的系统。 - -在`package.json`中定义的所有依赖都有精确的版本号,亦或是某个特定范围。你即使对某个包指定了一个精确的版本号,这个包所依赖的其它包不一定是固定的。这将仍然导致应用缺陷或者不安全、不期望的包更新。 - -可能的攻击方式: - -- “误植”域名 -- 篡改 Lockfile -- 受到侵害的维护者 -- 恶意第三方的包(类库) -- 依赖混淆 - -**缓解措施** - -- 使用 npm 的指令`--ignore-scripts`来禁止外部脚本运行。 - - 另外,你也可以直接使用 `npm config set ignore-scripts true` 方式禁止脚本运行 -- 给第三方包指定精确的版本,勿指定一个宽泛的版本范围,或者是不确定可变的更新源 -- 使用 lockfiles,固定每一个依赖包(无论直接引用或是间接的) - - 参考 [对 lockfile 恶意篡改的缓解措施][] 部分 -- 使用 CI 自动检测可能存在的缺陷,可以借助 [`npm-audit`][] - - 诸如 [`Socket`][] 的工具也可使用,他可以静态分析依赖包, 并且找出网络或文件系统方面的潜在风险性行为。 -- 使用 [`npm ci`][] 而不是 `npm install` 此命令强制比对 lockfile 里的版本号,如果和 _package.json_ 中的依赖发生冲突, 直接抛出异常而不是默默地忽略,迁就 _package.json_ 的定义 -- 小心检查 _package.json_ 文件里的每个依赖包的名称,切勿拼错 - -### 非法内存访问(CWE-284) - -基于内存或者基于堆栈的攻击都依赖于内存管理错误,或者内存分配泄露。正如其它程序一样,如果你的 Node.js 程序运行在共享机上,是有可能存在被攻击的。使用安全性高的堆栈确实有助于此问题的解决,防止从带有缺陷的超载或空载机器中泄露敏感信息。 - -不幸的是安全堆栈并不适合于 Windows 操作系统。预知详情请看[安全堆栈文档][]。 - -**缓解措施** - -- 使用 `--secure-heap=n`限定内存大小,“n”就是最大的字节大小。 -- 不要在共享机器中运行您的生产应用程序。 - -### 鱼目混珠(CWE-349) - -“鱼目混珠”(猴子补丁)指在运行时通过修改属性达到篡改原有行为的操作。举个例子: - -```js -// eslint-disable-next-line no-extend-native -Array.prototype.push = function (item) { - // overriding the global [].push -}; -``` - -**缓解措施** - -借助尝鲜版的 `--frozen-intrinsics` 符号[¹][experimental-features]来冻结内置对象的原型,这意味着所有的 JavaScript 对象以及其内部的一切函数等均不再可变。 有鉴于此,以下的脚本将不会覆盖原有的`Array.prototype.push`代码: - -```js -// eslint-disable-next-line no-extend-native -Array.prototype.push = function (item) { - // overriding the global [].push -}; - -// Uncaught: -// TypeError >>: -// Cannot assign to read only property 'push' of object '' -``` - -诚然如此,但你目前仍然可以使用 `globalThis`来定义新的,以及替换已有的全局变量。 - -```console -> globalThis.foo = 3; foo; // you can still define new globals -3 -> globalThis.Array = 4; Array; // However, you can also replace existing globals -4 -``` - -至此,Object.freeze(globalThis) 可以派上用场,以确保你无法更改任何全局性变量。 - -### 原型污染(CWE-1321) - -原型污染指滥用 **proto**、 _constructor_ 或 _prototype_,以及从内置方法中继承等方式 在 Javascript 内恶意篡改、注入一些东西。 - - - -```js -const a = { a: 1, b: 2 }; -const data = JSON.parse('{"__proto__": { "polluted": true}}'); - -const c = Object.assign({}, a, data); -console.log(c.polluted); // true - -// Potential DoS -const data2 = JSON.parse('{"__proto__": null}'); -const d = Object.assign(a, data2); -d.hasOwnProperty('b'); // Uncaught TypeError: d.hasOwnProperty is not a function -``` - -上面的 JavaScript 代码就暗含存在的隐患。 - -附上其它相关示例: - -- [CVE-2022-21824][] (Node.js) -- [CVE-2018-3721][] (3rd Party library: Lodash) - -**缓解措施** - -- 避免 [不安全的递归式合并][],参考 [CVE-2018-16487][] -- 对于外部以及不信任的对象,请使用 JSON 骨架(JSON Schema)来验证 -- 使用 `Object.create(null)` 创建无原型(prototype)的对象 -- 冻结对象原型: `Object.freeze(MyObject.prototype)` -- 使用 `--disable-proto` 禁止 `Object.prototype.__proto__` 属性 -- 请检查对象上是否存在着特定属性,而不是使用 `Object.hasOwn(obj, keyFromObj)`原型方法来检测 -- 避免使用 `Object.prototype` 的方法。 - -### 不可控的搜索路径对象(CWE-427) - -Node.js 根据[模块路径算法][]来加载模块,因此我们假定说模块中的某个文件夹是可信的。 - -基于此,这意味着以下的操作是符合预期的,让我们假设存在着以下的目录结构: - -- _app/_ - - _server.js_ - - _auth.js_ - - _auth_ - -如果服务端调用 `require('./auth')` ,结果加载 _auth _ 并非 _auth.js_ 。 - -**缓解措施** - -借助[¹][experimental-features] [完整检查路径的规则机制][]可避免此类问题。对于上述的路径,可以使用诸如下面的 `policy.json`: - -```json -{ - "resources": { - "./app/auth.js": { - "integrity": "sha256-iuGZ6SFVFpMuHUcJciQTIKpIyaQVigMZlvg9Lx66HV8=" - }, - "./app/server.js": { - "dependencies": { - "./auth": "./app/auth.js" - }, - "integrity": "sha256-NPtLCQ0ntPPWgfVEgX46ryTNpdvTWdQPoZO3kHo0bKI=" - } - } -} -``` - -自然而言,当调用 _auth_ 模块的时候,系统会验证路径完整性,如果发现无法找到 正确的匹配项,直接抛出异常: - -```console -» node --experimental-policy=policy.json app/server.js -node:internal/policy/sri:65 - throw new ERR_SRI_PARSE(str, str[prevIndex], prevIndex); - ^ - -SyntaxError [ERR_SRI_PARSE]: Subresource Integrity string "sha256-iuGZ6SFVFpMuHUcJciQTIKpIyaQVigMZlvg9Lx66HV8=%" had an unexpected "%" at position 51 - at new NodeError (node:internal/errors:393:5) - at Object.parse (node:internal/policy/sri:65:13) - at processEntry (node:internal/policy/manifest:581:38) - at Manifest.assertIntegrity (node:internal/policy/manifest:588:32) - at Module._compile (node:internal/modules/cjs/loader:1119:21) - at Module._extensions..js (node:internal/modules/cjs/loader:1213:10) - at Module.load (node:internal/modules/cjs/loader:1037:32) - at Module._load (node:internal/modules/cjs/loader:878:12) - at Module.require (node:internal/modules/cjs/loader:1061:19) - at require (node:internal/modules/cjs/helpers:99:18) { - code: 'ERR_SRI_PARSE' -} -``` - -请注意,我们总是推荐你使用 `--policy-integrity` 以避免路径发生变化时遇到问题。 - -## 生产环境中使用尝鲜版功能 - -在生产环境中直接使用尝鲜版功能绝不推荐!因为尝鲜功能有可能随时发生重大变更,而且他们实际的功能不一定稳定。虽然如此,我们还是非常乐于接受用户的反馈。 - -## OpenSSF 工具 - -[OpenSSF][] 正在引导一些可能非常有用的倡议,特别是如果您计划发布一个 npm 软件包。这些倡议包括: - -- [OpenSSF 计分卡][] 计分卡使用一系列自动安全风险检查来评估开源项目。 你可以使用它来主动评估你的代码基础中的脆弱性和依赖性,并就接受脆弱性做出明智的决定。 -- [OpenSSF 最佳做法徽章方案][] 项目可以通过描述它们如何遵守每个最佳做法而自愿自我认证。 这将生成一个可以添加到项目的徽章。 - -[威胁示例]: https://github.com/nodejs/node/security/policy#the-nodejs-threat-model -[安全指南讨论议题]: https://github.com/nodejs/security-wg/issues/488 -[nodejs 使用指南]: https://github.com/goldbergyoni/nodebestpractices -[OSSF 最佳实践做法]: https://github.com/ossf/wg-best-practices-os-developers -[Slowloris]: https://en.wikipedia.org/wiki/Slowloris_(computer_security) -[`http.Server`]: https://nodejs.org/api/http.html#class-httpserver -[http 文档]: https://nodejs.org/api/http.html -[--inspect switch]: https://nodejs.org/en/docs/guides/debugging-getting-started/ -[同源协议]: https://nodejs.org/en/docs/guides/debugging-getting-started/ -[DNS 重绑定维基百科]: https://en.wikipedia.org/wiki/DNS_rebinding -[文件属性]: https://docs.npmjs.com/cli/v8/configuring-npm/package-json#files -[如何撤消已有的发布]: https://docs.npmjs.com/unpublishing-packages-from-the-registry -[CWE-444]: https://cwe.mitre.org/data/definitions/444.html -[RFC7230]: https://datatracker.ietf.org/doc/html/rfc7230#section-3 -[规则机制]: https://nodejs.org/api/permissions.html#policies -[typosquatting]: https://en.wikipedia.org/wiki/Typosquatting -[对 lockfile 恶意篡改的缓解措施]: https://blog.ulisesgascon.com/lockfile-posioned -[`npm ci`]: https://docs.npmjs.com/cli/v8/commands/npm-ci -[安全堆栈文档]: https://nodejs.org/dist/latest-v18.x/docs/api/cli.html#--secure-heapn -[CVE-2022-21824]: https://www.cvedetails.com/cve/CVE-2022-21824/ -[CVE-2018-3721]: https://www.cvedetails.com/cve/CVE-2018-3721/ -[不安全的递归式合并]: https://gist.github.com/DaniAkash/b3d7159fddcff0a9ee035bd10e34b277#file-unsafe-merge-js -[CVE-2018-16487]: https://www.cve.org/CVERecord?id=CVE-2018-16487 -[scrypt]: https://nodejs.org/api/crypto.html#cryptoscryptpassword-salt-keylen-options-callback -[模块路径算法]: https://nodejs.org/api/modules.html#modules_all_together -[完整检查路径的规则机制]: https://nodejs.org/api/permissions.html#integrity-checks -[experimental-features]: #experimental-features-in-production -[`Socket`]: https://socket.dev/ -[OpenSSF]: https://openssf.org/ -[OpenSSF 计分卡]: https://securityscorecards.dev/ -[OpenSSF 最佳做法徽章方案]: https://bestpractices.coreinfrastructure.org/en diff --git a/pages/zh-cn/docs/guides/simple-profiling.md b/pages/zh-cn/docs/guides/simple-profiling.md deleted file mode 100644 index 8dfc83daab330..0000000000000 --- a/pages/zh-cn/docs/guides/simple-profiling.md +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: 易于分析的 Node.js 应用程序 -layout: docs.hbs ---- - -# 易于分析的 Node.js 应用程序 - -市面上有很多可以容易地分析 Node.js 应用程序的工具。但是在许多情况下,最简单的选项是使用 Node.js 内置的探查器。创建的探测器使用 [V8 内探测器][],它收集该堆栈在程序执行期间的定期间隔的样本。并且它这些样本的结果,包含诸如 jit 编译的重要的优化事件,如以下刻度系列标示: - -``` -code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~ -code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~ -code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~ -code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub" -code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub" -``` - -在以前你需要 V8 源代码去解释这些刻度。幸运的是,从 Node.js 4.4.0 开始此工具就被引入,这样就方便了这些信息的消费而不另行建立 V8 源。让我们看看内置探查器如何帮助您洞察应用程序性能。 - -为了说明滴答探查器的使用,我们将使用一个简单的快速应用程序。我们的应用程序将有两个处理程序,一个用于向系统中添加新用户: - -```javascript -app.get('/newUser', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users.username) { - return res.sendStatus(400); - } - - const salt = crypto.randomBytes(128).toString('base64'); - const hash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - users[username] = { salt, hash }; - - res.sendStatus(200); -}); -``` - -另外一个用于验证用户尝试登陆: - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || !users[username]) { - return res.sendStatus(400); - } - - const { salt, hash } = users[username]; - const encryptHash = crypto.pbkdf2Sync(password, salt, 10000, 512, 'sha512'); - - if (crypto.timingSafeEqual(hash, encryptHash)) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } -}); -``` - -_请注意,这些不是推荐的处理程序用于对 Node.js 中的用户进行身份验证;它们纯粹用于说明目的。您不应该尝试设计您自己的加密身份验证机制。使用现有的、经过验证的身份验证解决方案要好得多。_ - -现在假设我们已经部署了我们的应用程序,并且用户抱怨请求的延迟很大。我们可以轻松地运行应用程序与内置的探查器: - -``` -NODE_ENV=production node --prof app.js -``` - -然后使用 `ab` (ApacheBench) 在服务器上放些负载: - -``` -curl -X GET "http://localhost:8080/newUser?username=matt&password=password" -ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password" -``` - -然后你就可以得到 ab 的输出: - -``` -Concurrency Level: 20 -Time taken for tests: 46.932 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 5.33 [#/sec] (mean) -Time per request: 3754.556 [ms] (mean) -Time per request: 187.728 [ms] (mean, across all concurrent requests) -Transfer rate: 1.05 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 3755 - 66% 3804 - 75% 3818 - 80% 3825 - 90% 3845 - 95% 3858 - 98% 3874 - 99% 3875 - 100% 4225 (longest request) -``` - -从这个输出中我们可以看到我们只管理每秒约 5 个请求,并且平均请求只需要 4 秒的往返时间。在一个真实的世界例子中,我们可以代表用户请求在许多函数中做很多工作,但即使在简单的示例中,编译正则表达式、生成随机盐、从用户密码生成唯一哈希或在 Express 框架本身。 - -由于我们使用了 `--prof` 选项运行应用程序,因此在与应用程序的本地运行相同的目录中生成了一个刻度文件。它应该有形式 `isolate-0xnnnnnnnnnnnn-v8.log` (其中 `n` 为数字)。 - -为了使这个文件有意义,我们需要使用与 Node.js 捆绑在一起的刻度处理器。要运行处理器,请使用 `--prof-process` 标志: - -``` -node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt -``` - -在您最喜欢的文本编辑器中打开 processed.txt 将给您提供一些不同类型的信息。该文件被分解成部分,然后再次被语言分解。首先,我们看一下摘要部分: - -``` - [Summary]: - ticks total nonlib name - 79 0.2% 0.2% JavaScript - 36703 97.2% 99.2% C++ - 7 0.0% 0.0% GC - 767 2.0% Shared libraries - 215 0.6% Unaccounted -``` - -这告诉我们:收集到的所有样本中有 97% 是在 C++ 代码中进行的。当查看处理的输出的其它部分时,我们应该最注意 C++ 中所做的工作(而不是 JavaScript)。考虑到这一点,我们接下来会找到 \[C++\] 部分,其中包含有关 C++ 函数占用最多 CPU 时间的信息,然后查看一下: - -``` - [C++]: - ticks total nonlib name - 19557 51.8% 52.9% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 4510 11.9% 12.2% _sha1_block_data_order - 3165 8.4% 8.6% _malloc_zone_malloc -``` - -我们看到,前 3 个条目占了程序占用的 CPU 时间的 72.1%。从这个输出中,我们立即看到至少 51.8% 的 CPU 时间被称为 PBKDF2 的函数占用。它与用户密码中的哈希生成相对应。然而,较低的两个条目的因素是如何进入我们的应用程序(或者我们为了例子而假装如此)不会立即明显得看出来。为了更好地理解这些函数之间的关系,接下来我们将查看\[自下而上(重)配置文件\]部分,该节提供有关每个函数的主要调用方的信息。检查此部分,我们会发现: - -``` - ticks parent name - 19557 51.8% node::crypto::PBKDF2(v8::FunctionCallbackInfo const&) - 19557 100.0% v8::internal::Builtins::~Builtins() - 19557 100.0% LazyCompile: ~pbkdf2 crypto.js:557:16 - - 4510 11.9% _sha1_block_data_order - 4510 100.0% LazyCompile: *pbkdf2 crypto.js:557:16 - 4510 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 - - 3165 8.4% _malloc_zone_malloc - 3161 99.9% LazyCompile: *pbkdf2 crypto.js:557:16 - 3161 100.0% LazyCompile: *exports.pbkdf2Sync crypto.js:552:30 -``` - -分析此节需要的工作量比上面的原始刻度计数多一点。 在上面的每个“调用栈”中,父列中的百分比将告诉您在当前行中函数调用了上面行中的函数所占的样本百分比。例如,在中间“呼叫堆栈”以上为 \_sha1_block_data_order,我们看到 `_sha1_block_data_order` 发生在 11.9% 样品,我们知道从上面的原始计数。然而,在这里我们也可以说,它总是由 Node.js 内部的 pbkdf2 函数调用加密模块。我们看到,同样 `_malloc_zone_malloc` 被称为几乎完全相同的 pbkdf2 功能。因此,使用中的信息这种观点,我们可以说,我们从用户的密码帐户计算的哈希不仅为上面所述的 51.8%,但也是前 3 的 CPU 时间采样函数,因为调用 `_sha1_block_data_order` 和`_malloc_zone_malloc` 是代表 pbkdf2 的功能而制作的。 - -在这一点上,很明显:基于密码的哈希生成应该是我们优化的目标。谢天谢地,您已经完全了解了[异步编程的好处][],并且您认识到从用户密码生成哈希的工作正在以同步方式进行,从而绑定了事件循环。这将阻止我们在计算哈希时处理其它传入请求。 - -要解决此问题,请对上述处理程序进行小修改,以使用 pbkdf2 函数的异步版本: - -```javascript -app.get('/auth', (req, res) => { - let username = req.query.username || ''; - const password = req.query.password || ''; - - username = username.replace(/[!@#$%^&*]/g, ''); - - if (!username || !password || users[username]) { - return res.sendStatus(400); - } - - crypto.pbkdf2( - password, - users[username].salt, - 10000, - 512, - 'sha512', - (err, hash) => { - if (users[username].hash.toString() === hash.toString()) { - res.sendStatus(200); - } else { - res.sendStatus(401); - } - } - ); -}); -``` - -一次新的基于 ab ,关于以上异步版本的应用基准测试情况如下: - -``` -Concurrency Level: 20 -Time taken for tests: 12.846 seconds -Complete requests: 250 -Failed requests: 0 -Keep-Alive requests: 250 -Total transferred: 50250 bytes -HTML transferred: 500 bytes -Requests per second: 19.46 [#/sec] (mean) -Time per request: 1027.689 [ms] (mean) -Time per request: 51.384 [ms] (mean, across all concurrent requests) -Transfer rate: 3.82 [Kbytes/sec] received - -... - -Percentage of the requests served within a certain time (ms) - 50% 1018 - 66% 1035 - 75% 1041 - 80% 1043 - 90% 1049 - 95% 1063 - 98% 1070 - 99% 1071 - 100% 1079 (longest request) -``` - -耶!您的应用程序现在每秒服务约 20 个请求,大约是同步哈希生成的4倍。此外,平均滞后时间从 4 秒前下降到仅 1 秒。 - -希望通过对此(诚然是做作的)示例的性能调查,您已经看到了 V8 刻度处理器如何帮助您更好地了解 Node.js 应用程序的性能。 - -你也会发现[如何创建火焰图][]对你是有帮助的。 - -[V8 内探测器]: https://v8.dev/docs/profile -[异步编程的好处]: https://nodesource.com/blog/why-asynchronous -[如何创建火焰图]: /zh-cn/docs/guides/diagnostics-flamegraph/ diff --git a/pages/zh-cn/docs/guides/timers-in-node.md b/pages/zh-cn/docs/guides/timers-in-node.md deleted file mode 100644 index 69ec48ef11c6c..0000000000000 --- a/pages/zh-cn/docs/guides/timers-in-node.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Node.js 中的定时器 -layout: docs.hbs ---- - -# Node.js 中的定时器和其他相关项 - -Node.js 中的定时器模块包含了隔一定时间执行一遍代码的函数。定时器不必通过 `require()` 的方式引入,因为所有这些方法都是模拟浏览器中 JavaScript 函数,是全局的。为了更好的全面理解何时这些函数将执行,阅读 Node.js 中[事件轮询](/en/docs/guides/event-loop-timers-and-nexttick/)是一个好主意。 - -## 用 Node.js 控制时间的连续 - -Node.js 中的 API 函数提供了几种方式,允许代码从现在时间之后的某个时刻开始执行。以下给出的函数看上去很相似,因为它们在大多数浏览器中都可用。但是 Node.js 实际上提供了它自己的实现。定时器与系统非常紧密地结合在一起,尽管这些 API 是浏览器中函数的翻版,但是仍然在实现上有所不同。 - -### “当我这样说的时候” 的执行方式 ~ _`setTimeout()`_ - -`setTimeout()` 可被用来在一段指定时间之后执行某个代码任务。此函数与浏览器 JavaScript 函数 [`window.setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) 很相似,但是你不能把一串字符串传入执行。 - -`setTimeout()` 接受一个可执行的函数作为其第一个参数,然后有一个毫秒为单位的延时时间作为第二个参数。其余的参数也可纳入其中,作为传给此函数的参数使用。以下是一个例子: - -```js -function myFunc(arg) { - console.log(`arg was => ${arg}`); -} - -setTimeout(myFunc, 1500, 'funky'); -``` - -因为使用了 `setTimeout()`,以上函数 `myFunc()` 将在 1500 毫秒(或者1.5秒)左右时执行。 - -设置的定时间隔不能保证每次都是以 _精准_ 的毫秒间隔数执行代码,这是因为其它阻塞或者正在事件轮询上处理的代码将推迟此定时的执行。_唯一_ 保证的是定时器不会比声明的时间间隔 _提早_ 执行。 - -`setTimeout()` 返回一个 `Timeout` 对象,可通过该对象引用到设置的定时器。这个返回的对象可以被用来取消定时(见下面的 `clearTimeout()` 部分),同时还可以改变执行行为(见下面的 `unref()` 部分)。 - -### "在此之后立即执行" _`setImmediate()`_ - -`setImmediate()` 将在当前事件轮询的末尾处执行。 本代码将在当前事件轮询中的任何 I/O 操作 _后_,在任何下一轮定时器 _前_ 执行。代码执行可以被认为是“在此之后立即执行”,这意味着任何紧跟着 `setImmediate()` 函数调用将在 `setImmediate()` 函数参数前执行。 - -`setImmediate()` 的第一个参数是要执行的函数,当执行时,后面的参数将作为参数传入这个函数中。这是一个例子: - -```js -console.log('before immediate'); - -setImmediate(arg => { - console.log(`executing immediate: ${arg}`); -}, 'so immediate'); - -console.log('after immediate'); -``` - -传入 `setImmediate()` 的上述函数将在任何可执行的代码执行完后执行,所以输出结果是: - -``` -before immediate -after immediate -executing immediate: so immediate -``` - -`setImmediate()` 返回一个 `Immediate` 对象,它可以被用于取消安排的定时任务(见下面的 `clearImmediate()` )。 - -> 注意:不要把 `setImmediate()` 和 `process.nextTick()` 相混淆。它们有一些主要的差别:第一, `process.nextTick()` 将在任何设置好的 `Immediate` 以及任何安排好的 I/O _前_ 执行。第二, `process.nextTick()` 是不可擦除的,换句话说,一旦有代码使用 `process.nextTick()` 执行,执行无法中断,这就像一个普通函数一样,具体可以参考[此教程](/en/docs/guides/event-loop-timers-and-nexttick/#process-nexttick)来更好地理解 `process.nextTick()` 的操作。 - -### "永远的轮询" 执行 ~ _`setInterval()`_ - -如果存在一块函数,它需要多次执行,`setInterval()` 可以派上用场。`setInterval()` 接受一个函数作为其参数,该函数将被运行无限次,第二个参数便是一个给定的延时毫秒数。就像 `setTimeout()`,其余参数可以在这之后添加,作为传递给函数调用的参数使用。另外一个和 `setTimeout()` 类似的地方是延时不保证精确,因为有些操作可能在事件轮询上挂住,因此可以被认为是大致的延时。如以下例子: - -```js -function intervalFunc() v. - console.log('Cant stop me !'); -} - -setInterval(intervalFunc, 1500); -``` - -在上面的例子中,`intervalFunc()` 每 1500 毫秒执行一次(或每 1.5 秒执行一次),直到它被终止(见下)。 - -就像 `setTimeout()`,`setInterval()` 同样返回一个 `Timeout` 对象,它可以被引用并且改变设定的定时器。 - -## 清除定时器 - -如果 `Timeout` 或 `Immediate`需要被取消,我们该怎么办? `setTimeout()`, `setImmediate()`和 `setInterval()`返回一个定时器对象,它可以被用来引用设置过的 `Timeout`或 `Immediate`对象。通过把该对象传入 `clear`函数中,那个对象就会被终止执行。这些可接受的函数是 `clearTimeout()`, `clearImmediate()`和 `learInterval()`。看下面例子: - -```js -const timeoutObj = setTimeout(() => { - console.log('timeout beyond time'); -}, 1500); - -const immediateObj = setImmediate(() => { - console.log('immediately executing immediate'); -}); - -const intervalObj = setInterval(() => { - console.log('interviewing the interval'); -}, 500); - -clearTimeout(timeoutObj); -clearImmediate(immediateObj); -clearInterval(intervalObj); -``` - -## 让定时器在背后运行 - -你已经记住了 `Timeout` 对象是通过 `setTimeout` 和 `setInterval` 返回的。 `Timeout` 对象提供了两个针对 `Timeout` 行为的函数: `unref()` 和 `ref()`。如果有一个 `Timeout` 对象是通过 `set` 函数设定排程的,`unref()` 就可以用于那个对象。这会对它产生一些轻微的改变,那就是 _如果它是最后的执行代码_ ,将不会调用 `Timeout` 对象。 - -相似的是,`Timeout` 对象有 `unref()` 方法可以被调用从而移除通过在相同的 `Timeout` 对象上调用了 `ref()` 之后所施加的行为,从而保证它的执行。小心一点,它并不会 _准确地_ 恢复到初始化的行为状态。请见下面的例子: - -```js -const timerObj = setTimeout(() => { - console.log('will i run?'); -}); - -// if left alone, this statement will keep the above -// timeout from running, since the timeout will be the only -// thing keeping the program from exiting -timerObj.unref(); - -// we can bring it back to life by calling ref() inside -// an immediate -setImmediate(() => { - timerObj.ref(); -}); -``` - -## 进一步向下的事件循环 - -还有远比本篇多得多的,关于时间轮询和定时器的东西,本文未涉及到。你可以通过 [Node.js 的时间轮询,定时器以及 process.nextTick()](/zh-cn/docs/guides/event-loop-timers-and-nexttick/) 学习到更多有关于 Node.js 内部事件轮询机制,以及定时器在执行时如何操作的。 diff --git a/pages/zh-cn/docs/guides/working-with-different-filesystems.md b/pages/zh-cn/docs/guides/working-with-different-filesystems.md deleted file mode 100644 index 88f0ea0b74c18..0000000000000 --- a/pages/zh-cn/docs/guides/working-with-different-filesystems.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: 与不同的文件系统协同工作 -layout: docs.hbs ---- - -# 与不同的文件系统协同工作 - -Node.js 公开了许多文件系统的特性。但并不是所有的文件系统都相同。以下都是给你的最佳建议,它们能够让你的代码在不同的文件系统之间保持简单又安全。 - -## 文件系统的行为 - -在你开始与文件系统工作前,你需要知道它是如何工作的。不同的文件系统行为表现差异,而且相互之间有或多或少的特性:如大小写敏感、大小写不敏感、大小写保存、编码格式保存、时间戳解析、扩展特性、节点表、Unix 权限、备用数据流等。 - -你应该小心翼翼地通过 `process.platform` 推断文件系统类型。举一个例子,不要假设因为您的程序在 Darwin 系统上运行,因此您正在处理一个不区分大小写的文件系统(HFS+),因为用户可能使用一个区分大小写的文件系统(HFSX)。类似地,不要假设因为您的程序在 Linux 上运行,因此您正在处理支持 Unix 权限和 INODE 的文件系统,因为您可能在特定的外部驱动器上,USB 或网络驱动器不支持。 - -操作系统可能不容易推断文件系统行为,但都不会丢失。不用保存所有已知文件系统和行为的列表(这总是不完整的),您可以探测文件系统来查看它实际上是如何运行的。容易探测的某些特征的存在或不存在常常足以推断更难探测的其它特征的行为。 - -请记住,一些用户可能在工作树中的不同路径上安装了不同的文件系统。 - -## 避免最低公分母方法 - -您可能会试图使程序像最低公分母文件系统一样,通过将所有文件名规范为大写,将所有文件名规范为 NFC Unicode 格式,并将所有文件时间戳归一化以表示 1 秒分辨率。这将是最低的公分母方法。 - -不要这样做。您只能安全地与文件系统进行交互,该文件系统在各个方面具有完全相同的最低公分母特性。您将无法以用户期望的方式使用更高级的文件系统,并且您会遇到文件名或时间戳冲突。您肯定会通过一系列复杂的依赖事件造成用户数据丢失和损坏。你会不断给你自己制造缺陷,而且解决起来很困难。 - -当您稍后需要支持只有 2 秒或 24 小时时间戳分辨率的文件系统时会发生什么?当 Unicode 标准前进到包含稍微不同的归一化算法(如以前发生)时会发生什么? - -最常用的分母方法倾向于通过只使用“便携”系统调用来创建一个可移植的程序。这导致了程序泄漏,而实际上不是便携式的。 - -## 采用超集方法 - -充分利用你支持的每一个平台,采用超集方法。例如,一个可移植的备份程序应该正确地在 Windows 系统之间同步文件或文件夹,即使在 Linux 系统上不支持 btime,也不应该破坏或更改它。相同的便携式备份程序应在 Linux 之间正确同步 Unix 权限系统且不应破坏或更改 Unix 权限,即便 Unix 权限在 Windows 系统上不被支持。 - -通过使程序像更高级的文件系统一样处理不同的文件系统。支持所有可能功能的超集: 区分大小写、保存大小写、Unicode 敏感编码、Unicode 格式保存、Unix 权限、高分辨率纳秒时间戳、扩展属性等。 - -一旦你在程序中拥有了大小写保存设置后,如果需要与不区分大小写的文件系统进行交互,则始终可以实现不区分大小写。但是如果您放弃程序中的大小写保存,则无法与拥有大小写保存的文件系统安全地进行交互。对于 Unicode 编码保存和时间戳解析保存也是如此。 - -如果文件系统为您提供小写和大写混合的文件名,请将文件名保留在给定的大小写状态下。如果文件系统为您提供混合 Unicode 编码或 NFC 或 NFD (或 NFKC 或 NFKD),然后将文件名保留为给定的精确字节序列。如果文件系统为您提供毫秒时间戳,则将时间戳保留为毫秒分辨率。 - -当您使用较小的文件系统时,您总是可以适当地向下采样,并根据运行程序的文件系统的行为要求进行比较。如果您知道文件系统不支持 Unix 权限,则不应期望读取与您编写的相同的 Unix 权限。如果您知道文件系统不保留大小写,那么当你的程序创建 `ABC` 时,你应该准备在目录列表中看到 `ABC` 。但是,如果您知道文件系统确实保留了大小写区分,那么当检测到文件名重命名或文件系统区分大小写时,您应该考虑将 `ABC` 与 `abc` 作为不同的文件名进行区分。 - -## 大小写保留 - -您可以创建一个名为 `test/abc` 的目录,并惊讶地看到有时 `fs.readdir('test')` 返回 `['ABC']` 。这不是 Node.js 的 bug。Node.js 返回文件名,因为文件系统存储它;而不是所有文件系统 支持大小写保存。某些文件系统将所有文件名转换为大写(或小写)。 - -## Unicode 编码格式保存 - -_大小写保存和 Unicode 编码保存是相似的概念。要了解为什么要保留 Unicode 编码,请确保首先了解为什么应保留大小写。在正确理解时,Unicode 形式保存也同样简单。_ - -Unicode 可以使用多个不同的字节序列对相同的字符进行编码。多个字符串可能看起来相同,但有不同的字节序列。使用 UTF-8 字符串时请注意,您的期望与 Unicode 的工作方式一致。正如您不希望所有 UTF-8 字符都编码到单个字节一样,您不应该期望用人的肉眼看上去是是一样的几个 UTF-8 字符串一定具有相同的字节表示形式。这可能只是一个期望,你可以有 ASCII,但不是 UTF-8。 - -您可以创建一个名为 `test/café` 的目录(带有字节序列的 `<63 61 66 c3 a9>` 和 `string.length === 5` 的 NFC Unicode 编码)。然后你会惊讶地看到,有时 `fs.readdir('test')` 会返回 `['café']`(带有字节序列的 `<63 61 66 65 cc 81>` 和 `string.length === 6` 的 NFD Unicode 编码)。这不是 Node.js 的缺陷。Node.js 返回文件名因为文件系统存储它,而不是所有文件系统支持 Unicode 形式保存。 - -例如 HFS+ 将所有文件名正常化为一种格式,几乎总是与 NFD 格式相同。不要期望 HFS+ 与 NTFS 或 EXT4 的行为相同,反之亦然。不要尝试通过规范化来永久更改数据。这会对对文件系统间的 Unicode 差异进行了漏抽象总结。反而造成问题而不是解决它们。相反地,我们应该保留 Unicode 格式并仅使用正常化作为比较函数。 - -## 敏感的 Unicode 编码 - -Unicode 不敏感编码和 Unicode 编码保存是两种不同的文件系统行为,经常相互误解。正如在存储和传输文件名时将文件名永久规范化为大写时,有时会不正确地实现了不区分大小写;因此 Unicode 不敏感编码有时会被永久地错误地实现。在存储和传输文件名时,将文件名规范化为特定的 Unicode 形式(NFD 的情况下为 HFS+)。在不牺牲 Unicode 编码保存的情况下实现 Unicode 不敏感编码是可能的,而且最好使用 Unicode 规范化进行比较。 - -## 比较不同的 Unicode 编码 - -节点提供了 `string.normalize('NFC' / 'NFD')`,你可以使用它正常化一个 UTF-8 字符串,无论是 NFC 或 NFD。您不应将输出从该函数中存储,而只将其用作比较函数的一部分以测试两个 UTF-8 字符串是否与用户看起来相同。 - -你可以使用 `string1.normalize('NFC') === string2.normalize('NFC')` 或者 `string1.normalize('NFD') === string2.normalize('NFD')` 作为你的比较函数,至于使用哪种编码格式并不重要。 - -规范化速度很快,但您可能希望使用缓存作为比较函数的输入以避免多次对同一字符串进行规范化。如果该字符串不存在于缓存中,则将其规范化并缓存它。注意不要存储或保留缓存,仅将其用作缓存。 - -请注意,使用 `normalize()` 要求您的 Node.js 版本包括 ICU(否则 `normalize()` 函数将只返回原始字符串)。如果您从网站下载最新版本的 Node.js,那么它将包括 ICU。 - -## 时间戳解析 - -您可以将文件的 `mtime`(修改后的时间)设置为 `1444291759414`(毫秒分辨率),有时会惊讶地看到 `fs.stat` 返回新的 mtime 为 `1444291759000`(1 秒分辨率)或 `1444291758000`(2 秒分辨率)。这不是 Node.js 的 bug。Node.js 在文件系统存储时返回时间戳,而不是所有文件系统都支持纳秒、毫秒或 1 秒的时间戳解析。某些文件系统甚至对 atime 有非常粗略的分辨率。例如,某些 FAT 文件系统的 24 小时。 - -## 不要通过规范化来损坏文件名和时间戳 - -文件名和时间戳是用户数据。正如您永远不会自动将用户文件数据重写为大写的数据,或把 `CRLF` 转化为 `LF` 进行规范化一样,您永远不应更改、干扰或损坏文件名或时间戳。方式是大小写 / Unicode 格式 / 时戳规范化。规范化只应用于比较,而不应用于更改数据。 - -规范化实际上是一个有损的哈希代码。您可以使用它来测试某些类型的等价性(例如,即使它们有不同的字节序列,也可以使用多个字符串看起来相同)。但您永远不能将其用作实际数据的替代。您的程序应根据需要传递文件名和时间戳数据。 - -您的程序可以在 NFC(或它喜欢的任何 Unicode 形式组合)中创建新数据,或使用小写或大写的文件名,或者使用 2 秒的分辨率时间戳。但程序不应通过强制大小写 / Unicode 编码 / 时间戳规范化来损坏现有用户数据。相反,在程序中采用超集方法并保留大小写、Unicode 窗体和时间戳解析。这样您就能够安全地与执行同样操作的文件系统进行交互。 - -## 适当地使用规范化比较函数 - -请确保适当地使用大小写敏感 / Unicode 编码 / 时间戳比较函数。如果正在处理区分大小写的文件系统,请不要使用不区分大小写的文件名比较函数。如果正在处理 Unicode 编码敏感的文件系统(例如 NTFS 和大多数 Linux 文件系统,同时保留 NFC 和 NFD 或混合 Unicode 编码),则不要使用 Unicode 表单不敏感的比较函数。如果您正在使用纳秒时间戳解析文件系统,则不要将时间戳与 2 秒分辨率进行比较。 - -## 为比较函数的细微差别做好准备 - -请注意,您的比较函数与文件系统的功能匹配(或者,如果可能的话,可以探测文件系统,以查看它如何实际进行比较的)。例如,不区分大小写比简单的 `toLowerCase()` 复杂。事实上 `toUpperCase()` 通常比 `toLowerCase()` 好(因为它处理某些外语字符的方式不同)。但是最好还是探测文件系统,因为每个文件系统都有自己的编码比较表。 - -例如,苹果的 HFS+ 将文件名规范化为 NFD 形式,但此 NFD 表单实际上是当前 NFD 表单的较旧版本,有时可能与最新的 Unicode 标准的 NFD 形式稍有不同。不要期望 HFS+ NFD 和 Unicode NFD 总是完全相同的。 diff --git a/pages/zh-cn/docs/index.mdx b/pages/zh-cn/docs/index.mdx deleted file mode 100644 index 1255cd4f31f53..0000000000000 --- a/pages/zh-cn/docs/index.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: 相关文档 -layout: docs.hbs -labels: - lts: LTS ---- - -# 关于本文档 - -该网站上有几种类型的文档: - -- API 函数接口文档 -- ES6 特性 -- 上手指南 -- 相关依赖项 - -## API 函数接口文档 - -[API 参考文档](https://nodejs.org/api/) 提供了关于 Node.js 中函数或对象的详细信息。 本文档告诉你某一种方法接受了哪些参数、该方法的返回值以及可能与该方法有关的错误。 它还指出了各种不同版本的 Node.js 可用的方法。 - -此文档描述了 Node.js 提供的内置模块。它不记录社区提供的模块。 - -
- -### 寻找先前发布的 API 文档? - - - -[全部已发布的 Nodejs 文档](https://nodejs.org/docs/) - -
- -## ES6 特性 - -[ES6 部分](/zh-cn/docs/es6/) 描述了三个 ES6 功能组,以及在 Node.js 中默认启用的功能细节。除了解释性链接,它还指示你如何根据特定版本的 Node.js 找到与之对应版本的 V8。 - -## 上手指南 - -[上手指南](/zh-cn/docs/guides/)包含关于 Node.js 技术特征和能力的长期、深入的文章。 - -## 相关依赖项 - -Node.js 依赖于 Node.js 代码本身以外的附加组件。这些[相关依赖项](https://github.com/nodejs/node/blob/main/doc/contributing/main/contributing/defining/main-dependencies)提供原生代码和 JavaScript 代码,并且在 `src` 和 `lib` 目录下与代码一起构建,以创建 Node.js 二进制文件。 diff --git a/pages/zh-cn/download/current.md b/pages/zh-cn/download/current.md deleted file mode 100644 index 0461bdc036d82..0000000000000 --- a/pages/zh-cn/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: 下载 -download: 下载 -downloads: - headline: 下载 - lts: 长期维护版 - current: 最新尝鲜版 - tagline-current: 含最新功能 - tagline-lts: 推荐多数用户使用 - display-hint: 下载版本: - intro: > - 在你的平台上下载 Node.js 源码或预编译安装包,然后即可马上进行开发。 - currentVersion: 最新尝鲜版 - buildInstructions: 在所有支持的平台上,从源代码构建Node.js - WindowsInstaller: Windows 安装程序 - WindowsBinary: Windows 二进制文件 - MacOSInstaller: macOS 安装程序 - MacOSBinary: macOS 二进制文件 - LinuxBinaries: Linux 二进制文件 - SourceCode: 源代码文件 -additional: - headline: 其它平台 - intro: > - Node.js 社区为其它平台维护非官方的构建。请注意这些构建并不受 Node.js 核心团队技术支持,且可能尚未跟 Node.js 的最新尝鲜版保持一致。 - platform: 平台 - provider: 提供者 - SmartOSBinaries: SmartOS 二进制文件 - DockerImage: Docker 镜像 - officialDockerImage: 官方 Node.js Docker 镜像 - LinuxPowerSystems: Power LE Systems 上的 Linux - LinuxSystemZ: System z 上的 Linux - AIXPowerSystems: Power Systems 上的 AIX ---- diff --git a/pages/zh-cn/download/index.md b/pages/zh-cn/download/index.md deleted file mode 100644 index 93207c7d52374..0000000000000 --- a/pages/zh-cn/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: 下载 -download: 下载 -downloads: - headline: 下载 - lts: 长期维护版 - current: 最新尝鲜版 - tagline-current: 含最新功能 - tagline-lts: 推荐多数用户使用 - display-hint: 下载版本: - intro: > - 在你的平台上下载 Node.js 源码或预编译安装包,然后即可马上进行开发。 - currentVersion: 最新长期维护版 - buildInstructions: 在所有支持的平台上,从源代码构建Node.js - WindowsInstaller: Windows 安装程序 - WindowsBinary: Windows 二进制文件 - MacOSInstaller: macOS 安装程序 - MacOSBinary: macOS 二进制文件 - LinuxBinaries: Linux 二进制文件 - SourceCode: 源代码文件 -additional: - headline: 其它平台 - intro: > - Node.js 社区为其它平台维护非官方的构建。请注意这些构建并不受 Node.js 核心团队技术支持,且可能尚未跟 Node.js 的当前维护版本保持一致。 - platform: 平台 - provider: 提供者 - SmartOSBinaries: SmartOS 二进制文件 - DockerImage: Docker 镜像 - officialDockerImage: 官方 Node.js Docker 镜像 - LinuxPowerSystems: Power LE Systems 上的 Linux - LinuxSystemZ: System z 上的 Linux - AIXPowerSystems: Power Systems 上的 AIX ---- diff --git a/pages/zh-cn/download/package-manager.md b/pages/zh-cn/download/package-manager.md deleted file mode 100644 index 0bbc9af802fff..0000000000000 --- a/pages/zh-cn/download/package-manager.md +++ /dev/null @@ -1,396 +0,0 @@ ---- -layout: page.hbs -title: 通过包管理器安装 Node.js ---- - -# 通过包管理器方式安装 Node.js - -**_注意:_** 此页面上所有的安装包均有它们各自作者,**非** Node.js 核心团队负责进行维护和支持。如遇任何问题,请直接向有关作者报告。 如你的问题被证实是因为 Node.js 的缺陷引发的,维护者将直接向 Node.js 汇报此问题。 - ---- - -- [Alpine Linux](#alpine-linux) -- [Android](#android) -- [Arch Linux](#arch-linux) -- [CentOS, Fedora 和 Red Hat Enterprise Linux](#centos-fedora-和-red-hat-enterprise-linux) -- [基于 Linux 发布的 Debian 和 Ubuntu](#基于-linux-发布的-debian-和-ubuntu) -- [fnm](#fnm) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [nvm](#macos) -- [n](#n) -- [NetBSD](#netbsd) -- [Nodenv](#nodenv) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE 和 SLE](#opensuse-和-sle) -- [SmartOS 和 illumos](#smartos-和-illumos) -- [Snap](#snap) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) -- [z/OS](#zos) - ---- - -## Alpine Linux - -Node.js 以及 npm 包管理器在社区库中可如下方式使用: - -```bash -pkg install nodejs -pkg install nodejs-current -``` - -Node.js Current 可以从社区仓库安装。 - -```bash -pacman -S nodejs npm -``` - -## Android - -因为 Android 版的 Node.js 目前处于实验阶段,所以当下不提供预编译版本。 - -但是你有一些第三方的解决方案可供选择:拿 [Termux](https://termux.com/) 来说,它为安卓提供了终端模拟器和 Linux 环境,以及内置的包管理器和[可扩展应用集](https://github.com/termux/termux-packages),其中包含了大量预编译的应用。在 Termux 中,以下的命令将会安装最新版 Node.js: - -```bash -dnf module install nodejs: -``` - -目前,Termux 的 Node.js 二进制程序包与 `system-icu` (依赖于 `libicu` 包)相关联。 - -## Arch Linux - -Node.js 以及 npm 包管理器在社区库中可如下方式使用: - -```bash -pacman -S nodejs npm -``` - -## CentOS, Fedora 和 Red Hat Enterprise Linux - -Node.js可以在 CentOS/RHEL 8 和 Fedora 中作为名为 `nodejs` 的模块使用。 - -```bash -dnf module install nodejs: -``` - -其中 `` 对应于Node.js的主要版本。 要查看可使用如下命令: - -```bash -dnf module list nodejs -``` - -例如,安装 Node.js 18: - -```bash -dnf module install nodejs:18/common -``` - -### 可替换项 - -这些资源提供了与CentOS、Fedora和RHEL兼容的包。 - -- [Node.js 快照](#snap) 在 https://github.com/nodejs/snap 得到支持和维护。 -- [Node.js 二进制发布版](#debian-and-ubuntu-based-linux-distributions) 通过 [NodeSource](https://github.com/nodesource/distributions) 得到维护支持。 - -## 基于 Linux 发布的 Debian 和 Ubuntu - -[Node.js 二进制发行版](https://github.com/nodesource/distributions) 可从 NodeSource 获得。 - -### 可替换项 - -兼容基于 Debian 和 Ubuntu 的 Linux 发行版的软件包可通过 [Node.js snaps](#snap) 获取。 - -## fnm - -快速和简单的 Node.js 版本管理器构建于Rust 中,用于管理多个发布的 Node.js 版本。 它允许您执行安装、卸载、自动根据当前目录切换节点版本等操作。 要安装 fnm, 请使用此 [安装脚本](https://github.com/Schniz/fnm#using-a-script-macoslinux)。 - -fnm 有跨平台支持 (macOS, Windows, Linux) & 所有流行炮弹(Bash, Zsh, Fish, PowerShell, Windows 命令行提示)。 fnm 是用速度构建的,并支持 `.node-version` 和 `.nvmrc` 文件。 - -## FreeBSD - -最新发布的 Node.js 通过 [www/node](https://www.freshports.org/www/node) 端口可用。 - -通过 [pkg](https://www.freebsd.org/cgi/man.cgi?pkg) 安装二进制软件包: - -```bash -pkg install node -``` - -或者使用 [ports](https://www.freebsd.org/cgi/man.cgi?ports) 来自行编译: - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js 在 portage tree 中可用。 - -```bash -emerge nodejs -``` - -## IBM i - -Node.js的LTS版本可从IBM获取,可通过 [“yum”软件包管理器](https://ibm.biz/ibmi-rpms)获取。 软件包名称是 `nodejs` 后面是主要版本号 (例如) `nodejs12`, `nodejs14` 等) - -要从命令行安装 Node.js 14.x,请以 \*ALLOBJ 特殊授权用户模式下,运行以下命令: - -```bash -emerge nodejs -``` - -Node.js也可以通过IBM i Access Client Solutions 产品安装。请参阅 [此支持文档](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) 了解更多详情 - -## macOS - -直接从 [nodejs.org](https://nodejs.org/) 网站下载 [macOS Installer](https://nodejs.org/en/#home-downloadhead) - -_如果你想用命令行的方式安装:_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### 可替代方案 - -使用 **[自制程序](https://brew.sh/)**: - -```bash -brew install node -``` - -使用 **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# Example -port install nodejs7 -``` - -使用 **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -安装二进制软件包: - -```bash -pkgin -y install nodejs -``` - -或从 pkgsrc 手动构建: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## n - -`n` 是一个简单的使用 Node.js 版本管理器为 Mac 和 Linux 。 指定要安装的目标版本使用丰富的语法 或者从先前下载的版本的菜单中选择。 版本安装在全系统或用户范围内,对于更多的 目标用途,您可以直接从缓存下载运行版本。 - -请参阅 [主页](https://github.com/tj/n) 以获取安装方法 (bootstrap, npm, Homebrew, 第三方) 以及所有使用详细信息。 - -如果您已经有 `npm` 然后安装 `n` : - -``` -npm install -g n -n lts -``` - -## NetBSD - -Node.js 在 pkgsrc 树中可用: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -或者使用 pkgin 安装二进制软件包(如果您的平台可用): - -```bash -pkgin -y install nodejs -``` - -## Nodenv - -`nodenv` 是一个轻量级节点版本管理器,类似于 `nvm`。 它是简单和可预测的。一个丰富的插件生态系统可以让你裁剪它来满足你的需要。 使用 `nodenv` 为您的应用程序选择节点版本,并保证您的开发环境与生产相符。 - -Nodenv 安装程序通过[此GitHub 页](https://github.com/nodenv/nodenv#installation)进行维护。请访问并确保你完全遵循了最新版本的安装步骤。 - -## nvm - -节点版本管理器是一个基础脚本,用于管理多个发布的 Node.js 版本。 它允许 您执行诸如安装、卸载、切换版本等操作。 要安装 nvm,请使用 [安装脚本](https://github.com/nvm-sh/nvm#install--update-script)。 - -在 Unix / OS X 系统节点。 可以通过 [nvm](https://github.com/creationix/nvm) 通过安装到 nvm 期望的位置来安装源代码生成: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -在此之后,您可以使用 `nvm` 来切换发布版本和从源代码生成的 版本。 例如,如果Node.js版本是 v8.0.0-pre: - -```bash -nvm use 8 -``` - -一旦正式发行完毕,您将想要从源代码卸载生成的 版本: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -`nvs` 版本管理器是跨平台的,可以在 Windows 、 macOS 和 Unix 式系统上使用 - -若要在Windows上安装 `nvs` ,请到这里的 [发布页面](https://github.com/jasongin/nvs/releases) 并下载最新版本的 MSI安装程序文件。 - -您也可以使用 `chocolatey` 来安装它: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -您可以在这里的macOS/ Unix式系统 [找到关于 `nvs` 安装步骤的文档](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) - -#### 使用方法 - -在此之后,您可以使用 `nvs` 在不同版本的节点之间切换。 - -要添加最新版本的 Node: - -```bash -nvs add latest -``` - -或者添加最新的 LTS Node 版本: - -```bash -nvs add lts -``` - -然后运行 `nvs 使用` 命令将节点版本添加到您 `PATH` 当前shell: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -要永久添加到 `PATH` ,请使用 `nvs 链接`: - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js可以通过 Ports 系统获得。 - -```bash -/usr/ports/lang/node -``` - -在 OpenBSD 上使用 [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) - -```bash -pkg_add node -``` - -## openSUSE 和 SLE - -Node.js在以下软件包的主仓库中可用: - -- **openSUSE Leap 15.2**: `nodejs10`, `nodejs12`, `nodejs14` -- **openSUSE Tumbleweed**: `nodejs16` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs10`, `nodejs12`, and `nodejs14` ("Web and Scripting Module" 必须是 [启用](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12-SP5/#intro-modulesExtensionsRelated)状态) -- **SUSE Linux Enterprise Server (SLES) 15**: `nodejs10`, `nodejs12`, and `nodejs14` ("Web and Scripting Module" 必须是 [启用](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/15/#Intro.Module)状态) - -例如,若要在 openSUSE Leap 15.2上安装 Node.js 14.x,请以 root 身份运行以下命令: - -```bash -zypper install nodejs14 -``` - -可以同时安装和使用不同版本的节点。 - -## SmartOS 和 illumos - -SmartOS 镜像与 pkgsrc 是一起被预安装的。在其他illumos 发行版上,首先安装 **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**,然后您可以按照正常情况安装二进制软件包: - -```bash -pkgin -y install nodejs -``` - -或从 pkgsrc 手动构建: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Snap - -[Node.js snaps](https://github.com/nodejs/snap)在 Snap 商店的[`node`](https://snapcraft.io/node)中获取。 - -## Solus - -在主版本库中 Solus 提供了 Node.js,所以你可以这样安装: - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux 在主仓库中映射了 Node.js 一些稳定的功能。 - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -直接从 [nodejs.org](https://nodejs.org/) 网站下载 [Windows 安装程序](https://nodejs.org/en/#home-downloadhead) - -### 可替代方案 - -使用 **[Winget](https://aka.ms/winget-cli)**: - -```bash -winget install OpenJS.NodeJS -# or for LTS -winget install OpenJS.NodeJS.LTS -``` - -运行了上述两个命令中的一个。 可能需要在 `节点` CLI 命令可用之前重启终端仿真器。 - -使用 **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# or for full install with npm -cinst nodejs.install -``` - -使用 **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -# or for LTS -scoop install nodejs-lts -``` - -## z/OS - -IBM® SDK for Node.js - z/OS® 可用两种安装格式。 SMP/E 和 PAX 。 选择适用于您的安装格式: - -- [在 z/OS 上安装配置 Node.js 的 SMP/E 版本](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-smpe-edition) -- [在 z/OS 上安装和配置Node.js 的 PAX 版](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-pax-edition) diff --git a/pages/zh-cn/download/releases.md b/pages/zh-cn/download/releases.md deleted file mode 100644 index 8ab53ef82fa68..0000000000000 --- a/pages/zh-cn/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: 以往的版本 -modules: 'NODE_MODULE_VERSION 指的是 Node.js 的 ABI (application binary interface) 版本号,用来确定编译 Node.js 的 C++ 库版本,以确定是否可以直接加载而不需重新编译。在早期版本中其作为一位十六进制值来储存,而现在表示为一个整数。' ---- - -### io.js 与 Node.js - -1.x 到 3.x 版本被叫做 “io.js”,因为它们属于 io.js 的分支。从 Node.js 4.0.0 开始,之前版本的 io.js 与 Node.js 0.12.x 合并到统一的 Node.js 发行版中。 - -### 正在寻找某个版本的最新版? diff --git a/pages/zh-cn/get-involved/collab-summit.md b/pages/zh-cn/get-involved/collab-summit.md deleted file mode 100644 index d956ec4587aa8..0000000000000 --- a/pages/zh-cn/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 协作者峰会 -layout: contribute.hbs ---- - -# 协作者峰会 - -协作者峰会是一个非正式的会议,其目的在于让现有及具有潜力的协作者齐聚一堂,让大家以现场协作、教学及分享知识的方式一同讨论 Node.js。委员会及工作组每年有两次聚会,他们会一起做出重要的决定,同时推动一些令人期待的任务。 - -## 谁可以参与呢? - -欢迎所有人参加。峰会期间,组长们会在新进的协作者融入工作议程之前协助他们加入想要贡献的群组。 - -这是一个你可以学习社群事务的好机会,同时也能贡献及精进你的技能。在进行现场分组讨论之前,工作组会先安排行程好让人们可以互相熟悉对方。 - -工作组将编排一个日程表,以便人们能够在会议开始之前各自相互熟悉, 进行一般的合作者讨论,然后正式进入会议。 - -期待能与你在协作者峰会中相见![峰会回顾](https://github.com/nodejs/summit)中有即将到来及过往的协作者峰会信息,请记得看看[议题](https://github.com/nodejs/summit/issues),里面分享了个别工作组及委员会的讨论。 diff --git a/pages/zh-cn/get-involved/contribute.md b/pages/zh-cn/get-involved/contribute.md deleted file mode 100644 index 596e8238d438f..0000000000000 --- a/pages/zh-cn/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: 贡献 -layout: contribute.hbs ---- - -# 贡献 - -非常感谢你对于 Node.js 有兴趣而来做贡献!你有多种方式和可以做贡献的地方,我们也很乐意协助你找到这些地方和方法。 - -## 寻求一般的帮助 - -由于 `nodejs/node` 项目活跃度极高,若有功能请求或 Node.js 使用中有问题,请转至 [Node.js 帮助](https://github.com/nodejs/help/issues)。 - -## 汇报问题 - -如果你觉得你发现了 Node.js 的问题,请立即至 GitHub 项目中创建一个议题,不过要确保你的议题可以完整地陈述问题,且可依照你提供的步骤重现该问题,重现步骤不该包含任何外部想依赖的组件,也就是说,重现步骤不需使用 Node.js 以外的东西就能执行。 - -汇报问题时我们也需要一些关于执行环境的信息,我们不知道确切哪些信息是我们要的,所以请至少提供下列几项信息: - -- Node.js 的版本号 -- 当前运行的操作系统(macOS、SmartOS、Linux、Windows) -- 计算机架构体系(32 位还是 64 位;x86 或 ARM) - -目前 Node.js 项目分散在一些 GitHub 仓库中个别管理,每个仓库都有自己的议题数据库。 如果可以的话,请将你的问题汇报至适合的仓库,但也别怕不小心发错地方,我们的社群会很热心帮你找到对的地方。 - -- 若要汇报有关 Node.js 的问题,请到 [nodejs/node](https://github.com/nodejs/node)。 -- 若要汇报本网站的问题,请到 [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues)。 - -## 代码贡献者 - -若你想要协助 Node.js 修复缺陷或是增加新功能,请确保你已仔细阅读 [Node.js 贡献指南](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests),里面也解释了贡献至本项目并等待协作者审核的详细过程。 - -如果你想知道该从何开始,你可以参考 [Node 该做什么列表](https://www.nodetodo.org/),它可以引导你迈向你的第一个贡献。 - -## 如何成为一个协作者? - -协作者的影响力可扩及整个项目,成为协作者后将能审核他人的贡献内容、将问题进行分类,及策划项目未来。因重大贡献而被 TSC 认可的开发者可能会被授与项目协作者身份及享有项目的代码提交权限,重大贡献的评估标准如(包括但不限于)下方所列: - -- 代码提交以及 Pull Requests -- 文档修订提交及 Pull Requests -- 对问题的评论及 Pull Requests -- 对 Node.js 网站的贡献 -- 提供给终端用户及初学贡献者的帮助 -- 参与工作组 -- 参与其它 Node.js 社区群 - -若你自己认为已经做出重大贡献,却没有被授予提交权限,你可以尝试[开启 TSC 议题](https://github.com/nodejs/TSC/issues)或[直接联系 TSC 成员](https://github.com/nodejs/TSC#current-members)以获得相应权限。 diff --git a/pages/zh-cn/get-involved/index.md b/pages/zh-cn/get-involved/index.md deleted file mode 100644 index 84663c1bd457d..0000000000000 --- a/pages/zh-cn/get-involved/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 加入我们 -layout: contribute.hbs ---- - -# 加入我们 - -## 社区讨论 - -- [GitHub 议题清单](https://github.com/nodejs/node/issues)是讨论 Node.js 核心功能的好地方。 -- 想实时聊聊关于 Node.js 开发方面的内容,可以使用下列某一平台: - - 使用 IRC,请使用 [IRC 客户端](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients),转到 `irc.libera.chat` 中的 `#node.js` 頻道,或者在您的浏览器中使用 [Web 客户端](https://kiwiirc.com/nextclient/) 直接连接即可。 - - 使用 Slack,有两种选项: - - [OpenJSF Slack](https://slack-invite.openjsf.org/) 包含多个 Node.js 频道(带有 `#nodejs-` 前缀的都是与此项目相关)。 - - [Node Slackers](https://www.nodeslackers.com/) 是在 Slack 上针对 Node.js 的社区。 -- Node.js 官方的 Twitter 账号:[nodejs](https://twitter.com/nodejs). -- [Node.js 项目日历](https://nodejs.org/calendar) 是有关于所有 Node.js 团队会议的相关日程安排。 - -## 学习资源 - -- [官方 API 参考文档](https://nodejs.org/api/)中详细介绍了 Node 的 API 函数。 -- [NodeSchool.io](https://nodeschool.io/) 通过互动命令的方式教会你 Node.js 的概念。 -- [Stack Overflow Node.js tag](https://stackoverflow.com/questions/tagged/node.js) 每日收集最新资讯。 -- [The DEV Community Node.js tag](https://dev.to/t/node) 是一个共享 Node.js 项目、文章和教程,以及开始讨论并接受与 Node.js 相关的主题,我们欢迎任何级别的开发人员加入其中。 -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) 是一个 Node.js 后端开发者在 Discord 上互相支援的友好社区。 diff --git a/pages/zh-cn/index.md b/pages/zh-cn/index.md deleted file mode 100644 index 94fa98509adfa..0000000000000 --- a/pages/zh-cn/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: 最新尝鲜版 - download: 下载 - download-for: 下载平台为: - other-downloads: 其它下载 - current: 最新尝鲜版 - lts: 长期维护版 - tagline-current: 含最新功能 - tagline-lts: 推荐多数用户使用 - changelog: 更新日志 - api: API 文档 - version-schedule-prompt: 可参考 - version-schedule-prompt-link-text: 长期维护版(LTS)日程 ---- - -Node.js® 是一个开源、跨平台的 JavaScript 运行时环境。 diff --git a/pages/zh-tw/404.md b/pages/zh-tw/404.md deleted file mode 100644 index 407bf446808bd..0000000000000 --- a/pages/zh-tw/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404:找不到網頁 - -### ENOENT:無此檔案或目錄 diff --git a/pages/zh-tw/about/governance.md b/pages/zh-tw/about/governance.md deleted file mode 100644 index 06affab5771ea..0000000000000 --- a/pages/zh-tw/about/governance.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: 專案管理 -layout: about.hbs ---- - -# 專案管理 - -## 尋求共識的流程 - -Node.js 專案遵循 [Consensus Seeking][](尋求共識)的決策模式。 - -## 協作者 - -[nodejs/node][] 核心的 GitHub 由協作者維護,這些協作者則由 [TSC(Technical Steering Committee,技術指導委員會)][]選出。 - -對專案做出重大及有價值的貢獻之開發者將可被任命為協作者,並會給予專案的 commit 權限。這些開發者由 TSC 選出,並由現任的協作者討論其提名。 - -現任的協作者清單請見專案之 [README.md][]。 - -給協作者的指南請見 [collaborator-guide.md][]。 - -## 最高委員會 - -此專案由 [TSC][] 及 [CommComm][](Community Committee)聯合治理,前者負責此專案較高層級的指導,後者則負責一般指導及擴展 Node.js 社群。 - -[collaborator-guide.md]: https://github.com/nodejs/node/blob/main/doc/contributing/collaborator-guide.md -[CommComm]: https://github.com/nodejs/community-committee/blob/master/Community-Committee-Charter.md -[Consensus Seeking]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[README.md]: https://github.com/nodejs/node/blob/main/README.md#current-project-team-members -[TSC]: https://github.com/nodejs/TSC/blob/master/TSC-Charter.md -[TSC(Technical Steering Committee,技術指導委員會)]: https://github.com/nodejs/TSC -[nodejs/node]: https://github.com/nodejs/node diff --git a/pages/zh-tw/about/index.md b/pages/zh-tw/about/index.md deleted file mode 100644 index d6837cd7effb6..0000000000000 --- a/pages/zh-tw/about/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -layout: about.hbs -title: 關於 -trademark: Trademark ---- - -# 關於 Node.js® - -作為一個非同步事件驅動的 JavaScript 執行環境,Node.js 被設計來打造可擴充的網路應用程式。下方的 hello world 範例可以處理多個併發的連線,每個連線都會觸發回呼函式,但若沒有任務可執行,Node.js 就會進入休眠。 - -```javascript -const http = require('http'); - -const hostname = '127.0.0.1'; -const port = 3000; - -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello World'); -}); - -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); -}); -``` - -這與目前常見使用作業系統行程的併發模型形成鮮明對比,基於行程的網路操作相較之下更沒效率也更難使用。除此之外,因為沒有結的存在,Node.js 的使用者毋須擔心行程死結(deadlock)的問題。Node.js 中幾乎所有的函式都不能直接操作 I/O,因此行程從不阻塞,也因不阻塞,可擴充的系統在 Node.js 中也就水到渠成。 - -若你仍對上述說明有不清楚的地方,請參閱[阻塞 vs. 非阻塞][]。 - ---- - -Node.js 的設計上受到 Ruby [Event Machine][] 和 Python [Twisted][] 的啟發,且更近一步將[事件迴圈][]作為一個執行環境中的結構,而非一個函式庫。在其他系統中,事件迴圈開始前都會有個阻塞的呼叫。 - -通常執行的行為是透過腳本開頭的回呼函式定義的,接著再透過像 `EventMachine::run()` 這樣的阻塞呼叫來啟動伺服器,在 Node.js 中並沒有這樣的啟動事件迴圈呼叫,Node.js 在執行輸入的腳本後會直接進入事件迴圈,並在沒有任何回呼函式可呼叫時退出事件迴圈,這樣的行為就跟在瀏覽器中的 JavaScript 一樣,整個事件迴圈都在背後進行。 - -HTTP 是 Node.js 世界中的一等公民,設計之初就考量到了 stream 及低延遲,這使的 Node.js 相當適合作為網頁函式庫或框架的基礎。 - -[阻塞 vs. 非阻塞]: /en/docs/guides/blocking-vs-non-blocking/ -[事件迴圈]: /en/docs/guides/event-loop-timers-and-nexttick/ -[Event Machine]: https://github.com/eventmachine/eventmachine -[Twisted]: https://twistedmatrix.com/trac/ diff --git a/pages/zh-tw/docs/index.mdx b/pages/zh-tw/docs/index.mdx deleted file mode 100644 index cc2b584f94ebc..0000000000000 --- a/pages/zh-tw/docs/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: 文件 -layout: docs.hbs -labels: - lts: LTS ---- - -# 關於文件 - -本站提供下列幾種類型的文件: - -- API 參考文件 -- ES6 功能 -- 技術指南 - -## API 參考文件 - -[API 參考文件](https://nodejs.org/api/)提供了 Node.js 中的函式或物件的詳細資訊。此文件詳述了一個方法可接受哪些參數、其回傳值及哪些錯誤可能與之關聯,同時也記錄了在哪些 Node.js 版本中可使用此方法。 - -此文件僅會介紹由 Node.js 官方內建的模組,社群提供的模組則不在此列。 - -
- -### 在找舊版的 API 文件嗎? - - - -[所有版本](https://nodejs.org/docs/) - -
- -## ES6 功能 - -[ES6 章節](/zh-tw/docs/es6/)中介紹了三個 ES6 的特色群組以及 Node.js 預設啟用哪些功能的細節並附上連結。此章節也示範了如何查詢某版 Node.js 中的 V8 版本。 - -## 技術指南 - -[技術指南章節](/zh-tw/docs/guides/)中會深入且詳細地說明 Node.js 技術特點及功能。 diff --git a/pages/zh-tw/download/current.md b/pages/zh-tw/download/current.md deleted file mode 100644 index b6172e444ad9f..0000000000000 --- a/pages/zh-tw/download/current.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download-current.hbs -title: 下載 -download: 下載 -downloads: - headline: 下載 - lts: LTS - current: 目前版本 - tagline-current: 最新功能 - tagline-lts: 建議大部分使用者使用 - display-hint: 顯示 - intro: > - 下載適合您平台的 Node.js 原始碼或安裝套件。立刻開始使用 Node.js。 - currentVersion: 最新版 - buildInstructions: 在支援的平台上,使用原始碼建構 Node.js - WindowsInstaller: Windows 安裝包 - WindowsBinary: Windows 二進位檔案 - MacOSInstaller: macOS 安裝包 - MacOSBinary: macOS 二進位檔案 - LinuxBinaries: Linux 二進位檔案 - SourceCode: 原始碼 -additional: - headline: 其它平台 - intro: > - Node.js 社群為其它平台維護的非官方建構。請注意 Node.js 團隊並不為這些建置版本提供技術支援且其可能與現行 Node.js 版本不一致。 - platform: 平台 - provider: 提供者 - SmartOSBinaries: SmartOS 二進位檔案 - DockerImage: Docker 映像檔 - officialDockerImage: Node.js 官方 Docker 映像檔 - LinuxPowerSystems: 建置在 Power LE Systems 上的 Linux - LinuxSystemZ: 建置在 System z 上的 Linux - AIXPowerSystems: 建置在 Power Systems 上的 AIX ---- diff --git a/pages/zh-tw/download/index.md b/pages/zh-tw/download/index.md deleted file mode 100644 index 42235d09a6aa8..0000000000000 --- a/pages/zh-tw/download/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: download.hbs -title: 下載 -download: 下載 -downloads: - headline: 下載 - lts: LTS - current: 目前版本 - tagline-current: 最新功能 - tagline-lts: 建議大部分使用者使用 - display-hint: 顯示 - intro: > - 下載適合您平台的 Node.js 原始碼或安裝套件。立刻開始使用 Node.js。 - currentVersion: 最新版 - buildInstructions: 在支援的平台上,使用原始碼建構 Node.js - WindowsInstaller: Windows 安裝程式 - WindowsBinary: Windows 二進位檔案 - MacOSInstaller: macOS 安裝程式 - MacOSBinary: macOS 二進位檔案 - LinuxBinaries: Linux 二進位檔案 - SourceCode: 原始碼 -additional: - headline: 其它平台 - intro: > - Node.js 社群為其它平台維護的非官方組建。請注意 Node.js 團隊並不為這些組建版本提供技術支援且其可能與現行 Node.js 版本不一致。 - platform: 平台 - provider: 提供者 - SmartOSBinaries: SmartOS 二進位檔案 - DockerImage: Docker 映像檔 - officialDockerImage: Node.js 官方 Docker 映像檔 - LinuxPowerSystems: 建置在 Power LE Systems 上的 Linux - LinuxSystemZ: 建置在 System z 上的 Linux - AIXPowerSystems: 建置在 Power Systems 上的 AIX ---- diff --git a/pages/zh-tw/download/package-manager.md b/pages/zh-tw/download/package-manager.md deleted file mode 100644 index 7078434555338..0000000000000 --- a/pages/zh-tw/download/package-manager.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -layout: page.hbs -title: 使用套件管理器安裝 Node.js ---- - -# 使用套件管理器安裝 Node.js - -**_請注意:_** 下列的套件維護及支援 **並非由** Node.js 核心團隊提供,任何套件使用上的問題,應直接聯絡各套件的維護者,若發現問題出於 Node.js 本身,則應由套件維護者聯絡上游。 - ---- - -- [Android](#android) -- [Arch Linux](#arch-linux) -- [Debian 及 Ubuntu 系列發行版,企業版 Linux/Fedora 和 Snap packages](#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages) -- [FreeBSD](#freebsd) -- [Gentoo](#gentoo) -- [IBM i](#ibm-i) -- [NetBSD](#netbsd) -- [nvm](#nvm) -- [nvs](#nvs) -- [OpenBSD](#openbsd) -- [openSUSE 及 SLE](#opensuse-and-sle) -- [macOS](#macos) -- [SmartOS 及 illumos](#smartos-and-illumos) -- [Solus](#solus) -- [Void Linux](#void-linux) -- [Windows](#windows-1) - ---- - -## Android - -Android 的 Node.js 支援仍是試驗版,因此 Node.js 開發者尚未提供預先編譯的二進位檔。 - -但社群提供了第三方的解決方式,舉例來說,[Termux](https://termux.com/) 社群提供了終端機模擬器及 Android 的 Linux 環境,也有自己的套件管理器及許多預先編譯的[程式清單](https://github.com/termux/termux-packages)。 - -下列的指令在 Termux 中分別會安裝 Node.js LTS 版及最新版: - -```bash -pkg install nodejs -pkg install nodejs-current -``` - -目前,Termux 的 Node.js 二進位套裝程式與 `system-icu`(相依於 `libicu` 套件)相關聯。 - -## Arch Linux - -Node.js 及 npm 套件可由公有軟體庫取得。 - -```bash -pacman -S nodejs npm -``` - -## Debian 及 Ubuntu 系列發行版,企業版 Linux/Fedora 和 Snap packages - -[官方 Node.js 二進位發行版](https://github.com/nodesource/distributions) 透過 NodeSource 提供. - -## FreeBSD - -近期的版本已可透過 [www/node](https://www.freshports.org/www/node) port 取得 Node.js。 - -透過 [pkg](https://www.freebsd.org/cgi/man.cgi?pkg) 安裝二進位套件: - -```bash -pkg install node -``` - -或者透過 [ports](https://www.freebsd.org/cgi/man.cgi?ports) 編譯你自己的版本: - -```bash -cd /usr/ports/www/node && make install -``` - -## Gentoo - -Node.js 可透過 portage 樹取得: - -```bash -emerge nodejs -``` - -## IBM i - -IBM 提供了 Node.js 的長期支援版(LTS)並可透過 [yum 套件管理器](https://ibm.biz/ibmi-rpms)取得。套件命名規則為 `nodejs` 附加一個主版本號(如:`nodejs8` 、 `nodejs10` 或 `nodejs12` 等)。 - -若想於命令列安裝 Node.js 12.x,請以擁有 \*ALLOBJ 特殊權限的帳戶執行下列指令: - -```bash -yum install nodejs12 -``` - -Node.js 也可以透過 IBM i Access Client Solutions 產品來安裝,詳情請參閱[支援文件](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619)。 - -## NetBSD - -Node.js 可透過 pkgsrc 樹取得: - -```bash -cd /usr/pkgsrc/lang/nodejs && make install -``` - -或使用 pkgin 安裝二進位套件(若適用於你的平台的話): - -```bash -pkgin -y install nodejs -``` - -## nvm - -Node 版本管理器(Node Version Manager, nvm)是款用來管理 Node.js 多重版本的 bash 指令稿,它可讓你執行安裝、移除及切換版本等操作。 -若要安裝 NVM 可以使用此[安裝指令稿](https://github.com/nvm-sh/nvm#install--update-script)。 - -在 Unix / OS X 系統上從原始碼編譯的 Node.js 可以透過 [nvm](https://github.com/creationix/nvm) 安裝至其指定位置: - -```bash -env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" -``` - -安裝之後你便可以使用 `nvm` 切換正式版及編譯版。舉例來說若 Node.js 版本為 v8.0.0-pre: - -```bash -nvm use 8 -``` - -官方版本釋出後你將會需要移除從原始碼編譯的版本: - -```bash -nvm uninstall 8 -``` - -## nvs - -#### Windows - -`nvs` 是一個跨平台版本管理工具,可用於 Windows、macOS 以及 Unix-like 的作業系統。 - -在 Windows 上安裝 `nvs`,請到此 [發布頁](https://github.com/jasongin/nvs/releases) 下載最新發布的 MSI 安裝程式。 - -你也可以使用 `chocolatey` 進行安裝: - -```bash -choco install nvs -``` - -#### macOS,UnixLike - -你可以在 [此處](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) 找到關於在 macOS / Unix-like 作業系統的安裝步驟文件。 - -#### 使用方法 - -安裝完成後,你可以使用 `nvs` 在不同版本的 node 中來回切換。 - -新增最新版本的 node: - -```bash -nvs add latest -``` - -新增最新 LTS 版本的 node: - -```bash -nvs add lts -``` - -然後執行 `nvs use` ,為目前 shell 的 `PATH` 路徑下新增一個 node 版本: - -```bash -$ nvs use lts -PATH -= %LOCALAPPDATA%\nvs\default -PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 -``` - -如果需要永久在 `PATH` 裡新增,使用 `nvs link`: - -```bash -nvs link lts -``` - -## OpenBSD - -Node.js 可於 ports 系統中取得。 - -```bash -/usr/ports/lang/node -``` - -在 OpenBSD 上使用 [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1): - -```bash -pkg_add node -``` - -## openSUSE 及 SLE - -主要軟體庫中都提供了下列套件: - -- **openSUSE Leap 42.2**: `nodejs4` -- **openSUSE Leap 42.3**: `nodejs4`, `nodejs6` -- **openSUSE Tumbleweed**: `nodejs4`, `nodejs6`, `nodejs8` -- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs4`, `nodejs6`(必須[於安裝前加入](https://www.suse.com/documentation/sles-12/book_sle_deployment/data/sec_add-ons_extensions.html) "Web and Scripting Module") - -舉例來說,若想在 openSUSE Leap 42.2 上安裝 Node.js 4.x,用 root 權限執行下列指令: - -```bash -zypper install nodejs4 -``` - -## macOS - -只需從 [nodejs.org](https://nodejs.org/) 下載 [macOS 安裝器](https://nodejs.org/zh-tw/#home-downloadhead)即可。 - -_或者你也可以使用 bash 下載套件_ - -```bash -curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - -### 替代方案 - -使用 **[Homebrew](https://brew.sh/)**: - -```bash -brew install node -``` - -使用 **[MacPorts](https://www.macports.org/)**: - -```bash -port install nodejs - -# 範例 -port install nodejs7 -``` - -使用 **[pkgsrc](https://pkgsrc.joyent.com/install-on-osx/)**: - -安裝二進位套件: - -```bash -pkgin -y install nodejs -``` - -或從 pkgsrc 手動編譯: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## SmartOS 及 illumos - -SmartOS 映像檔已經預載了 pkgsrc,其他的 illumos 發行版則需要先**[安裝pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**,接著你就可以依照平常的方式安裝二進位套件: - -```bash -pkgin -y install nodejs -``` - -或從 pkgsrc手動編譯: - -```bash -cd pkgsrc/lang/nodejs && bmake install -``` - -## Solus - -Solus 在其主要軟體庫中提供了 Node.js。 - -```bash -sudo eopkg install nodejs -``` - -## Void Linux - -Void Linux 在其主要軟體庫中提供了 Node.js 穩定版。 - -```bash -xbps-install -Sy nodejs -``` - -## Windows - -只需從 [nodejs.org](https://nodejs.org/) 下載 [Windows 安裝器](https://nodejs.org/zh-tw/#home-downloadhead)即可。 - -### 其它方式 - -使用 **[Chocolatey](https://chocolatey.org/)**: - -```bash -cinst nodejs -# 或者是連同 npm 一起安裝 -cinst nodejs.install -``` - -使用 **[Scoop](https://scoop.sh/)**: - -```bash -scoop install nodejs -``` diff --git a/pages/zh-tw/download/releases.md b/pages/zh-tw/download/releases.md deleted file mode 100644 index 81bcf69a39157..0000000000000 --- a/pages/zh-tw/download/releases.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: download-releases.hbs -title: 先前釋出的版本 -modules: 'NODE_MODULE_VERSION 是 Node.js ABI (application binary interface) 的版本號碼,其代表編譯 Node.js 的 C++ 函式庫版本,用來確定是否不需經過重新編譯就能直接使用。早期版本號碼是個十六進位數值,現在則為一個整數。' ---- - -### io.js 與 Node.js - -1.x 到 3.x 的版本被稱為「io.js」,因為它們屬於 io.js 的分支。從 Node.js 4.0.0 開始,io.js 與 Node.js 合併到 Node.js 的發行版本中。 - -### 在找某個主要版本的最新版嗎? diff --git a/pages/zh-tw/get-involved/collab-summit.md b/pages/zh-tw/get-involved/collab-summit.md deleted file mode 100644 index 18f40b52966ee..0000000000000 --- a/pages/zh-tw/get-involved/collab-summit.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 協作者峰會 -layout: contribute.hbs ---- - -# 協作者峰會 - -協作者峰會(Collaboration Summit)是個非正式會議(un-conference),其目的在於讓現有及具有淺力的協作者齊聚一堂,讓大家以現場協作、教學及分享知識的方式一同討論 Node.js。 - -## 誰能參與? - -委員會及工作組每年有兩次聚會,他們會一起做出重要的決定,同時推動一些令人期待的任務。 - -歡迎所有人參加協作者峰會。峰會期間,組長們會在新進的協作者融入工作議程之前,協助他們加入想要貢獻的群組。 - -這是一個你可以學習社群事務的好機會,同時也能貢獻及精進你的技能。 - -在進行現場分組討論之前,工作組會先安排行程好讓人們可以互相熟悉對方。 diff --git a/pages/zh-tw/get-involved/contribute.md b/pages/zh-tw/get-involved/contribute.md deleted file mode 100644 index 524206cee11a7..0000000000000 --- a/pages/zh-tw/get-involved/contribute.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: 貢獻 -layout: contribute.hbs ---- - -# 貢獻 - -很開心你對貢獻 Node.js 感到興趣!我們在這協助你找到你能貢獻的地方及方式。 - -## 尋求一般協助 - -由於 `nodejs/node` 專案非常的活躍,若有功能請求或 Node.js 使用問題請改至 [Node.js help](https://github.com/nodejs/help/issues)。 - -## 回報問題 - -如果你覺得你發現了 Node.js 的問題,歡迎至 GitHub 專案中開啟 issue,但請確保你的 issue 完整的陳述問題,且可依照你提供的步驟重現該問題,重現步驟不該包含任何外部相依套件,也就是說重現步驟不需使用 Node.js 以外的東西就能執行。 - -回報問題時我們也需要一些關於執行環境的資訊,我們不知道確切哪些資訊是我們要的,所以請至少提供下列幾項資訊: - -- Node.js 版本 -- 作業系統(macOS、SmartOS、Linux 或 Windows) -- 你的機器架構(32bit 或 64bit 及 x86 或 ARM 等) - -目前 Node.js 專案分散在一些 GitHub repository 中個別管理,每個 repository 都有自己的 issue 資料庫。如果可以的話,請將你的問題回報至適合的 repository,但也別怕不小心發錯地方,我們的社群會很熱心幫你找到對的地方。 - -- 若要回報 Node.js 問題請至 [nodejs/node](https://github.com/nodejs/node) -- 若要回報本網站的問題請至 [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org/issues) - -## 程式碼貢獻者 - -若你想要協助 Node.js 修復 bug 或是增加新功能,請確保你已詳讀 [Node.js Contribution Guidelines](https://github.com/nodejs/node/blob/main/CONTRIBUTING.md/#pull-requests),裡頭也解釋了貢獻至本專案等待協作者審核的詳細過程。 - -如果你想知道該從何開始,你可以參考 [Node Todo](https://www.nodetodo.org/),它可以引導你邁向你的第一個貢獻。 - -## 成為協作者 - -協作者的影響力可擴及整個專案,成為協作者後將能審核他人的貢獻內容、分類 issue 及策劃專案未來。因重大貢獻而被 TSC 認可的開發者可能會被授與專案協作者身份及享有專案的 commit 權限,重大貢獻的評估標準如(包括但不限於)下方所列: - -- 程式碼 commit 及 pull request 的品質 -- 文件 commit 及 pull request 的品質 -- 於 issue 及 pull request 留下的評論品質 -- Node.js 網站的貢獻品質 -- 提供給專端用戶及初學貢獻者協助的品質 -- 參與工作組的品質 -- 其他 Node.js 社群的參與品質 - -若你自認做出重大貢獻卻沒被授與 commit 權限,可嘗試[開啟 issue](https://github.com/nodejs/TSC/issues) 或[直接聯絡 TSC 成員](https://github.com/nodejs/TSC#current-members)。 diff --git a/pages/zh-tw/get-involved/index.md b/pages/zh-tw/get-involved/index.md deleted file mode 100644 index 23c16765bca5f..0000000000000 --- a/pages/zh-tw/get-involved/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 加入我們 -layout: contribute.hbs ---- - -# 加入我們 - -## 社群討論 - -- [GitHub issues 清單](https://github.com/nodejs/node/issues)是討論 Node.js 核心功能的好地方。 -- 想即時聊聊關於 Node.js 開發方面的內容,可以使用以下平臺: - - 使用 IRC,請使用 [IRC 用戶端](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients),轉到 `irc.libera.chat` 中的 `#node.js` 頻道,或者在您的瀏覽器中使用 [Web 用戶端](https://kiwiirc.com/nextclient/) 直接連接即可。 - - 使用 Slack,有兩種選項: - - [Node Slackers](https://www.nodeslackers.com/) 是一個針對 Node.js 開發的社群,一些工作小組在那邊有相關的討論頻道。 - - [OpenJSF Slack](https://slack-invite.openjsf.org/) 包含多個 Node.js 頻道(帶有 `#nodejs-` 前綴的都是與此專案相關),一些工作小組在那邊也有討論頻道。 -- Node.js 官方的 Twitter 帳號是 [nodejs](https://twitter.com/nodejs)。 -- [Node.js Foundation 行事曆](https://nodejs.org/calendar) 中列出了所有的公開團隊會議。 - -## 學習資源 - -- [官方 API 參考文件](https://nodejs.org/api/)中詳細介紹了 Node API。 -- [NodeSchool.io](https://nodeschool.io/) 以互動命令列的方式,教會你 Node.js 的概念。 -- [Stack Overflow 上的 Node.js 標籤](https://stackoverflow.com/questions/tagged/node.js)搜羅了每日新資訊。 -- [開發社區上的 Node.js 標籤](https://dev.to/t/node) 是一個共亯 Node.js項目、文章和教程,以及開始討論、並接受與 Node.js 相關的主題。歡迎所有技能級別的開發人員參與。 -- [Nodeiflux](https://discordapp.com/invite/vUsrbjd) 是一個 Node.js 後端開發者在 Discord 上互相支援的友好社區。 diff --git a/pages/zh-tw/index.md b/pages/zh-tw/index.md deleted file mode 100644 index 88e28358abd59..0000000000000 --- a/pages/zh-tw/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: index.hbs -labels: - current-version: 目前版本 - download: 下載 - download-for: 目前版本: - other-downloads: 其它版本 - current: 最新版本 - lts: 長期維護版 - tagline-current: 包含最新功能 - tagline-lts: 適合給大部分使用者 - changelog: 更新紀錄 - api: API 文件 - version-schedule-prompt: 或參考 - version-schedule-prompt-link-text: LTS(長期維護版)時程 ---- - -Node.js® 是一個開源、跨平台的 JavaScript 執行環境。 diff --git a/redirects.json b/redirects.json index df26f5cfba3cd..83c5cadcf710b 100644 --- a/redirects.json +++ b/redirects.json @@ -28,14 +28,6 @@ "source": "/:locale/contribute/accepting_contributions.html", "destination": "https://github.com/nodejs/dev-policy" }, - { - "source": "/:locale/about/releases", - "destination": "https://github.com/nodejs/release#release-schedule" - }, - { - "source": "/:locale/about/security", - "destination": "https://github.com/nodejs/node/security/policy#security" - }, { "source": "/:locale/advisory-board", "destination": "https://github.com/nodejs/TSC" @@ -161,6 +153,14 @@ { "source": "/logos/:path*", "destination": "/static/images/logos/:path*" + }, + { + "source": "/:locale/download/releases", + "destination": "/:locale/about/previous-releases" + }, + { + "source": "/:locale/about/security", + "destination": "/:locale/about/security-reporting" } ] } diff --git a/styles/old/base.css b/styles/old/base.css index d460b25071ad4..a912cffec4b29 100644 --- a/styles/old/base.css +++ b/styles/old/base.css @@ -22,6 +22,10 @@ h5 { font-weight: 400; } +h2 { + font-size: 1.3em; +} + a, a:link, a:active { diff --git a/styles/old/page-modules/anchorLinks.css b/styles/old/page-modules/anchorLinks.css index 38d6588b6c91a..0ddd677fc2cf5 100644 --- a/styles/old/page-modules/anchorLinks.css +++ b/styles/old/page-modules/anchorLinks.css @@ -2,6 +2,7 @@ background: none; color: $light-gray2; padding: 0 0.25em; + float: right; &:link, &:active, diff --git a/styles/old/page-modules/header.css b/styles/old/page-modules/header.css index 48a49b30f55d2..56ec5e445f601 100644 --- a/styles/old/page-modules/header.css +++ b/styles/old/page-modules/header.css @@ -76,7 +76,6 @@ header { list-style-type: none; margin: 0; max-height: 400px; - min-height: 200px; overflow: auto; padding: 0; position: absolute; diff --git a/types/navigation.ts b/types/navigation.ts index e63900e363989..62210759adcb1 100644 --- a/types/navigation.ts +++ b/types/navigation.ts @@ -1,10 +1,8 @@ export type NavigationKeys = - | 'home' | 'about' | 'download' | 'docs' | 'getInvolved' - | 'security' | 'certification' | 'blog';