如何從0開發一個Atom元件

Jiasm發表於2018-04-11

最近用Atom寫部落格比較多,然後發現一個很嚴重的問題。。 沒有一個我想要的上傳圖片的方式,比如某乎上邊就可以直接copy/paste檔案,然後進行上傳。 然而在Atom上沒有找到類似的外掛,最接近的一個,也還是需要手動選擇檔案,然後進行上傳。 這個操作流程太繁瑣,索性自己寫一個外掛用好了。

成品外掛下載地址:atom.io/packages/at…

規劃

首先,我們確定了需求,要通過可以直接copy檔案,然後在Atom中paste即可完成上傳的操作。 確定了以後,我們就要開始搬磚了。

外掛開發

因為Atom是一個Electron應用:electronjs.org

是使用JavaScript來開發的桌面應用,所以對於一個前端來說,簡直是太美好了。 我們先去翻看Atom的官方文件,檢視關於建立外掛相關的操作: 首先我們在Atom中開啟命令皮膚,然後輸入Generate Package

如何從0開發一個Atom元件
按下回車後,將會彈出一個對話方塊,在框中輸入要建立的包名即可完成一個Package的建立。
如何從0開發一個Atom元件
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表示只在文字編輯器範圍內生效。

如何從0開發一個Atom元件
Atom官方文件

lib

這裡就是存放外掛主要程式碼的地方了。 預設會生成兩個檔案:

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

預設外掛生成的主入口檔案指向這裡。

如何從0開發一個Atom元件

入口檔案的表現方式為一個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主選單欄上:

如何從0開發一個Atom元件
同樣的,context-menu會區分兩個環境,text-editorworkspace

spec

這裡存放的是一些測試用例,建立Package會生成一些預設的斷言。 寫測試確實是一個好習慣。

styles

如果Package有很多View要展示的話,可以在這裡編寫,預設使用的是Less語法。 由於我們只做一個C/V的操作,不會涉及到介面,所以styles直接就刪掉了。

開始搬磚

大致結構已經瞭解了,我們就可以開始搬磚了。 因為是一個Electron應用,所以我們直接在Atom中按下alt + command + i,撥出我們熟悉的控制檯介面。

如何從0開發一個Atom元件

Atom是不會把Electron的各種文件重新寫一遍的,所以我們現在控制檯裡邊試一下我們的猜測是否正確。 一些想要的東西是否存在。

如何從0開發一個Atom元件
經過驗證確定了,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。 至此,我們的程式碼已經編寫完了,剩下的就是一些互動上的優化。

完成後的效果圖:

如何從0開發一個Atom元件

以及,最後:我們要進行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

相關文章