mirror of https://github.com/webpack/webpack.git
commit
c17dfde7a8
|
|
@ -75,6 +75,16 @@ export type ExternalItem =
|
||||||
* via the `definition` "ArrayOfStringValues".
|
* via the `definition` "ArrayOfStringValues".
|
||||||
*/
|
*/
|
||||||
export type ArrayOfStringValues = string[];
|
export type ArrayOfStringValues = string[];
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `WebpackOptions`'s JSON-Schema
|
||||||
|
* via the `definition` "FilterTypes".
|
||||||
|
*/
|
||||||
|
export type FilterTypes = FilterItemTypes | FilterItemTypes[];
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `WebpackOptions`'s JSON-Schema
|
||||||
|
* via the `definition` "FilterItemTypes".
|
||||||
|
*/
|
||||||
|
export type FilterItemTypes = RegExp | string | ((value: string) => boolean);
|
||||||
/**
|
/**
|
||||||
* One or multiple rule conditions
|
* One or multiple rule conditions
|
||||||
*
|
*
|
||||||
|
|
@ -256,16 +266,6 @@ export type OptimizationSplitChunksSizes =
|
||||||
*/
|
*/
|
||||||
[k: string]: number;
|
[k: string]: number;
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* This interface was referenced by `WebpackOptions`'s JSON-Schema
|
|
||||||
* via the `definition` "FilterTypes".
|
|
||||||
*/
|
|
||||||
export type FilterTypes = FilterItemTypes | FilterItemTypes[];
|
|
||||||
/**
|
|
||||||
* This interface was referenced by `WebpackOptions`'s JSON-Schema
|
|
||||||
* via the `definition` "FilterItemTypes".
|
|
||||||
*/
|
|
||||||
export type FilterItemTypes = RegExp | string | Function;
|
|
||||||
|
|
||||||
export interface WebpackOptions {
|
export interface WebpackOptions {
|
||||||
/**
|
/**
|
||||||
|
|
@ -314,6 +314,19 @@ export interface WebpackOptions {
|
||||||
* Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`.
|
* Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`.
|
||||||
*/
|
*/
|
||||||
externals?: Externals;
|
externals?: Externals;
|
||||||
|
/**
|
||||||
|
* Options for infrastructure level logging
|
||||||
|
*/
|
||||||
|
infrastructureLogging?: {
|
||||||
|
/**
|
||||||
|
* Enable debug logging for specific loggers
|
||||||
|
*/
|
||||||
|
debug?: FilterTypes | boolean;
|
||||||
|
/**
|
||||||
|
* Log level
|
||||||
|
*/
|
||||||
|
level?: "none" | "error" | "warn" | "info" | "log" | "verbose";
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Custom values available in the loader context.
|
* Custom values available in the loader context.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1435,6 +1448,18 @@ export interface StatsOptions {
|
||||||
* add the hash of the compilation
|
* add the hash of the compilation
|
||||||
*/
|
*/
|
||||||
hash?: boolean;
|
hash?: boolean;
|
||||||
|
/**
|
||||||
|
* add logging output
|
||||||
|
*/
|
||||||
|
logging?: boolean | ("none" | "error" | "warn" | "info" | "log" | "verbose");
|
||||||
|
/**
|
||||||
|
* Include debug logging of specified loggers (i. e. for plugins or loaders). Filters can be Strings, RegExps or Functions
|
||||||
|
*/
|
||||||
|
loggingDebug?: FilterTypes | boolean;
|
||||||
|
/**
|
||||||
|
* add stack traces to logging output
|
||||||
|
*/
|
||||||
|
loggingTrace?: boolean;
|
||||||
/**
|
/**
|
||||||
* Set the maximum number of modules to be shown
|
* Set the maximum number of modules to be shown
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ const ChunkRenderError = require("./ChunkRenderError");
|
||||||
const ChunkTemplate = require("./ChunkTemplate");
|
const ChunkTemplate = require("./ChunkTemplate");
|
||||||
const DependencyTemplates = require("./DependencyTemplates");
|
const DependencyTemplates = require("./DependencyTemplates");
|
||||||
const Entrypoint = require("./Entrypoint");
|
const Entrypoint = require("./Entrypoint");
|
||||||
|
const ErrorHelpers = require("./ErrorHelpers");
|
||||||
const FileSystemInfo = require("./FileSystemInfo");
|
const FileSystemInfo = require("./FileSystemInfo");
|
||||||
const {
|
const {
|
||||||
connectChunkGroupAndChunk,
|
connectChunkGroupAndChunk,
|
||||||
|
|
@ -41,6 +42,7 @@ const RuntimeGlobals = require("./RuntimeGlobals");
|
||||||
const RuntimeTemplate = require("./RuntimeTemplate");
|
const RuntimeTemplate = require("./RuntimeTemplate");
|
||||||
const Stats = require("./Stats");
|
const Stats = require("./Stats");
|
||||||
const WebpackError = require("./WebpackError");
|
const WebpackError = require("./WebpackError");
|
||||||
|
const { Logger, LogType } = require("./logging/Logger");
|
||||||
const StatsFactory = require("./stats/StatsFactory");
|
const StatsFactory = require("./stats/StatsFactory");
|
||||||
const StatsPrinter = require("./stats/StatsPrinter");
|
const StatsPrinter = require("./stats/StatsPrinter");
|
||||||
const AsyncQueue = require("./util/AsyncQueue");
|
const AsyncQueue = require("./util/AsyncQueue");
|
||||||
|
|
@ -127,6 +129,14 @@ const { arrayToSetDeprecation } = require("./util/deprecation");
|
||||||
* @property {(Record<string, (length: number) => string>)=} contentHashWithLength
|
* @property {(Record<string, (length: number) => string>)=} contentHashWithLength
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} LogEntry
|
||||||
|
* @property {string} type
|
||||||
|
* @property {any[]} args
|
||||||
|
* @property {number} time
|
||||||
|
* @property {string[]=} trace
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} ModulePathData
|
* @typedef {Object} ModulePathData
|
||||||
* @property {string|number} id
|
* @property {string|number} id
|
||||||
|
|
@ -405,6 +415,9 @@ class Compilation {
|
||||||
"compilerIndex"
|
"compilerIndex"
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
/** @type {SyncBailHook<[string, LogEntry], true>} */
|
||||||
|
log: new SyncBailHook(["origin", "logEntry"]),
|
||||||
|
|
||||||
/** @type {HookMap<SyncHook<[Object, Object]>>} */
|
/** @type {HookMap<SyncHook<[Object, Object]>>} */
|
||||||
statsPreset: new HookMap(() => new SyncHook(["options", "context"])),
|
statsPreset: new HookMap(() => new SyncHook(["options", "context"])),
|
||||||
/** @type {SyncHook<[Object, Object]>} */
|
/** @type {SyncHook<[Object, Object]>} */
|
||||||
|
|
@ -520,6 +533,8 @@ class Compilation {
|
||||||
this.warnings = [];
|
this.warnings = [];
|
||||||
/** @type {Compilation[]} */
|
/** @type {Compilation[]} */
|
||||||
this.children = [];
|
this.children = [];
|
||||||
|
/** @type {Map<string, LogEntry[]>} */
|
||||||
|
this.logging = new Map();
|
||||||
/** @type {Map<DepConstructor, ModuleFactory>} */
|
/** @type {Map<DepConstructor, ModuleFactory>} */
|
||||||
this.dependencyFactories = new Map();
|
this.dependencyFactories = new Map();
|
||||||
/** @type {DependencyTemplates} */
|
/** @type {DependencyTemplates} */
|
||||||
|
|
@ -582,6 +597,69 @@ class Compilation {
|
||||||
return statsPrinter;
|
return statsPrinter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string | (function(): string)} name name of the logger, or function called once to get the logger name
|
||||||
|
* @returns {Logger} a logger with that name
|
||||||
|
*/
|
||||||
|
getLogger(name) {
|
||||||
|
if (!name) {
|
||||||
|
throw new TypeError("Compilation.getLogger(name) called without a name");
|
||||||
|
}
|
||||||
|
/** @type {LogEntry[] | undefined} */
|
||||||
|
let logEntries;
|
||||||
|
return new Logger((type, args) => {
|
||||||
|
if (typeof name === "function") {
|
||||||
|
name = name();
|
||||||
|
if (!name) {
|
||||||
|
throw new TypeError(
|
||||||
|
"Compilation.getLogger(name) called with a function not returning a name"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let trace;
|
||||||
|
switch (type) {
|
||||||
|
case LogType.warn:
|
||||||
|
case LogType.error:
|
||||||
|
case LogType.trace:
|
||||||
|
trace = ErrorHelpers.cutOffLoaderExecution(new Error("Trace").stack)
|
||||||
|
.split("\n")
|
||||||
|
.slice(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/** @type {LogEntry} */
|
||||||
|
const logEntry = {
|
||||||
|
time: Date.now(),
|
||||||
|
type,
|
||||||
|
args,
|
||||||
|
trace
|
||||||
|
};
|
||||||
|
if (this.hooks.log.call(name, logEntry) === undefined) {
|
||||||
|
if (logEntry.type === LogType.profileEnd) {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.profileEnd === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.profileEnd(`[${name}] ${logEntry.args[0]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (logEntries === undefined) {
|
||||||
|
logEntries = this.logging.get(name);
|
||||||
|
if (logEntries === undefined) {
|
||||||
|
logEntries = [];
|
||||||
|
this.logging.set(name, logEntries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logEntries.push(logEntry);
|
||||||
|
if (logEntry.type === LogType.profile) {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.profile === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.profile(`[${name}] ${logEntry.args[0]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Module} module module to be added that was created
|
* @param {Module} module module to be added that was created
|
||||||
* @param {ModuleCallback} callback returns the module in the compilation,
|
* @param {ModuleCallback} callback returns the module in the compilation,
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ const RequestShortener = require("./RequestShortener");
|
||||||
const ResolverFactory = require("./ResolverFactory");
|
const ResolverFactory = require("./ResolverFactory");
|
||||||
const Stats = require("./Stats");
|
const Stats = require("./Stats");
|
||||||
const Watching = require("./Watching");
|
const Watching = require("./Watching");
|
||||||
|
const { Logger } = require("./logging/Logger");
|
||||||
const { join, dirname, mkdirp } = require("./util/fs");
|
const { join, dirname, mkdirp } = require("./util/fs");
|
||||||
const { makePathsRelative } = require("./util/identifier");
|
const { makePathsRelative } = require("./util/identifier");
|
||||||
|
|
||||||
|
|
@ -133,6 +134,9 @@ class Compiler {
|
||||||
/** @type {SyncHook<[]>} */
|
/** @type {SyncHook<[]>} */
|
||||||
watchClose: new SyncHook([]),
|
watchClose: new SyncHook([]),
|
||||||
|
|
||||||
|
/** @type {SyncBailHook<[string, string, any[]], true>} */
|
||||||
|
infrastructurelog: new SyncBailHook(["origin", "type", "args"]),
|
||||||
|
|
||||||
// TODO the following hooks are weirdly located here
|
// TODO the following hooks are weirdly located here
|
||||||
// TODO move them for webpack 5
|
// TODO move them for webpack 5
|
||||||
/** @type {SyncHook<[]>} */
|
/** @type {SyncHook<[]>} */
|
||||||
|
|
@ -178,6 +182,8 @@ class Compiler {
|
||||||
/** @type {ResolverFactory} */
|
/** @type {ResolverFactory} */
|
||||||
this.resolverFactory = new ResolverFactory();
|
this.resolverFactory = new ResolverFactory();
|
||||||
|
|
||||||
|
this.infrastructureLogger = undefined;
|
||||||
|
|
||||||
/** @type {WebpackOptions} */
|
/** @type {WebpackOptions} */
|
||||||
this.options = /** @type {WebpackOptions} */ ({});
|
this.options = /** @type {WebpackOptions} */ ({});
|
||||||
|
|
||||||
|
|
@ -201,6 +207,33 @@ class Compiler {
|
||||||
this._assetEmittingWrittenFiles = new Map();
|
this._assetEmittingWrittenFiles = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string | (function(): string)} name name of the logger, or function called once to get the logger name
|
||||||
|
* @returns {Logger} a logger with that name
|
||||||
|
*/
|
||||||
|
getInfrastructureLogger(name) {
|
||||||
|
if (!name) {
|
||||||
|
throw new TypeError(
|
||||||
|
"Compiler.getInfrastructureLogger(name) called without a name"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return new Logger((type, args) => {
|
||||||
|
if (typeof name === "function") {
|
||||||
|
name = name();
|
||||||
|
if (!name) {
|
||||||
|
throw new TypeError(
|
||||||
|
"Compiler.getInfrastructureLogger(name) called with a function not returning a name"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.hooks.infrastructurelog.call(name, type, args) === undefined) {
|
||||||
|
if (this.infrastructureLogger !== undefined) {
|
||||||
|
this.infrastructureLogger(name, type, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {WatchOptions} watchOptions the watcher's options
|
* @param {WatchOptions} watchOptions the watcher's options
|
||||||
* @param {Callback<Stats>} handler signals when the call finishes
|
* @param {Callback<Stats>} handler signals when the call finishes
|
||||||
|
|
|
||||||
|
|
@ -248,16 +248,20 @@ class NormalModule extends Module {
|
||||||
|
|
||||||
createLoaderContext(resolver, options, compilation, fs) {
|
createLoaderContext(resolver, options, compilation, fs) {
|
||||||
const requestShortener = compilation.runtimeTemplate.requestShortener;
|
const requestShortener = compilation.runtimeTemplate.requestShortener;
|
||||||
|
const getCurrentLoaderName = () => {
|
||||||
|
const currentLoader = this.getCurrentLoader(loaderContext);
|
||||||
|
if (!currentLoader) return "(not in loader scope)";
|
||||||
|
return requestShortener.shorten(currentLoader.loader);
|
||||||
|
};
|
||||||
const loaderContext = {
|
const loaderContext = {
|
||||||
version: 2,
|
version: 2,
|
||||||
emitWarning: warning => {
|
emitWarning: warning => {
|
||||||
if (!(warning instanceof Error)) {
|
if (!(warning instanceof Error)) {
|
||||||
warning = new NonErrorEmittedError(warning);
|
warning = new NonErrorEmittedError(warning);
|
||||||
}
|
}
|
||||||
const currentLoader = this.getCurrentLoader(loaderContext);
|
|
||||||
this.warnings.push(
|
this.warnings.push(
|
||||||
new ModuleWarning(warning, {
|
new ModuleWarning(warning, {
|
||||||
from: requestShortener.shorten(currentLoader.loader)
|
from: getCurrentLoaderName()
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -265,13 +269,20 @@ class NormalModule extends Module {
|
||||||
if (!(error instanceof Error)) {
|
if (!(error instanceof Error)) {
|
||||||
error = new NonErrorEmittedError(error);
|
error = new NonErrorEmittedError(error);
|
||||||
}
|
}
|
||||||
const currentLoader = this.getCurrentLoader(loaderContext);
|
|
||||||
this.errors.push(
|
this.errors.push(
|
||||||
new ModuleError(error, {
|
new ModuleError(error, {
|
||||||
from: requestShortener.shorten(currentLoader.loader)
|
from: getCurrentLoaderName()
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
getLogger: name => {
|
||||||
|
const currentLoader = this.getCurrentLoader(loaderContext);
|
||||||
|
return compilation.getLogger(() =>
|
||||||
|
[currentLoader && currentLoader.loader, name, this.identifier()]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join("|")
|
||||||
|
);
|
||||||
|
},
|
||||||
resolve(context, request, callback) {
|
resolve(context, request, callback) {
|
||||||
resolver.resolve({}, context, request, {}, callback);
|
resolver.resolve({}, context, request, {}, callback);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -443,6 +443,12 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
|
||||||
this.set("resolveLoader.mainFields", ["loader", "main"]);
|
this.set("resolveLoader.mainFields", ["loader", "main"]);
|
||||||
this.set("resolveLoader.extensions", [".js"]);
|
this.set("resolveLoader.extensions", [".js"]);
|
||||||
this.set("resolveLoader.mainFiles", ["index"]);
|
this.set("resolveLoader.mainFiles", ["index"]);
|
||||||
|
|
||||||
|
this.set("infrastructureLogging", "call", value =>
|
||||||
|
Object.assign({}, value)
|
||||||
|
);
|
||||||
|
this.set("infrastructureLogging.level", "info");
|
||||||
|
this.set("infrastructureLogging.debug", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Tobias Koppers @sokra
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
const LogType = Object.freeze({
|
||||||
|
error: "error", // message, c style arguments
|
||||||
|
warn: "warn", // message, c style arguments
|
||||||
|
info: "info", // message, c style arguments
|
||||||
|
log: "log", // message, c style arguments
|
||||||
|
debug: "debug", // message, c style arguments
|
||||||
|
|
||||||
|
trace: "trace", // no arguments
|
||||||
|
|
||||||
|
group: "group", // [label]
|
||||||
|
groupCollapsed: "groupCollapsed", // [label]
|
||||||
|
groupEnd: "groupEnd", // [label]
|
||||||
|
|
||||||
|
profile: "profile", // [profileName]
|
||||||
|
profileEnd: "profileEnd", // [profileName]
|
||||||
|
|
||||||
|
time: "time", // name, time as [seconds, nanoseconds]
|
||||||
|
|
||||||
|
clear: "clear" // no arguments
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.LogType = LogType;
|
||||||
|
|
||||||
|
/** @typedef {LogType} LogTypeEnum */
|
||||||
|
|
||||||
|
const LOG_SYMBOL = Symbol("webpack logger raw log method");
|
||||||
|
const TIMERS_SYMBOL = Symbol("webpack logger times");
|
||||||
|
|
||||||
|
class WebpackLogger {
|
||||||
|
/**
|
||||||
|
* @param {function(LogType, any[]=): void} log log function
|
||||||
|
*/
|
||||||
|
constructor(log) {
|
||||||
|
this[LOG_SYMBOL] = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
error(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.error, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.warn, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
info(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.info, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.log, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.debug, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(assertion, ...args) {
|
||||||
|
if (!assertion) {
|
||||||
|
this[LOG_SYMBOL](LogType.error, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace() {
|
||||||
|
this[LOG_SYMBOL](LogType.trace, ["Trace"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this[LOG_SYMBOL](LogType.clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
group(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.group, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupCollapsed(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.groupCollapsed, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupEnd(...args) {
|
||||||
|
this[LOG_SYMBOL](LogType.groupEnd, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
profile(label) {
|
||||||
|
this[LOG_SYMBOL](LogType.profile, [label]);
|
||||||
|
}
|
||||||
|
|
||||||
|
profileEnd(label) {
|
||||||
|
this[LOG_SYMBOL](LogType.profileEnd, [label]);
|
||||||
|
}
|
||||||
|
|
||||||
|
time(label) {
|
||||||
|
this[TIMERS_SYMBOL] = this[TIMERS_SYMBOL] || new Map();
|
||||||
|
this[TIMERS_SYMBOL].set(label, process.hrtime());
|
||||||
|
}
|
||||||
|
|
||||||
|
timeLog(label) {
|
||||||
|
const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
|
||||||
|
if (!prev) {
|
||||||
|
throw new Error(`No such label '${label}' for WebpackLogger.timeLog()`);
|
||||||
|
}
|
||||||
|
const time = process.hrtime(prev);
|
||||||
|
this[LOG_SYMBOL](LogType.time, [label, ...time]);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeEnd(label) {
|
||||||
|
const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
|
||||||
|
if (!prev) {
|
||||||
|
throw new Error(`No such label '${label}' for WebpackLogger.timeEnd()`);
|
||||||
|
}
|
||||||
|
const time = process.hrtime(prev);
|
||||||
|
this[TIMERS_SYMBOL].delete(label);
|
||||||
|
this[LOG_SYMBOL](LogType.time, [label, ...time]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.Logger = WebpackLogger;
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Tobias Koppers @sokra
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { LogType } = require("./Logger");
|
||||||
|
|
||||||
|
/** @typedef {import("../../declarations/WebpackOptions").FilterItemTypes} FilterItemTypes */
|
||||||
|
/** @typedef {import("../../declarations/WebpackOptions").FilterTypes} FilterTypes */
|
||||||
|
/** @typedef {import("./Logger").LogTypeEnum} LogTypeEnum */
|
||||||
|
|
||||||
|
/** @typedef {function(string): boolean} FilterFunction */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} LoggerOptions
|
||||||
|
* @property {false|true|"none"|"error"|"warn"|"info"|"log"|"verbose"} options.level loglevel
|
||||||
|
* @property {FilterTypes|boolean} options.debug filter for debug logging
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FilterItemTypes} item an input item
|
||||||
|
* @returns {FilterFunction} filter funtion
|
||||||
|
*/
|
||||||
|
const filterToFunction = item => {
|
||||||
|
if (typeof item === "string") {
|
||||||
|
const regExp = new RegExp(
|
||||||
|
`[\\\\/]${item.replace(
|
||||||
|
// eslint-disable-next-line no-useless-escape
|
||||||
|
/[-[\]{}()*+?.\\^$|]/g,
|
||||||
|
"\\$&"
|
||||||
|
)}([\\\\/]|$|!|\\?)`
|
||||||
|
);
|
||||||
|
return ident => regExp.test(ident);
|
||||||
|
}
|
||||||
|
if (item && typeof item === "object" && typeof item.test === "function") {
|
||||||
|
return ident => item.test(ident);
|
||||||
|
}
|
||||||
|
if (typeof item === "function") {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
if (typeof item === "boolean") {
|
||||||
|
return () => item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {number} */
|
||||||
|
const LogLevel = {
|
||||||
|
none: 6,
|
||||||
|
false: 6,
|
||||||
|
error: 5,
|
||||||
|
warn: 4,
|
||||||
|
info: 3,
|
||||||
|
log: 2,
|
||||||
|
true: 2,
|
||||||
|
verbose: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {LoggerOptions} options options object
|
||||||
|
* @returns {function(string, LogTypeEnum, any[]): void} logging function
|
||||||
|
*/
|
||||||
|
module.exports = ({ level = "info", debug = false }) => {
|
||||||
|
const debugFilters =
|
||||||
|
typeof debug === "boolean"
|
||||||
|
? [() => debug]
|
||||||
|
: /** @type {FilterItemTypes[]} */ ([])
|
||||||
|
.concat(debug)
|
||||||
|
.map(filterToFunction);
|
||||||
|
/** @type {number} */
|
||||||
|
const loglevel = LogLevel[`${level}`] || 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name name of the logger
|
||||||
|
* @param {LogTypeEnum} type type of the log entry
|
||||||
|
* @param {any[]} args arguments of the log entry
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
const logger = (name, type, args) => {
|
||||||
|
const labeledArgs = (prefix = "") => {
|
||||||
|
if (Array.isArray(args)) {
|
||||||
|
if (args.length > 0 && typeof args[0] === "string") {
|
||||||
|
return [`${prefix}[${name}] ${args[0]}`, ...args.slice(1)];
|
||||||
|
} else {
|
||||||
|
return [`${prefix}[${name}]`, ...args];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const debug = debugFilters.some(f => f(name));
|
||||||
|
switch (type) {
|
||||||
|
case LogType.debug:
|
||||||
|
if (!debug) return;
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.debug === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.debug(...labeledArgs());
|
||||||
|
} else {
|
||||||
|
console.log(...labeledArgs());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LogType.log:
|
||||||
|
if (!debug && loglevel > LogLevel.log) return;
|
||||||
|
console.log(...labeledArgs());
|
||||||
|
break;
|
||||||
|
case LogType.info:
|
||||||
|
if (!debug && loglevel > LogLevel.info) return;
|
||||||
|
console.info(...labeledArgs("<i> "));
|
||||||
|
break;
|
||||||
|
case LogType.warn:
|
||||||
|
if (!debug && loglevel > LogLevel.warn) return;
|
||||||
|
console.warn(...labeledArgs("<w> "));
|
||||||
|
break;
|
||||||
|
case LogType.error:
|
||||||
|
if (!debug && loglevel > LogLevel.error) return;
|
||||||
|
console.error(...labeledArgs("<e> "));
|
||||||
|
break;
|
||||||
|
case LogType.trace:
|
||||||
|
if (!debug) return;
|
||||||
|
console.trace();
|
||||||
|
break;
|
||||||
|
case LogType.group:
|
||||||
|
if (!debug && loglevel > LogLevel.log) return;
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.group === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.group(...labeledArgs());
|
||||||
|
} else {
|
||||||
|
console.log(...labeledArgs());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LogType.groupCollapsed:
|
||||||
|
if (!debug && loglevel > LogLevel.log) return;
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.groupCollapsed === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.groupCollapsed(...labeledArgs());
|
||||||
|
} else {
|
||||||
|
console.log(...labeledArgs("<g> "));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LogType.groupEnd:
|
||||||
|
if (!debug && loglevel > LogLevel.log) return;
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.groupEnd === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.groupEnd();
|
||||||
|
} else {
|
||||||
|
console.log(...labeledArgs("</g> "));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LogType.time:
|
||||||
|
if (!debug && loglevel > LogLevel.log) return;
|
||||||
|
console.log(
|
||||||
|
`[${name}] ${args[0]}: ${args[1] * 1000 + args[2] / 1000000}ms`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case LogType.profile:
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.profile === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.profile(...labeledArgs());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LogType.profileEnd:
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.profileEnd === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.profileEnd(...labeledArgs());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LogType.clear:
|
||||||
|
if (!debug && loglevel > LogLevel.log) return;
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
if (typeof console.clear === "function") {
|
||||||
|
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||||
|
console.clear();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unexpected LogType ${type}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return logger;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Tobias Koppers @sokra
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const SyncBailHook = require("tapable/lib/SyncBailHook");
|
||||||
|
const { Logger } = require("./Logger");
|
||||||
|
const createConsoleLogger = require("./createConsoleLogger");
|
||||||
|
|
||||||
|
/** @type {createConsoleLogger.LoggerOptions} */
|
||||||
|
let currentDefaultLoggerOptions = {
|
||||||
|
level: "info",
|
||||||
|
debug: false
|
||||||
|
};
|
||||||
|
let currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name name of the logger
|
||||||
|
* @returns {Logger} a logger
|
||||||
|
*/
|
||||||
|
exports.getLogger = name => {
|
||||||
|
return new Logger((type, args) => {
|
||||||
|
if (exports.hooks.log.call(name, type, args) === undefined) {
|
||||||
|
currentDefaultLogger(name, type, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {createConsoleLogger.LoggerOptions} options new options, merge with old options
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
exports.configureDefaultLogger = options => {
|
||||||
|
Object.assign(currentDefaultLoggerOptions, options);
|
||||||
|
currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.hooks = {
|
||||||
|
log: new SyncBailHook(["origin", "type", "args"])
|
||||||
|
};
|
||||||
|
|
@ -7,16 +7,30 @@
|
||||||
|
|
||||||
const CachedInputFileSystem = require("enhanced-resolve/lib/CachedInputFileSystem");
|
const CachedInputFileSystem = require("enhanced-resolve/lib/CachedInputFileSystem");
|
||||||
const fs = require("graceful-fs");
|
const fs = require("graceful-fs");
|
||||||
|
const createConsoleLogger = require("../logging/createConsoleLogger");
|
||||||
const NodeWatchFileSystem = require("./NodeWatchFileSystem");
|
const NodeWatchFileSystem = require("./NodeWatchFileSystem");
|
||||||
|
|
||||||
/** @typedef {import("../Compiler")} Compiler */
|
/** @typedef {import("../Compiler")} Compiler */
|
||||||
|
|
||||||
class NodeEnvironmentPlugin {
|
class NodeEnvironmentPlugin {
|
||||||
|
constructor(options) {
|
||||||
|
this.options = options || {};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Compiler} compiler the compiler instance
|
* @param {Compiler} compiler the compiler instance
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
apply(compiler) {
|
apply(compiler) {
|
||||||
|
compiler.infrastructureLogger = createConsoleLogger(
|
||||||
|
Object.assign(
|
||||||
|
{
|
||||||
|
level: "info",
|
||||||
|
debug: false
|
||||||
|
},
|
||||||
|
this.options.infrastructureLogging
|
||||||
|
)
|
||||||
|
);
|
||||||
compiler.inputFileSystem = new CachedInputFileSystem(fs, 60000);
|
compiler.inputFileSystem = new CachedInputFileSystem(fs, 60000);
|
||||||
const inputFileSystem = compiler.inputFileSystem;
|
const inputFileSystem = compiler.inputFileSystem;
|
||||||
compiler.outputFileSystem = fs;
|
compiler.outputFileSystem = fs;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const formatLocation = require("../formatLocation");
|
const formatLocation = require("../formatLocation");
|
||||||
|
const { LogType } = require("../logging/Logger");
|
||||||
const AggressiveSplittingPlugin = require("../optimize/AggressiveSplittingPlugin");
|
const AggressiveSplittingPlugin = require("../optimize/AggressiveSplittingPlugin");
|
||||||
const ConcatenatedModule = require("../optimize/ConcatenatedModule");
|
const ConcatenatedModule = require("../optimize/ConcatenatedModule");
|
||||||
const SizeLimitsPlugin = require("../performance/SizeLimitsPlugin");
|
const SizeLimitsPlugin = require("../performance/SizeLimitsPlugin");
|
||||||
|
|
@ -19,6 +20,7 @@ const {
|
||||||
compareModulesById,
|
compareModulesById,
|
||||||
compareModulesByIdOrIdentifier
|
compareModulesByIdOrIdentifier
|
||||||
} = require("../util/comparators");
|
} = require("../util/comparators");
|
||||||
|
const identifierUtils = require("../util/identifier");
|
||||||
|
|
||||||
/** @typedef {import("webpack-sources").Source} Source */
|
/** @typedef {import("webpack-sources").Source} Source */
|
||||||
/** @typedef {import("../Chunk")} Chunk */
|
/** @typedef {import("../Chunk")} Chunk */
|
||||||
|
|
@ -46,6 +48,7 @@ const {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} UsualOptions
|
* @typedef {Object} UsualOptions
|
||||||
|
* @property {string} context
|
||||||
* @property {RequestShortener} requestShortener
|
* @property {RequestShortener} requestShortener
|
||||||
* @property {string} chunksSort
|
* @property {string} chunksSort
|
||||||
* @property {string} modulesSort
|
* @property {string} modulesSort
|
||||||
|
|
@ -54,6 +57,9 @@ const {
|
||||||
* @property {Function[]} excludeModules
|
* @property {Function[]} excludeModules
|
||||||
* @property {Function[]} warningsFilter
|
* @property {Function[]} warningsFilter
|
||||||
* @property {number} maxModules
|
* @property {number} maxModules
|
||||||
|
* @property {false|"none"|"error"|"warn"|"info"|"log"|"verbose"} logging
|
||||||
|
* @property {Function[]} loggingDebug
|
||||||
|
* @property {boolean} loggingTrace
|
||||||
* @property {any} _env
|
* @property {any} _env
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -280,6 +286,128 @@ const SIMPLE_EXTRACTORS = {
|
||||||
context
|
context
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
logging: (object, compilation, _context, options, factory) => {
|
||||||
|
const util = require("util");
|
||||||
|
const { loggingDebug, loggingTrace, context } = options;
|
||||||
|
object.logging = {};
|
||||||
|
let acceptedTypes;
|
||||||
|
let collapsedGroups = false;
|
||||||
|
switch (options.logging) {
|
||||||
|
case "none":
|
||||||
|
acceptedTypes = new Set([]);
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
|
acceptedTypes = new Set([LogType.error]);
|
||||||
|
break;
|
||||||
|
case "warn":
|
||||||
|
acceptedTypes = new Set([LogType.error, LogType.warn]);
|
||||||
|
break;
|
||||||
|
case "info":
|
||||||
|
acceptedTypes = new Set([LogType.error, LogType.warn, LogType.info]);
|
||||||
|
break;
|
||||||
|
case "log":
|
||||||
|
acceptedTypes = new Set([
|
||||||
|
LogType.error,
|
||||||
|
LogType.warn,
|
||||||
|
LogType.info,
|
||||||
|
LogType.log,
|
||||||
|
LogType.group,
|
||||||
|
LogType.groupEnd,
|
||||||
|
LogType.groupCollapsed,
|
||||||
|
LogType.clear
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
case "verbose":
|
||||||
|
acceptedTypes = new Set([
|
||||||
|
LogType.error,
|
||||||
|
LogType.warn,
|
||||||
|
LogType.info,
|
||||||
|
LogType.log,
|
||||||
|
LogType.group,
|
||||||
|
LogType.groupEnd,
|
||||||
|
LogType.groupCollapsed,
|
||||||
|
LogType.profile,
|
||||||
|
LogType.profileEnd,
|
||||||
|
LogType.time,
|
||||||
|
LogType.clear
|
||||||
|
]);
|
||||||
|
collapsedGroups = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let depthInCollapsedGroup = 0;
|
||||||
|
for (const [origin, logEntries] of compilation.logging) {
|
||||||
|
const debugMode = loggingDebug.some(fn => fn(origin));
|
||||||
|
const groupStack = [];
|
||||||
|
const rootList = [];
|
||||||
|
let currentList = rootList;
|
||||||
|
let processedLogEntries = 0;
|
||||||
|
for (const entry of logEntries) {
|
||||||
|
let type = entry.type;
|
||||||
|
if (!debugMode && !acceptedTypes.has(type)) continue;
|
||||||
|
|
||||||
|
// Expand groups in verbose and debug modes
|
||||||
|
if (type === LogType.groupCollapsed && (debugMode || collapsedGroups))
|
||||||
|
type = LogType.group;
|
||||||
|
|
||||||
|
if (depthInCollapsedGroup === 0) {
|
||||||
|
processedLogEntries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === LogType.groupEnd) {
|
||||||
|
groupStack.pop();
|
||||||
|
if (groupStack.length > 0) {
|
||||||
|
currentList = groupStack[groupStack.length - 1].children;
|
||||||
|
} else {
|
||||||
|
currentList = rootList;
|
||||||
|
}
|
||||||
|
if (depthInCollapsedGroup > 0) depthInCollapsedGroup--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let message = undefined;
|
||||||
|
if (entry.type === LogType.time) {
|
||||||
|
message = `${entry.args[0]}: ${entry.args[1] * 1000 +
|
||||||
|
entry.args[2] / 1000000}ms`;
|
||||||
|
} else if (entry.args && entry.args.length > 0) {
|
||||||
|
message = util.format(entry.args[0], ...entry.args.slice(1));
|
||||||
|
}
|
||||||
|
const newEntry = {
|
||||||
|
...entry,
|
||||||
|
type,
|
||||||
|
message,
|
||||||
|
trace: loggingTrace ? entry.trace : undefined,
|
||||||
|
children:
|
||||||
|
type === LogType.group || type === LogType.groupCollapsed
|
||||||
|
? []
|
||||||
|
: undefined
|
||||||
|
};
|
||||||
|
currentList.push(newEntry);
|
||||||
|
if (newEntry.children) {
|
||||||
|
groupStack.push(newEntry);
|
||||||
|
currentList = newEntry.children;
|
||||||
|
if (depthInCollapsedGroup > 0) {
|
||||||
|
depthInCollapsedGroup++;
|
||||||
|
} else if (type === LogType.groupCollapsed) {
|
||||||
|
depthInCollapsedGroup = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let name = identifierUtils
|
||||||
|
.makePathsRelative(context, origin, compilation.cache)
|
||||||
|
.replace(/\|/g, " ");
|
||||||
|
if (name in object.logging) {
|
||||||
|
let i = 1;
|
||||||
|
while (`${name}#${i}` in object.logging) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
name = `${name}#${i}`;
|
||||||
|
}
|
||||||
|
object.logging[name] = {
|
||||||
|
entries: rootList,
|
||||||
|
filteredEntries: logEntries.length - processedLogEntries,
|
||||||
|
debug: debugMode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
children: (object, compilation, context, options, factory) => {
|
children: (object, compilation, context, options, factory) => {
|
||||||
const { type } = context;
|
const { type } = context;
|
||||||
object.children = factory.create(
|
object.children = factory.create(
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ const NAMED_PRESETS = {
|
||||||
optimizationBailout: true,
|
optimizationBailout: true,
|
||||||
errorDetails: true,
|
errorDetails: true,
|
||||||
publicPath: true,
|
publicPath: true,
|
||||||
|
logging: "verbose",
|
||||||
orphanModules: true,
|
orphanModules: true,
|
||||||
runtime: true,
|
runtime: true,
|
||||||
exclude: false,
|
exclude: false,
|
||||||
|
|
@ -55,6 +56,7 @@ const NAMED_PRESETS = {
|
||||||
optimizationBailout: true,
|
optimizationBailout: true,
|
||||||
errorDetails: true,
|
errorDetails: true,
|
||||||
publicPath: true,
|
publicPath: true,
|
||||||
|
logging: true,
|
||||||
runtimeModules: true,
|
runtimeModules: true,
|
||||||
runtime: true,
|
runtime: true,
|
||||||
exclude: false,
|
exclude: false,
|
||||||
|
|
@ -65,17 +67,20 @@ const NAMED_PRESETS = {
|
||||||
modules: true,
|
modules: true,
|
||||||
maxModules: 0,
|
maxModules: 0,
|
||||||
errors: true,
|
errors: true,
|
||||||
warnings: true
|
warnings: true,
|
||||||
|
logging: "warn"
|
||||||
},
|
},
|
||||||
"errors-only": {
|
"errors-only": {
|
||||||
all: false,
|
all: false,
|
||||||
errors: true,
|
errors: true,
|
||||||
moduleTrace: true
|
moduleTrace: true,
|
||||||
|
logging: "error"
|
||||||
},
|
},
|
||||||
"errors-warnings": {
|
"errors-warnings": {
|
||||||
all: false,
|
all: false,
|
||||||
errors: true,
|
errors: true,
|
||||||
warnings: true
|
warnings: true,
|
||||||
|
logging: "warn"
|
||||||
},
|
},
|
||||||
none: {
|
none: {
|
||||||
all: false
|
all: false
|
||||||
|
|
@ -132,6 +137,10 @@ const DEFAULTS = {
|
||||||
errorDetails: OFF_FOR_TO_STRING,
|
errorDetails: OFF_FOR_TO_STRING,
|
||||||
warnings: NORMAL_ON,
|
warnings: NORMAL_ON,
|
||||||
publicPath: OFF_FOR_TO_STRING,
|
publicPath: OFF_FOR_TO_STRING,
|
||||||
|
logging: ({ all }, { forToString }) =>
|
||||||
|
(forToString && all !== false ? "info" : false),
|
||||||
|
loggingDebug: () => [],
|
||||||
|
loggingTrace: OFF_FOR_TO_STRING,
|
||||||
excludeModules: () => [],
|
excludeModules: () => [],
|
||||||
excludeAssets: () => [],
|
excludeAssets: () => [],
|
||||||
maxModules: (o, { forToString }) => ((forToString ? 15 : Infinity)),
|
maxModules: (o, { forToString }) => ((forToString ? 15 : Infinity)),
|
||||||
|
|
@ -142,7 +151,7 @@ const DEFAULTS = {
|
||||||
colors: () => false
|
colors: () => false
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeExclude = item => {
|
const normalizeFilter = item => {
|
||||||
if (typeof item === "string") {
|
if (typeof item === "string") {
|
||||||
const regExp = new RegExp(
|
const regExp = new RegExp(
|
||||||
`[\\\\/]${item.replace(
|
`[\\\\/]${item.replace(
|
||||||
|
|
@ -169,13 +178,13 @@ const NORMALIZER = {
|
||||||
if (!Array.isArray(value)) {
|
if (!Array.isArray(value)) {
|
||||||
value = value ? [value] : [];
|
value = value ? [value] : [];
|
||||||
}
|
}
|
||||||
return value.map(normalizeExclude);
|
return value.map(normalizeFilter);
|
||||||
},
|
},
|
||||||
excludeAssets: value => {
|
excludeAssets: value => {
|
||||||
if (!Array.isArray(value)) {
|
if (!Array.isArray(value)) {
|
||||||
value = value ? [value] : [];
|
value = value ? [value] : [];
|
||||||
}
|
}
|
||||||
return value.map(normalizeExclude);
|
return value.map(normalizeFilter);
|
||||||
},
|
},
|
||||||
warningsFilter: value => {
|
warningsFilter: value => {
|
||||||
if (!Array.isArray(value)) {
|
if (!Array.isArray(value)) {
|
||||||
|
|
@ -195,6 +204,16 @@ const NORMALIZER = {
|
||||||
`Can only filter warnings with Strings or RegExps. (Given: ${filter})`
|
`Can only filter warnings with Strings or RegExps. (Given: ${filter})`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
logging: value => {
|
||||||
|
if (value === true) value = "log";
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
loggingDebug: value => {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
value = value ? [value] : [];
|
||||||
|
}
|
||||||
|
return value.map(normalizeFilter);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,12 @@ const printSizes = (sizes, { formatSize }) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mapLines = (str, fn) =>
|
||||||
|
str
|
||||||
|
.split("\n")
|
||||||
|
.map(fn)
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} n a number
|
* @param {number} n a number
|
||||||
* @returns {string} number as two digit string, leading 0
|
* @returns {string} number as two digit string, leading 0
|
||||||
|
|
@ -130,6 +136,14 @@ const SIMPLE_PRINTERS = {
|
||||||
: filteredAssets
|
: filteredAssets
|
||||||
} ${plural(filteredAssets, "asset", "assets")}`
|
} ${plural(filteredAssets, "asset", "assets")}`
|
||||||
: undefined,
|
: undefined,
|
||||||
|
"compilation.logging": (logging, context, printer) =>
|
||||||
|
Array.isArray(logging)
|
||||||
|
? undefined
|
||||||
|
: printer.print(
|
||||||
|
context.type,
|
||||||
|
Object.entries(logging).map(([name, value]) => ({ ...value, name })),
|
||||||
|
context
|
||||||
|
),
|
||||||
"compilation.children[].compilation.name": name =>
|
"compilation.children[].compilation.name": name =>
|
||||||
name ? `Child ${name}:` : "Child",
|
name ? `Child ${name}:` : "Child",
|
||||||
|
|
||||||
|
|
@ -402,12 +416,45 @@ const SIMPLE_PRINTERS = {
|
||||||
"error.moduleTrace": moduleTrace => undefined,
|
"error.moduleTrace": moduleTrace => undefined,
|
||||||
"error.separator!": () => "\n",
|
"error.separator!": () => "\n",
|
||||||
|
|
||||||
|
"loggingEntry(error).loggingEntry.message": (message, { red }) =>
|
||||||
|
mapLines(message, x => `<e> ${red(x)}`),
|
||||||
|
"loggingEntry(warn).loggingEntry.message": (message, { yellow }) =>
|
||||||
|
mapLines(message, x => `<w> ${yellow(x)}`),
|
||||||
|
"loggingEntry(info).loggingEntry.message": (message, { green }) =>
|
||||||
|
mapLines(message, x => `<i> ${green(x)}`),
|
||||||
|
"loggingEntry(log).loggingEntry.message": (message, { bold }) =>
|
||||||
|
mapLines(message, x => bold(x)),
|
||||||
|
"loggingEntry(debug).loggingEntry.message": message => message,
|
||||||
|
"loggingEntry(trace).loggingEntry.message": message => message,
|
||||||
|
"loggingEntry(profile).loggingEntry.message": (message, { magenta }) =>
|
||||||
|
mapLines(message, x => `<p> ${magenta(x)}`),
|
||||||
|
"loggingEntry(profileEnd).loggingEntry.message": (message, { magenta }) =>
|
||||||
|
mapLines(message, x => `</p> ${magenta(x)}`),
|
||||||
|
"loggingEntry(time).loggingEntry.message": (message, { magenta }) =>
|
||||||
|
mapLines(message, x => `<t> ${magenta(x)}`),
|
||||||
|
"loggingEntry(group).loggingEntry.message": (message, { cyan }) =>
|
||||||
|
mapLines(message, x => cyan(x)),
|
||||||
|
"loggingEntry(groupCollapsed).loggingEntry.message": (message, { cyan }) =>
|
||||||
|
mapLines(message, x => `<+> ${cyan(x)}`),
|
||||||
|
"loggingEntry(clear).loggingEntry": () => "-------",
|
||||||
|
"loggingEntry(groupCollapsed).loggingEntry.children": () => "",
|
||||||
|
"loggingEntry.trace[]": trace =>
|
||||||
|
trace ? mapLines(trace, x => `| ${x}`) : undefined,
|
||||||
|
|
||||||
"moduleTraceItem.originName": originName => originName,
|
"moduleTraceItem.originName": originName => originName,
|
||||||
|
|
||||||
|
loggingGroup: loggingGroup =>
|
||||||
|
loggingGroup.entries.length === 0 ? "" : undefined,
|
||||||
|
"loggingGroup.debug": (flag, { red }) => ((flag ? red("DEBUG") : undefined)),
|
||||||
|
"loggingGroup.name": (name, { bold }) => bold(`LOG from ${name}`),
|
||||||
|
"loggingGroup.separator!": () => "\n",
|
||||||
|
"loggingGroup.filteredEntries": filteredEntries =>
|
||||||
|
filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined,
|
||||||
|
|
||||||
"moduleTraceDependency.loc": loc => loc
|
"moduleTraceDependency.loc": loc => loc
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @type {Record<string, string>} */
|
/** @type {Record<string, string | Function>} */
|
||||||
const ITEM_NAMES = {
|
const ITEM_NAMES = {
|
||||||
"compilation.assets[]": "asset",
|
"compilation.assets[]": "asset",
|
||||||
"compilation.modules[]": "module",
|
"compilation.modules[]": "module",
|
||||||
|
|
@ -416,6 +463,7 @@ const ITEM_NAMES = {
|
||||||
"compilation.namedChunkGroups[]": "chunkGroup",
|
"compilation.namedChunkGroups[]": "chunkGroup",
|
||||||
"compilation.errors[]": "error",
|
"compilation.errors[]": "error",
|
||||||
"compilation.warnings[]": "error",
|
"compilation.warnings[]": "error",
|
||||||
|
"compilation.logging[]": "loggingGroup",
|
||||||
"compilation.children[]": "compilation",
|
"compilation.children[]": "compilation",
|
||||||
"asset.chunks[]": "assetChunk",
|
"asset.chunks[]": "assetChunk",
|
||||||
"asset.auxiliaryChunks[]": "assetChunk",
|
"asset.auxiliaryChunks[]": "assetChunk",
|
||||||
|
|
@ -427,6 +475,10 @@ const ITEM_NAMES = {
|
||||||
"chunk.origins[]": "chunkOrigin",
|
"chunk.origins[]": "chunkOrigin",
|
||||||
"chunk.rootModules[]": "module",
|
"chunk.rootModules[]": "module",
|
||||||
"chunk.modules[]": "module",
|
"chunk.modules[]": "module",
|
||||||
|
"loggingGroup.entries[]": logEntry =>
|
||||||
|
`loggingEntry(${logEntry.type}).loggingEntry`,
|
||||||
|
"loggingEntry.children[]": logEntry =>
|
||||||
|
`loggingEntry(${logEntry.type}).loggingEntry`,
|
||||||
"error.moduleTrace[]": "moduleTraceItem",
|
"error.moduleTrace[]": "moduleTraceItem",
|
||||||
"moduleTraceItem.dependencies[]": "moduleTraceDependency"
|
"moduleTraceItem.dependencies[]": "moduleTraceDependency"
|
||||||
};
|
};
|
||||||
|
|
@ -467,6 +519,7 @@ const PREFERED_ORDERS = {
|
||||||
"chunks",
|
"chunks",
|
||||||
"modules",
|
"modules",
|
||||||
"filteredModules",
|
"filteredModules",
|
||||||
|
"logging",
|
||||||
"warnings",
|
"warnings",
|
||||||
"errors",
|
"errors",
|
||||||
"children",
|
"children",
|
||||||
|
|
@ -572,6 +625,15 @@ const PREFERED_ORDERS = {
|
||||||
error: ERROR_PREFERED_ORDER,
|
error: ERROR_PREFERED_ORDER,
|
||||||
warning: ERROR_PREFERED_ORDER,
|
warning: ERROR_PREFERED_ORDER,
|
||||||
"chunk.childrenByOrder[]": ["type", "children"],
|
"chunk.childrenByOrder[]": ["type", "children"],
|
||||||
|
loggingGroup: [
|
||||||
|
"debug",
|
||||||
|
"name",
|
||||||
|
"separator!",
|
||||||
|
"entries",
|
||||||
|
"separator!",
|
||||||
|
"filtredEntries"
|
||||||
|
],
|
||||||
|
loggingEntry: ["message", "trace", "children"],
|
||||||
"chunkGroup.childAssets[]": ["type", "children"]
|
"chunkGroup.childAssets[]": ["type", "children"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -608,7 +670,10 @@ const SIMPLE_ITEMS_JOINER = {
|
||||||
.join(" "),
|
.join(" "),
|
||||||
"compilation.errors": itemsJoinMoreSpacing,
|
"compilation.errors": itemsJoinMoreSpacing,
|
||||||
"compilation.warnings": itemsJoinMoreSpacing,
|
"compilation.warnings": itemsJoinMoreSpacing,
|
||||||
|
"compilation.logging": itemsJoinMoreSpacing,
|
||||||
"moduleTraceItem.dependencies": itemsJoinOneLine,
|
"moduleTraceItem.dependencies": itemsJoinOneLine,
|
||||||
|
"loggingEntry.children": items =>
|
||||||
|
indent(items.filter(Boolean).join("\n"), " ", false),
|
||||||
"compilation.children": items =>
|
"compilation.children": items =>
|
||||||
items.map(item => indent(item, " ", true)).join("\n")
|
items.map(item => indent(item, " ", true)).join("\n")
|
||||||
};
|
};
|
||||||
|
|
@ -701,7 +766,9 @@ const SIMPLE_ELEMENT_JOINERS = {
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (!item.content) continue;
|
if (!item.content) continue;
|
||||||
const needMoreSpace =
|
const needMoreSpace =
|
||||||
item.element === "warnings" || item.element === "errors";
|
item.element === "warnings" ||
|
||||||
|
item.element === "errors" ||
|
||||||
|
item.element === "logging";
|
||||||
if (result.length !== 0) {
|
if (result.length !== 0) {
|
||||||
result.push(needMoreSpace || lastNeedMore ? "\n\n" : "\n");
|
result.push(needMoreSpace || lastNeedMore ? "\n\n" : "\n");
|
||||||
}
|
}
|
||||||
|
|
@ -797,6 +864,7 @@ const SIMPLE_ELEMENT_JOINERS = {
|
||||||
chunkOrigin: items => " > " + joinOneLine(items),
|
chunkOrigin: items => " > " + joinOneLine(items),
|
||||||
"errors[].error": joinError(true),
|
"errors[].error": joinError(true),
|
||||||
"warnings[].error": joinError(false),
|
"warnings[].error": joinError(false),
|
||||||
|
loggingGroup: items => joinExplicitNewLine(items, "").trimRight(),
|
||||||
moduleTraceItem: items => " @ " + joinOneLine(items),
|
moduleTraceItem: items => " @ " + joinOneLine(items),
|
||||||
moduleTraceDependency: joinOneLine
|
moduleTraceDependency: joinOneLine
|
||||||
};
|
};
|
||||||
|
|
@ -973,7 +1041,10 @@ class DefaultStatsPrinterPlugin {
|
||||||
const itemName = ITEM_NAMES[key];
|
const itemName = ITEM_NAMES[key];
|
||||||
stats.hooks.getItemName
|
stats.hooks.getItemName
|
||||||
.for(key)
|
.for(key)
|
||||||
.tap("DefaultStatsPrinterPlugin", () => itemName);
|
.tap(
|
||||||
|
"DefaultStatsPrinterPlugin",
|
||||||
|
typeof itemName === "string" ? () => itemName : itemName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const key of Object.keys(SIMPLE_ITEMS_JOINER)) {
|
for (const key of Object.keys(SIMPLE_ITEMS_JOINER)) {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ const createCompiler = options => {
|
||||||
options = new WebpackOptionsDefaulter().process(options);
|
options = new WebpackOptionsDefaulter().process(options);
|
||||||
const compiler = new Compiler(options.context);
|
const compiler = new Compiler(options.context);
|
||||||
compiler.options = options;
|
compiler.options = options;
|
||||||
new NodeEnvironmentPlugin().apply(compiler);
|
new NodeEnvironmentPlugin({
|
||||||
|
infrastructureLogging: options.infrastructureLogging
|
||||||
|
}).apply(compiler);
|
||||||
if (Array.isArray(options.plugins)) {
|
if (Array.isArray(options.plugins)) {
|
||||||
for (const plugin of options.plugins) {
|
for (const plugin of options.plugins) {
|
||||||
if (typeof plugin === "function") {
|
if (typeof plugin === "function") {
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"instanceof": "Function",
|
"instanceof": "Function",
|
||||||
"tsType": "Function"
|
"tsType": "((value: string) => boolean)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -2006,6 +2006,35 @@
|
||||||
"description": "add the hash of the compilation",
|
"description": "add the hash of the compilation",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"logging": {
|
||||||
|
"description": "add logging output",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"description": "enable/disable logging output (true: shows normal logging output, loglevel: log)",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "specify log level of logging output",
|
||||||
|
"enum": ["none", "error", "warn", "info", "log", "verbose"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"loggingDebug": {
|
||||||
|
"description": "Include debug logging of specified loggers (i. e. for plugins or loaders). Filters can be Strings, RegExps or Functions",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/FilterTypes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enable/Disable debug logging for all loggers",
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"loggingTrace": {
|
||||||
|
"description": "add stack traces to logging output",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"maxModules": {
|
"maxModules": {
|
||||||
"description": "Set the maximum number of modules to be shown",
|
"description": "Set the maximum number of modules to be shown",
|
||||||
"type": "number"
|
"type": "number"
|
||||||
|
|
@ -2263,6 +2292,29 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"infrastructureLogging": {
|
||||||
|
"description": "Options for infrastructure level logging",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"debug": {
|
||||||
|
"description": "Enable debug logging for specific loggers",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/FilterTypes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enable/Disable debug logging for all loggers",
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"level": {
|
||||||
|
"description": "Log level",
|
||||||
|
"enum": ["none", "error", "warn", "info", "log", "verbose"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"loader": {
|
"loader": {
|
||||||
"description": "Custom values available in the loader context.",
|
"description": "Custom values available in the loader context.",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
|
|
|
||||||
|
|
@ -709,4 +709,152 @@ describe("Compiler", () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe("infrastructure logging", () => {
|
||||||
|
const CONSOLE_METHODS = [
|
||||||
|
"error",
|
||||||
|
"warn",
|
||||||
|
"info",
|
||||||
|
"log",
|
||||||
|
"debug",
|
||||||
|
"trace",
|
||||||
|
"profile",
|
||||||
|
"profileEnd",
|
||||||
|
"group",
|
||||||
|
"groupEnd",
|
||||||
|
"groupCollapsed"
|
||||||
|
];
|
||||||
|
const spies = {};
|
||||||
|
beforeEach(() => {
|
||||||
|
for (const method of CONSOLE_METHODS) {
|
||||||
|
if (console[method]) {
|
||||||
|
spies[method] = jest.spyOn(console, method).mockImplementation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
for (const method in spies) {
|
||||||
|
spies[method].mockRestore();
|
||||||
|
delete spies[method];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
const logger = compiler.getInfrastructureLogger("MyPlugin");
|
||||||
|
logger.time("Time");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.timeEnd("Time");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it("should log to the console (verbose)", done => {
|
||||||
|
const compiler = webpack({
|
||||||
|
context: path.join(__dirname, "fixtures"),
|
||||||
|
entry: "./a",
|
||||||
|
output: {
|
||||||
|
path: "/",
|
||||||
|
filename: "bundle.js"
|
||||||
|
},
|
||||||
|
infrastructureLogging: {
|
||||||
|
level: "verbose"
|
||||||
|
},
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
|
});
|
||||||
|
compiler.outputFileSystem = new MemoryFs();
|
||||||
|
compiler.run((err, stats) => {
|
||||||
|
expect(spies.group).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.group).toHaveBeenCalledWith("[MyPlugin] Group");
|
||||||
|
expect(spies.groupCollapsed).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.groupCollapsed).toHaveBeenCalledWith(
|
||||||
|
"[MyPlugin] Collaped group"
|
||||||
|
);
|
||||||
|
expect(spies.error).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.error).toHaveBeenCalledWith("<e> [MyPlugin] Error");
|
||||||
|
expect(spies.warn).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.warn).toHaveBeenCalledWith("<w> [MyPlugin] Warning");
|
||||||
|
expect(spies.info).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.info).toHaveBeenCalledWith("<i> [MyPlugin] Info");
|
||||||
|
expect(spies.log).toHaveBeenCalledTimes(3);
|
||||||
|
expect(spies.log).toHaveBeenCalledWith("[MyPlugin] Log");
|
||||||
|
expect(spies.log).toHaveBeenCalledWith(
|
||||||
|
"[MyPlugin] Log inside collapsed group"
|
||||||
|
);
|
||||||
|
expect(spies.debug).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.groupEnd).toHaveBeenCalledTimes(2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should log to the console (debug mode)", done => {
|
||||||
|
const compiler = webpack({
|
||||||
|
context: path.join(__dirname, "fixtures"),
|
||||||
|
entry: "./a",
|
||||||
|
output: {
|
||||||
|
path: "/",
|
||||||
|
filename: "bundle.js"
|
||||||
|
},
|
||||||
|
infrastructureLogging: {
|
||||||
|
level: "error",
|
||||||
|
debug: /MyPlugin/
|
||||||
|
},
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
|
});
|
||||||
|
compiler.outputFileSystem = new MemoryFs();
|
||||||
|
compiler.run((err, stats) => {
|
||||||
|
expect(spies.group).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.group).toHaveBeenCalledWith("[MyPlugin] Group");
|
||||||
|
expect(spies.groupCollapsed).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.groupCollapsed).toHaveBeenCalledWith(
|
||||||
|
"[MyPlugin] Collaped group"
|
||||||
|
);
|
||||||
|
expect(spies.error).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.error).toHaveBeenCalledWith("<e> [MyPlugin] Error");
|
||||||
|
expect(spies.warn).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.warn).toHaveBeenCalledWith("<w> [MyPlugin] Warning");
|
||||||
|
expect(spies.info).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.info).toHaveBeenCalledWith("<i> [MyPlugin] Info");
|
||||||
|
expect(spies.log).toHaveBeenCalledTimes(3);
|
||||||
|
expect(spies.log).toHaveBeenCalledWith("[MyPlugin] Log");
|
||||||
|
expect(spies.log).toHaveBeenCalledWith(
|
||||||
|
"[MyPlugin] Log inside collapsed group"
|
||||||
|
);
|
||||||
|
expect(spies.debug).toHaveBeenCalledTimes(1);
|
||||||
|
expect(spies.debug).toHaveBeenCalledWith("[MyPlugin] Debug");
|
||||||
|
expect(spies.groupEnd).toHaveBeenCalledTimes(2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should log to the console (none)", done => {
|
||||||
|
const compiler = webpack({
|
||||||
|
context: path.join(__dirname, "fixtures"),
|
||||||
|
entry: "./a",
|
||||||
|
output: {
|
||||||
|
path: "/",
|
||||||
|
filename: "bundle.js"
|
||||||
|
},
|
||||||
|
infrastructureLogging: {
|
||||||
|
level: "none"
|
||||||
|
},
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
|
});
|
||||||
|
compiler.outputFileSystem = new MemoryFs();
|
||||||
|
compiler.run((err, stats) => {
|
||||||
|
expect(spies.group).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.groupCollapsed).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.error).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.warn).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.info).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.log).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.debug).toHaveBeenCalledTimes(0);
|
||||||
|
expect(spies.groupEnd).toHaveBeenCalledTimes(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -259,69 +259,63 @@ describe("JavascriptParser", () => {
|
||||||
const state = testCases[name][1];
|
const state = testCases[name][1];
|
||||||
|
|
||||||
const testParser = new JavascriptParser({});
|
const testParser = new JavascriptParser({});
|
||||||
testParser.hooks.canRename.tap(
|
testParser.hooks.canRename
|
||||||
"abc",
|
.for("abc")
|
||||||
"JavascriptParserTest",
|
.tap("JavascriptParserTest", expr => true);
|
||||||
expr => true
|
testParser.hooks.canRename
|
||||||
);
|
.for("ijk")
|
||||||
testParser.hooks.canRename.tap(
|
.tap("JavascriptParserTest", expr => true);
|
||||||
"ijk",
|
testParser.hooks.call.for("abc").tap("JavascriptParserTest", expr => {
|
||||||
"JavascriptParserTest",
|
|
||||||
expr => true
|
|
||||||
);
|
|
||||||
testParser.hooks.call.tap("abc", "JavascriptParserTest", expr => {
|
|
||||||
if (!testParser.state.abc) testParser.state.abc = [];
|
if (!testParser.state.abc) testParser.state.abc = [];
|
||||||
testParser.state.abc.push(testParser.parseString(expr.arguments[0]));
|
testParser.state.abc.push(testParser.parseString(expr.arguments[0]));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
testParser.hooks.call.tap("cde.abc", "JavascriptParserTest", expr => {
|
testParser.hooks.call.for("cde.abc").tap("JavascriptParserTest", expr => {
|
||||||
if (!testParser.state.cdeabc) testParser.state.cdeabc = [];
|
if (!testParser.state.cdeabc) testParser.state.cdeabc = [];
|
||||||
testParser.state.cdeabc.push(testParser.parseString(expr.arguments[0]));
|
testParser.state.cdeabc.push(testParser.parseString(expr.arguments[0]));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
testParser.hooks.call.tap("cde.ddd.abc", "JavascriptParserTest", expr => {
|
testParser.hooks.call
|
||||||
|
.for("cde.ddd.abc")
|
||||||
|
.tap("JavascriptParserTest", expr => {
|
||||||
if (!testParser.state.cdedddabc) testParser.state.cdedddabc = [];
|
if (!testParser.state.cdedddabc) testParser.state.cdedddabc = [];
|
||||||
testParser.state.cdedddabc.push(
|
testParser.state.cdedddabc.push(
|
||||||
testParser.parseString(expr.arguments[0])
|
testParser.parseString(expr.arguments[0])
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
testParser.hooks.expression.tap("fgh", "JavascriptParserTest", expr => {
|
testParser.hooks.expression
|
||||||
|
.for("fgh")
|
||||||
|
.tap("JavascriptParserTest", expr => {
|
||||||
if (!testParser.state.fgh) testParser.state.fgh = [];
|
if (!testParser.state.fgh) testParser.state.fgh = [];
|
||||||
testParser.state.fgh.push(
|
testParser.state.fgh.push(
|
||||||
Array.from(testParser.scope.definitions.asSet()).join(" ")
|
Array.from(testParser.scope.definitions.asSet()).join(" ")
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
testParser.hooks.expression.tap(
|
testParser.hooks.expression
|
||||||
"fgh.sub",
|
.for("fgh.sub")
|
||||||
"JavascriptParserTest",
|
.tap("JavascriptParserTest", expr => {
|
||||||
expr => {
|
|
||||||
if (!testParser.state.fghsub) testParser.state.fghsub = [];
|
if (!testParser.state.fghsub) testParser.state.fghsub = [];
|
||||||
testParser.state.fghsub.push(
|
testParser.state.fghsub.push(
|
||||||
testParser.scope.inTry ? "try" : "notry"
|
testParser.scope.inTry ? "try" : "notry"
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
});
|
||||||
);
|
testParser.hooks.expression
|
||||||
testParser.hooks.expression.tap(
|
.for("ijk.sub")
|
||||||
"ijk.sub",
|
.tap("JavascriptParserTest", expr => {
|
||||||
"JavascriptParserTest",
|
|
||||||
expr => {
|
|
||||||
if (!testParser.state.ijksub) testParser.state.ijksub = [];
|
if (!testParser.state.ijksub) testParser.state.ijksub = [];
|
||||||
testParser.state.ijksub.push("test");
|
testParser.state.ijksub.push("test");
|
||||||
return true;
|
return true;
|
||||||
}
|
});
|
||||||
);
|
testParser.hooks.expression
|
||||||
testParser.hooks.expression.tap(
|
.for("memberExpr")
|
||||||
"memberExpr",
|
.tap("JavascriptParserTest", expr => {
|
||||||
"JavascriptParserTest",
|
|
||||||
expr => {
|
|
||||||
if (!testParser.state.expressions) testParser.state.expressions = [];
|
if (!testParser.state.expressions) testParser.state.expressions = [];
|
||||||
testParser.state.expressions.push(expr.name);
|
testParser.state.expressions.push(expr.name);
|
||||||
return true;
|
return true;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
testParser.hooks.new.tap("xyz", "JavascriptParserTest", expr => {
|
testParser.hooks.new.tap("xyz", "JavascriptParserTest", expr => {
|
||||||
if (!testParser.state.xyz) testParser.state.xyz = [];
|
if (!testParser.state.xyz) testParser.state.xyz = [];
|
||||||
testParser.state.xyz.push(testParser.parseString(expr.arguments[0]));
|
testParser.state.xyz.push(testParser.parseString(expr.arguments[0]));
|
||||||
|
|
@ -367,21 +361,19 @@ describe("JavascriptParser", () => {
|
||||||
describe("expression evaluation", () => {
|
describe("expression evaluation", () => {
|
||||||
function evaluateInParser(source) {
|
function evaluateInParser(source) {
|
||||||
const parser = new JavascriptParser();
|
const parser = new JavascriptParser();
|
||||||
parser.hooks.call.tap("test", "JavascriptParserTest", expr => {
|
parser.hooks.call.for("test").tap("JavascriptParserTest", expr => {
|
||||||
parser.state.result = parser.evaluateExpression(expr.arguments[0]);
|
parser.state.result = parser.evaluateExpression(expr.arguments[0]);
|
||||||
});
|
});
|
||||||
parser.hooks.evaluateIdentifier.tap(
|
parser.hooks.evaluateIdentifier
|
||||||
"aString",
|
.for("aString")
|
||||||
"JavascriptParserTest",
|
.tap("JavascriptParserTest", expr =>
|
||||||
expr =>
|
|
||||||
new BasicEvaluatedExpression()
|
new BasicEvaluatedExpression()
|
||||||
.setString("aString")
|
.setString("aString")
|
||||||
.setRange(expr.range)
|
.setRange(expr.range)
|
||||||
);
|
);
|
||||||
parser.hooks.evaluateIdentifier.tap(
|
parser.hooks.evaluateIdentifier
|
||||||
"b.Number",
|
.for("b.Number")
|
||||||
"JavascriptParserTest",
|
.tap("JavascriptParserTest", expr =>
|
||||||
expr =>
|
|
||||||
new BasicEvaluatedExpression().setNumber(123).setRange(expr.range)
|
new BasicEvaluatedExpression().setNumber(123).setRange(expr.range)
|
||||||
);
|
);
|
||||||
return parser.parse("test(" + source + ");").result;
|
return parser.parse("test(" + source + ");").result;
|
||||||
|
|
@ -615,7 +607,7 @@ describe("JavascriptParser", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const parser = new JavascriptParser();
|
const parser = new JavascriptParser();
|
||||||
parser.hooks.call.tap("require", "JavascriptParserTest", expr => {
|
parser.hooks.call.for("require").tap("JavascriptParserTest", expr => {
|
||||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||||
parser.state.param = param.string;
|
parser.state.param = param.string;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,15 @@ const fs = require("graceful-fs");
|
||||||
|
|
||||||
const webpack = require("..");
|
const webpack = require("..");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes regular expression metacharacters
|
||||||
|
* @param {string} str String to quote
|
||||||
|
* @returns {string} Escaped string
|
||||||
|
*/
|
||||||
|
const quotemeta = str => {
|
||||||
|
return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
|
||||||
|
};
|
||||||
|
|
||||||
const base = path.join(__dirname, "statsCases");
|
const base = path.join(__dirname, "statsCases");
|
||||||
const outputBase = path.join(__dirname, "js", "stats");
|
const outputBase = path.join(__dirname, "js", "stats");
|
||||||
const tests = fs
|
const tests = fs
|
||||||
|
|
@ -129,24 +138,21 @@ describe("StatsTestCases", () => {
|
||||||
if (!hasColorSetting) {
|
if (!hasColorSetting) {
|
||||||
actual = actual
|
actual = actual
|
||||||
.replace(/\u001b\[[0-9;]*m/g, "")
|
.replace(/\u001b\[[0-9;]*m/g, "")
|
||||||
.replace(/[0-9]+(\s?ms)/g, "X$1");
|
.replace(/[.0-9]+(\s?ms)/g, "X$1");
|
||||||
} else {
|
} else {
|
||||||
actual = actual
|
actual = actual
|
||||||
.replace(/\u001b\[1m\u001b\[([0-9;]*)m/g, "<CLR=$1,BOLD>")
|
.replace(/\u001b\[1m\u001b\[([0-9;]*)m/g, "<CLR=$1,BOLD>")
|
||||||
.replace(/\u001b\[1m/g, "<CLR=BOLD>")
|
.replace(/\u001b\[1m/g, "<CLR=BOLD>")
|
||||||
.replace(/\u001b\[39m\u001b\[22m/g, "</CLR>")
|
.replace(/\u001b\[39m\u001b\[22m/g, "</CLR>")
|
||||||
.replace(/\u001b\[([0-9;]*)m/g, "<CLR=$1>")
|
.replace(/\u001b\[([0-9;]*)m/g, "<CLR=$1>")
|
||||||
.replace(/[0-9]+(<\/CLR>)?(\s?ms)/g, "X$1$2");
|
.replace(/[.0-9]+(<\/CLR>)?(\s?ms)/g, "X$1$2");
|
||||||
}
|
}
|
||||||
const testPath = path.join(base, testName);
|
const testPath = path.join(base, testName);
|
||||||
const testPathPattern = testPath.replace(
|
|
||||||
/[-[\]\\/{}()*+?.^$|]/g,
|
|
||||||
"\\$&"
|
|
||||||
);
|
|
||||||
actual = actual
|
actual = actual
|
||||||
.replace(/\r\n?/g, "\n")
|
.replace(/\r\n?/g, "\n")
|
||||||
.replace(/[\t ]*Version:.+\n/g, "")
|
.replace(/[\t ]*Version:.+\n/g, "")
|
||||||
.replace(new RegExp(testPathPattern, "g"), "Xdir/" + testName)
|
.replace(new RegExp(quotemeta(testPath), "g"), "Xdir/" + testName)
|
||||||
|
.replace(/(\w)\\(\w)/g, "$1/$2")
|
||||||
.replace(/, additional resolving: Xms/g, "");
|
.replace(/, additional resolving: Xms/g, "");
|
||||||
expect(actual).toMatchSnapshot();
|
expect(actual).toMatchSnapshot();
|
||||||
done();
|
done();
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ describe("Validation", () => {
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration has an unknown property 'postcss'. These properties are valid:
|
- configuration has an unknown property 'postcss'. These properties are valid:
|
||||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, serve?, stats?, target?, watch?, watchOptions? }
|
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, serve?, stats?, target?, watch?, watchOptions? }
|
||||||
For typos: please correct them.
|
For typos: please correct them.
|
||||||
For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
|
For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
|
||||||
Loaders should be updated to allow passing options via loader options in module.rules.
|
Loaders should be updated to allow passing options via loader options in module.rules.
|
||||||
|
|
|
||||||
|
|
@ -1277,6 +1277,43 @@ Child 4 chunks:
|
||||||
[767] ./d.js 22 bytes {524} [built]"
|
[767] ./d.js 22 bytes {524} [built]"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`StatsTestCases should print correct stats for logging 1`] = `
|
||||||
|
"Hash: <CLR=BOLD>17d1aced1f8edabe0aa9</CLR>
|
||||||
|
Time: <CLR=BOLD>X</CLR>ms
|
||||||
|
Built at: 1970-04-20 <CLR=BOLD>12:42:42</CLR>
|
||||||
|
<CLR=BOLD>Asset</CLR> <CLR=BOLD>Size</CLR> <CLR=BOLD>Chunks</CLR> <CLR=BOLD>Chunk Names</CLR>
|
||||||
|
<CLR=32,BOLD>main.js</CLR> 1.32 KiB {<CLR=33,BOLD>179</CLR>} <CLR=32,BOLD>[emitted]</CLR> main
|
||||||
|
Entrypoint <CLR=BOLD>main</CLR> = <CLR=32,BOLD>main.js</CLR>
|
||||||
|
[390] <CLR=BOLD>./index.js</CLR> 1 bytes {<CLR=33,BOLD>179</CLR>} <CLR=32,BOLD>[built]</CLR>
|
||||||
|
|
||||||
|
<CLR=BOLD>LOG from MyPlugin</CLR>
|
||||||
|
<i> <CLR=32,BOLD>Plugin is now active</CLR>
|
||||||
|
<+> <CLR=36,BOLD>Nested</CLR>
|
||||||
|
+ 3 hidden lines
|
||||||
|
|
||||||
|
<CLR=31,BOLD>DEBUG</CLR> <CLR=BOLD>LOG from ./node_modules/custom-loader/index.js ./node_modules/custom-loader/index.js!./index.js</CLR>
|
||||||
|
<e> <CLR=31,BOLD>An error</CLR>
|
||||||
|
| at Object.<anonymous>.module.exports (Xdir/logging/node_modules/custom-loader/index.js:5:9)
|
||||||
|
<w> <CLR=33,BOLD>A warning</CLR>
|
||||||
|
| at Object.<anonymous>.module.exports (Xdir/logging/node_modules/custom-loader/index.js:6:9)
|
||||||
|
<CLR=36,BOLD>Unimportant</CLR>
|
||||||
|
<i> <CLR=32,BOLD>Info message</CLR>
|
||||||
|
<CLR=BOLD>Just log</CLR>
|
||||||
|
Just debug
|
||||||
|
<t> <CLR=35,BOLD>Measure: Xms</CLR>
|
||||||
|
<CLR=36,BOLD>Nested</CLR>
|
||||||
|
<CLR=BOLD>Log inside collapsed group</CLR>
|
||||||
|
Trace
|
||||||
|
| at Object.<anonymous>.module.exports (Xdir/logging/node_modules/custom-loader/index.js:15:9)
|
||||||
|
<t> <CLR=35,BOLD>Measure: Xms</CLR>
|
||||||
|
-------
|
||||||
|
<CLR=BOLD>After clear</CLR>
|
||||||
|
|
||||||
|
<CLR=31,BOLD>DEBUG</CLR> <CLR=BOLD>LOG from ./node_modules/custom-loader/index.js Named Logger ./node_modules/custom-loader/index.js!./index.js</CLR>
|
||||||
|
Message with named logger
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for max-modules 1`] = `
|
exports[`StatsTestCases should print correct stats for max-modules 1`] = `
|
||||||
"Hash: 8a3d2df87a4f01705c82
|
"Hash: 8a3d2df87a4f01705c82
|
||||||
Time: Xms
|
Time: Xms
|
||||||
|
|
@ -2062,20 +2099,48 @@ webpack/runtime/jsonp chunk loading 3.36 KiB {179} [runtime]
|
||||||
[used exports unknown]
|
[used exports unknown]
|
||||||
webpack/runtime/publicPath 27 bytes {179} [runtime]
|
webpack/runtime/publicPath 27 bytes {179} [runtime]
|
||||||
[no exports]
|
[no exports]
|
||||||
[used exports unknown]"
|
[used exports unknown]
|
||||||
|
|
||||||
|
LOG from MyPlugin
|
||||||
|
Group
|
||||||
|
<e> Error
|
||||||
|
<w> Warning
|
||||||
|
<i> Info
|
||||||
|
Log
|
||||||
|
<+> Collaped group
|
||||||
|
+ 3 hidden lines
|
||||||
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for preset-errors-only 1`] = `""`;
|
exports[`StatsTestCases should print correct stats for preset-errors-only 1`] = `""`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for preset-errors-only-error 1`] = `
|
exports[`StatsTestCases should print correct stats for preset-errors-only-error 1`] = `
|
||||||
"ERROR in ./index.js 1:0-25
|
"LOG from MyPlugin
|
||||||
|
<e> Error
|
||||||
|
+ 9 hidden lines
|
||||||
|
|
||||||
|
ERROR in ./index.js 1:0-25
|
||||||
Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/preset-errors-only-error'
|
Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/preset-errors-only-error'
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for preset-errors-warnings 1`] = `""`;
|
exports[`StatsTestCases should print correct stats for preset-errors-warnings 1`] = `
|
||||||
|
"LOG from MyPlugin
|
||||||
|
<e> Error
|
||||||
|
<w> Warning
|
||||||
|
+ 8 hidden lines
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for preset-minimal 1`] = `" 10 modules"`;
|
exports[`StatsTestCases should print correct stats for preset-minimal 1`] = `
|
||||||
|
" 10 modules
|
||||||
|
|
||||||
|
LOG from MyPlugin
|
||||||
|
<e> Error
|
||||||
|
<w> Warning
|
||||||
|
+ 8 hidden lines
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for preset-minimal-simple 1`] = `" 1 module"`;
|
exports[`StatsTestCases should print correct stats for preset-minimal-simple 1`] = `" 1 module"`;
|
||||||
|
|
||||||
|
|
@ -2109,7 +2174,14 @@ Entrypoint main = main.js
|
||||||
[767] ./d.js 22 bytes {524} [built]
|
[767] ./d.js 22 bytes {524} [built]
|
||||||
[847] ./a.js 22 bytes {179} [built]
|
[847] ./a.js 22 bytes {179} [built]
|
||||||
[996] ./b.js 22 bytes {996} [built]
|
[996] ./b.js 22 bytes {996} [built]
|
||||||
+ 4 hidden modules"
|
+ 4 hidden modules
|
||||||
|
|
||||||
|
LOG from MyPlugin
|
||||||
|
<e> Error
|
||||||
|
<w> Warning
|
||||||
|
<i> Info
|
||||||
|
+ 7 hidden lines
|
||||||
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for preset-normal-performance 1`] = `
|
exports[`StatsTestCases should print correct stats for preset-normal-performance 1`] = `
|
||||||
|
|
@ -2230,7 +2302,18 @@ chunk {996} 996.js 22 bytes <{179}> [rendered]
|
||||||
[996] ./b.js 22 bytes {996} [depth 1] [built]
|
[996] ./b.js 22 bytes {996} [depth 1] [built]
|
||||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||||
amd require ./b [10] ./index.js 2:0-16
|
amd require ./b [10] ./index.js 2:0-16
|
||||||
[10] Xms -> Xms (resolving: Xms, restoring: Xms, integration: Xms, building: Xms, storing: Xms)"
|
[10] Xms -> Xms (resolving: Xms, restoring: Xms, integration: Xms, building: Xms, storing: Xms)
|
||||||
|
|
||||||
|
LOG from MyPlugin
|
||||||
|
Group
|
||||||
|
<e> Error
|
||||||
|
<w> Warning
|
||||||
|
<i> Info
|
||||||
|
Log
|
||||||
|
Collaped group
|
||||||
|
Log inside collapsed group
|
||||||
|
+ 1 hidden lines
|
||||||
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = `
|
exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = `
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* eslint-disable node/no-unsupported-features/node-builtins */
|
||||||
|
module.exports = function(source) {
|
||||||
|
const logger = this.getLogger ? this.getLogger() : console;
|
||||||
|
logger.time("Measure");
|
||||||
|
logger.error("An error");
|
||||||
|
logger.warn("A %s", "warning");
|
||||||
|
logger.group("Unimportant");
|
||||||
|
logger.info("Info message");
|
||||||
|
logger.log("Just log");
|
||||||
|
logger.debug("Just debug");
|
||||||
|
logger.timeLog("Measure");
|
||||||
|
logger.groupCollapsed("Nested");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd("Nested");
|
||||||
|
logger.trace();
|
||||||
|
logger.timeEnd("Measure");
|
||||||
|
logger.clear();
|
||||||
|
logger.log("After clear");
|
||||||
|
this.getLogger("Named Logger").debug("Message with named logger");
|
||||||
|
return source;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.info("Plugin is now active");
|
||||||
|
logger.debug("Debug message should not be visible");
|
||||||
|
logger.groupCollapsed("Nested");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd("Nested");
|
||||||
|
|
||||||
|
const otherLogger = compilation.getLogger("MyOtherPlugin");
|
||||||
|
otherLogger.debug("debug message only");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: "production",
|
||||||
|
entry: "./index",
|
||||||
|
performance: false,
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /index\.js$/,
|
||||||
|
use: "custom-loader"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [new MyPlugin()],
|
||||||
|
stats: {
|
||||||
|
colors: true,
|
||||||
|
logging: true,
|
||||||
|
loggingDebug: "custom-loader",
|
||||||
|
loggingTrace: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,5 +1,24 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
entry: "./index",
|
entry: "./index",
|
||||||
stats: "detailed"
|
stats: "detailed",
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,24 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
entry: "./index",
|
entry: "./index",
|
||||||
stats: "errors-only"
|
stats: "errors-only",
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,24 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
entry: "./index",
|
entry: "./index",
|
||||||
stats: "errors-warnings"
|
stats: "errors-warnings",
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,24 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
entry: "./index",
|
entry: "./index",
|
||||||
stats: "minimal"
|
stats: "minimal",
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,24 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
entry: "./index",
|
entry: "./index",
|
||||||
stats: false
|
stats: false,
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,24 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
entry: "./index",
|
entry: "./index",
|
||||||
stats: "normal"
|
stats: "normal",
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,25 @@
|
||||||
|
class MyPlugin {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.compilation.tap("MyPlugin", compilation => {
|
||||||
|
const logger = compilation.getLogger("MyPlugin");
|
||||||
|
logger.group("Group");
|
||||||
|
logger.error("Error");
|
||||||
|
logger.warn("Warning");
|
||||||
|
logger.info("Info");
|
||||||
|
logger.log("Log");
|
||||||
|
logger.debug("Debug");
|
||||||
|
logger.groupCollapsed("Collaped group");
|
||||||
|
logger.log("Log inside collapsed group");
|
||||||
|
logger.groupEnd();
|
||||||
|
logger.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "production",
|
mode: "production",
|
||||||
entry: "./index",
|
entry: "./index",
|
||||||
profile: true,
|
profile: true,
|
||||||
stats: "verbose"
|
stats: "verbose",
|
||||||
|
plugins: [new MyPlugin()]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
46
yarn.lock
46
yarn.lock
|
|
@ -373,9 +373,9 @@
|
||||||
integrity sha512-MeatbbUsZ80BEsKPXby6pUZjUM9ZuHIpWElN0siopih3fvnlpX2O9L6D5+dzDIb36lf9tM/8U4PVdLQ+L4qr4A==
|
integrity sha512-MeatbbUsZ80BEsKPXby6pUZjUM9ZuHIpWElN0siopih3fvnlpX2O9L6D5+dzDIb36lf9tM/8U4PVdLQ+L4qr4A==
|
||||||
|
|
||||||
"@types/node@^10.12.21":
|
"@types/node@^10.12.21":
|
||||||
version "10.14.12"
|
version "10.14.13"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7"
|
||||||
integrity sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg==
|
integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ==
|
||||||
|
|
||||||
"@types/prettier@^1.16.1":
|
"@types/prettier@^1.16.1":
|
||||||
version "1.16.1"
|
version "1.16.1"
|
||||||
|
|
@ -609,9 +609,9 @@ acorn@^5.5.3:
|
||||||
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
|
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
|
||||||
|
|
||||||
acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.0:
|
acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.0:
|
||||||
version "6.2.0"
|
version "6.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51"
|
||||||
integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==
|
integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==
|
||||||
|
|
||||||
ajv-errors@^1.0.0:
|
ajv-errors@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
|
|
@ -1321,10 +1321,10 @@ commander@^2.14.1, commander@^2.19.0, commander@^2.9.0, commander@~2.20.0:
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||||
|
|
||||||
comment-parser@^0.5.5:
|
comment-parser@^0.6.0:
|
||||||
version "0.5.5"
|
version "0.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.5.5.tgz#c2584cae7c2f0afc773e96b2ee98f8c10cbd693d"
|
resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.6.1.tgz#88040c7c0a57c62e64962c3e888518620a42e7c9"
|
||||||
integrity sha512-oB3TinFT+PV3p8UwDQt71+HkG03+zwPwikDlKU6ZDmql6QX2zFlQ+G0GGSDqyJhdZi4PSlzFBm+YJ+ebOX3Vgw==
|
integrity sha512-Putzd7Ilyvknmb1KxGf5el9uw0sPx9gEVnDrm8tlvXGN1i8Uaa2VBxB32hUhfzTlrEhhxNQ+pKq4ZNe8wNxjmw==
|
||||||
|
|
||||||
commondir@^1.0.1:
|
commondir@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
|
|
@ -1841,16 +1841,16 @@ eslint-plugin-es@^1.3.1:
|
||||||
regexpp "^2.0.1"
|
regexpp "^2.0.1"
|
||||||
|
|
||||||
eslint-plugin-jest@^22.2.2:
|
eslint-plugin-jest@^22.2.2:
|
||||||
version "22.8.0"
|
version "22.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.8.0.tgz#242ef5459e8da25d2c41438e95eb546e03d7fae1"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.13.0.tgz#d7d134c6e3c2f67cc50f5fa89a329db579d28428"
|
||||||
integrity sha512-2VftZMfILmlhL3VMq5ptHRIuyyXb3ShDEDb1J1UjvWNzm4l+UK/YmwNuTuJcM0gv8pJuOfiR/8ZptJ8Ou68pFw==
|
integrity sha512-bIr8LL7buUXS8Pk69SFgaDKgyvPQkDu6i8ko0lP54uccszlo4EOwtstDXOZl5Af3JwudbECxRUbCpL/2cKDkkg==
|
||||||
|
|
||||||
eslint-plugin-jsdoc@^15.3.2:
|
eslint-plugin-jsdoc@^15.3.2:
|
||||||
version "15.5.2"
|
version "15.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-15.5.2.tgz#89768320c64ec2f30d12209e1926c4decca0568a"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-15.5.3.tgz#44e408e3bf2f60f3ad18dc829f9b9a1e34f33154"
|
||||||
integrity sha512-5s39RYGaqugWVoOfc6pAwj9yeNh7mclygBWTyYVJX+sGiNchwCtgHbn2AjeonOw0g168CPI3itiXetHj2Yo8gg==
|
integrity sha512-lw8wYa1UFV53JLoqKOQR8YBkKlE/aguR+HGyytL9VKsVvm83DK8ReYnNNDRKik3MF661cGuaUuGfIEcdqg9l4A==
|
||||||
dependencies:
|
dependencies:
|
||||||
comment-parser "^0.5.5"
|
comment-parser "^0.6.0"
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
flat-map-polyfill "^0.3.8"
|
flat-map-polyfill "^0.3.8"
|
||||||
jsdoctypeparser "5.0.1"
|
jsdoctypeparser "5.0.1"
|
||||||
|
|
@ -3835,9 +3835,9 @@ lodash.sortby@^4.7.0:
|
||||||
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
||||||
|
|
||||||
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.4:
|
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.4:
|
||||||
version "4.17.14"
|
version "4.17.15"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||||
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
|
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||||
|
|
||||||
log-driver@^1.2.7:
|
log-driver@^1.2.7:
|
||||||
version "1.2.7"
|
version "1.2.7"
|
||||||
|
|
@ -5500,9 +5500,9 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||||
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
||||||
|
|
||||||
simple-git@^1.65.0, simple-git@^1.85.0:
|
simple-git@^1.65.0, simple-git@^1.85.0:
|
||||||
version "1.121.0"
|
version "1.122.0"
|
||||||
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.121.0.tgz#4bdf0828cd1b0bb3cb7ed9bead2771982ef5876a"
|
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.122.0.tgz#33b2d3a760aa02df470c79fbab5413d4f4e68945"
|
||||||
integrity sha512-LyYri/nuAX8+cx9nZw38mWO6oHNi//CmiPlkBL7aVjZIsdldve7eeDwXu9L4wP/74MpNHucXkXc/BOuIQShhPg==
|
integrity sha512-plTwhnkIHrw2TFMJbJH/mKwWGgFbj03V9wcfBKa4FsuvgJbpwdlSJnlvkIQWDV1CVLaf2Gl6zSNeRRnxBRhX1g==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.0.1"
|
debug "^4.0.1"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue