自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Rust 編譯為 WebAssembly 在前端項(xiàng)目中的使用

開發(fā) 項(xiàng)目管理
為了保持構(gòu)建速度非???,web-sys?將每個(gè)Web接口都封裝在一個(gè)Cargo特性后面。在API文檔中找到我們要使用的類型或方法;它將列出必須啟用的特性才能訪問該API。

前言

最近,加大了對(duì)Rust相關(guān)文章的輸出。在評(píng)論區(qū)或者私信區(qū)有一些不同的聲音說:“Rust沒有前途,然后...."。其實(shí)呢,看一個(gè)技術(shù)是否有需要學(xué)習(xí)的動(dòng)力。想必大家的底層理由都是「一切都是向錢看」,畢竟在國(guó)內(nèi)大家都是業(yè)務(wù)為主,想自己純手搞一套符合自己的技術(shù)框架和范式,這是不切實(shí)際的。(當(dāng)然也不能一桿子打死,還是有很多技術(shù)大牛的)現(xiàn)在大家糾結(jié)或者對(duì)這個(gè)技術(shù)屬于觀望態(tài)度,無非就是在平時(shí)開發(fā)工作中沒有涉及到的點(diǎn)。

同時(shí),由于國(guó)內(nèi)技術(shù)的「滯后性」,有一些應(yīng)用場(chǎng)景其實(shí)還是處于蠻荒的狀態(tài)。(不是崇洋媚外,事實(shí)確實(shí)如此)。所以,在一些可以用到新的技術(shù)點(diǎn)的方向上,國(guó)內(nèi)還是處于藍(lán)海階段。

所以,本著對(duì)該技術(shù)的獨(dú)有關(guān)注度,我還是選擇義無反顧的投身到學(xué)習(xí)和實(shí)際中?!笡_破黎明之前的黑暗,你會(huì)擁有太陽(yáng),而晨曦中第一縷陽(yáng)光也是為你而耀眼」。

圖片圖片

而具體,Rust到底能給你帶來點(diǎn)啥,我們之前有文章講過,這里就不在贅述了。

Last but not leaset,由于現(xiàn)在本人暫時(shí)專注于前端領(lǐng)域居多,所以我更多關(guān)注Rust能為前端帶來點(diǎn)啥。而說到Rust和前端,第一點(diǎn)的聯(lián)想就是:WebAssembly。(如果,不了解何為WebAssembly,可以參考我們之前的文章瀏覽器第四種語言-WebAssembly,里面的例子是用Emscripten寫的)

其實(shí),我們之前寫過如何用C寫wasm,也寫過WebAssembly-C與JS互相操作等文章。但是,由于一些不可言喻的原因擱置了。

我們今天將使用Rust創(chuàng)建一個(gè)WebAssembly Hello World程序。我們將深入了解由wasm-bindgen生成的代碼,以及它們?nèi)绾喂餐瑓f(xié)作來幫助我們進(jìn)行開發(fā)。我們還將使用wabt來探索生成的wasm代碼。這將使我們更好地理解Rust WebAssembly,并為我們的開發(fā)奠定良好的基礎(chǔ)。

好了,天不早了,干點(diǎn)正事哇。

我們能所學(xué)到的知識(shí)點(diǎn)

  1. 前置知識(shí)點(diǎn)
  2. 項(xiàng)目搭建
  3. 原理探析
  4. 內(nèi)容拓展

1. 前置知識(shí)點(diǎn)

「前置知識(shí)點(diǎn)」,只是做一個(gè)概念的介紹,不會(huì)做深度解釋。因?yàn)?,這些概念在下面文章中會(huì)有出現(xiàn),為了讓行文更加的順暢,所以將本該在文內(nèi)的概念解釋放到前面來?!溉绻蠹覍?duì)這些概念熟悉,可以直接忽略」同時(shí),由于閱讀我文章的群體有很多,所以有些知識(shí)點(diǎn)可能「我視之若珍寶,爾視只如草芥,棄之如敝履」。以下知識(shí)點(diǎn),請(qǐng)「酌情使用」。

