Deno Fresh 2.x 迁移指南:从旧版本平滑升级
前言
Deno Fresh 2.x 版本带来了诸多改进和优化,虽然团队尽可能减少了破坏性变更,但某些改动仍需要开发者手动调整。本文将详细介绍如何将 Fresh 1.x 项目迁移至 2.x 版本,帮助开发者顺利完成升级过程。
自动更新工具
Fresh 提供了便捷的自动更新工具,可以处理大部分 API 变更:
deno run -Ar jsr:@fresh/update
执行此命令会自动完成诸如将 $fresh/server.ts
导入改为 fresh
等变更。
项目结构调整
配置文件简化
Fresh 2.x 不再需要专门的配置文件,可以安全删除以下文件:
fresh.config.ts
fresh.gen.ts
开发与生产环境分离
Fresh 2.x 明确区分了开发和生产环境代码,这种分离带来了更小的部署体积和更快的启动速度。
更新 dev.ts
开发环境配置现在通过 Builder
类实例进行管理:
import { Builder } from "fresh/dev";
import { tailwind } from "@fresh/plugin-tailwind";
import { app } from "./main.ts";
const builder = new Builder({ target: "safari12" });
// 开发环境插件配置示例
tailwind(builder, app, {});
// 构建生产资源
if (Deno.args.includes("build")) {
await builder.build(app);
} else {
// 启动开发服务器
await builder.listen(app);
}
更新 main.ts
生产环境配置通过 App
类实例管理:
import { App, fsRoutes, staticFiles } from "fresh";
export const app = new App()
.use(staticFiles());
// 文件系统路由配置
await fsRoutes(app, {
loadIsland: (path) => import(`./islands/${path}`),
loadRoute: (path) => import(`./routes/${path}`),
});
if (import.meta.main) {
await app.listen();
}
错误页面统一处理
Fresh 2.x 将 _404.tsx
和 _500.tsx
合并为单一的 _error.tsx
模板:
export default function ErrorPage(props: PageProps) {
const error = props.error;
if (error instanceof HttpError) {
const status = error.status;
// 自定义404页面
if (status === 404) {
return <h1>404 - 页面不存在</h1>;
}
}
return <h1>系统错误</h1>;
}
Head组件替代方案
<Head>
组件因性能考虑被移除,推荐使用 ctx.state
管理头部信息:
// 路由处理器中设置标题
export const handler = {
GET(ctx) {
ctx.state.title = "关于我们";
return page();
},
};
// _app.tsx中渲染
export default function AppWrapper(ctx: FreshContext) {
return (
<html>
<head>
{ctx.state.title && <title>{ctx.state.title}</title>}
</head>
<body>
<ctx.Component />
</body>
</html>
);
}
部署调整
Fresh 2.x 要求在部署时预先构建资源,而非按需构建。确保部署流程中包含:
deno task build
路径斜杠处理
斜杠处理现在作为可选中间件提供:
import { trailingSlashes } from "fresh";
app.use(trailingSlashes("never")); // 或 "always"
API变更详解
统一的中间件签名
所有处理器签名统一为单参数形式:
- const handler = (req, ctx) => {...}
+ const handler = (ctx) => {...}
上下文接口合并
多种上下文类型合并为 FreshContext
:
| 旧版本 | 新版本 |
|--------|--------|
| AppContext
, LayoutContext
, RouteContext
| FreshContext
|
上下文方法变更
| 旧版本 | 新版本 |
|--------|--------|
| ctx.renderNotFound()
| throw new HttpError(404)
|
| ctx.basePath
| ctx.config.basePath
|
| ctx.remoteAddr
| ctx.info.remoteAddr
|
最佳实践建议
- 逐步迁移:建议先在开发环境测试迁移,确认无误后再部署到生产环境
- 版本控制:迁移前确保项目已提交到版本控制系统
- 测试覆盖:迁移后全面测试应用功能,特别是自定义中间件和错误处理
- 性能监控:升级后关注应用性能指标,验证改进效果
通过遵循本指南,开发者可以顺利完成 Fresh 1.x 到 2.x 的迁移,享受新版本带来的性能提升和开发体验优化。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考