隨着掘金開啓了第一期技術專題之「聊聊 Deno 的一些事兒」的徵稿活動,趕在截稿日的最後一天(08/04),一篇新的 Deno 文章呼之欲出。拜讀了下其餘夥伴的 Deno 徵文,有 Deno TCP Echo Server、在 Deno 上進行 TDD 實踐、Deno 程序如何調用 Rust、Deno 命令行開發方案、Deno 造一個簡單的 Router、Deno 的簡單應用以及 Deno 從入門到跑路、Deno 從零到架構開發等等文章,每篇都很生動精彩。那麼...若是你是這兩天看到的這篇文章,以爲有所幫助,歡(gan)迎(jin)來個人掘金文章裏點點贊,可讓我得到一個不錯的掘金周邊禮物~若是是將來某天看到的,戳這裏。git
本篇的主題是「通讀 Deno 架構」,切入的方向是「命令行指令通讀」的角度。關於「通讀 Deno 架構」主題,感受能夠挖坑出一個系列文章來,好比從 CLI、標準庫、內核以及工具庫角度來深刻到源碼之中。github
從命令行指令能夠看出,Deno 官方內置了不少工具用來測試、打包、格式化、Linter、安裝依賴庫等;而在 Node 中,咱們可能須要尋找並選型大量的第三方庫來填補每個功能。一塊兒來看看都有哪些工具吧!本文寫做時間 14h+,大量重構後沉澱出的目錄結構:web
《Deno 鑽研之術》系列於 Deno v1 發佈之日全新推出,不按期更新在 Github 中( https://github.com/hylerrix/deno-tutorial ✨),官網( http://deno-tutorial.js.org)。讓咱們一塊兒按部就班學 Deno,先易後難補 Node,面向將來開發屬於本身的 Deno Web App。歡迎訂閱,歡迎交流。
瞭解一個命令的最快速實用的方法就是直接閱讀其幫助文檔,每行幫助信息都是簡短且關鍵的介紹,不難理解和翻譯。終端輸入以下命令(help 或 --help 用來打印全局幫助信息或給定子命令的幫助信息):chrome
$ deno --help
從而得到 Deno 的基本幫助信息:shell
# 以 REPL 模式啓動: $ deno # 執行一個腳本: $ deno run https://deno.land/std/examples/welcome.ts # 在 Shell 中執行一段代碼: $ deno eval "console.log(30933 + 404)"
結合 deno --help 中出現的選項以及一般也會在 14 個內置工具包的幫助信息中看到的選項,將通用指令整理在這裏作一個通覽(只要某指令被使用兩次及以上便視爲通用指令,幾乎涵蓋了全部):編程
注:如下表格整理了好幾小時,若是能幫到你,別忘記多多點贊喲。挖個坑:之後能夠繪製出一個思惟導圖來。同時,若是哪裏有差錯,歡迎在評論區 Github 倉庫 issues 裏留言哈。
序號 | 選項 | 哪些工具可使用? | 用途 |
---|---|---|---|
01 | -h, --help | 所有 | 打印幫助信息 |
02 | -L, --log-level <log-level> | 所有 | 設置日誌級別 [可能的值: debug, info] |
03 | -q, --quiet | 所有 | 禁止診斷輸出;默認狀況下,子命令會將可讀性友好的診斷消息打印到 stderr;若是設置了這個標誌,則將這些消息限制爲 errors |
04 | -A, --allow-all | run, install, test | 容許全部權限,這將禁用全部安全限制 |
05 | --allow-env | run, install, test | 容許環境訪問,例如讀取和設置環境變量 |
06 | --allow-hrtime | run, install, test | 容許高精度時間測量,高精度時間可以在計時攻擊和特徵識別中使用 |
07 | --allow-net=<allow-net> | run, install, test | 容許網絡訪問。能夠指定一系列用逗號分隔的域名,來提供域名白名單 |
08 | --allow-plugin | run, install, test | 容許加載插件。請注意:這目前是一個不穩定功能 |
09 | --allow-read=<allow-read> | run, install, test | 容許讀取文件系統。能夠指定一系列用逗號分隔的目錄或文件,來提供文件系統白名單。 |
10 | --allow-run | run, install, test | 容許運行子進程。請注意,子進程不在沙箱中運行,所以沒有與 deno 進程相同的安全限制,請謹慎使用 |
11 | --allow-write=<allow-write> | run, install, test | 容許寫入文件系統。您能夠指定一系列用逗號分隔的目錄或文件,來提供文件系統白名單 |
12 | --cert <FILE> | run, install, bundle, chche, eval, info, test, upgrade, repl | 從 PEM 編碼的文件中加載證書頒發機構 |
13 | -c, --config <FILE> | run, install, budle, cache, test | 讀取 tsconfig.json 配置文件 |
14 | --unstable | run, install, bundle, cache, doc, eval, fmt, info, lint, test, types, repl | 開啓不穩定的 APIs 支持 |
15 | --inspect=<HOST:PORT> | run, eval, test, repl | 激活監聽器 主機:端口 (默認: 127.0.0.1:9229) |
16 | --inspect-brk=<HOST:PORT> | run, eval, test, repl | 在 主機:端口 上激活監聽器,並在用戶腳本啓動時中斷 |
17 | --v8-flags=<v8-flags> | run, eval, test, repl | 設置 V8 命令行選項。幫助: --v8-flags=--help |
18 | --cached-only | run, test | 要求遠程依賴項已經被緩存 |
19 | -r, --reload=<CACHE_BLOCKLIST> | run, cache, doc, test | 從新加載源代碼緩存(從新編譯TypeScript)。從新加載所有/僅標準模塊/特定模塊 |
20 | --lock <FILE> | run, bundle, cache, test | 檢查指定的鎖文件 |
21 | --lock-write | run, bundle, cache, test | 寫入鎖文件,和 --lock 一塊兒使用 |
22 | --no-check | run, cache, info, test | 禁用 TypeScript 的類型檢查,這會大大減小程序的啓動時間 |
23 | --no-remote | run, cache, test | 不解析遠程模塊 |
24 | --seed <NUMBER> | run, test | Math.random() 種子 |
25 | --importmap <FILE> | run, install, bundle, test | 不穩定:讀取 import map 文件 |
26 | --json | doc, info | 以 JSON 格式輸出文檔 |
具體通用指令會在「通讀 Deno 通用指令」章節進行深刻了解。json
幫助信息中初步介紹了這 14 個內置工具(爲了強調每一個工具的獨立性,這些工具暫時都翻譯爲「xx 器」):緩存
序號 | 名稱 | 命令 | 功能 |
---|---|---|---|
01 | 運行器 | deno run | 運行指定文件名或 URL 程序。 使用「-」做爲文件名從標準輸入中讀取 |
02 | 腳本安裝器 | deno install | 將腳本安裝爲可執行文件 |
03 | 打包器 | deno bundle | 將模塊和依賴項打包到單個文件中 |
04 | 緩存器 | deno cache | 緩存依賴 |
05 | 文檔生成器 | deno doc | 顯示某模塊的文檔 |
06 | 執行器 | deno eval | 執行一段腳本 |
07 | 格式化器 | deno fmt | 格式化源文件 |
08 | 依賴檢查器 | deno info | 顯示有關緩存的信息或與源文件相關的信息 |
09 | 規範器 | deno lint | 規範化源文件 |
10 | 測試器 | deno test | 執行測試 |
11 | 類型器 | deno types | 打印運行時 TypeScript 聲明 |
12 | 補全器 | deno completions | 生成 Shell 補全信息 |
13 | 升級器 | deno upgrade | 將 Deno 可執行文件升級到給定版本 |
14 | REPL 器 | deo repl | 讀取/執行/打印/循環 |
具體工具會在「通讀 Deno 內置工具包」章節進行深刻了解。安全
幫助信息裏初步介紹了這 6 個環境變量:bash
序號 | 變量名 | 用途 | 備註 |
---|---|---|---|
01 | DENO_DIR | 設置緩存目錄 | |
02 | DENO_INSTALL_ROOT | 設置 Deno 安裝的軟件包輸入目錄 | 默認爲 $HOME/.deno/bin |
03 | NO_COLOR | 設置禁止使用顏色 | |
04 | DENO_CERT | 從 PEM 編碼的文件加載證書頒發機構 | |
05 | HTTP_PROXY | HTTP 請求的代理地址 | 模塊 downloads 和 fetch |
06 | HTTPS_PROXY | HTTPS 請求的代理地址 | 模塊 downloads 和 fetch |
具體基本環境變量會在「通讀 Deno 環境變量」章節進行深刻了解。
相關實戰代碼都收錄在 《Deno 鑽研之術》倉庫中的 demos/ningowood/v1-cli-example 下。
本章目錄按照 14 個內置工具使用到的數量進行由大到小的排序。
這兩個指令全部內置工具均可以使用。
在 --log-level 中,能夠加入 debug 或 info 參數 來設置日誌等級。其中設置爲 debug 時會出現以下信息。此時是很是詳細的信息,一個簡單的啓動和網絡訪問都會打印出不少行的日誌來。
$ deno run --allow-net --log-level debug main.ts Deno isolate init with snapshots. rust:shared_queue:reset DEBUG JS - cwd /Users/{$HOME}/WorkSpace/Hylerrix/deno-tutorial/demos/ningowood/v1-cli-example DEBUG JS - args [] ... ⚠️️ Granted network access to "0.0.0.0:8000" New listener 3 0.0.0.0:8000 Welcome to Deno 🦕 http://localhost:8000/ DEBUG JS - sendAsync op_accept
--quiet 指令於 2019-10-20 日的 issues 被提出新功能建議(#3162),2020-03-10 日成功添加。目的之一是解決屢次運行同一程序但得到到不一樣的輸出的狀況。官方文檔上該指令介紹是:將原本可讀性友好的診斷消息限制爲通用錯誤類型。
這三個指令是除了全部指令都能用到的 --log-level 和 --quiet 外,被使用量最大的前三名。
--unstable 容許程序執行時使用不穩定的 API 列表。什麼樣的 API 是不穩定的?官網文檔這麼解答:
縱使 Deno v1 開始 Deno 命名空間的 API 穩定起來,但並不是 Deno 的全部功能均可以投入生產。因爲還沒有準備就緒的功能仍處於草稿階段,所以將其鎖定在 --unstable 命令行標誌後面。
不穩定的 API 大多沒有通過安全性檢查,未來可能會發生重大的 API 更改,而且還沒有準備好投入生產環境。
同時,Deno 的標準模塊(https://deno.land/std/)也尚不穩定。當前 Deno 對標準模塊的版本與 CLI 不一樣,以強調不穩定這一特色。 請注意,與 Deno 命名空間不一樣,使用標準模塊不須要 --unstable 標誌(除非標準模塊自己使用了不穩定的 Deno 功能)。測試方式:
$ deno install --unstable --allow-read --allow-write --allow-net https://deno.land/x/pagic/mod.ts
--cert 用來從 PEM 編碼的文件中加載證書頒發機構。那麼問題來了:
--config 用來讀取 tsconfig.json 文件,固然也能夠讀取其它名稱的文件來看成 tsconfig.json。
deno run --allow-net main.ts --config tsconfig.json
這幾個指令均只能在 run、eval、test 或 repl 四個工具包中使用。
Deno 支持 V8 Inspector Protocol,使用 --inspect 或 --inspect-brk 指令能夠在 Chrome Devtools 或其餘支持該協議的客戶端(好比 VSCode)上調試 Deno 程序。
--inspect 容許在任什麼時候間點鏈接調試器,而 --inspect-brk 選項會等待調試器鏈接,在第一行代碼處暫停執行。輸入如下代碼,打開 chrome://inspect,點擊 target 旁邊的 Inspect 進行調試測試:
$ deno run --inspect-brk --allow-read --allow-net https://deno.land/std/http/file_server.ts Debugger listening on ws://127.0.0.1:9229/ws/4947ac73-b9fc-4fd2-9336-c6071f4f3e9e Debugger session started. Debugger session ended: WebSocket protocol error: Connection reset without closing handshake. HTTP server listening on http://0.0.0.0:4507/
--v8-flags 前身是 --v8-options,於 2019-11-21 日(#3389)更替爲 --v8-flags,負責設置 v8 的命令行選項。能夠這樣瞭解具體參數:
$ deno run --v8-flags=--help main.ts SSE3=1 SSSE3=1 SSE4_1=1 SSE4_2=1 SAHF=1 AVX=1 FMA3=1 BMI1=1 BMI2=1 LZCNT=1 POPCNT=1 ATOM=0 Synopsis: shell [options] [--shell] [<file>...] d8 [options] [-e <string>] [--shell] [[--module] <file>...] ...
--allow-* 做爲一個總體,只被 run、install 和 test 三個工具分別使用,其中包括:
在 Denon (監聽 Deno 應用程序中的全部更改並自動從新啓動,還能夠配置更多功能)中,能夠這樣簡單的設置在 denon.config.ts 中:
import { DenonConfig } from "https://deno.land/x/denon/mod.ts" import { config as env } from "https://deno.land/x/dotenv/mod.ts" const config: DenonConfig = { scripts: { start: { allow: [ "env", "net", "read", "write", "plugin" ], ... } export default config
執行 denon start 這將默認替換爲:
$ deno run --allow-net --allow-env --allow-write --allow-read --allow-plugin --unstable main.ts
這兩個指令只被 run 和 test 工具使用。
--cached-only 要求遠程依賴已經被緩存,當咱們使用這個指令從遠程找一個沒有緩存過其軟件包的 Deno 程序執行的時候,會報錯沒法從緩存中找到這個軟件包:
$ deno run --allow-net --cached-only not-cache.ts error: Cannot find module "https://deno.land/x/alosaur@v0.21.1/mod.ts" from "file:///Users/{$HOME}/WorkSpace/Hylerrix/deno-tutorial/ ...demos/ningowood/v1-cli-example/not-cache.ts" in cache, --cached-only is specified
--seed 爲程序提供種子隨機值。程序怎麼獲取這個隨機值?留下來之後思考。
$ deno run --allow-net --seed 1 main.ts
這五個指令是剩餘的最後指令,分別被如下工具使用:
--reload 將從新緩存源碼,並從新編譯 TypeScript,其中又包括:
--lock 和 --lock-write 用來檢查鎖文件,由於在眼花繚亂的各大庫的多版本中,管理、鎖定文件版本也是很重要的;--no-check 禁用 TypeScript 的類型檢查,從而大大減小程序的啓動時間;--no-remote 來不解析遠程模塊。
$ deno run --allow-net --reload main.ts $ deno run --allow-net --lock lock.json main.ts Subresource integrity check failed --lock=lock.json https://deno.land/std@0.63.0/textproto/mod.tsa $ deno run --allow-net --no-check main.ts $ deno run --allow-net --no-remote main.ts
相關實戰代碼都收錄在 《Deno 鑽研之術》倉庫中的 demos/ningowood/v1-cli-example 下。
因爲本文在「通讀 Deno 通用指令章節」將 Deno 內置工具包可複用的指令都已經一一介紹了一遍。本章重點以目錄的形式強調 14 個內置工具包的獨立性(中文名以 xx 器來命名),並進行除了通用指令外的一些獨特介紹。
run 工具支持近乎 100% 的通用指令列表(--json 指令除外),且上一個章節的通用指令示例都以 run 工具來舉例,這裏無需多講。
deno run [OPTIONS] <腳本參數>...
# 默認狀況下全部的程序都會運行在安全沙盒中,沒法訪問硬盤、網絡或生成子進程。 $ deno run https://deno.land/std/examples/welcome.ts # 給予全部權限 $ deno run -A https://deno.land/std/http/file_server.ts # 給予讀取權限和網絡監聽權限: $ deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts # 給予容許讀取權限的硬盤目錄白名單: $ deno run --allow-read=/etc https://deno.land/std/http/file_server.ts # Deno 容許指定文件名 「-」 以從 stdin 中讀取文件。 $ curl https://deno.land/std/examples/welcome.ts | target/debug/deno run -
deno install [OPTIONS] <命令>...
獨特指令:
-f, --force
:強制覆蓋現有安裝-n, --name <NAME>
:可執行文件名--root <PATH>
:安裝路徑$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts $ deno install https://deno.land/std/examples/colors.ts # 要更改可執行文件的名稱,請使用 -n/-name: $ deno install --allow-net --allow-read -n serve https://deno.land/std/http/file_server.ts # 可執行文件名稱默認狀況下被推斷: # - 嘗試獲取 URL 路徑文件結構。正如上方上面的例子 # become 'file_server'. # - 若是文件結構是通用名稱(例如「main」、「mod」、「index」或「 cli」),而且該路徑沒有父級,則採用父級路徑的文件名。不然,使用通用名稱解決。 # 要更改安裝根目錄,請使用 --root: $ deno install --allow-net --allow-read --root /usr/local https://deno.land/std/http/file_server.ts # 按優先級肯定安裝路徑的根目錄: # - --root option # - DENO_INSTALL_ROOT 環境變量 # - $HOME/.deno # 若是須要,必須將它們手動添加到路徑中。
deno bundle [OPTIONS] <source_file> [out_file]
# 輸入一個單獨的 JavaScript 文件,其擁有全部相關依賴: $ deno bundle https://deno.land/std/examples/colors.ts colors.bundle.js # 若是沒有指定輸入文件,輸入將會寫入到標準輸出流中: $ deno bundle https://deno.land/std/examples/colors.ts
deno cache [OPTIONS] <file>...
# 下載並編譯包括全部靜態依賴項的模塊並保存在 # 本地緩存中,無需運行任何代碼: $ deno cache https://deno.land/std/http/file_server.ts # 除非之後運行此模塊,不然不會觸發下載或編譯 # --reload 已指定。
deno doc [OPTIONS] [ARGS]
獨特指令:
--private
:輸出私有文檔# 輸出文檔到標準輸入流中: $ deno doc ./path/to/module.ts # 輸出私有文檔到標準輸出流中: $ deno doc --private ./path/to/module.ts # 以 JSON 格式輸出文檔: $ deno doc --json ./path/to/module.ts # 定位特定的符號: $ deno doc ./path/to/module.ts MyClass.someField # 顯示運行時內置文檔: $ deno doc $ deno doc --builtin Deno.Listener
deno eval [OPTIOS] <CODE>
獨特指令:
-p, --print
:打印結果到標準輸出流中-T, --ts
:將輸入視爲 TypeScript# 從命令行中執行 JavaScript。 $ deno eval "console.log('hello world')" # 以 TypeScript 方式執行: $ deno eval -T "const v: string = 'hello'; console.log(v)" # 此命令具備對全部權限的隱式訪問權限(--allow-all)。
deno fmt [OPTIONS] [FILE]...
獨特指令:
--check
:檢查源文件是否已被格式化--ignore=<ignore>
:忽略格式化特定的源文件。 與 --unstable 一塊兒使用。$ deno fmt --help $ deno fmt $ deno fmt myfile1.ts myfile2.ts $ deno fmt --check # 格式化標準輸入流並輸出到標準輸出流: $ cat file.ts | deno fmt - # 經過在其前面加上忽略註釋來忽略此行代碼格式化: # // deno-fmt-ignore # 經過在文件頂部添加忽略註釋來忽略此文件格式化: # // deno-fmt-ignore-file
deno info [OPTIONS] [FILE]
# 獲取有關模塊的信息: $ deno info https://deno.land/std/http/file_server.ts # 將顯示如下信息: # local: 文件的本地路徑 # type: JavaScript、TypeScript 或者 JSON。 # compiled: 編譯源代碼的本地路徑。(僅 TypeScript) # map: 源映射的本地路徑。 (僅 TypeScript) # deps: 源文件的依賴關係樹。 # 沒有任何其餘參數,「deno info」 將顯示: # DENO_DIR: 包含 Deno 管理文件的目錄。 # Remote modules cache: 包含下載的遠程模塊的子目錄。 # TypeScript compiler cache: 包含 TS 編譯器輸出的子目錄。
獨特指令:
[OPTIONS] [FILE]...
$ deno lint --unstable $ deno lint --unstable myfile1.ts myfile2.js # 列出可用規則: $ deno lint --unstable --rules # 經過在其前面加上忽略註釋來忽略下一行的診斷,規則名稱: # // deno-lint-ignore no-explicit-any # // deno-lint-ignore require-await no-empty # 必須在忽略註釋以後指定要忽略的規則的名稱。 # 還支持 ESLint 忽略註釋: # // eslint-ignore-next-line @typescrit-eslint/no-explicit-any no-empty # 經過在文件頂部添加忽略註釋來忽略整個文件: # // deno-lint-ignore-file
deno test [OPTIONS] [文件名]...
獨特指令:
# 執行給定的模塊,運行'Deno.test()'聲明的全部測試,而後將結果輸出到到標準輸出溜中: $ deno test src/fetch_test.ts src/signal_test.ts # 目錄參數擴展爲與 glob 匹配的全部包含文件 # {*_,*.,}test.{js,mjs,ts,jsx,tsx}: $ deno test src/
deno types [OPTIONS]
$ deno types --help $ deno types > lib.deno.d.ts # 聲明文件能夠保存並用於錄入新內容。
deno completions [OPTIONS] <shell>
$ deno completions bash > /usr/local/etc/bash_completion.d/deno.bash $ source /usr/local/etc/bash_completion.d/deno.bash # [shell 可能的值: zsh, bash, fish, powershell, elvish]
deno upgrade [OPTIONS]
獨特指令:
--dry-run
:執行全部檢查,而不替換舊的 exe-f, --force
:即便不是過時也要替換當前的 exe--output <output>
:將更新版本輸出到的路徑--version <version>
:想要升級到的版本號$ deno upgrade --help # 默認將更新到最新版。 # 該版本是從這裏下載: # https://github.com/denoland/deno/releases # 而且用於替換當前的可執行文件。 # 若是您不想替換當前的 Deno 可執行文件,而是下載一個新版本到其餘位置,請使用 --output 標誌 $ deno upgrade --output $HOME/my_deno
deno repl [OPTIONS]
$ deno repl # deno
相關實戰代碼都收錄在 《Deno 鑽研之術》倉庫中的 demos/ningowood/v1-cli-example 下。
DENO_DIR 默認爲 $HOME/.cache/deno,但能夠設置爲任何路徑。這是 Deno 存放生成的代碼和緩存的源碼的路徑。
輸入 deno info,能夠看到本身的緩存位置,其中爲遠程模塊、TypeScript 編譯位置提供了專門的目錄。
$ deno info # DENO_DIR 位置: "/Users/{$HOME}/Library/Caches/deno" # 遠程模塊緩存位置: "/Users/{$HOME}/Library/Caches/deno/deps" # TypeScript 編譯緩存位置: "/Users/{$HOME}/Library/Caches/deno/gen" $ tree -L 2 /Users/{$HOME}/Library/Caches/deno . ├── deno_history.txt ├── deps │ ├── http │ └── https ├── gen │ ├── xxx.js │ ├── xxx.js.map │ ├── file │ └── https ├── lib.deno.d.ts ├── lib.deno_runtime.d.ts └── lib.webworker.d.ts
默認爲 $HOME/.deno/bin。輸入以下命令,能夠看到我目前安裝在全局的幾個 Deno 程序:
$ tree /Users/{$HOME}/.deno . └── bin ├── Trex ├── Trex_Cache_Map ├── deno ├── denon ├── pagic └── vr
若是 NO_COLOR 被設置,Deno 將會關閉彩色輸出 (https://no-color.org)。用戶代碼能夠經過布爾常量 Deno.noColor 測試 NO_COLOR 是否被設置,這不須要環境權限 (--allow-env)。
$ deno run var.ts Check file:///Users/didi/WorkSpace/Hylerrix/deno-tutorial/demos/ningowood/v1-cli-example/no-color.ts false
留個空白猜猜怎麼用。
至此,《從 CLI 指令通讀 Deno v1.x 全特性》文章大功告成。在寫做的這 14h+ 過程當中,產生了不少靈感,也對更多內容感興趣以爲能夠深挖。奈何一篇文章能承載的內容十分有限,因此能夠從本文引起思考的一些有趣的主題也就先推遲再看了。同時,將來極可能會有更多的指令做爲新功能推出,或許也有些指令因爲不在文檔幫助信息中而沒辦法收錄。
總之能夠繼續學習的地方還有不少!能夠入手學習 Deno 的角度也很是之多。期待一塊兒進行更多的編程實戰後,對 Deno CLI 特性會有更爲全面的認識。
訂閱?你懂得: