再见Node.js缓冲区,是时候从 Buffer 转移到 Uint8Array 了
从一开始,该Buffer类型就一直是 Node.js 中二进制数据处理的基石。然而,现在我们有了Uint8Array,它是一种原生 JavaScript 类型并且可以跨平台工作。虽然Buffer是 的一个实例Uint8Array,但它引入了许多在其他 JavaScript 环境中不可用的方法。因此,利用特定于 Buffer 的方法的代码需要进行多填充,从而阻止许多有价值的包与浏览器兼容。
Buffer还带有额外的警告。在Uint8Array#slice()创建不可变副本时,Buffer#slice()会创建链接到原始缓冲区的可变段,从而导致可能出现不可预测的行为。问题不在于方法的行为Buffer#slice(),而在于它Buffer是继承方法的子类Uint8Array并完全改变了继承方法的行为。Buffer#slice()请使用Uint8Array#subarray()或来代替Buffer#subarray()。此外,缓冲区通过全局变量暴露私有信息,这是一个潜在的安全风险。
是时候继续前进了。
计划
我打算将所有包从Bufferusing移至Uint8Array. 如果您是 JavaScript 包的维护者,我鼓励您也这样做。
Buffer永远不会被删除,甚至可能永远不会被弃用,但至少社区可以慢慢摆脱它。我希望 Node.js 团队至少会开始阻止使用Buffer.
如何
首先,熟悉和之间微妙的不兼容性。Uint8ArrayBuffer
我制作了这个uint8array-extras包以使过渡更容易。欢迎请求其他实用程序。
如果您的代码接受 aBuffer并且不使用任何Buffer特定于 的方法,您只需将文档和类型更新为Uint8Array. 将输入类型从Bufferto更改Uint8Array为非破坏性更改,因为Buffer是 的实例Uint8Array。
将返回类型从 更改Buffer为Uint8Array是一个重大更改,因为消费者可能会使用Buffer特定的方法。
如果您确实需要将 a 转换Uint8Array为 a Buffer,则可以使用Buffer.from(uint8Array)(复制数据) 或Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength)(不复制)。然而,通常有更好的方法。
主要过渡步骤是:
- 删除所有import {Buffer} from 'node:buffer'导入。
- 删除所有出现的Buffer全局。
- 停止使用Buffer特定方法。
- 替换Buffer读/写方法。
问题
Buffer最初为什么存在?
Buffer早在Uint8Array存在之前就被创建了。
如何使用 Base64 进行转换Uint8Array?
你现在可以使用我的uint8array-extras包。它很可能最终会在 JavaScript 中得到原生支持。
如何处理返回 a 的 Node.js api Buffer(如fs方法)?
由于Buffer是 的子类Uint8Array,因此您可以将其视为Uint8Array. 只需确保您不使用.slice()(行为不同)或任何特定于缓冲区的方法。
例子
JavaScript
+import {stringToBase64} from 'uint8array-extras';
-Buffer.from(string).toString('base64');
+stringToBase64(string);+import {uint8ArrayToHex} from 'uint8array-extras';
-buffer.toString('hex');
+uint8ArrayToHex(uint8Array); const bytes = getBytes();
+const view = new DataView(bytes.buffer);
-const value = bytes.readInt32BE(1);
+const value = view.getInt32(1); import crypto from 'node:crypto';
-import {Buffer} from 'node:buffer';
+import {isUint8Array} from 'uint8array-extras';
export default function hash(data) {
- if (!(typeof data === 'string' || Buffer.isBuffer(data))) {
+ if (!(typeof data === 'string' || isUint8Array(data))) {
throw new TypeError('Incorrect type.');
}
return crypto.createHash('md5').update(data).digest('hex');
}大多数 Node.js APIUint8Array也接受,因此不需要额外的工作。理想情况下,此代码还应转换为Web Crypto,但这与本示例无关。
TypeScript
-import {Buffer} from 'node:buffer';
-export function getSize(input: string | Buffer): number { … }
+export function getSize(input: string | Uint8Array): number { … }执行
我建议强制执行Uint8Arraylinting Buffer。
将其添加到您的 ESLint 配置中:
{
'no-restricted-globals': [
'error',
{
name: 'Buffer',
message: 'Use Uint8Array instead.'
}
],
'no-restricted-imports': [
'error',
{
name: 'buffer',
message: 'Use Uint8Array instead.'
},
{
name: 'node:buffer',
message: 'Use Uint8Array instead.'
}
]
}如果您使用 TypeScript,请添加以下内容:
{
'@typescript-eslint/ban-types': [
'error',
{
types: {
Buffer: {
message: 'Use Uint8Array instead.',
suggest: [
'Uint8Array'
]
}
}
}
]
}如果您使用XO,它很快就会默认带有此配置。
翻译来自:https://sindresorhus.com/blog/goodbye-nodejs-buffer
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!