Wails2 系列 05:前端调用层:不要让页面直接依赖 wailsjs
cbowen

适合读者

适合使用 React、Vue 或 Svelte 开发 Wails 前端,并已经通过 wailsjs 调用 Go 方法的开发者。

问题场景

Wails 会为绑定的 Go 服务生成前端调用代码。这个能力很方便,但也容易让页面直接依赖生成文件:

1
import { SaveTodo } from "../../wailsjs/go/todo/TodoService"

如果只有一两个页面,这样写很自然。项目变大后,页面、组件、store 到处都在 import wailsjs,后端方法一改名,前端全项目跟着震动。更麻烦的是,错误处理、默认值转换、类型适配也会散落在各个页面。

项目观察

当前项目中可以观察到三个前端层次:

  • frontend/wailsjs:Wails 生成代码。
  • frontend/src/services/api:前端自己的 API 封装层。
  • frontend/src/storefrontend/src/pages:状态和页面使用封装后的 API。

这个边界很关键:wailsjs 是桥,不是业务层。

拆分原则

前端页面不要直接依赖生成绑定。推荐加一层很薄的 API wrapper:

1
page/store -> services/api -> wailsjs -> Go service

这层 wrapper 不需要复杂。它的价值在于:

  • 隔离生成代码路径。
  • 统一命名风格。
  • 统一错误处理。
  • 做轻量类型转换。
  • 给测试或 mock 留入口。

同时要记住:frontend/wailsjs 是生成目录,不建议手动维护。Go 绑定变化后,应通过 Wails 工具重新生成。

改造示例

不推荐页面直接这样写:

1
2
3
4
5
6
7
import { ListToday, SaveTodo } from "../../wailsjs/go/todo/TodoService"

export function TodoPage() {
async function load() {
const items = await ListToday()
}
}

可以先封装成 services/api/todo.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
import { ListToday, SaveTodo } from "../../wailsjs/go/todo/TodoService"

export async function listTodayTodos() {
return await ListToday()
}

export async function createTodo(title: string) {
if (!title.trim()) {
throw new Error("待办标题不能为空")
}

return await SaveTodo(title.trim())
}

页面或 store 再调用自己的 API:

1
2
3
4
5
import { createTodo, listTodayTodos } from "@/services/api/todo"

export async function refreshTodos() {
return await listTodayTodos()
}

这样以后 Go 方法改名,主要影响 services/api/todo.ts,不会让页面到处跟着改。

检查清单

  • 页面是否还大量直接 import frontend/wailsjs
  • 生成绑定是否只集中在 services/api 或类似目录中?
  • API wrapper 是否使用前端更自然的命名?
  • 错误处理和参数清洗是否集中在 wrapper 或 store 中?
  • frontend/wailsjs 是否被明确视为生成代码?
  • 后端方法改名时,是否只需要改少数封装文件?
  • 测试前端逻辑时,是否能替换 API 层?

下一篇

下一篇会继续梳理前端内部结构:页面、组件和 store 分别应该承担什么职责。

 评论
评论插件加载失败
正在加载评论插件