存儲(chǔ)庫(kù)中的大多數(shù)模塊都應(yīng)具有以下版權(quán)標(biāo)題:
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
如果代碼來(lái)源于其他地方,請(qǐng)確保文件擁有適當(dāng)?shù)陌鏅?quán)擁有者。 我們只允許 MIT、BSD 和 Apache 許可代碼。
例如: 將文件命名為 file_server.ts 而不是 file-server.ts。
每個(gè)模塊都應(yīng)該包含或伴隨著對(duì)其公共功能的測(cè)試。
TODO 注釋通常應(yīng)該將一個(gè) issue 或者作者的 github 用戶名放在括號(hào)中。例如: // TODO(ry): Add tests. // TODO(#123): Support Windows. // FIXME(#349): Sometimes panics.
即使要寫(xiě)更多的代碼,也要力求明確。 在某些情況下,使用這些技術(shù)可能是有意義的,但是在絕大多數(shù)情況下,它們是沒(méi)有意義的。
請(qǐng)遵循有關(guān)包含代碼的準(zhǔn)則,網(wǎng)址為: https://chromium.googlesource.com/chromium/src/+/master/styleguide/inclusive_code.md
遵循 Rust 約定,并與現(xiàn)有代碼保持一致。
代碼庫(kù)的 TypeScript 部分包括內(nèi)置的 cli/js 和標(biāo)準(zhǔn)庫(kù) std。
為了保證明確性和一致性,避免使用術(shù)語(yǔ) “l(fā)ibrary” 和 “package” ,而是使用 “module” 來(lái)引用一個(gè) JS 或 TS 文件,或者一個(gè) TS/JS 代碼目錄。
Deno 不會(huì)以特殊的方式處理 “index.js” 或 “index.ts” 文件。如果使用了這些名稱,就意味著當(dāng)它們需要模塊說(shuō)明符時(shí),可能被排除在外。這會(huì)造成誤解。 如果一個(gè)代碼目錄需要一個(gè)默認(rèn)的入口點(diǎn),使用文件名 mod.ts。 文件名 mod.ts 遵循 Rust 的約定,比 index.ts 短,并且沒(méi)有任何關(guān)于它如何工作的先入為主的概念。
// 錯(cuò)誤示例:可選參數(shù)不是選項(xiàng)對(duì)象的一部分 (#2)
export function resolve(
hostname: string,
family?: "ipv4" | "ipv6",
timeout?: number
): IPAddress[] {}
// 正確示例:
export interface ResolveOptions {
family?: "ipv4" | "ipv6";
timeout?: number;
}
export function resolve(
hostname: string,
options: ResolveOptions = {}
): IPAddress[] {}
export interface Environment {
[key: string]: string;
}
// 錯(cuò)誤示例:`env`可以是一個(gè)常規(guī)對(duì)象,因此無(wú)法與選項(xiàng)對(duì)象區(qū)分 (#3)
export function runShellWithEnv(cmdline: string, env: Environment): string {}
// 正確示例
export interface RunShellOptions {
env: Environment;
}
export function runShellWithEnv(
cmdline: string,
options: RunShellOptions
): string {}
// 錯(cuò)誤示例:多于3個(gè)參數(shù) (#1),多個(gè)可選參數(shù) (#2)。
export function renameSync(
oldname: string,
newname: string,
replaceExisting?: boolean,
followLinks?: boolean
) {}
// 正確示例
interface RenameOptions {
replaceExisting?: boolean;
followLinks?: boolean;
}
export function renameSync(
oldname: string,
newname: string,
options: RenameOptions = {}
) {}
// 錯(cuò)誤示例:參數(shù)過(guò)多 (#1)
export function pwrite(
fd: number,
buffer: TypedArray,
offset: number,
length: number,
position: number
) {}
// 正確示例:
export interface PWrite {
fd: number;
buffer: TypedArray;
offset: number;
length: number;
position: number;
}
export function pwrite(options: PWrite) {}
// 錯(cuò)誤示例:參數(shù)過(guò)多 (#1)
export function pwrite(
fd: number,
buffer: TypedArray,
offset: number,
length: number,
position: number
) {}
// 正確示例:
export interface PWrite {
fd: number;
buffer: TypedArray;
offset: number;
length: number;
position: number;
}
export function pwrite(options: PWrite) {}
盡管 cli/js 和 std 沒(méi)有外部依賴關(guān)系,但仍然必須注意保持內(nèi)部依賴關(guān)系的簡(jiǎn)單性和可管理性。請(qǐng)尤為注意,不要引入循環(huán)導(dǎo)入。
有時(shí)候可能需要一個(gè)內(nèi)部模塊,但是它的 API 并不穩(wěn)定或者不被連接。這種情況下,在文件名前面加一個(gè)下劃線。按照慣例,只有它自己目錄中的文件才能導(dǎo)入它。
我們力求文檔的完整性。理想情況下,每個(gè)導(dǎo)出的文檔符號(hào)都應(yīng)該有一個(gè)文檔行。 如果可能的話,最好寫(xiě)單行 JSDoc。例如:
/** foo does bar. */
export function foo() {
// ...
}
文檔易于閱讀是很重要的,但是還需要提供額外的樣式信息,以確保生成的文檔有更豐富的含義。因此,JSDoc 通常應(yīng)該遵循 markdown 標(biāo)記來(lái)豐富文本。 雖然 markdown 支持 HTML 標(biāo)記,但是在 JSDoc 塊中是禁止的。 代碼字符串文字應(yīng)使用反引號(hào)(`)括起來(lái),而不是用引號(hào)。例如:
/** Import something from the `deno` module. */
不要記錄函數(shù)參數(shù),除非它們的意圖不明顯(當(dāng)然,如果它們沒(méi)有明顯的意圖,應(yīng)該重新考慮 API 的設(shè)計(jì))。因此,通常不應(yīng)使用 @param。如果使用了 @param,則不應(yīng)該包含 type ,因?yàn)?TypeScript 已經(jīng)是強(qiáng)類型化的了。
/**
* Function with non obvious param.
* @param foo Description of non obvious parameter.
*/
應(yīng)盡可能減小垂直間距。因此單行注釋?xiě)?yīng)寫(xiě)為:
/** 這樣寫(xiě)單行 JSDoc 注釋。 */
不要寫(xiě)為:
/**
* 不要這樣寫(xiě)單行 JSDoc 注釋。
*/
代碼示例不應(yīng)使用三個(gè)反引號(hào)(```)標(biāo)記。它們應(yīng)該用縮進(jìn)標(biāo)記,要求在示例代碼塊前加入一個(gè)空行,并且示例代碼的每一行需要有 6 個(gè)額外空格。比注釋的第一列多 4 個(gè)空格。例如:
/** A straight forward comment and an example:
*
* import { foo } from "deno";
* foo("bar");
*/
既然代碼示例已經(jīng)是一個(gè)注釋了,它就不應(yīng)再包含其他注釋。如果它需要進(jìn)一步的注釋,那意味著它不是一個(gè)很好的示例。
每個(gè)模塊都應(yīng)該附帶一個(gè)測(cè)試模塊 每個(gè)帶有公共功能 foo.ts 的模塊都應(yīng)該附帶一個(gè)測(cè)試模塊 foo_test.ts。由于 cli/js 模塊的上下文不同,它的測(cè)試應(yīng)該放在 cli/js/tests 中,或者它應(yīng)只是測(cè)試模塊的同級(jí)模塊。
為了更好地理解測(cè)試,函數(shù)應(yīng)該在測(cè)試命令中按照提示正確命名,如:
test myTestFunction ... ok
測(cè)試示例:
import { assertEquals } from "https://deno.land/std@v0.11/testing/asserts.ts";
import { foo } from "./mod.ts";
Deno.test("myTestFunction" function() {
assertEquals(foo(), { bar: "bar" });
});
頂級(jí)函數(shù)應(yīng)使用 function 關(guān)鍵字。箭頭語(yǔ)法應(yīng)限于閉包。 錯(cuò)誤示例:
export const foo = (): string => {
return "bar";
};
正確示例:
export function foo(): string {
return "bar";
}
不要依賴外部代碼 https://deno.land/std/ 旨在成為所有 Deno 程序可以依賴的基礎(chǔ)功能。我們希望向用戶保證,此代碼不包含任何可能未經(jīng)審核的第三方代碼。 文檔以及維護(hù)瀏覽器兼容性 如果一個(gè)模塊兼容瀏覽器,在模塊頂部的 JSDoc 中包含以下聲明:
/* This module is browser compatible. / 為該模塊維護(hù)瀏覽器兼容性,在代碼和測(cè)試中都不要使用 Deno 命名空間,確保任何新的依賴都兼容瀏覽器。
更多建議: