GitHub 如何基於 Node.js 和 Chromium 開發 Atom?

參看了部分「Atom Editor」項目的源代碼,看到該項目實現技術框架是:Node「CoffeeScript」+ Chromium,或者說就是通過Node將Chromium打造成一款文本編輯器。

這是開發桌面應用的一個新思路,有過來人能分享下學習經驗,還有通過這種方式開發移動應用呢?

「或者說基於Node開發類桌面應用有什麼建議? 」


看到回答里, 多數都沒有回答到點子上, 還有些給了非常主觀的意見而沒有給出實際結論和分析過程.

題主的問題有四個:

1. Github 如何基於 Node.js 和 Chromium 開發 Atom?

Atom 是基於 Atom-Shell (atom/atom-shell · GitHub) 開發的, atom-shell 是一個將 Chromium 和 Node.js (在最近的版本中已經替換成了 io.js 了) 整合在一起的 shell 框架. 那麼他是如何整合 node.js 和 chromium 的呢? Atom-Shell 在瀏覽器的底層和渲染層分別加入了 node.js 的事件循環, 由此在瀏覽器內核中驅動了 node.js. 之所以將渲染層和內核層的事件循環區分, 是為了 CEF3 的渲染架構而這麼設計的, 而為了能夠讓渲染層之間, 以及渲染層和內核層之間通訊, 採用 ipc 進行封裝, 具體的 ipc 實現我沒深入去查看源代碼, 應該是直接走了 Chromium 的 IPC 介面.

類似的 Shell 技術還有 nw.js 和 bracket-shell. 但是這些 shell 技術都有差異, 具體的差異可以閱讀這幾篇文檔:

atom-shell/atom-shell-vs-node-webkit.md at master · atom/atom-shell · GitHub

https://speakerdeck.com/zcbenz/practice-on-embedding-node-dot-js-into-atom-editor

https://speakerdeck.com/zcbenz/node-webkit-app-runtime-based-on-chromium-and-node-dot-js

Github 的 Atom 就是在 Atom-Shell 的基礎上, 通過 coffee-script 寫頁面端的表現, 通過 node.js/io.js 的整合處理 io 層的需求. 然後通過 atom-shell 整合操作系統中一些 native 窗口的能力.

2. 有過來人能分享學習經驗?

學習經驗倒也談不上, 我基本上是閱讀了一遍 atom-shell 官方的文檔, 重點學習了一下如何使用 ipc 進行窗口間, 內核層之間的通訊方式以及頁面編程相關的知識. 這個過程中, 我覺得有幾個地方可以系統學習:

1. 通訊模型的建立:

為了更好的進行 ipc 通訊, 我們需要一些有效的經驗模型來總結通訊的方法, 為此, 我找了兩個通訊模型的文檔進行學習:

Getting Started with "nanomsg"

http://zguide.zeromq.org/page:all

通過對 nanomsg, zero-mq 中提出的幾種通訊方式的總結, 我們漸漸地設計出符合我們需求的消息通訊編碼規範, 和通訊類型.

2. CSS 排版, DOM 頁面渲染知識:

為了能夠讓我寫的 GUI 高效的在頁面中運轉, 我需要掌握更多的關於瀏覽器如何渲染 DOM, 如何解析 CSS 等瀏覽器渲染內核的知識, 為此我閱讀了以下文檔:

How Browsers Work: Behind the scenes of modern web browsers (這是一篇基礎入門的好文章, 他讓我在短短1個禮拜內, 通過自己的編碼實踐和擴展閱讀理解了瀏覽器的大概的工作原理)

Getting Started With the WebKit Layout Code (這也是一篇非常好的文章, 他通過解析 Webkit 的底層 layout 代碼, 讓你明白整個瀏覽器是如何進行 css 排版工作的)

A Visual Method for Understanding WebKit Layout (這篇文章繼承上一篇, 通過實踐進一步理解 layout 的技術內容)

