#scoped-css #css #css-class #web #scss #cli-tool #css-modules

stylance

为 Rust 项目提供的局部 CSS

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 网页编程

Download history 24/week @ 2024-04-29 28/week @ 2024-05-06 135/week @ 2024-05-13 271/week @ 2024-05-20 44/week @ 2024-05-27 39/week @ 2024-06-03 39/week @ 2024-06-10 14/week @ 2024-06-17 13/week @ 2024-06-24 247/week @ 2024-07-01 42/week @ 2024-07-08 38/week @ 2024-07-15 24/week @ 2024-07-22 76/week @ 2024-07-29 24/week @ 2024-08-05 22/week @ 2024-08-12

每月下载量 146

MIT/Apache

22KB
162

Stylance crates.io tests

Stylance 是一个用于在 Rust 中处理局部 CSS 的库和 CLI 工具。

特性

  • 将 CSS 文件中的哈希类名导入 Rust 代码作为字符串常量。
    • 尝试使用 CSS 文件中不存在的类名会导致错误。
    • 未使用的类名将变为警告。
  • 使用 stylance CLI 将 CSS 模块文件捆绑成单个输出 CSS 文件,所有类名都转换为包含哈希。
  • 类名哈希是确定的,基于 CSS 文件和你的 crate 的清单目录(Cargo.toml 所在的目录)之间的相对路径。
  • CSS 捆绑生成与 Rust 构建过程独立,允许在修改 CSS 样式规则内容时进行快速迭代。

用法

Stylance 分为两部分

  1. Rust proc macros 将 CSS 文件中的局部类名作为字符串常量导入 Rust 代码。
  2. 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