From 18759629ab268db449472866aad0263ebedb02a8 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 10:09:29 -0700 Subject: [PATCH 1/9] doc: Extend esm examples /w imports for process + Buffer --- doc/api/async_context.md | 205 +++- doc/api/async_hooks.md | 209 +++- doc/api/buffer.md | 1819 ++++++++++++++++++++++++++++++-- doc/api/cluster.md | 193 +++- doc/api/crypto.md | 298 +++--- doc/api/dgram.md | 107 +- doc/api/diagnostics_channel.md | 98 +- doc/api/process.md | 1240 ++++++++++++++++++++-- 8 files changed, 3771 insertions(+), 398 deletions(-) diff --git a/doc/api/async_context.md b/doc/api/async_context.md index 7092a2d5bf2913..4c8f3e20e8912e 100644 --- a/doc/api/async_context.md +++ b/doc/api/async_context.md @@ -14,7 +14,11 @@ in other languages. The `AsyncLocalStorage` and `AsyncResource` classes are part of the `async_hooks` module: -```js +```mjs +import async_hooks from 'async_hooks'; +``` + +```cjs const async_hooks = require('async_hooks'); ``` @@ -40,7 +44,39 @@ The following example uses `AsyncLocalStorage` to build a simple logger that assigns IDs to incoming HTTP requests and includes them in messages logged within each request. -```js +```mjs +import http from 'http'; +import { AsyncLocalStoraget } from 'async_hooks'; + +const asyncLocalStorage = new AsyncLocalStorage(); + +function logWithId(msg) { + const id = asyncLocalStorage.getStore(); + console.log(`${id !== undefined ? id : '-'}:`, msg); +} + +let idSeq = 0; +http.createServer((req, res) => { + asyncLocalStorage.run(idSeq++, () => { + logWithId('start'); + // Imagine any chain of async operations here + setImmediate(() => { + logWithId('finish'); + res.end(); + }); + }); +}).listen(8080); + +http.get('http://localhost:8080'); +http.get('http://localhost:8080'); +// Prints: +// 0: start +// 1: start +// 0: finish +// 1: finish +``` + +```cjs const http = require('http'); const { AsyncLocalStorage } = require('async_hooks'); @@ -299,7 +335,35 @@ The `init` hook will trigger when an `AsyncResource` is instantiated. The following is an overview of the `AsyncResource` API. -```js +```mjs +import { AsyncResource, executionAsyncId } from 'async_hooks'; + +// AsyncResource() is meant to be extended. Instantiating a +// new AsyncResource() also triggers init. If triggerAsyncId is omitted then +// async_hook.executionAsyncId() is used. +const asyncResource = new AsyncResource( + type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false } +); + +// Run a function in the execution context of the resource. This will +// * establish the context of the resource +// * trigger the AsyncHooks before callbacks +// * call the provided function `fn` with the supplied arguments +// * trigger the AsyncHooks after callbacks +// * restore the original execution context +asyncResource.runInAsyncScope(fn, thisArg, ...args); + +// Call AsyncHooks destroy callbacks. +asyncResource.emitDestroy(); + +// Return the unique ID assigned to the AsyncResource instance. +asyncResource.asyncId(); + +// Return the trigger ID for the AsyncResource instance. +asyncResource.triggerAsyncId(); +``` + +```cjs const { AsyncResource, executionAsyncId } = require('async_hooks'); // AsyncResource() is meant to be extended. Instantiating a @@ -446,7 +510,14 @@ database connection pools, can follow a similar model. Assuming that the task is adding two numbers, using a file named `task_processor.js` with the following content: -```js +```mjs +import { parentPort } from 'worker_threads'; +parentPort.on('message', (task) => { + parentPort.postMessage(task.a + task.b); +}); +``` + +```cjs const { parentPort } = require('worker_threads'); parentPort.on('message', (task) => { parentPort.postMessage(task.a + task.b); @@ -455,7 +526,95 @@ parentPort.on('message', (task) => { a Worker pool around it could use the following structure: -```js +```mjs +import { AsyncResource } from 'async_hooks'; +import { EventEmitter } from 'events'; +import path from 'path'; +import { Worker } from 'worker_threads'; + +const kTaskInfo = Symbol('kTaskInfo'); +const kWorkerFreedEvent = Symbol('kWorkerFreedEvent'); + +class WorkerPoolTaskInfo extends AsyncResource { + constructor(callback) { + super('WorkerPoolTaskInfo'); + this.callback = callback; + } + + done(err, result) { + this.runInAsyncScope(this.callback, null, err, result); + this.emitDestroy(); // `TaskInfo`s are used only once. + } +} + +export default class WorkerPool extends EventEmitter { + constructor(numThreads) { + super(); + this.numThreads = numThreads; + this.workers = []; + this.freeWorkers = []; + this.tasks = []; + + for (let i = 0; i < numThreads; i++) + this.addNewWorker(); + + // Any time the kWorkerFreedEvent is emitted, dispatch + // the next task pending in the queue, if any. + this.on(kWorkerFreedEvent, () => { + if (this.tasks.length > 0) { + const { task, callback } = this.tasks.shift(); + this.runTask(task, callback); + } + }); + } + + addNewWorker() { + const worker = new Worker(new URL('task_processer.js', import.meta.url)); + worker.on('message', (result) => { + // In case of success: Call the callback that was passed to `runTask`, + // remove the `TaskInfo` associated with the Worker, and mark it as free + // again. + worker[kTaskInfo].done(null, result); + worker[kTaskInfo] = null; + this.freeWorkers.push(worker); + this.emit(kWorkerFreedEvent); + }); + worker.on('error', (err) => { + // In case of an uncaught exception: Call the callback that was passed to + // `runTask` with the error. + if (worker[kTaskInfo]) + worker[kTaskInfo].done(err, null); + else + this.emit('error', err); + // Remove the worker from the list and start a new Worker to replace the + // current one. + this.workers.splice(this.workers.indexOf(worker), 1); + this.addNewWorker(); + }); + this.workers.push(worker); + this.freeWorkers.push(worker); + this.emit(kWorkerFreedEvent); + } + + runTask(task, callback) { + if (this.freeWorkers.length === 0) { + // No free threads, wait until a worker thread becomes free. + this.tasks.push({ task, callback }); + return; + } + + const worker = this.freeWorkers.pop(); + worker[kTaskInfo] = new WorkerPoolTaskInfo(callback); + worker.postMessage(task); + } + + close() { + for (const worker of this.workers) worker.terminate(); + } +} +``` + +```cjs const { AsyncResource } = require('async_hooks'); const { EventEmitter } = require('events'); const path = require('path'); @@ -553,7 +712,23 @@ were scheduled. This pool could be used as follows: -```js +```mjs +import WorkerPool from './worker_pool.js'; +import os from 'os'; + +const pool = new WorkerPool(os.cpus().length); + +let finished = 0; +for (let i = 0; i < 10; i++) { + pool.runTask({ a: 42, b: 100 }, (err, result) => { + console.log(i, err, result); + if (++finished === 10) + pool.close(); + }); +} +``` + +```cjs const WorkerPool = require('./worker_pool.js'); const os = require('os'); @@ -579,7 +754,22 @@ The following example shows how to use the `AsyncResource` class to properly associate an event listener with the correct execution context. The same approach can be applied to a [`Stream`][] or a similar event-driven class. -```js +```mjs +import { createServer } from 'http'; +import { AsyncResource, executionAsyncId } from 'async_hooks'; + +const server = createServer((req, res) => { + req.on('close', AsyncResource.bind(() => { + // Execution context is bound to the current outer scope. + })); + req.on('close', () => { + // Execution context is bound to the scope that caused 'close' to emit. + }); + res.end(); +}).listen(3000); +``` + +```cjs const { createServer } = require('http'); const { AsyncResource, executionAsyncId } = require('async_hooks'); @@ -593,6 +783,7 @@ const server = createServer((req, res) => { res.end(); }).listen(3000); ``` + [`AsyncResource`]: #async_context_class_asyncresource [`EventEmitter`]: events.md#events_class_eventemitter [`Stream`]: stream.md#stream_stream diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index f6805102fdf050..bc9acd9b7994ed 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -9,7 +9,11 @@ The `async_hooks` module provides an API to track asynchronous resources. It can be accessed using: -```js +```mjs +import async_hooks from 'async_hooks'; +``` + +```cjs const async_hooks = require('async_hooks'); ``` @@ -29,7 +33,55 @@ interface, and each thread will use a new set of async IDs. Following is a simple overview of the public API. -```js +```mjs +import async_hooks from 'async_hooks'; + +// Return the ID of the current execution context. +const eid = async_hooks.executionAsyncId(); + +// Return the ID of the handle responsible for triggering the callback of the +// current execution scope to call. +const tid = async_hooks.triggerAsyncId(); + +// Create a new AsyncHook instance. All of these callbacks are optional. +const asyncHook = + async_hooks.createHook({ init, before, after, destroy, promiseResolve }); + +// Allow callbacks of this AsyncHook instance to call. This is not an implicit +// action after running the constructor, and must be explicitly run to begin +// executing callbacks. +asyncHook.enable(); + +// Disable listening for new asynchronous events. +asyncHook.disable(); + +// +// The following are the callbacks that can be passed to createHook(). +// + +// init is called during object construction. The resource may not have +// completed construction when this callback runs, therefore all fields of the +// resource referenced by "asyncId" may not have been populated. +function init(asyncId, type, triggerAsyncId, resource) { } + +// Before is called just before the resource's callback is called. It can be +// called 0-N times for handles (such as TCPWrap), and will be called exactly 1 +// time for requests (such as FSReqCallback). +function before(asyncId) { } + +// After is called just after the resource's callback has finished. +function after(asyncId) { } + +// Destroy is called when the resource is destroyed. +function destroy(asyncId) { } + +// promiseResolve is called only for promise resources, when the +// `resolve` function passed to the `Promise` constructor is invoked +// (either directly or through other means of resolving a promise). +function promiseResolve(asyncId) { } +``` + +```cjs const async_hooks = require('async_hooks'); // Return the ID of the current execution context. @@ -102,7 +154,16 @@ be tracked, then only the `destroy` callback needs to be passed. The specifics of all functions that can be passed to `callbacks` is in the [Hook Callbacks][] section. -```js +```mjs +import { createHook } from 'async_hooks'; + +const asyncHook = createHook({ + init(asyncId, type, triggerAsyncId, resource) { }, + destroy(asyncId) { } +}); +``` + +```cjs const async_hooks = require('async_hooks'); const asyncHook = async_hooks.createHook({ @@ -158,7 +219,17 @@ synchronous logging operation such as `fs.writeFileSync(file, msg, flag)`. This will print to the file and will not invoke AsyncHooks recursively because it is synchronous. -```js +```mjs +import { writeFileSync } from 'fs'; +import { format } from 'util'; + +function debug(...args) { + // Use a function like this one when debugging inside an AsyncHooks callback + writeFileSync('log.out', `${format(...args)}\n`, { flag: 'a' }); +} +``` + +```cjs const fs = require('fs'); const util = require('util'); @@ -189,7 +260,13 @@ provided, enabling is a no-op. The `AsyncHook` instance is disabled by default. If the `AsyncHook` instance should be enabled immediately after creation, the following pattern can be used. -```js +```mjs +import { createHook } from 'async_hooks'; + +const hook = createHook(callbacks).enable(); +``` + +```cjs const async_hooks = require('async_hooks'); const hook = async_hooks.createHook(callbacks).enable(); @@ -229,7 +306,15 @@ This behavior can be observed by doing something like opening a resource then closing it before the resource can be used. The following snippet demonstrates this. -```js +```mjs +import { createServer } from 'net'; + +net.createServer().listen(function() { this.close(); }); +// OR +clearTimeout(setTimeout(() => {}, 10)); +``` + +```cjs require('net').createServer().listen(function() { this.close(); }); // OR clearTimeout(setTimeout(() => {}, 10)); @@ -270,12 +355,29 @@ created, while `triggerAsyncId` shows *why* a resource was created. The following is a simple demonstration of `triggerAsyncId`: -```js -const { fd } = process.stdout; +```mjs +import { createHook, executionASyncId } from 'async_hooks'; +import { stdout } from 'process'; -async_hooks.createHook({ +createHook({ init(asyncId, type, triggerAsyncId) { - const eid = async_hooks.executionAsyncId(); + const eid = executionAsyncId(); + fs.writeSync( + stdout.fd, + `${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`); + } +}).enable(); + +net.createServer((conn) => {}).listen(8080); +``` + +```cjs +const { createHook, executionAsyncId } = require('async_hooks'); +const { fd } = require('process').stdout; + +createHook({ + init(asyncId, type, triggerAsyncId) { + const eid = executionAsyncId(); fs.writeSync( fd, `${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`); @@ -506,7 +608,17 @@ Using `executionAsyncResource()` in the top-level execution context will return an empty object as there is no handle or request object to use, but having an object representing the top-level can be helpful. -```js +```mjs +import { open } from 'fs'; +import { executionAsyncId, executionAsyncResource } from 'async_hooks'; + +console.log(executionAsyncId(), executionAsyncResource()); // 1 {} +open(fileURLToPath(import.meta.url), 'r', (err, fd) => { + console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap +}); +``` + +```cjs const { open } = require('fs'); const { executionAsyncId, executionAsyncResource } = require('async_hooks'); @@ -519,7 +631,33 @@ open(__filename, 'r', (err, fd) => { This can be used to implement continuation local storage without the use of a tracking `Map` to store the metadata: -```js +```mjs +import { createServer } from 'http'; +import { + executionAsyncId, + executionAsyncResource, + createHook +} from 'async_hooks'; +const sym = Symbol('state'); // Private symbol to avoid pollution + +createHook({ + init(asyncId, type, triggerAsyncId, resource) { + const cr = executionAsyncResource(); + if (cr) { + resource[sym] = cr[sym]; + } + } +}).enable(); + +const server = createServer((req, res) => { + executionAsyncResource()[sym] = { state: req.url }; + setTimeout(function() { + res.end(JSON.stringify(executionAsyncResource()[sym])); + }, 100); +}).listen(3000); +``` + +```cjs const { createServer } = require('http'); const { executionAsyncId, @@ -558,7 +696,16 @@ changes: * Returns: {number} The `asyncId` of the current execution context. Useful to track when something calls. -```js +```mjs +import { executionAsyncId } from 'async_hooks'; + +console.log(executionAsyncId()); // 1 - bootstrap +fs.open(path, 'r', (err, fd) => { + console.log(executionAsyncId()); // 6 - open() +}); +``` + +```cjs const async_hooks = require('async_hooks'); console.log(async_hooks.executionAsyncId()); // 1 - bootstrap @@ -616,10 +763,21 @@ expensive nature of the [promise introspection API][PromiseHooks] provided by V8. This means that programs using promises or `async`/`await` will not get correct execution and trigger ids for promise callback contexts by default. -```js -const ah = require('async_hooks'); +```mjs +import { executionAsyncId, triggerAsyncId } from 'async_hooks'; + +Promise.resolve(1729).then(() => { + console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`); +}); +// produces: +// eid 1 tid 0 +``` + +```cjs +const { executionAsyncId, triggerAsyncId } = require('async_hooks'); + Promise.resolve(1729).then(() => { - console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`); + console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`); }); // produces: // eid 1 tid 0 @@ -633,11 +791,22 @@ the resource that caused (triggered) the `then()` callback to be executed. Installing async hooks via `async_hooks.createHook` enables promise execution tracking: -```js -const ah = require('async_hooks'); -ah.createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled. +```mjs +import { createHook, executionAsyncId, triggerAsyncId } from 'async_hooks'; +createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled. +Promise.resolve(1729).then(() => { + console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`); +}); +// produces: +// eid 7 tid 6 +``` + +```cjs +const { createHook, exectionAsyncId, triggerAsyncId } = require('async_hooks'); + +createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled. Promise.resolve(1729).then(() => { - console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`); + console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`); }); // produces: // eid 7 tid 6 diff --git a/doc/api/buffer.md b/doc/api/buffer.md index dd965bbf226194..bd6057f39999ec 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -13,10 +13,45 @@ The `Buffer` class is a subclass of JavaScript's [`Uint8Array`][] class and extends it with methods that cover additional use cases. Node.js APIs accept plain [`Uint8Array`][]s wherever `Buffer`s are supported as well. -The `Buffer` class is within the global scope, making it unlikely that one -would need to ever use `require('buffer').Buffer`. +While the `Buffer` class is available within the global scope, it is still +recommended to explicitly reference it via an import or require statement. + +```mjs +import { Buffer } from 'buffer'; + +// Creates a zero-filled Buffer of length 10. +const buf1 = Buffer.alloc(10); + +// Creates a Buffer of length 10, +// filled with bytes which all have the value `1`. +const buf2 = Buffer.alloc(10, 1); + +// Creates an uninitialized buffer of length 10. +// This is faster than calling Buffer.alloc() but the returned +// Buffer instance might contain old data that needs to be +// overwritten using fill(), write(), or other functions that fill the Buffer's +// contents. +const buf3 = Buffer.allocUnsafe(10); + +// Creates a Buffer containing the bytes [1, 2, 3]. +const buf4 = Buffer.from([1, 2, 3]); + +// Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries +// are all truncated using `(value & 255)` to fit into the range 0–255. +const buf5 = Buffer.from([257, 257.5, -255, '1']); + +// Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést': +// [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation) +// [116, 195, 169, 115, 116] (in decimal notation) +const buf6 = Buffer.from('tést'); + +// Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74]. +const buf7 = Buffer.from('tést', 'latin1'); +``` + +```cjs +const { Buffer } = require('buffer'); -```js // Creates a zero-filled Buffer of length 10. const buf1 = Buffer.alloc(10); @@ -65,7 +100,25 @@ When converting between `Buffer`s and strings, a character encoding may be specified. If no character encoding is specified, UTF-8 will be used as the default. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('hello world', 'utf8'); + +console.log(buf.toString('hex')); +// Prints: 68656c6c6f20776f726c64 +console.log(buf.toString('base64')); +// Prints: aGVsbG8gd29ybGQ= + +console.log(Buffer.from('fhqwhgads', 'utf8')); +// Prints: +console.log(Buffer.from('fhqwhgads', 'utf16le')); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('hello world', 'utf8'); console.log(buf.toString('hex')); @@ -142,7 +195,23 @@ The following legacy character encodings are also supported: of UTF-16 that did not support characters that had code points larger than U+FFFF. In Node.js, these code points are always supported. -```js +```mjs +import { Buffer } from 'buffer'; + +Buffer.from('1ag', 'hex'); +// Prints , data truncated when first non-hexadecimal value +// ('g') encountered. + +Buffer.from('1a7g', 'hex'); +// Prints , data truncated when data ends in single digit ('7'). + +Buffer.from('1634', 'hex'); +// Prints , all data represented. +``` + +```cjs +const { Buffer } = require('buffer'); + Buffer.from('1ag', 'hex'); // Prints , data truncated when first non-hexadecimal value // ('g') encountered. @@ -191,7 +260,20 @@ There are two ways to create new [`TypedArray`][] instances from a `Buffer`: contents, interpreted as an array of integers, and not as a byte sequence of the target type. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([1, 2, 3, 4]); +const uint32array = new Uint32Array(buf); + +console.log(uint32array); + +// Prints: Uint32Array(4) [ 1, 2, 3, 4 ] +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([1, 2, 3, 4]); const uint32array = new Uint32Array(buf); @@ -203,7 +285,23 @@ console.log(uint32array); * Passing the `Buffer`s underlying [`ArrayBuffer`][] will create a [`TypedArray`][] that shares its memory with the `Buffer`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('hello', 'utf16le'); +const uint16array = new Uint16Array( + buf.buffer, + buf.byteOffset, + buf.length / Uint16Array.BYTES_PER_ELEMENT); + +console.log(uint16array); + +// Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ] +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('hello', 'utf16le'); const uint16array = new Uint16Array( buf.buffer, @@ -220,7 +318,36 @@ memory as a [`TypedArray`][] instance by using the `TypedArray` object’s `.buffer` property in the same way. [`Buffer.from()`][`Buffer.from(arrayBuf)`] behaves like `new Uint8Array()` in this context. -```js +```mjs +import { Buffer } from 'buffer'; + +const arr = new Uint16Array(2); + +arr[0] = 5000; +arr[1] = 4000; + +// Copies the contents of `arr`. +const buf1 = Buffer.from(arr); + +// Shares memory with `arr`. +const buf2 = Buffer.from(arr.buffer); + +console.log(buf1); +// Prints: +console.log(buf2); +// Prints: + +arr[1] = 6000; + +console.log(buf1); +// Prints: +console.log(buf2); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const arr = new Uint16Array(2); arr[0] = 5000; @@ -249,7 +376,19 @@ When creating a `Buffer` using a [`TypedArray`][]'s `.buffer`, it is possible to use only a portion of the underlying [`ArrayBuffer`][] by passing in `byteOffset` and `length` parameters. -```js +```mjs +import { Buffer } from 'buffer'; + +const arr = new Uint16Array(20); +const buf = Buffer.from(arr.buffer, 0, 16); + +console.log(buf.length); +// Prints: 16 +``` + +```cjs +const { Buffer } = require('buffer'); + const arr = new Uint16Array(20); const buf = Buffer.from(arr.buffer, 0, 16); @@ -276,7 +415,23 @@ function: `Buffer` instances can be iterated over using `for..of` syntax: -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([1, 2, 3]); + +for (const b of buf) { + console.log(b); +} +// Prints: +// 1 +// 2 +// 3 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([1, 2, 3]); for (const b of buf) { @@ -378,11 +533,39 @@ destinations without transferring or immediately copying the data. The data contained by the `Blob` is copied only when the `arrayBuffer()` or `text()` methods are called. -```js -const { Blob } = require('buffer'); +```mjs +import { Blob, Buffer } from 'buffer'; +import { setTimeout as delay } from 'timers/promises'; + const blob = new Blob(['hello there']); + +const mc1 = new MessageChannel(); +const mc2 = new MessageChannel(); + +mc1.port1.onmessage = async ({ data }) => { + console.log(await data.arrayBuffer()); + mc1.port1.close(); +}; + +mc2.port1.onmessage = async ({ data }) => { + await delay(1000); + console.log(await data.arrayBuffer()); + mc2.port1.close(); +}; + +mc1.port2.postMessage(blob); +mc2.port2.postMessage(blob); + +// The Blob is still usable after posting. +data.text().then(console.log); +``` + +```cjs +const { Blob, Buffer } = require('buffer'); const { setTimeout: delay } = require('timers/promises'); +const blob = new Blob(['hello there']); + const mc1 = new MessageChannel(); const mc2 = new MessageChannel(); @@ -440,7 +623,18 @@ changes: Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the `Buffer` will be zero-filled. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.alloc(5); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.alloc(5); console.log(buf); @@ -454,7 +648,18 @@ is thrown. If `fill` is specified, the allocated `Buffer` will be initialized by calling [`buf.fill(fill)`][`buf.fill()`]. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.alloc(5, 'a'); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.alloc(5, 'a'); console.log(buf); @@ -464,7 +669,18 @@ console.log(buf); If both `fill` and `encoding` are specified, the allocated `Buffer` will be initialized by calling [`buf.fill(fill, encoding)`][`buf.fill()`]. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); console.log(buf); @@ -502,7 +718,23 @@ initialized*. The contents of the newly created `Buffer` are unknown and *may contain sensitive data*. Use [`Buffer.alloc()`][] instead to initialize `Buffer` instances with zeroes. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(10); + +console.log(buf); +// Prints (contents may vary): + +buf.fill(0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(10); console.log(buf); @@ -564,7 +796,29 @@ memory from a pool for an indeterminate amount of time, it may be appropriate to create an un-pooled `Buffer` instance using `Buffer.allocUnsafeSlow()` and then copying out the relevant bits. -```js +```mjs +import { Buffer } from 'buffer'; + +// Need to keep around a few small chunks of memory. +const store = []; + +socket.on('readable', () => { + let data; + while (null !== (data = readable.read())) { + // Allocate for retained data. + const sb = Buffer.allocUnsafeSlow(10); + + // Copy the data into the new allocation. + data.copy(sb, 0, 0, 10); + + store.push(sb); + } +}); +``` + +```cjs +const { Buffer } = require('buffer'); + // Need to keep around a few small chunks of memory. const store = []; @@ -612,7 +866,19 @@ For strings that contain non-base64/hex-encoded data (e.g. whitespace), the return value might be greater than the length of a `Buffer` created from the string. -```js +```mjs +import { Buffer } from 'buffer'; + +const str = '\u00bd + \u00bc = \u00be'; + +console.log(`${str}: ${str.length} characters, ` + + `${Buffer.byteLength(str, 'utf8')} bytes`); +// Prints: ½ + ¼ = ¾: 9 characters, 12 bytes +``` + +```cjs +const { Buffer } = require('buffer'); + const str = '\u00bd + \u00bc = \u00be'; console.log(`${str}: ${str.length} characters, ` + @@ -642,7 +908,21 @@ Compares `buf1` to `buf2`, typically for the purpose of sorting arrays of `Buffer` instances. This is equivalent to calling [`buf1.compare(buf2)`][`buf.compare()`]. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from('1234'); +const buf2 = Buffer.from('0123'); +const arr = [buf1, buf2]; + +console.log(arr.sort(Buffer.compare)); +// Prints: [ , ] +// (This result is equal to: [buf2, buf1].) +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from('1234'); const buf2 = Buffer.from('0123'); const arr = [buf1, buf2]; @@ -680,7 +960,30 @@ If `totalLength` is provided, it is coerced to an unsigned integer. If the combined length of the `Buffer`s in `list` exceeds `totalLength`, the result is truncated to `totalLength`. -```js +```mjs +import { Buffer } from 'buffer'; + +// Create a single `Buffer` from a list of three `Buffer` instances. + +const buf1 = Buffer.alloc(10); +const buf2 = Buffer.alloc(14); +const buf3 = Buffer.alloc(18); +const totalLength = buf1.length + buf2.length + buf3.length; + +console.log(totalLength); +// Prints: 42 + +const bufA = Buffer.concat([buf1, buf2, buf3], totalLength); + +console.log(bufA); +// Prints: +console.log(bufA.length); +// Prints: 42 +``` + +```cjs +const { Buffer } = require('buffer'); + // Create a single `Buffer` from a list of three `Buffer` instances. const buf1 = Buffer.alloc(10); @@ -712,15 +1015,24 @@ added: v5.10.0 Allocates a new `Buffer` using an `array` of bytes in the range `0` – `255`. Array entries outside that range will be truncated to fit into it. -```js +```mjs +import { Buffer } from 'buffer'; + // Creates a new Buffer containing the UTF-8 bytes of the string 'buffer'. const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); ``` -A `TypeError` will be thrown if `array` is not an `Array` or another type -appropriate for `Buffer.from()` variants. +```cjs +const { Buffer } = require('buffer'); -`Buffer.from(array)` and [`Buffer.from(string)`][] may also use the internal +// Creates a new Buffer containing the UTF-8 bytes of the string 'buffer'. +const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); +``` + +A `TypeError` will be thrown if `array` is not an `Array` or another type +appropriate for `Buffer.from()` variants. + +`Buffer.from(array)` and [`Buffer.from(string)`][] may also use the internal `Buffer` pool like [`Buffer.allocUnsafe()`][] does. ### Static method: `Buffer.from(arrayBuffer[, byteOffset[, length]])` @@ -740,7 +1052,30 @@ memory. For example, when passed a reference to the `.buffer` property of a [`TypedArray`][] instance, the newly created `Buffer` will share the same allocated memory as the [`TypedArray`][]'s underlying `ArrayBuffer`. -```js +```mjs +import { Buffer } from 'buffer'; + +const arr = new Uint16Array(2); + +arr[0] = 5000; +arr[1] = 4000; + +// Shares memory with `arr`. +const buf = Buffer.from(arr.buffer); + +console.log(buf); +// Prints: + +// Changing the original Uint16Array changes the Buffer also. +arr[1] = 6000; + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const arr = new Uint16Array(2); arr[0] = 5000; @@ -762,7 +1097,19 @@ console.log(buf); The optional `byteOffset` and `length` arguments specify a memory range within the `arrayBuffer` that will be shared by the `Buffer`. -```js +```mjs +import { Buffer } from 'buffer'; + +const ab = new ArrayBuffer(10); +const buf = Buffer.from(ab, 0, 2); + +console.log(buf.length); +// Prints: 2 +``` + +```cjs +const { Buffer } = require('buffer'); + const ab = new ArrayBuffer(10); const buf = Buffer.from(ab, 0, 2); @@ -779,7 +1126,21 @@ of memory that extends beyond the bounds of a `TypedArray` view. A new `Buffer` created using the `buffer` property of a `TypedArray` may extend beyond the range of the `TypedArray`: -```js +```mjs +import { Buffer } from 'buffer'; + +const arrA = Uint8Array.from([0x63, 0x64, 0x65, 0x66]); // 4 elements +const arrB = new Uint8Array(arrA.buffer, 1, 2); // 2 elements +console.log(arrA.buffer === arrB.buffer); // true + +const buf = Buffer.from(arrB.buffer); +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const arrA = Uint8Array.from([0x63, 0x64, 0x65, 0x66]); // 4 elements const arrB = new Uint8Array(arrA.buffer, 1, 2); // 2 elements console.log(arrA.buffer === arrB.buffer); // true @@ -799,7 +1160,23 @@ added: v5.10.0 Copies the passed `buffer` data onto a new `Buffer` instance. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from('buffer'); +const buf2 = Buffer.from(buf1); + +buf1[0] = 0x61; + +console.log(buf1.toString()); +// Prints: auffer +console.log(buf2.toString()); +// Prints: buffer +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from('buffer'); const buf2 = Buffer.from(buf1); @@ -826,7 +1203,16 @@ added: v8.2.0 For objects whose `valueOf()` function returns a value not strictly equal to `object`, returns `Buffer.from(object.valueOf(), offsetOrEncoding, length)`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from(new String('this is a test')); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from(new String('this is a test')); // Prints: ``` @@ -834,7 +1220,22 @@ const buf = Buffer.from(new String('this is a test')); For objects that support `Symbol.toPrimitive`, returns `Buffer.from(object[Symbol.toPrimitive]('string'), offsetOrEncoding)`. -```js +```mjs +import { Buffer } from 'buffer'; + +class Foo { + [Symbol.toPrimitive]() { + return 'this is a test'; + } +} + +const buf = Buffer.from(new Foo(), 'utf8'); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + class Foo { [Symbol.toPrimitive]() { return 'this is a test'; @@ -859,7 +1260,23 @@ added: v5.10.0 Creates a new `Buffer` containing `string`. The `encoding` parameter identifies the character encoding to be used when converting `string` into bytes. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from('this is a tést'); +const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex'); + +console.log(buf1.toString()); +// Prints: this is a tést +console.log(buf2.toString()); +// Prints: this is a tést +console.log(buf1.toString('latin1')); +// Prints: this is a tést +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from('this is a tést'); const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex'); @@ -884,7 +1301,19 @@ added: v0.1.101 Returns `true` if `obj` is a `Buffer`, `false` otherwise. -```js +```mjs +import { Buffer } from 'buffer'; + +Buffer.isBuffer(Buffer.alloc(10)); // true +Buffer.isBuffer(Buffer.from('foo')); // true +Buffer.isBuffer('a string'); // false +Buffer.isBuffer([]); // false +Buffer.isBuffer(new Uint8Array(1024)); // false +``` + +```cjs +const { Buffer } = require('buffer'); + Buffer.isBuffer(Buffer.alloc(10)); // true Buffer.isBuffer(Buffer.from('foo')); // true Buffer.isBuffer('a string'); // false @@ -903,7 +1332,25 @@ added: v0.9.1 Returns `true` if `encoding` is the name of a supported character encoding, or `false` otherwise. -```js +```mjs +import { Buffer } from 'buffer'; + +console.log(Buffer.isEncoding('utf8')); +// Prints: true + +console.log(Buffer.isEncoding('hex')); +// Prints: true + +console.log(Buffer.isEncoding('utf/8')); +// Prints: false + +console.log(Buffer.isEncoding('')); +// Prints: false +``` + +```cjs +const { Buffer } = require('buffer'); + console.log(Buffer.isEncoding('utf8')); // Prints: true @@ -941,7 +1388,27 @@ access is the same as `Uint8Array`. In other words, `buf[index]` returns `buf[index] = value` does not modify the buffer if `index` is negative or `>= buf.length`. -```js +```mjs +import { Buffer } from 'buffer'; + +// Copy an ASCII string into a `Buffer` one byte at a time. +// (This only works for ASCII-only strings. In general, one should use +// `Buffer.from()` to perform this conversion.) + +const str = 'Node.js'; +const buf = Buffer.allocUnsafe(str.length); + +for (let i = 0; i < str.length; i++) { + buf[i] = str.charCodeAt(i); +} + +console.log(buf.toString('utf8')); +// Prints: Node.js +``` + +```cjs +const { Buffer } = require('buffer'); + // Copy an ASCII string into a `Buffer` one byte at a time. // (This only works for ASCII-only strings. In general, one should use // `Buffer.from()` to perform this conversion.) @@ -965,7 +1432,19 @@ console.log(buf.toString('utf8')); This `ArrayBuffer` is not guaranteed to correspond exactly to the original `Buffer`. See the notes on `buf.byteOffset` for details. -```js +```mjs +import { Buffer } from 'buffer'; + +const arrayBuffer = new ArrayBuffer(16); +const buffer = Buffer.from(arrayBuffer); + +console.log(buffer.buffer === arrayBuffer); +// Prints: true +``` + +```cjs +const { Buffer } = require('buffer'); + const arrayBuffer = new ArrayBuffer(16); const buffer = Buffer.from(arrayBuffer); @@ -988,7 +1467,21 @@ to the `Buffer` object itself. A common issue when creating a `TypedArray` object that shares its memory with a `Buffer` is that in this case one needs to specify the `byteOffset` correctly: -```js +```mjs +import { Buffer } from 'buffer'; + +// Create a buffer smaller than `Buffer.poolSize`. +const nodeBuffer = new Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + +// When casting the Node.js Buffer to an Int8Array, use the byteOffset +// to refer only to the part of `nodeBuffer.buffer` that contains the memory +// for `nodeBuffer`. +new Int8Array(nodeBuffer.buffer, nodeBuffer.byteOffset, nodeBuffer.length); +``` + +```cjs +const { Buffer } = require('buffer'); + // Create a buffer smaller than `Buffer.poolSize`. const nodeBuffer = new Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); @@ -1030,7 +1523,31 @@ Comparison is based on the actual sequence of bytes in each `Buffer`. * `1` is returned if `target` should come *before* `buf` when sorted. * `-1` is returned if `target` should come *after* `buf` when sorted. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from('ABC'); +const buf2 = Buffer.from('BCD'); +const buf3 = Buffer.from('ABCD'); + +console.log(buf1.compare(buf1)); +// Prints: 0 +console.log(buf1.compare(buf2)); +// Prints: -1 +console.log(buf1.compare(buf3)); +// Prints: -1 +console.log(buf2.compare(buf1)); +// Prints: 1 +console.log(buf2.compare(buf3)); +// Prints: 1 +console.log([buf1, buf2, buf3].sort(Buffer.compare)); +// Prints: [ , , ] +// (This result is equal to: [buf1, buf3, buf2].) +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('BCD'); const buf3 = Buffer.from('ABCD'); @@ -1054,7 +1571,23 @@ The optional `targetStart`, `targetEnd`, `sourceStart`, and `sourceEnd` arguments can be used to limit the comparison to specific ranges within `target` and `buf` respectively. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]); +const buf2 = Buffer.from([5, 6, 7, 8, 9, 1, 2, 3, 4]); + +console.log(buf1.compare(buf2, 5, 9, 0, 4)); +// Prints: 0 +console.log(buf1.compare(buf2, 0, 6, 4)); +// Prints: -1 +console.log(buf1.compare(buf2, 5, 6, 5)); +// Prints: 1 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]); const buf2 = Buffer.from([5, 6, 7, 8, 9, 1, 2, 3, 4]); @@ -1090,7 +1623,9 @@ memory region overlaps with `buf`. for all TypedArrays, including Node.js `Buffer`s, although it takes different function arguments. -```js +```mjs +import { Buffer } from 'buffer'; + // Create two `Buffer` instances. const buf1 = Buffer.allocUnsafe(26); const buf2 = Buffer.allocUnsafe(26).fill('!'); @@ -1109,7 +1644,49 @@ console.log(buf2.toString('ascii', 0, 25)); // Prints: !!!!!!!!qrst!!!!!!!!!!!!! ``` -```js +```cjs +const { Buffer } = require('buffer'); + +// Create two `Buffer` instances. +const buf1 = Buffer.allocUnsafe(26); +const buf2 = Buffer.allocUnsafe(26).fill('!'); + +for (let i = 0; i < 26; i++) { + // 97 is the decimal ASCII value for 'a'. + buf1[i] = i + 97; +} + +// Copy `buf1` bytes 16 through 19 into `buf2` starting at byte 8 of `buf2`. +buf1.copy(buf2, 8, 16, 20); +// This is equivalent to: +// buf2.set(buf1.subarray(16, 20), 8); + +console.log(buf2.toString('ascii', 0, 25)); +// Prints: !!!!!!!!qrst!!!!!!!!!!!!! +``` + +```mjs +import { Buffer } from 'buffer'; + +// Create a `Buffer` and copy data from one region to an overlapping region +// within the same `Buffer`. + +const buf = Buffer.allocUnsafe(26); + +for (let i = 0; i < 26; i++) { + // 97 is the decimal ASCII value for 'a'. + buf[i] = i + 97; +} + +buf.copy(buf, 0, 4, 10); + +console.log(buf.toString()); +// Prints: efghijghijklmnopqrstuvwxyz +``` + +```cjs +const { Buffer } = require('buffer'); + // Create a `Buffer` and copy data from one region to an overlapping region // within the same `Buffer`. @@ -1136,7 +1713,28 @@ added: v1.1.0 Creates and returns an [iterator][] of `[index, byte]` pairs from the contents of `buf`. -```js +```mjs +import { Buffer } from 'buffer'; + +// Log the entire contents of a `Buffer`. + +const buf = Buffer.from('buffer'); + +for (const pair of buf.entries()) { + console.log(pair); +} +// Prints: +// [0, 98] +// [1, 117] +// [2, 102] +// [3, 102] +// [4, 101] +// [5, 114] +``` + +```cjs +const { Buffer } = require('buffer'); + // Log the entire contents of a `Buffer`. const buf = Buffer.from('buffer'); @@ -1170,7 +1768,22 @@ Returns `true` if both `buf` and `otherBuffer` have exactly the same bytes, `false` otherwise. Equivalent to [`buf.compare(otherBuffer) === 0`][`buf.compare()`]. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from('ABC'); +const buf2 = Buffer.from('414243', 'hex'); +const buf3 = Buffer.from('ABCD'); + +console.log(buf1.equals(buf2)); +// Prints: true +console.log(buf1.equals(buf3)); +// Prints: false +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('414243', 'hex'); const buf3 = Buffer.from('ABCD'); @@ -1216,7 +1829,20 @@ changes: Fills `buf` with the specified `value`. If the `offset` and `end` are not given, the entire `buf` will be filled: -```js +```mjs +import { Buffer } from 'buffer'; + +// Fill a `Buffer` with the ASCII character 'h'. + +const b = Buffer.allocUnsafe(50).fill('h'); + +console.log(b.toString()); +// Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +``` + +```cjs +const { Buffer } = require('buffer'); + // Fill a `Buffer` with the ASCII character 'h'. const b = Buffer.allocUnsafe(50).fill('h'); @@ -1232,17 +1858,43 @@ filled with `value & 255`. If the final write of a `fill()` operation falls on a multi-byte character, then only the bytes of that character that fit into `buf` are written: -```js +```mjs +import { Buffer } from 'buffer'; + // Fill a `Buffer` with character that takes up two bytes in UTF-8. console.log(Buffer.allocUnsafe(5).fill('\u0222')); // Prints: ``` -If `value` contains invalid characters, it is truncated; if no valid -fill data remains, an exception is thrown: +```cjs +const { Buffer } = require('buffer'); + +// Fill a `Buffer` with character that takes up two bytes in UTF-8. + +console.log(Buffer.allocUnsafe(5).fill('\u0222')); +// Prints: +``` + +If `value` contains invalid characters, it is truncated; if no valid +fill data remains, an exception is thrown: + +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(5); + +console.log(buf.fill('a')); +// Prints: +console.log(buf.fill('aazz', 'hex')); +// Prints: +console.log(buf.fill('zz', 'hex')); +// Throws an exception. +``` + +```cjs +const { Buffer } = require('buffer'); -```js const buf = Buffer.allocUnsafe(5); console.log(buf.fill('a')); @@ -1267,7 +1919,30 @@ added: v5.3.0 Equivalent to [`buf.indexOf() !== -1`][`buf.indexOf()`]. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('this is a buffer'); + +console.log(buf.includes('this')); +// Prints: true +console.log(buf.includes('is')); +// Prints: true +console.log(buf.includes(Buffer.from('a buffer'))); +// Prints: true +console.log(buf.includes(97)); +// Prints: true (97 is the decimal ASCII value for 'a') +console.log(buf.includes(Buffer.from('a buffer example'))); +// Prints: false +console.log(buf.includes(Buffer.from('a buffer example').slice(0, 8))); +// Prints: true +console.log(buf.includes('this', 4)); +// Prints: false +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('this is a buffer'); console.log(buf.includes('this')); @@ -1319,7 +1994,35 @@ If `value` is: * a number, `value` will be interpreted as an unsigned 8-bit integer value between `0` and `255`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('this is a buffer'); + +console.log(buf.indexOf('this')); +// Prints: 0 +console.log(buf.indexOf('is')); +// Prints: 2 +console.log(buf.indexOf(Buffer.from('a buffer'))); +// Prints: 8 +console.log(buf.indexOf(97)); +// Prints: 8 (97 is the decimal ASCII value for 'a') +console.log(buf.indexOf(Buffer.from('a buffer example'))); +// Prints: -1 +console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8))); +// Prints: 8 + +const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'utf16le'); + +console.log(utf16Buffer.indexOf('\u03a3', 0, 'utf16le')); +// Prints: 4 +console.log(utf16Buffer.indexOf('\u03a3', -4, 'utf16le')); +// Prints: 6 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('this is a buffer'); console.log(buf.indexOf('this')); @@ -1351,7 +2054,27 @@ If `byteOffset` is not a number, it will be coerced to a number. If the result of coercion is `NaN` or `0`, then the entire buffer will be searched. This behavior matches [`String.prototype.indexOf()`][]. -```js +```mjs +import { Buffer } from 'buffer'; + +const b = Buffer.from('abcdef'); + +// Passing a value that's a number, but not a valid byte. +// Prints: 2, equivalent to searching for 99 or 'c'. +console.log(b.indexOf(99.9)); +console.log(b.indexOf(256 + 99)); + +// Passing a byteOffset that coerces to NaN or 0. +// Prints: 1, searching the whole buffer. +console.log(b.indexOf('b', undefined)); +console.log(b.indexOf('b', {})); +console.log(b.indexOf('b', null)); +console.log(b.indexOf('b', [])); +``` + +```cjs +const { Buffer } = require('buffer'); + const b = Buffer.from('abcdef'); // Passing a value that's a number, but not a valid byte. @@ -1380,7 +2103,26 @@ added: v1.1.0 Creates and returns an [iterator][] of `buf` keys (indices). -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('buffer'); + +for (const key of buf.keys()) { + console.log(key); +} +// Prints: +// 0 +// 1 +// 2 +// 3 +// 4 +// 5 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('buffer'); for (const key of buf.keys()) { @@ -1417,7 +2159,37 @@ changes: Identical to [`buf.indexOf()`][], except the last occurrence of `value` is found rather than the first occurrence. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('this buffer is a buffer'); + +console.log(buf.lastIndexOf('this')); +// Prints: 0 +console.log(buf.lastIndexOf('buffer')); +// Prints: 17 +console.log(buf.lastIndexOf(Buffer.from('buffer'))); +// Prints: 17 +console.log(buf.lastIndexOf(97)); +// Prints: 15 (97 is the decimal ASCII value for 'a') +console.log(buf.lastIndexOf(Buffer.from('yolo'))); +// Prints: -1 +console.log(buf.lastIndexOf('buffer', 5)); +// Prints: 5 +console.log(buf.lastIndexOf('buffer', 4)); +// Prints: -1 + +const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'utf16le'); + +console.log(utf16Buffer.lastIndexOf('\u03a3', undefined, 'utf16le')); +// Prints: 6 +console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'utf16le')); +// Prints: 4 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('this buffer is a buffer'); console.log(buf.lastIndexOf('this')); @@ -1451,7 +2223,30 @@ If `byteOffset` is not a number, it will be coerced to a number. Any arguments that coerce to `NaN`, like `{}` or `undefined`, will search the whole buffer. This behavior matches [`String.prototype.lastIndexOf()`][]. -```js +```mjs +import { Buffer } from 'buffer'; + +const b = Buffer.from('abcdef'); + +// Passing a value that's a number, but not a valid byte. +// Prints: 2, equivalent to searching for 99 or 'c'. +console.log(b.lastIndexOf(99.9)); +console.log(b.lastIndexOf(256 + 99)); + +// Passing a byteOffset that coerces to NaN. +// Prints: 1, searching the whole buffer. +console.log(b.lastIndexOf('b', undefined)); +console.log(b.lastIndexOf('b', {})); + +// Passing a byteOffset that coerces to 0. +// Prints: -1, equivalent to passing 0. +console.log(b.lastIndexOf('b', null)); +console.log(b.lastIndexOf('b', [])); +``` + +```cjs +const { Buffer } = require('buffer'); + const b = Buffer.from('abcdef'); // Passing a value that's a number, but not a valid byte. @@ -1481,7 +2276,25 @@ added: v0.1.90 Returns the number of bytes in `buf`. -```js +```mjs +import { Buffer } from 'buffer'; + +// Create a `Buffer` and write a shorter string to it using UTF-8. + +const buf = Buffer.alloc(1234); + +console.log(buf.length); +// Prints: 1234 + +buf.write('some string', 0, 'utf8'); + +console.log(buf.length); +// Prints: 1234 +``` + +```cjs +const { Buffer } = require('buffer'); + // Create a `Buffer` and write a shorter string to it using UTF-8. const buf = Buffer.alloc(1234); @@ -1559,7 +2372,18 @@ Reads an unsigned, big-endian 64-bit integer from `buf` at the specified This function is also available under the `readBigUint64BE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]); + +console.log(buf.readBigUInt64BE(0)); +// Prints: 4294967295n +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]); console.log(buf.readBigUInt64BE(0)); @@ -1588,7 +2412,18 @@ Reads an unsigned, little-endian 64-bit integer from `buf` at the specified This function is also available under the `readBigUint64LE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]); + +console.log(buf.readBigUInt64LE(0)); +// Prints: 18446744069414584320n +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]); console.log(buf.readBigUInt64LE(0)); @@ -1611,7 +2446,18 @@ changes: Reads a 64-bit, big-endian double from `buf` at the specified `offset`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); + +console.log(buf.readDoubleBE(0)); +// Prints: 8.20788039913184e-304 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); console.log(buf.readDoubleBE(0)); @@ -1634,7 +2480,20 @@ changes: Reads a 64-bit, little-endian double from `buf` at the specified `offset`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); + +console.log(buf.readDoubleLE(0)); +// Prints: 5.447603722011605e-270 +console.log(buf.readDoubleLE(1)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); console.log(buf.readDoubleLE(0)); @@ -1659,7 +2518,18 @@ changes: Reads a 32-bit, big-endian float from `buf` at the specified `offset`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([1, 2, 3, 4]); + +console.log(buf.readFloatBE(0)); +// Prints: 2.387939260590663e-38 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([1, 2, 3, 4]); console.log(buf.readFloatBE(0)); @@ -1682,7 +2552,20 @@ changes: Reads a 32-bit, little-endian float from `buf` at the specified `offset`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([1, 2, 3, 4]); + +console.log(buf.readFloatLE(0)); +// Prints: 1.539989614439558e-36 +console.log(buf.readFloatLE(1)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([1, 2, 3, 4]); console.log(buf.readFloatLE(0)); @@ -1709,7 +2592,22 @@ Reads a signed 8-bit integer from `buf` at the specified `offset`. Integers read from a `Buffer` are interpreted as two's complement signed values. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([-1, 5]); + +console.log(buf.readInt8(0)); +// Prints: -1 +console.log(buf.readInt8(1)); +// Prints: 5 +console.log(buf.readInt8(2)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([-1, 5]); console.log(buf.readInt8(0)); @@ -1738,7 +2636,18 @@ Reads a signed, big-endian 16-bit integer from `buf` at the specified `offset`. Integers read from a `Buffer` are interpreted as two's complement signed values. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0, 5]); + +console.log(buf.readInt16BE(0)); +// Prints: 5 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0, 5]); console.log(buf.readInt16BE(0)); @@ -1764,7 +2673,20 @@ Reads a signed, little-endian 16-bit integer from `buf` at the specified Integers read from a `Buffer` are interpreted as two's complement signed values. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0, 5]); + +console.log(buf.readInt16LE(0)); +// Prints: 1280 +console.log(buf.readInt16LE(1)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0, 5]); console.log(buf.readInt16LE(0)); @@ -1791,7 +2713,18 @@ Reads a signed, big-endian 32-bit integer from `buf` at the specified `offset`. Integers read from a `Buffer` are interpreted as two's complement signed values. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0, 0, 0, 5]); + +console.log(buf.readInt32BE(0)); +// Prints: 5 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0, 0, 0, 5]); console.log(buf.readInt32BE(0)); @@ -1817,7 +2750,20 @@ Reads a signed, little-endian 32-bit integer from `buf` at the specified Integers read from a `Buffer` are interpreted as two's complement signed values. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0, 0, 0, 5]); + +console.log(buf.readInt32LE(0)); +// Prints: 83886080 +console.log(buf.readInt32LE(1)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0, 0, 0, 5]); console.log(buf.readInt32LE(0)); @@ -1846,7 +2792,22 @@ Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as a big-endian, two's complement signed value supporting up to 48 bits of accuracy. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); + +console.log(buf.readIntBE(0, 6).toString(16)); +// Prints: 1234567890ab +console.log(buf.readIntBE(1, 6).toString(16)); +// Throws ERR_OUT_OF_RANGE. +console.log(buf.readIntBE(1, 0).toString(16)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); console.log(buf.readIntBE(0, 6).toString(16)); @@ -1877,7 +2838,18 @@ Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as a little-endian, two's complement signed value supporting up to 48 bits of accuracy. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); + +console.log(buf.readIntLE(0, 6).toString(16)); +// Prints: -546f87a9cbee +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); console.log(buf.readIntLE(0, 6).toString(16)); @@ -1907,7 +2879,22 @@ Reads an unsigned 8-bit integer from `buf` at the specified `offset`. This function is also available under the `readUint8` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([1, -2]); + +console.log(buf.readUInt8(0)); +// Prints: 1 +console.log(buf.readUInt8(1)); +// Prints: 254 +console.log(buf.readUInt8(2)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([1, -2]); console.log(buf.readUInt8(0)); @@ -1942,7 +2929,20 @@ Reads an unsigned, big-endian 16-bit integer from `buf` at the specified This function is also available under the `readUint16BE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56]); + +console.log(buf.readUInt16BE(0).toString(16)); +// Prints: 1234 +console.log(buf.readUInt16BE(1).toString(16)); +// Prints: 3456 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56]); console.log(buf.readUInt16BE(0).toString(16)); @@ -1975,7 +2975,22 @@ Reads an unsigned, little-endian 16-bit integer from `buf` at the specified This function is also available under the `readUint16LE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56]); + +console.log(buf.readUInt16LE(0).toString(16)); +// Prints: 3412 +console.log(buf.readUInt16LE(1).toString(16)); +// Prints: 5634 +console.log(buf.readUInt16LE(2).toString(16)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56]); console.log(buf.readUInt16LE(0).toString(16)); @@ -2010,7 +3025,18 @@ Reads an unsigned, big-endian 32-bit integer from `buf` at the specified This function is also available under the `readUint32BE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]); + +console.log(buf.readUInt32BE(0).toString(16)); +// Prints: 12345678 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]); console.log(buf.readUInt32BE(0).toString(16)); @@ -2041,7 +3067,20 @@ Reads an unsigned, little-endian 32-bit integer from `buf` at the specified This function is also available under the `readUint32LE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]); + +console.log(buf.readUInt32LE(0).toString(16)); +// Prints: 78563412 +console.log(buf.readUInt32LE(1).toString(16)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]); console.log(buf.readUInt32LE(0).toString(16)); @@ -2077,7 +3116,20 @@ up to 48 bits of accuracy. This function is also available under the `readUintBE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); + +console.log(buf.readUIntBE(0, 6).toString(16)); +// Prints: 1234567890ab +console.log(buf.readUIntBE(1, 6).toString(16)); +// Throws ERR_OUT_OF_RANGE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); console.log(buf.readUIntBE(0, 6).toString(16)); @@ -2113,7 +3165,18 @@ up to 48 bits of accuracy. This function is also available under the `readUintLE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); + +console.log(buf.readUIntLE(0, 6).toString(16)); +// Prints: ab9078563412 +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); console.log(buf.readUIntLE(0, 6).toString(16)); @@ -2141,7 +3204,33 @@ This method is inherited from [`TypedArray.prototype.subarray()`][]. Modifying the new `Buffer` slice will modify the memory in the original `Buffer` because the allocated memory of the two objects overlap. -```js +```mjs +import { Buffer } from 'buffer'; + +// Create a `Buffer` with the ASCII alphabet, take a slice, and modify one byte +// from the original `Buffer`. + +const buf1 = Buffer.allocUnsafe(26); + +for (let i = 0; i < 26; i++) { + // 97 is the decimal ASCII value for 'a'. + buf1[i] = i + 97; +} + +const buf2 = buf1.subarray(0, 3); + +console.log(buf2.toString('ascii', 0, buf2.length)); +// Prints: abc + +buf1[0] = 33; + +console.log(buf2.toString('ascii', 0, buf2.length)); +// Prints: !bc +``` + +```cjs +const { Buffer } = require('buffer'); + // Create a `Buffer` with the ASCII alphabet, take a slice, and modify one byte // from the original `Buffer`. @@ -2166,7 +3255,27 @@ console.log(buf2.toString('ascii', 0, buf2.length)); Specifying negative indexes causes the slice to be generated relative to the end of `buf` rather than the beginning. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('buffer'); + +console.log(buf.subarray(-6, -1).toString()); +// Prints: buffe +// (Equivalent to buf.subarray(0, 5).) + +console.log(buf.subarray(-6, -2).toString()); +// Prints: buff +// (Equivalent to buf.subarray(0, 4).) + +console.log(buf.subarray(-5, -2).toString()); +// Prints: uff +// (Equivalent to buf.subarray(1, 4).) +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('buffer'); console.log(buf.subarray(-6, -1).toString()); @@ -2212,7 +3321,23 @@ This method is not compatible with the `Uint8Array.prototype.slice()`, which is a superclass of `Buffer`. To copy the slice, use `Uint8Array.prototype.slice()`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('buffer'); + +const copiedBuf = Uint8Array.prototype.slice.call(buf); +copiedBuf[0]++; +console.log(copiedBuf.toString()); +// Prints: cuffer + +console.log(buf.toString()); +// Prints: buffer +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('buffer'); const copiedBuf = Uint8Array.prototype.slice.call(buf); @@ -2235,7 +3360,28 @@ Interprets `buf` as an array of unsigned 16-bit integers and swaps the byte order *in-place*. Throws [`ERR_INVALID_BUFFER_SIZE`][] if [`buf.length`][] is not a multiple of 2. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + +console.log(buf1); +// Prints: + +buf1.swap16(); + +console.log(buf1); +// Prints: + +const buf2 = Buffer.from([0x1, 0x2, 0x3]); + +buf2.swap16(); +// Throws ERR_INVALID_BUFFER_SIZE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); console.log(buf1); @@ -2255,7 +3401,16 @@ buf2.swap16(); One convenient use of `buf.swap16()` is to perform a fast in-place conversion between UTF-16 little-endian and UTF-16 big-endian: -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('This is little-endian UTF-16', 'utf16le'); +buf.swap16(); // Convert to big-endian UTF-16 text. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from('This is little-endian UTF-16', 'utf16le'); buf.swap16(); // Convert to big-endian UTF-16 text. ``` @@ -2271,7 +3426,28 @@ Interprets `buf` as an array of unsigned 32-bit integers and swaps the byte order *in-place*. Throws [`ERR_INVALID_BUFFER_SIZE`][] if [`buf.length`][] is not a multiple of 4. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + +console.log(buf1); +// Prints: + +buf1.swap32(); + +console.log(buf1); +// Prints: + +const buf2 = Buffer.from([0x1, 0x2, 0x3]); + +buf2.swap32(); +// Throws ERR_INVALID_BUFFER_SIZE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); console.log(buf1); @@ -2298,7 +3474,28 @@ added: v6.3.0 Interprets `buf` as an array of 64-bit numbers and swaps byte order *in-place*. Throws [`ERR_INVALID_BUFFER_SIZE`][] if [`buf.length`][] is not a multiple of 8. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + +console.log(buf1); +// Prints: + +buf1.swap64(); + +console.log(buf1); +// Prints: + +const buf2 = Buffer.from([0x1, 0x2, 0x3]); + +buf2.swap64(); +// Throws ERR_INVALID_BUFFER_SIZE. +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); console.log(buf1); @@ -2328,7 +3525,28 @@ this function when stringifying a `Buffer` instance. `Buffer.from()` accepts objects in the format returned from this method. In particular, `Buffer.from(buf.toJSON())` works like `Buffer.from(buf)`. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); +const json = JSON.stringify(buf); + +console.log(json); +// Prints: {"type":"Buffer","data":[1,2,3,4,5]} + +const copy = JSON.parse(json, (key, value) => { + return value && value.type === 'Buffer' ? + Buffer.from(value) : + value; +}); + +console.log(copy); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); const json = JSON.stringify(buf); @@ -2365,7 +3583,34 @@ then each invalid byte is replaced with the replacement character `U+FFFD`. The maximum length of a string instance (in UTF-16 code units) is available as [`buffer.constants.MAX_STRING_LENGTH`][]. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf1 = Buffer.allocUnsafe(26); + +for (let i = 0; i < 26; i++) { + // 97 is the decimal ASCII value for 'a'. + buf1[i] = i + 97; +} + +console.log(buf1.toString('utf8')); +// Prints: abcdefghijklmnopqrstuvwxyz +console.log(buf1.toString('utf8', 0, 5)); +// Prints: abcde + +const buf2 = Buffer.from('tést'); + +console.log(buf2.toString('hex')); +// Prints: 74c3a97374 +console.log(buf2.toString('utf8', 0, 3)); +// Prints: té +console.log(buf2.toString(undefined, 0, 3)); +// Prints: té +``` + +```cjs +const { Buffer } = require('buffer'); + const buf1 = Buffer.allocUnsafe(26); for (let i = 0; i < 26; i++) { @@ -2395,10 +3640,40 @@ added: v1.1.0 * Returns: {Iterator} -Creates and returns an [iterator][] for `buf` values (bytes). This function is -called automatically when a `Buffer` is used in a `for..of` statement. +Creates and returns an [iterator][] for `buf` values (bytes). This function is +called automatically when a `Buffer` is used in a `for..of` statement. + +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.from('buffer'); + +for (const value of buf.values()) { + console.log(value); +} +// Prints: +// 98 +// 117 +// 102 +// 102 +// 101 +// 114 + +for (const value of buf) { + console.log(value); +} +// Prints: +// 98 +// 117 +// 102 +// 102 +// 101 +// 114 +``` + +```cjs +const { Buffer } = require('buffer'); -```js const buf = Buffer.from('buffer'); for (const value of buf.values()) { @@ -2442,7 +3717,27 @@ Writes `string` to `buf` at `offset` according to the character encoding in not contain enough space to fit the entire string, only part of `string` will be written. However, partially encoded characters will not be written. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.alloc(256); + +const len = buf.write('\u00bd + \u00bc = \u00be', 0); + +console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); +// Prints: 12 bytes: ½ + ¼ = ¾ + +const buffer = Buffer.alloc(10); + +const length = buffer.write('abcd', 8); + +console.log(`${length} bytes: ${buffer.toString('utf8', 8, 10)}`); +// Prints: 2 bytes : ab +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.alloc(256); const len = buf.write('\u00bd + \u00bc = \u00be', 0); @@ -2474,7 +3769,20 @@ Writes `value` to `buf` at the specified `offset` as big-endian. `value` is interpreted and written as a two's complement signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(8); + +buf.writeBigInt64BE(0x0102030405060708n, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(8); buf.writeBigInt64BE(0x0102030405060708n, 0); @@ -2499,7 +3807,20 @@ Writes `value` to `buf` at the specified `offset` as little-endian. `value` is interpreted and written as a two's complement signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(8); + +buf.writeBigInt64LE(0x0102030405060708n, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(8); buf.writeBigInt64LE(0x0102030405060708n, 0); @@ -2530,7 +3851,20 @@ Writes `value` to `buf` at the specified `offset` as big-endian. This function is also available under the `writeBigUint64BE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(8); + +buf.writeBigUInt64BE(0xdecafafecacefaden, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(8); buf.writeBigUInt64BE(0xdecafafecacefaden, 0); @@ -2559,7 +3893,20 @@ changes: Writes `value` to `buf` at the specified `offset` as little-endian -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(8); + +buf.writeBigUInt64LE(0xdecafafecacefaden, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(8); buf.writeBigUInt64LE(0xdecafafecacefaden, 0); @@ -2589,7 +3936,20 @@ Writes `value` to `buf` at the specified `offset` as big-endian. The `value` must be a JavaScript number. Behavior is undefined when `value` is anything other than a JavaScript number. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(8); + +buf.writeDoubleBE(123.456, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(8); buf.writeDoubleBE(123.456, 0); @@ -2617,7 +3977,20 @@ Writes `value` to `buf` at the specified `offset` as little-endian. The `value` must be a JavaScript number. Behavior is undefined when `value` is anything other than a JavaScript number. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(8); + +buf.writeDoubleLE(123.456, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(8); buf.writeDoubleLE(123.456, 0); @@ -2644,7 +4017,20 @@ changes: Writes `value` to `buf` at the specified `offset` as big-endian. Behavior is undefined when `value` is anything other than a JavaScript number. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeFloatBE(0xcafebabe, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeFloatBE(0xcafebabe, 0); @@ -2671,7 +4057,20 @@ changes: Writes `value` to `buf` at the specified `offset` as little-endian. Behavior is undefined when `value` is anything other than a JavaScript number. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeFloatLE(0xcafebabe, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeFloatLE(0xcafebabe, 0); @@ -2701,7 +4100,21 @@ a signed 8-bit integer. `value` is interpreted and written as a two's complement signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(2); + +buf.writeInt8(2, 0); +buf.writeInt8(-2, 1); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(2); buf.writeInt8(2, 0); @@ -2732,7 +4145,20 @@ anything other than a signed 16-bit integer. The `value` is interpreted and written as a two's complement signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(2); + +buf.writeInt16BE(0x0102, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(2); buf.writeInt16BE(0x0102, 0); @@ -2762,7 +4188,20 @@ anything other than a signed 16-bit integer. The `value` is interpreted and written as a two's complement signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(2); + +buf.writeInt16LE(0x0304, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(2); buf.writeInt16LE(0x0304, 0); @@ -2792,7 +4231,20 @@ anything other than a signed 32-bit integer. The `value` is interpreted and written as a two's complement signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeInt32BE(0x01020304, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeInt32BE(0x01020304, 0); @@ -2822,7 +4274,20 @@ anything other than a signed 32-bit integer. The `value` is interpreted and written as a two's complement signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeInt32LE(0x05060708, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeInt32LE(0x05060708, 0); @@ -2852,7 +4317,20 @@ Writes `byteLength` bytes of `value` to `buf` at the specified `offset` as big-endian. Supports up to 48 bits of accuracy. Behavior is undefined when `value` is anything other than a signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(6); + +buf.writeIntBE(0x1234567890ab, 0, 6); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(6); buf.writeIntBE(0x1234567890ab, 0, 6); @@ -2882,7 +4360,20 @@ Writes `byteLength` bytes of `value` to `buf` at the specified `offset` as little-endian. Supports up to 48 bits of accuracy. Behavior is undefined when `value` is anything other than a signed integer. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(6); + +buf.writeIntLE(0x1234567890ab, 0, 6); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(6); buf.writeIntLE(0x1234567890ab, 0, 6); @@ -2917,7 +4408,23 @@ other than an unsigned 8-bit integer. This function is also available under the `writeUint8` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeUInt8(0x3, 0); +buf.writeUInt8(0x4, 1); +buf.writeUInt8(0x23, 2); +buf.writeUInt8(0x42, 3); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeUInt8(0x3, 0); @@ -2955,7 +4462,21 @@ is anything other than an unsigned 16-bit integer. This function is also available under the `writeUint16BE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeUInt16BE(0xdead, 0); +buf.writeUInt16BE(0xbeef, 2); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeUInt16BE(0xdead, 0); @@ -2991,7 +4512,21 @@ anything other than an unsigned 16-bit integer. This function is also available under the `writeUint16LE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeUInt16LE(0xdead, 0); +buf.writeUInt16LE(0xbeef, 2); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeUInt16LE(0xdead, 0); @@ -3027,7 +4562,20 @@ is anything other than an unsigned 32-bit integer. This function is also available under the `writeUint32BE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeUInt32BE(0xfeedface, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeUInt32BE(0xfeedface, 0); @@ -3062,7 +4610,20 @@ anything other than an unsigned 32-bit integer. This function is also available under the `writeUint32LE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(4); + +buf.writeUInt32LE(0xfeedface, 0); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(4); buf.writeUInt32LE(0xfeedface, 0); @@ -3099,7 +4660,20 @@ when `value` is anything other than an unsigned integer. This function is also available under the `writeUintBE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(6); + +buf.writeUIntBE(0x1234567890ab, 0, 6); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(6); buf.writeUIntBE(0x1234567890ab, 0, 6); @@ -3136,7 +4710,20 @@ when `value` is anything other than an unsigned integer. This function is also available under the `writeUintLE` alias. -```js +```mjs +import { Buffer } from 'buffer'; + +const buf = Buffer.allocUnsafe(6); + +buf.writeUIntLE(0x1234567890ab, 0, 6); + +console.log(buf); +// Prints: +``` + +```cjs +const { Buffer } = require('buffer'); + const buf = Buffer.allocUnsafe(6); buf.writeUIntLE(0x1234567890ab, 0, 6); @@ -3382,10 +4969,18 @@ Encodings supported by `buffer.transcode()` are: `'ascii'`, `'utf8'`, The transcoding process will use substitution characters if a given byte sequence cannot be adequately represented in the target encoding. For instance: -```js -const buffer = require('buffer'); +```mjs +import { Buffer, transcode } from 'buffer'; + +const newBuf = transcode(Buffer.from('€'), 'utf8', 'ascii'); +console.log(newBuf.toString('ascii')); +// Prints: '?' +``` + +```cjs +const { Buffer, transcode } = require('buffer'); -const newBuf = buffer.transcode(Buffer.from('€'), 'utf8', 'ascii'); +const newBuf = transcode(Buffer.from('€'), 'utf8', 'ascii'); console.log(newBuf.toString('ascii')); // Prints: '?' ``` diff --git a/doc/api/cluster.md b/doc/api/cluster.md index d12c1f12d256d8..e8e72468f08fa2 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -13,7 +13,37 @@ processes to handle the load. The cluster module allows easy creation of child processes that all share server ports. -```js +```mjs +import cluster from 'cluster'; +import http from 'http'; +import { cpus } from 'os'; + +const numCPUs = cpus().length; + +if (cluster.isPrimary) { + console.log(`Primary ${process.pid} is running`); + + // Fork workers. + for (let i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + cluster.on('exit', (worker, code, signal) => { + console.log(`worker ${worker.process.pid} died`); + }); +} else { + // Workers can share any TCP connection + // In this case it is an HTTP server + http.createServer((req, res) => { + res.writeHead(200); + res.end('hello world\n'); + }).listen(8000); + + console.log(`Worker ${process.pid} started`); +} +``` + +```cjs const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; @@ -157,7 +187,24 @@ added: v0.11.2 Similar to the `cluster.on('exit')` event, but specific to this worker. -```js +```mjs +import cluster from 'cluster'; + +const worker = cluster.fork(); +worker.on('exit', (code, signal) => { + if (signal) { + console.log(`worker was killed by signal: ${signal}`); + } else if (code !== 0) { + console.log(`worker exited with error code: ${code}`); + } else { + console.log('worker success!'); + } +}); +``` + +```cjs +const cluster = require('cluster'); + const worker = cluster.fork(); worker.on('exit', (code, signal) => { if (signal) { @@ -179,7 +226,17 @@ added: v0.7.0 Similar to the `cluster.on('listening')` event, but specific to this worker. -```js +```mjs +import cluster from 'cluster'; + +cluster.fork().on('listening', (address) => { + // Worker is listening +}); +``` + +```cjs +const cluster = require('cluster'); + cluster.fork().on('listening', (address) => { // Worker is listening }); @@ -204,7 +261,50 @@ See [`process` event: `'message'`][]. Here is an example using the message system. It keeps a count in the primary process of the number of HTTP requests received by the workers: -```js +```mjs +import cluster from 'cluster'; +import http from 'http'; +import { cpus } from 'os'; + +if (cluster.isPrimary) { + + // Keep track of http requests + let numReqs = 0; + setInterval(() => { + console.log(`numReqs = ${numReqs}`); + }, 1000); + + // Count requests + function messageHandler(msg) { + if (msg.cmd && msg.cmd === 'notifyRequest') { + numReqs += 1; + } + } + + // Start workers and listen for messages containing notifyRequest + const numCPUs = cpus().length; + for (let i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + for (const id in cluster.workers) { + cluster.workers[id].on('message', messageHandler); + } + +} else { + + // Worker processes have a http server. + http.Server((req, res) => { + res.writeHead(200); + res.end('hello world\n'); + + // Notify primary about the request + process.send({ cmd: 'notifyRequest' }); + }).listen(8000); +} +``` + +```cjs const cluster = require('cluster'); const http = require('http'); @@ -387,7 +487,39 @@ added: v0.11.14 This function returns `true` if the worker's process has terminated (either because of exiting or being signaled). Otherwise, it returns `false`. -```js +```mjs +import cluster from 'cluster'; +import http from 'http'; +import { cpus } from 'os'; + +const numCPUs = cpus().length; + +if (cluster.isPrimary) { + console.log(`Primary ${process.pid} is running`); + + // Fork workers. + for (let i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + cluster.on('fork', (worker) => { + console.log('worker is dead:', worker.isDead()); + }); + + cluster.on('exit', (worker, code, signal) => { + console.log('worker is dead:', worker.isDead()); + }); +} else { + // Workers can share any TCP connection. In this case, it is an HTTP server. + http.createServer((req, res) => { + res.writeHead(200); + res.end(`Current process\n ${process.pid}`); + process.kill(process.pid); + }).listen(8000); +} +``` + +```cjs const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; @@ -817,8 +949,25 @@ the `env` passed to [`.fork()`][]. The defaults above apply to the first call only; the defaults for later calls are the current values at the time of `cluster.setupPrimary()` is called. -```js +```mjs +import cluster from 'cluster'; + +cluster.setupPrimary({ + exec: 'worker.js', + args: ['--use', 'https'], + silent: true +}); +cluster.fork(); // https worker +cluster.setupPrimary({ + exec: 'worker.js', + args: ['--use', 'http'] +}); +cluster.fork(); // http worker +``` + +```cjs const cluster = require('cluster'); + cluster.setupPrimary({ exec: 'worker.js', args: ['--use', 'https'], @@ -843,7 +992,19 @@ added: v0.7.0 A reference to the current worker object. Not available in the primary process. -```js +```mjs +import cluster from 'cluster'; + +if (cluster.isPrimary) { + console.log('I am primary'); + cluster.fork(); + cluster.fork(); +} else if (cluster.isWorker) { + console.log(`I am worker #${cluster.worker.id}`); +} +``` + +```cjs const cluster = require('cluster'); if (cluster.isPrimary) { @@ -871,7 +1032,23 @@ _and_ exited. The order between these two events cannot be determined in advance. However, it is guaranteed that the removal from the `cluster.workers` list happens before last `'disconnect'` or `'exit'` event is emitted. -```js +```mjs +import cluster from 'cluster'; + +// Go through all workers +function eachWorker(callback) { + for (const id in cluster.workers) { + callback(cluster.workers[id]); + } +} +eachWorker((worker) => { + worker.send('big announcement to all workers'); +}); +``` + +```cjs +const cluster = require('cluster'); + // Go through all workers function eachWorker(callback) { for (const id in cluster.workers) { diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 8bd28d20b0c6ee..84959c286548cb 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -99,7 +99,7 @@ changes: includes a public key and a challenge. ```mjs -const { Certificate } = await import('crypto'); +import { Certificate } from 'crypto'; const spkac = getSpkacSomehow(); const challenge = Certificate.exportChallenge(spkac); console.log(challenge.toString('utf8')); @@ -130,7 +130,7 @@ changes: which includes a public key and a challenge. ```mjs -const { Certificate } = await import('crypto'); +import { Certificate } from 'crypto'; const spkac = getSpkacSomehow(); const publicKey = Certificate.exportPublicKey(spkac); console.log(publicKey); @@ -162,7 +162,7 @@ changes: `false` otherwise. ```mjs -const { Certificate } = await import('crypto'); +import { Certificate } from 'crypto'; const spkac = getSpkacSomehow(); console.log(Certificate.verifySpkac(Buffer.from(spkac))); // Prints: true or false @@ -188,7 +188,7 @@ Instances of the `Certificate` class can be created using the `new` keyword or by calling `crypto.Certificate()` as a function: ```mjs -const { Certificate } = await import('crypto'); +import { Certificate } from 'crypto'; const cert1 = new Certificate(); const cert2 = Certificate(); @@ -212,7 +212,7 @@ added: v0.11.8 includes a public key and a challenge. ```mjs -const { Certificate } = await import('crypto'); +import { Certificate } from 'crypto'; const cert = Certificate(); const spkac = getSpkacSomehow(); const challenge = cert.exportChallenge(spkac); @@ -240,7 +240,7 @@ added: v0.11.8 which includes a public key and a challenge. ```mjs -const { Certificate } = await import('crypto'); +import { Certificate } from 'crypto'; const cert = Certificate(); const spkac = getSpkacSomehow(); const publicKey = cert.exportPublicKey(spkac); @@ -268,7 +268,7 @@ added: v0.11.8 `false` otherwise. ```mjs -const { Certificate } = await import('crypto'); +import { Certificate } from 'crypto'; const cert = Certificate(); const spkac = getSpkacSomehow(); console.log(cert.verifySpkac(Buffer.from(spkac))); @@ -305,11 +305,11 @@ directly using the `new` keyword. Example: Using `Cipher` objects as streams: ```mjs -const { +import { scrypt, randomFill, createCipheriv -} = await import('crypto'); +} from 'crypto'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -382,11 +382,11 @@ import { pipeline } from 'stream'; -const { +import { scrypt, randomFill, - createCipheriv, -} = await import('crypto'); + createCipheriv +} from 'crypto'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -453,11 +453,11 @@ scrypt(password, 'salt', 24, (err, key) => { Example: Using the [`cipher.update()`][] and [`cipher.final()`][] methods: ```mjs -const { +import { scrypt, randomFill, - createCipheriv, -} = await import('crypto'); + createCipheriv +} from 'crypto'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -626,10 +626,10 @@ directly using the `new` keyword. Example: Using `Decipher` objects as streams: ```mjs -const { +import { scryptSync, - createDecipheriv, -} = await import('crypto'); + createDecipheriv +} from 'crypto'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -703,10 +703,10 @@ import { createWriteStream, } from 'fs'; -const { +import { scryptSync, - createDecipheriv, -} = await import('crypto'); + createDecipheriv +} from 'crypto'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -752,10 +752,10 @@ input.pipe(decipher).pipe(output); Example: Using the [`decipher.update()`][] and [`decipher.final()`][] methods: ```mjs -const { +import { scryptSync, - createDecipheriv, -} = await import('crypto'); + createDecipheriv +} from 'crypto'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -941,9 +941,9 @@ Instances of the `DiffieHellman` class can be created using the ```mjs import assert from 'assert'; -const { - createDiffieHellman, -} = await import('crypto'); +import { + createDiffieHellman +} from 'crypto'; // Generate Alice's keys... const alice = createDiffieHellman(2048); @@ -1120,7 +1120,7 @@ its keys after creation. In other words, it does not implement `setPublicKey()` or `setPrivateKey()` methods. ```mjs -const { createDiffieHellmanGroup } = await import('crypto'); +import { createDiffieHellmanGroup } from 'crypto'; const dh = createDiffieHellmanGroup('modp1'); ``` @@ -1158,9 +1158,9 @@ Instances of the `ECDH` class can be created using the ```mjs import assert from 'assert'; -const { - createECDH, -} = await import('crypto'); +import { + createECDH +} from 'crypto'; // Generate Alice's keys... const alice = createECDH('secp521r1'); @@ -1232,10 +1232,10 @@ If the `inputEncoding` is not provided, `key` is expected to be a [`Buffer`][], Example (uncompressing a key): ```mjs -const { +import { createECDH, - ECDH, -} = await import('crypto'); + ECDH +} from 'crypto'; const ecdh = createECDH('secp256k1'); ecdh.generateKeys(); @@ -1398,10 +1398,10 @@ set. Example (obtaining a shared secret): ```mjs -const { +import { createECDH, - createHash, -} = await import('crypto'); + createHash +} from 'crypto'; const alice = createECDH('secp256k1'); const bob = createECDH('secp256k1'); @@ -1472,9 +1472,9 @@ objects are not to be created directly using the `new` keyword. Example: Using `Hash` objects as streams: ```mjs -const { - createHash, -} = await import('crypto'); +import { + createHash +} from 'crypto'; const hash = createHash('sha256'); @@ -1520,9 +1520,9 @@ Example: Using `Hash` and piped streams: ```mjs import { createReadStream } from 'fs'; -const { - createHash, -} = await import('crypto'); +import { + createHash +} from 'crypto'; const hash = createHash('sha256'); const input = createReadStream('test.js'); @@ -1547,9 +1547,9 @@ input.pipe(hash).setEncoding('hex').pipe(process.stdout); Example: Using the [`hash.update()`][] and [`hash.digest()`][] methods: ```mjs -const { - createHash, -} = await import('crypto'); +import { + createHash +} from 'crypto'; const hash = createHash('sha256'); @@ -1592,9 +1592,9 @@ its [`hash.digest()`][] method has been called. ```mjs // Calculate a rolling hash. -const { - createHash, -} = await import('crypto'); +import { + createHash +} from 'crypto'; const hash = createHash('sha256'); @@ -1687,9 +1687,9 @@ objects are not to be created directly using the `new` keyword. Example: Using `Hmac` objects as streams: ```mjs -const { - createHmac, -} = await import('crypto'); +import { + createHmac +} from 'crypto'; const hmac = createHmac('sha256', 'a secret'); @@ -1735,9 +1735,9 @@ Example: Using `Hmac` and piped streams: ```mjs import { createReadStream } from 'fs'; -const { - createHmac, -} = await import('crypto'); +import { + createHmac +} from 'crypto'; const hmac = createHmac('sha256', 'a secret'); @@ -1763,9 +1763,9 @@ input.pipe(hmac).pipe(process.stdout); Example: Using the [`hmac.update()`][] and [`hmac.digest()`][] methods: ```mjs -const { - createHmac, -} = await import('crypto'); +import { + createHmac +} from 'crypto'; const hmac = createHmac('sha256', 'a secret'); @@ -1863,12 +1863,8 @@ added: v15.0.0 Example: Converting a `CryptoKey` instance to a `KeyObject`: ```mjs -const { - webcrypto: { - subtle, - }, - KeyObject, -} = await import('crypto'); +import { webcrypto, KeyObject } from 'crypto'; +const { subtle } = webcrypto; const key = await subtle.generateKey({ name: 'HMAC', @@ -2055,11 +2051,11 @@ to be created directly using the `new` keyword. Example: Using `Sign` and [`Verify`][] objects as streams: ```mjs -const { +import { generateKeyPairSync, createSign, - createVerify, -} = await import('crypto'); + createVerify +} from 'crypto'; const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'sect239k1' @@ -2103,11 +2099,11 @@ console.log(verify.verify(publicKey, signature, 'hex')); Example: Using the [`sign.update()`][] and [`verify.update()`][] methods: ```mjs -const { +import { generateKeyPairSync, createSign, - createVerify, -} = await import('crypto'); + createVerify +} from 'crypto'; const { privateKey, publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048, @@ -2351,7 +2347,7 @@ Encapsulates an X509 certificate and provides read-only access to its information. ```mjs -const { X509Certificate } = await import('crypto'); +import { X509Certificate } from 'crypto'; const x509 = new X509Certificate('{... pem encoded cert ...}'); @@ -3027,9 +3023,9 @@ import { createReadStream } from 'fs'; -const { - createHash, -} = await import('crypto'); +import { + createHash +} from 'crypto'; const filename = process.argv[2]; @@ -3113,9 +3109,9 @@ import { createReadStream } from 'fs'; -const { - createHmac, -} = await import('crypto'); +import { + createHmac +} from 'crypto'; const filename = process.argv[2]; @@ -3335,9 +3331,9 @@ Asynchronously generates a new random secret key of the given `length`. The `type` will determine which validations will be performed on the `length`. ```mjs -const { - generateKey, -} = await import('crypto'); +import { + generateKey +} from 'crypto'; generateKey('hmac', { length: 64 }, (err, key) => { if (err) throw err; @@ -3407,9 +3403,9 @@ It is recommended to encode public keys as `'spki'` and private keys as `'pkcs8'` with encryption for long-term storage: ```mjs -const { - generateKeyPair, -} = await import('crypto'); +import { + generateKeyPair +} from 'crypto'; generateKeyPair('rsa', { modulusLength: 4096, @@ -3504,9 +3500,9 @@ private keys, it is recommended to use `'pkcs8'` with a strong passphrase, and to keep the passphrase confidential. ```mjs -const { - generateKeyPairSync, -} = await import('crypto'); +import { + generateKeyPairSync +} from 'crypto'; const { publicKey, @@ -3572,9 +3568,9 @@ Synchronously generates a new random secret key of the given `length`. The `type` will determine which validations will be performed on the `length`. ```mjs -const { - generateKeySync, -} = await import('crypto'); +import { + generateKeySync +} from 'crypto'; const key = generateKeySync('hmac', 64); console.log(key.export().toString('hex')); // e89..........41e @@ -3709,9 +3705,9 @@ added: v0.9.3 algorithms. ```mjs -const { - getCiphers, -} = await import('crypto'); +import { + getCiphers +} from 'crypto'; console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...] ``` @@ -3732,9 +3728,9 @@ added: v2.3.0 * Returns: {string[]} An array with the names of the supported elliptic curves. ```mjs -const { - getCurves, -} = await import('crypto'); +import { + getCurves +} from 'crypto'; console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...] ``` @@ -3769,9 +3765,9 @@ and communication time. Example (obtaining a shared secret): ```mjs -const { - getDiffieHellman, -} = await import('crypto'); +import { + getDiffieHellman +} from 'crypto'; const alice = getDiffieHellman('modp14'); const bob = getDiffieHellman('modp14'); @@ -3821,9 +3817,9 @@ added: v0.9.3 such as `'RSA-SHA256'`. Hash algorithms are also called "digest" algorithms. ```mjs -const { - getHashes, -} = await import('crypto'); +import { + getHashes +} from 'crypto'; console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...] ``` @@ -3866,9 +3862,9 @@ be passed to the callback as an {ArrayBuffer}. An error will be thrown if any of the input aguments specify invalid values or types. ```mjs -const { - hkdf, -} = await import('crypto'); +import { + hkdf +} from 'crypto'; hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => { if (err) throw err; @@ -3915,9 +3911,9 @@ An error will be thrown if any of the input aguments specify invalid values or types, or if the derived key cannot be generated. ```mjs -const { - hkdfSync, -} = await import('crypto'); +import { + hkdfSync +} from 'crypto'; const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64); console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' @@ -3991,9 +3987,9 @@ When passing strings for `password` or `salt`, please consider [caveats when using strings as inputs to cryptographic APIs][]. ```mjs -const { - pbkdf2, -} = await import('crypto'); +import { + pbkdf2 +} from 'crypto'; pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => { if (err) throw err; @@ -4017,7 +4013,7 @@ The `crypto.DEFAULT_ENCODING` property can be used to change the way the deprecated and use should be avoided. ```mjs -const crypto = await import('crypto'); +import crypto from 'crypto'; crypto.DEFAULT_ENCODING = 'hex'; crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, derivedKey) => { if (err) throw err; @@ -4088,9 +4084,9 @@ When passing strings for `password` or `salt`, please consider [caveats when using strings as inputs to cryptographic APIs][]. ```mjs -const { - pbkdf2Sync, -} = await import('crypto'); +import { + pbkdf2Sync +} from 'crypto'; const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512'); console.log(key.toString('hex')); // '3745e48...08d59ae' @@ -4110,7 +4106,7 @@ The `crypto.DEFAULT_ENCODING` property may be used to change the way the should be avoided. ```mjs -const crypto = await import('crypto'); +import crypto from 'crypto'; crypto.DEFAULT_ENCODING = 'hex'; const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 512, 'sha512'); console.log(key); // '3745e48...aa39b34' @@ -4326,9 +4322,9 @@ If an error occurs, `err` will be an `Error` object; otherwise it is `null`. The ```mjs // Asynchronous -const { - randomBytes, -} = await import('crypto'); +import { + randomBytes +} from 'crypto'; randomBytes(256, (err, buf) => { if (err) throw err; @@ -4354,9 +4350,9 @@ there is a problem generating the bytes. ```mjs // Synchronous -const { - randomBytes, -} = await import('crypto'); +import { + randomBytes +} from 'crypto'; const buf = randomBytes(256); console.log( @@ -4411,9 +4407,9 @@ changes: Synchronous version of [`crypto.randomFill()`][]. ```mjs -const { - randomFillSync, -} = await import('crypto'); +import { + randomFillSync +} from 'crypto'; const buf = Buffer.alloc(10); console.log(randomFillSync(buf).toString('hex')); @@ -4446,9 +4442,9 @@ Any `ArrayBuffer`, `TypedArray` or `DataView` instance may be passed as `buffer`. ```mjs -const { - randomFillSync, -} = await import('crypto'); +import { + randomFillSync +} from 'crypto'; const a = new Uint32Array(10); console.log(Buffer.from(randomFillSync(a).buffer, @@ -4504,9 +4500,9 @@ requires that a callback is passed in. If the `callback` function is not provided, an error will be thrown. ```mjs -const { - randomFill, -} = await import('crypto'); +import { + randomFill +} from 'crypto'; const buf = Buffer.alloc(10); randomFill(buf, (err, buf) => { @@ -4559,9 +4555,9 @@ contains finite numbers only, they are not drawn from a uniform random distribution and have no meaningful lower or upper bounds. ```mjs -const { - randomFill, -} = await import('crypto'); +import { + randomFill +} from 'crypto'; const a = new Uint32Array(10); randomFill(a, (err, buf) => { @@ -4641,9 +4637,9 @@ generated synchronously. ```mjs // Asynchronous -const { - randomInt, -} = await import('crypto'); +import { + randomInt +} from 'crypto'; randomInt(3, (err, n) => { if (err) throw err; @@ -4665,9 +4661,9 @@ randomInt(3, (err, n) => { ```mjs // Synchronous -const { - randomInt, -} = await import('crypto'); +import { + randomInt +} from 'crypto'; const n = randomInt(3); console.log(`Random number chosen from (0, 1, 2): ${n}`); @@ -4685,9 +4681,9 @@ console.log(`Random number chosen from (0, 1, 2): ${n}`); ```mjs // With `min` argument -const { - randomInt, -} = await import('crypto'); +import { + randomInt +} from 'crypto'; const n = randomInt(1, 7); console.log(`The dice rolled: ${n}`); @@ -4775,9 +4771,9 @@ An exception is thrown when any of the input arguments specify invalid values or types. ```mjs -const { - scrypt, -} = await import('crypto'); +import { + scrypt +} from 'crypto'; // Using the factory defaults. scrypt('password', 'salt', 64, (err, derivedKey) => { @@ -4855,9 +4851,9 @@ An exception is thrown when any of the input arguments specify invalid values or types. ```mjs -const { - scryptSync, -} = await import('crypto'); +import { + scryptSync +} from 'crypto'; // Using the factory defaults. const key1 = scryptSync('password', 'salt', 64); @@ -5212,11 +5208,11 @@ mode must adhere to certain restrictions when using the cipher API: authentication tag. ```mjs -const { +import { createCipheriv, createDecipheriv, - randomBytes, -} = await import('crypto'); + randomBytes +} from 'crypto'; const key = 'keykeykeykeykeykeykeykey'; const nonce = randomBytes(12); diff --git a/doc/api/dgram.md b/doc/api/dgram.md index 8813f9bffaf384..d27379366e3917 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -10,7 +10,30 @@ The `dgram` module provides an implementation of UDP datagram sockets. -```js +```mjs +import dgram from 'dgram'; + +const server = dgram.createSocket('udp4'); + +server.on('error', (err) => { + console.log(`server error:\n${err.stack}`); + server.close(); +}); + +server.on('message', (msg, rinfo) => { + console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); +}); + +server.on('listening', () => { + const address = server.address(); + console.log(`server listening ${address.address}:${address.port}`); +}); + +server.bind(41234); +// Prints: server listening 0.0.0.0:41234 +``` + +```cjs const dgram = require('dgram'); const server = dgram.createSocket('udp4'); @@ -123,9 +146,25 @@ When sharing a UDP socket across multiple `cluster` workers, the `socket.addMembership()` function must be called only once or an `EADDRINUSE` error will occur: -```js +```mjs +import cluster from 'cluster'; +import dgram from 'dgram'; + +if (cluster.isPrimary) { + cluster.fork(); // Works ok. + cluster.fork(); // Fails with EADDRINUSE. +} else { + const s = dgram.createSocket('udp4'); + s.bind(1234, () => { + s.addMembership('224.0.0.114'); + }); +} +``` + +```cjs const cluster = require('cluster'); const dgram = require('dgram'); + if (cluster.isPrimary) { cluster.fork(); // Works ok. cluster.fork(); // Fails with EADDRINUSE. @@ -205,7 +244,30 @@ attempting to bind with a closed socket), an [`Error`][] may be thrown. Example of a UDP server listening on port 41234: -```js +```mjs +import dgram from 'dgram'; + +const server = dgram.createSocket('udp4'); + +server.on('error', (err) => { + console.log(`server error:\n${err.stack}`); + server.close(); +}); + +server.on('message', (msg, rinfo) => { + console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); +}); + +server.on('listening', () => { + const address = server.address(); + console.log(`server listening ${address.address}:${address.port}`); +}); + +server.bind(41234); +// Prints: server listening 0.0.0.0:41234 +``` + +```cjs const dgram = require('dgram'); const server = dgram.createSocket('udp4'); @@ -480,7 +542,17 @@ This method throws [`ERR_SOCKET_BAD_PORT`][] if called on an unbound socket. Example of sending a UDP packet to a port on `localhost`; -```js +```mjs +import dgram from 'dgram'; + +const message = Buffer.from('Some bytes'); +const client = dgram.createSocket('udp4'); +client.send(message, 41234, 'localhost', (err) => { + client.close(); +}); +``` + +```cjs const dgram = require('dgram'); const message = Buffer.from('Some bytes'); const client = dgram.createSocket('udp4'); @@ -492,7 +564,18 @@ client.send(message, 41234, 'localhost', (err) => { Example of sending a UDP packet composed of multiple buffers to a port on `127.0.0.1`; -```js +```mjs +import dgram from 'dgram'; + +const buf1 = Buffer.from('Some '); +const buf2 = Buffer.from('bytes'); +const client = dgram.createSocket('udp4'); +client.send([buf1, buf2], 41234, (err) => { + client.close(); +}); +``` + +```cjs const dgram = require('dgram'); const buf1 = Buffer.from('Some '); const buf2 = Buffer.from('bytes'); @@ -510,7 +593,19 @@ however, sending multiple buffers is faster. Example of sending a UDP packet using a socket connected to a port on `localhost`: -```js +```mjs +import dgram from 'dgram'; + +const message = Buffer.from('Some bytes'); +const client = dgram.createSocket('udp4'); +client.connect(41234, 'localhost', (err) => { + client.send(message, (err) => { + client.close(); + }); +}); +``` + +```cjs const dgram = require('dgram'); const message = Buffer.from('Some bytes'); const client = dgram.createSocket('udp4'); diff --git a/doc/api/diagnostics_channel.md b/doc/api/diagnostics_channel.md index 7a22b2f56eec1d..ba02a5092c3731 100644 --- a/doc/api/diagnostics_channel.md +++ b/doc/api/diagnostics_channel.md @@ -11,7 +11,11 @@ to report arbitrary message data for diagnostics purposes. It can be accessed using: -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); ``` @@ -33,7 +37,27 @@ other modules. Following is a simple overview of the public API. -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; + +// Get a reusable channel object +const channel = diagnostics_channel.channel('my-channel'); + +// Subscribe to the channel +channel.subscribe((message, name) => { + // Received data +}); + +// Check if the channel has an active subscriber +if (channel.hasSubscribers) { + // Publish data to the channel + channel.publish({ + some: 'data' + }); +} +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); // Get a reusable channel object @@ -64,7 +88,15 @@ the message you want to send might be expensive to prepare. This API is optional but helpful when trying to publish messages from very performance-sensitive code. -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; + +if (diagnostics_channel.hasSubscribers('my-channel')) { + // There are subscribers, prepare and publish message +} +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); if (diagnostics_channel.hasSubscribers('my-channel')) { @@ -81,7 +113,13 @@ This is the primary entry-point for anyone wanting to interact with a named channel. It produces a channel object which is optimized to reduce overhead at publish time as much as possible. -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; + +const channel = diagnostics_channel.channel('my-channel'); +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); @@ -107,7 +145,17 @@ the message you want to send might be expensive to prepare. This API is optional but helpful when trying to publish messages from very performance-sensitive code. -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; + +const channel = diagnostics_channel.channel('my-channel'); + +if (channel.hasSubscribers) { + // There are subscribers, prepare and publish message +} +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); @@ -124,7 +172,17 @@ if (channel.hasSubscribers) { Publish a message to any subscribers to the channel. This will trigger message handlers synchronously so they will execute within the same context. -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; + +const channel = diagnostics_channel.channel('my-channel'); + +channel.publish({ + some: 'message' +}); +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); @@ -144,7 +202,17 @@ Register a message handler to subscribe to this channel. This message handler will be run synchronously whenever a message is published to the channel. Any errors thrown in the message handler will trigger an [`'uncaughtException'`][]. -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; + +const channel = diagnostics_channel.channel('my-channel'); + +channel.subscribe((message, name) => { + // Received data +}); +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); @@ -161,7 +229,21 @@ channel.subscribe((message, name) => { Remove a message handler previously registered to this channel with [`channel.subscribe(onMessage)`][]. -```js +```mjs +import diagnostics_channel from 'diagnostics_channel'; + +const channel = diagnostics_channel.channel('my-channel'); + +function onMessage(message, name) { + // Received data +} + +channel.subscribe(onMessage); + +channel.unsubscribe(onMessage); +``` + +```cjs const diagnostics_channel = require('diagnostics_channel'); const channel = diagnostics_channel.channel('my-channel'); diff --git a/doc/api/process.md b/doc/api/process.md index 85e3bf5458a901..6a5d00f706e8c9 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -5,12 +5,15 @@ -The `process` object is a `global` that provides information about, and control -over, the current Node.js process. As a global, it is always available to -Node.js applications without using `require()`. It can also be explicitly -accessed using `require()`: +The `process` object provides information about, and control over, the current +Node.js process. While it is available as a global, it is recommended to +explicitly access it via require or import: -```js +```mjs +import process from 'process'; +``` + +```cjs const process = require('process'); ``` @@ -38,7 +41,28 @@ termination, such as calling [`process.exit()`][] or uncaught exceptions. The `'beforeExit'` should *not* be used as an alternative to the `'exit'` event unless the intention is to schedule additional work. -```js +```mjs +import process from 'process'; + +process.on('beforeExit', (code) => { + console.log('Process beforeExit event with code: ', code); +}); + +process.on('exit', (code) => { + console.log('Process exit event with code: ', code); +}); + +console.log('This message is displayed first.'); + +// Prints: +// This message is displayed first. +// Process beforeExit event with code: 0 +// Process exit event with code: 0 +``` + +```cjs +const process = require('process'); + process.on('beforeExit', (code) => { console.log('Process beforeExit event with code: ', code); }); @@ -84,7 +108,17 @@ The listener callback function is invoked with the exit code specified either by the [`process.exitCode`][] property, or the `exitCode` argument passed to the [`process.exit()`][] method. -```js +```mjs +import process from 'process'; + +process.on('exit', (code) => { + console.log(`About to exit with code: ${code}`); +}); +``` + +```cjs +const process = require('process'); + process.on('exit', (code) => { console.log(`About to exit with code: ${code}`); }); @@ -95,7 +129,19 @@ process will exit immediately after calling the `'exit'` event listeners causing any additional work still queued in the event loop to be abandoned. In the following example, for instance, the timeout will never occur: -```js +```mjs +import process from 'process'; + +process.on('exit', (code) => { + setTimeout(() => { + console.log('This will not run'); + }, 0); +}); +``` + +```cjs +const process = require('process'); + process.on('exit', (code) => { setTimeout(() => { console.log('This will not run'); @@ -148,7 +194,38 @@ This is useful for tracking potential errors in an application while using the the occurrence of this event does not necessarily indicate an error. For example, [`Promise.race()`][] can trigger a `'multipleResolves'` event. -```js +```mjs +import process from 'process'; + +process.on('multipleResolves', (type, promise, reason) => { + console.error(type, promise, reason); + setImmediate(() => process.exit(1)); +}); + +async function main() { + try { + return await new Promise((resolve, reject) => { + resolve('First call'); + resolve('Swallowed resolve'); + reject(new Error('Swallowed reject')); + }); + } catch { + throw new Error('Failed'); + } +} + +main().then(console.log); +// resolve: Promise { 'First call' } 'Swallowed resolve' +// reject: Promise { 'First call' } Error: Swallowed reject +// at Promise (*) +// at new Promise () +// at main (*) +// First call +``` + +```cjs +const process = require('process'); + process.on('multipleResolves', (type, promise, reason) => { console.error(type, promise, reason); setImmediate(() => process.exit(1)); @@ -206,7 +283,21 @@ In asynchronous code, the `'unhandledRejection'` event is emitted when the list of unhandled rejections grows, and the `'rejectionHandled'` event is emitted when the list of unhandled rejections shrinks. -```js +```mjs +import process from 'process'; + +const unhandledRejections = new Map(); +process.on('unhandledRejection', (reason, promise) => { + unhandledRejections.set(promise, reason); +}); +process.on('rejectionHandled', (promise) => { + unhandledRejections.delete(promise); +}); +``` + +```cjs +const process = require('process'); + const unhandledRejections = new Map(); process.on('unhandledRejection', (reason, promise) => { unhandledRejections.set(promise, reason); @@ -250,7 +341,29 @@ behavior. Alternatively, change the [`process.exitCode`][] in the provided exit code. Otherwise, in the presence of such handler the process will exit with 0. -```js +```mjs +import process from 'process'; + +process.on('uncaughtException', (err, origin) => { + fs.writeSync( + process.stderr.fd, + `Caught exception: ${err}\n` + + `Exception origin: ${origin}` + ); +}); + +setTimeout(() => { + console.log('This will still run.'); +}, 500); + +// Intentionally cause an exception, but don't catch it. +nonexistentFunc(); +console.log('This will not run.'); +``` + +```cjs +const process = require('process'); + process.on('uncaughtException', (err, origin) => { fs.writeSync( process.stderr.fd, @@ -321,7 +434,21 @@ Installing an `'uncaughtExceptionMonitor'` listener does not change the behavior once an `'uncaughtException'` event is emitted. The process will still crash if no `'uncaughtException'` listener is installed. -```js +```mjs +import process from 'process'; + +process.on('uncaughtExceptionMonitor', (err, origin) => { + MyMonitoringTool.logSync(err, origin); +}); + +// Intentionally cause an exception, but don't catch it. +nonexistentFunc(); +// Still crashes Node.js +``` + +```cjs +const process = require('process'); + process.on('uncaughtExceptionMonitor', (err, origin) => { MyMonitoringTool.logSync(err, origin); }); @@ -356,7 +483,22 @@ are propagated through a `Promise` chain. The `'unhandledRejection'` event is useful for detecting and keeping track of promises that were rejected whose rejections have not yet been handled. -```js +```mjs +import process from 'process'; + +process.on('unhandledRejection', (reason, promise) => { + console.log('Unhandled Rejection at:', promise, 'reason:', reason); + // Application specific logging, throwing an error, or other logic here +}); + +somePromise.then((res) => { + return reportToUser(JSON.pasre(res)); // Note the typo (`pasre`) +}); // No `.catch()` or `.then()` +``` + +```cjs +const process = require('process'); + process.on('unhandledRejection', (reason, promise) => { console.log('Unhandled Rejection at:', promise, 'reason:', reason); // Application specific logging, throwing an error, or other logic here @@ -370,7 +512,21 @@ somePromise.then((res) => { The following will also trigger the `'unhandledRejection'` event to be emitted: -```js +```mjs +import process from 'process'; + +function SomeResource() { + // Initially set the loaded status to a rejected promise + this.loaded = Promise.reject(new Error('Resource not yet loaded!')); +} + +const resource = new SomeResource(); +// no .catch or .then on resource.loaded for at least a turn +``` + +```cjs +const process = require('process'); + function SomeResource() { // Initially set the loaded status to a rejected promise this.loaded = Promise.reject(new Error('Resource not yet loaded!')); @@ -406,7 +562,19 @@ are not part of the normal Node.js and JavaScript error handling flow. Node.js can emit warnings whenever it detects bad coding practices that could lead to sub-optimal application performance, bugs, or security vulnerabilities. -```js +```mjs +import process from 'process'; + +process.on('warning', (warning) => { + console.warn(warning.name); // Print the warning name + console.warn(warning.message); // Print the warning message + console.warn(warning.stack); // Print the stack trace +}); +``` + +```cjs +const process = require('process'); + process.on('warning', (warning) => { console.warn(warning.name); // Print the warning name console.warn(warning.message); // Print the warning message @@ -511,7 +679,28 @@ The signal handler will receive the signal's name (`'SIGINT'`, The name of each event will be the uppercase common name for the signal (e.g. `'SIGINT'` for `SIGINT` signals). -```js +```mjs +import process from 'process'; + +// Begin reading from stdin so the process does not exit. +process.stdin.resume(); + +process.on('SIGINT', () => { + console.log('Received SIGINT. Press Control-D to exit.'); +}); + +// Using a single function to handle multiple signals +function handle(signal) { + console.log(`Received ${signal}`); +} + +process.on('SIGINT', handle); +process.on('SIGTERM', handle); +``` + +```cjs +const process = require('process'); + // Begin reading from stdin so the process does not exit. process.stdin.resume(); @@ -613,7 +802,20 @@ appear only *once*; each will begin with one or more dashes. Flags passed through to V8 will contain underscores instead of non-leading dashes: -```js +```mjs +import process from 'process'; + +process.allowedNodeEnvironmentFlags.forEach((flag) => { + // -r + // --inspect-brk + // --abort_on_uncaught_exception + // ... +}); +``` + +```cjs +const process = require('process'); + process.allowedNodeEnvironmentFlags.forEach((flag) => { // -r // --inspect-brk @@ -641,7 +843,15 @@ The operating system CPU architecture for which the Node.js binary was compiled. Possible values are: `'arm'`, `'arm64'`, `'ia32'`, `'mips'`,`'mipsel'`, `'ppc'`, `'ppc64'`, `'s390'`, `'s390x'`, `'x32'`, and `'x64'`. -```js +```mjs +import process from 'process'; + +console.log(`This processor architecture is ${process.arch}`); +``` + +```cjs +const process = require('process'); + console.log(`This processor architecture is ${process.arch}`); ``` @@ -661,7 +871,18 @@ arguments. For example, assuming the following script for `process-args.js`: -```js +```mjs +import process from 'process'; + +// print process.argv +process.argv.forEach((val, index) => { + console.log(`${index}: ${val}`); +}); +``` + +```cjs +const process = require('process'); + // print process.argv process.argv.forEach((val, index) => { console.log(`${index}: ${val}`); @@ -753,7 +974,21 @@ The `process.chdir()` method changes the current working directory of the Node.js process or throws an exception if doing so fails (for instance, if the specified `directory` does not exist). -```js +```mjs +import process from 'process'; + +console.log(`Starting directory: ${process.cwd()}`); +try { + process.chdir('/tmp'); + console.log(`New directory: ${process.cwd()}`); +} catch (err) { + console.error(`chdir: ${err}`); +} +``` + +```cjs +const process = require('process'); + console.log(`Starting directory: ${process.cwd()}`); try { process.chdir('/tmp'); @@ -784,7 +1019,40 @@ running the `./configure` script. An example of the possible output looks like: -```js +```mjs +import process from 'process'; + +{ + target_defaults: + { cflags: [], + default_configuration: 'Release', + defines: [], + include_dirs: [], + libraries: [] }, + variables: + { + host_arch: 'x64', + napi_build_version: 5, + node_install_npm: 'true', + node_prefix: '', + node_shared_cares: 'false', + node_shared_http_parser: 'false', + node_shared_libuv: 'false', + node_shared_zlib: 'false', + node_use_dtrace: 'false', + node_use_openssl: 'true', + node_shared_openssl: 'false', + strict_aliasing: 'true', + target_arch: 'x64', + v8_use_snapshot: 1 + } +} +``` + + +```cjs +const process = require('process'); + { target_defaults: { cflags: [], @@ -855,7 +1123,23 @@ actual elapsed time if multiple CPU cores are performing work for this process. The result of a previous call to `process.cpuUsage()` can be passed as the argument to the function, to get a diff reading. -```js +```mjs +import process from 'process'; + +const startUsage = process.cpuUsage(); +// { user: 38579, system: 6986 } + +// spin the CPU for 500 milliseconds +const now = Date.now(); +while (Date.now() - now < 500); + +console.log(process.cpuUsage(startUsage)); +// { user: 514883, system: 11226 } +``` + +```cjs +const process = require('process'); + const startUsage = process.cpuUsage(); // { user: 38579, system: 6986 } @@ -877,7 +1161,15 @@ added: v0.1.8 The `process.cwd()` method returns the current working directory of the Node.js process. -```js +```mjs +import process from 'process'; + +console.log(`Current directory: ${process.cwd()}`); +``` + +```cjs +const process = require('process'); + console.log(`Current directory: ${process.cwd()}`); ``` @@ -890,7 +1182,15 @@ added: v0.7.2 The port used by the Node.js debugger when enabled. -```js +```mjs +import process from 'process'; + +process.debugPort = 5858; +``` + +```cjs +const process = require('process'); + process.debugPort = 5858; ``` @@ -941,7 +1241,21 @@ that exports a `foo` function. All the symbols are loaded before the call returns, by passing the `RTLD_NOW` constant. In this example the constant is assumed to be available. -```js +```mjs +import process from 'process'; +import os from 'os'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const module = { exports: {} }; +process.dlopen(module, fileURLToPath(new URL('local.node', import.meta.url)), + os.constants.dlopen.RTLD_NOW); +module.exports.foo(); +``` + +```cjs +const process = require('process'); + const os = require('os'); const path = require('path'); const module = { exports: {} }; @@ -969,7 +1283,22 @@ The `process.emitWarning()` method can be used to emit custom or application specific process warnings. These can be listened for by adding a handler to the [`'warning'`][process_warning] event. -```js +```mjs +import process from 'process'; + +// Emit a warning with a code and additional detail. +process.emitWarning('Something happened!', { + code: 'MY_WARNING', + detail: 'This is some additional information' +}); +// Emits: +// (node:56338) [MY_WARNING] Warning: Something happened! +// This is some additional information +``` + +```cjs +const process = require('process'); + // Emit a warning with a code and additional detail. process.emitWarning('Something happened!', { code: 'MY_WARNING', @@ -984,7 +1313,21 @@ In this example, an `Error` object is generated internally by `process.emitWarning()` and passed through to the [`'warning'`][process_warning] handler. -```js +```mjs +import process from 'process'; + +process.on('warning', (warning) => { + console.warn(warning.name); // 'Warning' + console.warn(warning.message); // 'Something happened!' + console.warn(warning.code); // 'MY_WARNING' + console.warn(warning.stack); // Stack trace + console.warn(warning.detail); // 'This is some additional information' +}); +``` + +```cjs +const process = require('process'); + process.on('warning', (warning) => { console.warn(warning.name); // 'Warning' console.warn(warning.message); // 'Something happened!' @@ -1013,19 +1356,48 @@ The `process.emitWarning()` method can be used to emit custom or application specific process warnings. These can be listened for by adding a handler to the [`'warning'`][process_warning] event. -```js +```mjs +import process from 'process'; + +// Emit a warning using a string. +process.emitWarning('Something happened!'); +// Emits: (node: 56338) Warning: Something happened! +``` + +```cjs +const process = require('process'); + // Emit a warning using a string. process.emitWarning('Something happened!'); // Emits: (node: 56338) Warning: Something happened! ``` -```js +```mjs +import process from 'process'; + // Emit a warning using a string and a type. process.emitWarning('Something Happened!', 'CustomWarning'); // Emits: (node:56338) CustomWarning: Something Happened! ``` -```js +```cjs +const process = require('process'); + +// Emit a warning using a string and a type. +process.emitWarning('Something Happened!', 'CustomWarning'); +// Emits: (node:56338) CustomWarning: Something Happened! +``` + +```mjs +import process from 'process'; + +process.emitWarning('Something happened!', 'CustomWarning', 'WARN001'); +// Emits: (node:56338) [WARN001] CustomWarning: Something happened! +``` + +```cjs +const process = require('process'); + process.emitWarning('Something happened!', 'CustomWarning', 'WARN001'); // Emits: (node:56338) [WARN001] CustomWarning: Something happened! ``` @@ -1034,7 +1406,20 @@ In each of the previous examples, an `Error` object is generated internally by `process.emitWarning()` and passed through to the [`'warning'`][process_warning] handler. -```js +```mjs +import process from 'process'; + +process.on('warning', (warning) => { + console.warn(warning.name); + console.warn(warning.message); + console.warn(warning.code); + console.warn(warning.stack); +}); +``` + +```cjs +const process = require('process'); + process.on('warning', (warning) => { console.warn(warning.name); console.warn(warning.message); @@ -1047,7 +1432,22 @@ If `warning` is passed as an `Error` object, it will be passed through to the `'warning'` event handler unmodified (and the optional `type`, `code` and `ctor` arguments will be ignored): -```js +```mjs +import process from 'process'; + +// Emit a warning using an Error object. +const myWarning = new Error('Something happened!'); +// Use the Error name property to specify the type name +myWarning.name = 'CustomWarning'; +myWarning.code = 'WARN001'; + +process.emitWarning(myWarning); +// Emits: (node:56338) [WARN001] CustomWarning: Something happened! +``` + +```cjs +const process = require('process'); + // Emit a warning using an Error object. const myWarning = new Error('Something happened!'); // Use the Error name property to specify the type name @@ -1080,7 +1480,24 @@ As a best practice, warnings should be emitted only once per process. To do so, it is recommended to place the `emitWarning()` behind a simple boolean flag as illustrated in the example below: -```js +```mjs +import process from 'process'; + +function emitMyWarning() { + if (!emitMyWarning.warned) { + emitMyWarning.warned = true; + process.emitWarning('Only warn once!'); + } +} +emitMyWarning(); +// Emits: (node: 56339) Warning: Only warn once! +emitMyWarning(); +// Emits nothing +``` + +```cjs +const process = require('process'); + function emitMyWarning() { if (!emitMyWarning.warned) { emitMyWarning.warned = true; @@ -1115,7 +1532,27 @@ See environ(7). An example of this object looks like: -```js +```mjs +import process from 'process'; + +{ + TERM: 'xterm-256color', + SHELL: '/usr/local/bin/bash', + USER: 'maciej', + PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', + PWD: '/Users/maciej', + EDITOR: 'vim', + SHLVL: '1', + HOME: '/Users/maciej', + LOGNAME: 'maciej', + _: '/usr/local/bin/node' +} +``` + + +```cjs +const process = require('process'); + { TERM: 'xterm-256color', SHELL: '/usr/local/bin/bash', @@ -1141,7 +1578,16 @@ $ node -e 'process.env.foo = "bar"' && echo $foo While the following will: -```js +```mjs +import process from 'process'; + +process.env.foo = 'bar'; +console.log(process.env.foo); +``` + +```cjs +const process = require('process'); + process.env.foo = 'bar'; console.log(process.env.foo); ``` @@ -1150,7 +1596,20 @@ Assigning a property on `process.env` will implicitly convert the value to a string. **This behavior is deprecated.** Future versions of Node.js may throw an error when the value is not a string, number, or boolean. -```js +```mjs +import process from 'process'; + +process.env.test = null; +console.log(process.env.test); +// => 'null' +process.env.test = undefined; +console.log(process.env.test); +// => 'undefined' +``` + +```cjs +const process = require('process'); + process.env.test = null; console.log(process.env.test); // => 'null' @@ -1161,7 +1620,18 @@ console.log(process.env.test); Use `delete` to delete a property from `process.env`. -```js +```mjs +import process from 'process'; + +process.env.TEST = 1; +delete process.env.TEST; +console.log(process.env.TEST); +// => undefined +``` + +```cjs +const process = require('process'); + process.env.TEST = 1; delete process.env.TEST; console.log(process.env.TEST); @@ -1170,7 +1640,17 @@ console.log(process.env.TEST); On Windows operating systems, environment variables are case-insensitive. -```js +```mjs +import process from 'process'; + +process.env.TEST = 1; +console.log(process.env.test); +// => 1 +``` + +```cjs +const process = require('process'); + process.env.TEST = 1; console.log(process.env.test); // => 1 @@ -1204,14 +1684,32 @@ $ node --harmony script.js --version Results in `process.execArgv`: -```js +```mjs +import process from 'process'; + +['--harmony'] +``` + + +```cjs +const process = require('process'); + ['--harmony'] ``` And `process.argv`: -```js +```mjs +import process from 'process'; + +['/usr/local/bin/node', 'script.js', '--version'] +``` + + +```cjs +const process = require('process'); + ['/usr/local/bin/node', 'script.js', '--version'] ``` @@ -1229,7 +1727,16 @@ The `process.execPath` property returns the absolute pathname of the executable that started the Node.js process. Symbolic links, if any, are resolved. -```js +```mjs +import process from 'process'; + +'/usr/local/bin/node' +``` + + +```cjs +const process = require('process'); + '/usr/local/bin/node' ``` @@ -1248,7 +1755,15 @@ called. To exit with a 'failure' code: -```js +```mjs +import process from 'process'; + +process.exit(1); +``` + +```cjs +const process = require('process'); + process.exit(1); ``` @@ -1268,7 +1783,19 @@ For instance, the following example illustrates a *misuse* of the `process.exit()` method that could lead to data printed to stdout being truncated and lost: -```js +```mjs +import process from 'process'; + +// This is an example of what *not* to do: +if (someConditionNotMet()) { + printUsageToStdout(); + process.exit(1); +} +``` + +```cjs +const process = require('process'); + // This is an example of what *not* to do: if (someConditionNotMet()) { printUsageToStdout(); @@ -1285,7 +1812,20 @@ Rather than calling `process.exit()` directly, the code *should* set the `process.exitCode` and allow the process to exit naturally by avoiding scheduling any additional work for the event loop: -```js +```mjs +import process from 'process'; + +// How to properly set the exit code while letting +// the process exit gracefully. +if (someConditionNotMet()) { + printUsageToStdout(); + process.exitCode = 1; +} +``` + +```cjs +const process = require('process'); + // How to properly set the exit code while letting // the process exit gracefully. if (someConditionNotMet()) { @@ -1323,7 +1863,17 @@ added: v2.0.0 The `process.getegid()` method returns the numerical effective group identity of the Node.js process. (See getegid(2).) -```js +```mjs +import process from 'process'; + +if (process.getegid) { + console.log(`Current gid: ${process.getegid()}`); +} +``` + +```cjs +const process = require('process'); + if (process.getegid) { console.log(`Current gid: ${process.getegid()}`); } @@ -1342,7 +1892,17 @@ added: v2.0.0 The `process.geteuid()` method returns the numerical effective user identity of the process. (See geteuid(2).) -```js +```mjs +import process from 'process'; + +if (process.geteuid) { + console.log(`Current uid: ${process.geteuid()}`); +} +``` + +```cjs +const process = require('process'); + if (process.geteuid) { console.log(`Current uid: ${process.geteuid()}`); } @@ -1361,7 +1921,17 @@ added: v0.1.31 The `process.getgid()` method returns the numerical group identity of the process. (See getgid(2).) -```js +```mjs +import process from 'process'; + +if (process.getgid) { + console.log(`Current gid: ${process.getgid()}`); +} +``` + +```cjs +const process = require('process'); + if (process.getgid) { console.log(`Current gid: ${process.getgid()}`); } @@ -1381,7 +1951,17 @@ The `process.getgroups()` method returns an array with the supplementary group IDs. POSIX leaves it unspecified if the effective group ID is included but Node.js ensures it always is. -```js +```mjs +import process from 'process'; + +if (process.getgroups) { + console.log(process.getgroups()); // [ 16, 21, 297 ] +} +``` + +```cjs +const process = require('process'); + if (process.getgroups) { console.log(process.getgroups()); // [ 16, 21, 297 ] } @@ -1400,7 +1980,17 @@ added: v0.1.28 The `process.getuid()` method returns the numeric user identity of the process. (See getuid(2).) -```js +```mjs +import process from 'process'; + +if (process.getuid) { + console.log(`Current uid: ${process.getuid()}`); +} +``` + +```cjs +const process = require('process'); + if (process.getuid) { console.log(`Current uid: ${process.getuid()}`); } @@ -1446,7 +2036,25 @@ These times are relative to an arbitrary time in the past, and not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals: -```js +```mjs +import process from 'process'; + +const NS_PER_SEC = 1e9; +const time = process.hrtime(); +// [ 1800216, 25 ] + +setTimeout(() => { + const diff = process.hrtime(time); + // [ 1, 552 ] + + console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`); + // Benchmark took 1000000552 nanoseconds +}, 1000); +``` + +```cjs +const process = require('process'); + const NS_PER_SEC = 1e9; const time = process.hrtime(); // [ 1800216, 25 ] @@ -1474,7 +2082,24 @@ Unlike [`process.hrtime()`][], it does not support an additional `time` argument since the difference can just be computed directly by subtraction of the two `bigint`s. -```js +```mjs +import process from 'process'; + +const start = process.hrtime.bigint(); +// 191051479007711n + +setTimeout(() => { + const end = process.hrtime.bigint(); + // 191052633396993n + + console.log(`Benchmark took ${end - start} nanoseconds`); + // Benchmark took 1154389282 nanoseconds +}, 1000); +``` + +```cjs +const process = require('process'); + const start = process.hrtime.bigint(); // 191051479007711n @@ -1502,7 +2127,19 @@ access or the `CAP_SETGID` capability. Use care when dropping privileges: -```js +```mjs +import process from 'process'; + +console.log(process.getgroups()); // [ 0 ] +process.initgroups('nodeuser', 1000); // switch user +console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] +process.setgid(1000); // drop root gid +console.log(process.getgroups()); // [ 27, 30, 46, 1000 ] +``` + +```cjs +const process = require('process'); + console.log(process.getgroups()); // [ 0 ] process.initgroups('nodeuser', 1000); // switch user console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] @@ -1538,7 +2175,24 @@ Even though the name of this function is `process.kill()`, it is really just a signal sender, like the `kill` system call. The signal sent may do something other than kill the target process. -```js +```mjs +import process from 'process'; + +process.on('SIGHUP', () => { + console.log('Got SIGHUP signal.'); +}); + +setTimeout(() => { + console.log('Exiting.'); + process.exit(0); +}, 100); + +process.kill(process.pid, 'SIGHUP'); +``` + +```cjs +const process = require('process'); + process.on('SIGHUP', () => { console.log('Got SIGHUP signal.'); }); @@ -1597,7 +2251,23 @@ changes: Returns an object describing the memory usage of the Node.js process measured in bytes. -```js +```mjs +import process from 'process'; + +console.log(process.memoryUsage()); +// Prints: +// { +// rss: 4935680, +// heapTotal: 1826816, +// heapUsed: 650472, +// external: 49879, +// arrayBuffers: 9386 +// } +``` + +```cjs +const process = require('process'); + console.log(process.memoryUsage()); // Prints: // { @@ -1645,7 +2315,16 @@ process, including all C++ and JavaScript objects and code. This is the same value as the `rss` property provided by `process.memoryUsage()` but `process.memoryUsage.rss()` is faster. -```js +```mjs +import process from 'process'; + +console.log(process.memoryUsage.rss()); +// 35655680 +``` + +```cjs +const process = require('process'); + console.log(process.memoryUsage.rss()); // 35655680 ``` @@ -1668,7 +2347,23 @@ completion and before the event loop is allowed to continue. It's possible to create an infinite loop if one were to recursively call `process.nextTick()`. See the [Event Loop][] guide for more background. -```js +```mjs +import process from 'process'; + +console.log('start'); +process.nextTick(() => { + console.log('nextTick callback'); +}); +console.log('scheduled'); +// Output: +// start +// scheduled +// nextTick callback +``` + +```cjs +const process = require('process'); + console.log('start'); process.nextTick(() => { console.log('nextTick callback'); @@ -1684,7 +2379,26 @@ This is important when developing APIs in order to give users the opportunity to assign event handlers *after* an object has been constructed but before any I/O has occurred: -```js +```mjs +import process from 'process'; + +function MyThing(options) { + this.setupOptions(options); + + process.nextTick(() => { + this.startDoingStuff(); + }); +} + +const thing = new MyThing(); +thing.getReadyForStuff(); + +// thing.startDoingStuff() gets called now, not before. +``` + +```cjs +const process = require('process'); + function MyThing(options) { this.setupOptions(options); @@ -1702,7 +2416,23 @@ thing.getReadyForStuff(); It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example: -```js +```mjs +import process from 'process'; + +// WARNING! DO NOT USE! BAD UNSAFE HAZARD! +function maybeSync(arg, cb) { + if (arg) { + cb(); + return; + } + + fs.stat('file', cb); +} +``` + +```cjs +const process = require('process'); + // WARNING! DO NOT USE! BAD UNSAFE HAZARD! function maybeSync(arg, cb) { if (arg) { @@ -1716,7 +2446,21 @@ function maybeSync(arg, cb) { This API is hazardous because in the following case: -```js +```mjs +import process from 'process'; + +const maybeTrue = Math.random() > 0.5; + +maybeSync(maybeTrue, () => { + foo(); +}); + +bar(); +``` + +```cjs +const process = require('process'); + const maybeTrue = Math.random() > 0.5; maybeSync(maybeTrue, () => { @@ -1730,7 +2474,22 @@ It is not clear whether `foo()` or `bar()` will be called first. The following approach is much better: -```js +```mjs +import process from 'process'; + +function definitelyAsync(arg, cb) { + if (arg) { + process.nextTick(cb); + return; + } + + fs.stat('file', cb); +} +``` + +```cjs +const process = require('process'); + function definitelyAsync(arg, cb) { if (arg) { process.nextTick(cb); @@ -1749,7 +2508,21 @@ execute the then, catch, and finally handlers of resolved promises. Within Node.js, every time the "next tick queue" is drained, the microtask queue is drained immediately after. -```js +```mjs +import process from 'process'; + +Promise.resolve().then(() => console.log(2)); +queueMicrotask(() => console.log(3)); +process.nextTick(() => console.log(1)); +// Output: +// 1 +// 2 +// 3 +``` + +```cjs +const process = require('process'); + Promise.resolve().then(() => console.log(2)); queueMicrotask(() => console.log(3)); process.nextTick(() => console.log(1)); @@ -1765,7 +2538,23 @@ JavaScript platform environments and should be favored over `process.nextTick()` In simple scenarios, `queueMicrotask()` can be a drop-in replacement for `process.nextTick()`. -```js +```mjs +import process from 'process'; + +console.log('start'); +queueMicrotask(() => { + console.log('microtask callback'); +}); +console.log('scheduled'); +// Output: +// start +// scheduled +// microtask callback +``` + +```cjs +const process = require('process'); + console.log('start'); queueMicrotask(() => { console.log('microtask callback'); @@ -1782,7 +2571,25 @@ allows specifying additional values that will be passed as arguments to the deferred function when it is called. Achieving the same result with `queueMicrotask()` requires using either a closure or a bound function: -```js +```mjs +import process from 'process'; + +function deferred(a, b) { + console.log('microtask', a + b); +} + +console.log('start'); +queueMicrotask(deferred.bind(undefined, 1, 2)); +console.log('scheduled'); +// Output: +// start +// scheduled +// microtask 3 +``` + +```cjs +const process = require('process'); + function deferred(a, b) { console.log('microtask', a + b); } @@ -1827,7 +2634,15 @@ added: v0.1.15 The `process.pid` property returns the PID of the process. -```js +```mjs +import process from 'process'; + +console.log(`This process is pid ${process.pid}`); +``` + +```cjs +const process = require('process'); + console.log(`This process is pid ${process.pid}`); ``` @@ -1851,7 +2666,15 @@ Currently possible values are: * `'sunos'` * `'win32'` -```js +```mjs +import process from 'process'; + +console.log(`This platform is ${process.platform}`); +``` + +```cjs +const process = require('process'); + console.log(`This platform is ${process.platform}`); ``` @@ -1872,7 +2695,15 @@ added: The `process.ppid` property returns the PID of the parent of the current process. -```js +```mjs +import process from 'process'; + +console.log(`The parent process is pid ${process.ppid}`); +``` + +```cjs +const process = require('process'); + console.log(`The parent process is pid ${process.ppid}`); ``` @@ -1914,7 +2745,22 @@ tarball. For other LTS Release code names, see [Node.js Changelog Archive](https://github.com/nodejs/node/blob/HEAD/doc/changelogs/CHANGELOG_ARCHIVE.md) -```js +```mjs +import process from 'process'; + +{ + name: 'node', + lts: 'Erbium', + sourceUrl: 'https://nodejs.org/download/release/v12.18.1/node-v12.18.1.tar.gz', + headersUrl: 'https://nodejs.org/download/release/v12.18.1/node-v12.18.1-headers.tar.gz', + libUrl: 'https://nodejs.org/download/release/v12.18.1/win-x64/node.lib' +} +``` + + +```cjs +const process = require('process'); + { name: 'node', lts: 'Erbium', @@ -1958,7 +2804,15 @@ Write reports in a compact format, single-line JSON, more easily consumable by log processing systems than the default multi-line format designed for human consumption. -```js +```mjs +import process from 'process'; + +console.log(`Reports are compact? ${process.report.compact}`); +``` + +```cjs +const process = require('process'); + console.log(`Reports are compact? ${process.report.compact}`); ``` @@ -1979,7 +2833,15 @@ Directory where the report is written. The default value is the empty string, indicating that reports are written to the current working directory of the Node.js process. -```js +```mjs +import process from 'process'; + +console.log(`Report directory is ${process.report.directory}`); +``` + +```cjs +const process = require('process'); + console.log(`Report directory is ${process.report.directory}`); ``` @@ -2000,7 +2862,15 @@ Filename where the report is written. If set to the empty string, the output filename will be comprised of a timestamp, PID, and sequence number. The default value is the empty string. -```js +```mjs +import process from 'process'; + +console.log(`Report filename is ${process.report.filename}`); +``` + +```cjs +const process = require('process'); + console.log(`Report filename is ${process.report.filename}`); ``` @@ -2022,7 +2892,20 @@ Returns a JavaScript Object representation of a diagnostic report for the running process. The report's JavaScript stack trace is taken from `err`, if present. -```js +```mjs +import process from 'process'; + +const data = process.report.getReport(); +console.log(data.header.nodejsVersion); + +// Similar to process.report.writeReport() +import fs from 'fs'; +fs.writeFileSync('my-report.log', util.inspect(data), 'utf8'); +``` + +```cjs +const process = require('process'); + const data = process.report.getReport(); console.log(data.header.nodejsVersion); @@ -2049,7 +2932,15 @@ changes: If `true`, a diagnostic report is generated on fatal errors, such as out of memory errors or failed C++ assertions. -```js +```mjs +import process from 'process'; + +console.log(`Report on fatal error: ${process.report.reportOnFatalError}`); +``` + +```cjs +const process = require('process'); + console.log(`Report on fatal error: ${process.report.reportOnFatalError}`); ``` @@ -2069,7 +2960,15 @@ changes: If `true`, a diagnostic report is generated when the process receives the signal specified by `process.report.signal`. -```js +```mjs +import process from 'process'; + +console.log(`Report on signal: ${process.report.reportOnSignal}`); +``` + +```cjs +const process = require('process'); + console.log(`Report on signal: ${process.report.reportOnSignal}`); ``` @@ -2088,7 +2987,15 @@ changes: If `true`, a diagnostic report is generated on uncaught exception. -```js +```mjs +import process from 'process'; + +console.log(`Report on exception: ${process.report.reportOnUncaughtException}`); +``` + +```cjs +const process = require('process'); + console.log(`Report on exception: ${process.report.reportOnUncaughtException}`); ``` @@ -2108,7 +3015,15 @@ changes: The signal used to trigger the creation of a diagnostic report. Defaults to `'SIGUSR2'`. -```js +```mjs +import process from 'process'; + +console.log(`Report signal: ${process.report.signal}`); +``` + +```cjs +const process = require('process'); + console.log(`Report signal: ${process.report.signal}`); ``` @@ -2135,7 +3050,15 @@ Writes a diagnostic report to a file. If `filename` is not provided, the default filename includes the date, time, PID, and a sequence number. The report's JavaScript stack trace is taken from `err`, if present. -```js +```mjs +import process from 'process'; + +process.report.writeReport(); +``` + +```cjs +const process = require('process'); + process.report.writeReport(); ``` @@ -2189,7 +3112,36 @@ added: v12.6.0 process becoming runnable or because the current process exceeded its time slice. This field is not supported on Windows. -```js +```mjs +import process from 'process'; + +console.log(process.resourceUsage()); +/* + Will output: + { + userCPUTime: 82872, + systemCPUTime: 4143, + maxRSS: 33164, + sharedMemorySize: 0, + unsharedDataSize: 0, + unsharedStackSize: 0, + minorPageFault: 2469, + majorPageFault: 0, + swappedOut: 0, + fsRead: 0, + fsWrite: 8, + ipcSent: 0, + ipcReceived: 0, + signalsCount: 0, + voluntaryContextSwitches: 79, + involuntaryContextSwitches: 1 + } +*/ +``` + +```cjs +const process = require('process'); + console.log(process.resourceUsage()); /* Will output: @@ -2251,7 +3203,23 @@ The `process.setegid()` method sets the effective group identity of the process. name string. If a group name is specified, this method blocks while resolving the associated a numeric ID. -```js +```mjs +import process from 'process'; + +if (process.getegid && process.setegid) { + console.log(`Current gid: ${process.getegid()}`); + try { + process.setegid(501); + console.log(`New gid: ${process.getegid()}`); + } catch (err) { + console.log(`Failed to set gid: ${err}`); + } +} +``` + +```cjs +const process = require('process'); + if (process.getegid && process.setegid) { console.log(`Current gid: ${process.getegid()}`); try { @@ -2279,7 +3247,23 @@ The `process.seteuid()` method sets the effective user identity of the process. string. If a username is specified, the method blocks while resolving the associated numeric ID. -```js +```mjs +import process from 'process'; + +if (process.geteuid && process.seteuid) { + console.log(`Current uid: ${process.geteuid()}`); + try { + process.seteuid(501); + console.log(`New uid: ${process.geteuid()}`); + } catch (err) { + console.log(`Failed to set uid: ${err}`); + } +} +``` + +```cjs +const process = require('process'); + if (process.geteuid && process.seteuid) { console.log(`Current uid: ${process.geteuid()}`); try { @@ -2307,7 +3291,23 @@ setgid(2).) The `id` can be passed as either a numeric ID or a group name string. If a group name is specified, this method blocks while resolving the associated numeric ID. -```js +```mjs +import process from 'process'; + +if (process.getgid && process.setgid) { + console.log(`Current gid: ${process.getgid()}`); + try { + process.setgid(501); + console.log(`New gid: ${process.getgid()}`); + } catch (err) { + console.log(`Failed to set gid: ${err}`); + } +} +``` + +```cjs +const process = require('process'); + if (process.getgid && process.setgid) { console.log(`Current gid: ${process.getgid()}`); try { @@ -2336,7 +3336,22 @@ process to have `root` or the `CAP_SETGID` capability. The `groups` array can contain numeric group IDs, group names, or both. -```js +```mjs +import process from 'process'; + +if (process.getgroups && process.setgroups) { + try { + process.setgroups([501]); + console.log(process.getgroups()); // new groups + } catch (err) { + console.log(`Failed to set groups: ${err}`); + } +} +``` + +```cjs +const process = require('process'); + if (process.getgroups && process.setgroups) { try { process.setgroups([501]); @@ -2363,7 +3378,23 @@ setuid(2).) The `id` can be passed as either a numeric ID or a username string. If a username is specified, the method blocks while resolving the associated numeric ID. -```js +```mjs +import process from 'process'; + +if (process.getuid && process.setuid) { + console.log(`Current uid: ${process.getuid()}`); + try { + process.setuid(501); + console.log(`New uid: ${process.getuid()}`); + } catch (err) { + console.log(`Failed to set uid: ${err}`); + } +} +``` + +```cjs +const process = require('process'); + if (process.getuid && process.setuid) { console.log(`Current uid: ${process.getuid()}`); try { @@ -2462,7 +3493,15 @@ a [Writable][] stream. For example, to copy `process.stdin` to `process.stdout`: -```js +```mjs +import process from 'process'; + +process.stdin.pipe(process.stdout); +``` + +```cjs +const process = require('process'); + process.stdin.pipe(process.stdout); ``` @@ -2622,7 +3661,19 @@ added: v0.1.19 `process.umask(mask)` sets the Node.js process's file mode creation mask. Child processes inherit the mask from the parent process. Returns the previous mask. -```js +```mjs +import process from 'process'; + +const newmask = 0o022; +const oldmask = process.umask(newmask); +console.log( + `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}` +); +``` + +```cjs +const process = require('process'); + const newmask = 0o022; const oldmask = process.umask(newmask); console.log( @@ -2654,7 +3705,16 @@ added: v0.1.3 The `process.version` property contains the Node.js version string. -```js +```mjs +import process from 'process'; + +console.log(`Version: ${process.version}`); +// Version: v14.8.0 +``` + +```cjs +const process = require('process'); + console.log(`Version: ${process.version}`); // Version: v14.8.0 ``` @@ -2681,7 +3741,15 @@ Node.js and its dependencies. `process.versions.modules` indicates the current ABI version, which is increased whenever a C++ API changes. Node.js will refuse to load modules that were compiled against a different module ABI version. -```js +```mjs +import process from 'process'; + +console.log(process.versions); +``` + +```cjs +const process = require('process'); + console.log(process.versions); ``` From 60a75e924fae4f506aeb1e3dc906bd03e8457b40 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 13:38:09 -0700 Subject: [PATCH 2/9] Apply suggestions from code review Co-authored-by: Antoine du Hamel --- doc/api/async_hooks.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index bc9acd9b7994ed..e09e89fc377cbb 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -309,7 +309,7 @@ this. ```mjs import { createServer } from 'net'; -net.createServer().listen(function() { this.close(); }); +createServer().listen(function() { this.close(); }); // OR clearTimeout(setTimeout(() => {}, 10)); ``` @@ -358,6 +358,7 @@ The following is a simple demonstration of `triggerAsyncId`: ```mjs import { createHook, executionASyncId } from 'async_hooks'; import { stdout } from 'process'; +import net from 'net'; createHook({ init(asyncId, type, triggerAsyncId) { @@ -374,6 +375,7 @@ net.createServer((conn) => {}).listen(8080); ```cjs const { createHook, executionAsyncId } = require('async_hooks'); const { fd } = require('process').stdout; +const net = require('net'); createHook({ init(asyncId, type, triggerAsyncId) { @@ -613,7 +615,7 @@ import { open } from 'fs'; import { executionAsyncId, executionAsyncResource } from 'async_hooks'; console.log(executionAsyncId(), executionAsyncResource()); // 1 {} -open(fileURLToPath(import.meta.url), 'r', (err, fd) => { +open(new URL(import.meta.url), 'r', (err, fd) => { console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap }); ``` From fef62a1a7db8432738cb7539f64991e79672c320 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 13:40:39 -0700 Subject: [PATCH 3/9] Update doc/api/async_context.md Co-authored-by: Bradley Farias --- doc/api/async_context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/async_context.md b/doc/api/async_context.md index 4c8f3e20e8912e..11a7a55558707c 100644 --- a/doc/api/async_context.md +++ b/doc/api/async_context.md @@ -46,7 +46,7 @@ logged within each request. ```mjs import http from 'http'; -import { AsyncLocalStoraget } from 'async_hooks'; +import { AsyncLocalStorage } from 'async_hooks'; const asyncLocalStorage = new AsyncLocalStorage(); From e3eb5119cc15303b03ab09526a678de317840ff8 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 14:02:03 -0700 Subject: [PATCH 4/9] update process examples to use destructured imports --- doc/api/process.md | 613 +++++++++++++++++---------------------------- 1 file changed, 226 insertions(+), 387 deletions(-) diff --git a/doc/api/process.md b/doc/api/process.md index 6a5d00f706e8c9..dbc6c8d57360a2 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -803,9 +803,9 @@ passed through to V8 will contain underscores instead of non-leading dashes: ```mjs -import process from 'process'; +import { allowedNodeEnvironmentFlags } from 'process'; -process.allowedNodeEnvironmentFlags.forEach((flag) => { +allowedNodeEnvironmentFlags.forEach((flag) => { // -r // --inspect-brk // --abort_on_uncaught_exception @@ -814,9 +814,9 @@ process.allowedNodeEnvironmentFlags.forEach((flag) => { ``` ```cjs -const process = require('process'); +const { allowedNodeEnvironmentFlags } = require('process'); -process.allowedNodeEnvironmentFlags.forEach((flag) => { +allowedNodeEnvironmentFlags.forEach((flag) => { // -r // --inspect-brk // --abort_on_uncaught_exception @@ -844,13 +844,13 @@ Possible values are: `'arm'`, `'arm64'`, `'ia32'`, `'mips'`,`'mipsel'`, `'ppc'`, `'ppc64'`, `'s390'`, `'s390x'`, `'x32'`, and `'x64'`. ```mjs -import process from 'process'; +import { arch } from 'process'; -console.log(`This processor architecture is ${process.arch}`); +console.log(`This processor architecture is ${arch}`); ``` ```cjs -const process = require('process'); +const { arch } = require('process'); console.log(`This processor architecture is ${process.arch}`); ``` @@ -872,19 +872,19 @@ arguments. For example, assuming the following script for `process-args.js`: ```mjs -import process from 'process'; +import { argv } from 'process'; // print process.argv -process.argv.forEach((val, index) => { +argv.forEach((val, index) => { console.log(`${index}: ${val}`); }); ``` ```cjs -const process = require('process'); +const { argv } = require('process'); // print process.argv -process.argv.forEach((val, index) => { +argv.forEach((val, index) => { console.log(`${index}: ${val}`); }); ``` @@ -975,24 +975,24 @@ Node.js process or throws an exception if doing so fails (for instance, if the specified `directory` does not exist). ```mjs -import process from 'process'; +import { chdir, cwd } from 'process'; -console.log(`Starting directory: ${process.cwd()}`); +console.log(`Starting directory: ${cwd()}`); try { - process.chdir('/tmp'); - console.log(`New directory: ${process.cwd()}`); + chdir('/tmp'); + console.log(`New directory: ${cwd()}`); } catch (err) { console.error(`chdir: ${err}`); } ``` ```cjs -const process = require('process'); +const { chdir, cwd } = require('process'); -console.log(`Starting directory: ${process.cwd()}`); +console.log(`Starting directory: ${cwd()}`); try { - process.chdir('/tmp'); - console.log(`New directory: ${process.cwd()}`); + chdir('/tmp'); + console.log(`New directory: ${cwd()}`); } catch (err) { console.error(`chdir: ${err}`); } @@ -1019,40 +1019,7 @@ running the `./configure` script. An example of the possible output looks like: -```mjs -import process from 'process'; - -{ - target_defaults: - { cflags: [], - default_configuration: 'Release', - defines: [], - include_dirs: [], - libraries: [] }, - variables: - { - host_arch: 'x64', - napi_build_version: 5, - node_install_npm: 'true', - node_prefix: '', - node_shared_cares: 'false', - node_shared_http_parser: 'false', - node_shared_libuv: 'false', - node_shared_zlib: 'false', - node_use_dtrace: 'false', - node_use_openssl: 'true', - node_shared_openssl: 'false', - strict_aliasing: 'true', - target_arch: 'x64', - v8_use_snapshot: 1 - } -} -``` - - -```cjs -const process = require('process'); - +```js { target_defaults: { cflags: [], @@ -1124,30 +1091,30 @@ The result of a previous call to `process.cpuUsage()` can be passed as the argument to the function, to get a diff reading. ```mjs -import process from 'process'; +import { cpuUsage } from 'process'; -const startUsage = process.cpuUsage(); +const startUsage = cpuUsage(); // { user: 38579, system: 6986 } // spin the CPU for 500 milliseconds const now = Date.now(); while (Date.now() - now < 500); -console.log(process.cpuUsage(startUsage)); +console.log(cpuUsage(startUsage)); // { user: 514883, system: 11226 } ``` ```cjs -const process = require('process'); +const { cpuUsage } = require('process'); -const startUsage = process.cpuUsage(); +const startUsage = cpuUsage(); // { user: 38579, system: 6986 } // spin the CPU for 500 milliseconds const now = Date.now(); while (Date.now() - now < 500); -console.log(process.cpuUsage(startUsage)); +console.log(cpuUsage(startUsage)); // { user: 514883, system: 11226 } ``` @@ -1162,15 +1129,15 @@ The `process.cwd()` method returns the current working directory of the Node.js process. ```mjs -import process from 'process'; +import { cwd } from 'process'; -console.log(`Current directory: ${process.cwd()}`); +console.log(`Current directory: ${cwd()}`); ``` ```cjs -const process = require('process'); +const { cwd } = require('process'); -console.log(`Current directory: ${process.cwd()}`); +console.log(`Current directory: ${cwd()}`); ``` ## `process.debugPort` @@ -1242,25 +1209,23 @@ the call returns, by passing the `RTLD_NOW` constant. In this example the constant is assumed to be available. ```mjs -import process from 'process'; -import os from 'os'; -import path from 'path'; +import { dlopen } from 'process'; +import { constants } from 'os'; import { fileURLToPath } from 'url'; const module = { exports: {} }; -process.dlopen(module, fileURLToPath(new URL('local.node', import.meta.url)), - os.constants.dlopen.RTLD_NOW); +dlopen(module, fileURLToPath(new URL('local.node', import.meta.url)), + constants.dlopen.RTLD_NOW); module.exports.foo(); ``` ```cjs -const process = require('process'); +const { dlopen } = require('process'); +const { constants } = require('os'); +const { join } = require('path'); -const os = require('os'); -const path = require('path'); const module = { exports: {} }; -process.dlopen(module, path.join(__dirname, 'local.node'), - os.constants.dlopen.RTLD_NOW); +dlopen(module, join(__dirname, 'local.node'), constants.dlopen.RTLD_NOW); module.exports.foo(); ``` @@ -1284,10 +1249,10 @@ specific process warnings. These can be listened for by adding a handler to the [`'warning'`][process_warning] event. ```mjs -import process from 'process'; +import { emitWarning } from 'process'; // Emit a warning with a code and additional detail. -process.emitWarning('Something happened!', { +emitWarning('Something happened!', { code: 'MY_WARNING', detail: 'This is some additional information' }); @@ -1297,10 +1262,10 @@ process.emitWarning('Something happened!', { ``` ```cjs -const process = require('process'); +const { emitWarning } = require('process'); // Emit a warning with a code and additional detail. -process.emitWarning('Something happened!', { +emitWarning('Something happened!', { code: 'MY_WARNING', detail: 'This is some additional information' }); @@ -1357,46 +1322,46 @@ specific process warnings. These can be listened for by adding a handler to the [`'warning'`][process_warning] event. ```mjs -import process from 'process'; +import { emitWarning } from 'process'; // Emit a warning using a string. -process.emitWarning('Something happened!'); +emitWarning('Something happened!'); // Emits: (node: 56338) Warning: Something happened! ``` ```cjs -const process = require('process'); +const { emitWarning } = require('process'); // Emit a warning using a string. -process.emitWarning('Something happened!'); +emitWarning('Something happened!'); // Emits: (node: 56338) Warning: Something happened! ``` ```mjs -import process from 'process'; +import { emitWarning } from 'process'; // Emit a warning using a string and a type. -process.emitWarning('Something Happened!', 'CustomWarning'); +emitWarning('Something Happened!', 'CustomWarning'); // Emits: (node:56338) CustomWarning: Something Happened! ``` ```cjs -const process = require('process'); +const { emitWarning } = require('process'); // Emit a warning using a string and a type. -process.emitWarning('Something Happened!', 'CustomWarning'); +emitWarning('Something Happened!', 'CustomWarning'); // Emits: (node:56338) CustomWarning: Something Happened! ``` ```mjs -import process from 'process'; +import { emitWarning } from 'process'; -process.emitWarning('Something happened!', 'CustomWarning', 'WARN001'); +emitWarning('Something happened!', 'CustomWarning', 'WARN001'); // Emits: (node:56338) [WARN001] CustomWarning: Something happened! ``` ```cjs -const process = require('process'); +const { emitWarning } = require('process'); process.emitWarning('Something happened!', 'CustomWarning', 'WARN001'); // Emits: (node:56338) [WARN001] CustomWarning: Something happened! @@ -1433,7 +1398,7 @@ If `warning` is passed as an `Error` object, it will be passed through to the `code` and `ctor` arguments will be ignored): ```mjs -import process from 'process'; +import { emitWarning } from 'process'; // Emit a warning using an Error object. const myWarning = new Error('Something happened!'); @@ -1441,12 +1406,12 @@ const myWarning = new Error('Something happened!'); myWarning.name = 'CustomWarning'; myWarning.code = 'WARN001'; -process.emitWarning(myWarning); +emitWarning(myWarning); // Emits: (node:56338) [WARN001] CustomWarning: Something happened! ``` ```cjs -const process = require('process'); +const { emitWarning } = require('process'); // Emit a warning using an Error object. const myWarning = new Error('Something happened!'); @@ -1454,7 +1419,7 @@ const myWarning = new Error('Something happened!'); myWarning.name = 'CustomWarning'; myWarning.code = 'WARN001'; -process.emitWarning(myWarning); +emitWarning(myWarning); // Emits: (node:56338) [WARN001] CustomWarning: Something happened! ``` @@ -1481,12 +1446,12 @@ so, it is recommended to place the `emitWarning()` behind a simple boolean flag as illustrated in the example below: ```mjs -import process from 'process'; +import { emitWarning } from 'process'; function emitMyWarning() { if (!emitMyWarning.warned) { emitMyWarning.warned = true; - process.emitWarning('Only warn once!'); + emitWarning('Only warn once!'); } } emitMyWarning(); @@ -1496,12 +1461,12 @@ emitMyWarning(); ``` ```cjs -const process = require('process'); +const { emitWarning } = require('process'); function emitMyWarning() { if (!emitMyWarning.warned) { emitMyWarning.warned = true; - process.emitWarning('Only warn once!'); + emitWarning('Only warn once!'); } } emitMyWarning(); @@ -1532,27 +1497,7 @@ See environ(7). An example of this object looks like: -```mjs -import process from 'process'; - -{ - TERM: 'xterm-256color', - SHELL: '/usr/local/bin/bash', - USER: 'maciej', - PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', - PWD: '/Users/maciej', - EDITOR: 'vim', - SHLVL: '1', - HOME: '/Users/maciej', - LOGNAME: 'maciej', - _: '/usr/local/bin/node' -} -``` - - -```cjs -const process = require('process'); - +```js { TERM: 'xterm-256color', SHELL: '/usr/local/bin/bash', @@ -1579,17 +1524,17 @@ $ node -e 'process.env.foo = "bar"' && echo $foo While the following will: ```mjs -import process from 'process'; +import { env } from 'process'; -process.env.foo = 'bar'; -console.log(process.env.foo); +env.foo = 'bar'; +console.log(env.foo); ``` ```cjs -const process = require('process'); +const { env } = require('process'); -process.env.foo = 'bar'; -console.log(process.env.foo); +env.foo = 'bar'; +console.log(env.foo); ``` Assigning a property on `process.env` will implicitly convert the value @@ -1597,62 +1542,62 @@ to a string. **This behavior is deprecated.** Future versions of Node.js may throw an error when the value is not a string, number, or boolean. ```mjs -import process from 'process'; +import { env } from 'process'; -process.env.test = null; -console.log(process.env.test); +env.test = null; +console.log(env.test); // => 'null' -process.env.test = undefined; -console.log(process.env.test); +env.test = undefined; +console.log(env.test); // => 'undefined' ``` ```cjs -const process = require('process'); +const { env } = require('process'); -process.env.test = null; -console.log(process.env.test); +env.test = null; +console.log(env.test); // => 'null' -process.env.test = undefined; -console.log(process.env.test); +env.test = undefined; +console.log(env.test); // => 'undefined' ``` Use `delete` to delete a property from `process.env`. ```mjs -import process from 'process'; +import { env } from 'process'; -process.env.TEST = 1; -delete process.env.TEST; -console.log(process.env.TEST); +env.TEST = 1; +delete env.TEST; +console.log(env.TEST); // => undefined ``` ```cjs -const process = require('process'); +const { env } = require('process'); -process.env.TEST = 1; -delete process.env.TEST; -console.log(process.env.TEST); +env.TEST = 1; +delete env.TEST; +console.log(env.TEST); // => undefined ``` On Windows operating systems, environment variables are case-insensitive. ```mjs -import process from 'process'; +import { env } from 'process'; -process.env.TEST = 1; -console.log(process.env.test); +env.TEST = 1; +console.log(env.test); // => 1 ``` ```cjs -const process = require('process'); +const { env } = require('process'); -process.env.TEST = 1; -console.log(process.env.test); +env.TEST = 1; +console.log(env.test); // => 1 ``` @@ -1684,32 +1629,14 @@ $ node --harmony script.js --version Results in `process.execArgv`: -```mjs -import process from 'process'; - -['--harmony'] -``` - - -```cjs -const process = require('process'); - +```js ['--harmony'] ``` And `process.argv`: -```mjs -import process from 'process'; - -['/usr/local/bin/node', 'script.js', '--version'] -``` - - -```cjs -const process = require('process'); - +```js ['/usr/local/bin/node', 'script.js', '--version'] ``` @@ -1727,16 +1654,7 @@ The `process.execPath` property returns the absolute pathname of the executable that started the Node.js process. Symbolic links, if any, are resolved. -```mjs -import process from 'process'; - -'/usr/local/bin/node' -``` - - -```cjs -const process = require('process'); - +```js '/usr/local/bin/node' ``` @@ -1756,15 +1674,15 @@ called. To exit with a 'failure' code: ```mjs -import process from 'process'; +import { exit } from 'process'; -process.exit(1); +exit(1); ``` ```cjs -const process = require('process'); +const { exit } = require('process'); -process.exit(1); +exit(1); ``` The shell that executed Node.js should see the exit code as `1`. @@ -1784,22 +1702,22 @@ For instance, the following example illustrates a *misuse* of the truncated and lost: ```mjs -import process from 'process'; +import { exit } from 'process'; // This is an example of what *not* to do: if (someConditionNotMet()) { printUsageToStdout(); - process.exit(1); + exit(1); } ``` ```cjs -const process = require('process'); +const { exit } = require('process'); // This is an example of what *not* to do: if (someConditionNotMet()) { printUsageToStdout(); - process.exit(1); + exit(1); } ``` @@ -2037,14 +1955,14 @@ past, and not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals: ```mjs -import process from 'process'; +import { hrtime } from 'process'; const NS_PER_SEC = 1e9; -const time = process.hrtime(); +const time = hrtime(); // [ 1800216, 25 ] setTimeout(() => { - const diff = process.hrtime(time); + const diff = hrtime(time); // [ 1, 552 ] console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`); @@ -2053,14 +1971,14 @@ setTimeout(() => { ``` ```cjs -const process = require('process'); +const { hrtime } = require('process'); const NS_PER_SEC = 1e9; -const time = process.hrtime(); +const time = hrtime(); // [ 1800216, 25 ] setTimeout(() => { - const diff = process.hrtime(time); + const diff = hrtime(time); // [ 1, 552 ] console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`); @@ -2083,13 +2001,13 @@ argument since the difference can just be computed directly by subtraction of the two `bigint`s. ```mjs -import process from 'process'; +import { hrtime } from 'process'; -const start = process.hrtime.bigint(); +const start = hrtime.bigint(); // 191051479007711n setTimeout(() => { - const end = process.hrtime.bigint(); + const end = hrtime.bigint(); // 191052633396993n console.log(`Benchmark took ${end - start} nanoseconds`); @@ -2098,13 +2016,13 @@ setTimeout(() => { ``` ```cjs -const process = require('process'); +const { hrtime } = require('process'); -const start = process.hrtime.bigint(); +const start = hrtime.bigint(); // 191051479007711n setTimeout(() => { - const end = process.hrtime.bigint(); + const end = hrtime.bigint(); // 191052633396993n console.log(`Benchmark took ${end - start} nanoseconds`); @@ -2128,23 +2046,23 @@ access or the `CAP_SETGID` capability. Use care when dropping privileges: ```mjs -import process from 'process'; +import { getgroups, initgroups, setgid } from 'process'; -console.log(process.getgroups()); // [ 0 ] -process.initgroups('nodeuser', 1000); // switch user -console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] -process.setgid(1000); // drop root gid -console.log(process.getgroups()); // [ 27, 30, 46, 1000 ] +console.log(getgroups()); // [ 0 ] +initgroups('nodeuser', 1000); // switch user +console.log(getgroups()); // [ 27, 30, 46, 1000, 0 ] +setgid(1000); // drop root gid +console.log(getgroups()); // [ 27, 30, 46, 1000 ] ``` ```cjs -const process = require('process'); +const { getgroups, initgroups, setgid } = require('process'); -console.log(process.getgroups()); // [ 0 ] -process.initgroups('nodeuser', 1000); // switch user -console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] -process.setgid(1000); // drop root gid -console.log(process.getgroups()); // [ 27, 30, 46, 1000 ] +console.log(getgroups()); // [ 0 ] +initgroups('nodeuser', 1000); // switch user +console.log(getgroups()); // [ 27, 30, 46, 1000, 0 ] +setgid(1000); // drop root gid +console.log(getgroups()); // [ 27, 30, 46, 1000 ] ``` This function is only available on POSIX platforms (i.e. not Windows or @@ -2176,7 +2094,7 @@ signal sender, like the `kill` system call. The signal sent may do something other than kill the target process. ```mjs -import process from 'process'; +import process, { kill } from 'process'; process.on('SIGHUP', () => { console.log('Got SIGHUP signal.'); @@ -2187,7 +2105,7 @@ setTimeout(() => { process.exit(0); }, 100); -process.kill(process.pid, 'SIGHUP'); +kill(process.pid, 'SIGHUP'); ``` ```cjs @@ -2252,9 +2170,9 @@ Returns an object describing the memory usage of the Node.js process measured in bytes. ```mjs -import process from 'process'; +import { memoryUsage } from 'process'; -console.log(process.memoryUsage()); +console.log(memoryUsage()); // Prints: // { // rss: 4935680, @@ -2266,9 +2184,9 @@ console.log(process.memoryUsage()); ``` ```cjs -const process = require('process'); +const { memoryUsage } = require('process'); -console.log(process.memoryUsage()); +console.log(memoryUsage()); // Prints: // { // rss: 4935680, @@ -2316,16 +2234,16 @@ This is the same value as the `rss` property provided by `process.memoryUsage()` but `process.memoryUsage.rss()` is faster. ```mjs -import process from 'process'; +import { memoryUsage } from 'process'; -console.log(process.memoryUsage.rss()); +console.log(memoryUsage.rss()); // 35655680 ``` ```cjs -const process = require('process'); +const { rss } = require('process'); -console.log(process.memoryUsage.rss()); +console.log(memoryUsage.rss()); // 35655680 ``` @@ -2348,10 +2266,10 @@ create an infinite loop if one were to recursively call `process.nextTick()`. See the [Event Loop][] guide for more background. ```mjs -import process from 'process'; +import { nextTick } from 'process'; console.log('start'); -process.nextTick(() => { +nextTick(() => { console.log('nextTick callback'); }); console.log('scheduled'); @@ -2362,10 +2280,10 @@ console.log('scheduled'); ``` ```cjs -const process = require('process'); +const { nextTick } = require('process'); console.log('start'); -process.nextTick(() => { +nextTick(() => { console.log('nextTick callback'); }); console.log('scheduled'); @@ -2380,12 +2298,12 @@ to assign event handlers *after* an object has been constructed but before any I/O has occurred: ```mjs -import process from 'process'; +import { nextTick } from 'process'; function MyThing(options) { this.setupOptions(options); - process.nextTick(() => { + nextTick(() => { this.startDoingStuff(); }); } @@ -2397,12 +2315,12 @@ thing.getReadyForStuff(); ``` ```cjs -const process = require('process'); +const { nextTick } = require('process'); function MyThing(options) { this.setupOptions(options); - process.nextTick(() => { + nextTick(() => { this.startDoingStuff(); }); } @@ -2416,23 +2334,7 @@ thing.getReadyForStuff(); It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example: -```mjs -import process from 'process'; - -// WARNING! DO NOT USE! BAD UNSAFE HAZARD! -function maybeSync(arg, cb) { - if (arg) { - cb(); - return; - } - - fs.stat('file', cb); -} -``` - -```cjs -const process = require('process'); - +```js // WARNING! DO NOT USE! BAD UNSAFE HAZARD! function maybeSync(arg, cb) { if (arg) { @@ -2446,21 +2348,7 @@ function maybeSync(arg, cb) { This API is hazardous because in the following case: -```mjs -import process from 'process'; - -const maybeTrue = Math.random() > 0.5; - -maybeSync(maybeTrue, () => { - foo(); -}); - -bar(); -``` - -```cjs -const process = require('process'); - +```js const maybeTrue = Math.random() > 0.5; maybeSync(maybeTrue, () => { @@ -2475,11 +2363,11 @@ It is not clear whether `foo()` or `bar()` will be called first. The following approach is much better: ```mjs -import process from 'process'; +import { nextTick } from 'process'; function definitelyAsync(arg, cb) { if (arg) { - process.nextTick(cb); + nextTick(cb); return; } @@ -2488,11 +2376,11 @@ function definitelyAsync(arg, cb) { ``` ```cjs -const process = require('process'); +const { nextTick } = require('process'); function definitelyAsync(arg, cb) { if (arg) { - process.nextTick(cb); + nextTick(cb); return; } @@ -2509,11 +2397,11 @@ Node.js, every time the "next tick queue" is drained, the microtask queue is drained immediately after. ```mjs -import process from 'process'; +import { nextTick } from 'process'; Promise.resolve().then(() => console.log(2)); queueMicrotask(() => console.log(3)); -process.nextTick(() => console.log(1)); +nextTick(() => console.log(1)); // Output: // 1 // 2 @@ -2521,11 +2409,11 @@ process.nextTick(() => console.log(1)); ``` ```cjs -const process = require('process'); +const { nextTick } = require('process'); Promise.resolve().then(() => console.log(2)); queueMicrotask(() => console.log(3)); -process.nextTick(() => console.log(1)); +nextTick(() => console.log(1)); // Output: // 1 // 2 @@ -2538,23 +2426,7 @@ JavaScript platform environments and should be favored over `process.nextTick()` In simple scenarios, `queueMicrotask()` can be a drop-in replacement for `process.nextTick()`. -```mjs -import process from 'process'; - -console.log('start'); -queueMicrotask(() => { - console.log('microtask callback'); -}); -console.log('scheduled'); -// Output: -// start -// scheduled -// microtask callback -``` - -```cjs -const process = require('process'); - +```js console.log('start'); queueMicrotask(() => { console.log('microtask callback'); @@ -2571,25 +2443,7 @@ allows specifying additional values that will be passed as arguments to the deferred function when it is called. Achieving the same result with `queueMicrotask()` requires using either a closure or a bound function: -```mjs -import process from 'process'; - -function deferred(a, b) { - console.log('microtask', a + b); -} - -console.log('start'); -queueMicrotask(deferred.bind(undefined, 1, 2)); -console.log('scheduled'); -// Output: -// start -// scheduled -// microtask 3 -``` - -```cjs -const process = require('process'); - +```js function deferred(a, b) { console.log('microtask', a + b); } @@ -2635,15 +2489,15 @@ added: v0.1.15 The `process.pid` property returns the PID of the process. ```mjs -import process from 'process'; +import { pid } from 'process'; -console.log(`This process is pid ${process.pid}`); +console.log(`This process is pid ${pid}`); ``` ```cjs -const process = require('process'); +const { pid } = require('process'); -console.log(`This process is pid ${process.pid}`); +console.log(`This process is pid ${pid}`); ``` ## `process.platform` @@ -2667,15 +2521,15 @@ Currently possible values are: * `'win32'` ```mjs -import process from 'process'; +import { platform } from 'process'; -console.log(`This platform is ${process.platform}`); +console.log(`This platform is ${platform}`); ``` ```cjs -const process = require('process'); +const { platform } = require('process'); -console.log(`This platform is ${process.platform}`); +console.log(`This platform is ${platform}`); ``` The value `'android'` may also be returned if the Node.js is built on the @@ -2696,15 +2550,15 @@ The `process.ppid` property returns the PID of the parent of the current process. ```mjs -import process from 'process'; +import { ppid } from 'process'; -console.log(`The parent process is pid ${process.ppid}`); +console.log(`The parent process is pid ${ppid}`); ``` ```cjs -const process = require('process'); +const { ppid } = require('process'); -console.log(`The parent process is pid ${process.ppid}`); +console.log(`The parent process is pid ${ppid}`); ``` ## `process.release` @@ -2745,22 +2599,7 @@ tarball. For other LTS Release code names, see [Node.js Changelog Archive](https://github.com/nodejs/node/blob/HEAD/doc/changelogs/CHANGELOG_ARCHIVE.md) -```mjs -import process from 'process'; - -{ - name: 'node', - lts: 'Erbium', - sourceUrl: 'https://nodejs.org/download/release/v12.18.1/node-v12.18.1.tar.gz', - headersUrl: 'https://nodejs.org/download/release/v12.18.1/node-v12.18.1-headers.tar.gz', - libUrl: 'https://nodejs.org/download/release/v12.18.1/win-x64/node.lib' -} -``` - - -```cjs -const process = require('process'); - +```js { name: 'node', lts: 'Erbium', @@ -2805,15 +2644,15 @@ by log processing systems than the default multi-line format designed for human consumption. ```mjs -import process from 'process'; +import { report } from 'process'; -console.log(`Reports are compact? ${process.report.compact}`); +console.log(`Reports are compact? ${report.compact}`); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -console.log(`Reports are compact? ${process.report.compact}`); +console.log(`Reports are compact? ${report.compact}`); ``` ### `process.report.directory` @@ -2834,15 +2673,15 @@ indicating that reports are written to the current working directory of the Node.js process. ```mjs -import process from 'process'; +import { report } from 'process'; -console.log(`Report directory is ${process.report.directory}`); +console.log(`Report directory is ${report.directory}`); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -console.log(`Report directory is ${process.report.directory}`); +console.log(`Report directory is ${report.directory}`); ``` ### `process.report.filename` @@ -2863,15 +2702,15 @@ filename will be comprised of a timestamp, PID, and sequence number. The default value is the empty string. ```mjs -import process from 'process'; +import { report } from 'process'; -console.log(`Report filename is ${process.report.filename}`); +console.log(`Report filename is ${report.filename}`); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -console.log(`Report filename is ${process.report.filename}`); +console.log(`Report filename is ${report.filename}`); ``` ### `process.report.getReport([err])` @@ -2893,9 +2732,9 @@ running process. The report's JavaScript stack trace is taken from `err`, if present. ```mjs -import process from 'process'; +import { report } from 'process'; -const data = process.report.getReport(); +const data = report.getReport(); console.log(data.header.nodejsVersion); // Similar to process.report.writeReport() @@ -2904,9 +2743,9 @@ fs.writeFileSync('my-report.log', util.inspect(data), 'utf8'); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -const data = process.report.getReport(); +const data = report.getReport(); console.log(data.header.nodejsVersion); // Similar to process.report.writeReport() @@ -2933,15 +2772,15 @@ If `true`, a diagnostic report is generated on fatal errors, such as out of memory errors or failed C++ assertions. ```mjs -import process from 'process'; +import { report } from 'process'; -console.log(`Report on fatal error: ${process.report.reportOnFatalError}`); +console.log(`Report on fatal error: ${report.reportOnFatalError}`); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -console.log(`Report on fatal error: ${process.report.reportOnFatalError}`); +console.log(`Report on fatal error: ${report.reportOnFatalError}`); ``` ### `process.report.reportOnSignal` @@ -2961,15 +2800,15 @@ If `true`, a diagnostic report is generated when the process receives the signal specified by `process.report.signal`. ```mjs -import process from 'process'; +import { report } from 'process'; -console.log(`Report on signal: ${process.report.reportOnSignal}`); +console.log(`Report on signal: ${report.reportOnSignal}`); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -console.log(`Report on signal: ${process.report.reportOnSignal}`); +console.log(`Report on signal: ${report.reportOnSignal}`); ``` ### `process.report.reportOnUncaughtException` @@ -2988,15 +2827,15 @@ changes: If `true`, a diagnostic report is generated on uncaught exception. ```mjs -import process from 'process'; +import { report } from 'process'; -console.log(`Report on exception: ${process.report.reportOnUncaughtException}`); +console.log(`Report on exception: ${report.reportOnUncaughtException}`); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -console.log(`Report on exception: ${process.report.reportOnUncaughtException}`); +console.log(`Report on exception: ${report.reportOnUncaughtException}`); ``` ### `process.report.signal` @@ -3016,15 +2855,15 @@ The signal used to trigger the creation of a diagnostic report. Defaults to `'SIGUSR2'`. ```mjs -import process from 'process'; +import { report } from 'process'; -console.log(`Report signal: ${process.report.signal}`); +console.log(`Report signal: ${report.signal}`); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -console.log(`Report signal: ${process.report.signal}`); +console.log(`Report signal: ${report.signal}`); ``` ### `process.report.writeReport([filename][, err])` @@ -3051,15 +2890,15 @@ filename includes the date, time, PID, and a sequence number. The report's JavaScript stack trace is taken from `err`, if present. ```mjs -import process from 'process'; +import { report } from 'process'; -process.report.writeReport(); +report.writeReport(); ``` ```cjs -const process = require('process'); +const { report } = require('process'); -process.report.writeReport(); +report.writeReport(); ``` Additional documentation is available in the [report documentation][]. @@ -3113,9 +2952,9 @@ added: v12.6.0 time slice. This field is not supported on Windows. ```mjs -import process from 'process'; +import { resourceUsage } from 'process'; -console.log(process.resourceUsage()); +console.log(resourceUsage()); /* Will output: { @@ -3140,9 +2979,9 @@ console.log(process.resourceUsage()); ``` ```cjs -const process = require('process'); +const { resourceUsage } = require('process'); -console.log(process.resourceUsage()); +console.log(resourceUsage()); /* Will output: { @@ -3494,15 +3333,15 @@ a [Writable][] stream. For example, to copy `process.stdin` to `process.stdout`: ```mjs -import process from 'process'; +import { stdin, stdout } from 'process'; -process.stdin.pipe(process.stdout); +stdin.pipe(stdout); ``` ```cjs -const process = require('process'); +const { stdin, stdout } = require('process'); -process.stdin.pipe(process.stdout); +stdin.pipe(stdout); ``` `process.stdout` differs from other Node.js streams in important ways. See @@ -3662,20 +3501,20 @@ added: v0.1.19 processes inherit the mask from the parent process. Returns the previous mask. ```mjs -import process from 'process'; +import { umask } from 'process'; const newmask = 0o022; -const oldmask = process.umask(newmask); +const oldmask = umask(newmask); console.log( `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}` ); ``` ```cjs -const process = require('process'); +const { umask } = require('process'); const newmask = 0o022; -const oldmask = process.umask(newmask); +const oldmask = umask(newmask); console.log( `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}` ); @@ -3706,16 +3545,16 @@ added: v0.1.3 The `process.version` property contains the Node.js version string. ```mjs -import process from 'process'; +import { version } from 'process'; -console.log(`Version: ${process.version}`); +console.log(`Version: ${version}`); // Version: v14.8.0 ``` ```cjs -const process = require('process'); +const { version } = require('process'); -console.log(`Version: ${process.version}`); +console.log(`Version: ${version}`); // Version: v14.8.0 ``` @@ -3742,15 +3581,15 @@ ABI version, which is increased whenever a C++ API changes. Node.js will refuse to load modules that were compiled against a different module ABI version. ```mjs -import process from 'process'; +import { versions } from 'process'; -console.log(process.versions); +console.log(versions); ``` ```cjs -const process = require('process'); +const { versions } = require('process'); -console.log(process.versions); +console.log(versions); ``` Will generate an object similar to: From 70683b02922bd6bf4494d4a968066ae7bd5499e9 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 14:10:52 -0700 Subject: [PATCH 5/9] bmeck feedback, including eslintrc globals --- .eslintrc.js | 8 ++++++++ doc/api/cluster.md | 6 ++++++ doc/api/dgram.md | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index bda641797e2951..14d4193a9284da 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -98,6 +98,14 @@ module.exports = { name: 'require', message: 'Use import instead', }, + { + name: 'Buffer', + message: 'Import Buffer instead of using the global' + }, + { + name: 'process', + message: 'Import process instead of using the global' + } ] }, }, ], diff --git a/doc/api/cluster.md b/doc/api/cluster.md index e8e72468f08fa2..2b515ab82e3b6b 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -17,6 +17,7 @@ server ports. import cluster from 'cluster'; import http from 'http'; import { cpus } from 'os'; +import process from 'process'; const numCPUs = cpus().length; @@ -47,6 +48,7 @@ if (cluster.isPrimary) { const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; +const process = require('process'); if (cluster.isPrimary) { console.log(`Primary ${process.pid} is running`); @@ -265,6 +267,7 @@ process of the number of HTTP requests received by the workers: import cluster from 'cluster'; import http from 'http'; import { cpus } from 'os'; +import process from 'process'; if (cluster.isPrimary) { @@ -307,6 +310,7 @@ if (cluster.isPrimary) { ```cjs const cluster = require('cluster'); const http = require('http'); +const process = require('process'); if (cluster.isPrimary) { @@ -491,6 +495,7 @@ because of exiting or being signaled). Otherwise, it returns `false`. import cluster from 'cluster'; import http from 'http'; import { cpus } from 'os'; +import process from 'process'; const numCPUs = cpus().length; @@ -523,6 +528,7 @@ if (cluster.isPrimary) { const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; +const process = require('process'); if (cluster.isPrimary) { console.log(`Primary ${process.pid} is running`); diff --git a/doc/api/dgram.md b/doc/api/dgram.md index d27379366e3917..365c30c9ae64a7 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -544,6 +544,7 @@ Example of sending a UDP packet to a port on `localhost`; ```mjs import dgram from 'dgram'; +import { Buffer } from 'buffer'; const message = Buffer.from('Some bytes'); const client = dgram.createSocket('udp4'); @@ -554,6 +555,8 @@ client.send(message, 41234, 'localhost', (err) => { ```cjs const dgram = require('dgram'); +const { Buffer } = require('buffer'); + const message = Buffer.from('Some bytes'); const client = dgram.createSocket('udp4'); client.send(message, 41234, 'localhost', (err) => { @@ -566,6 +569,7 @@ Example of sending a UDP packet composed of multiple buffers to a port on ```mjs import dgram from 'dgram'; +import { Buffer } from 'buffer'; const buf1 = Buffer.from('Some '); const buf2 = Buffer.from('bytes'); @@ -577,6 +581,8 @@ client.send([buf1, buf2], 41234, (err) => { ```cjs const dgram = require('dgram'); +const { Buffer } = require('buffer'); + const buf1 = Buffer.from('Some '); const buf2 = Buffer.from('bytes'); const client = dgram.createSocket('udp4'); @@ -595,6 +601,7 @@ Example of sending a UDP packet using a socket connected to a port on ```mjs import dgram from 'dgram'; +import { Buffer } from 'buffer'; const message = Buffer.from('Some bytes'); const client = dgram.createSocket('udp4'); @@ -607,6 +614,8 @@ client.connect(41234, 'localhost', (err) => { ```cjs const dgram = require('dgram'); +const { Buffer } = require('buffer'); + const message = Buffer.from('Some bytes'); const client = dgram.createSocket('udp4'); client.connect(41234, 'localhost', (err) => { From 694e1726907914d34522d457d9064fe58dddd7b7 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 14:23:58 -0700 Subject: [PATCH 6/9] fixup all Buffer, process usage per lint rule --- doc/api/assert.md | 1 + doc/api/crypto.md | 105 ++++++++++++++++++++++++---------------------- doc/api/esm.md | 7 +++- doc/api/fs.md | 5 +++ doc/api/wasi.md | 11 +++-- 5 files changed, 73 insertions(+), 56 deletions(-) diff --git a/doc/api/assert.md b/doc/api/assert.md index 7eb952ace7be71..037d233be0acd9 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -240,6 +240,7 @@ for the verification to take place. The usual pattern would be to call it in a ```mjs import assert from 'assert'; +import process from 'process'; const tracker = new assert.CallTracker(); diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 84959c286548cb..6a072c1bcd04b6 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -163,6 +163,8 @@ changes: ```mjs import { Certificate } from 'crypto'; +import { Buffer } from 'buffer'; + const spkac = getSpkacSomehow(); console.log(Certificate.verifySpkac(Buffer.from(spkac))); // Prints: true or false @@ -170,6 +172,8 @@ console.log(Certificate.verifySpkac(Buffer.from(spkac))); ```cjs const { Certificate } = require('crypto'); +const { Buffer } = require('buffer'); + const spkac = getSpkacSomehow(); console.log(Certificate.verifySpkac(Buffer.from(spkac))); // Prints: true or false @@ -269,6 +273,8 @@ added: v0.11.8 ```mjs import { Certificate } from 'crypto'; +import { Buffer } from 'buffer'; + const cert = Certificate(); const spkac = getSpkacSomehow(); console.log(cert.verifySpkac(Buffer.from(spkac))); @@ -277,6 +283,8 @@ console.log(cert.verifySpkac(Buffer.from(spkac))); ```cjs const { Certificate } = require('crypto'); +const { Buffer } = require('buffer'); + const cert = Certificate(); const spkac = getSpkacSomehow(); console.log(cert.verifySpkac(Buffer.from(spkac))); @@ -630,6 +638,7 @@ import { scryptSync, createDecipheriv } from 'crypto'; +import { Buffer } from 'buffer'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -665,6 +674,7 @@ const { scryptSync, createDecipheriv, } = require('crypto'); +const { Buffer } = require('buffer'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -702,11 +712,11 @@ import { createReadStream, createWriteStream, } from 'fs'; - import { scryptSync, createDecipheriv } from 'crypto'; +import { Buffer } from 'buffer'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -728,11 +738,11 @@ const { createReadStream, createWriteStream, } = require('fs'); - const { scryptSync, createDecipheriv, } = require('crypto'); +const { Buffer } = require('buffer'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -756,6 +766,7 @@ import { scryptSync, createDecipheriv } from 'crypto'; +import { Buffer } from 'buffer'; const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -780,6 +791,7 @@ const { scryptSync, createDecipheriv, } = require('crypto'); +const { Buffer } = require('buffer'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -1519,29 +1531,24 @@ Example: Using `Hash` and piped streams: ```mjs import { createReadStream } from 'fs'; +import { createHash } from 'crypto'; +import { stdout } from 'process'; -import { - createHash -} from 'crypto'; const hash = createHash('sha256'); const input = createReadStream('test.js'); -input.pipe(hash).setEncoding('hex').pipe(process.stdout); +input.pipe(hash).setEncoding('hex').pipe(stdout); ``` ```cjs -const { - createReadStream, -} = require('fs'); - -const { - createHash, -} = require('crypto'); +const { createReadStream } = require('fs'); +const { createHash } = require('crypto'); +const { stdout } = require('process'); const hash = createHash('sha256'); const input = createReadStream('test.js'); -input.pipe(hash).setEncoding('hex').pipe(process.stdout); +input.pipe(hash).setEncoding('hex').pipe(stdout); ``` Example: Using the [`hash.update()`][] and [`hash.digest()`][] methods: @@ -1734,30 +1741,30 @@ Example: Using `Hmac` and piped streams: ```mjs import { createReadStream } from 'fs'; - import { createHmac } from 'crypto'; +import { stdout } from 'process'; const hmac = createHmac('sha256', 'a secret'); const input = createReadStream('test.js'); -input.pipe(hmac).pipe(process.stdout); +input.pipe(hmac).pipe(stdout); ``` ```cjs const { createReadStream, } = require('fs'); - const { createHmac, } = require('crypto'); +const { stdout } = require('process'); const hmac = createHmac('sha256', 'a secret'); const input = createReadStream('test.js'); -input.pipe(hmac).pipe(process.stdout); +input.pipe(hmac).pipe(stdout); ``` Example: Using the [`hmac.update()`][] and [`hmac.digest()`][] methods: @@ -3022,12 +3029,12 @@ Example: generating the sha256 sum of a file import { createReadStream } from 'fs'; - import { createHash } from 'crypto'; +import { argv } from 'process'; -const filename = process.argv[2]; +const filename = argv[2]; const hash = createHash('sha256'); @@ -3048,12 +3055,12 @@ input.on('readable', () => { const { createReadStream, } = require('fs'); - const { createHash, } = require('crypto'); +const { argv } = require('process'); -const filename = process.argv[2]; +const filename = argv[2]; const hash = createHash('sha256'); @@ -3108,12 +3115,12 @@ Example: generating the sha256 HMAC of a file import { createReadStream } from 'fs'; - import { createHmac } from 'crypto'; +import { argv } from 'process'; -const filename = process.argv[2]; +const filename = argv[2]; const hmac = createHmac('sha256', 'a secret'); @@ -3134,12 +3141,12 @@ input.on('readable', () => { const { createReadStream, } = require('fs'); - const { createHmac, } = require('crypto'); +const { argv } = require('process'); -const filename = process.argv[2]; +const filename = argv[2]; const hmac = createHmac('sha256', 'a secret'); @@ -3865,6 +3872,7 @@ of the input aguments specify invalid values or types. import { hkdf } from 'crypto'; +import { Buffer } from 'buffer'; hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => { if (err) throw err; @@ -3876,6 +3884,7 @@ hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => { const { hkdf, } = require('crypto'); +const { Buffer } = require('buffer'); hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => { if (err) throw err; @@ -3914,6 +3923,7 @@ types, or if the derived key cannot be generated. import { hkdfSync } from 'crypto'; +import { Buffer } from 'buffer'; const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64); console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' @@ -3923,6 +3933,7 @@ console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' const { hkdfSync, } = require('crypto'); +const { Buffer } = require('buffer'); const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64); console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' @@ -4407,9 +4418,8 @@ changes: Synchronous version of [`crypto.randomFill()`][]. ```mjs -import { - randomFillSync -} from 'crypto'; +import { randomFillSync } from 'crypto'; +import { Buffer } from 'buffer'; const buf = Buffer.alloc(10); console.log(randomFillSync(buf).toString('hex')); @@ -4423,9 +4433,8 @@ console.log(buf.toString('hex')); ``` ```cjs -const { - randomFillSync, -} = require('crypto'); +const { randomFillSync } = require('crypto'); +const { Buffer } = require('buffer'); const buf = Buffer.alloc(10); console.log(randomFillSync(buf).toString('hex')); @@ -4442,9 +4451,8 @@ Any `ArrayBuffer`, `TypedArray` or `DataView` instance may be passed as `buffer`. ```mjs -import { - randomFillSync -} from 'crypto'; +import { randomFillSync } from 'crypto'; +import { Buffer } from 'buffer'; const a = new Uint32Array(10); console.log(Buffer.from(randomFillSync(a).buffer, @@ -4459,9 +4467,8 @@ console.log(Buffer.from(randomFillSync(c)).toString('hex')); ``` ```cjs -const { - randomFillSync, -} = require('crypto'); +const { randomFillSync } = require('crypto'); +const { Buffer } = require('buffer'); const a = new Uint32Array(10); console.log(Buffer.from(randomFillSync(a).buffer, @@ -4500,9 +4507,8 @@ requires that a callback is passed in. If the `callback` function is not provided, an error will be thrown. ```mjs -import { - randomFill -} from 'crypto'; +import { randomFill } from 'crypto'; +import { Buffer } from 'buffer'; const buf = Buffer.alloc(10); randomFill(buf, (err, buf) => { @@ -4523,9 +4529,8 @@ randomFill(buf, 5, 5, (err, buf) => { ``` ```cjs -const { - randomFill, -} = require('crypto'); +const { randomFill } = require('crypto'); +const { Buffer } = require('buffer'); const buf = Buffer.alloc(10); randomFill(buf, (err, buf) => { @@ -4555,9 +4560,8 @@ contains finite numbers only, they are not drawn from a uniform random distribution and have no meaningful lower or upper bounds. ```mjs -import { - randomFill -} from 'crypto'; +import { randomFill } from 'crypto'; +import { Buffer } from 'buffer'; const a = new Uint32Array(10); randomFill(a, (err, buf) => { @@ -4581,9 +4585,8 @@ randomFill(c, (err, buf) => { ``` ```cjs -const { - randomFill, -} = require('crypto'); +const { randomFill } = require('crypto'); +const { Buffer } = require('buffer'); const a = new Uint32Array(10); randomFill(a, (err, buf) => { @@ -5213,6 +5216,7 @@ import { createDecipheriv, randomBytes } from 'crypto'; +import { Buffer } from 'buffer'; const key = 'keykeykeykeykeykeykeykey'; const nonce = randomBytes(12); @@ -5257,6 +5261,7 @@ const { createDecipheriv, randomBytes, } = require('crypto'); +const { Buffer } = require('buffer'); const key = 'keykeykeykeykeykeykeykey'; const nonce = randomBytes(12); diff --git a/doc/api/esm.md b/doc/api/esm.md index 40cb34ee90899b..534addc3330932 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -247,6 +247,7 @@ readFile('./foo.txt', (err, source) => { ```js import fs, { readFileSync } from 'fs'; import { syncBuiltinESMExports } from 'module'; +import { Buffer } from 'buffer'; fs.readFileSync = () => Buffer.from('Hello, ESM'); syncBuiltinESMExports(); @@ -819,8 +820,9 @@ globalThis.someInjectedProperty = 42; console.log('I just set some globals!'); const { createRequire } = getBuiltin('module'); +const { cwd } = getBuiltin('process'); -const require = createRequire(process.cwd() + '/'); +const require = createRequire(cwd() + '/'); // [...] `; } @@ -921,8 +923,9 @@ purposes. // coffeescript-loader.mjs import { URL, pathToFileURL } from 'url'; import CoffeeScript from 'coffeescript'; +import { cwd } from 'process'; -const baseURL = pathToFileURL(`${process.cwd()}/`).href; +const baseURL = pathToFileURL(`${cwd()}/`).href; // CoffeeScript files end in .coffee, .litcoffee or .coffee.md. const extensionsRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/; diff --git a/doc/api/fs.md b/doc/api/fs.md index b4f2c1e11a14b0..09b0d97c3de841 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1313,6 +1313,7 @@ to be written. ```mjs import { writeFile } from 'fs/promises'; +import { Buffer } from 'buffer'; try { const controller = new AbortController(); @@ -3951,6 +3952,7 @@ If `data` is a normal object, it must have an own `toString` function property. ```mjs import { writeFile } from 'fs'; +import { Buffer } from 'buffer'; const data = new Uint8Array(Buffer.from('Hello Node.js')); writeFile('message.txt', data, (err) => { @@ -3981,6 +3983,7 @@ to be written. ```mjs import { writeFile } from 'fs'; +import { Buffer } from 'buffer'; const controller = new AbortController(); const { signal } = controller; @@ -4002,6 +4005,7 @@ calling `fs.write()` like: ```mjs import { write } from 'fs'; +import { Buffer } from 'buffer'; write(fd, Buffer.from(data, options.encoding), callback); ``` @@ -6522,6 +6526,7 @@ Example using an absolute path on POSIX: ```mjs import { open } from 'fs/promises'; +import { Buffer } from 'buffer'; let fd; try { diff --git a/doc/api/wasi.md b/doc/api/wasi.md index d5213b9c9eb460..58c310edd82585 100644 --- a/doc/api/wasi.md +++ b/doc/api/wasi.md @@ -13,10 +13,11 @@ underlying operating system via a collection of POSIX-like functions. ```mjs import fs from 'fs'; import { WASI } from 'wasi'; +import { argv, env } from 'process'; const wasi = new WASI({ - args: process.argv, - env: process.env, + args: argv, + env, preopens: { '/sandbox': '/some/real/path/that/wasm/can/access' } @@ -33,9 +34,11 @@ wasi.start(instance); 'use strict'; const fs = require('fs'); const { WASI } = require('wasi'); +const { argv, env } = require('process'); + const wasi = new WASI({ - args: process.argv, - env: process.env, + args: argv, + env, preopens: { '/sandbox': '/some/real/path/that/wasm/can/access' } From e3943e9b0145cf76e1d8f965cfc72ebce89ee998 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 14:27:07 -0700 Subject: [PATCH 7/9] fixup lint file --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 14d4193a9284da..f5100fd3cc91b8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -105,7 +105,7 @@ module.exports = { { name: 'process', message: 'Import process instead of using the global' - } + }, ] }, }, ], From 25feabff58b0f5eb5e50cbb4e4b713cd0caaf9dd Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 14:35:34 -0700 Subject: [PATCH 8/9] revert removing dynamic import in crypto examples --- doc/api/crypto.md | 210 +++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 6a072c1bcd04b6..2f42643d440c6d 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -10,7 +10,7 @@ The `crypto` module provides cryptographic functionality that includes a set of wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign, and verify functions. ```mjs -import { createHmac } from 'crypto'; +const { createHmac } = await import('crypto'); const secret = 'abcdefg'; const hash = createHmac('sha256', secret) @@ -99,7 +99,7 @@ changes: includes a public key and a challenge. ```mjs -import { Certificate } from 'crypto'; +const { Certificate } = await import('crypto'); const spkac = getSpkacSomehow(); const challenge = Certificate.exportChallenge(spkac); console.log(challenge.toString('utf8')); @@ -130,7 +130,7 @@ changes: which includes a public key and a challenge. ```mjs -import { Certificate } from 'crypto'; +const { Certificate } = await import('crypto'); const spkac = getSpkacSomehow(); const publicKey = Certificate.exportPublicKey(spkac); console.log(publicKey); @@ -162,8 +162,8 @@ changes: `false` otherwise. ```mjs -import { Certificate } from 'crypto'; import { Buffer } from 'buffer'; +const { Certificate } = await import('crypto'); const spkac = getSpkacSomehow(); console.log(Certificate.verifySpkac(Buffer.from(spkac))); @@ -192,7 +192,7 @@ Instances of the `Certificate` class can be created using the `new` keyword or by calling `crypto.Certificate()` as a function: ```mjs -import { Certificate } from 'crypto'; +const { Certificate } = await import('crypto'); const cert1 = new Certificate(); const cert2 = Certificate(); @@ -216,7 +216,7 @@ added: v0.11.8 includes a public key and a challenge. ```mjs -import { Certificate } from 'crypto'; +const { Certificate } = await import('crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); const challenge = cert.exportChallenge(spkac); @@ -244,7 +244,7 @@ added: v0.11.8 which includes a public key and a challenge. ```mjs -import { Certificate } from 'crypto'; +const { Certificate } = await import('crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); const publicKey = cert.exportPublicKey(spkac); @@ -272,8 +272,8 @@ added: v0.11.8 `false` otherwise. ```mjs -import { Certificate } from 'crypto'; import { Buffer } from 'buffer'; +const { Certificate } = await import('crypto'); const cert = Certificate(); const spkac = getSpkacSomehow(); @@ -313,11 +313,11 @@ directly using the `new` keyword. Example: Using `Cipher` objects as streams: ```mjs -import { +const { scrypt, randomFill, createCipheriv -} from 'crypto'; +} = await import('crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -390,11 +390,11 @@ import { pipeline } from 'stream'; -import { +const { scrypt, randomFill, createCipheriv -} from 'crypto'; +} = await import('crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -461,11 +461,11 @@ scrypt(password, 'salt', 24, (err, key) => { Example: Using the [`cipher.update()`][] and [`cipher.final()`][] methods: ```mjs -import { +const { scrypt, randomFill, createCipheriv -} from 'crypto'; +} = await import('crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -634,11 +634,11 @@ directly using the `new` keyword. Example: Using `Decipher` objects as streams: ```mjs -import { +import { Buffer } from 'buffer'; +const { scryptSync, createDecipheriv -} from 'crypto'; -import { Buffer } from 'buffer'; +} = await import('crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -712,11 +712,11 @@ import { createReadStream, createWriteStream, } from 'fs'; -import { +import { Buffer } from 'buffer'; +const { scryptSync, createDecipheriv -} from 'crypto'; -import { Buffer } from 'buffer'; +} = await import('crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -762,11 +762,11 @@ input.pipe(decipher).pipe(output); Example: Using the [`decipher.update()`][] and [`decipher.final()`][] methods: ```mjs -import { +import { Buffer } from 'buffer'; +const { scryptSync, createDecipheriv -} from 'crypto'; -import { Buffer } from 'buffer'; +} = await import('crypto'); const algorithm = 'aes-192-cbc'; const password = 'Password used to generate key'; @@ -953,9 +953,9 @@ Instances of the `DiffieHellman` class can be created using the ```mjs import assert from 'assert'; -import { +const { createDiffieHellman -} from 'crypto'; +} = await import('crypto'); // Generate Alice's keys... const alice = createDiffieHellman(2048); @@ -1132,7 +1132,7 @@ its keys after creation. In other words, it does not implement `setPublicKey()` or `setPrivateKey()` methods. ```mjs -import { createDiffieHellmanGroup } from 'crypto'; +const { createDiffieHellmanGroup } = await import('crypto'); const dh = createDiffieHellmanGroup('modp1'); ``` @@ -1170,9 +1170,9 @@ Instances of the `ECDH` class can be created using the ```mjs import assert from 'assert'; -import { +const { createECDH -} from 'crypto'; +} = await import('crypto'); // Generate Alice's keys... const alice = createECDH('secp521r1'); @@ -1244,10 +1244,10 @@ If the `inputEncoding` is not provided, `key` is expected to be a [`Buffer`][], Example (uncompressing a key): ```mjs -import { +const { createECDH, ECDH -} from 'crypto'; +} = await import('crypto'); const ecdh = createECDH('secp256k1'); ecdh.generateKeys(); @@ -1410,10 +1410,10 @@ set. Example (obtaining a shared secret): ```mjs -import { +const { createECDH, createHash -} from 'crypto'; +} = await import('crypto'); const alice = createECDH('secp256k1'); const bob = createECDH('secp256k1'); @@ -1484,9 +1484,9 @@ objects are not to be created directly using the `new` keyword. Example: Using `Hash` objects as streams: ```mjs -import { +const { createHash -} from 'crypto'; +} = await import('crypto'); const hash = createHash('sha256'); @@ -1531,8 +1531,8 @@ Example: Using `Hash` and piped streams: ```mjs import { createReadStream } from 'fs'; -import { createHash } from 'crypto'; import { stdout } from 'process'; +const { createHash } = await import('crypto'); const hash = createHash('sha256'); @@ -1554,9 +1554,9 @@ input.pipe(hash).setEncoding('hex').pipe(stdout); Example: Using the [`hash.update()`][] and [`hash.digest()`][] methods: ```mjs -import { +const { createHash -} from 'crypto'; +} = await import('crypto'); const hash = createHash('sha256'); @@ -1599,9 +1599,9 @@ its [`hash.digest()`][] method has been called. ```mjs // Calculate a rolling hash. -import { +const { createHash -} from 'crypto'; +} = await import('crypto'); const hash = createHash('sha256'); @@ -1694,9 +1694,9 @@ objects are not to be created directly using the `new` keyword. Example: Using `Hmac` objects as streams: ```mjs -import { +const { createHmac -} from 'crypto'; +} = await import('crypto'); const hmac = createHmac('sha256', 'a secret'); @@ -1741,10 +1741,10 @@ Example: Using `Hmac` and piped streams: ```mjs import { createReadStream } from 'fs'; -import { - createHmac -} from 'crypto'; import { stdout } from 'process'; +const { + createHmac +} = await import('crypto'); const hmac = createHmac('sha256', 'a secret'); @@ -1770,9 +1770,9 @@ input.pipe(hmac).pipe(stdout); Example: Using the [`hmac.update()`][] and [`hmac.digest()`][] methods: ```mjs -import { +const { createHmac -} from 'crypto'; +} = await import('crypto'); const hmac = createHmac('sha256', 'a secret'); @@ -1870,7 +1870,7 @@ added: v15.0.0 Example: Converting a `CryptoKey` instance to a `KeyObject`: ```mjs -import { webcrypto, KeyObject } from 'crypto'; +const { webcrypto, KeyObject } = await import('crypto'); const { subtle } = webcrypto; const key = await subtle.generateKey({ @@ -2058,11 +2058,11 @@ to be created directly using the `new` keyword. Example: Using `Sign` and [`Verify`][] objects as streams: ```mjs -import { +const { generateKeyPairSync, createSign, createVerify -} from 'crypto'; +} = await import('crypto'); const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'sect239k1' @@ -2106,11 +2106,11 @@ console.log(verify.verify(publicKey, signature, 'hex')); Example: Using the [`sign.update()`][] and [`verify.update()`][] methods: ```mjs -import { +const { generateKeyPairSync, createSign, createVerify -} from 'crypto'; +} = await import('crypto'); const { privateKey, publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048, @@ -2354,7 +2354,7 @@ Encapsulates an X509 certificate and provides read-only access to its information. ```mjs -import { X509Certificate } from 'crypto'; +const { X509Certificate } = await import('crypto'); const x509 = new X509Certificate('{... pem encoded cert ...}'); @@ -3029,10 +3029,10 @@ Example: generating the sha256 sum of a file import { createReadStream } from 'fs'; -import { - createHash -} from 'crypto'; import { argv } from 'process'; +const { + createHash +} = await import('crypto'); const filename = argv[2]; @@ -3115,10 +3115,10 @@ Example: generating the sha256 HMAC of a file import { createReadStream } from 'fs'; -import { - createHmac -} from 'crypto'; import { argv } from 'process'; +const { + createHmac +} = await import('crypto'); const filename = argv[2]; @@ -3338,9 +3338,9 @@ Asynchronously generates a new random secret key of the given `length`. The `type` will determine which validations will be performed on the `length`. ```mjs -import { +const { generateKey -} from 'crypto'; +} = await import('crypto'); generateKey('hmac', { length: 64 }, (err, key) => { if (err) throw err; @@ -3410,9 +3410,9 @@ It is recommended to encode public keys as `'spki'` and private keys as `'pkcs8'` with encryption for long-term storage: ```mjs -import { +const { generateKeyPair -} from 'crypto'; +} = await import('crypto'); generateKeyPair('rsa', { modulusLength: 4096, @@ -3507,9 +3507,9 @@ private keys, it is recommended to use `'pkcs8'` with a strong passphrase, and to keep the passphrase confidential. ```mjs -import { +const { generateKeyPairSync -} from 'crypto'; +} = await import('crypto'); const { publicKey, @@ -3575,9 +3575,9 @@ Synchronously generates a new random secret key of the given `length`. The `type` will determine which validations will be performed on the `length`. ```mjs -import { +const { generateKeySync -} from 'crypto'; +} = await import('crypto'); const key = generateKeySync('hmac', 64); console.log(key.export().toString('hex')); // e89..........41e @@ -3712,9 +3712,9 @@ added: v0.9.3 algorithms. ```mjs -import { +const { getCiphers -} from 'crypto'; +} = await import('crypto'); console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...] ``` @@ -3735,9 +3735,9 @@ added: v2.3.0 * Returns: {string[]} An array with the names of the supported elliptic curves. ```mjs -import { +const { getCurves -} from 'crypto'; +} = await import('crypto'); console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...] ``` @@ -3772,9 +3772,9 @@ and communication time. Example (obtaining a shared secret): ```mjs -import { +const { getDiffieHellman -} from 'crypto'; +} = await import('crypto'); const alice = getDiffieHellman('modp14'); const bob = getDiffieHellman('modp14'); @@ -3824,9 +3824,9 @@ added: v0.9.3 such as `'RSA-SHA256'`. Hash algorithms are also called "digest" algorithms. ```mjs -import { +const { getHashes -} from 'crypto'; +} = await import('crypto'); console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...] ``` @@ -3869,10 +3869,10 @@ be passed to the callback as an {ArrayBuffer}. An error will be thrown if any of the input aguments specify invalid values or types. ```mjs -import { - hkdf -} from 'crypto'; import { Buffer } from 'buffer'; +const { + hkdf +} = await import('crypto'); hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => { if (err) throw err; @@ -3920,10 +3920,10 @@ An error will be thrown if any of the input aguments specify invalid values or types, or if the derived key cannot be generated. ```mjs -import { - hkdfSync -} from 'crypto'; import { Buffer } from 'buffer'; +const { + hkdfSync +} = await import('crypto'); const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64); console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' @@ -3998,9 +3998,9 @@ When passing strings for `password` or `salt`, please consider [caveats when using strings as inputs to cryptographic APIs][]. ```mjs -import { +const { pbkdf2 -} from 'crypto'; +} = await import('crypto'); pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => { if (err) throw err; @@ -4095,9 +4095,9 @@ When passing strings for `password` or `salt`, please consider [caveats when using strings as inputs to cryptographic APIs][]. ```mjs -import { +const { pbkdf2Sync -} from 'crypto'; +} = await import('crypto'); const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512'); console.log(key.toString('hex')); // '3745e48...08d59ae' @@ -4333,9 +4333,9 @@ If an error occurs, `err` will be an `Error` object; otherwise it is `null`. The ```mjs // Asynchronous -import { +const { randomBytes -} from 'crypto'; +} = await import('crypto'); randomBytes(256, (err, buf) => { if (err) throw err; @@ -4361,9 +4361,9 @@ there is a problem generating the bytes. ```mjs // Synchronous -import { +const { randomBytes -} from 'crypto'; +} = await import('crypto'); const buf = randomBytes(256); console.log( @@ -4418,8 +4418,8 @@ changes: Synchronous version of [`crypto.randomFill()`][]. ```mjs -import { randomFillSync } from 'crypto'; import { Buffer } from 'buffer'; +const { randomFillSync } = await import('crypto'); const buf = Buffer.alloc(10); console.log(randomFillSync(buf).toString('hex')); @@ -4451,8 +4451,8 @@ Any `ArrayBuffer`, `TypedArray` or `DataView` instance may be passed as `buffer`. ```mjs -import { randomFillSync } from 'crypto'; import { Buffer } from 'buffer'; +const { randomFillSync } = await import('crypto'); const a = new Uint32Array(10); console.log(Buffer.from(randomFillSync(a).buffer, @@ -4507,8 +4507,8 @@ requires that a callback is passed in. If the `callback` function is not provided, an error will be thrown. ```mjs -import { randomFill } from 'crypto'; import { Buffer } from 'buffer'; +const { randomFill } = await import('crypto'); const buf = Buffer.alloc(10); randomFill(buf, (err, buf) => { @@ -4560,8 +4560,8 @@ contains finite numbers only, they are not drawn from a uniform random distribution and have no meaningful lower or upper bounds. ```mjs -import { randomFill } from 'crypto'; import { Buffer } from 'buffer'; +const { randomFill } = await import('crypto'); const a = new Uint32Array(10); randomFill(a, (err, buf) => { @@ -4640,9 +4640,9 @@ generated synchronously. ```mjs // Asynchronous -import { +const { randomInt -} from 'crypto'; +} = await import('crypto'); randomInt(3, (err, n) => { if (err) throw err; @@ -4664,9 +4664,9 @@ randomInt(3, (err, n) => { ```mjs // Synchronous -import { +const { randomInt -} from 'crypto'; +} = await import('crypto'); const n = randomInt(3); console.log(`Random number chosen from (0, 1, 2): ${n}`); @@ -4684,9 +4684,9 @@ console.log(`Random number chosen from (0, 1, 2): ${n}`); ```mjs // With `min` argument -import { +const { randomInt -} from 'crypto'; +} = await import('crypto'); const n = randomInt(1, 7); console.log(`The dice rolled: ${n}`); @@ -4774,9 +4774,9 @@ An exception is thrown when any of the input arguments specify invalid values or types. ```mjs -import { +const { scrypt -} from 'crypto'; +} = await import('crypto'); // Using the factory defaults. scrypt('password', 'salt', 64, (err, derivedKey) => { @@ -4854,9 +4854,9 @@ An exception is thrown when any of the input arguments specify invalid values or types. ```mjs -import { +const { scryptSync -} from 'crypto'; +} = await import('crypto'); // Using the factory defaults. const key1 = scryptSync('password', 'salt', 64); @@ -5211,12 +5211,12 @@ mode must adhere to certain restrictions when using the cipher API: authentication tag. ```mjs -import { +import { Buffer } from 'buffer'; +const { createCipheriv, createDecipheriv, randomBytes -} from 'crypto'; -import { Buffer } from 'buffer'; +} = await import('crypto'); const key = 'keykeykeykeykeykeykeykey'; const nonce = randomBytes(12); From 37247c895c654129988b49ffd69e33f6c10423f5 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 15 Jun 2021 14:40:48 -0700 Subject: [PATCH 9/9] Update doc/api/async_hooks.md Co-authored-by: Antoine du Hamel --- doc/api/async_hooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index e09e89fc377cbb..ea66f495fb1723 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -638,7 +638,7 @@ import { createServer } from 'http'; import { executionAsyncId, executionAsyncResource, - createHook + createHook, } from 'async_hooks'; const sym = Symbol('state'); // Private symbol to avoid pollution