Rendering: repaint, reflow/relayout, restyle / Stoyan"s phpied.com (這篇文章也是講關於 reflow 的底層細節)

Understanding the CSS Specifications (然後因為 css 的文檔本身太晦澀, 我一個初入門 web 前端編程的人一開始沒能讀懂, 所以我就先找到了這篇進行學習)

Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification (在那之後, 我進行了一些實踐, 差不多覺得可以掌握了, 就通讀了一遍這篇文檔, 並通過少量編碼, 完成大部分 css2 的排版計算過程, 打通了我心中對於排版的諸多疑問)

這之後, 我又擴展閱讀了以下一些 css 草案:

  • CSS Animations CSS3 Animation 草案
  • CSS Transitions CSS3 Transition 草案,transition和animaiton貌似有很多重合點,有待深究
  • Web Animations 1.0 Web Animation 草案
  • CSS Flexible Box Layout Module Level 1 CSS3 Flexbox 草案
  • CSS Grid Layout Module Level 1 CSS3 Grid Layout 草案
  • CSS Transforms Module Level 1 CSS3 Transform 草案,Transform 和 position 還是有不同之處,兩個屬性並沒有過度冗餘
  • CSS Shapes Module Level 1 CSS3 Float Shape 草案,圖文混排方面,屬於進階需求

然後通過上面的幾輪實踐, 我又回過頭來學習了以下幾篇關於排版的知識點:

  • Introduction to Layout in Mozilla 這是 Mozilla Gecko 引擎的 Layout 技術細節
  • David Baron"s CSS Playground Mozilla 的開發者的Blog,裡頭有非常多技術詳解
  • David"s Inline Box Model 這是上述開發者里的一片關於 Inline Box 的詳解
  • The WebKit Open Source Project 這是 WebKit 中關於其技術細節的相關文檔。
  • CSS animations and transitions performance: looking inside the browser

大概前前後後花了約 4 個月時間, 完成了整個 web 渲染和排版的基礎知識.

3. Node.js/io.js 學習

Node.js 的學習我是在項目中持續進行的, 這期間由於項目進度比較緊張, 我並沒有很好的做好各種學習筆記, 所以不好意思, 沒有特別多可以分享的經驗.

3. 還有通過這種方式開發移動應用呢?

有一些 Hybrid 的應用通過相似的方法構建, 比較出名的有:

  • PhoneGap | Home

  • The Crosswalk Project

這方面我接觸的不多, 所以沒有太多的經驗可以分享.

4. 基於 Node 開發類桌面應用有什麼建議?

我覺得還是要從項目本身的需求出發點考慮, 如果你是一個 javascript 依賴較多的項目, 或者一個偏頁面應用的項目, 那麼基於 Node/Chromium 構建的桌面 APP 將給你帶來非常好的基礎結構, 讓你專註在開發本身.


題主不必把眼光局限在 ATOM,對於一般的應用程序,我更推薦 XDK 使用的框架 node-webkit,也就是現在的 NW.js,這個框架做起來非常順手。

我不推薦 ATOM 所用的 atom-shell,原因在於它比較難上手,特別是引入了 ipc 通訊機制。如果你是做一些類似 CS 架構的應用,那麼 ipc 是你的得力助手。如果你只是做一些普通的桌面應用,ipc 會逼著你把簡單的任務複雜化,違反了 KISS 原則。而且 ipc 有很多坑,會成為你開發中最浪費時間的部分。

下文統一介紹一下這個領域現成的技術框架和成功案例:

  • Atom

atom 基於 atom-shell 開發而來,atom-shell 基於 node.js(io.js) 和 Chromium(CEF2) 開發而來。

atom-shell 代表案例可參考 Fireball 總設計師回答的這個帖子:還要多少年, 前端開發才能像客戶端開發那樣輕鬆? - Johnny Wu 的回答

  • NW.js

NW.js 由 node-webkit 更名而來,技術底層和 atom-shell 是一樣的,比 atom-shell 還容易上手,用的人最多。node-webkit 是為了支撐 Intel 自家的 XDK 而做的,誰會想到這樣的 IDE 神器竟然是用 JavaScript 寫的?但也正是由於這點,nw 之前的更新停滯了一段時間,於是被我們無情拋棄了,這個項目最近似乎重新活躍了起來。

看完上面的兩個框架和對應的案例,我想題主心中會有答案。此外類似的框架還有比較小眾的 brackets-shell 和 heX,分別支撐 brackets 和 有道詞典的開發。

下面是吐槽時刻:

nodejs + chromium ≈ sb

為什麼這麼說,先說≠的部分,如果你要在linux花30分鐘寫出一個界面酷炫功能簡單的小工具,nodejs+chromium(也就是node-webkit)是很好的選擇,在windows上是vb,要界面酷炫的話http://vb.net/c# + wpf,mac也請退坑,默認的就夠好了。

誰都知道WPF和VB很好用,但是要跨平台怎麼辦?想要跨平台的話,用 node+web 再好不過了。

如果你要做個比較重的東西,chromium的效率和bug會把你拖累成狗,你說npm絕贊?node-webkit索然披著node皮但是用到本地代碼的編譯起來炒雞蛋疼。

atom-shell 的 bug 響應時間是按天算的呢,chromium的效率還真的很棒。本地代碼的編譯蛋疼在哪了…… 不就一個命令行搞定的事嗎?你要是換了其它技術,那編譯起來各種依賴庫才叫一個酸爽呢。

如果你要做一個小玩意,但是給人用,帶個node-webkit不知道多重……

好幾十MB,聽起來是很重,但是我用有道詞典那麼多年了,一直沒發現它很重啊?誰會注意到它是 CEF 做的呢。你做了一個棒棒的工具,這年頭誰還會在乎體積啊?

其他的,你要炫酷界面opengl/directui

網頁做界面才叫酷炫呢,看看我上面的 atom-shell 案例

你要跨平台gtk / qt各有各的好

AIR 和 Java 更好,gtk/qt 已經入土為安了。

速度慢, 執行效率低.

看我的案例,遊戲引擎都能做了,XDK 這樣的重量級 IDE 都能做了,還有什麼性能上可質疑的呢?

佔用資源較多.

你做的什麼應用,要常駐後台嗎?你的內存還差這幾十MB?

開發周期長.

明明是縮短了開發周期好嗎…… 不信你跨個平台試試。就算不跨平台,你看看我前面 atom-shell 貼的案例吧,網頁做起 UI 開發效率很高的。

--------------------------

更新:

時間來到了 2016 年,atom-shell 更名為 Electron,發展的更快了。我承認 Electron 可能沒辦法像 WPF, QT, GTK 甚至 Swing 那樣長命,但至少目前我還沒找到更適合個人和小團隊的 UI 框架,同時我也相信今後基於同類框架構建的混合應用會成為桌面軟體的常態。

下面是反反吐槽時刻:

誰都知道WPF和VB很好用,但是要跨平台怎麼辦?想要跨平台的話,用 node+web 再好不過了。

----------

Windows上當然用WPF或者vb,已經能cover很大一部分需求了,沒有nede+web生存的空間。

我問的是跨平台怎麼你又扯到 Windows。

網頁做界面才叫酷炫呢,看看我上面的 atom-shell 案例

----------

沒有directui 炫,不送。

拋開跨平台問題,你告訴題主拿 opengl / directui 做 UI 最酷炫?能給點合理建議嗎…… 那你乾脆說用Win32做 UI 性能最強好了。好吧我承認網頁做界面不夠酷炫。

看我的案例,遊戲引擎都能做了,XDK 這樣的重量級 IDE 都能做了,還有什麼性能上可質疑的呢?

----------

你玩過Intel那個幼稚園向的HTML5手機遊戲嗎?

