Skip to content

Commit

Permalink
feat: use undici as fetch polyfill (#9106)
Browse files Browse the repository at this point in the history
jacob-ebey authored Mar 22, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 964a94d commit ad83e53
Showing 17 changed files with 67 additions and 86 deletions.
5 changes: 0 additions & 5 deletions jest/jest.config.shared.js
Original file line number Diff line number Diff line change
@@ -9,11 +9,6 @@ const ignorePatterns = [
/** @type {import('jest').Config} */
module.exports = {
moduleNameMapper: {
"^@remix-run/web-blob$": require.resolve("@remix-run/web-blob"),
"^@remix-run/web-fetch$": require.resolve("@remix-run/web-fetch"),
"^@remix-run/web-file": require.resolve("@remix-run/web-file"),
"^@remix-run/web-form-data$": require.resolve("@remix-run/web-form-data"),
"^@remix-run/web-stream$": require.resolve("@remix-run/web-stream"),
"^@web3-storage/multipart-parser$": require.resolve(
"@web3-storage/multipart-parser"
),
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -61,7 +61,6 @@
"@remix-run/css-bundle": "workspace:*",
"@remix-run/dev": "workspace:*",
"@remix-run/node": "workspace:*",
"@remix-run/web-fetch": "^4.4.2",
"@remix-run/react": "workspace:*",
"@remix-run/testing": "workspace:*",
"@rollup/plugin-babel": "^5.2.2",
8 changes: 4 additions & 4 deletions packages/remix-architect/__tests__/server-test.ts
Original file line number Diff line number Diff line change
@@ -217,7 +217,7 @@ describe("architect createRemixHeaders", () => {
"x-foo": "bar, baz",
"x-bar": "baz",
});
expect(headers.getAll("x-foo")).toEqual(["bar, baz"]);
expect(headers.get("x-foo")).toEqual("bar, baz");
expect(headers.get("x-bar")).toBe("baz");
});

@@ -226,9 +226,9 @@ describe("architect createRemixHeaders", () => {
"__session=some_value",
"__other=some_other_value",
]);
expect(headers.getAll("cookie")).toEqual([
"__session=some_value; __other=some_other_value",
]);
expect(headers.get("cookie")).toEqual(
"__session=some_value; __other=some_other_value"
);
});
});
});
4 changes: 3 additions & 1 deletion packages/remix-architect/server.ts
Original file line number Diff line number Diff line change
@@ -88,7 +88,9 @@ export function createRemixHeaders(
}

if (requestCookies) {
headers.append("Cookie", requestCookies.join("; "));
for (let cookie of requestCookies) {
headers.append("Cookie", cookie);
}
}

return headers;
4 changes: 2 additions & 2 deletions packages/remix-express/__tests__/server-test.ts
Original file line number Diff line number Diff line change
@@ -178,7 +178,7 @@ describe("express createRemixHeaders", () => {
"x-foo": ["bar", "baz"],
"x-bar": "baz",
});
expect(headers.getAll("x-foo")).toEqual(["bar", "baz"]);
expect(headers.get("x-foo")).toEqual("bar, baz");
expect(headers.get("x-bar")).toBe("baz");
});

