WebAssembly
WebAssembly (Wasm) 컴파일
Dart 팀은 웹용 Dart와 Flutter 앱을 빌드할 때 WebAssembly를 컴파일 대상으로 추가하게 되어 정말 기뻐요. WebAssembly 지원 개발은 여전히 계속 진행 중이라 자주 변경될 가능성이 있어요. 최신 업데이트는 이 페이지를 다시 확인해 주세요.
본문
참고 — Wasm 지원이 이제 stable 채널에 포함됐어요! Dart 웹용 WebAssembly 지원이 Dart stable 채널에서 제공되고 있답니다.
WebAssembly 지원
현재 Dart의 WebAssembly 컴파일은 몇 가지 제약이 있어요.
- Garbage Collection이 있는 WebAssembly(WasmGC)를 대상으로 하기 때문에, 현재 모든 브라우저가 지원되는 건 아니에요. 현재 지원되는 브라우저 목록은 Flutter 문서에서 확인할 수 있어요.
- 컴파일된 Wasm 출력물은 현재 JavaScript 환경(예: 브라우저)을 대상으로 해요. 그래서 wasmtime이나 wasmer 같은 표준 Wasm 런타임에서는 아직 실행을 지원하지 않아요. 자세한 내용은 issue #53884을 참고해 주세요.
- Wasm으로 컴파일할 때는 Dart의 차세대(next-gen) JS 상호 운용 메커니즘만 지원돼요.
- 현재
webdev도구에는 실행(webdev serve)이나 빌드(webdev build) 지원이 없어요. 아래 단계에 임시 해결책이 있으니 참고하세요. 자세한 내용은 webdev issue 2206을 확인해 주세요.
참고 — 기본적으로 컴파일된 애플리케이션은 지연 로딩(deferred loading)을 사용하지 않아요. Wasm에서는 지연 로딩이 실험적이고, 활성화하려면
--enable-deferred-loading플래그를 사용해 주세요.
$ dart compile wasm --enable-deferred-loading ...
지연 로딩을 활성화하면 앱 로더가 모듈 바이트를 로드하는 콜백을 제공해야 해요.
const app = await compileStreaming(...); // or compile(...)
const instantiatedApp = await app.instantiate({}, {
loadDeferredModules: (modules, handleModuleByteSource) => {
return Promise.all(
modules.map((m) => fetch(m).then((r) => handleModuleByteSource(m, r)))
);
},
});
instantiatedApp.invokeMain();
이 기능은 Dart 3.13 stable 릴리스부터 사용할 수 있어요.
지원되는 패키지
Wasm 호환 패키지를 찾으려면 pub.dev의 wasm-ready 필터를 사용해 주세요.
wasm-ready 패키지는 dart:html, dart:js 같은 Wasm 비준수 라이브러리를 임포트하지 않는 패키지예요. 허용되지 않는 라이브러리의 전체 목록은 JS interop 페이지에서 확인할 수 있어요.
웹 앱을 Wasm으로 컴파일하기
Dart와 Flutter에서 Wasm 컴파일러를 호출하는 지원이 dart CLI에 들어갔어요.
$ dart help compile wasm
Compile Dart to a WebAssembly/WasmGC module.
Usage: dart compile wasm [arguments] <dart entry point>
-h, --help Print this usage information.
-o, --output Write the output to <file name>.
This can be an absolute or relative path.
-v, --verbose Print debug output during compilation
--enable-asserts Enable assert statements.
--[no-]source-maps Generate a source map file.
(defaults to on)
-D, --define=<key=value> Define an environment declaration. To specify multiple declarations, use multiple
options or use commas to separate key-value pairs.
For example: dart compile wasm -Da=1,b=2 main.dart
Wasm 컴파일은 stable에서 사용 가능하지만 아직 preview 상태예요. 개발자 경험을 개선하기 위해 도구를 계속 최적화하는 동안, 여기 정리된 임시 단계를 따라 오늘 바로 Dart를 Wasm으로 컴파일해 볼 수 있어요.
- 웹 앱으로 시작하기:
dart create -t web mywebapp- 템플릿이
package:web을 사용하는 작은 웹 앱을 만들어요. Wasm을 실행하려면package:web이 필요하거든요. 웹 앱이dart:html에서package:web으로 마이그레이션되어 있는지 확인해 주세요.
- 템플릿이
- 새
site출력 디렉터리로 Wasm으로 컴파일하기:
$ dart compile wasm web/main.dart -o site/main.wasm
참고 — 기본적으로
dart compile wasm은.wasm출력물 옆에.wasm.map소스 맵 파일을 생성해요. 프로덕션 빌드에서 소스 맵 생성을 비활성화하려면--no-source-maps를 전달하세요. 소스 맵 배포 시 보안 고려 사항은 Web deployment를 참고해 주세요.
- 웹 파일 복사하기:
cp web/index.html web/styles.css site/ - Wasm 코드를 로드하는 JS 부트스트랩 파일 만들기:
- 새 파일
site/main.dart.js를 추가하고, 이main.dart.js샘플의 내용으로 채워 주세요.
- 새 파일
- 출력물 서빙하기:
dart pub global run dhttpd(문서)
여기서 이 작은 예제를 직접 시도해 볼 수도 있어요.
더 알아보기
- JS interop — Wasm에서 지원하는 차세대 JS 상호 운용과 허용되는 라이브러리 목록.
- Web deployment — 소스 맵 배포 시 고려 사항.
- Flutter 웹의 Wasm 지원 — 지원 브라우저 목록.