electron.vite 项目创建以及better-sqlite3数据库使用

news/2025/2/11 14:55:38/

1.安装electron.vite

npm create @quick-start/electron@latest

中文官网:https://cn.electron-vite.org/

2. 安装项目依赖

npm i

3.修改 electron-builder 配置文件

appId: com.electron.app
productName: text33
directories:buildResources: build
files:- '!**/.vscode/*'- '!src/*'- '!electron.vite.config.{js,ts,mjs,cjs}'- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'- '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'
asarUnpack:- resources/**
win:icon: build/icon.ico# 配置文件示例,包含输入验证和异常处理逻辑target:- target: "nsis"  # 目标名称,必须为字符串arch: ["x64"]  # 架构列表,必须为非空列表executableName: text33
nsis:artifactName: ${name}-${version}-setup.${ext}shortcutName: ${productName}uninstallDisplayName: ${productName}createDesktopShortcut: alwaysoneClick: false # 设置为 false 以提供安装类型选择界面,允许用户选择是否创建桌面图标,允许用户选择安装路径perMachine: true # 设置为 true 将使安装程序默认为所有用户安装应用,这需要管理员权限allowToChangeInstallationDirectory: true # 如果设置为 true,安装程序将允许用户更改安装目录allowElevation: true #  一般情况下,此字段不会被直接使用,权限提升主要依赖于 perMachine 的设定。当perMachine为true,安装程序会请求管理员权限deleteAppDataOnUninstall: true # 如果设置为 true,卸载程序将删除AppData中的所有程序数据createStartMenuShortcut: true   # 如果设置为 true,安装程序将在开始菜单中创建程序快捷方式
mac:entitlementsInherit: build/entitlements.mac.plistextendInfo:- NSCameraUsageDescription: Application requests access to the device's camera.- NSMicrophoneUsageDescription: Application requests access to the device's microphone.- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.notarize: false
dmg:artifactName: ${name}-${version}.${ext}
linux:target:- AppImage- snap- debmaintainer: electronjs.orgcategory: Utility
appImage:artifactName: ${name}-${version}.${ext}
npmRebuild: false
publish:provider: genericurl: https://example.com/auto-updates
electronDownload:mirror: https://npmmirror.com/mirrors/electron/

4.修改启动文件package.json

"scripts": {"format": "prettier --write .","lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix","typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false","typecheck:web": "vue-tsc --noEmit -p tsconfig.web.json --composite false","typecheck": "npm run typecheck:node && npm run typecheck:web","start": "electron-vite preview","dev": "electron-vite dev","postinstall": "electron-builder install-app-deps", "build": "npm run typecheck && electron-vite build","build:unpack": "npm run build && electron-builder --dir","build:win": "npm run build && electron-builder --win","build:mac": "npm run build && electron-builder --mac","build:linux": "npm run build && electron-builder --linux"},

5.安装better-sqlite3数据库

npm i better-sqlite3 -S

数据库可视化 SQLiteStudio 下载地址 https://github.com/pawelsalawa/sqlitestudio/releases

better-sqlite3 https://www.npmjs.com/package/better-sqlite3

{"scripts": {"postinstall": "npx electron-rebuild -f", "postinstall_backup": "electron-builder install-app-deps", "rebuild-sqlite": "electron-rebuild -f -w better-sqlite3"// ...},"dependencies": {"@electron-toolkit/preload": "^3.0.1","@electron-toolkit/utils": "^3.0.0","better-sqlite3": "^11.8.1"}// ....
}

6.修改 electron-builder 配置文件

files:- '!**/.vscode/*'- '!src/*'- '!electron.vite.config.{js,ts,mjs,cjs}'- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'- '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'- '!**/better-sqlite3/{deps/**/*,src/**/*}'

7.better-sqlite3使用
新建src/main/database/index.js文件

