Improve incremental build times

This commit is contained in:
Ruin0x11 2021-05-08 18:14:27 -07:00
parent ca77149597
commit 0f5e086eba
4 changed files with 5223 additions and 174 deletions

View file

@ -4,20 +4,20 @@
// ------------------------------------------------- // -------------------------------------------------
const webapp_icons = [ const webapp_icons = [
{name: 'android-chrome-192x192.png', size: 192}, { name: 'android-chrome-192x192.png', size: 192 },
{name: 'android-chrome-512x512.png', size: 512}, { name: 'android-chrome-512x512.png', size: 512 },
{name: 'apple-touch-icon.png', size: 180}, { name: 'apple-touch-icon.png', size: 180 },
{name: 'mstile-150x150.png', size: 150} { name: 'mstile-150x150.png', size: 150 }
]; ];
const webapp_splash_screens = [ const webapp_splash_screens = [
{w: 640, h: 1136, center: 320}, { w: 640, h: 1136, center: 320 },
{w: 750, h: 1294, center: 375}, { w: 750, h: 1294, center: 375 },
{w: 1125, h: 2436, center: 565}, { w: 1125, h: 2436, center: 565 },
{w: 1242, h: 2148, center: 625}, { w: 1242, h: 2148, center: 625 },
{w: 1536, h: 2048, center: 770}, { w: 1536, h: 2048, center: 770 },
{w: 1668, h: 2224, center: 820}, { w: 1668, h: 2224, center: 820 },
{w: 2048, h: 2732, center: 1024} { w: 2048, h: 2732, center: 1024 }
]; ];
const external_js = [ const external_js = [
@ -57,6 +57,8 @@ const glob = require('glob');
const path = require('path'); const path = require('path');
const util = require('util'); const util = require('util');
const execSync = require('child_process').execSync; const execSync = require('child_process').execSync;
const browserify = require('browserify');
const chokidar = require('chokidar');
function readTextFile(path) { function readTextFile(path) {
return fs.readFileSync(path, 'utf-8'); return fs.readFileSync(path, 'utf-8');
@ -112,7 +114,7 @@ function bundleHtml() {
(match, number) => { return placeholders[number]; }); (match, number) => { return placeholders[number]; });
const functionText = underscore.template( const functionText = underscore.template(
templateText, {variable: 'ctx'}).source; templateText, { variable: 'ctx' }).source;
compiledTemplateJs.push(`templates['${name}'] = ${functionText};`); compiledTemplateJs.push(`templates['${name}'] = ${functionText};`);
} }
@ -131,7 +133,7 @@ function bundleCss() {
let css = ''; let css = '';
for (const file of glob.sync('./css/**/*.styl')) { for (const file of glob.sync('./css/**/*.styl')) {
css += stylus.render(readTextFile(file), {filename: file}); css += stylus.render(readTextFile(file), { filename: file });
} }
fs.writeFileSync('./public/css/app.min.css', minifyCss(css)); fs.writeFileSync('./public/css/app.min.css', minifyCss(css));
if (process.argv.includes('--gzip')) { if (process.argv.includes('--gzip')) {
@ -148,26 +150,23 @@ function bundleCss() {
console.info('Bundled CSS'); console.info('Bundled CSS');
} }
function bundleJs() { function minifyJs(path) {
const browserify = require('browserify');
function minifyJs(path) {
return require('terser').minify( return require('terser').minify(
fs.readFileSync(path, 'utf-8'), {compress: {unused: false}}).code; fs.readFileSync(path, 'utf-8'), { compress: { unused: false } }).code;
} }
function writeJsBundle(b, path, compress, callback) { function writeJsBundle(b, path, compress, callback) {
let outputFile = fs.createWriteStream(path); let outputFile = fs.createWriteStream(path);
b.bundle().pipe(outputFile); b.bundle().on('error', console.error).pipe(outputFile);
outputFile.on('finish', () => { outputFile.on('finish', () => {
if (compress) { if (compress) {
fs.writeFileSync(path, minifyJs(path)); fs.writeFileSync(path, minifyJs(path));
} }
callback(); callback();
}); });
} }
if (!process.argv.includes('--no-vendor-js')) { function bundleVendorJs(compress) {
let b = browserify(); let b = browserify();
for (let lib of external_js) { for (let lib of external_js) {
b.require(lib); b.require(lib);
@ -176,28 +175,39 @@ function bundleJs() {
b.add(require.resolve('babel-polyfill')); b.add(require.resolve('babel-polyfill'));
} }
const file = './public/js/vendor.min.js'; const file = './public/js/vendor.min.js';
writeJsBundle(b, file, true, () => { writeJsBundle(b, file, compress, () => {
if (process.argv.includes('--gzip')) { if (process.argv.includes('--gzip')) {
gzipFile(file); gzipFile(file);
} }
console.info('Bundled vendor JS'); console.info('Bundled vendor JS');
}); });
} }
if (!process.argv.includes('--no-app-js')) { function bundleAppJs(b, compress, callback) {
let b = browserify({debug: process.argv.includes('--debug')});
if (!process.argv.includes('--no-transpile')) {
b = b.transform('babelify');
}
b = b.external(external_js).add(glob.sync('./js/**/*.js'));
const compress = !process.argv.includes('--debug');
const file = './public/js/app.min.js'; const file = './public/js/app.min.js';
writeJsBundle(b, file, compress, () => { writeJsBundle(b, file, compress, () => {
if (process.argv.includes('--gzip')) { if (process.argv.includes('--gzip')) {
gzipFile(file); gzipFile(file);
} }
console.info('Bundled app JS'); console.info('Bundled app JS');
callback();
}); });
}
function bundleJs() {
if (!process.argv.includes('--no-vendor-js')) {
bundleVendorJs(true);
}
if (!process.argv.includes('--no-app-js')) {
let watchify = require('watchify');
let b = browserify({ debug: process.argv.includes('--debug') });
if (!process.argv.includes('--no-transpile')) {
b = b.transform('babelify');
}
b = b.external(external_js).add(glob.sync('./js/**/*.js'));
const compress = !process.argv.includes('--debug');
bundleAppJs(b, compress, () => { });
} }
} }
@ -298,22 +308,66 @@ function makeOutputDirs() {
} }
} }
function watch() {
chokidar.watch('./fonts/**/*').on('change', bundleBinaryAssets);
chokidar.watch('./img/**/*').on('change', bundleWebAppFiles);
chokidar.watch('./html/**/*.tpl').on('change', bundleHtml);
chokidar.watch('./css/**/*.styl').on('change', bundleCss);
bundleBinaryAssets();
bundleWebAppFiles();
bundleCss();
bundleHtml();
let watchify = require('watchify');
let b = browserify({
debug: process.argv.includes('--debug'),
entries: ['js/main.js'],
cache: {},
packageCache: {},
});
b.plugin(watchify);
if (!process.argv.includes('--no-transpile')) {
b = b.transform('babelify');
}
b = b.external(external_js).add(glob.sync('./js/**/*.js'));
const compress = false;
function bundle(id) {
console.info("Rebundling app JS...");
let start = new Date();
bundleAppJs(b, compress, () => {
let end = new Date() - start;
console.info('Rebundled in %ds.', end / 1000)
});
}
b.on('update', bundle);
bundle();
}
// ------------------------------------------------- // -------------------------------------------------
makeOutputDirs(); makeOutputDirs();
bundleConfig(); bundleConfig();
if (!process.argv.includes('--no-binary-assets')) { if (process.argv.includes('--watch')) {
watch();
} else {
if (!process.argv.includes('--no-binary-assets')) {
bundleBinaryAssets(); bundleBinaryAssets();
} }
if (!process.argv.includes('--no-web-app-files')) { if (!process.argv.includes('--no-web-app-files')) {
bundleWebAppFiles(); bundleWebAppFiles();
} }
if (!process.argv.includes('--no-html')) { if (!process.argv.includes('--no-html')) {
bundleHtml(); bundleHtml();
} }
if (!process.argv.includes('--no-css')) { if (!process.argv.includes('--no-css')) {
bundleCss(); bundleCss();
} }
if (!process.argv.includes('--no-js')) { if (!process.argv.includes('--no-js')) {
bundleJs(); bundleJs();
}
} }

5143
client/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,8 @@
"private": true, "private": true,
"scripts": { "scripts": {
"build": "node build.js", "build": "node build.js",
"watch": "c1=\"\";while :;do c2=$(find html js css img -type f -and -not -iname '*autogen*'|sort|xargs cat|md5sum);[[ $c1 != $c2 ]]&&npm run build -- --debug --no-vendor-js;c1=$c2;sleep 1;done" "watch": "bash watch.sh",
"watchify": "watchify ./js/**/*.js -o ./public/js/app.min.js -d -v"
}, },
"dependencies": { "dependencies": {
"dompurify": "^2.0.17", "dompurify": "^2.0.17",
@ -21,12 +22,14 @@
"babel-preset-env": "^1.7.0", "babel-preset-env": "^1.7.0",
"babelify": "^8.0.0", "babelify": "^8.0.0",
"browserify": "^16.2.2", "browserify": "^16.2.2",
"chokidar": "^3.5.1",
"csso": "^3.5.1", "csso": "^3.5.1",
"glob": "^7.1.2", "glob": "^7.1.2",
"html-minifier": "^3.5.18", "html-minifier": "^3.5.18",
"jimp": "^0.13.0", "jimp": "^0.13.0",
"stylus": "^0.54.5", "stylus": "^0.54.5",
"terser": "^3.7.7", "terser": "^3.7.7",
"underscore": "^1.9.1" "underscore": "^1.9.1",
"watchify": "^4.0.0"
} }
} }

15
client/watch.sh Normal file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail
npm run watchify &
c1="";
while :; do
c2=$(find html css img -type f -and -not -iname '*autogen*'|sort|xargs cat|md5sum);
[[ $c1 != $c2 ]] && npm run build -- --debug --no-js --no-binary-assets --no-web-app-files
c1=$c2;
sleep 1;
done
wait