forked from jiahmargallo/Complexity-Jenga
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.js
More file actions
221 lines (187 loc) · 7.49 KB
/
Copy pathbuild.js
File metadata and controls
221 lines (187 loc) · 7.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/**
* Build Script for Complexity-Jenga Project
*
* This script creates a minified, production-ready version of the project
* in the /release folder. It performs the following optimizations:
*
* 1. Minifies all JavaScript files (removes comments, whitespace, console.log)
* 2. Minifies CSS files (removes whitespace, optimizes rules)
* 3. Minifies HTML (removes comments, whitespace)
* 4. Copies all static assets (data, images, models, textures)
*
* USAGE:
* npm install # Install build dependencies (first time only)
* npm run build # Create release version
*
* OUTPUT:
* - Creates /release folder with optimized files
* - Typical size reduction: 35-45% for text files
* - Three.js: ~1.2MB → ~700KB
* - Ready for production deployment
*
* DEPLOYMENT:
* - Upload contents of /release folder to your web server
* - Ensure server can serve static files (.js, .css, .wasm, .gltf, .csv)
* - No server-side processing required
*/
const fs = require('fs-extra');
const path = require('path');
const { minify } = require('terser');
const CleanCSS = require('clean-css');
const { minify: minifyHtml } = require('html-minifier');
const sourceDir = __dirname;
const releaseDir = path.join(__dirname, 'release');
async function build() {
console.log('🏗️ Building release version...');
// Clean and create release directory
await fs.remove(releaseDir);
await fs.ensureDir(releaseDir);
// Copy static assets that don't need minification
console.log('📁 Copying static assets...');
await copyStaticAssets();
// Minify JavaScript files
console.log('📦 Minifying JavaScript...');
await minifyJavaScript();
// Minify CSS files
console.log('🎨 Minifying CSS...');
await minifyCSS();
// Minify HTML
console.log('🏠 Minifying HTML...');
await minifyHTML();
console.log('✅ Build complete! Release files are in the /release folder');
console.log('💡 To deploy: Upload the contents of /release to your web server');
}
/**
* Copy static assets that don't require minification
* Includes: data files, images, 3D models, textures, binary files
*/
async function copyStaticAssets() {
// Copy data files (CSV datasets)
await fs.copy(path.join(sourceDir, 'data'), path.join(releaseDir, 'data'));
// Copy images (SVG icons and UI elements)
await fs.copy(path.join(sourceDir, 'imgs'), path.join(releaseDir, 'imgs'));
// Copy 3D models (GLTF table model and textures)
await fs.copy(path.join(sourceDir, 'models'), path.join(releaseDir, 'models'));
// Copy background textures
await fs.copy(path.join(sourceDir, 'textures'), path.join(releaseDir, 'textures'));
// Copy specific libs that shouldn't be minified (binary files, already minified)
await fs.ensureDir(path.join(releaseDir, 'libs'));
// Ammo.js physics engine (WebAssembly - don't modify)
await fs.copy(path.join(sourceDir, 'libs/ammo.wasm.js'), path.join(releaseDir, 'libs/ammo.wasm.js'));
await fs.copy(path.join(sourceDir, 'libs/ammo.wasm.wasm'), path.join(releaseDir, 'libs/ammo.wasm.wasm'));
// Bootstrap CSS framework (already minified)
await fs.copy(path.join(sourceDir, 'libs/bootstrap-5.3.3-dist'), path.join(releaseDir, 'libs/bootstrap-5.3.3-dist'));
// D3.js data visualization library
await fs.copy(path.join(sourceDir, 'libs/d3.v5.js'), path.join(releaseDir, 'libs/d3.v5.js'));
// Already minified GUI library
await fs.copy(path.join(sourceDir, 'libs/lil-gui.module.min.js'), path.join(releaseDir, 'libs/lil-gui.module.min.js'));
// Stats monitoring (already minified)
await fs.copy(path.join(sourceDir, 'libs/stats.module.js'), path.join(releaseDir, 'libs/stats.module.js'));
}
/**
* Minify JavaScript files using Terser
* Removes comments, console.log statements, and unnecessary whitespace
* Mangles variable names for additional size reduction
*/
async function minifyJavaScript() {
const jsFiles = [
// Core application modules
'components/main.js',
'components/state.js',
'components/graphics.js',
'components/physics.js',
'components/input.js',
'components/gui.js',
'components/data.js',
'components/legend.js',
'components/infographics.js',
'components/Dropdown.js',
// Three.js core and addons
'libs/three.module.js',
'libs/OrbitControls.js',
'libs/DragControls.js',
'libs/loaders/GLTFLoader.js',
'libs/loaders/FontLoader.js',
'libs/utils/BufferGeometryUtils.js',
'libs/utils/TextGeometry.js'
];
for (const file of jsFiles) {
const sourcePath = path.join(sourceDir, file);
const targetPath = path.join(releaseDir, file);
if (await fs.pathExists(sourcePath)) {
const code = await fs.readFile(sourcePath, 'utf8');
try {
const result = await minify(code, {
compress: {
drop_console: true, // Remove console.log statements
drop_debugger: true // Remove debugger statements
},
mangle: true, // Shorten variable names
format: {
comments: false // Remove all comments
}
});
await fs.ensureDir(path.dirname(targetPath));
await fs.writeFile(targetPath, result.code);
console.log(` ✓ ${file}`);
} catch (error) {
// If minification fails, copy original file
console.warn(` ⚠️ Failed to minify ${file}, copying original:`, error.message);
await fs.ensureDir(path.dirname(targetPath));
await fs.copy(sourcePath, targetPath);
}
}
}
}
/**
* Minify CSS files using CleanCSS
* Removes whitespace, combines rules, optimizes values
*/
async function minifyCSS() {
const cssFiles = [
'styles/main.css', // Main application styles
'styles/dropdown.css' // Dropdown component styles
];
const cleanCSS = new CleanCSS({
level: 2, // Advanced optimizations
returnPromise: true
});
for (const file of cssFiles) {
const sourcePath = path.join(sourceDir, file);
const targetPath = path.join(releaseDir, file);
if (await fs.pathExists(sourcePath)) {
const css = await fs.readFile(sourcePath, 'utf8');
try {
const result = await cleanCSS.minify(css);
await fs.ensureDir(path.dirname(targetPath));
await fs.writeFile(targetPath, result.styles);
console.log(` ✓ ${file}`);
} catch (error) {
console.warn(` ⚠️ Failed to minify ${file}, copying original:`, error.message);
await fs.ensureDir(path.dirname(targetPath));
await fs.copy(sourcePath, targetPath);
}
}
}
}
/**
* Minify HTML file
* Removes comments, whitespace, and optimizes inline CSS/JS
*/
async function minifyHTML() {
const htmlContent = await fs.readFile(path.join(sourceDir, 'index.html'), 'utf8');
const minified = minifyHtml(htmlContent, {
collapseWhitespace: true, // Remove whitespace
removeComments: true, // Remove HTML comments
removeRedundantAttributes: true, // Remove redundant attributes
removeScriptTypeAttributes: true, // Remove type="text/javascript"
removeStyleLinkTypeAttributes: true, // Remove type="text/css"
useShortDoctype: true, // Use <!DOCTYPE html>
minifyCSS: true, // Minify inline CSS
minifyJS: true // Minify inline JavaScript
});
await fs.writeFile(path.join(releaseDir, 'index.html'), minified);
console.log(' ✓ index.html');
}
// Run the build process
build().catch(console.error);