├── docs ├── rustdoc ├── typedoc ├── welcome.ts ├── favicon.ico ├── images │ ├── deno_logo.png │ ├── deno_logo_2.gif │ ├── schematic_v0.2.png │ └── deno_logo_3.svg ├── toc.js ├── sticky_toc.js ├── manual.html ├── style_guide.html ├── style.css ├── showdown_toc.js ├── app_test.js ├── benchmarks.html ├── style_guide.zh.md ├── index.html ├── app.js ├── style_guide.md ├── manual.zh.md └── manual.md ├── .mds-list ├── .gitignore ├── sync-en.sh ├── readme.md ├── style_guide.zh.md ├── style_guide.md ├── manual.zh.md └── manual.md /docs/rustdoc: -------------------------------------------------------------------------------- 1 | ../target/doc/ -------------------------------------------------------------------------------- /docs/typedoc: -------------------------------------------------------------------------------- 1 | ../target/typedoc/ -------------------------------------------------------------------------------- /.mds-list: -------------------------------------------------------------------------------- 1 | source/manual.md 2 | source/style_guide.md 3 | -------------------------------------------------------------------------------- /docs/welcome.ts: -------------------------------------------------------------------------------- 1 | console.log("Welcome to Deno 🦕"); 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | fork 4 | source 5 | hub-create.sh -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chinanf-boy/deno-website-zh/master/docs/favicon.ico -------------------------------------------------------------------------------- /docs/images/deno_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chinanf-boy/deno-website-zh/master/docs/images/deno_logo.png -------------------------------------------------------------------------------- /docs/images/deno_logo_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chinanf-boy/deno-website-zh/master/docs/images/deno_logo_2.gif -------------------------------------------------------------------------------- /docs/images/schematic_v0.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chinanf-boy/deno-website-zh/master/docs/images/schematic_v0.2.png -------------------------------------------------------------------------------- /docs/toc.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | let H = `
    `; 3 | 4 | function liEl(str, id) { 5 | return `
  1. ${str}
  2. `; 6 | } 7 | 8 | function run() { 9 | setTimeout(() => { 10 | if (window.anchors && window.anchors.elements.length) { 11 | let lis = window.anchors.elements.map(el => { 12 | return liEl(el.innerText, el.id); 13 | }); 14 | let result = `${H}${lis.join('\n')}
`; 15 | document.getElementsByClassName("toc")[0].innerHTML = result; 16 | } else { 17 | console.log('query anchors again'); 18 | run(); 19 | } 20 | }, 100); 21 | } 22 | 23 | run(); 24 | })(); 25 | -------------------------------------------------------------------------------- /sync-en.sh: -------------------------------------------------------------------------------- 1 | cat './.mds-list' | while read line || [[ -n ${line} ]] 2 | do 3 | testseq="zh.md" 4 | if [[ $line =~ $testseq || "$line" == "" ]]; then 5 | echo "skip $line" 6 | else 7 | lowline=`echo "$line" | awk '{print tolower($0)}'` 8 | # lowwer string 9 | zh=${line//source\//} 10 | dir=$(dirname $zh) 11 | 12 | source_readme="./source/readme.md" 13 | if [[ $lowline == $source_readme ]];then 14 | # source/[readme|REAMDE].md => en.md 15 | filename="en.md" 16 | else 17 | # source/other.md => ./other.md 18 | filename=$(basename $zh) 19 | fi 20 | echo "$line >> $dir/$filename" 21 | mkdir -p $dir && cp $line "$_/$filename" 22 | fi 23 | done -------------------------------------------------------------------------------- /docs/sticky_toc.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | const isTopOut = function(elem) { 3 | const bounding = elem.getBoundingClientRect(); 4 | return bounding.top <= 20 && bounding.left >= 0; 5 | }; 6 | 7 | function changePosition(el, add) { 8 | if (add) { 9 | el.style.position = 'fixed'; // actually use fixed 10 | el.style.top = '0em'; 11 | el.style.bottom = '1em'; 12 | // el.style.right = '0em'; 13 | el.style.maxHeight = 'max-content'; 14 | 15 | } else { 16 | el.style.position = 'absolute'; 17 | // el.style.right = '1em'; 18 | el.style.top = ''; 19 | el.style.bottom = ''; 20 | } 21 | } 22 | let manualEl; 23 | let tocEl; 24 | 25 | window.addEventListener('scroll', event => { 26 | !manualEl && (manualEl = document.getElementById('manual')); 27 | !tocEl && (tocEl = document.getElementsByClassName('toc')[0]); 28 | 29 | if (window.innerWidth >= 1200) { 30 | if (isTopOut(manualEl) && tocEl.style.position != 'fixed') { 31 | changePosition(tocEl, true); 32 | } else if (!isTopOut(manualEl) && tocEl.style.position == 'fixed') { 33 | changePosition(tocEl, false); 34 | } 35 | } 36 | }); 37 | })(); 38 | -------------------------------------------------------------------------------- /docs/manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Deno Manual 6 | 7 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 |
26 |
27 | 28 | 55 |
56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/style_guide.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Deno Style Guide 6 | 7 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 |
26 |
27 | 28 | 55 |
56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #444; 3 | background: #f0f0f0; 4 | padding: 0; 5 | 6 | line-height: 1.5; 7 | font-family: sans-serif; 8 | 9 | margin: 5ex 10ex; 10 | max-width: 80ex; 11 | } 12 | 13 | #manual img { 14 | width: 100%; 15 | max-width: 800px; 16 | } 17 | 18 | h1, 19 | h2, 20 | h3, 21 | h4 { 22 | font-weight: normal; 23 | margin-bottom: 0; 24 | } 25 | 26 | h1, 27 | h2, 28 | h3, 29 | h4, 30 | p, 31 | table { 32 | margin-left: 8px; 33 | margin-right: 8px; 34 | } 35 | 36 | table { 37 | border-collapse: collapse; 38 | margin-top: 8px; 39 | } 40 | td, 41 | th { 42 | font-weight: normal; 43 | text-align: center; 44 | border: 1px dotted #bbb; 45 | padding: 4px; 46 | } 47 | 48 | svg { 49 | margin: 0px; 50 | width: 100%; 51 | height: 300px; 52 | } 53 | 54 | a { 55 | color: #106ad5; 56 | } 57 | 58 | pre a { 59 | color: #001631; 60 | } 61 | 62 | h2 a, 63 | h3 a { 64 | display: none; 65 | color: #3bace5; 66 | text-decoration: none; 67 | } 68 | 69 | h2:hover a, 70 | h3:hover a { 71 | display: inline; 72 | } 73 | 74 | pre { 75 | /* background: rgba(36, 126, 233, 0.03); */ 76 | color: #161616; 77 | background: rgba(36, 126, 233, 0.1); 78 | padding: 15px; 79 | word-wrap: normal; 80 | overflow-x: auto; 81 | } 82 | 83 | header { 84 | display: flex; 85 | align-items: center; 86 | margin: 16px 4px; 87 | } 88 | 89 | header > * { 90 | margin: 8px; 91 | } 92 | 93 | header h1 { 94 | margin: 8px 0; 95 | } 96 | 97 | @media only screen and (max-device-width: 480px) { 98 | body { 99 | margin: 0; 100 | } 101 | } 102 | 103 | code { 104 | background: rgba(36, 126, 233, 0.1); 105 | padding: 2px 5px; 106 | color: #333; 107 | } 108 | 109 | .hljs { 110 | background: transparent; 111 | } 112 | 113 | .toc { 114 | position: relative; 115 | } 116 | 117 | @media only screen and (min-width: 1250px) { 118 | .toc { 119 | background-color: #fbf6ec; 120 | max-width: 40%; 121 | position: absolute; 122 | border: #968674 dashed 3px; 123 | right: 1em; 124 | width: var(--sidebar-width); 125 | overflow-y: auto; 126 | padding: 0 10px; 127 | font-size: 0.875em; 128 | box-sizing: border-box; 129 | -webkit-overflow-scrolling: touch; 130 | overscroll-behavior-y: contain; 131 | background-color: var(--sidebar-bg); 132 | color: var(--sidebar-fg); 133 | } 134 | 135 | .toc li { 136 | padding: 1px 3px; 137 | } 138 | 139 | .toc::-webkit-scrollbar { 140 | display: none; 141 | } 142 | } 143 | 144 | -------------------------------------------------------------------------------- /docs/showdown_toc.js: -------------------------------------------------------------------------------- 1 | // Extension loading compatible with AMD and CommonJs 2 | (function(extension) { 3 | "use strict"; 4 | 5 | if (typeof showdown === "object") { 6 | // global (browser or nodejs global) 7 | showdown.extension("toc", extension()); 8 | } else if (typeof define === "function" && define.amd) { 9 | // AMD 10 | define("toc", extension()); 11 | } else if (typeof exports === "object") { 12 | // Node, CommonJS-like 13 | module.exports = extension(); 14 | } else { 15 | // showdown was not found so we throw 16 | throw Error("Could not find showdown library"); 17 | } 18 | })(function() { 19 | function getHeaderEntries(sourceHtml) { 20 | if (typeof window === "undefined") { 21 | return getHeaderEntriesInNodeJs(sourceHtml); 22 | } else { 23 | return getHeaderEntriesInBrowser(sourceHtml); 24 | } 25 | } 26 | 27 | function getHeaderEntriesInNodeJs(sourceHtml) { 28 | var cheerio = require("cheerio"); 29 | var $ = cheerio.load(sourceHtml); 30 | var headers = $("h1, h2, h3, h4, h5, h6"); 31 | 32 | var headerList = []; 33 | for (var i = 0; i < headers.length; i++) { 34 | var el = headers[i]; 35 | headerList.push(new TocEntry(el.name, $(el).text(), $(el).attr("id"))); 36 | } 37 | 38 | return headerList; 39 | } 40 | 41 | function getHeaderEntriesInBrowser(sourceHtml) { 42 | // Generate dummy element 43 | var source = document.createElement("div"); 44 | source.innerHTML = sourceHtml; 45 | 46 | // Find headers 47 | var headers = source.querySelectorAll("h1, h2, h3, h4, h5, h6"); 48 | var headerList = []; 49 | for (var i = 0; i < headers.length; i++) { 50 | var el = headers[i]; 51 | headerList.push(new TocEntry(el.tagName, el.textContent, el.id)); 52 | } 53 | 54 | return headerList; 55 | } 56 | 57 | function TocEntry(tagName, text, anchor) { 58 | this.tagName = tagName; 59 | this.text = text; 60 | this.anchor = anchor; 61 | this.children = []; 62 | } 63 | 64 | TocEntry.prototype.childrenToString = function() { 65 | if (this.children.length === 0) { 66 | return ""; 67 | } 68 | var result = "\n"; 73 | return result; 74 | }; 75 | 76 | TocEntry.prototype.toString = function() { 77 | var result = "
  • "; 78 | if (this.text) { 79 | result += '' + this.text + ""; 80 | } 81 | result += this.childrenToString(); 82 | result += "
  • \n"; 83 | return result; 84 | }; 85 | 86 | function sortHeader(tocEntries, level) { 87 | level = level || 1; 88 | var tagName = "H" + level, 89 | result = [], 90 | currentTocEntry; 91 | 92 | function push(tocEntry) { 93 | if (tocEntry !== undefined) { 94 | if (tocEntry.children.length > 0) { 95 | tocEntry.children = sortHeader(tocEntry.children, level + 1); 96 | } 97 | result.push(tocEntry); 98 | } 99 | } 100 | 101 | for (var i = 0; i < tocEntries.length; i++) { 102 | var tocEntry = tocEntries[i]; 103 | if (tocEntry.tagName.toUpperCase() !== tagName) { 104 | if (currentTocEntry === undefined) { 105 | currentTocEntry = new TocEntry(); 106 | } 107 | currentTocEntry.children.push(tocEntry); 108 | } else { 109 | push(currentTocEntry); 110 | currentTocEntry = tocEntry; 111 | } 112 | } 113 | 114 | push(currentTocEntry); 115 | return result; 116 | } 117 | 118 | return { 119 | type: "output", 120 | filter: function(sourceHtml) { 121 | var headerList = getHeaderEntries(sourceHtml); 122 | 123 | // No header found 124 | if (headerList.length === 0) { 125 | return sourceHtml; 126 | } 127 | 128 | // Sort header 129 | headerList = sortHeader(headerList); 130 | 131 | // Skip the title. 132 | if (headerList.length == 1) { 133 | headerList = headerList[0].children; 134 | } 135 | 136 | // Build result and replace all [toc] 137 | var result = 138 | '
    \n\n
    \n"; 139 | return sourceHtml.replace(/\[toc\]/gi, result); 140 | } 141 | }; 142 | }); 143 | -------------------------------------------------------------------------------- /docs/app_test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. 2 | 3 | import { test, testPerm, assert, assertEquals } from "../js/test_util.ts"; 4 | import { 5 | createBinarySizeColumns, 6 | createExecTimeColumns, 7 | createThreadCountColumns, 8 | createSyscallCountColumns, 9 | createSha1List 10 | } from "./app.js"; 11 | 12 | const regularData = [ 13 | { 14 | created_at: "2018-01-01T01:00:00Z", 15 | sha1: "abcdef", 16 | binary_size: { 17 | deno: 100000000, 18 | "main.js": 90000000, 19 | "main.js.map": 80000000, 20 | "snapshot_deno.bin": 70000000 21 | }, 22 | throughput: { 23 | "100M_tcp": 3.6, 24 | "100M_cat": 3.0, 25 | "10M_tcp": 1.6, 26 | "10M_cat": 1.0 27 | }, 28 | req_per_sec: { 29 | node: 16000, 30 | deno: 1000 31 | }, 32 | benchmark: { 33 | hello: { 34 | mean: 0.05 35 | }, 36 | relative_import: { 37 | mean: 0.06 38 | }, 39 | cold_hello: { 40 | mean: 0.05 41 | }, 42 | cold_relative_import: { 43 | mean: 0.06 44 | } 45 | }, 46 | thread_count: { 47 | set_timeout: 4, 48 | fetch_deps: 6 49 | }, 50 | syscall_count: { 51 | hello: 600, 52 | fetch_deps: 700 53 | } 54 | }, 55 | { 56 | created_at: "2018-01-02T01:00:00Z", 57 | sha1: "012345", 58 | binary_size: { 59 | deno: 100000001, 60 | "main.js": 90000001, 61 | "main.js.map": 80000001, 62 | "snapshot_deno.bin": 70000001 63 | }, 64 | throughput: { 65 | "100M_tcp": 3.6, 66 | "100M_cat": 3.0, 67 | "10M_tcp": 1.6, 68 | "10M_cat": 1.0 69 | }, 70 | req_per_sec: { 71 | node: 1600, 72 | deno: 3.0 73 | }, 74 | benchmark: { 75 | hello: { 76 | mean: 0.055 77 | }, 78 | relative_import: { 79 | mean: 0.065 80 | }, 81 | cold_hello: { 82 | mean: 0.055 83 | }, 84 | cold_relative_import: { 85 | mean: 0.065 86 | } 87 | }, 88 | thread_count: { 89 | set_timeout: 5, 90 | fetch_deps: 7 91 | }, 92 | syscall_count: { 93 | hello: 700, 94 | fetch_deps: 800 95 | } 96 | } 97 | ]; 98 | 99 | const irregularData = [ 100 | { 101 | created_at: "2018-01-01T01:00:00Z", 102 | sha1: "123", 103 | benchmark: {}, 104 | throughput: {}, 105 | binary_size: {}, 106 | thread_count: {}, 107 | syscall_count: {} 108 | }, 109 | { 110 | created_at: "2018-02-01T01:00:00Z", 111 | sha1: "456", 112 | benchmark: { 113 | hello: {}, 114 | relative_import: {}, 115 | cold_hello: {}, 116 | cold_relative_import: {} 117 | }, 118 | throughput: { 119 | "100M_tcp": 3.0 120 | }, 121 | binary_size: { 122 | deno: 1 123 | }, 124 | thread_count: { 125 | set_timeout: 5, 126 | fetch_deps: 7 127 | }, 128 | syscall_count: { 129 | hello: 700, 130 | fetch_deps: 800 131 | } 132 | } 133 | ]; 134 | 135 | test(function createExecTimeColumnsRegularData() { 136 | const columns = createExecTimeColumns(regularData); 137 | assertEquals(columns, [ 138 | ["hello", 0.05, 0.055], 139 | ["relative_import", 0.06, 0.065], 140 | ["cold_hello", 0.05, 0.055], 141 | ["cold_relative_import", 0.06, 0.065] 142 | ]); 143 | }); 144 | 145 | test(function createExecTimeColumnsIrregularData() { 146 | const columns = createExecTimeColumns(irregularData); 147 | assertEquals(columns, [ 148 | ["hello", null, null], 149 | ["relative_import", null, null], 150 | ["cold_hello", null, null], 151 | ["cold_relative_import", null, null] 152 | ]); 153 | }); 154 | 155 | test(function createBinarySizeColumnsRegularData() { 156 | const columns = createBinarySizeColumns(regularData); 157 | assertEquals(columns, [ 158 | ["deno", 100000000, 100000001], 159 | ["main.js", 90000000, 90000001], 160 | ["main.js.map", 80000000, 80000001], 161 | ["snapshot_deno.bin", 70000000, 70000001] 162 | ]); 163 | }); 164 | 165 | test(function createBinarySizeColumnsIrregularData() { 166 | const columns = createBinarySizeColumns(irregularData); 167 | assertEquals(columns, [["deno", null, 1]]); 168 | }); 169 | 170 | test(function createThreadCountColumnsRegularData() { 171 | const columns = createThreadCountColumns(regularData); 172 | assertEquals(columns, [["set_timeout", 4, 5], ["fetch_deps", 6, 7]]); 173 | }); 174 | 175 | test(function createThreadCountColumnsIrregularData() { 176 | const columns = createThreadCountColumns(irregularData); 177 | assertEquals(columns, [["set_timeout", null, 5], ["fetch_deps", null, 7]]); 178 | }); 179 | 180 | test(function createSyscallCountColumnsRegularData() { 181 | const columns = createSyscallCountColumns(regularData); 182 | assertEquals(columns, [["hello", 600, 700], ["fetch_deps", 700, 800]]); 183 | }); 184 | 185 | test(function createSyscallCountColumnsIrregularData() { 186 | const columns = createSyscallCountColumns(irregularData); 187 | assertEquals(columns, [["hello", null, 700], ["fetch_deps", null, 800]]); 188 | }); 189 | 190 | test(function createSha1ListRegularData() { 191 | const sha1List = createSha1List(regularData); 192 | assertEquals(sha1List, ["abcdef", "012345"]); 193 | }); 194 | -------------------------------------------------------------------------------- /docs/benchmarks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Deno Benchmarks 6 | 7 | 8 | 9 | 10 | 11 | 12 |
    13 | 14 |

    Deno Continuous Benchmarks

    15 | 16 |

    17 | These plots are updated on every commit to 18 | master branch. 19 |

    20 | 21 |

    recent data

    22 |

    all data (takes a moment to load)

    23 | 24 |

    Execution time #

    25 |

    26 | This shows how much time total it takes to run a few simple deno 27 | programs: 28 | 31 | tests/002_hello.ts 32 | , 33 | tests/003_relative_import.ts, 37 | tests/worker_round_robin_bench.ts, and 41 | tests/worker_startup_bench.ts. For deno to execute typescript, it must first compile it to JS. A 45 | warm startup is when deno has a cached JS output already, so it should 46 | be fast because it bypasses the TS compiler. A cold startup is when deno 47 | must compile from scratch. 48 |

    49 |
    50 | 51 |

    Throughput #

    52 | 53 |

    54 | Time it takes to pipe a certain amount of data through Deno. 55 | 56 | 59 | echo_server.ts 60 | 61 | and 62 | 63 | cat.ts . Smaller is better. 65 |

    66 | 67 |
    68 | 69 |

    Req/Sec #

    70 | 71 |

    72 | Tests HTTP server performance. 10 keep-alive connections do as many 73 | hello-world requests as possible. Bigger is better. 74 |

    75 | 76 | 117 | 118 |
    119 | 120 |

    Max Latency #

    121 | 122 |

    123 | Max latency during the same test used above for requests/second. Smaller is better. 124 |

    125 | 126 |
    127 | 128 |

    Executable size #

    129 |

    deno ships only a single binary. We track its size here.

    130 |
    131 | 132 |

    Thread count #

    133 |

    How many threads various programs use.

    134 |
    135 | 136 |

    Syscall count #

    137 |

    138 | How many total syscalls are performed when executing a given script. 139 |

    140 |
    141 |
    142 | 143 | 144 | 145 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # denoland/deno [![explain]][source] [![translate-svg]][translate-list] 2 | 3 | 4 | 5 | [explain]: http://llever.com/explain.svg 6 | [source]: https://github.com/chinanf-boy/Source-Explain 7 | [translate-svg]: http://llever.com/translate.svg 8 | [translate-list]: https://github.com/chinanf-boy/chinese-translate-list 9 | [size-img]: https://packagephobia.now.sh/badge?p=Name 10 | [size]: https://packagephobia.now.sh/result?p=Name 11 | 12 | 「 JavaScript 和 TypeScript 安全运行时,使用 V8, Rust, 和 Tokio 构建。」 13 | 14 | [中文](./readme.md) | [english](https://github.com/denoland/deno) 15 | 16 | --- 17 | 18 | ## 校对 ✅ 19 | 20 | 21 | 22 | 23 | 24 | 25 | | 翻译的原文 | 与日期 | 最新更新 | 更多 | 26 | | ---------- | ------------- | -------- | -------------------------- | 27 | | [commit] | ⏰ 2019-04-07 | ![last] | [中文翻译][translate-list] | 28 | 29 | [last]: https://img.shields.io/github/last-commit/denoland/deno.svg 30 | [commit]: https://github.com/denoland/deno/tree/3324afbd404a4237f0339e50a345a5f20c4ea7dd 31 | 32 | 33 | 34 | 原文:denoland/deno/website 35 | 36 | - [x] readme 37 | - [x] [手册](./manual.zh.md) 38 | - [x] [风格指南](./style_guide.zh.md) 39 | 40 | ### 贡献 41 | 42 | 欢迎 👏 勘误/校对/更新贡献 😊 [具体贡献请看](https://github.com/chinanf-boy/chinese-translate-list#贡献) 43 | 44 | ## 生活 45 | 46 | [help me live , live need money 💰](https://github.com/chinanf-boy/live-need-money) 47 | 48 | --- 49 | 50 | 51 | 52 | 53 | # Deno 54 | 55 | JavaScript 和 TypeScript 安全运行时,使用 V8, Rust, 和 Tokio 构建。 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 72 | 79 | 80 | 81 | 82 | 92 | 93 | 94 | 97 | 104 | 114 | 115 | 116 | 117 | 124 | 125 |
    Linux & MacWindows
    deno 66 | 67 | 70 | 71 | 73 | 74 | 77 | 78 |
    deno_std 83 | 87 | 90 | 91 |
    95 | deno_install 96 | 98 | 99 | 102 | 103 | 105 | 109 | 112 | 113 |
    registry 118 | 119 | 122 | 123 |
    126 | 127 | ## 安装 128 | 129 | 使用 Shell: 130 | 131 | ```bash 132 | curl -fsSL https://github.com/denoland/deno_install/blob/master/install.sh | sh 133 | ``` 134 | 135 | Or 使用 PowerShell: 136 | 137 | ``` 138 | iwr https://github.com/denoland/deno_install/blob/master/install.ps1 | iex 139 | ``` 140 | 141 | 查看 [deno_install](https://github.com/denoland/deno_install) ,了解更多 142 | 143 | ## 例子 144 | 145 | 尝试运行一个简单程序: 146 | 147 | ```bash 148 | deno https://deno.land/welcome.ts 149 | ``` 150 | 151 | 或更为复杂点的: 152 | 153 | ```typescript 154 | import {serve} from 'https://deno.land/std@v0.3.2/http/server.ts'; 155 | 156 | async function main() { 157 | const body = new TextEncoder().encode('Hello World\n'); 158 | for await (const req of serve(':8000')) { 159 | req.respond({body}); 160 | } 161 | } 162 | 163 | main(); 164 | ``` 165 | 166 | ## 深挖... 167 | 168 | **[手册](http://llever.com/deno-website-zh/manual.html)** 169 | 170 | [API 参考](https://deno.land/typedoc/) 171 | 172 | [风格指南](http://llever.com/deno-website-zh/style_guide.html) 173 | 174 | [模块 存储库](https://deno.land/x/) 175 | 176 | [Twitter](https://twitter.com/deno_land) 177 | 178 | [发布记录](https://github.com/denoland/deno/blob/master/Releases.md) 179 | 180 | [社区聊天室](https://gitter.im/denolife/Lobby) 181 | 182 | [基准](https://deno.land/benchmarks.html) 183 | 184 | [awesome Deno](https://github.com/denolib/awesome-deno) 185 | -------------------------------------------------------------------------------- /docs/style_guide.zh.md: -------------------------------------------------------------------------------- 1 | # Deno 风格指南 2 | 3 | ## 使用 TypeScript 4 | 5 | ## 使用术语"模块(module)",而不是"库(library)"或"包(package)" 6 | 7 | 为了明确性和一致性,请避免使用术语"库"和"包"。而是使用"module"来指明单个 JS 或 TS 文件,当然还包括 TS / JS 代码的目录。 8 | 9 | ## 不要使用文件名`"index.ts"或"index.js"` 10 | 11 | Deno 不会对"index.js"或"index.ts"特殊处理。这些文件名的使用,会对当不用它们时,却可以被排除在模块描述之外,感到困惑。 12 | 13 | 如果代码目录需要默认入口点,请使用文件名`mod.ts`。文件名`mod.ts`遵循 Rust 的惯例,比`index.ts`简短,并且没有任何先入为主,关于其应该如何运作的观念。 14 | 15 | ## 在"deno-std"中,不依赖外部代码 16 | 17 | `deno_std`旨在成为所有 Deno 程序可以依赖的地基功能。我们希望向用户保证此代码,不包含可能未经审核的第三方代码。 18 | 19 | ## 在"deno-std"中,最小化依赖关系;不要进行循环导入。 20 | 21 | 虽然`deno_std`是一个独立的代码库,我们仍然必须小心保持,内部依赖关系的简单和易于管理。特别要注意,不要产生(死)循环导入。 22 | 23 | ## 为了保持一致性,文件名请使用下划线,而不是短划线。 24 | 25 | 示例:不是`file-server.ts`,使用`file_server.ts`。 26 | 27 | ## 使用 prettier 格式化代码。 28 | 29 | 更具体地说,代码行应在 80 列内,使用 2 空格缩进,并使用驼峰式。使用`//format.ts`调用 prettier。 30 | 31 | ## 导出的函数:最多 2 个参数,将其余的参数放入 options 对象。 32 | 33 | 设计函数接口时,请遵守以下规则。 34 | 35 | 1. 作为公有 API 一部分的函数需要 0-2 个必需参数,如果需要的话,加上一个选项(options)对象(总共最多 3 个)。 36 | 37 | 2. 可选参数,通常应该放进 options 对象。 38 | 39 | 如果只有一个参数,且我们将来不太可能添加更多可选参数,那么不在选项对象中的可选参数,是能够接受的。 40 | 41 | 3. 'options'参数是唯一的常规'Object'类型。 42 | 43 | 其他参数可以是对象(/容器类型),但它们必须与"普通"对象(`Object`)运行时,区分开来,方法是: 44 | 45 | - 一个有区别的原型(例如`Array`,`Map`,`Date`,`class MyThing`) 46 | - 一个众所周知的符号属性(例如,一个可迭代的`Symbol.iterator`)。 47 | 48 | 这允许 API 以向后兼容的方式扩展,即使选项对象的位置,发生变化也能行。 49 | 50 | ```ts 51 | // 不好的方式: 可选参数,不是options 对象的一部分。 (#2) 52 | export function resolve( 53 | hostname: string, 54 | family?: 'ipv4' | 'ipv6', 55 | timeout?: number 56 | ): IPAddress[] {} 57 | 58 | // 好的方式. 59 | export interface ResolveOptions { 60 | family?: 'ipv4' | 'ipv6'; 61 | timeout?: number; 62 | } 63 | export function resolve( 64 | hostname: string, 65 | options: ResolveOptions = {} 66 | ): IPAddress[] {} 67 | ``` 68 | 69 | ```ts 70 | export interface Environment { 71 | [key: string]: string; 72 | } 73 | 74 | // 不好的方式: `env` 可能是常规对象,因此无法区分是否为一个选项对象. (#3) 75 | export function runShellWithEnv(cmdline: string, env: Environment): string {} 76 | 77 | // 好的方式. 78 | export interface RunShellOptions { 79 | env: Environment; 80 | } 81 | export function runShellWithEnv( 82 | cmdline: string, 83 | options: RunShellOptions 84 | ): string {} 85 | ``` 86 | 87 | ```ts 88 | // 不好的方式: 超过 3 参数 (#1), 过多可选参数 (#2). 89 | export function renameSync( 90 | oldname: string, 91 | newname: string, 92 | replaceExisting?: boolean, 93 | followLinks?: boolean 94 | ) {} 95 | 96 | // 好的方式. 97 | interface RenameOptions { 98 | replaceExisting?: boolean; 99 | followLinks?: boolean; 100 | } 101 | export function renameSync( 102 | oldname: string, 103 | newname: string, 104 | options: RenameOptions = {} 105 | ) {} 106 | ``` 107 | 108 | ```ts 109 | // 不好的方式: 过多参数. (#1) 110 | export function pwrite( 111 | fd: number, 112 | buffer: TypedArray, 113 | offset: number, 114 | length: number, 115 | position: number 116 | ) {} 117 | 118 | // 更好. 119 | export interface PWrite { 120 | fd: number; 121 | buffer: TypedArray; 122 | offset: number; 123 | length: number; 124 | position: number; 125 | } 126 | export function pwrite(options: PWrite) {} 127 | ``` 128 | 129 | ## TODO 注释(待续讨论) 130 | 131 | TODO 注释应该在括号中,包含问题或作者的 github 用户名。例: 132 | 133 | ```ts 134 | // TODO(ry) Add tests. 135 | // TODO(#123) Support Windows. 136 | ``` 137 | 138 | ## 版权标题 139 | 140 | `deno_std`大多数文件,应具有以下版权标题: 141 | 142 | ```ts 143 | // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. 144 | ``` 145 | 146 | 如果代码来自其他地方,请确保该文件,具有适当的版权标题。我们`deno_std`只允许使用 MIT,BSD 和 Apache 许可代码。 147 | 148 | ## 顶级函数,不应使用箭头语法 149 | 150 | 顶级函数应该使用`function`关键词。箭头语法,应仅限闭包使用。 151 | 152 | 坏 153 | 154 | ```ts 155 | export const foo(): string => { 156 | return "bar"; 157 | } 158 | ``` 159 | 160 | 好 161 | 162 | ```ts 163 | export function foo(): string { 164 | return 'bar'; 165 | } 166 | ``` 167 | 168 | ## 不鼓励,使用元编程。包括代理的用法。 169 | 170 | 即使它意味着更多的代码,也要代码具备明确性。 171 | 172 | 在某些情况下,使用这些技术,可能是有意义的,但在绝大多数情况下,没有。 173 | 174 | ## 如果文件名,以下划线开头,请不要链接到它:"\_foo.ts"` 175 | 176 | 有时可能存在内部模块的需要,但其 API 不是稳定或可供链接的情况。在这种情况下,用下划线作为前缀。按照惯例,只有本文件目录中的(文件),才能导入它。 177 | 178 | ## 使用 jsdoc 文档化,导出 API 的情况 179 | 180 | 我们力求完整的文档。理想情况下,每个导出的符号,都应该有文档行。 181 | 182 | 如果可能,请编写 JS 文档。例: 183 | 184 | ```ts 185 | /** foo 做了某 bar. */ 186 | export function foo() { 187 | // ... 188 | } 189 | ``` 190 | 191 | 重要的是文档,易于给人阅读,但还需要提供额外的样式信息,以确保生成的文档是,更丰富的文本。因此,JSDoc 通常遵循 markdown 标记,来丰富文本。 192 | 193 | 虽然 markdown 支持 HTML 标签,但在 JSDoc 区块中,禁止使用。 194 | 195 | 代码格式字符串,应使用反引号(\`)标记而不是引号。例如: 196 | 197 | ```ts 198 | /** Import something from the `deno` module. */ 199 | ``` 200 | 201 | 不要文档化函数参数,除非它们的意图不明显(尽管它们,具有不明显意图,但 API 无论如何都应该考虑清楚)。因此`@param`通常,不应该使用。如果`@param`真使用了,那它不应该包括`type`,因为 TypeScript 已经是强类型的。 202 | 203 | ```ts 204 | /** 205 | * 带有不明显意图参数的函数 206 | * @param foo 描述不明显意图的参数 207 | */ 208 | ``` 209 | 210 | 应尽可能减小垂直间距。因此,单行注释应写为: 211 | 212 | ```ts 213 | /** JSDoc 单行标准写法 */ 214 | ``` 215 | 216 | 而不是 217 | 218 | ```ts 219 | /** 220 | * JSDoc 差的示例 221 | */ 222 | ``` 223 | 224 | 代码示例(区块),不应使用三个反引号(\`\`\`)表示。它们应该只用缩进:具体需要在区块之前空一行,并为示例的每一行,添加 6 个额外的空格。这比注释的第一列,多 4 个。例如: 225 | 226 | ```ts 227 | /** A straight forward comment and an example: 228 | * 229 | * import { foo } from "deno"; 230 | * foo("bar"); 231 | */ 232 | ``` 233 | 234 | 代码示例,不应包含其他注释。它已经在外注释中。如果它需要进一步的注释,那就不是一个很好的例子。 235 | 236 | ## 每个模块都应该有测试 237 | 238 | 每个模块应该有个测试文件`modulename_test.ts`,作为它的兄弟姐妹。例如模块`foo.ts`应该带着它的兄弟姐妹`foo_test.ts`。 239 | 240 | ## 单元测试应该是明确的 241 | 242 | 为了更好地理解测试,应在整个测试命令中,正确命名函数,比如: 243 | 244 | ``` 245 | test myTestFunction ... ok 246 | ``` 247 | 248 | 测试示例: 249 | 250 | ```ts 251 | import {assertEquals} from 'https://deno.land/std@v0.3.1/testing/asserts.ts'; 252 | import {test} from 'https://deno.land/std@v0.3.1/testing/mod.ts'; 253 | import {foo} from './mod.ts'; 254 | 255 | test(function myTestFunction() { 256 | assertEquals(foo(), {bar: 'bar'}); 257 | }); 258 | ``` 259 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Deno 6 | 7 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
    22 |
    23 | 24 |
    25 |

    Deno

    26 | JavaScript 和 TypeScript 安全运行时,使用 V8, Rust, 和 Tokio 构建。 27 |
    28 |
    29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | 52 | 53 | 54 | 55 | 65 | 66 | 67 | 70 | 77 | 87 | 88 | 89 | 90 | 97 | 98 |
    Linux & MacWindows
    deno 39 | 40 | 43 | 44 | 46 | 47 | 50 | 51 |
    deno_std 56 | 60 | 63 | 64 |
    68 | deno_install 69 | 71 | 72 | 75 | 76 | 78 | 82 | 85 | 86 |
    registry 91 | 92 | 95 | 96 |
    99 | 100 |

    安装 #

    101 | 102 |

    使用 Shell:

    103 |
    curl -fsSL https://deno.land/x/install/install.sh | sh
    105 |

    Or 使用 PowerShell:

    106 |
    iwr https://deno.land/x/install/install.ps1 | iex
    108 |

    109 | 查看 110 | deno_install 111 | ,了解更多。 112 |

    113 | 114 |

    例子 #

    115 | 116 |

    尝试运行一个简单程序:

    117 |
    deno https://deno.land/welcome.ts
    118 | 119 |

    或更为复杂点的:

    120 | 121 |
    import {serve} from 'https://deno.land/std@v0.3.2/http/server.ts';
    122 | 
    123 | async function main() {
    124 |   const body = new TextEncoder().encode('Hello World\n');
    125 |   for await (const req of serve(':8000')) {
    126 |     req.respond({body});
    127 |   }
    128 | }
    129 | 
    130 | main();
    131 | 132 |

    深挖... #

    133 | 134 |

    135 | 手册 136 |

    137 | 138 |

    API 参考

    139 | 140 |

    风格指南

    141 | 142 |

    模块 存储库

    143 | 144 |

    Twitter

    145 | 146 |

    147 | 发布记录 150 |

    151 | 152 |

    社区聊天室

    153 | 154 |

    155 | 基准 156 |

    157 | 158 |

    159 | awesome Deno 160 |

    161 | 162 | 170 |
    171 | 172 | 173 | -------------------------------------------------------------------------------- /docs/images/deno_logo_3.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 87 | 89 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /docs/app.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. 2 | 3 | // How much to multiply time values in order to process log graphs properly. 4 | const TimeScaleFactor = 10000; 5 | 6 | export async function getJson(path) { 7 | return (await fetch(path)).json(); 8 | } 9 | 10 | function getBenchmarkVarieties(data, benchmarkName) { 11 | // Look at last sha hash. 12 | const last = data[data.length - 1]; 13 | return Object.keys(last[benchmarkName]); 14 | } 15 | 16 | export function createColumns(data, benchmarkName) { 17 | const varieties = getBenchmarkVarieties(data, benchmarkName); 18 | return varieties.map(variety => [ 19 | variety, 20 | ...data.map(d => { 21 | if (d[benchmarkName] != null) { 22 | if (d[benchmarkName][variety] != null) { 23 | const v = d[benchmarkName][variety]; 24 | if (benchmarkName == "benchmark") { 25 | const meanValue = v ? v.mean : 0; 26 | return meanValue || null; 27 | } else { 28 | return v; 29 | } 30 | } 31 | } 32 | return null; 33 | }) 34 | ]); 35 | } 36 | 37 | export function createExecTimeColumns(data) { 38 | return createColumns(data, "benchmark"); 39 | } 40 | 41 | export function createThroughputColumns(data) { 42 | return createColumns(data, "throughput"); 43 | } 44 | 45 | export function createReqPerSecColumns(data) { 46 | return createColumns(data, "req_per_sec"); 47 | } 48 | 49 | export function createMaxLatencyColumns(data) { 50 | return createColumns(data, "max_latency"); 51 | } 52 | 53 | export function createBinarySizeColumns(data) { 54 | const propName = "binary_size"; 55 | const binarySizeNames = Object.keys(data[data.length - 1][propName]); 56 | return binarySizeNames.map(name => [ 57 | name, 58 | ...data.map(d => { 59 | const binarySizeData = d["binary_size"]; 60 | switch (typeof binarySizeData) { 61 | case "number": // legacy implementation 62 | return name === "deno" ? binarySizeData : 0; 63 | default: 64 | if (!binarySizeData) { 65 | return null; 66 | } 67 | return binarySizeData[name] || null; 68 | } 69 | }) 70 | ]); 71 | } 72 | 73 | export function createThreadCountColumns(data) { 74 | const propName = "thread_count"; 75 | const threadCountNames = Object.keys(data[data.length - 1][propName]); 76 | return threadCountNames.map(name => [ 77 | name, 78 | ...data.map(d => { 79 | const threadCountData = d[propName]; 80 | if (!threadCountData) { 81 | return null; 82 | } 83 | return threadCountData[name] || null; 84 | }) 85 | ]); 86 | } 87 | 88 | export function createSyscallCountColumns(data) { 89 | const propName = "syscall_count"; 90 | const syscallCountNames = Object.keys(data[data.length - 1][propName]); 91 | return syscallCountNames.map(name => [ 92 | name, 93 | ...data.map(d => { 94 | const syscallCountData = d[propName]; 95 | if (!syscallCountData) { 96 | return null; 97 | } 98 | return syscallCountData[name] || null; 99 | }) 100 | ]); 101 | } 102 | 103 | export function createSha1List(data) { 104 | return data.map(d => d.sha1); 105 | } 106 | 107 | export function formatMB(bytes) { 108 | return (bytes / (1024 * 1024)).toFixed(2); 109 | } 110 | 111 | export function formatReqSec(reqPerSec) { 112 | return reqPerSec / 1000; 113 | } 114 | 115 | /** 116 | * @param {string} id The id of dom element 117 | * @param {string[]} categories categories for x-axis values 118 | * @param {any[][]} columns The columns data 119 | * @param {function} onclick action on clicking nodes of chart 120 | * @param {string} yLabel label of y axis 121 | * @param {function} yTickFormat formatter of y axis ticks 122 | */ 123 | function generate( 124 | id, 125 | categories, 126 | columns, 127 | onclick, 128 | yLabel = "", 129 | yTickFormat = null 130 | ) { 131 | const yAxis = { 132 | padding: { bottom: 0 }, 133 | min: 0, 134 | label: yLabel 135 | }; 136 | if (yTickFormat) { 137 | yAxis.tick = { 138 | format: yTickFormat 139 | }; 140 | if (yTickFormat == logScale) { 141 | delete yAxis.min; 142 | for (let col of columns) { 143 | for (let i = 1; i < col.length; i++) { 144 | if (col[i] == null) { 145 | continue; 146 | } 147 | col[i] = Math.log10(col[i] * TimeScaleFactor); 148 | } 149 | } 150 | } 151 | } 152 | 153 | // @ts-ignore 154 | c3.generate({ 155 | bindto: id, 156 | data: { 157 | columns, 158 | onclick 159 | }, 160 | axis: { 161 | x: { 162 | type: "category", 163 | show: false, 164 | categories 165 | }, 166 | y: yAxis 167 | } 168 | }); 169 | } 170 | 171 | function logScale(t) { 172 | return (Math.pow(10, t) / TimeScaleFactor).toFixed(4); 173 | } 174 | 175 | function formatSecsAsMins(t) { 176 | // TODO use d3.round() 177 | const a = t % 60; 178 | const min = Math.floor(t / 60); 179 | return a < 30 ? min : min + 1; 180 | } 181 | 182 | /** 183 | * @param dataUrl The url of benchramk data json. 184 | */ 185 | export function drawCharts(dataUrl) { 186 | // TODO Using window["location"]["hostname"] instead of 187 | // window.location.hostname because when deno runs app_test.js it gets a type 188 | // error here, not knowing about window.location. Ideally Deno would skip 189 | // type check entirely on JS files. 190 | if (window["location"]["hostname"] != "deno.github.io") { 191 | dataUrl = "https://denoland.github.io/deno/" + dataUrl; 192 | } 193 | drawChartsFromBenchmarkData(dataUrl); 194 | } 195 | 196 | /** 197 | * Draws the charts from the benchmark data stored in gh-pages branch. 198 | */ 199 | export async function drawChartsFromBenchmarkData(dataUrl) { 200 | const data = await getJson(dataUrl); 201 | 202 | const execTimeColumns = createExecTimeColumns(data); 203 | const throughputColumns = createThroughputColumns(data); 204 | const reqPerSecColumns = createReqPerSecColumns(data); 205 | const maxLatencyColumns = createMaxLatencyColumns(data); 206 | const binarySizeColumns = createBinarySizeColumns(data); 207 | const threadCountColumns = createThreadCountColumns(data); 208 | const syscallCountColumns = createSyscallCountColumns(data); 209 | const sha1List = createSha1List(data); 210 | const sha1ShortList = sha1List.map(sha1 => sha1.substring(0, 6)); 211 | 212 | const viewCommitOnClick = _sha1List => d => { 213 | // @ts-ignore 214 | window.open( 215 | `https://github.com/denoland/deno/commit/${_sha1List[d["index"]]}` 216 | ); 217 | }; 218 | 219 | function gen(id, columns, yLabel = "", yTickFormat = null) { 220 | generate( 221 | id, 222 | sha1ShortList, 223 | columns, 224 | viewCommitOnClick(sha1List), 225 | yLabel, 226 | yTickFormat 227 | ); 228 | } 229 | 230 | gen("#exec-time-chart", execTimeColumns, "seconds", logScale); 231 | gen("#throughput-chart", throughputColumns, "seconds", logScale); 232 | gen("#req-per-sec-chart", reqPerSecColumns, "1000 req/sec", formatReqSec); 233 | gen("#max-latency-chart", maxLatencyColumns, "milliseconds", logScale); 234 | gen("#binary-size-chart", binarySizeColumns, "megabytes", formatMB); 235 | gen("#thread-count-chart", threadCountColumns, "threads"); 236 | gen("#syscall-count-chart", syscallCountColumns, "syscalls"); 237 | } 238 | -------------------------------------------------------------------------------- /style_guide.zh.md: -------------------------------------------------------------------------------- 1 | # Deno 风格指南 2 | 3 | 4 | 5 | 6 | 7 | - [使用 TypeScript](#%E4%BD%BF%E7%94%A8-typescript) 8 | - [使用术语"模块(module)",而不是"库(library)"或"包(package)"](#%E4%BD%BF%E7%94%A8%E6%9C%AF%E8%AF%AD%E6%A8%A1%E5%9D%97module%E8%80%8C%E4%B8%8D%E6%98%AF%E5%BA%93library%E6%88%96%E5%8C%85package) 9 | - [不要使用文件名`"index.ts"或"index.js"`](#%E4%B8%8D%E8%A6%81%E4%BD%BF%E7%94%A8%E6%96%87%E4%BB%B6%E5%90%8Dindexts%E6%88%96indexjs) 10 | - [在"deno-std"中,不依赖外部代码](#%E5%9C%A8deno-std%E4%B8%AD%E4%B8%8D%E4%BE%9D%E8%B5%96%E5%A4%96%E9%83%A8%E4%BB%A3%E7%A0%81) 11 | - [在"deno-std"中,最小化依赖关系;不要进行循环导入。](#%E5%9C%A8deno-std%E4%B8%AD%E6%9C%80%E5%B0%8F%E5%8C%96%E4%BE%9D%E8%B5%96%E5%85%B3%E7%B3%BB%E4%B8%8D%E8%A6%81%E8%BF%9B%E8%A1%8C%E5%BE%AA%E7%8E%AF%E5%AF%BC%E5%85%A5) 12 | - [为了保持一致性,文件名请使用下划线,而不是短划线。](#%E4%B8%BA%E4%BA%86%E4%BF%9D%E6%8C%81%E4%B8%80%E8%87%B4%E6%80%A7%E6%96%87%E4%BB%B6%E5%90%8D%E8%AF%B7%E4%BD%BF%E7%94%A8%E4%B8%8B%E5%88%92%E7%BA%BF%E8%80%8C%E4%B8%8D%E6%98%AF%E7%9F%AD%E5%88%92%E7%BA%BF) 13 | - [使用 prettier 格式化代码。](#%E4%BD%BF%E7%94%A8-prettier-%E6%A0%BC%E5%BC%8F%E5%8C%96%E4%BB%A3%E7%A0%81) 14 | - [导出的函数:最多 2 个参数,将其余的参数放入 options 对象。](#%E5%AF%BC%E5%87%BA%E7%9A%84%E5%87%BD%E6%95%B0%E6%9C%80%E5%A4%9A-2-%E4%B8%AA%E5%8F%82%E6%95%B0%E5%B0%86%E5%85%B6%E4%BD%99%E7%9A%84%E5%8F%82%E6%95%B0%E6%94%BE%E5%85%A5-options-%E5%AF%B9%E8%B1%A1) 15 | - [TODO 注释(待续讨论)](#todo-%E6%B3%A8%E9%87%8A%E5%BE%85%E7%BB%AD%E8%AE%A8%E8%AE%BA) 16 | - [版权标题](#%E7%89%88%E6%9D%83%E6%A0%87%E9%A2%98) 17 | - [顶级函数,不应使用箭头语法](#%E9%A1%B6%E7%BA%A7%E5%87%BD%E6%95%B0%E4%B8%8D%E5%BA%94%E4%BD%BF%E7%94%A8%E7%AE%AD%E5%A4%B4%E8%AF%AD%E6%B3%95) 18 | - [不鼓励,使用元编程。包括代理的用法。](#%E4%B8%8D%E9%BC%93%E5%8A%B1%E4%BD%BF%E7%94%A8%E5%85%83%E7%BC%96%E7%A8%8B%E5%8C%85%E6%8B%AC%E4%BB%A3%E7%90%86%E7%9A%84%E7%94%A8%E6%B3%95) 19 | - [如果文件名,以下划线开头,请不要链接到它:"_foo.ts"`](#%E5%A6%82%E6%9E%9C%E6%96%87%E4%BB%B6%E5%90%8D%E4%BB%A5%E4%B8%8B%E5%88%92%E7%BA%BF%E5%BC%80%E5%A4%B4%E8%AF%B7%E4%B8%8D%E8%A6%81%E9%93%BE%E6%8E%A5%E5%88%B0%E5%AE%83_foots) 20 | - [使用 jsdoc 文档化,导出 API 的情况](#%E4%BD%BF%E7%94%A8-jsdoc-%E6%96%87%E6%A1%A3%E5%8C%96%E5%AF%BC%E5%87%BA-api-%E7%9A%84%E6%83%85%E5%86%B5) 21 | - [每个模块都应该有测试](#%E6%AF%8F%E4%B8%AA%E6%A8%A1%E5%9D%97%E9%83%BD%E5%BA%94%E8%AF%A5%E6%9C%89%E6%B5%8B%E8%AF%95) 22 | - [单元测试应该是明确的](#%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%BA%94%E8%AF%A5%E6%98%AF%E6%98%8E%E7%A1%AE%E7%9A%84) 23 | 24 | 25 | 26 | ## 使用 TypeScript 27 | 28 | ## 使用术语"模块(module)",而不是"库(library)"或"包(package)" 29 | 30 | 为了明确性和一致性,请避免使用术语"库"和"包"。而是使用"module"来指明单个 JS 或 TS 文件,当然还包括 TS / JS 代码的目录。 31 | 32 | ## 不要使用文件名`"index.ts"或"index.js"` 33 | 34 | Deno 不会对"index.js"或"index.ts"特殊处理。这些文件名的使用,会对当不用它们时,却可以被排除在模块描述之外,感到困惑。 35 | 36 | 如果代码目录需要默认入口点,请使用文件名`mod.ts`。文件名`mod.ts`遵循 Rust 的惯例,比`index.ts`简短,并且没有任何先入为主,关于其应该如何运作的观念。 37 | 38 | ## 在"deno-std"中,不依赖外部代码 39 | 40 | `deno_std`旨在成为所有 Deno 程序可以依赖的地基功能。我们希望向用户保证此代码,不包含可能未经审核的第三方代码。 41 | 42 | ## 在"deno-std"中,最小化依赖关系;不要进行循环导入。 43 | 44 | 虽然`deno_std`是一个独立的代码库,我们仍然必须小心保持,内部依赖关系的简单和易于管理。特别要注意,不要产生(死)循环导入。 45 | 46 | ## 为了保持一致性,文件名请使用下划线,而不是短划线。 47 | 48 | 示例:不是`file-server.ts`,使用`file_server.ts`。 49 | 50 | ## 使用 prettier 格式化代码。 51 | 52 | 更具体地说,代码行应在 80 列内,使用 2 空格缩进,并使用驼峰式。使用`//format.ts`调用 prettier。 53 | 54 | ## 导出的函数:最多 2 个参数,将其余的参数放入 options 对象。 55 | 56 | 设计函数接口时,请遵守以下规则。 57 | 58 | 1. 作为公有 API 一部分的函数需要 0-2 个必需参数,如果需要的话,加上一个选项(options)对象(总共最多 3 个)。 59 | 60 | 2. 可选参数,通常应该放进 options 对象。 61 | 62 | 如果只有一个参数,且我们将来不太可能添加更多可选参数,那么不在选项对象中的可选参数,是能够接受的。 63 | 64 | 3. 'options'参数是唯一的常规'Object'类型。 65 | 66 | 其他参数可以是对象(/容器类型),但它们必须与"普通"对象(`Object`)运行时,区分开来,方法是: 67 | 68 | - 一个有区别的原型(例如`Array`,`Map`,`Date`,`class MyThing`) 69 | - 一个众所周知的符号属性(例如,一个可迭代的`Symbol.iterator`)。 70 | 71 | 这允许 API 以向后兼容的方式扩展,即使选项对象的位置,发生变化也能行。 72 | 73 | ```ts 74 | // 不好的方式: 可选参数,不是options 对象的一部分。 (#2) 75 | export function resolve( 76 | hostname: string, 77 | family?: 'ipv4' | 'ipv6', 78 | timeout?: number 79 | ): IPAddress[] {} 80 | 81 | // 好的方式. 82 | export interface ResolveOptions { 83 | family?: 'ipv4' | 'ipv6'; 84 | timeout?: number; 85 | } 86 | export function resolve( 87 | hostname: string, 88 | options: ResolveOptions = {} 89 | ): IPAddress[] {} 90 | ``` 91 | 92 | ```ts 93 | export interface Environment { 94 | [key: string]: string; 95 | } 96 | 97 | // 不好的方式: `env` 可能是常规对象,因此无法区分是否为一个选项对象. (#3) 98 | export function runShellWithEnv(cmdline: string, env: Environment): string {} 99 | 100 | // 好的方式. 101 | export interface RunShellOptions { 102 | env: Environment; 103 | } 104 | export function runShellWithEnv( 105 | cmdline: string, 106 | options: RunShellOptions 107 | ): string {} 108 | ``` 109 | 110 | ```ts 111 | // 不好的方式: 超过 3 参数 (#1), 过多可选参数 (#2). 112 | export function renameSync( 113 | oldname: string, 114 | newname: string, 115 | replaceExisting?: boolean, 116 | followLinks?: boolean 117 | ) {} 118 | 119 | // 好的方式. 120 | interface RenameOptions { 121 | replaceExisting?: boolean; 122 | followLinks?: boolean; 123 | } 124 | export function renameSync( 125 | oldname: string, 126 | newname: string, 127 | options: RenameOptions = {} 128 | ) {} 129 | ``` 130 | 131 | ```ts 132 | // 不好的方式: 过多参数. (#1) 133 | export function pwrite( 134 | fd: number, 135 | buffer: TypedArray, 136 | offset: number, 137 | length: number, 138 | position: number 139 | ) {} 140 | 141 | // 更好. 142 | export interface PWrite { 143 | fd: number; 144 | buffer: TypedArray; 145 | offset: number; 146 | length: number; 147 | position: number; 148 | } 149 | export function pwrite(options: PWrite) {} 150 | ``` 151 | 152 | ## TODO 注释(待续讨论) 153 | 154 | TODO 注释应该在括号中,包含问题或作者的 github 用户名。例: 155 | 156 | ```ts 157 | // TODO(ry) Add tests. 158 | // TODO(#123) Support Windows. 159 | ``` 160 | 161 | ## 版权标题 162 | 163 | `deno_std`大多数文件,应具有以下版权标题: 164 | 165 | ```ts 166 | // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. 167 | ``` 168 | 169 | 如果代码来自其他地方,请确保该文件,具有适当的版权标题。我们`deno_std`只允许使用 MIT,BSD 和 Apache 许可代码。 170 | 171 | ## 顶级函数,不应使用箭头语法 172 | 173 | 顶级函数应该使用`function`关键词。箭头语法,应仅限闭包使用。 174 | 175 | 坏 176 | 177 | ```ts 178 | export const foo(): string => { 179 | return "bar"; 180 | } 181 | ``` 182 | 183 | 好 184 | 185 | ```ts 186 | export function foo(): string { 187 | return 'bar'; 188 | } 189 | ``` 190 | 191 | ## 不鼓励,使用元编程。包括代理的用法。 192 | 193 | 即使它意味着更多的代码,也要代码具备明确性。 194 | 195 | 在某些情况下,使用这些技术,可能是有意义的,但在绝大多数情况下,没有。 196 | 197 | ## 如果文件名,以下划线开头,请不要链接到它:"_foo.ts"` 198 | 199 | 有时可能存在内部模块的需要,但其 API 不是稳定或可供链接的情况。在这种情况下,用下划线作为前缀。按照惯例,只有本文件目录中的(文件),才能导入它。 200 | 201 | ## 使用 jsdoc 文档化,导出 API 的情况 202 | 203 | 我们力求完整的文档。理想情况下,每个导出的符号,都应该有文档行。 204 | 205 | 如果可能,请编写 JS 文档。例: 206 | 207 | ```ts 208 | /** foo 做了某 bar. */ 209 | export function foo() { 210 | // ... 211 | } 212 | ``` 213 | 214 | 重要的是文档,易于给人阅读,但还需要提供额外的样式信息,以确保生成的文档是,更丰富的文本。因此,JSDoc 通常遵循 markdown 标记,来丰富文本。 215 | 216 | 虽然 markdown 支持 HTML 标签,但在 JSDoc 区块中,禁止使用。 217 | 218 | 代码格式字符串,应使用反引号(\`)标记而不是引号。例如: 219 | 220 | ```ts 221 | /** Import something from the `deno` module. */ 222 | ``` 223 | 224 | 不要文档化函数参数,除非它们的意图不明显(尽管它们,具有不明显意图,但 API 无论如何都应该考虑清楚)。因此`@param`通常,不应该使用。如果`@param`真使用了,那它不应该包括`type`,因为 TypeScript 已经是强类型的。 225 | 226 | ```ts 227 | /** 228 | * 带有不明显意图参数的函数 229 | * @param foo 描述不明显意图的参数 230 | */ 231 | ``` 232 | 233 | 应尽可能减小垂直间距。因此,单行注释应写为: 234 | 235 | ```ts 236 | /** JSDoc 单行标准写法 */ 237 | ``` 238 | 239 | 而不是 240 | 241 | ```ts 242 | /** 243 | * JSDoc 差的示例 244 | */ 245 | ``` 246 | 247 | 代码示例(区块),不应使用三个反引号(\`\`\`)表示。它们应该只用缩进:具体需要在区块之前空一行,并为示例的每一行,添加 6 个额外的空格。这比注释的第一列,多 4 个。例如: 248 | 249 | ```ts 250 | /** A straight forward comment and an example: 251 | * 252 | * import { foo } from "deno"; 253 | * foo("bar"); 254 | */ 255 | ``` 256 | 257 | 代码示例,不应包含其他注释。它已经在外注释中。如果它需要进一步的注释,那就不是一个很好的例子。 258 | 259 | ## 每个模块都应该有测试 260 | 261 | 每个模块应该有个测试文件`modulename_test.ts`,作为它的兄弟姐妹。例如模块`foo.ts`应该带着它的兄弟姐妹`foo_test.ts`。 262 | 263 | ## 单元测试应该是明确的 264 | 265 | 为了更好地理解测试,应在整个测试命令中,正确命名函数,比如: 266 | 267 | ``` 268 | test myTestFunction ... ok 269 | ``` 270 | 271 | 测试示例: 272 | 273 | ```ts 274 | import {assertEquals} from 'https://deno.land/std@v0.3.1/testing/asserts.ts'; 275 | import {test} from 'https://deno.land/std@v0.3.1/testing/mod.ts'; 276 | import {foo} from './mod.ts'; 277 | 278 | test(function myTestFunction() { 279 | assertEquals(foo(), {bar: 'bar'}); 280 | }); 281 | ``` 282 | -------------------------------------------------------------------------------- /style_guide.md: -------------------------------------------------------------------------------- 1 | # Deno Style Guide 2 | 3 | [toc] 4 | 5 | ## Use TypeScript 6 | 7 | ## Use the term "module" instead of "library" or "package" 8 | 9 | For clarity and consistency avoid the terms "library" and "package". Instead use 10 | "module" to refer to a single JS or TS file and also to refer to a directory of 11 | TS/JS code. 12 | 13 | ## Do not use the filename `index.ts` nor `index.js` 14 | 15 | Deno does not treat "index.js" or "index.ts" in a special way. By using these 16 | filenames, it suggests that they can be left out of the module specifier when 17 | they cannot. This is confusing. 18 | 19 | If a directory of code needs a default entry point, use the filename `mod.ts`. 20 | The filename `mod.ts` follows Rust’s convention, is shorter than `index.ts`, and 21 | doesn’t come with any preconceived notions about how it might work. 22 | 23 | ## Within `deno_std`, do not depend on external code 24 | 25 | `deno_std` is intended to be baseline functionality that all Deno programs can 26 | rely on. We want to guarantee to users that this code does not include 27 | potentially unreviewed third party code. 28 | 29 | ## Within `deno_std`, minimize dependencies; do not make circular imports. 30 | 31 | Although `deno_std` is a standalone codebase, we must still be careful to keep 32 | the internal dependencies simple and manageable. In particular, be careful to 33 | not to introduce circular imports. 34 | 35 | ## For consistency, use underscores, not dashes in filenames. 36 | 37 | Example: Instead of `file-server.ts` use `file_server.ts`. 38 | 39 | ## Format code according using prettier. 40 | 41 | More specifically, code should be wrapped at 80 columns and use 2-space 42 | indentation and use camel-case. Use `//format.ts` to invoke prettier. 43 | 44 | ## Exported functions: max 2 args, put the rest into an options object. 45 | 46 | When designing function interfaces, stick to the following rules. 47 | 48 | 1. A function that is part of the public API takes 0-2 required arguments, plus 49 | (if necessary) an options object (so max 3 total). 50 | 51 | 2. Optional parameters should generally go into the options object. 52 | 53 | An optional parameter that's not in an options object might be acceptable if 54 | there is only one, and it seems inconceivable that we would add more optional 55 | parameters in the future. 56 | 57 | 3. The 'options' argument is the only argument that is a regular 'Object'. 58 | 59 | Other arguments can be objects, but they must be distinguishable from a 60 | 'plain' Object runtime, by having either: 61 | 62 | - a distinguishing prototype (e.g. `Array`, `Map`, `Date`, `class MyThing`) 63 | - a well-known symbol property (e.g. an iterable with `Symbol.iterator`). 64 | 65 | This allows the API to evolve in a backwards compatible way, even when the 66 | position of the options object changes. 67 | 68 | ```ts 69 | // BAD: optional parameters not part of options object. (#2) 70 | export function resolve( 71 | hostname: string, 72 | family?: "ipv4" | "ipv6", 73 | timeout?: number 74 | ): IPAddress[] {} 75 | 76 | // GOOD. 77 | export interface ResolveOptions { 78 | family?: "ipv4" | "ipv6"; 79 | timeout?: number; 80 | } 81 | export function resolve( 82 | hostname: string, 83 | options: ResolveOptions = {} 84 | ): IPAddress[] {} 85 | ``` 86 | 87 | ```ts 88 | export interface Environment { 89 | [key: string]: string; 90 | } 91 | 92 | // BAD: `env` could be a regular Object and is therefore indistinguishable 93 | // from an options object. (#3) 94 | export function runShellWithEnv(cmdline: string, env: Environment): string {} 95 | 96 | // GOOD. 97 | export interface RunShellOptions { 98 | env: Environment; 99 | } 100 | export function runShellWithEnv( 101 | cmdline: string, 102 | options: RunShellOptions 103 | ): string {} 104 | ``` 105 | 106 | ```ts 107 | // BAD: more than 3 arguments (#1), multiple optional parameters (#2). 108 | export function renameSync( 109 | oldname: string, 110 | newname: string, 111 | replaceExisting?: boolean, 112 | followLinks?: boolean 113 | ) {} 114 | 115 | // GOOD. 116 | interface RenameOptions { 117 | replaceExisting?: boolean; 118 | followLinks?: boolean; 119 | } 120 | export function renameSync( 121 | oldname: string, 122 | newname: string, 123 | options: RenameOptions = {} 124 | ) {} 125 | ``` 126 | 127 | ```ts 128 | // BAD: too many arguments. (#1) 129 | export function pwrite( 130 | fd: number, 131 | buffer: TypedArray, 132 | offset: number, 133 | length: number, 134 | position: number 135 | ) {} 136 | 137 | // BETTER. 138 | export interface PWrite { 139 | fd: number; 140 | buffer: TypedArray; 141 | offset: number; 142 | length: number; 143 | position: number; 144 | } 145 | export function pwrite(options: PWrite) {} 146 | ``` 147 | 148 | ## TODO Comments 149 | 150 | TODO comments should include an issue or the author's github username in 151 | parentheses. Example: 152 | 153 | ```ts 154 | // TODO(ry) Add tests. 155 | // TODO(#123) Support Windows. 156 | ``` 157 | 158 | ## Copyright headers 159 | 160 | Most files in `deno_std` should have the following copyright header: 161 | 162 | ```ts 163 | // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. 164 | ``` 165 | 166 | If the code originates elsewhere, ensure that the file has the proper copyright 167 | headers. We only allow MIT, BSD, and Apache licensed code in `deno_std`. 168 | 169 | ## Top level functions should not use arrow syntax 170 | 171 | Top level functions should use the `function` keyword. Arrow syntax should be 172 | limited to closures. 173 | 174 | Bad 175 | 176 | ```ts 177 | export const foo(): string => { 178 | return "bar"; 179 | } 180 | ``` 181 | 182 | Good 183 | 184 | ```ts 185 | export function foo(): string { 186 | return "bar"; 187 | } 188 | ``` 189 | 190 | ## Meta-programming is discouraged. Including the use of Proxy. 191 | 192 | Be explicit even when it means more code. 193 | 194 | There are some situations where it may make sense to use such techniques, but in 195 | the vast majority of cases it does not. 196 | 197 | ## If a filename starts with underscore, do not link to it: `_foo.ts` 198 | 199 | Sometimes there maybe situations where an internal module is necessary but its 200 | API is not meant to be stable or linked to. In this case prefix it with an 201 | underscore. By convention, only files in its own directory should import it. 202 | 203 | ## Use JSDoc to document exported machinery 204 | 205 | We strive for complete documentation. Every exported symbol ideally should have 206 | a documentation line. 207 | 208 | If possible, use a single line for the JS Doc. Example: 209 | 210 | ```ts 211 | /** foo does bar. */ 212 | export function foo() { 213 | // ... 214 | } 215 | ``` 216 | 217 | It is important that documentation is easily human readable, but there is also a 218 | need to provide additional styling information to ensure generated documentation 219 | is more rich text. Therefore JSDoc should generally follow markdown markup to 220 | enrich the text. 221 | 222 | While markdown supports HTML tags, it is forbidden in JSDoc blocks. 223 | 224 | Code string literals should be braced with the back-tick (\`) instead of quotes. 225 | For example: 226 | 227 | ```ts 228 | /** Import something from the `deno` module. */ 229 | ``` 230 | 231 | Do not document function arguments unless they are non-obvious of their intent 232 | (though if they are non-obvious intent, the API should be considered anyways). 233 | Therefore `@param` should generally not be used. If `@param` is used, it should 234 | not include the `type` as TypeScript is already strongly typed. 235 | 236 | ```ts 237 | /** 238 | * Function with non obvious param 239 | * @param foo Description of non obvious parameter 240 | */ 241 | ``` 242 | 243 | Vertical spacing should be minimized whenever possible. Therefore single line 244 | comments should be written as: 245 | 246 | ```ts 247 | /** This is a good single line JSDoc */ 248 | ``` 249 | 250 | And not 251 | 252 | ```ts 253 | /** 254 | * This is a bad single line JSDoc 255 | */ 256 | ``` 257 | 258 | Code examples should not utilise the triple-back tick (\`\`\`) notation or tags. 259 | They should just be marked by indentation, which requires a break before the 260 | block and 6 additional spaces for each line of the example. This is 4 more than 261 | the first column of the comment. For example: 262 | 263 | ```ts 264 | /** A straight forward comment and an example: 265 | * 266 | * import { foo } from "deno"; 267 | * foo("bar"); 268 | */ 269 | ``` 270 | 271 | Code examples should not contain additional comments. It is already inside a 272 | comment. If it needs further comments is not a good example. 273 | 274 | ## Each module should come with tests 275 | 276 | Each module should come with its test as a sibling with the name 277 | `modulename_test.ts`. For example the module `foo.ts` should come with its 278 | sibling `foo_test.ts`. 279 | 280 | ## Unit Tests should be explicit 281 | 282 | For a better understanding of the tests, function should be correctly named as 283 | its prompted throughout the test command. Like: 284 | 285 | ``` 286 | test myTestFunction ... ok 287 | ``` 288 | 289 | Example of test: 290 | 291 | ```ts 292 | import { assertEquals } from "https://deno.land/std@v0.3.1/testing/asserts.ts"; 293 | import { test } from "https://deno.land/std@v0.3.1/testing/mod.ts"; 294 | import { foo } from "./mod.ts"; 295 | 296 | test(function myTestFunction() { 297 | assertEquals(foo(), { bar: "bar" }); 298 | }); 299 | ``` 300 | -------------------------------------------------------------------------------- /docs/style_guide.md: -------------------------------------------------------------------------------- 1 | # Deno Style Guide 2 | 3 | [toc] 4 | 5 | ## Use TypeScript 6 | 7 | ## Use the term "module" instead of "library" or "package" 8 | 9 | For clarity and consistency avoid the terms "library" and "package". Instead use 10 | "module" to refer to a single JS or TS file and also to refer to a directory of 11 | TS/JS code. 12 | 13 | ## Do not use the filename `index.ts` nor `index.js` 14 | 15 | Deno does not treat "index.js" or "index.ts" in a special way. By using these 16 | filenames, it suggests that they can be left out of the module specifier when 17 | they cannot. This is confusing. 18 | 19 | If a directory of code needs a default entry point, use the filename `mod.ts`. 20 | The filename `mod.ts` follows Rust’s convention, is shorter than `index.ts`, and 21 | doesn’t come with any preconceived notions about how it might work. 22 | 23 | ## Within `deno_std`, do not depend on external code 24 | 25 | `deno_std` is intended to be baseline functionality that all Deno programs can 26 | rely on. We want to guarantee to users that this code does not include 27 | potentially unreviewed third party code. 28 | 29 | ## Within `deno_std`, minimize dependencies; do not make circular imports. 30 | 31 | Although `deno_std` is a standalone codebase, we must still be careful to keep 32 | the internal dependencies simple and manageable. In particular, be careful to 33 | not to introduce circular imports. 34 | 35 | ## For consistency, use underscores, not dashes in filenames. 36 | 37 | Example: Instead of `file-server.ts` use `file_server.ts`. 38 | 39 | ## Format code according using prettier. 40 | 41 | More specifically, code should be wrapped at 80 columns and use 2-space 42 | indentation and use camel-case. Use `//format.ts` to invoke prettier. 43 | 44 | ## Exported functions: max 2 args, put the rest into an options object. 45 | 46 | When designing function interfaces, stick to the following rules. 47 | 48 | 1. A function that is part of the public API takes 0-2 required arguments, plus 49 | (if necessary) an options object (so max 3 total). 50 | 51 | 2. Optional parameters should generally go into the options object. 52 | 53 | An optional parameter that's not in an options object might be acceptable if 54 | there is only one, and it seems inconceivable that we would add more optional 55 | parameters in the future. 56 | 57 | 3. The 'options' argument is the only argument that is a regular 'Object'. 58 | 59 | Other arguments can be objects, but they must be distinguishable from a 60 | 'plain' Object runtime, by having either: 61 | 62 | - a distinguishing prototype (e.g. `Array`, `Map`, `Date`, `class MyThing`) 63 | - a well-known symbol property (e.g. an iterable with `Symbol.iterator`). 64 | 65 | This allows the API to evolve in a backwards compatible way, even when the 66 | position of the options object changes. 67 | 68 | ```ts 69 | // BAD: optional parameters not part of options object. (#2) 70 | export function resolve( 71 | hostname: string, 72 | family?: "ipv4" | "ipv6", 73 | timeout?: number 74 | ): IPAddress[] {} 75 | 76 | // GOOD. 77 | export interface ResolveOptions { 78 | family?: "ipv4" | "ipv6"; 79 | timeout?: number; 80 | } 81 | export function resolve( 82 | hostname: string, 83 | options: ResolveOptions = {} 84 | ): IPAddress[] {} 85 | ``` 86 | 87 | ```ts 88 | export interface Environment { 89 | [key: string]: string; 90 | } 91 | 92 | // BAD: `env` could be a regular Object and is therefore indistinguishable 93 | // from an options object. (#3) 94 | export function runShellWithEnv(cmdline: string, env: Environment): string {} 95 | 96 | // GOOD. 97 | export interface RunShellOptions { 98 | env: Environment; 99 | } 100 | export function runShellWithEnv( 101 | cmdline: string, 102 | options: RunShellOptions 103 | ): string {} 104 | ``` 105 | 106 | ```ts 107 | // BAD: more than 3 arguments (#1), multiple optional parameters (#2). 108 | export function renameSync( 109 | oldname: string, 110 | newname: string, 111 | replaceExisting?: boolean, 112 | followLinks?: boolean 113 | ) {} 114 | 115 | // GOOD. 116 | interface RenameOptions { 117 | replaceExisting?: boolean; 118 | followLinks?: boolean; 119 | } 120 | export function renameSync( 121 | oldname: string, 122 | newname: string, 123 | options: RenameOptions = {} 124 | ) {} 125 | ``` 126 | 127 | ```ts 128 | // BAD: too many arguments. (#1) 129 | export function pwrite( 130 | fd: number, 131 | buffer: TypedArray, 132 | offset: number, 133 | length: number, 134 | position: number 135 | ) {} 136 | 137 | // BETTER. 138 | export interface PWrite { 139 | fd: number; 140 | buffer: TypedArray; 141 | offset: number; 142 | length: number; 143 | position: number; 144 | } 145 | export function pwrite(options: PWrite) {} 146 | ``` 147 | 148 | ## TODO Comments 149 | 150 | TODO comments should include an issue or the author's github username in 151 | parentheses. Example: 152 | 153 | ```ts 154 | // TODO(ry) Add tests. 155 | // TODO(#123) Support Windows. 156 | ``` 157 | 158 | ## Copyright headers 159 | 160 | Most files in `deno_std` should have the following copyright header: 161 | 162 | ```ts 163 | // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. 164 | ``` 165 | 166 | If the code originates elsewhere, ensure that the file has the proper copyright 167 | headers. We only allow MIT, BSD, and Apache licensed code in `deno_std`. 168 | 169 | ## Top level functions should not use arrow syntax 170 | 171 | Top level functions should use the `function` keyword. Arrow syntax should be 172 | limited to closures. 173 | 174 | Bad 175 | 176 | ```ts 177 | export const foo(): string => { 178 | return "bar"; 179 | } 180 | ``` 181 | 182 | Good 183 | 184 | ```ts 185 | export function foo(): string { 186 | return "bar"; 187 | } 188 | ``` 189 | 190 | ## Meta-programming is discouraged. Including the use of Proxy. 191 | 192 | Be explicit even when it means more code. 193 | 194 | There are some situations where it may make sense to use such techniques, but in 195 | the vast majority of cases it does not. 196 | 197 | ## If a filename starts with underscore, do not link to it: `_foo.ts` 198 | 199 | Sometimes there maybe situations where an internal module is necessary but its 200 | API is not meant to be stable or linked to. In this case prefix it with an 201 | underscore. By convention, only files in its own directory should import it. 202 | 203 | ## Use JSDoc to document exported machinery 204 | 205 | We strive for complete documentation. Every exported symbol ideally should have 206 | a documentation line. 207 | 208 | If possible, use a single line for the JS Doc. Example: 209 | 210 | ```ts 211 | /** foo does bar. */ 212 | export function foo() { 213 | // ... 214 | } 215 | ``` 216 | 217 | It is important that documentation is easily human readable, but there is also a 218 | need to provide additional styling information to ensure generated documentation 219 | is more rich text. Therefore JSDoc should generally follow markdown markup to 220 | enrich the text. 221 | 222 | While markdown supports HTML tags, it is forbidden in JSDoc blocks. 223 | 224 | Code string literals should be braced with the back-tick (\`) instead of quotes. 225 | For example: 226 | 227 | ```ts 228 | /** Import something from the `deno` module. */ 229 | ``` 230 | 231 | Do not document function arguments unless they are non-obvious of their intent 232 | (though if they are non-obvious intent, the API should be considered anyways). 233 | Therefore `@param` should generally not be used. If `@param` is used, it should 234 | not include the `type` as TypeScript is already strongly typed. 235 | 236 | ```ts 237 | /** 238 | * Function with non obvious param 239 | * @param foo Description of non obvious parameter 240 | */ 241 | ``` 242 | 243 | Vertical spacing should be minimized whenever possible. Therefore single line 244 | comments should be written as: 245 | 246 | ```ts 247 | /** This is a good single line JSDoc */ 248 | ``` 249 | 250 | And not 251 | 252 | ```ts 253 | /** 254 | * This is a bad single line JSDoc 255 | */ 256 | ``` 257 | 258 | Code examples should not utilise the triple-back tick (\`\`\`) notation or tags. 259 | They should just be marked by indentation, which requires a break before the 260 | block and 6 additional spaces for each line of the example. This is 4 more than 261 | the first column of the comment. For example: 262 | 263 | ```ts 264 | /** A straight forward comment and an example: 265 | * 266 | * import { foo } from "deno"; 267 | * foo("bar"); 268 | */ 269 | ``` 270 | 271 | Code examples should not contain additional comments. It is already inside a 272 | comment. If it needs further comments is not a good example. 273 | 274 | ## Each module should come with tests 275 | 276 | Each module should come with its test as a sibling with the name 277 | `modulename_test.ts`. For example the module `foo.ts` should come with its 278 | sibling `foo_test.ts`. 279 | 280 | ## Unit Tests should be explicit 281 | 282 | For a better understanding of the tests, function should be correctly named as 283 | its prompted throughout the test command. Like: 284 | 285 | ``` 286 | test myTestFunction ... ok 287 | ``` 288 | 289 | Example of test: 290 | 291 | ```ts 292 | import { assertEquals } from "https://deno.land/std@v0.3.1/testing/asserts.ts"; 293 | import { test } from "https://deno.land/std@v0.3.1/testing/mod.ts"; 294 | import { foo } from "./mod.ts"; 295 | 296 | test(function myTestFunction() { 297 | assertEquals(foo(), { bar: "bar" }); 298 | }); 299 | ``` 300 | -------------------------------------------------------------------------------- /docs/manual.zh.md: -------------------------------------------------------------------------------- 1 | # Deno 手册 2 | 3 | ## 免责声明 4 | 5 | 警告语:Deno 正在开发中。我们鼓励勇敢的早期采用者,但期望反馈大或小的 Bug。API 如有变更,恕不另行通知。[错误报告](https://github.com/denoland/deno/issues)会有用! 6 | 7 | ## 介绍 8 | 9 | 使用 V8、Rust 和 Tokio 构建的安全 javascript/typescript 运行时 10 | 11 | ### 哲学 12 | 13 | Deno 的目标是为现代程序员提供一个高效、安全的脚本环境。 14 | 15 | 它始终以单个可执行文件形态,作为分发文件,并且该可执行文件,足够运行任何 deno 程序。给定一个 deno 程序的 URL,您应该能够用不超过 50MB 的 Deno 可执行文件,来执行它。 16 | 17 | Deno 明确承担运行时,和包管理器的角色。它用标准的浏览器兼容协议,来加载模块:URLs。 18 | 19 | Deno 为提供了程序访问系统的安全保证,默认情况下,它是最严格的安全沙盒。 20 | 21 | Deno 提供一套经过评审(审核)的标准模块这保证了与 Deno 的合作。 22 | 23 | ### 目标 24 | 25 | - 支持现成的 typescript。 26 | 27 | - 与浏览器一样,允许(模块)以 URL 形式导入: 28 | 29 | ```ts 30 | import * as log from 'https://deno.land/std/log/mod.ts'; 31 | ``` 32 | 33 | - 远程代码在第一次执行时,被获取和缓存,并且在使用`--reload`标志,才会更新(同一 URL 路径的代码)。(所以,还能在飞机上使用。见`~/.deno/src`,有关缓存的详细信息。) 34 | 35 | - 使用"ES 模块",不支持`require()`. 36 | 37 | - 为了沙盒代码的运行,会对文件系统和网络访问(权限)有所控制。V8(没权限)和 Rust(权限)之间的访问,只能通过在[flatbuffer](https://github.com/denoland/deno/blob/master/cli/msg.fbs)定义的序列化消息,完成沟通。这使得审计变得容易。例如,要启用 write(写) 访问,请使用标志`--allow-write`,或用于网络访问`--allow-net`。 38 | 39 | - 只运输一个可执行文件。 40 | 41 | - 总是死(崩溃)于,未发现的错误。 42 | 43 | - 浏览器兼容:Deno 程序的子集,完全用 JavaScript 编写,它(或它的功能测试)并没有使用全局`Deno`名称空间,想来应该能够在现代 Web 浏览器上运行,而不需要更改。 44 | 45 | - [目标:支持顶级`await`.](https://github.com/denoland/deno/issues/471) 46 | 47 | - 能够高效地服务 HTTP。([目前,速度比较慢。](https://deno.land/benchmarks.html#req-per-sec)) 48 | 49 | - 提供现成的有用工具: 50 | - 命令行调试器[还没有](https://github.com/denoland/deno/issues/1120) 51 | - linter[还没有](https://github.com/denoland/deno/issues/1880) 52 | - 依赖关系检查器(`deno info`) 53 | - 代码格式化程序(`deno fmt`) 54 | 55 | ### 反目标 56 | 57 | - 没有`package.json`. 58 | 59 | - 没有 npm。 60 | 61 | - 与 Node 不显式兼容。 62 | 63 | ## 安装程序 64 | 65 | ### 二进制安装 66 | 67 | Deno 在 OSX、Linux 和 Windows 上工作。deno 是单个二进制可执行文件。它没有外部依赖关系。 68 | 69 | [deno_install](https://github.com/denoland/deno_install)提供方便的脚本,来下载和安装二进制文件。 70 | 71 | 使用 Shell: 72 | 73 | ```shellsession 74 | $ curl -fsSL https://deno.land/x/install/install.sh | sh 75 | ``` 76 | 77 | 使用 PowerShell: 78 | 79 | ```shellsession 80 | > iwr https://deno.land/x/install/install.ps1 | iex 81 | ``` 82 | 83 | 使用[Scoop](https://scoop.sh/)(Windows): 84 | 85 | ``` 86 | scoop install deno 87 | ``` 88 | 89 | 也可以通过[github.com/denoland/deno/releases](https://github.com/denoland/deno/releases)下载 tarball 或 zip 文件,手动安装 deno。这些包只包含一个可执行文件。您必须在 Mac 和 Linux 上,设置可执行的环境变量(PATH)。 90 | 91 | 一旦它安装和已在`$PATH`,开始试试吧: 92 | 93 | ```shellsession 94 | $ deno https://deno.land/welcome.ts 95 | ``` 96 | 97 | ### 从源代码生成 98 | 99 | ```bash 100 | # 获取 源和开发依赖. 101 | git clone --recurse-submodules https://github.com/denoland/deno.git 102 | cd deno 103 | ./tools/setup.py 104 | 105 | # 你可能需要确保 sccache 是在运行的。 106 | # (TODO 需要与否,其实并不明确.) 107 | # prebuilt/mac/sccache --start-server 108 | 109 | # 构建. 110 | ./tools/build.py 111 | 112 | # 运行. 113 | ./target/debug/deno tests/002_hello.ts 114 | 115 | # 测试. 116 | ./tools/test.py 117 | 118 | # 格式化代码. 119 | ./tools/format.py 120 | ``` 121 | 122 | #### 先决条件 123 | 124 | 为了确保构建的可重复性,deno 在 git 子模块中有其大部分依赖项。但是,您需要单独安装: 125 | 126 | 1. [Rust](https://www.rust-lang.org/en-US/install.html)> 1.31.1 127 | 2. [Node](https://nodejs.org/) 128 | 3. Python 2。[不是 3](https://github.com/denoland/deno/issues/464#issuecomment-411795578). 129 | 130 | Mac 用户的额外步骤:安装[XCode](https://developer.apple.com/xcode/) :( 131 | 132 | Windows 用户的额外步骤: 133 | 134 | 1. 添加`python.exe`到`PATH`(例如 `set PATH=%PATH%;C:\Python27\python.exe`) 135 | 2. 得到[VS Community 2017](https://www.visualstudio.com/downloads/),随着"Desktop development with C++"工具包,并确保选择以下列出所有的 C++工具。 136 | - Windows 10 SDK >= 10.0.17134 137 | - X86 和 X64 的 Visual C++ ATL 138 | - X86 和 X64 的 Visual C++ MFC 139 | - C++ profiling 工具 140 | 3. 启用"Windows 调试工具"。转到"控制面板"→"程序"→"程序和功能"→ 选择"Windows 软件开发工具包-Windows 10"→"更改"→"更改"→ 检查"Windows 调试工具"→"更改"->"完成" 141 | 142 | > ("Control Panel" → "Programs" → "Programs and Features" → Select "Windows Software >Development Kit - Windows 10" → 143 | > "Change" → "Change" → Check "Debugging Tools >For Windows" → "Change" -> "Finish")。 144 | 145 | 4. 确保使用的是 Git 2.19.2.Windows.1 或更高版本。 146 | 147 | #### 其他有用的命令 148 | 149 | ```bash 150 | # 手动呼叫 ninja。 151 | ./third_party/depot_tools/ninja -C target/debug 152 | 153 | # 构建发布二进制文件。 154 | ./tools/build.py --release deno 155 | 156 | # 列出可执行目标。 157 | ./third_party/depot_tools/gn ls target/debug //:* --as=output --type=executable 158 | 159 | # 列表构建配置。 160 | ./third_party/depot_tools/gn args target/debug/ --list 161 | 162 | # 编辑构建配置。 163 | ./third_party/depot_tools/gn args target/debug/ 164 | 165 | # 描述一个目标。 166 | ./third_party/depot_tools/gn desc target/debug/ :deno 167 | ./third_party/depot_tools/gn help 168 | 169 | # 更新third_party模块 170 | git submodule update 171 | ``` 172 | 173 | 环境变量:`DENO_BUILD_MODE`,`DENO_BUILD_PATH`,`DENO_BUILD_ARGS`,`DENO_DIR`。 174 | 175 | ## API 参考 176 | 177 | ### deno --types 178 | 179 | 要获得 Deno 运行时,准确的 API 参考,请在命令行中,运行以下命令: 180 | 181 | ```shellsession 182 | $ deno --types 183 | ``` 184 | 185 | [这就是输出的样子。](https://gist.github.com/ry/46da4724168cdefa763e13207d27ede5) 186 | 187 | ### 参考网站 188 | 189 | [TypeScript Deno api](https://deno.land/typedoc/index.html)。 190 | 191 | 如果要在 Rust 程序中,嵌入 deno,请参见[Rust Deno API](https://deno.land/rustdoc/deno/index.html)。 192 | 193 | ## 实例 194 | 195 | ### Unix "cat"程序的实现 196 | 197 | 在这个程序中,每个命令行参数,都被假定为文件名,文件被打开,并打印到 stdout。 198 | 199 | ```ts 200 | (async () => { 201 | for (let i = 1; i < Deno.args.length; i++) { 202 | let filename = Deno.args[i]; 203 | let file = await Deno.open(filename); 204 | await Deno.copy(Deno.stdout, file); 205 | file.close(); 206 | } 207 | })(); 208 | ``` 209 | 210 | 这个`copy()`函数,实际上只做了,必要的内核->用户空间->内核副本。也就是说,从文件读取来的数据的相同内存,被写入 stdout。这说明了 deno 中,关于 I/O 流的通用设计目标。 211 | 212 | 尝试程序: 213 | 214 | ```shellsession 215 | $ deno --allow-read https://deno.land/std/examples/cat.ts /etc/passwd 216 | ``` 217 | 218 | ### TCP 回音服务器 219 | 220 | 这是一个简单服务器的例子,它接受端口 8080 上的连接,并将它发送的任何内容,返回给客户端。 221 | 222 | ```ts 223 | const {listen, copy} = Deno; 224 | 225 | (async () => { 226 | const addr = '0.0.0.0:8080'; 227 | const listener = listen('tcp', addr); 228 | console.log('listening on', addr); 229 | while (true) { 230 | const conn = await listener.accept(); 231 | copy(conn, conn); 232 | } 233 | })(); 234 | ``` 235 | 236 | 启动此程序时,将提示用户,要有在网络上侦听的权限: 237 | 238 | ```shellsession 239 | $ deno https://deno.land/std/examples/echo_server.ts 240 | ⚠️ Deno requests network access to "listen". Grant? [yN] y 241 | listening on 0.0.0.0:8080 242 | ``` 243 | 244 | 出于安全原因,Deno 不允许程序,在没有明确许可的情况下访问网络。要避免控制台提示,请使用命令行标志: 245 | 246 | ```shellsession 247 | $ deno https://deno.land/std/examples/echo_server.ts --allow-net 248 | ``` 249 | 250 | 要测试它,请尝试使用 curl 向它发送 HTTP 请求。请求会被直接写回客户端。 251 | 252 | ```shellsession 253 | $ curl http://localhost:8080/ 254 | GET / HTTP/1.1 255 | Host: localhost:8080 256 | User-Agent: curl/7.54.0 257 | Accept: */* 258 | ``` 259 | 260 | 值得注意的是,类似`cat.ts`那个例子,这里的`copy()`函数,也不会进行不必要的内存复制。它从内核接收一个数据包,并发送回来,没有进一步的复杂性。 261 | 262 | ### 检查和撤消权限 263 | 264 | 有时程序可能希望撤消以前授予的权限。当程序在后期需要这些权限时,则向用户显示一个新的提示。 265 | 266 | ```ts 267 | const {permissions, revokePermission, open, remove} = Deno; 268 | 269 | (async () => { 270 | // 查看一个权限 271 | if (!permissions().write) { 272 | throw new Error('need write permission'); 273 | } 274 | 275 | const log = await open('request.log', 'a+'); 276 | 277 | // 撤消一些权限 278 | revokePermission('read'); 279 | revokePermission('write'); 280 | 281 | // 使用 log file 282 | await log.write(encoder.encode('hello\n')); 283 | 284 | // 然后提示需要 write 权限或者失败。 285 | await remove('request.log'); 286 | })(); 287 | ``` 288 | 289 | ### 文件服务器 290 | 291 | 这一个在 HTTP 中,提供服务的本地目录。 292 | 293 | ```bash 294 | alias file_server="deno --allow-net --allow-read \ 295 | https://deno.land/std/http/file_server.ts" 296 | ``` 297 | 298 | 运行它: 299 | 300 | ```shellsession 301 | $ file_server . 302 | Downloading https://deno.land/std/http/file_server.ts... 303 | [...] 304 | HTTP server listening on http://0.0.0.0:4500/ 305 | ``` 306 | 307 | 如果您想升级到,最新发布的版本: 308 | 309 | ```shellsession 310 | $ file_server --reload 311 | ``` 312 | 313 | ### 运行子过程 314 | 315 | [API 参考](https://deno.land/typedoc/index.html#run) 316 | 317 | 例子: 318 | 319 | ```ts 320 | async function main() { 321 | // 创建子进程 322 | const p = Deno.run({ 323 | args: ['echo', 'hello'] 324 | }); 325 | 326 | // await(等待) 完成 327 | await p.status(); 328 | } 329 | 330 | main(); 331 | ``` 332 | 333 | 运行它: 334 | 335 | ```shellsession 336 | $ deno --allow-run ./subprocess_simple.ts 337 | hello 338 | ``` 339 | 340 | 默认情况下,`Deno.run()`的子进程,会继承父进程的`stdin`,`stdout`和`stdout`。如果要与已启动的子进程通信,可以使用`"piped"`选项。 341 | 342 | ```ts 343 | async function main() { 344 | const decoder = new TextDecoder(); 345 | 346 | const fileNames = Deno.args.slice(1); 347 | 348 | const p = Deno.run({ 349 | args: [ 350 | 'deno', 351 | '--allow-read', 352 | 'https://deno.land/std/examples/cat.ts', 353 | ...fileNames 354 | ], 355 | stdout: 'piped', 356 | stderr: 'piped' 357 | }); 358 | 359 | const {code} = await p.status(); 360 | 361 | if (code === 0) { 362 | const rawOutput = await p.output(); 363 | Deno.stdout.write(rawOutput); 364 | } else { 365 | const rawError = await p.stderrOutput(); 366 | Deno.stdout.write(rawError); 367 | } 368 | 369 | Deno.exit(code); 370 | } 371 | 372 | main(); 373 | ``` 374 | 375 | 运行时: 376 | 377 | ```shellsession 378 | $ deno ./subprocess.ts --allow-run 379 | [file content] 380 | 381 | $ deno ./subprocess.ts --allow-run non_existent_file.md 382 | 383 | Uncaught NotFound: No such file or directory (os error 2) 384 | at DenoError (deno/js/errors.ts:19:5) 385 | at maybeError (deno/js/errors.ts:38:12) 386 | at handleAsyncMsgFromRust (deno/js/dispatch.ts:27:17) 387 | ``` 388 | 389 | ### 链接到第三方代码 390 | 391 | 在上面的例子中,我们看到了 deno 可以用 URL 执行脚本。和浏览器 javascript 一样,deno 可以直接用 URL 导入库。此示例使用 URL 导入,测试运行程序库: 392 | 393 | ```ts 394 | import {test, runIfMain} from 'https://deno.land/std/testing/mod.ts'; 395 | import {assertEquals} from 'https://deno.land/std/testing/asserts.ts'; 396 | 397 | test(function t1() { 398 | assertEquals('hello', 'hello'); 399 | }); 400 | 401 | test(function t2() { 402 | assertEquals('world', 'world'); 403 | }); 404 | 405 | runIfMain(import.meta); 406 | ``` 407 | 408 | 尝试运行此: 409 | 410 | ```shellsession 411 | $ deno test.ts 412 | running 2 tests 413 | test t1 ... ok 414 | test t2 ... ok 415 | 416 | test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out 417 | ``` 418 | 419 | 注意,我们不必提供`--allow-net`此程序的标志,但它访问了网络。事实上,Deno 运行时具有,下载导入(文件),并将其缓存到磁盘的特殊访问权。 420 | 421 | deno 将远程导入,缓存到`$DENO_DIR`环境变量。如果`$DENO_DIR`未指定。下次运行程序时,将不会进行下载。如果程序没有更改,也不会重新编译。默认目录为: 422 | 423 | - 在 Linux/Redox:`$XDG_CACHE_HOME/deno`或`$HOME/.cache/deno` 424 | - 在 Windows 上:`%LOCALAPPDATA%/deno`(`%LOCALAPPDATA%` = `FOLDERID_LocalAppData`) 425 | - 在 MaOS:`$HOME/Library/Caches/deno` 426 | - 如果某件事失败了,它会回到`$HOME/.deno` 427 | 428 | **但是如果`https://deno.land/`失联了?**依赖外部服务器便于开发,但在生产环境中,却很脆弱。生产软件应始终捆绑其依赖项。具体在 deno 的操作是,通过让`$DENO_DIR`,搭上你的源代码管理系统,把运行时的`$DENO_DIR`环境变量,指定为该路径。 429 | 430 | **如何导入到特定版本?**只需在 URL 中,指定版本。例如,此 URL 完全指定,正在运行的代码:`https://unpkg.com/liltest@0.0.5/dist/liltest.js`。 结合上述在生产环境,设置`$DENO_DIR`,来存储代码的方式,你可以完全指定,要运行的确切代码,还可以在没有网络访问的情况下,执行代码。 431 | 432 | **在任何地方导入 URL 似乎都不方便。如果其中一个 URL ,链接到了一个稍微不同的库版本呢?在大型项目中,维护 URL 是否容易出错?**解决方案是在中心`deps.ts`文件,导入和重新导出外部库(与 Node 的`package.json`文件目的相同)。例如,假设您在一个大型项目中,使用了上述测试库。要做的,不是在任何地方导入`"https://deno.land/std/testing/mod.ts"`,而是可以创建一个`deps.ts`,用来导出第三方代码: 433 | 434 | ```ts 435 | export {test, assertEquals} from 'https://deno.land/std/testing/mod.ts'; 436 | ``` 437 | 438 | 在整个项目中,都可以从`deps.ts`导入,这样就可以避免对同一个 URL 进行多次引用: 439 | 440 | ```ts 441 | import {test, assertEquals} from './deps.ts'; 442 | ``` 443 | 444 | 这种设计避免了,由于包管理软件、集中的代码库和多余的文件格式,而产生的过多复杂性。 445 | 446 | ### 测试当前文件,是否为主程序 447 | 448 | 通过检查`import.meta.main`,测测当前脚本,是否已作为程序的主输入执行。 449 | 450 | ```ts 451 | if (import.meta.main) { 452 | console.log('main'); 453 | } 454 | ``` 455 | 456 | ## 命令行界面 457 | 458 | ### 标志 459 | 460 | ```shellsession 461 | $ deno -h 462 | deno 463 | 464 | USAGE: 465 | deno_dev [FLAGS] [OPTIONS] [SUBCOMMAND] 466 | 467 | FLAGS: 468 | -A, --allow-all 允许所有权限 469 | --allow-env   允许环境访问 470 | --allow-net   允许网络访问 471 | --allow-read   允许文件系统读访问权限 472 | --allow-run   允许运行子进程 473 | --allow-write   允许文件系统写访问权限 474 | -h, --help   打印帮助信息 475 | -D, --log-debug   记录调试输出 476 | --no-prompt   不要使用提示 477 | --prefetch   预取依赖项 478 | -r, --reload   重新加载源代码缓存(重新编译 TypeScript) 479 | --types   打印运行时的 TypeScript 声明 480 | --v8-options   打印 V8 命令行选项 481 | -v, --version   打印版本 482 | 483 | OPTIONS: 484 | --v8-flags= 设置V8命令行选项 485 | 486 | SUBCOMMANDS(子命令): 487 |