From 30900ab86a63a143cccc2431b7a4ff2b046df6ad Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 24 Oct 2023 04:46:28 +0700 Subject: [PATCH] Buffer blog post --- source/components/blog/Post.astro | 7 +- source/content/apps/aiko.md | 1 - source/content/blog/goodbye-nodejs-buffer.md | 98 ++++++++++++++++++++ source/content/config.ts | 1 + 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 source/content/blog/goodbye-nodejs-buffer.md diff --git a/source/components/blog/Post.astro b/source/components/blog/Post.astro index 09e4c57e..09192de9 100644 --- a/source/components/blog/Post.astro +++ b/source/components/blog/Post.astro @@ -3,6 +3,11 @@ import {getFormattedDate} from '~/utils/utils.js'; const {post} = Astro.props; + +// This `proseCSS` is similiar to the one I use for apps, but not exactly the same. + +// `prose-code:before:hidden prose-code:after:hidden`: https://github.com/tailwindlabs/tailwindcss-typography/issues/18#issuecomment-1280797041 +const proseCSS = 'mx-auto px-6 sm:px-6 py-6 pb-20 max-w-3xl prose prose-lg lg:prose-xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-primary-600 dark:prose-a:text-primary-400 prose-img:rounded-md prose-img:shadow-lg mt-8 prose-code:before:hidden prose-code:after:hidden prose-a:text-black/75 dark:prose-a:text-white/90 prose-a:underline prose-a:underline-offset-4 prose-a:decoration-primary-500 hover:prose-a:decoration-primary-600 prose-a:decoration-2 hover:prose-a:decoration-4 hover:prose-a:text-black dark:hover:prose-a:text-white'; ---
@@ -26,7 +31,7 @@ const {post} = Astro.props;
diff --git a/source/content/apps/aiko.md b/source/content/apps/aiko.md index c7ea3e09..33453b92 100644 --- a/source/content/apps/aiko.md +++ b/source/content/apps/aiko.md @@ -19,7 +19,6 @@ My goal is to keep the app simple. If you have more advanced needs, check out [M **Upcoming features** - Batch conversion -- Significantly improved performance on iOS thanks to CoreML - Export to karaoke file
diff --git a/source/content/blog/goodbye-nodejs-buffer.md b/source/content/blog/goodbye-nodejs-buffer.md new file mode 100644 index 00000000..bf6a80a8 --- /dev/null +++ b/source/content/blog/goodbye-nodejs-buffer.md @@ -0,0 +1,98 @@ +--- +title: Goodbye, Node.js Buffer +description: It's time to move from Buffer to Uint8Array. +pubDate: 2023-10-24 +tags: + - nodejs + - javascript + - open-source +--- + +The [`Buffer`](https://nodejs.org/api/buffer.html) type has been the cornerstone for binary data handling in Node.js since the beginning. However, these days we have [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array), which is a native JavaScript type and works cross-platform. While `Buffer` is an instance of `Uint8Array`, it introduces numerous methods that are not available in other JavaScript environments. Consequently, code leveraging Buffer-specific methods needs polyfilling, preventing many valuable packages from being browser-compatible. + +`Buffer` also comes with additional caveats. For instance, `buffer.slice()` creates a mutable segment linked to the original `Buffer`, while `uint8array.slice()` creates an immutable copy, resulting in possible unpredictable behavior. Furthermore, [buffers expose private information](https://github.com/nodejs/node/issues/41588#issuecomment-1016269584) through global variables, a potential security risk. + +It's time to move on. + +## The Plan + +I intend to move [all my packages](https://github.com/search?q=owner%3Asindresorhus+%22node%3Abuffer%22&type=code) from using `Buffer` to `Uint8Array`. If you are a maintainer of an npm package, I encourage you to do the same. + +`Buffer` will never be removed, and probably never even deprecated, but at least the community can slowly move away from it. My hope is that the Node.js team will at least start discouraging the use of `Buffer`. + +## How + +First, make yourself familiar with the [subtle incompatibilities](https://nodejs.org/api/buffer.html#buffers-and-typedarrays) between `Uint8Array` and `Buffer`. + +I have made the [`uint8array-extras` package](https://github.com/sindresorhus/uint8array-extras) to make the transition easier. Pull requests are welcome for additional utilities. + +If your code accepts a `Buffer` and don't use any `Buffer`-specific methods, you can simply update your docs and types to `Uint8Array`. Changing the input type from `Buffer` to `Uint8Array` is a non-breaking change since `Buffer` is an instance of `Uint8Array`. + +Changing the return type from `Buffer` to `Uint8Array` is a breaking change. + +If you really have to convert to a `Buffer`, you can use `Buffer.from(uint8Array)`. However, there's usually a better way. + +## Enforcement + +I recommend enforcing `Uint8Array` over `Buffer` with linting. + +Add this to your ESLint config: + +```js +{ + '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.' + } + ] +} +``` + +And if you use TypeScript, add this: + +```js +{ + '@typescript-eslint/ban-types': [ + 'error', + { + types: { + Buffer: { + message: 'Use Uint8Array instead.', + suggest: [ + 'Uint8Array' + ] + } + } + } + ] +} +``` + +If you use [XO](https://github.com/xojs/xo), it will soon come with this config by default. + +## How Can I Help? + +[Voice your support](https://github.com/nodejs/node/issues/41588) for Node.js using `Uint8Array` for new APIs. + +Help me move [my packages](https://github.com/search?q=owner%3Asindresorhus+%22node%3Abuffer%22&type=code) to `Uint8Array`. Pick one and give it a go. + +Help us make a [lint rule](https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1808) to prevent the use of `Buffer` methods. + +## The End + +Let's make the JavaScript package ecosystem more cross-platform. Thanks for reading. + +[Discuss](https://github.com/sindresorhus/meta/discussions/22) diff --git a/source/content/config.ts b/source/content/config.ts index 98fec30b..0ac1e7db 100644 --- a/source/content/config.ts +++ b/source/content/config.ts @@ -37,6 +37,7 @@ const blogCollection = defineCollection({ tags: z.array(z.enum([ 'open-source', 'javascript', + 'nodejs', ])).optional(), redirectUrl: z.string().url().optional(), }).strict(),