Node.js

"Node.js" (written and spoken guidelines)arrow-up-right

Written and spkoen guidelines

Libraries

Unorganized:

Configuration:

Parse DOM (HTML, XML, SVG) and CSSOM:

Security:

Network:

Relative path

Is parent path

Aka is subdir

List files recursively

Keep local copy of dependencies

Usefull to keep it on version control system or in context of security

  • https://github.com/JamieMason/shrinkpack

  • https://docs.npmjs.com/cli/shrinkwrap

In all node_modules directory on an hard drive.

  • https://github.com/jeffbski/pkglink

Turn off Spotflight indexation of dependencies

Performances

Load balancer and reverse proxy

process.env.IN_PASSENGER === "1" typeof PhusionPassenger !== "undefined"

Debug

Send log infos client side

HTTP header X-ChromeLogger-Data: jsonbase64value

Profile

CPU profile file:

  • use the node --cpu-prof option that will generate a cpuprofile file

  • use Chrome Dev Tools Performance tab to read the file as flamegraph where the x-axis represents when a call happened. It annotate the source code with the sampled traces this gives an approximate time how much each line took to execute

  • use speedscopearrow-up-right (GitHub - jlfwong/speedscope: 🔬 A fast, interactive web-based viewer for performance profiles.arrow-up-right) to read the file as flamegraph but it merge similar call-stacks together to see where the time is being spent, the x-axis represents time consumed of the total time. It referred to as a "left-heavy" visualization. It's not a standard flamegraph where the x-axis represents when a call happened.

  • use node --cpu-prof $(which npm) run myscript to do it when run a scriptarrow-up-right

Heap profile file:

Performance

Child processes

Cluster is child_process in a more convenient way to listen the same port by all children (it use child_process internally): Cluster | Node.j v9.6.1 Documentationarrow-up-right

Standart input / output

Command line

Aka CLI

Shebang:

Syntax check without executing:

Parse command line arguments:

Express

Test server capacity with mcollina/autocannon: fast HTTP/1.1 benchmarking tool written in Node.jsarrow-up-right

Order route registration from most specific to less specific: /foo/bar, /foo, /

Internal redirect, aka reroute: node.js - Forward request to alternate request handler instead of redirect - Stack Overflowarrow-up-right. See Express 4.x - API Referencearrow-up-right

Reroute:

Global error handling

At app level or a parent route level, register the error handler (a middleware with 4 arguments) after all other used middleware and routes handlers

Examples:

Express libraries

RESTful routing (resource, facet):

Get client IP with Express

NPM and packages

Updates:

Security and trust

Format and lint package JSON

Prettier config to override default / projet config for package JSONs:

Inspect package

Package variables

Aka environment variables

Install for continuous integration

Packages version

npm outdated to list "Current", "Wanted" (aka fuzzy, latest minor release) and "Latest" (latest major release) version, use npm install <package name>@latest to install latest version

Scopes packages

Aka monorepos and multi packages

