Fresh大火!下一代 Web 全栈框架!

家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!


高级前端‬进阶

前言

Fresh 是面向 JavaScript 和 TypeScript 开发人员的全栈现代 Web 框架,旨在提供创建高质量、高性能、个性化 Web 应用程序的新方式。 开发者可以使用 Fresh 来创建主页、博客、大型 Web 应用程序(如 GitHub 或 Twitter)等等。

Fresh 的核心是路由框架和模板引擎的组合,可在服务器上按需渲染页面。 除了服务器上的即时 (JIT) 渲染之外,Fresh 还提供了一个接口,用于在客户端无缝渲染某些组件,以实现最大程度的可交互性。 Fresh 框架使用 Preact 和 JSX 在服务器和客户端上进行渲染和模板化。Fresh 底层基于 Preact、并使用基于孤岛架构的客户端水合作用。

同时,Fresh 没有任何构建步骤,开发者的代码可直接在服务端、客户端运行。 TypeScript 或 JSX 到纯 JavaScript 的任何必要转换都是在需要时即时完成的。从而极大的加快迭代、部署效率。开发者可以借助于 deno 手动将新项目部署到任何平台,但是为了最佳体验建议部署在类似 Deno Deploy 等边缘运行时。

目前 Fresh 在 Github 上有 10.2k 的 star,400+的 fork、超过 120+的开发者贡献代码。因此,这篇文章将详细介绍 Fresh 提供的功能。

1.什么是 Deno

Deno(/diːnoʊ/,发音为 dee-no)是一个安全的 JavaScript、TypeScript 和 WebAssembly 运行时,同时具有出色的开发人员体验。 它建立在 V8(谷歌的 JavaScript 运行时引擎)、Rust 和 Tokio 之上。Deno 构建于以下几个核心能力:

下表从语言支持、包管理、安全&权限、代码集成、机器执行等诸多维度展示了 Node.js 和 Deno 的主要区别:

Deno 提供了以下核心特性:

2.什么是 Fresh?

Fresh 建立在 Deno 之上,开发者使用 TypeScript 编写应用程序。 Fresh 自称是用于服务器端渲染的下一代全栈 Web 框架,它类似于其他全栈 Web 框架,如: Django、Ruby on Rails、Symfony 或 Larvel 等等。

从本质上讲,Fresh 是一个路由框架,它使用 Preact(一种轻量级的 React 替代方案)作为模板引擎。 模板引擎使开发者能够在应用程序中使用静态模板文件。 Fresh 负责将模板中的变量替换为实际值,并将模板转换为发送给客户端的 HTML 文件。

深入了解 Fresh 旨在解决的问题之前,大家一起先看看 Deno 博客中的几段话:

1. 客户端渲染很昂贵, React等框架通常会在每次请求时向用户发送数百 KB 的客户端 JavaScript。 这些 JS 包通常只是渲染静态内容,但这些静态内容也可以作为纯 HTML 提供。

2. 一些框架也支持服务器端渲染, 这有助于通过在服务器上预渲染来减少页面加载时间。 但是大多数当前实现仍然将完整的应用程序渲染结构发送给客户端,以便页面可以在客户端上完全重新渲染。

3. 这是一个糟糕的体验,客户端 JavaScript 非常昂贵,它会显著降低用户体验,大大增加移动设备的功耗,而且通常不是很健壮。

那么 Fresh 与 Next.js 或 Remix 等其他 JavaScript 框架的工作方式究竟有何不同?以 Next.js 为例, 它预渲染每个页面,本质上意味着它提前为页面生成 HTML,而不是让客户端去做。 这会带来更好的性能和 SEO,因为机器人能够更有效地“抓取”站点内容。 当一个页面被浏览器加载时, JavaScript 代码就会运行,并通过一个称为 补水(Hydration )的过程使页面完全交互。

Fresh 与 Next.js 类似,无需将 JavaScript 代码发送到浏览器,而是在服务器上将所有内容渲染为静态 HTML。但是,网站需要交互性,而仅静态 HTML 并不能解决交互问题, 这就是孤岛架构的用武之地。

Fresh 有一个 islands 目录,其中包含所有交互式组件,这些组件需要将 JavaScript 发送到浏览器, 而非 islands 目录的所有其他组件将渲染为静态 HTML。 这就是 Fresh 采用的部分水化(Partial Hydration)机制。

3.Fresh 特点

与所有其他 JavaScript 框架一样,Fresh 为开发者提供了很多优秀的功能。接下来一起看看这些功能是什么,以及它们的作用。

3.1 边缘即时渲染

Fresh 在服务器上将所有内容渲染为静态 HTML。 最重要的是,当开发者在 Fresh 中创建 API 路由时,它基于 Fetch API 接口,允许将其部署到无服务器边缘函数(Serverless Edge Functions ),例如 Deno Deploy。

3.2 基于孤岛架构的客户水合

本质上,基于孤岛架构的客户端水合适用于应用程序的一小部分内容,该部分需要 JavaScript 才能进行交互。 例如,在 Fresh 主页底部有一个计数器,它可以被水合以提供更好的交互性。