安裝Rust

如果是你一個(gè)Rust萌新,我們也給你提供Rust環(huán)境配置和入門指南。

如果,想獨(dú)立完成安裝,可以到Rust 安裝頁(yè)面跟著教程安裝。

在安裝成功Rust后,它會(huì)安裝一個(gè)名為rustup的工具,這個(gè)工具能讓我們管理多個(gè)不同版本的 Rust。默認(rèn)情況下,它會(huì)安裝用于慣常 Rust 開發(fā)的 stable 版本 Rust Release。

Rustup 會(huì)安裝

  • Rust 的編譯器 rustc
  • Rust 的包管理工具 cargo
  • Rust 的標(biāo)準(zhǔn)庫(kù) rust-std
  • 以及一些有用的文檔 rust-docs

因?yàn)?,我本機(jī)已經(jīng)安裝好了Rust。我們可以通過rustup --version來查看rustup的版本。以下是我本機(jī)的rustup版本信息。下文中所有的代碼,都基于該版本。

rustup --version
rustup 1.26.0 (5af9b9484 2023-04-05)

安裝WebAssembly二進(jìn)制工具包(wabt)

圖片圖片

這些工具旨在用于開發(fā)工具鏈或其他系統(tǒng),這些系統(tǒng)希望「操作WebAssembly文件」。與WebAssembly規(guī)范解釋器不同(該解釋器旨在盡可能簡(jiǎn)單、聲明性和“規(guī)范性”),這些工具是用C/C++編寫的,并設(shè)計(jì)成更容易集成到其他系統(tǒng)中。這些工具不旨在提供優(yōu)化平臺(tái)或更高級(jí)的編譯目標(biāo);相反,它們旨在實(shí)現(xiàn)與規(guī)范的完全適應(yīng)和遵從。

我們可以利用brew來在Mac環(huán)境下安裝。

圖片圖片

2. 項(xiàng)目搭建

2.1 安裝wasm-bindgen

我們可以通過cargo install --list來查看在$HOME/.cargo/bin位置安裝過的Rust二進(jìn)制文件。

在一些其他的教程中可以不使用wasm-bindgen構(gòu)建Hello World程序,但是在本文中,我們將使用它,因?yàn)樗赗ust WebAssembly開發(fā)中是必不可少的。

cargo install wasm-bindgen-cli

Rust WebAssembly允許我們將WebAssembly模塊有針對(duì)性地插入到現(xiàn)有的JavaScript應(yīng)用程序中,尤其是在「性能關(guān)鍵的代碼路徑」中。我們可以將wasm-bindgen視為一種工具,它通過生成用于JavaScript和WebAssembly之間高效交互的「粘合代碼」和綁定來幫助我們實(shí)現(xiàn)絲滑的交互體驗(yàn)。

2.2 創(chuàng)建Rust WebAssembly項(xiàng)目

巴拉拉小魔仙,念誦如下咒語,構(gòu)建一個(gè)Rust WebAssembly項(xiàng)目。

cargo new hello_world --lib

上面的代碼是使用Cargo工具創(chuàng)建一個(gè)新的Rust項(xiàng)目,項(xiàng)目的名稱是hello_world,并且指定它是一個(gè)庫(kù)(--lib)。這將創(chuàng)建一個(gè)包含基本項(xiàng)目結(jié)構(gòu)的文件夾,其中包括一個(gè)Cargo.toml文件和一個(gè)src文件夾。

+-- Cargo.toml
+-- src
    +-- lib.rs
  • Cargo.toml文件用于管理項(xiàng)目的依賴和配置
  • src文件夾包含項(xiàng)目的Rust源代碼文件
  • 項(xiàng)目名稱hello_world是一個(gè)示例名稱,我們可以根據(jù)自己的需求為項(xiàng)目指定不同的名稱。

2.3 修改Cargo.toml配置項(xiàng)

