ViteでThree.jsのWebGPURendererが使えない
Three.jsのWebGPURendererを試してみようとViteを使って雑にコードを書いてみたらいろいろハマった話 Top-level await
ビルド時、以下のエラーが発生した
code:ansi
✘ ERROR Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides) node_modules/.pnpm/three@0.157.0/node_modules/three/examples/jsm/capabilities/WebGPU.js:11:17:
11 │ const adapter = await navigator.gpu.requestAdapter();
╵ ~~~~~
エラーが出ているのはThree.jsのコード内、 /three/examples/jsm/capabilities/WebGPU.js
WebGPUをサポートしている環境はどうせTop-level awaitもサポートしとるだろということだろうか エラー文でちょっと調べてみたところ、 vite.config.ts を以下のように変えれば治るっぽい
code:vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
build: {
target: 'esnext',
},
});
これで治らない……
もうちょっと調べたところ、アプリケーションのコードと依存のコードで参照する設定が違うらしい
yarn dev のときは依存コードについては optimizeDeps.esbuildOptions.target を参照するっぽい
即ち、以下の設定
code:vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
build: {
target: 'esnext',
},
optimizeDeps: {
esbuildOptions: {
target: 'esnext', // Three.js uses top-level await
},
},
});
Code Chunking
ここまでやったところ、ViteのCode Chunkingが悪さをしているらしく、ランタイムで以下のエラーが発生した
code:ansi
Uncaught TypeError: nodeImmutable(...).label is not a function
at chunk-WOINWYRS.js?v=c7293a43:2467:71
optimizeDeps.exclude 🔗 に three を指定することでこの問題は回避できる 即ち、以下の設定で治った
optimizeDeps.esbuildOptions.target については、 three をViteの最適化を通さないようにするため、もう必要ない
code:vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
build: {
target: 'esnext',
},
optimizeDeps: {
exclude: [
'three', // to prevent Vite's code chunking which causes an error
],
},
});
Build Error
npm run build したところ、以下のエラーが発生した
code:ansi
$ tsc && vite build
error TS2688: Cannot find type definition file for 'stats.js'.
The file is in the program because:
Entry point for implicit type library 'stats.js'
error TS2688: Cannot find type definition file for 'webxr'.
The file is in the program because:
Entry point for implicit type library 'webxr'
Found 2 errors.
stats.js および webxr の型定義が参照できないとのこと
それぞれ、型定義を入れてやろう
$ npm i -D @types/@stats.js @types/webxr