为什么Renovate更新依赖后构建突然失败?
我在项目里配置了Renovate自动更新依赖,昨天成功更新了lodash到4.17.23,但今天构建时突然报错TypeError: _lodash.default.debouce is not a function。已经试过删除node_modules和lock文件重新安装,但问题依旧。
检查Renovate配置发现pinDigests: true,难道是版本锁定的问题?或者可能是新版本删除了某些默认导出?
错误发生在使用import debounce from 'lodash/debounce'的组件里。查看package.json发现依赖写的是"lodash": "^4.17.21",而package-lock里确实锁定了4.17.23版本。
其他同事没有这个问题,可能是我的本地环境问题吗?还是Renovate更新时有隐藏的配置冲突?
你用的
import debounce from 'lodash/debounce'这种按需导入,在 lodash 4.17.22 及之后的版本有兼容性问题。报错信息default.debouce is not a function说明导入的模块结构跟之前不一样了。两个解决办法:
第一个,改用完整导入。把代码里的
import debounce from 'lodash/debounce'改成import { debounce } from 'lodash',这样基本能覆盖大多数场景。第二个,锁定到一个已知稳定的版本。在 package.json 里把依赖从
"lodash": "^4.17.21"改成"lodash": "4.17.21"(去掉 ^),然后手动安装这个版本。这样 Renovate 以后就不会自动升到有问题的版本了。如果业务上确实需要按需导入来减少 bundle 大小,可以考虑换成 lodash-es,或者用 babel-plugin-lodash 来做自动按需导入。
另外,pinDigests 那个配置是管 docker 镜像 digest 锁定的,跟 npm 包版本没关系,你这个场景用不上。
你遇到的错误是因为混用了默认导入和命名导入的方式。在lodash 4.17.23版本里,正确的用法是使用命名导入而不是默认导入。把代码从
import debounce from 'lodash/debounce'改成import { debounce } from 'lodash'就能解决问题。至于为什么其他同事没问题,很可能是因为他们的构建工具配置不同,或者node环境版本不一样导致解析模块的方式有差异。不过根本解决方案还是改用正确的导入方式。
顺便说个开发小技巧,这种问题可以用以下代码快速验证:
最后提醒一下,pinDigests这个配置其实是为了确保依赖的确定性,跟这个错误关系不大。建议团队统一一下lodash的使用规范,避免类似问题。