Angular、Rust、WebAssembly、Node.js、无服务器,还有……全新的 Azure 静态 Web 应用!🎉 我们正在创造什么?我们如何创造?我们如何构建?隆重推出:Azure 静态 Web 应用!🎉 试用资源

2025-06-08

Angular、Rust、WebAssembly、Node.js、无服务器,还有……全新的 Azure 静态 Web 应用!🎉

我们正在创造什么?

我们如何创造它?

我们如何构建它?

隆重推出:Azure 静态 Web 应用!🎉

尝试一下

资源

在本指南中,我们将了解如何采用前端 Angular 应用程序、用 Rust 编写并编译为 Web Assembly 的后端 API,并将所有内容部署到全新Azure 静态 Web 应用程序服务上的无服务器环境中。

虽然 UI 是用Angular编写的,但这款应用的有趣之处在于,其后端 API 的核心部分——生成器,完全用 Rust 编写,然后编译为 Web Assembly(简称 WASM)。公共 API 通过无服务器 Azure Function 暴露在 Node.js 的后台

让我们开始吧...

我们正在创造什么?

我们要开发一款猫咪取名应用。我喜欢猫,相信你也一样。这款应用能帮你为心爱的宠物找到独一无二的猫咪名字。

⚡️ 在https://catsify.app上试用该应用⚡️

我们的应用程序结构如下(仅显示重要部分):

.
├── api
│   ├── dist
│   │   └── func
│   ├── func
│   ├── ...
│   ├── Cargo.toml
│   └── rust
├── app
│   ├── dist
│   │   └── ui
│   ├── ...
│   └── src
├── ...
└── scripts
Enter fullscreen mode Exit fullscreen mode

一些亮点:

  • api是标准的 Azure Functions App 文件夹。
  • api/func包含 Node.js 无服务器功能。
  • api/rust包含 Rust 源代码。
  • app包含 Angular 源代码。

和...

  • api/dist/func包含API构建工件。
  • app/dist/ui包含APP构建工件。

接下来我们将描述每个堆栈的作用:Rust/WASM、Node.js、Angular;然后解释每个部分是如何构建和部署的。

我们如何创造它?

Azure Functions:Node.js 代码

我们的公共后端 API 是一个充当Façade的 Node.js Azure Function 。

./api/func/index.ts文件中,我们只需导入并调用“a”generate()函数(参见下一部分),获取结果并将结果发送回客户端。

以下是代码的简化版本:

const { generate } = require("./wasm_loader");

const func = async function (context, req) {
   const name = await generate();
   const [adjective, noun] = name.split(" ");
   context.res = {
     body: {
       adjective,
       noun,
     },
   };
};

export default func;
Enter fullscreen mode Exit fullscreen mode

然而,在./api/func/wasm_loader.ts文件中,奇迹发生了,我们实际上加载了从 Rust 编译的 WASM 模块(参见 Rust 故事),调用该generate_name_str函数,传入种子参数,并解码结果字符串输出。

以下是代码的简化版本:

const fs = require('fs');
const path = require('path');

// the WASM file is copied to dis/func during the build
const wasmFile = path.join(__dirname, 'generator.wasm');

// a bunch of utilities to decode the WASM binary
function getInt32Memory(wasm) {...}
function getUint8Memory(wasm) {...}
function getStringFromWasm(wasm, ptr, len) {...}

// export a JavaScript function 
export const generate = async function() {

  // load the WASM module
  const bytes = new Uint8Array(fs.readFileSync(wasmFile));
  const result = await WebAssembly.instantiate(bytes);
  const wasm = await Promise.resolve(result.instance.exports);

  // setup args
  const retptr = 8;
  const seed = Date.now() % 1000 | 0;

  // invoke the WASM code
  const ret = wasm.generate_name_str(retptr, seed);

  // decode result
  const memi32 = getInt32Memory(wasm);
  const v0 = getStringFromWasm(...);
  wasm.__wbindgen_free(...);

  // this is final the decoded name
  return v0;
};
Enter fullscreen mode Exit fullscreen mode

核心 API:Rust 代码

这不是 Rust 代码或 WASM 的深度指南。您可以在Rust 官方网站上了解 Rust 和 WASM 。

正如我之前提到的,后端 API 的主要部分是用 Rust 编写的名称生成器。

use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn generate_name_str(seed: i32) -> String {
    // the seed is coming from the JS side
    let a = seed % (ADJECTIVES.len() as i32);
    let b = seed % (NOUNS.len() as i32);
    [ADJECTIVES[a as usize].to_string(), " ".to_string(), NOUNS[b as usize].to_string()].join("")
}

const ADJECTIVES: [&str; 1116] = [
"aback",
"abaft",
//...
];
const NOUNS: [&str; 1201] = [
"abbey",
"abbie",
//...
];

