대중 녹슨 및 복판 조립 - wasm bindgen

wasm bindgen을 사용하여 WebAssembly 및 JavaScript 바인딩


WebAssembly can only send and receive number between JavaScript and WebAssembly module.


문자열, 대상, 함수 등 다른 데이터를 전달하기 위해서 귀속 파일을 만들어야 합니다.
바인딩 파일에서 다음을 수행합니다.
  • 은 문자열이나 대상을 WebAssembly 모듈에서 이해할 수 있는 내용으로 변환합니다.
  • 은 WebAssembly 모듈에서 반환되는 값을 JavaScript가 이해할 수 있는 문자열이나 대상으로 변환합니다.
  • 그러나 매번 그것을 바꾸는 것은 평범한 임무이며 실수하기 쉽다.다행히도 러스트월드는 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 and TextEncoder support. The wasm-bindgen checks and uses them if they are available else it loads it using polyfill.


    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 함수는 공유 그룹 버퍼에서 문자열을 되돌려줍니다. 그 중에서 ptrlen입니다.
    출력을 받은 후, 우리는 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.rshello_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의 댓글을 읽어 보세요.
    이 함수는 자바스크립트 파일(ptrlen)을 바인딩하는 형식으로 문자열을 반환합니다.

    실행🏃‍♂️


    로컬 웹 서버가 아닌 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-bindgenNode.jsbrowser 환경에 귀속 파일을 생성하는 옵션을 제공합니다.우리 그 깃발들을 좀 봅시다.--nodejs - 노드에만 적용되는 출력을 생성합니다.js.ESModules가 없습니다.--browser - ESModules가 있는 브라우저에만 사용할 수 있는 출력을 생성합니다.--no-modules - 브라우저에만 사용할 수 있는 출력을 생성합니다.ESModules가 없습니다.ESModules가 지원되지 않는 브라우저에서는 사용할 수 있습니다.--no-typescript 플래그를 사용하여 유형 정의 파일(*.d.ts)을 닫을 수 있습니다.
    만약 네가 이 글을 좋아한다면, 너는 내가 쓴 녹슨 것과 인터넷 조립에 관한 책을 좋아할 것이다.here 보기
    👇 되팔다👇

    센디르 쿠마르 / rustwasm 소개


    품질의 녹식과 복판 조립 - 안내


    흥미가 있고 탐색이 더 많아...


    사용자 정의 섹션에 대한 자세한 내용을 확인하십시오.here 보기
    웹 페이지 here에 대한 더 많은 정보 보기
    this편의 좋은 블로그 글을 보고 ECMAScript 모듈에 대한 더 많은 정보를 얻을 수 있습니다.
    너는 나를 따라와도 된다.
    만약 당신이 이 문장을 좋아한다면, 좋아하거나 평론을 남겨 주세요.❤️

    좋은 웹페이지 즐겨찾기