Skip to content

Commit da6ba53

Browse files
authored
[UMD] Remove umd builds (#28735)
In React 19 React will finally stop publishing UMD builds. This is motivated primarily by the lack of use of UMD format and the added complexity of maintaining build infra for these releases. Additionally with ESM becoming more prevalent in browsers and services like esm.sh which can host React as an ESM module there are other options for doing script tag based react loading. This PR removes all the UMD build configs and forks. There are some fixtures that still have references to UMD builds however many of them already do not work (for instance they are using legacy features like ReactDOM.render) and rather than block the removal on these fixtures being brought up to date we'll just move forward and fix or removes fixtures as necessary in the future.
1 parent 0c245df commit da6ba53

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1124
-842
lines changed

.eslintrc.js

-1
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,6 @@ module.exports = {
545545
__EXTENSION__: 'readonly',
546546
__PROFILE__: 'readonly',
547547
__TEST__: 'readonly',
548-
__UMD__: 'readonly',
549548
__VARIANT__: 'readonly',
550549
__unmockReact: 'readonly',
551550
gate: 'readonly',

fixtures/dom/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ of the React project. Then:
1010
```
1111
cd fixtures/dom
1212
yarn
13-
yarn start
13+
yarn dev
1414
```
1515

16-
The `start` command runs a script that copies over the local build of react into
16+
The `dev` command runs a script that copies over the local build of react into
1717
the public directory.

fixtures/dom/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
},
2121
"scripts": {
2222
"dev": "react-scripts start",
23-
"predev": "cp ../../build/oss-stable/scheduler/umd/scheduler-unstable_mock.development.js ../../build/oss-stable/scheduler/umd/scheduler-unstable_mock.production.min.js ../../build/oss-stable/react/umd/react.development.js ../../build/oss-stable/react-dom/umd/react-dom.development.js ../../build/oss-stable/react/umd/react.production.min.js ../../build/oss-stable/react-dom/umd/react-dom.production.min.js ../../build/oss-stable/react-dom/umd/react-dom-server.browser.development.js ../../build/oss-stable/react-dom/umd/react-dom-server.browser.production.min.js ../../build/oss-stable/react-dom/umd/react-dom-test-utils.development.js ../../build/oss-stable/react-dom/umd/react-dom-test-utils.production.min.js public/ && cp -a ../../build/oss-stable/. node_modules",
23+
"predev": "cp -a ../../build/oss-stable/. node_modules",
2424
"build": "react-scripts build && cp build/index.html build/200.html",
2525
"test": "react-scripts test --env=jsdom",
2626
"eject": "react-scripts eject"

fixtures/dom/src/index.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@ loadReact()
66
.then(App => {
77
const {React, ReactDOM} = window;
88

9-
ReactDOM.render(
10-
React.createElement(App.default),
11-
document.getElementById('root')
12-
);
9+
if (typeof window.ReactDOMClient !== 'undefined') {
10+
// we are in a React that only supports modern roots
11+
12+
ReactDOM.createRoot(document.getElementById('root')).render(
13+
React.createElement(App.default)
14+
);
15+
} else {
16+
ReactDOM.render(
17+
React.createElement(App.default),
18+
document.getElementById('root')
19+
);
20+
}
1321
});

fixtures/dom/src/react-loader.js

+72-13
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,33 @@ function loadScript(src) {
3636
});
3737
}
3838

39+
function loadModules(SymbolSrcPairs) {
40+
let firstScript = document.getElementsByTagName('script')[0];
41+
42+
let imports = '';
43+
SymbolSrcPairs.map(([symbol, src]) => {
44+
imports += `import ${symbol} from "${src}";\n`;
45+
imports += `window.${symbol} = ${symbol};\n`;
46+
});
47+
48+
return new Promise((resolve, reject) => {
49+
const timeout = setTimeout(
50+
() => reject(new Error('Timed out loading react modules over esm')),
51+
5000
52+
);
53+
window.__loaded = () => {
54+
clearTimeout(timeout);
55+
resolve();
56+
};
57+
58+
const moduleScript = document.createElement('script');
59+
moduleScript.type = 'module';
60+
moduleScript.textContent = imports + 'window.__loaded();';
61+
62+
firstScript.parentNode.insertBefore(moduleScript, firstScript);
63+
});
64+
}
65+
3966
function getVersion() {
4067
let query = parseQuery(window.location.search);
4168
return query.version || 'local';
@@ -47,12 +74,15 @@ export function reactPaths(version = getVersion()) {
4774
let environment = isProduction ? 'production.min' : 'development';
4875
let reactPath = `react.${environment}.js`;
4976
let reactDOMPath = `react-dom.${environment}.js`;
77+
let reactDOMClientPath = `react-dom.${environment}.js`;
5078
let reactDOMServerPath = `react-dom-server.browser.${environment}.js`;
5179
let needsCreateElement = true;
5280
let needsReactDOM = true;
81+
let usingModules = false;
5382

5483
if (version !== 'local') {
5584
const {major, minor, prerelease} = semver(version);
85+
console.log('semver', semver(version));
5686

5787
if (major === 0) {
5888
needsCreateElement = minor >= 12;
@@ -62,7 +92,16 @@ export function reactPaths(version = getVersion()) {
6292
const [preReleaseStage] = prerelease;
6393
// The file structure was updated in 16. This wasn't the case for alphas.
6494
// Load the old module location for anything less than 16 RC
65-
if (major >= 16 && !(minor === 0 && preReleaseStage === 'alpha')) {
95+
if (major >= 19) {
96+
usingModules = true;
97+
const devQuery = environment === 'development' ? '?dev' : '';
98+
reactPath = 'https://esm.sh/react@' + version + '/' + devQuery;
99+
reactDOMPath = 'https://esm.sh/react-dom@' + version + '/' + devQuery;
100+
reactDOMClientPath =
101+
'https://esm.sh/react-dom@' + version + '/client' + devQuery;
102+
reactDOMServerPath =
103+
'https://esm.sh/react-dom@' + version + '/server.browser' + devQuery;
104+
} else if (major >= 16 && !(minor === 0 && preReleaseStage === 'alpha')) {
66105
reactPath =
67106
'https://unpkg.com/react@' +
68107
version +
@@ -90,30 +129,50 @@ export function reactPaths(version = getVersion()) {
90129
reactPath =
91130
'https://cdnjs.cloudflare.com/ajax/libs/react/' + version + '/react.js';
92131
}
132+
} else {
133+
throw new Error(
134+
'This fixture no longer works with local versions. Provide a version query parameter that matches a version published to npm to use the fixture.'
135+
);
93136
}
94137

95138
return {
96139
reactPath,
97140
reactDOMPath,
141+
reactDOMClientPath,
98142
reactDOMServerPath,
99143
needsCreateElement,
100144
needsReactDOM,
145+
usingModules,
101146
};
102147
}
103148

104149
export default function loadReact() {
105-
const {reactPath, reactDOMPath, needsReactDOM} = reactPaths();
106-
107-
let request = loadScript(reactPath);
108-
109-
if (needsReactDOM) {
110-
request = request.then(() => loadScript(reactDOMPath));
150+
console.log('reactPaths', reactPaths());
151+
const {
152+
reactPath,
153+
reactDOMPath,
154+
reactDOMClientPath,
155+
needsReactDOM,
156+
usingModules,
157+
} = reactPaths();
158+
159+
if (usingModules) {
160+
return loadModules([
161+
['React', reactPath],
162+
['ReactDOM', reactDOMPath],
163+
['ReactDOMClient', reactDOMClientPath],
164+
]);
111165
} else {
112-
// Aliasing React to ReactDOM for compatibility.
113-
request = request.then(() => {
114-
window.ReactDOM = window.React;
115-
});
116-
}
166+
let request = loadScript(reactPath, usingModules);
117167

118-
return request;
168+
if (needsReactDOM) {
169+
request = request.then(() => loadScript(reactDOMPath, usingModules));
170+
} else {
171+
// Aliasing React to ReactDOM for compatibility.
172+
request = request.then(() => {
173+
window.ReactDOM = window.React;
174+
});
175+
}
176+
return request;
177+
}
119178
}

0 commit comments

Comments
 (0)