@@ -189,7 +189,7 @@ describe("express createRemixHeaders", () => {
"__other=some_other_value; Path=/; Secure; HttpOnly; Expires=Wed, 21 Oct 2015 07:28:00 GMT; SameSite=Lax",
],
});
expect(headers.getAll("set-cookie")).toEqual([
expect(headers.getSetCookie()).toEqual([
"__session=some_value; Path=/; Secure; HttpOnly; MaxAge=7200; SameSite=Lax",
"__other=some_other_value; Path=/; Secure; HttpOnly; Expires=Wed, 21 Oct 2015 07:28:00 GMT; SameSite=Lax",
]);
5 changes: 0 additions & 5 deletions packages/remix-node/__tests__/fileUploadHandler-test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import * as fs from "node:fs";
import * as path from "node:path";
import { ReadableStream } from "@remix-run/web-stream";

import { NodeOnDiskFile } from "../upload/fileUploadHandler";
import { readableStreamToString } from "../stream";

beforeAll(() => {
global.ReadableStream = ReadableStream;
});

describe("NodeOnDiskFile", () => {
let filepath = path.resolve(__dirname, "assets/test.txt");
let size = fs.statSync(filepath).size;
52 changes: 15 additions & 37 deletions packages/remix-node/globals.ts
Original file line number Diff line number Diff line change
@@ -5,22 +5,7 @@ import {
Headers as NodeHeaders,
Request as NodeRequest,
Response as NodeResponse,
} from "@remix-run/web-fetch";
import {
ByteLengthQueuingStrategy as NodeByteLengthQueuingStrategy,
CountQueuingStrategy as NodeCountQueuingStrategy,
ReadableByteStreamController as NodeReadableByteStreamController,
ReadableStream as NodeReadableStream,
ReadableStreamBYOBReader as NodeReadableStreamBYOBReader,
ReadableStreamBYOBRequest as NodeReadableStreamBYOBRequest,
ReadableStreamDefaultController as NodeReadableStreamDefaultController,
ReadableStreamDefaultReader as NodeReadableStreamDefaultReader,
TransformStream as NodeTransformStream,
TransformStreamDefaultController as NodeTransformStreamDefaultController,
WritableStream as NodeWritableStream,
WritableStreamDefaultController as NodeWritableStreamDefaultController,
WritableStreamDefaultWriter as NodeWritableStreamDefaultWriter,
} from "@remix-run/web-stream";
} from "undici";

declare global {
namespace NodeJS {
@@ -41,30 +26,23 @@ declare global {
WritableStream: typeof WritableStream;
}
}

interface RequestInit {
duplex?: "half";
}
}

export function installGlobals() {
global.File = NodeFile;
global.File = NodeFile as unknown as typeof File;

global.Headers = NodeHeaders as typeof Headers;
global.Request = NodeRequest as typeof Request;
global.Response = NodeResponse as unknown as typeof Response;
global.fetch = nodeFetch as typeof fetch;
// @ts-expect-error - overriding globals
global.Headers = NodeHeaders;
// @ts-expect-error - overriding globals
global.Request = NodeRequest;
// @ts-expect-error - overriding globals
global.Response = NodeResponse;
// @ts-expect-error - overriding globals
global.fetch = nodeFetch;
// @ts-expect-error - overriding globals
global.FormData = NodeFormData;

// Export everything from https://developer.mozilla.org/en-US/docs/Web/API/Streams_API
global.ByteLengthQueuingStrategy = NodeByteLengthQueuingStrategy;
global.CountQueuingStrategy = NodeCountQueuingStrategy;
global.ReadableByteStreamController = NodeReadableByteStreamController;
global.ReadableStream = NodeReadableStream;
global.ReadableStreamBYOBReader = NodeReadableStreamBYOBReader;
global.ReadableStreamBYOBRequest = NodeReadableStreamBYOBRequest;
global.ReadableStreamDefaultController = NodeReadableStreamDefaultController;
global.ReadableStreamDefaultReader = NodeReadableStreamDefaultReader;
global.TransformStream = NodeTransformStream;
global.TransformStreamDefaultController =
NodeTransformStreamDefaultController;
global.WritableStream = NodeWritableStream;
global.WritableStreamDefaultController = NodeWritableStreamDefaultController;
global.WritableStreamDefaultWriter = NodeWritableStreamDefaultWriter;
}
6 changes: 2 additions & 4 deletions packages/remix-node/package.json
Original file line number Diff line number Diff line change
@@ -21,13 +21,11 @@
},
"dependencies": {
"@remix-run/server-runtime": "workspace:*",
"@remix-run/web-fetch": "^4.4.2",
"@remix-run/web-file": "^3.1.0",
"@remix-run/web-stream": "^1.1.0",
"@web3-storage/multipart-parser": "^1.0.0",
"cookie-signature": "^1.1.0",
"source-map-support": "^0.5.21",
"stream-slice": "^0.1.2"
"stream-slice": "^0.1.2",
"undici": "^6.10.1"
},
"devDependencies": {
"@types/cookie-signature": "^1.0.3",
9 changes: 7 additions & 2 deletions packages/remix-react/__tests__/setup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { installGlobals } from "@remix-run/node";
const JSDOMFormData = global.FormData;
global.TextDecoder = require("util").TextDecoder;
global.TextEncoder = require("util").TextEncoder;
global.ReadableStream = require("stream/web").ReadableStream;
global.WritableStream = require("stream/web").WritableStream;

installGlobals();
require("@remix-run/node").installGlobals();
global.FormData = JSDOMFormData;
10 changes: 9 additions & 1 deletion packages/remix-server-runtime/__tests__/formData-test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { parseMultipartFormData } from "../formData";

declare global {
interface RequestInit {
duplex?: "half";
}
}

class CustomError extends Error {
constructor() {
super("test error");
@@ -21,7 +27,7 @@ describe("parseMultipartFormData", () => {
let parsedFormData = await parseMultipartFormData(
req,
async ({ filename, data, contentType }) => {
let chunks = [];
let chunks: Uint8Array[] = [];
for await (let chunk of data) {
chunks.push(chunk);
}
@@ -111,6 +117,7 @@ describe("parseMultipartFormData", () => {
method: "post",
body,
headers: underlyingRequest.headers,
duplex: "half",
});

let error: Error;
@@ -151,6 +158,7 @@ describe("parseMultipartFormData", () => {
method: "post",
body,
headers: underlyingRequest.headers,
duplex: "half",
});

let error: Error;
9 changes: 7 additions & 2 deletions packages/remix-testing/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { installGlobals } from "@remix-run/node";
const JSDOMFormData = global.FormData;
global.TextDecoder = require("util").TextDecoder;
global.TextEncoder = require("util").TextEncoder;
global.ReadableStream = require("stream/web").ReadableStream;
global.WritableStream = require("stream/web").WritableStream;

installGlobals();
require("@remix-run/node").installGlobals();
global.FormData = JSDOMFormData;
2 changes: 1 addition & 1 deletion packages/remix-testing/package.json
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@
"@types/node": "^18.17.1",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"jest-environment-jsdom": "^29.6.4",
"jest-environment-jsdom": "^29.7.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.1.6"
28 changes: 12 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions scripts/bump-fetch-versions.sh
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ if [ "${VERSION}" == "" ]; then
fi


echo "Updating the web-std-io dependencies to version '${VERSION}'"
echo "Updating the undici dependencies to version '${VERSION}'"
echo ""

if [ ! -d "packages/remix-node" ]; then
@@ -18,7 +18,7 @@ fi
set -x

cd packages/remix-node
pnpm add @remix-run/web-fetch@${VERSION} @remix-run/web-file@${VERSION} @remix-run/web-stream@${VERSION}
pnpm add undici@${VERSION}
cd ../..

set +x
2 changes: 1 addition & 1 deletion scripts/deployment-test/_shared.mjs
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@ import crypto from "node:crypto";
import { sync as spawnSync } from "cross-spawn";
import PackageJson from "@npmcli/package-json";
import jsonfile from "jsonfile";
import { fetch } from "@remix-run/web-fetch";
import retry from "fetch-retry";
import { fetch } from "undici";

let fetchRetry = retry(fetch);

2 changes: 1 addition & 1 deletion scripts/deployment-test/cf-pages.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import path from "node:path";
import { sync as spawnSync } from "cross-spawn";
import fse from "fs-extra";
import { fetch } from "@remix-run/web-fetch";
import PackageJson from "@npmcli/package-json";
import { fetch } from "undici";

import {
addCypress,
2 changes: 1 addition & 1 deletion scripts/deployment-test/cf-workers.mjs
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@ import path from "node:path";
import { sync as spawnSync } from "cross-spawn";
import fse from "fs-extra";
import toml from "@iarna/toml";
import { fetch } from "@remix-run/web-fetch";
import PackageJson from "@npmcli/package-json";
import { fetch } from "undici";

import {
addCypress,

0 comments on commit ad83e53

Please sign in to comment.