웹어셈블리 - Node.js와 함께 작업하기

안녕하세요, 미래의 프로그래머 여러분! 오늘 우리는 웹어셈블리와 Node.js의 세계에 흥미로운 여정을 떠납니다. 이 용어들이 외계어 같게 들린다면 걱정하지 마세요 - 이 튜토리얼이 끝나면 여러분은 이를 자유자재로 사용할 수 있을 것입니다!

WebAssembly - Working with Nodejs

웹어셈블리는 무엇인가요?

웹어셈블리, 흔히 Wasm으로 줄인 것은 프로그래밍 세계의 슈퍼 헴으로 불립니다. C, C++, Rust와 같은 언어로 작성된 코드를 웹 브라우저에서 거의 네이티브 속도에 가깝게 실행할 수 있게 해주는 바이너리 지시 형식입니다. 브라우저 내에서 복잡한 3D 게임을 플레이할 수 있다고 상상해 보세요 - 이就是这样한 힘을 웹어셈블리가 제공해 줍니다!

Node.js의 이유는 무엇인가요?

이제 여러분은 "Node.js와 이 모든 것이 무엇이 관련이 있나요?"라고 물을 수도 있습니다. Node.js는 마법을 일으키는 무대 뒤의 크루와 같습니다. JavaScript 런타임으로, 브라우저 외부에서 JavaScript를 실행할 수 있게 해줍니다. 웹어셈블리와 Node.js를 결합하면 두 가지의 최고를 얻을 수 있습니다 - 웹어셈블리의 속도와 Node.js의 다재다능함.

우리의 환경을 설정하기

코드에 뛰어들기 전에, 우리의 작업 공간을 설정해보겠습니다. 걱정하지 마세요, 새 스마트폰을 설정하는 것보다 쉽습니다!

  1. 공식 웹사이트에서 Node.js를 설치하세요 (https://nodejs.org)
  2. 터미널이나 명령 프롬프트를 엽니다
  3. 우리 프로젝트를 위한 새 디렉토리를 만듭니다:
    mkdir wasm-nodejs-tutorial
    cd wasm-nodejs-tutorial
  4. 새 Node.js 프로젝트를 초기화합니다:
    npm init -y

좋아요! 이제 코드 작성을 시작할 준비가 되었습니다.

첫 번째 웹어셈블리 모듈

이제 두 수를 더하는 간단한 웹어셈블리 모듈을 만들어보겠습니다. 우리는 C로 작성하고 웹어셈블리로 컴파일할 것입니다.

단계 1: C 코드 작성

다음 내용을 포함하는 add.c 파일을 생성합니다:

#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
int add(int a, int b) {
return a + b;
}

이게 무엇인지 당황하지 마세요! 이를 하나씩 풀어보겠습니다:

  • #include <emscripten.h>는 Emscripten 라이브러리를 포함시키며, 이는 C를 웹어셈블리로 컴파일하는 데 도움을 줍니다.
  • EMSCRIPTEN_KEEPALIVE는 컴파일러에게 이 함수를 자바스크립트에서 접근할 수 있게 유지하도록 지시합니다.
  • int add(int a, int b)는 두 정수를 받아서 그 합을 반환하는 함수입니다.

단계 2: 웹어셈블리로 컴파일

이 C 코드를 웹어셈블리로 컴파일하려면 Emscripten을 설치해야 합니다. Emscripten 웹사이트(https://emscripten.org/docs/getting_started/downloads.html)의 설치 지침을 따라 설치합니다.

설치 후, 다음 명령어를 실행합니다:

emcc add.c -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -o add.js

이 명령어는 우리의 C 코드를 웹어셈블리로 컴파일하고 add.wasmadd.js 두 파일을 생성합니다.

Node.js에서 웹어셈블리 사용하기

이제 흥미로운 부분입니다 - 우리의 웹어셈블리 모듈을 Node.js에서 사용하는 것입니다!

다음 내용을 포함하는 index.js 파일을 생성합니다:

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

const wasmBuffer = fs.readFileSync(path.join(__dirname, 'add.wasm'));

WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
const add = wasmModule.instance.exports._add;
console.log('5 + 3 =', add(5, 3));
});

이를 하나씩 풀어보겠습니다:

  1. 우리는 필요한 Node.js 모듈을 임포트합니다: fs는 파일 시스템 연산을 위한 것이고, path는 파일 경로를 다루기 위한 것입니다.
  2. 우리는 웹어셈블리 파일을 버퍼에 읽어들입니다.
  3. 우리는 WebAssembly.instantiate()를 사용하여 웹어셈블리 모듈을 로드하고 컴파일합니다.
  4. 로드 후, 우리는 wasmModule.instance.exports._add를 통해 add 함수에 접근할 수 있습니다.
  5. 마지막으로, 우리는 함수를 호출하고 결과를 로그합니다.

이 스크립트를 다음과 같이 실행합니다:

node index.js

모든 것이 제대로 작동하면, 다음과 같은 결과를 볼 수 있을 것입니다: 5 + 3 = 8

축하합니다! 여러분은 Node.js에서 첫 번째 웹어셈블리 모듈을 실행했습니다!

성능 비교

이제 우리의 웹어셈블리 함수와 네이티브 자바스크립트 함수의 성능을 비교해보겠습니다.

index.js 파일에 다음을 추가합니다:

function jsAdd(a, b) {
return a + b;
}

const iterations = 1000000;

console.time('WebAssembly');
for (let i = 0; i < iterations; i++) {
add(5, 3);
}
console.timeEnd('WebAssembly');

console.time('JavaScript');
for (let i = 0; i < iterations; i++) {
jsAdd(5, 3);
}
console.timeEnd('JavaScript');

이 코드는 웹어셈블리와 자바스크립트 버전의 add 함수를 백만 번 실행하고 각각의 시간을 측정합니다.

스크립트를 다시 실행하면, 웹어셈블리 버전이 더 빠르다는 것을 확인할 수 있을 것입니다!

결론

우리는 웹어셈블리와 Node.js의 가능성을 겨우 표면에 긁어봤을 뿐입니다. 상상해 보세요 - C나 Rust로 작성된 복잡한 알고리즘, 게임 엔진, 아니면 전체 애플리케이션을 네이티브 속도에 가깝게 Node.js에서 실행할 수 있습니다!

코드를 배우는 것은 자전거 타는 것과 같습니다.처음에는 흔들릴 수 있지만, 연습을 하면 곧 달릴 수 있을 것입니다. 계속 실험하고 배우며, 가장 중요한 것은 즐기세요!

여기 우리가 사용한 주요 메서드를 요약한 표를 제공합니다:

메서드 설명
WebAssembly.instantiate() 웹어셈블리 모듈을 컴파일하고 인스턴스화합니다
fs.readFileSync() 파일을 동기식으로 읽습니다
path.join() 경로 세그먼트를 결합합니다
console.time() 타이머를 시작합니다
console.timeEnd() 타이머를 종료하고 시간을 로그합니다

미래의 웹어셈블리 마법사 여러분, 즐겁게 코딩하세요!

Credits: Image by storyset