Skip to content

Commit

Permalink
[UMD] Remove umd builds (#28735)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
gnoff authored Apr 17, 2024
1 parent 0c245df commit da6ba53
Show file tree
Hide file tree
Showing 42 changed files with 1,124 additions and 842 deletions.
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,6 @@ module.exports = {
__EXTENSION__: 'readonly',
__PROFILE__: 'readonly',
__TEST__: 'readonly',
__UMD__: 'readonly',
__VARIANT__: 'readonly',
__unmockReact: 'readonly',
gate: 'readonly',
Expand Down
4 changes: 2 additions & 2 deletions fixtures/dom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ of the React project. Then:
```
cd fixtures/dom
yarn
yarn start
yarn dev
```

The `start` command runs a script that copies over the local build of react into
The `dev` command runs a script that copies over the local build of react into
the public directory.
2 changes: 1 addition & 1 deletion fixtures/dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"scripts": {
"dev": "react-scripts start",
"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",
"predev": "cp -a ../../build/oss-stable/. node_modules",
"build": "react-scripts build && cp build/index.html build/200.html",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
Expand Down
16 changes: 12 additions & 4 deletions fixtures/dom/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@ loadReact()
.then(App => {
const {React, ReactDOM} = window;

ReactDOM.render(
React.createElement(App.default),
document.getElementById('root')
);
if (typeof window.ReactDOMClient !== 'undefined') {
// we are in a React that only supports modern roots

ReactDOM.createRoot(document.getElementById('root')).render(
React.createElement(App.default)
);
} else {
ReactDOM.render(
React.createElement(App.default),
document.getElementById('root')
);
}
});
85 changes: 72 additions & 13 deletions fixtures/dom/src/react-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,33 @@ function loadScript(src) {
});
}

function loadModules(SymbolSrcPairs) {
let firstScript = document.getElementsByTagName('script')[0];

let imports = '';
SymbolSrcPairs.map(([symbol, src]) => {
imports += `import ${symbol} from "${src}";\n`;
imports += `window.${symbol} = ${symbol};\n`;
});

return new Promise((resolve, reject) => {
const timeout = setTimeout(
() => reject(new Error('Timed out loading react modules over esm')),
5000
);
window.__loaded = () => {
clearTimeout(timeout);
resolve();
};

const moduleScript = document.createElement('script');
moduleScript.type = 'module';
moduleScript.textContent = imports + 'window.__loaded();';

firstScript.parentNode.insertBefore(moduleScript, firstScript);
});
}

function getVersion() {
let query = parseQuery(window.location.search);
return query.version || 'local';
Expand All @@ -47,12 +74,15 @@ export function reactPaths(version = getVersion()) {
let environment = isProduction ? 'production.min' : 'development';
let reactPath = `react.${environment}.js`;
let reactDOMPath = `react-dom.${environment}.js`;
let reactDOMClientPath = `react-dom.${environment}.js`;
let reactDOMServerPath = `react-dom-server.browser.${environment}.js`;
let needsCreateElement = true;
let needsReactDOM = true;
let usingModules = false;

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

if (major === 0) {
needsCreateElement = minor >= 12;
Expand All @@ -62,7 +92,16 @@ export function reactPaths(version = getVersion()) {
const [preReleaseStage] = prerelease;
// The file structure was updated in 16. This wasn't the case for alphas.
// Load the old module location for anything less than 16 RC
if (major >= 16 && !(minor === 0 && preReleaseStage === 'alpha')) {
if (major >= 19) {
usingModules = true;
const devQuery = environment === 'development' ? '?dev' : '';
reactPath = 'https://esm.sh/react@' + version + '/' + devQuery;
reactDOMPath = 'https://esm.sh/react-dom@' + version + '/' + devQuery;
reactDOMClientPath =
'https://esm.sh/react-dom@' + version + '/client' + devQuery;
reactDOMServerPath =
'https://esm.sh/react-dom@' + version + '/server.browser' + devQuery;
} else if (major >= 16 && !(minor === 0 && preReleaseStage === 'alpha')) {
reactPath =
'https://unpkg.com/react@' +
version +
Expand Down Expand Up @@ -90,30 +129,50 @@ export function reactPaths(version = getVersion()) {
reactPath =
'https://cdnjs.cloudflare.com/ajax/libs/react/' + version + '/react.js';
}
} else {
throw new Error(
'This fixture no longer works with local versions. Provide a version query parameter that matches a version published to npm to use the fixture.'
);
}

return {
reactPath,
reactDOMPath,
reactDOMClientPath,
reactDOMServerPath,
needsCreateElement,
needsReactDOM,
usingModules,
};
}

export default function loadReact() {
const {reactPath, reactDOMPath, needsReactDOM} = reactPaths();

let request = loadScript(reactPath);

if (needsReactDOM) {
request = request.then(() => loadScript(reactDOMPath));
console.log('reactPaths', reactPaths());
const {
reactPath,
reactDOMPath,
reactDOMClientPath,
needsReactDOM,
usingModules,
} = reactPaths();

if (usingModules) {
return loadModules([
['React', reactPath],
['ReactDOM', reactDOMPath],
['ReactDOMClient', reactDOMClientPath],
]);
} else {
// Aliasing React to ReactDOM for compatibility.
request = request.then(() => {
window.ReactDOM = window.React;
});
}
let request = loadScript(reactPath, usingModules);

return request;
if (needsReactDOM) {
request = request.then(() => loadScript(reactDOMPath, usingModules));
} else {
// Aliasing React to ReactDOM for compatibility.
request = request.then(() => {
window.ReactDOM = window.React;
});
}
return request;
}
}
Loading

0 comments on commit da6ba53

Please sign in to comment.