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 CHANGED
@@ -1,15 +1,34 @@
1
1
  # compress-shader-literals
2
2
 
3
- > **Size matters.** Minify your GLSL & WGSL shader strings at build time — automatically, in any bundler.
3
+ > **Size matters.** Strip everything strippable from your GLSL & WGSL shaders at build time.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/compress-shader-literals?color=cb3837&logo=npm)](https://www.npmjs.com/package/compress-shader-literals)
6
6
  [![minzipped size](https://img.shields.io/bundlephobia/minzip/compress-shader-literals?color=success)](https://bundlephobia.com/package/compress-shader-literals)
7
7
  [![npm downloads](https://img.shields.io/npm/dm/compress-shader-literals?color=success)](https://www.npmjs.com/package/compress-shader-literals)
8
8
  [![license](https://img.shields.io/npm/l/compress-shader-literals?color=blue)](./LICENSE)
9
9
 
10
- Your shaders ship with every comment, indent, and blank line you wrote them with. This strips all of it block comments, line comments, redundant whitespace — from `glsl` / `wgsl` template literals, **before** your bundler minifies the rest. Smaller bundles, zero source changes, full sourcemaps.
10
+ Smaller WebGL & WebGPU bundles for freeshrink your shaders at build time, in any bundler.
11
11
 
12
- Built on [unplugin](https://github.com/unjs/unplugin), so it runs in **Vite, Rollup, webpack, esbuild, Rspack, Rolldown & Farm** from one package.
12
+ ![Alt Preview](./assets/preview.png)
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
- That's it. Shaders are compressed on the way through; everything else is untouched.
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 (great for editor syntax highlighting)
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
- both become a single tight line, no comments, no padding.
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 (see [What it compresses](#what-it-compresses)).
102
- 3. Strips comments + collapses whitespace, rewriting via [`magic-string`](https://github.com/Rich-Harris/magic-string) so **sourcemaps stay intact**.
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)
@@ -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
- const stats = { before: 0, after: 0, files: 0 };
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: resultCode,
98
+ code: ms.toString(),
120
99
  map: ms.generateMap({ hires: true, source: id })
121
100
  };
122
101
  },
123
102
  buildEnd() {
124
- if (options.outputRatio && stats.files > 0) {
125
- printRatio(stats.before, stats.after, stats.files);
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.4",
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
  }