image.png

rust 在去年一年火遍了整个开发社区,相当多的客户在生产环境使用了 rust,rust 官网给自己定位也相当的清晰,在2018 年 rust 官方决定在以下几个地方加大投入。
image.png

尤其是 rust 是最早支持的 Web­Assembly 的语言之一,作为一个前端很想试试这种范式完全不同的新语言,但是一直没有什么好的切入点,只能草草的跑点 demo,上个月在晚上冲浪的时候看到了 modern-unix 里面大部分项目都用了 rust 来实现命令行,包括我最近一直在观察的 deno_lint 也是用rust的写的,于是我觉得写个用 rust 读取路由并且给出格式检查的工具。

准备工作

安装 rust https://www.rust-lang.org/zh-CN/
学习 rust 语法 https://kaisery.github.io/trpl-zh-cn/
安装 vsocde 和 rust 插件 https://code.visualstudio.com/

初始化

rust 提供了官方的脚手架工具,我们可以使用官网的脚手架来快速完成。

  1. cargo new router-lint

与前端不同的是,rust 是通过 cargo build 来安装依赖的,安装完成后可以执行 cargo run 执行代码,出现这个代码就代表已经成功初始化了脚手架。
image.png

读取文件内容

作为一个 cli,我们首先要定义好参数, rust 提供了一个非常好用的结构化参数工具。

  1. /// Search for a pattern in a file and display the lines that contain it.
  2. #[derive(StructOpt)]
  3. struct Cli {
  4. /// The path to the file to read
  5. #[structopt(parse(from_os_str))]
  6. path: std::path::PathBuf,
  7. h: bool
  8. }

以上的配置就告诉 rust 我需要这两个参数,你帮我自动格式化一下。

  1. fn main() {
  2. let args = Cli::from_args();
  3. let path = &args.path;
  4. // display 可以转化成需要显示的文案
  5. let path_str: String = path.as_path().display().to_string();
  6. let content = std::fs::read_to_string(&args.path)
  7. .map_err(|err| ReadFileError(format!("读取文件异常: `{}`: {}", path_str, err)))?;
  8. println!("file content: {}", content);
  9. }

解析语法树

这时候就要用到 swc 这个前端之光了,swc 速度非常快,也是用 rust 写的, 直接裸写 swc 对我来说有点超纲了,我们用一下 deno 封装 deno_ast ,因为我们只需要的解析 ast 不需要生成新的 ast 树。

  1. [dependencies]
  2. structopt = "0.3.13"
  3. indicatif = {version = "*", features = ["rayon"]}
  4. deno_ast = { version = "0.4.1", features = ["transforms", "utils", "visit", "view"] }

读取文件内容并获取 ast

  1. use deno_ast::swc::parser::Syntax;
  2. use deno_ast::view as ast_view;
  3. use deno_ast::Diagnostic;
  4. use deno_ast::MediaType;
  5. use deno_ast::ParsedSource;
  6. use structopt::StructOpt;
  7. fn parse_program(
  8. file_name: &str,
  9. syntax: Syntax,
  10. source_code: String,
  11. ) -> Result<ParsedSource, Diagnostic> {
  12. deno_ast::parse_program(deno_ast::ParseParams {
  13. specifier: file_name.to_string(),
  14. media_type: MediaType::Unknown,
  15. source: deno_ast::SourceTextInfo::from_string(source_code),
  16. capture_tokens: true,
  17. maybe_syntax: Some(syntax),
  18. scope_analysis: true,
  19. })
  20. }
  21. fn main() -> Result<(), ReadFileError> {
  22. let syntax = deno_ast::get_syntax(MediaType::TypeScript);
  23. let ast = parse_program(&path_str, syntax, content).unwrap();
  24. }

遍历 ast,读取项目里面所有的注释

  1. ast.with_view(|program| {
  2. program
  3. .comment_container()
  4. .unwrap()
  5. .leading_comments(program.span().lo())
  6. .for_each(|comment| {
  7. let comment_text = comment.text.trim();
  8. println!("{}", comment_text);
  9. })
  10. });

总结

  • rust 速度的确很快,生态现在也不错尤其是与 js 相关的,因为 swc 和 deno 相关生态非常完善。
  • rust 学习曲线非常陡峭,代码也非常啰嗦,虽然 bug 少,但是要投入很多时间。
  • rust 写一个工具成本很高,如果不是对体验要求高,或者写完之后能被用很多年,不然不推荐使用 rust。
  • 用别的语言来重写 js 的生态是趋势,未来还会看到很多。