ViteでThree.jsのWebGPURendererが使えない
#Top-level_await #WebGPU #Three.js #Vite #苦難
🐟.icon Three.js r166現在
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();
╵ ~~~~~
即ち、「Top-level awaitを使える環境向けの設定ではないので、Top-level awaitやめるか設定変えてね」、ということ
エラーが出ているのは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 を参照するっぽい
https://github.com/vitejs/vite/issues/13756#issuecomment-1646981372
即ち、以下の設定
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 を指定することでこの問題は回避できる
See: https://discourse.threejs.org/t/r159-vite-modelnode-js-26-uncaught-typeerror-nodeimmutable-label-temp-is-not-a-function/58909
即ち、以下の設定で治った
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