Deno
Deno 的開發環境和 Deno 本身都很粗糙,不應將其用於生產環境。
從 Deno 的開發時間來考慮,Deno 團隊的表現不佳,
以至於 Node.js 已經逐漸趕上 Deno 的特性,還出現了 Bun 這樣相同生態位的競爭對手。
很難對 Deno 的未來有信心。
以至於 Node.js 已經逐漸趕上 Deno 的特性,還出現了 Bun 這樣相同生態位的競爭對手。
很難對 Deno 的未來有信心。
- 用 Rust 開發。
- API 盡可能與 Web 環境兼容。
- 具有主見的 `=deno fmt=`, `=deno lint=`, `=deno test=`, `=deno bench=`。
- 預設安全,具有細粒度的權限系統,支援動態請求權限。
目前,由於 Deno 有許多內部使用的欄位,細粒度權限用起來可能很不方便,最後還是會被迫去使用粗粒度權限。 - 原生支援 TypeScript,這點正變得越來越重要,因為 JavaScript 社群正在向 TypeScript 轉變。
- Node.js 兼容性。
Deno 的內建功能普遍缺乏嚴謹的測試,依賴社群回饋錯誤。
儘管 LTS 在各種專案裡都有越來越短的跡象,但 Deno 2 在發佈時將 6 個月聲明為 LTS 仍然令人忍俊不禁。
Deno Land Inc. 熱衷於開發其他生態環境產品的克隆/替代品。
這些產品明顯缺乏深思熟慮,可維護性存疑。
這些產品明顯缺乏深思熟慮,可維護性存疑。
這種傾向也影響了 Deno 本身,例如 Node.js 兼容性就是一個行銷炒作凌駕於實際交付的典型例子:
https://docs.deno.com/runtime/reference/node_apis/#fully-supported-modules
https://docs.deno.com/runtime/reference/node_apis/#fully-supported-modules
稍有規模的 Deno 專案就會導致 LSP 的響應速度變慢,很容易勸退想要使用 Deno 的開發人員。
相比之下,基於 Node.js 和 TypeScript 的專案則完全沒有類似的問題。
Deno 的 LSP 預設配置相當保守,例如,`=documentPreloadLimit=` 的預設值為 1000,實際開發中很容易超出。
WHATWG 流模型的設計相當簡陋,遠遠比不上 Node.js 的流。
舉例來說,使用者甚至無法知道一個流是否關閉,或是什麼時候關閉的。
模組會根據被導入的情況,決定其協定。
當模組作為本地模組被導入時,模組的 `=import.meta.url=` 為 file 協定。
當模組作為遠端模組被導入時,其 `=import.meta.url=` 為 http/https 協定。
當模組作為本地模組被導入時,模組的 `=import.meta.url=` 為 file 協定。
當模組作為遠端模組被導入時,其 `=import.meta.url=` 為 http/https 協定。
問題在於相當多的 API 只支援一種協定,例如 `=Deno.readFile=` 僅支援 file 協定,不支援 http/https 協定。
這種情況導致開發者在使用 `=import.meta.url=` 時有更多的心智負擔。
根本問題出在 Deno 不暴露導入模組(快取)的本地路徑,而這本身是一個在設計層面就可以解決的問題。
這種情況導致開發者在使用 `=import.meta.url=` 時有更多的心智負擔。
根本問題出在 Deno 不暴露導入模組(快取)的本地路徑,而這本身是一個在設計層面就可以解決的問題。
https://github.com/denoland/deno/issues/5987
相當可悲地,Deno 透過讓 `fetch` 函數支援 file 協定來解決讀取檔案相關的問題。
https://github.com/denoland/deno/issues/3196
TypeScript 不支援將 `.ts` 擴展名的模組路徑編譯為 `.js` 擴展名,
而 Deno 的模組路徑一定是 `.ts` 擴展名。
因此,為 Node.js 模組設計的 TypeScript 專案的程式碼將無法在 Deno 裡運行。
而 Deno 的模組路徑一定是 `.ts` 擴展名。
因此,為 Node.js 模組設計的 TypeScript 專案的程式碼將無法在 Deno 裡運行。
TypeScript 5 開始支援 `allowImportingTsExtensions` 配置項,這允許在專案裡使用 `.ts` 擴展名,
但該配置項被限制為只能在配置為 `noEmit` 或 `emitDeclarationOnly` 的情況下使用,
這意味著使用 `.ts` 擴展名的同時不能生成可用於 Node.js 的程式碼。
但該配置項被限制為只能在配置為 `noEmit` 或 `emitDeclarationOnly` 的情況下使用,
這意味著使用 `.ts` 擴展名的同時不能生成可用於 Node.js 的程式碼。
Deno 官方推進的 JavaScript 套件註冊表。
儘管 JSR 在宣傳上標榜自己是一個現代 JavaScript 的套件註冊表,但它仍然只是 Deno 版本的 npm。
JSR 不是 npm 的超集,就像 TypeScript 不是 JavaScript 的超集一樣。
儘管 JSR 在宣傳上標榜自己是一個現代 JavaScript 的套件註冊表,但它仍然只是 Deno 版本的 npm。
JSR 不是 npm 的超集,就像 TypeScript 不是 JavaScript 的超集一樣。
該註冊表很大程度上是為了解決 Deno 存在的依賴管理問題(Ryan Dahl 在 2018 年擲出的迴旋鏢終於打中了自己):
不同的模組會導入來自不同註冊表的依賴項,或是因為缺乏 SemVer 導致導入同一註冊表依賴項的不同子版本。
這導致專案的體積膨脹(會增加 LSP 負擔),導入的依賴項之間缺乏引用相等性。
不同的模組會導入來自不同註冊表的依賴項,或是因為缺乏 SemVer 導致導入同一註冊表依賴項的不同子版本。
這導致專案的體積膨脹(會增加 LSP 負擔),導入的依賴項之間缺乏引用相等性。
Deno 官方聲稱原來的套件註冊表 deno.land/x仍可繼續使用,
但考慮到官方的標準庫 std 在 deno.land/x 上已經停更,預期繼續在 deno.land/x 發佈套件是沒有意義的。
但考慮到官方的標準庫 std 在 deno.land/x 上已經停更,預期繼續在 deno.land/x 發佈套件是沒有意義的。
現在可以(像 Deno 1.28 添加的對 npm 模組的支援那樣)使用專用前綴 `=jsr:=`,簡化了 URL。
https://github.com/oakserver/oak
https://fresh.deno.dev/
Deno 官方於 2022 年推出的全棧 Web 框架,對標 Next.js。
不建議使用它,因為:
- 幾乎沒有 React 函式庫為 Deno 支援做測試。
- 內部使用的是 React 的輕量變體 Preact,這是一個沒有前途的技術路線。
Deno 可以透過 CDN 導入 JSDOM。
import { JSDOM } from 'https://esm.sh/jsdom@22.1.0'https://github.com/b-fuze/deno-dom
該專案是 Rust 的 html5ever 套件的綁定。
使用 Deno FFI 的 SQLite。
優點:
- 介面與 better-sqlite3 基本相同。
- 高性能。
編譯為 WASM 的 SQLite。
優點:
- 最小權限。
- 跨平台。
缺點:
- 受到 Deno 檔案系統 API 的限制。
- 預設啟用的編譯選項非常少,很可能需要自己編譯。
自 Deno 1.21 開始,標準庫提供了相當多的測試功能,
這使得在大多數情況下不需要使用第三方函式庫就可以完成測試。
Deno 的這種技術選擇有效避免了 Node.js 測試的供應商綁定問題。
這使得在大多數情況下不需要使用第三方函式庫就可以完成測試。
Deno 的這種技術選擇有效避免了 Node.js 測試的供應商綁定問題。
當前標準庫已經支援 BDD 風格、mock/stub、快照匹配、計時器模擬:
https://deno.land/std@0.181.0/testing
https://deno.land/std@0.181.0/testing
https://github.com/denoland/deno_std/issues/1779
Deno 提供一個內建的命令 `=deno bundle=` 用於將專案打包成一個腳本檔案。
Ryan Dahl 曾提議刪除此命令,但這個想法後來被撤回。
然而,在 v1.31 裡,該命令仍在沒有經過社群討論的情況下被列為棄用,官方手冊建議改用 esbuild。
然而,在 v1.31 裡,該命令仍在沒有經過社群討論的情況下被列為棄用,官方手冊建議改用 esbuild。
在 v2.4,deno bundle 莫名其妙回歸,其底層使用 esbuild。
在 v2.5,支援以 HTML 檔案作為打包的入口點。
在 v2.5,支援以 HTML 檔案作為打包的入口點。
用 `=deno run=` 命令運行腳本時,會載入 TypeScript 類型檢查器,這會導致 Deno 進程使用更多的記憶體。
如果先透過 `=deno compile=` 編譯後再運行,腳本的記憶體用量會有明顯改善。
如果先透過 `=deno compile=` 編譯後再運行,腳本的記憶體用量會有明顯改善。