在 vite+vue3+electron 中使用 express

一、Vite + Vue3 + Electron 项目的搭建

详细的项目构建和打包可参考另一篇文章:

使用 electron-vite-vue 构建 electron + vue3 项目并打包

二、搭建 express 环境

1、安装 express 框架所需依赖

yarn add express cors morgan cookie-parser

根据自身情况下载相关依赖包。

2、创建 express 项目

在项目根目录下创建一个 server 文件夹,项目目录结构如下:

项目目录结构

如果 express 项目是基于 express-generator 构建的,只需将 app.js 文件修改成 app.ts 再做部分修改即可。

完整的 app.ts 文件内容如下:

var express = require('express');
var appPath = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');

// 加载路由文件
const indexRouter = require(appPath.join(__dirname,'./routes/index.ts'));

var app = express();

// 解决跨域
app.use(cors());

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

app.use('/api/index', indexRouter);

// ----------------------
const http = require("http");
const server = http.createServer(app);
// var port = normalizePort(process.env.PORT || "3000");

// 导出启动服务器的函数
async function startServer(port) {
    app.set("port", port);
    return new Promise((resolve, reject) => {
        server.listen(port, () => {
            console.log(`Server listening on port ${port}`);
            resolve(server);
        });
        server.on("error", (error) => {
            reject(error);
        });
    });
}

// 停止服务器
async function stopServer() {
    return new Promise((resolve) => {
        server.close(() => {
            console.log("Server stopped");
            resolve('');
        });
    });
}

module.exports = {
    startServer,
    stopServer
};

该文件的内容是基于 express-generator 构建后生成的 app.js 文件并结合了 bin/www 文件的部分内容。此处导出启动服务器的函数,便于后续启动 electron 时一并启用该服务。

3、配置路由

可以在 server/routes 文件夹下创建一个 index.ts 文件,文件内容如下:

const router = require('express').Router();

router.get('/', function (req, res) {
    res.send('hello express !!!');
});

module.exports = router;
4、启动 express 服务

可根据需要安装 get-port,用于监听可用端口,避免端口出现冲突导致服务无法启动:

yarn add get-port

修改 electron/main.ts 文件,导入 express 启动服务相关函数:

// electron/main.ts
import { app, BrowserWindow } from "electron";
import { createRequire } from "node:module";
import { fileURLToPath } from "node:url";
import path from "node:path";

// get-port => 查找可用端口
import getPort, { portNumbers } from "get-port";

const require = createRequire(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));

// 导入 express 启动服务函数
const { startServer, stopServer } = require(path.join(__dirname, "../server/app.ts"));

启动服务:

// electron/main.ts
function createWindow() { ... }

...

app.on("window-all-closed", () => {
    if (process.platform !== "darwin") {
        app.quit();
        win = null;
        // 停止 express 服务
        stopServer();
    }
});

app.whenReady().then(async () => {
    try {
        // 使用 getPort 查找可用端口 (范围 3000 ~ 3100)
        const port = await getPort({ port: portNumbers(3000, 3100) });
        // 启动 express 服务
        await startServer(port);
        createWindow();
    } catch (error) {
        console.error("Failed to start server:", error);
    }
});
5、启动 electron 并获取数据

为了测试是否能够获取 express 中的数据,可以在 Vue3 中安装并使用 axios 获取数据,修改 App.vue 文件内容如下:

<script setup lang="ts">
import { onMounted } from "vue";
import axios from "axios";

onMounted(async () => {
    let res = await axios.get('http://localhost:3000/api/index');
    console.log(res);
})
</script>

在 electron 中查看接收的数据:

获取数据

注意:杀毒软件(如:火绒)或防火墙可能拦截相关请求,应允许相关请求。

三、项目打包

打包后启动程序可能出现相关模块无法找到的问题,可尝试修改以下配置文件后再打包。

修改 tsconfig.json 文件夹下的 include 参数:

