likes
comments
collection
share

使用Electron打桌面端需要知道哪些

作者站长头像
站长
· 阅读数 48

Electron 打桌面端

Electron 是一个使用 JavaScript、HTMLCSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验

简单来说就是他有俩关键api, loadFile、loadURL,就是加载一个html、还是加载一个网页url。其他的就都是Electron内置的能力了,比如拖动、支持拉伸、缩小。就跟你使用的桌面应用一样。

Electron 解决了使用 Web 技术构建跨平台桌面应用程序的难题,并极大地简化了桌面应用程序的开发过程。

相比web端也不用考虑客户哪里浏览器兼容性了,因为Electron会根据你选用的版本会使用不同的谷歌浏览器版本。

两种构建方式

electron-builder@electron-forge都是用于打包和部署 Electron 应用程序的工具,都能帮咱们打包出安装包,以下会相对说下这俩种打包方式的区别。

  • 配置方式:electron-builder 支持使用配置文件或命令行参数进行配置,而 @electron-forge 使用一个专用的 forge.config.js 文件来配置应用程序。这使得 @electron-forge 更易于理解和管理,尤其是对于需要更多自定义的项目来说。

  • 项目结构:electron-builder 可以适应各种项目结构,而 @electron-forge 假设您的项目遵循特定的约定和结构。这意味着如果您的项目与预期的结构不同,您可能需要手动调整配置或项目结构才能使用 @electron-forge

  • 功能特性:electron-builder 提供了许多功能特性,如自动更新、代码签名、翻译等。而 @electron-forge 的特点主要集中在提供一些常见任务的默认实现(例如启动应用程序、创建菜单栏、处理捆绑依赖项等),这使得开发人员可以更快速地开始并快速构建应用程序。

  • 社区支持:由于 electron-builder 更早出现,因此它拥有比 @electron-forge 更广泛的社区支持。这意味着您可以更容易地找到有关 electron-builder 的文档、教程和支持资源。

说下本人使用心得我一开始选择是 @electron-forge 的,确实省事直接给你打包出来一个ext直接用。

缺点:

不能配置,没找到相关配置图标、title再或者用户自定义引导安装也没有,完全就是点一下exe文件整个就算是安装成功了。

优点: 当使用者没有更多自定义配置需求选择这个确实省心。

electron-builder 就能满足我本次开发迭代能支持自定义图标、title以及用户自定义引导安装,看起来更像是一个完整的桌面包装包, 提供一份我的package.json,使用了cross-env区分开发环境、生产环境。

{
  "name": "electron-builder-app",
  "version": "1.0.0",
  "description": "桌面应用",
  "main": "src/main.js",
  "scripts": {
    "start": "cross-env NODE_ENV=development electron .",
    "build": "electron-builder"
  },
  "keywords": [],
  "author": "所属组织",
  "license": "ISC",
  "devDependencies": {
    "cross-env": "^7.0.3",
    "electron": "^18.2.0",
    "electron-builder": "^23.0.3"
  },
  "build": {
    "appId": "com.example.app", 
    "productName": "你的应用名称",
    "directories": {
      "output": "out"
    },
    "files": [
      "package.json",
      "src/**/*"
    ],
    "win": {
      "target": ["nsis"],
      "icon": "src/logo.png"
    },
    "nsis": {                          
      "oneClick": false,              
      "language": "2052",              
      "perMachine": true,              
      "allowToChangeInstallationDirectory": true   
    }
 }
}

electron 的一些常用配置

有一些使用到的electron应用程序的常用设置如下:

设置窗口大小和样式

const { BrowserWindow } = require('electron');

// 创建窗口
const mainWindow = new BrowserWindow({
  width: 800, // 设置初始化大小
  height: 600, // 设置初始化大小
  webPreferences: {
    // 允许使用Node.js API
    nodeIntegration: true
  }
});

// 加载应用界面
mainWindow.loadFile('index.html');

设置打开应用撑满整个全屏

const { BrowserWindow, screen } = require('electron');

// 创建窗口
const { width, height } = screen.getPrimaryDisplay().workAreaSize;

const mainWindow = new BrowserWindow({
  width, // 设置初始化大小
  height, // 设置初始化大小
  webPreferences: {
    // 允许使用Node.js API
    nodeIntegration: true
  }
});
// 加载应用界面
mainWindow.loadFile('index.html');

设置默认居中、title、icon

const { BrowserWindow } = require('electron');

// 创建窗口
const mainWindow = new BrowserWindow({
  width: 800, // 设置初始化大小
  height: 600, // 设置初始化大小
  center: true, // 居中
  icon: path.resolve(__dirname, 'logo.png'), // icon
  webPreferences: {
    preload: path.join(__dirname, 'preload.js')
  },
   title: '自定义title',
});

// 加载应用界面
mainWindow.loadFile('index.html');

设置初始化是否可以支持拉伸

设置初始化是否可以支持拉伸,以及动态设置是否可拉伸

const { BrowserWindow } = require('electron');

// 创建窗口
const mainWindow = new BrowserWindow({
  width: 800, // 设置初始化大小
  height: 600, // 设置初始化大小
  resizable: false, // true是可以拉伸,false为不可拉伸
  webPreferences: {
    preload: path.join(__dirname, 'preload.js')
  },
   title: '自定义title',
});

// 加载应用界面
mainWindow.loadFile('index.html');

// 可以再某个时机设置为是否可拖拽
mainWindow.setResizable(true);

打开开发者工具

