@whook/whook
Version:
Build strong and efficient REST web services.
115 lines (113 loc) • 5.11 kB
JavaScript
import { exit, stderr } from 'node:process';
import { readFile, writeFile } from 'node:fs/promises';
import { join, relative } from 'node:path';
import { pathToFileURL } from 'node:url';
import { mkdirp } from 'mkdirp';
import { Knifecycle, constant, initInitializerBuilder } from 'knifecycle';
import initCompiler, { DEFAULT_COMPILER_OPTIONS } from './services/compiler.js';
import initProxiedENV from './services/PROXIED_ENV.js';
import initBuildAutoloader from './services/_buildAutoload.js';
import { printStackTrace } from 'yerror';
import { parseArgs } from './libs/args.js';
export const DEFAULT_BUILD_DIR = 'server';
export const DEFAULT_BUILD_INITIALIZER_PATH_MAP = {
$fatalError: 'knifecycle/dist/fatalError.js',
BASE_URL: '@whook/whook/dist/services/BASE_URL.js',
DEFINITIONS: '@whook/whook/dist/services/DEFINITIONS.js',
logger: '@whook/whook/dist/services/logger.js',
exit: '@whook/whook/dist/services/exit.js',
PORT: '@whook/whook/dist/services/PORT.js',
HOST: '@whook/whook/dist/services/HOST.js',
WHOOK_RESOLVED_PLUGINS: '@whook/whook/dist/services/WHOOK_RESOLVED_PLUGINS.js',
httpRouter: '@whook/whook/dist/services/httpRouter.js',
httpTransaction: '@whook/whook/dist/services/httpTransaction.js',
httpServer: '@whook/whook/dist/services/httpServer.js',
apm: '@whook/whook/dist/services/apm.js',
obfuscator: '@whook/whook/dist/services/obfuscator.js',
errorHandler: '@whook/whook/dist/services/errorHandler.js',
APP_CONFIG: 'application-services/dist/services/APP_CONFIG.js',
PROJECT_DIR: 'application-services/dist/services/PROJECT_DIR.js',
PROCESS_ENV: 'application-services/dist/services/PROCESS_ENV.js',
process: 'application-services/dist/services/process.js',
ENV: 'application-services/dist/services/ENV.js',
log: 'common-services/dist/services/log.js',
time: 'common-services/dist/services/time.js',
delay: 'common-services/dist/services/delay.js',
random: 'common-services/dist/services/random.js',
importer: 'common-services/dist/services/importer.js',
resolve: 'common-services/dist/services/resolve.js',
};
export async function prepareBuildEnvironment($ = new Knifecycle()) {
$.register(initBuildAutoloader);
$.register(initInitializerBuilder);
$.register(initCompiler);
$.register(initProxiedENV);
$.register(constant('INITIALIZER_PATH_MAP', DEFAULT_BUILD_INITIALIZER_PATH_MAP));
$.register(constant('args', parseArgs([])));
$.register(constant('BUILD_DIR', DEFAULT_BUILD_DIR));
$.register(constant('COMPILER_OPTIONS', DEFAULT_COMPILER_OPTIONS));
return $;
}
export async function runBuild(aPrepareBuildEnvironment) {
try {
const $ = await aPrepareBuildEnvironment();
const { APP_ENV, PROJECT_DIR, BUILD_DIR, COMPILER_OPTIONS, compiler, log, buildInitializer, } = await $.run([
'APP_ENV',
'PROJECT_DIR',
'BUILD_DIR',
'COMPILER_OPTIONS',
'compiler',
'log',
'buildInitializer',
'process',
]);
log('info', 'Build environment initialized 🚀🌕');
const distPath = join(PROJECT_DIR, 'dist');
const srcPath = join(PROJECT_DIR, 'src');
const buildPath = join(PROJECT_DIR, 'builds', APP_ENV, BUILD_DIR);
const srcRelativePath = relative(buildPath, srcPath);
const initializerContent = (await buildInitializer(['httpServer', 'process'])).replaceAll(pathToFileURL(srcPath).toString(), srcRelativePath);
const indexContent = await buildIndex();
await mkdirp(distPath);
await mkdirp(buildPath);
await Promise.all([
ensureFile({ log }, join(buildPath, 'initialize.js'), initializerContent),
ensureFile({ log }, join(buildPath, 'main.js'), indexContent),
]);
const entryPoint = `${buildPath}/main.js`;
const { contents, mappings } = await compiler(entryPoint, COMPILER_OPTIONS);
await Promise.all([
ensureFile({ log }, `${buildPath}/start.js`, contents),
mappings
? ensureFile({ log }, `${buildPath}/start.js.map`, mappings)
: Promise.resolve(),
]);
}
catch (err) {
stderr.write(`💀 - Cannot launch the build: ${printStackTrace(err)}`);
exit(1);
}
}
async function ensureFile({ log }, path, content) {
try {
const oldContent = (await readFile(path)).toString();
if (oldContent === content) {
log('debug', `🗀 - Ignore unchanged file: "${path}".`);
return;
}
}
catch (err) {
log('debug', `🗀 - Write new file: "${path}".`);
log('debug-stack', printStackTrace(err));
return await writeFile(path, content);
}
log('debug', `🗀 - Write changed file: "${path}".`);
return await writeFile(path, content);
}
async function buildIndex() {
return `// Built with \`@whook\`, do not edit in place!
import { initialize } from './initialize.js';
await initialize();
`;
}
//# sourceMappingURL=build.js.map