I've had enough experience with deploying GLSL on many Android devices and also WebGL to be disillusioned with it. There's no great modern textual shading language out there, GLSL is missing a lot of modern niceities, HLSL isn't really an "independent language" (could talk more about that), and Apple's WHLSL/WSL proposal is drastically underspec'd to the point of hilarity.
I think if you want to compile shaders from source, you are free to include your favorite transpiler as WebAssembly, like glslang. That's currently what I'm doing for my WebGPU prototype project.
Generic types are probably one of the biggest ones. GLSL has generic builtins, but you can't define your own. But besides that, HLSL's support and management of buffers and bindings is a great deal saner than GLSL's. Especially the new syntax for loading structures from a ByteAddressBuffer. Beats the craziness that is SSBOs and image load/store.
GLSL's upbringing with integrated texture/samplers is a bit ridiculous in a separable texture/sampler world, like in Vulkan. You need to create an integrated texture/sampler with the sampler2D constructor, and then immediately use it. The GLSL spec specifically says you can't pass it to your own user-created functions, I'm guessing because they didn't trust platform vendors to write working compilers?
You also can't put any binding object like texture2D in a struct, even though you can pass it between functions? The whole enterprise really feels like it was limitations in baby's-first-compiler that added a bunch of weird restrictions.
HLSL is a C++-esque derivative that supports quite a bit more functionality than you probably imagine, and a lot less of the goofy limitations, given that it has a single compiler stack made by a company with competent compiler engineers.
I think if you want to compile shaders from source, you are free to include your favorite transpiler as WebAssembly, like glslang. That's currently what I'm doing for my WebGPU prototype project.