deno fmt 从 prettier 切换到 dprint,性能提升 10+ 倍

如果问 Deno 的发布带来了什么,最重要的无疑是将高性能的 Rust 工具链带到了前端。

提到 JavaScript 总给人一种感觉:慢。

Deno 使用 TypeScript 和 Rust 开发,Deno 除了可以运行 JS(X) 和 TS(X) 代码外,还提供了其它命令行参数。比如 deno fmt, deno lint, deno doc 等等。今天我们的话题就是 deno fmt:代码格式化工具。

运行 deno fmt --help 的输出:

deno-fmt
Auto-format JavaScript/TypeScript source code.
  deno fmt
  deno fmt myfile1.ts myfile2.ts
  deno fmt --check

Format stdin and write to stdout:
  cat file.ts | deno fmt -

Ignore formatting code by preceding it with an ignore comment:
  // deno-fmt-ignore

Ignore formatting a file by adding an ignore comment at the top of the file:
  // deno-fmt-ignore-file

USAGE:
    deno fmt [OPTIONS] [files]...

OPTIONS:
        --check
            Check if the source files are formatted.

    -h, --help
            Prints help information

    -L, --log-level <log-level>
            Set log level [possible values: debug, info]

    -q, --quiet
            Suppress diagnostic output
            By default, subcommands print human-readable diagnostic messages to stderr.
            If the flag is set, restrict these messages to errors.

ARGS:
    <files>...

在最初的版本中,Deno 格式化工具使用的是 prettier。prettier 是前端非常非常流行的代码格式化工具,在 npm 上的月下载量是三四千万。

不久前 Deno 的格式化工具切换到了 dprint。大概一年前(2019年6月)David Sherret 开始开发 dprint,最初是作为一个 Node.js 项目。今年开始作者将 dprint 的代码都迁移到了 Rust。

dprint cli 本身并不处理文件的格式化,对特定类型文件格式化的操作是由插件提供,目前官方提供了 4 个插件可以用来格式化 ts/js、json、rust、markdown。这些插件也是使用 Rust 编写,并被编译为 wasm 和 crate(crate 是 Rust 的包)。

dprint 的所有插件都是 wasm 格式,而 deno fmt 则直接使用了 crate,因此在性能方面 deno fmt 要优于 dprint。

我在自己的电脑上测试了一个包含 590 个文件的 TypeScript React 项目:

Formatted 590 files.
dprint fmt 7.82s user 3.05s system 326% cpu  3.334 total
deno fmt   4.41s user 2.49s system 748% cpu  0.921 total
prettier  15.77s user 4.28s system 124% cpu 16.042 total

可以看到 dprint 是 prettier 的 5 倍,deno fmt 是 prettier 的 17 倍。

目前 dprint 还在快速迭代,将来还会有更多的格式化插件开发出来,这样就可以更快的格式化更多的文件类型,比如 vue、css、pug 等等。

我已经打算在下一个 React 项目中使用 deno fmt 代替 prettier 了。

除了 deno fmt 之外,deno lint 也已经发布了 0.1.19 版。基准测试数据显示 deno_lint 的性能大概是 eslint 的 14 倍。

:hugs: