Skip to content

Commit

Permalink
drop support for Node 12
Browse files Browse the repository at this point in the history
drop support for Node 12

BREAKING CHANGE: drop support for Node 12
  • Loading branch information
jimmywarting committed Jan 27, 2022
1 parent ba23fd2 commit 8c1fe41
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 8 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
node: ["12.20.0", "14.13.1", "16.0.0"]
node: ["14.17", "16.0.0"]
exclude:
# On Windows, run tests with only the LTS environments.
- os: windows-latest
node: "12.22.3"
node: "14.17"
- os: windows-latest
node: "16.0.0"
# On macOS, run tests with only the LTS environments.
- os: macOS-latest
node: "12.22.3"
node: "14.17"
- os: macOS-latest
node: "16.0.0"

Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,21 +88,21 @@ See Jason Miller's [isomorphic-unfetch](https://www.npmjs.com/package/isomorphic
- Stay consistent with `window.fetch` API.
- Make conscious trade-off when following [WHATWG fetch spec][whatwg-fetch] and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known differences.
- Use native promise and async functions.
- Use native Node streams for body, on both request and response.
- Use web streams for body, on both request and response.
- Decode content encoding (gzip/deflate/brotli) properly, and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically.
- Useful extensions such as redirect limit, response size limit, [explicit errors][error-handling.md] for troubleshooting.

## Difference from client-side fetch

- See known differences:
- [As of v4.x](docs/v4-LIMITS.md)
- [As of v3.x](docs/v3-LIMITS.md)
- [As of v2.x](docs/v2-LIMITS.md)
- If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue.
- Pull requests are welcomed too!

## Installation

Current stable release (`3.x`) requires at least Node.js 12.20.0.
Current beta release (`4.x`) requires at least Node.js 14.17.0.