你真的嘗試過用webgl寫過稍微大一些的遊戲嗎?

順便一說,用webgl還不如native呢!

我說的是桌面軟體,不是遊戲呀…… 題主又不關心遊戲怎麼做。你所謂的「速度慢, 執行效率低.」,不會是主觀印象嗎?到了今天,我又用了 atom-shell 做了一年的遊戲引擎,還是同樣反駁你的觀點。參考案例:Apps - Electron

atom-shell 的 bug 響應時間是按天算的呢,chromium的效率還真的很棒。本地代碼的編譯蛋疼在哪了…… 不就一個命令行搞定的事嗎?你要是換了其它技術,那編譯起來各種依賴庫才叫一個酸爽呢。

-----------

atom-shell響應快有卵用。我眼睜睜看著chromium那群傻逼把一個bug從版本號31刷到35。

chromium編譯起來有多麻煩誰用誰知道。和同樣c++的qt比起來是兩個次元。

用戶不需要編譯 chromium。atom-shell 確實有坑,但是整體而言很穩定,幾乎沒有偶發的 bug 或隨機性的崩潰。


「或者說基於Node開發類桌面應用有什麼建議? 」

看這裡

http://appjs.com/

這個沒什麼奇怪的思路,作為node程序員,100%都有在本地機跑伺服器,本地機上瀏覽器調試的經驗。


node-webkit is an app runtime based on Chromium and node.js. You can
write native apps in HTML and JavaScript with node-webkit. It also lets you
call Node.js modules directly from the DOM and enables a new way of writing
native applications with all Web technologies.

List of apps and companies using node webkit 路 rogerwang/node-webkit Wiki 路 GitHub


這種搭配不是什麼新思路. app.js和node-webkit樓上樓下也都提到了, 這種應用程序的開發需要很強的web端開發能力作為基礎, 而且調試起來比本地語言麻煩, 總之是難度大並且開發周期長.

可為什麼還有人知難而上? 這種技術有什麼好處?

1. 因為採用了跨平台的Node.js和Chromium, 而Javascript又是平台無關語言, 所以它可以很輕鬆的跨平台, Atom能支持Mac, Linux和Windows就是得益於此.

2. 可以輕鬆的部署到Web上, 這是其他開發方式難以做到的, 以實現"雲開發環境"的效果, Cloud9就是這種產品, 用過的都知道, 連接Github倉庫簡直不要太方便.

3. 個人定製容易. Javascript的學習門檻很低, 雖然掌握高級Javascript技術的難度很高,

但對於修改Atom而言, 應該用不到那種高級技術, 所以還是容易.

4. 界面華麗: CSS3很酷, Canvas很酷, WebGL屌爆了.

缺點也很明顯:

1. 速度慢, 執行效率低.

2. 佔用資源較多.

3. 開發周期長.

這裡缺點1也就是最大的障礙, 其實可以依靠Chromium的Javascript二進位化功能和Node.js的二進位模塊解決或得到緩解的, 剩下的比較影響效率的也就只剩DOM操作了.

如果開發團隊強大到用Canvas或者WebGL做全套界面, 那麼DOM的性能問題可能也將不在. 上面提到的這些技術很多開發人員不了解, 所以依然有效率低的第一印象也不難理解.

AngularJS和Backbone這類MVVM框架的出現, 加速了WebApp的開發, 同時也對node-webkit這類桌面應用給予了一定幫助, 開發周期也因此有所縮短. 如果要做這方面的開發, 選好框架很重要.

可惜, 以上, 都是從開發者角度出發的.

如果從用戶角度出發, 一個桌面程序的佔用空間動輒需要幾十甚至一百多MB, 會很不受待見, 除非軟體的功能值得起這個大小, 不然很容易有一種硬碟空間被浪費的錯覺, 換句話說, 就是不爽.

