美文网首页前端Project - IM
Electron - 工程开发Tips

Electron - 工程开发Tips

作者: 红薯爱帅 | 来源:发表于2021-10-22 20:56 被阅读0次

    1. 概述

    本文介绍Electron项目开发的一些经验和坑,主要是基于Electron的IM项目。

    2. 开发基础

    2.1. Vue和React脚手架

    2.2. Electron Store

    2.3. Electron多窗口 + 托盘 + 截图

    https://www.cnblogs.com/xiaoyan2017/p/14403820.html
    https://github.com/nashaofu/dingtalk
    https://www.cnblogs.com/xiaoyan2017/p/14454624.html
    https://www.cnblogs.com/xiaoyan2017

    2.4. Default Path

    • 自动升级的安装包下载路径
      C:\Users\Administrator\AppData\Local\foxchat-updater

    • electron-log的默认路径
      C:\Users\Administrator\AppData\Roaming\FoxChat\logs

    3. Electron samples

    3.1. fsharechat

    商业项目,基于Vue的UI,看着不错
    还有webrtc功能,做音视频时可以参考
    https://github.com/fsharechat/vue-chat
    https://github.com/han960619/Vue-chat
    https://han960619.github.io/Vue-chat/#/chat

    3.2. aermin

    react的im,不错的项目,可以重点学习,有正在运行的实例
    没有用第三方组件库,而是react原生的组件
    https://github.com/aermin/ghChat
    https://im.aermin.top

    3.3. chat-react

    可以跑起来,前端react,后端go,数据库用mysql
    UI一般,没有太多参考的价值
    后端用Go写的,有空可以学习下

    go run .
    yarn start
    

    https://gitee.com/ltly/chat-react
    https://gitee.com/ltly/chat-online

    4. Feature

    开发IM客户端时,实现Feature过程的思考

    4.1. emoji feature

    emoji-mart

    https://github.com/missive/emoji-mart

    优点:表情很丰富,功能也很全,支持自定义emoji

    缺点:

    • 单个emoji的展示,需要自己完成
    • 加载很多emoji时候,很卡,尤其是第一次
    • emoji不会动,不美观

    third party: rich editor

    https://ant.design/docs/react/recommendation
    https://github.com/zenoamaro/react-quill
    https://github.com/margox/braft-editor
    功能都挺全,用在IM里面有点重(不用支持表情和文本即可,不用加粗、斜体、字号等),所以暂且舍弃

    react-contenteditable

    https://github.com/lovasoa/react-contenteditable
    https://codesandbox.io/s/l91xvkox9l
    符合IM当前需求,可以自定义支持的tag,很赞~
    渲染前,通知sanitize-html消一下毒
    https://github.com/apostrophecms/sanitize-html
    渲染时候,通过dangerouslySetInnerHTML渲染即可
    https://www.pluralsight.com/guides/how-to-render-html-in-state-string

    4.2. catch chat input focus

    方法1,removeAllRanges之后,lastRange又回到了开始位置0,怀疑是引用导致,在失去焦点时候,改成document.getSelection().getRangeAt(0).cloneRange()也不行

    if (this.state.lastRange) {
      selection.removeAllRanges()
      selection.addRange(this.state.lastRange)
    }
    

    但是,下面这个例子是work的。很奇怪,有时间再深入研究
    https://segmentfault.com/a/1190000005869372

    方法2,步骤和优缺点如下

    • 失去焦点onBlur时候,记录range.endOffset
    const lr = document.getSelection().getRangeAt(0)
    lastRangeEndOffset = lr.endOffset // number
    
    • 获取到焦点时候,设置光标位置
    const obj = document.getElementById("inputbox")
    selection?.collapse(obj, lastRangeEndOffset)
    

    优缺点

    • 优点:记录input失去焦点是光标位置,下次获取焦点,能够成功插入,在两个场景上体验较好:input没有获取焦点时,点击表情面板并输入表情;input没有获取焦点时,键盘输入可见字符时。

    • 缺点:当text和emoji混合时,记录的光标位置,可能是基于Text的,也可能是基于整个nodeList的,所以,恢复焦点时,设置光标位置,就不能简单的如上操作。会导致光标位置不正确,或者js报错(当lastRangeEndOffset > nodeList.length时)

    方法3,input非焦点时,点击输入emoji或者键盘输入可见字符时,直接插入到最后即可

    var selection = document.getSelection()
    const obj = document.getElementById("inputbox")
    selection?.collapse(obj, obj.childNodes.length)
    

    飞书的做法:只支持emoji输入到既定光标上。当键盘输入字符时,默认插入到最后,而且当输入中文时,第一个字母会丢失(原因是用于获取focus,上述3个方法同样存在)。

    综合对比,采用方法3,逻辑清晰,体验还好。

    5. 坑

    5.1. change BrowserRouter to HashRouter

    React assets图片,在build之后,经过react-route之后,会报错404,解决办法:

    • import
    import { Image } from 'antd';
    import imgUrl from '../../assets/images/coding.png'
    
    <Image preview={false} src={imgUrl}/>
    <img src={imgUrl}></img>
    

    5.2. ipcMain.handle

    同一个channel只能被ipcMain.handle只能注册一次,第二次注册会被block住(莫名其妙,还不错报个错),如果想第二次注册成功,需要先调用ipcMain.removeHandler
    https://www.electronjs.org/docs/api/ipc-main#ipcmainremovehandlerchannel

    5.3. auto-updater取错本地版本号

    electron-updater自身的bug,会去取Electron的版本
    解决方案: 修改electron-updater中appUpdater.js中isUpdateAvailable函数代码

    const pkg=require('../../../package.json');
    const isLatestVersionNewer = (0, _semver().gt)(latestVersion, pkg.version);
    

    5.4. Proxy

    Linux的proxy,只支持10.0.0.0/8,不支持10.*
    Windows下,通过cygwin64,也应该如下配置no_proxy,否则通过yarn electron-builder --publish always,也会发布失败。例如:

    $ export no_proxy=localhost,10.0.0.0/8,127.0.0.1,::1
    

    相关文章

      网友评论

        本文标题:Electron - 工程开发Tips

        本文链接:https://www.haomeiwen.com/subject/lzyhaltx.html