compress-shader-literals 0.0.8 → 1.0.0

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
@@ -22,13 +22,13 @@ Measured on the real shaders shipped by popular libraries:
22
22
  | Package | Shaders | Before | After | Saved |
23
23
  | --------------------- | ------: | --------: | --------: | --------: |
24
24
  | `three` | 281 | 240,772 B | 203,428 B | **15.5%** |
25
- | `@jayf0x/fluidity-js` | 9 | 9,524 B | 7,133 B | **25.1%** |
25
+ | `@jayf0x/fluidity-js` | 9 | 11,095 B | 7,788 B | **29.8%** |
26
26
  | `ogl` | 22 | 6,109 B | 5,335 B | **12.7%** |
27
27
  | `shader-park-core` | 18 | 10,794 B | 9,033 B | **16.3%** |
28
28
  | `curtainsjs` | 7 | 3,406 B | 2,563 B | **24.8%** |
29
- | **Total** | 337 | 270,605 B | 227,492 B | **15.9%** |
29
+ | **Total** | 337 | 272,176 B | 228,147 B | **16.2%** |
30
30
 
31
- _Auto-generated by [`tests/e2e.js`](tests/e2e.js) · packages [verified](tests/validate.js) loadable · 2026-06-24_
31
+ _Auto-generated by [`tests/e2e.js`](tests/e2e.js) · packages [verified](tests/validate.js) loadable · 2026-06-27_
32
32
 
33
33
  <!-- STATS:END -->
