Multi page manual (#5110)

This commit is contained in:
Luca Casonato 2020-05-07 00:21:13 +02:00 committed by GitHub
parent 846c049c9b
commit 34ec3b2254
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1994 additions and 1695 deletions

60
docs/contributing.md Normal file
View File

@ -0,0 +1,60 @@
# Contributing
- Read the [style guide](style_guide.md).
- Progress towards future releases is tracked
[here](https://github.com/denoland/deno/milestones).
- Please don't make [the benchmarks](https://deno.land/benchmarks.html) worse.
- Ask for help in the [community chat room](https://discord.gg/TGMHGv6).
- If you are going to work on an issue, mention so in the issue comments
_before_ you start working on the issue.
## Development
Instructions on how to build from source can be found
[here](./building-from-source).
## Submitting a Pull Request
Before submitting, please make sure the following is done:
1. That there is a related issue and it is referenced in the PR text.
2. There are tests that cover the changes.
3. Ensure `cargo test` passes.
4. Format your code with `tools/format.py`
5. Make sure `./tools/lint.py` passes.
## Changes to `third_party`
[`deno_third_party`](https://github.com/denoland/deno_third_party) contains most
of the external code that Deno depends on, so that we know exactly what we are
executing at any given time. It is carefully maintained with a mixture of manual
labor and private scripts. It's likely you will need help from @ry or
@piscisaureus to make changes.
## 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).
## 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";
```

View File

@ -0,0 +1,50 @@
## Internal details
### Deno and Linux analogy
| **Linux** | **Deno** |
| ------------------------------: | :------------------------------- |
| Processes | Web Workers |
| Syscalls | Ops |
| File descriptors (fd) | [Resource ids (rid)](#resources) |
| Scheduler | Tokio |
| Userland: libc++ / glib / boost | https://deno.land/std/ |
| /proc/\$\$/stat | [Deno.metrics()](#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
const { resources, close } = Deno;
console.log(resources());
// { 0: "stdin", 1: "stdout", 2: "stderr" }
close(0);
console.log(resources());
// { 1: "stdout", 2: "stderr" }
```
#### Metrics
Metrics is Deno's internal counter for various statistics.
```shell
> console.table(Deno.metrics())
┌──────────────────┬────────┐
│ (index) │ Values │
├──────────────────┼────────┤
│ opsDispatched │ 9 │
│ opsCompleted │ 9 │
│ bytesSentControl │ 504 │
│ bytesSentData │ 0 │
│ bytesReceived │ 856 │
└──────────────────┴────────┘
```
### Schematic diagram
![architectural schematic](https://deno.land/images/schematic_v0.2.png)

View File

@ -0,0 +1,89 @@
## 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:
```bash
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:
```bash
git config --global core.symlinks true
git clone --recurse-submodules https://github.com/denoland/deno.git
```
### Prerequisites
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 2](https://www.python.org/downloads). Ensure that a suffix-less
`python`/`python.exe` exists in your `PATH` and it refers to Python 2,
[not 3](https://github.com/denoland/deno/issues/464#issuecomment-411795578).
For Linux users glib-2.0 development files must also be installed. (On Ubuntu,
run `apt install libglib2.0-dev`.)
Mac users must have [XCode](https://developer.apple.com/xcode/) installed.
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:
```bash
# Build:
cargo build -vv
# Build errors? Ensure you have latest master and try building again, or if that doesn't work try:
cargo clean && cargo build -vv
# Run:
./target/debug/deno cli/tests/002_hello.ts
```

View File

@ -0,0 +1,171 @@
## Testing and Tools
### Tests
Test `deno`:
```bash
# Run the whole suite:
cargo test
# Only test cli/js/:
cargo test js_unit_tests
```
Test `std/`:
```bash
cargo test std_tests
```
### Lint and format
Lint the code:
```bash
./tools/lint.py
```
Format the code:
```bash
./tools/format.py
```
### Profiling
To start profiling,
```sh
# Make sure we're only building release.
# Build deno and V8's d8.
ninja -C target/release d8
# Start the program we want to benchmark with --prof
./target/release/deno run tests/http_bench.ts --allow-net --v8-flags=--prof &
# Exercise it.
third_party/wrk/linux/wrk http://localhost:4500/
kill `pgrep deno`
```
V8 will write a file in the current directory that looks like this:
`isolate-0x7fad98242400-v8.log`. To examine this file:
```sh
D8_PATH=target/release/ ./third_party/v8/tools/linux-tick-processor
isolate-0x7fad98242400-v8.log > prof.log
# on macOS, use ./third_party/v8/tools/mac-tick-processor instead
```
`prof.log` will contain information about tick distribution of different calls.
To view the log with Web UI, generate JSON file of the log:
```sh
D8_PATH=target/release/ ./third_party/v8/tools/linux-tick-processor
isolate-0x7fad98242400-v8.log --preprocess > prof.json
```
Open `third_party/v8/tools/profview/index.html` in your browser, and select
`prof.json` to view the distribution graphically.
Useful V8 flags during profiling:
- --prof
- --log-internal-timer-events
- --log-timer-events
- --track-gc
- --log-source-code
- --track-gc-object-stats
To learn more about `d8` and profiling, check out the following links:
- [https://v8.dev/docs/d8](https://v8.dev/docs/d8)
- [https://v8.dev/docs/profile](https://v8.dev/docs/profile)
### Debugging with LLDB
We can use LLDB to debug Deno.
```shell
$ lldb -- target/debug/deno run tests/worker.js
> run
> bt
> up
> up
> l
```
To debug Rust code, we can use `rust-lldb`. It should come with `rustc` and is a
wrapper around LLDB.
```shell
$ rust-lldb -- ./target/debug/deno run --allow-net tests/http_bench.ts
# On macOS, you might get warnings like
# `ImportError: cannot import name _remove_dead_weakref`
# In that case, use system python by setting PATH, e.g.
# PATH=/System/Library/Frameworks/Python.framework/Versions/2.7/bin:$PATH
(lldb) command script import "/Users/kevinqian/.rustup/toolchains/1.36.0-x86_64-apple-darwin/lib/rustlib/etc/lldb_rust_formatters.py"
(lldb) type summary add --no-value --python-function lldb_rust_formatters.print_val -x ".*" --category Rust
(lldb) type category enable Rust
(lldb) target create "../deno/target/debug/deno"
Current executable set to '../deno/target/debug/deno' (x86_64).
(lldb) settings set -- target.run-args "tests/http_bench.ts" "--allow-net"
(lldb) b op_start
(lldb) r
```
### V8 flags
V8 has many many internal command-line flags.
```shell
# list available v8 flags
$ deno --v8-flags=--help
# example for applying multiple flags
$ deno --v8-flags=--expose-gc,--use-strict
```
Particularly useful ones:
```
--async-stack-trace
```
### Continuous Benchmarks
See our benchmarks [over here](https://deno.land/benchmarks)
The benchmark chart supposes
https://github.com/denoland/benchmark_data/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;
};
}
```

View File

11
docs/embedding_deno.md Normal file
View File

@ -0,0 +1,11 @@
# 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 -->

4
docs/examples.md Normal file
View File

@ -0,0 +1,4 @@
# Examples
In this chapter you can find some example programs that you can use to learn
more about the runtime.

View File

@ -0,0 +1,22 @@
## File server
This one serves a local directory in HTTP.
```bash
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
```
Run it:
```shell
$ file_server .
Downloading https://deno.land/std/http/file_server.ts...
[...]
HTTP server listening on http://0.0.0.0:4500/
```
And if you ever want to upgrade to the latest published version:
```shell
$ file_server --reload
```

View File

@ -0,0 +1,35 @@
## Handle OS Signals
> This program makes use of an unstable Deno feature. Learn more about
> [unstable features](../../runtime/unstable).
[API Reference](https://deno.land/typedoc/index.html#signal)
You can use `Deno.signal()` function for handling OS signals.
```
for await (const _ of Deno.signal(Deno.Signal.SIGINT)) {
console.log("interrupted!");
}
```
`Deno.signal()` also works as a promise.
```
await Deno.signal(Deno.Singal.SIGINT);
console.log("interrupted!");
```
If you want to stop watching the signal, you can use `dispose()` method of the
signal object.
```
const sig = Deno.signal(Deno.Signal.SIGINT);
setTimeout(() => { sig.dispose(); }, 5000);
for await (const _ of sig) {
console.log("interrupted");
}
```
The above for-await loop exits after 5 seconds when sig.dispose() is called.

View File

@ -0,0 +1,28 @@
## Inspecting and revoking permissions
> This program makes use of an unstable Deno feature. Learn more about
> [unstable features](../../runtime/unstable).
Sometimes a program may want to revoke previously granted permissions. When a
program, at a later stage, needs those permissions, it will fail.
```ts
// lookup a permission
const status = await Deno.permissions.query({ name: "write" });
if (status.state !== "granted") {
throw new Error("need write permission");
}
const log = await Deno.open("request.log", "a+");
// revoke some permissions
await Deno.permissions.revoke({ name: "read" });
await Deno.permissions.revoke({ name: "write" });
// use the log file
const encoder = new TextEncoder();
await log.write(encoder.encode("hello\n"));
// this will fail.
await Deno.remove("request.log");
```

View File

@ -0,0 +1,74 @@
## Run subprocess
[API Reference](https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts#Deno.run)
Example:
```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
```
Here a function is assigned to `window.onload`. This function is called after
the main script is loaded. This is the same as
[onload](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload)
of the browsers, and it can be used as the main entrypoint.
By default when you use `Deno.run()` subprocess inherits `stdin`, `stdout` and
`stderr` of parent process. If you want to communicate with started subprocess
you can use `"piped"` option.
```ts
const fileNames = Deno.args;
const p = Deno.run({
cmd: [
"deno",
"run",
"--allow-read",
"https://deno.land/std/examples/cat.ts",
...fileNames,
],
stdout: "piped",
stderr: "piped",
});
const { code } = await p.status();
if (code === 0) {
const rawOutput = await p.output();
await Deno.stdout.write(rawOutput);
} else {
const rawError = await p.stderrOutput();
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)
```

41
docs/examples/tcp_echo.md Normal file
View File

@ -0,0 +1,41 @@
## TCP echo server
This is an example of a simple server which accepts connections on port 8080,
and returns to the client anything it sends.
```ts
const listener = Deno.listen({ port: 8080 });
console.log("listening on 0.0.0.0:8080");
for await (const conn of listener) {
Deno.copy(conn, conn);
}
```
When this program is started, it throws PermissionDenied error.
```shell
$ deno run https://deno.land/std/examples/echo_server.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8080", run again with the --allow-net flag
► $deno$/dispatch_json.ts:40:11
at DenoError ($deno$/errors.ts:20:5)
...
```
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/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 back,
without further complexity.

View File

@ -0,0 +1,10 @@
## Testing if current file is the main program
To test if the current script has been executed as the main input to the program
check `import.meta.main`.
```ts
if (import.meta.main) {
console.log("main");
}
```

24
docs/examples/unix_cat.md Normal file
View File

@ -0,0 +1,24 @@
## An implementation of the unix "cat" program
In this program each command-line argument is assumed to be a filename, the file
is opened, and printed to stdout.
```ts
for (let i = 0; i < Deno.args.length; i++) {
let filename = Deno.args[i];
let file = await Deno.open(filename);
await Deno.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/examples/cat.ts /etc/passwd
```

9
docs/getting_started.md Normal file
View File

@ -0,0 +1,9 @@
# Getting Started
In this chapter we'll discuss:
- Installing Deno
- Running a simple `Hello World` script
- Writing our own script
- Using Deno with TypeScript
- Using WebAssembly

View File

@ -0,0 +1,144 @@
## First steps
This page contains some simple examples that can 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 folow 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 and TypeScript and tries to be web compatible
and use modern features whereever possible.
Because of this browser compatibility a simple `Hello World` program is actually
no different to one you can run in the browser:
```typescript
console.log("Welcome to Deno 🦕");
```
Try the program:
```bash
deno run https://deno.land/std/examples/welcome.ts
```
### Making an HTTP request
Something a lot of programs do is fetching data from from a webserver via an
HTTP request. Lets write a small program that fetches a file and prints the
content 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:
```typescript
const url = Deno.args[0];
const res = await fetch(url);
const body = new Uint8Array(await res.arrayBuffer());
await Deno.stdout.write(body);
```
Lets walk through what this application does:
1. We get the first argument passed to the application and store it in the
variable `url`.
2. We make a request to the url specified, await the response, and store it in a
variable named `res`.
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, convert it into a
[`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)
and store it in the variable `body`.
4. We write the contents of the `body` variable to `stdout`.
Try it out:
```bash
deno run https://deno.land/std/examples/curl.ts https://example.com
```
You will see that 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 that is secure by default. This means that you need to explicitly give
programs the permission to do certain 'privledged' actions like network access.
Try it out again with the correct permission flag:
```bash
deno run --allow-net=example.com https://deno.land/std/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/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts).
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
for (let i = 0; i < Deno.args.length; i++) {
let filename = Deno.args[i];
let file = await Deno.open(filename);
await Deno.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:
```bash
deno run --allow-read https://deno.land/std/examples/cat.ts /etc/passwd
```
### A simple TCP server
This is an example of a simple server which accepts connections on port 8080,
and returns to the client anything it sends.
```ts
const listener = Deno.listen({ port: 8080 });
console.log("listening on 0.0.0.0:8080");
for await (const conn of listener) {
Deno.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/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 back,
without further complexity.
### More examples
You can find more examples, like an HTTP file server, in the `Examples` chapter.

View File

@ -0,0 +1,70 @@
## 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 [Cargo](https://crates.io/crates/deno) (Windows, macOS, Linux):
```shell
cargo install deno
```
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.
### 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. Use
`deno help <subcommand>` for subcommand-specific flags.
### Updating
To update a previously installed version of Deno, you can run `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.
### Building from source
Information about how to build from source can be found in the `Contributing`
chapter.

View File

@ -0,0 +1,37 @@
## Permissions
<!-- TODO(lucacasonato): what are permissions -->
<!-- TODO(lucacasonato): description of all permissions -->
### Permissions whitelist
Deno also provides permissions whitelist.
This is an example to restrict file system access by whitelist.
```shell
$ deno run --allow-read=/usr https://deno.land/std/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)
...
```
You can grant read permission under `/etc` dir
```shell
$ deno run --allow-read=/etc https://deno.land/std/examples/cat.ts /etc/passwd
```
`--allow-write` works same as `--allow-read`.
This is an example to restrict host.
```ts
const result = await fetch("https://deno.land/");
```
```shell
$ deno run --allow-net=deno.land https://deno.land/std/examples/curl.ts https://deno.land/
```

View File

@ -0,0 +1,60 @@
## Setup 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/.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:
```shell
deno completions bash > /usr/local/etc/bash_completion.d/deno.bash
source /usr/local/etc/bash_completion.d/deno.bash
```
### Editors and IDEs
Because Deno requires the use of file extensions for module imports and allows
http imports, and the 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](https://marketplace.visualstudio.com/items?itemName=axetroy.vscode-deno)
by [@axetroy](https://github.com/axetroy).
Support for JetBrains IDEs is not yet available, but you can follow and upvote
these issues to stay up to date:
- https://youtrack.jetbrains.com/issue/WEB-41607
- https://youtrack.jetbrains.com/issue/WEB-42983
- https://youtrack.jetbrains.com/issue/WEB-31667
If you don't see your favorite IDE on this list, maybe you can develop an
extension. Our [community Discord group](https://discord.gg/TGMHGv6) can give
you some pointers on where to get started.

View File

@ -0,0 +1,151 @@
## Using TypeScript
<!-- TODO(lucacasonato): text on 'just import .ts' -->
### Using external type definitions
Deno supports both JavaScript and TypeScript as first class languages at
runtime. This means it requires fully qualified module names, including the
extension (or a server providing the correct media type). In addition, Deno has
no "magical" module resolution.
The out of the box TypeScript compiler though relies on both extension-less
modules and the Node.js module resolution logic to apply types to JavaScript
modules.
In order to bridge this gap, Deno supports three ways of referencing type
definition files without having to resort to "magic" resolution.
#### Compiler hint
If you are importing a JavaScript module, and you know where the type definition
for that module is located, you can specify the type definition at import. This
takes the form of a compiler hint. Compiler hints inform Deno the location of
`.d.ts` files and the JavaScript code that is imported that they relate to. The
hint is `@deno-types` and when specified the value will be used in the compiler
instead of the JavaScript module. For example, if you had `foo.js`, but you know
that along side of it was `foo.d.ts` which was the types for the file, the code
would look like this:
```ts
// @deno-types="./foo.d.ts"
import * as foo from "./foo.js";
```
The value follows the same resolution logic as importing a module, meaning the
file needs to have an extension and is relative to the current module. Remote
specifiers are also allowed.
The hint affects the next `import` statement (or `export ... from` statement)
where the value of the `@deno-types` will be substituted at compile time instead
of the specified module. Like in the above example, the Deno compiler will load
`./foo.d.ts` instead of `./foo.js`. Deno will still load `./foo.js` when it runs
the program.
#### Triple-slash reference directive in JavaScript files
If you are hosting modules which you want to be consumed by Deno, and you want
to inform Deno about the location of the type definitions, you can utilise a
triple-slash directive in the actual code. For example, if you have a JavaScript
module and you would like to provide Deno with the location of the type
definitions which happen to be alongside that file, your JavaScript module named
`foo.js` might look like this:
```js
/// <reference types="./foo.d.ts" />
export const foo = "foo";
```
Deno will see this, and the compiler will use `foo.d.ts` when type checking the
file, though `foo.js` will be loaded at runtime. The resolution of the value of
the directive follows the same resolution logic as importing a module, meaning
the file needs to have an extension and is relative to the current file. Remote
specifiers are also allowed.
#### X-TypeScript-Types custom header
If you are hosting modules which you want to be consumed by Deno, and you want
to inform Deno the location of the type definitions, you can use a custom HTTP
header of `X-TypeScript-Types` to inform Deno of the location of that file.
The header works in the same way as the triple-slash reference mentioned above,
it just means that the content of the JavaScript file itself does not need to be
modified, and the location of the type definitions can be determined by the
server itself.
**Not all type definitions are supported.**
Deno will use the compiler hint to load the indicated `.d.ts` files, but some
`.d.ts` files contain unsupported features. Specifically, some `.d.ts` files
expect to be able to load or reference type definitions from other packages
using the module resolution logic. For example a type reference directive to
include `node`, expecting to resolve to some path like
`./node_modules/@types/node/index.d.ts`. Since this depends on non-relative
"magical" resolution, Deno cannot resolve this.
**Why not use the triple-slash type reference in TypeScript files?**
The TypeScript compiler supports triple-slash directives, including a type
reference directive. If Deno used this, it would interfere with the behavior of
the TypeScript compiler. Deno only looks for the directive in JavaScript (and
JSX) files.
### Custom TypeScript Compiler Options
In the Deno ecosystem, all strict flags are enabled in order to comply with
TypeScript's ideal of being `strict` by default. However, in order to provide a
way to support customization a configuration file such as `tsconfig.json` might
be provided to Deno on program execution.
You need to explicitly tell Deno where to look for this configuration by setting
the `-c` argument when executing your application.
```bash
deno run -c tsconfig.json mod.ts
```
Following are the currently allowed settings and their default values in Deno:
```json
{
"compilerOptions": {
"allowJs": false,
"allowUmdGlobalAccess": false,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"alwaysStrict": true,
"assumeChangesOnlyAffectDirectDependencies": false,
"checkJs": false,
"disableSizeLimit": false,
"generateCpuProfile": "profile.cpuprofile",
"jsx": "react",
"jsxFactory": "React.createElement",
"lib": [],
"noFallthroughCasesInSwitch": false,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitUseStrict": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveConstEnums": false,
"removeComments": false,
"resolveJsonModule": true,
"strict": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"suppressExcessPropertyErrors": false,
"suppressImplicitAnyIndexErrors": false,
"useDefineForClassFields": false
}
}
```
For documentation on allowed values and use cases please visit the
[typescript docs](https://www.typescriptlang.org/docs/handbook/compiler-options.html).
**Note**: Any options not listed above are either not supported by Deno or are
listed as deprecated/experimental in the TypeScript documentation.

View File

@ -0,0 +1,31 @@
## WASM support
Deno can execute [wasm](https://webassembly.org/) binaries.
<!-- prettier-ignore-start -->
```js
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);
console.log(wasmInstance.exports.main().toString());
```
<!-- prettier-ignore-end -->
### ES Module style imports
> This is an unstable feature. Learn more about
> [unstable features](../../runtime/unstable).
WASM files can also be loaded using imports:
```ts
import { fib } from "./fib.wasm";
console.log(fib(20));
```

84
docs/introduction.md Normal file
View File

@ -0,0 +1,84 @@
# 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/tree/master/std)
that are guaranteed to work with Deno.
- Scripts can be bundled 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 ~15 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
- Only ship a single executable (`deno`).
- Provide Secure Defaults
- Unless specifically allowed, scripts can't access files, the environment, or
the network.
- 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 like unit testing, code formatting, and linting to
improve developer experience.
- Does not leak V8 concepts into user land.
- Be able to 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.
- Uses "ES Modules" and does not support `require()`. Third party modules are
imported via URLs:
```javascript
import * as log from "https://deno.land/std/log/mod.ts";
```
## Other key behaviors
- Remote code is fetched and cached on first execution, and never updated 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.
## Logos
These Deno logos, like the Deno software, are distributed under the MIT license
(public domain and free for use)
- [A hand drawn one by @ry](https://deno.land/images/deno_logo.png)
- [An animated one by @hashrock](https://github.com/denolib/animated-deno-logo/)
- [A high resolution SVG one by @kevinkassimo](https://github.com/denolib/high-res-deno-logo)
- [A pixelated animation one by @tanakaworld](https://deno.land/images/deno_logo_4.gif)

View File

@ -0,0 +1,93 @@
# Linking to third party code
In the [Getting Started](../getting_started) section, we saw that 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:
```ts
import { assertEquals } from "https://deno.land/std/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/testing/asserts.ts
Download https://deno.land/std/fmt/colors.ts
Download https://deno.land/std/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`
environmental 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
### But what if `https://deno.land/` goes down?
Relying on external servers is convenient for development but brittle in
production. Production software should always bundle its dependencies. In Deno
this is done by checking the `$DENO_DIR` into your source control system, and
specifying that path as the `$DENO_DIR` environmental variable at runtime.
### How can I trust a URL that may change?
By using a lock file (using the `--lock` command line flag) you can ensure
you're running the code you expect to be. You can learn more about this
[here](./integrity_checking).
### How do you import to a specific version?
Simply 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`. Combined with
the aforementioned technique of setting `$DENO_DIR` in production to stored
code, one can fully specify the exact code being run, and execute the code
without network access.
### 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/testing/asserts.ts"`
everywhere, you could create a `deps.ts` file that exports the third-party code:
```ts
export {
assert,
assertEquals,
assertStrContains,
} from "https://deno.land/std/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.

View File

@ -0,0 +1,42 @@
## Import maps
> This is an unstable feature. Learn more about
> [unstable features](../../runtime/unstable).
Deno supports [import maps](https://github.com/WICG/import-maps).
You can use import map with the `--importmap=<FILE>` CLI flag.
Current limitations:
- single import map
- no fallback URLs
- Deno does not support `std:` namespace
- supports only `file:`, `http:` and `https:` schemes
Example:
```js
// import_map.json
{
"imports": {
"http/": "https://deno.land/std/http/"
}
}
```
```ts
// hello_server.ts
import { serve } from "http/server.ts";
const body = new TextEncoder().encode("Hello World\n");
for await (const req of serve(":8000")) {
req.respond({ body });
}
```
```shell
$ deno run --importmap=import_map.json hello_server.ts
```

View File

@ -0,0 +1,5 @@
## Integrity checking & lock files
Deno can store and check module 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`.

View File

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

View File

@ -0,0 +1,22 @@
## Reloading modules
You can invalidate your local `DENO_DIR` cache using the `--reload` flag. It's
usage is described below:
To reload everything
`--reload`
Sometimes we want to upgrade only some modules. You can control it by passing an
argument to a `--reload` flag.
To reload all standard modules
`--reload=https://deno.land/std`
To reload specific modules (in this example - colors and file system utils) use
a comma to separate URLs
`--reload=https://deno.land/std/fs/utils.ts,https://deno.land/std/fmt/colors.ts`
<!-- Should this be part of examples? --

36
docs/runtime.md Normal file
View File

@ -0,0 +1,36 @@
# Runtime
Documentation for all runtime functions (Web APIs + `Deno` global) can be found
on
[`doc.deno.land`](https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts).
## Web APIs
For APIs where a web standard already exists, like `fetch` for HTTP requests,
Deno uses these rather than inventing a new proprietary API.
The documentation for all of these Web APIs can be found on
[doc.deno.land](https://doc.deno.land/https/raw.githubusercontent.com/denoland/deno/master/cli/js/lib.deno.shared_globals.d.ts).
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/master/cli/js/lib.deno.shared_globals.d.ts)
and
[`lib.deno.window.d.ts`](https://github.com/denoland/deno/blob/master/cli/js/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/master/cli/js/lib.deno.worker.d.ts)
file.
## `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, and executing
subprocesses, ect.
The TypeScript definitions for the Deno namespaces can be found in the
[`lib.deno.ns.d.ts`](https://github.com/denoland/deno/blob/master/cli/js/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/master/cli/js/lib.deno.ns.d.ts).

View File

@ -0,0 +1,218 @@
## Compiler API
Deno supports runtime access to the built-in TypeScript compiler. There are
three methods in the `Deno` namespace that provide this access.
### `Deno.compile()`
This works similar to `deno cache` in that it can fetch and cache the code,
compile it, but not run it. It takes up to three arguments, the `rootName`,
optionally `sources`, and optionally `options`. The `rootName` is the root
module which will be used to generate the resulting program. This is like the
module name you would pass on the command line in
`deno run --reload example.ts`. The `sources` is a hash where the key is the
fully qualified module name, and the value is the text source of the module. If
`sources` is passed, Deno will resolve all the modules from within that hash and
not attempt to resolve them outside of Deno. If `sources` are not provided, Deno
will resolve modules as if the root module had been passed on the command line.
Deno will also cache any of these resources. The `options` argument is a set of
options of type `Deno.CompilerOptions`, which is a subset of the TypeScript
compiler options containing the ones supported by Deno.
The method resolves with a tuple. The first argument contains any diagnostics
(syntax or type errors) related to the code. The second argument is a map where
the keys are the output filenames and the values are the content.
An example of providing sources:
```ts
const [diagnostics, emitMap] = await Deno.compile("/foo.ts", {
"/foo.ts": `import * as bar from "./bar.ts";\nconsole.log(bar);\n`,
"/bar.ts": `export const bar = "bar";\n`,
});
assert(diagnostics == null); // ensuring no diagnostics are returned
console.log(emitMap);
```
We would expect map to contain 4 "files", named `/foo.js.map`, `/foo.js`,
`/bar.js.map`, and `/bar.js`.
When not supplying resources, you can use local or remote modules, just like you
could do on the command line. So you could do something like this:
```ts
const [diagnostics, emitMap] = await Deno.compile(
"https://deno.land/std/examples/welcome.ts"
);
```
In this case `emitMap` will contain a simple `console.log()` statement.
### `Deno.bundle()`
This works a lot like `deno bundle` does on the command line. It is also like
`Deno.compile()`, except instead of returning a map of files, it returns a
single string, which is a self-contained JavaScript ES module which will include
all of the code that was provided or resolved as well as exports of all the
exports of the root module that was provided. It takes up to three arguments,
the `rootName`, optionally `sources`, and optionally `options`. The `rootName`
is the root module which will be used to generate the resulting program. This is
like module name you would pass on the command line in `deno bundle example.ts`.
The `sources` is a hash where the key is the fully qualified module name, and
the value is the text source of the module. If `sources` is passed, Deno will
resolve all the modules from within that hash and not attempt to resolve them
outside of Deno. If `sources` are not provided, Deno will resolve modules as if
the root module had been passed on the command line. Deno will also cache any of
these resources. The `options` argument is a set of options of type
`Deno.CompilerOptions`, which is a subset of the TypeScript compiler options
containing the ones supported by Deno.
An example of providing sources:
```ts
const [diagnostics, emit] = await Deno.bundle("/foo.ts", {
"/foo.ts": `import * as bar from "./bar.ts";\nconsole.log(bar);\n`,
"/bar.ts": `export const bar = "bar";\n`,
});
assert(diagnostics == null); // ensuring no diagnostics are returned
console.log(emit);
```
We would expect `emit` to be the text for an ES module, which would contain the
output sources for both modules.
When not supplying resources, you can use local or remote modules, just like you
could do on the command line. So you could do something like this:
```ts
const [diagnostics, emit] = await Deno.bundle(
"https://deno.land/std/http/server.ts"
);
```
In this case `emit` will be a self contained JavaScript ES module with all of
its dependencies resolved and exporting the same exports as the source module.
### `Deno.transpileOnly()`
This is based off of the TypeScript function `transpileModule()`. All this does
is "erase" any types from the modules and emit JavaScript. There is no type
checking and no resolution of dependencies. It accepts up to two arguments, the
first is a hash where the key is the module name and the value is the content.
The only purpose of the module name is when putting information into a source
map, of what the source file name was. The second argument contains optional
`options` of the type `Deno.CompilerOptions`. The function resolves with a map
where the key is the source module name supplied, and the value is an object
with a property of `source` and optionally `map`. The first is the output
contents of the module. The `map` property is the source map. Source maps are
provided by default, but can be turned off via the `options` argument.
An example:
```ts
const result = await Deno.transpileOnly({
"/foo.ts": `enum Foo { Foo, Bar, Baz };\n`,
});
console.log(result["/foo.ts"].source);
console.log(result["/foo.ts"].map);
```
We would expect the `enum` would be rewritten to an IIFE which constructs the
enumerable, and the map to be defined.
### Referencing TypeScript library files
When you use `deno run`, or other Deno commands which type check TypeScript,
that code is evaluated against custom libraries which describe the environment
that Deno supports. By default, the compiler runtime APIs which type check
TypeScript also use these libraries (`Deno.compile()` and `Deno.bundle()`).
But if you want to compile or bundle TypeScript for some other runtime, you may
want to override the default libraries. To do this, the runtime APIs support the
`lib` property in the compiler options. For example, if you had TypeScript code
that is destined for the browser, you would want to use the TypeScript `"dom"`
library:
```ts
const [errors, emitted] = await Deno.compile(
"main.ts",
{
"main.ts": `document.getElementById("foo");\n`,
},
{
lib: ["dom", "esnext"],
}
);
```
For a list of all the libraries that TypeScript supports, see the
[`lib` compiler option](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
documentation.
**Don't forget to include the JavaScript library**
Just like `tsc`, when you supply a `lib` compiler option, it overrides the
default ones, which means that the basic JavaScript library won't be included
and you should include the one that best represents your target runtime (e.g.
`es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020` or `esnext`).
#### Including the `Deno` namespace
In addition to the libraries that are provided by TypeScript, there are four
libraries that are built into Deno that can be referenced:
- `deno.ns` - Provides the `Deno` namespace.
- `deno.shared_globals` - Provides global interfaces and variables which Deno
supports at runtime that are then exposed by the final runtime library.
- `deno.window` - Exposes the global variables plus the Deno namespace that are
available in the Deno main worker and is the default for the runtime compiler
APIs.
- `deno.worker` - Exposes the global variables that are available in workers
under Deno.
So to add the Deno namespace to a compilation, you would include the `deno.ns`
lib in the array. For example:
```ts
const [errors, emitted] = await Deno.compile(
"main.ts",
{
"main.ts": `document.getElementById("foo");\n`,
},
{
lib: ["dom", "esnext", "deno.ns"],
}
);
```
**Note** that the Deno namespace expects a runtime environment that is at least
ES2018 or later. This means if you use a lib "lower" than ES2018 you will get
errors logged as part of the compilation.
#### Using the triple slash reference
You do not have to specify the `lib` in the compiler options. Deno also supports
[the triple-slash reference to a lib](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-lib-).
which can be embedded in the contents of the file. For example, if you have a
`main.ts` like:
```ts
/// <reference lib="dom" />
document.getElementById("foo");
```
It would compile without errors like this:
```ts
const [errors, emitted] = await Deno.compile("./main.ts", undefined, {
lib: ["esnext"],
});
```
**Note** that the `dom` library conflicts with some of the default globals that
are defined in the default type library for Deno. To avoid this, you need to
specify a `lib` option in the compiler options to the runtime compiler APIs.

View File

@ -0,0 +1,68 @@
## 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.
Listener for `load` events can be asynchronous and will be awaited. Listener for
`unload` events need to be synchronous. Both events cannot be cancelled.
Example:
```typescript
// main.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)`);
};
// imported.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 example:
```shell
$ deno run main.ts
log from imported script
log from main script
got load event in onload function (main)
got load event in event handler (imported)
got load event in event handler (main)
got unload event in onunload function (main)
got unload event in event handler (imported)
got unload event in event handler (main)
```
All listeners added using `window.addEventListener` were run, but
`window.onload` and `window.onunload` defined in `main.ts` overridden handlers
defined in `imported.ts`.

15
docs/runtime/unstable.md Normal file
View File

@ -0,0 +1,15 @@
## Unstable
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. 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://github.com/denoland/deno/blob/master/cli/js/lib.deno.unstable.d.ts)
file to the list of TypeScript definitions that are used for typechecking.
This includes the output of `deno types`.
You should be aware that unstable APIs have probably **not undergone a security
review**, are likely to have **breaking API changes** in the future and are
**not ready for production**.

83
docs/toc.json Normal file
View File

@ -0,0 +1,83 @@
{
"introduction": {
"name": "Introduction"
},
"getting_started": {
"name": "Getting Started",
"children": {
"installation": "Installation",
"setup_your_environment": "Setup your environment",
"first_steps": "First steps",
"permissions": "Permissions",
"typescript": "Using TypeScript",
"webassembly": "Using WebAssembly"
}
},
"runtime": {
"name": "The Runtime",
"children": {
"program_lifecycle": "Program Lifecycle",
"compiler_apis": "Compiler APIs",
"unstable": "Unstable APIs"
}
},
"linking_to_external_code": {
"name": "Linking to external code",
"children": {
"reloading_modules": "Reloading modules",
"integrity_checking": "Integrity checking",
"proxies": "Proxies",
"import_maps": "Import maps"
}
},
"testing": {
"name": "Testing",
"children": {
"writing": "Writing tests",
"running": "Running tests"
}
},
"plugins": {
"name": "Plugins",
"children": {
"how_do_plugins_work": "How do plugins work?",
"creating_plugins": "Creating plugins",
"using_plugins": "Using plugins"
}
},
"tools": {
"name": "Tools",
"children": {
"debugger": "Debugger",
"script_installer": "Script installer",
"formatter": "Formatter",
"bundler": "Bundler",
"documentation_generator": "Documentation generator",
"dependency_inspector": "Dependency inspector"
}
},
"embedding_deno": {
"name": "Embedding Deno"
},
"contributing": {
"name": "Contributing",
"children": {
"building_from_source": "Building from source",
"development_tools": "Development tools",
"architecture": "Architecture"
}
},
"examples": {
"name": "Examples",
"children": {
"unix_cat": "Unix cat program",
"fileserver": "File server",
"tcp_echo": "TCP echo server",
"subprocess": "Creating a subprocess",
"permissions": "Inspecting and revoking permissions",
"os_signals": "OS Signals",
"file_system_events": "File system events",
"testing_if_main": "Checking if file is main"
}
}
}

17
docs/tools.md Normal file
View File

@ -0,0 +1,17 @@
# Built-in tooling
Deno provides some built in tooling that is useful when working with JavaScript
and TypeScript:
<!-- prettier-ignore-start -->
<!-- prettier incorrectly moves the coming soon links to new lines -->
- [test runner (`deno test`)](../testing)
- [code formatter (`deno fmt`)](./formatter)
- [bundler (`deno bundle`)](./bundler)
- [debugger (`--debug`)](./debugger)
- [documentation generator (`deno doc`)](./documentation_generator)
- [dependency inspector (`deno info`)](./dependency_inspector)
- linter (`deno lint`) [coming soon](https://github.com/denoland/deno/issues/1880)
<!-- prettier-ignore-end -->

50
docs/tools/bundler.md Normal file
View File

@ -0,0 +1,50 @@
## Bundling
`deno bundle [URL]` will output a single JavaScript file, which includes all
dependencies of the specified input. For example:
```
> deno bundle https://deno.land/std/examples/colors.ts colors.bundle.js
Bundling "colors.bundle.js"
Emitting bundle to "colors.bundle.js"
9.2 kB emitted.
```
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:
```
deno 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 { foo, bar } 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>
```

3
docs/tools/debugger.md Normal file
View File

@ -0,0 +1,3 @@
## Debugger
<!-- TODO(lucacasonto): write things -->

View File

@ -0,0 +1,3 @@
## Dependency Inspector
<!-- TODO(lucacasonto): write things -->

View File

@ -0,0 +1,3 @@
## Documentation Generator
<!-- TODO(lucacasonto): write things -->

33
docs/tools/formatter.md Normal file
View File

@ -0,0 +1,33 @@
## 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:
<!-- prettier-ignore-start -->
```ts
// deno-fmt-ignore
export const identity = [
1, 0, 0,
0, 1, 0,
0, 0, 1,
];
```
<!-- prettier-ignore-end -->
Or ignore an entire file by adding a `// deno-fmt-ignore-file` comment at the
top of the file.

View File

@ -0,0 +1,88 @@
## 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 place in the installation root's
`bin` directory.
Example:
```shell
$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
[1/1] Compiling https://deno.land/std/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/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.
To change the installation root, use `--root`:
```shell
$ deno install --allow-net --allow-read --root /usr/local https://deno.land/std/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/http/file_server.ts 8080
```
The above command creates an executable called `file_server` that runs with
write and read permissions and binds to port 8080.
For good practice, use the
[`import.meta.main`](#testing-if-current-file-is-the-main-program) idiom to
specify the entry point in an executable script.
Example:
```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
```

File diff suppressed because it is too large Load Diff