如何评价 Next.js?

作者:你不知道我是谁
链接:https://www.zhihu.com/question/52365623/answer/2814907079
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

16年的问题了,在6年后的平安夜刷到了。

Next.js,是第二个让我由心觉得好用,觉得「我艹,可以啊」的一个框架。第一个是在2015年的时候,接触到的Angular 1.x.

我们公司,在去年11月,开始对前端重构优化,将公司的主要页面由 egg.js + requireJS + jQuery 切换至 Next.js,由我来owner,最多时投入9个前端人力,日常4个,立项时排期3个月,实际历时5个月。

有兴趣的朋友可以看下效果: www.tianyancha.com/company/33934422

先说下最初的选型过程,是怎么一步步走进Next.js这个坑的心路历程:

  • 首先是Vue React,这个没啥好选的,组内成员对这两个框架的熟悉程度都差不多,但是我相对更熟悉React,所以就没得选咯
  • web server,由于之前用的egg.js,大家对这一套比较熟悉,所以选择了egg的升级版,midway。(web server这一层不符合对前端架构的整体规划,后续也给干掉了)
  • SSR,由于要支持SEO,所以就要选择一个支持SSR的方案。 为了减少出错,和提升开发效率,我们希望SSR是渐进增强的,实际开发人员在开发时,完全不需要考虑SSR的存在,最后再有一到两个人力来集中管理SSR的配置。由此,我们有两个方案:
    • 增加一个pre-render层,该pre-render层就类似是puppeteer,NG判断是SEO的请求,就转到pre-render层,pre-render再请求实际的前端服务。为此我们主要尝试了两个框架做这个事情:
    • 常规的SSR。还是前面说的,期望的效果是,开发人员在一开始开发时,完全不需要考虑SSR,直到最后再由专人去配置SSR功能,SSR类似是一个装饰器或者说是插件的形式存在。为此,找到一个省心的方案是使用react-query。具体它的实现方案就不细说了,简单来说就是通过react-query对请求的缓存和预请求逻辑,来实现页面实际有价值的SSR。并且react-query在介绍SSR时,还特别讲了搭配Next.js使用。
  • 最后就是前端框架,
    • 一个就是create-react-app整一个,eject出webpack的配置改巴改巴
    • 另一个就是Next.js,没踩坑之前,看文档看到的肯定都是好的,其中有几个开箱即用的功能,对我们来说,的确很有诱惑:1. 路由功能,替换react-router 2. 基于getServerSideProps的SSR功能。 3. 集成好的打包配置和打包优化
  • 状态管理,在当时组内相对比较熟悉的有 redux-trunk、redux-saga、dva。 但是我个人是比较反感redux这一套,而且在梳理和规划了我们的业务逻辑之后,我觉得把数据分散在每个小的业务组件中是可行的,需要共享的数据并不多。所以我们就完全是有需要共享数据,就手动全局包一个Context,最后实际发现,的确也没包几个Context。

前面提到一个重要的思想,就是SSR一定是渐进增强的,从而一开始开工可以先不考虑这个,先抓紧快速开发。

同时为了不让build的问题占用我们的时间,以及为了预选的两种SSR方案以后都能支持,所以选择使用 react-query + Next.js

最终,我们开工时确认的基础选型为: React + midway + Next.js + 无全局的状态管理库 + react-query。

蹲坑把腿蹲麻了,有人看了后续在写吧。。。


气短,胸闷,不敢睡觉。。。一个人住,担心万一睡过去了都没人知道,唉。。。

再扯两句,

用Next时有一个感觉不爽的点是,它要求除_app.js以外,引入的样式都必须走css module,但是我们希望能用全局样式,好在我们还搞了自己的组件库,可以绕过这一限制。

另外还有两种方式绕过这个限制,一个是配置css moudle对类名的哈希算法,对于指定格式的类名直接原样返回。另一个是在css moudle里使用:global语法。这两种方式我感觉都太骚了,所以没有用。

在next.js中,通过使用react-query缓存请求来做SSR时,需要注意一点就是,可能会导致页面上有个_NEXT_DATA元素里的内容特别的大。这个元素里就是server端发起的所有请求的返回值。没有找到好的方式避免这个问题,我们目前是在代码里对所有请求又包了一层预处理,或者也可以理解成增加了一层 后端接口返回值 和 前端数据model 的转换,从而尽可能的减少_NEXT_DATA元素的体积。

另一个问题,就是自动化测试,这里最麻烦的是元素定位。最初配置css moudle后的类名是纯哈希,然后给元素增加额外的data-属性用于元素定位。但是由于测试脚本是qa组来写,配合起来很费劲很低效。所以后来索性也不加data-属性了,qa需要哪个就f12自己找类名,然后css moudle生成的类名也改回了默认的「文件_类名_哈希」的格式,让他们的代码看起来更语义化一点。

还有一个和build相关的问题。next.js的spa逻辑判断,依赖一个.json文件,这个文件的路径包含一个buidId,可通过next.config里的generateBuildId()修改这个buildId的生成逻辑。

会导致一个问题:假设我们有20台负载机器,有一个功能我为了灰度50%,所以只发布10台机器,此时就有10台新代码机器,和10台旧代码机器。假设此时一个页面的请求,经过负载均衡落在了新代码的机器上,页面返回,在浏览器加载后再次请求用于spa的.json文件,该json文件的请求落在了旧代码的机器上,因为buildId的不同,在旧代码机器上找不到这个json文件,于是返回404,从而导致该用户的spa功能失效。解决办法就是每次发版都全量发布,灰度逻辑完全由代码控制。

感觉新冠不仅影响心脏,还间接影响了脑子表达的表达能力,不知道啰嗦的这些有没有表达清楚,写到哪算哪吧。。

祝2023我身体健康。

posted on 2024-04-19 16:49  漫思  阅读(79)  评论(0编辑  收藏  举报

导航