mainWindow.webContents.openDevTools();

隐藏窗口边框和标题栏

mainWindow.setFramelessWindow(true);

禁止缩放和最小化窗口

mainWindow.setResizable(false);
mainWindow.setMinimizable(false);

监听导航更改

mainWindow.webContents.on('did-start-navigation',(_, url)=>{
  if(url.endsWith('home') || url.endsWith('home/')) {
    mainWindow.setSize(1080, 720, true);
    mainWindow.setResizable(true);
  }
});

去掉默认菜单栏

const { Menu } = require('electron')
Menu.setApplicationMenu(null);

设置快捷键

const { globalShortcut  } = require('electron')
globalShortcut.register('Alt+CommandOrControl+Shift+D', () => { 
  mainWindow.webContents.openDevTools({mode:'detach'}) //开启开发者工具
});

监听打开子窗口并做些设置

mainWindow.webContents.setWindowOpenHandler(({ url }) => {
  return { // 设置子窗口得配置
    action: 'allow',
    overrideBrowserWindowOptions: {
      fullscreenable: false,
      backgroundColor: 'black',
      width: 1080,
      height: 720,
      resizable: false,
      center: true,
      icon: path.resolve(__dirname, 'logo.png'),
      webPreferences: {
        preload: path.join(__dirname, 'preload.js')
      },
      title: '自定义title',
    }
  }
})

忽略访问得是https证书问题

const { app } = require('electron')
app.commandLine.appendSwitch("--disable-http-cache");
app.commandLine.appendSwitch('ignore-certificate-errors', true);

完整得使用配置main.js如下:

const { app, BrowserWindow, screen, Menu, globalShortcut,  } = require('electron')
const path = require('path')

const isDev = process.env.NODE_ENV === 'development';
app.commandLine.appendSwitch("--disable-http-cache");
app.commandLine.appendSwitch('ignore-certificate-errors', true);
Menu.setApplicationMenu(null);

function createWindow () {
  // const { width, height } = screen.getPrimaryDisplay().workAreaSize;
  const win = new BrowserWindow({
    width: 1080,
    height: 720,
    resizable: false,
    center: true,
    icon: path.resolve(__dirname, 'logo.png'),
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    },
    title: 'XXXXX',
  });

 const webContents =  win.webContents
  win.loadURL('https://www.baidu.com/');

  webContents.setWindowOpenHandler(({ url }) => {
      return {
        action: 'allow',
        overrideBrowserWindowOptions: {
          fullscreenable: false,
          backgroundColor: 'black',
          width: 1080,
          height: 720,
          resizable: false,
          center: true,
          icon: path.resolve(__dirname, 'logo.png'),
          webPreferences: {
            preload: path.join(__dirname, 'preload.js')
          },
          title: 'XXXXX',
        }
      }
  })

    webContents.on('did-start-navigation',(_, url)=>{
      if(url.endsWith('home') || url.endsWith('home/')) {
        win.setSize(1080, 720, true);
        win.setResizable(true);
      }
      console.log('did-start-navigation', url);
    });

  if(isDev) {
    win.webContents.openDevTools();
  }
  
  globalShortcut.register('Alt+CommandOrControl+Shift+D', () => {
    win.webContents.openDevTools({mode:'detach'}) //开启开发者工具
  });
  return win;
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

electron 检测断网情况

再开发CS应用需要考虑下断网情况,然后展示对应得断网重连界面,在Electron应用程序中检测断网,您可以使用Node.js的net模块来进行网络连接检测。以下是一个示例代码:

const { app } = require('electron');
const net = require('net');

function checkInternetConnection() {
  const socket = net.createConnection({
    host: 'www.google.com',
    port: 80
  });

  socket.on('connect', () => {
    console.log('Internet connection is available');
    socket.end();
  });

  socket.on('error', (error) => {
    console.error('No internet connection:', error.message);
  });
}

app.whenReady().then(checkInternetConnection);

为了保持持续的互联网连接检测,可以使用定时器在一定时间间隔内定期运行检测函数。这样可以实时监测网络连接状态,并及时处理断网情况。

我们是使用的另外一种方式如下原理是差不多得(一直使用定时器获取login html,然后判断断网loadFile对应得html):

const https = require('https');

const https_options = {
  hostname: 'XXXXXXX',
  port: 443,
  path: '/login',
  method: 'GET',
  rejectUnauthorized: false, // 忽略 SSL 证书错误
  timeout: 4000
};

setInterval(() => {
  https.get(https_options, (res) => { //
     if (res.statusCode != 200) {
        console.log('Offline!');
        win.loadFile('offline.html'); // 这个是断网得html。
      }
  }).on('error', (e) => {
    console.error(`Bad Request: ${e.message}`);
  });
}, 5000);


win.webContents.on('did-fail-load', (event, errorCode) => {
  if (errorCode === -106) { // ERR_INTERNET_DISCONNECTED
    win.loadFile('offline.html');
  }
});

再点击offline.html重新检测按钮后对应得js是

document.getElementById('retry').addEventListener('click', () => {
     // 重新拉取下登录html 进行检测 
    fetch('xxxxxxx').then(response => {
        window.location.href = '';
        console.log("Network is offline in disconnection page.");
    }).catch(error => {
        console.error("Still offline, please check the network!");
    })
});

结语

以上就是使用electron 方法集成日志实践以及相关总结。如果对您有帮助欢迎点赞收藏关注。

转载自:https://juejin.cn/post/7252278941137502245
评论
请登录