如何從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

相關文章
相關標籤/搜索