前言
在rust世界中,cargo所扮演的角色是包管理器,类似Node.js中npm的作用。默认情况下cargo会从 crates.io 下载所需要的依赖包,你可以在这上面注册账号并推送包,类似你在 npmjs.com 所做的那样
对应关系
项目配置文件
在Node.js中我们使用package.json作为配置文件,而在rust中我们采用Cargo.toml。Cargo.toml采用的是 toml 格式而非JSON。Cargo.toml文件的作用是告诉cargo当前项目依赖哪些模块、如何运行测试以及如何build你的项目,更多信息可见 The Manifest Format
初始化新项目
在Node.js中我们使用npm init命令进行初始化,在rust中我们使用cargo init和cargo new命令做同样的事情。cargo init会在当前文件夹中做初始化,cargo new则是会指定一个文件夹
安装依赖
在Node.js中我们使用npm install [dep]命令来安装依赖的模块,如果安装了 cargo-edit 那么在rust中我们可以使用cargo add [dep]来增添依赖,安装方法:
cargo install cargo-edit
安装完毕后,会增加4个子命令:add、rm、upgrade、set-version
全局安装
类比Node.js中的npm install --global,在rust中我们使用cargo install
运行测试
类比Node.js中的npm test,在rust中我们使用cargo test
发布模块
类比Node.js中的npm publish,在rust中我们使用cargo publish
运行任务
在Node.js中我们使用npm run xxx来运行任务,然而在rust中除了几个常见的命令外,其余的都是取决于用户自己。例如我们可以通过cargo run来运行一个代码,或者用cargo bench分析一段代码的性能,或者是用cargo build来做打包,或者是用cargo clean来清空打包目录(默认是target),或者是用cargo doc生成文档。cargo还支持 Build Scripts 机制确保可以打包之前运行指定的程序。
在JavaScript中已经不需要Makefile,但在Rust中就没那么幸运了,Makefile还是很常见。不过 just 正在被广泛接受,它弥补了Makefile的一些弱点,语法上也很相似,可以如下安装:
$ cargo install just
cargo-make和cargo-cmd也是很好的替代方案
workspace与monorepo
包管理器在处理大项目中的小模块时一般都会用到workspace概念,在Rust中你可以在根目录下创建一个Cargo.toml文件作为workspace的入口,描述清楚workspace中所包含的内容,大体上类似如下:
[workspace]
members = [
"crates/*"
]
workspace中相互引用的各个模块可以指向本地的文件夹作为依赖项:
[dependencies]
other-project = { path = "../other-project" }
额外的工具
cargo-edit
上文已经介绍、不再赘述
cargo-workspaces
cargo workspaces(或cargo ws)将workspaces的创建和管理进行了简化,受Node.js的lerna启发,最大的价值在于自动发布workspaces中的模块以及替换本地依赖。我们可以通过如下方式进行安装:
$ cargo install cargo-workspaces
cargo-expand
在Rust中宏是如此的常见,以至于即便是你的第一个hello word程序也离不开宏的使用。宏可以帮助你减少冗余代码,但是却会增加调试的困难,cargo-expand有助于减少调试中遇到的困难。cargo-expand依赖于nightly工具链:
rustup install nightly
然后安装cargo-expand:
$ cargo install cargo-expand
安装完成后,可以通过cargo expand [item]打印出完整的源码
注意:
cargo expand接受一个名称,不是一个文件路径。cargo expand main命令不是展开src/main.rs,而是展开项目的根目录中的main()函数。通常来说,展开src/some_module/another文件中的模块,可以运行cargo expand some_module::another。 不用担心,后面会继续深入介绍。
举例来说,执行cargo new命令会生成一个src/main.rs文件:
fn main() {
println!("Hello, world!");
}
其中println!()就是一个宏,我们运行cargo expand命令来看看生成的结果:
fn main() {
{
::std::io::_print(::core::fmt::Arguments::new_v1(
&["Hello, world!\n"],
&match () {
() => [],
},
));
};
}
tomlq
这不是一个cargo xx类型的命令,在查询.toml文件中的数据时很有用处
总结
当你添加了cargo-edit之后从npm到cargo的对照显得非常清晰,后面会介绍如何在Visual Studio Code中配置rust开发环境