conventions for 3rd party modules (work in progess).
It is a bit messy at the moment. The deno landscape is growing fast and modules take all different forms and conventions. There is a style guide for deno contributions, but not on what a 3rd party module should look like.
- easy to implement conventions
- familiarity between modules
- crossconnectivity between modules
Write .ts
files. Avoid .js
and .d.ts
files.
Format your code with deno fmt
.
- Use snake case for file names
Example:
- my_file.ts
instead of
- my-file.ts
- myFile.ts
- MyFile.ts
- Have a toplevel
mod.ts
file that exports everything that is needed when one is to use your module
Example:
// mod.ts
export { doSomething } from "./do_something.ts"
export { doSomethingElse } from "./do_something_else.ts"
export const someConstant = "hello world"
- Have a toplevel
deps.ts
file that exports external dependencies. This prevents the same url in different files and also to have an overview over the module dependencies and versions.
Example:
module
- deps.ts
- mod.ts
// deps.ts
export * as path from "https://deno.land/[email protected]/path/mod.ts";
export * as colors from "https://deno.land/[email protected]/fmt/colors.ts";
export * as fs from "https://deno.land/[email protected]/fs/mod.ts";
For more complex modules, deps files should be named [kind]_deps.ts
.
Example:
module
- deps.ts
- mod.ts
- test_deps.ts
// test_deps.ts
export { assertEquals } from "https://deno.land/[email protected]/testing/mod.ts";
- Avoid using a
test
ortests
directory.
For modules with only a few files and few tests, they can be grouped together in test.ts
.
Example:
module
- mod.ts
- test.ts
For more complex modules, test files should be named [filename]_test.ts
.
Test files should be next to the tested file.
Example:
module
- mod.ts
- strategies
- github.ts
- github_test.ts
- facebook.ts
- facebook_test.ts
- google.ts
- google_test.ts
A file that is intended to be installed with deno install
should be named cli.ts
.
Example:
module
- cli.ts
- mod.ts
If There are multiple installable files in one module, the name should be [filename]_cli.ts
.
Example:
module
- do_something_cli.ts
- do_something_else_cli.ts
- mod.ts
Because the file does not always have to be installed in order to use it. Sometimes cli.ts
might just be run with deno run
.
Avoid unexpressive directory names like lib
, src
and dist
. Deno modules are different from other languages because typescript does not need to be compiled and can be imported directly into projects via url. Having an additional /src
in the import url is ugly and not necessary.
These directories can be replaced by directories with expressive names in almost every case.
Example:
module
- mod.ts
- strategies
- github.ts
- facebook.ts
- google.ts
- README.md
instead of
module
- mod.ts
- src
- github.ts
- facebook.ts
- google.ts
- README.md
- use CamelCase
- do not abreveate words except common javascript API abbreviations (Examples:
URL
,JSON
,DOM
, etc.) - choose epressive names. Most function names will start with a verb (Examples:
has
,filter
,set
,findIndex
,createSpecifierMap
)
Example:
function returnHelloWorld() {
return "Hello, world"
}
instead of
function returnhelloworld() {
return "Hello, world"
}
function return_hello_world() {
return "Hello, world"
}
function ReturnHelloWorld() {
return "Hello, world"
}
Functions should have the parameter types they need. They should not do extra work that can be done outside the function like parsing, reading, type convertions etc. This makes them more flexible.
function checkFoo(object: Record<string, any>) {
return object.foo === true
}
const jsonString = `{ foo: true }`
const parsedObject = JSON.parse(jsonString)
const valid = checkFoo(parsedObject)
instead of
function checkFoo(jsonString: string) {
const parsedObject = JSON.parse(jsonString)
return object.foo === true
}
const jsonString = `{ foo: true }`
const valid = checkFoo(jsonString)
- use
const
whenever possible. Else uselet
. Avoid usingvar
.
- use camel case.
Example:
let myVariable = "good"
const myConstant = "good"
instead of
let myvariable = "bad"
let my_variable = "bad"
const My_Constant = "bad"
- Use Pascal Case
Example:
class MyClass {
}
instead of
class myclass {
}
class myClass {
}
class My_Class {
}
If your module is used in context of another module, prefix that class with the module name and let the user set the instance themselves during the new call. This will allow better integrity between modules.
Example:
import { OakSomething } from "./something/mod.ts"
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
const something = new OakSomething(app)
instead of
import { OakSomething } from "./functionality.ts"
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
const something = new OakSomething( { framwork: "oak" })
app.use(something.middleware)