deno+WebView2实现桌面程序?实战与经验

in 前后端开发 with 0 comment

这之中真的很坑,网上也很少有这样的教程。
这里我们会使用deno写一个桌面程序,实现轻量编辑器

测试

何为WebView

首先来介绍一下WebView2,出门右转,打开设置

这就是WebView2啦

简单来说就是将MSEdge(没错,就是微软强制安装的Edge)分离,为应用程序提供接口调用WebView2实现Web程序运行和交互
比如我在用的Clash Verge就是使用RUST作为支撑,调用WebView的程序
是不是有一股来自HTML+CSS的香气?

Clash Verge

如何WebView

很不巧,deno中的V8 VM没有调用WebView的函数,也无法创建任何窗口
那怎么办呢?开外挂呗
我们可以使用封装好的库,如 https://deno.land/x/webview/
每次启动应用,都会出现一个叫做 2024-02-06T00:27:33.png 的文件
没错哦,最终是通过deno-ffi调用这个dll实现webview的。那么就介绍到这里,开搞吧

开搞前必须明白的

run()

注意啦,注意啦,这3个单词很重要
run()会破坏deno的Event Loop,所以这么写永远不会有结果

app.bind('_read',async function(path:string){
    return await Deno.readTextFile(path);
});

很坑,所以务必改为使用deno的同步IO,简而言之就是加上Sync。
改成这样即可:

app.bind('_read',function(path:string){
    return Deno.readTextFileSync(path);
});

然后就是

navigate()

也就是说,你需要一个HTTP服务器服务你的HTML+CSS+JS,且不能在主程序中
(为什么?都说了run()会破坏deno的Event Loop,请求永远不会响应)

怎么办?土豪的选择通常是使用自己的服务器提供网页,那我们这些穷B怎么办呢?
那主进程不行,再开一个进程不就行了?

子进程大法

那server.ts就显得朴实无华了啊,直接贴出来吧

import { serveDir } from "https://deno.land/std/http/file_server.ts";

export const port = parseInt(Deno.args[0]),
    server = Deno.serve(
        {port,hostname: '127.0.0.1'},
        req => serveDir(req,{
            fsRoot: 'root/'
        })
    );

就是这样,简单吧?(我自己都不信)

开搞

...自己写吧,我搞了一天筋疲力尽了
我实现的编辑器没有上语法高亮和文件浏览,就不放出来了。托管在这里
简单来说就是

app.bind('_write',(data:string,path:string) => Deno.writeTextFileSync(path,data));
app.bind('_read',function(path:string){
    if(!path) throw new Error('null');
    return Deno.readTextFileSync(path);
});
app.bind('_scan',(dir:string) => Deno.readDirSync(dir));

bind向WebView实例暴露一个函数,然后前端就可以快速开搞了
其实我写的RPC V2实现的功能比WebView进程通信更加丰富,支持PIPE、错误传递、双向调用(注意,服务端可以调用客户端的函数,且全程异步)等。咳咳,串台了
那么,好运!

Responses