Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
glsl-shader-loader
✓ loader: 'glsl-shader-loader'
✗ loader: require('glsl-shader-loader')
This is how the loader is referenced and configured within your `webpack.config.js` file, not a direct JavaScript import.
ShaderModule
✓ import fragmentShaderSource from './fragmentShaderSource.glsl';
✗ const fragmentShaderSource = require('./fragmentShaderSource.glsl');
After configuring the loader in Webpack, `.glsl` files can be imported into JavaScript/TypeScript as strings, representing the processed shader source. The CJS `require` might work with specific Webpack configs, but ESM `import` is more idiomatic.
GLSLFunctionImport
✓ #pragma loader: import { functionName } from './file.glsl';
✗ import { functionName } from './file.glsl';
This is a special directive used *within GLSL files* to import functions from other GLSL files. It is not a JavaScript `import` statement but a preprocessor command processed by the loader.
This quickstart demonstrates how to configure glsl-shader-loader in Webpack to process `.glsl` files, including internal GLSL `#pragma loader: import` statements, and then import the resulting shader string into a JavaScript application.
import path from 'path';
import webpack from 'webpack';
import MemoryFS from 'memory-fs';
// Basic webpack config to use glsl-shader-loader
const config = {
mode: 'development',
entry: './app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.(frag|vert|glsl)$/,
use: [
{
loader: 'glsl-shader-loader',
options: {
// Optional: specify a root path for absolute GLSL imports
// root: path.resolve(__dirname, 'src/shaders')
}
}
]
}
]
}
};
// Example application JS (app.js)
const appJsContent = `
import fragmentShaderSource from './fragmentShaderSource.glsl';
console.log('--- Compiled Fragment Shader Source ---');
console.log(fragmentShaderSource);
// In a real WebGL app, you'd use:
// const gl = canvas.getContext('webgl');
// const shader = gl.createShader(gl.FRAGMENT_SHADER);
// gl.shaderSource(shader, fragmentShaderSource);
// gl.compileShader(shader);
`;
// Example GLSL file (fragmentShaderSource.glsl)
const fragmentShaderContent = `
precision mediump float;
varying vec2 v_texCoord;
#pragma loader: import { randomColor } from './utils.glsl';
void main() {
vec3 color = randomColor(v_texCoord);
gl_FragColor = vec4(color, 1.0);
}
`;
// Example GLSL utility file (utils.glsl)
const utilsGlslContent = `
vec3 randomColor(vec2 coord) {
// Simple pseudo-random color based on coordinates
float r = fract(sin(dot(coord.xy, vec2(12.9898, 78.233))) * 43758.5453);
float g = fract(sin(dot(coord.xy, vec2(53.123, 19.345))) * 53758.9876);
float b = fract(sin(dot(coord.xy, vec2(87.654, 34.567))) * 63758.1234);
return vec3(r, g, b);
}
vec3 anotherFunction() {
return vec3(0.0);
}
`;
// Setup an in-memory file system for webpack to read from
const fs = new MemoryFS();
fs.mkdirpSync(path.resolve(__dirname, 'dist'));
fs.mkdirpSync(path.resolve(__dirname, 'src'));
fs.mkdirpSync(path.resolve(__dirname, 'utils'));
fs.writeFileSync('./app.js', appJsContent);
fs.writeFileSync('./fragmentShaderSource.glsl', fragmentShaderContent);
fs.writeFileSync('./utils.glsl', utilsGlslContent);
const compiler = webpack(config);
compiler.inputFileSystem = fs;
compiler.outputFileSystem = fs;
compiler.run((err, stats) => {
if (err) {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
return;
}
const info = stats.toJson();
if (stats.hasErrors()) {
console.error(info.errors);
}
if (stats.hasWarnings()) {
console.warn(info.warnings);
}
console.log('\nWebpack build completed.');
const bundlePath = path.resolve(__dirname, 'dist', 'bundle.js');
const bundleContent = fs.readFileSync(bundlePath, 'utf8');
// In a real scenario, you'd typically serve this bundle or inject it.
// For this quickstart, we'll just show the generated content.
// To demonstrate the *processed* GLSL, we'd need to run the bundle
// which is outside the scope of this quickstart directly.
// The console.log in app.js inside the bundle would show the processed shader.
});
Errors
Common errors & fixes
Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
Webpack is trying to parse a `.glsl` file as a standard JavaScript module because glsl-shader-loader is not correctly configured or applied.
fixAdd or verify the `glsl-shader-loader` configuration in your `webpack.config.js` under `module.rules`, ensuring the `test` regex matches your GLSL file extensions (e.g., `test: /\.(frag|vert|glsl)$/`).
Error: Can't resolve './file.glsl' in 'path/to/shader/'
The `#pragma loader: import` path within a `.glsl` file is incorrect or cannot be resolved by the loader.
fixDouble-check the relative path specified in the `#pragma loader: import` statement. If using the `root` option in the loader configuration, ensure absolute paths starting with `/` correctly map to your specified root directory.
SyntaxError: Unexpected identifier 'functionName'
Attempting to use a standard JavaScript `import` statement for a GLSL file directly, or incorrect syntax within the GLSL `#pragma` directive.
fixEnsure you are using `import myShaderSource from './myShader.glsl'` in your JavaScript files, and `glsl-shader-loader` is configured. Within GLSL files, strictly use `#pragma loader: import { functionName } from './file.glsl';` for function imports. Audit
Dependencies
webpackrequiredThis package is a Webpack loader and requires Webpack for its functionality.