redux的applyMiddleware仅在CommonJS下生效,如何适配ES Module?
问题原因
这个问题是Node.js对CommonJS模块和ES Module的兼容逻辑差异导致的,核心原因有两个:
- 你使用的Redux及相关中间件版本较低(Redux v4.x、redux-thunk v2.x及更早版本),这类版本仅提供CommonJS格式产物,未做原生ES Module适配。
- 当你在
package.json中配置"type": "module"启用ES Module规范后,Node.js导入CommonJS模块时,会将CommonJS的module.exports整体封装为ES Module的default导出,不会自动拆分命名导出。此时你直接用命名导入或者默认导入拿到的中间件/Redux API可能不是实际的函数值:- 如果你用
import { applyMiddleware } from 'redux'导入,旧版本Redux没有暴露对应命名导出,拿到的applyMiddleware是undefined,调用时会直接报错 - 如果你导入中间件时用
import thunk from 'redux-thunk',拿到的是一个包含default属性的对象,而非实际的thunk函数,把这个对象传给applyMiddleware就会触发TypeError: middleware is not a function的报错
- 如果你用
解决方案
根据你的项目依赖情况选择任意一种即可:
- 方案1:升级依赖到支持ES Module的版本
把Redux升级到v5.x及以上版本,相关中间件(如redux-thunk升级到v3.x、redux-logger升级到v4.x及以上),新版本均原生支持ES Module,原有import { createStore, applyMiddleware } from "redux"的导入语法不需要修改即可直接运行。 - 方案2:适配旧版本的导入语法
如果你必须使用旧版本Redux,修改所有Redux相关的导入语句,手动从default属性中取实际导出值:// 导入Redux API import redux from 'redux' const { createStore, applyMiddleware } = redux // 导入中间件的写法示例 import thunkPkg from 'redux-thunk' const thunk = thunkPkg.default import loggerPkg from 'redux-logger' const logger = loggerPkg.default // 正常调用applyMiddleware const store = createStore(rootReducer, applyMiddleware(thunk, logger)) - 方案3:使用CommonJS导入语法的ES Module兼容写法
可以用Node.js提供的createRequire方法直接沿用CommonJS的导入逻辑,不需要修改原有导入后的代码:import { createRequire } from 'module' const require = createRequire(import.meta.url) const { createStore, applyMiddleware } = require('redux') const thunk = require('redux-thunk') const logger = require('redux-logger')
内容的提问来源于stack exchange,提问作者Mustafa Montaser
相关产品推荐
相关产品推荐

