Nextjs缺点

Next.js 的正反两面

Nextjs缺点

开发网站应该是一种自由的体验。

如果您使用高代码,则可以自由选择您想使用的任何框架。

内 Fathym 的可组合前端架构, 您可以使用任何 JavaScript 框架(甚至其他一些框架)来构建您网站的一个方面。然后,如果您愿意,可以使用不同的框架,或者高代码、低代码和无代码构建器的组合。

太棒了,对吧?正确的。

因此,本着传播可组合前端的精神——你可以使用它 Fathym 的新用户界面 — 我们来看看 Next.js 中的一个较新的框架。

Next.js 流行度

我们深入研究了 StackOverflow 的 2022 年开发者调查,其中他们将 最流行的框架。

虽然 Svelte 在 2021 年排名第一,但它已被 Phoenix Framework 超越,我们看到许多其他新人进入榜单,包括 Next.js。

令人惊讶的是,Next.js 是 2022 年用于前端开发的第五大流行框架,甚至超过了第六位的 React。所以,很明显人们很喜欢 Next 提供的东西。

Nextjs缺点

出于多种原因,框架的流行很重要。

首先,如果您和您的团队正在从事一个长期的大型项目,您需要确保您使用的框架在整个过程中都存在。想象一下,开始一个重要的网站构建,框架突然从地球上掉下来,那将是一场噩梦。

其次,这种流行性保证了更多的开发人员知道如何使用该特定框架。如果您的第一个开发人员离开了,您应该能够用另一个团队成员来填补他们的位置。或者,对于我们的模块化前端,您可能希望同一团队中的多个团队成员了解同一框架。他们可以合作并帮助彼此建立一些特别的东西。

如果您的公司扩张,您将能够找到使用该流行框架的新开发人员。

让我们看看它是什么,它做了什么以及 Next.js 的优点/缺点。

Next.js 是什么?

Next.js 由 Vercel 的 CEO Guillermo Rauch 于 2016 年开发,目前是 12.2 版本,于 2022 年 6 月下旬发布。而且 Next.js 实际上是在 Node.js 之上编写的,因此它需要你有 Node .js 与节点包管理器 (npm) 一起使用。

Next.js 的功能之一是它在服务器端和客户端的呈现方式,也称为“通用应用程序”。这对于它构建的单页应用程序 (SPA) 以及它如何帮助这些 SPA 在 SEO(搜索引擎优化)方面取得很大成功至关重要。

正如 SEO 专家 Barry Adams 解释的那样:

“当你在没有服务器端渲染的情况下使用 React 时会发生什么,爬虫会在第一页停止,因为它看不到任何要遵循的超链接。它将页面发送到索引器,然后它必须呈现页面并提取超链接,然后将其添加到爬虫的队列中。然后爬虫最终将爬取下一组页面,并再次停止,因为在 JavaScript 呈现之前所有链接都是不可见的。所以它必须等待索引器返回一组新的 URL 来抓取,”Adams 解释说 在一篇中篇文章中。

用最简单的术语来说:SEO 对于希望通过 Google 搜索发现网站的任何人来说都是至关重要的,而 Next.js 正是在这方面提供了巨大帮助。 SPA 非常棒,因为它们快速、灵活且适应性强。但是 SPA 的一个主要缺点是,因为它们大多是客户端呈现的,所以当 Google 的爬虫查找数据时,它们也无法找到任何数据,直到它们也呈现在服务器端。

Next.js 在客户端和服务器端都呈现:网站的部分或全部呈现在服务器端,因此 Google 的爬虫可以找到信息(URL、元标记和内容等),从而将其放入搜索结果中。

“服务器端渲染 (SSR) 是一种流行的技术,用于在服务器上渲染通常只有客户端的单页应用程序 (SPA),然后将完全渲染的页面发送到客户端,”如解释 geeksforgeeks.org。 .

为了帮助减少加载时间并将代码分解成更小的块,Next.js 确实为开发人员执行了自动代码拆分。

对于营销人员来说,改进后的 SEO 非常棒。对于企业主而言,得益于 Next.js 中的许多预制组件,可以加快网站和应用程序的上市时间。此外,由于 Next.js 有助于制作静态网站,因此提高了安全性;也没有与数据库或用户数据的连接。

Next.js 的优缺点

优点

  • 在加载时间方面表现出色
  • 加载时间有助于“延迟加载”和自动代码拆分
  • 对开发人员的大量支持
  • 出色的用户体验
  • 更快的上市时间

Next.js 的缺点是

  • 一些开发者觉得它太固执己见
  • 多个开发人员抱怨 Next.js 如何进行路由,其他人则支持它

结论

你试过 Next.js 吗?

嗯,你可以上 今天免费使用 Fathym 平台!

如果你有,也许你想评估 Next.js 以及其他框架,如 React、Angular 或 Svelte。

或者,使用 Next.js 为一条路线(可能是您的主页)构建一个应用程序,然后在旁边使用无代码工具为另一条路线(也许是博客)使用无代码工具?对于开发人员来说,选择是无限的,所以今天就选择你自己的旅程吧。

最初发表于 https://www.fathym.com .

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/23112/51510913

Next.js是一个用于生产环境的React 应用框架(官方介绍:The React Framework for Production),使用它可以快速上手开发 React 应用( enables you to build superfast and extremely user-friendly static websites,),而不需要花很多时间和精力去折腾各种开发工具。所谓的用于生产环境,是指功能和稳定性足够,有大量的实际应用案例。

在整理编辑大人给的《狼书(卷3):Node.js高级技术》修订版,给next.js一个明确观点:"整体来看,Next.js在Node.js Web开发领域是一个非常优秀的SSR框架,其众多优秀特性,外加Blitzjs这种周边生态,对于开箱即用的项目来说是极好的。从架构的角度,笔者以为Next.js是过度设计,从商业的角度,我认同Next.js的做法,易用性应该是开发领域最该重视的核心。"

之所以给出这样一个观点,是基于下面5个方面总结出来的。

  • next.js是什么?有哪些优点?为啥狼叔觉得它看起来像一个海王?

  • 对比cra,umi和next.js,它们之间的差异是什么?

  • next.js生态除了vercel,还有rust和blitzjs,你都了解吗?

  • 实现一个框架有哪4方面的思考?

  • 在服务端渲染领域,对比next.js和ykfe/ssr,有何异同?

内容有点多,大家需要有点耐心。

1、Next是什么?

针对上面的点评,还需要明确一下next.js的介绍要点,不冲突

  • 基于React,支持csr、ssr、isr、ssg等渲染或用于渲染的生成方式

  • 支持ssr,但只是next.js的一个场景而已

  • next.js是Node web领域优秀的ssr框架,这只是其一,其实2019年之后,next.js也开始支持serverless了

  • 搭配vercel部署,对serverless支持极好

  • 开箱即用,简单易用

下面看一下next的基本特性,如下。

简单汇总一下。

  • 基础页面,数据获取,布局,国际化等,都已经是前端领域最佳实践了,这点上umi和next几乎一模一样。各种优化手段,图片,字体,脚本等,基本上都是最潮最新的好东西。

  • 文件即路由,从ruby on rails开始,前端也借鉴了,umi大概也是借鉴了next的。ykfe/ssr也是借鉴了的。

  • 自动按页面拆分代码,其实是webpack做的事儿,NextJS 将每个页面单独打包,打开首页时会加载应用基础代码和首页代码,其它页面代码只会在打开时才去加载,这对于大型应用来说非常有用。

  • 静态页面导出,可以将整个 NextJS 应用导出为一个静态网站,完美的JamStack

  • CSS-in-JS,内置了 styled-jsx 方案,样式写法遵循标准,并且样式作用域局限于组件内部而不是全局,避免了组件之间样式互相影响。

在今天,习惯Umi类脚手架和react开发的人,基本上会认为这些是标配,事实上,我们是需要感谢next.js团队的开拓之功的。

1.1、易用极致

nextjs很明显选择易用性,像一个海王一样,太懂用户的心了。所以它也是for  企业,小客户和个人开发者的通用方案,从基础框架,到发布运维都帮你解决了,是极为方便的技术,以致于很多人都把它作为第一梯队的选择。

早期的next.js写法是非常简单的,就只有getInitialProps一个静态方法。

function Page(props) {
  return <div> {props.name} </div>
}

Page.getInitialProps = async (ctx) => {
  return Promise.resolve({
    name: 'Egg + React + SSR'
  })
}

export default Page

