chore: remove undici polyfill (#8729)

This commit is contained in:
Arsh 2023-10-04 10:28:36 +00:00 committed by Martin Trapp
parent 05833ab44e
commit d50aaea36d
12 changed files with 22 additions and 105 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/telemetry': patch
---
Removed an unnecessary dependency.

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Node-based adapters now create less server-side javascript

View file

@ -3,7 +3,6 @@
// ISOMORPHIC FILE: NO TOP-LEVEL IMPORT/REQUIRE() ALLOWED
// This file has to run as both ESM and CJS on older Node.js versions
// Needed for Stackblitz: https://github.com/stackblitz/webcontainer-core/issues/281
const CI_INSTRUCTIONS = {
NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript',
@ -16,15 +15,11 @@ const CI_INSTRUCTIONS = {
const engines = '>=18.14.1';
const skipSemverCheckIfAbove = 19;
// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported
// TODO: Remove when Node 18 is supported on Stackblitz
const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null;
/** `astro *` */
async function main() {
const version = process.versions.node;
// Fast-path for higher Node.js versions
if (!isStackblitz && (parseInt(version) || 0) <= skipSemverCheckIfAbove) {
if ((parseInt(version) || 0) <= skipSemverCheckIfAbove) {
try {
const semver = await import('semver');
if (!semver.satisfies(version, engines)) {

View file

@ -168,7 +168,6 @@
"string-width": "^6.1.0",
"strip-ansi": "^7.1.0",
"tsconfig-resolver": "^3.0.1",
"undici": "^5.23.0",
"unist-util-visit": "^4.1.2",
"vfile": "^5.3.7",
"vite": "^4.4.9",

View file

@ -39,7 +39,6 @@ export function createAPIContext({
props,
adapterName,
}: CreateAPIContext): APIContext {
initResponseWithEncoding();
const context = {
cookies: new AstroCookies(request),
request,
@ -92,10 +91,7 @@ export function createAPIContext({
type ResponseParameters = ConstructorParameters<typeof Response>;
export let ResponseWithEncoding: ReturnType<typeof initResponseWithEncoding>;
// TODO Remove this after StackBlitz supports Node 18.
let initResponseWithEncoding = () => {
class LocalResponseWithEncoding extends Response {
export class ResponseWithEncoding extends Response {
constructor(
body: ResponseParameters[0],
init: ResponseParameters[1],
@ -122,15 +118,6 @@ let initResponseWithEncoding = () => {
}
}
// Set the module scoped variable.
ResponseWithEncoding = LocalResponseWithEncoding;
// Turn this into a noop.
initResponseWithEncoding = (() => {}) as any;
return LocalResponseWithEncoding;
};
export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>(
mod: EndpointHandler,
env: Environment,

View file

@ -1,63 +1,7 @@
import crypto from 'node:crypto';
import {
ByteLengthQueuingStrategy,
CountQueuingStrategy,
ReadableByteStreamController,
ReadableStream,
ReadableStreamBYOBReader,
ReadableStreamBYOBRequest,
ReadableStreamDefaultController,
ReadableStreamDefaultReader,
TransformStream,
WritableStream,
WritableStreamDefaultController,
WritableStreamDefaultWriter,
} from 'node:stream/web';
import { File, FormData, Headers, Request, Response, fetch } from 'undici';
// NOTE: This file does not intend to polyfill everything that exists, its main goal is to make life easier
// for users deploying to runtime that do support these features. In the future, we hope for this file to disappear.
// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported
// TODO: Remove when Node 18 is supported on Stackblitz. File should get imported from `node:buffer` instead of `undici` once this is removed
const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null;
import buffer from 'node:buffer';
export function apply() {
if (isStackblitz) {
const neededPolyfills = {
ByteLengthQueuingStrategy,
CountQueuingStrategy,
ReadableByteStreamController,
ReadableStream,
ReadableStreamBYOBReader,
ReadableStreamBYOBRequest,
ReadableStreamDefaultController,
ReadableStreamDefaultReader,
TransformStream,
WritableStream,
WritableStreamDefaultController,
WritableStreamDefaultWriter,
File,
FormData,
Headers,
Request,
Response,
fetch,
};
for (let polyfillName of Object.keys(neededPolyfills)) {
if (Object.hasOwnProperty.call(globalThis, polyfillName)) continue;
// Add polyfill to globalThis
Object.defineProperty(globalThis, polyfillName, {
configurable: true,
enumerable: true,
writable: true,
value: neededPolyfills[polyfillName as keyof typeof neededPolyfills],
});
}
}
// Remove when Node 18 is dropped for Node 20
if (!globalThis.crypto) {
Object.defineProperty(globalThis, 'crypto', {
@ -68,7 +12,7 @@ export function apply() {
// Remove when Node 18 is dropped for Node 20
if (!globalThis.File) {
Object.defineProperty(globalThis, 'File', {
value: File,
value: buffer.File,
});
}
}

View file

@ -170,7 +170,7 @@ export async function loadFixture(inlineConfig) {
try {
return await fetch(resolvedUrl, init);
} catch (err) {
// undici throws a vague error when it fails, so we log the url here to easily debug it
// node fetch throws a vague error when it fails, so we log the url here to easily debug it
if (err.message?.includes('fetch failed')) {
console.error(`[astro test] failed to fetch ${resolvedUrl}`);
console.error(err);

View file

@ -49,8 +49,7 @@
"cheerio": "1.0.0-rc.12",
"express": "^4.18.2",
"mocha": "^10.2.0",
"node-mocks-http": "^1.13.0",
"undici": "^5.23.0"
"node-mocks-http": "^1.13.0"
},
"publishConfig": {
"provenance": true

View file

@ -8,15 +8,12 @@ import type { OutgoingHttpHeaders } from 'node:http';
* @returns NodeJS OutgoingHttpHeaders object with multiple set-cookie handled as an array of values
*/
export const createOutgoingHttpHeaders = (
webHeaders: Headers | undefined | null
headers: Headers | undefined | null
): OutgoingHttpHeaders | undefined => {
if (!webHeaders) {
if (!headers) {
return undefined;
}
// re-type to access Header.getSetCookie()
const headers = webHeaders as HeadersWithGetSetCookie;
// at this point, a multi-value'd set-cookie header is invalid (it was concatenated as a single CSV, which is not valid for set-cookie)
const nodeHeaders: OutgoingHttpHeaders = Object.fromEntries(headers.entries());
@ -26,7 +23,8 @@ export const createOutgoingHttpHeaders = (
// if there is > 1 set-cookie header, we have to fix it to be an array of values
if (headers.has('set-cookie')) {
const cookieHeaders = headers.getSetCookie();
// @ts-expect-error
const cookieHeaders = headers.getSetCookie() as string[];
if (cookieHeaders.length > 1) {
// the Headers.entries() API already normalized all header names to lower case so we can safely index this as 'set-cookie'
nodeHeaders['set-cookie'] = cookieHeaders;
@ -35,8 +33,3 @@ export const createOutgoingHttpHeaders = (
return nodeHeaders;
};
interface HeadersWithGetSetCookie extends Headers {
// the @astrojs/webapi polyfill makes this available (as of undici@5.19.0), but tsc doesn't pick it up on the built-in Headers type from DOM lib
getSetCookie(): string[];
}

View file

@ -35,7 +35,6 @@
"dset": "^3.1.2",
"is-docker": "^3.0.0",
"is-wsl": "^3.0.0",
"undici": "^5.23.0",
"which-pm-runs": "^1.1.0"
},
"devDependencies": {

View file

@ -1,5 +1,4 @@
const ASTRO_TELEMETRY_ENDPOINT = `https://telemetry.astro.build/api/v1/record`;
import { fetch } from 'undici';
export function post(body: Record<string, any>): Promise<any> {
return fetch(ASTRO_TELEMETRY_ENDPOINT, {

View file

@ -628,9 +628,6 @@ importers:
tsconfig-resolver:
specifier: ^3.0.1
version: 3.0.1
undici:
specifier: ^5.23.0
version: 5.23.0
unist-util-visit:
specifier: ^4.1.2
version: 4.1.2
@ -4307,9 +4304,6 @@ importers:
node-mocks-http:
specifier: ^1.13.0
version: 1.13.0
undici:
specifier: ^5.23.0
version: 5.23.0
packages/integrations/node/test/fixtures/api-route:
dependencies:
@ -5005,9 +4999,6 @@ importers:
is-wsl:
specifier: ^3.0.0
version: 3.0.0
undici:
specifier: ^5.23.0
version: 5.23.0
which-pm-runs:
specifier: ^1.1.0
version: 1.1.0
@ -17276,6 +17267,7 @@ packages:
engines: {node: '>=14.0'}
dependencies:
busboy: 1.6.0
dev: true
/unherit@3.0.1:
resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==}