Vite를 통해 React를 개발하던 중 npm 라이브러리에서 `both async and sync fetching of the wasm failed` 에러가 발생할 때가 있습니다.
위와 같은 에러 발생 시 해결방법을 공유해 보도록 하겠습니다.
문제 발생 상황
모바일 애플리케이션을 만들던 중 비디오 녹화를 통해 `mp4-wasm` 이라는 패키지를 사용해야 할 상황이 발생하였습니다.
(참고 : https://www.npmjs.com/package/mp4-wasm)
위 라이브러리의 사용법은 간단한데요
import loadMP4Module, { isWebCodecsSupported } from 'https://unpkg.com/mp4-wasm@1.0.6'
이런 식으로 mp4Module 이라는 객체를 호출하여 현재 화면이나 Canvas를 mp4 파일로 저장할 수 있는 기능을 제공합니다.
하지만 외부 패키지 의존성이 있는 것이 좋지 않아 아래와 같이
import loadMP4Module, { isWebCodecsSupported } from 'mp4-wasm'
npm 방식으로 바꾼 후 해당 라이브러리를 사용하니
`both async and sync fetching of the wasm failed` 라는 메시지와 함께 wasm 에러가 나며 앱이 멈추었습니다.
이는 Vite에서 Wasm 기술을 사용하여 만들어진 패키지를 사용할 때 발생하는 에러인데, Wasm 파일이 컴포넌트에서 import가 될 때 비동기적으로 load 되지 않아서 발생한 문제로 보입니다.
해당 Wasm 문제를 해결하기 위해서는 `vite-plugin-wasm` 이라는 패키지를 사용해야 합니다.
vite-plugin-wasm
해당 vite 플러그인은 WebAssembly (WASM) 파일을 비동기적으로 로딩하고, 이를 Vite 빌드 시스템 내에서 ECMAScript Modules (ESM) 형태로 통합하는 기능을 추가하기 위한 패키지입니다.
해당 패키지를 이용하여 아래처럼 vite.config.js 를 수정해 줍니다.
- optimizeDeps 를 통해 mp4-wasm 패키지를 미리 번들링 합니다.
- wasm, topLevelAwait 플러그인을 설치합니다.
더 자세한 내용은 공식 npm 문서에 나와 있습니다.
위와 같이 설정을 한 뒤에 vite를 DEV 환경으로 실행시키면 해당 npm 패키지가 올바르게 동작하는 것을 확인할 수 있습니다.
+ 추가 문제상황 )
위 설정 이후에 DEV 환경에서만 동작하고 Production 빌드 시에는 wasm 패키지가 빌드 소스파일에 포함되지 않는 문제가 발생하였습니다. ( 해당 이슈 : https://github.com/Menci/vite-plugin-wasm/issues/57 )
일단 저의 경우에는 assetsInclude에 wasm 파일을 추가한 뒤 빌드 경로에 포함시켜서 빌드했더니 해결은 되었습니다.
더 좋은 방법이 있으면 다시 추가 해결방법에 대해 공유하도록 하겠습니다.