使用宇宙最強(qiáng)IDE -VScode,打開Cargo.toml文件。我們應(yīng)該會(huì)看到以下內(nèi)容。

[package]
name = "hello_world"
version = "0.1.0"
authors = ["789"]
edition = "2021"

[dependencies]

將其修改成下面的內(nèi)容

[package]
name = "hello_world"
version = "0.1.0"
authors = ["789"]
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

上面的大部分字段大家都能看懂,其中l(wèi)ib項(xiàng)的配置,這里稍微解釋一下:

crate-type = ["cdylib"]: 這一行「指定了生成的庫(kù)的類型」。在這里,crate-type 設(shè)置為["cdylib"],這表示我們正在創(chuàng)建一個(gè)動(dòng)態(tài)鏈接庫(kù)(C-compatible dynamic library)。這用于編譯一個(gè)供其他編程語言加載的動(dòng)態(tài)庫(kù)。此輸出類型將在Linux上創(chuàng)建*.so文件,在macOS上創(chuàng)建*.dylib文件,在Windows上創(chuàng)建*.dll文件。

這種類型的庫(kù)可以被其他編程語言調(diào)用,因?yàn)樗鼈兣cC語言兼容。這對(duì)于與WebAssembly(Wasm)互操作性很重要,因?yàn)閃asm通常需要與C語言接口進(jìn)行交互。因此,cdylib 表示該庫(kù)是一個(gè)可供其他語言使用的動(dòng)態(tài)鏈接庫(kù)。

2.4 編輯lib.rs

打開src/lib.rs文件。將其更改為以下內(nèi)容:

extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;

// 導(dǎo)入 'window.alert'
#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

// 導(dǎo)出一個(gè) 'helloworld' 函數(shù)
#[wasm_bindgen]
pub fn helloworld(name: &str) {
    alert(&format!("Hello World : {}!", name));
}

我們簡(jiǎn)單解釋一下核心代碼:

  1. extern crate wasm_bindgen;: 這一行聲明了對(duì)wasm_bindgen庫(kù)的依賴。wasm_bindgen是一個(gè)Rust庫(kù),用于構(gòu)建Wasm模塊并提供與JavaScript的互操作性。在 Rust 當(dāng)中,庫(kù)被稱為crates,因?yàn)槲覀兪褂玫氖且粋€(gè)外部庫(kù),所以有 extern。
  2. use wasm_bindgen::prelude::*;: 這一行導(dǎo)入了wasm_bindgen庫(kù)的預(yù)導(dǎo)出(prelude)模塊中的所有內(nèi)容,以便在后續(xù)代碼中使用。

在 Rust 中調(diào)用來自 JavaScript 的外部函數(shù)

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

#[wasm_bindgen]: 在 #[] 中的內(nèi)容叫做 "屬性",并以某種方式改變下面的語句。#[wasm_bindgen]是一個(gè)「屬性標(biāo)記」,用于指定與WebAssembly互操作相關(guān)的特性。

extern "C" { fn alert(s: &str); }: 這里聲明了一個(gè)「外部函數(shù)」alert,它使用extern "C" 指定了C ABI(應(yīng)用二進(jìn)制接口),這意味著它「可以與C語言進(jìn)行交互」?!高@個(gè)alert函數(shù)沒有在Rust中實(shí)現(xiàn),而是在JavaScript中實(shí)現(xiàn),用于在瀏覽器中顯示警告框」。

在 JavaScript 中調(diào)用的 Rust 函數(shù)

#[wasm_bindgen]
pub fn helloworld(name: &str) {
    alert(&format!("Hello World : {}!", name));
}

#[wasm_bindgen] pub fn helloworld(name: &str): 這是一個(gè)Rust函數(shù)helloworld,它被標(biāo)記為wasm_bindgen,這意味著它「可以被JavaScript調(diào)用」。這個(gè)函數(shù)接受一個(gè)「字符串參數(shù)」name,然后調(diào)用「之前聲明」的alert函數(shù),以顯示帶有Hello World消息的彈框,并在消息中包括name參數(shù)的內(nèi)容。

