Deno是程式碼瀏覽器:沒有軟體包管理器或集中式包儲存庫 - kitsonkelly

banq發表於2020-05-29

我們需要改變我們的思維模式。許多人都將包管理器和集中式程式碼登錄檔作為普遍要求,以擁有一個包管理器和一個集中式程式碼登錄檔。因為它們存在並不意味著它們是必需的。之所以出現它們,是因為它們以特定的方式解決了問題,我們剛剛接受它們作為解決該問題的唯一方法。我認為那是不正確的。

瀏覽器的特點
為了釋出網站,我們不會登入到中央Google伺服器,將我們的網站上傳到google的中央登錄檔中。然後,如果有人想檢視我們的網站,他們會使用命令列工具,該工具會讀取browser.json配置檔案,在我們本地計算機上的檔案中新增一個條目,然後訪問並獲取整個網站,以及該網站連結到我們本地websites目錄之前的所有其他網站。然後,我們啟動瀏覽器以實際檢視該網站。這太瘋狂了吧?那麼為什麼要接受執行程式碼的這種模型呢?
Deno CLI的工作方式類似於瀏覽器,但是適用於程式碼的瀏覽器。您在程式碼中匯入一個URL,Deno將去獲取該程式碼並將其快取在本地,就像瀏覽器一樣。此外,就像瀏覽器一樣,您的程式碼在沙箱中執行,沙箱對正在執行的程式碼的信任度為零,而與原始碼無關。您(呼叫程式碼的人)從外部告訴該程式碼可以做什麼和不能做什麼。此外,就像瀏覽器一樣,程式碼可以要求您執行操作,您可以選擇授予或拒絕。
HTTP協議提供了提供有關程式碼資訊所需的一切,並且Deno嘗試完全利用該協議,而不必建立新協議。

發現程式碼
首先要考慮的是,像瀏覽器一樣,Deno CLI不想對您執行的程式碼有任何看法。它列出瞭如何獲取程式碼以及如何將程式碼從執行的計算機中沙箱化的規則。在我看來,這是執行環境應該擁有的立場。
在Node.js / npm生態系統中,我們已將本地計算機上的程式碼管理與集中式程式碼登錄檔結合在一起,以幫助促進發現。我認為,兩者都有非常嚴重的缺陷。
早在網際網路的早期,我們就嘗試了npm型別的可發現性。您可以將您的網站新增到Yahoo!。根據正確的分類,人們可能會使用搜尋功能,但這全都是基於提供內容者的觀點來構建的,而不是真正基於針對消費者需求的最佳化而構建的。最終出現了Google。Google為什麼贏了?因為它很有用。它以一種簡單的方式將網站編入索引,該方式將需求的簡單表達(搜尋詞)與滿足需求的最相關的網頁相匹配,同時考慮了多種因素,包括後設資料提供的內容提供商是其中的一個因素。
雖然我們還沒有用於Deno的程式碼的模型,但它是可行的模型。此外,我們之所以使用Google是因為它為我們解決了問題,而不是被告知“您必須使用Google”,以及Google還有其他可行的替代方案。

可重複的構建
在npm生態系統中,這成為一個問題。由於嚴重依賴語義版本控制,並且複雜的依賴關係圖往往來自Node.js / npm生態系統,因此具有可重複的構建成為一個真正的問題。Yarn引入了鎖定檔案的概念,npm隨之而來。
我個人的感覺是,這有點像是在搖尾狗,因為生態系統中開發人員的行為造成了一個問題,然後需要一個不完善的解決方案來解決它。我們中長期生活在生態系統中的任何人都知道解決許多問題的方法是 rm -rf node_modules package-lock.json && npm install。
話雖如此,Deno為此提供了兩種解決方案。首先,是Deno快取模組。可以將該快取記憶體檢入到原始碼管理中,並且該 --cached-only標誌將確保不嘗試檢索遠端模組。DENO_DIR環境變數可用於指定所述快取記憶體位於以提供進一步的靈活性。
其次,Deno支援鎖定檔案。--lock lock.json --lock-write會針對給定的工作負載寫出一個具有所有依賴項雜湊值的鎖定檔案。使用時,這將用於驗證以後的執行--lock lock.json。
還有一些其他命令可以管理可重複的構建。 deno cache將解決所提供模組的所有依賴關係,並填充Deno快取。deno bundle可以用於生成工作負載的單個檔案“構建”,所有依賴關係都已解決幷包含在該檔案中,因此以後的deno run命令只需要單個檔案即可。

