60초 이내에 WebAssembly를 사용하여 Go 지원으로 반응 앱을 만드는 방법

WebAssembly를 사용하여 react 및 Typescript로 브라우저에서 Go 실행

TL; DR

$ npx create-react-app my-app --template typescript-golang


왜 create-react-app인가?



create-react-app를 사용하면 최신 반응 앱(Webpack, Babel, ESlint 등)을 만드는 데 필요한 핵심 인프라 위에 추상화 수준을 제공하여 반응 애플리케이션을 부트스트랩하는 데 필요한 상용구를 빠르게 생성할 수 있습니다.

Go를 포함하는 이유는 무엇입니까?



Go은 Google에서 설계한 정적으로 유형이 지정되고 컴파일된 프로그래밍 언어이며 구문적으로는 C와 유사하지만 메모리 안전, 가비지 수집, 구조적 유형 지정 및 CSP-style concurrency이 있습니다.
제 경우에는 Go for JSON schema validations 를 실행해야 했습니다. 다른 경우에는 CPU 집약적인 작업을 수행하거나 CLI tool written in Go 을 사용할 수 있습니다.

그러나 WebAssembly는 모든 브라우저에서 지원되지 않습니다!



나도 그렇게 생각했다. 실제로는 2017년 11월부터 WebAssembly is supported in all major browsers . 따라서 Internet Explorer을 지원할 필요가 없는 한 걱정할 것이 없습니다.


사업을 시작합시다 😎



먼저 완전히 새로운 create-react-app 프로젝트를 초기화하세요. 절대 야만인이 아니라고 가정하고 Typescript 템플릿을 사용하세요 😇

$ npx create-react-app my-app --template typescript


다음으로/src/LoadWasm 아래에 폴더를 만듭니다.

$ cd my-app
$ mkdir ./src/LoadWasm`


Window 유형 선언을 확장할 파일을 생성합니다. 곧 사용할 것입니다.
/src/LoadWasm/wasmTypes.d.ts

declare global {
  export interface Window {
    Go: any;
    myGolangFunction: (num1: number, num2: number) => number
  }
}

export {};


WebAssembly 코드를 브라우저에 로드하는 데 사용되는 파일을 복사하면 전역 창 개체에 Go 속성이 추가되고 Javascript와 WebAssembly 사이의 브리지 역할을 합니다.

이 파일은 the one from the official Go repository 과 유사하며 몇 가지 사소한 조정만 있으면 다음 섹션에서 사용할 것입니다.

$ curl https://raw.githubusercontent.com/royhadad/cra-template-typescript-golang/main/template/src/LoadWasm/wasm_exec.js > ./src/LoadWasm/wasm_exec.js`


다음으로 전체 애플리케이션을 래핑하고 WebAssembly가 로드될 때까지 기다리는 래퍼 구성 요소를 만듭니다. 이것은 성능 목적을 위해 최적화될 수 있지만 단순함을 위해 지금은 충분합니다.
/src/LoadWasm/index.tsx

import './wasm_exec.js';
import './wasmTypes.d.ts';

import React, { useEffect } from 'react';

async function loadWasm(): Promise<void> {
  const goWasm = new window.Go();
  const result = await WebAssembly.instantiateStreaming(fetch('main.wasm'), goWasm.importObject);
  goWasm.run(result.instance);
}

export const LoadWasm: React.FC<React.PropsWithChildren<{}>> = (props) => {
  const [isLoading, setIsLoading] = React.useState(true);

  useEffect(() => {
    loadWasm().then(() => {
      setIsLoading(false);
    });
  }, []);

  if (isLoading) {
    return (
      <div>
        loading WebAssembly...
      </div>
    );
  } else {
    return <React.Fragment>{props.children}</React.Fragment>;
  }
};


마지막으로 LoadWasm 구성 요소로 전체 응용 프로그램을 래핑합니다. 이렇게 하면 WebAssembly가 로드되기 전에 다른 구성 요소가 로드되지 않습니다.
/src/index.tsx

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <LoadWasm>
      <App />
    </LoadWasm>
  </React.StrictMode>
);


하지만 Go 코드는 어디에 있습니까?



Go 모듈 초기화로 시작

$ mkdir ./wasm
$ cd ./wasm
$ go mod init wasm
$ go mod tidy
$ touch ./main.go
$ cd ..


이제 syscall/js package을 사용하여 javascript 전역 범위에 액세스하고 함수를 설정합니다.
둘째, Go 코드가 종료되지 않도록 약간의 핵을 구현할 것입니다. 채널을 열고 사용하지 않고 완료될 때까지 기다립니다 😈
이렇게 하면 매번 다시 인스턴스화할 필요 없이 Go 코드와 지속적으로 통신할 수 있습니다.

/wasm/main.go

package main

import (
   "syscall/js"
)

func myGolangFunction() js.Func {
   return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
      return args[0].Int() + args[1].Int()
   })
}

func main() {
   ch := make(chan struct{}, 0)
   js.Global().Set("myGolangFunction", myGolangFunction())
   <-ch
}


참고: WebAssembly를 지원하도록 IDE를 구성해야 할 수도 있습니다. VS Code guide , Intellij guide을 참조하십시오.

이제 이 버튼을 애플리케이션 어딘가에 추가할 수 있습니다. 아마도 App.tsx일 것입니다.

<button onClick={() => { alert(window.myGolangFunction(2, 3)); }}>
  Click here to invoke WebAssembly!
</button>


함께 모아서



마지막으로 webAssembly의 빌드 및 핫 리로드를 지원하도록 package.json 스크립트를 변경합니다.

짓다:




"build": "npm run build:wasm && npm run build:ts",
"build:ts": "react-scripts build",
"build:wasm": "cd wasm && GOOS=js GOARCH=wasm go build -o ../public/main.wasm && cd .. && echo \"compiled wasm successfully!\""


핫 리로드



몇 가지 종속성이 필요합니다.

$ npm install watch concurrently --save-dev


시작 스크립트에서 사용하십시오.

"start": "concurrently \"npm run watch:ts\" \"npm run watch:wasm\"",
"watch:ts": "react-scripts start",
"watch:wasm": "watch \"npm run build:wasm\" ./wasm",


마지막으로 npm start를 실행하고 앱에 액세스합니다localhost:3000.
전체 예제는 this GitHub repository에서 찾을 수 있습니다.

60초 걸린다고 하지 않았어? 거짓말쟁이!





좋습니다. 시간이 좀 걸릴 수 있지만 더 이상 두려워하지 마세요! 당신의 게으름에 대한 치료법이 있습니다!
custom create-react-app template for typescript-golang을 생성했습니다. 작업 디렉토리에서 다음 명령을 실행하기만 하면 됩니다.

$ npx create-react-app my-app --template typescript-golang


그리고… 쾅! Typescript 및 Go를 지원하는 작동하는 반응 앱으로 바로 코딩을 시작할 수 있습니다 🥳

Github &을(를) 통해 팔로우하고 연결하세요.

좋은 웹페이지 즐겨찾기