【electron】5分钟把网页打包成可安装的exe桌面应用

老板们突发奇想,把现有的一个管理后台系统打包成桌面端可安装应用,当时我脑海就浮现出两套方案,Electron或Flutter的Webview来打包应用,相对来说Electron熟悉点,就优先考虑了使用Electron,当然后来也使用Flutter实现了一版,效果差别不大,我们先来看看Electron是怎么实现的。

准备工作

初始化项目

新建项目文件夹electron-app,记得在命令行窗口把路径切换到electron-app目录下,执行初始化命令

shell 复制代码
npm init -y

最新的文件结构应该如下所示,多了一个package.json文件。

markdown 复制代码
- electron-app
    - package.json

用编辑器打开package.json

json 复制代码
{
  "name": "electron-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

要特别注意里面"main"这项配置,这个配置指向了项目的入口,目前对应的文件是index.js,但我们项目中还没有,那就新建一个。

markdown 复制代码
- electron-app
    - index.js
    - package.json

填充index.js文件内容如下

js 复制代码
// index.js
​
const { app, BrowserWindow } = require('electron')
​
const createWindow = () => {
​
    // 创建浏览器窗口
    const win = new BrowserWindow({
      autoHideMenuBar: true,
    })
​
    // 全屏
    win.maximize()
    
    // 载入网页链接
    win.loadURL('https://www.jd.com/')
}
​
// 应用程序准备好后加载窗口
app.whenReady().then(() => {
    createWindow()
​
    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})
​
// 窗口关闭后退出应用程序
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})

上面的代码中我们只需要关注createWindow中内容即可,createWindow方法中使用了BrowserWindow创建应用窗口并且载入一个网页链接(JD首页),正常来说我们启动程序后应该能看到一个京东的桌面端应用了。

安装依赖electron@electron-forge/cli

css 复制代码
npm install --save-dev electron @electron-forge/cli

安装完毕后继续修改package.jsonscripts配置,删除原来的内容,新增一条start配置,其中的electron-forge start命令是安装了@electron-forge/cli才可以使用的,类似@vue/cli

json 复制代码
"scripts": {
    "start": "electron-forge start"
},

启动

shell 复制代码
npm run start

大功告成,恭喜你已经学会开发桌面端应用了,只需要把win.loadURL('https://www.jd.com/')的链接替换成你想要的链接即可。

虽然项目是跑起来了,但是我们还有几个问题要解决。

  • 项目左上角的icon图标不对
  • 如何打包成exe安装包?

修改ICON

icon需要分为两部分,一个是打开的窗口左上角的图标,一个是安装到桌面的图标,安装的图标我们稍后再说,先来修改左上角的。

非常简单,修改BrowserWindowicon配置即可。

js 复制代码
// index.js
​
// 创建浏览器窗口
const win = new BrowserWindow({
    autoHideMenuBar: true,
    // 左上角的图标
    icon: './images/logo.png',
})

别忘了在根目录下新建一个images文件夹,且放一张名为logo.png的图片。

打包exe安装包

打exe安装包我们使用electron-builder工具包,安装命令如下。

css 复制代码
npm install --save-dev electron-builder

修改package.json,添加一条scripts命令和build配置。

json 复制代码
{
    "name": "electron-app",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "start": "electron-forge start",
        "build": "electron-builder --win" // 打包命令
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@electron-forge/cli": "^6.2.1",
        "electron": "^25.4.0",
        "electron-builder": "^24.6.3"
    },
    // `electron-builder`配置
    "build": {
        "productName": "我的应用", // 安装应用后桌面名称
        "directories": {
            "output": "out" // 输出的文件目录
        },
        "win": {
            "icon": "./ico/logo.ico", // 安装的图标
            "target": [
                {
                    "target": "nsis",
                    "arch": [
                        "x64",
                        "ia32"
                    ]
                }
            ]
        },
        "nsis": {
            "oneClick": false,
            "allowElevation": true,
            "allowToChangeInstallationDirectory": true,
            "installerIcon": "./ico/logo.ico",
            "uninstallerIcon": "./ico/logo.ico",
            "installerHeaderIcon": "./ico/logo.ico",
            "createDesktopShortcut": true,
            "createStartMenuShortcut": true,
            "shortcutName": "我的应用"
        }
    }
}
​

注意,json文件不能带注释,复制上面的文本后记得注释去掉。

上面所有带icon都指向了一个文件./ico/logo.icoico图标实际上是多张不同格式的图片的集合体,用作不同屏幕尺寸下的适配,当然这里我们就不展开了,我们先去得到一个logo.ico文件来实现可安装包。

可以随便百度关键字"png转换成ico",会出来一堆在线转换的网站,我使用的是[Convertio --- 文件转换器](https://convertio.co/zh/),把logo.png丢进去即可转成一张logo.ico文件,文件下载后记得放到ico目录下。

开始打包

arduino 复制代码
npm run build

完成后查看out目录

关于electron的更多使用欢迎一起讨论。

相关推荐
秋田君2 分钟前
Vue3 + VitePress 搭建部署组件库文档平台(结合 Element Plus 与 Arco Design Vue)—— 超详细图文教程
前端·vue.js·arco design
code_Bo3 分钟前
前端使用snapdom报错问题
前端·javascript·vue.js
一壶浊酒..23 分钟前
什么是AJAX
前端·javascript·ajax
fruge3651 小时前
从零到一:我在 Rokid Glasses 上“画”出一个远程协作系统
前端
BumBle1 小时前
高频扫码场景下的去重与接口调用方案
前端·javascript
Mapmost1 小时前
半透明模型渲染全白?Mapmost Studio一招搞定
前端
SpiderPex1 小时前
JavaWeb登录模块完整实现解析:从前端点击到后端验证的全流程
前端
可乐爱宅着1 小时前
在VSCode的next.js项目中更好的使用eslint/prettier工具
前端·next.js
_大学牲1 小时前
🫡我在掘金写文章:一气之下开源 视频转无水印GIF 插件
前端·javascript
地方地方1 小时前
深入理解 instanceof 操作符:从原理到手动实现
前端·javascript