fix(fetch): defer global access to avoid module-load TypeError#7260
fix(fetch): defer global access to avoid module-load TypeError#7260jasonsaayman merged 1 commit intoaxios:v1.xfrom
Conversation
ed56157 to
cdc3bb9
Compare
|
gg well played |
8a9a5a8 to
92d03d5
Compare
There was a problem hiding this comment.
Pull request overview
This PR prevents a module-load TypeError in the fetch adapter by making destructuring from utils.global safe when it is undefined (as reported in #7259).
Changes:
- Add a default value (
= {}) to the destructured parameter used to extractRequest/Responsefromutils.global. - Guard
ReadableStream/TextEncoderdestructuring by falling back to{}whenutils.globalis falsy.
jasonsaayman
left a comment
There was a problem hiding this comment.
Thanks @Jye10032. When fetch.js's top-level code runs before utils.js's default export has finished populating (a circular-import / evaluation-order quirk that bundlers like Vite can surface), utils.global reads as undefined, and the original destructure has no default, so it throws at module load before anything in axios can recover. Moving the read into factory() sidesteps that entirely; by the time factory is invoked from getFetch(), the ESM graph has settled.
Two small simplifications before this lands.
Flatten the fallback. utils.global is itself globalThis ?? self ?? window ?? global, so the only realistic case where it's undefined is the circular-import one and in that case globalThis is equally available. The ?? {} arm is unreachable in any environment that runs ESM:
const globalObject = utils.global ?? globalThis;Drop the IIFE around Request/Response. With globalObject already in scope, the IIFE's only purpose (handling destructure-of-undefined at module load) is gone:
const { Request, Response } = globalObject;
const globalFetchAPI = { Request, Response };Same shape going into the utils.merge.call(…, globalFetchAPI, env) below.
Optional but nice: a regression test that stubs utils.global to undefined, calls factory({}), and asserts no throw. The bundler-graph case is hard to reproduce in unit tests directly, but stubbing the module is a reasonable proxy.
e899732 to
dac3e73
Compare
|
Rebased onto the latest Changes in the latest revision:
I also re-ran the local fetch adapter tests and verified the original repro no longer throws the |
Description
Fixes #7259
Similar to #7153 which fixed unsafe destructuring in
config.env, this PR fixes another unsafe destructuring pattern in the fetch adapter that causesTypeErrorwhenutils.globalisundefinedduring module loading.Problem
The current code (lines 15-17 in
lib/adapters/fetch.js) directly destructuresutils.globalwithout checking if it's defined:This throws
TypeError: Cannot destructure property 'Request' of 'undefined'in certain build environments (Vite, webpack) where module initialization timing can causeutils.globalto be temporarily undefined.Summary
Defer
utils.globalaccess tofactory()and guard it with a fallback object to prevent module-load crashes when globals are not ready.
Fix
Request/Response/ReadableStream/TextEncoderaccess intofactory()undefinedReproduction
Minimal repro repo:
https://github.com/Jye10032/axios-repo
Steps:
npm installnpm run buildnpm run previewTypeError: Cannot destructure property 'Request' of 'undefined'
Related
config.envdestructuring