如何从0开发一个Atom组件

最近用Atom写博客比较多,而后发现一个很严重的问题。。 没有一个我想要的上传图片的方式,好比某乎上边就能够直接copy/paste文件,而后进行上传。 然而在Atom上没有找到相似的插件,最接近的一个,也仍是须要手动选择文件,而后进行上传。 这个操做流程太繁琐,索性本身写一个插件用好了。javascript

成品插件下载地址:atom.io/packages/at…前端

规划

首先,咱们肯定了需求,要经过能够直接copy文件,而后在Atom中paste便可完成上传的操做。 肯定了之后,咱们就要开始搬砖了。java

插件开发

由于Atom是一个Electron应用:electronjs.orgshell

是使用JavaScript来开发的桌面应用,因此对于一个前端来讲,简直是太美好了。 咱们先去翻看Atom的官方文档,查看关于建立插件相关的操做: 首先咱们在Atom中打开命令面板,而后输入Generate Package json

按下回车后,将会弹出一个对话框,在框中输入要创建的包名便可完成一个 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外边的那个keyatom-workspace表示在Atom中生效 atom-text-editor表示只在文本编辑器范围内生效。 less

Atom官方文档

lib

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

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

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

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

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

menus

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

{
  "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

相关文章
相关标签/搜索