compress-shader-literals 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -49
- package/dist/index.d.ts +23 -0
- package/dist/index.js +10 -31
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/package.json +15 -3
package/README.md
CHANGED
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
# compress-shader-literals
|
|
2
2
|
|
|
3
|
-
> **Size matters.**
|
|
3
|
+
> **Size matters.** Strip everything strippable from your GLSL & WGSL shaders at build time.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/compress-shader-literals)
|
|
6
6
|
[](https://bundlephobia.com/package/compress-shader-literals)
|
|
7
7
|
[](https://www.npmjs.com/package/compress-shader-literals)
|
|
8
8
|
[](./LICENSE)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Smaller WebGL & WebGPU bundles for free — shrink your shaders at build time, in any bundler.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
## Stats
|
|
15
|
+
|
|
16
|
+
Measured on the real shaders shipped by popular libraries:
|
|
17
|
+
|
|
18
|
+
<!-- STATS:START -->
|
|
19
|
+
|
|
20
|
+
| Package | Shaders | Before | After | Saved |
|
|
21
|
+
| --------------------- | ------: | --------: | --------: | --------: |
|
|
22
|
+
| `three` | 281 | 240,772 B | 203,428 B | **15.5%** |
|
|
23
|
+
| `@jayf0x/fluidity-js` | 9 | 9,524 B | 7,133 B | **25.1%** |
|
|
24
|
+
| `ogl` | 22 | 6,109 B | 5,335 B | **12.7%** |
|
|
25
|
+
| `shader-park-core` | 18 | 10,794 B | 9,033 B | **16.3%** |
|
|
26
|
+
| `curtainsjs` | 7 | 3,406 B | 2,563 B | **24.8%** |
|
|
27
|
+
| **Total** | 337 | 270,605 B | 227,492 B | **15.9%** |
|
|
28
|
+
|
|
29
|
+
_Auto-generated by [`tests/e2e.js`](tests/e2e.js) · packages [verified](tests/validate.js) loadable · 2026-06-23_
|
|
30
|
+
|
|
31
|
+
<!-- STATS:END -->
|
|
13
32
|
|
|
14
33
|
## Install
|
|
15
34
|
|
|
@@ -34,10 +53,21 @@ export default { plugins: [compressShaderLiterals.vite({ outputRatio: true })] }
|
|
|
34
53
|
// Rspack / Rolldown / Farm → .rspack() / .rolldown() / .farm()
|
|
35
54
|
```
|
|
36
55
|
|
|
37
|
-
|
|
56
|
+
## Options
|
|
57
|
+
|
|
58
|
+
| Option | Default | Description |
|
|
59
|
+
| ------------- | ---------------------------- | --------------------------------------- |
|
|
60
|
+
| `tags` | `['glsl', 'wgsl', 'shader']` | Tag names / comment markers to match |
|
|
61
|
+
| `include` | `[/\.[jt]sx?$/]` | Files to process |
|
|
62
|
+
| `exclude` | `[/node_modules/, /dist/]` | Files to skip |
|
|
63
|
+
| `outputRatio` | `false` | Print a bytes-saved summary after build |
|
|
64
|
+
|
|
65
|
+
---
|
|
38
66
|
|
|
39
67
|
## What it compresses
|
|
40
68
|
|
|
69
|
+
Comments, indentation, and blank lines — stripped from your `glsl` / `wgsl` literals before your bundler even runs. Zero source changes, full sourcemaps. One [unplugin](https://github.com/unjs/unplugin) covers **Vite, Rollup, webpack, esbuild, Rspack, Rolldown & Farm**.
|
|
70
|
+
|
|
41
71
|
```ts
|
|
42
72
|
// Tagged template literal
|
|
43
73
|
const vert = glsl`
|
|
@@ -46,62 +76,22 @@ const vert = glsl`
|
|
|
46
76
|
void main() { gl_Position = vec4(0.0); }
|
|
47
77
|
`;
|
|
48
78
|
|
|
49
|
-
// Comment-prefixed template literal (
|
|
79
|
+
// Comment-prefixed template literal (keeps editor syntax highlighting)
|
|
50
80
|
const frag = /* wgsl */ `
|
|
51
81
|
/* fragment */
|
|
52
82
|
fn main() {}
|
|
53
83
|
`;
|
|
54
84
|
```
|
|
55
85
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
## Options
|
|
59
|
-
|
|
60
|
-
| Option | Default | Description |
|
|
61
|
-
| ------------- | ---------------------------- | --------------------------------------- |
|
|
62
|
-
| `tags` | `['glsl', 'wgsl', 'shader']` | Tag names / comment markers to match |
|
|
63
|
-
| `include` | `[/\.[jt]sx?$/]` | Files to process |
|
|
64
|
-
| `exclude` | `[/node_modules/, /dist/]` | Files to skip |
|
|
65
|
-
| `outputRatio` | `false` | Print a bytes-saved summary after build |
|
|
66
|
-
|
|
67
|
-
With `outputRatio: true`:
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
compress-shader-literals
|
|
71
|
-
────────────────────────
|
|
72
|
-
215.00 B → 134.00 B
|
|
73
|
-
saved: 81.00 B (37.67% smaller)
|
|
74
|
-
shaders: 1
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Real-world stats
|
|
78
|
-
|
|
79
|
-
Run against the actual shaders shipped in **[three.js](https://www.npmjs.com/package/three)**, **[ogl](https://www.npmjs.com/package/ogl)**, **[shader-park-core](https://www.npmjs.com/package/shader-park-core)**, **[curtains.js](https://www.npmjs.com/package/curtainsjs)** and more — measured by this plugin's own engine ([`tests/e2e.js`](tests/e2e.js)):
|
|
80
|
-
|
|
81
|
-
<!-- STATS:START -->
|
|
82
|
-
|
|
83
|
-
| Package | Shaders | Before | After | Saved |
|
|
84
|
-
| --------------------- | ------: | --------: | --------: | --------: |
|
|
85
|
-
| `three` | 281 | 240,772 B | 203,428 B | **15.5%** |
|
|
86
|
-
| `@jayf0x/fluidity-js` | 9 | 9,524 B | 7,133 B | **25.1%** |
|
|
87
|
-
| `ogl` | 22 | 6,109 B | 5,335 B | **12.7%** |
|
|
88
|
-
| `shader-park-core` | 18 | 10,794 B | 9,033 B | **16.3%** |
|
|
89
|
-
| `curtainsjs` | 7 | 3,406 B | 2,563 B | **24.8%** |
|
|
90
|
-
| **Total** | 337 | 270,605 B | 227,492 B | **15.9%** |
|
|
91
|
-
|
|
92
|
-
_337 real shaders from 5 package(s), compressed by this plugin's engine._
|
|
93
|
-
|
|
94
|
-
<!-- STATS:END -->
|
|
95
|
-
|
|
96
|
-
Free bytes off code you already ship — no source changes. Marginal per shader, but it compounds across every shader in every bundle, and at infra scale even 1% is worth shipping.
|
|
86
|
+
Both collapse to a single tight line — no comments, no padding.
|
|
97
87
|
|
|
98
88
|
## How it works
|
|
99
89
|
|
|
100
90
|
1. Parses each matched file with Babel (TS/JSX aware).
|
|
101
|
-
2. Finds tagged and comment-prefixed shader literals
|
|
102
|
-
3. Strips comments + collapses whitespace
|
|
91
|
+
2. Finds tagged and comment-prefixed shader literals.
|
|
92
|
+
3. Strips comments + collapses whitespace via [`magic-string`](https://github.com/Rich-Harris/magic-string), so **sourcemaps stay intact**.
|
|
103
93
|
4. Runs as a `pre` transform, so your bundler's own minifier still sees the result.
|
|
104
94
|
|
|
105
95
|
## License
|
|
106
96
|
|
|
107
|
-
[MIT](./LICENSE) © jayF0x
|
|
97
|
+
[MIT](./LICENSE) © [jayF0x](https://github.com/jayf0x)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { UnpluginInstance } from 'unplugin';
|
|
2
|
+
|
|
3
|
+
/** A picomatch glob string, RegExp, or a list of them — matched against module ids. */
|
|
4
|
+
type FilterPattern = string | RegExp | ReadonlyArray<string | RegExp> | null;
|
|
5
|
+
|
|
6
|
+
export interface CompressShaderLiteralsOptions {
|
|
7
|
+
/** Tag names / comment markers to match. Default: `['glsl', 'wgsl', 'shader']` */
|
|
8
|
+
tags?: string[];
|
|
9
|
+
/** Files to process. Default: `[/\.[jt]sx?$/]` */
|
|
10
|
+
include?: FilterPattern;
|
|
11
|
+
/** Files to skip. Default: `[/node_modules/, /dist/]` */
|
|
12
|
+
exclude?: FilterPattern;
|
|
13
|
+
/** Print a bytes-saved summary after build. Default: `false` */
|
|
14
|
+
outputRatio?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Minify GLSL/WGSL shader template literals at build time.
|
|
19
|
+
*
|
|
20
|
+
* Universal plugin — call the bundler you use: `.vite()`, `.rollup()`,
|
|
21
|
+
* `.webpack()`, `.esbuild()`, `.rspack()`, `.rolldown()`, `.farm()`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const compressShaderLiterals: UnpluginInstance<CompressShaderLiteralsOptions | undefined, boolean>;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/plugin.js
|
|
2
2
|
import { createFilter } from "@rollup/pluginutils";
|
|
3
|
+
import { diff, snap } from "byte-snap";
|
|
3
4
|
import MagicString from "magic-string";
|
|
4
5
|
import { createUnplugin } from "unplugin";
|
|
5
6
|
|
|
@@ -62,31 +63,11 @@ function minifyShader(src) {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
// src/plugin.js
|
|
65
|
-
function fmtBytes(bytes) {
|
|
66
|
-
const units = ["B", "KB", "MB", "GB"];
|
|
67
|
-
let v = bytes;
|
|
68
|
-
let u = 0;
|
|
69
|
-
while (v >= 1024 && u < units.length - 1) {
|
|
70
|
-
v /= 1024;
|
|
71
|
-
u++;
|
|
72
|
-
}
|
|
73
|
-
return `${v.toFixed(2)} ${units[u]}`;
|
|
74
|
-
}
|
|
75
|
-
function printRatio(beforeBytes, afterBytes, files) {
|
|
76
|
-
const saved = beforeBytes - afterBytes;
|
|
77
|
-
const pct = beforeBytes === 0 ? 0 : saved / beforeBytes * 100;
|
|
78
|
-
console.log(`
|
|
79
|
-
compress-shader-literals`);
|
|
80
|
-
console.log("────────────────────────");
|
|
81
|
-
console.log(`${fmtBytes(beforeBytes)} → ${fmtBytes(afterBytes)}`);
|
|
82
|
-
console.log(`saved: ${fmtBytes(saved)} (${pct.toFixed(2)}% smaller)`);
|
|
83
|
-
console.log(`shaders: ${files}
|
|
84
|
-
`);
|
|
85
|
-
}
|
|
86
66
|
var compressShaderLiterals = createUnplugin((options = {}) => {
|
|
87
67
|
const tags = options.tags || ["glsl", "wgsl", "shader"];
|
|
88
68
|
const filter = createFilter(options.include || [/\.[jt]sx?$/], options.exclude || [/node_modules/, /dist/]);
|
|
89
|
-
|
|
69
|
+
let beforeText = "";
|
|
70
|
+
let afterText = "";
|
|
90
71
|
return {
|
|
91
72
|
name: "compress-shader-literals",
|
|
92
73
|
enforce: "pre",
|
|
@@ -106,23 +87,21 @@ var compressShaderLiterals = createUnplugin((options = {}) => {
|
|
|
106
87
|
ms.overwrite(literal.start, literal.end, `\`${minified}\``);
|
|
107
88
|
hasChanges = true;
|
|
108
89
|
}
|
|
90
|
+
if (options.outputRatio) {
|
|
91
|
+
beforeText += literal.value;
|
|
92
|
+
afterText += minified;
|
|
93
|
+
}
|
|
109
94
|
}
|
|
110
95
|
if (!hasChanges)
|
|
111
96
|
return null;
|
|
112
|
-
const resultCode = ms.toString();
|
|
113
|
-
if (options.outputRatio) {
|
|
114
|
-
stats.before += Buffer.byteLength(code);
|
|
115
|
-
stats.after += Buffer.byteLength(resultCode);
|
|
116
|
-
stats.files += 1;
|
|
117
|
-
}
|
|
118
97
|
return {
|
|
119
|
-
code:
|
|
98
|
+
code: ms.toString(),
|
|
120
99
|
map: ms.generateMap({ hires: true, source: id })
|
|
121
100
|
};
|
|
122
101
|
},
|
|
123
102
|
buildEnd() {
|
|
124
|
-
if (options.outputRatio &&
|
|
125
|
-
|
|
103
|
+
if (options.outputRatio && beforeText) {
|
|
104
|
+
diff(snap.text(beforeText), snap.text(afterText)).print();
|
|
126
105
|
}
|
|
127
106
|
}
|
|
128
107
|
};
|
package/dist/index.js.br
CHANGED
|
Binary file
|
package/dist/index.js.gz
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compress-shader-literals",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Size matters. Minify GLSL/WGSL shader template literals at build time — universal plugin for Vite, Rollup, webpack, esbuild & more.",
|
|
6
6
|
"keywords": [
|
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
"glsl",
|
|
9
9
|
"wgsl",
|
|
10
10
|
"minify",
|
|
11
|
+
"minification",
|
|
11
12
|
"compress",
|
|
13
|
+
"compression",
|
|
14
|
+
"bundle-size",
|
|
15
|
+
"optimization",
|
|
16
|
+
"code-size",
|
|
17
|
+
"typescript",
|
|
12
18
|
"webgl",
|
|
13
19
|
"webgpu",
|
|
14
20
|
"three",
|
|
@@ -36,8 +42,10 @@
|
|
|
36
42
|
},
|
|
37
43
|
"main": "./dist/index.js",
|
|
38
44
|
"module": "./dist/index.js",
|
|
45
|
+
"types": "./dist/index.d.ts",
|
|
39
46
|
"exports": {
|
|
40
47
|
".": {
|
|
48
|
+
"types": "./dist/index.d.ts",
|
|
41
49
|
"import": "./dist/index.js"
|
|
42
50
|
}
|
|
43
51
|
},
|
|
@@ -46,9 +54,11 @@
|
|
|
46
54
|
],
|
|
47
55
|
"sideEffects": false,
|
|
48
56
|
"scripts": {
|
|
49
|
-
"build": "bun build src/plugin.js --outdir dist --entry-naming index.js --target node --format esm --external @babel/parser --external @babel/traverse --external @rollup/pluginutils --external magic-string --external unplugin && node scripts/compress-dist.js",
|
|
57
|
+
"build": "bun build src/plugin.js --outdir dist --entry-naming index.js --target node --format esm --external @babel/parser --external @babel/traverse --external @rollup/pluginutils --external byte-snap --external magic-string --external unplugin && cp src/index.d.ts dist/index.d.ts && node scripts/compress-dist.js",
|
|
58
|
+
"typecheck": "tsc --noEmit --strict --skipLibCheck src/index.d.ts",
|
|
50
59
|
"test": "bun test",
|
|
51
60
|
"test:run": "bun test",
|
|
61
|
+
"test:validate": "cd tests && bun install && node validate.js",
|
|
52
62
|
"test:e2e": "cd tests && bun install && node e2e.js",
|
|
53
63
|
"format": "prettier --write .",
|
|
54
64
|
"format:check": "prettier --check .",
|
|
@@ -59,11 +69,13 @@
|
|
|
59
69
|
"@babel/parser": "^8.0.0",
|
|
60
70
|
"@babel/traverse": "^8.0.0",
|
|
61
71
|
"@rollup/pluginutils": "^5.4.0",
|
|
72
|
+
"byte-snap": "^1.0.0",
|
|
62
73
|
"magic-string": "^0.30.21",
|
|
63
74
|
"unplugin": "^3.0.0"
|
|
64
75
|
},
|
|
65
76
|
"devDependencies": {
|
|
66
77
|
"@trivago/prettier-plugin-sort-imports": "^5.0.0",
|
|
67
|
-
"prettier": "^3.0.0"
|
|
78
|
+
"prettier": "^3.0.0",
|
|
79
|
+
"typescript": "^5.6.0"
|
|
68
80
|
}
|
|
69
81
|
}
|