編譯deno,deno結構解析

zy445566發表於2019-01-25

deno原本在我不被重視技術列表中,但在github的年度開源star榜單上,斬獲年度第四。讓我不得不思考為什麼deno能廣受好評,我想我需要刨開deno看看了。

編譯

為什麼不能直接解刨,呃。。。這和我的習慣有關係,我喜歡先編譯,並一步一步除錯,畢竟原始碼是不可能騙人的,再加上我喜歡魔改的臭習慣。廢話不多說,開搞。

本次編譯在mac上進行,其他系統可能不是很適應

步驟如下:

  1. 安裝rust,並注意安裝nightly的rust。
  • 為什麼要安裝nightly的rust?
    • 這個原因可以說是作者比較激進,有很多地方使用了實驗性特性,導致有些地方編譯的時候正式版的特性還不足以支援。在這點基礎上,我認為作者也是將deno定位激進的先進產品,或許這點我不敢苟同。。。

安裝rust,並用rust的版本控制器使用rustup切換到nightly。

注: rustup可以理解為node的nvm。

命令如下:

curl https://sh.rustup.rs -sSf | sh
rustup install nightly
rustup default nightly
複製程式碼
  1. 安裝Xcode開啟,同意一下各種不平等條款,再開啟執行一下,並切換到當前的Xcode版本。

命令如下:

sudo xcode-select -s /Applications/Xcode.app
複製程式碼
  1. 準備工作基本完成了,接下來需要克隆倉庫了

注意:這裡必須使用--recurse-submodules引數,原因是deno將多個倉庫作為了子模組進行開發,包括deno_std和third_party等等。

git clone --recurse-submodules https://github.com/denoland/deno.git
複製程式碼
  1. 使用工具安裝第三方依賴

感覺這一步就是單純實現的懶人神器功能。

注意:這裡必須開啟終端翻牆,否則會失敗,因為這裡會同步谷歌原始碼管理中心的資料,包括v8的同步,很重要!

cd deno
./tools/setup.py
複製程式碼
  1. 編譯

編譯就是漫長的等待了

cd deno
./tools/build.py # 如果要構建release,請DENO_BUILD_MODE=release
複製程式碼

直到輸出:

ninja: Entering directory `/xxx/xxx/deno/target/debug'
複製程式碼

到這裡就成功了,你可以直接在/xxx/xxx/deno/target/debug中執行一下

cd deno
cd ./target/debug 
./deno #如果出現REPL互動就成功了
複製程式碼

目錄解析

/build # 儲存v8構建的配置,最後軟鏈到/third_party/v8的目錄中
/build_extra # 儲存一些deno的構建配置
/buildtools # 顧名思義,一些構建工具,最後軟鏈到/third_party/v8的目錄中
/js # 這就是一些用js寫的一些原始碼,這點和node的js部分有點像,只不過改成用ts寫了
/libdeno #  我認為這是一個橋接v8和rust的介面卡程式碼
/node_modules # 給/js資料夾裝的一些依賴,軟鏈到/third_party的目錄中
/prebuilt # 因為切換到gn了,所以需要一些是否構建的檢查,顧名思義,預構建的一些檔案,都是自己生成的
/src # rust程式碼。像fs,http都在這裡實現,就是實現一些瀏覽幹不了的事情
/target # 編譯後的檔案,分debug和release,玩過rust的就知道,編譯release比較久,因為編譯器要做程式碼摺疊
/testing # v8的測試用例,軟鏈到/third_party/v8的目錄中
/test # deno的測試用例
/third_party # 第三方依賴如flatbuffers和v8等等
/tools #各種雜七雜八的指令碼,比如用於構建程式碼和檢查程式碼格式等等。
/website #deno的官方網站
複製程式碼

針對目錄解析,可能大家會有幾個問題:

  • 問題1:為什麼要一個libdeno做rust的橋接器?
    • 因為V8是C++寫的,同時V8很多自己的結構,那麼你要rust要較好的使用,你就必須寫一個橋接器來讓rust和V8能購相互呼叫。
  • 問題2:為什麼要用rust而不像node一樣,直接在v8上累程式碼?
    • 因為這樣可以減少對V8的依賴,比如V8底層一變,上層就需要大變,這樣對執行時開發者來說無疑是心智負擔。
  • 問題3:那麼這樣做deno對我們什麼好處呢?
    • 對於普通開發者:1.deno其實設計就是想趨於瀏覽器,那麼比如像node的require這種全域性變數本身其實就不應該存在的,因為瀏覽器中沒有這樣的全域性變數,且這種全域性變數還會造成很大的安全問題,所以要解決這個問題,但又要可以操作檔案和http等操作,解決途徑就是不暴露這樣的全域性變數,將deno做為一個import可以引進來的庫,這樣既可以和瀏覽器趨同,又不會暴露全域性。2.抹平了大部分和瀏覽器的區別,比如相同程式碼在瀏覽器和執行時的結果不同,同時更加相容,移植JS更加方便。
    • 對於執行時開發者:1.拋棄了gyp使用了gn,改一行程式碼再也不用全量編譯了。2.V8引擎的修改,再也不需要牽一髮而動全身了。3.一句話總結就是降低了開發者的心智負擔。

結語

這篇文章作為deno的先導篇,有機會還會在寫,但不保證這不是最後一篇。deno確實有很多優勢,這也讓我改變了一些對它的評價,但作為一個劃時代的產品,我認為多少還是差了一點意思,只能說期待deno更亮眼的功能吧。

重點:deno是可以執行js的!deno是可以執行js的!deno是可以執行js的!重要的事情說三遍。所以完全不用擔心deno會搶node飯碗,如果是普通開發者,學習deno的成本,本人認為和學習一個庫的成本差不多,所以不用過度擔心,且deno在生產環境溜一溜的結果也未可知,等待deno什麼時候GA,期待deno在生產環境的結果吧。

相關文章