最近用Atom寫部落格比較多,然後發現一個很嚴重的問題。。 沒有一個我想要的上傳圖片的方式,比如某乎上邊就可以直接copy/paste檔案,然後進行上傳。 然而在Atom上沒有找到類似的外掛,最接近的一個,也還是需要手動選擇檔案,然後進行上傳。 這個操作流程太繁瑣,索性自己寫一個外掛用好了。
成品外掛下載地址:atom.io/packages/at…
規劃
首先,我們確定了需求,要通過可以直接copy
檔案,然後在Atom中paste
即可完成上傳的操作。
確定了以後,我們就要開始搬磚了。
外掛開發
因為Atom
是一個Electron
應用: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
表示只在文字編輯器範圍內生效。
lib
這裡就是存放外掛主要程式碼的地方了。 預設會生成兩個檔案:
package.js
package.view.js
預設外掛生成的主入口檔案指向這裡。
入口檔案的表現方式為一個JSON
物件,可以實現如下幾個函式:
activate
: 當Package
被啟用時會執行該方法,函式的簽名表示會接受一個state
引數,該引數是通過serialize
方法傳遞過來的(如果有實現它的話)deactivate
: 當Package
失效時會出發的方法,這兩個方法可以理解為React
中的componentWillMount
和componentWillUnmount
serialize
: 也就是上邊說到的那個方法,可以返回一個JSON
物件供下次啟用後使用- 自定義快捷鍵對應的事件名: 每次
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-editor
和workspace
。
spec
這裡存放的是一些測試用例,建立Package
會生成一些預設的斷言。
寫測試確實是一個好習慣。
styles
如果Package
有很多View
要展示的話,可以在這裡編寫,預設使用的是Less
語法。
由於我們只做一個C/V
的操作,不會涉及到介面,所以styles
直接就刪掉了。
開始搬磚
大致結構已經瞭解了,我們就可以開始搬磚了。
因為是一個Electron
應用,所以我們直接在Atom
中按下alt + command + i
,撥出我們熟悉的控制檯介面。
Atom
是不會把Electron
的各種文件重新寫一遍的,所以我們現在控制檯裡邊試一下我們的猜測是否正確。
一些想要的東西是否存在。
Electron
的clipboard
物件可以直接在Atom
中使用,這就很開心了。
require('electron').clipboard.readImage().toPng()
複製程式碼
這樣我們就拿到剪下板中的圖片資料了,一個二進位制的陣列物件。
我們在觸發Paste
操作時,從clipboard
中獲取,如果剪下板中是圖片的話,我們就將它上傳並顯示到編輯器中。
所以,接下來我們要做的就是:
- 進行上傳圖片的操作
- 將上傳後的圖片顯示到編輯器中
上傳圖片
上傳圖片我們選擇的是七牛,我們選擇七牛來作為圖床使用,因為他家提供了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
中存在如下幾個引數:
name
description
repository
我們可以先使用如下命令來檢查包名是否衝突。
apm show 你的包名
複製程式碼
如果沒有衝突,我們就可以直接執行以下命令進行上傳了。
apm publish 你的包名
複製程式碼
後續的程式碼修改,只需在該包的目錄下執行:
apm publish
複製程式碼
一些可選的引數:
major
,增加版本號的第一位1.0.0
->2.0.0
minor
,增加版本號的第二位0.1.0
->0.2.0
patch
,增加版本號的第三位0.0.1
->0.0.2
通過apm help
可以獲取到更多的幫助資訊。
以上,就是開發一個Atom
外掛的完整流程咯。