Remix 集成 MUI

devtools/2024/10/18 5:44:59/

Remix 如何接入 MUI 组件库,MUI 官网提供了一个 Remix 接入 MUI 的例子,用的是老的 Remix版本,如何接入新的 Vite 版本呢?

由于 MUI 支持 SSR,只需要改造对应的 Client 和 Server 即可实现。安装 MUI 组件组件库,修改对应的 Client/Server 文件,代码如下:

安装 MUI

npm install @mui/material @emotion/react @emotion/styled @mui/icons-material

创建 MUI Provider

import { CacheProvider } from "@emotion/react";import { ThemeProvider } from "@mui/material";
import theme from "./theme";
import createCache from "@emotion/cache";function createEmotionCache() {return createCache({ key: "css" });
}export function MuiProvider({ children }: { children: React.ReactNode }) {const cache = createEmotionCache();return (<CacheProvider value={cache}><ThemeProvider theme={theme}>{children}</ThemeProvider></CacheProvider>);
}

修改 client、server

### entry.client.tsx
/*** By default, Remix will handle hydrating your app on the client for you.* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨* For more information, see https://remix.run/file-conventions/entry.client*/import { RemixBrowser } from "@remix-run/react";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import { MuiProvider } from "./mui/MuiProvider";startTransition(() => {hydrateRoot(document,<StrictMode><MuiProvider><RemixBrowser /></MuiProvider></StrictMode>);
});
### entry.server.tsx
/*** By default, Remix will handle generating the HTTP Response for you.* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨* For more information, see https://remix.run/file-conventions/entry.server*/import { PassThrough } from "node:stream";import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";
import { MuiProvider } from "./mui/MuiProvider";const ABORT_DELAY = 5_000;export default function handleRequest(request: Request,responseStatusCode: number,responseHeaders: Headers,remixContext: EntryContext,// This is ignored so we can keep it in the template for visibility.  Feel// free to delete this parameter in your app if you're not using it!// eslint-disable-next-line @typescript-eslint/no-unused-varsloadContext: AppLoadContext
) {return isbot(request.headers.get("user-agent") || "")? handleBotRequest(request,responseStatusCode,responseHeaders,remixContext): handleBrowserRequest(request,responseStatusCode,responseHeaders,remixContext);
}function handleBotRequest(request: Request,responseStatusCode: number,responseHeaders: Headers,remixContext: EntryContext
) {return new Promise((resolve, reject) => {let shellRendered = false;const { pipe, abort } = renderToPipeableStream(<RemixServercontext={remixContext}url={request.url}abortDelay={ABORT_DELAY}/>,{onAllReady() {shellRendered = true;const body = new PassThrough();const stream = createReadableStreamFromReadable(body);responseHeaders.set("Content-Type", "text/html");resolve(new Response(stream, {headers: responseHeaders,status: responseStatusCode,}));pipe(body);},onShellError(error: unknown) {reject(error);},onError(error: unknown) {responseStatusCode = 500;// Log streaming rendering errors from inside the shell.  Don't log// errors encountered during initial shell rendering since they'll// reject and get logged in handleDocumentRequest.if (shellRendered) {console.error(error);}},});setTimeout(abort, ABORT_DELAY);});
}function handleBrowserRequest(request: Request,responseStatusCode: number,responseHeaders: Headers,remixContext: EntryContext
) {return new Promise((resolve, reject) => {let shellRendered = false;const { pipe, abort } = renderToPipeableStream(<MuiProvider><RemixServercontext={remixContext}url={request.url}abortDelay={ABORT_DELAY}/></MuiProvider>,{onShellReady() {shellRendered = true;const body = new PassThrough();const stream = createReadableStreamFromReadable(body);responseHeaders.set("Content-Type", "text/html");resolve(new Response(stream, {headers: responseHeaders,status: responseStatusCode,}));pipe(body);},onShellError(error: unknown) {reject(error);},onError(error: unknown) {responseStatusCode = 500;// Log streaming rendering errors from inside the shell.  Don't log// errors encountered during initial shell rendering since they'll// reject and get logged in handleDocumentRequest.if (shellRendered) {console.error(error);}},});setTimeout(abort, ABORT_DELAY);});
}

主要用了 ThemeProvider,有了 ThemeProvider,Theme的配置就可以传递到组件了。完整的项目,可以访问 git https://github.com/sjwan/remix-mui

项目中用加了 meta theme-color,有了这个主题颜色,浏览器的整体颜色就会一起变化,IOS 15 以上的系统浏览器 Safari 支持这个效果,macos 并不支持。
在这里插入图片描述


http://www.ppmy.cn/devtools/42042.html

相关文章

物联网促进信息化——​青创智通工业物联网解决方案​

随着传感器网络&#xff08;WSN)、无线射频识别&#xff08;RFID&#xff09;以及微电子机械系统(MEIVIS&#xff09;等技术的不断成熟,扩展了人们对信息获取和使用的能力&#xff0c;并将提高制造效率、改善产品质量、降低产品成本和资源消耗、为用户提供更加透明和个性化的服…

Golang 的 unmarshal 踩坑指南

文章目录 1. 写在最前面2. 字段区分出空字段还是未设置字段2.1 问题描述2.2 解决 3. 字段支持多种类型 & 按需做不同类型处理3.1 问题描述3.2 解决 4. 碎碎念5. 参考资料 1. 写在最前面 笔者最近在实现将内部通知系统的数据定义转化为产品定义的对外提供的数据结构。 举例…

2D Chests Assets - Mega Pack

科幻/奇幻/经典主题的箱子和容器。AAA质量,高分辨率,VFX,源PSD文件。 这是一个带有手绘套装的大包装: -【梦幻之栗】 -【科幻钱包】 AAA质量。高分辨率。一切都已准备就绪,可供使用。包括PSD文件。 在1.1版本中添加了VFX并将项目更新为URP。请注意,新的VFX仅适用于URP/HD…

【考研数学】进入强化,基础过关《660》不会做怎么办?

做题没思路&#xff0c;说明学习的过程中走了弯路 很多人&#xff0c;按部就班的学习&#xff0c;觉得课我也听了&#xff0c;讲义也看了&#xff0c;怎么别人做题很顺&#xff0c;自己翻开书就一头雾水。搞清楚其中的差别&#xff0c;也就解决了做题没思路的问题。 首先我们…

RustGUI学习(iced/iced_aw)之小部件(十九):如何使用context_menu部件来创建右击菜单?

前言 本专栏是学习Rust的GUI库iced的合集,将介绍iced涉及的各个小部件分别介绍,最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个,目前处于发展中(即版本可能会改变),本专栏基于版本0.12.1. 概述 这是本专栏的第十九篇,主要讲述context_menu右击菜单部件的使…

Rancher-Kubewarden-保姆级教学-含Demo测试

一、什么是Kubewarden&#xff1f; What is Kubewarden? | Kubewarden 1、就是容器集群的准入策略引擎。 1、使用的策略其实就是k8s原生的security context. 2、使用WebAssembly来编写策略。 1、WebAssembly&#xff0c;可以使用擅长的开发语言来编写策略。&#xff08;下面的…

webpack优化构建速度示例-合理配置loader的include exclude:

实际上&#xff0c;babel-loader 在 Webpack 配置中默认并不包含 exclude 和 include 选项的默认值&#xff0c;通常&#xff0c;为了优化构建性能&#xff0c;开发者会显式地设置 exclude 和 include 选项&#xff0c;以便 babel-loader 只处理必要的文件。 src/index.js impo…

大模型微调之 在亚马逊AWS上实战LlaMA案例(九)

大模型微调之 在亚马逊AWS上实战LlaMA案例&#xff08;九&#xff09; 代码阅读 src/llama_recipes/inference/prompt_format_utils.py 这段代码是一个Python模块&#xff0c;它定义了几个类和模板&#xff0c;用于生成安全评估的提示文本。以下是对每一行代码的注释和提示词…