@types/react 依赖风波

2022-04-08

今天公司 Staging 环境部署老项目 DM 的时候出现了报错,是某个组件的 TS 类型检查出现了问题,按照往常经验来讲,大概率就是安装的依赖版本有问题。

// 涉及到的代码,FC 自带 children 属性(定义为 ReactNode 类型),而不需要你再次进行定义
// 排错后,发现最新 18.X.X 版本的包取消了这样的规则
interface IProps {
  onClick: () => void
  dataSource: any
}

const ActionLog: FC<IProps> = (props) => {
  ...
}

最简单的办法就是准备一个全新的环境安装一遍,我又拿我的阿里云服务器整了活,发现原因是 @types/react 这个包发布了最新版本 V18,而最新版本和此前 V17 的类型定义有很多调整,就例如前面提到的 FC 的改变。我首先是给项目 package.jsondevDependencies 下手动定义两个包的版本成 17,子依赖写的是 "@types/react": "*",应该会自动复用和继承?结果发现并没有用。

和其他同事沟通未果,我还是去请教了下 @Innei,他说给 package.json 定义 resolutions 字段就行,不过我参考了下 NPM 官方文档的 package.json 配置项说明,这里面就没有 resolutions 这个功能,只有 yarn 才有。

可公司用于部署 Staging 的环境是 K8S 整的,理论上每次安装都是船新的环境,原先的所有部署流程都是使用 npm 完成的,我让部署尝试使用 yarn 来替代,这个 @types/react 依赖的问题确实没有了,但是这坨 💩 又产生了新的问题,提示 Support for the experimental syntax 'decorators-legacy' isn't currently enabled,是老版本的 Mobx 默认使用了 TS 的装饰器语法,究极恶心!我就还在想,是不是还是没装到正确的依赖版本?

@Innei 给我找了个叫 npm-force-resolutions 的库,我尝试在自己服务器上用这个方案解决,大多数依赖确实改用了 V17 版本,可还是有漏网之鱼用上了 V18,究极的尴尬。

去围观了下 React 的 Issues 区,上面也有人提到了今天的这个大改动 Bug: React 18 types broken since the type release a view hours ago。最底下提供的解决方案就是 @Innei 说的这个,真的厉害!

晚上继续和后端连线,尝试了很多方法降级,其实上述的 resolutions 方法,都是最管用的,就是项目代码本身的那个“Mobx 装饰器”的那个问题确实很蛋疼,网上提供的解决办法都是说要改 Babel 配置文件的 @babel/plugin-proposal-decorators 参数,但是这条配置在这项目里面很早之前就一直存在,此前部署也都是正常,为什么就这次改了一个 @types/react 就会不生效了?我在我服务器上能正常部署,可一到公司的 Docker 环境就始终不行。

今晚公司还有发版部署的任务,我在想其他老项目会不会也这么爆炸,还特地让后端去确认了下容器环境,发现其中某个老项目的依赖竟然没问题!!!

使用命令 npm ls @types/react 可以检查项目本身及其依赖项都到底安装使用了什么版本的 @types/react,发现是因为这个项目其中的第一个依赖 @shopify/polaris 里面指定了它的版本,理论上只要有第一个包钦定了一个版本,其他依赖项的版本号写 * 都会自动复用和继承。

而我这个出事的老项目 DM 仔细一看其实没有指定任何一个版本,包括其子依赖,都是 *,那自然就是装 V18 最新版了。也就是说,出现那个「Mobx 装饰器」问题反倒是正确的,可这配置项不生效就真的是把我彻底搞懵。这大半天折腾了这么久看似都有了些思路和结果,可最终还是没能解决问题,实在是太难受了!也不知道要怎么继续排查下去了...

配乐 疲惫
概览页 时间轴
奇趣音乐盒 技术源于 Kico Player
Emmm,这里是歌词君