From f8fdb6c7fb13234117f9d48eeb6ef15fedd17cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=B7=E6=B8=A1?= Date: Thu, 7 May 2020 13:49:20 +0800 Subject: [PATCH] first commit --- README.md | 4 + en/README.md | 47 ++++ en/contributing.md | 60 +++++ en/contributing/architecture.md | 50 ++++ en/contributing/building_from_source.md | 89 +++++++ en/contributing/development_tools.md | 171 ++++++++++++++ en/contributing/profiling.md | 0 en/embedding_deno.md | 11 + en/examples.md | 4 + en/examples/fileserver.md | 22 ++ en/examples/os_signals.md | 35 +++ en/examples/permissions.md | 28 +++ en/examples/subprocess.md | 74 ++++++ en/examples/tcp_echo.md | 41 ++++ en/examples/testing_if_main.md | 10 + en/examples/unix_cat.md | 24 ++ en/getting_started.md | 9 + en/getting_started/first_steps.md | 144 ++++++++++++ en/getting_started/installation.md | 70 ++++++ en/getting_started/permissions.md | 37 +++ en/getting_started/setup_your_environment.md | 60 +++++ en/getting_started/typescript.md | 151 ++++++++++++ en/getting_started/wasm.md | 31 +++ en/introduction.md | 84 +++++++ en/linking_to_external_code.md | 93 ++++++++ en/linking_to_external_code/import_maps.md | 42 ++++ .../integrity_checking.md | 5 + en/linking_to_external_code/proxies.md | 9 + .../reloading_modules.md | 22 ++ en/runtime.md | 36 +++ en/runtime/compiler_apis.md | 218 ++++++++++++++++++ en/runtime/program_lifecycle.md | 68 ++++++ en/runtime/unstable.md | 15 ++ en/toc.json | 83 +++++++ en/tools.md | 17 ++ en/tools/bundler.md | 50 ++++ en/tools/debugger.md | 3 + en/tools/dependency_inspector.md | 3 + en/tools/documentation_generator.md | 3 + en/tools/formatter.md | 33 +++ en/tools/script_installer.md | 88 +++++++ zh-cn/README.md | 47 ++++ zh-cn/contributing.md | 60 +++++ zh-cn/contributing/architecture.md | 50 ++++ zh-cn/contributing/building_from_source.md | 89 +++++++ zh-cn/contributing/development_tools.md | 171 ++++++++++++++ zh-cn/contributing/profiling.md | 0 zh-cn/embedding_deno.md | 11 + zh-cn/examples.md | 4 + zh-cn/examples/fileserver.md | 22 ++ zh-cn/examples/os_signals.md | 35 +++ zh-cn/examples/permissions.md | 28 +++ zh-cn/examples/subprocess.md | 74 ++++++ zh-cn/examples/tcp_echo.md | 41 ++++ zh-cn/examples/testing_if_main.md | 10 + zh-cn/examples/unix_cat.md | 24 ++ zh-cn/getting_started.md | 9 + zh-cn/getting_started/first_steps.md | 144 ++++++++++++ zh-cn/getting_started/installation.md | 70 ++++++ zh-cn/getting_started/permissions.md | 37 +++ .../getting_started/setup_your_environment.md | 60 +++++ zh-cn/getting_started/typescript.md | 151 ++++++++++++ zh-cn/getting_started/wasm.md | 31 +++ zh-cn/introduction.md | 84 +++++++ zh-cn/linking_to_external_code.md | 93 ++++++++ zh-cn/linking_to_external_code/import_maps.md | 42 ++++ .../integrity_checking.md | 5 + zh-cn/linking_to_external_code/proxies.md | 9 + .../reloading_modules.md | 22 ++ zh-cn/runtime.md | 36 +++ zh-cn/runtime/compiler_apis.md | 218 ++++++++++++++++++ zh-cn/runtime/program_lifecycle.md | 68 ++++++ zh-cn/runtime/unstable.md | 15 ++ zh-cn/toc.json | 83 +++++++ zh-cn/tools.md | 17 ++ zh-cn/tools/bundler.md | 50 ++++ zh-cn/tools/debugger.md | 3 + zh-cn/tools/dependency_inspector.md | 3 + zh-cn/tools/documentation_generator.md | 3 + zh-cn/tools/formatter.md | 33 +++ zh-cn/tools/script_installer.md | 88 +++++++ 81 files changed, 4084 insertions(+) create mode 100644 README.md create mode 100644 en/README.md create mode 100644 en/contributing.md create mode 100644 en/contributing/architecture.md create mode 100644 en/contributing/building_from_source.md create mode 100644 en/contributing/development_tools.md create mode 100644 en/contributing/profiling.md create mode 100644 en/embedding_deno.md create mode 100644 en/examples.md create mode 100644 en/examples/fileserver.md create mode 100644 en/examples/os_signals.md create mode 100644 en/examples/permissions.md create mode 100644 en/examples/subprocess.md create mode 100644 en/examples/tcp_echo.md create mode 100644 en/examples/testing_if_main.md create mode 100644 en/examples/unix_cat.md create mode 100644 en/getting_started.md create mode 100644 en/getting_started/first_steps.md create mode 100644 en/getting_started/installation.md create mode 100644 en/getting_started/permissions.md create mode 100644 en/getting_started/setup_your_environment.md create mode 100644 en/getting_started/typescript.md create mode 100644 en/getting_started/wasm.md create mode 100644 en/introduction.md create mode 100644 en/linking_to_external_code.md create mode 100644 en/linking_to_external_code/import_maps.md create mode 100644 en/linking_to_external_code/integrity_checking.md create mode 100644 en/linking_to_external_code/proxies.md create mode 100644 en/linking_to_external_code/reloading_modules.md create mode 100644 en/runtime.md create mode 100644 en/runtime/compiler_apis.md create mode 100644 en/runtime/program_lifecycle.md create mode 100644 en/runtime/unstable.md create mode 100644 en/toc.json create mode 100644 en/tools.md create mode 100644 en/tools/bundler.md create mode 100644 en/tools/debugger.md create mode 100644 en/tools/dependency_inspector.md create mode 100644 en/tools/documentation_generator.md create mode 100644 en/tools/formatter.md create mode 100644 en/tools/script_installer.md create mode 100644 zh-cn/README.md create mode 100644 zh-cn/contributing.md create mode 100644 zh-cn/contributing/architecture.md create mode 100644 zh-cn/contributing/building_from_source.md create mode 100644 zh-cn/contributing/development_tools.md create mode 100644 zh-cn/contributing/profiling.md create mode 100644 zh-cn/embedding_deno.md create mode 100644 zh-cn/examples.md create mode 100644 zh-cn/examples/fileserver.md create mode 100644 zh-cn/examples/os_signals.md create mode 100644 zh-cn/examples/permissions.md create mode 100644 zh-cn/examples/subprocess.md create mode 100644 zh-cn/examples/tcp_echo.md create mode 100644 zh-cn/examples/testing_if_main.md create mode 100644 zh-cn/examples/unix_cat.md create mode 100644 zh-cn/getting_started.md create mode 100644 zh-cn/getting_started/first_steps.md create mode 100644 zh-cn/getting_started/installation.md create mode 100644 zh-cn/getting_started/permissions.md create mode 100644 zh-cn/getting_started/setup_your_environment.md create mode 100644 zh-cn/getting_started/typescript.md create mode 100644 zh-cn/getting_started/wasm.md create mode 100644 zh-cn/introduction.md create mode 100644 zh-cn/linking_to_external_code.md create mode 100644 zh-cn/linking_to_external_code/import_maps.md create mode 100644 zh-cn/linking_to_external_code/integrity_checking.md create mode 100644 zh-cn/linking_to_external_code/proxies.md create mode 100644 zh-cn/linking_to_external_code/reloading_modules.md create mode 100644 zh-cn/runtime.md create mode 100644 zh-cn/runtime/compiler_apis.md create mode 100644 zh-cn/runtime/program_lifecycle.md create mode 100644 zh-cn/runtime/unstable.md create mode 100644 zh-cn/toc.json create mode 100644 zh-cn/tools.md create mode 100644 zh-cn/tools/bundler.md create mode 100644 zh-cn/tools/debugger.md create mode 100644 zh-cn/tools/dependency_inspector.md create mode 100644 zh-cn/tools/documentation_generator.md create mode 100644 zh-cn/tools/formatter.md create mode 100644 zh-cn/tools/script_installer.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..8312652 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Deno Docs + +- [English](./en) +- [简体中文](./zh-cn) diff --git a/en/README.md b/en/README.md new file mode 100644 index 0000000..07e72ae --- /dev/null +++ b/en/README.md @@ -0,0 +1,47 @@ +# Deno Docs + +- [Introduction](./introduction.md) +- [Getting Started](./getting_started.md) + - [Installation](./getting_started/installation.md) + - [Setup your environment](./getting_started/setup_your_environment.md) + - [First steps](./getting_started/first_steps.md) + - [Permissions](./getting_started/permissions.md) + - [Using TypeScript](./getting_started/typescript.md) + - [Using WebAssembly](./getting_started/wasm.md) +- [The Runtime](./runtime.md) + - [Program Lifecycle](./runtime/program_lifecycle.md) + - [Compiler APIs](./runtime/compiler_apis.md) + - [Unstable APIs](./runtime/unstable.md) +- [Linking to external code](./linking_to_external_code.md) + - [Reloading modules](./linking_to_external_code/reloading_modules.md) + - [Integrity checking](./linking_to_external_code/integrity_checking.md) + - [Proxies](./linking_to_external_code/proxies.md) + - [Import maps](./linking_to_external_code/import_maps.md) +- [Testing](./testing.md) + - [Writing tests](./testing/writing.md) + - [Running tests](./testing/running.md) +- [Plugins](./plugins.md) + - [How do plugins work?](./plugins/how_do_plugins_work.md) + - [Creating plugins](./plugins/creating_plugins.md) + - [Using plugins](./plugins/using_plugins.md) +- [Tools](./tools.md) + - [Debugger](./tools/debugger.md) + - [Script installer](./tools/script_installer.md) + - [Formatter](./tools/formatter.md) + - [Bundler](./tools/bundler.md) + - [Documentation generator](./tools/documentation_generator.md) + - [Dependency inspector](./tools/dependency_inspector.md) +- [Embedding Deno](./embedding_deno.md) +- [Contributing](./contributing.md) + - [Building from source](./contributing/building_from_source.md) + - [Development tools](./contributing/development_tools.md) + - [Architecture](./contributing/architecture.md) +- [Examples](./examples.md) + - [Unix cat program](./examples/unix_cat.md) + - [File server](./examples/fileserver.md) + - [TCP echo server](./examples/tcp_echo.md) + - [Creating a subprocess](./examples/subprocess.md) + - [Inspecting and revoking permissions](./examples/permissions.md) + - [OS Signals](./examples/os_signals.md) + - [File system events](./examples/file_system_events.md) + - [Checking if file is main](./examples/testing_if_main.md) diff --git a/en/contributing.md b/en/contributing.md new file mode 100644 index 0000000..5394405 --- /dev/null +++ b/en/contributing.md @@ -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"; +``` diff --git a/en/contributing/architecture.md b/en/contributing/architecture.md new file mode 100644 index 0000000..0a1ba3b --- /dev/null +++ b/en/contributing/architecture.md @@ -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) diff --git a/en/contributing/building_from_source.md b/en/contributing/building_from_source.md new file mode 100644 index 0000000..fb1e1ef --- /dev/null +++ b/en/contributing/building_from_source.md @@ -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 +``` diff --git a/en/contributing/development_tools.md b/en/contributing/development_tools.md new file mode 100644 index 0000000..35bd5a5 --- /dev/null +++ b/en/contributing/development_tools.md @@ -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; + }; +} +``` diff --git a/en/contributing/profiling.md b/en/contributing/profiling.md new file mode 100644 index 0000000..e69de29 diff --git a/en/embedding_deno.md b/en/embedding_deno.md new file mode 100644 index 0000000..aa8cd58 --- /dev/null +++ b/en/embedding_deno.md @@ -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). + + diff --git a/en/examples.md b/en/examples.md new file mode 100644 index 0000000..13c15a2 --- /dev/null +++ b/en/examples.md @@ -0,0 +1,4 @@ +# Examples + +In this chapter you can find some example programs that you can use to learn +more about the runtime. diff --git a/en/examples/fileserver.md b/en/examples/fileserver.md new file mode 100644 index 0000000..3ed9d90 --- /dev/null +++ b/en/examples/fileserver.md @@ -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 +``` diff --git a/en/examples/os_signals.md b/en/examples/os_signals.md new file mode 100644 index 0000000..5f66f33 --- /dev/null +++ b/en/examples/os_signals.md @@ -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. diff --git a/en/examples/permissions.md b/en/examples/permissions.md new file mode 100644 index 0000000..7d404d5 --- /dev/null +++ b/en/examples/permissions.md @@ -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"); +``` diff --git a/en/examples/subprocess.md b/en/examples/subprocess.md new file mode 100644 index 0000000..80d0cc7 --- /dev/null +++ b/en/examples/subprocess.md @@ -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 +[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) +``` diff --git a/en/examples/tcp_echo.md b/en/examples/tcp_echo.md new file mode 100644 index 0000000..d7c2e9e --- /dev/null +++ b/en/examples/tcp_echo.md @@ -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. diff --git a/en/examples/testing_if_main.md b/en/examples/testing_if_main.md new file mode 100644 index 0000000..67be703 --- /dev/null +++ b/en/examples/testing_if_main.md @@ -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"); +} +``` diff --git a/en/examples/unix_cat.md b/en/examples/unix_cat.md new file mode 100644 index 0000000..7534ef0 --- /dev/null +++ b/en/examples/unix_cat.md @@ -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 +``` diff --git a/en/getting_started.md b/en/getting_started.md new file mode 100644 index 0000000..159d3de --- /dev/null +++ b/en/getting_started.md @@ -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 diff --git a/en/getting_started/first_steps.md b/en/getting_started/first_steps.md new file mode 100644 index 0000000..13118a2 --- /dev/null +++ b/en/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/en/getting_started/installation.md b/en/getting_started/installation.md new file mode 100644 index 0000000..158e181 --- /dev/null +++ b/en/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 ` 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/en/getting_started/permissions.md b/en/getting_started/permissions.md new file mode 100644 index 0000000..a3d0a9e --- /dev/null +++ b/en/getting_started/permissions.md @@ -0,0 +1,37 @@ +## 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/en/getting_started/setup_your_environment.md b/en/getting_started/setup_your_environment.md new file mode 100644 index 0000000..294e86f --- /dev/null +++ b/en/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 ` 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/en/getting_started/typescript.md b/en/getting_started/typescript.md new file mode 100644 index 0000000..5f406e6 --- /dev/null +++ b/en/getting_started/typescript.md @@ -0,0 +1,151 @@ +## Using TypeScript + + + +### 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 +/// +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/en/getting_started/wasm.md b/en/getting_started/wasm.md new file mode 100644 index 0000000..f1c7e6f --- /dev/null +++ b/en/getting_started/wasm.md @@ -0,0 +1,31 @@ +## WASM support + +Deno can execute [wasm](https://webassembly.org/) binaries. + + +```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()); +``` + + +### 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)); +``` diff --git a/en/introduction.md b/en/introduction.md new file mode 100644 index 0000000..091cc7d --- /dev/null +++ b/en/introduction.md @@ -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) diff --git a/en/linking_to_external_code.md b/en/linking_to_external_code.md new file mode 100644 index 0000000..5484a78 --- /dev/null +++ b/en/linking_to_external_code.md @@ -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. diff --git a/en/linking_to_external_code/import_maps.md b/en/linking_to_external_code/import_maps.md new file mode 100644 index 0000000..7ec963d --- /dev/null +++ b/en/linking_to_external_code/import_maps.md @@ -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=` 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 +``` diff --git a/en/linking_to_external_code/integrity_checking.md b/en/linking_to_external_code/integrity_checking.md new file mode 100644 index 0000000..820ea1d --- /dev/null +++ b/en/linking_to_external_code/integrity_checking.md @@ -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`. diff --git a/en/linking_to_external_code/proxies.md b/en/linking_to_external_code/proxies.md new file mode 100644 index 0000000..11c66a5 --- /dev/null +++ b/en/linking_to_external_code/proxies.md @@ -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. diff --git a/en/linking_to_external_code/reloading_modules.md b/en/linking_to_external_code/reloading_modules.md new file mode 100644 index 0000000..6589ea6 --- /dev/null +++ b/en/linking_to_external_code/reloading_modules.md @@ -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` + + + + +- [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) + + diff --git a/en/tools/bundler.md b/en/tools/bundler.md new file mode 100644 index 0000000..0844dfd --- /dev/null +++ b/en/tools/bundler.md @@ -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 + +``` + +Or you could import it into another ES module to consume: + +```html + +``` diff --git a/en/tools/debugger.md b/en/tools/debugger.md new file mode 100644 index 0000000..626032d --- /dev/null +++ b/en/tools/debugger.md @@ -0,0 +1,3 @@ +## Debugger + + diff --git a/en/tools/dependency_inspector.md b/en/tools/dependency_inspector.md new file mode 100644 index 0000000..37bd13c --- /dev/null +++ b/en/tools/dependency_inspector.md @@ -0,0 +1,3 @@ +## Dependency Inspector + + diff --git a/en/tools/documentation_generator.md b/en/tools/documentation_generator.md new file mode 100644 index 0000000..07b0b5c --- /dev/null +++ b/en/tools/documentation_generator.md @@ -0,0 +1,3 @@ +## Documentation Generator + + diff --git a/en/tools/formatter.md b/en/tools/formatter.md new file mode 100644 index 0000000..16a5a9a --- /dev/null +++ b/en/tools/formatter.md @@ -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: + + + +```ts +// deno-fmt-ignore +export const identity = [ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, +]; +``` + + + +Or ignore an entire file by adding a `// deno-fmt-ignore-file` comment at the +top of the file. diff --git a/en/tools/script_installer.md b/en/tools/script_installer.md new file mode 100644 index 0000000..ffd920c --- /dev/null +++ b/en/tools/script_installer.md @@ -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 { + -- 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 +``` diff --git a/zh-cn/README.md b/zh-cn/README.md new file mode 100644 index 0000000..07e72ae --- /dev/null +++ b/zh-cn/README.md @@ -0,0 +1,47 @@ +# Deno Docs + +- [Introduction](./introduction.md) +- [Getting Started](./getting_started.md) + - [Installation](./getting_started/installation.md) + - [Setup your environment](./getting_started/setup_your_environment.md) + - [First steps](./getting_started/first_steps.md) + - [Permissions](./getting_started/permissions.md) + - [Using TypeScript](./getting_started/typescript.md) + - [Using WebAssembly](./getting_started/wasm.md) +- [The Runtime](./runtime.md) + - [Program Lifecycle](./runtime/program_lifecycle.md) + - [Compiler APIs](./runtime/compiler_apis.md) + - [Unstable APIs](./runtime/unstable.md) +- [Linking to external code](./linking_to_external_code.md) + - [Reloading modules](./linking_to_external_code/reloading_modules.md) + - [Integrity checking](./linking_to_external_code/integrity_checking.md) + - [Proxies](./linking_to_external_code/proxies.md) + - [Import maps](./linking_to_external_code/import_maps.md) +- [Testing](./testing.md) + - [Writing tests](./testing/writing.md) + - [Running tests](./testing/running.md) +- [Plugins](./plugins.md) + - [How do plugins work?](./plugins/how_do_plugins_work.md) + - [Creating plugins](./plugins/creating_plugins.md) + - [Using plugins](./plugins/using_plugins.md) +- [Tools](./tools.md) + - [Debugger](./tools/debugger.md) + - [Script installer](./tools/script_installer.md) + - [Formatter](./tools/formatter.md) + - [Bundler](./tools/bundler.md) + - [Documentation generator](./tools/documentation_generator.md) + - [Dependency inspector](./tools/dependency_inspector.md) +- [Embedding Deno](./embedding_deno.md) +- [Contributing](./contributing.md) + - [Building from source](./contributing/building_from_source.md) + - [Development tools](./contributing/development_tools.md) + - [Architecture](./contributing/architecture.md) +- [Examples](./examples.md) + - [Unix cat program](./examples/unix_cat.md) + - [File server](./examples/fileserver.md) + - [TCP echo server](./examples/tcp_echo.md) + - [Creating a subprocess](./examples/subprocess.md) + - [Inspecting and revoking permissions](./examples/permissions.md) + - [OS Signals](./examples/os_signals.md) + - [File system events](./examples/file_system_events.md) + - [Checking if file is main](./examples/testing_if_main.md) diff --git a/zh-cn/contributing.md b/zh-cn/contributing.md new file mode 100644 index 0000000..5394405 --- /dev/null +++ b/zh-cn/contributing.md @@ -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"; +``` diff --git a/zh-cn/contributing/architecture.md b/zh-cn/contributing/architecture.md new file mode 100644 index 0000000..0a1ba3b --- /dev/null +++ b/zh-cn/contributing/architecture.md @@ -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) diff --git a/zh-cn/contributing/building_from_source.md b/zh-cn/contributing/building_from_source.md new file mode 100644 index 0000000..fb1e1ef --- /dev/null +++ b/zh-cn/contributing/building_from_source.md @@ -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 +``` diff --git a/zh-cn/contributing/development_tools.md b/zh-cn/contributing/development_tools.md new file mode 100644 index 0000000..35bd5a5 --- /dev/null +++ b/zh-cn/contributing/development_tools.md @@ -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; + }; +} +``` diff --git a/zh-cn/contributing/profiling.md b/zh-cn/contributing/profiling.md new file mode 100644 index 0000000..e69de29 diff --git a/zh-cn/embedding_deno.md b/zh-cn/embedding_deno.md new file mode 100644 index 0000000..aa8cd58 --- /dev/null +++ b/zh-cn/embedding_deno.md @@ -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). + + diff --git a/zh-cn/examples.md b/zh-cn/examples.md new file mode 100644 index 0000000..13c15a2 --- /dev/null +++ b/zh-cn/examples.md @@ -0,0 +1,4 @@ +# Examples + +In this chapter you can find some example programs that you can use to learn +more about the runtime. diff --git a/zh-cn/examples/fileserver.md b/zh-cn/examples/fileserver.md new file mode 100644 index 0000000..3ed9d90 --- /dev/null +++ b/zh-cn/examples/fileserver.md @@ -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 +``` diff --git a/zh-cn/examples/os_signals.md b/zh-cn/examples/os_signals.md new file mode 100644 index 0000000..5f66f33 --- /dev/null +++ b/zh-cn/examples/os_signals.md @@ -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. diff --git a/zh-cn/examples/permissions.md b/zh-cn/examples/permissions.md new file mode 100644 index 0000000..7d404d5 --- /dev/null +++ b/zh-cn/examples/permissions.md @@ -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"); +``` diff --git a/zh-cn/examples/subprocess.md b/zh-cn/examples/subprocess.md new file mode 100644 index 0000000..80d0cc7 --- /dev/null +++ b/zh-cn/examples/subprocess.md @@ -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 +[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) +``` diff --git a/zh-cn/examples/tcp_echo.md b/zh-cn/examples/tcp_echo.md new file mode 100644 index 0000000..d7c2e9e --- /dev/null +++ b/zh-cn/examples/tcp_echo.md @@ -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. diff --git a/zh-cn/examples/testing_if_main.md b/zh-cn/examples/testing_if_main.md new file mode 100644 index 0000000..67be703 --- /dev/null +++ b/zh-cn/examples/testing_if_main.md @@ -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"); +} +``` diff --git a/zh-cn/examples/unix_cat.md b/zh-cn/examples/unix_cat.md new file mode 100644 index 0000000..7534ef0 --- /dev/null +++ b/zh-cn/examples/unix_cat.md @@ -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 +``` diff --git a/zh-cn/getting_started.md b/zh-cn/getting_started.md new file mode 100644 index 0000000..159d3de --- /dev/null +++ b/zh-cn/getting_started.md @@ -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 diff --git a/zh-cn/getting_started/first_steps.md b/zh-cn/getting_started/first_steps.md new file mode 100644 index 0000000..13118a2 --- /dev/null +++ b/zh-cn/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/zh-cn/getting_started/installation.md b/zh-cn/getting_started/installation.md new file mode 100644 index 0000000..158e181 --- /dev/null +++ b/zh-cn/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 ` 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/zh-cn/getting_started/permissions.md b/zh-cn/getting_started/permissions.md new file mode 100644 index 0000000..a3d0a9e --- /dev/null +++ b/zh-cn/getting_started/permissions.md @@ -0,0 +1,37 @@ +## 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/zh-cn/getting_started/setup_your_environment.md b/zh-cn/getting_started/setup_your_environment.md new file mode 100644 index 0000000..294e86f --- /dev/null +++ b/zh-cn/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 ` 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/zh-cn/getting_started/typescript.md b/zh-cn/getting_started/typescript.md new file mode 100644 index 0000000..5f406e6 --- /dev/null +++ b/zh-cn/getting_started/typescript.md @@ -0,0 +1,151 @@ +## Using TypeScript + + + +### 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 +/// +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/zh-cn/getting_started/wasm.md b/zh-cn/getting_started/wasm.md new file mode 100644 index 0000000..f1c7e6f --- /dev/null +++ b/zh-cn/getting_started/wasm.md @@ -0,0 +1,31 @@ +## WASM support + +Deno can execute [wasm](https://webassembly.org/) binaries. + + +```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()); +``` + + +### 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)); +``` diff --git a/zh-cn/introduction.md b/zh-cn/introduction.md new file mode 100644 index 0000000..091cc7d --- /dev/null +++ b/zh-cn/introduction.md @@ -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) diff --git a/zh-cn/linking_to_external_code.md b/zh-cn/linking_to_external_code.md new file mode 100644 index 0000000..5484a78 --- /dev/null +++ b/zh-cn/linking_to_external_code.md @@ -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. diff --git a/zh-cn/linking_to_external_code/import_maps.md b/zh-cn/linking_to_external_code/import_maps.md new file mode 100644 index 0000000..7ec963d --- /dev/null +++ b/zh-cn/linking_to_external_code/import_maps.md @@ -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=` 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 +``` diff --git a/zh-cn/linking_to_external_code/integrity_checking.md b/zh-cn/linking_to_external_code/integrity_checking.md new file mode 100644 index 0000000..820ea1d --- /dev/null +++ b/zh-cn/linking_to_external_code/integrity_checking.md @@ -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`. diff --git a/zh-cn/linking_to_external_code/proxies.md b/zh-cn/linking_to_external_code/proxies.md new file mode 100644 index 0000000..11c66a5 --- /dev/null +++ b/zh-cn/linking_to_external_code/proxies.md @@ -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. diff --git a/zh-cn/linking_to_external_code/reloading_modules.md b/zh-cn/linking_to_external_code/reloading_modules.md new file mode 100644 index 0000000..6589ea6 --- /dev/null +++ b/zh-cn/linking_to_external_code/reloading_modules.md @@ -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` + + + + +- [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) + + diff --git a/zh-cn/tools/bundler.md b/zh-cn/tools/bundler.md new file mode 100644 index 0000000..0844dfd --- /dev/null +++ b/zh-cn/tools/bundler.md @@ -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 + +``` + +Or you could import it into another ES module to consume: + +```html + +``` diff --git a/zh-cn/tools/debugger.md b/zh-cn/tools/debugger.md new file mode 100644 index 0000000..626032d --- /dev/null +++ b/zh-cn/tools/debugger.md @@ -0,0 +1,3 @@ +## Debugger + + diff --git a/zh-cn/tools/dependency_inspector.md b/zh-cn/tools/dependency_inspector.md new file mode 100644 index 0000000..37bd13c --- /dev/null +++ b/zh-cn/tools/dependency_inspector.md @@ -0,0 +1,3 @@ +## Dependency Inspector + + diff --git a/zh-cn/tools/documentation_generator.md b/zh-cn/tools/documentation_generator.md new file mode 100644 index 0000000..07b0b5c --- /dev/null +++ b/zh-cn/tools/documentation_generator.md @@ -0,0 +1,3 @@ +## Documentation Generator + + diff --git a/zh-cn/tools/formatter.md b/zh-cn/tools/formatter.md new file mode 100644 index 0000000..16a5a9a --- /dev/null +++ b/zh-cn/tools/formatter.md @@ -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: + + + +```ts +// deno-fmt-ignore +export const identity = [ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, +]; +``` + + + +Or ignore an entire file by adding a `// deno-fmt-ignore-file` comment at the +top of the file. diff --git a/zh-cn/tools/script_installer.md b/zh-cn/tools/script_installer.md new file mode 100644 index 0000000..ffd920c --- /dev/null +++ b/zh-cn/tools/script_installer.md @@ -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 { + -- 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 +```