human/server/build.js

252 lines
7.2 KiB
JavaScript
Raw Normal View History

2021-05-25 14:58:20 +02:00
/**
* Implements Human build process
* Used to generate prod builds for releases or by dev server to generate on-the-fly debug builds
*/
const fs = require('fs');
2021-04-15 15:43:55 +02:00
const path = require('path');
2020-11-17 05:58:06 +01:00
const log = require('@vladmandic/pilogger');
2021-02-08 18:47:38 +01:00
const esbuild = require('esbuild');
2021-06-03 15:41:53 +02:00
const tfjs = require('@tensorflow/tfjs/package.json');
2021-06-05 18:59:11 +02:00
const changelog = require('./changelog.js');
2021-06-05 23:51:46 +02:00
const lint = require('./lint.js');
const typedoc = require('./typedoc.js');
const typings = require('./typings.js');
2021-02-08 17:39:09 +01:00
let busy = false;
2021-06-03 15:41:53 +02:00
2021-02-21 13:20:58 +01:00
const config = {
2021-06-05 18:59:11 +02:00
build: {
2021-06-05 23:51:46 +02:00
banner: { js: `
/*
Human library
homepage: <https://github.com/vladmandic/human>
author: <https://github.com/vladmandic>'
*/` },
tsconfig: './tsconfig.json',
2021-02-21 13:20:58 +01:00
logLevel: 'error',
bundle: true,
metafile: true,
target: 'es2018',
2021-02-21 13:20:58 +01:00
},
debug: {
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
},
production: {
minifyWhitespace: true,
minifyIdentifiers: true,
minifySyntax: true,
},
2021-06-05 23:51:46 +02:00
buildLog: 'build.log',
2021-06-05 18:59:11 +02:00
changelog: '../CHANGELOG.md',
2021-06-05 23:51:46 +02:00
lintLocations: ['server/', 'demo/', 'src/', 'test/'],
2020-11-17 05:58:06 +01:00
};
const targets = {
2021-02-21 19:34:26 +01:00
node: {
tfjs: {
platform: 'node',
format: 'cjs',
entryPoints: ['src/tfjs/tf-node.ts'],
outfile: 'dist/tfjs.esm.js',
external: ['@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: false,
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
2021-02-21 19:34:26 +01:00
},
node: {
platform: 'node',
format: 'cjs',
entryPoints: ['src/human.ts'],
outfile: 'dist/human.node.js',
external: ['@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: false,
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
2021-02-21 19:34:26 +01:00
},
},
nodeGPU: {
tfjs: {
platform: 'node',
format: 'cjs',
entryPoints: ['src/tfjs/tf-node-gpu.ts'],
outfile: 'dist/tfjs.esm.js',
external: ['@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: false,
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
2021-02-21 19:34:26 +01:00
},
node: {
platform: 'node',
format: 'cjs',
entryPoints: ['src/human.ts'],
outfile: 'dist/human.node-gpu.js',
external: ['@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: false,
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
2021-02-21 19:34:26 +01:00
},
},
2021-04-14 03:45:45 +02:00
nodeWASM: {
tfjs: {
platform: 'node',
format: 'cjs',
entryPoints: ['src/tfjs/tf-node-wasm.ts'],
outfile: 'dist/tfjs.esm.js',
external: ['@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: false,
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
2021-04-14 03:45:45 +02:00
},
node: {
platform: 'node',
format: 'cjs',
entryPoints: ['src/human.ts'],
outfile: 'dist/human.node-wasm.js',
external: ['@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: false,
minifyWhitespace: false,
minifyIdentifiers: false,
minifySyntax: false,
2021-04-14 03:45:45 +02:00
},
},
2021-02-21 19:34:26 +01:00
browserNoBundle: {
tfjs: {
platform: 'browser',
format: 'esm',
2021-02-08 17:39:09 +01:00
entryPoints: ['src/tfjs/tf-browser.ts'],
outfile: 'dist/tfjs.esm.js',
2021-02-25 13:50:13 +01:00
external: ['fs', 'buffer', 'util', 'os', '@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: true,
},
esm: {
platform: 'browser',
format: 'esm',
2021-02-08 17:39:09 +01:00
entryPoints: ['src/human.ts'],
outfile: 'dist/human.esm-nobundle.js',
2021-02-25 13:50:13 +01:00
external: ['fs', 'buffer', 'util', 'os', '@tensorflow'],
2021-04-25 19:16:04 +02:00
sourcemap: true,
},
2020-11-17 05:58:06 +01:00
},
browserBundle: {
tfjs: {
platform: 'browser',
format: 'esm',
2021-02-08 17:39:09 +01:00
entryPoints: ['src/tfjs/tf-browser.ts'],
outfile: 'dist/tfjs.esm.js',
2021-02-25 13:50:13 +01:00
external: ['fs', 'buffer', 'util', 'os'],
2021-06-06 18:58:06 +02:00
treeShaking: 'ignore-annotations',
2021-04-25 19:16:04 +02:00
sourcemap: true,
},
iife: {
platform: 'browser',
format: 'iife',
globalName: 'Human',
2021-02-08 17:39:09 +01:00
entryPoints: ['src/human.ts'],
2021-03-10 00:32:35 +01:00
outfile: 'dist/human.js',
2021-02-25 13:50:13 +01:00
external: ['fs', 'buffer', 'util', 'os'],
sourcemap: false,
},
esm: {
platform: 'browser',
format: 'esm',
2021-02-08 17:39:09 +01:00
entryPoints: ['src/human.ts'],
outfile: 'dist/human.esm.js',
2021-02-25 13:50:13 +01:00
external: ['fs', 'buffer', 'util', 'os'],
2021-04-25 19:16:04 +02:00
sourcemap: true,
},
2021-03-29 20:40:34 +02:00
/*
2021-06-05 18:59:11 +02:00
demo: {
platform: 'browser',
format: 'esm',
entryPoints: ['demo/browser.js'],
outfile: 'dist/demo-browser-index.js',
external: ['fs', 'buffer', 'util', 'os'],
},
*/
2020-11-17 05:58:06 +01:00
},
};
2021-03-10 00:32:35 +01:00
async function getStats(json) {
2020-11-17 18:38:48 +01:00
const stats = {};
2021-03-10 00:32:35 +01:00
if (json && json.metafile?.inputs && json.metafile?.outputs) {
for (const [key, val] of Object.entries(json.metafile.inputs)) {
2020-11-17 18:38:48 +01:00
if (key.startsWith('node_modules')) {
stats.modules = (stats.modules || 0) + 1;
stats.moduleBytes = (stats.moduleBytes || 0) + val.bytes;
} else {
stats.imports = (stats.imports || 0) + 1;
stats.importBytes = (stats.importBytes || 0) + val.bytes;
}
}
const files = [];
2021-03-10 00:32:35 +01:00
for (const [key, val] of Object.entries(json.metafile.outputs)) {
2020-11-17 18:38:48 +01:00
if (!key.endsWith('.map')) {
files.push(key);
stats.outputBytes = (stats.outputBytes || 0) + val.bytes;
}
}
stats.outputFiles = files.join(', ');
}
return stats;
}
2021-02-08 18:47:38 +01:00
// rebuild typings
2021-06-03 15:41:53 +02:00
2020-11-17 05:58:06 +01:00
// rebuild on file change
2021-02-21 13:20:58 +01:00
async function build(f, msg, dev = false) {
2021-02-08 17:39:09 +01:00
if (busy) {
log.state('Build: busy...');
2021-04-09 14:07:58 +02:00
setTimeout(() => build(f, msg, dev), 500);
2021-02-08 17:39:09 +01:00
return;
}
busy = true;
2021-02-21 13:20:58 +01:00
log.info('Build: file', msg, f, 'type:', dev ? 'debug' : 'production', 'config:', dev ? config.debug : config.production);
2020-11-17 05:58:06 +01:00
// common build options
try {
// rebuild all target groups and types
for (const [targetGroupName, targetGroup] of Object.entries(targets)) {
for (const [targetName, targetOptions] of Object.entries(targetGroup)) {
// if triggered from watch mode, rebuild only browser bundle
2021-04-08 18:10:15 +02:00
// if ((require.main !== module) && ((targetGroupName === 'browserNoBundle') || (targetGroupName === 'nodeGPU'))) continue;
2021-06-05 18:59:11 +02:00
const opt = dev ? config.debug : config.production;
// @ts-ignore // eslint-typescript complains about string enums used in js code
const meta = await esbuild.build({ ...config.build, ...opt, ...targetOptions });
2021-03-10 00:32:35 +01:00
const stats = await getStats(meta);
2021-06-05 18:59:11 +02:00
log.state(` target: ${targetGroupName} type: ${targetName}:`, stats);
}
2020-11-17 05:58:06 +01:00
}
2021-06-03 15:41:53 +02:00
if (!dev) { // only for prod builds, skipped for dev build
2021-06-05 23:51:46 +02:00
await lint.run(config.lintLocations); // run linter
await typings.run(targets.browserBundle.esm.entryPoints); // generate typings
2021-06-05 18:59:11 +02:00
await changelog.update(config.changelog); // generate changelog
2021-06-05 23:51:46 +02:00
await typedoc.run(targets.browserBundle.esm.entryPoints); // generate typedoc
2021-03-14 04:31:09 +01:00
}
2020-11-25 15:13:19 +01:00
if (require.main === module) process.exit(0);
2020-11-17 05:58:06 +01:00
} catch (err) {
// catch errors and print where it occured
log.error('Build error', JSON.stringify(err.errors || err, null, 2));
2020-11-25 15:13:19 +01:00
if (require.main === module) process.exit(1);
2020-11-17 05:58:06 +01:00
}
2021-02-08 17:39:09 +01:00
busy = false;
2020-11-17 05:58:06 +01:00
}
2020-11-25 15:13:19 +01:00
if (require.main === module) {
2021-06-05 23:51:46 +02:00
config.buildLog = path.join(__dirname, config.buildLog);
if (fs.existsSync(config.buildLog)) fs.unlinkSync(config.buildLog);
log.logFile(config.buildLog);
2020-11-17 05:58:06 +01:00
log.header();
2021-06-05 23:51:46 +02:00
log.info(`Toolchain: tfjs: ${tfjs.version} esbuild ${esbuild.version}; typescript ${typings.version}; typedoc: ${typedoc.version} eslint: ${lint.version}`);
2020-11-17 05:58:06 +01:00
build('all', 'startup');
} else {
exports.build = build;
}