deno
+Deno
+ +Deno is program for executing JavaScript and TypeScript outside of the + web browser.
Intro -
Rust API +
Documentation + +
diff --git a/Docs.md b/Docs.md index e9750ffb22..770d58cf73 100644 --- a/Docs.md +++ b/Docs.md @@ -1,18 +1,28 @@ -# Deno Docs +# Deno Documentation + +## Disclaimer + +A word of caution: Deno is very much under development. We encourage brave early +adopters, but expect bugs large and small. The API is subject to change without +notice. + +[Bug reports](https://github.com/denoland/deno/issues) do help! ## Install -Deno works on OSX, Linux, and Windows. We provide binary download scripts: +Deno works on OSX, Linux, and Windows. Deno is a single binary executable. It +has no external dependencies. -With Python: +[deno_install](https://github.com/denoland/deno_install) provides convenience +scripts to download and install the binary. + +Using Python: ``` curl -sSf https://raw.githubusercontent.com/denoland/deno_install/master/install.py | python ``` -See also [deno_install](https://github.com/denoland/deno_install). - -With PowerShell: +Or using PowerShell: ```powershell iex (iwr https://raw.githubusercontent.com/denoland/deno_install/master/install.ps1) @@ -22,10 +32,15 @@ _Note: Depending on your security settings, you may have to run `Set-ExecutionPolicy RemoteSigned -Scope CurrentUser` first to allow downloaded scripts to be executed._ +Deno can also be installed manually, by downloading a tarball or 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 Mac and Linux. + Try it: ``` -> deno http://deno.land/thumb.ts +> deno https://deno.land/thumb.ts ``` ## API Reference @@ -34,58 +49,186 @@ To get an exact reference of deno's runtime API, run the following in the command line: ``` -deno --types +> deno --types ``` -In case you don't have it installed yet, but are curious, here is an out-of-date -copy of the output: https://gist.github.com/78855aeeaddeef7c1fce0aeb8ffef8b2 +Or see the [doc website](https://deno.land/typedoc/index.html). -(We do not yet have an HTML version of this. See -https://github.com/denoland/deno/issues/573) +If you are embedding deno in a Rust program, see +[the rust docs](https://deno.land/rustdoc/deno/index.html). -## Examples +## Tutorial -### Example: An implementation of the unix "cat" program +### An implementation of the unix "cat" program -The copy here is actually zero-copy. That is, it reads data from the socket and -writes it back to it without ever calling a memcpy() or similar. +In this program each command-line argument is assumed to be a filename, the file +is opened, and printed to stdout. ```ts import * as deno from "deno"; -for (let i = 1; i < deno.args.length; i++) { - let filename = deno.args[i]; - let file = await deno.open(filename); - await deno.copy(deno.stdout, file); -} +(async () => { + for (let i = 1; i < deno.args.length; i++) { + let filename = deno.args[i]; + let file = await deno.open(filename); + await deno.copy(deno.stdout, file); + file.close(); + } +})(); ``` -### Example: A TCP Server echo server +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. -The copy here is actually zero-copy. That is, it reads data from the socket and -writes it back to it without ever calling a memcpy() or similar. +Try the program: + +``` +> deno https://deno.land/x/examples/cat.ts /etc/passwd +``` + +### 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 import { listen, copy } from "deno"; -const listener = listen("tcp", ":8080"); -while (true) { - const conn = await listener.accept(); - copy(conn, conn); -} -// TODO top level await doesn't work yet. + +(async () => { + const addr = "0.0.0.0:8080"; + const listener = listen("tcp", addr); + console.log("listening on", addr); + while (true) { + const conn = await listener.accept(); + copy(conn, conn); + } +})(); ``` -### Example: Url imports +When this program is started, the user is prompted for permission to listen on +the network: + +``` +> deno https://deno.land/x/examples/echo_server.ts +deno requests network access to "listen". Grant? [yN] y +listening on 0.0.0.0:8080 +``` + +For security reasons, deno does not allow programs to access the network without +explicit permission. To avoid the console prompt, use a command-line flag: + +``` +> deno https://deno.land/x/examples/echo_server.ts --allow-net +``` + +To test it, try sending a HTTP request to it by using curl. The request gets +written directly back to the client. + +``` +> curl http://localhost:8080/ +GET / HTTP/1.1 +Host: localhost:8080 +User-Agent: curl/7.54.0 +Accept: */* +``` + +It's worth noting that 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. + +### Linking to third party code + +In the above examples, 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 a test runner library: ```ts -import { printHello } from "https://raw.githubusercontent.com/denoland/deno/master/tests/subdir/print_hello.ts"; -printHello(); +import { test, assertEqual } from "https://deno.land/x/testing/testing.ts"; + +test(function t1() { + assertEqual("hello", "hello"); +}); + +test(function t2() { + assertEqual("world", "world"); +}); ``` -The next time you import the same file from same uri it will use the cached -resource instead of downloading it again. +Try running this: -## How to Profile Deno +``` +> deno https://deno.land/x/examples/example_test.ts +Compiling /Users/rld/src/deno_examples/example_test.ts +Downloading https://deno.land/x/testing/testing.ts +Downloading https://deno.land/x/testing/util.ts +Compiling https://deno.land/x/testing/testing.ts +Compiling https://deno.land/x/testing/util.ts +running 2 tests +test t1 +... ok +test t2 +... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +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 default to `$HOME/.deno` 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. + +**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 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 `package.ts` file (which serves the same purpose +as Node's `package.json` file). For example, let's say you were using the above +testing library across a large project. Rather than importing +`"https://deno.land/x/testing/testing.ts"` everywhere, you could create a +`package.ts` file the exports the third-party code: + +```ts +export { test, assertEqual } from "https://deno.land/x/testing/testing.ts"; +``` + +And throughout project one can import from the `package.ts` and avoid having +many references to the same URL: + +```ts +import { test, assertEqual } from "./package.ts"; +``` + +This design circumvents a plethora of complexity spawned by package management +software, centralized code repositories, and superfluous file formates. + +## Useful command line flags + +V8 has many many command-line flags, that you can see with `--v8-options`. Here +are a few particularly useful ones: + +``` +--async-stack-traces +``` + +## How to Profile deno ```sh # Make sure we're only building release. @@ -108,11 +251,11 @@ isolate-0x7fad98242400-v8.log ### Prerequisites: -To ensure reproducible builds, Deno has most of its dependencies in a git +To ensure reproducible builds, deno has most of its dependencies in a git submodule. However, you need to install separately: 1. [Rust](https://www.rust-lang.org/en-US/install.html) -2. [Node](http://nodejs.org/) +2. [Node](https://nodejs.org/) 3. Python 2. [Not 3](https://github.com/denoland/deno/issues/464#issuecomment-411795578). 4. [ccache](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/ccache) @@ -175,7 +318,7 @@ Environment variables: `DENO_BUILD_MODE`, `DENO_BUILD_PATH`, `DENO_BUILD_ARGS`, ### Internal: libdeno API. -Deno's privileged side will primarily be programmed in Rust. However there will +deno's privileged side will primarily be programmed in Rust. However there will be a small C API that wraps V8 to 1) define the low-level message passing semantics, 2) provide a low-level test target, 3) provide an ANSI C API binding interface for Rust. V8 plus this C API is called "libdeno" and the important @@ -239,9 +382,9 @@ V8's GC will lead to difficult contention problems down the road. The V8Worker2 binding/concept is being ported to a new C++ library called libdeno. libdeno will include the entire JS runtime as a V8 snapshot. It still follows the message passing paradigm. Rust will be bound to this library to -implement the privileged part of Deno. See deno2/README.md for more details. +implement the privileged part of deno. See deno2/README.md for more details. -V8 Snapshots allow Deno to avoid recompiling the TypeScript compiler at startup. +V8 Snapshots allow deno to avoid recompiling the TypeScript compiler at startup. This is already working. When the rewrite is at feature parity with the Go prototype, we will release @@ -253,20 +396,18 @@ https://github.com/denoland/deno/tree/golang https://www.youtube.com/watch?v=M3BM9TB-8yA -http://tinyclouds.org/jsconf2018.pdf +https://tinyclouds.org/jsconf2018.pdf ### 2007-2017 / Prehistory https://github.com/ry/v8worker -http://libuv.org/ +https://libuv.org/ -http://tinyclouds.org/iocp-links.html +https://tinyclouds.org/iocp-links.html https://nodejs.org/ https://github.com/nodejs/http-parser -http://tinyclouds.org/libebb/ - -https://en.wikipedia.org/wiki/Merb +https://tinyclouds.org/libebb/ diff --git a/website/index.html b/website/index.html index f56a312ee1..fc69f257b0 100644 --- a/website/index.html +++ b/website/index.html @@ -2,20 +2,23 @@
-Deno is program for executing JavaScript and TypeScript outside of the + web browser.
Intro -
Rust API +
Documentation + +