Webpack 5配置指南:解决Axios打包后Node.js运行时XMLHttpRequest is not defined错误
The Root Cause
Your issue happens because Webpack 5 incorrectly merges Axios's two environment-specific adapter imports into a single module. Originally, Axios checks the runtime environment to load either the XHR adapter (for browsers) or the HTTP adapter (for Node.js), but after bundling, both branches end up using the same module reference (the XHR one), causing the error when running in Node.js where XMLHttpRequest doesn't exist.
Two key reasons for this:
- Webpack's default browser target: Without explicitly setting
target: 'node', Webpack bundles for the browser environment. It strips out Node-specific globals likeprocessand may tree-shake the Node-only HTTP adapter, treating it as dead code. - Static analysis over-optimization: Webpack's static module analyzer tries to optimize conditional imports. When it can't accurately determine the dynamic nature of Axios's environment check, it incorrectly merges the two adapter imports into one.
Solutions
1. Set Webpack Target to Node.js
First, tell Webpack you're bundling for Node.js by adding target: 'node' to your webpack.config.js. This preserves Node globals and ensures Node-specific modules aren't discarded:
module.exports = { // ... other config target: 'node', };
2. Disable Static Replacement of typeof Checks
Webpack defaults to statically replacing typeof expressions (e.g., turning typeof XMLHttpRequest into 'undefined' at build time), which breaks Axios's runtime environment detection. Disable this in your parser rules:
module.exports = { // ... other config module: { rules: [ { parser: { javascript: { typeofs: false, // Prevent Webpack from optimizing typeof checks }, }, }, ], }, };
3. Manually Assign the Node.js Adapter (Fallback)
If the above configs don't work, you can bypass Axios's automatic adapter selection by manually importing and setting the HTTP adapter:
const axios = require('axios').default; const httpAdapter = require('axios/lib/adapters/http'); // Force Axios to use the Node.js HTTP adapter axios.defaults.adapter = httpAdapter;
This is a direct fix but removes cross-environment compatibility—use it only if your code exclusively runs in Node.js.
4. Exclude Axios from Bundling (Alternative)
If you don't need to bundle Axios with your code, configure Webpack to treat it as an external dependency. This lets Node.js load Axios directly from node_modules at runtime, where its environment detection works normally:
module.exports = { // ... other config externals: { axios: 'commonjs axios', }, };
Verification
After updating your Webpack config and rebuilding, check the bundled getDefaultAdapter function—you should see two different module IDs referenced in the conditional branches. Running your code in Node.js should no longer throw the XMLHttpRequest is not defined error.
内容的提问来源于stack exchange,提问作者Chosan

