# esbuild-plugin-polyfill-node

[ESBuild](https://esbuild.github.io/) plugin to polyfill Node.js built-ins and globals, geared towards edge environments and Deno (including Deno Deploy). It consists of two plugins: `polyfillNode`, which should work for most cases, and `polyfillNodeForDeno` which targets Deno and Deno Deploy specifically.

## Installation

```sh
npm install esbuild-plugin-polyfill-node
```

## `polyfillNode`

### Usage

```js
import { build } from "esbuild";
import { polyfillNode } from "esbuild-plugin-polyfill-node";

build({
	entryPoints: ["src/index.js"],
	bundle: true,
	outfile: "dist/bundle.js",
	plugins: [
		polyfillNode({
			// Options (optional)
		}),
	],
});
```

### Options

- `globals.buffer`: Whether to inject the `Buffer` global. Disable it to prevent code like `if (typeof Buffer !== "undefined")` from pulling in the (quite large) `buffer-es6` polyfill. Default: `true`.
- `globals.process`: Whether to inject the `process` global. Disable it to prevent `process.env.NODE_ENV` from pulling in the `process-es6` polyfill. You can use the `define` option to replace `process.env.NODE_ENV` instead. Default: `true`.
- `polyfills`: Polyfills to inject. It's an object where the keys are the names of the polyfills and the values are `false`, `true`, or `"empty"`. `false` disables the polyfill, `true` enables it, and `"empty"` injects an empty polyfill.

### Implemented polyfills

- `_buffer_list` as implemented in [`readable-stream`](https://www.npmjs.com/package/readable-stream)
- `_stream_passthrough` as implemented in [`readable-stream`](https://www.npmjs.com/package/readable-stream)
- `_stream_readable` as implemented in [`readable-stream`](https://www.npmjs.com/package/readable-stream)
- `_stream_transform` as implemented in [`readable-stream`](https://www.npmjs.com/package/readable-stream)
- `_stream_writable` as implemented in [`readable-stream`](https://www.npmjs.com/package/readable-stream)
- `assert` as implemented in [`assert`](https://www.npmjs.com/package/assert)
- `buffer` as implemented in [`buffer-es6`](https://www.npmjs.com/package/buffer-es6)
- `console` as implemented in [`console-browserify`](https://www.npmjs.com/package/console-browserify)
- `crypto`¹ as implemented in [`crypto-browserify`](https://www.npmjs.com/package/crypto-browserify)
- `domain` as implemented in [`domain-browser`](https://www.npmjs.com/package/domain-browser)
- `events` as implemented in [`events`](https://www.npmjs.com/package/events)
- `fs`¹ as implemented in [`browserify-fs`](https://www.npmjs.com/package/browserify-fs)
- `http` as implemented in [`stream-http`](https://www.npmjs.com/package/stream-http)
- `https` as implemented in [`stream-http`](https://www.npmjs.com/package/stream-http)
- `os` as implemented in [`os`](https://www.npmjs.com/package/os)
- `path` as implemented in [`path`](https://www.npmjs.com/package/path)
- `process` as implemented in [`process-es6`](https://www.npmjs.com/package/process-es6)
- `punycode` as implemented in [`punycode`](https://www.npmjs.com/package/punycode)
- `querystring` as implemented in [`querystring`](https://www.npmjs.com/package/querystring)
- `stream` as implemented in [`stream`](https://www.npmjs.com/package/stream)
- `string_decoder` as implemented in [`string_decoder`](https://www.npmjs.com/package/string_decoder)
- `sys` as implemented in [`util`](https://www.npmjs.com/package/util)
- `timers` as implemented in [`timers-browserify`](https://www.npmjs.com/package/timers-browserify)
- `tty` as implemented in [`tty-browserify`](https://www.npmjs.com/package/tty-browserify)
- `url` as implemented in [`url`](https://www.npmjs.com/package/url)
- `util` as implemented in [`util`](https://www.npmjs.com/package/util)
- `vm` as implemented in [`vm-browserify`](https://www.npmjs.com/package/vm-browserify)
- `zlib` as implemented in [`browserify-zlib`](https://www.npmjs.com/package/browserify-zlib)

¹ All except `crypto` and `fs` polyfills are on by default. `crypto` and `fs` have to be explicitly enabled. Otherwise, they will be replaced with empty stubs.

### Empty stubs

The followings modules are only provided as empty stubs. It is illegal to pass `true` for them.

- `dns`
- `dgram`
- `child_process`
- `cluster`
- `module`
- `net`
- `readline`
- `repl`
- `tls`

### Globals

- `global` (aliased to `globalThis`)
- `process`¹ (imports the `process` module)
- `Buffer`¹ (imports the `buffer` module)
- `__dirname` (always `"/"`)
- `__filename` (always `"/index.js"`)

¹ `process` and `Buffer` shims can be disabled by passing `globals.process: false` and `globals.buffer: false` to the plugin options.

## `polyfillNodeForDeno`

This plugin uses Deno's [`std/node`](https://deno.land/std/node) library to polyfill Node builtins and globals. Optionally, it can use polyfills from NPM instead.

### Usage

```js
import { build } from "esbuild";
import { polyfillNodeForDeno } from "esbuild-plugin-polyfill-node";

build({
	entryPoints: ["src/index.js"],
	bundle: true,
	outfile: "dist/bundle.js",
	plugins: [
		polyfillNodeForDeno({
			// Options (optional)
		}),
	],
});
```

### Options

- `stdVersion`: Version of the Deno standard library to use. Default: `"0.160.0"`.
- `globals`: Whether to inject global polyfills (`process`, `Buffer`, `setImmediate`, `clearImmediate`, `__dirname`, and `__filename`). Default: `true`.
- `polyfills`: Polyfills to inject. It's an object where the keys are the names of the polyfills and the values are `false`, `true`, `"npm"` or `"empty"`. `false` disables the polyfill, `true` enables it (default where exists), `"npm"` injects a polyfill from the NPM (default for `"domain"`, `"punycode"`, `"vm"`, and `"zlib"`), and `"empty"` injects an empty polyfill (default for [missing polyfills](#empty-stubs)).

## Credits

- [Fatih Aygün](https://github.com/cyco130), under the [MIT license](./LICENSE)
- Loosely based on [rollup-plugin-polyfill-node](https://github.com/FredKSchott/rollup-plugin-polyfill-node)
