diff options
author | Luca Casonato <lucacasonato@yahoo.com> | 2020-05-07 00:21:13 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-06 18:21:13 -0400 |
commit | 34ec3b225425cecdccf754fbc87f4a8f3728890d (patch) | |
tree | 35db52bf25ccf64425692116197df61a69ea8838 /docs/getting_started | |
parent | 846c049c9b3ab36d0893292a204c4d0a18de4c8e (diff) |
Multi page manual (#5110)
Diffstat (limited to 'docs/getting_started')
-rw-r--r-- | docs/getting_started/first_steps.md | 144 | ||||
-rw-r--r-- | docs/getting_started/installation.md | 70 | ||||
-rw-r--r-- | docs/getting_started/permissions.md | 37 | ||||
-rw-r--r-- | docs/getting_started/setup_your_environment.md | 60 | ||||
-rw-r--r-- | docs/getting_started/typescript.md | 151 | ||||
-rw-r--r-- | docs/getting_started/wasm.md | 31 |
6 files changed, 493 insertions, 0 deletions
diff --git a/docs/getting_started/first_steps.md b/docs/getting_started/first_steps.md new file mode 100644 index 000000000..13118a2cf --- /dev/null +++ b/docs/getting_started/first_steps.md @@ -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. diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md new file mode 100644 index 000000000..158e18133 --- /dev/null +++ b/docs/getting_started/installation.md @@ -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. diff --git a/docs/getting_started/permissions.md b/docs/getting_started/permissions.md new file mode 100644 index 000000000..a3d0a9ea0 --- /dev/null +++ b/docs/getting_started/permissions.md @@ -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/ +``` diff --git a/docs/getting_started/setup_your_environment.md b/docs/getting_started/setup_your_environment.md new file mode 100644 index 000000000..294e86fb3 --- /dev/null +++ b/docs/getting_started/setup_your_environment.md @@ -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. diff --git a/docs/getting_started/typescript.md b/docs/getting_started/typescript.md new file mode 100644 index 000000000..5f406e6bd --- /dev/null +++ b/docs/getting_started/typescript.md @@ -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. diff --git a/docs/getting_started/wasm.md b/docs/getting_started/wasm.md new file mode 100644 index 000000000..f1c7e6fd2 --- /dev/null +++ b/docs/getting_started/wasm.md @@ -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)); +``` |