UNPKG

kist

Version:

Package Pipeline Processor

110 lines (94 loc) 3.91 kB
// ============================================================================ // Import // ============================================================================ import { promises as fs } from "fs"; import path from "path"; import { minify, MinifyOptions } from "terser"; import { Action } from "../../core/pipeline/Action"; import { ActionOptionsType } from "../../types/ActionOptionsType"; import terserConfig from "./terser.config.js"; // ============================================================================ // Classes // ============================================================================ /** * JavaScriptMinifyAction handles the minification of JavaScript files. * Uses Terser to reduce file size and optimize performance. */ export class JavaScriptMinifyAction extends Action { /** * Executes the JavaScript minification action. * * @param options - The options containing input and output file paths. * @returns A Promise that resolves when the minification process completes. * @throws {Error} If input file is missing, minification fails, or output cannot be written. */ async execute(options: ActionOptionsType): Promise<void> { const { inputPath, outputPath, customConfig = {} } = options; if (!inputPath || !outputPath) { throw new Error( "Invalid options: 'inputPath' and 'outputPath' are required.", ); } this.logInfo( `Minifying JavaScript file: ${inputPath}${outputPath}`, ); try { await this.minifyFile(inputPath, outputPath, customConfig); this.logInfo(`JavaScript minification completed: ${outputPath}`); } catch (error) { this.logError("JavaScript minification failed.", error); throw error; } } /** * Minifies a JavaScript file using Terser. * * @param inputPath - Path to the input JavaScript file. * @param outputPath - Path where the minified file will be saved. * @param customConfig - Custom Terser configuration. * @returns A Promise that resolves when the minification is complete. */ private async minifyFile( inputPath: string, outputPath: string, customConfig: Record<string, any>, ): Promise<void> { try { const resolvedInputPath = path.resolve(inputPath); const resolvedOutputPath = path.resolve(outputPath); // Read JavaScript file const inputCode = await fs.readFile(resolvedInputPath, "utf8"); // Merge Terser configuration with explicit type casting const terserOptions: MinifyOptions = { ...terserConfig, ...customConfig, ecma: terserConfig.ecma as MinifyOptions["ecma"], // Ensure ecma is correctly typed nameCache: terserConfig.nameCache ?? undefined, // Ensure nameCache is undefined if null }; // Minify using Terser const result = await minify(inputCode, terserOptions); if (!result.code) { throw new Error("Minification resulted in empty output."); } // Write minified file await fs.writeFile(resolvedOutputPath, result.code, "utf8"); this.logDebug( `Minified JavaScript file saved to ${resolvedOutputPath}`, ); } catch (error) { this.logError( `Error minifying JavaScript file: ${inputPath}`, error, ); throw error; } } /** * Provides a description of the action. * * @returns A string description of the action. */ describe(): string { return "Minifies JavaScript files using Terser to reduce size and optimize performance."; } }