UNPKG

css-mangle-webpack-plugin

Version:

This webpack plugin package is a CSS mangler that globally optimizes and shortens identifier names.

141 lines (121 loc) 6.23 kB
import { Compiler } from "webpack"; import { CSSMinificationManglerOptions, CSSMinificationManglerTranspiler, CSSQueryManglerTranspiler, CSSVariableManglerOptions, CSSVariableManglerTranspiler, DrivenManglerTranspiler } from "../core/mangler_transpiler"; import { CSSMangleReserved } from "../types"; import { ManglerUtil } from "../utils/mangler"; import "colors"; export interface CSSMangleWebpackPluginOptions { /** * Whether unique identifiers in JavaScript and JSX should not be * targets for transpilation. */ ignoreScript?: boolean; /** * This option value defines which bundle process stage of Webpack * to proceed with optimization task. */ processStage?: "OPTIMIZE" | "OPTIMIZE_INLINE"; printLogs?: "ALL" | "WARNING" | "NONE"; debugLogs?: "ALL" | "TIMEOUT" | "NONE"; reserved?: CSSMangleReserved; minify?: boolean | Partial<CSSMinificationManglerOptions>; mangle?: boolean | { variableName?: boolean | CSSVariableManglerOptions; className?: boolean; idName?: boolean; options?: { /** * Whether an undeclared identifier in this webpack plugin would * still be considered for minification. */ undeclared: boolean; } } } export class CSSMangleWebpackPlugin { transpilers: DrivenManglerTranspiler<any>[] = []; constructor(public options: CSSMangleWebpackPluginOptions) { if (options?.minify ?? false) { const minifyOptions = options.minify as CSSMinificationManglerOptions; this.transpilers.push(new CSSMinificationManglerTranspiler({ rgbToHex: minifyOptions?.rgbToHex ?? true, comments: minifyOptions?.comments ?? true, escapeSequence: minifyOptions?.escapeSequence ?? true })); } // When is not active to compress about the identifiers of CSS. if (!(options?.mangle ?? true)) return /** @ts-ignore */ const variableName: boolean = options?.mangle?.variableName ?? true; /** @ts-ignore */ const className: boolean = options?.mangle?.className ?? false; /** @ts-ignore */ const idName: boolean = options?.mangle?.idName ?? false; /** @ts-ignore */ const canUndeclared: boolean = options?.mangle?.options?.undeclared ?? false; // When a developer want to compress a variable names of CSS. if (variableName === true || variableName["property"] != null || variableName["literals"] != null) { this.transpilers.push(new CSSVariableManglerTranspiler({ reversed: [], canUndeclared: canUndeclared, property: variableName["property"] ?? true, literals: variableName["literals"] ?? true })); } // When a developer want to compress a class-names of CSS. if ((className ?? false) || (idName ?? false)) { this.transpilers.push(new CSSQueryManglerTranspiler()); } } apply(compiler: Compiler) { const useMangleScript = !(this.options?.ignoreScript ?? false); const processStage = this.options?.processStage ?? "OPTIMIZE_INLINE"; const debugLogs = this.options?.debugLogs ?? "TIMEOUT"; const reversed = this.options?.reserved ?? []; compiler.hooks.compilation.tap("CSSMangleWebpackPlugin", (compilation) => { compilation.hooks.processAssets.tap( { name: "CSSMangleWebpackPlugin", stage: processStage == "OPTIMIZE_INLINE" ? compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE : compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE }, (assets) => { for (const assetName in assets) { // When a given assets name and reversed assets names matched. if (reversed.find(name => name == assetName)) { return; } if (assetName.endsWith(".html") || assetName.endsWith(".js") && useMangleScript || assetName.endsWith(".jsx") && useMangleScript || assetName.endsWith(".css")) { const startTime = performance.now(); for (const transpiler of this.transpilers) { const source = assets[assetName].source().toString(); const result = transpiler.transform({ syntaxText: source, syntaxType: ManglerUtil.assetTypeOf(assetName) }); compilation.updateAsset(assetName, new compiler.webpack.sources.RawSource(result)); } if (debugLogs == "ALL" || debugLogs == "TIMEOUT") { const timeout = Math.round(performance.now() - startTime); // ms const message = "is minimized by (css-mangle-webpack-plugin)"; // Notifies a developer the current asset-name and timeout to microseconds format. console.log("asset " + assetName.green.bold + ` ${message} ` + `[${timeout}ms]`.yellow.bold); } } } if (this.options?.printLogs == "ALL" ?? false) { this.transpilers.forEach(e => e.context.parent.forEach(m => m.printLogs())); } if (this.options?.printLogs == "WARNING" ?? false) { this.transpilers.forEach(e => e.context.parent.forEach(m => m.printLogsUnused())); } } ); }); } }