Wails + SvelteKit 构建桌面应用
作为一名 web 后端 CRUD boy,我一直希望开发一个自己的桌面 app。
但是当我稍微了解了一下之后,🫠发现这并不是一件容易的事情。但是转念一想,🤔反正我也不打算写一个特别复杂的应用,直接选择 web 相关技术来做就好,门槛较低、自己也稍微熟悉一点。
由于我不会 nodejs 和 rust,只对 go 比较熟悉,所以选择了 Wails 作为桌面开发框架🥳。前端框架也希望简单因此选择了 SvelteKit。至于 UI,我发现 Svelte 相关的 UI 库相对较少,而且文档也不是很友好(我的英语也不好😢)。看了一圈之后最后决定还是用 bootstrap 吧,它看起来比较简单直接。
项目搭建步骤#
- 首先安装 wails 以及相关工具,这一步官网已经有详细的介绍,参考官网教程
- 安装好相关工具以后,使用 wails 初始化一个项目
wails init -n otool -t svelte
, 这里指定项目名称 otool 以及项目模板使用 svelte。命令执行完毕,就会在当前目录下创建一个名为 otool 的项目 - 接着重新初始化前端模块。进入 otool 目录,可以发现自带的前端模块目录 frontend。我们使用 SvelteKit 这个 web 框架,因此自带的不需要,直接删除 frontend 目录。然后执行
npm create svelte@latest frontend
创建一个 SveleteKit 项目的 frontend 目录。执行该命令后,将询问你一系列问题:
- 首先是选择创建应用的类型,我们选择 Skeleton project 来生成一个基本的应用骨架
- 接着会询问你是否需要 TypeScript 类型检查等问题,我选择的是第一个:使用 JavaScript with JSDoc comments
- 最后选择一些附加选项,按需选择即可
初始化前端模块以后,还需要更改前端的配置。首先需要修改 SvelteKit 适配器,该配置用于将 Svelte 应用程序部署到不同的服务器环境中。默认的适配器是 adapter-auto,由于是桌面应用开发为纯静态页面,因此更改适配器为 adapter-static。
进入 frontend 目录,修改 package.json 中的 devDependencies 下的”@sveltejs/adapter-auto” 为”@sveltejs/adapter-static”(静态站点适配器)。修改 svelte.config.js 中的‘@sveltejs/adapter-auto’ 为‘@sveltejs/adapter-static’
回到 otool 目录然后执行
wails dev
, 该命令会自动安装相关依赖并在开发模式下运行应用。第一次执行会报错all routes must be fully prerenderable, but found the following routes that are dynamic
, 在 adapter-static 模式下,需要我们告诉 SvelteKit 需要渲染哪些路由,因此会出现这个错误。一般我们是加载所有符合路由规则的文件,所以在 frontend/src/routes 目录下创建 + layout.js 文件并写入export const prerender = true;
。再次运行wails dev
就可以看到弹出的应用窗口了,窗口中会显示 Welcome to SvelteKit调试模式下没问题后,我们执行
wails build
看下编译后的 app 效果。此时会发现编译的 app 无法正常运行,因为 SvelteKit 编译后的文件是在 frontend/build 目录下,因此打开 main.go 修改嵌入的前端资源路径。将//go:embed all:frontend/dist
修改为//go:embed all:frontend/build
。再次编译就可以正常打开 app 了
以上基本工作就做好了,可以开始开发我们的应用
应用布局#
我们使用 bootstrap 来作为 ui 库,在 frontend 目录下运行 npm install bootstrap@5.3.0-alpha1
安装 bootstrap。为了适配 bootstrap 需要再次在 frontend/src/routes/+layout.js 文件中写入 export const ssr = false;
通过关闭服务端渲染来避免 document is not defined
此类浏览器端 api 在服务端运行时下的错误。
然后创建布局文件 frontend/src/routes/+layout.svelte,放入如下代码:
<script>
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.bundle.min.js'
import Menu from './Menu.svelte'
</script>
<div class="main d-flex flex-row">
<Menu />
<div class="flex-fill overflow-scroll">
<slot></slot>
</div>
</div>
<style>
.main {
height: 100vh;
width: 100vw;
overflow-x: auto;
overflow-y: hidden;
}
</style>
同目录下创建 Menu.svelte,代码如下:
<script>
let activeItem = null;
let menus = [
{ name: "menu1", url: "/hello" },
];
function setActive(index) {
activeItem = index;
}
</script>
<div class="flex-shrink-0 text-bg-dark p-2 overflow-scroll w-25" style="max-width: 220px;">
<a
href="/"
on:click={() => setActive(-1)}
class="d-flex justify-content-center text-white text-decoration-none"
>
<span class="fs-4">oapp</span>
</a>
<hr />
<ul class="nav nav-pills flex-column mb-auto">
{#each menus as item, index}
<li class="nav-item">
<a
href={item.url}
class="nav-link text-white d-flex justify-content-center"
class:active={activeItem === index}
on:click={() => setActive(index)}
>
{item.name}
</a>
</li>
{/each}
</ul>
</div>
接着创建菜单组件中的”/hello” 对应文件,在 routes 目录下创建 hello/+page.svelte,在其中随便写点内容。
运行 wails dev 就可以看到一个经典侧边栏菜单布局的应用了,点击 menu1 菜单就可以跳转到相关页面
末尾#
在布局完成后,还需要配置一下前端允许访问的外部资源路径。可以看到 wails 生成的 go 代码绑定 js 文件位于 src 同级的 wailsjs 目录下,先配置这个路径,执行 npm install @types/node
, 然后在 vite.config.js 中加入:
...
import path from "path";
...
export default defineConfig({
...
resolve: {
alias: {
$wailsjs: path.resolve(__dirname, "./wailsjs"),
},
},
server: {
fs: {
allow: ["./wailsjs"],
},
},
...
});
在前端代码中就可以像这样 import * as app from "$wailsjs/go/backend/App";
引入 wailsjs 文件
完整项目可以参考 github.com/welllog/otool
ps: 项目比较简陋。如果觉得帮助到您请给个 star
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: