|
1 | | -/* eslint-disable no-console -- this module is the console logger */ |
2 | | -// A self-contained level-gated console logger. webpack's logging runtime is |
3 | | -// deliberately not used: it pulls tapable into the bundle, whose hook |
4 | | -// compiler calls `new Function` — which throws under a |
5 | | -// `require-trusted-types-for 'script'` Content Security Policy. |
6 | | - |
7 | | -const LOG_PREFIX = "[webpack-dev-middleware]"; |
8 | | - |
9 | | -/** @typedef {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} LogLevel */ |
10 | | - |
11 | | -const LEVELS = ["none", "error", "warn", "info", "log", "verbose"]; |
| 1 | +// @ts-expect-error -- no published types for this entry point |
| 2 | +import logger from "webpack/lib/logging/runtime.js"; |
12 | 3 |
|
| 4 | +const LOGGER_NAME = "webpack-dev-middleware"; |
13 | 5 | const DEFAULT_LEVEL = "info"; |
14 | 6 |
|
15 | | -let currentLevel = DEFAULT_LEVEL; |
| 7 | +/** @typedef {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} LogLevel */ |
16 | 8 |
|
17 | 9 | /** |
18 | | - * @param {LogLevel} level log level (or `false` for off, `true` for "log") |
| 10 | + * @param {LogLevel} level log level (or `false` for off, `true` for default) |
19 | 11 | */ |
20 | 12 | export function setLogLevel(level) { |
21 | | - if (level === false) { |
22 | | - currentLevel = "none"; |
23 | | - } else if (level === true) { |
24 | | - currentLevel = "log"; |
25 | | - } else if (LEVELS.includes(level)) { |
26 | | - currentLevel = level; |
27 | | - } |
| 13 | + logger.configureDefaultLogger({ level }); |
28 | 14 | } |
29 | 15 |
|
30 | | -/** |
31 | | - * @param {string} level level of the message |
32 | | - * @returns {boolean} true when the current level shows the message |
33 | | - */ |
34 | | -function enabled(level) { |
35 | | - return LEVELS.indexOf(currentLevel) >= LEVELS.indexOf(level); |
36 | | -} |
| 16 | +setLogLevel(DEFAULT_LEVEL); |
| 17 | + |
| 18 | +const rawLog = logger.getLogger(LOGGER_NAME); |
37 | 19 |
|
38 | 20 | /** |
39 | | - * Prefix like webpack's logger: merged into the first argument when it is a |
40 | | - * string, passed separately otherwise (e.g. Error objects). |
41 | | - * @param {unknown[]} args arguments |
42 | | - * @returns {unknown[]} prefixed arguments |
| 21 | + * Guard a logger method: under a `require-trusted-types-for 'script'` |
| 22 | + * Content Security Policy, tapable (bundled through webpack's logging |
| 23 | + * runtime) cannot compile its hooks — `new Function` throws an EvalError on |
| 24 | + * the first log call. Swallowing it keeps HMR fully functional with logging |
| 25 | + * off instead of breaking whatever listener happened to log. |
| 26 | + * @param {string} method logger method name |
| 27 | + * @returns {(...args: unknown[]) => void} guarded method |
43 | 28 | */ |
44 | | -function prefixed(args) { |
45 | | - return typeof args[0] === "string" |
46 | | - ? [`${LOG_PREFIX} ${args[0]}`, ...args.slice(1)] |
47 | | - : [LOG_PREFIX, ...args]; |
| 29 | +function guarded(method) { |
| 30 | + return (...args) => { |
| 31 | + try { |
| 32 | + rawLog[method](...args); |
| 33 | + } catch { |
| 34 | + // Logging is unavailable (e.g. Trusted Types enforcement). |
| 35 | + } |
| 36 | + }; |
48 | 37 | } |
49 | 38 |
|
50 | 39 | export const log = { |
51 | | - /** |
52 | | - * @param {...unknown} args arguments |
53 | | - */ |
54 | | - error(...args) { |
55 | | - if (enabled("error")) console.error(...prefixed(args)); |
56 | | - }, |
57 | | - /** |
58 | | - * @param {...unknown} args arguments |
59 | | - */ |
60 | | - warn(...args) { |
61 | | - if (enabled("warn")) console.warn(...prefixed(args)); |
62 | | - }, |
63 | | - /** |
64 | | - * @param {...unknown} args arguments |
65 | | - */ |
66 | | - info(...args) { |
67 | | - if (enabled("info")) console.info(...prefixed(args)); |
68 | | - }, |
69 | | - /** |
70 | | - * @param {...unknown} args arguments |
71 | | - */ |
72 | | - log(...args) { |
73 | | - if (enabled("log")) console.log(...prefixed(args)); |
74 | | - }, |
75 | | - /** |
76 | | - * @param {...unknown} args arguments |
77 | | - */ |
78 | | - groupCollapsed(...args) { |
79 | | - if (enabled("log")) console.groupCollapsed(...prefixed(args)); |
80 | | - }, |
81 | | - groupEnd() { |
82 | | - if (enabled("log")) console.groupEnd(); |
83 | | - }, |
| 40 | + error: guarded("error"), |
| 41 | + warn: guarded("warn"), |
| 42 | + info: guarded("info"), |
| 43 | + log: guarded("log"), |
| 44 | + groupCollapsed: guarded("groupCollapsed"), |
| 45 | + groupEnd: guarded("groupEnd"), |
84 | 46 | }; |
0 commit comments