NiQin (blog: 泥芹) shared the aphorism --
I returned and saw under the sun, that the race is not to the swift, nor the battle to the strong, neither yet bread to the wise, nor yet riches to men of understanding, nor yet favour to men of skill; but time and chance happeneth to them all. -- 《圣经》

[Rust] 使用 tide、handlebars、rhai、graphql 开发 Rust web 前端(3)- rhai 脚本、静态/资源文件、环境变量等

💥 内容涉及著作权,均归属作者本人。若非作者注明,默认欢迎转载:请注明出处,及相关链接。

Summary: 《使用 tide、handlebars、rhai、graphql 开发 Rust web 前端》第三部分:在 handlebars 模板中,使用 rhai 嵌入式脚本语言,作为脚本助手;另外,还有静态/资源文件、环境变量等方面的使用阐述。

Topics: rust graphql tide rust-web handlebars rhai dotenv

前 2 篇文章《crate 选择及环境搭建》《获取并解析 GraphQL 数据》中,我们已经整合应用 tide、graphql-client、handlebars,以及 surf,从 GraphQL 服务后端 API 获取 GraphQL 数据并解析、渲染到 html 模板。这已经是一个完整的技术组合,其成熟度足以用于生产环境,构建自己的想法和应用了。

handlebars 模板支持 JavaScript 脚本及助手代码,应用方面非常灵活和强大。handlebars-rust 模板引擎是对 handlebars 模板语法规范的 Rust 实现,在前文中评测中(详见 crate 选择及环境搭建),笔者提及:此次实践选择 handlebars-rust 模板引擎,主要是因为其对 rhai(Rust 的嵌入式脚本引擎)的支持方面,笔者非常感兴趣,是故选择。

所以本文是一个补充:我们补充整合 Rust 的嵌入式脚本引擎—— rhai 脚本语言的应用实践。开发者可以在项目中,用性能出众、语法类同 Rust 语言的 RhaiScript 脚本,替代 JavaScript,为数据展示和页面渲染提供辅助。

rhai 嵌入式脚本语言

基于 Rust 语言丰富和创新的特性,以及超高性能的执行效率,目前在开源界,产生了众多 Rust 语言的嵌入式脚本引擎。rhai 是新兴的,但创新性较高的一个。其在 Rust 语言特性之上实现,具有 no-std 特性,以及动态类型。编译时开销非常低,但执行效率很可观:在单核 2.3 GHz 的 Linux 虚拟机上,0.3 秒内,达到了超百万次迭代。

rhai 脚本语言可以独立使用,也可以嵌入 Rust 代码中使用。作为 Rust 的内嵌代码使用时,可以和原生 Rust 代码一样,调用其它 crate。尤其是,rhai 支持模块/库的动态加载、解析,并且支持最小构建。

  • 类似于 Rust + JavaScript,且具有动态类型。
  • 与 Rust 函数和类型紧密集成。
  • 通过外部作用域,将 Rust 变量/常量无损传递到脚本中,无需实现任何特殊特性。
  • 从 Rust 代码内,轻松调用脚本定义的函数。
  • 很少的依赖项,实际必须具有的仅 2 个第三方 Rust crate。
  • 动态:函数重载、运算符过载、函数指针可动态调度。
  • 动态加载的模块,以组织代码库。
  • 可以捕获共享变量的闭包。
  • 支持面向对象编程(OOP)。
  • 支持大多数构建目标,包括 no-std、WebAssembly(WASM)等。
  • 可自行精确禁用关键字、运算符,以限制语言。
  • 可用作 DSL。
  • ……

总体来说,rhai 提供了一种安全、简单的方式,向任何应用程序添加以 Rust 语法编写的脚本,但保持了 Rust 语言“零开销”的执行效率。rhai 可以给 Rust 生态带来很多扩展。详细优势可参阅 rhai 文档,其开源仓库 rhaiscript/rhai/examples 提供了大量示例代码:包括 Rust 内嵌代码、独立脚本。

Rust web 项目中对 rhai 的使用,主要是在模板的渲染过程中。如作为模板内嵌助手脚本,对获取到的 API 数据进行计算。由此说来,即是在 handlebars-rust 模板引擎层面的使用。

Cargo.toml 中,启用 handlebars 依赖项的 script_helper 特性。

handlebars = { version = "4.0.0", features = ["script_helper"] }

rhai 脚本示例

在目录 frontend-handlebars 中,创建 scripts 目录,以及 scripts/length.rhai 文件。

scripts/length.rhai 文件的代码是一个最简单的可用于 handlebars 模板的 rhai 脚本示例:计算传入数据的字符长度。