```sh
npm install node-fetch
Expand Down Expand Up @@ -169,6 +169,7 @@ import './fetch-polyfill'

Using an old version of node-fetch? Check out the following files:

- [3.x to 4.x upgrade guide](docs/v4-UPGRADE-GUIDE.md)
- [2.x to 3.x upgrade guide](docs/v3-UPGRADE-GUIDE.md)
- [1.x to 2.x upgrade guide](docs/v2-UPGRADE-GUIDE.md)
- [Changelog](docs/CHANGELOG.md)
Expand Down Expand Up @@ -868,4 +869,4 @@ Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid
[error-handling.md]: https://github.com/node-fetch/node-fetch/blob/master/docs/ERROR-HANDLING.md
[FormData]: https://developer.mozilla.org/en-US/docs/Web/API/FormData
[Blob]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
[File]: https://developer.mozilla.org/en-US/docs/Web/API/File
[File]: https://developer.mozilla.org/en-US/docs/Web/API/File
30 changes: 30 additions & 0 deletions docs/v4-LIMITS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Known differences
=================

*As of 4.x release*

- Topics such as Cross-Origin, Content Security Policy, Mixed Content, Service Workers are ignored, given our server-side context.

- On the upside, there are no forbidden headers.

- `res.url` contains the final url when following redirects.

- For convenience, `res.body` is a Node.js [Readable stream][readable-stream], so decoding can be handled independently.

- Similarly, `req.body` can either be `null`, a buffer or a Readable stream.

- Also, you can handle rejected fetch requests through checking `err.type` and `err.code`. See [ERROR-HANDLING.md][] for more info.

- Only support `res.text()`, `res.json()`, `res.blob()`, `res.arraybuffer()`, `res.buffer()`

- There is currently no built-in caching, as server-side caching varies by use-cases.

- Current implementation lacks server-side cookie store, you will need to extract `Set-Cookie` headers manually.

- If you are using `res.clone()` and writing an isomorphic app, note that stream on Node.js has a smaller internal buffer size (16Kb, aka `highWaterMark`) from client-side browsers (>1Mb, not consistent across browsers). Learn [how to get around this][highwatermark-fix].

- Because Node.js stream doesn't expose a [*disturbed*](https://fetch.spec.whatwg.org/#concept-readablestream-disturbed) property like Stream spec, using a consumed stream for `new Response(body)` will not set `bodyUsed` flag correctly.

[readable-stream]: https://nodejs.org/api/stream.html#stream_readable_streams
[ERROR-HANDLING.md]: https://github.com/node-fetch/node-fetch/blob/master/docs/ERROR-HANDLING.md
[highwatermark-fix]: https://github.com/node-fetch/node-fetch/blob/master/README.md#custom-highwatermark
89 changes: 89 additions & 0 deletions docs/v4-UPGRADE-GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Upgrade to node-fetch v3.x

node-fetch v4.x brings about many changes that increase the compliance of
WHATWG's [Fetch Standard][whatwg-fetch]. However, many of these changes mean
that apps written for earlier version needs to be updated to work with
node-fetch v3.x and be conformant with the Fetch Standard. This document helps
you make this transition.

Note that this document is not an exhaustive list of all changes made in v3.x,
but rather that of the most important breaking changes. See our releases for
other comparatively minor modifications.

---

## Minimum supported Node.js version is now 14.17

Node.js 12 ends long time support in April 2022, we have decided that
node-fetch v4 will drop support for Node.js 14.17 and below (which were
previously supported). We strongly encourage you to upgrade if you still haven't
done so. Check out the Node.js official [LTS plan] for more information.


#### Why 14.17 and not 14.x?
fetch is built around AbortController & AbortSignal in mind. v14.17 is the first
version that added support for passing in a AbortSignal into `http.request()`
We wish to use this feature and pass it along to the request.

Request is also required to have a AbortSignal as a property.

## Removed functionalities.

We strive harder to match the spec, so that you can expect the same functionality
across different environments to work the same wherever you are. That meant that
some node-fetch only features had to go away.

- Deprecated `response.buffer()` have been removed
- The node-fetch only `size` limit option have been removed.
- The `form-data` package have been removed in favor of a spec'ed one instead
`import { FormData } from 'node-fetch'`.

## Headers class have been swapped out for the `fetch-headers` package
We have had a own Headers class that have extended the `URLSearchParams` and
brought all of the features of URLSearchParams into the Headers, This is not OK.
The `fetch-headers` package have been broken out into a separate package for
others to use who only wish to use this.
This `fetch-headers` also runs all test against WPT, same test run by browsers
to make sure it work as it should.

Noticeable differences are:
- `headers.raw()` is no longer possible to use.
- `headers.getAll()` is no longer possible to use.
- `content-encoding` is no longer normalized to all lowercase letters.

## The `.body` stream have changed.
Many have long wished for fetch to be built in right into NodeJS. But it's built
up by so many peaces. One of the requirements is that it uses web streams instead
of Node streams. We would never thought that NodeJS would ever add this when we
first started this project and would only complicate things such as writing files
to the filesystem. But now here they are built right into NodeJS!

The `response.body` and `request.body` is now a whatwg stream instead of a Node
stream.

We use built in `node:stream/web` whenever it's available and fallback to using
`web-streams-polyfill` when it's not available thanks to top level await for
conditional imports.

if you still need it to be a Node stream then you can use either
[stream.Readable.from()](fromIterable) or [stream.Readable.fromWeb](fromWeb)

Alternative you can go the other way around and convert your node streams to web
stream
```js
import stream from 'node:stream'
import { CompressionStream } from 'node:stream/web'
import fs from 'node:fs'

const writable = fs.createWriteStream('sample.bin')
const writableStream = stream.Writable.toWeb(writable)

new Response('abc').body
.pipeThrough(new CompressionStream('gzip'))
.pipeTo(writableStream)
```



[fromIterable]: https://nodejs.org/dist/latest-v17.x/docs/api/stream.html#streamreadablefromiterable-options
[fromWeb]: https://nodejs.org/dist/latest-v17.x/docs/api/stream.html#streamreadablefromwebreadablestream-options
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"types": "./@types/index.d.ts",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"node": "^14.17.1 || >=16.0.0"
},
"scripts": {
"test": "mocha",
Expand Down

0 comments on commit 8c1fe41

Please sign in to comment.