Open jinzhongjia opened 7 months ago
I'm exploring Deno (vs Zig), and just got an example to compile to exe.
I had problems with using an express wrapper on CouchDb, so I'm testing ways to link PouchDb into the Deno directly, and call it from the front end JS. This is a test project.
If I go this route (Deno, instead of Zig or Rust or..), I could prepare a series of examples of increasing complexity.
But I'm not sure about a number of things. I don't know if dynamic loading is the way to do it, but I could not think of another way to have my (compiled) SvelteKit SPA call functions that are defined in the Deno project but not yet defined (until runtime) in the Svelte code.
So, for example, here is a main.ts
file of a Deno project:
import { WebUI } from "https://deno.land/x/webui/mod.ts";
import express, { Express, Request, Response } from "npm:express";
import cors from "npm:cors"
// To make this an Exe:
// deno compile --allow-read --allow-env --unstable-ffi --allow-ffi --allow-net main.ts
// FRONT END:
const file_content =
`
<html lang="en">
<head>
...
<script src="webui.js"></script>
</head>
<body>
<div>
<button OnClick="couch_doit()">Do it</button>
</div>
<script>
function loadJS(FILE_URL, async = true) {
let scriptEle = document.createElement("script");
scriptEle.setAttribute("src", FILE_URL);
scriptEle.setAttribute("type", "text/javascript");
scriptEle.setAttribute("async", async);
document.body.appendChild(scriptEle);
scriptEle.addEventListener("load", () => {
console.log("File loaded")
});
scriptEle.addEventListener("error", (ev) => {
console.log("Error on loading file", ev);
});
}
loadJS("couch_api.js", true);
</script>
</body>
</html>
`;
const path = "./ui/build";
const nwin = new WebUI();
nwin.setRootFolder(path);
nwin.bind("doSomething", do_something); // see couch_api.js
nwin.show(file_content);
// BACK-END:
async function do_something(e: WebUI.Event) {
const a = e.arg.string(0); // First argument
const b = e.arg.string(1); // Second argument
let obj = JSON.parse(b);
console.log("1", a); // to backend console
console.log("2", obj.name)
console.log("2", obj.last)
return `Received: ${a} , ${b}`; // to browser console
}
const port = 3000;
const app: Express = express();
app.use(cors())
app.use(express.json({ limit: '50mb' }))
app.use(express.urlencoded({extended : true}))
const expressServer = app.listen(port, () => {
console.log(`[server]: Server is running at http://localhost:${port}`);
});
WebUI.wait().then(() => {
console.log("shutting down...");
expressServer.close(() => {
console.log('Express closed.');
});
})
Then in a separate couch_api.js
file (which can be imported dynamically by the Svelte app, too), is the OnClick handler
function:
function couch_doit() {
let obj = {name: "David", last: "Alm"};
let j = JSON.stringify(obj);
doSomething('Message from JSON', j).then((response) => {
console.log(response); // "Message from C
});
}
The exe runs fine with the dynamic JS loading.
The current deno example is somewhat outdated and will output some warning messages.