piral-cli-webpack5
Version:
Provides debug and build capabilities for pilets and Piral instances using Webpack v5.
112 lines (99 loc) • 2.93 kB
text/typescript
import * as webpack from 'webpack';
import { resolve, basename, dirname } from 'path';
import { EventEmitter } from 'events';
import type { LogLevels, BundleHandlerResponse } from 'piral-cli';
function getOutput(stats: webpack.Stats) {
const { outputPath, entrypoints } = stats.toJson();
for (const name of Object.keys(entrypoints)) {
const assets = entrypoints[name].assets;
const firstAsset = assets.find((m) => m.name.endsWith('.js') || m.name.endsWith('.mjs'));
if (firstAsset) {
return resolve(outputPath, firstAsset.name);
}
}
}
function getPreset(logLevel: LogLevels) {
switch (logLevel) {
case 0: //LogLevels.disabled
return 'none';
case 1: //LogLevels.error
return 'errors-only';
case 2: //LogLevels.warning
return 'errors-warnings';
case 4: //LogLevels.verbose
case 5: //LogLevels.debug
return 'verbose';
case 3: //LogLevels.info
default:
return 'normal';
}
}
export function runWebpack(wpConfig: webpack.Configuration, logLevel: LogLevels): BundleHandlerResponse {
const eventEmitter = new EventEmitter();
const outDir = wpConfig.output.path;
const bundle = {
outFile: '',
outDir,
name: '',
hash: '',
requireRef: undefined,
};
const updateBundle = (stats: webpack.Stats) => {
const file = getOutput(stats);
bundle.name = basename(file);
bundle.requireRef = stats.compilation.outputOptions?.uniqueName;
bundle.hash = stats.hash;
bundle.outFile = `/${basename(file)}`;
bundle.outDir = dirname(file);
};
wpConfig.plugins.push({
apply(compiler: webpack.Compiler) {
compiler.hooks.beforeCompile.tap('piral-cli', () => {
eventEmitter.emit('start');
});
compiler.hooks.done.tap('piral-cli', (stats) => {
updateBundle(stats);
eventEmitter.emit('end', bundle);
});
},
});
return {
bundle() {
return new Promise((resolve, reject) => {
const preset = {
current: undefined,
};
const process = webpack(wpConfig, (err, stats) => {
if (err) {
console.error(err);
reject(err);
} else {
console.log(
stats.toString({
...preset.current,
colors: true,
}),
);
if (stats.hasErrors()) {
reject(stats.toJson(preset.current));
} else {
updateBundle(stats);
resolve(bundle);
}
}
});
if (process) {
// process is undefined in case of an error
const compilation = process.createCompilation(undefined);
preset.current = compilation.createStatsOptions(getPreset(logLevel));
}
});
},
onStart(cb) {
eventEmitter.on('start', cb);
},
onEnd(cb) {
eventEmitter.on('end', cb);
},
};
}