1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

chore: move docs to separate repository

This commit is contained in:
Bartek Iwańczuk 2021-07-20 16:25:36 +02:00 committed by GitHub
parent 9b9becf1ae
commit d744c0c6d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
90 changed files with 3 additions and 8520 deletions

3
docs/README.md Normal file
View file

@ -0,0 +1,3 @@
Documentation is available at: https://deno.land/manual
Documentation repository is at: https://github.com/denoland/manual

View file

@ -1,81 +0,0 @@
# Contributing
- Read the [style guide](./contributing/style_guide.md).
- Please don't make [the benchmarks](https://deno.land/benchmarks) worse.
- Ask for help in the [community chat room](https://discord.gg/deno).
- If you are going to work on an issue, mention so in the issue comments
_before_ you start working on the issue.
- If you are going to work on a new feature, create an issue and discuss with
other contributors _before_ you start working on the feature.
- Please be professional in the forums. We follow
[Rust's code of conduct](https://www.rust-lang.org/policies/code-of-conduct)
(CoC). Have a problem? Email ry@tinyclouds.org.
## Development
Instructions on how to build from source can be found
[here](./contributing/building_from_source.md).
## Submitting a Pull Request
Before submitting, please make sure the following is done:
1. Give the PR a descriptive title.
Examples of good PR title:
- fix(std/http): Fix race condition in server
- docs(console): Update docstrings
- feat(doc): Handle nested re-exports
Examples of bad PR title:
- fix #7123
- update docs
- fix bugs
2. Ensure there is a related issue and it is referenced in the PR text.
3. Ensure there are tests that cover the changes.
4. Ensure `cargo test` passes.
5. Ensure `./tools/format.js` passes without changing files.
6. Ensure `./tools/lint.js` passes.
## Adding Ops (aka bindings)
We are very concerned about making mistakes when adding new APIs. When adding an
Op to Deno, the counterpart interfaces on other platforms should be researched.
Please list how this functionality is done in Go, Node, Rust, and Python.
As an example, see how `Deno.rename()` was proposed and added in
[PR #671](https://github.com/denoland/deno/pull/671).
## Releases
Summary of the changes from previous releases can be found
[here](https://github.com/denoland/deno/releases).
## Documenting APIs
It is important to document public APIs and we want to do that inline with the
code. This helps ensure that code and documentation are tightly coupled
together.
### Utilize JSDoc
All publicly exposed APIs and types, both via the `deno` module as well as the
global/`window` namespace should have JSDoc documentation. This documentation is
parsed and available to the TypeScript compiler, and therefore easy to provide
further downstream. JSDoc blocks come just prior to the statement they apply to
and are denoted by a leading `/**` before terminating with a `*/`. For example:
```ts
/** A simple JSDoc comment */
export const FOO = "foo";
```
Find more at: https://jsdoc.app/

View file

@ -1,64 +0,0 @@
## Internal details
### Deno and Linux analogy
| **Linux** | **Deno** |
| ------------------------------: | :------------------------------------------- |
| Processes | Web Workers |
| Syscalls | Ops |
| File descriptors (fd) | [Resource ids (rid)](architecture#resources) |
| Scheduler | Tokio |
| Userland: libc++ / glib / boost | https://deno.land/std/ |
| /proc/\$\$/stat | [Deno.metrics()](architecture#metrics) |
| man pages | deno types |
#### Resources
Resources (AKA `rid`) are Deno's version of file descriptors. They are integer
values used to refer to open files, sockets, and other concepts. For testing it
would be good to be able to query the system for how many open resources there
are.
```ts
console.log(Deno.resources());
// { 0: "stdin", 1: "stdout", 2: "stderr" }
Deno.close(0);
console.log(Deno.resources());
// { 1: "stdout", 2: "stderr" }
```
#### Metrics
Metrics is Deno's internal counter for various statistics.
```shell
> console.table(Deno.metrics())
┌─────────────────────────┬───────────┐
│ (idx) │ Values │
├─────────────────────────┼───────────┤
│ opsDispatched │ 9 │
│ opsDispatchedSync │ 0 │
│ opsDispatchedAsync │ 0 │
│ opsDispatchedAsyncUnref │ 0 │
│ opsCompleted │ 9 │
│ opsCompletedSync │ 0 │
│ opsCompletedAsync │ 0 │
│ opsCompletedAsyncUnref │ 0 │
│ bytesSentControl │ 504 │
│ bytesSentData │ 0 │
│ bytesReceived │ 856 │
└─────────────────────────┴───────────┘
```
### Schematic diagram
![architectural schematic](https://deno.land/images/schematic_v0.2.png)
### Conference
- Ryan Dahl. (May 27, 2020).
[An interesting case with Deno](https://www.youtube.com/watch?v=1b7FoBwxc7E).
Deno Israel.
- Bartek Iwańczuk. (Oct 6, 2020).
[Deno internals - how modern JS/TS runtime is
built](https://www.youtube.com/watch?v=AOvg_GbnsbA&t=35m13s). Paris Deno.

View file

@ -1,104 +0,0 @@
## Building from source
Below are instructions on how to build Deno from source. If you just want to use
Deno you can download a prebuilt executable (more information in the
`Getting Started` chapter).
### Cloning the Repository
Clone on Linux or Mac:
```shell
git clone --recurse-submodules https://github.com/denoland/deno.git
```
Extra steps for Windows users:
1. [Enable "Developer Mode"](https://www.google.com/search?q=windows+enable+developer+mode)
(otherwise symlinks would require administrator privileges).
2. Make sure you are using git version 2.19.2.windows.1 or newer.
3. Set `core.symlinks=true` before the checkout:
```shell
git config --global core.symlinks true
git clone --recurse-submodules https://github.com/denoland/deno.git
```
### Prerequisites
> Deno requires the progressively latest stable release of Rust. Deno does not
> support the Rust nightlies.
[Update or Install Rust](https://www.rust-lang.org/tools/install). Check that
Rust installed/updated correctly:
```
rustc -V
cargo -V
```
### Building Deno
The easiest way to build Deno is by using a precompiled version of V8:
```
cargo build -vv
```
However if you want to build Deno and V8 from source code:
```
V8_FROM_SOURCE=1 cargo build -vv
```
When building V8 from source, there are more dependencies:
[Python 3](https://www.python.org/downloads) for running WPT tests. Ensure that
a suffix-less `python`/`python.exe` exists in your `PATH` and it refers to
Python 3.
For Linux users glib-2.0 development files must also be installed. (On Ubuntu,
run `apt install libglib2.0-dev`.)
Mac users must have Command Line Tools installed.
([XCode](https://developer.apple.com/xcode/) already includes CLT. Run
`xcode-select --install` to install it without XCode.)
For Windows users:
1. Get [VS Community 2019](https://www.visualstudio.com/downloads/) with
"Desktop development with C++" toolkit and make sure to select the following
required tools listed below along with all C++ tools.
- Visual C++ tools for CMake
- Windows 10 SDK (10.0.17763.0)
- Testing tools core features - Build Tools
- Visual C++ ATL for x86 and x64
- Visual C++ MFC for x86 and x64
- C++/CLI support
- VC++ 2015.3 v14.00 (v140) toolset for desktop
2. Enable "Debugging Tools for Windows". Go to "Control Panel" → "Programs" →
"Programs and Features" → Select "Windows Software Development Kit - Windows
10" → "Change" → "Change" → Check "Debugging Tools For Windows" → "Change" →
"Finish". Or use:
[Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/)
(Notice: it will download the files, you should install
`X64 Debuggers And Tools-x64_en-us.msi` file manually.)
See [rusty_v8's README](https://github.com/denoland/rusty_v8) for more details
about the V8 build.
### Building
Build with Cargo:
```shell
# Build:
cargo build -vv
# Build errors? Ensure you have latest main and try building again, or if that doesn't work try:
cargo clean && cargo build -vv
# Run:
./target/debug/deno run cli/tests/002_hello.ts
```

View file

@ -1,69 +0,0 @@
## Testing and Tools
### Tests
Test `deno`:
```shell
# Run the whole suite:
cargo test
# Only test cli/tests/unit/:
cargo test js_unit_tests
```
Test `std/`:
```shell
cargo test std_tests
```
### Lint and format
Lint the code:
```shell
deno run -A --unstable ./tools/lint.js
```
Format the code:
```shell
deno run -A --unstable ./tools/format.js
```
### Continuous Benchmarks
See our benchmarks [over here](https://deno.land/benchmarks)
The benchmark chart supposes
https://github.com/denoland/benchmark_data/blob/gh-pages/data.json has the type
`BenchmarkData[]` where `BenchmarkData` is defined like the below:
```ts
interface ExecTimeData {
mean: number;
stddev: number;
user: number;
system: number;
min: number;
max: number;
}
interface BenchmarkData {
created_at: string;
sha1: string;
benchmark: {
[key: string]: ExecTimeData;
};
binarySizeData: {
[key: string]: number;
};
threadCountData: {
[key: string]: number;
};
syscallCountData: {
[key: string]: number;
};
}
```

File diff suppressed because it is too large Load diff

View file

@ -1,35 +0,0 @@
## Release Schedule
A new minor release for the `deno` cli is released every 6 weeks. After 1.9.0 we
will be switching to a 4 week release cycle. A new patch version is released
weekly, as necessary.
The release dates for the upcoming minor releases are:
- 1.11.0: June 8, 2021
- 1.12.0: July 13, 2021
- 1.13.0: August 10, 2021
- 1.14.0: September 14, 2021
Stable releases can be found on the
[GitHub releases page](https://github.com/denoland/deno/releases).
### Canary channel
In addition to the stable channel described above, canaries are released
multiple times daily (for each commit on main). You can upgrade to the latest
canary release by running:
```
deno upgrade --canary
```
To update to a specific canary, pass the commit hash in the `--version` option:
```
deno upgrade --canary --version=973af61d8bb03c1709f61e456581d58386ed4952
```
To switch back to the stable channel, run `deno upgrade`.
Canaries can be downloaded from https://dl.deno.land.

View file

@ -1,360 +0,0 @@
# Deno Style Guide
## Copyright Headers
Most modules in the repository should have the following copyright header:
```ts
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
```
If the code originates elsewhere, ensure that the file has the proper copyright
headers. We only allow MIT, BSD, and Apache licensed code.
## Use underscores, not dashes in filenames.
Example: Use `file_server.ts` instead of `file-server.ts`.
## Add tests for new features.
Each module should contain or be accompanied by tests for its public
functionality.
## TODO Comments
TODO comments should usually include an issue or the author's github username in
parentheses. Example:
```ts
// TODO(ry): Add tests.
// TODO(#123): Support Windows.
// FIXME(#349): Sometimes panics.
```
## Meta-programming is discouraged. Including the use of Proxy.
Be explicit even when it means more code.
There are some situations where it may make sense to use such techniques, but in
the vast majority of cases it does not.
## Inclusive code
Please follow the guidelines for inclusive code outlined at
https://chromium.googlesource.com/chromium/src/+/master/styleguide/inclusive_code.md.
## Rust
Follow Rust conventions and be consistent with existing code.
## TypeScript
The TypeScript portion of the code base is the standard library `std`.
### Use TypeScript instead of JavaScript.
### Use the term "module" instead of "library" or "package".
For clarity and consistency avoid the terms "library" and "package". Instead use
"module" to refer to a single JS or TS file and also to refer to a directory of
TS/JS code.
### Do not use the filename `index.ts`/`index.js`.
Deno does not treat "index.js" or "index.ts" in a special way. By using these
filenames, it suggests that they can be left out of the module specifier when
they cannot. This is confusing.
If a directory of code needs a default entry point, use the filename `mod.ts`.
The filename `mod.ts` follows Rusts convention, is shorter than `index.ts`, and
doesnt come with any preconceived notions about how it might work.
### Exported functions: max 2 args, put the rest into an options object.
When designing function interfaces, stick to the following rules.
1. A function that is part of the public API takes 0-2 required arguments, plus
(if necessary) an options object (so max 3 total).
2. Optional parameters should generally go into the options object.
An optional parameter that's not in an options object might be acceptable if
there is only one, and it seems inconceivable that we would add more optional
parameters in the future.
3. The 'options' argument is the only argument that is a regular 'Object'.
Other arguments can be objects, but they must be distinguishable from a
'plain' Object runtime, by having either:
- a distinguishing prototype (e.g. `Array`, `Map`, `Date`, `class MyThing`).
- a well-known symbol property (e.g. an iterable with `Symbol.iterator`).
This allows the API to evolve in a backwards compatible way, even when the
position of the options object changes.
```ts
// BAD: optional parameters not part of options object. (#2)
export function resolve(
hostname: string,
family?: "ipv4" | "ipv6",
timeout?: number,
): IPAddress[] {}
// GOOD.
export interface ResolveOptions {
family?: "ipv4" | "ipv6";
timeout?: number;
}
export function resolve(
hostname: string,
options: ResolveOptions = {},
): IPAddress[] {}
```
```ts
export interface Environment {
[key: string]: string;
}
// BAD: `env` could be a regular Object and is therefore indistinguishable
// from an options object. (#3)
export function runShellWithEnv(cmdline: string, env: Environment): string {}
// GOOD.
export interface RunShellOptions {
env: Environment;
}
export function runShellWithEnv(
cmdline: string,
options: RunShellOptions,
): string {}
```
```ts
// BAD: more than 3 arguments (#1), multiple optional parameters (#2).
export function renameSync(
oldname: string,
newname: string,
replaceExisting?: boolean,
followLinks?: boolean,
) {}
// GOOD.
interface RenameOptions {
replaceExisting?: boolean;
followLinks?: boolean;
}
export function renameSync(
oldname: string,
newname: string,
options: RenameOptions = {},
) {}
```
```ts
// BAD: too many arguments. (#1)
export function pwrite(
fd: number,
buffer: TypedArray,
offset: number,
length: number,
position: number,
) {}
// BETTER.
export interface PWrite {
fd: number;
buffer: TypedArray;
offset: number;
length: number;
position: number;
}
export function pwrite(options: PWrite) {}
```
### Export all interfaces that are used as parameters to an exported member
Whenever you are using interfaces that are included in the arguments of an
exported member, you should export the interface that is used. Here is an
example:
```ts
// my_file.ts
export interface Person {
name: string;
age: number;
}
export function createPerson(name: string, age: number): Person {
return { name, age };
}
// mod.ts
export { createPerson } from "./my_file.ts";
export type { Person } from "./my_file.ts";
```
### Minimize dependencies; do not make circular imports.
Although `std` has no external dependencies, we must still be careful to keep
internal dependencies simple and manageable. In particular, be careful not to
introduce circular imports.
### If a filename starts with an underscore: `_foo.ts`, do not link to it.
Sometimes there may be situations where an internal module is necessary but its
API is not meant to be stable or linked to. In this case prefix it with an
underscore. By convention, only files in its own directory should import it.
### Use JSDoc for exported symbols.
We strive for complete documentation. Every exported symbol ideally should have
a documentation line.
If possible, use a single line for the JSDoc. Example:
```ts
/** foo does bar. */
export function foo() {
// ...
}
```
It is important that documentation is easily human readable, but there is also a
need to provide additional styling information to ensure generated documentation
is more rich text. Therefore JSDoc should generally follow markdown markup to
enrich the text.
While markdown supports HTML tags, it is forbidden in JSDoc blocks.
Code string literals should be braced with the back-tick (\`) instead of quotes.
For example:
```ts
/** Import something from the `deno` module. */
```
Do not document function arguments unless they are non-obvious of their intent
(though if they are non-obvious intent, the API should be considered anyways).
Therefore `@param` should generally not be used. If `@param` is used, it should
not include the `type` as TypeScript is already strongly typed.
```ts
/**
* Function with non obvious param.
* @param foo Description of non obvious parameter.
*/
```
Vertical spacing should be minimized whenever possible. Therefore single line
comments should be written as:
```ts
/** This is a good single line JSDoc. */
```
And not:
```ts
/**
* This is a bad single line JSDoc.
*/
```
Code examples should utilize markdown format, like so:
````ts
/** A straight forward comment and an example:
* ```ts
* import { foo } from "deno";
* foo("bar");
* ```
*/
````
Code examples should not contain additional comments and must not be indented.
It is already inside a comment. If it needs further comments it is not a good
example.
### Resolve linting problems using directives
Currently, the building process uses `dlint` to validate linting problems in the
code. If the task requires code that is non-conformant to linter use
`deno-lint-ignore <code>` directive to suppress the warning.
```typescript
// deno-lint-ignore no-explicit-any
let x: any;
```
This ensures the continuous integration process doesn't fail due to linting
problems, but it should be used scarcely.
### Each module should come with a test module.
Every module with public functionality `foo.ts` should come with a test module
`foo_test.ts`. A test for a `std` module should go in `std/tests` due to their
different contexts, otherwise it should just be a sibling to the tested module.
### Unit Tests should be explicit.
For a better understanding of the tests, function should be correctly named as
its prompted throughout the test command. Like:
```
test myTestFunction ... ok
```
Example of test:
```ts
import { assertEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
import { foo } from "./mod.ts";
Deno.test("myTestFunction", function () {
assertEquals(foo(), { bar: "bar" });
});
```
### Top level functions should not use arrow syntax.
Top level functions should use the `function` keyword. Arrow syntax should be
limited to closures.
Bad:
```ts
export const foo = (): string => {
return "bar";
};
```
Good:
```ts
export function foo(): string {
return "bar";
}
```
### `std`
#### Do not depend on external code.
`https://deno.land/std/` is intended to be baseline functionality that all Deno
programs can rely on. We want to guarantee to users that this code does not
include potentially unreviewed third party code.
#### Document and maintain browser compatibility.
If a module is browser compatible, include the following in the JSDoc at the top
of the module:
```ts
// This module is browser compatible.
```
Maintain browser compatibility for such a module by either not using the global
`Deno` namespace or feature-testing for it. Make sure any new dependencies are
also browser compatible.

View file

@ -1,133 +0,0 @@
## Web Platform Test
Deno uses a custom test runner for Web Platform Tests. It can be found at
`./tools/wpt.ts`.
### Running tests
> If you are on Windows, or your system does not support shebangs, prefix all
> `./tools/wpt.ts` commands with
> `deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run`.
Before attempting to run WPT tests for the first time, please run the WPT setup.
You must also run this command every time the `./test_util/wpt` submodule is
updated:
```shell
./tools/wpt.ts setup
```
To run all available web platform tests, run the following command:
```shell
./tools/wpt.ts run
# You can also filter which test files to run by specifying filters:
./tools/wpt.ts run -- streams/piping/general hr-time
```
The test runner will run each web platform test and record its status (failed or
ok). It will then compare this output to the expected output of each test as
specified in the `./tools/wpt/expectation.json` file. This file is a nested JSON
structure that mirrors the `./test_utils/wpt` directory. It describes for each
test file, if it should pass as a whole (all tests pass, `true`), if it should
fail as a whole (test runner encounters an exception outside of a test or all
tests fail, `false`), or which tests it expects to fail (a string array of test
case names).
### Updating enabled tests or expectations
You can update the `./tools/wpt/expectation.json` file manually by changing the
value of each of the test file entries in the JSON structure. The alternative
and preferred option is to have the WPT runner run all, or a filtered subset of
tests, and then automatically update the `expectation.json` file to match the
current reality. You can do this with the `./wpt.ts update` command. Example:
```shell
./tools/wpt.ts update -- hr-time
```
After running this command the `expectation.json` file will match the current
output of all the tests that were run. This means that running `wpt.ts run`
right after a `wpt.ts update` should always pass.
### Subcommands
#### `setup`
Validate that your environment is configured correctly, or help you configure
it.
This will check that the python3 (or `python.exe` on Windows) is actually
Python 3.
You can specify the following flags to customize behaviour:
```
--rebuild
Rebuild the manifest instead of downloading. This can take up to 3 minutes.
--auto-config
Automatically configure /etc/hosts if it is not configured (no prompt will be shown).
```
#### `run`
Run all tests like specified in `expectation.json`.
You can specify the following flags to customize behaviour:
```
--release
Use the ./target/release/deno binary instead of ./target/debug/deno
--quiet
Disable printing of `ok` test cases.
--json=<file>
Output the test results as JSON to the file specified.
```
You can also specify exactly which tests to run by specifying one of more
filters after a `--`:
```
./tools/wpt.ts run -- hr-time streams/piping/general
```
### `update`
Update the `expectation.json` to match the current reality.
You can specify the following flags to customize behaviour:
```
--release
Use the ./target/release/deno binary instead of ./target/debug/deno
--quiet
Disable printing of `ok` test cases.
--json=<file>
Output the test results as JSON to the file specified.
```
You can also specify exactly which tests to run by specifying one of more
filters after a `--`:
```
./tools/wpt.ts update -- hr-time streams/piping/general
```
### FAQ
#### Upgrading the wpt submodule:
```shell
cd test_util/wpt/
# Rebase to retain our modifications
git rebase origin/master
git push denoland
```
All contributors will need to rerun `./tools/wpt.ts setup` after this.

View file

@ -1,11 +0,0 @@
# Embedding Deno
Deno consists of multiple parts, one of which is `deno_core`. This is a rust
crate that can be used to embed a JavaScript runtime into your rust application.
Deno is built on top of `deno_core`.
The Deno crate is hosted on [crates.io](https://crates.io/crates/deno_core).
You can view the API on [docs.rs](https://docs.rs/deno_core).
<!-- TODO(lucacasonato): better docs -->

View file

@ -1,23 +0,0 @@
# Examples
In this chapter you can find some example programs that you can use to learn
more about the runtime.
## Basic
- [Hello world](./examples/hello_world.md)
- [Import and export modules](./examples/import_export.md)
- [Manage dependencies](./examples/manage_dependencies.md)
- [Fetch data](./examples/fetch_data.md)
- [Read and write files](./examples/read_write_files.md)
## Advanced
- [Unix cat program](./examples/unix_cat.md)
- [HTTP web server](./examples/http_server.md)
- [File server](./examples/file_server.md)
- [TCP echo server](./examples/tcp_echo.md)
- [Creating a subprocess](./examples/subprocess.md)
- [OS signals](./examples/os_signals.md)
- [File system events](./examples/file_system_events.md)
- [Module metadata](./examples/module_metadata.md)

View file

@ -1,58 +0,0 @@
# Fetch data
## Concepts
- Like browsers, Deno implements web standard APIs such as
[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
- Deno is secure by default, meaning explicit permission must be granted to
access the network.
- See also: Deno's [permissions](../getting_started/permissions.md) model.
## Overview
When building any sort of web application developers will usually need to
retrieve data from somewhere else on the web. This works no differently in Deno
than in any other JavaScript application, just call the `fetch()` method. For
more information on fetch read the
[MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
The exception with Deno occurs when running a script which makes a call over the
web. Deno is secure by default which means access to IO (Input / Output) is
prohibited. To make a call over the web Deno must be explicitly told it is ok to
do so. This is achieved by adding the `--allow-net` flag to the `deno run`
command.
## Example
**Command:** `deno run --allow-net fetch.ts`
```js
/**
* Output: JSON Data
*/
const json = fetch("https://api.github.com/users/denoland");
json.then((response) => {
return response.json();
}).then((jsonData) => {
console.log(jsonData);
});
/**
* Output: HTML Data
*/
const text = fetch("https://deno.land/");
text.then((response) => {
return response.text();
}).then((textData) => {
console.log(textData);
});
/**
* Output: Error Message
*/
const error = fetch("https://does.not.exist/");
error.catch((error) => console.log(error.message));
```

View file

@ -1,63 +0,0 @@
# File server
## Concepts
- Use the Deno standard library
[file_server.ts](https://deno.land/std@$STD_VERSION/http/file_server.ts) to
run your own file server and access your files from your web browser.
- Run [Deno install](../tools/script_installer.md) to install the file server
locally.
## Example
Serve a local directory via HTTP. First install the remote script to your local
file system. This will install the script to the Deno installation root's bin
directory, e.g. `/home/alice/.deno/bin/file_server`.
```shell
deno install --allow-net --allow-read https://deno.land/std@$STD_VERSION/http/file_server.ts
```
You can now run the script with the simplified script name. Run it:
```shell
$ file_server .
Downloading https://deno.land/std@$STD_VERSION/http/file_server.ts...
[...]
HTTP server listening on http://0.0.0.0:4507/
```
Now go to [http://0.0.0.0:4507/](http://0.0.0.0:4507/) in your web browser to
see your local directory contents.
## Help
Help and a complete list of options are available via:
```shell
file_server --help
```
Example output:
```
Deno File Server
Serves a local directory in HTTP.
INSTALL:
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
USAGE:
file_server [path] [options]
OPTIONS:
-h, --help Prints help information
-p, --port <PORT> Set port
--cors Enable CORS via the "Access-Control-Allow-Origin" header
--host <HOST> Hostname (default is 0.0.0.0)
-c, --cert <FILE> TLS certificate file (enables TLS)
-k, --key <FILE> TLS key file (enables TLS)
--no-dir-listing Disable directory listing
All TLS options are required when one is provided.
```

View file

@ -1,40 +0,0 @@
# File system events
## Concepts
- Use [Deno.watchFs](https://doc.deno.land/builtin/stable#Deno.watchFs) to watch
for file system events.
- Results may vary between operating systems.
## Example
To poll for file system events in the current directory:
```ts
/**
* watcher.ts
*/
const watcher = Deno.watchFs(".");
for await (const event of watcher) {
console.log(">>>> event", event);
// Example event: { kind: "create", paths: [ "/home/alice/deno/foo.txt" ] }
}
```
Run with:
```shell
deno run --allow-read watcher.ts
```
Now try adding, removing and modifying files in the same directory as
`watcher.ts`.
Note that the exact ordering of the events can vary between operating systems.
This feature uses different syscalls depending on the platform:
- Linux: [inotify](https://man7.org/linux/man-pages/man7/inotify.7.html)
- macOS:
[FSEvents](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/FSEvents_ProgGuide/Introduction/Introduction.html)
- Windows:
[ReadDirectoryChangesW](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-readdirectorychangesw)

View file

@ -1,79 +0,0 @@
# Hello world
## Concepts
- Deno can run JavaScript or TypeScript out of the box with no additional tools
or config required.
## Overview
Deno is a secure runtime for both JavaScript and TypeScript. As the hello world
examples below highlight the same functionality can be created in JavaScript or
TypeScript, and Deno will execute both.
## JavaScript
In this JavaScript example the message `Hello [name]` is printed to the console
and the code ensures the name provided is capitalized.
**Command:** `deno run hello-world.js`
```js
/**
* hello-world.js
*/
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.slice(1);
}
function hello(name) {
return "Hello " + capitalize(name);
}
console.log(hello("john"));
console.log(hello("Sarah"));
console.log(hello("kai"));
/**
* Output:
*
* Hello John
* Hello Sarah
* Hello Kai
**/
```
## TypeScript
This TypeScript example is exactly the same as the JavaScript example above, the
code just has the additional type information which TypeScript supports.
The `deno run` command is exactly the same, it just references a `*.ts` file
rather than a `*.js` file.
**Command:** `deno run hello-world.ts`
```ts
/**
* hello-world.ts
*/
function capitalize(word: string): string {
return word.charAt(0).toUpperCase() + word.slice(1);
}
function hello(name: string): string {
return "Hello " + capitalize(name);
}
console.log(hello("john"));
console.log(hello("Sarah"));
console.log(hello("kai"));
/**
* Output:
*
* Hello John
* Hello Sarah
* Hello Kai
**/
```

View file

@ -1,88 +0,0 @@
# Simple HTTP web server
## Concepts
- Use Deno's integrated HTTP server to run your own web server.
## Overview
With just a few lines of code you can run your own HTTP web server with control
over the response status, request headers and more.
> The _native_ HTTP server is currently unstable, meaning the API is not
> finalized and may change in breaking ways in future version of Deno. To have
> the APIs discussed here available, you must run Deno with the `--unstable`
> flag.
## Sample web server
In this example, the user-agent of the client is returned to the client:
**webserver.ts**:
```ts
// Start listening on port 8080 of localhost.
const server = Deno.listen({ port: 8080 });
console.log(`HTTP webserver running. Access it at: http://localhost:8080/`);
// Connections to the server will be yielded up as an async iterable.
for await (const conn of server) {
// In order to not be blocking, we need to handle each connection individually
// in its own async function.
(async () => {
// This "upgrades" a network connection into an HTTP connection.
const httpConn = Deno.serveHttp(conn);
// Each request sent over the HTTP connection will be yielded as an async
// iterator from the HTTP connection.
for await (const requestEvent of httpConn) {
// The native HTTP server uses the web standard `Request` and `Response`
// objects.
const body = `Your user-agent is:\n\n${requestEvent.request.headers.get(
"user-agent",
) ?? "Unknown"}`;
// The requestEvent's `.respondWith()` method is how we send the response
// back to the client.
requestEvent.respondWith(
new Response(body, {
status: 200,
}),
);
}
})();
}
```
Then run this with:
```shell
deno run --allow-net --unstable webserver.ts
```
Then navigate to `http://localhost:8080/` in a browser.
### Using the `std/http` library
If you do not want to use the unstable APIs, you can still use the standard
library's HTTP server:
**webserver.ts**:
```ts
import { serve } from "https://deno.land/std@$STD_VERSION/http/server.ts";
const server = serve({ port: 8080 });
console.log(`HTTP webserver running. Access it at: http://localhost:8080/`);
for await (const request of server) {
let bodyContent = "Your user-agent is:\n\n";
bodyContent += request.headers.get("user-agent") || "Unknown";
request.respond({ status: 200, body: bodyContent });
}
```
Then run this with:
```shell
deno run --allow-net webserver.ts
```

View file

@ -1,120 +0,0 @@
# Import and export modules
## Concepts
- [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)
allows you to include and use modules held elsewhere, on your local file
system or remotely.
- Imports are URLs or file system paths.
- [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)
allows you to specify which parts of your module are accessible to users who
import your module.
## Overview
Deno by default standardizes the way modules are imported in both JavaScript and
TypeScript using the ECMAScript 6 `import/export` standard.
It adopts browser-like module resolution, meaning that file names must be
specified in full. You may not omit the file extension and there is no special
handling of `index.js`.
```js
import { add, multiply } from "./arithmetic.ts";
```
Dependencies are also imported directly, there is no package management
overhead. Local modules are imported in exactly the same way as remote modules.
As the examples show below, the same functionality can be produced in the same
way with local or remote modules.
## Local Import
In this example the `add` and `multiply` functions are imported from a local
`arithmetic.ts` module.
**Command:** `deno run local.ts`
```ts
/**
* local.ts
*/
import { add, multiply } from "./arithmetic.ts";
function totalCost(outbound: number, inbound: number, tax: number): number {
return multiply(add(outbound, inbound), tax);
}
console.log(totalCost(19, 31, 1.2));
console.log(totalCost(45, 27, 1.15));
/**
* Output
*
* 60
* 82.8
*/
```
## Remote Import
In the local import example above an `add` and `multiply` method are imported
from a locally stored arithmetic module. The same functionality can be created
by importing `add` and `multiply` methods from a remote module too.
In this case the Ramda module is referenced, including the version number. Also
note a JavaScript module is imported directly into a TypeScript module, Deno has
no problem handling this.
**Command:** `deno run ./remote.ts`
```ts
/**
* remote.ts
*/
import {
add,
multiply,
} from "https://x.nest.land/ramda@0.27.0/source/index.js";
function totalCost(outbound: number, inbound: number, tax: number): number {
return multiply(add(outbound, inbound), tax);
}
console.log(totalCost(19, 31, 1.2));
console.log(totalCost(45, 27, 1.15));
/**
* Output
*
* 60
* 82.8
*/
```
## Export
In the local import example above the `add` and `multiply` functions are
imported from a locally stored arithmetic module. To make this possible the
functions stored in the arithmetic module must be exported.
To do this just add the keyword `export` to the beginning of the function
signature as is shown below.
```ts
/**
* arithmetic.ts
*/
export function add(a: number, b: number): number {
return a + b;
}
export function multiply(a: number, b: number): number {
return a * b;
}
```
All functions, classes, constants and variables which need to be accessible
inside external modules must be exported. Either by prepending them with the
`export` keyword or including them in an export statement at the bottom of the
file.

View file

@ -1,73 +0,0 @@
# Managing dependencies
## Concepts
- Deno uses URLs for dependency management.
- One convention places all these dependent URLs into a local `deps.ts` file.
Functionality is then exported out of `deps.ts` for use by local modules.
- Continuing this convention, dev only dependencies can be kept in a
`dev_deps.ts` file.
- See also [Linking to external code](../linking_to_external_code.md)
## Overview
In Deno there is no concept of a package manager as external modules are
imported directly into local modules. This raises the question of how to manage
remote dependencies without a package manager. In big projects with many
dependencies it will become cumbersome and time consuming to update modules if
they are all imported individually into individual modules.
The standard practice for solving this problem in Deno is to create a `deps.ts`
file. All required remote dependencies are referenced in this file and the
required methods and classes are re-exported. The dependent local modules then
reference the `deps.ts` rather than the remote dependencies. If now for example
one remote dependency is used in several files, upgrading to a new version of
this remote dependency is much simpler as this can be done just within
`deps.ts`.
With all dependencies centralized in `deps.ts`, managing these becomes easier.
Dev dependencies can also be managed in a separate `dev_deps.ts` file, allowing
clean separation between dev only and production dependencies.
## Example
```ts
/**
* deps.ts
*
* This module re-exports the required methods from the dependant remote Ramda module.
**/
export {
add,
multiply,
} from "https://x.nest.land/ramda@0.27.0/source/index.js";
```
In this example the same functionality is created as is the case in the
[local and remote import examples](./import_export.md). But in this case instead
of the Ramda module being referenced directly it is referenced by proxy using a
local `deps.ts` module.
**Command:** `deno run example.ts`
```ts
/**
* example.ts
*/
import { add, multiply } from "./deps.ts";
function totalCost(outbound: number, inbound: number, tax: number): number {
return multiply(add(outbound, inbound), tax);
}
console.log(totalCost(19, 31, 1.2));
console.log(totalCost(45, 27, 1.15));
/**
* Output
*
* 60
* 82.8
*/
```

View file

@ -1,68 +0,0 @@
# Module metadata
## Concepts
- [import.meta](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import.meta)
can provide information on the context of the module.
- The boolean
[import.meta.main](https://doc.deno.land/builtin/stable#ImportMeta) will let
you know if the current module is the program entry point.
- The string [import.meta.url](https://doc.deno.land/builtin/stable#ImportMeta)
will give you the URL of the current module.
- The string
[Deno.mainModule](https://doc.deno.land/builtin/stable#Deno.mainModule) will
give you the URL of the main module entry point, i.e. the module invoked by
the deno runtime.
## Example
The example below uses two modules to show the difference between
`import.meta.url`, `import.meta.main` and `Deno.mainModule`. In this example,
`module_a.ts` is the main module entry point:
```ts
/**
* module_b.ts
*/
export function outputB() {
console.log("Module B's import.meta.url", import.meta.url);
console.log("Module B's mainModule url", Deno.mainModule);
console.log(
"Is module B the main module via import.meta.main?",
import.meta.main,
);
}
```
```ts
/**
* module_a.ts
*/
import { outputB } from "./module_b.ts";
function outputA() {
console.log("Module A's import.meta.url", import.meta.url);
console.log("Module A's mainModule url", Deno.mainModule);
console.log(
"Is module A the main module via import.meta.main?",
import.meta.main,
);
}
outputA();
console.log("");
outputB();
```
If `module_a.ts` is located in `/home/alice/deno` then the output of
`deno run --allow-read module_a.ts` is:
```
Module A's import.meta.url file:///home/alice/deno/module_a.ts
Module A's mainModule url file:///home/alice/deno/module_a.ts
Is module A the main module via import.meta.main? true
Module B's import.meta.url file:///home/alice/deno/module_b.ts
Module B's mainModule url file:///home/alice/deno/module_a.ts
Is module B the main module via import.meta.main? false
```

View file

@ -1,83 +0,0 @@
# Handle OS Signals
> This program makes use of an unstable Deno feature. Learn more about
> [unstable features](../runtime/stability.md).
## Concepts
- Use the `--unstable` flag to access new or unstable features in Deno.
- [Deno.signal](https://doc.deno.land/builtin/unstable#Deno.signal) can be used
to capture and monitor OS signals.
- Use the `dispose()` function of the Deno.signal
[SignalStream](https://doc.deno.land/builtin/unstable#Deno.SignalStream) to
stop watching the signal.
## Async iterator example
You can use `Deno.signal()` function for handling OS signals:
```ts
/**
* async-iterator-signal.ts
*/
console.log("Press Ctrl-C to trigger a SIGINT signal");
for await (const _ of Deno.signal(Deno.Signal.SIGINT)) {
console.log("interrupted!");
Deno.exit();
}
```
Run with:
```shell
deno run --unstable async-iterator-signal.ts
```
## Promise based example
`Deno.signal()` also works as a promise:
```ts
/**
* promise-signal.ts
*/
console.log("Press Ctrl-C to trigger a SIGINT signal");
await Deno.signal(Deno.Signal.SIGINT);
console.log("interrupted!");
Deno.exit();
```
Run with:
```shell
deno run --unstable promise-signal.ts
```
## Stop watching signals
If you want to stop watching the signal, you can use `dispose()` method of the
signal object:
```ts
/**
* dispose-signal.ts
*/
const sig = Deno.signal(Deno.Signal.SIGINT);
setTimeout(() => {
sig.dispose();
console.log("No longer watching SIGINT signal");
}, 5000);
console.log("Watching SIGINT signals");
for await (const _ of sig) {
console.log("interrupted");
}
```
Run with:
```shell
deno run --unstable dispose-signal.ts
```
The above for-await loop exits after 5 seconds when `sig.dispose()` is called.

View file

@ -1,108 +0,0 @@
# Read and write files
## Concepts
- Deno's runtime API provides the
[Deno.readTextFile](https://doc.deno.land/builtin/stable#Deno.readTextFile)
and
[Deno.writeTextFile](https://doc.deno.land/builtin/stable#Deno.writeTextFile)
asynchronous functions for reading and writing entire text files.
- Like many of Deno's APIs, synchronous alternatives are also available. See
[Deno.readTextFileSync](https://doc.deno.land/builtin/stable#Deno.readTextFileSync)
and
[Deno.writeTextFileSync](https://doc.deno.land/builtin/stable#Deno.writeTextFileSync).
- Use `--allow-read` and `--allow-write` permissions to gain access to the file
system.
## Overview
Interacting with the filesystem to read and write files is a common requirement.
Deno provides a number of ways to do this via the
[standard library](https://deno.land/std) and the
[Deno runtime API](https://doc.deno.land/builtin/stable).
As highlighted in the [Fetch Data example](./fetch_data) Deno restricts access
to Input / Output by default for security reasons. Therefore when interacting
with the filesystem the `--allow-read` and `--allow-write` flags must be used
with the `deno run` command.
## Reading a text file
The Deno runtime API makes it possible to read text files via the
`Deno.readTextFile()` method, it just requires a path string or URL object. The
method returns a promise which provides access to the file's text data.
**Command:** `deno run --allow-read read.ts`
```typescript
/**
* read.ts
*/
const text = Deno.readTextFile("./people.json");
text.then((response) => console.log(response));
/**
* Output:
*
* [
* {"id": 1, "name": "John", "age": 23},
* {"id": 2, "name": "Sandra", "age": 51},
* {"id": 5, "name": "Devika", "age": 11}
* ]
*/
```
## Writing a text file
The Deno runtime API allows developers to write text to files via the
`Deno.writeTextFile()` method. It just requires a file path and text string. The
method returns a promise which resolves when the file was successfully written.
To run the command the `--allow-write` flag must be supplied to the `deno run`
command.
**Command:** `deno run --allow-write write.ts`
```typescript
/**
* write.ts
*/
const write = Deno.writeTextFile("./hello.txt", "Hello World!");
write.then(() => console.log("File written to ./hello.txt"));
/**
* Output: File written to ./hello.txt
*/
```
By combining `Deno.writeTextFile` and `JSON.stringify` you can easily write
serialized JSON objects to a file. This example uses synchronous
`Deno.writeTextFileSync`, but this can also be done asynchronously using
`await Deno.writeTextFile`.
To execute the code the `deno run` command needs the write flag.
**Command:** `deno run --allow-write write.ts`
```typescript
/**
* write.ts
*/
function writeJson(path: string, data: object): string {
try {
Deno.writeTextFileSync(path, JSON.stringify(data));
return "Written to " + path;
} catch (e) {
return e.message;
}
}
console.log(writeJson("./data.json", { hello: "World" }));
/**
* Output: Written to ./data.json
*/
```

View file

@ -1,99 +0,0 @@
# Creating a subprocess
## Concepts
- Deno is capable of spawning a subprocess via
[Deno.run](https://doc.deno.land/builtin/stable#Deno.run).
- `--allow-run` permission is required to spawn a subprocess.
- Spawned subprocesses do not run in a security sandbox.
- Communicate with the subprocess via the
[stdin](https://doc.deno.land/builtin/stable#Deno.stdin),
[stdout](https://doc.deno.land/builtin/stable#Deno.stdout) and
[stderr](https://doc.deno.land/builtin/stable#Deno.stderr) streams.
- Use a specific shell by providing its path/name and its string input switch,
e.g. `Deno.run({cmd: ["bash", "-c", '"ls -la"']});`
## Simple example
This example is the equivalent of running `'echo hello'` from the command line.
```ts
/**
* subprocess_simple.ts
*/
// create subprocess
const p = Deno.run({
cmd: ["echo", "hello"],
});
// await its completion
await p.status();
```
Run it:
```shell
$ deno run --allow-run ./subprocess_simple.ts
hello
```
## Security
The `--allow-run` permission is required for creation of a subprocess. Be aware
that subprocesses are not run in a Deno sandbox and therefore have the same
permissions as if you were to run the command from the command line yourself.
## Communicating with subprocesses
By default when you use `Deno.run()` the subprocess inherits `stdin`, `stdout`
and `stderr` of the parent process. If you want to communicate with started
subprocess you can use `"piped"` option.
```ts
/**
* subprocess.ts
*/
const fileNames = Deno.args;
const p = Deno.run({
cmd: [
"deno",
"run",
"--allow-read",
"https://deno.land/std@$STD_VERSION/examples/cat.ts",
...fileNames,
],
stdout: "piped",
stderr: "piped",
});
const { code } = await p.status();
// Reading the outputs closes their pipes
const rawOutput = await p.output();
const rawError = await p.stderrOutput();
if (code === 0) {
await Deno.stdout.write(rawOutput);
} else {
const errorString = new TextDecoder().decode(rawError);
console.log(errorString);
}
Deno.exit(code);
```
When you run it:
```shell
$ deno run --allow-run ./subprocess.ts <somefile>
[file content]
$ deno run --allow-run ./subprocess.ts non_existent_file.md
Uncaught NotFound: No such file or directory (os error 2)
at DenoError (deno/js/errors.ts:22:5)
at maybeError (deno/js/errors.ts:41:12)
at handleAsyncMsgFromRust (deno/js/dispatch.ts:27:17)
```

View file

@ -1,47 +0,0 @@
# TCP echo server
## Concepts
- Listening for TCP port connections with
[Deno.listen](https://doc.deno.land/builtin/stable#Deno.listen).
- Use
[copy](https://doc.deno.land/https/deno.land/std@$STD_VERSION/io/util.ts#copy)
to take inbound data and redirect it to be outbound data.
## Example
This is an example of a server which accepts connections on port 8080, and
returns to the client anything it sends.
```ts
/**
* echo_server.ts
*/
import { copy } from "https://deno.land/std@$STD_VERSION/io/util.ts";
const listener = Deno.listen({ port: 8080 });
console.log("listening on 0.0.0.0:8080");
for await (const conn of listener) {
copy(conn, conn).finally(() => conn.close());
}
```
Run with:
```shell
deno run --allow-net echo_server.ts
```
To test it, try sending data to it with
[netcat](https://en.wikipedia.org/wiki/Netcat) (Linux/MacOS only). Below
`'hello world'` is sent over the connection, which is then echoed back to the
user:
```shell
$ nc localhost 8080
hello world
hello world
```
Like the [cat.ts example](./unix_cat.md), the `copy()` function here also does
not make unnecessary memory copies. It receives a packet from the kernel and
sends back, without further complexity.

View file

@ -1,36 +0,0 @@
# An implementation of the unix "cat" program
## Concepts
- Use the Deno runtime API to output the contents of a file to the console.
- [Deno.args](https://doc.deno.land/builtin/stable#Deno.args) accesses the
command line arguments.
- [Deno.open](https://doc.deno.land/builtin/stable#Deno.open) is used to get a
handle to a file.
- [copy](https://doc.deno.land/https/deno.land/std@$STD_VERSION/io/util.ts#copy)
is used to transfer data from the file to the output stream.
- Files should be closed when you are finished with them
- Modules can be run directly from remote URLs.
## Example
In this program each command-line argument is assumed to be a filename, the file
is opened, and printed to stdout (e.g. the console).
```ts
/**
* cat.ts
*/
import { copy } from "https://deno.land/std@$STD_VERSION/io/util.ts";
for (const filename of Deno.args) {
const file = await Deno.open(filename);
await copy(file, Deno.stdout);
file.close();
}
```
To run the program:
```shell
deno run --allow-read https://deno.land/std@$STD_VERSION/examples/cat.ts /etc/passwd
```

View file

@ -1,12 +0,0 @@
# Getting Started
In this chapter we'll discuss:
- [Installing Deno](./getting_started/installation.md)
- [Setting up your environment](./getting_started/setup_your_environment.md)
- [Running a `Hello World` script](./getting_started/first_steps.md)
- [Writing our own script](./getting_started/first_steps.md)
- [Command line interface](./getting_started/command_line_interface.md)
- [Understanding permissions](./getting_started/permissions.md)
- [Using WebAssembly](./getting_started/webassembly.md)
- [Debugging your code](./getting_started/debugging_your_code.md)

View file

@ -1,145 +0,0 @@
## Command line interface
Deno is a command line program. You should be familiar with some simple commands
having followed the examples thus far and already understand the basics of shell
usage.
There are multiple ways of viewing the main help text:
```shell
# Using the subcommand.
deno help
# Using the short flag -- outputs the same as above.
deno -h
# Using the long flag -- outputs more detailed help text where available.
deno --help
```
Deno's CLI is subcommand-based. The above commands should show you a list of
those supported, such as `deno bundle`. To see subcommand-specific help for
`bundle`, you can similarly run one of:
```shell
deno help bundle
deno bundle -h
deno bundle --help
```
Detailed guides to each subcommand can be found [here](../tools.md).
### Script source
Deno can grab the scripts from multiple sources, a filename, a url, and '-' to
read the file from stdin. The last is useful for integration with other
applications.
```shell
deno run main.ts
deno run https://mydomain.com/main.ts
cat main.ts | deno run -
```
### Script arguments
Separately from the Deno runtime flags, you can pass user-space arguments to the
script you are running by specifying them after the script name:
```shell
deno run main.ts a b -c --quiet
```
```ts
// main.ts
console.log(Deno.args); // [ "a", "b", "-c", "--quiet" ]
```
**Note that anything passed after the script name will be passed as a script
argument and not consumed as a Deno runtime flag.** This leads to the following
pitfall:
```shell
# Good. We grant net permission to net_client.ts.
deno run --allow-net net_client.ts
# Bad! --allow-net was passed to Deno.args, throws a net permission error.
deno run net_client.ts --allow-net
```
Some see it as unconventional that:
> a non-positional flag is parsed differently depending on its position.
However:
1. This is the most logical and ergonomic way of distinguishing between runtime
flags and script arguments.
2. This is, in fact, the same behaviour as that of any other popular runtime.
- Try `node -c index.js` and `node index.js -c`. The first will only do a
syntax check on `index.js` as per Node's `-c` flag. The second will
_execute_ `index.js` with `-c` passed to `require("process").argv`.
---
There exist logical groups of flags that are shared between related subcommands.
We discuss these below.
### Watch mode
You can supply the `--watch` flag to `deno run` to enable the built in file
watcher. When Deno starts up with this flag it watches the entrypoint, and all
local files the entrypoint statically imports. Whenever one of these files is
changed on disk, the program will automatically be restarted.
```
deno run --watch main.ts
```
### Integrity flags
Affect commands which can download resources to the cache: `deno cache`,
`deno run` and `deno test`.
```
--lock <FILE> Check the specified lock file
--lock-write Write lock file. Use with --lock.
```
Find out more about these
[here](../linking_to_external_code/integrity_checking.md).
### Cache and compilation flags
Affect commands which can populate the cache: `deno cache`, `deno run` and
`deno test`. As well as the flags above this includes those which affect module
resolution, compilation configuration etc.
```
--config <FILE> Load tsconfig.json configuration file
--import-map <FILE> UNSTABLE: Load import map file
--no-remote Do not resolve remote modules
--reload=<CACHE_BLOCKLIST> Reload source code cache (recompile TypeScript)
--unstable Enable unstable APIs
```
### Runtime flags
Affect commands which execute user code: `deno run` and `deno test`. These
include all of the above as well as the following.
#### Permission flags
These are listed [here](./permissions.md#permissions-list).
#### Other runtime flags
More flags which affect the execution environment.
```
--cached-only Require that remote dependencies are already cached
--inspect=<HOST:PORT> activate inspector on host:port ...
--inspect-brk=<HOST:PORT> activate inspector on host:port and break at ...
--seed <NUMBER> Seed Math.random()
--v8-flags=<v8-flags> Set V8 command line options. For help: ...
```

View file

@ -1,145 +0,0 @@
## Debugging your code
Deno supports the [V8 Inspector Protocol](https://v8.dev/docs/inspector).
It's possible to debug Deno programs using Chrome Devtools or other clients that
support the protocol (eg. VSCode).
To activate debugging capabilities run Deno with the `--inspect` or
`--inspect-brk` flags.
The `--inspect` flag allows attaching the debugger at any point in time, while
`--inspect-brk` will wait for the debugger to attach and will pause execution on
the first line of code.
### Chrome Devtools
Let's try debugging a program using Chrome Devtools. For this, we'll use
[file_server.ts](https://deno.land/std@$STD_VERSION/http/file_server.ts) from
`std`, a static file server.
Use the `--inspect-brk` flag to break execution on the first line:
```shell
$ deno run --inspect-brk --allow-read --allow-net https://deno.land/std@$STD_VERSION/http/file_server.ts
Debugger listening on ws://127.0.0.1:9229/ws/1e82c406-85a9-44ab-86b6-7341583480b1
Download https://deno.land/std@$STD_VERSION/http/file_server.ts
Compile https://deno.land/std@$STD_VERSION/http/file_server.ts
...
```
Open `chrome://inspect` and click `Inspect` next to target:
![chrome://inspect](../images/debugger1.jpg)
It might take a few seconds after opening the Devtools to load all modules.
![Devtools opened](../images/debugger2.jpg)
You might notice that Devtools paused execution on the first line of
`_constants.ts` instead of `file_server.ts`. This is expected behavior and is
caused by the way ES modules are evaluated by V8 (`_constants.ts` is left-most,
bottom-most dependency of `file_server.ts` so it is evaluated first).
At this point all source code is available in the Devtools, so let's open up
`file_server.ts` and add a breakpoint there; go to "Sources" pane and expand the
tree:
![Open file_server.ts](../images/debugger3.jpg)
_Looking closely you'll find duplicate entries for each file; one written
regularly and one in italics. The former is compiled source file (so in the case
of `.ts` files it will be emitted JavaScript source), while the latter is a
source map for the file._
Next, add a breakpoint in the `listenAndServe` method:
![Break in file_server.ts](../images/debugger4.jpg)
As soon as we've added the breakpoint Devtools automatically opened up the
source map file, which allows us step through the actual source code that
includes types.
Now that we have our breakpoints set, we can resume the execution of our script
so that we might inspect an incoming request. Hit the Resume script execution
button to do so. You might even need to hit it twice!
Once our script is running again, let's send a request and inspect it in
Devtools:
```
$ curl http://0.0.0.0:4507/
```
![Break in request handling](../images/debugger5.jpg)
At this point we can introspect the contents of the request and go step-by-step
to debug the code.
### VSCode
Deno can be debugged using VSCode.
Official support via the plugin is being worked on -
https://github.com/denoland/vscode_deno/issues/12
We can still attach the debugger by manually providing a
[`launch.json`](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations)
config:
```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Deno",
"type": "pwa-node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "deno",
"runtimeArgs": ["run", "--inspect-brk", "-A", "${file}"],
"attachSimplePort": 9229
}
]
}
```
**NOTE**: This uses the file you have open as the entry point; replace `${file}`
with a script name if you want a fixed entry point.
Let's try out debugging a local source file. Create `server.ts`:
```ts
import { serve } from "https://deno.land/std@$STD_VERSION/http/server.ts";
const server = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of server) {
req.respond({ body: "Hello World\n" });
}
```
Then we can set a breakpoint, and run the created configuration:
![VSCode debugger](../images/debugger7.jpg)
### JetBrains IDEs
You can debug Deno using your JetBrains IDE by right-clicking the file you want
to debug and selecting the `Debug 'Deno: <file name>'` option. This will create
a run/debug configuration with no permission flags set. To configure these flags
edit the run/debug configuration and modify the `Arguments` field with the
required flags.
### Other
Any client that implements the Devtools protocol should be able to connect to a
Deno process.
### Limitations
Devtools support is still immature. There is some functionality that is known to
be missing or buggy:
- autocomplete in Devtools' console causes the Deno process to exit.
- profiling and memory dumps might not work correctly.

View file

@ -1,146 +0,0 @@
## First steps
This page contains some examples to teach you about the fundamentals of Deno.
This document assumes that you have some prior knowledge of JavaScript,
especially about `async`/`await`. If you have no prior knowledge of JavaScript,
you might want to follow a guide
[on the basics of JavaScript](https://developer.mozilla.org/en-US/docs/Learn/JavaScript)
before attempting to start with Deno.
### Hello World
Deno is a runtime for JavaScript/TypeScript which tries to be web compatible and
use modern features wherever possible.
Browser compatibility means a `Hello World` program in Deno is the same as the
one you can run in the browser:
```ts
console.log("Welcome to Deno!");
```
Try the program:
```shell
deno run https://deno.land/std@$STD_VERSION/examples/welcome.ts
```
### Making an HTTP request
Many programs use HTTP requests to fetch data from a webserver. Let's write a
small program that fetches a file and prints its contents out to the terminal.
Just like in the browser you can use the web standard
[`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) API to
make HTTP calls:
```ts
const url = Deno.args[0];
const res = await fetch(url);
const body = new Uint8Array(await res.arrayBuffer());
await Deno.stdout.write(body);
```
Let's walk through what this application does:
1. We get the first argument passed to the application, and store it in the
`url` constant.
2. We make a request to the url specified, await the response, and store it in
the `res` constant.
3. We parse the response body as an
[`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer),
await the response, and convert it into a
[`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)
to store in the `body` constant.
4. We write the contents of the `body` constant to `stdout`.
Try it out:
```shell
deno run https://deno.land/std@$STD_VERSION/examples/curl.ts https://example.com
```
You will see this program returns an error regarding network access, so what did
we do wrong? You might remember from the introduction that Deno is a runtime
which is secure by default. This means you need to explicitly give programs the
permission to do certain 'privileged' actions, such as access the network.
Try it out again with the correct permission flag:
```shell
deno run --allow-net=example.com https://deno.land/std@$STD_VERSION/examples/curl.ts https://example.com
```
### Reading a file
Deno also provides APIs which do not come from the web. These are all contained
in the `Deno` global. You can find documentation for these APIs on
[doc.deno.land](https://doc.deno.land/builtin/stable#Deno).
Filesystem APIs for example do not have a web standard form, so Deno provides
its own API.
In this program each command-line argument is assumed to be a filename, the file
is opened, and printed to stdout.
```ts
import { copy } from "https://deno.land/std@$STD_VERSION/io/util.ts";
const filenames = Deno.args;
for (const filename of filenames) {
const file = await Deno.open(filename);
await copy(file, Deno.stdout);
file.close();
}
```
The `copy()` function here actually makes no more than the necessary
kernel→userspace→kernel copies. That is, the same memory from which data is read
from the file, is written to stdout. This illustrates a general design goal for
I/O streams in Deno.
Try the program:
```shell
deno run --allow-read https://deno.land/std@$STD_VERSION/examples/cat.ts /etc/passwd
```
### TCP server
This is an example of a server which accepts connections on port 8080, and
returns to the client anything it sends.
```ts
import { copy } from "https://deno.land/std@$STD_VERSION/io/util.ts";
const hostname = "0.0.0.0";
const port = 8080;
const listener = Deno.listen({ hostname, port });
console.log(`Listening on ${hostname}:${port}`);
for await (const conn of listener) {
copy(conn, conn);
}
```
For security reasons, Deno does not allow programs to access the network without
explicit permission. To allow accessing the network, use a command-line flag:
```shell
deno run --allow-net https://deno.land/std@$STD_VERSION/examples/echo_server.ts
```
To test it, try sending data to it with netcat:
```shell
$ nc localhost 8080
hello world
hello world
```
Like the `cat.ts` example, the `copy()` function here also does not make
unnecessary memory copies. It receives a packet from the kernel and sends it
back, without further complexity.
### More examples
You can find more examples, like an HTTP file server, in the `Examples` chapter.

View file

@ -1,92 +0,0 @@
## Installation
Deno works on macOS, Linux, and Windows. Deno is a single binary executable. It
has no external dependencies.
### Download and install
[deno_install](https://github.com/denoland/deno_install) provides convenience
scripts to download and install the binary.
Using Shell (macOS and Linux):
```shell
curl -fsSL https://deno.land/x/install/install.sh | sh
```
Using PowerShell (Windows):
```shell
iwr https://deno.land/x/install/install.ps1 -useb | iex
```
Using [Scoop](https://scoop.sh/) (Windows):
```shell
scoop install deno
```
Using [Chocolatey](https://chocolatey.org/packages/deno) (Windows):
```shell
choco install deno
```
Using [Homebrew](https://formulae.brew.sh/formula/deno) (macOS):
```shell
brew install deno
```
Using [Nix](https://nixos.org/download.html) (macOS and Linux):
```shell
nix-shell -p deno
```
Build and install from source using [Cargo](https://crates.io/crates/deno):
```shell
cargo install deno --locked
```
Deno binaries can also be installed manually, by downloading a zip file at
[github.com/denoland/deno/releases](https://github.com/denoland/deno/releases).
These packages contain just a single executable file. You will have to set the
executable bit on macOS and Linux.
### Docker
For more information and instructions on the official Docker images:
[https://github.com/denoland/deno_docker](https://github.com/denoland/deno_docker)
### Testing your installation
To test your installation, run `deno --version`. If this prints the Deno version
to the console the installation was successful.
Use `deno help` to see help text documenting Deno's flags and usage. Get a
detailed guide on the CLI [here](./command_line_interface.md).
### Updating
To update a previously installed version of Deno, you can run:
```shell
deno upgrade
```
This will fetch the latest release from
[github.com/denoland/deno/releases](https://github.com/denoland/deno/releases),
unzip it, and replace your current executable with it.
You can also use this utility to install a specific version of Deno:
```shell
deno upgrade --version 1.0.1
```
### Building from source
Information about how to build from source can be found in the `Contributing`
chapter.

View file

@ -1,96 +0,0 @@
## Permissions
Deno is secure by default. Therefore, unless you specifically enable it, a deno
module has no file, network, or environment access for example. Access to
security-sensitive areas or functions requires the use of permissions to be
granted to a deno process on the command line.
For the following example, `mod.ts` has been granted read-only access to the
file system. It cannot write to it, or perform any other security-sensitive
functions.
```shell
deno run --allow-read mod.ts
```
### Permissions list
The following permissions are available:
- **-A, --allow-all** Allow all permissions. This disables all security.
- **--allow-env=\<allow-env\>** Allow environment access for things like getting
and setting of environment variables. Since Deno 1.9, you can specify a
optional, comma-separated list of environment variables to provide an
allow-list of allowed environment variables.
- **--allow-hrtime** Allow high-resolution time measurement. High-resolution
time can be used in timing attacks and fingerprinting.
- **--allow-net=\<allow-net\>** Allow network access. You can specify an
optional, comma-separated list of domains to provide an allow-list of allowed
domains.
- **--allow-plugin** Allow loading plugins. Please note that --allow-plugin is
an unstable feature.
- **--allow-read=\<allow-read\>** Allow file system read access. You can specify
an optional, comma-separated list of directories or files to provide an
allow-list of allowed file system access.
- **--allow-run=\<allow-run\>** Allow running subprocesses. Since Deno 1.9, You
can specify an options, comma-separated list of subprocesses to provide an
allow-list of allowed subprocesses. Be aware that subprocesses are not run in
a sandbox and therefore do not have the same security restrictions as the deno
process. Therefore, use with caution.
- **--allow-write=\<allow-write\>** Allow file system write access. You can
specify an optional, comma-separated list of directories or files to provide
an allow-list of allowed file system access.
### Permissions allow-list
Deno also allows you to control the granularity of some permissions with
allow-lists.
This example restricts file system access by allow-listing only the `/usr`
directory, however the execution fails as the process was attempting to access a
file in the `/etc` directory:
```shell
$ deno run --allow-read=/usr https://deno.land/std@$STD_VERSION/examples/cat.ts /etc/passwd
error: Uncaught PermissionDenied: read access to "/etc/passwd", run again with the --allow-read flag
► $deno$/dispatch_json.ts:40:11
at DenoError ($deno$/errors.ts:20:5)
...
```
Try it out again with the correct permissions by allow-listing `/etc` instead:
```shell
deno run --allow-read=/etc https://deno.land/std@$STD_VERSION/examples/cat.ts /etc/passwd
```
`--allow-write` works the same as `--allow-read`.
### Network access:
_fetch.ts_:
```ts
const result = await fetch("https://deno.land/");
```
This is an example of how to allow-list hosts/urls:
```shell
deno run --allow-net=github.com,deno.land fetch.ts
```
If `fetch.ts` tries to establish network connections to any other domain, the
process will fail.
Allow net calls to any host/url:
```shell
deno run --allow-net fetch.ts
```
### Conference
Ryan Dahl. (September 25, 2020).
[The Deno security model](https://www.youtube.com/watch?v=r5F6dekUmdE#t=34m57).
Speakeasy JS.

View file

@ -1,329 +0,0 @@
## Set up your environment
To productively get going with Deno you should set up your environment. This
means setting up shell autocomplete, environmental variables and your editor or
IDE of choice.
### Environmental variables
There are several env vars that control how Deno behaves:
`DENO_DIR` defaults to `$HOME/.cache/deno` but can be set to any path to control
where generated and cached source code is written and read to.
`NO_COLOR` will turn off color output if set. See https://no-color.org/. User
code can test if `NO_COLOR` was set without having `--allow-env` by using the
boolean constant `Deno.noColor`.
### Shell autocomplete
You can generate completion script for your shell using the
`deno completions <shell>` command. The command outputs to stdout so you should
redirect it to an appropriate file.
The supported shells are:
- zsh
- bash
- fish
- powershell
- elvish
Example (bash):
```shell
deno completions bash > /usr/local/etc/bash_completion.d/deno.bash
source /usr/local/etc/bash_completion.d/deno.bash
```
Example (zsh without framework):
```shell
mkdir ~/.zsh # create a folder to save your completions. it can be anywhere
deno completions zsh > ~/.zsh/_deno
```
then add this to your `.zshrc`
```shell
fpath=(~/.zsh $fpath)
autoload -Uz compinit
compinit -u
```
and restart your terminal. note that if completions are still not loading, you
may need to run `rm ~/.zcompdump/` to remove previously generated completions
and then `compinit` to generate them again.
Example (zsh + oh-my-zsh) [recommended for zsh users] :
```shell
mkdir ~/.oh-my-zsh/custom/plugins/deno
deno completions zsh > ~/.oh-my-zsh/custom/plugins/deno/_deno
```
After this add deno plugin under plugins tag in `~/.zshrc` file. for tools like
`antigen` path will be `~/.antigen/bundles/robbyrussell/oh-my-zsh/plugins` and
command will be `antigen bundle deno` and so on.
Example (Powershell):
```shell
deno completions powershell >> $profile
.$profile
```
This will be create a Powershell profile at
`$HOME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1` by default,
and it will be run whenever you launch the PowerShell.
### Editors and IDEs
Because Deno requires the use of file extensions for module imports and allows
http imports, and most editors and language servers do not natively support this
at the moment, many editors will throw errors about being unable to find files
or imports having unnecessary file extensions.
The community has developed extensions for some editors to solve these issues:
#### VS Code
The beta version of [vscode_deno](https://github.com/denoland/vscode_deno) is
published on the
[Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno).
Please report any issues.
#### JetBrains IDEs
Support for JetBrains IDEs is available through
[the Deno plugin](https://plugins.jetbrains.com/plugin/14382-deno).
Once installed, replace the content of
`External Libraries > Deno Library > lib > lib.deno.d.ts` with the output of
`deno types`. This will ensure the typings for the extension match the current
version. You will have to do this every time you update the version of Deno. For
more information on how to set-up your JetBrains IDE for Deno, read
[this comment](https://youtrack.jetbrains.com/issue/WEB-41607#focus=streamItem-27-4160152.0-0)
on YouTrack.
#### Vim and NeoVim
Vim works fairly well for Deno/TypeScript if you install
[CoC](https://github.com/neoclide/coc.nvim) (intellisense engine and language
server protocol) or [ALE](https://github.com/dense-analysis/ale) (syntax checker
and language server protocol client).
##### CoC
After CoC is installed, from inside Vim, run`:CocInstall coc-tsserver` and
`:CocInstall coc-deno`. Run `:CocCommand deno.initializeWorkspace` in your
project to initialize workspace configurations. From now on, things like `gd`
(go to definition) and `gr` (goto/find references) should work.
##### ALE
ALE integrates with Deno's LSP out of the box and should not require any extra
configuration. However, if your Deno executable is not located in `$PATH`, has a
different name than `deno` or you want to use unstable features/APIs, you need
to override ALE's default values. See
[`:help ale-typescript`](https://github.com/dense-analysis/ale/blob/master/doc/ale-typescript.txt).
ALE provides support for autocompletion, refactoring, going to definition,
finding references and more, however, key bindings need to be configured
manually. Copy the snippet below into your `vimrc`/`init.vim` for basic
configuration or consult the
[official documentation](https://github.com/dense-analysis/ale#table-of-contents)
for a more in-depth look at how to configure ALE.
ALE can fix linter issues by running `deno fmt`. To instruct ALE to use the Deno
formatter the `ale_linter` setting needs to be set either on a per buffer basis
(`let b:ale_linter = ['deno']`) or globally for all TypeScript files
(`let g:ale_fixers={'typescript': ['deno']}`)
```vim
" Use ALE autocompletion with Vim's 'omnifunc' setting (press <C-x><C-o> in insert mode)
autocmd FileType typescript set omnifunc=ale#completion#OmniFunc
" Make sure to use map instead of noremap when using a <Plug>(...) expression as the {rhs}
nmap gr <Plug>(ale_rename)
nmap gR <Plug>(ale_find_reference)
nmap gd <Plug>(ale_go_to_definition)
nmap gD <Plug>(ale_go_to_type_definition)
let g:ale_fixers = {'typescript': ['deno']}
let g:ale_fix_on_save = 1 " run deno fmt when saving a buffer
```
#### Emacs
Emacs works pretty well for a TypeScript project targeted to Deno by using a
combination of [tide](https://github.com/ananthakumaran/tide) which is the
canonical way of using TypeScript within Emacs and
[typescript-deno-plugin](https://github.com/justjavac/typescript-deno-plugin)
which is what is used by the
[official VSCode extension for Deno](https://github.com/denoland/vscode_deno).
To use it, first make sure that `tide` is setup for your instance of Emacs.
Next, as instructed on the
[typescript-deno-plugin](https://github.com/justjavac/typescript-deno-plugin)
page, first `npm install --save-dev typescript-deno-plugin typescript` in your
project (`npm init -y` as necessary), then add the following block to your
`tsconfig.json` and you are off to the races!
```jsonc
{
"compilerOptions": {
"plugins": [
{
"name": "typescript-deno-plugin",
"enable": true, // default is `true`
"importmap": "import_map.json"
}
]
}
}
```
You can also use built-in Deno language server by using
[`eglot`](https://github.com/joaotavora/eglot).
Example configuration:
```elisp
(add-to-list 'eglot-server-programs '((js-mode typescript-mode) . (eglot-deno "deno" "lsp")))
(defclass eglot-deno (eglot-lsp-server) ()
:documentation "A custom class for deno lsp.")
(cl-defmethod eglot-initialization-options ((server eglot-deno))
"Passes through required deno initialization options"
(list :enable t
:lint t))
```
#### Atom
Install [atom-ide-base](https://atom.io/packages/atom-ide-base) package and
[atom-ide-deno](https://atom.io/packages/atom-ide-deno) package on Atom.
#### LSP clients
Deno has builtin support for the
[Language server protocol](https://langserver.org) as of version 1.6.0 or later.
If your editor supports the LSP, you can use Deno as a language server for
TypeScript and JavaScript.
The editor can start the server with `deno lsp`.
##### Example for Kakoune
After installing the [`kak-lsp`](https://github.com/kak-lsp/kak-lsp) LSP client
you can add the Deno language server by adding the following to your
`kak-lsp.toml`
```toml
[language.deno]
filetypes = ["typescript", "javascript"]
roots = [".git"]
command = "deno"
args = ["lsp"]
[language.deno.initialization_options]
enable = true
lint = true
```
##### Example for Vim/Neovim
After installing the [`vim-lsp`](https://github.com/prabirshrestha/vim-lsp) LSP
client you can add the Deno language server by adding the following to your
`vimrc`/`init.vim`:
```vim
if executable("deno")
augroup LspTypeScript
autocmd!
autocmd User lsp_setup call lsp#register_server({
\ "name": "deno lsp",
\ "cmd": {server_info -> ["deno", "lsp"]},
\ "root_uri": {server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), "tsconfig.json"))},
\ "allowlist": ["typescript", "typescript.tsx"],
\ "initialization_options": {
\ "enable": v:true,
\ "lint": v:true,
\ "unstable": v:true,
\ },
\ })
augroup END
endif
```
##### Example for Sublime Text
- Install the [Sublime LSP package](https://packagecontrol.io/packages/LSP)
- Install the
[TypeScript package](https://packagecontrol.io/packages/TypeScript) to get
syntax highlighting
- Add the following `.sublime-project` file to your project folder
```jsonc
{
"settings": {
"LSP": {
"deno": {
"command": [
"deno",
"lsp"
],
"initializationOptions": {
// "config": "", // Sets the path for the config file in your project
"enable": true,
// "importMap": "", // Sets the path for the import-map in your project
"lint": true,
"unstable": false
},
"enabled": true,
"languages": [
{
"languageId": "javascript",
"scopes": ["source.js"],
"syntaxes": [
"Packages/Babel/JavaScript (Babel).sublime-syntax",
"Packages/JavaScript/JavaScript.sublime-syntax"
]
},
{
"languageId": "javascriptreact",
"scopes": ["source.jsx"],
"syntaxes": [
"Packages/Babel/JavaScript (Babel).sublime-syntax",
"Packages/JavaScript/JavaScript.sublime-syntax"
]
},
{
"languageId": "typescript",
"scopes": ["source.ts"],
"syntaxes": [
"Packages/TypeScript-TmLanguage/TypeScript.tmLanguage",
"Packages/TypeScript Syntax/TypeScript.tmLanguage"
]
},
{
"languageId": "typescriptreact",
"scopes": ["source.tsx"],
"syntaxes": [
"Packages/TypeScript-TmLanguage/TypeScriptReact.tmLanguage",
"Packages/TypeScript Syntax/TypeScriptReact.tmLanguage"
]
}
]
}
}
}
}
```
If you don't see your favorite IDE on this list, maybe you can develop an
extension. Our [community Discord group](https://discord.gg/deno) can give you
some pointers on where to get started.

View file

@ -1,4 +0,0 @@
## Using TypeScript
> This section has been moved to
> [Using TypeScript Chapter](../typescript.md).

View file

@ -1,43 +0,0 @@
## WebAssembly support
Deno can execute [WebAssembly](https://webassembly.org/) modules with the same
interfaces that
[browsers provide](https://developer.mozilla.org/en-US/docs/WebAssembly).
<!-- deno-fmt-ignore -->
```ts
const wasmCode = new Uint8Array([
0, 97, 115, 109, 1, 0, 0, 0, 1, 133, 128, 128, 128, 0, 1, 96, 0, 1, 127,
3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0,
5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145,
128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97,
105, 110, 0, 0, 10, 138, 128, 128, 128, 0, 1, 132, 128, 128, 128, 0, 0,
65, 42, 11
]);
const wasmModule = new WebAssembly.Module(wasmCode);
const wasmInstance = new WebAssembly.Instance(wasmModule);
const main = wasmInstance.exports.main as CallableFunction
console.log(main().toString());
```
For files:
```ts
const wasmCode = await Deno.readFile("main.wasm");
const wasmModule = new WebAssembly.Module(wasmCode);
const wasmInstance = new WebAssembly.Instance(wasmModule);
const main = wasmInstance.exports.main as CallableFunction;
console.log(main().toString());
```
And for loading WebAssembly modules over the network (note that the file must be
served with `application/wasm` MIME type):
```ts
const { instance, module } = await WebAssembly.instantiateStreaming(
fetch("https://wpt.live/wasm/incrementer.wasm"),
);
const increment = instance.exports.increment as (input: number) => number;
console.log(increment(41));
```

View file

@ -1,18 +0,0 @@
# Where To Get Help
Stuck? Lost? Get Help from the Community.
### [Stack Overflow](https://stackoverflow.com/questions/tagged/deno)
Stack Overflow is a popular forum to ask code-level questions or if youre stuck
with a specific error.
[ask your own!](https://stackoverflow.com/questions/ask?tags=deno)
### [Community Discord](https://discord.gg/deno)
Ask questions and chat with community members in real-time.
### [DEV's Deno Community](https://dev.to/t/deno)
A great place to find interesting articles about best practices, application
architecture and new learnings. Post your articles with the tag `deno`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View file

@ -1,73 +0,0 @@
# Introduction
Deno is a JavaScript/TypeScript runtime with secure defaults and a great
developer experience.
It's built on V8, Rust, and Tokio.
## Feature highlights
- Secure by default. No file, network, or environment access (unless explicitly
enabled).
- Supports TypeScript out of the box.
- Ships a single executable (`deno`).
- Has built-in utilities like a dependency inspector (`deno info`) and a code
formatter (`deno fmt`).
- Has
[a set of reviewed (audited) standard
modules](https://github.com/denoland/deno_std) that are guaranteed to work
with Deno.
- Can bundle scripts into a single JavaScript file.
## Philosophy
Deno aims to be a productive and secure scripting environment for the modern
programmer.
Deno will always be distributed as a single executable. Given a URL to a Deno
program, it is runnable with nothing more than
[the ~25 megabyte zipped executable](https://github.com/denoland/deno/releases).
Deno explicitly takes on the role of both runtime and package manager. It uses a
standard browser-compatible protocol for loading modules: URLs.
Among other things, Deno is a great replacement for utility scripts that may
have been historically written with Bash or Python.
## Goals
- Ship as just a single executable (`deno`).
- Provide secure defaults.
- Unless specifically allowed, scripts can't access files, the environment, or
the network.
- Be browser-compatible.
- The subset of Deno programs which are written completely in JavaScript and
do not use the global `Deno` namespace (or feature test for it), ought to
also be able to be run in a modern web browser without change.
- Provide built-in tooling to improve developer experience.
- E.g. unit testing, code formatting, and linting.
- Keep V8 concepts out of user land.
- Serve HTTP efficiently.
## Comparison to Node.js
- Deno does not use `npm`.
- It uses modules referenced as URLs or file paths.
- Deno does not use `package.json` in its module resolution algorithm.
- All async actions in Deno return a promise. Thus Deno provides different APIs
than Node.
- Deno requires explicit permissions for file, network, and environment access.
- Deno always dies on uncaught errors.
- Deno uses "ES Modules" and does not support `require()`. Third party modules
are imported via URLs:
```javascript
import * as log from "https://deno.land/std@$STD_VERSION/log/mod.ts";
```
## Other key behaviors
- Fetch and cache remote code upon first execution, and never update it until
the code is run with the `--reload` flag. (So, this will still work on an
airplane.)
- Modules/files loaded from remote URLs are intended to be immutable and
cacheable.

View file

@ -1,110 +0,0 @@
# Linking to third party code
In the [Getting Started](./getting_started.md) section, we saw Deno could
execute scripts from URLs. Like browser JavaScript, Deno can import libraries
directly from URLs. This example uses a URL to import an assertion library:
**test.ts**
```ts
import { assertEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
assertEquals("hello", "hello");
assertEquals("world", "world");
console.log("Asserted! ✓");
```
Try running this:
```shell
$ deno run test.ts
Compile file:///mnt/f9/Projects/github.com/denoland/deno/docs/test.ts
Download https://deno.land/std@$STD_VERSION/testing/asserts.ts
Download https://deno.land/std@$STD_VERSION/fmt/colors.ts
Download https://deno.land/std@$STD_VERSION/testing/diff.ts
Asserted! ✓
```
Note that we did not have to provide the `--allow-net` flag for this program,
and yet it accessed the network. The runtime has special access to download
imports and cache them to disk.
Deno caches remote imports in a special directory specified by the `DENO_DIR`
environment variable. It defaults to the system's cache directory if `DENO_DIR`
is not specified. The next time you run the program, no downloads will be made.
If the program hasn't changed, it won't be recompiled either. The default
directory is:
- On Linux/Redox: `$XDG_CACHE_HOME/deno` or `$HOME/.cache/deno`
- On Windows: `%LOCALAPPDATA%/deno` (`%LOCALAPPDATA%` = `FOLDERID_LocalAppData`)
- On macOS: `$HOME/Library/Caches/deno`
- If something fails, it falls back to `$HOME/.deno`
## FAQ
### How do I import a specific version of a module?
Specify the version in the URL. For example, this URL fully specifies the code
being run: `https://unpkg.com/liltest@0.0.5/dist/liltest.js`.
### It seems unwieldy to import URLs everywhere.
> What if one of the URLs links to a subtly different version of a library?
> Isn't it error prone to maintain URLs everywhere in a large project?
The solution is to import and re-export your external libraries in a central
`deps.ts` file (which serves the same purpose as Node's `package.json` file).
For example, let's say you were using the above assertion library across a large
project. Rather than importing
`"https://deno.land/std@$STD_VERSION/testing/asserts.ts"` everywhere, you could
create a `deps.ts` file that exports the third-party code:
**deps.ts**
```ts
export {
assert,
assertEquals,
assertStrContains,
} from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
```
And throughout the same project, you can import from the `deps.ts` and avoid
having many references to the same URL:
```ts
import { assertEquals, runTests, test } from "./deps.ts";
```
This design circumvents a plethora of complexity spawned by package management
software, centralized code repositories, and superfluous file formats.
### How can I trust a URL that may change?
By using a lock file (with the `--lock` command line flag), you can ensure that
the code pulled from a URL is the same as it was during initial development. You
can learn more about this
[here](./linking_to_external_code/integrity_checking.md).
### But what if the host of the URL goes down? The source won't be available.
This, like the above, is a problem faced by _any_ remote dependency system.
Relying on external servers is convenient for development but brittle in
production. Production software should always vendor its dependencies. In Node
this is done by checking `node_modules` into source control. In Deno this is
done by pointing `$DENO_DIR` to some project-local directory at runtime, and
similarly checking that into source control:
```shell
# Download the dependencies.
DENO_DIR=./deno_dir deno cache src/deps.ts
# Make sure the variable is set for any command which invokes the cache.
DENO_DIR=./deno_dir deno test src
# Check the directory into source control.
git add -u deno_dir
git commit
```

View file

@ -1,53 +0,0 @@
## Import maps
Deno supports [import maps](https://github.com/WICG/import-maps).
You can use import maps with the `--import-map=<FILE>` CLI flag.
Example:
**import_map.json**
```js
{
"imports": {
"fmt/": "https://deno.land/std@$STD_VERSION/fmt/"
}
}
```
**color.ts**
```ts
import { red } from "fmt/colors.ts";
console.log(red("hello world"));
```
Then:
```shell
$ deno run --import-map=import_map.json color.ts
```
To use your project root for absolute imports:
**import_map.json**
```jsonc
{
"imports": {
"/": "./",
"./": "./"
}
}
```
**main.ts**
```ts
import { MyUtil } from "/util.ts";
```
This causes import specifiers starting with `/` to be resolved relative to the
import map's URL or file path.

View file

@ -1,85 +0,0 @@
## Integrity checking & lock files
### Introduction
Let's say your module depends on remote module `https://some.url/a.ts`. When you
compile your module for the first time `a.ts` is retrieved, compiled and cached.
It will remain this way until you run your module on a new machine (say in
production) or reload the cache (through `deno cache --reload` for example). But
what happens if the content in the remote url `https://some.url/a.ts` is
changed? This could lead to your production module running with different
dependency code than your local module. Deno's solution to avoid this is to use
integrity checking and lock files.
### Caching and lock files
Deno can store and check subresource integrity for modules using a small JSON
file. Use the `--lock=lock.json` to enable and specify lock file checking. To
update or create a lock use `--lock=lock.json --lock-write`. The
`--lock=lock.json` tells Deno what the lock file to use is, while the
`--lock-write` is used to output dependency hashes to the lock file
(`--lock-write` must be used in conjunction with `--lock`).
A `lock.json` might look like this, storing a hash of the file against the
dependency:
```json
{
"https://deno.land/std@$STD_VERSION/textproto/mod.ts": "3118d7a42c03c242c5a49c2ad91c8396110e14acca1324e7aaefd31a999b71a4",
"https://deno.land/std@$STD_VERSION/io/util.ts": "ae133d310a0fdcf298cea7bc09a599c49acb616d34e148e263bcb02976f80dee",
"https://deno.land/std@$STD_VERSION/async/delay.ts": "35957d585a6e3dd87706858fb1d6b551cb278271b03f52c5a2cb70e65e00c26a",
...
}
```
A typical workflow will look like this:
**src/deps.ts**
```ts
// Add a new dependency to "src/deps.ts", used somewhere else.
export { xyz } from "https://unpkg.com/xyz-lib@v0.9.0/lib.ts";
```
Then:
```shell
# Create/update the lock file "lock.json".
deno cache --lock=lock.json --lock-write src/deps.ts
# Include it when committing to source control.
git add -u lock.json
git commit -m "feat: Add support for xyz using xyz-lib"
git push
```
Collaborator on another machine -- in a freshly cloned project tree:
```shell
# Download the project's dependencies into the machine's cache, integrity
# checking each resource.
deno cache --reload --lock=lock.json src/deps.ts
# Done! You can proceed safely.
deno test --allow-read src
```
### Runtime verification
Like caching above, you can also use the `--lock=lock.json` option during use of
the `deno run` sub command, validating the integrity of any locked modules
during the run. Remember that this only validates against dependencies
previously added to the `lock.json` file. New dependencies will be cached but
not validated.
You can take this a step further as well by using the `--cached-only` flag to
require that remote dependencies are already cached.
```shell
deno run --lock=lock.json --cached-only mod.ts
```
This will fail if there are any dependencies in the dependency tree for mod.ts
which are not yet cached.
<!-- TODO - Add detail on dynamic imports -->

View file

@ -1,75 +0,0 @@
## Private modules and repositories
There maybe instances where you want to load a remote module that is located in
a _private_ repository, like a private repository on GitHub.
Deno supports sending bearer tokens when requesting a remote module. Bearer
tokens are the predominant type of access token used with OAuth 2.0 and is
broadly supported by hosting services (e.g. GitHub, Gitlab, BitBucket,
Cloudsmith, etc.).
### DENO_AUTH_TOKENS
The Deno CLI will look for an environment variable named `DENO_AUTH_TOKENS` to
determine what authentication tokens it should consider using when requesting
remote modules. The value of the environment variable is in the format of a _n_
number of tokens deliminated by a semi-colon (`;`) where each token is in the
format of `{token}@{hostname[:port]}`.
For example a single token for would look something like this:
```sh
DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land
```
And multiple tokens would look like this:
```sh
DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land;f1e2d3c4b5a6@example.com:8080
```
When Deno goes to fetch a remote module, where the hostname matches the hostname
of the remote module, Deno will set the `Authorization` header of the request to
the value of `Bearer {token}`. This allows the remote server to recognize that
the request is an authorized request tied to a specific authenticated user, and
provide access to the appropriate resources and modules on the server.
### GitHub
To be able to access private repositories on GitHub, you would need to issue
yourself a _personal access token_. You do this by logging into GitHub and going
under _Settings -> Developer settings -> Personal access tokens_:
![Personal access tokens settings on GitHub](../images/private-pat.png)
You would then choose to _Generate new token_ and give your token a description
and appropriate access:
![Creating a new personal access token on GitHub](../images/private-github-new-token.png)
And once created GitHub will display the new token a single time, the value of
which you would want to use in the environment variable:
![Display of newly created token on GitHub](../images/private-github-token-display.png)
In order to access modules that are contained in a private repository on GitHub,
you would want to use the generated token in the `DENO_AUTH_TOKENS` environment
variable scoped to the `raw.githubusercontent.com` hostname. For example:
```sh
DENO_AUTH_TOKENS=a1b2c3d4e5f6@raw.githubusercontent.com
```
This should allow Deno to access any modules that the user who the token was
issued for has access to.
When the token is incorrect, or the user does not have access to the module,
GitHub will issue a `404 Not Found` status, instead of an unauthorized status.
So if you are getting errors that the modules you are trying to access are not
found on the command line, check the environment variable settings and the
personal access token settings.
In addition, `deno run -L debug` should print out a debug message about the
number of tokens that are parsed out of the environment variable. It will print
an error message if it feels any of the tokens are malformed. It won't print any
details about the tokens for security purposes.

View file

@ -1,9 +0,0 @@
## Proxies
Deno supports proxies for module downloads and the Web standard `fetch` API.
Proxy configuration is read from environmental variables: `HTTP_PROXY`,
`HTTPS_PROXY` and `NO_PROXY`.
In case of Windows, if environment variables are not found Deno falls back to
reading proxies from registry.

View file

@ -1,33 +0,0 @@
## Reloading modules
By default, a module in the cache will be reused without fetching or
re-compiling it. Sometimes this is not desirable and you can force deno to
refetch and recompile modules into the cache. You can invalidate your local
`DENO_DIR` cache using the `--reload` flag of the `deno cache` subcommand. It's
usage is described below:
### To reload everything
```bash
deno cache --reload my_module.ts
```
### To reload specific modules
Sometimes we want to upgrade only some modules. You can control it by passing an
argument to a `--reload` flag.
To reload all \$STD_VERSION standard modules:
```bash
deno cache --reload=https://deno.land/std@$STD_VERSION my_module.ts
```
To reload specific modules (in this example - colors and file system copy) use a
comma to separate URLs.
```bash
deno cache --reload=https://deno.land/std@$STD_VERSION/fs/copy.ts,https://deno.land/std@$STD_VERSION/fmt/colors.ts my_module.ts
```
<!-- Should this be part of examples? -->

View file

@ -1,59 +0,0 @@
# Using npm/Node.js code
While Deno is pretty powerful itself, there is a large eco-system of code in the
[npm](https://npmjs.com/) registry, and many people will want to re-leverage
tools, code and libraries that are built for [Node.js](https://nodejs.org/). In
this chapter we will explore how to use it.
The good news, is that in many cases, it _just works_.
There are some foundational things to understand about differences between
Node.js and Deno that can help in understanding what challenges might be faced:
- Current Node.js supports both CommonJS and ES Modules, while Deno only
supports ES Modules. The addition of stabilized ES Modules in Node.js is
relatively recent and most code written for Node.js is in the CommonJS format.
- Node.js has quite a few built-in modules that can be imported and they are a
fairly expansive set of APIs. On the other hand, Deno focuses on implementing
web standards and where functionality goes beyond the browser, we locate APIs
in a single global `Deno` variable/namespace. Lots of code written for Node.js
expects/depends upon these built-in APIs to be available.
- Node.js has a non-standards based module resolution algorithm, where you can
import bare-specifiers (e.g. `react` or `lodash`) and Node.js will look in
your local and global `node_modules` for a path, introspect the `package.json`
and try to see if there is a module named the right way. Deno resolves modules
the same way a browser does. For local files, Deno expects a full module name,
including the extension. When dealing with remote imports, Deno expects the
web server to do any "resolving" and provide back the media type of the code
(see the
[Determining the type of file](../typescript/overview.md#determining-the-type-of-file)
for more information).
- Node.js effectively doesn't work without a `package.json` file. Deno doesn't
require an external meta-data file to function or resolve modules.
- Node.js doesn't support remote HTTP imports. It expects all 3rd party code to
be installed locally on your machine using a package manager like `npm` into
the local or global `node_modules` folder. Deno supports remote HTTP imports
(as well as `data` and `blob` URLs) and will go ahead and fetch the remote
code and cache it locally, similar to the way a browser works.
In order to help mitigate these differences, we will further explore in this
chapter:
- Using the [`std/node`](./npm_nodejs/std_node.md) modules of the Deno standard
library to "polyfill" the built-in modules of Node.js
- Using [CDNs](./npm_nodejs/cdns.md) to access the vast majority of npm packages
in ways that work under Deno.
- How [import maps](./npm_nodejs/import_maps.md) can be used to provide "bare
specifier" imports like Node.js under Deno, without needing to use a package
manager to install packages locally.
- And finally, a general section of
[frequently asked questions](./npm_nodejs/faqs.md)
That being said, there are some differences that cannot be overcome:
- Node.js has a plugin system that is incompatible with Deno, and Deno will
never support Node.js plugins. If the Node.js code you want to use requires a
"native" Node.js plugin, it won't work under Deno.
- Node.js has some built in modules (e.g. like `vm`) that are effectively
incompatible with the scope of Deno and therefore there aren't easy ways to
provide a _polyfill_ of the functionality in Deno.

View file

@ -1,186 +0,0 @@
## Packages from CDNs
Because Deno supports remote HTTP modules, and content delivery networks (CDNs)
can be powerful tools to transform code, the combination allows an easy way to
access code in the npm registry via Deno, usually in a way that works with Deno
without any further actions, and often enriched with TypeScript types. In this
section we will explore that in detail.
### What about `deno.land/x/`?
The [`deno.land/x/`](https://deno.land/x/) is a public registry for code,
hopefully code written specifically for Deno. It is a public registry though and
all it does is "redirect" Deno to the location where the code exists. It doesn't
transform the code in any way. There is a lot of great code on the registry, but
at the same time, there is some code that just isn't well maintained (or doesn't
work at all). If you are familiar with the npm registry, you know that as well,
there are varying degrees of quality.
Because it simply serves up the original published source code, it doesn't
really help when trying to use code that didn't specifically consider Deno when
authored.
### Deno "friendly" CDNs
Deno friendly content delivery networks (CDNs) not only host packages from npm,
they provide them in a way that maximizes their integration to Deno. They
directly address some of the challenges in consuming code written for Node.js:
- The provide packages and modules in the ES Module format, irrespective of how
they are published on npm.
- They resolve all the dependencies as the modules are served, meaning that all
the Node.js specific module resolution logic is handled by the CDN.
- Often, they inform Deno of type definitions for a package, meaning that Deno
can use them to type check your code and provide a better development
experience.
- The CDNs also "polyfill" the built-in Node.js modules, making a lot of code
that leverages the built-in Node.js modules _just work_.
- The CDNs deal with all the semver matching for packages that a package manager
like `npm` would be required for a Node.js application, meaning you as a
developer can express your 3rd party dependency versioning as part of the URL
you use to import the package.
#### esm.sh
[esm.sh](https://esm.sh/) is a CDN that was specifically designed for Deno,
though addressing the concerns for Deno also makes it a general purpose CDN for
accessing npm packages as ES Module bundles. esm.sh uses
[esbuild](https://esbuild.github.io/) to take an arbitrary npm package and
ensure that it is consumable as an ES Module. In many cases you can just import
the npm package into your Deno application:
```ts
import React from "https://esm.sh/react";
export default class A extends React.Component {
render() {
return (
<div></div>
);
}
}
```
esm.sh supports the use of both specific versions of packages, as well as
[semver](https://semver.npmjs.com/) versions of packages, so you can express
your dependency in a similar way you would in a `package.json` file when you
import it. For example, to get a specific version of a package:
```ts
import React from "https://esm.sh/react@17.0.2";
```
Or to get the latest patch release of a minor release:
```ts
import React from "https://esm.sh/react@~16.13.0";
```
esm.sh uses the `std/node` polyfills to replace the built-in modules in Node.js,
meaning that code that uses those built-in modules will have the same
limitations and caveats as those modules in `std/node`.
esm.sh also automatically sets a header which Deno recognizes that allows Deno
to be able to retrieve type definitions for the package/module. See
[Using `X-TypeScript-Types` header](../typescript/types.md#using-x-typescript-types-header)
in this manual for more details on how this works.
The CDN is also a good choice for people who develop in mainland China, as the
hosting of the CDN is specifically designed to work with "the great firewall of
China", as well as esm.sh provides information on self hosting the CDN as well.
Check out the [esm.sh homepage](https://esm.sh/) for more detailed information
on how the CDN can be used and what features it has.
#### Skypack
[Skypack.dev](https://www.skypack.dev/) is designed to make development overall
easier by not requiring packages to be installed locally, even for Node.js
development, and to make it easy to create web and Deno applications that
leverage code from the npm registry.
Skypack has a great way of discovering packages in the npm registry, by
providing a lot of contextual information about the package, as well as a
"scoring" system to try to help determine if the package follows best-practices.
Skypack detects Deno's user agent when requests for modules are received and
ensures the code served up is tailored to meet the needs of Deno. The easiest
way to load a package is to use the
[lookup URL](https://docs.skypack.dev/skypack-cdn/api-reference/lookup-urls) for
the package:
```ts
import React from "https://cdn.skypack.dev/react";
export default class A extends React.Component {
render() {
return (
<div></div>
);
}
}
```
Lookup URLs can also contain the [semver](https://semver.npmjs.com/) version in
the URL:
```ts
import React from "https://cdn.skypack.dev/react@~16.13.0";
```
By default, Skypack does not set the types header on packages. In order to have
the types header set, which is automatically recognized by Deno, you have to
append `?dts` to the URL for that package:
```ts
import { pathToRegexp } from "https://cdn.skypack.dev/path-to-regexp?dts";
const re = pathToRegexp("/path/:id");
```
See
[Using `X-TypeScript-Types` header](../typescript/types.md#using-x-typescript-types-header)
in this manual for more details on how this works.
Skypack docs have a
[specific page on usage with Deno](https://docs.skypack.dev/skypack-cdn/code/deno)
for more information.
### Other CDNs
There are a couple of other CDNs worth mentioning.
#### UNPKG
[UNPKG](https://unpkg.com/) is the most well known CDN for npm packages. For
packages that include an ES Module distribution for things like the browsers,
many of them can be used directly off of UNPKG. That being said, everything
available on UNPKG is available on more Deno friendly CDNs.
#### JSPM
The [jspm.io](https://jspm.io) CDN is specifically designed to provide npm and
other registry packages as ES Modules in a way that works well with import maps.
While it doesn't currently cater to Deno, the fact that Deno can utilize import
maps, allows you to use the [JSPM.io generator](https://generator.jspm.io/) to
generate an import-map of all the packages you want to use and have them served
up from the CDN.
### Considerations
While CDNs can make it easy to allow Deno to consume packages and modules from
the npm registry, there can still be some things to consider:
- Deno does not (and will not) support Node.js plugins. If the package requires
a native plugin, it won't work under Deno.
- Dependency management can always be a bit of a challenge and a CDN can make it
a bit more obfuscated what dependencies are there. You can always use
`deno info` with the module or URL to get a full breakdown of how Deno
resolves all the code.
- While the Deno friendly CDNs try their best to serve up types with the code
for consumption with Deno, lots of types for packages conflict with other
packages and/or don't consider Deno, which means you can often get strange
diagnostic message when type checking code imported from these CDNs, though
skipping type checking will result in the code working perfectly fine. This is
a fairly complex topic and is covered in the
[Types and type declarations](../typescript/types.md) section of the manual.

View file

@ -1,55 +0,0 @@
## Frequently asked questions
### Getting errors when type checking like `cannot find namespace NodeJS`
One of the modules you are using has type definitions that depend upon the
NodeJS global namespace, but those types don't include the NodeJS global
namespace in their types.
The quickest fix is to skip type checking. You can do this by using the
`--no-check` flag.
Skipping type checking might not be acceptable though. You could try to load the
Node.js types yourself. For example from UNPKG it would look something like
this:
```ts
import type {} from "https://unpkg.com/@types/node/index.d.ts";
```
Or from esm.sh:
```ts
import type {} from "https://esm.sh/@types/node/index.d.ts";
```
Or from Skypack:
```ts
import type {} from "https://cdn.skypack.dev/@types/node/index.d.ts";
```
You could also try to provide only specifically what the 3rd party package is
missing. For example the package `@aws-sdk/client-dynamodb` has a dependency on
the `NodeJS.ProcessEnv` type in its type definitions. In one of the modules of
your project that imports it as a dependency, you could put something like this
in there which will solve the problem:
```ts
declare global {
namespace NodeJS {
type ProcessEnv = Record<string, string>;
}
}
```
### Getting type errors like cannot find `document` or `HTMLElement`
The library you are using has dependencies on the DOM. This is common for
packages that are designed to run in a browser as well as server-side. By
default, Deno only includes the libraries that are directly supported. Assuming
the package properly identifies what environment it is running in at runtime it
is "safe" to use the DOM libraries to type check the code. For more information
on this, check out the
[Targeting Deno and the Browser](../typescript/configuration.md#targeting-deno-and-the-browser)
section of the manual.

View file

@ -1,112 +0,0 @@
## Using import maps
Deno supports [import maps](../linking_to_external_code/import_maps.md) which
allow you to supply Deno with information about how to resolve modules that
overrides the default behavior. Import maps are a web platform standard that is
increasingly being included natively in browsers. They are specifically useful
with adapting Node.js code to work well with Deno, as you can use import maps to
map "bare" specifiers to a specific module.
When coupled with Deno friendly [CDNs](./cdns.md) import maps can be a powerful
tool in managing code and dependencies without need of a package management
tool.
### Bare and extension-less specifiers
Deno will only load a fully qualified module, including the extension. The
import specifier needs to either be relative or absolute. Specifiers that are
neither relative or absolute are often called "bare" specifiers. For example
`"./lodash/index.js"` is a relative specifier and
`https://cdn.skypack.dev/lodash` is an absolute specifier. Where is `"lodash"`
would be a bare specifier.
Also Deno requires that for local modules, the module to load is fully
resolve-able. When an extension is not present, Deno would have to "guess" what
the author intended to be loaded. For example does `"./lodash"` mean
`./lodash.js`, `./lodash.ts`, `./lodash.tsx`, `./lodash.jsx`,
`./lodash/index.js`, `./lodash/index.ts`, `./lodash/index.jsx`, or
`./lodash/index.tsx`?
When dealing with remote modules, Deno allows the CDN/web server define whatever
semantics around resolution the server wants to define. It just treats a URL,
including its query string, as a "unique" module that can be loaded. It expects
the CDN/web server to provide it with a valid media/content type to instruct
Deno how to handle the file. More information on how media types impact how Deno
handles modules can be found in the
[Determining the type of file](../typescript/overview.md#determining-the-type-of-file)
section of the manual.
Node.js does have defined semantics for resolving specifiers, but they are
complex, assume unfettered access to the local file system to query it. Deno has
chosen not to go down that path.
But, import maps can be used to provide some of the ease of the developer
experience if you wish to use bare specifiers. For example, if we want to do the
following in our code:
```ts
import lodash from "lodash";
```
We can accomplish this using an import map, and we don't even have to install
the `lodash` package locally. We would want to create a JSON file (for example
**import_map.json**) with the following:
```json
{
"imports": {
"lodash": "https://cdn.skypack.dev/lodash"
}
}
```
And we would run our program like:
```
> deno run --import-map ./import_map.json example.ts
```
If you wanted to manage the versions in the import map, you could do this as
well. For example if you were using Skypack CDN, you can used a
[pinned URL](https://docs.skypack.dev/skypack-cdn/api-reference/pinned-urls-optimized)
for the dependency in your import map. For example, to pin to lodash version
4.17.21 (and minified production ready version), you would do this:
```json
{
"imports": {
"lodash": "https://cdn.skypack.dev/pin/lodash@v4.17.21-K6GEbP02mWFnLA45zAmi/mode=imports,min/optimized/lodash.js"
}
}
```
### Overriding imports
The other situation where import maps can be very useful is the situation where
you have tried your best to make something work, but have failed. For example
you are using an npm package which has a dependency on some code that just
doesn't work under Deno, and you want to substitute another module that
"polyfills" the incompatible APIs.
For example, let's say we have a package that is using a version of the built in
`"fs"` module that we have a local module we want to replace it with when it
tries to import it, but we want other code we are loading to use the standard
library replacement module for `"fs"`. We would want to create an import map
that looked something like this:
```ts
{
"imports": {
"fs": "https://deno.land/std@$STD_VERSION/node/fs.ts"
},
"scopes": {
"https://deno.land/x/example": {
"fs": "./patched/fs.ts"
}
}
}
```
Import maps can be very powerful, check out the official
[standards README](https://github.com/WICG/import-maps#the-import-map) for more
information.

View file

@ -1,100 +0,0 @@
## The `std/node` library
The `std/node` part of the Deno standard library is a Node.js compatibility
layer. It's primary focus is providing "polyfills" for Node.js's
[built-in modules](https://github.com/denoland/deno_std/tree/main/node#supported-builtins).
It also provides a mechanism for loading CommonJS modules into Deno.
The library is most useful when trying to use your own or private code that was
written for Node.js. If you are trying to consume public npm packages, you are
likely to get a better result using a [CDN](./cdns.md).
### Node.js built-in modules
The standard library provides several "replacement" modules for Node.js built-in
modules. These either replicate the functionality of the built-in or they call
the Deno native APIs, returning an interface that is compatible with Node.js.
The standard library provides modules for the the following built-ins:
- [`assert`](https://doc.deno.land/https/deno.land/std/node/assert.ts)
(_partly_)
- [`buffer`](https://doc.deno.land/https/deno.land/std/node/buffer.ts)
- [`child_process`](https://doc.deno.land/https/deno.land/std/node/child_process.ts)
(_partly_)
- [`console`](https://doc.deno.land/https/deno.land/std/node/console.ts)
(_partly_)
- [`constants`](https://doc.deno.land/https/deno.land/std/node/constants.ts)
(_partly_)
- [`crypto`](https://doc.deno.land/https/deno.land/std/node/crypto.ts)
(_partly_)
- [`events`](https://doc.deno.land/https/deno.land/std/node/events.ts)
- [`fs`](https://doc.deno.land/https/deno.land/std/node/fs.ts) (_partly_)
- [`module`](https://doc.deno.land/https/deno.land/std/node/module.ts)
- [`os`](https://doc.deno.land/https/deno.land/std/node/os.ts) (_partly_)
- [`path`](https://doc.deno.land/https/deno.land/std/node/path.ts)
- [`process`](https://doc.deno.land/https/deno.land/std/node/process.ts)
(_partly_)
- [`querystring`](https://doc.deno.land/https/deno.land/std/node/querystring.ts)
- [`stream`](https://doc.deno.land/https/deno.land/std/node/stream.ts)
- [`string_decoder`](https://doc.deno.land/https/deno.land/std/node/string_decoder.ts)
- [`timers`](https://doc.deno.land/https/deno.land/std/node/timers.ts)
- [`tty`](https://doc.deno.land/https/deno.land/std/node/tty.ts) (_partly_)
- [`url`](https://doc.deno.land/https/deno.land/std/node/url.ts)
- [`util`](https://doc.deno.land/https/deno.land/std/node/util.ts) (_partly_)
In addition, there is the
[`std/node/global.ts`](https://doc.deno.land/https/deno.land/std/node/global.ts)
module which provides some of the Node.js globals like `global`, `process`, and
`Buffer`.
If you want documentation for any of the modules, you can simply type `deno doc`
and the URL of the module in your terminal:
```
> deno doc https://deno.land/std/assert.ts
```
### Loading CommonJS modules
Deno only supports natively loading ES Modules, but a lot of Node.js code is
still written in the CommonJS format. As mentioned above, for public npm
packages, it is often better to use a CDN to transpile CommonJS modules to ES
Modules for consumption by Deno. Not only do you get reliable conversion plus
all the dependency resolution and management without requiring a package manager
to install the packages on your local machine, you get the advantages of being
able to share your code easier without requiring other users to setup some of
the Node.js infrastructure to consume your code with Node.js.
That being said, the built-in Node.js module `"module"` provides a function
named `createRequire()` which allows you to create a Node.js compatible
`require()` function which can be used to load CommonJS modules, as well as use
the same resolution logic that Node.js uses when trying to load a module.
`createRequire()` will also install the Node.js globals for you.
Example usage would look like this:
```ts
import { createRequire } from "https://deno.land/std@$STD_VERSION/node/module.ts";
// import.meta.url will be the location of "this" module (like `__filename` in
// Node.js), and then serve as the root for your "package", where the
// `package.json` is expected to be, and where the `node_modules` will be used
// for resolution of packages.
const require = createRequire(import.meta.url);
// Loads the built-in module Deno "replacement":
const path = require("path");
// Loads a CommonJS module (without specifying the extension):
const cjsModule = require("./my_mod");
// Uses Node.js resolution in `node_modules` to load the package/module. The
// package would need to be installed locally via a package management tool
// like npm:
const leftPad = require("left-pad");
```
When modules are loaded via the created `require()`, they are executed in a
context which is similar to a Node.js context, which means that a lot of code
written targeting Node.js will work.

View file

@ -1,25 +0,0 @@
# Runtime
Documentation for all runtime functions (Web APIs + `Deno` global) can be found
on [`doc.deno.land`](https://doc.deno.land/builtin/stable).
## Web Platform APIs
For APIs where a web standard already exists, like `fetch` for HTTP requests,
Deno uses these rather than inventing a new proprietary API.
For more details, view the chapter on
[Web Platform APIs](./runtime/web_platform_apis.md).
## `Deno` global
All APIs that are not web standard are contained in the global `Deno` namespace.
It has the APIs for reading from files, opening TCP sockets, serving HTTP, and
executing subprocesses, etc.
The TypeScript definitions for the Deno namespaces can be found in the
[`lib.deno.ns.d.ts`](https://github.com/denoland/deno/blob/$CLI_VERSION/cli/dts/lib.deno.ns.d.ts)
file.
The documentation for all of the Deno specific APIs can be found on
[doc.deno.land](https://doc.deno.land/https/raw.githubusercontent.com/denoland/deno/main/cli/dts/lib.deno.ns.d.ts).

View file

@ -1,4 +0,0 @@
## Compiler APIs
> This section has been moved to
> [TypeScript Runtime APIs](../typescript/runtime.md).

View file

@ -1,258 +0,0 @@
## HTTP Server APIs
As of Deno 1.9 and later, _native_ HTTP server APIs were introduced which allow
users to create robust and performant web servers in Deno.
The API tries to leverage as much of the web standards as is possible as well as
tries to be simple and straight forward.
> The APIs are currently unstable, meaning they can change in the future in
> breaking ways and should be carefully considered before using in production
> code. They require the `--unstable` flag to make them available.
### Listening for a connection
In order to accept requests, first you need to listen for a connection on a
network port. To do this in Deno, you use `Deno.listen()`:
```ts
const server = Deno.listen({ port: 8080 });
```
> When supplying a port, Deno assumes you are going to listen on a TCP socket
> as well as bind to the localhost. You can specify `transport: "tcp"` to be
> more explicit as well as provide an IP address or hostname in the `hostname`
> property as well.
If there is an issue with opening the network port, `Deno.listen()` will throw,
so often in a server sense, you will want to wrap it in the `try ... catch`
block in order to handle exceptions, like the port already being in use.
You can also listen for a TLS connection (e.g. HTTPS) using `Deno.listenTls()`:
```ts
const server = Deno.listenTls({
port: 8443,
certFile: "localhost.crt",
keyFile: "localhost.key",
alpnProtocols: ["h2", "http/1.1"],
});
```
The `certFile` and `keyFile` options are required and point to the appropriate
certificate and key files for the server. They are relative to the CWD for Deno.
The `alpnProtocols` property is optional, but if you want to be able to support
HTTP/2 on the server, you add the protocols here, as the protocol negotiation
happens during the TLS negotiation with the client and server.
> Generating SSL certificates is outside of the scope of this documentation.
> There are many resources on the web which address this.
### Handling connections
Once we are listening for a connection, we need to handle the connection. The
return value of `Deno.listen()` or `Deno.listenTls()` is a `Deno.Listener` which
is an async iterable which yields up `Deno.Conn` connections as well as provide
a couple methods for handling connections.
To use it as an async iterable we would do something like this:
```ts
const server = Deno.listen({ port: 8080 });
for await (const conn of server) {
// ...handle the connection...
}
```
Every connection made would yielded up a `Deno.Conn` assigned to `conn`. Then
further processing can be applied to the connection.
There is also the `.accept()` method on the listener which can be used:
```ts
const server = Deno.listen({ port: 8080 });
while (true) {
try {
const conn = await server.accept();
// ... handle the connection ...
} catch (err) {
// The listener has closed
break;
}
}
```
Whether using the async iterator or the `.accept()` method, exceptions can be
thrown and robust production code should handle these using `try ... catch`
blocks. Especially when it comes to accepting TLS connections, there can be many
conditions, like invalid or unknown certificates which can be surfaced on the
listener and might need handling in the user code.
A listener also has a `.close()` method which can be used to close the listener.
### Serving HTTP
Once a connection is accepted, you can use `Deno.serveHttp()` to handle HTTP
requests and responses on the connection. `Deno.serveHttp()` returns a
`Deno.HttpConn`. A `Deno.HttpConn` is like a `Deno.Listener` in that requests
the connection receives from the client are asynchronously yielded up as a
`Deno.RequestEvent`.
To deal with HTTP requests as async iterable it would look something like this:
```ts
const server = Deno.listen({ port: 8080 });
for await (const conn of server) {
(async () => {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
// ... handle requestEvent ...
}
})();
}
```
The `Deno.HttpConn` also has the method `.nextRequest()` which can be used to
await the next request. It would look something like this:
```ts
const server = Deno.listen({ port: 8080 });
while (true) {
try {
const conn = await server.accept();
(async () => {
const httpConn = Deno.serveHttp(conn);
while (true) {
try {
const requestEvent = await httpConn.nextRequest();
// ... handle requestEvent ...
} catch (err) {
// the connection has finished
break;
}
}
})();
} catch (err) {
// The listener has closed
break;
}
}
```
Note that in both cases we are using an IIFE to create an inner function to deal
with each connection. If we awaited the HTTP requests in the same function scope
as the one we were receiving the connections, we would be blocking accepting
additional connections, which would make it seem that our server was "frozen".
In practice, it might make more sense to have a separate function all together:
```ts
async function handle(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
// ... handle requestEvent
}
}
const server = Deno.listen({ port: 8080 });
for await (const conn of server) {
handle(conn);
}
```
In the examples from this point on, we will focus on what would occur within an
example `handle()` function and remove the listening and connection
"boilerplate".
### HTTP Requests and Responses
HTTP requests and responses in Deno are essentially the inverse of web standard
[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). The
Deno HTTP Server API and the Fetch API leverage the
[`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and
[`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object
classes. So if you are familiar with the Fetch API you just need to flip them
around in your mind and now it is a server API.
As mentioned above, a `Deno.HttpConn` asynchronously yields up
`Deno.RequestEvent`s. These request events contain a `.request` property and a
`.respondWith()` method.
The `.request` property is an instance of the `Request` class with the
information about the request. For example, if we wanted to know what URL path
was being requested, we would do something like this:
```ts
async function handle(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
const url = new URL(requestEvent.request.url);
console.log(`path: ${url.path}`);
}
}
```
The `.respondWith()` method is how we complete a request. The method takes
either a `Response` object or a `Promise` which resolves with a `Response`
object. Responding with a basic "hello world" would look like this:
```ts
async function handle(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
await requestEvent.respondWith(
new Response("hello world", {
status: 200,
}),
);
}
}
```
Note that we awaited the `.respondWith()` method. It isn't required, but in
practice any errors in processing the response will cause the promise returned
from the method to be rejected, like if the client disconnected before all the
response could be sent. While there may not be anything your application needs
to do, not handling the rejection will cause an "unhandled rejection" to occur
which will terminate the Deno process, which isn't so good for a server. In
addition, you might want to await the promise returned in order to determine
when to do any cleanup from for the request/response cycle.
The web standard `Response` object is pretty powerful, allowing easy creation of
complex and rich responses to a client, and Deno strives to provide a `Response`
object that as closely matches the web standard as possible, so if you are
wondering how to send a particular response, checkout out the documentation for
the web standard
[`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
### HTTP/2 Support
HTTP/2 support is effectively transparent within the Deno runtime. Typically
HTTP/2 is negotiated between a client and a server during the TLS connection
setup via
[ALPN](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation). To
enable this, you need to provide the protocols you want to support when you
start listening via the `alpnProtocols` property. This will enable the
negotiation to occur when the connection is made. For example:
```ts
const server = Deno.listenTls({
port: 8443,
certFile: "localhost.crt",
keyFile: "localhost.key",
alpnProtocols: ["h2", "http/1.1"],
});
```
The protocols are provided in order of preference. In practice, the only two
protocols that are supported currently are HTTP/2 and HTTP/1.1 which are
expressed as `h2` and `http/1.1`.
Currently Deno does not support upgrading a plain-text HTTP/1.1 connection to an
HTTP/2 cleartext connection via the `Upgrade` header (see:
[#10275](https://github.com/denoland/deno/issues/10275)), so therefore HTTP/2
support is only available via a TLS/HTTPS connection.

View file

@ -1,76 +0,0 @@
## Location API
Deno supports the
[`location`](https://developer.mozilla.org/en-US/docs/Web/API/Window/location)
global from the web. Please read on.
### Location flag
There is no "web page" whose URL we can use for a location in a Deno process. We
instead allow users to emulate a document location by specifying one on the CLI
using the `--location` flag. It can be a `http` or `https` URL.
```ts
// deno run --location https://example.com/path main.ts
console.log(location.href);
// "https://example.com/path"
```
You must pass `--location <href>` for this to work. If you don't, any access to
the `location` global will throw an error.
```ts
// deno run main.ts
console.log(location.href);
// error: Uncaught ReferenceError: Access to "location", run again with --location <href>.
```
Setting `location` or any of its fields will normally cause navigation in
browsers. This is not applicable in Deno, so it will throw in this situation.
```ts
// deno run --location https://example.com/path main.ts
location.pathname = "./foo";
// error: Uncaught NotSupportedError: Cannot set "location.pathname".
```
### Extended usage
On the web, resource resolution (excluding modules) typically uses the value of
`location.href` as the root on which to base any relative URLs. This affects
some web APIs adopted by Deno.
#### Fetch API
```ts
// deno run --location https://api.github.com/ --allow-net main.ts
const response = await fetch("./orgs/denoland");
// Fetches "https://api.github.com/orgs/denoland".
```
The `fetch()` call above would throw if the `--location` flag was not passed,
since there is no web-analogous location to base it onto.
#### Worker modules
```ts
// deno run --location https://example.com/index.html --allow-net main.ts
const worker = new Worker("./workers/hello.ts", { type: "module" });
// Fetches worker module at "https://example.com/workers/hello.ts".
```
### Only use if necessary
For the above use cases, it is preferable to pass URLs in full rather than
relying on `--location`. You can manually base a relative URL using the `URL`
constructor if needed.
The `--location` flag is intended for those who have some specific purpose in
mind for emulating a document location and are aware that this will only work at
application-level. However, you may also use it to silence errors from a
dependency which is frivolously accessing the `location` global.

View file

@ -1,186 +0,0 @@
## Permission APIs
Permissions are granted from the CLI when running the `deno` command. User code
will often assume its own set of required permissions, but there is no guarantee
during execution that the set of _granted_ permissions will align with this.
In some cases, ensuring a fault-tolerant program requires a way to interact with
the permission system at runtime.
### Permission descriptors
On the CLI, read permission for `/foo/bar` is represented as
`--allow-read=/foo/bar`. In runtime JS, it is represented as the following:
```ts
const desc = { name: "read", path: "/foo/bar" } as const;
```
Other examples:
```ts
// Global write permission.
const desc1 = { name: "write" } as const;
// Write permission to `$PWD/foo/bar`.
const desc2 = { name: "write", path: "foo/bar" } as const;
// Global net permission.
const desc3 = { name: "net" } as const;
// Net permission to 127.0.0.1:8000.
const desc4 = { name: "net", host: "127.0.0.1:8000" } as const;
// High-resolution time permission.
const desc5 = { name: "hrtime" } as const;
```
### Query permissions
Check, by descriptor, if a permission is granted or not.
```ts
// deno run --allow-read=/foo main.ts
const desc1 = { name: "read", path: "/foo" } as const;
console.log(await Deno.permissions.query(desc1));
// PermissionStatus { state: "granted" }
const desc2 = { name: "read", path: "/foo/bar" } as const;
console.log(await Deno.permissions.query(desc2));
// PermissionStatus { state: "granted" }
const desc3 = { name: "read", path: "/bar" } as const;
console.log(await Deno.permissions.query(desc3));
// PermissionStatus { state: "prompt" }
```
### Permission states
A permission state can be either "granted", "prompt" or "denied". Permissions
which have been granted from the CLI will query to `{ state: "granted" }`. Those
which have not been granted query to `{ state: "prompt" }` by default, while
`{ state: "denied" }` reserved for those which have been explicitly refused.
This will come up in [Request permissions](#request-permissions).
### Permission strength
The intuitive understanding behind the result of the second query in
[Query permissions](#query-permissions) is that read access was granted to
`/foo` and `/foo/bar` is within `/foo` so `/foo/bar` is allowed to be read.
We can also say that `desc1` is
_[stronger than](https://www.w3.org/TR/permissions/#ref-for-permissiondescriptor-stronger-than)_
`desc2`. This means that for any set of CLI-granted permissions:
1. If `desc1` queries to `{ state: "granted" }` then so must `desc2`.
2. If `desc2` queries to `{ state: "denied" }` then so must `desc1`.
More examples:
```ts
const desc1 = { name: "write" } as const;
// is stronger than
const desc2 = { name: "write", path: "/foo" } as const;
const desc3 = { name: "net", host: "127.0.0.1" } as const;
// is stronger than
const desc4 = { name: "net", host: "127.0.0.1:8000" } as const;
```
### Request permissions
Request an ungranted permission from the user via CLI prompt.
```ts
// deno run main.ts
const desc1 = { name: "read", path: "/foo" } as const;
const status1 = await Deno.permissions.request(desc1);
// ⚠️ Deno requests read access to "/foo". Grant? [g/d (g = grant, d = deny)] g
console.log(status1);
// PermissionStatus { state: "granted" }
const desc2 = { name: "read", path: "/bar" } as const;
const status2 = await Deno.permissions.request(desc2);
// ⚠️ Deno requests read access to "/bar". Grant? [g/d (g = grant, d = deny)] d
console.log(status2);
// PermissionStatus { state: "denied" }
```
If the current permission state is "prompt", a prompt will appear on the user's
terminal asking them if they would like to grant the request. The request for
`desc1` was granted so its new status is returned and execution will continue as
if `--allow-read=/foo` was specified on the CLI. The request for `desc2` was
denied so its permission state is downgraded from "prompt" to "denied".
If the current permission state is already either "granted" or "denied", the
request will behave like a query and just return the current status. This
prevents prompts both for already granted permissions and previously denied
requests.
### Revoke permissions
Downgrade a permission from "granted" to "prompt".
```ts
// deno run --allow-read=/foo main.ts
const desc = { name: "read", path: "/foo" } as const;
console.log(await Deno.permissions.revoke(desc));
// PermissionStatus { state: "prompt" }
```
However, what happens when you try to revoke a permission which is _partial_ to
one granted on the CLI?
```ts
// deno run --allow-read=/foo main.ts
const desc = { name: "read", path: "/foo/bar" } as const;
console.log(await Deno.permissions.revoke(desc));
// PermissionStatus { state: "granted" }
```
It was not revoked.
To understand this behaviour, imagine that Deno stores an internal set of
_explicitly granted permission descriptors_. Specifying `--allow-read=/foo,/bar`
on the CLI initializes this set to:
```ts
[
{ name: "read", path: "/foo" },
{ name: "read", path: "/bar" },
];
```
Granting a runtime request for `{ name: "write", path: "/foo" }` updates the set
to:
```ts
[
{ name: "read", path: "/foo" },
{ name: "read", path: "/bar" },
{ name: "write", path: "/foo" },
];
```
Deno's permission revocation algorithm works by removing every element from this
set which the argument permission descriptor is _stronger than_. So to ensure
`desc` is not longer granted, pass an argument descriptor _stronger than_
whichever _explicitly granted permission descriptor_ is _stronger than_ `desc`.
```ts
// deno run --allow-read=/foo main.ts
const desc = { name: "read", path: "/foo/bar" } as const;
console.log(await Deno.permissions.revoke(desc)); // Insufficient.
// PermissionStatus { state: "granted" }
const strongDesc = { name: "read", path: "/foo" } as const;
await Deno.permissions.revoke(strongDesc); // Good.
console.log(await Deno.permissions.query(desc));
// PermissionStatus { state: "prompt" }
```

View file

@ -1,79 +0,0 @@
## Program lifecycle
Deno supports browser compatible lifecycle events: `load` and `unload`. You can
use these events to provide setup and cleanup code in your program.
Listeners for `load` events can be asynchronous and will be awaited. Listeners
for `unload` events need to be synchronous. Both events cannot be cancelled.
Example:
**main.ts**
```ts
import "./imported.ts";
const handler = (e: Event): void => {
console.log(`got ${e.type} event in event handler (main)`);
};
window.addEventListener("load", handler);
window.addEventListener("unload", handler);
window.onload = (e: Event): void => {
console.log(`got ${e.type} event in onload function (main)`);
};
window.onunload = (e: Event): void => {
console.log(`got ${e.type} event in onunload function (main)`);
};
console.log("log from main script");
```
**imported.ts**
```ts
const handler = (e: Event): void => {
console.log(`got ${e.type} event in event handler (imported)`);
};
window.addEventListener("load", handler);
window.addEventListener("unload", handler);
window.onload = (e: Event): void => {
console.log(`got ${e.type} event in onload function (imported)`);
};
window.onunload = (e: Event): void => {
console.log(`got ${e.type} event in onunload function (imported)`);
};
console.log("log from imported script");
```
Note that you can use both `window.addEventListener` and
`window.onload`/`window.onunload` to define handlers for events. There is a
major difference between them, let's run the example:
```shell
$ deno run main.ts
log from imported script
log from main script
got load event in event handler (imported)
got load event in event handler (main)
got load event in onload function (main)
got unload event in event handler (imported)
got unload event in event handler (main)
got unload event in onunload function (main)
```
All listeners added using `window.addEventListener` were run, but
`window.onload` and `window.onunload` defined in `main.ts` overrode handlers
defined in `imported.ts`.
In other words, you can register multiple `window.addEventListener` `"load"` or
`"unload"` events, but only the last loaded `window.onload` or `window.onunload`
event handlers will be executed. It is preferable to use `addEventListener` when
possible for this reason.

View file

@ -1,32 +0,0 @@
## Stability
As of Deno 1.0.0, the `Deno` namespace APIs are stable. That means we will
strive to make code working under 1.0.0 continue to work in future versions.
However, not all of Deno's features are ready for production yet. Features which
are not ready, because they are still in draft phase, are locked behind the
`--unstable` command line flag.
```shell
deno run --unstable mod_which_uses_unstable_stuff.ts
```
Passing this flag does a few things:
- It enables the use of unstable APIs during runtime.
- It adds the
[`lib.deno.unstable.d.ts`](https://doc.deno.land/https/raw.githubusercontent.com/denoland/deno/main/cli/dts/lib.deno.unstable.d.ts)
file to the list of TypeScript definitions that are used for type checking.
This includes the output of `deno types`.
You should be aware that many unstable APIs have **not undergone a security
review**, are likely to have **breaking API changes** in the future, and are
**not ready for production**.
### Standard modules
Deno's standard modules (https://deno.land/std/) are not yet stable. We
currently version the standard modules differently from the CLI to reflect this.
Note that unlike the `Deno` namespace, the use of the standard modules do not
require the `--unstable` flag (unless the standard module itself makes use of an
unstable Deno feature).

View file

@ -1,97 +0,0 @@
# Web Platform APIs
Deno aims to use web platform APIs (like `fetch`) instead of inventing a new
proprietary API where it makes sense. These APIs generally follow the
specifications and should match the implementation in Chrome and Firefox. In
some cases it makes sense to deviate from the spec slightly, because of the
different security model Deno has.
Here is a list of web platform APIs Deno implements:
## `fetch` API
### Overview
The `fetch` API can be used to make HTTP requests. It is implemented as
specified in the [WHATWG `fetch` spec](https://fetch.spec.whatwg.org/).
You can find documentation about this API on
[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
### Spec deviations
- The Deno user agent does not have a cookie jar. As such, the `set-cookie`
header on a response is not processed, or filtered from the visible response
headers.
- Deno does not follow the same-origin policy, because the Deno user agent
currently does not have the concept of origins, and it does not have a cookie
jar. This means Deno does not need to protect against leaking authenticated
data cross origin. Because of this Deno does not implement the following
sections of the WHATWG `fetch` specification:
- Section `3.1. 'Origin' header`.
- Section `3.2. CORS protocol`.
- Section `3.5. CORB`.
- Section `3.6. 'Cross-Origin-Resource-Policy' header`.
- `Atomic HTTP redirect handling`.
- The `opaqueredirect` response type.
- A `fetch` with a `redirect` mode of `manual` will return a `basic` response
rather than an `opaqueredirect` response.
## `CustomEvent`, `EventTarget` and `EventListener`
### Overview
The DOM Event API can be used to dispatch and listen to events happening in an
application. It is implemented as specified in the
[WHATWG DOM spec](https://dom.spec.whatwg.org/#events).
You can find documentation about this API on
[MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget).
### Spec deviations
- Events do not bubble, because Deno does not have a DOM hierarchy, so there is
no tree for Events to bubble/capture through.
## Web Worker API
### Overview
The WebWorker API can be used to executing code in a separate thread. It is
implemented as specified in the
[WHATWG HTML spec](https://html.spec.whatwg.org/multipage/workers.html#workers).
You can find documentation about this API on
[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Worker).
### Spec deviations
- Currently creating workers from blob URLs is not supported.
- Currently posted data is serialized to JSON instead of structured cloning.
- Currently object ownership cannot be transferred between workers.
## Other APIs
- [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
- [Console](https://developer.mozilla.org/en-US/docs/Web/API/Console)
- [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
- [Performance](https://developer.mozilla.org/en-US/docs/Web/API/Performance)
- [setTimeout, setInterval, clearInterval](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout)
- [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)
- [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL)
- [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
- [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
---
## Typings
The TypeScript definitions for the implemented web APIs can be found in the
[`lib.deno.shared_globals.d.ts`](https://github.com/denoland/deno/blob/$CLI_VERSION/cli/dts/lib.deno.shared_globals.d.ts)
and
[`lib.deno.window.d.ts`](https://github.com/denoland/deno/blob/$CLI_VERSION/cli/dts/lib.deno.window.d.ts)
files.
Definitions that are specific to workers can be found in the
[`lib.deno.worker.d.ts`](https://github.com/denoland/deno/blob/$CLI_VERSION/cli/dts/lib.deno.worker.d.ts)
file.

View file

@ -1,39 +0,0 @@
## Web Storage API
As of Deno 1.10, the Web Storage API (`localStorage` & `sessionStorage`) was
introduced, which through `localStorage` allows persistent storage, whereas
`sessionStorage` is a non-persistent memory-based storage.
To use persistent storage, you need to pass the `--location` flag. The location
for persistent storage is listed in `deno info`, and additionally passing the
`--location` will give you the path for the specified origin.
To learn more about the Web Storage APIs, visit the
[MDN page on Web Storage](https://developer.mozilla.org/en-US/docs/Web/API/Storage).
### Example
The following snippet accesses the local storage bucket for the current origin
and adds a data item to it using `setItem()`.
```ts
localStorage.setItem("myDemo", "Deno App");
```
The syntax for reading the localStorage item is as follows:
```ts
const cat = localStorage.getItem("myDemo");
```
The syntax for removing the localStorage item is as follows:
```ts
localStorage.removeItem("myDemo");
```
The syntax for removing all the localStorage items is as follows:
```ts
localStorage.clear();
```

View file

@ -1,251 +0,0 @@
## Workers
Deno supports
[`Web Worker API`](https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker).
Workers can be used to run code on multiple threads. Each instance of `Worker`
is run on a separate thread, dedicated only to that worker.
Currently Deno supports only `module` type workers; thus it's essential to pass
the `type: "module"` option when creating a new worker.
Use of relative module specifiers in the main worker are only supported with
`--location <href>` passed on the CLI. This is not recommended for portability.
You can instead use the `URL` constructor and `import.meta.url` to easily create
a specifier for some nearby script. Dedicated workers, however, have a location
and this capability by default.
```ts
// Good
new Worker(new URL("./worker.js", import.meta.url).href, { type: "module" });
// Bad
new Worker(new URL("./worker.js", import.meta.url).href);
new Worker(new URL("./worker.js", import.meta.url).href, { type: "classic" });
new Worker("./worker.js", { type: "module" });
```
### Instantiation permissions
Creating a new `Worker` instance is similar to a dynamic import; therefore Deno
requires appropriate permission for this action.
For workers using local modules; `--allow-read` permission is required:
**main.ts**
```ts
new Worker(new URL("./worker.ts", import.meta.url).href, { type: "module" });
```
**worker.ts**
```ts
console.log("hello world");
self.close();
```
```shell
$ deno run main.ts
error: Uncaught PermissionDenied: read access to "./worker.ts", run again with the --allow-read flag
$ deno run --allow-read main.ts
hello world
```
For workers using remote modules; `--allow-net` permission is required:
**main.ts**
```ts
new Worker("https://example.com/worker.ts", { type: "module" });
```
**worker.ts** (at https[]()://example.com/worker.ts)
```ts
console.log("hello world");
self.close();
```
```shell
$ deno run main.ts
error: Uncaught PermissionDenied: net access to "https://example.com/worker.ts", run again with the --allow-net flag
$ deno run --allow-net main.ts
hello world
```
### Using Deno in worker
> This is an unstable Deno feature. Learn more about
> [unstable features](./stability.md).
By default the `Deno` namespace is not available in worker scope.
To enable the `Deno` namespace pass `deno.namespace = true` option when creating
new worker:
**main.js**
```ts
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
type: "module",
deno: {
namespace: true,
},
});
worker.postMessage({ filename: "./log.txt" });
```
**worker.js**
```ts
self.onmessage = async (e) => {
const { filename } = e.data;
const text = await Deno.readTextFile(filename);
console.log(text);
self.close();
};
```
**log.txt**
```
hello world
```
```shell
$ deno run --allow-read --unstable main.js
hello world
```
### Specifying worker permissions
> This is an unstable Deno feature. Learn more about
> [unstable features](./stability.md).
The permissions available for the worker are analogous to the CLI permission
flags, meaning every permission enabled there can be disabled at the level of
the Worker API. You can find a more detailed description of each of the
permission options [here](../getting_started/permissions.md).
By default a worker will inherit permissions from the thread it was created in,
however in order to allow users to limit the access of this worker we provide
the `deno.permissions` option in the worker API.
- For permissions that support granular access you can pass in a list of the
desired resources the worker will have access to, and for those who only have
the on/off option you can pass true/false respectively.
```ts
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
type: "module",
deno: {
namespace: true,
permissions: {
net: [
"https://deno.land/",
],
read: [
new URL("./file_1.txt", import.meta.url),
new URL("./file_2.txt", import.meta.url),
],
write: false,
},
},
});
```
- Granular access permissions receive both absolute and relative routes as
arguments, however take into account that relative routes will be resolved
relative to the file the worker is instantiated in, not the path the worker
file is currently in
```ts
const worker = new Worker(
new URL("./worker/worker.js", import.meta.url).href,
{
type: "module",
deno: {
namespace: true,
permissions: {
read: [
"/home/user/Documents/deno/worker/file_1.txt",
"./worker/file_2.txt",
],
},
},
},
);
```
- Both `deno.permissions` and its children support the option `"inherit"`, which
implies it will borrow its parent permissions.
```ts
// This worker will inherit its parent permissions
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
type: "module",
deno: {
namespace: true,
permissions: "inherit",
},
});
```
```ts
// This worker will inherit only the net permissions of its parent
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
type: "module",
deno: {
namespace: true,
permissions: {
env: false,
hrtime: false,
net: "inherit",
plugin: false,
read: false,
run: false,
write: false,
},
},
});
```
- Not specifying the `deno.permissions` option or one of its children will cause
the worker to inherit by default.
```ts
// This worker will inherit its parent permissions
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
type: "module",
});
```
```ts
// This worker will inherit all the permissions of its parent BUT net
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
type: "module",
deno: {
namespace: true,
permissions: {
net: false,
},
},
});
```
- You can disable the permissions of the worker all together by passing `"none"`
to the `deno.permissions` option.
```ts
// This worker will not have any permissions enabled
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
type: "module",
deno: {
namespace: true,
permissions: "none",
},
});
```

View file

@ -1,116 +0,0 @@
{
"$id": "https://deno.land/schemas/module-graph.json",
"$schema": "http://json-schema.org/draft-07/schema",
"description": "A JSON representation of a Deno module dependency graph.",
"required": [
"root",
"modules",
"size"
],
"title": "Deno Dependency Graph Schema",
"type": "object",
"properties": {
"root": {
"default": "",
"description": "The root specifier for the graph.",
"examples": [
"https://deno.land/x/mod.ts"
],
"type": "string"
},
"modules": {
"default": [],
"description": "The modules that are part of the graph.",
"type": "array",
"items": {
"$ref": "#/definitions/module"
}
},
"size": {
"type": "integer",
"description": "The total size of all the unique dependencies in the graph in bytes.",
"default": 0
}
},
"definitions": {
"module": {
"type": "object",
"required": [
"specifier"
],
"properties": {
"specifier": {
"type": "string",
"description": "The fully qualified module specifier (URL) for the module."
},
"dependencies": {
"type": "array",
"description": "An array of dependencies of the module.",
"items": {
"$ref": "#/definitions/dependency"
}
},
"size": {
"type": "integer",
"description": "The size of the module on disk in bytes."
},
"mediaType": {
"type": "string",
"description": "How the file is treated within Deno. All the possible media types that Deno considers are listed here, but in practice, several of them would never appear in a module graph.",
"enum": [
"JavaScript",
"TypeScript",
"JSX",
"TSX",
"Dts",
"Json",
"Wasm",
"TsBuildInfo",
"SourceMap",
"Unknown"
]
},
"local": {
"type": "string",
"description": "The path to the local file. For local modules this will be the local file path, for remote modules and data URLs, this would be the path to the file in the Deno cache."
},
"checksum": {
"type": "string",
"description": "The checksum of the local source file. This can be used to validate if the current on disk version matches the version described here."
},
"emit": {
"type": "string",
"description": "The path to an emitted version of the module, if the module requires transpilation to be loaded into the Deno runtime."
},
"map": {
"type": "string",
"description": "The path to an optionally emitted source map between the original and emitted version of the file."
},
"error": {
"type": "string",
"description": "If when resolving the module, Deno encountered an error and the module is unavailable, the text of that error will be indicated here."
}
}
},
"dependency": {
"type": "object",
"required": [
"specifier"
],
"properties": {
"specifier": {
"type": "string",
"description": "The specifier provided from within the module."
},
"code": {
"type": "string",
"description": "The fully qualified module specifier (URL) for the code dependency."
},
"type": {
"type": "string",
"description": "The fully qualified module specifier (URL) for the type only dependency."
}
}
}
}
}

View file

@ -1,76 +0,0 @@
# Standard library
Deno provides a set of standard modules that are audited by the core team and
are guaranteed to work with Deno.
Standard library is available at: https://deno.land/std/
## Versioning and stability
Standard library is not yet stable and therefore it is versioned differently
than Deno. For latest release consult https://deno.land/std/ or
https://deno.land/std/version.ts. The standard library is released each time
Deno is released.
We strongly suggest to always use imports with pinned version of standard
library to avoid unintended changes. For example, rather than linking to the
default branch of code, which may change at any time, potentially causing
compilation errors or unexpected behavior:
```typescript
// import the latest release, this should be avoided
import { copy } from "https://deno.land/std/fs/copy.ts";
```
instead, used a version of the std library which is immutable and will not
change:
```typescript
// imports from v$STD_VERSION of std, never changes
import { copy } from "https://deno.land/std@$STD_VERSION/fs/copy.ts";
```
## Troubleshooting
Some of the modules provided in standard library use unstable Deno APIs.
Trying to run such modules without `--unstable` CLI flag ends up with a lot of
TypeScript errors suggesting that some APIs in the `Deno` namespace do not
exist:
```typescript
// main.ts
import { copy } from "https://deno.land/std@$STD_VERSION/fs/copy.ts";
copy("log.txt", "log-old.txt");
```
```shell
$ deno run --allow-read --allow-write main.ts
Compile file:///dev/deno/main.ts
Download https://deno.land/std@$STD_VERSION/fs/copy.ts
Download https://deno.land/std@$STD_VERSION/fs/ensure_dir.ts
Download https://deno.land/std@$STD_VERSION/fs/_util.ts
error: TS2339 [ERROR]: Property 'utime' does not exist on type 'typeof Deno'. 'Deno.utime' is an unstable API. Did you forget to run with the '--unstable' flag?
await Deno.utime(dest, statInfo.atime, statInfo.mtime);
~~~~~
at https://deno.land/std@$STD_VERSION/fs/copy.ts:92:16
TS2339 [ERROR]: Property 'utimeSync' does not exist on type 'typeof Deno'. 'Deno.utimeSync' is an unstable API. Did you forget to run with the '--unstable' flag?
Deno.utimeSync(dest, statInfo.atime, statInfo.mtime);
~~~~~~~~~
at https://deno.land/std@$STD_VERSION/fs/copy.ts:103:10
```
Solution to that problem requires adding `--unstable` flag:
```shell
deno run --allow-read --allow-write --unstable main.ts
```
To make sure that API producing error is unstable check
[`lib.deno.unstable.d.ts`](https://github.com/denoland/deno/blob/$CLI_VERSION/cli/dts/lib.deno.unstable.d.ts)
declaration.
This problem should be fixed in the near future. Feel free to omit the flag if
the particular modules you depend on compile successfully without it.

View file

@ -1,169 +0,0 @@
# Testing
Deno has a built-in test runner that you can use for testing JavaScript or
TypeScript code.
`deno test` will search in `./*` and `./**/*` recursively, for test files:
- named `test.{ts, tsx, js, mjs, jsx}`,
- or ending with `.test.{ts, tsx, js, mjs, jsx}`,
- or ending with `_test.{ts, tsx, js, mjs, jsx}`
## Writing tests
To define a test you need to register it with a call to `Deno.test` with a name
and function to be tested. There are two styles you can use.
```ts
import { assertEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
// Simple name and function, compact form, but not configurable
Deno.test("hello world #1", () => {
const x = 1 + 2;
assertEquals(x, 3);
});
// Fully fledged test definition, longer form, but configurable (see below)
Deno.test({
name: "hello world #2",
fn: () => {
const x = 1 + 2;
assertEquals(x, 3);
},
});
```
### Async functions
You can also test asynchronous code by passing a test function that returns a
promise. For this you can use the `async` keyword when defining a function:
```ts
import { delay } from "https://deno.land/std@$STD_VERSION/async/delay.ts";
Deno.test("async hello world", async () => {
const x = 1 + 2;
// await some async task
await delay(100);
if (x !== 3) {
throw Error("x should be equal to 3");
}
});
```
## Running tests
To run the test, call `deno test` with the file that contains your test
function. You can also omit the file name, in which case all tests in the
current directory (recursively) that match the glob
`{*_,*.,}test.{js,mjs,ts,jsx,tsx}` will be run. If you pass a directory, all
files in the directory that match this glob will be run.
```shell
# Run all tests in the current directory and all sub-directories
deno test
# Run all tests in the util directory
deno test util/
# Run just my_test.ts
deno test my_test.ts
```
`deno test` uses the same permission model as `deno run` and therefore will
require, for example, `--allow-write` to write to the file system during
testing.
To see all runtime options with `deno test`, you can reference the command line
help:
```shell
deno help test
```
## Filtering
There are a number of options to filter the tests you are running.
### Command line filtering
Tests can be run individually or in groups using the command line `--filter`
option.
The filter flags accept a string or a pattern as value.
Assuming the following tests:
```ts
Deno.test({ name: "my-test", fn: myTest });
Deno.test({ name: "test-1", fn: test1 });
Deno.test({ name: "test2", fn: test2 });
```
This command will run all of these tests because they all contain the word
"test".
```shell
deno test --filter "test" tests/
```
On the flip side, the following command uses a pattern and will run the second
and third tests.
```shell
deno test --filter "/test-*\d/" tests/
```
_To let Deno know that you want to use a pattern, wrap your filter with
forward-slashes like the JavaScript syntactic sugar for a REGEX._
### Test definition filtering
Within the tests themselves, you have two options for filtering.
#### Filtering out (Ignoring these tests)
Sometimes you want to ignore tests based on some sort of condition (for example
you only want a test to run on Windows). For this you can use the `ignore`
boolean in the test definition. If it is set to true the test will be skipped.
```ts
Deno.test({
name: "do macOS feature",
ignore: Deno.build.os !== "darwin",
fn() {
doMacOSFeature();
},
});
```
#### Filtering in (Only run these tests)
Sometimes you may be in the middle of a problem within a large test class and
you would like to focus on just that test and ignore the rest for now. For this
you can use the `only` option to tell the test framework to only run tests with
this set to true. Multiple tests can set this option. While the test run will
report on the success or failure of each test, the overall test run will always
fail if any test is flagged with `only`, as this is a temporary measure only
which disables nearly all of your tests.
```ts
Deno.test({
name: "Focus on this test only",
only: true,
fn() {
testComplicatedStuff();
},
});
```
## Failing fast
If you have a long running test suite and wish for it to stop on the first
failure, you can specify the `--fail-fast` flag when running the suite.
```shell
deno test --fail-fast
```

View file

@ -1,263 +0,0 @@
## Assertions
To help developers write tests the Deno standard library comes with a built in
[assertions module](https://deno.land/std@$STD_VERSION/testing/asserts.ts) which
can be imported from `https://deno.land/std@$STD_VERSION/testing/asserts.ts`.
```js
import { assert } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
Deno.test("Hello Test", () => {
assert("Hello");
});
```
The assertions module provides 10 assertions:
- `assert(expr: unknown, msg = ""): asserts expr`
- `assertEquals(actual: unknown, expected: unknown, msg?: string): void`
- `assertExists(actual: unknown,msg?: string): void`
- `assertNotEquals(actual: unknown, expected: unknown, msg?: string): void`
- `assertStrictEquals(actual: unknown, expected: unknown, msg?: string): void`
- `assertStringIncludes(actual: string, expected: string, msg?: string): void`
- `assertArrayIncludes(actual: unknown[], expected: unknown[], msg?: string): void`
- `assertMatch(actual: string, expected: RegExp, msg?: string): void`
- `assertNotMatch(actual: string, expected: RegExp, msg?: string): void`
- `assertObjectMatch( actual: Record<PropertyKey, unknown>, expected: Record<PropertyKey, unknown>): void`
- `assertThrows(fn: () => void, ErrorClass?: Constructor, msgIncludes = "", msg?: string): Error`
- `assertThrowsAsync(fn: () => Promise<void>, ErrorClass?: Constructor, msgIncludes = "", msg?: string): Promise<Error>`
### Assert
The assert method is a simple 'truthy' assertion and can be used to assert any
value which can be inferred as true.
```js
Deno.test("Test Assert", () => {
assert(1);
assert("Hello");
assert(true);
});
```
### Exists
The `assertExists` can be used to check if a value is not `null` or `undefined`.
```js
assertExists("Denosaurus");
Deno.test("Test Assert Exists", () => {
assertExists("Denosaurus");
assertExists(false);
assertExists(0);
});
```
### Equality
There are three equality assertions available, `assertEquals()`,
`assertNotEquals()` and `assertStrictEquals()`.
The `assertEquals()` and `assertNotEquals()` methods provide a general equality
check and are capable of asserting equality between primitive types and objects.
```js
Deno.test("Test Assert Equals", () => {
assertEquals(1, 1);
assertEquals("Hello", "Hello");
assertEquals(true, true);
assertEquals(undefined, undefined);
assertEquals(null, null);
assertEquals(new Date(), new Date());
assertEquals(new RegExp("abc"), new RegExp("abc"));
class Foo {}
const foo1 = new Foo();
const foo2 = new Foo();
assertEquals(foo1, foo2);
});
Deno.test("Test Assert Not Equals", () => {
assertNotEquals(1, 2);
assertNotEquals("Hello", "World");
assertNotEquals(true, false);
assertNotEquals(undefined, "");
assertNotEquals(new Date(), Date.now());
assertNotEquals(new RegExp("abc"), new RegExp("def"));
});
```
By contrast `assertStrictEquals()` provides a simpler, stricter equality check
based on the `===` operator. As a result it will not assert two instances of
identical objects as they won't be referentially the same.
```js
Deno.test("Test Assert Strict Equals", () => {
assertStrictEquals(1, 1);
assertStrictEquals("Hello", "Hello");
assertStrictEquals(true, true);
assertStrictEquals(undefined, undefined);
});
```
The `assertStrictEquals()` assertion is best used when you wish to make a
precise check against two primitive types.
### Contains
There are two methods available to assert a value contains a value,
`assertStringIncludes()` and `assertArrayIncludes()`.
The `assertStringIncludes()` assertion does a simple includes check on a string
to see if it contains the expected string.
```js
Deno.test("Test Assert String Contains", () => {
assertStringIncludes("Hello World", "Hello");
});
```
The `assertArrayIncludes()` assertion is slightly more advanced and can find
both a value within an array and an array of values within an array.
```js
Deno.test("Test Assert Array Contains", () => {
assertArrayIncludes([1, 2, 3], [1]);
assertArrayIncludes([1, 2, 3], [1, 2]);
assertArrayIncludes(Array.from("Hello World"), Array.from("Hello"));
});
```
### Regex
You can assert regular expressions via `assertMatch()` and `assertNotMatch()`
assertions.
```js
Deno.test("Test Assert Match", () => {
assertMatch("abcdefghi", new RegExp("def"));
const basicUrl = new RegExp("^https?://[a-z.]+.com$");
assertMatch("https://www.google.com", basicUrl);
assertMatch("http://facebook.com", basicUrl);
});
Deno.test("Test Assert Not Match", () => {
assertNotMatch("abcdefghi", new RegExp("jkl"));
const basicUrl = new RegExp("^https?://[a-z.]+.com$");
assertNotMatch("https://deno.land/", basicUrl);
});
```
### Object
Use `assertObjectMatch` to check that a JavaScript object matches a subset of
the properties of an object.
```js
// Simple subset
assertObjectMatch(
{ foo: true, bar: false },
{
foo: true,
},
);
```
### Throws
There are two ways to assert whether something throws an error in Deno,
`assertThrows()` and `assertThrowsAsync()`. Both assertions allow you to check
an
[Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
has been thrown, the type of error thrown and what the message was.
The difference between the two assertions is `assertThrows()` accepts a standard
function and `assertThrowsAsync()` accepts a function which returns a
[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
The `assertThrows()` assertion will check an error has been thrown, and
optionally will check the thrown error is of the correct type, and assert the
error message is as expected.
```js
Deno.test("Test Assert Throws", () => {
assertThrows(
() => {
throw new Error("Panic!");
},
Error,
"Panic!",
);
});
```
The `assertThrowsAsync()` assertion is a little more complicated, mainly because
it deals with Promises. But basically it will catch thrown errors or rejections
in Promises. You can also optionally check for the error type and error message.
```js
Deno.test("Test Assert Throws Async", () => {
assertThrowsAsync(
() => {
return new Promise(() => {
throw new Error("Panic! Threw Error");
});
},
Error,
"Panic! Threw Error",
);
assertThrowsAsync(
() => {
return Promise.reject(new Error("Panic! Reject Error"));
},
Error,
"Panic! Reject Error",
);
});
```
### Custom Messages
Each of Deno's built in assertions allow you to overwrite the standard CLI error
message if you wish. For instance this example will output "Values Don't Match!"
rather than the standard CLI error message.
```js
Deno.test("Test Assert Equal Fail Custom Message", () => {
assertEquals(1, 2, "Values Don't Match!");
});
```
### Custom Tests
While Deno comes with powerful
[assertions modules](https://deno.land/std@$STD_VERSION/testing/asserts.ts) but
there is always something specific to the project you can add. Creating
`custom assertion function` can improve readability and reduce the amount of
code.
```js
function assertPowerOf(actual: number, expected: number, msg?: string): void {
let received = actual;
while (received % expected === 0) received = received / expected;
if (received !== 1) {
if (!msg) {
msg = `actual: "${actual}" expected to be a power of : "${expected}"`;
}
throw new AssertionError(msg);
}
}
```
Use this matcher in your code like this:
```js
Deno.test("Test Assert PowerOf", () => {
assertPowerOf(8, 2);
assertPowerOf(11, 4);
});
```

View file

@ -1,36 +0,0 @@
# Test coverage
Deno will collect test coverage into a directory for your code if you specify
the `--coverage` flag when starting `deno test`.
This coverage information is acquired directly from the JavaScript engine (V8)
which is very accurate.
This can then be further processed from the internal format into well known
formats by the `deno coverage` tool.
```bash
# Go into your project's working directory
git clone https://github.com/oakserver/oak && cd oak
# Collect your coverage profile with deno test --coverage=<output_directory>
deno test --coverage=cov_profile
# From this you can get a pretty printed diff of uncovered lines
deno coverage cov_profile
# Or generate an lcov report
deno coverage cov_profile --lcov > cov_profile.lcov
# Which can then be further processed by tools like genhtml
genhtml -o cov_profile/html cov_profile.lcov
```
By default, `deno coverage` will exclude any files matching the regular
expression `test\.(js|mjs|ts|jsx|tsx)` and only consider including specifiers
matching the regular expression `^file:` - ie. remote files will be excluded
from coverage report.
These filters can be overridden using the `--exclude` and `--include` flags. A
module specifier must _match_ the include_regular expression and _not match_ the
exclude_ expression for it to be a part of the report.

View file

@ -1,39 +0,0 @@
# Documentation tests
Deno supports type-checking your documentation examples.
This makes sure that examples within your documentation are up to date and
working.
The basic idea is this:
````ts
/**
* # Examples
*
* ```ts
* const x = 42;
* ```
*/
````
The triple backticks mark the start and end of code blocks.
If this example was in a file named foo.ts, running `deno test --doc foo.ts`
will extract this example, and then type-check it as a standalone module living
in the same directory as the module being documented.
To document your exports, import the module using a relative path specifier:
````ts
/**
* # Examples
*
* ```ts
* import { foo } from "./foo.ts";
* ```
*/
export function foo(): string {
return "foo";
}
````

View file

@ -1,69 +0,0 @@
# Test Sanitizers
The test runner offers several sanitizers to ensure that the test behaves in a
reasonable and expected way.
### Resource sanitizer
Certain actions in Deno create resources in the resource table
([learn more here](./contributing/architecture.md)).
These resources should be closed after you are done using them.
For each test definition, the test runner checks that all resources created in
this test have been closed. This is to prevent resource 'leaks'. This is enabled
by default for all tests, but can be disabled by setting the `sanitizeResources`
boolean to false in the test definition.
```ts
Deno.test({
name: "leaky resource test",
async fn() {
await Deno.open("hello.txt");
},
sanitizeResources: false,
});
```
### Op sanitizer
The same is true for async operation like interacting with the filesystem. The
test runner checks that each operation you start in the test is completed before
the end of the test. This is enabled by default for all tests, but can be
disabled by setting the `sanitizeOps` boolean to false in the test definition.
```ts
Deno.test({
name: "leaky operation test",
fn() {
setTimeout(function () {}, 1000);
},
sanitizeOps: false,
});
```
### Exit sanitizer
There's also the exit sanitizer which ensures that tested code doesn't call
`Deno.exit()` signaling a false test success.
This is enabled by default for all tests, but can be disabled by setting the
`sanitizeExit` boolean to false in the test definition.
```ts
Deno.test({
name: "false success",
fn() {
Deno.exit(0);
},
sanitizeExit: false,
});
// This test never runs, because the process exits during "false success" test
Deno.test({
name: "failing test",
fn() {
throw new Error("this test fails");
},
});
```

View file

@ -1,120 +0,0 @@
{
"introduction": {
"name": "Introduction"
},
"getting_started": {
"name": "Getting Started",
"children": {
"installation": "Installation",
"setup_your_environment": "Setup your environment",
"first_steps": "First steps",
"command_line_interface": "Command line interface",
"permissions": "Permissions",
"webassembly": "Using WebAssembly",
"debugging_your_code": "Debugging your code"
}
},
"runtime": {
"name": "The Runtime",
"children": {
"stability": "Stability",
"program_lifecycle": "Program lifecycle",
"permission_apis": "Permission APIs",
"web_platform_apis": "Web Platform APIs",
"http_server_apis": "HTTP Server APIs",
"location_api": "Location API",
"web_storage_api": "Web Storage API",
"workers": "Workers"
}
},
"linking_to_external_code": {
"name": "Linking to external code",
"children": {
"reloading_modules": "Reloading modules",
"integrity_checking": "Integrity checking",
"proxies": "Proxies",
"private": "Private modules",
"import_maps": "Import maps"
}
},
"npm_nodejs": {
"name": "Using npm/Node.js code",
"children": {
"std_node": "The std/node library",
"cdns": "Packages from CDNs",
"import_maps": "Using import maps",
"faqs": "Frequently asked questions"
}
},
"typescript": {
"name": "Using TypeScript",
"children": {
"overview": "Overview",
"configuration": "Configuration",
"types": "Types and type declarations",
"migration": "Migrating to/from JavaScript",
"runtime": "Runtime compiler APIs",
"faqs": "Frequently asked questions"
}
},
"standard_library": {
"name": "Standard library"
},
"examples": {
"name": "Examples",
"children": {
"hello_world": "Hello world",
"import_export": "Import and export modules",
"manage_dependencies": "Manage dependencies",
"fetch_data": "Fetch data",
"read_write_files": "Read and write files",
"unix_cat": "Unix cat program",
"http_server": "HTTP web server",
"file_server": "File server",
"tcp_echo": "TCP echo server",
"subprocess": "Creating a subprocess",
"os_signals": "OS signals",
"file_system_events": "File system events",
"module_metadata": "Module metadata"
}
},
"testing": {
"name": "Testing",
"children": {
"assertions": "Assertions",
"coverage": "Coverage",
"documentation": "Documentation",
"sanitizers": "Sanitizers"
}
},
"tools": {
"name": "Tools",
"children": {
"script_installer": "Script installer",
"formatter": "Formatter",
"repl": "Read-eval-print-loop",
"bundler": "Bundler",
"compiler": "Compiling executables",
"documentation_generator": "Documentation generator",
"dependency_inspector": "Dependency inspector",
"linter": "Linter"
}
},
"embedding_deno": {
"name": "Embedding Deno"
},
"help": {
"name": "Help"
},
"contributing": {
"name": "Contributing",
"children": {
"building_from_source": "Building from source",
"development_tools": "Development tools",
"web_platform_tests": "Web platform tests",
"style_guide": "Style guide",
"architecture": "Architecture",
"release_schedule": "Release schedule"
}
}
}

View file

@ -1,14 +0,0 @@
# Built-in tooling
Deno provides some built in tooling that is useful when working with JavaScript
and TypeScript:
- [bundler (`deno bundle`)](./tools/bundler.md)
- [compiling executables (`deno compile`)](./tools/compiler.md)
- [installer (`deno install`)](./tools/script_installer.md)
- [dependency inspector (`deno info`)](./tools/dependency_inspector.md)
- [documentation generator (`deno doc`)](./tools/documentation_generator.md)
- [formatter (`deno fmt`)](./tools/formatter.md)
- [repl (`deno repl`)](./tools/repl.md)
- [test runner (`deno test`)](./testing.md)
- [linter (`deno lint`)](./tools/linter.md)

View file

@ -1,51 +0,0 @@
## Bundling
`deno bundle [URL]` will output a single JavaScript file, which includes all
dependencies of the specified input. For example:
```bash
deno bundle https://deno.land/std@$STD_VERSION/examples/colors.ts colors.bundle.js
Bundle https://deno.land/std@$STD_VERSION/examples/colors.ts
Download https://deno.land/std@$STD_VERSION/examples/colors.ts
Download https://deno.land/std@$STD_VERSION/fmt/colors.ts
Emit "colors.bundle.js" (9.83KB)
```
If you omit the out file, the bundle will be sent to `stdout`.
The bundle can just be run as any other module in Deno would:
```bash
deno run colors.bundle.js
```
The output is a self contained ES Module, where any exports from the main module
supplied on the command line will be available. For example, if the main module
looked something like this:
```ts
export { foo } from "./foo.js";
export const bar = "bar";
```
It could be imported like this:
```ts
import { bar, foo } from "./lib.bundle.js";
```
Bundles can also be loaded in the web browser. The bundle is a self-contained ES
module, and so the attribute of `type` must be set to `"module"`. For example:
```html
<script type="module" src="website.bundle.js"></script>
```
Or you could import it into another ES module to consume:
```html
<script type="module">
import * as website from "website.bundle.js";
</script>
```

View file

@ -1,36 +0,0 @@
## Compiling Executables
`deno compile [--output <OUT>] <SRC>` will compile the script into a
self-contained executable.
```
> deno compile https://deno.land/std/examples/welcome.ts
```
If you omit the `OUT` parameter, the name of the executable file will be
inferred.
### Flags
As with [`deno install`](./script_installer.md), the runtime flags used to
execute the script must be specified at compilation time. This includes
permission flags.
```
> deno compile --allow-read --allow-net https://deno.land/std/http/file_server.ts
```
[Script arguments](../getting_started/command_line_interface.md#script-arguments)
can be partially embedded.
```
> deno compile --allow-read --allow-net https://deno.land/std/http/file_server.ts -p 8080
> ./file_server --help
```
### Cross Compilation
You can compile binaries for other platforms by adding the `--target` CLI flag.
Deno currently supports compiling to Windows x64, macOS x64, macOS ARM and Linux
x64. Use `deno compile --help` to list the full values for each compilation
target.

View file

@ -1,74 +0,0 @@
## Dependency Inspector
`deno info [URL]` will inspect ES module and all of its dependencies.
```shell
deno info https://deno.land/std@0.67.0/http/file_server.ts
Download https://deno.land/std@0.67.0/http/file_server.ts
...
local: /home/deno/.cache/deno/deps/https/deno.land/f57792e36f2dbf28b14a75e2372a479c6392780d4712d76698d5031f943c0020
type: TypeScript
compiled: /home/deno/.cache/deno/gen/https/deno.land/f57792e36f2dbf28b14a75e2372a479c6392780d4712d76698d5031f943c0020.js
deps: 23 unique (total 139.89KB)
https://deno.land/std@0.67.0/http/file_server.ts (10.49KB)
├─┬ https://deno.land/std@0.67.0/path/mod.ts (717B)
│ ├── https://deno.land/std@0.67.0/path/_constants.ts (2.35KB)
│ ├─┬ https://deno.land/std@0.67.0/path/win32.ts (27.36KB)
│ │ ├── https://deno.land/std@0.67.0/path/_interface.ts (657B)
│ │ ├── https://deno.land/std@0.67.0/path/_constants.ts *
│ │ ├─┬ https://deno.land/std@0.67.0/path/_util.ts (3.3KB)
│ │ │ ├── https://deno.land/std@0.67.0/path/_interface.ts *
│ │ │ └── https://deno.land/std@0.67.0/path/_constants.ts *
│ │ └── https://deno.land/std@0.67.0/_util/assert.ts (405B)
│ ├─┬ https://deno.land/std@0.67.0/path/posix.ts (12.67KB)
│ │ ├── https://deno.land/std@0.67.0/path/_interface.ts *
│ │ ├── https://deno.land/std@0.67.0/path/_constants.ts *
│ │ └── https://deno.land/std@0.67.0/path/_util.ts *
│ ├─┬ https://deno.land/std@0.67.0/path/common.ts (1.14KB)
│ │ └─┬ https://deno.land/std@0.67.0/path/separator.ts (264B)
│ │ └── https://deno.land/std@0.67.0/path/_constants.ts *
│ ├── https://deno.land/std@0.67.0/path/separator.ts *
│ ├── https://deno.land/std@0.67.0/path/_interface.ts *
│ └─┬ https://deno.land/std@0.67.0/path/glob.ts (8.12KB)
│ ├── https://deno.land/std@0.67.0/path/_constants.ts *
│ ├── https://deno.land/std@0.67.0/path/mod.ts *
│ └── https://deno.land/std@0.67.0/path/separator.ts *
├─┬ https://deno.land/std@0.67.0/http/server.ts (10.23KB)
│ ├── https://deno.land/std@0.67.0/encoding/utf8.ts (433B)
│ ├─┬ https://deno.land/std@0.67.0/io/bufio.ts (21.15KB)
│ │ ├── https://deno.land/std@0.67.0/bytes/mod.ts (4.34KB)
│ │ └── https://deno.land/std@0.67.0/_util/assert.ts *
│ ├── https://deno.land/std@0.67.0/_util/assert.ts *
│ ├─┬ https://deno.land/std@0.67.0/async/mod.ts (202B)
│ │ ├── https://deno.land/std@0.67.0/async/deferred.ts (1.03KB)
│ │ ├── https://deno.land/std@0.67.0/async/delay.ts (279B)
│ │ ├─┬ https://deno.land/std@0.67.0/async/mux_async_iterator.ts (1.98KB)
│ │ │ └── https://deno.land/std@0.67.0/async/deferred.ts *
│ │ └── https://deno.land/std@0.67.0/async/pool.ts (1.58KB)
│ └─┬ https://deno.land/std@0.67.0/http/_io.ts (11.25KB)
│ ├── https://deno.land/std@0.67.0/io/bufio.ts *
│ ├─┬ https://deno.land/std@0.67.0/textproto/mod.ts (4.52KB)
│ │ ├── https://deno.land/std@0.67.0/io/bufio.ts *
│ │ ├── https://deno.land/std@0.67.0/bytes/mod.ts *
│ │ └── https://deno.land/std@0.67.0/encoding/utf8.ts *
│ ├── https://deno.land/std@0.67.0/_util/assert.ts *
│ ├── https://deno.land/std@0.67.0/encoding/utf8.ts *
│ ├── https://deno.land/std@0.67.0/http/server.ts *
│ └── https://deno.land/std@0.67.0/http/http_status.ts (5.93KB)
├─┬ https://deno.land/std@0.67.0/flags/mod.ts (9.54KB)
│ └── https://deno.land/std@0.67.0/_util/assert.ts *
└── https://deno.land/std@0.67.0/_util/assert.ts *
```
Dependency inspector works with any local or remote ES modules.
## Cache location
`deno info` can be used to display information about cache location:
```shell
deno info
DENO_DIR location: "/Users/deno/Library/Caches/deno"
Remote modules cache: "/Users/deno/Library/Caches/deno/deps"
TypeScript compiler cache: "/Users/deno/Library/Caches/deno/gen"
```

View file

@ -1,31 +0,0 @@
## Documentation Generator
`deno doc` followed by a list of one or more source files will print the JSDoc
documentation for each of the module's **exported** members.
For example, given a file `add.ts` with the contents:
```ts
/**
* Adds x and y.
* @param {number} x
* @param {number} y
* @returns {number} Sum of x and y
*/
export function add(x: number, y: number): number {
return x + y;
}
```
Running the Deno `doc` command, prints the function's JSDoc comment to `stdout`:
```shell
deno doc add.ts
function add(x: number, y: number): number
Adds x and y. @param {number} x @param {number} y @returns {number} Sum of x and y
```
Use the `--json` flag to output the documentation in JSON format. This JSON
format is consumed by the
[deno doc website](https://github.com/denoland/doc_website) and is used to
generate module documentation.

View file

@ -1,29 +0,0 @@
## Code formatter
Deno ships with a built in code formatter that auto-formats TypeScript and
JavaScript code.
```shell
# format all JS/TS files in the current directory and subdirectories
deno fmt
# format specific files
deno fmt myfile1.ts myfile2.ts
# check if all the JS/TS files in the current directory and subdirectories are formatted
deno fmt --check
# format stdin and write to stdout
cat file.ts | deno fmt -
```
Ignore formatting code by preceding it with a `// deno-fmt-ignore` comment:
```ts
// deno-fmt-ignore
export const identity = [
1, 0, 0,
0, 1, 0,
0, 0, 1,
];
```
Or ignore an entire file by adding a `// deno-fmt-ignore-file` comment at the
top of the file.

View file

@ -1,150 +0,0 @@
## Linter
Deno ships with a built in code linter for JavaScript and TypeScript.
```shell
# lint all JS/TS files in the current directory and subdirectories
deno lint
# lint specific files
deno lint myfile1.ts myfile2.ts
# print result as JSON
deno lint --json
# read from stdin
cat file.ts | deno lint -
```
For more detail, run `deno lint --help`.
### Available rules
- `adjacent-overload-signatures`
- `ban-ts-comment`
- `ban-types`
- `ban-untagged-ignore`
- `camelcase`
- `constructor-super`
- `for-direction`
- `getter-return`
- `no-array-constructor`
- `no-async-promise-executor`
- `no-case-declarations`
- `no-class-assign`
- `no-compare-neg-zero`
- `no-cond-assign`
- `no-constant-condition`
- `no-control-regex`
- `no-debugger`
- `no-delete-var`
- `no-deprecated-deno-api`
- `no-dupe-args`
- `no-dupe-class-members`
- `no-dupe-else-if`
- `no-dupe-keys`
- `no-duplicate-case`
- `no-empty`
- `no-empty-character-class`
- `no-empty-interface`
- `no-empty-pattern`
- `no-ex-assign`
- `no-explicit-any`
- `no-extra-boolean-cast`
- `no-extra-non-null-assertion`
- `no-extra-semi`
- `no-fallthrough`
- `no-func-assign`
- `no-global-assign`
- `no-import-assign`
- `no-inferrable-types`
- `no-inner-declarations`
- `no-invalid-regexp`
- `no-irregular-whitespace`
- `no-misused-new`
- `no-mixed-spaces-and-tabs`
- `no-namespace`
- `no-new-symbol`
- `no-obj-calls`
- `no-octal`
- `no-prototype-builtins`
- `no-redeclare`
- `no-regex-spaces`
- `no-self-assign`
- `no-setter-return`
- `no-shadow-restricted-names`
- `no-this-alias`
- `no-this-before-super`
- `no-unreachable`
- `no-unsafe-finally`
- `no-unsafe-negation`
- `no-unused-labels`
- `no-unused-vars`
- `no-with`
- `prefer-as-const`
- `prefer-const`
- `prefer-namespace-keyword`
- `require-await`
- `require-yield`
- `use-isnan`
- `valid-typeof`
For more detail about each rule, visit
[the deno_lint rule documentation](https://lint.deno.land).
### Ignore directives
#### Files
To ignore whole file `// deno-lint-ignore-file` directive should placed at the
top of the file:
```ts
// deno-lint-ignore-file
function foo(): any {
// ...
}
```
Ignore directive must be placed before first statement or declaration:
```ts
// Copyright 2020 the Deno authors. All rights reserved. MIT license.
/**
* Some JS doc
**/
// deno-lint-ignore-file
import { bar } from "./bar.js";
function foo(): any {
// ...
}
```
You can also ignore certain diagnostics in the whole file
```ts
// deno-lint-ignore-file no-explicit-any no-empty
function foo(): any {
// ...
}
```
#### Diagnostics
To ignore certain diagnostic `// deno-lint-ignore <codes...>` directive should
be placed before offending line. Specifying ignored rule name is required:
```ts
// deno-lint-ignore no-explicit-any
function foo(): any {
// ...
}
// deno-lint-ignore no-explicit-any explicit-function-return-type
function bar(a: any) {
// ...
}
```

View file

@ -1,52 +0,0 @@
# Read-eval-print-loop
`deno repl` starts an read-eval-print-loop, which lets you interactively build
up program state in the global context.
## Keyboard shortcuts
| Keystroke | Action |
| --------------------- | ------------------------------------------------------------------------------------------------ |
| Ctrl-A, Home | Move cursor to the beginning of line |
| Ctrl-B, Left | Move cursor one character left |
| Ctrl-C | Interrupt and cancel the current edit |
| Ctrl-D | If if line _is_ empty, signal end of line |
| Ctrl-D, Del | If line is _not_ empty, delete character under cursor |
| Ctrl-E, End | Move cursor to end of line |
| Ctrl-F, Right | Move cursor one character right |
| Ctrl-H, Backspace | Delete character before cursor |
| Ctrl-I, Tab | Next completion |
| Ctrl-J, Ctrl-M, Enter | Finish the line entry |
| Ctrl-K | Delete from cursor to end of line |
| Ctrl-L | Clear screen |
| Ctrl-N, Down | Next match from history |
| Ctrl-P, Up | Previous match from history |
| Ctrl-R | Reverse Search history (Ctrl-S forward, Ctrl-G cancel) |
| Ctrl-T | Transpose previous character with current character |
| Ctrl-U | Delete from start of line to cursor |
| Ctrl-V | Insert any special character without performing its associated action |
| Ctrl-W | Delete word leading up to cursor (using white space as a word boundary) |
| Ctrl-X Ctrl-U | Undo |
| Ctrl-Y | Paste from Yank buffer |
| Ctrl-Y | Paste from Yank buffer (Meta-Y to paste next yank instead) |
| Ctrl-Z | Suspend (Unix only) |
| Ctrl-_ | Undo |
| Meta-0, 1, ..., - | Specify the digit to the argument. `` starts a negative argument. |
| Meta-< | Move to first entry in history |
| Meta-> | Move to last entry in history |
| Meta-B, Alt-Left | Move cursor to previous word |
| Meta-Backspace | Kill from the start of the current word, or, if between words, to the start of the previous word |
| Meta-C | Capitalize the current word |
| Meta-D | Delete forwards one word |
| Meta-F, Alt-Right | Move cursor to next word |
| Meta-L | Lower-case the next word |
| Meta-T | Transpose words |
| Meta-U | Upper-case the next word |
| Meta-Y | See Ctrl-Y |
## Special variables
| Identifier | Description |
| ---------- | ------------------------------------ |
| _ | Yields the last evaluated expression |
| _error | Yields the last thrown error |

View file

@ -1,90 +0,0 @@
## Script installer
Deno provides `deno install` to easily install and distribute executable code.
`deno install [OPTIONS...] [URL] [SCRIPT_ARGS...]` will install the script
available at `URL` under the name `EXE_NAME`.
This command creates a thin, executable shell script which invokes `deno` using
the specified CLI flags and main module. It is placed in the installation root's
`bin` directory.
Example:
```shell
$ deno install --allow-net --allow-read https://deno.land/std@$STD_VERSION/http/file_server.ts
[1/1] Compiling https://deno.land/std@$STD_VERSION/http/file_server.ts
✅ Successfully installed file_server.
/Users/deno/.deno/bin/file_server
```
To change the executable name, use `-n`/`--name`:
```shell
deno install --allow-net --allow-read -n serve https://deno.land/std@$STD_VERSION/http/file_server.ts
```
The executable name is inferred by default:
- Attempt to take the file stem of the URL path. The above example would become
'file_server'.
- If the file stem is something generic like 'main', 'mod', 'index' or 'cli',
and the path has no parent, take the file name of the parent path. Otherwise
settle with the generic name.
- If the resulting name has an '@...' suffix, strip it.
To change the installation root, use `--root`:
```shell
deno install --allow-net --allow-read --root /usr/local https://deno.land/std@$STD_VERSION/http/file_server.ts
```
The installation root is determined, in order of precedence:
- `--root` option
- `DENO_INSTALL_ROOT` environment variable
- `$HOME/.deno`
These must be added to the path manually if required.
```shell
echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.bashrc
```
You must specify permissions that will be used to run the script at installation
time.
```shell
deno install --allow-net --allow-read https://deno.land/std@$STD_VERSION/http/file_server.ts -p 8080
```
The above command creates an executable called `file_server` that runs with
network and read permissions and binds to port 8080.
For good practice, use the [`import.meta.main`](../examples/module_metadata.md)
idiom to specify the entry point in an executable script.
Example:
<!-- deno-fmt-ignore -->
```ts
// https://example.com/awesome/cli.ts
async function myAwesomeCli(): Promise<void> {
-- snip --
}
if (import.meta.main) {
myAwesomeCli();
}
```
When you create an executable script make sure to let users know by adding an
example installation command to your repository:
```shell
# Install using deno install
$ deno install -n awesome_cli https://example.com/awesome/cli.ts
```

View file

@ -1,10 +0,0 @@
# Using TypeScript
In this chapter we will discuss:
- [Overview of TypeScript in Deno](./typescript/overview.md)
- [Configuring TypeScript in Deno](./typescript/configuration.md)
- [Types and Type Declarations](./typescript/types.md)
- [Migrating to/from JavaScript](./typescript/migration.md)
- [Runtime compiler APIs](./typescript/runtime.md)
- [FAQs about TypeScript in Deno](./typescript/faqs.md)

View file

@ -1,206 +0,0 @@
## Configuring TypeScript in Deno
TypeScript comes with a load of different options that can be configured, but
Deno strives to make it easy to use TypeScript with Deno. Lots of different
options frustrates that goal. To make things easier, Deno configures TypeScript
to "just work" and shouldn't require additional configuration.
That being said, Deno does support using a TypeScript configuration file, though
like the rest of Deno, the detection and use of a configuration file is not
automatic. To use a TypeScript configuration file with Deno, you have to provide
a path on the command line. For example:
```
> deno run --config ./tsconfig.json main.ts
```
> ⚠️ Do consider though that if you are creating libraries that require a
> configuration file, all of the consumers of your modules will require that
> configuration file too if you distribute your modules as TypeScript. In
> addition, there could be settings you do in the configuration file that make
> other TypeScript modules incompatible. Honestly it is best to use the Deno
> defaults and to think long and hard about using a configuration file.
### How Deno uses a configuration file
Deno does not process a TypeScript configuration file like `tsc` does, as there
are lots of parts of a TypeScript configuration file that are meaningless in a
Deno context or would cause Deno to not function properly if they were applied.
Deno only looks at the `compilerOptions` section of a configuration file, and
even then it only considers certain compiler options, with the rest being
ignored.
Here is a table of compiler options that can be changed, their default in Deno
and any other notes about that option:
| Option | Default | Notes |
| -------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowJs` | `true` | This almost never needs to be changed |
| `allowUnreachableCode` | `false` | |
| `allowUnusedLabels` | `false` | |
| `checkJs` | `false` | If `true` causes TypeScript to type check JavaScript |
| `experimentalDecorators` | `true` | We enable these by default as they are already opt-in in the code and when we skip type checking, the Rust based emitter has them on by default. We strongly discourage the use of legacy decorators, as they are incompatible with the future decorators standard in JavaScript |
| `jsx` | `"react"` | |
| `jsxFactory` | `"React.createElement"` | |
| `jsxFragmentFactory` | `"React.Fragment"` | |
| `keyofStringsOnly` | `false` | |
| `lib` | `[ "deno.window" ]` | The default for this varies based on other settings in Deno. If it is supplied, it overrides the default. See below for more information. |
| `noFallthroughCasesInSwitch` | `false` | |
| `noImplicitAny` | `true` | |
| `noImplicitReturns` | `false` | |
| `noImplicitThis` | `true` | |
| `noImplicitUseStrict` | `true` | |
| `noStrictGenericChecks` | `false` | |
| `noUnusedLocals` | `false` | |
| `noUnusedParameters` | `false` | |
| `noUncheckedIndexedAccess` | `false` | |
| `reactNamespace` | `React` | |
| `strict` | `true` | |
| `strictBindCallApply` | `true` | |
| `strictFunctionTypes` | `true` | |
| `strictPropertyInitialization` | `true` | |
| `strictNullChecks` | `true` | |
| `suppressExcessPropertyErrors` | `false` | |
| `suppressImplicitAnyIndexErrors` | `false` | |
For a full list of compiler options and how they affect TypeScript, please refer
to the
[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
### What an implied tsconfig.json looks like
It is impossible to get `tsc` to behave like Deno. It is also difficult to get
the TypeScript language service to behave like Deno. This is why we have built a
language service directly into Deno. That being said, it can be useful to
understand what is implied.
If you were to write a `tsconfig.json` for Deno, it would look something like
this:
```json
{
"compilerOptions": {
"allowJs": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"inlineSourceMap": true,
"isolatedModules": true,
"jsx": "react",
"lib": ["deno.window"],
"module": "esnext",
"strict": true,
"target": "esnext",
"useDefineForClassFields": true
}
}
```
You can't copy paste this into a `tsconfig.json` and get it to work,
specifically because of the built in type libraries that are custom to Deno
which are provided to the TypeScript compiler. This can somewhat be mocked by
running `deno types` on the command line and piping the output to a file and
including that in the files as part of the program, removing the `"lib"` option,
and setting the `"noLib"` option to `true`.
If you use the `--unstable` flag, Deno will change the `"lib"` option to
`[ "deno.window", "deno.unstable" ]`. If you are trying to load a worker, that
is type checked with `"deno.worker"` instead of `"deno.window"`. See
[Type Checking Web Workers](./types#type-checking-web-workers) for more
information on this.
### Using the "lib" property
Deno has several libraries built into it that are not present in other
platforms, like `tsc`. This is what enables Deno to properly check code written
for Deno. In some situations though, this automatic behavior can cause
challenges, for example like writing code that is intended to also run in a
browser. In these situations the `"lib"` property of a `tsconfig.json` can be
used to modify the behavior of Deno when type checking code.
The built-in libraries that are of interest to users:
- `"deno.ns"` - This includes all the custom `Deno` global namespace APIs plus
the Deno additions to `import.meta`. This should generally not conflict with
other libraries or global types.
- `"deno.unstable"` - This includes the addition unstable `Deno` global
namespace APIs.
- `"deno.window"` - This is the "default" library used when checking Deno main
runtime scripts. It includes the `"deno.ns"` as well as other type libraries
for the extensions that are built into Deno. This library will conflict with
libraries like `"dom"` and `"dom.iterable"` that are standard TypeScript
libraries.
- `"deno.worker"` - This is the library used when checking a Deno web worker
script. For more information about web workers, check out
[Type Checking Web Workers](./types#type-checking-web-workers).
- `"dom.asynciterable"` - TypeScript currently does not include the DOM async
iterables that Deno implements (plus several browsers), so we have implemented
it ourselves until it becomes available in TypeScript.
These are common libraries that Deno doesn't use, but are useful when writing
code that is intended to also work in another runtime:
- `"dom"` - The main browser global library that ships with TypeScript. The type
definitions conflict in many ways with `"deno.window"` and so if `"dom"` is
used, then consider using just `"deno.ns"` to expose the Deno specific APIs.
- `"dom.iterable"` - The iterable extensions to the browser global library.
- `"scripthost"` - The library for the Microsoft Windows Script Host.
- `"webworker"` - The main library for web workers in the browser. Like `"dom"`
this will conflict with `"deno.window"` or `"deno.worker"`, so consider using
just `"deno.ns"` to expose the Deno specific APIs.
- `"webworker.importscripts"` - The library that exposes the `importScripts()`
API in the web worker.
- `"webworker.iterable"` - The library that adds iterables to objects within a
web worker. Modern browsers support this.
#### Targeting Deno and the Browser
A common use case is writing code that works in Deno and the browser, and have
the code "sniff" to determine if it is running in the browser or in Deno. If
that is the case a common configuration of a `tsconfig.json` would look like
this:
```json
{
"compilerOptions": {
"target": "esnext",
"lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
}
}
```
This should allow most code to be type checked properly by Deno.
If you expect to run the code in Deno with the `--unstable` flag, then you will
want to add that library to the mix as well:
```json
{
"compilerOptions": {
"target": "esnext",
"lib": [
"dom",
"dom.iterable",
"dom.asynciterable",
"deno.ns",
"deno.unstable"
]
}
}
```
Typically when you use the `"lib"` option in TypeScript, you need to include an
"es" library as well. In the case of `"deno.ns"` and `"deno.unstable"`, they
automatically include `"esnext"` when you bring them in.
The biggest "danger" when doing something like this, is that the type checking
is significantly looser, and there is no way to validate that you are doing
sufficient and effective feature detection in your code, which may lead to what
could be trivial errors becoming runtime errors.
### Using the "types" property
The `"types"` property in `"compilerOptions"` can be used to specify arbitrary
type definitions to include when type checking a programme. For more information
on this see
[Using ambient or global types](./types#using-ambient-or-global-types).

View file

@ -1,136 +0,0 @@
## FAQs about TypeScript in Deno
### Can I use TypeScript not written for Deno?
Maybe. That is the best answer, we are afraid. For lots of reasons, Deno has
chosen to have fully qualified module specifiers. In part this is because it
treats TypeScript as a first class language. Also, Deno uses explicit module
resolution, with no _magic_. This is effectively the same way browsers
themselves work, though they don't obviously support TypeScript directly. If the
TypeScript modules use imports that don't have these design decisions in mind,
they may not work under Deno.
Also, in recent versions of Deno (starting with 1.5), we have started to use a
Rust library to do transformations of TypeScript to JavaScript in certain
scenarios. Because of this, there are certain situations in TypeScript where
type information is required, and therefore those are not supported under Deno.
If you are using `tsc` as stand-alone, the setting to use is `"isolatedModules"`
and setting it to `true` to help ensure that your code can be properly handled
by Deno.
One of the ways to deal with the extension and the lack of Node.js non-standard
resolution logic is to use
[import maps](../linking_to_external_code/import_maps.md) which would allow you
to specify "packages" of bare specifiers which then Deno could resolve and load.
### What version(s) of TypeScript does Deno support?
Deno is built with a specific version of TypeScript. To find out what this is,
type the following on the command line:
```shell
> deno --version
```
The TypeScript version (along with the version of Deno and v8) will be printed.
Deno tries to keep up to date with general releases of TypeScript, providing
them in the next patch or minor release of Deno.
### There was a breaking change in the version of TypeScript that Deno uses, why did you break my program?
We do not consider changes in behavior or breaking changes in TypeScript
releases as breaking changes for Deno. TypeScript is a generally mature language
and breaking changes in TypeScript are almost always "good things" making code
more sound, and it is best that we all keep our code sound. If there is a
blocking change in the version of TypeScript and it isn't suitable to use an
older release of Deno until the problem can be resolved, then you should be able
to use `--no-check` to skip type checking all together.
In addition you can utilize `@ts-ignore` to _ignore_ a specific error in code
that you control. You can also replace whole dependencies, using
[import maps](../linking_to_external_code/import_maps), for situations where a
dependency of a dependency isn't being maintained or has some sort of breaking
change you want to bypass while waiting for it to be updated.
### How do I write code that works in Deno and a browser, but still type checks?
You can do this by using a `tsconfig.json` file with the `--config` option on
the command line and adjusting the `"lib"` option in the `"compilerOptions"` in
the file. For more information see
[Targeting Deno and the Browser](./configuration#targeting-deno-and-the-browser).
### Why are you forcing me to use isolated modules, why can't I use const enums with Deno, why do I need to do export type?
As of Deno 1.5 we defaulted to _isolatedModules_ to `true` and in Deno 1.6 we
removed the options to set it back to `false` via a configuration file. The
_isolatedModules_ option forces the TypeScript compiler to check and emit
TypeScript as if each module would stand on its own. TypeScript has a few _type
directed emits_ in the language at the moment. While not allowing type directed
emits into the language was a design goal for TypeScript, it has happened
anyways. This means that the TypeScript compiler needs to understand the
erasable types in the code to determine what to emit, which when you are trying
to make a fully erasable type system on top of JavaScript, that becomes a
problem.
When people started transpiling TypeScript without `tsc`, these type directed
emits became a problem, since the likes of Babel simply try to erase the types
without needing to understand the types to direct the emit. In the internals of
Deno we have started to use a Rust based emitter which allows us to optionally
skip type checking and generates the bundles for things like `deno bundle`. Like
all transpilers, it doesn't care about the types, it just tries to erase them.
This means in certain situations we cannot support those type directed emits.
So instead of trying to get every user to understand when and how we could
support the type directed emits, we made the decision to disable the use of them
by forcing the _isolatedModules_ option to `true`. This means that even when we
are using the TypeScript compiler to emit the code, it will follow the same
"rules" that the Rust based emitter follows.
This means that certain language features are not supportable. Those features
are:
- Re-exporting of types is ambiguous and requires knowing if the source module
is exporting runtime code or just type information. Therefore, it is
recommended that you use `import type` and `export type` for type only imports
and exports. This will help ensure that when the code is emitted, that all the
types are erased.
- `const enum` is not supported. `const enum`s require type information to
direct the emit, as `const enum`s get written out as hard coded values.
Especially when `const enum`s get exported, they are a type system only
construct.
- `export =` and `import =` are legacy TypeScript syntax which we do not
support.
- Only `declare namespace` is support. Runtime `namespace` is legacy TypeScript
syntax that is not supported.
### Why don't you support language service plugins or transformer plugins?
While `tsc` supports language service plugins, Deno does not. Deno does not
always use the built in TypeScript compiler to do what it does, and the
complexity of adding support for a language service plugin is not feasible.
TypeScript does not support emitter plugins, but there are a few community
projects which _hack_ emitter plugins into TypeScript. First, we wouldn't want
to support something that TypeScript doesn't support, plus we do not always use
the TypeScript compiler for the emit, which would mean we would need to ensure
we supported it in all modes, and the other emitter is written in Rust, meaning
that any emitter plugin for TypeScript wouldn't be available for the Rust
emitter.
The TypeScript in Deno isn't intended to be a fully flexible TypeScript
compiler. Its main purpose is to ensure that TypeScript and JavaScript can run
under Deno. The secondary ability to do TypeScript and JavaScript emitting via
the runtime API `Deno.emit()` is intended to be simple and straight forward and
support a certain set of use cases.
### How do I combine Deno code with non-Deno code in my IDE?
The Deno language server supports the ability to have a "per-resource"
configuration of enabling Deno or not. This also requires a client IDE to
support this ability. For Visual Studio Code the official
[Deno extension](https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno)
supports the vscode concept of
[multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces).
This means you just need to add folders to the workspace and set the
`deno.enable` setting as required on each folder.
For other IDEs, the client extensions needs to support the similar IDE concepts.

View file

@ -1,71 +0,0 @@
## Migrating to and from JavaScript
One of the advantages of Deno is that it treats TypeScript and JavaScript pretty
equally. This might mean that transitioning from JavaScript to TypeScript or
even from TypeScript to JavaScript is something you want to accomplish. There
are several features of Deno that can help with this.
### Type checking JavaScript
You might have some JavaScript that you would like to ensure is more type sound
but you don't want to go through a process of adding type annotations
everywhere.
Deno supports using the TypeScript type checker to type check JavaScript. You
can mark any individual file by adding the check JavaScript pragma to the file:
```js
// @ts-check
```
This will cause the type checker to infer type information about the JavaScript
code and raise any issues as diagnostic issues.
These can be turned on for all JavaScript files in a program by providing a
configuration file with the check JS option enabled:
```json
{
"compilerOptions": {
"checkJs": true
}
}
```
And setting the `--config` option on the command line.
### Using JSDoc in JavaScript
If you are type checking JavaScript, or even importing JavaScript into
TypeScript you can use JSDoc in JavaScript to express more types information
than can just be inferred from the code itself. Deno supports this without any
additional configuration, you simply need to annotate the code in line with the
supported
[TypeScript JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html).
For example to set the type of an array:
```js
/** @type {string[]} */
const a = [];
```
### Skipping type checking
You might have TypeScript code that you are experimenting with, where the syntax
is valid but not fully type safe. You can always bypass type checking for a
whole program by passing the `--no-check`.
You can also skip whole files being type checked, including JavaScript if you
have check JS enabled, by using the no-check pragma:
```js
// @ts-nocheck
```
### Just renaming JS files to TS files
While this might work in some cases, it has some severe limits in Deno. This is
because Deno, by default, runs type checking in what is called _strict mode_.
This means a lot of unclear or ambiguous situations where are not caught in
non-strict mode will result in diagnostics being generated, and JavaScript is
nothing but unclear and ambiguous when it comes to types.

View file

@ -1,159 +0,0 @@
## Overview of TypeScript in Deno
One of the benefits of Deno is that it treats TypeScript as a first class
language, just like JavaScript or Web Assembly, when running code in Deno. What
that means is you can run or import TypeScript without installing anything more
than the Deno CLI.
_But wait a minute, does Deno really run TypeScript?_ you might be asking
yourself. Well, depends on what you mean by run. One could argue that in a
browser you don't actually _run_ JavaScript either. The JavaScript engine in the
browser translates the JavaScript to a series of operation codes, which it then
executes in a sandbox. So it translates JavaScript to something close to
assembly. Even Web Assembly goes through a similar translation, in that Web
Assembly is architecture agnostic while it needs to be translated into the
machine specific operation codes needed for the particular platform architecture
it is running on. So when we say TypeScript is a first class language in Deno,
we mean that we try to make the user experience in authoring and running
TypeScript as easy and straightforward as JavaScript and Web Assembly.
Behind the scenes, we use a combination of technologies, in Rust and JavaScript,
to provide that experience.
### How does it work?
At a high level, Deno converts TypeScript (as well as TSX and JSX) into
JavaScript. It does this via a combination of the
[TypeScript compiler](https://github.com/microsoft/TypeScript), which we build
into Deno, and a Rust library called [swc](https://swc.rs/). When the code has
been type checked and transformed, it is stored in a cache, ready for the next
run without the need to convert it from its source to JavaScript again.
You can see this cache location by running `deno info`:
```shell
> deno info
DENO_DIR location: "/path/to/cache/deno"
Remote modules cache: "/path/to/cache/deno/deps"
TypeScript compiler cache: "/path/to/cache/deno/gen"
```
If you were to look in that cache, you would see a directory structure that
mimics that source directory structure and individual `.js` and `.meta` files
(also potentially `.map` files). The `.js` file is the transformed source file
while the `.meta` file contains meta data we want to cache about the file, which
at the moment contains a _hash_ of the source module that helps us manage cache
invalidation. You might also see a `.buildinfo` file as well, which is a
TypeScript compiler incremental build information file, which we cache to help
speed up type checking.
### Type Checking
One of the main advantages of TypeScript is that you can make code more type
safe, so that what would be syntactically valid JavaScript becomes TypeScript
with warnings about being "unsafe".
In Deno we handle TypeScript in two major ways. We can type check TypeScript,
the default, or you can opt into skipping that checking using the `--no-check`
flag. For example if you had a program you wanted to run, normally you would do
something like this:
```
deno run --allow-net my_server.ts
```
But if you wanted to skip the type checking, you would do something like this:
```
deno run --allow-net --no-check my_server.ts
```
Type checking can take a significant amount of time, especially if you are
working on a code base where you are making a lot of changes. We have tried to
optimise the type checking, but it still comes at a cost. If you just want to
hack at some code, or if you are working in an IDE which is type checking your
code as you author it, using `--no-check` can certainly speed up the process of
running TypeScript in Deno.
### Determining the type of file
Since Deno supports JavaScript, TypeScript, JSX, TSX modules, Deno has to make a
decision about how to treat each of these kinds of files. For local modules,
Deno makes this determination based fully on the extension. When the extension
is absent in a local file, it is assumed to be JavaScript.
For remote modules, the media type (mime-type) is used to determine the type of
the module, where the path of the module is used to help influence the file
type, when it is ambiguous what type of file it is.
For example, a `.d.ts` file and a `.ts` file have different semantics in
TypeScript as well as have different ways they need to be handled in Deno. While
we expect to convert a `.ts` file into JavaScript, a `.d.ts` file contains no
"runnable" code, and is simply describing types (often of "plain" JavaScript).
So when we fetch a remote module, the media type for a `.ts.` and `.d.ts` file
looks the same. So we look at the path, and if we see something that has a path
that ends with `.d.ts` we treat it as a type definition only file instead of
"runnable" TypeScript.
#### Supported media types
The following table provides a list of media types which Deno supports when
identifying the type of file of a remote module:
| Media Type | How File is Handled |
| -------------------------- | ----------------------------------------------------------- |
| `application/typescript` | TypeScript (with path extension influence) |
| `text/typescript` | TypeScript (with path extension influence) |
| `video/vnd.dlna.mpeg-tts` | TypeScript (with path extension influence) |
| `video/mp2t` | TypeScript (with path extension influence) |
| `application/x-typescript` | TypeScript (with path extension influence) |
| `application/javascript` | JavaScript (with path extensions influence) |
| `text/javascript` | JavaScript (with path extensions influence) |
| `application/ecmascript` | JavaScript (with path extensions influence) |
| `text/ecmascript` | JavaScript (with path extensions influence) |
| `application/x-javascript` | JavaScript (with path extensions influence) |
| `application/node` | JavaScript (with path extensions influence) |
| `text/jsx` | JSX |
| `text/tsx` | TSX |
| `text/plain` | Attempt to determine that path extension, otherwise unknown |
| `application/octet-stream` | Attempt to determine that path extension, otherwise unknown |
### Strict by default
Deno type checks TypeScript in _strict_ mode by default, and the TypeScript core
team recommends _strict_ mode as a sensible default. This mode generally enables
features of TypeScript that probably should have been there from the start, but
as TypeScript continued to evolve, would be breaking changes for existing code.
### Mixing JavaScript and TypeScript
By default, Deno does not type check JavaScript. This can be changed, and is
discussed further in [Configuring TypeScript in Deno](./configuration.md). Deno
does support JavaScript importing TypeScript and TypeScript importing
JavaScript, in complex scenarios.
An important note though is that when type checking TypeScript, by default Deno
will "read" all the JavaScript in order to be able to evaluate how it might have
an impact on the TypeScript types. The type checker will do the best it can to
figure out what the types are of the JavaScript you import into TypeScript,
including reading any JSDoc comments. Details of this are discussed in detail in
the [Types and type declarations](./types.md) section.
### Diagnostics are terminal
While `tsc` by default will still emit JavaScript when run while encountering
diagnostic (type checking) issues, Deno currently treats them as terminal. It
will halt on these warnings, not cache any of the emitted files, and exit the
process.
In order to avoid this, you will either need to resolve the issue, utilise the
`// @ts-ignore` or `// @ts-expect-error` pragmas, or utilise `--no-check` to
bypass type checking all together.
### Type resolution
One of the core design principles of Deno is to avoid non-standard module
resolution, and this applies to type resolution as well. If you want to utilise
JavaScript that has type definitions (e.g. a `.d.ts` file), you have to
explicitly tell Deno about this. The details of how this is accomplished are
covered in the [Types and type declarations](./types.md) section.

View file

@ -1,270 +0,0 @@
## Runtime compiler APIs
> ⚠️ The runtime compiler API is unstable (and requires the `--unstable` flag to
> be used to enable it).
The runtime compiler API allows access to the internals of Deno to be able to
type check, transpile and bundle JavaScript and TypeScript. As of Deno 1.7,
several disparate APIs we consolidated into a single API, `Deno.emit()`.
### Deno.emit()
The API is defined in the `Deno` namespace as:
```ts
function emit(
rootSpecifier: string | URL,
options?: EmitOptions,
): Promise<EmitResult>;
```
The emit options are defined in the `Deno` namespace as:
```ts
interface EmitOptions {
/** Indicate that the source code should be emitted to a single file
* JavaScript bundle that is a single ES module (`"module"`) or a single
* file self contained script we executes in an immediately invoked function
* when loaded (`"classic"`). */
bundle?: "module" | "classic";
/** If `true` then the sources will be typed checked, returning any
* diagnostic errors in the result. If `false` type checking will be
* skipped. Defaults to `true`.
*
* *Note* by default, only TypeScript will be type checked, just like on
* the command line. Use the `compilerOptions` options of `checkJs` to
* enable type checking of JavaScript. */
check?: boolean;
/** A set of options that are aligned to TypeScript compiler options that
* are supported by Deno. */
compilerOptions?: CompilerOptions;
/** An [import-map](https://deno.land/manual/linking_to_external_code/import_maps#import-maps)
* which will be applied to the imports. */
importMap?: ImportMap;
/** An absolute path to an [import-map](https://deno.land/manual/linking_to_external_code/import_maps#import-maps).
* Required to be specified if an `importMap` is specified to be able to
* determine resolution of relative paths. If a `importMap` is not
* specified, then it will assumed the file path points to an import map on
* disk and will be attempted to be loaded based on current runtime
* permissions.
*/
importMapPath?: string;
/** A record of sources to use when doing the emit. If provided, Deno will
* use these sources instead of trying to resolve the modules externally. */
sources?: Record<string, string>;
}
```
The emit result is defined in the `Deno` namespace as:
```ts
interface EmitResult {
/** Diagnostic messages returned from the type checker (`tsc`). */
diagnostics: Diagnostic[];
/** Any emitted files. If bundled, then the JavaScript will have the
* key of `deno:///bundle.js` with an optional map (based on
* `compilerOptions`) in `deno:///bundle.js.map`. */
files: Record<string, string>;
/** An optional array of any compiler options that were ignored by Deno. */
ignoredOptions?: string[];
/** An array of internal statistics related to the emit, for diagnostic
* purposes. */
stats: Array<[string, number]>;
}
```
The API is designed to support several use cases, which are described in the
sections below.
### Using external sources
Using external sources, both local and remote, `Deno.emit()` can behave like
`deno cache` does on the command line, resolving those external dependencies,
type checking those dependencies, and providing an emitted output.
By default, `Deno.emit()` will utilise external resources. The _rootSpecifier_
supplied as the first argument will determine what module will be used as the
root. The root module is similar to what you would provide on the command line.
For example if you did:
```
> deno run mod.ts
```
You could do something similar with `Deno.emit()`:
```ts
try {
const { files } = await Deno.emit("mod.ts");
for (const [fileName, text] of Object.entries(files)) {
console.log(`emitted ${fileName} with a length of ${text.length}`);
}
} catch (e) {
// something went wrong, inspect `e` to determine
}
```
`Deno.emit()` will use the same on disk cache for remote modules that the
standard CLI does, and it inherits the permissions and cache options of the
process that executes it.
If the _rootSpecifier_ is a relative path, then the current working directory of
the Deno process will be used to resolve the specifier. (Not relative to the
current module!)
The _rootSpecifier_ can be a string file path, a string URL, or a URL.
`Deno.emit()` supports the same protocols for URLs that Deno supports, which are
currently `file`, `http`, `https`, and `data`.
### Providing sources
Instead of resolving modules externally, you can provide `Deno.emit()` with the
sources directly. This is especially useful for a server to be able to provide
_on demand_ compiling of code supplied by a user, where the Deno process has
collected all the code it wants to emit.
The sources are passed in the _sources_ property of the `Deno.emit()` _options_
argument:
```ts
const { files } = await Deno.emit("/mod.ts", {
sources: {
"/mod.ts": `import * as a from "./a.ts";\nconsole.log(a);\n`,
"/a.ts": `export const a: Record<string, string> = {};\n`,
},
});
```
When sources are provided, Deno will no longer look externally and will try to
resolve all modules from within the map of sources provided, though the module
resolution follow the same rules as if the modules were external. For example
all module specifiers need their full filename. Also, because there are no media
types, if you are providing remote URLs in the sources, the path should end with
the appropriate extension, so that Deno can determine how to handle the file.
### Type checking and emitting
By default, `Deno.emit()` will type check any TypeScript (and TSX) it
encounters, just like on the command line. It will also attempt to transpile
JSX, but will leave JavaScript "alone". This behavior can be changed by changing
the compiler options. For example if you wanted Deno to type check your
JavaScript as well, you could set the _checkJs_ option to `true` in the compiler
options:
```ts
const { files, diagnostics } = await Deno.emit("./mod.js", {
compilerOptions: {
checkJs: true,
},
});
```
The `Deno.emit()` result provides any diagnostic messages about the code
supplied. On the command line, any diagnostic messages get logged to stderr and
the Deno process terminates, but with `Deno.emit()` they are returned to the
caller.
Typically you will want to check if there are any diagnostics and handle them
appropriately. You can introspect the diagnostics individually, but there is a
handy formatting function available to make it easier to potentially log the
diagnostics to the console for the user called `Deno.formatDiagnostics()`:
```ts
const { files, diagnostics } = await Deno.emit("./mod.ts");
if (diagnostics.length) {
// there is something that impacted the emit
console.warn(Deno.formatDiagnostics(diagnostics));
}
```
### Bundling
`Deno.emit()` is also capable of providing output similar to `deno bundle` on
the command line. This is enabled by setting the _bundle_ option to `"module"`
or `"classic"`. Currently Deno supports bundling as a single file ES module
(`"module"`) or a single file self contained legacy script (`"classic"`).
```ts
const { files, diagnostics } = await Deno.emit("./mod.ts", {
bundle: "module",
});
```
The _files_ of the result will contain a single key named `deno:///bundle.js` of
which the value with be the resulting bundle.
> ⚠️ Just like with `deno bundle`, the bundle will not include things like
> dynamic imports or worker scripts, and those would be expected to be resolved
> and available when the code is run.
### Import maps
`Deno.emit()` supports import maps as well, just like on the command line. This
is a really powerful feature that can be used even more effectively to emit and
bundle code.
Because of the way import maps work, when using with `Deno.emit()` you also have
to supply an absolute URL for the import map. This allows Deno to resolve any
relative URLs specified in the import map. This needs to be supplied even if the
import map doesn't contain any relative URLs. The URL does not need to really
exist, it is just feed to the API.
An example might be that I want to use a bare specifier to load a special
version of _lodash_ I am using with my project. I could do the following:
```ts
const { files } = await Deno.emit("mod.ts", {
bundle: "module",
importMap: {
imports: {
"lodash": "https://deno.land/x/lodash",
},
},
importMapPath: "file:///import-map.json",
});
```
> ⚠️ If you are not bundling your code, the emitted code specifiers do not get
> rewritten, that means that whatever process will consume the code, Deno or a
> browser for example, would need to support import maps and have that map
> available at runtime.
### Skip type checking/transpiling only
`Deno.emit()` supports skipping type checking similar to the `--no-check` flag
on the command line. This is accomplished by setting the _check_ property to
`false`:
```ts
const { files } = await Deno.emit("./mod.ts", {
check: false,
});
```
Setting _check_ to `false` will instruct Deno to not utilise the TypeScript
compiler to type check the code and emit it, instead only transpiling the code
from within Deno. This can be significantly quicker than doing the full type
checking.
### Compiler options
`Deno.emit()` supports quite a few compiler options that can impact how code is
type checked and emitted. They are similar to the options supported by a
`tsconfig.json` in the `compilerOptions` section, but there are several options
that are not supported. This is because they are either meaningless in Deno or
would cause Deno to not be able to work properly. The defaults for `Deno.emit()`
are the same defaults that are on the command line. The options are
[documented here](https://doc.deno.land/builtin/unstable#Deno.CompilerOptions)
along with their default values and are built into the Deno types.
If you are type checking your code, the compiler options will be type checked
for you, but if for some reason you are either dynamically providing the
compiler options or are not type checking, then the result of `Deno.emit()` will
provide you with an array of _ignoredOptions_ if there are any.
> ⚠️ we have only tried to disable/remove options that we know won't work, that
> does not mean we extensively test all options in all configurations under
> `Deno.emit()`. You may find that some behaviors do not match what you can get
> from `tsc` or are otherwise incompatible. If you do find something that
> doesn't work, please do feel free to raise an issue.

View file

@ -1,290 +0,0 @@
## Types and Type Declarations
One of the design principles of Deno is no non-standard module resolution. When
TypeScript is type checking a file, it only cares about the types for the file,
and the `tsc` compiler has a lot of logic to try to resolve those types. By
default, it expects _ambiguous_ module specifiers with an extension, and will
attempt to look for the file under the `.ts` specifier, then `.d.ts`, and
finally `.js` (plus a whole other set of logic when the module resolution is set
to `"node"`). Deno deals with explicit specifiers.
This can cause a couple problems though. For example, let's say I want to
consume a TypeScript file that has already been transpiled to JavaScript along
with a type definition file. So I have `mod.js` and `mod.d.ts`. If I try to
import `mod.js` into Deno, it will only do what I ask it to do, and import
`mod.js`, but that means my code won't be as well type checked as if TypeScript
was considering the `mod.d.ts` file in place of the `mod.js` file.
In order to support this in Deno, Deno has two solutions, of which there is a
variation of a solution to enhance support. The two main situations you come
across would be:
- As the importer of a JavaScript module, I know what types should be applied to
the module.
- As the supplier of the JavaScript module, I know what types should be applied
to the module.
The latter case is the better case, meaning you as the provider or host of the
module, everyone can consume it without having to figure out how to resolve the
types for the JavaScript module, but when consuming modules that you may not
have direct control over, the ability to do the former is also required.
### Providing types when importing
If you are consuming a JavaScript module and you have either created types (a
`.d.ts` file) or have otherwise obtained the types, you want to use, you can
instruct Deno to use that file when type checking instead of the JavaScript file
using the `@deno-types` compiler hint. `@deno-types` needs to be a single line
double slash comment, where when used impacts the next import or re-export
statement.
For example if I have a JavaScript modules `coolLib.js` and I had a separate
`coolLib.d.ts` file that I wanted to use, I would import it like this:
```ts
// @deno-types="./coolLib.d.ts"
import * as coolLib from "./coolLib.js";
```
When type checking `coolLib` and your usage of it in the file, the
`coolLib.d.ts` types will be used instead of looking at the JavaScript file.
The pattern matching for the compiler hint is somewhat forgiving and will accept
quoted and non-question values for the specifier as well as it accepts
whitespace before and after the equals sign.
### Providing types when hosting
If you are in control of the source code of the module, or you are in control of
how the file is hosted on a web server, there are two ways to inform Deno of the
types for a given module, without requiring the importer to do anything special.
#### Using the triple-slash reference directive
Deno supports using the triple-slash reference `types` directive, which adopts
the reference comment used by TypeScript in TypeScript files to _include_ other
files and applies it only to JavaScript files.
For example, if I had created `coolLib.js` and along side of it I had created my
type definitions for my library in `coolLib.d.ts` I could do the following in
the `coolLib.js` file:
```js
/// <reference types="./coolLib.d.ts" />
// ... the rest of the JavaScript ...
```
When Deno encounters this directive, it would resolve the `./coolLib.d.ts` file
and use that instead of the JavaScript file when TypeScript was type checking
the file, but still load the JavaScript file when running the program.
> _Note_ this is a repurposed directive for TypeScript that only applies to
> JavaScript files. Using the triple-slash reference directive of `types` in a
> TypeScript file works under Deno as well, but has essentially the same
> behavior as the `path` directive.
#### Using X-TypeScript-Types header
Similar to the triple-slash directive, Deno supports a header for remote modules
that instructs Deno where to locate the types for a given module. For example, a
response for `https://example.com/coolLib.js` might look something like this:
```
HTTP/1.1 200 OK
Content-Type: application/javascript; charset=UTF-8
Content-Length: 648
X-TypeScript-Types: ./coolLib.d.ts
```
When seeing this header, Deno would attempt to retrieve
`https://example.com/coolLib.d.ts` and use that when type checking the original
module.
### Using ambient or global types
Overall it is better to use module/UMD type definitions with Deno, where a
module expressly imports the types it depends upon. Modular type definitions can
express
[augmentation of the global scope](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html)
via the `declare global` in the type definition. For example:
```ts
declare global {
var AGlobalString: string;
}
```
This would make `AGlobalString` available in the global namespace when importing
the type definition.
In some cases though, when leveraging other existing type libraries, it may not
be possible to leverage modular type definitions. Therefore there are ways to
include arbitrary type definitions when type checking programmes.
#### Using a triple-slash directive
This option couples the type definitions to the code itself. By adding a
triple-slash `types` directive near the type of a module, type checking the file
will include the type definition. For example:
```ts
/// <reference types="./types.d.ts" />
```
The specifier provided is resolved just like any other specifier in Deno, which
means it requires an extension, and is relative to the module referencing it. It
can be a fully qualified URL as well:
```ts
/// <reference types="https://deno.land/x/pkg@1.0.0/types.d.ts" />
```
#### Using a `tsconfig.json` file
Another option is to use a `tsconfig.json` file that is configured to include
the type definitions, by supplying a `"types"` value to the `"compilerOptions"`.
For example:
```json
{
"compilerOptions": {
"types": [
"./types.d.ts",
"https://deno.land/x/pkg@1.0.0/types.d.ts",
"/Users/me/pkg/types.d.ts"
]
}
}
```
Like the triple-slash reference above, the specifier supplied in the `"types"`
array will be resolved like other specifiers in Deno. In the case of relative
specifiers, it will be resolved relative to the path to the `tsconfig.json`.
### Type Checking Web Workers
When Deno loads a TypeScript module in a web worker, it will automatically type
check the module and its dependencies against the Deno web worker library. This
can present a challenge in other contexts like `deno cache`, `deno bundle`, or
in editors. There are a couple of ways to instruct Deno to use the worker
libraries instead of the standard Deno libraries.
#### Using triple-slash directives
This option couples the library settings with the code itself. By adding the
following triple-slash directives near the top of the entry point file for the
worker script, Deno will now type check it as a Deno worker script, irrespective
of how the module is analyzed:
```ts
/// <reference no-default-lib="true" />
/// <reference lib="deno.worker" />
```
The first directive ensures that no other default libraries are used. If this is
omitted, you will get some conflicting type definitions, because Deno will try
to apply the standard Deno library as well. The second instructs Deno to apply
the built in Deno worker type definitions plus dependent libraries (like
`"esnext"`).
When you run a `deno cache` or `deno bundle` command or use an IDE which uses
the Deno language server, Deno should automatically detect these directives and
apply the correct libraries when type checking.
The one disadvantage of this, is that it makes the code less portable to other
non-Deno platforms like `tsc`, as it is only Deno which has the `"deno.worker"`
library built into it.
#### Using a `tsconfig.json` file
Another option is to use a `tsconfig.json` file that is configured to apply the
library files. A minimal file that would work would look something like this:
```json
{
"compilerOptions": {
"target": "esnext",
"lib": ["deno.worker"]
}
}
```
Then when running a command on the command line, you would need to pass the
`--config tsconfig.json` argument, or if you are using an IDE which leverages
the Deno language server, set the `deno.config` setting.
If you also have non-worker scripts, you will either need to omit the `--config`
argument, or have one that is configured to meet the needs of your non-worker
scripts.
### Important points
#### Type declaration semantics
Type declaration files (`.d.ts` files) follow the same semantics as other files
in Deno. This means that declaration files are assumed to be module declarations
(_UMD declarations_) and not ambient/global declarations. It is unpredictable
how Deno will handle ambient/global declarations.
In addition, if a type declaration imports something else, like another `.d.ts`
file, its resolution follow the normal import rules of Deno. For a lot of the
`.d.ts` files that are generated and available on the web, they may not be
compatible with Deno.
To overcome this problem, some solution providers, like the
[Skypack CDN](https://www.skypack.dev/), will automatically bundle type
declarations just like they provide bundles of JavaScript as ESM.
#### Deno Friendly CDNs
There are CDNs which host JavaScript modules that integrate well with Deno.
- [Skypack.dev](https://docs.skypack.dev/skypack-cdn/code/deno) is a CDN which
provides type declarations (via the `X-TypeScript-Types` header) when you
append `?dts` as a query string to your remote module import statements. For
example:
```ts
import React from "https://cdn.skypack.dev/react?dts";
```
### Behavior of JavaScript when type checking
If you import JavaScript into TypeScript in Deno and there are no types, even if
you have `checkJs` set to `false` (the default for Deno), the TypeScript
compiler will still access the JavaScript module and attempt to do some static
analysis on it, to at least try to determine the shape of the exports of that
module to validate the import in the TypeScript file.
This is usually never a problem when trying to import a "regular" ES module, but
in some cases if the module has special packaging, or is a global _UMD_ module,
TypeScript's analysis of the module can fail and cause misleading errors. The
best thing to do in this situation is provide some form of types using one of
the methods mention above.
#### Internals
While it isn't required to understand how Deno works internally to be able to
leverage TypeScript with Deno well, it can help to understand how it works.
Before any code is executed or compiled, Deno generates a module graph by
parsing the root module, and then detecting all of its dependencies, and then
retrieving and parsing those modules, recursively, until all the dependencies
are retrieved.
For each dependency, there are two potential "slots" that are used. There is the
code slot and the type slot. As the module graph is filled out, if the module is
something that is or can be emitted to JavaScript, it fills the code slot, and
type only dependencies, like `.d.ts` files fill the type slot.
When the module graph is built, and there is a need to type check the graph,
Deno starts up the TypeScript compiler and feeds it the names of the modules
that need to be potentially emitted as JavaScript. During that process, the
TypeScript compiler will request additional modules, and Deno will look at the
slots for the dependency, offering it the type slot if it is filled before
offering it the code slot.
This means when you import a `.d.ts` module, or you use one of the solutions
above to provide alternative type modules for JavaScript code, that is what is
provided to TypeScript instead when resolving the module.