@clicktap/ui 2.0.7 → 2.0.8
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.
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# The build fails if it emits the development JSX runtime
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-08-24
|
|
4
|
+
**Package:** `@clicktap/ui` (also `@clicktap/state`, `@clicktap/csx`)
|
|
5
|
+
**Affects:** anyone building or publishing these packages. Consumers receive a guarantee, not a change.
|
|
6
|
+
**Classification:** BUGFIX
|
|
7
|
+
**Breaking:** No. A correct build is unaffected; an incorrect one now fails instead of publishing.
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
A build could emit React's **development** JSX runtime — `jsxDEV(...)` call sites
|
|
12
|
+
plus a bundled `assets/jsx-dev-runtime-*.js` chunk. A consumer's production React
|
|
13
|
+
does not export `jsxDEV`, so the package compiles and then dies at prerender:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
TypeError: r.j.jsxDEV is not a function
|
|
17
|
+
at .next/server/app/page.js
|
|
18
|
+
Error occurred prerendering page "/"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
⚠️ **Nothing in the build looked at the JSX runtime.** Not
|
|
22
|
+
`verifyUseClientDirectives`, not typecheck, not lint. The artifact was
|
|
23
|
+
structurally valid and publishable; only a consumer's `next build` found it.
|
|
24
|
+
|
|
25
|
+
## It was never intermittent
|
|
26
|
+
|
|
27
|
+
CTAP-1393 recorded this as intermittent — seen twice, then not reproducible across
|
|
28
|
+
five clean builds. It is deterministic, and the trigger was in `project.json`:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
"configurations": {
|
|
32
|
+
"development": { "mode": "development" },
|
|
33
|
+
"production": { "mode": "production" }
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`@vitejs/plugin-react` selects the dev JSX runtime from the resolved mode. So
|
|
38
|
+
`--configuration=development` — or any dependent target that propagated it —
|
|
39
|
+
produced a dev-runtime artifact, every time. The five "clean" builds used the
|
|
40
|
+
default production configuration.
|
|
41
|
+
|
|
42
|
+
Measured on this repo, and matching the original report's numbers exactly:
|
|
43
|
+
|
|
44
|
+
| build | emitted files referencing `jsxDEV` |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| default (production) | **0** |
|
|
47
|
+
| `--mode=development` | **206** |
|
|
48
|
+
|
|
49
|
+
## Fix — three layers, and only one of them is load-bearing
|
|
50
|
+
|
|
51
|
+
1. **The `development` build configuration is removed** from `ui`, `state`, `csx`
|
|
52
|
+
and `conversion-tracking-facebook`. A published library artifact has no
|
|
53
|
+
legitimate development mode, and nothing in the repo invoked it. This removes
|
|
54
|
+
the mechanism.
|
|
55
|
+
2. **`verifyProductionJsxRuntime`** now runs in the same `closeBundle` family as
|
|
56
|
+
`verifyUseClientDirectives`, on `ui`, `state` and `csx`. It fails the build if
|
|
57
|
+
any emitted `.js` references `jsxDEV` or `jsx-dev-runtime`.
|
|
58
|
+
3. It also asserts the **positive** direction: a package whose output references
|
|
59
|
+
React must show at least one `react/jsx-runtime` import. Checking only "no
|
|
60
|
+
jsxDEV" passes vacuously on a build that emitted nothing.
|
|
61
|
+
|
|
62
|
+
⚠️ **(2) is the one that holds.** A configuration fix cannot cover a mode arriving
|
|
63
|
+
from a CLI flag, an inherited configuration on a dependent target, or a direct
|
|
64
|
+
vite invocation. The assertion looks at what was actually EMITTED, so it holds
|
|
65
|
+
however the mode was arrived at — which is the difference between making this
|
|
66
|
+
unlikely and making it impossible.
|
|
67
|
+
|
|
68
|
+
The positive check is conditioned on React output rather than required outright:
|
|
69
|
+
`csx` legitimately emits no components (two files, no React), and an assertion
|
|
70
|
+
that fails a correct build gets deleted.
|
|
71
|
+
|
|
72
|
+
## Verified in both directions
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
ui production 248 file(s) clean; 205 import react/jsx-runtime -> build passes
|
|
76
|
+
ui --mode=dev 206 emitted file(s) reference the DEV runtime -> build FAILS
|
|
77
|
+
state production 44 file(s) clean; 12 import react/jsx-runtime -> build passes
|
|
78
|
+
state --mode=dev 14 emitted file(s) reference the DEV runtime -> build FAILS
|
|
79
|
+
csx production 2 file(s) scanned; no React output to check -> build passes
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Migration checklist
|
|
83
|
+
|
|
84
|
+
- [ ] Nothing to do as a consumer.
|
|
85
|
+
- [ ] If you fork these packages and script a build with
|
|
86
|
+
`--configuration=development`, that configuration no longer exists — drop
|
|
87
|
+
the flag. It was producing an artifact that could not be published.
|
|
88
|
+
- [ ] If you add a new published frontend library, wire
|
|
89
|
+
`verifyProductionJsxRuntime(<its dist dir>)` into its vite plugins and do
|
|
90
|
+
not give it a `development` build configuration.
|
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"path": "2026/08/ui-2026-08-24-production-jsx-runtime-guard.md",
|
|
4
|
+
"module": "libs/frontend-modules/ui",
|
|
5
|
+
"package": "@clicktap/ui",
|
|
6
|
+
"date": "2026-08-24",
|
|
7
|
+
"title": "The build fails if it emits the development JSX runtime",
|
|
8
|
+
"classification": "BUGFIX",
|
|
9
|
+
"breaking": "No. A correct build is unaffected; an incorrect one now fails instead of publishing.",
|
|
10
|
+
"affects": "anyone building or publishing these packages. Consumers receive a guarantee, not a change."
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"path": "2026/08/ui-2026-08-24-accordion-author-key-space.md",
|
|
14
|
+
"module": "libs/frontend-modules/ui",
|
|
15
|
+
"package": "@clicktap/ui",
|
|
16
|
+
"date": "2026-08-24",
|
|
17
|
+
"title": "Accordion controlled selection matches authored keys again",
|
|
18
|
+
"classification": "BUGFIX",
|
|
19
|
+
"breaking": "No — unless you shipped a workaround that pre-prefixes keys (see crispi note).",
|
|
20
|
+
"affects": "every controlled or default-expanded `Accordion` — checkout payment method selection, checkout's `defaultExpandedKeys={['cart']}`, totals/discount panel, PDP mobile overview, filter groups."
|
|
21
|
+
},
|
|
2
22
|
{
|
|
3
23
|
"path": "2026/08/ui-2026-08-23-use-client-propagates-to-barrels.md",
|
|
4
24
|
"module": "libs/frontend-modules/ui",
|