import Database from "better-sqlite3"; // 用于操作 SQLite 数据库的库
import { app, ipcMain } from "electron"; // 用于 Electron 应用的全局功能
import path from "path"; // 用于处理和操作文件路径的模块
import fs from "fs";
let db; // 声明一个变量用来存储数据库实例// 数据库版本
const DB_VERSION = 1; // 当前数据库版本
// 初始化数据库的函数
export function initDatabase() {// 判断当前环境是否是开发环境let databasePath = path.join(app.getPath("userData"), "database");console.log(databasePath);// 确保数据库文件夹存在,如果不存在则创建它if (!fs.existsSync(databasePath)) {fs.mkdirSync(databasePath, { recursive: true });}// 初始化数据库并创建或打开指定路径的 SQLite 数据库文件db = new Database(path.join(databasePath, "uploadfile.db"), {verbose: console.log,});// 设置数据库的日志模式为 WAL(写时日志)模式,提高性能db.pragma("journal_mode = WAL");// 创建版本表createVersionTable();// 获取当前数据库版本const currentVersion = getCurrentDatabaseVersion();// 如果数据库版本不匹配,执行数据库更新if (currentVersion !== DB_VERSION) {updateDatabase(currentVersion);}// 创建表,如果表不存在则创建createTable();// 在 Electron 的主进程中注册一个 IPC 事件处理器ipcMain.handle("db_query", async (_, query, params=[]) => {const stmt = db.prepare(query); // 准备 SQL 查询return stmt.all(...params); // 执行查询并返回结果});// 在应用退出时关闭数据库连接app.on("quit", () => {db.close(); // 关闭数据库连接});
}// 创建版本表
function createVersionTable() {const createVersionTableQuery = `CREATE TABLE IF NOT EXISTS version (id INTEGER PRIMARY KEY AUTOINCREMENT,version INTEGER NOT NULL);`;db.prepare(createVersionTableQuery).run();// 检查是否有版本记录,若没有,则插入默认版本 1const currentVersion = getCurrentDatabaseVersion();if (!currentVersion) {const insertVersionQuery = `INSERT INTO version (version) VALUES (?);`;const stmt = db.prepare(insertVersionQuery);stmt.run(1); // 默认插入版本 1}
}// 更新数据库
function updateDatabase(currentVersion) {console.log(`Updating database from version ${currentVersion} to ${DB_VERSION}`);if (currentVersion === 1) {// 执行 1 -> 2 的更新操作updateToVersion2();}// 更新数据库版本记录const updateVersionQuery = `INSERT INTO version (version) VALUES (?);`;const stmt = db.prepare(updateVersionQuery);stmt.run(DB_VERSION);console.log(`Database updated to version ${DB_VERSION}`);
}// 创建任务列表表
function createTable() {const createTableQuery = `CREATE TABLE IF NOT EXISTS todo_list (user_id_role TEXT,todo_id TEXT UNIQUE,task_title TEXT,task_description TEXT,priority INTEGER,due_date TEXT,status TEXT,created_at INTEGER,updated_at INTEGER,id INTEGER PRIMARY KEY AUTOINCREMENT);`;// 执行创建表的 SQL 语句db.prepare(createTableQuery).run();
}

@src/main/index.ts文件修改

import { initDatabase } from "./database/index";
// 在启动项目里面使用
app.whenReady().then(() => { // 初始化数据库ipcMain.on("initDatabase", () => {// 初始化数据库initDatabase();});
}

页面可以直接调用

// 初始化数据库const initDatabase = () => {window.electron.ipcRenderer.send('initDatabase');}
// 获取数据库中的所有待办事项
const getTodoList = () => {// 获取数据库数据window.ipcRenderer.invoke("db_query", "SELECT * FROM todo_list;").then((res)=>{console.log('getTodoList', res);getTodoListData.value = res;}).catch((err)=>{})};

on对应send,不返回
handle对应invoke,返回

8.多窗口使用

  // 创建新窗口ipcMain.on('create-new-window', () => { if (newWindow) {// 是否是最小化if (newWindow.isMinimized()) {newWindow.restore()};newWindow.focus() // 存在 则聚焦return}newWindow = new BrowserWindow({width: 312,height: 422,show: false,autoHideMenuBar: true,...(process.platform === "linux" ? { icon } : {}),webPreferences: {preload: join(__dirname, "../preload/about.js"),sandbox: false,},});newWindow.webContents.setWindowOpenHandler((details) => {shell.openExternal(details.url);return { action: "deny" };});newWindow.on("ready-to-show", () => {newWindow.show();});// 关闭清理newWindow.on('closed', () => {newWindow = null});// HMR for renderer base on electron-vite cli.// Load the remote URL for development or the local html file for production.if (is.dev && process.env["ELECTRON_RENDERER_URL"]) {console.log("process.env['ELECTRON_RENDERER_URL']",process.env["ELECTRON_RENDERER_URL"] + "/about.html");newWindow.loadURL(process.env["ELECTRON_RENDERER_URL"] + "/about.html");} else {newWindow.loadFile(join(__dirname, "../renderer/about.html"));}});

…/preload/about.js 文件内容

import { contextBridge } from "electron";
import { electronAPI } from "@electron-toolkit/preload";// Custom APIs for renderer
const api = {};// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {try {contextBridge.exposeInMainWorld("electron", electronAPI);contextBridge.exposeInMainWorld("api", api);} catch (error) {console.error(error);}
} else {// @ts-ignore (define in dts)window.electron = electronAPI// @ts-ignore (define in dts)window.api = api
}

在这里插入图片描述
遇到问题

mac在打包win,安装完成会出现以下错误属于系统编辑问题,请使用win系统进行对应打包
请添加图片描述

npm i 安装不上,网络正常情况
npm config set registry https://registry.npmmirror.com
淘宝镜像可能会出现问题

win在打包是否出现的权限问题需要开启管理员权限

如遇到其他问题可以沟通


http://www.ppmy.cn/news/1571178.html

相关文章

RsAbC CTF解密工具

在 CTF(Capture The Flag)竞赛中,加密题是不可或缺的一部分,而 RSA 加密作为最常见的加密算法之一,常常出现在各类题目中。和大家分享一款我在 CTF 备赛过程中发现工具RsAbC,它能帮助我们解决基本RSA 加密相…

产品详情页中 品牌官网详情 对应后端的字段是 detail

文章目录 1、在这个Vue代码中,品牌官网详情 对应后端的字段是 detail2、品牌官网详情 功能相关的代码片段3、export const productSave (data: any) >4、ProductController5、ProductDto 类6、ProductApiService 1、在这个Vue代码中,品牌官网详情 对…

【推荐】爽,在 IDE 中做 LeetCode 题目的插件

大家好,我是 V 哥。 今天给大家推荐一款神器插件,废话不多说,马上开整。leetcode-editor 是一个可以在 IDE 中做 LeetCode 题目的插件仓库,以下是对该仓库的详细介绍: 来看一下这个神器是啥 基本信息 名称&#xff…

如何修改DNS解析?

DNS(域名系统)就像互联网的“电话簿”,负责将我们输入的网址转换为计算机能够理解的IP地址。如果DNS解析出现问题,访问网站就会受到影响。那我们该如何修改DNS解析呢?接下来,我们就来介绍一下这个话题。 为什么要修改DNS解析? 使用默认的…

JVM栈帧中|局部变量表、操作数栈、动态链接各自的任务是什么?

局部变量表和动态链接确实在栈帧中存在,用于存储方法的参数、局部变量和方法的动态链接信息(如常量池索引等),但这些并不等同于操作数栈。 让我们理清楚两者之间的区别和它们各自的作用。 🚀 栈帧和操作数栈的关系 1…

网络编程-day4-TPC之文件传输

服务器 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <semaphore.h> #includ…

c++ template-3

第 7 章 按值传递还是按引用传递 从一开始&#xff0c;C就提供了按值传递&#xff08;call-by-value&#xff09;和按引用传递&#xff08;call-by-reference&#xff09;两种参数传递方式&#xff0c;但是具体该怎么选择&#xff0c;有时并不容易确定&#xff1a;通常对复杂类…

DeepSeek 与网络安全:AI 驱动的智能防御

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 随着人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;深度学习技术正渗透到多个领域&#xff0c;从医疗诊断到…