// used for debugging only
pub fn main() {
    println!("{:?}", generate_name_str(1));
}
Enter fullscreen mode Exit fullscreen mode

无需赘述,我们基本上使用两个 Rust 向量来存储猫的名词和形容词,然后从每个向量中选择一个随机值来构造一个字符串。该generate_name_str函数使用 outer 属性从 Rust 导出到 JavaScript #[wasm_bindgen]。这将使我们能够从 JavaScript 代码中调用此函数,并传入 seed 参数。

UI:Angular 代码

该 Angular 应用是使用Angular CLI版本 10.0.0-next.4生成的。经典配置!

我们如何构建它?

Azure 函数

我们的 Node.js Azure Function Node.js 代码是用 TypeScript 编写的,因此我们使用tsc它将其转换为 JavaScript 并将结果输出到./dist/func文件夹中。

cd api
tsc # will create ./dist/func/
Enter fullscreen mode Exit fullscreen mode

Rust 到 WASM

对于 Rust 代码,为了编译它并生成 WASM 模块,我们使用[wasm-pack](https://github.com/rustwasm/wasm-pack)

cd api
wasm-pack build # will create ./pkg/
Enter fullscreen mode Exit fullscreen mode

并且以下配置api/Cargo.toml

[dependencies]
wasm-bindgen = "0.2.58"

[lib]
crate-type = ["cdylib", "rlib"]
path = "rust/lib.rs"

[[bin]]
name = "generator"
path = "rust/lib.rs"

[profile.release]
lto = true
panic = "abort"
# Tell `rustc` to optimize for small code size.
opt-level = "s"
Enter fullscreen mode Exit fullscreen mode

注意:wasm-pack生成一个 Node.js 包装器来加载 WASM 模块。由于我们自己编写了加载器,所以我们只关注*.wasm文件本身。然后,我们需要将 WASM 文件复制到./api/dist/func

cp pkg/catsify_bg.wasm dist/func/generator.wasm
Enter fullscreen mode Exit fullscreen mode

Angular 构建

构建 Angular 应用非常简单。Angular CLI 负责处理所有事情:

ng build --prod
Enter fullscreen mode Exit fullscreen mode

此命令将在 下生成应用程序包./app/dist/ui

项目建设回顾

cd api
tsc                # builds the Azure function.
wasm-pack build    # builds the WASM module.
cp pkg/catsify_bg.wasm \
   dist/func/generator.wasm
cd ../app
ng build --prod    # builds the front-end app.
Enter fullscreen mode Exit fullscreen mode

现在我们已经创建了一个前端 Angular 应用程序和一个后端无服务器 API,那么在 Azure 上最容易实现静态无服务器的应用程序是什么?

隆重推出:Azure 静态 Web 应用!🎉

静态 Web 应用是 Azure 应用服务推出的一项新功能。它是一种全新且简化的托管选项,适用于由无服务器 API 提供支持的现代 Web 应用。

替代文本

静态 Web 应用程序提供:

  • 免费的静态内容网络托管,例如 HTML、CSS、JavaScript 和图像。
  • Azure Functions 提供的集成API支持。
  • 第一方 GitHub 集成,其中存储库更改触发构建和部署。
  • 全球分布的静态内容,使内容更贴近您的用户。
  • 免费 SSL 证书,自动更新。
  • 自定义域名为您的应用提供品牌定制。
  • 调用 API 时具有反向代理的无缝安全模型,无需 CORS 配置。
  • 身份验证提供程序与 Azure Active Directory、Facebook、Google、GitHub 和 Twitter 集成。
  • 可定制的授权角色定义和分配。
  • 后端路由规则使您能够完全控制您所提供的内容和路线。
  • 由拉取请求支持的生成暂存版本可在发布之前启用站点的预览版本。

让我们通过 3 个步骤部署我们的应用程序!

连接 GitHub 帐户

替代文本

提供构建信息

替代文本

观看 GitHub 在 Azure 静态 Web 应用上构建和部署应用程序

替代文本

注意:Azure Static Web Apps 创建的YML 工作流文件已使用自定义构建步骤进行了更新。

尝试一下

资源

GitHub 徽标 招财猫/猫咪变身

Catsify 是一款简单而富有创意的应用程序,可以帮助您为可爱的猫咪找到一个独特的名字

Azure 静态 Web 应用 CI/CD

Catsify 是什么?

Catsify 是一款猫咪名字生成器,托管在 Azure 静态 Web 应用上。其技术栈包括:

  • 用 Angular v10(预览版)编写的UI
  • 用 Rust 编写的API ,编译为 WASM通过 Node.js 无服务器函数公开。

Bazel依赖图






鏂囩珷鏉ユ簮锛�https://dev.to/azure/angular-rust-web assembly-node-js-serverless-and-the-new-azure-static-web-apps-cnb
PREV
宣布推出全新免费课程:机器学习入门
NEXT
Vite.js 或者我如何成为当今最快的程序员。