全栈框架Remix热度爆表?v1.16版本发布,2.0版本准备就绪!

发表时间: 2023-05-17 06:09

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

高级前端‬进阶

今天给大家带来的主题是全栈框架 Remix,同时介绍了Remix v1.16的诸多新特性,话不多说,直接进入正题。

前言

如今,当想要基于 React 创建一个新的 Web 项目时,有许多不同的框架可以选择。 作为一名前端开发人员,您会发现自己很难知道应该选择哪一个框架,或者哪一个框架最适合你的开发需求。

最常用的框架之一是 Next.js,Netflix、Twitch 或 Uber 等公司都已经在生产项目中使用它, Next.js 被认为是增长最快的 React 框架之一。其他框架很难与 Next.js 媲美,因为它涵盖了三种不同的页面渲染策略,但自 2021 年 11 月以来,前端又多了一个全新的、强大的备选框架,称为 Remix。

随着 Remix v1.16 版本的发布,Remix 也成为越来越多 React 开发者的不二选择。

为何需要 Remix 而不是纯 React

React 可以制作单页应用程序 (SPA),其仅使用一个 HTML 文件来渲染所有网页,路由由客户端控制。

当客户端发出初始请求时,浏览器会立即收到一个包含所有应用程序的 HTML 页面,没有预渲染内容。当用户在应用导航时,JavaScript 仅替换那些与请求路由相关的组件和内容,但 HTML 文件内容保持不变。 简而言之,浏览器负责管理应加载哪个 JavaScript 文件以渲染当前页面,这就是客户端渲染 ,即 CSR。

客户端渲染,图片来自https://www.heavy.ai/

但是,CSR 也存在诸多限制:

  • Slow Initial Render:当用户第一次访问页面时,需要很长时间才能加载完成。 这意味着较长的空白页面,直到 JavaScript 加载并渲染所有内容。
  • SEO:因为初始时只有一个 HTML 页面,所以很难让搜索引擎对内容进行索引。
  • 缓存问题:HTML 结构无法缓存,因为它在第一次渲染时不可用。

由于 CSR 的三大核心问题,Next.js 和 Remix 出现了, Remix 可以在发送客户端请求之前在服务器端渲染内容,从而最大限度的缩短页面白屏时间。

什么是 Remix

Remix 是一个完整的堆栈 Web 框架,让开发者专注于用户界面并通过 Web 基础知识进行工作,以提供快速、流畅和有弹性的用户体验,该体验可以部署到任何 Node.js 服务器甚至非 Node.js 环境,比如: Cloudflare Workers 的边缘平台。

目前 Remix 在 Github 上有超过 23.4k 的 star、1.9k 的 fork、26.9k 的项目依赖量,代码贡献者 550+,是一个妥妥的前端开源明星项目。

Remix v1.16.0 新特性

Remix 团队目前正在全力为即将发布的 v2 版本做准备,而 Remix v1.16.0 稳定了一些 CSS 功能,对新 Remix 开发服务器的内部结构进行了重大变更,并修复了一堆错误。

CSS Modules/Vanilla Extract/CSS Side-Effect Imports

Remix 版本 v1.16.0 稳定了对 CSS module、Vanilla Extract 和 CSS 副作用导入的内置支持,以前只能通过未来标志(future.unstable_cssModules、future.unstable_vanillaExtract、future.unstable_cssSideEffectImports)获得这些特性。

PostCSS 支持

Remix v1.16.0 版通过 remix.config.js 中的新 postcss 选项稳定了内置的 PostCSS 支持。 因此,future.unstable_postcss 选项在该版本中也已被弃用。 postcss 选项默认为 false,但是当设置为 true 时,如果存在 postcss.config.js,将启用使用 PostCSS 处理所有 CSS 文件。

如果遵循 Remix 的原始 PostCSS 设置指南,开发者可能会有一个如下所示的文件夹结构,将源文件与其处理后的输出分开:

.├── app│   └── styles (processed files)│       ├── app.css│       └── routes│           └── index.css└── styles (source files)    ├── app.css    └── routes        └── index.css

启用新的 postcss 选项后,开发者可以从 app/styles 文件夹中删除已处理的文件,并将源文件从 styles 移动到 app/styles:

.├── app│   └── styles (source files)│       ├── app.css│       └── routes│           └── index.css

然后开发者应该从 .gitignore 文件中删除 app/styles, 因为它现在包含源文件而不是处理过的输出。

然后开发者可以更新 package.json 脚本以删除任何对 postcss 的使用,因为 Remix 会自动处理它。 例如,如果遵循了原始设置指南:

{  "scripts": {-    "dev:css": "postcss styles --base styles --dir app/styles -w",-    "build:css": "postcss styles --base styles --dir app/styles --env production",-    "dev": "concurrently \"npm run dev:css\" \"remix dev\""+    "dev": "remix dev"  }}

Tailwind

Remix v1.16 版通过 remix.config.js 中的新 tailwind 选项稳定了内置的 Tailwind 支持。 因此,future.unstable_tailwind 选项在该版本中也已被弃用。

默认情况下,tailwind 选项为 false,但设置为 true 时,如果安装了 tailwindcss,将在 CSS 文件中启用对 Tailwind 函数和指令的内置支持。

如果开发者遵循 Remix 的原始 Tailwind 设置指南并想要使用此功能,应该首先删除生成的 app/tailwind.css。然后,如果有 styles/tailwind.css 文件,则应将其移至 app/tailwind.css。

rm app/tailwind.cssmv styles/tailwind.css app/tailwind.css

否则,如果还没有 app/tailwind.css 文件,应该创建一个包含以下内容的文件:

@tailwind base;@tailwind components;@tailwind utilities;

然后,应该从 .gitignore 文件中删除 /app/tailwind.css,因为它现在包含源代码而不是处理后的输出。接着需要更新 package.json 脚本以删除任何对 tailwindcss 的使用,因为 Remix 会自动处理它。 例如,如果遵循了原始设置指南:

{  "scripts": {-    "build": "run-s \"build:*\"",+    "build": "remix build",-    "build:css": "npm run generate:css -- --minify",-    "build:remix": "remix build",-    "dev": "run-p \"dev:*\"",+    "dev": "remix dev",-    "dev:css": "npm run generate:css -- --watch",-    "dev:remix": "remix dev",-    "generate:css": "npx tailwindcss -o ./app/tailwind.css"  }}

开发服务器变更

Remix v1.16.0 版包含对新开发服务器的重大改进,可以通过 remix.config.js 中的 future.unstable_dev 标志启用。 Remix 开发服务器现在将应用程序服务器作为托管子进程启动。 这使开发环境尽可能接近生产环境,也意味着 Remix 开发服务器与任何应用程序服务器兼容。

默认情况下,开发服务器将使用 Remix App Server,但开发者可以通过 -c/--command 标志指定运行它的命令来选择使用自己的应用服务器:

remix dev// uses `remix-serve <serve build path>` as the app serverremix dev -c "node ./server.js"//  uses your custom app server at `./server.js`

开发服务器将做以下几个事情:

  • 强制 NODE_ENV=development ,如果之前被设置为其他内容则抛出警告
  • 每当 Remix 应用程序代码更改时重新打包的应用程序
  • 每当重新打包成功时重新启动应用程序服务器
  • 处理实时重新加载和 HMR + 热数据重新验证

应用服务器协调

为了管理应用服务器,开发服务器需要被告知应用服务器当前正在使用什么服务器版本。 这是通过让应用服务器发送“I'm ready!”来实现的,以 Remix 服务器构建哈希作为有效负载的消息。

这是在 Remix App Server 中自动处理的,并通过调用官方 Remix 模板中的 broadcastDevReady 或 logDevReady 自动设置。如果没有使用 Remix App Server,并且服务器没有调用 broadcastDevReady,需要在应用服务器启动并运行后调用它。

例如,在 Express 服务器中:

// server.js// <other imports>import { broadcastDevReady } from '@remix-run/node';// Remix 服务器构建目录的路径(默认为“build/”)const BUILD_DIR = path.join(process.cwd(), 'build');// <设置快速服务器的代码>app.listen(3000, () => {  const build = require(BUILD_DIR);  console.log('Ready: http://localhost:' + port);  // 在开发中,在服务器启动并运行后调用`broadcastDevReady`  if (process.env.NODE_ENV === 'development') {    broadcastDevReady(build);  }});

Cloudflare

对于 CF 工作程序和页面,需要使用 logDevReady 而不是 broadcastDevReady,因为实验性 CF 运行时不能很好地与 fetch 配合使用,而 fetch 是 broadcastDevReady 的实现方式。

选项优先级顺序为:1. flags,2. config,3. defaults。

--http-* 标志仅用于内部开发服务器与应用服务器双向通信,应用程序将在应用程序服务器的正常 URL 上运行。

要设置 unstable_dev 配置,请将 unstable_dev: true 替换为 unstable_dev: { }。 例如,要静态设置 HTTP(S) 端口:

// remix.config.jsmodule.exports = {  future: {    unstable_dev: {      httpPort: 8001,    },  },};

如果开发者需要对开发服务器的 scheme、主机、端口进行细粒度控制,则只需要使用 --http-* 标志和 --websocket-port 标志。Remix 不会为开发者设置 SSL 和自定义主机。

--http-scheme 和 --http-host 标志用于告诉 Remix 开发者是如何设置的。 如果需要这些功能,则需要自行设置 SSL 证书和主机文件。

如果开发者想自己管理服务器更改,可以使用 --no-restart 标志告诉开发服务器在构建成功时不要重启应用程序服务器:

remix dev -c "node ./server.js" --no-restart

开发者还可以清除应用服务器的 require 缓存以使其在获取服务器更改时保持运行。 如果需要类似功能,则应该观察服务器构建路径(默认情况下为 build/)的更改,并且仅在检测到更改时清除 require 缓存。

如果使用 --no-restart,开发者需要自行处理在应用服务器接收到服务器更改时调用 broadcastDevReady。比如下面的示例利用 chokidar 实现了这个功能:

// server.dev.jsconst BUILD_PATH = path.resolve(__dirname, 'build');const watcher = chokidar.watch(BUILD_PATH);watcher.on('all', () => {  // 1. 清除require缓存  purgeRequireCache();  // 2. 加载更新的服务器构建  const build = require(BUILD_PATH);  // 3. 告诉开发服务器这个应用服务器现在准备好了  broadcastDevReady(build);});

其他变更

  • feat:在所有适配器中支持异步 getLoadContext (#6170)
  • 在使用 CSS 模块、 Vanilla Extract 和 CSS 副作用导入时修复 CSS url() 规则中的绝对路径 (#5788)
  • 展开加载器返回类型时更好的类型区分(#5516)
  • 将 AppLoadContext 传递给 handleRequest (#5836)
  • 添加 @remix-run/node/install 副作用以允许 node --require @remix-run/node/install (#6132)
  • 由于错误而未渲染的路由短路链接和元数据 (#6107)
  • React Router 的更新 Remix 不再依赖于 useSyncExternalStore (#6121)
  • 如果路由仅导出边界,则修复误报资源路由标识 (#6125)
  • 将 React Router 依赖项更新为最新版本:react-router-dom@6.11.0,@remix-run/router@1.6.0

参考资料

https://github.com/remix-run/remix/releases/tag/remix%401.16.0

https://www.oschina.net/news/241208/remix-1-16-released

https://github.com/remix-run/remix

https://dev.to/joshhortt/the-future-of-web-development-is-the-remix-framework-leading-the-way-4fpa

封面图版权:Jose Horta Calvario的 《The Future of Web Development: Is the Remix Framework Leading the Way?》