@emulsify/core 4.3.0 → 4.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,12 @@
18
18
  * message passes straight through to Vite's own logger untouched.
19
19
  */
20
20
 
21
+ import { isQuiet, isVerbose } from './verbosity.js';
22
+
23
+ // Re-exported because the Vite config and the reporter both branch on it, and
24
+ // this module was where it lived before verbosity grew a third level.
25
+ export { isVerbose };
26
+
21
27
  /**
22
28
  * Matches Vite's unresolved CSS asset notice.
23
29
  *
@@ -77,13 +83,68 @@ function isBareStackTrace(message) {
77
83
  }
78
84
 
79
85
  /**
80
- * Determine whether the reporter should stand aside and let Vite speak.
86
+ * Matches Vite's HMR notice.
87
+ *
88
+ * Emitted by the dev server as `hmr update <files>` through `logger.info`.
81
89
  *
82
- * @param {object} [env] - Environment variables.
83
- * @returns {boolean} TRUE when raw output should pass through.
90
+ * @type {RegExp}
91
+ */
92
+ const HMR_UPDATE_PATTERN = /(^|\s)hmr update\s/;
93
+
94
+ /**
95
+ * Wrap the Storybook dev server's logger to drop HMR notices.
96
+ *
97
+ * These come from Storybook's Vite dev server, not from the watch build, and
98
+ * there are a lot of them. The watch build rewrites every file in `dist/` on
99
+ * every cycle — Rollup regenerates the whole bundle — and Storybook imports its
100
+ * compiled CSS from `dist/`, so one saved stylesheet lands as several HMR events.
101
+ * Most name Storybook's own virtual modules:
102
+ *
103
+ * │ Vite hmr update
104
+ * │ /@id/__x00__virtual:/@storybook/builder-vite/project-annotations.js,
105
+ * │ /@id/__x00__virtual:/@storybook/builder-vite/vite-app.js
106
+ *
107
+ * Nothing there is actionable, and the reporter has already printed the rebuild
108
+ * line that says the same thing more precisely. Under `concurrently` both
109
+ * processes share one pipe, so these interleave with the build's output and are
110
+ * the last thing making one command look like two.
111
+ *
112
+ * The wrapper delegates to whatever logger is already configured rather than
113
+ * replacing it, so Storybook keeps its own prefixes and styling for every other
114
+ * message. Verbose modes pass everything through, because someone who asked for
115
+ * more output should not have this filtered away.
116
+ *
117
+ * @param {{
118
+ * baseLogger: import('vite').Logger,
119
+ * verbose?: boolean
120
+ * }} options - Logger options.
121
+ * @returns {import('vite').Logger} Wrapped logger.
84
122
  */
85
- export function isVerbose(env = process.env) {
86
- return Boolean(env.EMULSIFY_VERBOSE) && env.EMULSIFY_VERBOSE !== '0';
123
+ export function createDevServerLogger({ baseLogger, verbose } = {}) {
124
+ const passThrough = verbose === undefined ? !isQuiet() : verbose;
125
+
126
+ return {
127
+ get hasWarned() {
128
+ return baseLogger.hasWarned;
129
+ },
130
+
131
+ set hasWarned(value) {
132
+ baseLogger.hasWarned = value;
133
+ },
134
+
135
+ info(message, options) {
136
+ if (!passThrough && HMR_UPDATE_PATTERN.test(stripAnsi(String(message)))) {
137
+ return;
138
+ }
139
+ baseLogger.info(message, options);
140
+ },
141
+
142
+ warn: (message, options) => baseLogger.warn(message, options),
143
+ warnOnce: (message, options) => baseLogger.warnOnce(message, options),
144
+ error: (message, options) => baseLogger.error(message, options),
145
+ clearScreen: (type) => baseLogger.clearScreen(type),
146
+ hasErrorLogged: (error) => baseLogger.hasErrorLogged(error),
147
+ };
87
148
  }
88
149
 
89
150
  /**
@@ -37,7 +37,10 @@ import { buildInputs } from './entries.js';
37
37
  import { createSourceFileIndex } from './plugins/assets/source-file-index.js';
38
38
  import { createDiagnosticsCollector } from './plugins/reporter/diagnostics.js';
39
39
  import { createSassOptions } from './plugins/reporter/sass-logger.js';
40
- import { createReporterLogger } from './plugins/reporter/vite-logger.js';
40
+ import {
41
+ createReporterLogger,
42
+ isVerbose,
43
+ } from './plugins/reporter/vite-logger.js';
41
44
  import { isWatchInvocation } from './plugins/reporter/watch-mode.js';
42
45
  import { loadProjectExtensions } from './project-extensions.js';
43
46
  import { mergeReactSingletonResolve } from './utils/react-singleton.js';
@@ -101,10 +104,47 @@ export default defineConfig(async () => {
101
104
  // Core plugin set + project-provided plugins (if any).
102
105
  plugins: [...makePlugins(envWithSourceFileIndex), ...projectPlugins],
103
106
 
104
- // Route Vite's own diagnostics through the reporter during a watch build so
105
- // unresolved CSS asset URLs are summarized rather than printed mid-build.
107
+ // Quieting `develop` takes two independent switches, because the output has
108
+ // two independent sources.
109
+ //
110
+ // 1. `logLevel` gates Vite's build reporter, which is a native Rolldown
111
+ // plugin. Vite reads `config.logLevel` directly when constructing it and
112
+ // passes a `logInfo` callback only when the level admits info. Rolldown's
113
+ // Rust side registers its Transform, BuildStart, BuildEnd, RenderChunk,
114
+ // WriteBundle, and GenerateBundle hooks only when that callback exists,
115
+ // so raising the level does not merely hide the report — it stops
116
+ // Rolldown instrumenting transforms and computing gzip sizes at all.
117
+ // That removes the `transforming (N)` progress line, `N modules
118
+ // transformed.`, `rendering chunks...`, `computing gzip size...`, and the
119
+ // per-file asset table, and makes every rebuild cheaper.
120
+ //
121
+ // The progress line is the one that matters most for legibility: Rolldown
122
+ // writes it from Rust with a `\x1b[2K\r` prefix and no trailing newline,
123
+ // which is what collides with Storybook's output when `concurrently`
124
+ // merges both streams onto one pipe. Nothing on the JavaScript side can
125
+ // intercept it, so `logLevel` is the only lever that removes it.
126
+ //
127
+ // 2. `customLogger` gates Vite's own JavaScript chatter — `building client
128
+ // environment...`, `build started...`, `watching for file changes...`,
129
+ // and `built in Nms.` — and routes unresolved CSS asset URLs into the
130
+ // diagnostics collector so they are summarized rather than printed
131
+ // mid-build. The reporter writes straight to stdout rather than through
132
+ // this logger, so its own output survives the higher level, and warnings
133
+ // and errors still come through.
134
+ //
135
+ // Neither switch substitutes for the other: `createLogger` returns a
136
+ // supplied `customLogger` verbatim and never consults the level, while the
137
+ // build reporter consults the level and never consults the logger.
138
+ // `build.reportCompressedSize` is deliberately left alone; it suppresses
139
+ // only the gzip column, and the table it belongs to is already gone.
106
140
  ...(diagnostics
107
- ? { customLogger: createReporterLogger(diagnostics, createLogger()) }
141
+ ? {
142
+ logLevel: isVerbose() ? 'info' : 'warn',
143
+ customLogger: createReporterLogger(
144
+ diagnostics,
145
+ createLogger(isVerbose() ? 'info' : 'warn'),
146
+ ),
147
+ }
108
148
  : {}),
109
149
 
110
150
  // Keep React-based story helpers on the consumer project's React singleton.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@emulsify/core",
3
- "version": "4.3.0",
4
- "description": "Shared Vite build tooling and Storybook support for Twig, React, and custom elements",
3
+ "version": "4.3.2",
4
+ "description": "Bundled tooling for Storybook development + Vite Build",
5
5
  "keywords": [
6
6
  "component library",
7
7
  "craftcms",
@@ -47,6 +47,7 @@
47
47
  ".storybook/manager-head.css",
48
48
  ".storybook/manager.js",
49
49
  ".storybook/preview.js",
50
+ ".storybook/ready-reporter.js",
50
51
  ".storybook/utils.js",
51
52
  "assets/**/*",
52
53
  "config/.prettierrc.json",
@@ -72,6 +73,8 @@
72
73
  "config/vite/plugins/reporter/index.js",
73
74
  "config/vite/plugins/reporter/render.js",
74
75
  "config/vite/plugins/reporter/sass-logger.js",
76
+ "config/vite/plugins/reporter/source-roots.js",
77
+ "config/vite/plugins/reporter/verbosity.js",
75
78
  "config/vite/plugins/reporter/vite-logger.js",
76
79
  "config/vite/plugins/reporter/watch-mode.js",
77
80
  "config/vite/plugins/require-context.js",