glslとThree.jsのためのesbuild + TypeScript環境を作る

基本的に自分の環境ではgulpが全てを動かしてるのですが、設定などはgulpを通さない場合も一緒だと思います。
インポートするパッケージ
- three
- @types/three
- esbuild-plugin-glsl
esbuildの設定
esbuildの設定で、pluginsにesbuild-plugin-glslを指定します。
自分の場合はgulpfile.jsにesbuildの設定を書いているのでそこにpluginsをプラスします。
ついでにテクスチャを読み込めるようにloaderも記述しました。
const {glsl} = require("esbuild-plugin-glsl");
const esbuild = () => {
return gulp.src(baseDir + '/js/app.js')
.pipe(gulpEsbuild({
bundle: true,
outfile: "bundle.js",
// 〜〜
// ここ追加
plugins: [glsl({
minify: true
})],
loader: {
'.jpg': 'dataurl',
'.png': 'dataurl',
'.svg': 'text'
},
// sourcemap: true,
}))
.pipe(gulp.dest(dist + '/js/'))
.pipe(browserSync.stream());
}
シェーダーの型ファイル
glslファイルをimport文でインポートする時に、型がないとエラーになります。
こちらを参考にして、TypeScriptの方ファイルを作っておきます。
https://www.npmjs.com/package/esbuild-plugin-glsl
shaders.d.tsというファイル名で下記記載したものをプロジェクトフォルダに入れました。
declare module "*.wgsl" {
const value: string;
export default value;
}
declare module "*.glsl" {
const value: string;
export default value;
}
declare module "*.frag" {
const value: string;
export default value;
}
declare module "*.vert" {
const value: string;
export default value;
}
このファイルは、tsconfig.jsonでパスを指定したりしなくても、
ルート以下のどこにあっても自動で探してくれます。
今回はtypesというフォルダを作ってその中に入れました。
テクスチャファイル読み込み時も型エラーになるので、その型も作ります。
declare module "*.jpg"
declare module "*.png"
おまけ(ちょっとした問題)
だいたいこれでバンドルできるようになったのですが、import時の「.glsl」や、特定の「.js」拡張子の省略はいろいろやってみてもできなかったのでそこは諦めました。
「OrbitControlsのimportで拡張子は「.js」まで書きます。
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
ちなみにesbuildの設定で「resolveExtensions」というプロパティがあり、ここで省略したい拡張子を指定することができます。
ただ、glslだけ指定すると、今まで省略できていたts拡張子が省略できなくなった(もともと暗黙で設定されてるものがあり、それがこのプロパティをいれることによりリセットされるっぽい)ので公式の通り暗黙のものも全ていれる必要があります。
これでglslの拡張子を省略できたりするかなと思ったのですが、TypeScriptでglslの拡張子がないとエラーになり、色々調べていくと、これはバグではなくポリシー的なものかもしれない…という結論になり、「resolveExtensions」も不採用となりました。