let username = params[0];

username.len()

这个代码没什么需要解说的,如果一定要说点什么,那就是 params[0] 表示的含义是:由模板传入脚本的第一个参数,多个参数类推。

向模板注册 rhai 脚本

src/routes/users.rs 文件中,在模板声明语句之后,注册脚本名称和文件路径:

    let mut user_index: Tpl = Tpl::new("users/index").await;
    user_index
        .reg
        .register_script_helper_file(
            "length",
            format!("{}{}", "scripts/", "length.rhai"),
        )
        .unwrap();

:实际项目中,将字面量 "scripts/" 通过配置环境变量来读取,是较好的体验。

模板中使用 rhai 脚本

脚本助手的使用语法为 {{ <helper_name> <args> }}。我们注册脚本助手时,指定的助手名称为 length,所以 {{length u.username}} 即可。如 templates/users/index.html 中的用法:

    <ul>
      {{#each allUsers as |u|}}
        <li><b>{{u.username}} - (length: {{length u.username}})</b></li>
        <ul>
          <li>{{ u.id }}</li>
          <li>{{ u.email }}</li>
        </ul>
      {{/each}}
    </ul>

现在,编译和运行后,你可以看到用户列表页面,用户名的括号内,显示了用户名称的字符长度。

静态/资源文件、环境变量等

  • 静态/资源文件(样式表、图像、js,以及其它)的使用,是规范的 html 标签和元素的语法。静态/资源文件的服务路径,属于 tide 的路由配置:一个 serve_dir 方法,指定为放置静态/资源文件(样式表、图像、js,以及其它)的路径即可。如:
  app.at("/static").serve_dir("./static").unwrap();

  app.at("/").get(index);
  app.at("users").get(user_index);
  ……

至此,《使用 tide、handlebars、rhai、graphql 开发 Rust web 前端》的第一阶段就结束了;第二阶段,将专注于 cookie/session、rhai、jwt-auth,以及复杂的 GraphQL 查询等。

谢谢您的阅读!


Related Articles

  1. [Rust] iRust.net:基于 Rust-Web 技术栈,及 image-rs、fluent-rs、rhai-script ……
  2. [WebAssembly] yew SSR 服务器端渲染
  3. [Rust] async-std 创建者对于最近“项目是否已死?”,移除对其支持等的答复
  4. [Rust] Rust 1.56.0 版本和 Rust 2021 版次发布,新特性一览,及项目的迁移、升级
  5. [WebAssembly] Rust 和 Wasm 的融合,使用 yew 构建 WebAssembly 博客应用的体验报告
  6. [Rust] Rust 官方周报 399 期(2021-07-14)
  7. [WebAssembly] Rust 和 Wasm 的融合,使用 yew 构建 web 前端(5)- 构建 HTTP 请求、与外部服务器通信的两种方法
  8. [Rust] Rust 官方周报 398 期(2021-07-07)
  9. [Rust] Rust 官方周报 397 期(2021-06-30)
  10. [Rust] Rust 官方周报 396 期(2021-06-23)
  11. [Rust] Rust 官方周报 395 期(2021-06-16)
  12. [Rust] Rust 1.53.0 明日发布,关键新特性一瞥
  13. [Rust] 使用 tide、handlebars、rhai、graphql 开发 Rust web 前端(3)- rhai 脚本、静态/资源文件、环境变量等
  14. [Rust] 使用 tide、handlebars、rhai、graphql 开发 Rust web 前端(2)- 获取并解析 GraphQL 数据
  15. [Rust] 使用 tide、handlebars、rhai、graphql 开发 Rust web 前端(1)- crate 选择及环境搭建
  16. [Rust] Rust 官方周报 394 期(2021-06-09)
  17. [Rust] Rust web 前端库/框架评测,以及和 js 前端库/框架的比较
  18. [WebAssembly] Rust 和 Wasm 的融合,使用 yew 构建 web 前端(4)- 获取 GraphQL 数据并解析
  19. [WebAssembly] Rust 和 Wasm 的融合,使用 yew 构建 web 前端(3)- 资源文件及小重构
  20. [WebAssembly] Rust 和 Wasm 的融合,使用 yew 构建 WebAssembly 标准的 web 前端(2)- 组件和路由
  21. [WebAssembly] Rust 和 Wasm 的融合,使用 yew 构建 WebAssembly 标准的 web 前端(1)- 起步及 crate 选择
  22. [Rust] Rust 官方周报 393 期(2021-06-02)
  23. [Rust] Rust 官方周报 392 期(2021-05-26)
  24. [Rust] Rust 中,对网址进行异步快照,并添加水印效果的实践
  25. [Rust] Rust 官方周报 391 期(2021-05-19)
  26. [Rust] Rust,风雨六载,砥砺奋进
  27. [Rust] 为什么我们应当将 Rust 用于嵌入式开发?
  28. [Rust] Rust 官方周报 390 期(2021-05-12)
  29. [Rust] Rust + Android 的集成开发设计
  30. [Rust] Rust 1.52.1 已正式发布,及其新特性详述
  31. [Rust] 让我们用 Rust 重写那些伟大的软件吧
  32. [Rust] Rust 1.52.0 已正式发布,及其新特性详述
  33. [Rust] Rust 官方周报 389 期(2021-05-05)
  34. [GraphQL] 基于 actix-web + async-graphql + rbatis + postgresql / mysql 构建异步 Rust GraphQL 服务(4) - 变更服务,以及小重构
  35. [Rust] Rust 1.52.0 稳定版预发布测试中,关键新特性一瞥
  36. [Rust] Rust 生态中,最不知名的贡献者和轶事
  37. [Rust] Rust 基金会迎来新的白金会员:Facebook
  38. [Rust] Rustup 1.24.1 已官宣发布,及其新特性详述
  39. [Rust] Rust 官方周报 388 期(2021-04-28)
  40. [Rust] Rust 官方周报 387 期(2021-04-21)
  41. [GraphQL] 构建 Rust 异步 GraphQL 服务:基于 tide + async-graphql + mongodb(4)- 变更服务,以及第二次重构
  42. [Rust] Rustup 1.24.0 已官宣发布,及其新特性详述
  43. [Rust] basedrop:Rust 生态中,适用于实时音频的垃圾收集器
  44. [Rust] Rust 编译器团队对成员 Aaron Hill 的祝贺
  45. [Rust] Jacob Hoffman-Andrews 加入 Rustdoc 团队
  46. [机器人] 为什么应将 Rust 引入机器人平台?以及机器人平台的 Rust 资源推荐
  47. [Rust] rust-lang.org、crates.io,以及 docs.rs 的管理,已由 Mozilla 转移到 Rust 基金会
  48. [Rust] Rust 官方周报 386 期(2021-04-14)
  49. [Rust] Rust 编译器(Compiler)团队 4 月份计划 - Rust Compiler April Steering Cycle
  50. [GraphQL] 基于 actix-web + async-graphql + rbatis + postgresql / mysql 构建异步 Rust GraphQL 服务(3) - 重构
  51. [Rust] 头脑风暴进行中:Async Rust 的未来熠熠生辉
  52. [GraphQL] 基于 actix-web + async-graphql + rbatis + postgresql / mysql 构建异步 Rust GraphQL 服务(2) - 查询服务
  53. [GraphQL] 基于 actix-web + async-graphql + rbatis + postgresql / mysql 构建异步 Rust GraphQL 服务 - 起步及 crate 选择
  54. [Rust] Rust 2021 版本特性预览,以及工作计划
  55. [Rust] Rust 用在生产环境的 42 家公司
  56. [Rust] 构建最精简的 Rust Docker 镜像
  57. [Rust] Rust 官方周报 385 期(2021-04-07)
  58. [Rust] 使用 Rust 做异步数据采集的实践
  59. [Rust] Android 支持 Rust 编程语言,以避免内存缺陷
  60. [Rust] Android 平台基础支持转向 Rust
  61. [Rust] Android 团队宣布 Android 开源项目(AOSP),已支持 Rust 语言来开发 Android 系统本身
  62. [Rust] RustyHermit——基于 Rust 实现的下一代容器 Unikernel
  63. [Rust] Rustic:完善的纯粹 Rust 技术栈实现的国际象棋引擎,多平台支持(甚至包括嵌入式设备树莓派 Raspberry Pi、Buster)
  64. [Rust] Rust 迭代器(Iterator trait )的要诀和技巧
  65. [Rust] 使用 Rust 极致提升 Python 性能:图表和绘图提升 24 倍,数据计算提升 10 倍
  66. [Rust] 【2021-04-03】Rust 核心团队人员变动
  67. [Rust] Rust web 框架现状【2021 年 1 季度】
  68. [Rust] Rust 官方周报 384 期(2021-03-31)
  69. [Rust] Rust 中的解析器组合因子(parser combinators)
  70. [生活] 毕马威(KPMG)调查报告:人工智能的实际采用,在新冠疫情(COVID-19)期间大幅提升
  71. [Python] HPy - 为 Python 扩展提供更优秀的 C API
  72. [Rust] 2021 年,学习 Rust 的网络资源推荐(2)
  73. [Rust] 2021 年,学习 Rust 的网络资源推荐
  74. [生活] 况属高风晚,山山黄叶飞——彭州葛仙山露营随笔
  75. [Rust] Rust 1.51.0 已正式发布,及其新特性详述
  76. [Rust] 为 Async Rust 构建共享的愿景文档—— Rust 社区的讲“故事”,可获奖
  77. [Rust] Rust 纪元第 382 周最佳 crate:ibig 的实践,以及和 num crate 的比较
  78. [Rust] Rust 1.51.0 稳定版本改进介绍
  79. [Rust] Rust 中将 markdown 渲染为 html
  80. [生活] 国民应用 App 的用户隐私数据窥探
  81. [GraphQL] 构建 Rust 异步 GraphQL 服务:基于 tide + async-graphql + mongodb(3)- 重构
  82. [GraphQL] 构建 Rust 异步 GraphQL 服务:基于 tide + async-graphql + mongodb(2)- 查询服务
  83. [GraphQL] 构建 Rust 异步 GraphQL 服务:基于 tide + async-graphql + mongodb(1)- 起步及 crate 选择
  84. [Rust] Rust 操控大疆可编程 tello 无人机

Topics

rust(84)

graphql(17)

rust-官方周报(17)

webassembly(16)

wasm(10)

tide(9)

async-graphql(9)

yew(9)

rust-web(8)

rust-官方博客(8)

this-week-in-rust(6)

mysql(5)

actix-web(5)

rbatis(5)

android(4)

mongodb(3)

json-web-token(3)

jwt(3)

cargo(3)

技术延伸(3)

rust-wasm(3)

trunk(3)

handlebars(3)

rhai(3)

async-std(3)

用户隐私(2)

学习资料(2)

python(2)

ai(2)

人工智能(2)

postgresql(2)

rust-compiler(2)

rust-基金会(2)

rust-foundation(2)

rustup(2)

rust-toolchain(2)

rust-工具链(2)

rust-游戏开发(2)

rust-区块链(2)

rust-2021(2)

graphql-client(2)

surf(2)

rust-game(2)

rusthub(2)

tello(1)

drone(1)

无人机(1)

隐私数据(1)

markdown(1)

html(1)

crate(1)

async(1)

异步(1)

旅游(1)

不忘生活(1)

葛仙山(1)

hpy(1)

python-扩展(1)

正则表达式(1)

解析器组合因子(1)

组合器(1)

regular-expression(1)

parser-combinator(1)

regex(1)

官方更新(1)

rust-工作招聘(1)

rust-技术资料(1)

rust-周最佳-crate(1)

rust-web-框架(1)

rust-web-framework(1)

rust-核心团队(1)

rust-core-team(1)

rust-language-team(1)

pyo3(1)

rust-python-集成(1)

python-性能改进(1)

迭代器(1)

iterator-trait(1)

国际象棋(1)

chess(1)

游戏引擎(1)

game-engine(1)

虚拟化(1)

unikernel(1)

rustyhermit(1)

linux(1)

virtualization(1)

sandboxing(1)

沙箱技术(1)

数据采集(1)

异步数据采集(1)

docker(1)

镜像(1)

生产环境(1)

rust-评价(1)

rust-2021-edition(1)

rust-2021-版本(1)

graphql-查询(1)

vision-doc(1)

愿景文档(1)

代码重构(1)

steering-cycle(1)

方向周期(1)

隐私声明(1)

机器人(1)

robotics(1)

rustdoc(1)

rust-编译器(1)

实时音频(1)

real-time-audio(1)

变更服务(1)

mutation(1)

查询服务(1)

query(1)

rust-贡献者(1)

rust-轶事(1)

rust-稳定版(1)

rust-预发布(1)

rust-测试(1)

安全编程(1)

可信计算(1)

安全代码(1)

secure-code(1)

rust-android-integrate(1)

rust-embedded(1)

rust-嵌入式(1)

rust-生产环境(1)

rust-production(1)

网页快照(1)

网页截图(1)

水印效果(1)

图片水印(1)

yew-router(1)

css(1)

web-前端(1)

wasm-bindgen(1)

区块链(1)

blockchain(1)

dotenv(1)

标识符(1)

rust-1.53.0(1)

rust-1.56.0(1)

rust-项目升级(1)

异步运行时(1)

ssr(1)

tokio(1)

warp(1)

reqwest(1)

graphql-rust(1)


Elsewhere

- Open Source
  1. github/zzy
  2. github/sansx
- Learning & Studying
  1. Rust 学习资料 - iRust.net