值得一提的是,本篇文章是对 ROBIN WIERUCH 发表的《 10 Web Development Trends in 2023 》的文章的翻译,但是对部分内容进行了补充和修改,不喜勿喷。关于文章内部提到的诸多概念和前沿技术以前也有单独文章介绍过,下面是部分文章的传送门:
话不多说,直接进入正题!
单页应用程序 (SPA) 及其各自的框架(例如: React.js、Vue.js、Svelte.js)已经经历了很长的发展周期。 然而,随着元框架的兴起,应用程序表现出从客户端(CSR)转向服务器端渲染(SSR)的明显趋势。 如今,在使用 JAVAScript 框架时,SSR 无处不在。
元框架(Meta-Framework)是指一种框架的框架,即在现有的框架之上构建的框架,它的主要作用是为了更好地组织和管理多个框架之间的关系,从而提高开发效率和代码复用率。
最流行的元框架 Next.js 位于 React.js 之上。 React 核心开发人员 Andrew Clark 称其为 2022 年“真正的 React 18 版本”,其具备 React 提供的所有功能,例如: Suspense、流式 SSR。 目前,Vercel(Next.js 背后的公司)和 React.js 核心团队正在密切合作,提供出色的开发人员体验。
尽管许多开发人员以担忧的姿态时刻关注 Next.js 和 React.js 之间的密切关系,但 React.js 还有其他替代方案,例如: Remix(最近被 Shopify 收购)。 Remix 采用了不同的方法将 React.js 转变为元框架,例如:使用 Web 标准作为一等公民。但由于 Next.js 和 Remix 之前存在竞争,两个框架之间也存在一些聚合功能(例如嵌套路由)。
尽管 Next.js 已经是现代 SSR 领域的有力竞争者,并且将许多前端开发人员自然地转变为全栈开发人员,但是很多其他框架也同样优秀,值得关注。比如:SvelteKit(基于 Svelte.js 构建)及其最近的 1.0 版本由 Vercel 和 SolidStart(基于 Solid.js 构建)支持,与 React.js 相比,其 DX 有很大的改进。
虽然过去十年(2010 - 2020)一直由单页应用程序(SPA)及客户端渲染(CSR)主导,从 Knockout.js 和 Ember.js 到 Angular.js、React.js 和 Vue.js,过去几年人们对使用元框架的服务器端渲染(SSR)越来越感兴趣。
从表面上看,这个循环似乎已然结束,因为之前很长一段时间(2005 - 2010 年)一直在多页面应用程序 (MPA) 中使用带有 JavaScript(例如 jQuery、MooTools、Dojo.js)的 SSR。 然而,虽然以前 Java(例如 JSP)或后来的 Ruby on RAIls 已用于 SSR,但这次有所不同,因为已然改为依赖 JavaScript。 几年来,Next.js 一直是这一趋势背后的驱动力,然而,SvelteKit 等其他元框架也正在迎头赶上。
SSG (Static Site Generation) 是指在应用编译构建时预先渲染页面,并生成静态的 html。把生成的 HTML 静态资源部署到服务器后,浏览器不仅首次能请求到带页面内容的 HTML ,而且不需要服务器实时渲染和响应,大大节约了服务器运维成本和资源。
SSR 长期以来一直在与静态站点生成 (SSG) 竞争性能,尽管这两种模式服务于完全不同的目的。 后一种模式用于静态内容(例如博客等网站),而前者用于动态内容(例如 Web 应用程序)。 如果在 seo 的视角来看,SSR 和 SSG 都有意义。 然而,由于需要高度动态的内容或具有身份验证的以用户为中心的内容,开发人员无法选择 SSG(部署前构建一次,因此是静态的),而必须在 SSR(根据服务器上的单个数据根据请求按需构建)之间做出选择 或 CSR(按需获取客户端上的个人数据)。
不过,CSR、SSR、SSG 并不是渲染技术的最新趋势。 虽然 SSR 和 SSG 几年前就开启了性能优化的趋势,但增量静态再生 (ISR) 和流式 SSR 等更细致的渲染技术开始活跃起来。 前者推进了 SSG,因为允许在每个页面的基础上静态重建网站(例如每 60 秒重建页面 X),而不是重建整个网站。 更进一步,按需 ISR(也称为按需重新验证)可用于通过应用程序公开的 API 触发重建(例如,当 CMS 数据更新时)。
ISR(Incremental Static Regeneration)即增量式静态再生,是一种用于生成静态网页的技术。它在现代静态网站生成器和框架中得到广泛应用,旨在提高网站生成的效率和性能,同时解决 SSG 不适合高度动态内容的这个问题
另一方面,流式 SSR (Streaming Server-Side Rendering)优化了服务端渲染的单线程瓶颈。 普通 SSR 必须在服务器上等待数据才能将渲染的内容立即发送到客户端,而流式 SSR 允许开发人员将应用程序划分为多个块,这些块可以从服务器逐步并行发送到客户端。流式SSR 可以显著加快页面加载速度,提供更好的用户体验,并对搜索引擎优化产生积极影响。
在过去的几年里,SPA/MPA 中的 SSG 和 SSR 渲染模式非常简单。 然而,如今更微妙的版本正在流行。 但不仅 ISR 和 SSR 流变得更加相关,而且 Partial Hydration(例如 React Server Components)允许仅在客户端上对部分组件进行 Hydration,Progressive Hydration 可以对 Hydration 的顺序进行更细粒度的控制,Island 用于 MPA 中的独立应用程序或组件的架构(例如 Astro),以及使用可恢复性而不是水化(例如带有 Qwik City 元框架的 Qwik)如今正在成为有效的方法。
SSR 和 SSG 等渲染技术与边缘无服务器趋势高度相关,因为两者都是由性能驱动的,目标是在浏览器中提供无缝的用户体验。 从本质上讲,为用户提供更快的网站和 Web 应用程序服务的渴望激发了人们对边缘无服务器的兴趣。
无服务器(Serverless),也称为无服务器函数、无服务器计算(例如 AWS Lambda)或云函数(例如 google/Firebase Cloud Functions),多年来一直是云计算的大趋势。 虽然无服务器仍然意味着拥有正在运行的(远程)服务器,但开发人员不必管理服务器及其相关任务(例如基础设施按需扩展)。 相反,开发者必须将单个功能部署为无服务器功能,由云提供商负责。
无服务器功能释放了另一个优势,因为不必将应用程序服务器部署到一个(或几个)数据中心,而是可以在世界各地有数十个数据中心。 因此,在完美的世界中,无服务器功能将尽可能靠近用户运行,因为这意味着最短的客户端-服务器往返行程,从而改善用户体验。 将无服务器功能部署得尽可能靠近用户,创造了术语“边缘计算”和“边缘功能”。
许多云提供商(例如 Cloudflare 和 Cloudflare Workers、Vercel 和 Edge.NETwork、Deno 和 Deno Deploy)都在这个领域展开竞争,每个人都在优化最终用户的最佳交互时间 (TTI) 体验。 边缘功能不仅可以更快地提供 SSG/SSR 内容(因为到最终用户的线路更短),而且还可以将其结果缓存到离用户更近的地方。
但不仅性能很重要,即使它是主要驱动因素,边缘计算也会带来其他好处,比如降低成本。 例如,通常并非客户端和服务器(此处为边缘函数)之间发送的所有数据都需要由主数据中心计算。 在物联网中,有大量不相关的数据(例如每帧没有变化的视频记录)发送到主数据中心,这些数据可以简单地在边缘进行过滤。 毕竟,边缘函数只是开始。
随着无服务器(边缘)的出现,数据库也经历了复兴。 使用无服务器函数时,开发人员很快就会遇到打开过多数据库连接的问题,因为没有一台服务器保持一个连接打开,而是有许多无服务器函数与数据库建立了 1:1 连接。 连接池已成为此问题的解决方案,但要么必须自己处理,要么让第三方服务来处理。
无服务器数据库领域的热门竞争者是 PlanetScale (MySQL)、Neon (PostgreSQL) 和 Xata (PostgreSQL),它们具有许多功能,例如数据库分支、模式比较和强大的搜索/分析/见解。 当谈到世界各地的无服务器时,其都提供边缘缓存或分布式只读数据库,使数据更接近用户,以最小化延迟。
如果第三方服务不仅要分发数据库,还要分发应用程序,那么 Fly.io 会将所有内容打包到一个平台中。 这让我们不仅仅局限于数据库,数据库中也发生了很多变化。 Railway 被视为 Heroku 的继任者,它提供了平台即服务 (PaaS) 部署技术堆栈所需的一切。 如果想在服务链上向后端即服务 (BaaS) 迈进一步,可以使用 Supabase 获得 Firebase 的开源替代方案,它附带应用程序/数据库托管、身份验证和边缘功能。
JavaScript Runtime 始于 Ryan Dahl 在 2009 年的一次会议上宣布 Node.js。最初是一项将 JavaScript 与浏览器解耦并使其可在服务器上使用的实验,后来成为过去十年 JavaScript 成功故事的最大推动力之一。 本质上,Ryan Dahl 在 Node.js 中使用了名为 V8(由 Chrome 实现)的 JavaScript 引擎,而无需浏览器本身。 因此,Chrome 浏览器和 Node.js 使用相同的 JavaScript 引擎,但有自己的 JavaScript 运行时(例如浏览器 API 与 Node API)与之交互。
十年后,Ryan Dahl 宣布 Deno 作为 Node 的继任者,承诺为开发人员提供一个更安全、更快速的环境,其中包含类似浏览器 API、TypeScript 和开箱即用的标准库。 Deno 也运行在 V8 上,但它只是目前众多 JavaScript 运行时之一。
在边缘功能的竞争领域,许多云提供商实现了自己的 JavaScript 运行时(例如 Cloudflare Workers),该运行时针对自己的基础设施(例如 Cloudflare)进行了大量优化。 因此,Deno 的业务模型也正在通过 Deno Deploy 及其名为 Deno Fresh 的边缘渲染 SSR 框架(最初作为概念验证)成为云提供商。 像 Bun 这样的云提供商独立解决方案已然成为最近最快 JavaScript 运行时竞赛中的另一个热门产品。
curl -fsSL https://bun.sh/install | bash
开发者看到由于运行时不同而导致 JavaScript 领域存在大量碎片。 如果事情变得混乱,开发者最终会遇到与多年来浏览器中碎片化的 JavaScript 支持相同的情况,但这次在服务器上,当部署在不同的云提供商上时,并非所有 JavaScript 都可以在运行时之间得到平等的支持。 因此,所有利益相关者(例如 Deno、Vercel、Cloudflare)都加入了 WinterCG,就其 JavaScript 运行时之间的 API 互操作性进行协作。
过去,monorepos 主要用于大型应用程序,其中一个项目在一个版本控制存储库中包含较小的项目。 这些较小的项目中的每一个都可以是从单个应用程序(例如 SPA、MPA)到可重用包(例如功能、组件、服务)的任何内容。 组合项目的做法可以追溯到 2000 年初,当时称为共享代码库。
monorepo 是一个版本控制的代码存储库,包含许多项目。虽然这些项目可能是相关的,但它们在逻辑上通常是独立的,并由不同的团队运行。Monorepos 可以达到巨大的尺寸。例如,谷歌理论上拥有有史以来最大的代码存储库,每天有数十个提交,超过80 TB,其他使用 Monorepos 的公司还有微软、Facebook和Twitter。
然而,如今,monorepos 不仅适用于大型应用程序,而且也适用于小公司和开源项目。 例如,公司可以在单一存储库中拥有各种包,包括共享 UI 组件、共享设计系统(例如可重用协作设计)以及各自领域的常用实用程序功能。
这些包可以导入到各种应用程序中:使用所有这些共享包的实际应用程序(例如具有客户端渲染的 App.mywebsite.com)、主页/产品/登陆页面(例如具有服务器端渲染的 mywebsite.com) 或静态站点生成)考虑到 SEO 仅使用共享设计系统包,以及使用共享 UI 组件和共享设计系统包的技术文档页面(例如 docs.mywebsite.com)。
Turborepo 被 Vercel 收购再次引发了 JavaScript/TypeScript 中的 monorepo 炒作。 Turborepo 允许团队为 monorepo 中的所有应用程序和包创建构建管道,包括在本地计算机上的管道内或跨团队的云中缓存构建。 Turborepo 与其他重要的 monorepo 工具(例如 npm/yarn/pnpm 工作区(依赖管理)和变更集(版本控制))相结合,使该工具链成为今年值得关注的领域。
Turborepo 的竞争对手有 Nx、Rush 和 Lerna(有一段时间没有维护,后来被 Nx 的公司 Nrwl 收购)。
Tailwind CSS 是实用优先 CSS 的典型代表。 虽然一方面开发人员讨厌它在 UI 代码中显得冗长,但另一方面开发人员却喜欢它出色的 DX。 作为开发人员,可以在项目中配置一次,并立即在 HTML 中使用其预定义的 CSS。
不过,随着最近服务器端渲染 (SSR) 的兴起,这种对实用性优先 CSS 的情况有所改变。 几年来,CSS-in-JS 解决方案(例如 Styled Components (SC) 和 Emotion)已成为现代基于组件的 Web 应用程序样式设计的主流力量。 然而,如果 SSR 领域的性能是主要目标之一,那么 CSS-in-JS 会带来负面影响:包大小增加(SC 为 12.7kB,Emotion 为 7.9kB),更重要的是由于 CSS 序列化之前的运行时开销 将其插入到 DOM 中。比如下面的 JSS 的代码示例:
import React from 'react'
import {render} from 'react-dom'
import {createUseStyles} from 'react-jss'
// Create your Styles. Remember, since React-JSS uses the default preset,
// most plugins are available without further configuration needed.
const useStyles = createUseStyles({
myButton: {
color: 'green',
margin: {
// jss-expand gives more readable syntax
top: 5, // jss-default-unit makes this 5px
right: 0,
bottom: 0,
left: '1rem'
},
'& span': {
// jss-nested applies this to a child span
fontWeight: 'bold' // jss-camel-case turns this into 'font-weight'
}
},
myLabel: {
fontStyle: 'italic'
}
})
const Button = ({children}) => {
const classes = useStyles()
return (
<button className={classes.myButton}>
<span className={classes.myLabel}>{children}</span>
</button>
)
}
const App = () => <Button>Submit</Button>
render(<App />, document.getElementById('root'))
因此,可能会看到开发人员迁移到 SSR 友好的解决方案,例如:实用程序优先的 CSS(例如 Tailwind CSS、UnoCSS)与预定义的 UI 组件(例如 DaisyUI)搭配使用,其他同样流行的替代方案(例如 CSS 模块)或被称为零运行时的失败者 /compile-time CSS-in-JS(例如 vanilla-extract、linaria、astroturf、已编译)。
从 JavaScript 到 TypeScript 的演变是不可阻挡的。 在这次 Web 开发的大迁移中,全栈应用程序的 E2E 类型安全无疑是一个重要趋势。 此概念的实现取决于通信层 (API),通信层需要将类型实体(例如 User 类型、BlogPost 类型)从服务器桥接到客户端应用程序。
在 Web 开发中,客户端-服务器通信的常见方式是 REST 和 GraphQL。 两者都可以与 OpenAPI for REST 和 GraphQL Code Generator for GraphQL 一起使用,为前端应用程序生成类型化架构文件。
然而,类型安全 API 有一个新的后起之秀,称为 tRPC,它可以用作 REST/GraphQL 的替代品。 如果您正在使用前端和后端共享代码的 TypeScript monorepo,则 tRPC 能够将所有类型从后端导出到前端应用程序,而无需中间生成类型化模式。
// trpc.ts
import { initTRPC } from '@trpc/server';
/**
* Initialization of tRPC backend
* Should be done only once per backend!
*/
const t = initTRPC.create();
/**
* Export reusable router and procedure helpers
* that can be used throughout the router
*/
export const router = t.router;
export const publicProcedure = t.procedure;
随后,前端只需使用类型化函数即可调用后端的 API,这些函数通过 HTTP 在底层进行连接,以实现实际的客户端-服务器通信。 总体趋势肯定会倾向于在全栈应用程序中使用更多类型安全的解决方案,例如 tRPC、Zod、Prisma 和 TanStack Router,它们都在应用程序边缘提供类型安全。
在 React 领域,create-react-app (CRA) 主导了几年。 这在当时是一场小小的革命,因为初学者获得了一个现成的 React 入门项目,而无需再使用 React 设置来配置自定义 Webpack。 然而,目前 Webpack 俨然已经过时了。
当谈到单页应用程序(SPA)时,Vite 是新的挑战者,因为它可以与所有流行的框架(例如 React.js)一起使用来创建入门项目。 它由 Vue.js 的创建者 Evan You 实现,将自己打造为下一代前端工具。 在底层,它从 esbuild 获得了强大的功能,与其他 JavaScript 打包器相比,esbuild 是用 Go 编写的,因此打包依赖项的速度比竞争对手(例如 Webpack)快 10-100 倍。
// npm 6.x
npm create vite@latest my-vue-app --template vue
// npm 7+, extra double-dash is needed:
npm create vite@latest my-vue-app -- --template vue
// yarn
yarn create vite my-vue-app --template vue
// pnpm
pnpm create vite my-vue-app --template vue
虽然 Vite 的生态系统因 Vitest(Jest 的测试替代品)等新增功能而蓬勃发展,但 Vercel 的 Turbopack 等其他竞争对手最近才出现。 Turbopack 被称为 Webpack 的继承者,因为它是由 Webpack 的创建者 Tobias Koppers 领导的。 由于 Next.js 仍然使用 Webpack 和 Turbopack 是同一家公司开发的,因此我们可以预期 Next.js 和 Turbopack 在未来可能会成为完美的搭配。
人工智能最终会取代开发人员的工作吗? 这个问题目前还没有答案,但是,人工智能驱动的开发将在 2022 年成为热门话题。随着 Github Copilot 的发布,开发人员能够在他们最喜欢的 IDE 中与人工智能程序员配对。 它就像编写代码(或编写说明您想要编码的内容的注释)一样简单,GitHub Copilot 将自动完成实现细节以使其最好地理解。
但它并不止于此:OpenAI 的 ChatGPT 是一种更通用的语言模型,它也负责编程任务。 虽然您可以询问 ChatGPT 自由形式的问题,但它也可以执行编码任务。 许多开发人员已经发现自己正在使用 ChatGPT 作为 StackOverflow 的替代品。
有一些值得注意的也需要提一下,比如:Tauri 作为由 JavaScript/CSS/HTML 实现的桌面应用程序的 Electron 的替代品,Playwright 作为 E2E 的 Cypress 的替代品 测试,Warp 和 Fig 作为下一代终端,CSS 容器查询作为响应式设计的 CSS 媒体查询替代方案, htmx 作为丰富的 HTML,用于创建无需 JavaScript 的交互式用户界面。
https://www.robinwieruch.de/web-development-trends/
https://www.atatus.com/blog/the-serverless/
https://dev.to/manak/the-javascript-engine-52h2
https://adminlte.io/blog/tailwind-css-admin-and-dashboard-templates/
https://thenewstack.io/how-typescript-helps-enterprise-developers/
https://blog.csdn.net/OpenTiny/article/details/128103976
https://vitejs.dev/guide/
https://www.bytenote.net/article/149064595879755777