2.5 編譯代碼

在命令行中輸入以下命令:

cargo build --target wasm32-unknown-unknown

如果未安裝對(duì)應(yīng)的庫(kù),控制臺(tái)會(huì)給出提示。

圖片圖片

那我們就照貓畫虎的操作一下:

rustup target add wasm32-unknown-unknown?

  1. cargo build: 這是 Cargo 工具的命令,用于構(gòu)建 Rust 項(xiàng)目。它會(huì)編譯項(xiàng)目的源代碼并生成可執(zhí)行文件或庫(kù)文件,具體取決于項(xiàng)目的類型。
  2. --target wasm32-unknown-unknown: 這部分是構(gòu)建的目標(biāo)參數(shù)。--target 標(biāo)志用于指定要構(gòu)建的目標(biāo)平臺(tái)。在這里,wasm32-unknown-unknown 是指定了 WebAssembly 目標(biāo)平臺(tái)。這告訴 Cargo 生成「適用于 WebAssembly 的二進(jìn)制文件」,而不是生成本地平臺(tái)的二進(jìn)制文件。

當(dāng)運(yùn)行這個(gè)命令后,Cargo 會(huì)使用 Rust 編譯器(Rustc)以及與 WebAssembly 相關(guān)的工具鏈,將 Rust 代碼編譯為 WebAssembly 格式的二進(jìn)制文件。這個(gè)生成的 Wasm 文件可以在瀏覽器中運(yùn)行,或與其他支持 WebAssembly 的環(huán)境一起使用。

運(yùn)行結(jié)果如下:

cargo build --target wasm32-unknown-unknown 命令的「默認(rèn)輸出位置」是在項(xiàng)目的 target 目錄下,具體位置是:

target/wasm32-unknown-unknown/debug/

在這個(gè)目錄下,我們會(huì)找到生成的 WebAssembly 文件(通常是一個(gè) .wasm 文件),以及其他與編譯過程相關(guān)的文件。

圖片圖片

2.6 構(gòu)建 Web服務(wù)器

既然,我們通過上述的魔法,將Rust程序編譯為了可以在瀏覽器環(huán)境下引用執(zhí)行的格式。「為了這口醋,我們還專門包頓餃子」。

我們需要一個(gè)Web服務(wù)器來測(cè)試我們的WebAssembly程序。我們將使用Webpack,我們需要?jiǎng)?chuàng)建三個(gè)文件:index.js、package.json和webpack.config.js。

下面的代碼,我們最熟悉不過了,就不解釋了。

index.js

// 直接引入了,剛才編譯后的文件
const rust = import('./pkg/hello_world.js');

rust
  .then(m => m.helloworld('World!'))
  .catch(console.error);

package.json

{
  "scripts": {
    "build": "webpack",
    "serve": "webpack-dev-server"
  },

  "devDependencies": {
    "@wasm-tool/wasm-pack-plugin": "0.4.2",
    "text-encoding": "^0.7.0",
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.29.4",
    "webpack-cli": "^3.1.1",
    "webpack-dev-server": "^3.1.0"
  }
}

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");

module.exports = {
    entry: './index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'index.js',
    },
    plugins: [
        new HtmlWebpackPlugin(),
        new WasmPackPlugin({
            crateDirectory: path.resolve(__dirname, ".")
        }),
        // 讓這個(gè)示例在不包含`TextEncoder`或`TextDecoder`的Edge瀏覽器中正常工作。
        new webpack.ProvidePlugin({
            TextDecoder: ['text-encoding', 'TextDecoder'],
            TextEncoder: ['text-encoding', 'TextEncoder']
        })
    ],
    mode: 'development'
};

安裝指定的依賴。

npm install webpack --save-dev
npm install webpack-cli --save-dev
npm install webpack-dev-server --save-dev
npm install html-webpack-plugin --save-dev
npm install @wasm-tool/wasm-pack-plugin --save-dev
npm install text-encoding --save-dev

2.7 構(gòu)建&運(yùn)行程序

使用npm run build構(gòu)建程序。

使用npm run serve運(yùn)行Hello World程序

在瀏覽器中打開localhost:8080,我們將看到一個(gè)顯示 Hello World! 的彈窗。

圖片圖片

到目前為止,我們已經(jīng)構(gòu)建了一個(gè)wasm并且能夠和js實(shí)現(xiàn)功能交互的項(xiàng)目。其實(shí),到這里已經(jīng)完成了,我們這篇文章的使命。但是,在這里戛然而止,感覺缺失點(diǎn)啥。所以,我們繼續(xù)深挖上面的項(xiàng)目的實(shí)現(xiàn)原理。

3. 原理探析

在使用cargo和wasm_bindgen編譯源代碼時(shí),會(huì)在pkg文件中「自動(dòng)生成」以下文件:

  • "hello_world_bg.wasm"
  • "hello_world.js"
  • "hello_world.d.ts"
  • "package.json"

這些文件也可以通過使用以下wasm-bindgen命令手動(dòng)生成:

wasm-bindgen target/wasm32-unknown-unknown/debug/hello_world.wasm --out-dir ./pkg

瀏覽器調(diào)用順序

以下顯示了當(dāng)我們?cè)跒g覽器中訪問localhost:8080時(shí)發(fā)生的函數(shù)調(diào)用序列。

  1. index.js
  2. hello_world.js (調(diào)用hello_world_bg.js)
  3. helloworld_bg.wasm

index.js

const rust = import('./pkg/hello_world.js');

rust
  .then(m => m.helloworld('World!'))
  .catch(console.error);

index.js 導(dǎo)入了 hello_world.js 并調(diào)用其中的 helloworld 函數(shù)。

hello_world.js

下面是hello_world.js的內(nèi)容,在其中它調(diào)用了helloworld_bg.wasm

import * as wasm from "./hello_world_bg.wasm";
import { __wbg_set_wasm } from "./hello_world_bg.js";
__wbg_set_wasm(wasm);
export * from "./hello_world_bg.js";

hello_world_bg.js

// ...省去了部分代碼
export function helloworld(name) {
    const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    const len0 = WASM_VECTOR_LEN;
    wasm.helloworld(ptr0, len0);
}

hello_world_bg.js 文件是由wasm-bindgen自動(dòng)生成的,它包含了用于將DOM和JavaScript函數(shù)導(dǎo)入到Rust中的JavaScript粘合代碼。它還在生成的WebAssembly函數(shù)上向JavaScript公開了API。

Rust WebAssembly專注于將WebAssembly與現(xiàn)有的JavaScript應(yīng)用程序集成在一起。為了實(shí)現(xiàn)這一目標(biāo),我們需要在JavaScript和WebAssembly函數(shù)之間「?jìng)鬟f不同的值、對(duì)象或結(jié)構(gòu)。這并不容易,因?yàn)樾枰獏f(xié)調(diào)兩個(gè)不同系統(tǒng)的不同對(duì)象類型」。

更糟糕的是,當(dāng)前WebAssembly僅支持「整數(shù)」和「浮點(diǎn)數(shù)」,不支持字符串。這意味著我們不能簡(jiǎn)單地將字符串傳遞給WebAssembly函數(shù)。

要將字符串傳遞給WebAssembly,我們需要「將字符串轉(zhuǎn)換為數(shù)字」(請(qǐng)注意在webpack.config.js中指定的TextEncoderAPI),將這些數(shù)字放入WebAssembly的內(nèi)存空間中,最后「返回一個(gè)指向字符串的指針」給WebAssembly函數(shù),以便在JavaScript中使用它。在最后,我們需要釋放WebAssembly使用的字符串內(nèi)存空間。

