实战桌面端markdown编辑器入门Electron

前言

由于好奇Electron技术加上著名的markdown编辑器Typora宣布收费,于是就想借着开源的bytemd实现自己的markdown编辑器,顺便记录下在使用Electron中的踩的一些坑

开源项目地址:https://github.com/andyqier88/omd ,欢迎star~

Electron架构

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

electron.png
图截自Shelley Vohr 在 JSHeroes 演讲PPT

electronexcalidraw.png

Electron是整合了Chromium和Node.js,将Node.js集成到了Chromium;

如何将Node.js 集成到 Chromium

如下图Electron 起了一个新的安全线程去轮询 backend_fd,当 Node.js 有一个新的事件后,通过 PostTask 转发到 Chromium 的事件循环中,这样就实现了 Electron 的事件融合。

electron-nodejs.png

截自Shelley Vohr 在 JSHeroes 演讲PPT

工程搭建

借助vue/cli 和 electron-builder

  1. 安装Vue脚手架,若已安装则可以跳过,未安装可用如下方式安装

    yarn global add @vue/cli
    
  1. 创建项目

    vue create electronmd
    
  1. 配置Electron

    cd electronmd
    ​
    vue add electron-builder
    
  2. 启动

    yarn electron:serve
    

项目中用到的技术&业务实现

项目搭建好后,先确定下初步的关键需求,我们是想实现一个简单的markdown文档编辑工具

  1. markdown相关功能(集成bytemd)
  2. 把编辑好的内容保存(CTRL+S)成.md文件
集成bytemd

这个集成过程非常简单

通过包管理工具yarn add bytemd、相关插件(@bytemd/plugin-highlight等)、主题这里用的是github-markdown-css github的主题,社区还有很多其他主题,可以自行选择也可以自己定制。

集成完的代码:

<template>
  <Editor :value="value" :plugins="plugins" :fullscreen="true" @change="handleChange" />
</template>
​
<script>
import 'bytemd/dist/index.css'
import 'github-markdown-css/github-markdown.css'
import { Editor } from '@bytemd/vue-next'
import gfm from '@bytemd/plugin-gfm'
import mediumZoom from '@bytemd/plugin-medium-zoom'
import frontmatter from '@bytemd/plugin-frontmatter'
import highlight from '@bytemd/plugin-highlight'
import mermaid from '@bytemd/plugin-mermaid'
const plugins = [
  gfm(),
  mediumZoom(),
  frontmatter(),
  mermaid(),
  highlight()
  // Add more plugins here
]
​
export default {
  components: { Editor },
  data() {
    return { value: '', plugins }
  },
  methods: {
    // 获取编辑的内容
    handleChange(v) {
      console.log(v);
      this.value = v
    }
  }
}
</script>

集成好markdown编辑器后,通过electron主进程和渲染进程通信,来实现文件保存的功能,实现代码逻辑如下:监听keyup 事件,在.vue组件中监听

window.addEventListener('keyup', this.handleKeyPress, true)
handleKeyPress (event) {
  // You can put code here to handle the keypress.
  if(event.ctrlKey&&event.keyCode==83){
    // 向IPC通道发送信号,此时主线程收到信号立即执行相对应的响应函数
    window.electron.ipcRenderer.send('open-save-chart-dialog',this.value);
  }
},
踩坑-填坑方案

在实现上边代码之前遇到的一个问题就是,在.vue文件中使用electron API时webpack识别不了的一个报错

解决办法:

  1. 首先新建一个preload.js文件

    import { contextBridge, ipcRenderer } from "electron";
    contextBridge.exposeInMainWorld("electron", {
     ipcRenderer,
    });
    
  1. 其次在vue.config.js中配置

    pluginOptions: {
      electronBuilder: {
        preload: "./src/preload.js"
      }
    }
    
  1. 然后在electron main.js中在new BrowserWindow对象中配置webPreferences 如下代码:

    webPreferences: {
      preload: path.join(__dirname, "preload.js") 
    }
    

在electron官方文档中也能找到说明

preload string (可选) -在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。 当 node integration 关闭时, 预加载的脚本将从全局范围重新引入node的全局引用标志 参考示例

image-20220619140356427.png
填完此坑后,我们需要把当前的编辑的内容获取到,通过主进程和渲染进程通信调用文件保存

获取编辑内容很简单,就是在集成bytemd的组件中监听change事件之后赋值

handleChange(v) {
  this.value = v
}
主进程-渲染进程通信

拿到md编辑器的内容后,我们知道md编辑器的内容是在渲染进程中,如何把内容传递给主进程调用呢,就是在渲染进程发送事件ipcRenderer.send

window.electron.ipcRenderer.send('open-save-chart-dialog',this.value);

在main.js中通过ipcMain.on监听对应的事件名称达到通信的目的

ipcMain.on('open-save-chart-dialog', (event, message) => {
  // console.log(`receive message from render: ${message}`)
  save(message)
})
保存文件

接下来是实现save(message)的逻辑,通过electron的dialog API调起文件保存提示框,借助node.js的fs模块实现文件的保存,具体实例如下:

import { dialog, ipcMain } from "electron";
let fs = require("fs");
export function save(content) {
  dialog
    .showSaveDialog({
      filters: [
        {
          name: "MD文件",
          extensions: ["md"],
        },
      ],
      properties: ["openFile"],
      defaultPath: '',
      message: "选择要导入的Mackdown文件",
      buttonLabel: "导出",
      title: "保存文件",
    })
    .then((res) => {
      console.log(res);
      fs.writeFileSync(res.filePath, content);
    })
    .catch((req) => {
      console.log(req);
    });
}
​

初次尝试electron,不禁感觉electron的强大之处,有些功能还在完善中,如果你也在使用electron,欢迎交流

项目地址:https://github.com/andyqier88/omd,欢迎star~
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值