compress-shader-literals 0.0.3 → 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,43 +1,97 @@
1
1
  # compress-shader-literals
2
2
 
3
- Local Vite plugin that minifies GLSL and WGSL shader strings at build time.
3
+ > **Size matters.** Strip everything strippable from your GLSL & WGSL shaders at build time.
4
4
 
5
- Strips block comments, line comments, and redundant whitespace from shader template literals. Runs as a `pre` transform so the result feeds into esbuild minification.
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
+ [![minzipped size](https://img.shields.io/bundlephobia/minzip/compress-shader-literals?color=success)](https://bundlephobia.com/package/compress-shader-literals)
7
+ [![npm downloads](https://img.shields.io/npm/dm/compress-shader-literals?color=success)](https://www.npmjs.com/package/compress-shader-literals)
8
+ [![license](https://img.shields.io/npm/l/compress-shader-literals?color=blue)](./LICENSE)
9
+
10
+ Smaller WebGL & WebGPU bundles for free — shrink your shaders at build time, in any bundler.
11
+
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 -->
32
+
33
+ ## Install
34
+
35
+ ```sh
36
+ npm i -D compress-shader-literals
37
+ # or: bun add -d compress-shader-literals
38
+ ```
6
39
 
7
40
  ## Usage
8
41
 
42
+ Pick your bundler — same plugin, same options:
43
+
9
44
  ```js
10
- // vite.config.js
11
- import { compressShaderLiterals } from './compress-shader-literals/plugin.js';
45
+ import { compressShaderLiterals } from 'compress-shader-literals';
12
46
 
13
- export default {
14
- plugins: [compressShaderLiterals.vite({ outputRatio: true })],
15
- };
47
+ // Vite vite.config.js
48
+ export default { plugins: [compressShaderLiterals.vite({ outputRatio: true })] };
49
+
50
+ // Rollup rollup.config.js → compressShaderLiterals.rollup({ ... })
51
+ // webpack webpack.config.js → compressShaderLiterals.webpack({ ... })
52
+ // esbuild build script → compressShaderLiterals.esbuild({ ... })
53
+ // Rspack / Rolldown / Farm → .rspack() / .rolldown() / .farm()
16
54
  ```
17
55
 
18
56
  ## Options
19
57
 
20
- | Option | Default | Description |
21
- | ------------- | ---------------------------- | ------------------------------ |
22
- | `tags` | `['glsl', 'wgsl', 'shader']` | Tag names to match |
23
- | `include` | `/\.[jt]sx?$/` | Files to process |
24
- | `exclude` | `/node_modules/`, `/dist/` | Files to skip |
25
- | `outputRatio` | `false` | Print size summary after build |
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
+ ---
26
66
 
27
- ## Supported syntax
67
+ ## What it compresses
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**.
28
70
 
29
71
  ```ts
30
72
  // Tagged template literal
31
- const vert = wgsl`void main() { ... }`;
73
+ const vert = glsl`
74
+ // vertex shader ← stripped
75
+ precision highp float;
76
+ void main() { gl_Position = vec4(0.0); }
77
+ `;
32
78
 
33
- // Comment-prefixed template literal
34
- const frag = /* glsl */ `void main() { ... }`;
79
+ // Comment-prefixed template literal (keeps editor syntax highlighting)
80
+ const frag = /* wgsl */ `
81
+ /* fragment */
82
+ fn main() {}
83
+ `;
35
84
  ```
36
85
 
37
- ## Test
86
+ Both collapse to a single tight line — no comments, no padding.
38
87
 
39
- ```sh
40
- node compress-shader-literals/run-test.js
41
- ```
88
+ ## How it works
89
+
90
+ 1. Parses each matched file with Babel (TS/JSX aware).
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**.
93
+ 4. Runs as a `pre` transform, so your bundler's own minifier still sees the result.
94
+
95
+ ## License
42
96
 
43
- Runs the transform against `src/core/shaders.ts` and prints bytes saved.
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.3",
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,9 +8,22 @@
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",
20
+ "three",
21
+ "threejs",
22
+ "ogl",
23
+ "react-three-fiber",
24
+ "shader-park",
25
+ "curtainsjs",
26
+ "shadertoy",
14
27
  "vite-plugin",
15
28
  "rollup-plugin",
16
29
  "webpack-plugin",
@@ -29,8 +42,10 @@
29
42
  },
30
43
  "main": "./dist/index.js",
31
44
  "module": "./dist/index.js",
45
+ "types": "./dist/index.d.ts",
32
46
  "exports": {
33
47
  ".": {
48
+ "types": "./dist/index.d.ts",
34
49
  "import": "./dist/index.js"
35
50
  }
36
51
  },
@@ -39,9 +54,12 @@
39
54
  ],
40
55
  "sideEffects": false,
41
56
  "scripts": {
42
- "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",
43
59
  "test": "bun test",
44
60
  "test:run": "bun test",
61
+ "test:validate": "cd tests && bun install && node validate.js",
62
+ "test:e2e": "cd tests && bun install && node e2e.js",
45
63
  "format": "prettier --write .",
46
64
  "format:check": "prettier --check .",
47
65
  "npm:deploy": "bash ./scripts/publish-npm.sh",
@@ -51,11 +69,13 @@
51
69
  "@babel/parser": "^8.0.0",
52
70
  "@babel/traverse": "^8.0.0",
53
71
  "@rollup/pluginutils": "^5.4.0",
72
+ "byte-snap": "^1.0.0",
54
73
  "magic-string": "^0.30.21",
55
74
  "unplugin": "^3.0.0"
56
75
  },
57
76
  "devDependencies": {
58
77
  "@trivago/prettier-plugin-sort-imports": "^5.0.0",
59
- "prettier": "^3.0.0"
78
+ "prettier": "^3.0.0",
79
+ "typescript": "^5.6.0"
60
80
  }
61
81
  }