下載方面, 由於壓縮包通常能在30MB以下, 所以對用戶不會有太大影響. 如果能有一個統一的穩定的被開發者廣泛接受的程序作為運行時環境存在, 佔用空間的問題就能解決了, 但從nodd-webkit項目現在的情況來看, 離這一天的到來還很遠.

不管怎麼說, 在當下這是一種彆扭的開發方式, 短時間內不可能成為主流, 如果要開發這樣的程序, 還請三思而後行.


先回答問題,

node.js+chromium很簡單,拿出一個chromium源代碼,找到裡面的v8,掛上一個nodejs,把chromium的v8換成nodejs的,最後加上一些操作窗口的api。然後開始用js寫邏輯用html寫ui。

至於建議,

nodejs + chromium ≈ sb

為什麼這麼說,先說≠的部分,如果你要在linux花30分鐘寫出一個界面酷炫功能簡單的小工具,nodejs+chromium(也就是node-webkit)是很好的選擇,在windows上是vb,要界面酷炫的話http://vb.net/c# + wpf,mac也請退坑,默認的就夠好了。

其次,如果你的應用會大量用到json而且你不在乎效率,那無所謂啊……

如果你要做個比較重的東西,chromium的效率和bug會把你拖累成狗,你說npm絕贊?node-webkit索然披著node皮但是用到本地代碼的編譯起來炒雞蛋疼。

如果你要做一個小玩意,但是給人用,帶個node-webkit不知道多重……

其他的,你要炫酷界面opengl/directui

你要跨平台gtk / qt各有各的好

你要編碼效率python

你要執行效率c

都要的話swing不知道多方便。要帶nodejs也不是不行對吧……反正別把chromium拉上。

===

順便回答一下LS的吐槽

誰都知道WPF和VB很好用,但是要跨平台怎麼辦?想要跨平台的話,用 node+web 再好不過了。

Windows上當然用WPF或者vb,已經能cover很大一部分需求了,沒有nede+web生存的空間。

atom-shell 的 bug 響應時間是按天算的呢,chromium的效率還真的很棒。本地代碼的編譯蛋疼在哪了…… 不就一個命令行搞定的事嗎?你要是換了其它技術,那編譯起來各種依賴庫才叫一個酸爽呢。

atom-shell響應快有卵用。我眼睜睜看著chromium那群傻逼把一個bug從版本號31刷到35。

chromium編譯起來有多麻煩誰用誰知道。和同樣c++的qt比起來是兩個次元。

好幾十MB,聽起來是很重,但是我用有道詞典那麼多年了,一直沒發現它很重啊?誰會注意到它是 CEF 做的呢。你做了一個棒棒的工具,這年頭誰還會在乎體積啊?

當然在乎,一個公積金計算器25mb你怕不怕?

你給人寫個實用工具25mb你怕不怕?

網頁做界面才叫酷炫呢,看看我上面的 atom-shell 案例

沒有directui炫,不送。

AIR 和 Java 更好,gtk/qt 已經入土為安了。

air、java早就滾出ui圈了。放心atom-shell炸了qt都不會入土為安。qt裁剪一下能做到非常小。

看我的案例,遊戲引擎都能做了,XDK 這樣的重量級 IDE 都能做了,還有什麼性能上可質疑的呢?

你玩過Intel那個幼稚園向的HTML5手機遊戲嗎?

你真的嘗試過用webgl寫過稍微大一些的遊戲嗎?

順便一說,用webgl還不如native呢!


推薦閱讀:

在MSys版的Git中使用git pull --rebase進行代碼更新到底是做了什麼?
如何使用10個小時搭建出個人域名而又Geek的獨立博客?
GitHub 上有什麼好玩又有挑戰的前端項目?
SourceForge 是如何一步一步被 GitHub 超越的?
自己在github上寫的開源項目沒有人star是怎樣的一種體驗?

TAG:GoogleChrome | GitHub | Nodejs | editor | Atom文本編輯器 |