@build-script/heft-esbuild-plugin
Version:
lowlevel esbuild plugin for [heft]
166 lines (165 loc) • 6.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PLUGIN_NAME = void 0;
const common_1 = require("@idlebox/common");
const node_core_library_1 = require("@rushstack/node-core-library");
const config_js_1 = require("./common/config.js");
const execute_config_js_1 = require("./common/execute-config.js");
const misc_js_1 = require("./common/misc.js");
const write_js_1 = require("./common/write.js");
exports.PLUGIN_NAME = 'esbuild';
function emitResultErrors(result, session, rootDir) {
const createError = (item) => {
let e;
let msg;
if ('id' in item) {
msg = `${item.pluginName} [${item.id}] ${item.text}`;
}
else {
msg = `[Note] ${item.text}`;
}
if (item.location) {
e = new node_core_library_1.FileError(msg, {
projectFolder: rootDir,
absolutePath: item.location.file,
line: item.location.line,
column: item.location.column + 1,
});
}
else {
e = new Error(msg);
}
e.stack = e.message;
return e;
};
for (const error of result.errors) {
session.logger.emitError(createError(error));
for (const note of error.notes) {
session.logger.emitWarning(createError(note));
}
}
for (const warn of result.warnings) {
session.logger.emitWarning(createError(warn));
for (const note of warn.notes) {
session.logger.emitWarning(createError(note));
}
}
}
class ESBuildPlugin {
static PLUGIN_NAME = exports.PLUGIN_NAME;
PLUGIN_NAME = exports.PLUGIN_NAME;
apply(session, configuration, userInput) {
this.rootDir = (0, common_1.normalizePath)(configuration.buildFolderPath);
session.hooks.run.tapPromise(exports.PLUGIN_NAME, async () => {
const contexts = await this.getContext(session, configuration, userInput ?? {});
let writtenFiles = 0;
const allMeta = await Promise.all(contexts.map(async ({ context, options, emitter }) => {
const result = await context.rebuild();
emitResultErrors(result, session, this.rootDir);
const ret = await emitter({
metafile: result.metafile,
outputFiles: result.outputFiles,
options,
session,
});
writtenFiles += ret.writtenFiles;
return result.metafile;
}));
for (const e of allMeta) {
session.logger.terminal.writeLine(this._esbuild.analyzeMetafileSync(e));
}
showTip(contexts, writtenFiles);
await Promise.all(contexts.map(({ context }) => context.dispose()));
});
session.hooks.runIncremental.tapPromise(exports.PLUGIN_NAME, async () => {
const contexts = await this.getContext(session, configuration, userInput ?? {});
let writtenFiles = 0;
const allMeta = await Promise.all(contexts.map(async ({ context, options, emitter }) => {
const result = await context.rebuild();
emitResultErrors(result, session, this.rootDir);
const ret = await emitter({
metafile: result.metafile,
outputFiles: result.outputFiles,
options,
session,
});
writtenFiles += ret.writtenFiles;
return result.metafile;
}));
for (const e of allMeta) {
session.logger.terminal.writeVerboseLine(this._esbuild.analyzeMetafileSync(e));
}
showTip(contexts, writtenFiles);
});
function showTip(contexts, writtenFiles) {
const t1 = (0, misc_js_1.s)(contexts.length, 'project');
const t2 = (0, misc_js_1.s)(writtenFiles, 'file');
session.logger.terminal.writeLine(`complete build ${t1}, ${t2}.`);
}
}
async _initOptions(esbuild, session, configuration, userInput) {
let configFile;
for (const ext of ['.cts', '.mts', '.ts', '.cjs', '.mjs', '.json']) {
configFile = configuration.rigConfig.tryResolveConfigFilePath(`config/esbuild${ext}`);
if (configFile)
break;
}
if (!configFile) {
throw new Error('missing config file: config/esbuild.{ts|cjs|mjs|json}, it must `export const options: import("esbuild").BuildOptions` (or it\'s array)');
}
const configSession = {
esbuild,
logger: session.logger,
taskName: session.taskName,
rootDir: this.rootDir,
options: userInput,
tempFolderPath: session.tempFolderPath,
resolve(packageName) {
return configuration.rigPackageResolver.resolvePackageAsync(packageName, session.logger.terminal);
},
rigConfig: configuration.rigConfig,
watchFiles(_files) {
//TODO
},
};
Object.assign(globalThis, { session: configSession });
const { onEmit, options } = await (0, execute_config_js_1.executeConfigFile)(configFile, session, configuration);
Object.assign(globalThis, { session: undefined });
session.logger.terminal.writeVerboseLine(JSON.stringify(options, null, 4));
return {
optionsArray: options.map((e) => (0, config_js_1.filterOptions)(this.rootDir, e)),
onEmit,
};
}
async getEsbuild(session, configuration) {
if (!this._esbuild) {
session.logger.terminal.writeDebug('loading esbuild: ');
const esbuildPath = await configuration.rigPackageResolver.resolvePackageAsync('esbuild', session.logger.terminal);
session.logger.terminal.writeDebugLine(esbuildPath);
this._esbuild = require(esbuildPath);
}
return this._esbuild;
}
_contexts;
getContext(session, configuration, userInput) {
if (!this._contexts) {
this._contexts = this._getContext(session, configuration, userInput);
}
return this._contexts;
}
async _getContext(session, configuration, userInput) {
const esbuild = await this.getEsbuild(session, configuration);
const { optionsArray, onEmit } = await this._initOptions(esbuild, session, configuration, userInput);
const contexts = [];
for (const options of optionsArray) {
contexts.push({
context: await esbuild.context(options),
options,
emitter: (0, write_js_1.createEmitter)(onEmit),
});
}
return contexts;
}
}
exports.default = ESBuildPlugin;
//# sourceMappingURL=plugin.js.map