rust 在去年一年火遍了整个开发社区,相当多的客户在生产环境使用了 rust,rust 官网给自己定位也相当的清晰,在2018 年 rust 官方决定在以下几个地方加大投入。
尤其是 rust 是最早支持的 WebAssembly 的语言之一,作为一个前端很想试试这种范式完全不同的新语言,但是一直没有什么好的切入点,只能草草的跑点 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 提供了官方的脚手架工具,我们可以使用官网的脚手架来快速完成。
cargo new router-lint
与前端不同的是,rust 是通过 cargo build
来安装依赖的,安装完成后可以执行 cargo run
执行代码,出现这个代码就代表已经成功初始化了脚手架。
读取文件内容
作为一个 cli,我们首先要定义好参数, rust 提供了一个非常好用的结构化参数工具。
/// Search for a pattern in a file and display the lines that contain it.
#[derive(StructOpt)]
struct Cli {
/// The path to the file to read
#[structopt(parse(from_os_str))]
path: std::path::PathBuf,
h: bool
}
以上的配置就告诉 rust 我需要这两个参数,你帮我自动格式化一下。
fn main() {
let args = Cli::from_args();
let path = &args.path;
// display 可以转化成需要显示的文案
let path_str: String = path.as_path().display().to_string();
let content = std::fs::read_to_string(&args.path)
.map_err(|err| ReadFileError(format!("读取文件异常: `{}`: {}", path_str, err)))?;
println!("file content: {}", content);
}
解析语法树
这时候就要用到 swc 这个前端之光了,swc 速度非常快,也是用 rust 写的, 直接裸写 swc 对我来说有点超纲了,我们用一下 deno 封装 deno_ast ,因为我们只需要的解析 ast 不需要生成新的 ast 树。
[dependencies]
structopt = "0.3.13"
indicatif = {version = "*", features = ["rayon"]}
deno_ast = { version = "0.4.1", features = ["transforms", "utils", "visit", "view"] }
读取文件内容并获取 ast
use deno_ast::swc::parser::Syntax;
use deno_ast::view as ast_view;
use deno_ast::Diagnostic;
use deno_ast::MediaType;
use deno_ast::ParsedSource;
use structopt::StructOpt;
fn parse_program(
file_name: &str,
syntax: Syntax,
source_code: String,
) -> Result<ParsedSource, Diagnostic> {
deno_ast::parse_program(deno_ast::ParseParams {
specifier: file_name.to_string(),
media_type: MediaType::Unknown,
source: deno_ast::SourceTextInfo::from_string(source_code),
capture_tokens: true,
maybe_syntax: Some(syntax),
scope_analysis: true,
})
}
fn main() -> Result<(), ReadFileError> {
let syntax = deno_ast::get_syntax(MediaType::TypeScript);
let ast = parse_program(&path_str, syntax, content).unwrap();
}
遍历 ast,读取项目里面所有的注释
ast.with_view(|program| {
program
.comment_container()
.unwrap()
.leading_comments(program.span().lo())
.for_each(|comment| {
let comment_text = comment.text.trim();
println!("{}", comment_text);
})
});
总结
- rust 速度的确很快,生态现在也不错尤其是与 js 相关的,因为 swc 和 deno 相关生态非常完善。
- rust 学习曲线非常陡峭,代码也非常啰嗦,虽然 bug 少,但是要投入很多时间。
- rust 写一个工具成本很高,如果不是对体验要求高,或者写完之后能被用很多年,不然不推荐使用 rust。
- 用别的语言来重写 js 的生态是趋势,未来还会看到很多。