如果我們查看上面的JavaScript代碼,這正是自動(dòng)執(zhí)行的操作。helloworld函數(shù)首先調(diào)用passStringToWasm。

  • 這個(gè)函數(shù)在WebAssembly中「創(chuàng)建一些內(nèi)存空間」,將我們的字符串轉(zhuǎn)換為數(shù)字,將數(shù)字寫入內(nèi)存空間,并返回一個(gè)指向字符串的指針。

圖片圖片

  • 然后將指針傳遞給wasm.helloworld來執(zhí)行JavaScript的alert。最后,wasm.__wbindgen_free釋放了內(nèi)存。

如果只是傳遞一個(gè)簡(jiǎn)單的字符串,我們可能可以自己處理,但考慮到當(dāng)涉及到更復(fù)雜的對(duì)象和結(jié)構(gòu)時(shí),這個(gè)工作會(huì)很快變得非常復(fù)雜。這說明了wasm-bindgen在Rust WebAssembly開發(fā)中的重要性。

反編譯wasm到txt

在前面的步驟中,我們注意到wasm-bindgen生成了一個(gè)hello_world.js文件,其中的函數(shù)調(diào)用到我們生成的hello_world_bg.wasm中的WebAssembly代碼。

基本上,hello_world.js充當(dāng)其他JavaScript(如index.js)與生成的WebAssembly的helloworld_bg.wasm之間的橋梁。

我們可以通過輸入以下命令進(jìn)一步探索helloworld_bg.wasm:

wasm2wat hello_world_bg.wasm > hello_world.txt

這個(gè)命令使用wabt將WebAssembly轉(zhuǎn)換為WebAssembly文本格式,并將其保存到一個(gè)hello_world.txt文件中。打開helloworld.txt文件,然后查找$helloworld函數(shù)。這是我們?cè)趕rc/lib.rs中定義的helloworld函數(shù)的生成WebAssembly函數(shù)。

$helloworld函數(shù)

圖片圖片

在helloworld.txt中查找以下行:

(export "helloworld" (func $helloworld))

這一行導(dǎo)出了wasm.helloworld供宿主調(diào)用的WebAssembly函數(shù)。我們通過hello_world_bg.js中的wasm.helloworld來調(diào)用這個(gè)WebAssembly函數(shù)。

圖片圖片

接下來,查找以下行:

(import "./hello_world_bg.js" "__wbg_alert_9ea5a791b0d4c7a3" (func $hello_world::alert::__wbg_alert_9ea5a791b0d4c7a3::h93c656ecd0e94e40 (type 4)))

這對(duì)應(yīng)于在hello_world_bg.js中生成的以下JavaScript函數(shù):

export function __wbg_alert_9ea5a791b0d4c7a3() { return logError(function (arg0, arg1) {
    alert(getStringFromWasm0(arg0, arg1));
}, arguments) };

這是wasm-bindgen提供的「粘合部分」,幫助我們?cè)赪ebAssembly中使用JavaScript函數(shù)或DOM。

最后,讓我們看看wasm-bindgen生成的其他文件。

hello_world.d.ts

這個(gè).d.ts文件包含JavaScript粘合的TypeScript類型聲明,如果我們的現(xiàn)有JavaScript應(yīng)用程序正在使用TypeScript,它會(huì)很有用。我們可以對(duì)調(diào)用WebAssembly函數(shù)進(jìn)行「類型檢查」,或者讓我們的IDE提供自動(dòng)完成。如果我們不使用TypeScript,可以安全地忽略這個(gè)文件。

package.json

package.json文件包含有關(guān)生成的JavaScript和WebAssembly包的元數(shù)據(jù)。它會(huì)自動(dòng)從我們的Rust代碼中填充所有npm依賴項(xiàng),并使我們能夠發(fā)布到npm。

4. 內(nèi)容拓展

再次看一下以下代碼:

hello_world_bg.js

function helloworld(name) {
    const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    const len0 = WASM_VECTOR_LEN;
    wasm.helloworld(ptr0, len0);
}

