Deno, TypeScript, ESBuild, WebGL, VSCode
Hello! As the title suggests, I am using these technologies to create a web application:
* Deno
* TypeScript
* ESBuild
* WebGL (which uses .glsl shader files)
* VSCode
My goal is to have a .ts file be able to import a .glsl file as a string, and for there to be no errors or warnings about this in VSCode. This is a very common workflow for frontend development involving WebGL.
My understanding is that I need to create a modules.d.ts file at the root of my project that looks like so:
and then have Deno use it by having deno.json have a line like so:
I believe that this is all that should be needed to have any .ts file be able to import any .glsl as a string like so:
It appears that this actually works with ESBuild and the glsl plugin. However, in VSCode I am getting errors on the above import lines like so:
Module '"file:///<root path of my project>/fragmentShader.glsl"' has no default export
So what I am doing wrong here, and how can I get VSCode to be happy?20 Replies
https://docs.deno.com/runtime/manual/advanced/typescript/types#using-a-configuration-file
^ relevant docs for deno
Types and Type Declarations | Deno Docs
One of the design principles of Deno is no non-standard module resolution. When
hmmmm also when i do "deno check" i get this:
error: Expected a JavaScript or TypeScript module, but identified a Unknown module. Importing these types of modules is currently not supported.
You cannot do imports like that. The reason for which you do the
declare module …
is because under the hood, a bundler like webpack or rollup is used. Deno doesn't have those. One alternative is to just use Deno.readFile
and the likeOof, that is sad
Or just a .ts file with a single export
https://www.typescriptlang.org/play#example/typescript-with-webgl
deno_esbuild will love this simple string import.
https://github.com/esbuild/deno-esbuild
A deno_esbuild example from Hot-server: https://github.com/nhrones/Hot/blob/main/builder.ts usage:
A deno_esbuild example from Hot-server: https://github.com/nhrones/Hot/blob/main/builder.ts usage:
Yeah I currently have a .ts file with a single import of a string, but there’s a few sad things about this: 1) it treats glsl code as second class rather than first class, and more tangibly 2) it doesn’t allow syntax highlighting in vs code
Also Deno.readFile won’t work because this is for the front end. So I want the file contents in the bundle
Have you considered WebGPU and the WebGPU Shading Language? WGSL
It's now support in Deno https://deno.com/blog/v1.39
Hey nice! So I don’t have much experience with WebGPU but my understanding is that it gives more control at the cost of more complexity. So would def prefer WegGL
Good luck. I still think you can edit GLSL with a good extension, and then just save it as text in your build step!
Got it. I will play around with some things then and probably post back here with what I come up with, for posterity
hmm okay so im checking this out today. it appears that 1) webGPU is not widely supported yet (https://caniuse.com/webgpu) but likely will be soon and 2) even if it was, i would have the same problem with WGSL as i do with GLSL - so it doesnt really benefit me to use it
but from what i am reading, this comment does not seem to be true. the import setup i did was for the typescript compiler. it is a part of typescript itself.
issue from a long time ago that discusses this: https://github.com/Microsoft/TypeScript/issues/2709
GitHub
Importing files other than TS modules · Issue #2709 · microsoft/Typ...
I've successfully been using SystemJS and TypeScript for a while now. I've been about to use the CommonJS syntax to easily import other TS modules, as well as other resources: var OtherModu...
I believe somewhat soonish you'll be able to do:
That will then just read the file as plaintext and include it into the module graph.
Correct, we're working on these kind of imports
Oh that’s awesome! That would work great
Is there somewhere I could follow along on that progress?
The first PR is here https://github.com/denoland/deno_core/pull/402
GitHub
feat: Allow embedders to load custom module types by bartlomieju · ...
More generic solution than #344 and #357.
It allows embedders to load any module type they want.
Still some rough edges that need to be fixed. I will probably
split this PR into a few more.
Awesome, thanks!
hmmmmm okay i was going to ask why the plan is not to replicate how typescript does this as i discussed above, but i think im starting to get it.
in the non-deno case, there is a loader/bundler that takes all my TS and plaintext imports and handles the actual turning it into runnable JS code.
however in the deno case, TS is the native language, so it needs to be able to run the code without all this. so it cant simply say "this file will be a string" to satisfy the type system, it needs to know what particular string it will be.
is that getting at the right explanation?
until the new import method is available as you mentioned above, im leaning towards having a pre-build step that takes these two files im working in and generating a ts file that outputs the contents as a string. i think thatll do fine for a quick solution. and this is a small hobby project, so it doesnt need to be completely ideal
So basically
declare module *.foo
explains to the TypeScript compiler that you expect Someone (TSC doesn't care who) to convert imports pointing to imports of this style into whatever you declare in the declare declaration.
Because Deno handles transforming the code, Deno needs to be the "Someone" from above doing the transformation. But now Deno is both the loader doing the transformation AND the compiler doing the type checking. It doesn't make sense to do the declare *.foo
to tell Deno what the types of "*.foo" imports are PLUSA some other declaration to tell Deno that a particular import should be handled as a plaintext import.
It's simpler (at least from an implementation standpoint) to only provide the way to implement as plaintext and derive the type directly based on that. (Note that this is more general than the converse as now you can import eg. JS files as plaintext as well.)yeah yeah, exactly. okay that makes a ton of sense.
from a user perspective, i will still say that it is unfortunate that i would have to write
with { type: "string" }
after every GLSL (or CSS, or HTML, or whatever plaintext file i would use) import i do, instead of specify in one place that GLSL files should always be imported in this way.
for my use case this is totally fine, but just providing signal to you all for how i would anticipate larger projects would prefer to engage with this topicThe approach were taking plays nicely with other in-progress tc39 proposals and is completely in-bound solution in contrast to having some auxiliary files that need to tell how certain file have to be interpreted. Sure it's a few more keystrokes but give a lot more control and allow ecosystem to unify behind a single solution (import attributes)
That said, you can still use a pre build step if it fits your use case better!
ah got it, that adds more clarity for me! import attributes are new to me so i will look into them more. very much appreciate the responses and thoughtfulness you all take. thanks again!