@babel/*, @angular/*, etc.

Local packages

Fix package with patch

EACCES errors when installing global package

First: Just don't install packages globally

Install global with node-gyp can output errors:

Use --unsafe-perm paramter for npm to fix the issue, or update the NODE_PATH env var.

See Warning "root" does not have permission to access the dev dir · Issue #454 · nodejs/node-gyparrow-up-right

NPM install resolved packages from HTTPS to HTTP

npm config get registry should return https://registry.npmjs.org/

  1. rm -rf node_modules/

  2. npm cache clean --force

  3. Revert the changes in your package-lock.json file

  4. npm i

Package overrides

Inspect package

Crossplatform scripts

Note: ver only exist in cmd.exe (default shell used on Windows). The last part (after ||) will be executed in other shell (usally /bin/sh on POSIX)

Write scripts like npm do for bins (in node_modules/.bin/):

mycommand:

mycommand.cmd:

mycommand.ps1:

See also:

Promisify

Instead of:

Modules

Use URI as configuration

  • https://github.com/sidorares/node-mysql2/blob/5f0fb8f1f5035e2c0207490aa2f0b838dc82fdc2/lib/connection_config.js#L166-L196

  • https://github.com/nodemailer/nodemailer/blob/5da6c87766e258f1a5fa9b628f2d9f57c9d533ce/lib/shared/index.js#L16-L91

Global error handling

  • process.setUncaughtExceptionCaptureCallback

Node sources

Zlib will don't have extra gzip header fiels (empty values):

If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields.

  • https://github.com/nodejs/node/blob/master/deps/zlib/zlib.h

Zlib binding:

Read UTF-8 JSON with BOM

Require a virtual file

Warning

Depreciation

Path case sensitivity on Windows

Node handle pretty well path case insensibility on Windows. But if a module use a symbolic link or a junctionarrow-up-right and the working directory doesn't match the case of that path (d:\mydir instead of D:\MyDir) Node load the same module twice, for each path case. Note: NPM use junction for local path modulesarrow-up-right.

See an example:

Require specific version of NPM and node

If the version doesn't match, npm install:

Note: that doesn't work for npm ciarrow-up-right that ignore that check

Encryption with Node.js

Asynmmetric encryption usally encrypt an symectric key used to encrypt: RSA maximum bytes to encrypt, comparison to AES in terms of security? - Information Security Stack Exchangearrow-up-right

See security cryptography - "Diffie-Hellman Key Exchange" in plain English - Information Security Stack Exchangearrow-up-right

Node IPC

FNM

On Windows for Bash, add to %USERPROFILE%\.bashrc:

%USERPROFILE%\.bash_profile:

On Windows for CMD:

Exec the registry script:

%USERPROFILE%\autorun.cmd:

To spawn process without using a shell (node, npm, npx), use instead something like C:\path\to\node.cmd with the following content:

Max memory size

Aka --max-old-space-size, "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory", "EXEC : FATAL error : Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory"

Increase memory to 4GB: node --max-old-space-size=4096 index.js. 1024 for 1GB, 1536 for 1.5GB, 2048 for 2GB, 3072 for 3GB, 5120 for 5GB, 6144 for 6GB, 7168 for 7GB, 8192 for 8GB, etc.

It is recommended to always explicitly set the --max-old-space-size instead of relying on default imposed by Node.js

On a machine with 2 GiB of memory, consider setting this to 1536 (1.5 GiB) to leave some memory for other uses and avoid swapping.

Command-line API - --max-old-space-size=SIZE (in megabytes)arrow-up-right

TypeScript

Single executable application

SABs are not meant for bundling dependencies

HTTP Proxy

Node use interally the package undici, which parse the proxy URI with URL API for which the protocol is not optional:

EnvHttpProxyAgent automatically reads the proxy configuration from the environment variables http_proxy, https_proxy, and no_proxy and sets up the proxy agents accordingly. When http_proxy and https_proxy are set, http_proxy is used for HTTP requests and https_proxy is used for HTTPS requests. If only http_proxy is set, http_proxy is used for both HTTP and HTTPS requests. If only https_proxy is set, it is only used for HTTPS requests.

no_proxy is a comma or space-separated list of hostnames that should not be proxied. The list may contain leading wildcard characters (*). If no_proxy is set, the EnvHttpProxyAgent will bypass the proxy for requests to hosts that match the list. If > no_proxy is set to "*", the EnvHttpProxyAgent will bypass the proxy for all requests.

Uppercase environment variables are also supported: HTTP_PROXY, HTTPS_PROXY, and NO_PROXY. However, if both the lowercase and uppercase environment variables are set, the uppercase environment variables will be ignored.

Need to set full URI (not just the host and the port), eg. HTTPS_PROXY=http://example.com:8000

For some libraires / tools the procotol is optional and could use http or https as default protocol

  • https://github.com/nodejs/node/blob/2cd385ef6714b24b62edf22dd2ddd756eee9d16b/deps/undici/src/lib/dispatcher/env-http-proxy-agent.js#L35-L47

  • https://github.com/nodejs/node/blob/2cd385ef6714b24b62edf22dd2ddd756eee9d16b/deps/undici/src/docs/docs/api/EnvHttpProxyAgent.md?plain=1#L7-L11

  • https://github.com/nodejs/node/blob/5ad2ca920cdc6d99a8d673724b35115fef925e78/deps/openssl/openssl/crypto/http/http_client.c#L965C17-L965C36 -> https://github.com/nodejs/node/blob/5ad2ca920cdc6d99a8d673724b35115fef925e78/deps/openssl/openssl/crypto/http/http_lib.c#L74-L84

  • NPM use proxy-agent - npmarrow-up-right, which use proxy-from-envarrow-up-right use the request procol as default https://github.com/Rob--W/proxy-from-env/blob/095d1c26902f37a12e22bea1b8c6b67bf13fe8cd/index.js#L47-L50 ("default to the requested URL's scheme")

  • curl use HTTP as default protocol ("head: It's a HTTP proxy") https://github.com/curl/curl/blob/4af40b3646d3b09f68e419f7ca866ff395d1f897/lib/url.c#L4608-L4638

  • wget use HTTP as default protocol ("Just prepend "http://" to URL.") https://git.savannah.gnu.org/cgit/wget.git/tree/src/retr.c?id=93c1517c4071c4288ba5a4b038e7634e4c6b5482#n1283 https://git.savannah.gnu.org/cgit/wget.git/tree/src/url.c?id=93c1517c4071c4288ba5a4b038e7634e4c6b5482#n609

  • Python's urllib use request protocol as default https://github.com/python/cpython/blob/936135bb97fe04223aa30ca6e98eac8f3ed6b349/Lib/urllib/request.py#L801-L802

See also:

Last updated