1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Three.jsのWebGPURendererをVite環境で使えない問題を解決する

Posted at

環境について

Vite 5.4.0
Three.js r167
(↑three.webgpu.jsthree.webgpu.min.js のビルドが追加されたバージョン)
https://github.com/mrdoob/three.js/releases

遭遇した問題

Vite環境にて、Three.jsで WebGPURenderer を使用した際に、以下のエラー文に遭遇しました。

スクリーンショット 2024-08-12 17.51.28.png

 [ERROR] Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides)

    node_modules/three/build/three.webgpu.js:36252:15:
      36252 │   isAvailable = await navigator.gpu.requestAdapter();

WebGPURenderer のインスタンスを生成した際のコードを以下に抜粋します。

import * as THREE from "three";
import { WebGPURenderer } from "three/webgpu";

const renderer = new WebGPURenderer({
  canvas: document.querySelector('#myCanvas')
});

WebGPUを実際にガッツリ活用する際には WebGPURenderer のみをインポートすることはないだろうけど、サンプルということでご容赦を。

解決した方法

vite.config.js に以下を記述することで解決しました。

import { defineConfig } from 'vite'

export default defineConfig({
    build: {
        target: 'esnext',
    },
    optimizeDeps: {
        esbuildOptions: {
            target: 'esnext',
        },
    },
});

TypeScript環境の方は、他にもランタイムやビルド時にエラーが起きるそうです。
以下を参照。
https://scrapbox.io/0b5vr/Vite%E3%81%A7Three.js%E3%81%AEWebGPURenderer%E3%81%8C%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84

本題はここまで。

(補足1) Top-level await について

スクリーンショット 2024-08-12 17.51.28.png

エラー文に出現していた Top-level await についての解説です。

Top-level await は新しい機能(ES2022 で導入)であり、await 式が async 関数の外側で使えるようになる機能です。
詳しくは以下のリンクを参照。
https://www.tohoho-web.com/ex/es2022.html#top-level-await

WebGPURenderer の実装に、Top-level await が使われていましたが、Viteのデフォルト設定だと、ビルドターゲット環境がES2022に対応したものではありませんでした。

そこで、 vite.config.js を編集して、ビルドターゲットを変更してあげる必要があったわけです。

(補足2) Vite の defineConfig について

import { defineConfig } from 'vite'

export default defineConfig({
    build: {
        target: 'esnext',
    },
    optimizeDeps: {
        esbuildOptions: {
            target: 'esnext',
        },
    },
});

defineConfig はIDEに自動補完を提供してくれます。
以下にVSCode環境における、自動補完表示の例を示します。

スクリーンショット 2024-08-12 18.53.03.png
↑こちらは defineConfig を使わない場合に、 build.target のところをマウスホバーした際の表示。型表示のみ。

スクリーンショット 2024-08-12 18.53.37.png
↑こちらは defineConfig を使った場合に、 build.target のところをマウスホバーした際の表示。プロパティに関する詳細情報が記述される。

TypeScript環境の場合は、別の方法で自動補完を利用することが可能なので、詳しくはViteの公式ドキュメントを参照。
https://ja.vitejs.dev/config/

(補足3) Vite のビルドオプションについて

build.target のプロパティには、 esnext という値があります。
これはネイディブの動的インポートをサポートしていることを前提としており、トランスパイルが可能な限り少なくなります。
具体的には、ミニフィケーションの互換性を担保するトランスパイルのみを実行するようです。
デフォルトは modules という値が設定されており、 ES2022 を想定しないブラウザでの利用を想定したトランスパイルになります。

なぜ esnext に設定しているのが、 build.target だけではなく、 optimizeDeps.esbuildOptions.target にもあるのかは、こちらのViteのIssueを参照。

(補足4) Vite のビルドターゲットを変えずに Top-level await をサポートする方法

このプラグインを使いましょう。
READMEを参照。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?