Webpack 5未打包依赖:自定义TS库中Axios调用报错排查
问题描述
我有一个使用Axios的TypeScript库,代码如下:
import axios from 'axios'; export class Connector { readonly axios = axios.create(); ... }
发布后,在通过create-react-app --template=typescript创建的React新项目中引入该库,运行时实例化Connector:
import { Connector } from 'mylib'; const connector = new Connector();
在axios.create()调用处出现Uncaught TypeError: Cannot read properties of undefined错误。经调试发现:
- Webpack未打包该库依赖的Axios
- 直接在
App.tsx中导入Axios并调用axios.create()可正常工作,但库内的调用仍失败 - 库内的
axios对象为undefined,Webpack生成了指向node_modules/axios/dist/browser/axios.cjs的导入,但该文件未被包含在打包产物中
使用的是Webpack 5,请问这是什么原因?
原因分析
这是Webpack 5的模块解析规则、库的打包配置共同导致的问题,核心原因如下:
- 库的打包配置将Axios标记为外部依赖:如果你的TypeScript库在打包时(比如用Rollup、Webpack)把Axios设为
external,发布后的库代码不会包含Axios,而是依赖宿主React项目提供Axios。但如果宿主项目的Webpack解析逻辑和库的预期不匹配,就会出现找不到Axios的情况。 - Webpack 5的模块解析严格性:Webpack 5对CommonJS和ES模块的处理区分更严格,若你的库编译为CommonJS格式,而Axios浏览器环境的产物是
axios.cjs,宿主项目的Webpack可能无法正确识别该模块的导出,导致导入的axios为undefined。 - create-react-app的默认配置限制:CRA的Webpack默认配置对第三方库的依赖解析有特定规则,若你的库既没打包Axios,也没通过
peerDependencies声明依赖,就会出现依赖缺失。
解决方案
针对不同原因,对应解决办法如下:
- 调整库的打包配置:
- 若希望库自带Axios,在打包工具(如Rollup)的配置中移除Axios的
external设置,确保Axios被打包进库的产物中。 - 若希望依赖宿主项目的Axios,在库的
package.json中添加peerDependencies声明:
同时在宿主项目中手动安装匹配版本的Axios。"peerDependencies": { "axios": "^1.0.0" }
- 若希望库自带Axios,在打包工具(如Rollup)的配置中移除Axios的
- 修复模块导出格式:
- 确保你的库编译为ES模块格式:在
tsconfig.json中设置"module": "ESNext"、"moduleResolution": "NodeNext",避免CommonJS与ES模块的解析冲突。 - 若用Webpack打包库,设置
output.libraryTarget: 'module'并开启experiments.outputModule: true,符合ES模块规范。
- 确保你的库编译为ES模块格式:在
- 调整宿主项目的Webpack配置:
- 若无法修改库的配置,可通过
react-app-rewired或craco修改CRA的Webpack配置,添加Axios的解析别名:module.exports = { resolve: { alias: { 'axios': require.resolve('axios/dist/browser/axios.cjs') } } }
- 若无法修改库的配置,可通过
内容的提问来源于stack exchange,提问作者Alek
相关产品推荐
相关产品推荐