信任程式碼
無論出於何種原因,我們都信任集中式登錄檔中的程式碼。我們甚至都沒有考慮過。不僅如此,我們相信該程式碼已完全審查了其所有依賴關係,並且這些依賴關係將受到信任。我們進行了快速搜尋,然後輸入npm install some-random-package並認為“這很好!” 我認為豐富的npm軟體包生態系統使人們感到沾沾自喜。
為了彌補這種鬆懈和自滿,我們在工具鏈中實現了安全監視軟體,以分析我們的依存關係以及成千上萬行程式碼,以使我們知道某些程式碼可能是可利用的。公司設定私有登錄檔來託管可能比單個公共登錄檔稍微多一些的軟體包。
感覺好像房間裡有一頭大象。最好的策略是我們不應該信任任何程式碼。一旦我們建立了該功能,然後將其開啟即可輕鬆一些。但是,如果我們認為程式包管理器和集中式登錄檔可以解決此問題,或者甚至可以實質性地解決此問題,我們就會自欺欺人。實際上,我認為它們的利用使我們的警惕降低了。“好吧,在npm上,如果這對我不利,那麼肯定有人會把它取下來。”
Deno在這方面的工作還不盡如人意,但它是從一個好的位置開始的。它在啟動時具有零信任,並提供相當精細的許可權。

依賴管理
我認為我們需要坦率地談談npm生態系統中的依賴關係。實際程式碼為132個位元組,但整個包大小為3.4kb。可執行程式碼為整個程式包大小的3.8%。
我的意見是,這涉及幾個因素。其中很大一部分是我們顛倒了模型,我說過Deno是程式碼瀏覽器。問題在於,這種向後的模型已經感染了我們建立網站的方式。儘管沒有中央登錄檔,但是在構建網站時,我們會下載所有依賴的程式碼,並將其烘焙到伺服器上載入的內容中,然後每個使用者將一堆程式碼下載到本地計算機上。一些證據表明,所下載的程式碼中只有大約10%是該站點或Web應用程式唯一的,其餘的是我們正在下載到開發工作站並捆綁在一起的所有程式碼。這種模型被破壞是Snowpack等解決方案試圖解決的一些問題 。
另一個重要的問題是我們的依賴項雖然沒有與我們的程式碼耦合。將我們的程式碼中依賴關係放到了package.json。
這導致我們進入Deno模型,我喜歡稱其為Deps-in-JS,因為所有很酷的孩子都在做* -in-JS事情。將我們的外部依賴關係明確地表示為URL意味著程式碼依賴於其他程式碼簡潔明瞭,並且我們的程式碼和依賴關係緊密地耦合在一起。如果要檢視該依賴關係圖,只需要deno info與本地或遠端模組一起使用:

$ deno info https://deno.land/x/oak/examples/server.ts
local: $deno/deps/https/deno.land/d355242ae8430f3116c34165bdae5c156dca21aeef521e45acb51fcd21c9f724
type: TypeScript
compiled: $deno/gen/https/deno.land/x/oak/examples/server.ts.js
map: $deno/gen/https/deno.land/x/oak/examples/server.ts.js.map
deps:
https://deno.land/x/oak/examples/server.ts
  ├── https://deno.land/std@0.53.0/fmt/colors.ts
  └─┬ https://deno.land/x/oak/mod.ts
    ├─┬ https://deno.land/x/oak/application.ts
    │ ├─┬ https://deno.land/x/oak/context.ts
    │ │ ├── https://deno.land/x/oak/cookies.ts
    │ │ ├─┬ https://deno.land/x/oak/httpError.ts
    │ │ │ └─┬ https://deno.land/x/oak/deps.ts
    │ │ │   ├── https://deno.land/std@0.53.0/hash/sha256.ts
    │ │ │   ├─┬ https://deno.land/std@0.53.0/http/server.ts
    │ │ │   │ ├── https://deno.land/std@0.53.0/encoding/utf8.ts
    │ │ │   │ ├─┬ https://deno.land/std@0.53.0/io/bufio.ts
    │ │ │   │ │ ├─┬ https://deno.land/std@0.53.0/io/util.ts
--snip--


TypeScript的好處之一是,您可以全面驗證程式碼與其他程式碼的相容性。

請在沒有軟體包管理器或集中式軟體包儲存庫的情況下小試一下,看看它如何進行。您可能永遠不會回頭!

相關文章