使用 Rush + pnpm 的踩坑记录

2,184 阅读5分钟

如果是打算开始使用 Rush,可以看看最后的参考链接.

首选肯定是官方文档,仔细阅读其中的Developer tutorialsMaintainer tutorials两部分,跟着Maintainer tutorials操作一遍,基本上就能熟悉大部分使用 Rush 的场景了.(PS: 不过其中每一节大都有对应的前置知识,比如安装 Git hooks,前置知识就是了解 Git hooks 的相关知识,虽然不了解也能跟着操作,没问题,不过了解前置知识能更容易理解相关操作以及配置).

然后网上关于 Rush 的文章并不多,特别是缺少比较完整的分步指南,后面两篇是我看到比较好的这方面的文章,当作对官方文档的补充.

有可能是大多数使用 Rush 的人本身已经有 Monorepo 相关方面的经验了,所以上手比较容易.而像我这样之前没有使用 Monorepo 的经验,所以感觉上手会有点难度,有时候只能去 Issue 中一个个翻,有点累,所以更希望能有一个比较完整的指南,不过好在大多数问题都能解决掉 😆.

以下是我在开发 github.com/XYShaoKang/… 时遇到的一些问题,以及解决办法,主要是一些配置,如果有同学遇到同样的问题,希望能帮到你.

能力有限,可能有些地方会有更好的解决方案,希望前辈们不吝赐教.

strictPeerDependencies

Rush 官方推荐打开strictPeerDependencies配置,不过当使用淘宝镜像时,就算依赖的包中即使配置了 peerDependenciesMeta 为可选,安装是依然会报错,比如安装@pmmmwh/react-refresh-webpack-plugin时,会报错:

@pmmmwh/react-refresh-webpack-plugin@0.5.0-rc.4 requires a peer of @types/webpack@4.x || 5.x but none was installed

原因是 cnpm 返回的数据中少了peerDependenciesMeta这个字段.

而在国内,逃不开使用淘宝镜像,所以如果遇到这个问题的话,只能先关闭这个strictPeerDependencies选项,等 cnpm 修复吧!

VSCode 智能提示失效

当使用typescript@4.3.*版本时,VSCode 智能提示,以及自动导入会失效,经测试4.24.4之后均可正常使用.

当前 TS 已经发布了 4.4 版本,而最新的 VSCode 也内置了 4.4 版本,所以只要更新到最新的 VSCode 就能解决当前这个问题了,以下解决方案在需要切换 VSCode 的内置 TS 版本时,依旧可用.

解决办法:

  • 可以通过在包内安装4.2或者4.4之后的版本,配置 VSCode 使用工作区版本的 TS.
  • 或者可以安装JavaScript and TypeScript Nightly插件,这个插件支持将每晚构建的的 TS(typescript@next) 作为 VSCode 的内置 TS 版本.这样也可以解决.不过这样会比较不可控,也许哪次更新就又会出现问题,还得去测试,麻烦.推荐使用第一种方式.

设置 VSCode 使用的 TS 版本

前提: 先打开一个 TS 文件,将光标移移到这个 TS 文件中,再进行如下操作

  • Ctrl(Mac 下按Cmd) + Shift + P在命令面板中输入TypesCript: Select TypeScript Version按回车 ,之后就可以选择要使用的版本了
  • 或者可以点右下角的 TS 版本号如果没有修改过,一般都是现在最新的4.3.5版本,点击4.3.5,在弹出的选择窗口选择版本即可.

隐式依赖的类型

原本在项目中隐式依赖安装的类型(指当前项目依赖的第三方包中包含的依赖),是可以被使用的,比如@testing-library/jest-dom依赖于@types/testing-library__jest-dom,所以正常情况下安装@testing-library/jest-dom,@types/testing-library__jest-dom也会被安装到node_modules下,这样在使用toBeInTheDocument时 TS 引擎能找到对应的类型.

但是使用 Rush 之后,会将所有依赖都提取到common/temp/node_modules中,而项目下的node_modules只会保留直接依赖的链接,这样就导致隐式依赖的类型无法被 TS 引擎找到,需要在项目中显式安装对应的类型包.

ESLint

.eslintrc.js能在子目录中生效,不过.eslintignore却无法生效,可以通过使用.eslintrc.js中的ignorePatterns配置来代替.eslintignore

lint-staged

lint-staged能忽略我们定义的 ESLint 忽略规则.

lint-staged执行时不会管忽略文件的配置,可有些文件我们不需要去检查和修复,比如打包后的文件.官方给出了解决方案,可以通过自定义配置来解决:

在 CI 中因为 Jest 输出而导致的失败

原因是 Jest 在输出时会使用stderr,这会让 Rush 进程以非零状态退出,导致 CI 失败.

解决方案是: 自定义 Jest Reporter,替换掉默认的输出,保证不是错误的情况都是用标准输出stdout,只有真正产生错误时,才使用stderr


最后再不要脸的求个赞 😂

另外我开发的 github.com/XYShaoKang/… 是一个命令行工具,主要功能是指定一个目录,启动一个服务,然后在浏览器中查看目录中的视频,主要使用场景是方便直接在手机上看电脑上的视频.比如追个番啥的.

当然刚开发出来,目前还很简陋,这是用来自用的,所以会一直开发.如果有需要的朋友可以点个 Star,等它慢慢长大.

如果觉得本文有帮助到您,也可以帮忙点个 Star 😭

cli-preview.gif

更多阅读