what-compiler 0.10.0 → 0.11.1

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.
@@ -17,6 +17,41 @@ import { setupErrorOverlay } from './error-overlay.js';
17
17
  const VIRTUAL_ROUTES_ID = 'virtual:what-routes';
18
18
  const RESOLVED_VIRTUAL_ID = '\0' + VIRTUAL_ROUTES_ID;
19
19
 
20
+ /**
21
+ * Shape the "preserve JSX" transform config for the running Vite version.
22
+ *
23
+ * Vite ≤7 transforms with esbuild and takes `esbuild: { jsx: 'preserve' }`.
24
+ * Vite 8 (rolldown-based) transforms with oxc; the `esbuild` key still works
25
+ * but prints a deprecation warning on every dev/build run
26
+ * ("'esbuild' option ... is deprecated, please use 'oxc' instead"), so we
27
+ * emit `oxc: { jsx: 'preserve' }` there instead.
28
+ *
29
+ * Detection (either signal selects oxc):
30
+ * - feature: rolldown-vite exposes `this.meta.rolldownVersion` to plugins —
31
+ * the most reliable signal, also covers `rolldown-vite` aliased as vite 7.
32
+ * - version: `import('vite')` exports `version`; major ≥ 8 means rolldown.
33
+ *
34
+ * Exported for unit tests.
35
+ */
36
+ export function jsxPreserveConfig({ rolldownVersion, viteVersion } = {}) {
37
+ const major = parseInt(String(viteVersion ?? ''), 10);
38
+ const useOxc = Boolean(rolldownVersion) || (Number.isFinite(major) && major >= 8);
39
+ return useOxc
40
+ ? { oxc: { jsx: 'preserve' } }
41
+ : { esbuild: { jsx: 'preserve' } };
42
+ }
43
+
44
+ // Resolved once per process — the Vite version can't change mid-run.
45
+ let viteVersionPromise = null;
46
+ function detectViteVersion() {
47
+ if (!viteVersionPromise) {
48
+ viteVersionPromise = import('vite')
49
+ .then((vite) => vite.version || '')
50
+ .catch(() => ''); // vite not resolvable (tests) — esbuild fallback
51
+ }
52
+ return viteVersionPromise;
53
+ }
54
+
20
55
  // Pattern: exported function starting with uppercase = component
21
56
  const COMPONENT_EXPORT_RE = /export\s+(?:default\s+)?function\s+([A-Z]\w*)/;
22
57
  // Pattern: files that are likely signal/store/utility files
@@ -36,6 +71,11 @@ export default function whatVitePlugin(options = {}) {
36
71
  pages = 'src/pages',
37
72
  // HMR: enabled by default in dev, disabled in production
38
73
  hot = !production,
74
+ // Resolve the `production` exports condition (dist/*.min.js — pre-minified,
75
+ // dev warnings compiled out) during `vite build`. Set to false to build
76
+ // against package sources instead — needed e.g. in a monorepo where
77
+ // workspace-linked dist/ output may be stale or absent. See config() below.
78
+ prodBundles = true,
39
79
  } = options;
40
80
 
41
81
  let rootDir = '';
@@ -105,6 +145,13 @@ export default function whatVitePlugin(options = {}) {
105
145
  const result = transformSync(code, {
106
146
  filename: id,
107
147
  sourceMaps,
148
+ // Hermetic transform (SPRINT v0.11 C7): never load the project's
149
+ // babel.config.js/.babelrc. A user's React preset or unrelated
150
+ // plugins corrupting What's JSX output is a debugging nightmare —
151
+ // and scanning the disk for config files on every transform is
152
+ // wasted I/O in dev.
153
+ configFile: false,
154
+ babelrc: false,
108
155
  plugins: [
109
156
  [whatBabelPlugin, { production }]
110
157
  ],
@@ -165,12 +212,35 @@ export default function whatVitePlugin(options = {}) {
165
212
  },
166
213
 
167
214
  // Configure for development
168
- config(config, { mode }) {
215
+ async config(config, { mode, command }) {
216
+ // SPRINT v0.11 C7: make the `production` exports condition reachable.
217
+ // what-framework/what-core ship pre-minified production bundles behind
218
+ // the `production` condition in their exports maps, but Vite's default
219
+ // resolve conditions never include `production` — so production builds
220
+ // silently shipped the dev source (larger, with dev-only warnings).
221
+ //
222
+ // Guard rationale (documented choice):
223
+ // - Only during `vite build` in production mode — dev always uses src
224
+ // so the dev server, HMR, and devtools see un-minified modules.
225
+ // - Opt-out via `what({ prodBundles: false })` — in a monorepo with
226
+ // workspace-linked packages, dist/ can be stale (or missing before
227
+ // the first `npm run build`), and resolving `production` there would
228
+ // bundle outdated framework code. Apps installing from npm always
229
+ // have dist/ in sync with the published package, so the default is on.
230
+ // - `resolve.conditions` is ADDITIVE in Vite (extra conditions on top
231
+ // of the defaults), so import/browser/default resolution for other
232
+ // packages is unaffected.
233
+ const useProdCondition = command === 'build' && mode === 'production' && prodBundles;
234
+ // Preserve JSX so our babel plugin handles it — don't let the bundler's
235
+ // built-in transformer (esbuild on Vite ≤7, oxc on Vite 8+) touch it.
236
+ // jsxPreserveConfig picks the right option key for the running version.
237
+ const jsxPreserve = jsxPreserveConfig({
238
+ rolldownVersion: this?.meta?.rolldownVersion,
239
+ viteVersion: await detectViteVersion(),
240
+ });
169
241
  return {
170
- esbuild: {
171
- // Preserve JSX so our babel plugin handles it -- don't let esbuild transform it
172
- jsx: 'preserve',
173
- },
242
+ ...(useProdCondition ? { resolve: { conditions: ['production'] } } : {}),
243
+ ...jsxPreserve,
174
244
  optimizeDeps: {
175
245
  // Exclude framework packages from Vite's dependency pre-bundling.
176
246
  //