lmk123 / blog

个人技术博客,博文写在 Issues 里。
https://github.com/lmk123/blog/issues
623 stars 35 forks source link

Nx 的初步尝试 #113

Open lmk123 opened 1 year ago

lmk123 commented 1 year ago

最近我在尝试使用 monorepos 的方式管理代码,我第一个想到的工具就是 Lerna,因为我已经在很多项目中看到过 Lerna 了,最典型的就是 Babel

不过,在阅读 Lerna 文档的过程中,我看到了另一个工具的名字——Nx。Lerna 的文档中有如下描述:

Nrwl (the company behind the open source build system Nx) has taken over stewardship of Lerna.

我的理解如下:Lerna 是一个很老牌的管理工具,已经很久没有更新过了,于是有一天 Nx 接管了 Lerna,并在 Lerna 的底层使用了 Nx。

在看了 nx 的文档之后,我发现 Nx 完全可以替代 Lerna,于是打算改为使用 Nx,但在阅读文档的过程中发现 Nx 有两种使用方式:Integrated Repos 和 Package-Based Repos。

Package-Based Repos 很好理解,说白了就是 Lerna 这种方式,但 Integrated Repos 我还是第一次见到。官方文档提供了一个教程来让我体验这种方式:https://nx.dev/getting-started/react-tutorial

这个教程以开发一个带有后端服务器的 todo 应用的方式展示了 Nx 的 Integrated Repos,在跟着教程做完这个项目之后,我不得不感叹一句——这个模式真的很强大。

这个模式下,Nx 完全包办了开发流程,真正做到了开箱即用——不需要自己配置 Jest、Webpack、Rollup……Nx 通过一系列的插件来完成了开发流程上的工作,只靠输入命令就可以把前端网站、后台服务器、CLI、共享的 libs 等集成在一起。

这种方式非常适合公司里多人共同合作的项目,这样一来,所有人都可以专注于写业务代码,而开发流程只需要初期执行一条命令即可。

不过,“开箱即用”同时也代表着“不够灵活”,就我来看,这个模式不太适合我。

不方便发布 npm 包

由于所有项目集成在一起,所以没法像 Lerna 那样,单独将 packages 下的某一个包发布到 npm 里。使用了 Integrated Repos 之后,整个项目只会在根目录下有一个 package.json,没法单独将某个 package 分享出来。

对编辑器不够友好

npm 和 yarn 为了方便 Package-Based Repos 这种形式,原生支持了 workspace,例如 npm workspace。主流的代码编辑器一般原生就支持对这种形式下 package 的互相引用,比如我用的是 Webstorm,当我在一个 package 里引用另一个 package 时,Webstorm 能分析出来另一个 package 的代码。

但当我使用 Integrated Repos 的时候就不行了,这种形式已经脱离了 npm workspace 的形式,是 Nx 自己独有的开发形式,一旦我引用了另一个 package 里的代码,Webstorm 就会报错,说找不到名为 @myworkspace/xxx 的模块。

虽然有 Webstorm 插件可以提供对 Nx workspace 的支持,但这些 Webstorm 插件不是官方开发的,这意味着可能不会跟进 Nx 的最新功能、积极修复 bug 等。

另外,插件的形式还是比不上编辑器原生支持,以前我在使用 Vue 的 VSCode 插件时就遇到过很多次 Vue 一升级版本,插件就失效的问题。

太过依赖插件

由于 Nx 几乎完全用插件包办了开发流程,这就会出现一些问题:

有一定的学习和排查问题的成本

需要熟读 Nx 文档以及每个用到的插件的使用说明。如果出现了开发流程上的问题,还需要花时间判断到底是 Nx 的插件的问题还是底层的工具(比如 Webpack)的问题。

总结

在我看来,如果一个项目:

那么就非常适合尝试一下 Nx 的 Integrated Repos。

但对于我个人而言:

我还是老老实实用 Package-Based Repos 吧。

“追新” vs “保守”

最后说一点题外话。

初入职场时,我很喜欢“追新”。将 npm 包都升到最新版本、使用市面上新出的工具来开发项目……但是,“追新”的过程是比较坎坷的,要面对各种问题,而有些问题很有可能还没被解决。

到了现在,我的选择会更保守一些。我逐渐发现我应该专注于把业务代码写完、保持代码的稳定性,而不是在“追新”的过程中不断花时间在解决新的工具问题上。

我并不是不去“追新”了,而是不会像以前那样不顾一切的就选择“追新”了。