2026/10/23 12:45:11

Electron 打包 HTML 为全屏 exe:遮任务栏、Esc 退出与图标替换

Electron 打包 HTML 为全屏 exe:遮任务栏、Esc 退出与图标替换 简介这份资源面向希望把本地HTML网页封装成Windows桌面程序的开发者尤其适合刚接触Electron、需要快速产出可交付exe的初中级前端或全栈人员。内容围绕Electron框架展开覆盖HTML/CSS/JS资源打包、BrowserWindow全屏显示、隐藏任务栏、监听Esc键退出以及通过electron-packager或electron-builder自定义exe图标与文件名等关键环节并涉及版本管理、错误处理与跨平台测试思路。压缩包共约2000个文件以js、ts、map、json、md、license等源码与依赖文件为主另有pak、dll、exe等运行时资源整体约95.61MB目录结构完整便于直接运行与二次修改。目前已有1161人学习下载可作为从网页到桌面应用落地的参考工程帮助读者理解主进程与渲染进程通信、打包参数配置及常见排错路径。1. 从网页到桌面程序为什么我选 Electron 做 HTML 打包手里有一个写好的 HTML 页面可能是数据看板、可能是触屏查询机界面、也可能是内部培训课件现在需要把它变成一个双击就能打开的 exe还要全屏、盖住任务栏、按 Esc 退出、图标和文件名都得换成自己的。这种需求在展厅大屏、工厂工位机、学校机房这类场景里特别常见——浏览器一开地址栏就露出来用户随手就能关掉或者跳走体验完全不可控。Electron 就是干这个的它把 Chromium 和 Node.js 打包进一个可执行文件你的 HTML 跑在里面就像一个独立桌面程序。相比直接让用户开浏览器访问Electron 方案能控制窗口尺寸、隐藏菜单栏、拦截键盘事件、自定义图标还能在需要的时候调用本地文件系统。这篇就按「能干什么 → 怎么跑起来 → 怎么改」的顺序把整个打包流程拆一遍包括全屏遮任务栏、Esc 退出、图标和文件名替换这些具体操作。2. 环境搭建与项目骨架从零到能跑的第一个窗口2.1 安装 Node.js 与初始化项目Electron 本身就是一个 npm 包所以第一步是把 Node.js 装好。去 Node.js 官网下载 LTS 版本安装时勾选「Add to PATH」装完在命令行里验证node -v npm -v两条命令都能输出版本号就说明环境没问题。接下来建一个空文件夹作为项目根目录比如叫html-to-exe进去之后初始化mkdir html-to-exe cd html-to-exe npm init -ynpm init -y会生成一个默认的package.json里面记录了项目名、版本、入口文件等信息。这个文件后面要改因为 Electron 的入口不是默认的index.js而是我们指定的主进程文件。2.2 安装 Electron 并理解它的依赖结构安装 Electron 用一条命令npm install electron --save-dev这里用--save-dev是因为 Electron 只是开发期和打包期的工具最终产物是打包好的 exe不需要用户再装 Electron。安装过程会下载一个几百 MB 的 Chromium 二进制包国内网络环境下可能会慢常见做法是配置 npm 镜像源npm config set registry https://registry.npmmirror.com装完之后node_modules里会出现electron目录里面包含可执行文件。package.json的devDependencies里会多出一行electron: ^版本号。2.3 项目目录结构与主进程入口一个最小可用的 Electron 项目结构是这样的html-to-exe/ ├── package.json ├── main.js # 主进程入口 ├── preload.js # 预加载脚本可选 └── src/ └── index.html # 你的网页main.js是主进程负责创建窗口、控制窗口行为src/index.html就是你要展示的网页。package.json里要把main字段指向main.js{ name: html-to-exe, version: 1.0.0, main: main.js, scripts: { start: electron . } }改完之后运行npm start如果一切正常会弹出一个默认的 Electron 窗口。这一步先确认环境通了再往下做全屏和退出逻辑。3. 核心功能实现全屏、遮任务栏、Esc 退出与图标替换3.1 创建全屏窗口并遮住任务栏Electron 创建窗口用BrowserWindow全屏和遮任务栏的关键在构造参数。下面是一个完整的主进程代码const { app, BrowserWindow, globalShortcut } require(electron); const path require(path); let mainWindow null; function createWindow() { mainWindow new BrowserWindow({ width: 1920, height: 1080, fullscreen: true, // 全屏 frame: false, // 去掉标题栏和边框 kiosk: true, // kiosk 模式强制全屏并遮任务栏 alwaysOnTop: true, // 置顶防止被其他窗口盖住 skipTaskbar: true, // 不在任务栏显示 icon: path.join(__dirname, build/icon.ico), // 窗口图标 webPreferences: { preload: path.join(__dirname, preload.js), contextIsolation: true, nodeIntegration: false } }); mainWindow.loadFile(path.join(__dirname, src/index.html)); // 按 Esc 退出 mainWindow.webContents.on(before-input-event, (event, input) { if (input.key Escape input.type keyDown) { app.quit(); } }); } app.whenReady().then(() { createWindow(); app.on(activate, () { if (BrowserWindow.getAllWindows().length 0) createWindow(); }); }); app.on(window-all-closed, () { app.quit(); });逐段说明fullscreen: true让窗口占满屏幕但某些系统下任务栏仍可能弹出。kiosk: true是更彻底的全屏模式它会强制窗口覆盖整个屏幕并阻止用户退出任务栏被完全遮住。这是展厅、工位机场景最常用的配置。frame: false去掉系统自带的标题栏和关闭按钮防止用户点 X 关掉。alwaysOnTop: true保证窗口不会被其他程序盖住适合需要长期展示的场景。skipTaskbar: true让程序不在任务栏显示图标进一步减少用户误操作的可能。icon指定窗口左上角图标Windows 下用.ico格式macOS 用.icnsLinux 用.png。before-input-event是拦截键盘输入的关键。这里监听Escape键的keyDown事件触发app.quit()退出程序。注意要判断input.type keyDown否则按键抬起时也会触发一次。提示如果kiosk: true导致调试时无法退出可以在开发阶段先注释掉这行等打包前再打开。3.2 修改 exe 图标和文件名开发阶段窗口图标已经通过icon参数设置了但最终 exe 文件的图标和文件名需要在打包时指定。打包用electron-builder先安装npm install electron-builder --save-dev然后在package.json里加build配置{ build: { appId: com.example.htmltoexe, productName: MyApp, directories: { output: dist }, win: { target: nsis, icon: build/icon.ico }, nsis: { oneClick: false, allowToChangeInstallationDirectory: true, createDesktopShortcut: true, shortcutName: MyApp } } }参数说明productName决定最终 exe 的文件名比如设为MyApp产物就是MyApp Setup 1.0.0.exe和安装后的MyApp.exe。win.icon指定 exe 图标必须是 256x256 的.ico文件否则打包会报错。nsis.oneClick设为false会生成带安装向导的安装包用户可以选择安装路径设为true则是一键安装。shortcutName是桌面快捷方式的名字。图标文件放在项目根目录的build文件夹下命名为icon.ico。如果没有现成的 ico可以用在线工具把 png 转成 ico注意尺寸要包含 256x256。3.3 打包命令与产物验证在package.json的scripts里加一条打包命令{ scripts: { start: electron ., build: electron-builder --win } }运行npm run build打包完成后dist目录下会出现安装包和免安装的win-unpacked文件夹。双击win-unpacked里的 exe 验证是否全屏、任务栏是否被遮住、按 Esc 是否退出、图标和文件名是否正确。如果图标没变检查 ico 文件是否包含 256x256 尺寸如果任务栏没遮住确认kiosk: true是否生效。4. 避坑与常见问题排查4.1 打包后白屏或页面加载失败现象开发时npm start正常打包后打开 exe 是白屏。原因loadFile的路径用了相对路径打包后文件结构变了找不到 HTML。解决统一用path.join(__dirname, src/index.html)这种基于__dirname的绝对路径。如果 HTML 里引用了 CSS、JS、图片也要用相对路径并且确保这些文件被包含在打包产物里。electron-builder默认会打包项目根目录下除node_modules开发依赖外的所有文件但最好在build.files里显式声明{ build: { files: [ main.js, preload.js, src/**/* ] } }4.2 Esc 退出不生效现象按 Esc 没反应程序不退出。原因焦点不在webContents上或者事件被页面里的 JavaScript 拦截了。解决before-input-event是挂在webContents上的只要窗口有焦点就能触发。如果页面里有输入框或者某些库监听了键盘事件并preventDefault可能会影响。可以在页面里也加一个监听作为兜底document.addEventListener(keydown, (e) { if (e.key Escape) { window.close(); } });但window.close()在 Electron 里默认只能关闭由脚本打开的窗口所以更稳妥的做法是通过 preload 暴露一个退出方法或者直接用主进程的before-input-event。4.3 任务栏遮不住现象fullscreen: true了但鼠标移到屏幕底部任务栏还是弹出来。原因Windows 的任务栏在某些情况下会覆盖全屏窗口尤其是窗口没有置顶时。解决加上kiosk: true和alwaysOnTop: true。kiosk模式是专门为这种场景设计的它会阻止任务栏弹出。如果还不行检查是否有多显示器窗口可能创建在了副屏上。4.4 图标不生效现象打包后 exe 图标还是默认的 Electron 图标。原因ico 文件尺寸不对或者路径配置错误。解决确认build/icon.ico存在且包含 256x256 尺寸。electron-builder对 ico 文件要求比较严格建议用专业工具生成。另外win.icon的路径是相对于项目根目录的不要写成绝对路径。4.5 安装包体积过大现象打包出来的安装包几百 MB。原因Electron 本身包含 Chromium 和 Node.js体积天然就大。解决这是 Electron 的固有特性无法根本解决。可以通过electron-builder的asar压缩、排除不必要的文件来减小一些体积但预期管理要做好——Electron 应用的安装包通常在 50MB 到 150MB 之间。5. 二次开发与改造思路从能跑到好用5.1 把网页内容做成可配置如果这个 exe 要给多个场景用每次改 HTML 都要重新打包就很麻烦。常见做法是把 HTML 内容外置程序启动时读取同目录下的config.json或者直接加载外部 HTML 文件const fs require(fs); const configPath path.join(path.dirname(app.getPath(exe)), config.json); let targetUrl src/index.html; if (fs.existsSync(configPath)) { const config JSON.parse(fs.readFileSync(configPath, utf-8)); targetUrl config.url || targetUrl; } mainWindow.loadFile(targetUrl);这样运维人员只需要改config.json里的地址不用重新打包。如果加载的是远程 URL把loadFile换成loadURL即可。5.2 增加退出密码或组合键Esc 直接退出在生产环境可能太随意可以改成组合键比如CtrlShiftQmainWindow.webContents.on(before-input-event, (event, input) { if (input.control input.shift input.key.toLowerCase() q) { app.quit(); } });或者弹一个密码框验证通过才退出。这样既能防止误触又保留了维护通道。5.3 禁用右键菜单和开发者工具展厅场景不希望用户右键或者按 F12 打开开发者工具可以在主进程里禁用mainWindow.webContents.on(context-menu, (e) { e.preventDefault(); }); globalShortcut.register(CommandOrControlShiftI, () { return false; });context-menu事件拦截右键菜单globalShortcut拦截开发者工具快捷键。注意globalShortcut要在app.whenReady()之后注册。5.4 自动更新与版本管理如果程序部署在多台机器上手动更新很痛苦。electron-builder配合electron-updater可以实现自动更新。基本思路是在package.json里配置publish地址主进程里监听更新事件const { autoUpdater } require(electron-updater); app.whenReady().then(() { autoUpdater.checkForUpdatesAndNotify(); });自动更新需要有一个文件服务器或者对象存储来放安装包和latest.yml文件。对于内部使用的场景也可以简单点——程序启动时请求一个版本接口发现新版本就提示用户下载。5.5 性能与内存优化Electron 应用的内存占用一直是槽点。如果页面本身不复杂可以在webPreferences里关掉一些不必要的功能webPreferences: { preload: path.join(__dirname, preload.js), contextIsolation: true, nodeIntegration: false, enableRemoteModule: false, spellcheck: false, backgroundThrottling: false }backgroundThrottling: false在需要后台持续运行的场景下有用但会增加 CPU 占用。另外如果页面只是静态展示可以考虑用BrowserView或者WebContentsView替代BrowserWindow减少一层窗口管理的开销。从那以后我每次打包前都会强制走一遍检查清单ico 尺寸对不对、kiosk开没开、Esc 逻辑测没测、config.json路径对不对。这几步花不了五分钟但能省掉现场部署时的一堆麻烦。希望帮到你。本文还有配套的精品资源点击获取