试用 Deno

图片来自 deno twitter

Deno 1.0 正式版释出,趁着余温尝试一波。

安装

文档 中给出了多种安装姿势,mac 上 brew 当然是不二之选,简单高效。

$ brew install deno

运行 Demo

安装成功后就可以跑 Demo 了。Deno 中运行代码也是非常方便,因为天然支持从远端拉取。

$ deno run https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕

Hello World 程序正常打印出了信息, so far so good!

接着运行官网提供的另一示例,问题来了。

创建 index.ts 文件并写入以下代码:

import { serve } from "https://deno.land/std@0.50.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}

引入 server 标准库起一个本地服务器,没什么可说的,让我们跑起来:

$ deno index.ts

以下是运行上面的示例代码后的错误输出:

使用 deno 启动本地服务的报错信息
deno run --allow-net ./index.ts
Compile file:///Users/wayou/work/dev/github/deno-demo/index.ts
error TS2322: Type '(_: Uint8Array) => Promise<number | null>' is not assignable to type '(p: Uint8Array) => Promise<number | unique symbol>'.
  Type 'Promise<number | null>' is not assignable to type 'Promise<number | unique symbol>'.

► https://deno.land/std@0.50.0/http/_io.ts:10:5

10     read(_: Uint8Array): Promise<number | null> {
       ~~~~

error TS2322: Type '(buf: Uint8Array) => Promise<number | null>' is not assignable to type '(p: Uint8Array) => Promise<number | unique symbol>'.
  Type 'Promise<number | null>' is not assignable to type 'Promise<number | unique symbol>'.

► https://deno.land/std@0.50.0/http/_io.ts:35:12

35   return { read };
              ~~~~

error TS2322: Type '(buf: Uint8Array) => Promise<number | null>' is not assignable to type '(p: Uint8Array) => Promise<number | unique symbol>'.
  Type 'Promise<number | null>' is not assignable to type 'Promise<number | unique symbol>'.

► https://deno.land/std@0.50.0/http/_io.ts:113:12

113   return { read };
               ~~~~

error TS2339: Property 'iter' does not exist on type 'typeof Deno'.

► https://deno.land/std@0.50.0/http/_io.ts:167:34

167   for await (const chunk of Deno.iter(r)) {
                                     ~~~~

error TS2345: Argument of type 'Reader' is not assignable to parameter of type 'Writer'.
  Property 'write' is missing in type 'Reader' but required in type 'Writer'.

► https://deno.land/std@0.50.0/http/_io.ts:265:31

265     const n = await Deno.copy(r.body, writer);
                                  ~~~~~~

  'write' is declared here.

    ► $asset$/lib.deno.ns.d.ts:366:5

    366     write(p: Uint8Array): Promise<number>;
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


error TS2339: Property 'listenTls' does not exist on type 'typeof Deno'.

► https://deno.land/std@0.50.0/http/server.ts:16:17

16 const { listen, listenTls } = Deno;
                   ~~~~~~~~~

error TS2694: Namespace 'Deno' has no exported member 'ListenTlsOptions'.

► https://deno.land/std@0.50.0/http/server.ts:289:38

289 export type HTTPSOptions = Omit<Deno.ListenTlsOptions, "transport">;
                                         ~~~~~~~~~~~~~~~~

error TS2694: Namespace 'Deno' has no exported member 'ListenTlsOptions'.

► https://deno.land/std@0.50.0/http/server.ts:309:26

309   const tlsOptions: Deno.ListenTlsOptions = {
                             ~~~~~~~~~~~~~~~~

error TS2694: Namespace 'Deno' has no exported member 'WriterSync'.

► https://deno.land/std@0.50.0/io/bufio.ts:8:24

8 type WriterSync = Deno.WriterSync;
                         ~~~~~~~~~~

error TS2469: The '>=' operator cannot be applied to type 'symbol'.

► https://deno.land/std@0.50.0/io/bufio.ts:90:14

90       assert(rr >= 0, "negative read");
                ~~

error TS2365: Operator '+=' cannot be applied to types 'number' and 'number | unique symbol'.

► https://deno.land/std@0.50.0/io/bufio.ts:91:7

91       this.w += rr;
         ~~~~~~~~~~~~

error TS2469: The '>' operator cannot be applied to type 'symbol'.

► https://deno.land/std@0.50.0/io/bufio.ts:92:11

92       if (rr > 0) {
             ~~

error TS2416: Property 'read' in type 'BufReader' is not assignable to the same property in base type 'Reader'.
  Type '(p: Uint8Array) => Promise<number | null>' is not assignable to type '(p: Uint8Array) => Promise<number | unique symbol>'.
    Type 'Promise<number | null>' is not assignable to type 'Promise<number | unique symbol>'.
      Type 'number | null' is not assignable to type 'number | unique symbol'.
        Type 'null' is not assignable to type 'number | unique symbol'.

► https://deno.land/std@0.50.0/io/bufio.ts:123:9

123   async read(p: Uint8Array): Promise<number | null> {
            ~~~~

error TS2469: The '>=' operator cannot be applied to type 'symbol'.

► https://deno.land/std@0.50.0/io/bufio.ts:133:16

133         assert(nread >= 0, "negative read");
                   ~~~~~

error TS2322: Type 'number | unique symbol' is not assignable to type 'number | null'.
  Type 'unique symbol' is not assignable to type 'number | null'.

► https://deno.land/std@0.50.0/io/bufio.ts:138:9

138         return rr;
            ~~~~~~~~~~

error TS2322: Type 'number | unique symbol' is not assignable to type 'number | null'.
  Type 'unique symbol' is not assignable to type 'number | null'.

► https://deno.land/std@0.50.0/io/bufio.ts:145:7

145       rr = await this.rd.read(this.buf);
          ~~

error TS2367: This condition will always return 'false' since the types 'OperatingSystem' and '"windows"' have no overlap.

► https://deno.land/std@0.50.0/path/_constants.ts:51:19

51 const isWindows = build.os == "windows";
                     ~~~~~~~~~~~~~~~~~~~~~

error TS2367: This condition will always return 'false' since the types 'OperatingSystem' and '"windows"' have no overlap.

► https://deno.land/std@0.50.0/path/_globrex.ts:5:15

5 const isWin = Deno.build.os === "windows";
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~

error TS2367: This condition will always return 'false' since the types 'OperatingSystem' and '"windows"' have no overlap.

► https://deno.land/std@0.50.0/path/mod.ts:7:19

7 const isWindows = Deno.build.os == "windows";
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~

error TS2345: Argument of type 'string | URL' is not assignable to parameter of type 'string'.
  Type 'URL' is not assignable to type 'string'.

► https://deno.land/std@0.50.0/path/posix.ts:433:18

433   return new URL(url).pathname;
                     ~~~

error TS2367: This condition will always return 'false' since the types 'OperatingSystem' and '"windows"' have no overlap.

► https://deno.land/std@0.50.0/path/separator.ts:2:19

2 const isWindows = Deno.build.os == "windows";
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~

error TS2339: Property 'get' does not exist on type '{ (): { [index: string]: string; }; (key: string): string | undefined; }'.

► https://deno.land/std@0.50.0/path/win32.ts:42:18

42       path = env.get(`=${resolvedDevice}`) || cwd();
                    ~~~

error TS2345: Argument of type 'string | URL' is not assignable to parameter of type 'string'.
  Type 'URL' is not assignable to type 'string'.

► https://deno.land/std@0.50.0/path/win32.ts:911:18

911   return new URL(url).pathname
                     ~~~


Found 23 errors.

这么多报错,肯定姿势不对。细查后发现了问题,安装的 deno 版本并不是刚发布还热乎的 1.0!

$ deno -V
deno 0.36.0

再去看 brew 上面的版本,果然:

$ brew info deno
deno: stable 0.36.0 (bottled)
Command-line JavaScript / TypeScript engine
https://deno.land/
/usr/local/Cellar/deno/0.36.0 (9 files, 55.1MB) *
  Poured from bottle on 2020-05-17 at 14:31:34
From: https://mirrors.ustc.edu.cn/homebrew-core.git/Formula/deno.rb
==> Dependencies
Build: ninja ✔, rust ✘
==> Requirements
Build: xcode ✔
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions
==> Analytics
install: 13,653 (30 days), 20,861 (90 days), 37,002 (365 days)
install-on-request: 13,649 (30 days), 20,843 (90 days), 36,969 (365 days)
build-error: 0 (30 days)

之前一直有个习惯,安装完某个东西后会查看版本,以检查安装是否成功,顺便确定所装版本。这次栽了。

重新安装

使用 brew 安装前先 brew update 或不使用 brew,通过以下命令来安装:

$ curl -fsSL https://deno.land/x/install/install.sh | sh
通过 curl 安装 deno 过程中的输出
 curl -fsSL https://deno.land/x/install/install.sh | sh 

######################################################################## 100.0%
Archive:  /Users/wayou/.deno/bin/deno.zip
  inflating: deno
Deno was installed successfully to /Users/wayou/.deno/bin/deno
Manually add the directory to your $HOME/.bash_profile (or similar)
  export DENO_INSTALL="/Users/wayou/.deno"
  export PATH="$DENO_INSTALL/bin:$PATH"
Run '/Users/wayou/.deno/bin/deno --help' to get started

添加环境变量

如果使用 brew 安装可省略此步骤。

根据提示,需要将 deno 添加到环境变量中方可在命令行中执行:

  export DENO_INSTALL="/Users/wayou/.deno"
  export PATH="$DENO_INSTALL/bin:$PATH"

再次运行

检查安装:

$ deno -V
deno 1.0.0

现在对了,再次运行前面失败的示例:

$ deno run ./index.ts
Compile file:///Users/wayou/work/dev/github/deno-demo/index.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
    at Object.listen ($deno$/ops/net.ts:51:10)
    at listen ($deno$/net.ts:152:22)
    at serve (https://deno.land/std@0.50.0/http/server.ts:261:20)
    at file:///Users/wayou/work/dev/github/deno-demo/index.ts:2:11

还是报错,但错误不一样了。

权限问题

Deno 中对权限的要求更加细致,这里的命令需要给到网络权限。修正我们的命令再次运行:

$ deno run --allow-net ./index.ts
Compile file:///Users/wayou/work/dev/github/deno-demo/index.ts
http://localhost:8000/

访问 http://localhost:8000/,Demo 达成。

Screen Shot 2020-05-17 at 18 56 41

访问 Deno 启动的服务

What's next?

命令的自动补全

查看 deno 的帮助,发现其提供了各 shell 下的补全脚本,

$ deno -h
...
    completions    Generate shell completions
...

这就好玩了,对于 fish shell,其补全脚本为:

fish shell 的 deno 补全脚本
$ deno completions fish 
complete -c deno -n "__fish_use_subcommand" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_use_subcommand" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_use_subcommand" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_use_subcommand" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_use_subcommand" -f -a "bundle" -d 'Bundle module and dependencies into single file'
complete -c deno -n "__fish_use_subcommand" -f -a "completions" -d 'Generate shell completions'
complete -c deno -n "__fish_use_subcommand" -f -a "eval" -d 'Eval script'
complete -c deno -n "__fish_use_subcommand" -f -a "cache" -d 'Cache the dependencies'
complete -c deno -n "__fish_use_subcommand" -f -a "fmt" -d 'Format source files'
complete -c deno -n "__fish_use_subcommand" -f -a "info" -d 'Show info about cache or info related to source file'
complete -c deno -n "__fish_use_subcommand" -f -a "install" -d 'Install script as an executable'
complete -c deno -n "__fish_use_subcommand" -f -a "repl" -d 'Read Eval Print Loop'
complete -c deno -n "__fish_use_subcommand" -f -a "run" -d 'Run a program given a filename or url to the module'
complete -c deno -n "__fish_use_subcommand" -f -a "test" -d 'Run tests'
complete -c deno -n "__fish_use_subcommand" -f -a "types" -d 'Print runtime TypeScript declarations'
complete -c deno -n "__fish_use_subcommand" -f -a "upgrade" -d 'Upgrade deno executable to given version'
complete -c deno -n "__fish_use_subcommand" -f -a "doc" -d 'Show documentation for a module'
complete -c deno -n "__fish_use_subcommand" -f -a "help" -d 'Prints this message or the help of the given subcommand(s)'
complete -c deno -n "__fish_seen_subcommand_from bundle" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from bundle" -l importmap -d 'UNSTABLE: Load import map file'
complete -c deno -n "__fish_seen_subcommand_from bundle" -s c -l config -d 'Load tsconfig.json configuration file'
complete -c deno -n "__fish_seen_subcommand_from bundle" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from bundle" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from bundle" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from bundle" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from bundle" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from completions" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from completions" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from completions" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from completions" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from eval" -l inspect -d 'activate inspector on host:port (default: 127.0.0.1:9229)'
complete -c deno -n "__fish_seen_subcommand_from eval" -l inspect-brk -d 'activate inspector on host:port and break at start of user script'
complete -c deno -n "__fish_seen_subcommand_from eval" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from eval" -l v8-flags -d 'Set V8 command line options. For help: --v8-flags=--help'
complete -c deno -n "__fish_seen_subcommand_from eval" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from eval" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from eval" -s T -l ts -d 'Treat eval input as TypeScript'
complete -c deno -n "__fish_seen_subcommand_from eval" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from eval" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from eval" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from cache" -s r -l reload -d 'Reload source code cache (recompile TypeScript)'
complete -c deno -n "__fish_seen_subcommand_from cache" -l lock -d 'Check the specified lock file'
complete -c deno -n "__fish_seen_subcommand_from cache" -l importmap -d 'UNSTABLE: Load import map file'
complete -c deno -n "__fish_seen_subcommand_from cache" -s c -l config -d 'Load tsconfig.json configuration file'
complete -c deno -n "__fish_seen_subcommand_from cache" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from cache" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from cache" -l lock-write -d 'Write lock file. Use with --lock.'
complete -c deno -n "__fish_seen_subcommand_from cache" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from cache" -l no-remote -d 'Do not resolve remote modules'
complete -c deno -n "__fish_seen_subcommand_from cache" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from cache" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from cache" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from fmt" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from fmt" -l check -d 'Check if the source files are formatted.'
complete -c deno -n "__fish_seen_subcommand_from fmt" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from fmt" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from fmt" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from info" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from info" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from info" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from info" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from info" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from info" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from install" -l allow-read -d 'Allow file system read access'
complete -c deno -n "__fish_seen_subcommand_from install" -l allow-write -d 'Allow file system write access'
complete -c deno -n "__fish_seen_subcommand_from install" -l allow-net -d 'Allow network access'
complete -c deno -n "__fish_seen_subcommand_from install" -s n -l name -d 'Executable file name'
complete -c deno -n "__fish_seen_subcommand_from install" -l root -d 'Installation root'
complete -c deno -n "__fish_seen_subcommand_from install" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from install" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from install" -l allow-env -d 'Allow environment access'
complete -c deno -n "__fish_seen_subcommand_from install" -l allow-run -d 'Allow running subprocesses'
complete -c deno -n "__fish_seen_subcommand_from install" -l allow-plugin -d 'Allow loading plugins'
complete -c deno -n "__fish_seen_subcommand_from install" -l allow-hrtime -d 'Allow high resolution time measurement'
complete -c deno -n "__fish_seen_subcommand_from install" -s A -l allow-all -d 'Allow all permissions'
complete -c deno -n "__fish_seen_subcommand_from install" -s f -l force -d 'Forcefully overwrite existing installation'
complete -c deno -n "__fish_seen_subcommand_from install" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from install" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from install" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from install" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from repl" -l inspect -d 'activate inspector on host:port (default: 127.0.0.1:9229)'
complete -c deno -n "__fish_seen_subcommand_from repl" -l inspect-brk -d 'activate inspector on host:port and break at start of user script'
complete -c deno -n "__fish_seen_subcommand_from repl" -l v8-flags -d 'Set V8 command line options. For help: --v8-flags=--help'
complete -c deno -n "__fish_seen_subcommand_from repl" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from repl" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from repl" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from repl" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from repl" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from repl" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from run" -l inspect -d 'activate inspector on host:port (default: 127.0.0.1:9229)'
complete -c deno -n "__fish_seen_subcommand_from run" -l inspect-brk -d 'activate inspector on host:port and break at start of user script'
complete -c deno -n "__fish_seen_subcommand_from run" -l allow-read -d 'Allow file system read access'
complete -c deno -n "__fish_seen_subcommand_from run" -l allow-write -d 'Allow file system write access'
complete -c deno -n "__fish_seen_subcommand_from run" -l allow-net -d 'Allow network access'
complete -c deno -n "__fish_seen_subcommand_from run" -l importmap -d 'UNSTABLE: Load import map file'
complete -c deno -n "__fish_seen_subcommand_from run" -s r -l reload -d 'Reload source code cache (recompile TypeScript)'
complete -c deno -n "__fish_seen_subcommand_from run" -s c -l config -d 'Load tsconfig.json configuration file'
complete -c deno -n "__fish_seen_subcommand_from run" -l lock -d 'Check the specified lock file'
complete -c deno -n "__fish_seen_subcommand_from run" -l v8-flags -d 'Set V8 command line options. For help: --v8-flags=--help'
complete -c deno -n "__fish_seen_subcommand_from run" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from run" -l seed -d 'Seed Math.random()'
complete -c deno -n "__fish_seen_subcommand_from run" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from run" -l allow-env -d 'Allow environment access'
complete -c deno -n "__fish_seen_subcommand_from run" -l allow-run -d 'Allow running subprocesses'
complete -c deno -n "__fish_seen_subcommand_from run" -l allow-plugin -d 'Allow loading plugins'
complete -c deno -n "__fish_seen_subcommand_from run" -l allow-hrtime -d 'Allow high resolution time measurement'
complete -c deno -n "__fish_seen_subcommand_from run" -s A -l allow-all -d 'Allow all permissions'
complete -c deno -n "__fish_seen_subcommand_from run" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from run" -l lock-write -d 'Write lock file. Use with --lock.'
complete -c deno -n "__fish_seen_subcommand_from run" -l no-remote -d 'Do not resolve remote modules'
complete -c deno -n "__fish_seen_subcommand_from run" -l cached-only -d 'Require that remote dependencies are already cached'
complete -c deno -n "__fish_seen_subcommand_from run" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from run" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from run" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from test" -l inspect -d 'activate inspector on host:port (default: 127.0.0.1:9229)'
complete -c deno -n "__fish_seen_subcommand_from test" -l inspect-brk -d 'activate inspector on host:port and break at start of user script'
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-read -d 'Allow file system read access'
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-write -d 'Allow file system write access'
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-net -d 'Allow network access'
complete -c deno -n "__fish_seen_subcommand_from test" -l importmap -d 'UNSTABLE: Load import map file'
complete -c deno -n "__fish_seen_subcommand_from test" -s r -l reload -d 'Reload source code cache (recompile TypeScript)'
complete -c deno -n "__fish_seen_subcommand_from test" -s c -l config -d 'Load tsconfig.json configuration file'
complete -c deno -n "__fish_seen_subcommand_from test" -l lock -d 'Check the specified lock file'
complete -c deno -n "__fish_seen_subcommand_from test" -l v8-flags -d 'Set V8 command line options. For help: --v8-flags=--help'
complete -c deno -n "__fish_seen_subcommand_from test" -l cert -d 'Load certificate authority from PEM encoded file'
complete -c deno -n "__fish_seen_subcommand_from test" -l seed -d 'Seed Math.random()'
complete -c deno -n "__fish_seen_subcommand_from test" -l filter -d 'A pattern to filter the tests to run by'
complete -c deno -n "__fish_seen_subcommand_from test" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-env -d 'Allow environment access'
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-run -d 'Allow running subprocesses'
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-plugin -d 'Allow loading plugins'
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-hrtime -d 'Allow high resolution time measurement'
complete -c deno -n "__fish_seen_subcommand_from test" -s A -l allow-all -d 'Allow all permissions'
complete -c deno -n "__fish_seen_subcommand_from test" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from test" -l lock-write -d 'Write lock file. Use with --lock.'
complete -c deno -n "__fish_seen_subcommand_from test" -l no-remote -d 'Do not resolve remote modules'
complete -c deno -n "__fish_seen_subcommand_from test" -l cached-only -d 'Require that remote dependencies are already cached'
complete -c deno -n "__fish_seen_subcommand_from test" -l failfast -d 'Stop on first error'
complete -c deno -n "__fish_seen_subcommand_from test" -l allow-none -d 'Don\'t return error code if no test files are found'
complete -c deno -n "__fish_seen_subcommand_from test" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from test" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from test" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from types" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from types" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from types" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from types" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from types" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from upgrade" -l version -d 'The version to upgrade to'
complete -c deno -n "__fish_seen_subcommand_from upgrade" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from upgrade" -l dry-run -d 'Perform all checks without replacing old exe'
complete -c deno -n "__fish_seen_subcommand_from upgrade" -s f -l force -d 'Replace current exe even if not out-of-date'
complete -c deno -n "__fish_seen_subcommand_from upgrade" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from upgrade" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from doc" -s r -l reload -d 'Reload source code cache (recompile TypeScript)'
complete -c deno -n "__fish_seen_subcommand_from doc" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from doc" -l unstable -d 'Enable unstable APIs'
complete -c deno -n "__fish_seen_subcommand_from doc" -l json -d 'Output documentation in JSON format.'
complete -c deno -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from doc" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from doc" -s q -l quiet -d 'Suppress diagnostic output'
complete -c deno -n "__fish_seen_subcommand_from help" -s L -l log-level -d 'Set log level' -r -f -a "debug info"
complete -c deno -n "__fish_seen_subcommand_from help" -s h -l help -d 'Prints help information'
complete -c deno -n "__fish_seen_subcommand_from help" -s V -l version -d 'Prints version information'
complete -c deno -n "__fish_seen_subcommand_from help" -s q -l quiet -d 'Suppress diagnostic output'

将其制作成 fish 插件安装后,就可以通过 Tab 看到自动的命令提示了:

$ omf install https://github.com/wayou/plugin-deno

上面只是一点微小的工作,接下来,就是广大社区的拥趸们,开启又一轮造轮子狂欢热潮时候了。

其实一些轮子已经在路上了,从 Node.js 移民 deno 指南

从 Deno 证实了一些事情:

  • TypeScript 大势所趋,不管喜欢与否。其实早在 2014 年 Angular2 就将这个趋势奠定了,实力诠释了一波无敌是多么的寂寞。
  • 解决了 Ryan Dahl 在 10 Things I Regret About Node.js 演讲中提到的 10 个问题。根据 bug 守恒,问题不会减少,它只是换了种形式。

相关资源