대중 녹슨 및 복판 조립 - wasm bindgen
wasm bindgen을 사용하여 WebAssembly 및 JavaScript 바인딩
WebAssembly can only send and receive number between JavaScript and WebAssembly module.
문자열, 대상, 함수 등 다른 데이터를 전달하기 위해서 귀속 파일을 만들어야 합니다.
바인딩 파일에서 다음을 수행합니다.
WebAssembly can only send and receive number between JavaScript and WebAssembly module.
wasm-bindgen
을 받았다.wasmbindgen 회사
Facilitating high-level interactions between wasm modules and JavaScript - wasm-bindgen
smbindgen은 자바스크립트와 WebAssembly 사이에 디지털 이외의 내용, 즉 대상, 문자열, 그룹 등을 통신하는 채널을 제공합니다.
코드를 좀 쓰다✍️
wasmbindgen의
hello_world
부터 시작합시다.카고를 사용하여 새 프로젝트를 만듭니다.
$ cargo new --lib hello_world
Created library `hello_world` package
그러면 필요한 파일이 포함된 새 Rust 프로젝트가 생성됩니다.만든 후 가장 좋아하는 편집기에서 항목을 엽니다.
Cargo.toml
파일을 열고 wasm-bindgen
의존 항목을 추가합니다.내 책 좀 봐, 녹식과 WebAssembly here
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Sendil Kumar <[email protected]>"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2.56"
src/lib.rs
파일을 열고 다음 내용으로 대체합니다.use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn hello_world() -> String {
"Hello World".to_string()
}
wasm_bindgen
라이브러리 use wasm_bindgen::prelude::*;
을 가져왔습니다.#[wasm_bindgen]
태그를 사용하여 hello_world() 함수에 주석을 달았습니다.hello_world()
함수는 String
을 되돌려줍니다.WebAssembly 모듈을 생성하려면 다음을 실행하십시오.
$ cargo build --target=wasm32-unknown-unknown
cargo build
명령은 JavaScript 바인딩 파일을 생성하지 않습니다.바인딩 파일을 생성하기 위해서는 생성된 WebAssembly 모듈에서wasm bindgen CLI 도구를 실행해야 합니다.wasm-bindgen CLI
을 설치하여 바인딩 파일을 생성합니다.cargo
을 사용하여 wasm-bindgen-CLI
을 설치합니다.$ cargo install wasm-bindgen-cli
설치에 성공하면 생성된 WebAssembly 모듈에서wasm bindgen CLI를 실행합니다.$ wasm-bindgen target/wasm32-unknown-unknown/debug/hello_world.wasm --out-dir .
우리는 wasm-bindgen
이 생성된 WebAssembly 모듈을 위해 귀속 자바스크립트를 생성하도록 지시합니다.--out-dir
로고는 wasm-bindgen
이 어디에서 파일을 생성하는지 표시합니다.파일은 현재 폴더에서 생성됩니다.그러면 다음 파일이 생성됩니다.
$ ls -lrta
76330 hello_world_bg.wasm
1218 hello_world.js
109 hello_world.d.ts
190 hello_world_bg.d.ts
wasm-bindgen CLI
은 WebAssembly 모듈(cargo가 구축한 출력)을 입력으로 하고 귀속을 생성합니다.바인딩 JavaScript 파일의 크기는 약 1.2 KB
입니다.hello_world.js
은 JavaScript와 WebAssembly 모듈 간의 모든 번역을 완료합니다(필요).wasm bindgen CLI는 바인딩 파일과 함께 type definition file
hello_world.d.ts
을 생성합니다.WebAssembly 모듈의 유형 정의 파일(
hello_world.d.ts
)입니다.바인딩 파일을 사용하여 WebAssembly 모듈
hello_world.wasm
을 다시 작성합니다.JavaScript 바인딩 파일을 사용하면 WebAssembly 모듈을 로드하고 실행할 수 있습니다.
If you are using TypeScript, then the type definition will be helpful.
바인딩 파일에서
바인딩 파일은 WebAssembly 모듈로 가져옵니다.
import * as wasm from './hello_world_bg.wasm';
그리고 TextDecoder에서 온 문자열을 디코딩하기 위해 ArrayBuffer이 있습니다.사용할 수 있는 입력 매개 변수가 없기 때문에 TextEncoder(JavaScript의 문자열을 공유 메모리에 인코딩할 필요가 없습니다.)
wasm-bindgen
은 귀속 파일에만 필요한 함수를 생성합니다.이렇게 하면 바인딩 파일이 1.2KB로 작아집니다.Modern browsers have built-in
TextDecoder
andTextEncoder
support. Thewasm-bindgen
checks and uses them if they are available else it loads it usingpolyfill
.
const lTextDecoder = typeof TextDecoder === 'undefined' ? require('util').TextDecoder : TextDecoder;
let cachedTextDecoder = new lTextDecoder('utf-8');
JavaScript와 WebAssembly 모듈 간의 공유 메모리는 매번 초기화할 필요가 없습니다.우리는 그것을 한 번 초기화한 후에 전체 과정에서 그것을 사용한다.우리는 메모리를 한 번 불러오고 사용할 수 있는 두 가지 방법이 있다.
let cachegetInt32Memory0 = null;
function getInt32Memory0() {
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachegetInt32Memory0;
}
let cachegetUint8Memory0 = null;
function getUint8Memory0() {
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
}
return cachegetUint8Memory0;
}
Rust 코드는 String
을 JavaScript 영역으로 반환합니다.문자열은 공유 메모리를 통해 전달됩니다.공유 메모리는 ArrayBuffer에 불과합니다.따라서 오프셋 (스토리지 위치) 의 바늘과 문자열의 길이만 가리키면 문자열을 검색할 수 있습니다.위치 인덱스와 길이는 모두 숫자일 뿐이다.WebAssembly 플랫폼에서 JavaScript로 전달되는 데 아무런 문제가 없습니다.
다음 함수는 WebAssembly 모듈에서 문자열을 읽어들이는 데 사용됩니다.
function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
ptr
은 위치 편이의 인덱스입니다.len
은 문자열의 길이입니다.hello_world
함수를 가지고 있다./**
* @returns {string}
*/
export function hello_world() {
try {
wasm.hello_world(8);
var r0 = getInt32Memory0()[8 / 4 + 0];
var r1 = getInt32Memory0()[8 / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_free(r0, r1);
}
}
hello_world
함수를 내보냅니다.공유 메모리 버퍼에서 포인터와 길이를 가져옵니다.그리고 두 개의 숫자(r0, r1)를 getStringFromWasm
함수에 전달합니다.getStringFromWasm
함수는 공유 그룹 버퍼에서 문자열을 되돌려줍니다. 그 중에서 ptr
과 len
입니다.출력을 받은 후, 우리는
wasm.__wbindgen_free(r0, r1)
을 사용하여 분배된 메모리를 지웁니다.화물 확장
Rust 쪽에서 발생하는 상황을 이해하기 위해
cargo-expand
명령을 사용하여 매크로를 전개하고 코드가 어떻게 생성되는지 봅시다.Note: Check here for how to install cargo expand. It is not mandatory for the course of this book. But they will help you understand what wasm-bindgen actually generates.
터미널을 열고 프로젝트의 기본 디렉터리로 이동하여
cargo expand --target=wasm32-unknown-unknown > expanded.rs
을 실행합니다.위의 명령은
expanded.rs
을 생성합니다.간단한
#[wasm_bindgen]
주석 변경/공개 함수의 상세한 부분을 추가했습니다.컴파일러가 WebAssembly 모듈로 변환하는 데 필요한 모든 메타데이터입니다.Note: Check out more about the internals of the #[wasm_bindgen] command here
expanded.rs
은 hello_world
의 기능을 가지고 있다.pub fn hello_world() -> String {
"Hello World".to_string()
}
__wasm_bindgen_generated_hello_world
함수는 자동으로 생성됩니다.#[allow(non_snake_case)]
#[export_name = "hello_world"]
#[allow(clippy::all)]
pub extern "C" fn __wasm_bindgen_generated_hello_world(
) -> <String as wasm_bindgen::convert::ReturnWasmAbi>::Abi {
let _ret = { hello_world() };
<String as wasm_bindgen::convert::ReturnWasmAbi>::return_abi(_ret)
}
#[export_name = "hello_world"]
은 hello_world
이라는 함수를 내보냅니다.함수는
<String as wasm_bindgen::convert::ReturnWasmAbi>::Abi
을 반환합니다.우리는 뒤의 댓글에서 이런 유형에 대한 더 많은 정보를 볼 수 있을 것이다.하지만 이곳에서 무슨 일이 일어났는지 알고 싶으면 this의 댓글을 읽어 보세요.이 함수는 자바스크립트 파일(
ptr
및 len
)을 바인딩하는 형식으로 문자열을 반환합니다.실행🏃♂️
로컬 웹 서버가 아닌 Webpack이나 Parcel 같은 귀속기를 사용하여 생성된 파일을 불러오고 실행할 수 있습니다.
우리는 다음 장에서 이 묶음들이 어떻게 도움을 제공하는지 더욱 상세하게 이해할 것이다.
이제 생성된 파일을 실행하고 로드하는 방법을 살펴보겠습니다.
Note the following setup is common and we will refer it as the
"default"
webpack setup in the future examples.
웹 패키지가 파일을 처리하는 방법을 설정하기 위해
webpack.config.js
을 만듭니다.const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
plugins: [
new HtmlWebpackPlugin(),
],
mode: 'development'
};
이것은 HTMLWebpackPlugin
이 있는 표준 패키지 프로필입니다.이 플러그인은 우리가 만드는 것이 아니라 기본 index.html
을 만드는 데 도움을 줍니다.웹 패키지와 실행할 스크립트의 의존 항목을 묶기 위해
package.json
파일을 추가합니다.{
"scripts": {
"build": "webpack",
"serve": "webpack-dev-server"
},
"devDependencies": {
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1"
}
}
JavaScript 바인딩을 불러오는 index.js
파일을 만듭니다. 이 바인딩 JavaScript는 생성된 WebAssembly 모듈을 불러옵니다.import("./hello_world").then(module => {
console.log(module.hello_world());
});
이제 터미널로 이동해서 npm 의존 항목을 설치합니다.$ npm install
webpack-dev-server
실행 사용$ npm run serve
웹 페이지 dev 서버에서 제공하는 URL(기본 http://localhost:8080)로 이동하여 브라우저에서 개발자 컨트롤러를 열고 인쇄된'Hello World'를 보십시오.wasm bindgen 옵션
wasm-bindgen
에서 지원하는 다양한 옵션을 살펴보겠습니다.--out-dir
- 특정 디렉토리에서 파일을 생성합니다.--out-name
- 사용자 정의 파일 이름을 설정합니다.wasm bindgen에는 다음과 같은 플래그가 있습니다.
--디버깅
--debug
옵션은 생성된 WebAssembly 모듈에 추가 디버깅 정보를 포함합니다.그러면 WebAssembly 모듈의 크기가 증가합니다.그러나 그것은 발전 과정에서 유용하다.--디버깅 유지
WebAssembly 모듈은 custom sections이 있을 수도 있고 없을 수도 있습니다.이 사용자 정의 부분은 디버깅 정보를 저장하는 데 사용할 수 있습니다.그것들은 응용 프로그램을 디버깅할 때 매우 도움이 될 것이다. (예를 들어 브라우저 개발 도구에서)이렇게 하면 WebAssembly 모듈의 크기가 증가합니다.이것은 개발에 매우 유용하다.
- 필요 없음
이 로고는wasmbindgen에 녹 기호 이름을
demangle
으로 설정하지 말라고 알려 줍니다.Demangle은 최종 사용자가 Rust 파일에 정의한 동일한 이름을 사용하도록 도와줍니다.-- 이름 섹션 삭제
이것은 파일의 디버깅 이름 부분을 삭제합니다.잠시 후 WebAssembly 모듈에서 각 부분에 대한 더 많은 정보를 볼 수 있습니다.그러면 WebAssembly 모듈의 크기가 줄어듭니다.
-- 생산자 섹션 삭제
WebAssembly 모듈은 producer section을 사용할 수 있습니다.이 절에는 파일을 생성하는 방법 또는 누가 생성하는지에 대한 정보가 포함되어 있습니다.
기본적으로 생성된 WebAssembly 모듈에 생산자 부분이 추가됩니다.이 표지가 있으면 우리는 그것을 제거할 수 있다.
그것은 더 많은 바이트를 절약했다.
wasm-bindgen
은 Node.js
과 browser
환경에 귀속 파일을 생성하는 옵션을 제공합니다.우리 그 깃발들을 좀 봅시다.--nodejs
- 노드에만 적용되는 출력을 생성합니다.js.ESModules가 없습니다.--browser
- ESModules가 있는 브라우저에만 사용할 수 있는 출력을 생성합니다.--no-modules
- 브라우저에만 사용할 수 있는 출력을 생성합니다.ESModules가 없습니다.ESModules가 지원되지 않는 브라우저에서는 사용할 수 있습니다.--no-typescript
플래그를 사용하여 유형 정의 파일(*.d.ts)을 닫을 수 있습니다.만약 네가 이 글을 좋아한다면, 너는 내가 쓴 녹슨 것과 인터넷 조립에 관한 책을 좋아할 것이다.here 보기
👇 되팔다👇
센디르 쿠마르 / rustwasm 소개
품질의 녹식과 복판 조립 - 안내
흥미가 있고 탐색이 더 많아...
사용자 정의 섹션에 대한 자세한 내용을 확인하십시오.here 보기
웹 페이지 here에 대한 더 많은 정보 보기
this편의 좋은 블로그 글을 보고 ECMAScript 모듈에 대한 더 많은 정보를 얻을 수 있습니다.
너는 나를 따라와도 된다.
만약 당신이 이 문장을 좋아한다면, 좋아하거나 평론을 남겨 주세요.❤️
Reference
이 문제에 관하여(대중 녹슨 및 복판 조립 - wasm bindgen), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sendilkumarn/rust-and-webassembly-for-the-masses-wasm-bindgen-57fl텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)