@resolid/remix-plugins
v3.0.3
Published
Resolid Remix 扩展插件
Downloads
194
Readme
@resolid/remix-plugins
Resolid Remix 扩展插件包, 主要是对 Remix 进行强化的一些插件, 需配合 Vite 使用
功能
安装
pnpm add -D @resolid/remix-plugins
路由增强
Remix 默认使用的是平面文件路由,用 .
来分割 URL, 这种形式小项目还好, 一旦遇到大的项目就不太舒服了, 所以我开发了混合目录和文件的路由系统
配置
编辑 vite.config.ts
文件
import { vitePlugin as remix } from "@remix-run/dev";
import remixFlexRoutes from "@resolid/remix-plugins/flex-routes";
export default {
plugins: [
remix({
ignoredRouteFiles: ["**/*"],
routes: async () => {
return await remixFlexRoutes({
ignoredRouteFiles: ["**/.*"],
});
},
}),
],
};
规则
- 路由是使用文件夹定义和嵌套的, 与在 nginx 服务器上布局 HTML 文件的方式非常相似
_layout
文件包装了下游的所有路由, 这些需要一个<Outlet />
来渲染子路由_index
文件是文件夹的默认文件, 例如:/users/_index.tsx
将匹配/users
- 变量在文件路径中使用
$
表示, 例如:/users/$id/edit.tsx
将匹配/users/123/edit
- 将路线段括在括号中将使该段成为可选, 例如:
/($lang)/categories.tsx
将匹配/categories
,/zh/categories
- 可以使用
[]
对路由约定的特殊字符进行转义, 例如:/make-[$$$]-fast-online.tsx
将匹配/make-$$$-fast-online
- 以
_
为前缀的文件和文件夹变得不可见, 从而允许在不影响路由路径的情况下进行文件夹组织, 例如:/_legal-pages/privacy-policy.tsx
将匹配/privacy-policy
$.tsx
泼溅路由将匹配 URL 的其余部分, 包括斜杠, 比如/files/$.tsx
将匹配/files
,/files/one
,/files/one/two
路由规则大部分和 Remix 的路由兼容, 只是增加了文件夹结构
Hono 服务器
安装相关依赖
pnpm add hono @hono/node-server
Node.js 服务
创建 Node.js 服务
// app/server.node.ts
import { createHonoNodeServer } from "@resolid/remix-plugins/node-server";
export const server = await createHonoNodeServer();
配置 Remix 插件 Node.js Preset
// vite.config.ts
import { vitePlugin as remix } from "@remix-run/dev";
import { nodePreset } from "@resolid/remix-plugins/node-preset";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
remix({
presets: [
nodePreset({
// 入口文件
entryFile: "server.node.ts" // 默认为 server.ts
})
]
}),
tsconfigPaths()
]
});
支持 SERVER_PORT
和 SERVER_PATH
环境变量, SERVER_PATH
环境变量用于 Remix 的 serverBundles 功能
运行 build 成功以后自动会在
build/server
目录下生成server.mjs
和package.json
文件,package.json
文件里面定义了 Vite 设置的ssr.external
, 在服务器目录下运行npm install
即可安装构建时排除的依赖
配置开发服务器
首先修改 vite.config.ts 文件配置开发服务器
// vite.config.ts
import { vitePlugin as remix } from "@remix-run/dev";
import { devServer } from "@resolid/remix-plugins/dev-server";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
devServer({
// 入口文件
entryFile: "server.node.ts" // 默认为 server.ts
}),
remix(),
tsconfigPaths()
]
});
然后更新 package.json 里面的开发运行脚本, 使用 vite
// package.json
{
"scripts": {
"dev": "vite"
}
// ...
}
Vercel 服务
你可以使用 https://github.com/huijiewei/remix-vite-vercel-template 模版快速部署到 Vercel.
创建 Vercel 服务
// app/server.vercel.ts
import { createHonoVercelServer } from "@resolid/remix-plugins/vercel-server";
export const server = await createHonoVercelServer();
export default server;
配置 Remix 插件 Vercel Preset
// vite.config.ts
import { vitePlugin as remix } from "@remix-run/dev";
import { vercelPreset } from "@resolid/remix-plugins/vercel-preset";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
remix({
presets: [
vercelPreset({
// 部署区域
regions: "sin1",
// 有些包会根据不同平台引入二进制包, 安装的时候二进制包不在同一目录, 比如 @node-rs/bcrypt
copyParentModules: ["@node-rs/bcrypt"],
// 入口文件
entryFile: "server.vercel.ts" // 默认为 server.ts
})
]
}),
tsconfigPaths()
]
});
Vercel 项目 Framework Preset 需设置为 Vite, Node.js Version 需设置为 20.x
如果你使用的是 monorepo 结构, 请设置 Root Directory 为需要部署的项目目录, 然后自定义相关命令, Resolid 的配置如下图
Hono 中间件
中间件是在 Remix 调用加载器/操作之前调用的函数, 请参阅 Hono 文档 以获取更多信息。
你可以配置 createHonoNodeServer 或者 createHonoVercelServer 的 configure 来方便使用 Hono 中间件
import { createHonoNodeServer } from "@resolid/remix-plugins/node-server";
export const server = await createHonoNodeServer({
configure: (server) => {
server.use(/* Hono 中间件 */);
}
});
Remix 负载上下文
如果您想向 Remix 加载上下文添加其他属性,你可以配置 createHonoNodeServer 或者 createHonoVercelServer 的 getLoadContext 来增加加载上下文
import { createHonoNodeServer } from "@resolid/remix-plugins/node-server";
import type { HttpBindings } from "@hono/node-server";
import type { Context } from "hono";
export const server = await createHonoNodeServer({
getLoadContext: (c: Context<{ Bindings: HttpBindings }>) => {
return {
remoteAddress: c.env.incoming.socket.remoteAddress
};
}
});