diff --git a/.changeset/green-crabs-breathe.md b/.changeset/green-crabs-breathe.md new file mode 100644 index 000000000..bc4728da4 --- /dev/null +++ b/.changeset/green-crabs-breathe.md @@ -0,0 +1,5 @@ +--- +'@astrojs/telemetry': patch +--- + +Removed an unnecessary dependency. diff --git a/.changeset/thirty-ravens-fly.md b/.changeset/thirty-ravens-fly.md new file mode 100644 index 000000000..ec7d56f82 --- /dev/null +++ b/.changeset/thirty-ravens-fly.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Node-based adapters now create less server-side javascript diff --git a/packages/astro/astro.js b/packages/astro/astro.js index ef5349854..f227ae9e9 100755 --- a/packages/astro/astro.js +++ b/packages/astro/astro.js @@ -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)) { diff --git a/packages/astro/package.json b/packages/astro/package.json index aec2fb5e5..e335a6461 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -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", diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index 380e9e345..9720fea66 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -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; -export let ResponseWithEncoding: ReturnType; -// 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( mod: EndpointHandler, env: Environment, diff --git a/packages/astro/src/core/polyfill.ts b/packages/astro/src/core/polyfill.ts index ea7916eb3..3b271d464 100644 --- a/packages/astro/src/core/polyfill.ts +++ b/packages/astro/src/core/polyfill.ts @@ -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, }); } } diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index e71daa9ba..622ede1f6 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -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); diff --git a/packages/integrations/node/package.json b/packages/integrations/node/package.json index 20739cbd7..865c1541d 100644 --- a/packages/integrations/node/package.json +++ b/packages/integrations/node/package.json @@ -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 diff --git a/packages/integrations/node/src/createOutgoingHttpHeaders.ts b/packages/integrations/node/src/createOutgoingHttpHeaders.ts index e6c0c0ba4..a2f9b74e8 100644 --- a/packages/integrations/node/src/createOutgoingHttpHeaders.ts +++ b/packages/integrations/node/src/createOutgoingHttpHeaders.ts @@ -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[]; -} diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 56564db45..5593bce47 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -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": { diff --git a/packages/telemetry/src/post.ts b/packages/telemetry/src/post.ts index 1c1bd83b2..6aef03bc9 100644 --- a/packages/telemetry/src/post.ts +++ b/packages/telemetry/src/post.ts @@ -1,5 +1,4 @@ const ASTRO_TELEMETRY_ENDPOINT = `https://telemetry.astro.build/api/v1/record`; -import { fetch } from 'undici'; export function post(body: Record): Promise { return fetch(ASTRO_TELEMETRY_ENDPOINT, { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8af88487b..cd7051c04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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==}