remix-antd-admin 一个基于
Remix/Antd
的管理系统,可以快速了解 Remix 作为管理系统的性能(目前已经升级到 Remix v2 版本,偏前端)。
当前技术栈:React/Node.js
pkg | version | desc |
---|---|---|
remix | v2.0.1 | latest Remix |
antd | v5.9.4 | Antd UI |
@ant-design/pro-components | v2.6.28 | enhance AntdUI |
echarts | v5.4.3 | chart lib with ssr |
i18next | v23.5.1 | i18n 国际化 |
remix-development-tools | v3.0.3 | Remix DevTool |
... | - | - |
基于 React 社区和 Node.js 社区,当然需要了解 React SSR 的能力。当然目前也可以尝试迁移到 bun 运行时,拥有更加快速的响应速度。
简介
本项目基于 Remix 框架,目前实现了 40+
文件路由(即页面)和众多组件。
Remix 基于文件路由 用了就回不去了
,比配置式的路由更加直观。
本项目主要以前端为主,部署在 vercel(可能无法正常访问):
本项目主要探索,Remix 通过 Remix router 制作大型后台管理,前后端统一的书写的方式的可能性。经过了 5
个月时间,本期已经完成对 Remix v2 的升级,之前文章在此。
升级
- 主升级 Remix V2
- 切换到 ESM + TypeScript
- 使用 React 18 新的流式渲染,替代字符串渲染
- 移除 Styled-Components,使用原生 CSS
- 移除对服务端渲染支持不良好的依赖包等
- 可以通过如下方式体验本项目:
用法
sh
# clone the project
git clone https://github.com/yyong008/remix-antd-admin.git
# install deps
pnpm install
# start local server
pnpm run dev # pnpm dev
# build project for productin
pnpm run build #pnpm build
# start in production
pnpm run start # pnpm start
使用和一些变化
antd/icons
ts
import * as _icons from '@ant-design/icons';
const { MoreOutlined } = _icons;
全面切换到 React 流式服务端渲染
ts
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { PassThrough } from "node:stream";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import { renderToPipeableStream } from "react-dom/server";
import { startServerI18n, I18nextProviderWrap } from './i18n/server'
// utils
import isbot from "isbot";
const ABORT_DELAY = 5_000;
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
loadContext: 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 instance = startServerI18n(request, remixContext);
const { pipe, abort } = renderToPipeableStream(
<I18nextProviderWrap i18n={instance}>
<RemixServer
context={remixContext}
url={request.url}
abortDelay={ABORT_DELAY}
/>
</I18nextProviderWrap>,
{
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;
if (shellRendered) {
console.error(error);
}
},
}
);
setTimeout(abort, ABORT_DELAY);
});
}
function handleBrowserRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext
) {
return new Promise((resolve, reject) => {
//
}
}
全面的流式渲染需要对 React18 的 renderToPipeableStream
和新的 Web Fetch 系列的 API 进行了解。
欢迎提出宝贵意见
本项目在探索 Remix + antd 作为大型后台管理项目的可能性,目前已完成前端部分的大部分开发任务,但是仍然存在诸多问题,比如路由多了,编译速度慢(不同电脑的编译速度存在很大的问题),如果你也对此感兴趣,不妨 clone 一下,有你的体验运和宝贵意见。 相信 remix-antd-admin 会更加的饱满。作者持续关注 Remix 技术栈的发展,不妨关注本账号,三连,不定时更多分享。