瞭解為何 Excalidraw 專案決定淘汰 Electron 包裝函式,改用網路版本。
在Excalidraw 專案中,我們決定淘汰 Excalidraw Desktop,也就是 Excalidraw 的 Electron 包裝函式,改用您可以 (而且一向可以) 在 excalidraw.com 上找到的網頁版。經過仔細分析後,我們決定以漸進式網頁應用程式 (PWA) 為基礎,以便在未來進行建構。請繼續閱讀,瞭解原因。
Excalidraw Desktop 的開發歷程
@vjeux 在 2020 年 1 月建立 Excalidraw 初始版本並在部落格中介紹後不久,就在 Issue #561 中提出以下建議:
願意在 Electron (或同等應用程式) 中納入 Excalidraw,並以 [平台專屬] 應用程式的形式發布到各個應用程式商店。
@voluntadpear 立即回應建議:
您覺得如何改用 PWA?Android 目前支援將這類應用程式新增至 Play 商店做為受信任的網路活動,希望 iOS 很快就能跟進。在電腦上,Chrome 可讓您下載 PWA 的電腦捷徑。
@vjeux 最後的決策很簡單:
我們應該同時執行這兩項操作 :)
@voluntadpear 和其他人後來開始將 Excalidraw 版本轉換為 PWA,@lipis 獨立繼續,並為 Excalidraw Desktop 建立獨立的存放區。
時至今日,@vjeux 設定的初始目標尚未到達各種應用程式商店,這表示尚未到達不同的應用程式商店。老實說,沒有人開始向任何商店提交申請。但為什麼會這樣?在回答問題之前,讓我們先來瞭解 Electron 這個平台。
什麼是 Electron?
Electron 的獨特賣點是,您可以「使用 JavaScript、HTML 和 CSS 建構跨平台的電腦應用程式」。使用 Electron 建構的應用程式「與 Mac、Windows 和 Linux 相容」,也就是說「Electron 應用程式可在三個平台上建構及執行」。根據首頁說明,Electron 可簡化自動更新、系統層級選單和通知、當機回報、偵錯和分析,以及Windows 安裝程式等功能。原來部分承諾的功能需要仔細查看細則。
舉例來說,自動更新功能「目前僅支援 macOS 和 Windows,系統並未內建 Linux 上的自動更新器支援功能,因此建議您使用發行版的套件管理工具來更新應用程式」。
開發人員可以呼叫
Menu.setApplicationMenu(menu)
建立系統層級選單。在 Windows 和 Linux 上,系統會將選單設為每個視窗的頂端選單,而在 macOS 上,則有許多系統定義的標準選單,例如「Services」選單。如要將某個選單設為標準選單,開發人員應據此設定選單的role
,Electron 會辨識這些選單並成為標準選單。這表示許多與選單相關的程式碼都會使用以下平台檢查:const isMac = process.platform === 'darwin'
。您可以使用 windows-installer 建立 Windows 安裝程式。專案的 README 檔案強調「如要發布正式版應用程式,您需要為應用程式簽署。Internet Explorer 的 SmartScreen 篩選器會阻止他人下載您的應用程式,許多防毒廠商會將您的應用程式視為惡意軟體,除非您取得有效的憑證 [sic]。
從這三個範例來看,Electron 顯然無法達到「一次編寫,隨處執行」的目標。如要在應用程式商店發布應用程式,就必須簽署程式碼,這是一種用於認證應用程式擁有權的安全技術。封裝應用程式時,您必須使用 electron-forge 等工具,並考慮應用程式更新的套件代管位置。模型會相對快速複雜,尤其當目標為跨平台支援時更是如此我想請注意,您「絕對」可以用足夠的心力和精力,打造出令人驚豔的 Electron 應用程式。對 Excalidraw Desktop 而言,我們並不需要。
Excalidraw 桌面版的後續發展
目前 Excalidraw Desktop 基本上是將 Excalidraw 網頁應用程式以 .asar
檔案形式封裝,並新增「About Excalidraw」視窗。應用程式的外觀和風格與網路版本幾乎相同。
在 macOS 上,應用程式頂端現在有系統層級選單,但除了「關閉視窗」和「關於 Excalidraw」以外,其他選單動作都沒有連結至任何項目,因此在目前狀態下,選單幾乎沒有用處。同時,您當然也可以透過一般 Excalidraw 工具列和內容選單執行所有動作。
我們使用electron-builder,可支援檔案類型關聯。按兩下 .excalidraw
檔案時,最好會開啟 Excalidraw Desktop 應用程式。electron-builder.json
檔案的相關摘錄如下:
{
"fileAssociations": [
{
"ext": "excalidraw",
"name": "Excalidraw",
"description": "Excalidraw file",
"role": "Editor",
"mimeType": "application/json"
}
]
}
但實際上,這項做法不一定能正常運作,因為視安裝類型 (針對目前使用者、所有使用者) 而定,Windows 10 上的應用程式可能沒有權限將檔案類型連結至自身。
這些缺點和待處理的工作,讓我們無法在所有平台上提供真正類似應用程式的體驗 (再次強調,只要投入足夠的努力,這點是可行的),因此我們決定重新考慮投資 Excalidraw Desktop。不過,我們認為更重要的論點是,我們預測在我們的用途中,我們不需要 Electron 提供的所有功能。網路的功能不斷擴增,而且仍在持續增加,因此我們可以利用網路提供同樣 (甚至更優異) 的服務。
網路如何提供給我們現在與未來的服務
即使 2020 年,jQuery 仍廣受歡迎。對許多開發人員來說,使用 jQuery 已成為習慣,即使他們現在可能不需要 jQuery,Electron 也有類似的資源,名為「您可能不需要 Electron」。讓我概略說明為何我們認為不需要 Electron。
可安裝的漸進式網頁應用程式
目前的 Excalidraw 是可安裝的漸進式網頁應用程式,其中包含Service Worker 和網頁應用程式資訊清單。它會將所有資源快取到兩個快取中,一個用於字型和字型相關 CSS,另一個用於其他所有資源。
這表示應用程式可完全離線運作,無須連上網路也能執行。電腦和行動裝置上的 Chromium 瀏覽器會提示使用者安裝應用程式。您可以在下方螢幕截圖中看到安裝提示。
Excalidraw 是設為獨立應用程式的形式執行,所以安裝時,您會取得在獨立視窗中執行的應用程式。這項服務已完全整合至作業系統的多工處理 UI,並會在主畫面、Dock 或工作列上顯示專屬的應用程式圖示 (視安裝的平台而定)。
檔案系統存取權
Excalidraw 會使用 browser-fs-access 存取作業系統的檔案系統。在支援的瀏覽器上,這可以實現真正的開啟→編輯→儲存工作流程和實際過度儲存的情況,以及「另存新檔」,並為其他瀏覽器提供透明的備用方案。如要進一步瞭解這項功能,請參閱我的網誌文章「使用 browser-fs-access 程式庫讀取及寫入檔案和目錄」。
支援拖曳功能
您可以將檔案拖曳至 Excalidraw 視窗,就像在平台專屬應用程式中一樣。在支援 File System Access API 的瀏覽器上,您可以立即編輯放置的檔案,並將修改內容儲存到原始檔案。這麼直覺,有時您甚至會忘記自己正在使用的是網頁應用程式。
存取剪貼簿
Excalidraw 與作業系統的剪貼簿相容。您可以以 image/png
和 image/svg+xml
格式複製及貼上整個 Excalidraw 繪圖,或只複製個別物件,方便整合 Inkscape 等其他平台專屬工具,或是 SVGOMG 等網路工具。
檔案處理
Excalidraw 已支援實驗性的 File Handling API,這表示您可以在作業系統的檔案總管中雙擊 .excalidraw
檔案,並直接在 Excalidraw 應用程式中開啟,因為 Excalidraw 會註冊為作業系統中 .excalidraw
檔案的檔案處理常式。
宣告式連結擷取
您可以透過連結分享 Excalidraw 繪圖。以下是範例。日後,如果使用者將 Excalidraw 安裝為 PWA,這類連結就不會在瀏覽器分頁中開啟,而是會啟動新的獨立視窗。尚待實作,則可藉助宣告式連結擷取,在撰寫全新網路平台功能的過時提案時,採用「宣告式連結擷取」。
結論
網頁已發展了好幾年,越來越多功能在瀏覽器中推出,這些功能在幾年前甚至幾個月前,都還只是網頁上難以想像的功能,也是專屬於特定平台的應用程式。Excalidraw 是瀏覽器中功能最先進的工具,但我們也瞭解,並非所有平台上的所有瀏覽器都支援我們使用的每項功能。我們採用漸進式改善策略,盡可能使用最新的最佳技術,但不會讓任何人落後。建議使用任何瀏覽器觀看。
Electron 為我們帶來許多好處,但在 2020 年及以後,我們可以不使用 Electron。另外,針對 @vjeux 的目標:由於 Android Play 商店現在接受以 Trusted Web Activity 為名的容器格式提供的 PWA,且 Microsoft Store 也支援 PWA,因此您不久後就能在這些商店中找到 Excalidraw。同時,您隨時可以使用及安裝 Excalidraw 在瀏覽器中。
特別銘謝
本文經 @lipis、@dwelle 和 Joe Medley 審查。