웹어셈블리 - Node.js와 함께 작업하기
안녕하세요, 미래의 프로그래머 여러분! 오늘 우리는 웹어셈블리와 Node.js의 세계에 흥미로운 여정을 떠납니다. 이 용어들이 외계어 같게 들린다면 걱정하지 마세요 - 이 튜토리얼이 끝나면 여러분은 이를 자유자재로 사용할 수 있을 것입니다!
웹어셈블리는 무엇인가요?
웹어셈블리, 흔히 Wasm으로 줄인 것은 프로그래밍 세계의 슈퍼 헴으로 불립니다. C, C++, Rust와 같은 언어로 작성된 코드를 웹 브라우저에서 거의 네이티브 속도에 가깝게 실행할 수 있게 해주는 바이너리 지시 형식입니다. 브라우저 내에서 복잡한 3D 게임을 플레이할 수 있다고 상상해 보세요 - 이就是这样한 힘을 웹어셈블리가 제공해 줍니다!
Node.js의 이유는 무엇인가요?
이제 여러분은 "Node.js와 이 모든 것이 무엇이 관련이 있나요?"라고 물을 수도 있습니다. Node.js는 마법을 일으키는 무대 뒤의 크루와 같습니다. JavaScript 런타임으로, 브라우저 외부에서 JavaScript를 실행할 수 있게 해줍니다. 웹어셈블리와 Node.js를 결합하면 두 가지의 최고를 얻을 수 있습니다 - 웹어셈블리의 속도와 Node.js의 다재다능함.
우리의 환경을 설정하기
코드에 뛰어들기 전에, 우리의 작업 공간을 설정해보겠습니다. 걱정하지 마세요, 새 스마트폰을 설정하는 것보다 쉽습니다!
- 공식 웹사이트에서 Node.js를 설치하세요 (https://nodejs.org)
- 터미널이나 명령 프롬프트를 엽니다
- 우리 프로젝트를 위한 새 디렉토리를 만듭니다:
mkdir wasm-nodejs-tutorial cd wasm-nodejs-tutorial
- 새 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.wasm
과 add.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));
});
이를 하나씩 풀어보겠습니다:
- 우리는 필요한 Node.js 모듈을 임포트합니다:
fs
는 파일 시스템 연산을 위한 것이고,path
는 파일 경로를 다루기 위한 것입니다. - 우리는 웹어셈블리 파일을 버퍼에 읽어들입니다.
- 우리는
WebAssembly.instantiate()
를 사용하여 웹어셈블리 모듈을 로드하고 컴파일합니다. - 로드 후, 우리는
wasmModule.instance.exports._add
를 통해add
함수에 접근할 수 있습니다. - 마지막으로, 우리는 함수를 호출하고 결과를 로그합니다.
이 스크립트를 다음과 같이 실행합니다:
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