下图比较了孤岛架构、 SSR 、渐进式水合的不同。 其中 Marko、Astro 、Qwik 、Fresh 等框架都是采用这种孤岛架构进行服务器端渲染。

3.3 零运行时开销

这个功能源自之前谈到的基于岛屿的客户端水合作用。 默认情况下,在应用程序中,Fresh 不会向浏览器发送 JavaScript, 只是发送一个静态的 HTML 文件。

3.4 零构建

虽然 Fresh 旨在部署到 Deno Deploy,但实际上它可以部署到任何运行基于 Deno 的 Web 服务器的系统或平台。 下面示例表示将 Fresh 部署到运行 Docker 容器的平台。

为 Docker 打包 Fresh 应用程序时,务必在容器中设置 DENO_DEPLOYMENT_ID 环境变量。 此变量需要设置为一个不透明的字符串 ID,代表当前正在运行的应用程序的版本。 版本可以是 Git 提交的哈希,或项目中所有文件的哈希。比如下面的 Dockerfile 文件内容:

在 Git 存储库中构建 Docker 映像:

$ docker build --build-arg GIT_REVISION=$(git rev-parse HEAD) -t my-fresh-app .

然后运行 Docker 容器:

$ docker run -t -i -p 80:8000 my-fresh-app

3.5 无需配置

开发者无需真正配置任何内容即可开始使用 Fresh 开发应用程序, 只需使用 CLI 即可立即开始!

3.6 开箱即用的 TypeScript 支持

开发者不需要像在 Node.js 中那样在 Fresh 中单独配置 TypeScript, 这与 Deno 本身开箱即用的支持 TypeScript 类似 。

4.Fresh 示例

4.1 实例化项目

Fresh 需要 Deno CLI 1.25.0 或更高版本,可以通过下面命令安装或更新。

deno run -A -r https://fresh.deno.dev my-project

进入新建的项目目录,运行如下命令启动开发服务器:

deno task start

现在可以在浏览器中打开 http://localhost:8000 来查看该页面。

4.2 Fresh 组件拆分

Fresh 框架将构成页面的各种组件,分为 route 和 island 两类,约定存放在 routes/ 和 islands/ 两个目录,Fresh 处理这两类组件的方式完全不同:

这两类组件便是 Fresh 框架对孤岛架构(Islands Architecture) 的实现。在这个架构中,Routes 负责静态内容,无需交互,而 Islands 通过 JS 来提升页面交互性。Islands 之间相互独立,一个崩溃不会影响另一个,同时 hydrate 也保存独立,hydrate 完成后即可立即响应用户的交互(无任务阻塞情况下)。

Route 和 Island 这两种组件本质上都是 Preact 组件。Island 比 Route 更正常一些,和常规的参与 SSR 的组件没太大区别,任何需要在客户端执行 JS 的区块,都必须抽成一个 Island Component 独立出去。而 Route 更像是被 Fresh 当做模板引擎使用使用。

下面是官方 Fresh 的一个简单示例:

// routes/index.tsx
// Route组件
import Counter from '../islands/Counter.tsx';
export default function Home() {
  return (
    
      

Welcome to Fresh. Try to update this message in the ./routes/index.tsx file, and refresh.

); }
// islands/Counter.tsx
// islands组件
import { useState } from 'preact/hooks';
import { IS_BROWSER } from '$fresh/runtime.ts';

interface CounterProps {
  start: number;
}

export default function Counter(props: CounterProps) {
  const [count, setCount] = useState(props.start);
  return (
    
      

{count}

{/* disabled 具有交互性 */} ); }大家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

运行效果如下:

可以看到,客户端加载的 JS 代码很少:

如果开发者希望添加更多的可交互组件,与 island-counter.js 一样,需要独立为一个个互不影响的 island 组件。

需要注意的是:Fresh 内部强依赖 Preact,通过 Preact 将所有组件渲染为 HTML,给 Islands 打好标记。同时 JS 的依赖收集根据约定的目录控制好范围。在客户端,使用少量运行时和 Preact,完成 hydrate。

5.本文总结

除了官方宣传的几个特点之外,Fresh 框架还有几个特点值得关注:

当然了,Fresh 目前还不是很成熟,如静态文件处理、Debug、Hot Reload、第三方生态等方面都还很单薄,但这并不影响学习了解它的设计思路和架构。

因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!


参考资料

https://dev.to/harshhhdev/fresh-the-next-gen-javascript-web-framework-b39

https://keenwon.com/fresh-introduction/

https://keenwon.com/better-react-ssr/

https://morioh.com/p/a1eebaad1760

https://fresh.deno.dev/

https://fresh.deno.dev/docs/concepts/deployment

https://blog.openreplay.com/an-introduction-to-fresh/

https://morioh.com/p/a1eebaad1760

展开阅读全文

页面更新:2024-03-15

标签:框架   水合   孤岛   大火   开发者   静态   应用程序   架构   组件   客户端   代码

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top