ES模块导入lodash/merge仅生产可用,开发环境报错如何解决?
解决lodash/merge开发环境导入报错问题
嘿,这个问题我之前也碰到过!核心原因是lodash的单个子模块(比如lodash/merge)是CommonJS格式的,而你的开发环境打包工具(比如Vite、Webpack)在处理ES模块导入CommonJS模块时,默认导出的解析逻辑和生产环境不一样——生产环境可能自动做了兼容转换,但开发环境没处理到位,导致你拿到的_merge不是直接的函数,而是一个包含default属性的对象,所以才会报merge_1.default is not a function的错误。
下面给你几个不用改导入风格、也不用加载全量lodash的解决方案,按推荐程度排序:
1. 改用lodash-es的单个模块导入(最省心)
lodash-es是lodash官方推出的ES模块版本,所有子模块都是标准的ES格式,完全避开了CommonJS和ES模块的互操作问题。
- 先安装lodash-es:
npm install lodash-es --save
- 然后保持你习惯的ES模块导入风格,只改一下包路径:
import _merge from 'lodash-es/merge';
这样不管是开发还是生产环境,_merge都会直接是可用的函数,完全满足你的需求。
2. 配置开发环境打包工具,兼容CommonJS默认导出
如果你不想额外安装包,可以调整打包工具的配置,让它正确解析lodash子模块的默认导出:
针对Vite的配置
在vite.config.js里添加optimizeDeps的配置,强制Vite正确处理lodash的子模块:
import { defineConfig } from 'vite'; import fs from 'fs'; export default defineConfig({ optimizeDeps: { include: ['lodash/merge'], esbuildOptions: { plugins: [ { name: 'resolve-lodash-cjs', setup(build) { build.onLoad({ filter: /lodash\/.*\.js$/ }, async args => { const content = await fs.promises.readFile(args.path, 'utf8'); // 将CommonJS模块转换为ES模块默认导出 return { contents: `export default ${content}`, loader: 'js', }; }); }, }, ], }, }, });
针对Webpack的配置
在webpack.config.js里通过Babel插件处理lodash模块的默认导出:
module.exports = { module: { rules: [ { test: /\.js$/, // 只针对lodash的子模块做处理 include: /node_modules\/lodash\//, use: { loader: 'babel-loader', options: { plugins: [ // 自动将CommonJS的导出转换为ES模块的默认导出 '@babel/plugin-transform-modules-commonjs' ] } } } ] } };
3. 临时兼容写法(快速验证用,不推荐长期用)
如果你只是想快速验证问题,不想改配置或装包,可以手动处理默认导出——虽然这是个小改动,但也算保持了ES模块的导入风格:
import * as mergeModule from 'lodash/merge'; const _merge = mergeModule.default;
这个写法本质上是手动完成了打包工具该做的事,把CommonJS模块的默认导出提取出来,临时解决报错问题。
内容的提问来源于stack exchange,提问作者Omtechguy
相关产品推荐
相关产品推荐