在egg-react-ssr技术调研期,我们分别看了next.js和easywebpack。

  • easywebpack在使用上,我不认可使用 egg 的worker来做。easy-team的方案本地开发采用了在Node中启动webpack编译bundle的方案,将服务端bundle打包在内存中,agent进程通过memory-fs提供的api来读取文件内容,并且通过worker与agent进程的通信,来让worker进程可以获取到文件的字符串内容。然后采用了Node的runInNewContext api,类似于eval的方式去执行js字符。

  • next.js写法上是完美的。将请求方法抽取成静态方法,可以复用。另外在服务端渲染,先执行请求方法,是最高效的方式,比Biglet用的对象方法好。

在打包构建方面,本项目本地开发采用的方案为直接将服务端bundle打包到本地硬盘,通过webpack --watch的方式,来实现更新,同时本地开发的时候每次加载之前清空require bundle的缓存保证刷新后server端的内容与client端一致。结合webpack-dev-server,上手难度低,实现代码更少。

为了适应更多的渲染细化场景,基于getInitialProps都能完成,但next又进行了拆分,让每个写法都有特定的应用场景。好处是用的人简单,缺点是增加学习成本。

Nextjs缺点

除了核心特性上,做了渲染场景的细化外,next还做了非常多的易用性上的小心思,大家讨论最多的,大概就是image了。下面是山月在知乎上写的关于next image的体验。

内置 Image Proxy,对图片进行转换、压缩,使得图片体积最小化。并配合图片懒加载与 srcset 一系列关于图片优化的小点子优化网络体验 Next 团队宣传地也颇为实在

> In order to use images on web pages in a performant way a lot of aspects have to be considered: size, weight, lazy loading, and modern image formats.

举一个栗子,如果你使用了一张 10000px x 10000px 的 PNG 图片,放到了 100px x 100px 的小方格里。那么 next.js 将会做以下操作优化性能。

  1. 内置 Proxy 服务把它压缩成 100px 与 200px 两张图,大幅度压缩体积

  2. 内置 Proxy 服务把它转成 webp,一个体积更小的图片格式 (比 jpg 小 30% 的体积)

  1. 内置 Proxy 服务把它转成 75% 压缩质量的 webp,一个更小的体积与几乎无肉眼可见的图片质量变化

  2. 懒加载,看不到图片不加载

  1. 按需加载 (不像 Gatsby 那样需要在部署项目前耗费大量精力去压缩图片)

  2. 由于内置 Proxy 运行时处理,可支持非本域名上的图片处理

优点说完了,这里说一下它的缺点吧

  1. 无法利用 Long Term Cache,浏览器二次加载时图片速度慢,使 CDN 也无法性能最大化

  2. 小图片无法内置为 Data URI,大量的小图片将造成多次 HTTP 请求影响性能,比如我的这个网站: 开发者武器库

  1. 无法支持多分辨率屏幕

  2. CPU,如果部署在 Vercel 可以利用它的服务器资源做缓存服务,如果自部署处理图片需要消耗 CPU。但这个也不算很缺点,只是引入了复杂状态,国内可以利用 Ali_OSS 或公司共有 Image Proxy 做图片缓存服务 自定义一个 loader,详见文档 https://nextjs.org/docs/api-reference/next/image#loader

  1. 还有一个算不上缺点的具有迷惑性的点:虽然响应的后缀名是 png,但是返回的 MIME 是 image/webp

感谢山月的分享内容。

avif是下一代图片 image编解码格式,AVIF由开源组织AOMedia开发,Netflix、Google与Apple均是该组织的成员。看到没,几个大佬都在,因此是一统天下的图片格式。AVIF是基于AV1的新图像格式,使用HEIF作为容器(和Apple的HEVC一样)和AV1帧,压缩质量还真是叹为观止,而且还支持JS解析。在Next 12版本里,增加了对avif的支持,是不是做的极为贴心?像不像讨好开发者的海王?哈哈哈。

1.2、生态体系

justjavac说next和vercel不能分开看,这个观点我是认同的。从文档里就可以看出来,结合vercel亲爹的first-class支持,真的是用起来特别爽。

另外,关于for productin里也有很多优化。

Vercel的核心特性

  • 开发,基于next.js和serverless

  • 预览,基于serverless和cdn能力快速预览效果

  • 分发,真实发布

如果把nextjs和vercel整个链路放到一起看,你会发现,它整合的是开发和运维,让开发体验更流程,这部分内容在讲next.js的野心一节细讲。

1.3、重仓rust,改进开发体验

next12使用 swc 替换掉 babel和ts部分,性能得到非常大的提升。

> In early tests, previous code transformations using Babel dropped from ~500ms to ~10ms and code minification from Terser dropped from ~250ms to ~30ms using SWC. Overall, this resulted in twice as fast builds.

从这点上看,Rust作为构建高性能构建工具的语言,是极好的。今天,前端发展到了一个瓶颈,也忍受了很多,比如webpack构建,虽然前端也使用了很多优化手段,但js编写的,你只能利用巧妙的设计来优化,这不像rust/go这种系统级语言,天生的性能优势,于是有了swc和esbuild等编译工具,这对前端生态来说是极好的。

swc作者今年毕业,从deno转入职next的母公司vercel。parcel的一个核心维护者也加入了vercel,可谓兵强马壮。

> We're excited to announce DongYoon Kang, the creator of SWC, and Maia Teegarden, contributor to Parcel, have joined the Next.js team at Vercel to work on improving both next dev and next build performance. We will be sharing more results from our SWC adoption in the next release when it's made stable.

rust做一些基础模块改造是很好的,合理利用语言本身的优势。如果都用rust去做应用,把之前js写过的170万+模块都重写,想想都不现实,今天前端的瓶颈如果是编译速度,那就真的卷死了。

最近justjavac在postcss-rs,https://github.com/justjavac/postcss-rs 目前已经完成了 tokenizer 功能,性能极好,在单核 CPU 上,数据如下。

js:   0.11s user 0.02s system 126% cpu 0.102 total
rust: 0.00s user 0.00s system  66% cpu 0.006 total

# tokenize bootstrap-reboot.css               ~45x
js:   tokenizer/small(7K)                  3.063ms
rust: tokenizer/small(7K)                  0.068ms

# tokenize bootstrap.css                      ~26x
js:   tokenizer/fairly_large(201K)        25.672ms
rust: tokenizer/fairly_large(201K)         0.979ms

这性能也是没谁了,随随便便20倍以上的提升,做cpu密集型任务,rust真的有天然优势。

正是因为postcss-rs是rust写的,且性能很好,于是vercel的ceo就主动找justjavac,想收编。

综上所述,你看rust写编译器,运行时是js,这样才是最合理最高效的。一个商业公司,将开发体验作为目标,进一步拉拢开发者,是对商业和开发者都有利的事儿,必然会得道多助的。

1.4、渲染模式大而全

从服务端到浏览器,将ssr和csr整个过程梳理完,有5种。

我们现在所说的react ssr其实是第三者,基于hydration做的混合渲染。

Next.js项目组成员Parabola说的:Next不是 一个 SSR 框架。SSR 只是它的功能之一,它还支持 CSR、SSG、ISR 以及 API 路由(或是以任何方式组合在一起)。

starkwang在《新一代Web建站技术栈的演进:SSR、SSG、ISR、DPR都在做什么?》https://zhuanlan.zhihu.com/p/365113639,有更详细的描述。

先解释一下文章里用到的英文缩写:

  1. CSR:Client Side Rendering,客户端(通常是浏览器)渲染

  2. SSR:Server Side Rendering,服务端渲染

  1. SSG:Static Site Generation,静态网站生成

  2. ISR:Incremental Site Rendering,增量式的网站渲染

  1. DPR:Distributed Persistent Rendering,分布式的持续渲染

增量式更新(ISR)的概念,这个概念最早由 Next.js 在 9.5 版本中提出,既然全量预渲染整个网站是不现实的,那么我们可以做一个切分:

1、关键性的页面(如网站首页、热点数据等)预渲染为静态页面,缓存至 CDN,保证最佳的访问性能;

2、非关键性的页面(如流量很少的老旧内容)先响应 fallback 内容,然后浏览器渲染(CSR)为实际数据;同时对页面进行异步预渲染,之后缓存至 CDN,提升后续用户访问的性能。

页面的更新遵循 stale-while-revalidate 的逻辑,即始终返回 CDN 的缓存数据(无论是否过期);如果数据已经过期,那么触发异步的预渲染,异步更新 CDN 的缓存。

在 Next.js 中,你可以使用 getStaticPaths() 来定义哪些路径需要预渲染,通过 getStaticProps() 来获取预渲染需要的数据:

// 定义哪些页面需要预渲染
export async function getStaticPaths() {
  return {
    // 只有 /posts/1 和 /posts/2 会被预渲染
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
    // 其它页面,如 /posts/3,都会返回 fallback 页面,然后 CSR
    fallback: true,
  }
}

// 定义预渲染需要的数据
export async function getStaticProps({ params }) {
  // 拉取对应的文章内容
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  return {
    props: { post },
    revalidate: 60 // 数据有效期为 60 秒
  }
}

但 ISR 存在部分缺陷:

  1. 对于没有预渲染的页面,用户首次访问将会看到一个 fallback 页面,此时服务端才开始渲染页面,直到渲染完毕。这就导致用户体验上的不一致

  2. 对于已经被预渲染的页面,用户直接从 CDN 加载,但这些页面可能是已经过期的,甚至过期很久的,只有在用户刷新一次,第二次访问之后,才能看到新的数据。对于电商这样的场景而言,是不可接受的(比如商品已经卖完了,但用户看到的过期数据上显示还有)。

为了解决 ISR 的一系列问题,Netlify 在前段时间发起了一个新的提案:DPR,Distributed Persistent Rendering,感兴趣的自己去看.

感谢starkwang的分享。

这是csr和ssr中间折中灯下黑之地,属于优化范围内的,它很实用,但也有后遗症,一旦加了isr,在api层面必然会增加更多写法和兼容,比如引入getStaticPaths,getStaticProps,我不认为这是明智之举。

从用户角度讲,当然是直接用最好,从这个角度看,next做好社区需求,这是非常好的。但从框架定位上来看,克制一点,遵循KISS原因会更好。这种纠结,大概只有我愿意讲,其实商业公司本质上是逐利,在服务好客户的前提下做技术,这就好比大公司在kpi体系下做开源是一样的。next是一门解决用户问题的不可多得的好技术框架。这就够了。大家都不容易,next团队是真心热爱技术的,像我这样鸡蛋里挑骨头的不多。

1.5、blitzjs

blitzjs其实就是在Next.js之上加入访问数据库的能力(Everything End-to-End From the Database to the Frontend),最终形成类似Ruby on Rails的一栈式开发框架。

官方简介

Blitz is a batteries-included framework that's inspired by Ruby on Rails, is built on Next.js, and features a "Zero-API" data layer abstraction that eliminates the need for REST/GraphQL.

如果说,仅仅是加入了访问db的能力,从next选一个后端框架,加个orm就可以了。blitzjs是通prisma做到"Zero-API" Data Layer,在技术选型方面,可谓是很有想法的。

下面是一个简单的创建项目的代码,可谓干净,漂亮。

// app/pages/projects/new.tsx
import { Link, Routes, useRouter, useMutation, BlitzPage } from "blitz"
import Layout from "app/core/layouts/Layout"
// Notice how we import the server function directly
import createProject, {CreateProject} from "app/projects/mutations/createProject"
import { ProjectForm } from "app/projects/components/ProjectForm"

const NewProjectPage: BlitzPage = () => {
  const router = useRouter()
  const [createProjectMutation] = useMutation(createProject)

  return (
    <div>
      <h2>Create New Project</h2>

      <ProjectForm
        submitText="Create Project"
        schema={CreateProject}
        onSubmit={async (values) => {
          // This is equivalent to calling the server function directly
          const project = await createProjectMutation(values)
          // Notice the 'Routes' object Blitz provides for routing
          router.push(Routes.ProjectsPage({projectId: project.id}}))
        }}
      />
    </div>
  )
}

NewProjectPage.authenticate = true
NewProjectPage.getLayout = (page) => <Layout>{page}</Layout>

export default NewProjectPage

crud也特别干净

// app/projects/mutations/createProject.ts
import { resolver } from "blitz"
import db from "db"
import * as z from "zod"

// This provides runtime validation + type safety
export const CreateProject = z
  .object({
    name: z.string(),
  })

// resolver.pipe is a functional pipe
export default resolver.pipe(
  // Validate the input data
  resolver.zod(CreateProject),
  // Ensure user is logged in
  resolver.authorize(),
  // Perform business logic
  async (input) => {
    const project = await db.project.create({ data: input })
    return project
  }
)