該代碼用于分配和釋放內(nèi)存,這一切都是「由程序自動(dòng)處理」的。不需要垃圾回收器或完整的框架引擎,使得使用Rust編寫的WebAssembly應(yīng)用程序或模塊變得小巧且優(yōu)化。其他需要垃圾回收器的語言將需要包含用于其底層框架引擎的wasm代碼。因此,無論它們有多么優(yōu)化,其大小都不會(huì)小于Rust提供的大小。這使得Rust WebAssembly成為一個(gè)不錯(cuò)的選擇,如果我們需要將小型WebAssembly模塊集成或注入到JavaScript Web應(yīng)用程序中。

除了Hello World之外,還有一些其他需要注意的事項(xiàng):

web-sys

使用wasm-bindgen,我們可以通過使用extern在Rust WebAssembly中調(diào)用JavaScript函數(shù)。請(qǐng)記住src/lib.rs中的以下代碼:

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

Web具有大量API,從DOM操作到WebGL再到Web Audio等等。因此,如果我們的Rust WebAssembly程序增長(zhǎng),并且我們需要對(duì)Web API進(jìn)行多次不同的調(diào)用,我們將需要花時(shí)間編寫大量的extern代碼。

?

web-sys充當(dāng)wasm-bindgen的前端,為所有Web API提供原始綁定。

?

這意味著如果我們使用web-sys,可以節(jié)省時(shí)間,而不必編寫extern代碼。

圖片圖片

引入web-sys

將web-sys添加為Cargo.toml的依賴項(xiàng):

[dependencies]
wasm-bindgen = "0.2"

[dependencies.web-sys]
version = "0.3"
features = [
]

為了保持構(gòu)建速度非???,web-sys將每個(gè)Web接口都封裝在一個(gè)Cargo特性后面。在API文檔中找到我們要使用的類型或方法;它將列出必須啟用的特性才能訪問該API。

例如,如果我們要查找window.resizeTo函數(shù),我們會(huì)在API文檔中搜索resizeTo。我們將找到web_sys::Window::resize_to函數(shù),它需要啟用Window特性。要訪問該函數(shù),我們?cè)贑argo.toml中啟用Window特性:

[dependencies.web-sys]
version = "0.3"
features = [
  "Window"
]

調(diào)用這個(gè)方法:

use wasm_bindgen::prelude::*;
use web_sys::Window;

#[wasm_bindgen]
pub fn make_the_window_small() {
    // 調(diào)整窗口大小為500px x 500px。
    let window = web_sys::window().unwrap();
    window.resize_to(500, 500)
        .expect("無法調(diào)整窗口大小");
}

這段代碼的目的是調(diào)整瀏覽器窗口的大小為500x500像素,并演示了如何使用web-sys和啟用的Cargo特性來調(diào)用Web API。

責(zé)任編輯:武曉燕 來源: 前端柒八九
相關(guān)推薦

2024-09-30 09:25:29

2023-06-15 15:21:43

2022-06-22 10:04:29

JavaScriptRust語言

2023-04-21 10:08:00

版本工具依賴關(guān)系

2015-10-12 16:37:39

前端編碼雙向編譯

2018-01-27 21:19:06

前端Rust Service

2021-12-27 10:46:07

WebAPIserver簽名

2016-10-28 15:01:35

Cookie前端實(shí)踐

2021-06-11 09:00:00

語言WebWebAssembly

2017-01-09 07:05:26

谷歌編程語言

2021-08-18 08:00:00

Emscripten開發(fā)技術(shù)

2017-06-15 10:36:35

WebAssembly計(jì)算模塊

2009-06-24 17:34:58

使用JSF的經(jīng)驗(yàn)

2021-05-18 13:05:31

LinuxRust復(fù)用器

2023-09-22 14:33:24

微軟Rust開發(fā)工具

2022-06-02 08:01:11

云原生工具

2020-10-27 14:15:42

SpringBoot

2019-01-03 09:45:20

Go 前端 Web

2024-05-16 11:45:19

Rust項(xiàng)目代碼

2021-06-09 11:03:13

Web開發(fā)軟甲開發(fā)JavaScript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)