zoukankan      html  css  js  c++  java
  • 如何从0开发一个Atom组件

     

    最近用Atom写博客比较多,然后发现一个很严重的问题。。
    没有一个我想要的上传图片的方式,比如某乎上边就可以直接copy/paste文件,然后进行上传。
    然而在Atom上没有找到类似的插件,最接近的一个,也还是需要手动选择文件,然后进行上传。
    这个操作流程太繁琐,索性自己写一个插件用好了。

    成品插件下载地址:https://atom.io/packages/atom-image-uploader

    规划

    首先,我们确定了需求,要通过可以直接copy文件,然后在Atom中paste即可完成上传的操作。
    确定了以后,我们就要开始搬砖了。

    插件开发

    因为Atom是一个Electron应用:https://electronjs.org

    是使用JavaScript来开发的桌面应用,所以对于一个前端来说,简直是太美好了。
    我们先去翻看Atom的官方文档,查看关于创建插件相关的操作:
    首先我们在Atom中打开命令面板,然后输入Generate Package

    按下回车后,将会弹出一个对话框,在框中输入要建立的包名即可完成一个Package的创建。

    Atom会生成一套默认文件,并打开一个新的窗口。

    项目结构

    生成的插件目录如下:

    .
    ├── keymaps
    │   └── first-package.json
    ├── lib
    │   ├── first-package-view.js
    │   └── first-package.js
    ├── menus
    │   └── first-package.json
    ├── package.json
    ├── spec
    │   ├── first-package-spec.js
    │   └── first-package-view-spec.js
    └── styles
        └── first-package.less

    keymaps

    这里可以配置要监听的快捷键,我们可以设置一些自定义快捷键来触发一些我们插件的行为。

    {
      "atom-workspace": {
        "ctrl-alt-o": "first-package:toggle"
      }
    }

    我们可以添加各种自定义的快捷键在这里。
    Value的定义为:包名:触发的事件名
    需要注意的是:
    这里配置的快捷键还有一个作用域的概念。也就是JSON外边的那个key
    atom-workspace表示在Atom中生效
    atom-text-editor表示只在文本编辑器范围内生效。

    Atom官方文档

    lib

    这里就是存放插件主要代码的地方了。
    默认会生成两个文件:

    1. package.js
    2. package.view.js

    默认插件生成的主入口文件指向这里。

    入口文件的表现方式为一个JSON对象,可以实现如下几个函数:

    1. activate: 当Package被激活时会执行该方法,函数的签名表示会接受一个state参数,该参数是通过serialize方法传递过来的(如果有实现它的话)
    2. deactivate: 当Package失效时会出发的方法,这两个方法可以理解为React中的componentWillMountcomponentWillUnmount
    3. serialize: 也就是上边说到的那个方法,可以返回一个JSON对象供下次激活后使用
    4. 自定义快捷键对应的事件名: 每次Package被触发对应快捷键时都会执行的方法

    这里存放的是在应用菜单和编辑区域菜单栏的配置文件

    {
      "context-menu": {
        "atom-text-editor": [
          {
            "label": "Toggle first-package",
            "command": "first-package:toggle"
          }
        ]
      },
      "menu": [
        {
          "label": "Packages",
          "submenu": [
            {
              "label": "first-package",
              "submenu": [
                {
                  "label": "Toggle",
                  "command": "first-package:toggle"
                }
              ]
            }
          ]
        }
      ]
    }

    context-menu对应的元素会在对应的区域内右键触发时显示。
    menu则是出现在Atom主菜单栏上:

    同样的,context-menu会区分两个环境,text-editorworkspace

    spec

    这里存放的是一些测试用例,创建Package会生成一些默认的断言。
    写测试确实是一个好习惯。

    styles

    如果Package有很多View要展示的话,可以在这里编写,默认使用的是Less语法。
    由于我们只做一个C/V的操作,不会涉及到界面,所以styles直接就删掉了。

    开始搬砖

    大致结构已经了解了,我们就可以开始搬砖了。
    因为是一个Electron应用,所以我们直接在Atom中按下alt + command + i,呼出我们熟悉的控制台界面。

    Atom是不会把Electron的各种文档重新写一遍的,所以我们现在控制台里边试一下我们的猜测是否正确。
    一些想要的东西是否存在。

    经过验证确定了,Electronclipboard对象可以直接在Atom中使用,这就很开心了。

    require('electron').clipboard.readImage().toPng()

    这样我们就拿到剪切板中的图片数据了,一个二进制的数组对象。
    我们在触发Paste操作时,从clipboard中获取,如果剪切板中是图片的话,我们就将它上传并显示到编辑器中。
    所以,接下来我们要做的就是:

    1. 进行上传图片的操作
    2. 将上传后的图片显示到编辑器中

    上传图片

    上传图片我们选择的是七牛,我们选择七牛来作为图床使用,因为他家提供了10GB的免费存储,灰常适合自己这样的笔记型博客。
    但是用他家SDK时发现一个问题。。我将二进制数据转换为ReadStream后上传的资源损坏了-.-目前还没有找到原因。
    所以我们做了曲线救国的方式。
    将剪切板中的数据转换为Buffer然后暂存到本地,通过本地文件的方式来进行上传七牛。
    在操作完成后我们再将临时文件移除。

    try {
      let buffer = clipboard.readImage().toPng()
      let tempFilePath = 'XXX'
      fs.writeFileSync(tempFilePath, Buffer.from(buffer))
    } catch (e) {
      // catch error
    } finally {
      fs.unlink(tempFilePath) // 因为我们并不依赖于删除成功的回调,所以直接空调用异步方法即可
    }

    将上传后的资源显示到编辑器中

    因为考虑到上传可能会受到网络影响,从而上传时间不可预估。
    所以我们会先在文件中显示一部分占位文字。
    通过全局的atom对象可以拿到当前活跃的窗口:

    let editor = atom.workspace.getActiveTextEditor()

    为了避免同时上传多张图片时出现问题,我们将临时文件名作为填充的一部分。

    editor.insertText(`![](${placeHolderText})`, editor)

    然后在上传成功后,我们将对应的填充字符替换为上传后的URL就可以了。

    editor.scan(new RegExp(placeHolderText), tools => tools.replace(url))

    scan方法接收一个正则对象和回调函数。
    我们将前边用到的占位文本作为正则对象,然后在回调将其替换为上传后的url
    至此,我们的代码已经编写完了,剩下的就是一些交互上的优化。

    完成后的效果图:

    以及,最后:我们要进行Package的上传。

    上传开发完的Package

    首先我们需要保证package.json中存在如下几个参数:

    1. name
    2. description
    3. repository

    我们可以先使用如下命令来检查包名是否冲突。

    apm show 你的包名

    如果没有冲突,我们就可以直接执行以下命令进行上传了。

    apm publish 你的包名

    后续的代码修改,只需在该包的目录下执行:

    apm publish

    一些可选的参数:

    1. major,增加版本号的第一位1.0.0 -> 2.0.0
    2. minor,增加版本号的第二位0.1.0 -> 0.2.0
    3. patch,增加版本号的第三位0.0.1 -> 0.0.2

    通过apm help可以获取到更多的帮助信息。

    以上,就是开发一个Atom插件的完整流程咯。

    参考资料

    hacking-atom
    electron-doc

  • 相关阅读:
    024.Zabbix告警等级机制
    023.Zabbix自定义(邮箱)脚本告警-02
    022.Zabbix自定义(邮箱)脚本告警01
    021.Zabbix的邮件告警-01
    020.Zabbix的Actions配置
    019.Zabbix的Trigger及相关函数
    018.Zabbix维护时间和模板导入
    017.Zabbix宏介绍
    016.Zabbix聚合监控
    015.Zabbix的日志监控配置
  • 原文地址:https://www.cnblogs.com/jiasm/p/8799046.html
Copyright © 2011-2022 走看看