另外,从项目,代码质量,社区活跃度上看,这都是一个非常优秀的项目。

我以为他最大的价值是为next.js构建了全栈领域的实践。

2、next.js的野心

我在知乎上回答了《2021前端会有什么新的变化?》,单篇39.8万的阅读量,还是不错的,这里再讲我对Node.js相关内容的看法。如果是今年选Node.js Web框架,大概只有Midway、Nest和next.js了

Node.js Web框架2021年8大类分析

这里讲next.js最有野心的原因,原因从2013年到2017年,前端快速发展,整体难度是变大了很多,从2018年之后,创新放缓,慢慢的大家都在做沉淀和降低成本的事儿。从cra和umi,固化webpack最佳实践,可以看出前端自身的简化方面做出的努力。next.js除了前端简化外,还在ssr等做了场景上的增强,打通从开发到部署的一站式开发,你只需要通过git提交代码,自动部署。站在前端和Node基础上,整合开发发布链路,它为未来端开发指明了发展方向,这是趋势领导者。

  • 定位开箱即用,满足绝大部分场景,我的就是最好的,你不需要定制,所以它说提供了能力,但你定制起来极难,只要上了贼船,基本上下不来。

  • 易用性做到极致,你想要的功能它都有,比如image,数据分析,动态分隔等,真的是不能再贴心了。这也是为啥我觉得它像海王的原因。这是好话,懂用户的技术产品才是好产品。

  • 特定场景没有深耕,无伤大雅。当然,易用性之外再提深度,容易挨打。

这就是典型的入口和平台思维。构建了核心能力,易用性上让你上瘾,即使现在贴钱做市场也是值得的。另外整合研发链路,简化流程,进一步锁客。我想,这才是next.js的真正的商业价值。

3、ssr降级问题

编写一套代码,可以在ssr崩溃是做兜底,就需要csr也可以支持。于是有了ssr可以无缝降级csr的特性。这是在真实大流量场景下,才需要考虑的事儿,之所以要做这个功能是真实需求里诞生的。

按照next.js的逻辑,它可以ssg,然后在网关层把ssr和csr做降级处理,理论上也可以实现,只是不那么优雅和丝滑,不符合它之前在易用性做的那么好的一贯认知。事实上,从getInitialProps上分裂那么多细分方法,就注定这条路被堵死了。大概这也是框架设计者的取舍吧。

要做到无缝降级,最需要处理的就是数据获取的问题,什么时候应该在哪个端去加载数据。这块的逻辑应该是在框架层去做的。Next.js 通过 next/router 的方式劫持开发者的 push/pop 操作,在其中做非常多黑盒复杂的逻辑,我认为这非常的不优雅。事实上,在我们的项目中我们仅编写了一个高阶组件来完成这个功能。

在写法上,可以支持csr和ssr,在构建上更加简单,结合我们在使用的egg.js,就诞生了egg-react-ssr。后面加了插件化和serverless,就有了ykfe/ssr。这里不展开讲,避免有蹭热度之嫌。

不过next已经不只是ssr框架,这方面做得不够完美,其实也还好。

4、对比三巨头:cra、umi和next

前端框架和基本探索稳定后,大家就开始想如何更好的用,更简单的用。各家大厂都在前端技术栈思考如何选型和降低成本,统一技术栈。

关于 Webpack 的封装实践有很多,比如知名的 af-webpack,ykit,easywebpack。

  • af-webpack 是支付宝定制的Webpack,把 webpack-dev-server 等Node.js模块直接打包进去,同时对配置做了更好的处理,以及插件化

  • ykit 是去哪儿开源的Webpack,内置 Connect 作为Web server,结合dev和hot中间件,对于多项目构建提效明显,对版本文件发布有不错的实践

  • easywebpack 也是插件化,但对解决方案,boilerplate 等做了非常多的集成,比如egg的ssr是有深入思考的,尽管不赞同这种做法。

在 create-react-app(cra)项目里使用的是 react-scripts 作为启动脚本,它和 egg-scripts 类似,也都是通过约定,隐藏具体实现细节,让开发者不需要关注构建。在未来,类似的封装还会有更多的封装,偏于应用层面。

umi是一个和cra类似的具有蚂蚁特色的脚手架,它借鉴了next.js和cra的优点,同时基于af-webpack,便于定制webpack配置,同时对antd经典ui库支持最好,使得umi在蚂蚁内部以及开源社区有相当大的用户量。umi同时支持csr和ssr,ssg等,功能还是非常强大的。

