Skip to content

Commit

Permalink
Updates the dom fixture to load react 19 and later with esm.sh. This …
Browse files Browse the repository at this point in the history
…fixture looks to be in a state of significant bitrot. I'm not going to bother addressing these issues here but at the very least we can now render React 19 without UMD using this fixture
  • Loading branch information
gnoff committed Apr 12, 2024
1 parent d276c21 commit b100790
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 22 deletions.
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;
}
}
2 changes: 1 addition & 1 deletion netlify.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[build]
base = ""
publish = "fixtures/dom/build"
command = "yarn build --type=UMD_DEV && cd fixtures/dom/ && yarn && yarn predev && yarn build"
command = "yarn build --type=UMD_DEV && cd fixtures/dom/ && yarn && yarn build"

[[redirects]]
from = "/*"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
"test-www": "node ./scripts/jest/jest-cli.js --release-channel=www-modern",
"test-classic": "node ./scripts/jest/jest-cli.js --release-channel=www-classic",
"test-build-devtools": "node ./scripts/jest/jest-cli.js --build --project devtools --release-channel=experimental",
"test-dom-fixture": "cd fixtures/dom && yarn && yarn predev && yarn test",
"test-dom-fixture": "cd fixtures/dom && yarn && yarn test",
"flow": "node ./scripts/tasks/flow.js",
"flow-ci": "node ./scripts/tasks/flow-ci.js",
"prettier": "node ./scripts/prettier/index.js write-changed",
Expand Down

0 comments on commit b100790

Please sign in to comment.