34
34
 
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("@rollup/pluginutils"),l=require("byte-snap"),u=require("magic-string");u=s(u,1);let d=require("unplugin"),f=require("@babel/parser"),p=require("@babel/traverse");p=s(p,1);var m=[`glsl`,`wgsl`,`shader`],h=[/\.[jt]sx?$/],g=[/node_modules/,/dist/],_=e=>RegExp(`^\\s*(${e.join(`|`)})\\s*$`),v=p.default.default||p.default,y=(e,t=m)=>{let n=new Set(t),r=_(t),i=[];try{v((0,f.parse)(e,{sourceType:`module`,plugins:[`typescript`,`jsx`,`decorators-legacy`],allowReturnOutsideFunction:!0}),{TaggedTemplateExpression(e){let{tag:t,quasi:r}=e.node,a=null;t.type===`Identifier`&&n.has(t.name)?a=t.name:t.type===`MemberExpression`&&t.property.type===`Identifier`&&n.has(t.property.name)&&(a=t.property.name),a&&i.push({tag:a,value:r.quasis.map(e=>e.value.raw).join(``),start:r.start,end:r.end})},TemplateLiteral(e){let t=e.node,n=t.leadingComments||e.parentPath?.node?.leadingComments||[];for(let e of n){if(!e||e.type!==`CommentBlock`)continue;let n=e.value.match(r);if(n){i.push({tag:n[1],value:t.quasis.map(e=>e.value.raw).join(``),start:t.start,end:t.end});break}}}})}catch(e){if(e.name!==`SyntaxError`)throw e}return i},b=e=>e.replace(/\/\*[\s\S]*?\*\//g,``).replace(/\/\/.*$/gm,``).replace(/[ \t]+/g,` `).replace(/\n{2,}/g,`
2
+ `).trim(),x=(0,d.createUnplugin)((e={})=>{let t=e.tags||m,n=e.transform||b,r=(0,c.createFilter)(e.include||h,e.exclude||g),i=``,a=``;return{name:`compress-shader-literals`,enforce:`pre`,transform(o,s){if(!r(s)||!t.some(e=>o.includes(e)))return null;let c=y(o,t);if(c.length===0)return null;e.debug&&console.log(`[compress-shader-literals] ${s}: ${c.length} literal(s) — ${c.map(e=>e.tag).join(`, `)}`);let l=new u.default(o),d=!1;for(let t of c){let r=n(t.value);t.value!==r&&(l.overwrite(t.start,t.end,`\`${r}\``),d=!0),e.outputRatio&&(i+=t.value,a+=r)}return d?{code:l.toString(),map:l.generateMap({hires:!0,source:s})}:null},buildEnd(){e.outputRatio&&i&&(0,l.diff)(l.snap.text(i),l.snap.text(a)).print()}}});exports.compressShaderLiterals=x,exports.extractShaderLiterals=y,exports.minifyShader=b;
package/dist/index.js CHANGED
@@ -1,115 +1,83 @@
1
- // src/plugin.js
2
- import { createFilter } from "@rollup/pluginutils";
3
- import { diff, snap } from "byte-snap";
4
- import MagicString from "magic-string";
5
- import { createUnplugin } from "unplugin";
6
-
7
- // src/core.js
8
- import { parse } from "@babel/parser";
9
- import _traverse from "@babel/traverse";
10
- var traverse = _traverse.default || _traverse;
11
- function extractShaderLiterals(code, tags = ["glsl", "wgsl", "shader"]) {
12
- const tagSet = new Set(tags);
13
- const literals = [];
14
- try {
15
- const ast = parse(code, {
16
- sourceType: "module",
17
- plugins: ["typescript", "jsx", "decorators-legacy"],
18
- allowReturnOutsideFunction: true
19
- });
20
- traverse(ast, {
21
- TaggedTemplateExpression(path) {
22
- const { tag, quasi } = path.node;
23
- let tagName = null;
24
- if (tag.type === "Identifier" && tagSet.has(tag.name)) {
25
- tagName = tag.name;
26
- } else if (tag.type === "MemberExpression" && tag.property.type === "Identifier" && tagSet.has(tag.property.name)) {
27
- tagName = tag.property.name;
28
- }
29
- if (tagName) {
30
- literals.push({
31
- tag: tagName,
32
- value: quasi.quasis.map((q) => q.value.raw).join(""),
33
- start: quasi.start,
34
- end: quasi.end
35
- });
36
- }
37
- },
38
- TemplateLiteral(path) {
39
- const node = path.node;
40
- const leadingComments = node.leadingComments || path.parentPath?.node?.leadingComments || [];
41
- for (const comment of leadingComments) {
42
- if (!comment || comment.type !== "CommentBlock")
43
- continue;
44
- const m = comment.value.match(/^\s*(glsl|wgsl|shader)\s*$/);
45
- if (m) {
46
- literals.push({
47
- tag: m[1],
48
- value: node.quasis.map((q) => q.value.raw).join(""),
49
- start: node.start,
50
- end: node.end
51
- });
52
- break;
53
- }
54
- }
55
- }
56
- });
57
- } catch (e) {}
58
- return literals;
59
- }
60
- function minifyShader(src) {
61
- return src.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/[ \t]+/g, " ").replace(/\n{2,}/g, `
62
- `).trim();
63
- }
64
-
65
- // src/plugin.js
66
- var compressShaderLiterals = createUnplugin((options = {}) => {
67
- const tags = options.tags || ["glsl", "wgsl", "shader"];
68
- const minify = options.transform || minifyShader;
69
- const filter = createFilter(options.include || [/\.[jt]sx?$/], options.exclude || [/node_modules/, /dist/]);
70
- let beforeText = "";
71
- let afterText = "";
72
- return {
73
- name: "compress-shader-literals",
74
- enforce: "pre",
75
- transform(code, id) {
76
- if (!filter(id))
77
- return null;
78
- if (!tags.some((tag) => code.includes(tag)))
79
- return null;
80
- const literals = extractShaderLiterals(code, tags);
81
- if (literals.length === 0)
82
- return null;
83
- if (options.debug) {
84
- console.log(`[compress-shader-literals] ${id}: ${literals.length} literal(s) — ${literals.map((l) => l.tag).join(", ")}`);
85
- }
86
- const ms = new MagicString(code);
87
- let hasChanges = false;
88
- for (const literal of literals) {
89
- const minified = minify(literal.value);
90
- if (literal.value !== minified) {
91
- ms.overwrite(literal.start, literal.end, `\`${minified}\``);
92
- hasChanges = true;
93
- }
94
- if (options.outputRatio) {
95
- beforeText += literal.value;
96
- afterText += minified;
97
- }
98
- }
99
- if (!hasChanges)
100
- return null;
101
- return {
102
- code: ms.toString(),
103
- map: ms.generateMap({ hires: true, source: id })
104
- };
105
- },
106
- buildEnd() {
107
- if (options.outputRatio && beforeText) {
108
- diff(snap.text(beforeText), snap.text(afterText)).print();
109
- }
110
- }
111
- };
1
+ import { createFilter as e } from "@rollup/pluginutils";
2
+ import { diff as t, snap as n } from "byte-snap";
3
+ import r from "magic-string";
4
+ import { createUnplugin as i } from "unplugin";
5
+ import { parse as a } from "@babel/parser";
6
+ import o from "@babel/traverse";
7
+ //#region src/defaults.js
8
+ var s = [
9
+ "glsl",
10
+ "wgsl",
11
+ "shader"
12
+ ], c = [/\.[jt]sx?$/], l = [/node_modules/, /dist/], u = (e) => RegExp(`^\\s*(${e.join("|")})\\s*$`), d = o.default || o, f = (e, t = s) => {
13
+ let n = new Set(t), r = u(t), i = [];
14
+ try {
15
+ d(a(e, {
16
+ sourceType: "module",
17
+ plugins: [
18
+ "typescript",
19
+ "jsx",
20
+ "decorators-legacy"
21
+ ],
22
+ allowReturnOutsideFunction: !0
23
+ }), {
24
+ TaggedTemplateExpression(e) {
25
+ let { tag: t, quasi: r } = e.node, a = null;
26
+ t.type === "Identifier" && n.has(t.name) ? a = t.name : t.type === "MemberExpression" && t.property.type === "Identifier" && n.has(t.property.name) && (a = t.property.name), a && i.push({
27
+ tag: a,
28
+ value: r.quasis.map((e) => e.value.raw).join(""),
29
+ start: r.start,
30
+ end: r.end
31
+ });
32
+ },
33
+ TemplateLiteral(e) {
34
+ let t = e.node, n = t.leadingComments || e.parentPath?.node?.leadingComments || [];
35
+ for (let e of n) {
36
+ if (!e || e.type !== "CommentBlock") continue;
37
+ let n = e.value.match(r);
38
+ if (n) {
39
+ i.push({
40
+ tag: n[1],
41
+ value: t.quasis.map((e) => e.value.raw).join(""),
42
+ start: t.start,
43
+ end: t.end
44
+ });
45
+ break;
46
+ }
47
+ }
48
+ }
49
+ });
50
+ } catch (e) {
51
+ if (e.name !== "SyntaxError") throw e;
52
+ }
53
+ return i;
54
+ }, p = (e) => e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/[ \t]+/g, " ").replace(/\n{2,}/g, "\n").trim(), m = i((i = {}) => {
55
+ let a = i.tags || s, o = i.transform || p, u = e(i.include || c, i.exclude || l), d = "", m = "";
56
+ return {
57
+ name: "compress-shader-literals",
58
+ enforce: "pre",
59
+ transform(e, t) {
60
+ if (!u(t) || !a.some((t) => e.includes(t))) return null;
61
+ let n = f(e, a);
62
+ if (n.length === 0) return null;
63
+ i.debug && console.log(`[compress-shader-literals] ${t}: ${n.length} literal(s) — ${n.map((e) => e.tag).join(", ")}`);
64
+ let s = new r(e), c = !1;
65
+ for (let e of n) {
66
+ let t = o(e.value);
67
+ e.value !== t && (s.overwrite(e.start, e.end, `\`${t}\``), c = !0), i.outputRatio && (d += e.value, m += t);
68
+ }
69
+ return c ? {
70
+ code: s.toString(),
71
+ map: s.generateMap({
72
+ hires: !0,
73
+ source: t
74
+ })
75
+ } : null;
76
+ },
77
+ buildEnd() {
78
+ i.outputRatio && d && t(n.text(d), n.text(m)).print();
79
+ }
80
+ };
112
81
  });
113
- export {
114
- compressShaderLiterals
115
- };
82
+ //#endregion
83
+ export { m as compressShaderLiterals, f as extractShaderLiterals, p as minifyShader };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compress-shader-literals",
3
- "version": "0.0.8",
3
+ "version": "1.0.0",
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": [
@@ -34,19 +34,20 @@
34
34
  "author": "jayF0x",
35
35
  "repository": {
36
36
  "type": "git",
37
- "url": "https://github.com/jayf0x/compress-shader-literals"
37
+ "url": "git+https://github.com/jayf0x/compress-shader-literals.git"
38
38
  },
39
- "homepage": "https://github.com/jayF0x/compress-shader-literals#readme",
39
+ "homepage": "https://github.com/jayf0x/compress-shader-literals#readme",
40
40
  "bugs": {
41
- "url": "https://github.com/jayF0x/compress-shader-literals/issues"
41
+ "url": "https://github.com/jayf0x/compress-shader-literals/issues"
42
42
  },
43
- "main": "./dist/index.js",
43
+ "main": "./dist/index.cjs",
44
44
  "module": "./dist/index.js",
45
45
  "types": "./dist/index.d.ts",
46
46
  "exports": {
47
47
  ".": {
48
48
  "types": "./dist/index.d.ts",
49
- "import": "./dist/index.js"
49
+ "import": "./dist/index.js",
50
+ "require": "./dist/index.cjs"
50
51
  }
51
52
  },
52
53
  "files": [
@@ -54,28 +55,43 @@
54
55
  ],
55
56
  "sideEffects": false,
56
57
  "scripts": {
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",
58
+ "build": "vite build && cp src/index.d.ts dist/index.d.ts",
59
+ "build_old": "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 && bun build src/plugin.js --outdir dist --entry-naming index.cjs --target node --format cjs --external @babel/parser --external @babel/traverse --external @rollup/pluginutils --external byte-snap --external magic-string --external unplugin",
58
60
  "typecheck": "tsc --noEmit --strict --skipLibCheck src/index.d.ts",
59
61
  "test": "bun test",
60
62
  "test:run": "bun test",
63
+ "test:build": "bun run build && node tests/build-smoke.js",
61
64
  "test:validate": "cd tests && bun install && node validate.js",
62
65
  "test:e2e": "cd tests && bun install && node e2e.js",
63
66
  "format": "prettier --write .",
64
67
  "format:check": "prettier --check .",
65
68
  "npm:deploy": "bash ./scripts/publish-npm.sh",
66
- "rm:stalepr": "git branch -vv | grep '\\[gone\\]' | awk '{print $1}' | xargs git branch -D"
69
+ "rm:stalepr": "git branch -vv | grep '\\[gone\\]' | awk '{print $1}' | xargs git branch -D",
70
+ "size": "size-limit"
67
71
  },
68
72
  "dependencies": {
69
73
  "@babel/parser": "^8.0.0",
70
74
  "@babel/traverse": "^8.0.0",
71
75
  "@rollup/pluginutils": "^5.4.0",
72
- "byte-snap": "^1.0.3",
76
+ "byte-snap": "^1.0.5",
73
77
  "magic-string": "^0.30.21",
74
78
  "unplugin": "^3.0.0"
75
79
  },
76
80
  "devDependencies": {
81
+ "@size-limit/file": "^11.0.0",
77
82
  "@trivago/prettier-plugin-sort-imports": "^5.0.0",
78
83
  "prettier": "^3.0.0",
79
- "typescript": "^5.6.0"
80
- }
84
+ "size-limit": "^11.0.0",
85
+ "typescript": "^5.6.0",
86
+ "vite": "^8.1.0"
87
+ },
88
+ "engines": {
89
+ "node": ">=18"
90
+ },
91
+ "size-limit": [
92
+ {
93
+ "path": "dist/index.js",
94
+ "limit": "1.7 kB"
95
+ }
96
+ ]
81
97
  }