Skip to content

Commit f54b94b

Browse files
committed
Create build scripts
* Added NPM build scripts * Improved plugin workflow a little * In-sourced shader minifier * Removed ect binary from source tree (replaced with dev dependency)
1 parent c5b6fb7 commit f54b94b

10 files changed

Lines changed: 3457 additions & 159 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

build.mjs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { execFile } from 'node:child_process';
2+
import fs from "node:fs/promises";
3+
import { minify } from "terser";
4+
import ect from "ect-bin";
5+
6+
// List of all available plugins and their names
7+
const availablePlugins = [
8+
// Enables shader compilation logs
9+
"debug",
10+
11+
// Enables code for calculation of smooth normals
12+
"smooth",
13+
14+
// Enables the built-in shapes
15+
"builtinShapes",
16+
];
17+
18+
// Minifies any shader source code found in the src string
19+
function minifyFileShaders(src) {
20+
for (const shaderOld of src.match(/"#version 300 es[^"]*"/g)) {
21+
let shader = shaderOld;
22+
23+
// Remove comments and newlines
24+
shader = shader.replace(/(\/\/.*?)?\\n/g, " ");
25+
26+
// Remove any unneeded whitespace
27+
// Run these twice, to catch one-width character sequences
28+
for (let i = 0; i < 2; i++) {
29+
shader = shader.
30+
replace(/([\w\.])\s+([\w\.])/g, "$1 $2").
31+
replace(/([\w\.])\s+([^\w\.])/g, "$1$2").
32+
replace(/([^\w\.])\s+([\w\.])/g, "$1$2").
33+
replace(/([^\w\.])\s+([^\w\.])/g, "$1$2");
34+
}
35+
36+
// Re-add newline after #version directive
37+
shader = shader.replace(/(#version 300 es)\s+/, "$1\\n");
38+
39+
// Finally, replace shader source with new minified version
40+
src = src.replace(shaderOld, shader);
41+
}
42+
43+
// Return modified js source
44+
return src;
45+
}
46+
47+
// Main build function
48+
async function buildW(outJsFname, outZipFname, plugins = []) {
49+
50+
// Add plugin states to a map
51+
const pluginsObj = {};
52+
for (const pluginName of availablePlugins) {
53+
pluginsObj[`W.plugin.${pluginName}`] = plugins.includes(pluginName);
54+
}
55+
56+
// Read W source file
57+
const wSrc = (await fs.readFile("w.js")).toString();
58+
59+
// Run terser with provided flags
60+
const tersed = await minify(wSrc, {
61+
mangle: true,
62+
compress: {
63+
passes: 2,
64+
global_defs: {
65+
"W.built": true,
66+
...pluginsObj,
67+
},
68+
},
69+
});
70+
71+
// Minify any shaders hanging about
72+
const code = minifyFileShaders(tersed.code);
73+
74+
// Write .js file to file system
75+
await fs.writeFile(outJsFname, code);
76+
77+
// Remove existing .zip, to avoid ect throwing errors
78+
await fs.unlink(outZipFname);
79+
80+
// Put the .js file into a .zip using ect
81+
await new Promise((resolve, reject) => {
82+
execFile(ect, ["-9", "-strip", "-zip", outZipFname, outJsFname], (err, stdout) => {
83+
if (err) reject(stdout);
84+
resolve();
85+
});
86+
})
87+
}
88+
89+
// Build the lite version
90+
await buildW("w.min.lite.js", "w.min.lite.zip");
91+
92+
// Build the full version
93+
await buildW("w.min.full.js", "w.min.full.zip", ["smooth", "builtinShapes"]);
94+
95+
// Print file sizes
96+
console.log(`w.min.full.js: ${(await fs.stat("w.min.full.js")).size} bytes`);
97+
console.log(`w.min.lite.js: ${(await fs.stat("w.min.lite.js")).size} bytes`);
98+
console.log(`w.min.full.zip: ${(await fs.stat("w.min.full.zip")).size} bytes`);
99+
console.log(`w.min.lite.zip: ${(await fs.stat("w.min.lite.zip")).size} bytes`);

ect-0.8.3.exe

-1.8 MB
Binary file not shown.

0 commit comments

Comments
 (0)