| | |
| | | const Compiler = require("./Compiler"); |
| | | const MultiCompiler = require("./MultiCompiler"); |
| | | const NormalModule = require("./NormalModule"); |
| | | const createSchemaValidation = require("./util/create-schema-validation"); |
| | | const { contextify } = require("./util/identifier"); |
| | | |
| | | /** @typedef {import("tapable").Tap} Tap */ |
| | | /** |
| | | * Defines the hook type used by this module. |
| | | * @template T, R, AdditionalOptions |
| | | * @typedef {import("tapable").Hook<T, R, AdditionalOptions>} Hook |
| | | */ |
| | | /** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginArgument} ProgressPluginArgument */ |
| | | /** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginOptions} ProgressPluginOptions */ |
| | | /** @typedef {import("./Compilation").FactorizeModuleOptions} FactorizeModuleOptions */ |
| | | /** @typedef {import("./Dependency")} Dependency */ |
| | | /** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */ |
| | |
| | | /** @typedef {import("./logging/Logger").Logger} Logger */ |
| | | |
| | | /** |
| | | * Defines the async queue type used by this module. |
| | | * @template T, K, R |
| | | * @typedef {import("./util/AsyncQueue")<T, K, R>} AsyncQueue |
| | | */ |
| | | |
| | | /** |
| | | * Defines the counts data type used by this module. |
| | | * @typedef {object} CountsData |
| | | * @property {number} modulesCount modules count |
| | | * @property {number} dependenciesCount dependencies count |
| | | */ |
| | | |
| | | const validate = createSchemaValidation( |
| | | require("../schemas/plugins/ProgressPlugin.check"), |
| | | () => require("../schemas/plugins/ProgressPlugin.json"), |
| | | { |
| | | name: "Progress Plugin", |
| | | baseDataPath: "options" |
| | | } |
| | | ); |
| | | |
| | | /** |
| | | * Returns median. |
| | | * @param {number} a a |
| | | * @param {number} b b |
| | | * @param {number} c c |
| | |
| | | /** @typedef {(percentage: number, msg: string, ...args: string[]) => void} HandlerFn */ |
| | | |
| | | /** |
| | | * Creates a default handler. |
| | | * @param {boolean | null | undefined} profile need profile |
| | | * @param {Logger} logger logger |
| | | * @returns {HandlerFn} default handler |
| | |
| | | const SKIPPED_QUEUE_CONTEXTS = ["import-module", "load-module"]; |
| | | |
| | | /** |
| | | * Defines the report progress callback. |
| | | * @callback ReportProgress |
| | | * @param {number} p percentage |
| | | * @param {...string} args additional arguments |
| | |
| | | |
| | | const PLUGIN_NAME = "ProgressPlugin"; |
| | | |
| | | /** @type {Required<Omit<ProgressPluginOptions, "handler">>} */ |
| | | const DEFAULT_OPTIONS = { |
| | | profile: false, |
| | | modulesCount: 5000, |
| | | dependenciesCount: 10000, |
| | | modules: true, |
| | | dependencies: true, |
| | | activeModules: false, |
| | | entries: true, |
| | | percentBy: null |
| | | }; |
| | | |
| | | class ProgressPlugin { |
| | | /** |
| | | * Returns a progress reporter, if any. |
| | | * @param {Compiler} compiler the current compiler |
| | | * @returns {ReportProgress | undefined} a progress reporter, if any |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Creates an instance of ProgressPlugin. |
| | | * @param {ProgressPluginArgument} options options |
| | | */ |
| | | constructor(options = {}) { |
| | |
| | | }; |
| | | } |
| | | |
| | | validate(options); |
| | | options = { ...ProgressPlugin.defaultOptions, ...options }; |
| | | /** @type {ProgressPluginOptions} */ |
| | | this.options = options; |
| | | |
| | | this.profile = options.profile; |
| | | this.handler = options.handler; |
| | | this.modulesCount = options.modulesCount; |
| | | this.dependenciesCount = options.dependenciesCount; |
| | | this.showEntries = options.entries; |
| | | this.showModules = options.modules; |
| | | this.showDependencies = options.dependencies; |
| | | this.showActiveModules = options.activeModules; |
| | | this.percentBy = options.percentBy; |
| | | const merged = { ...DEFAULT_OPTIONS, ...options }; |
| | | this.profile = merged.profile; |
| | | this.handler = merged.handler; |
| | | this.modulesCount = merged.modulesCount; |
| | | this.dependenciesCount = merged.dependenciesCount; |
| | | this.showEntries = merged.entries; |
| | | this.showModules = merged.modules; |
| | | this.showDependencies = merged.dependencies; |
| | | this.showActiveModules = merged.activeModules; |
| | | this.percentBy = merged.percentBy; |
| | | } |
| | | |
| | | /** |
| | | * Applies the plugin by registering its hooks on the compiler. |
| | | * @param {Compiler | MultiCompiler} compiler webpack compiler |
| | | * @returns {void} |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Apply on multi compiler. |
| | | * @param {MultiCompiler} compiler webpack multi-compiler |
| | | * @param {HandlerFn} handler function that executes for every progress step |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided compiler. |
| | | * @param {Compiler} compiler webpack compiler |
| | | * @param {HandlerFn} handler function that executes for every progress step |
| | | * @returns {void} |
| | | */ |
| | | _applyOnCompiler(compiler, handler) { |
| | | compiler.hooks.validate.tap(PLUGIN_NAME, () => { |
| | | compiler.validate( |
| | | () => require("../schemas/plugins/ProgressPlugin.json"), |
| | | this.options, |
| | | { |
| | | name: "Progress Plugin", |
| | | baseDataPath: "options" |
| | | }, |
| | | (options) => require("../schemas/plugins/ProgressPlugin.check")(options) |
| | | ); |
| | | }); |
| | | |
| | | const showEntries = this.showEntries; |
| | | const showModules = this.showModules; |
| | | const showDependencies = this.showDependencies; |
| | |
| | | let doneModules = 0; |
| | | let doneDependencies = 0; |
| | | let doneEntries = 0; |
| | | /** @type {Set<string>} */ |
| | | const activeModules = new Set(); |
| | | let lastUpdate = 0; |
| | | |
| | |
| | | const percentByDependencies = |
| | | doneDependencies / |
| | | Math.max(lastDependenciesCount || 1, dependenciesCount); |
| | | /** @type {number} */ |
| | | let percentageFactor; |
| | | |
| | | switch (this.percentBy) { |
| | |
| | | )}` |
| | | ); |
| | | } else { |
| | | /** @type {string[]} */ |
| | | const statItems = []; |
| | | if (showEntries) { |
| | | statItems.push(`${doneEntries}/${entriesCount} entries`); |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Processes the provided factorize queue. |
| | | * @template T |
| | | * @param {AsyncQueue<FactorizeModuleOptions, string, Module | ModuleFactoryResult>} factorizeQueue async queue |
| | | * @param {T} _item item |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Processes the provided add module queue. |
| | | * @template T |
| | | * @param {AsyncQueue<Module, string, Module>} addModuleQueue async queue |
| | | * @param {T} _item item |
| | |
| | | |
| | | // only used when showActiveModules is set |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {Module} module the module |
| | | */ |
| | | const moduleBuild = (module) => { |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Processes the provided entry. |
| | | * @param {Dependency} entry entry dependency |
| | | * @param {EntryOptions} options options object |
| | | */ |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {Module} module the module |
| | | */ |
| | | const moduleDone = (module) => { |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Processes the provided entry. |
| | | * @param {Dependency} entry entry dependency |
| | | * @param {EntryOptions} options options object |
| | | */ |
| | |
| | | |
| | | // @ts-expect-error avoid dynamic require if bundled with webpack |
| | | if (typeof __webpack_require__ !== "function") { |
| | | /** @type {Set<string>} */ |
| | | const requiredLoaders = new Set(); |
| | | NormalModule.getCompilationHooks(compilation).beforeLoaders.tap( |
| | | PLUGIN_NAME, |
| | |
| | | } |
| | | }); |
| | | /** |
| | | * Processes the provided hook. |
| | | * @template {Hook<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>} T |
| | | * @param {T} hook hook |
| | | * @param {number} progress progress from 0 to 1 |
| | |
| | | handler(progress, category, name); |
| | | }, |
| | | /** |
| | | * Processes the provided tap. |
| | | * @param {Tap} tap tap |
| | | */ |
| | | tap(tap) { |
| | |
| | | } |
| | | } |
| | | |
| | | ProgressPlugin.defaultOptions = { |
| | | profile: false, |
| | | modulesCount: 5000, |
| | | dependenciesCount: 10000, |
| | | modules: true, |
| | | dependencies: true, |
| | | activeModules: false, |
| | | entries: true |
| | | }; |
| | | ProgressPlugin.defaultOptions = DEFAULT_OPTIONS; |
| | | |
| | | ProgressPlugin.createDefaultHandler = createDefaultHandler; |
| | | |