Skip to content

Commit a633576

Browse files
committed
[WOOTAX-294] Ban bundled React imports in the store notices tree
Nothing stopped a bundled React import from coming back into these files, and the unit tests cannot catch it: under Jest the host React and the bundled React are the same instance, so an element built with the wrong one still looks right. Restrict the react import in this tree instead, and record the constraint next to the code it applies to, along with the dependency list the entry relies on.
1 parent 81cc8ce commit a633576

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

.eslintrc.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,29 @@ Object.assign( calypsoLintConfig.globals, {
2323
global: true,
2424
});
2525

26+
// The store notices bundle is rendered by the React that WordPress provides, inside the
27+
// Cart/Checkout blocks. React 19 rejects elements created by an older React runtime, so
28+
// importing the plugin's bundled React here would break the block cart and checkout.
29+
// Everything in this tree must build its elements with window.wp.element instead.
30+
calypsoLintConfig.overrides = [
31+
...( calypsoLintConfig.overrides || [] ),
32+
{
33+
files: [ 'client/store-notices.js', 'client/components/store/notices/*.js' ],
34+
rules: {
35+
'no-restricted-imports': [
36+
'error',
37+
{
38+
paths: [
39+
{
40+
name: 'react',
41+
message:
42+
'This tree is rendered by the host React: build elements with window.wp.element instead. See client/store-notices.js.',
43+
},
44+
],
45+
},
46+
],
47+
},
48+
},
49+
];
50+
2651
module.exports = useE2EEsLintConfig( calypsoLintConfig );

client/store-notices.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
*/
44
import { StoreNotices } from 'components/store/notices';
55

6+
// Every global read here is a script dependency: keep this list in sync with the
7+
// dependencies declared in WooCommerceBlocksIntegration::register_script(), which is
8+
// what guarantees these are loaded before this script runs.
69
const { registerPlugin } = window.wp.plugins;
710
const { createElement } = window.wp.element;
811
const { ExperimentalOrderMeta } = window.wc.blocksCheckout;
@@ -13,11 +16,13 @@ const { ExperimentalOrderMeta } = window.wc.blocksCheckout;
1316
* Elements here must be created with the WordPress-provided React
1417
* (window.wp.element), not the plugin's bundled React: this tree is rendered
1518
* by the host React inside the Cart/Checkout blocks, and React 19 rejects
16-
* elements created by an older React runtime.
19+
* elements created by an older React runtime. This is why the slot fill is
20+
* built with createElement rather than the JSX used in the doc below.
1721
*
1822
* @see https://github.com/woocommerce/woocommerce/blob/a7231863c014a95602f5932f702171465fa7bcf2/docs/cart-and-checkout-blocks/available-slot-fills.md?plain=1#L53
23+
* ExperimentalOrderMeta slot fill reference.
1924
*
20-
* @return {Object} The plugin content.
25+
* @return {Object} The plugin content, as a host React element.
2126
*/
2227
const render = () => {
2328
return createElement( ExperimentalOrderMeta, null, createElement( StoreNotices ) );

0 commit comments

Comments
 (0)