Skip to content

Commit 2a4dda7

Browse files
authored
feat: React 19 behind a feature flag (#20816)
1 parent d17ff83 commit 2a4dda7

File tree

4 files changed

+50
-0
lines changed

4 files changed

+50
-0
lines changed

flow-server/src/main/java/com/vaadin/experimental/FeatureFlags.java

+5
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ public class FeatureFlags implements Serializable {
9595
"https://github.com/vaadin/web-components/issues/5340", true,
9696
"com.vaadin.flow.component.card.Card");
9797

98+
public static final Feature REACT19 = new Feature(
99+
"React 19 (default in Vaadin 25)", "react19",
100+
"https://react.dev/blog/2024/12/05/react-19", true, null);
101+
98102
private List<Feature> features = new ArrayList<>();
99103

100104
File propertiesFolder = null;
@@ -123,6 +127,7 @@ public FeatureFlags(Lookup lookup) {
123127
features.add(new Feature(COPILOT_EXPERIMENTAL));
124128
features.add(new Feature(DASHBOARD_COMPONENT));
125129
features.add(new Feature(CARD_COMPONENT));
130+
features.add(new Feature(REACT19));
126131
loadProperties();
127132
}
128133

flow-server/src/main/java/com/vaadin/flow/server/frontend/NodeUpdater.java

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.slf4j.Logger;
3838
import org.slf4j.LoggerFactory;
3939

40+
import com.vaadin.experimental.FeatureFlags;
4041
import com.vaadin.flow.server.Constants;
4142
import com.vaadin.flow.server.frontend.scanner.ClassFinder;
4243
import com.vaadin.flow.server.frontend.scanner.FrontendDependencies;
@@ -302,6 +303,10 @@ Map<String, String> getDefaultDependencies() {
302303
if (options.isReactEnabled()) {
303304
dependencies
304305
.putAll(readDependencies("react-router", "dependencies"));
306+
if (options.getFeatureFlags().isEnabled(FeatureFlags.REACT19)) {
307+
dependencies
308+
.putAll(readDependencies("react19", "dependencies"));
309+
}
305310
} else {
306311
dependencies
307312
.putAll(readDependencies("vaadin-router", "dependencies"));
@@ -368,6 +373,9 @@ Map<String, String> getDefaultDevDependencies() {
368373
if (options.isReactEnabled()) {
369374
defaults.putAll(
370375
readDependencies("react-router", "devDependencies"));
376+
if (options.getFeatureFlags().isEnabled(FeatureFlags.REACT19)) {
377+
defaults.putAll(readDependencies("react19", "devDependencies"));
378+
}
371379
}
372380

373381
return defaults;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"private": true,
3+
"description": "A list of Flow dependencies when using React 19",
4+
"dependencies": {
5+
"react": "19.0.0",
6+
"react-dom": "19.0.0"
7+
},
8+
"devDependencies": {
9+
"@types/react": "19.0.2",
10+
"@types/react-dom": "19.0.2"
11+
}
12+
}

flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdaterTest.java

+25
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,31 @@ public void getDefaultDependencies_includesAllDependencies() {
127127
Assert.assertEquals(expectedDependencies, actualDependendencies);
128128
}
129129

130+
@Test
131+
public void react19UsedWhenFeatureFlagIsOn() {
132+
Map<String, String> react18Deps = nodeUpdater.getDefaultDependencies();
133+
Map<String, String> react18DevDeps = nodeUpdater
134+
.getDefaultDevDependencies();
135+
Mockito.when(options.getFeatureFlags().isEnabled(FeatureFlags.REACT19))
136+
.thenReturn(true);
137+
138+
Map<String, String> react19Deps = nodeUpdater.getDefaultDependencies();
139+
Map<String, String> react19DevDeps = nodeUpdater
140+
.getDefaultDevDependencies();
141+
142+
Assert.assertTrue(react18Deps.get("react").startsWith("18."));
143+
Assert.assertTrue(react18Deps.get("react-dom").startsWith("18."));
144+
Assert.assertTrue(react18DevDeps.get("@types/react").startsWith("18."));
145+
Assert.assertTrue(
146+
react18DevDeps.get("@types/react-dom").startsWith("18."));
147+
148+
Assert.assertTrue(react19Deps.get("react").startsWith("19."));
149+
Assert.assertTrue(react19Deps.get("react-dom").startsWith("19."));
150+
Assert.assertTrue(react19DevDeps.get("@types/react").startsWith("19."));
151+
Assert.assertTrue(
152+
react19DevDeps.get("@types/react-dom").startsWith("19."));
153+
}
154+
130155
@Test
131156
public void getDefaultDevDependencies_includesAllDependencies_whenUsingVite() {
132157
Map<String, String> defaultDeps = nodeUpdater

0 commit comments

Comments
 (0)