next.js早期和umi很像,但新版不断迭代,在易用性上做的非常好,外加vercel(以前的now.sh)搭配,真的是上手简单,发布更简单。

next.js的过度设计问题,我的思考如下。

  • cra、umi、next.js的调试问题,webpack配置封装在框架里,要么eject,要么自己扒源码,那个过程还是非常痛苦的。

  • 定制问题:next.js里按照它的方式做,是极好用的。可是想定制点啥,你发现很难实现。除了代码量很大外,很有可能牵一发而动全身

  • 黑盒:比如next/dynamic这种单独封装,其实就react-loadable,用的时候如果文档里没有,能找死。

  • 甜心:像内置的组件封住,是很好用的,比如image,但很明显这是前端react代码里要处理的,如果内置了,是有益处,但也会面临一个惯性,后面各种前端的优化是不是next都要集成,一旦集成就会有csr和ssr等场景兼容问题。类似于Next.js Analytics,这种统计类的功能,它很贴心,但从职责上看,放到框架是否合适,我理解这也是需要考虑的。

我说它是过度设计,是因为最初做某c端项目选型的时候认真的考虑过,但经过分析,它确实不适合我们的场景。如果大家在next.js自身推荐的场景外,想深度定制的话,必然会遇到上面的。

之所以说next是过度定制,是因为我想深度定制。其实,next本身是不建议深度定制的,它希望的是开箱即用,这样才是它推荐的使用方式。

5、我眼中好的框架设计

如果想要实现一个框架,在今天看起来,还是挺难的,如下图。

你需要考虑4个问题:

  • 解决的场景:csr还是ssr,还是都有?

  • 支持的前端框架:react or vue2 or vue3,还是像next一样只支持react

  • 构建:webpack和vite,你总要选一样,至于esbuld或swc是可选的,或者想next一样能用rust重写工具链

  • 服务端运行时:传统Node.js web应用or Node Faas,好像有一种不支持都不好意思说自己的框架还不错

如果以next.js为例,你会发现它除了vue,都内置了。易用性做到极致,打通开发和发布链路,构建已Rust为核心的开发体验,这才是真的现代。

如果不考虑易用性,我会说:“好的框架是克制的,unoption的,技术栈无关的”。如果站在易用性的角度上看,约定大于配置也许是更好的选择。

6、总结

通过上面的讲解,相信大家能够理解我说的:“从架构的角度,我以为Next.js是过度设计,从商业的角度,我认同Next.js的做法,易用性应该是开发领域最该重视的核心”。Next.js是一款优秀的更Modern的框架,值得大家学习和使用。

此时,我们再回头看上面提出的5个问题:

  • next.js是什么?有哪些优点?为啥狼叔觉得它看起来像一个海王?

    • 易用性极佳,对用户需求理解的极好

    • 重视开发和发布体验

    • 使用Rust解决开发体验

  • 对比cra,umi和next.js,它们之间的差异是什么?

    • cra是react开发简化的代表

    • umi借鉴了next和cra,同时对antd支持极好,国内最佳react脚手架

    • next不只是ssr框架,支持多种渲染模式,它的野心极大,想变成未来开发者的唯一入口

  • next.js生态除了vercel,还有rust和blitzjs,你都了解吗?

    • rust生态,提升开发体验,但仅限于工具链。js依然是应用层最受欢迎的语言

    • blitzjs是基于next,但加入了访问数据的能力,全栈型框架

  • 实现一个框架有哪4方面的思考?

    • 场景、前端框架选型、服务端运行时,构建

    • 好的框架是克制的,unoption的,技术栈无关的

    • 如果站在易用性的角度上看,约定大于配置也许是更好的选择

  • 在服务端渲染领域,对比next.js和ykfe/ssr,有何异同?

    • 易用性和通用性next更好,ssr细分领域专业程度ykfe/ssr更好,此处留在下一篇讲ykfe/ssr的时候在讲

你理解多少呢?


说明

- 引用了Starkwang、Parabola、山月的部分知乎内容,文中已标出

- 感谢justjavac(postcss-rs以及rust部分知道)、张宇昂(ykfe/ssr部分)纠错


更多内容,可以在前端3.0的知识星球里沟通。