19 个版本 (5 个破坏性更新)
0.5.1 | 2024年7月2日 |
---|---|
0.5.0 | 2024年5月21日 |
0.4.0 | 2024年5月19日 |
0.3.0 | 2024年2月2日 |
0.0.12 | 2024年1月18日 |
#700 in 网页编程
每月下载量 146
22KB
162 行
Stylance

Stylance 是一个用于在 Rust 中处理局部 CSS 的库和 CLI 工具。
特性
- 将 CSS 文件中的哈希类名导入 Rust 代码作为字符串常量。
- 尝试使用 CSS 文件中不存在的类名会导致错误。
- 未使用的类名将变为警告。
- 使用 stylance CLI 将 CSS 模块文件捆绑成单个输出 CSS 文件,所有类名都转换为包含哈希。
- 类名哈希是确定的,基于 CSS 文件和你的 crate 的清单目录(Cargo.toml 所在的目录)之间的相对路径。
- CSS 捆绑生成与 Rust 构建过程独立,允许在修改 CSS 样式规则内容时进行快速迭代。
用法
Stylance 分为两部分
- Rust proc macros 将 CSS 文件中的局部类名作为字符串常量导入 Rust 代码。
- CLI 工具会查找你的 crate 中的所有 CSS 模块,并生成一个包含哈希类名的输出 CSS 文件。
Proc macro
将 stylance 添加为依赖项
cargo add stylance
然后使用 import_crate_style proc macro 读取 css/scss 文件,并将该文件中的类作为常量导入。
src/component/card/card.module.scss
文件的内容
.header {
background-color: red;
}
src/component/card/card.rs
文件的内容
// Import a css file's classes:
stylance::import_crate_style!(my_style, "src/component/card/card.module.scss");
fn use_style() {
// Use the classnames:
println!("{}", my_style::header) // prints header-f45126d
}
文件 src/component/card/card.module.scss
中找到的所有类名将作为常量包含在名为 import_style 作为第一个参数传递给模块的名称中。
该 proc macro 没有副作用,要生成转换后的 CSS 文件,我们使用 stylance CLI。
访问全局类名
有时你可能需要定位全局定义且不在CSS模块中的类名。为此,你可以用以下代码将这些类名包裹起来::global()
.my_scoped_class :global(.paragraph) {
color: red;
}
这将转换为
.my_scoped_class-f45126d .paragraph {
color: red;
}
`.my_scoped_class` 获取了模块哈希,但 `.paragraph` 保持原样,同时移除了 :global()
。
未使用的类名警告
导入样式宏将创建常量,如果未使用,将产生警告。
如果你不希望有未使用的CSS类,但又想关闭此警告,可以在宏中模块标识符前添加 #[allow(dead_code)]
。
示例
import_crate_style!(#[allow(dead_code)] my_style, "src/component/card/card.module.scss");
任何属性都是允许的,如果你想拒绝,也可以做到。
import_crate_style!(#[deny(dead_code)] my_style, "src/component/card/card.module.scss");
夜间功能
如果你使用Rust夜间版本,你可以启用 nightly
功能来访问 import_style!
宏,该宏允许你指定CSS模块文件相对于当前文件的相对路径。
启用夜间功能
stylance = { version = "<version here>", features = ["nightly"] }
然后以相对方式导入样式
src/component/card/card.rs
:
stylance::import_style!(my_style, "card.module.scss");
Stylance CLI
安装stylance CLI
cargo install stylance-cli
运行stylance CLI
stylance ./path/to/crate/dir/ --output-file ./bundled.scss
第一个参数是包含你的包/crate的Cargo.toml文件的目录路径。
这将找到所有以 .module.scss
和 .module.css
结尾的文件,并将它们捆绑到 ./bundled.scss
中,所有类都将修改为包含与 import_crate_style!
宏产生的哈希相匹配的哈希。
结果 ./bundled.scss
.header-f45126d {
background-color: red;
}
默认情况下,stylance CLI只会在crate的 ./src/
文件夹内查找CSS模块。这可以通过 配置 来改变。
使用 output-dir
以获得更好的SASS兼容性
如果你打算在SASS项目中使用stylance的输出(通过从 .scss 文件导入),那么我建议使用 output-dir
选项而不是 output-file
。
stylance ./path/to/crate/dir/ --output-dir ./styles/
这将创建 ./styles/stylance/
文件夹。
当使用 --output-dir(或在 package.metadata.stylance 中的 output_dir)时,stylance 不会捆绑转换后的模块文件,而是在指定的输出目录路径中创建一个 "stylance" 文件夹,该文件夹将包含所有转换后的CSS模块作为单独的文件。
此 "stylance" 文件夹还包括一个 _index.scss 文件,它导入所有转换后的SCSS模块。
然后你可以使用 @use "path/to/the/folder/stylance"
来将CSS模块导入到你的SASS项目中。
监视更改
在开发期间,使用sylance CLI的监视模式会很方便。
stylance --watch --output-file ./bundled.scss ./path/to/crate/dir/
然后stylance进程将监视任何 .module.css
和 .module.scss
文件的更改,并自动重建输出文件。
配置
Stylance配置位于你的crate的Cargo.toml文件中。
所有配置设置都是可选的。
[package.metadata.stylance]
# output_file
# When set, stylance-cli will bundle all css module files
# into by concatenating them and put the result in this file.
output_file = "./styles/bundle.scss"
# output_dir
# When set, stylance-cli will create a folder named "stylance" inside
# the output_dir directory.
# The stylance folder will be populated with one file per detected css module
# and one _all.scss file that contains one `@use "file.module-hash.scss";` statement
# per module file.
# You can use that file to import all your modules into your main scss project.
output_dir = "./styles/"
# folders
# folders in which stylance cli will look for css module files.
# defaults to ["./src/"]
folders = ["./src/", "./styles/"]
# extensions
# files ending with these extensions will be considered to be
# css modules by stylance cli and will be included in the output
# bundle
# defaults to [".module.scss", ".module.css"]
extensions = [".module.scss", ".module.css"]
# scss_prelude
# When generating an scss file stylance-cli will prepend this string
# Useful to include a @use statement to all scss modules.
scss_prelude = '@use "../path/to/prelude" as *;'
# hash_len
# Controls how long the hash name used in scoped classes should be.
# It is safe to lower this as much as you want, stylance cli will produce an
# error if two files end up with colliding hashes.
# defaults to 7
hash_len = 7
# class_name_pattern
# Controls the shape of the transformed scoped class names.
# [name] will be replaced with the original class name
# [hash] will be replaced with the hash of css module file path.
# defaults to "[name]-[hash]"
class_name_pattern = "my-project-[name]-[hash]"
Rust分析器完成问题
夜间 import_style!
Rust分析器不会为import_style!生成任何完成建议,这是因为它不支持用于获取当前rust文件路径的nightly特性。
稳定的import_crate_style!
Rust分析器将首次正确展开import_crate_style!(style, "src/mystyle.module.css")
宏,这意味着你可以在键入style::|
时获得完成建议。
不幸的是,RA将缓存结果,并且当src/mystyle.module.css
的内容改变时,它不会意识到需要重新评估proc宏。
这只会影响完成建议,cargo check的错误会正确更新。
强制RA重新评估宏的唯一方法是重启服务器或重新构建所有proc宏。遗憾的是,这需要很长时间。
我认为没有完成建议比过时的完成建议更好。
据说可以通过将此添加到.vscode/settings.json
中来禁用宏的展开。
"rust-analyzer.procMacro.ignored": {
"stylance": ["import_style_classes"]
},
不幸的是,这似乎不起作用,这个rust analyzer特性可能会解决这个问题:https://github.com/rust-lang/rust-analyzer/pull/15923
与此同时,nightly import_style
是我推荐的与此crate一起工作的方式。
依赖项
~1.5–2.1MB
~45K SLoC