使用Bun开发Windows的单独可执行桌面软件

二狗2025/01/02发布
bun
windows

首先我们新建个项目目录,我就用gui了,你们随意

然后打开终端 cd 到项目目录 bun init 初始化项目

PowerShell
PS C:\Users\7\Desktop\Bun\gui> bun init
bun init helps you get started with a minimal project and tries to guess sensible defaults. Press ^C anytime to quit

package name (gui):
entry point (index.ts): main.js

Done! A package.json file was saved in the current directory.
 + main.js
 + .gitignore
 + jsconfig.json (for editor auto-complete)
 + README.md

To get started, run:
  bun run main.js
PS C:\Users\7\Desktop\Bun\gui>

我之前一直是使用 webview 这个库然后自己编译成 dll 给 bun 调用 没想到发现了 webview-bun 国外友人已经封装好了一个库,省去自己去构建 webview 了

初始化完成后我们安装一下 bun i webview-bun

我们再新建一个 ui.html 来编写我们软件 ui

./ui.html
<div>
  <h1></h1>
</div>
<div>
  <button id="increment">+</button>
  <button id="decrement"></button>
  <span>Counter: <span id="counterResult">0</span></span>
</div>
<div>
  <button id="compute">Compute</button>
  <span>: <span id="computeResult">(not started)</span></span>
</div>
<script type="module">
  const ui = {};
  document.querySelectorAll('[id]').forEach((e) => (ui[e.id] = e));

  ui.increment.addEventListener('click', async () => {
    ui.counterResult.textContent = await window.count(1);
  });
  ui.decrement.addEventListener('click', async () => {
    ui.counterResult.textContent = await window.count(-1);
  });
  ui.compute.addEventListener('click', async () => {
    ui.compute.disabled = true;
    ui.computeResult.textContent = '(pending)';
    ui.computeResult.textContent = await window.compute(6, 7);
    ui.compute.disabled = false;
  });
  // 禁用右键菜单
  document.addEventListener('contextmenu', (e) => e.preventDefault());
</script>

我们在 main.js 里输入后端绑定的代码

./main.js
import { Webview, SizeHint } from "webview-bun";
// 把html嵌入到单独可执行文件中,编译无需带ui.html
import html from "./ui.html" with { type: "text" };
// 第一个参数是禁止开发者工具 SizeHint.FIXED是禁窗口最大化
const webview = new Webview(false, { height: 480, width: 640, hint: SizeHint.FIXED });

let counter = 0;
// 绑定前端button(increment,decrement)的事件
webview.bind("count", (a) => counter += a);
// 绑定前端button(compute)的事件
webview.bind("compute", (a, b) => a + b);
// 软件标题
webview.title = "Bun App";
webview.setHTML(html);
webview.run();

现在我们可以bun run main.js 看看效果啦

preview

速度是不是很快呢? 秒启动 (编译打包之后更快)

最后我们编译打包一下

  • --minify 最小体积
  • --compile 编译单独可执行文件
  • -windows-hide-console 隐藏 windows 控制台 (不隐藏的话,软件后面有个黑乎乎的大窗口,巨丑)

不懂的可以去看我提的 issues

Terminal
bun build ./main.js --compile --minify --windows-hide-console --outfile myapp

编译之后你目录会多了个 myapp.exe

当然,你还可以给你的可执行文件加个 icon

只需要在编译命令加上 --windows-icon=./icon.ico

Terminal
bun build ./main.js --compile --minify --windows-hide-console --windows-icon=./icon.ico --outfile myapp