9个版本
0.3.2 | 2023年2月19日 |
---|---|
0.3.1 | 2023年2月19日 |
0.2.0 | 2023年2月5日 |
0.1.4 | 2022年4月24日 |
0.1.3 | 2022年2月17日 |
#456 in Web编程
390KB
8K SLoC
“tailwindcss-to-rust
”命令行工具生成Rust代码,允许您从Rust代码中引用Tailwind类。这意味着任何尝试使用不存在类的操作都将导致编译时错误,您可以使用代码补全来列出可用的类。
此工具已在Tailwind 3.2.x版本上进行了测试。
生成的代码允许您在Rust前端代码中使用Tailwind CSS类,对类名进行编译时检查并提供代码补全。这些类根据Tailwind文档中的标题分组。它还生成完整的Tailwind修饰符列表的代码,如lg
、hover
等。
查看tailwindcss-to-rust-macros crate,以获取使用此工具生成的代码的最便捷方式。
所以,您不需要这样做
let class = "pt-4 pb-2 text-whit";
您可以这样做
let class = C![C::spc::pt_4 C::pb_2 C::typ::text_white];
请注意,第一个示例中的错误拼写“text-whit”(缺少“e”)如果在您写入C::typ::text_whit
时,将会变成编译时错误。
以下是快速入门指南
-
通过运行以下命令安装此工具
cargo install tailwindcss-to-rust
-
安装
tailwindcss
命令行工具。您可以使用npm
或npx
安装它,或者您可以从tailwindcss仓库下载独立的二进制文件。 -
通过运行以下命令使用工具创建一个
tailwind.config.js
文件tailwindcss init
-
根据需要编辑此文件,以添加插件或自定义生成的CSS。
-
为Tailwind创建一个CSS输入文件。在本例中,我们将假设它位于
css/tailwind.css
。标准文件如下所示@tailwind base; @tailwind components; @tailwind utilities;
-
通过运行以下命令生成您的Rust代码
tailwindcss-to-rust \ --tailwind-config tailwind.config.js \ --input tailwind.css \ --output src/css/generated.rs \ --rustfmt
当您运行
tailwindcss-to-rust
时,tailwindcss
可执行文件必须在您的PATH
中,或者您必须通过--tailwindcss
参数提供可执行文件的路径。 -
编辑您的
tailwind.config.js
文件,以便在Rust文件中查找Tailwind类名/** @type {import('tailwindcss').Config} */ module.exports = { content: { files: ["index.html", "**/*.rs"], // You do need to copy this big block of code in, unfortunately. extract: { rs: (content) => { const rs_to_tw = (rs) => { if (rs.startsWith("two_")) { rs = rs.replace("two_", "2"); } return rs .replaceAll("_of_", "/") .replaceAll("_p_", ".") .replaceAll("_", "-"); }; let one_class_re = "\\bC::[a-z0-9_]+::([a-z0-9_]+)\\b"; let class_re = new RegExp(one_class_re, "g"); let one_mod_re = "\\bM::([a-z0-9_]+)\\b"; let mod_re = new RegExp(one_mod_re + ", " + one_class_re, "g"); let classes = []; let matches = [...content.matchAll(mod_re)]; if (matches.length > 0) { classes.push( ...matches.map((m) => { let pieces = m.slice(1, m.length); return pieces.map((p) => rs_to_tw(p)).join(":"); }) ); } classes.push( ...[...content.matchAll(class_re)].map((m) => { return rs_to_tw(m[1]); }) ); return classes; }, }, }, theme: { extend: {}, }, plugins: [], };
请注意,您可能需要自定义
extract
函数中的正则表达式以匹配您的模板系统! 此示例中的正则表达式将匹配您在 tailwindcss-to-rust-macros 包中使用的语法。例如,如果您在未使用宏的情况下使用 askama,则可能需要匹配以下内容
<div class="{{ M::hover }}:{{ C::bg::bg_rose_500 }} {{ C::bg::bg_rose_800 }}" > ... </div>
相应的正则表达式可能如下所示
let one_class_re = "{{\\s*C::[a-z0-9_]+::([a-z0-9_]+)\\s*}}"; let class_re = new RegExp(one_class_re, "g"); let one_mod_re = "{{\\s*M::([a-z0-9_]+)\\s*}}"; let mod_re = new RegExp(one_mod_re + ":" + one_class_re, "g");
-
修修改改...
-
通过运行以下命令重新生成编译后的 Tailwind CSS 文件
tailwindcss --input css/tailwind.css --output css/tailwind_compiled.css`
-
请确保在您的 HTML 中导入编译后的 CSS
<link data-trunk rel="css" href="/css/tailwind_compiled.css" />
在此示例中,我使用的是 Trunk,这对于想要使用 Rust -> WASM 而不需要任何 node.js 工具的项目来说是一个出色的替代品。我的 Trunk.toml
看起来像这样
[build]
target = "index.html"
dist = "dist"
[[hooks]]
stage = "build"
# I'm not sure why we can't just invoke tailwindcss directly, but that doesn't
# seem to work for some reason.
command = "sh"
command_arguments = ["-c", "tailwindcss -i css/tailwind.css -o css/tailwind_compiled.css"]
当我运行 trunk
时,我必须确保忽略那个生成的文件
trunk --ignore ./css/tailwind_compiled.css ...
生成的名称包括 CSS 文件中出现的所有类名,但不包括以下名称:以连字符(-
)开头的名称,包含伪元素的名称,例如 .placeholder-opacity-100::-moz-placeholder
,以及包含修饰符(如 lg
或 hover
)的名称。名称将通过以下算法转换为 Rust 标识符
- 完全删除所有反斜杠转义,例如在
.inset-0\.5
中。 - 所有连字符(
-
)变为下划线(_
)。 - 所有点(
.
)变为_p_
,因此.inset-2\.5
变为inset_2_p_5
。 - 所有正斜杠(
/
)变为_of_
,因此.inset-2\/4
变为inset_2_of_4
。 - 如果名称 以数字 2 开头,例如
2xl
,则变为two_
,因此2xl
修饰符变为two_xl
。 - 名称
static
变为static_
。
生成的代码提供包含所有相关字符串的两个模块。
C
模块包含多个子模块,每个子模块对应 TailwindCSS 文档中记录的每个类组。组如下
pub(crate) mod C {
// Accessibility
pub(crate) mod acc { ... }
// Animation
pub(crate) mod anim { ... }
// Backgrounds
pub(crate) mod bg { ... }
// Borders
pub(crate) mod bor { ... }
// Effects
pub(crate) mod eff { ... }
// Filter
pub(crate) mod fil { ... }
// Flexbox & Grid
pub(crate) mod fg { ... }
// Interactivity
pub(crate) mod intr { ... }
// Layout
pub(crate) mod lay { ... }
// Sizing
pub(crate) mod siz { ... }
// Spacing
pub(crate) mod spc { ... }
// SVG
pub(crate) mod svg { ... }
// Tables
pub(crate) mod tbl { ... }
// Transforms
pub(crate) mod trn { ... }
// Typography
pub(crate) mod typ { ... }
}
在您的代码中,您可以使用 C::typ::text_lg
或 C::lay::flex
来引用类。如果您有任何自定义类,这些类将以 "unknown" 组结束,该组可通过 C::unk
获取。将这些自定义类放入其他组的实现是一个待办事项。
修饰符有自己的模块,称为 M
,其中每个修饰符对应一个字段,因此用作 M::lg
或 M::hover
。一些可参数化的修饰符未包含在内,例如 aria-*
,data-*
等。
了解生成的模块的最佳方式是在您的编辑器中打开生成的代码文件并查看它。
然后您可以在代码中导入这些常量,并使用它们来引用 Tailwind CSS 类名并进行编译时检查
element.set_class(C::lay::aspect_auto);
依赖项
~6–17MB
~227K SLoC