Deno Fresh 2.x 迁移指南:从旧版本平滑升级

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 |

最佳实践建议

  1. 逐步迁移:建议先在开发环境测试迁移,确认无误后再部署到生产环境
  2. 版本控制:迁移前确保项目已提交到版本控制系统
  3. 测试覆盖:迁移后全面测试应用功能,特别是自定义中间件和错误处理
  4. 性能监控:升级后关注应用性能指标,验证改进效果

通过遵循本指南,开发者可以顺利完成 Fresh 1.x 到 2.x 的迁移,享受新版本带来的性能提升和开发体验优化。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

严微海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值