"compilerOptions": { ... },
"include": ["server/**/*.ts","src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "electron"],

修改打包配置文件 electron-builder.json5 中的 files 属性:

"files": [
    "dist",
    "dist-electron",
    "server/**/*"
]

说明: 每次修改 server 文件中的内容都需要手动重启 electron,可以在 electron/main.ts 中任意空白位置敲空格再保存即可实现自动重启,暂时还不清楚怎么实现 express 的热更新…

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用viteVue3、TypeScript和Electron的SQLite3案例: 1. 首先,创建一个新的Electron项目: ``` mkdir my-electron-project cd my-electron-project npm init -y npm install --save-dev electron ``` 2. 安装vite作为前端构建工具: ``` npm install --save-dev vite ``` 3. 创建一个新的Vue3项目: ``` npm install --save-dev vue@next npm install --save-dev @vue/compiler-sfc ``` 4. 集成TypeScript: ``` npm install --save-dev typescript npm install --save-dev @types/node npm install --save-dev @types/electron ``` 5. 安装SQLite3依赖: ``` npm install --save sqlite3 ``` 6. 在你的项目根目录下创建一个`src`文件夹,然后在`src`下创建一个新的`main.ts`文件,作为Electron应用程序的入口点: ``` import { app, BrowserWindow } from 'electron'; let win: BrowserWindow | null = null; function createWindow() { win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false, }, }); win.loadURL(`http://localhost:3000`); win.webContents.openDevTools(); win.on('closed', () => { win = null; }); } app.on('ready', createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { if (win === null) { createWindow(); } }); ``` 7. 在`src`下创建一个新的`renderer.tsx`文件,用于渲染Vue3组件: ``` import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app'); ``` 8. 在`src`下创建一个新的`App.vue`文件,这是Vue3的根组件: ``` <template> <div id="app"> <h1>SQLite3 Example</h1> <p v-if="data">Data: {{ data }}</p> <button @click="fetchData">Fetch Data</button> </div> </template> <script lang="ts"> import { defineComponent, reactive } from 'vue'; import sqlite3 from 'sqlite3'; export default defineComponent({ setup() { const state = reactive({ data: null, }); const fetchData = () => { const db = new sqlite3.Database(':memory:'); db.serialize(() => { db.run('CREATE TABLE lorem (info TEXT)'); const stmt = db.prepare('INSERT INTO lorem VALUES (?)'); for (let i = 0; i < 10; i++) { stmt.run(`Ipsum ${i}`); } stmt.finalize(); const results: string[] = []; db.each('SELECT rowid AS id, info FROM lorem', (err, row) => { results.push(`${row.id}: ${row.info}`); }, (err, count) => { state.data = results.join('\n'); }); }); db.close(); }; return { data: state.data, fetchData, }; }, }); </script> <style> body { font-family: sans-serif; font-size: 16px; margin: 0; padding: 0; } #app { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; } button { margin-top: 2em; padding: 1em; font-size: inherit; } </style> ``` 9. 在项目根目录下创建一个新的`index.html`文件,作为Vue3应用程序的入口点: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SQLite3 Example</title> </head> <body> <div id="app"></div> <script type="module" src="/src/renderer.tsx"></script> </body> </html> ``` 10. 在项目根目录下创建一个新的`main.ts`文件,作为vite的入口点: ``` import { app, BrowserWindow } from 'electron'; import path from 'path'; import url from 'url'; import vite from 'vite'; let win: BrowserWindow | null = null; async function createWindow() { const viteServer = await vite.createServer({ server: { middlewareMode: true, }, }); await viteServer.listen(); win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false, }, }); if (process.env.NODE_ENV === 'development') { win.loadURL(`http://localhost:3000`); } else { win.loadURL( url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true, }) ); } win.webContents.openDevTools(); win.on('closed', () => { win = null; }); } app.on('ready', createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { if (win === null) { createWindow(); } }); ``` 11. 在`package.json`添加以下脚本: ``` "scripts": { "dev": "cross-env NODE_ENV=development electron .", "build": "cross-env NODE_ENV=production vite build && electron .", "start": "electron ." } ``` 12. 运行开发服务器: ``` npm run dev ``` 13. 运行Electron应用程序: ``` npm run start ``` 这样,你就可以在Electron应用程序使用SQLite3了。在这个示例,我们创建了一个内存数据库,并插入了10条数据。当用户点击“Fetch Data”按钮时,我们从数据库检索这些数据,并在屏幕上显示它们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值