mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
[Flight] Move bundler configs to use Suspense instead of returning thenable (#18367)
* Move bundler configs to use suspense instead of returning thenable * Fix some Flow types
This commit is contained in:
committed by
GitHub
parent
4b7f8496a8
commit
c0cd1be908
@@ -17,7 +17,6 @@ import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
|
||||
// import {
|
||||
// resolveModuleReference,
|
||||
// preloadModule,
|
||||
// loadModule,
|
||||
// requireModule,
|
||||
// } from './ReactFlightClientHostConfig';
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
declare var $$$hostConfig: any;
|
||||
|
||||
export opaque type ModuleMetaData = mixed; // eslint-disable-line no-undef
|
||||
export opaque type ModuleReference<T> = mixed; // eslint-disable-line no-undef
|
||||
export const resolveModuleReference = $$$hostConfig.resolveModuleReference;
|
||||
export const preloadModule = $$$hostConfig.preloadModule;
|
||||
export const requireModule = $$$hostConfig.requireModule;
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
export {
|
||||
resolveModuleReference,
|
||||
preloadModule,
|
||||
loadModule,
|
||||
requireModule,
|
||||
} from 'ReactFlightDOMRelayClientIntegration';
|
||||
|
||||
|
||||
@@ -18,9 +18,6 @@ const ReactFlightDOMRelayClientIntegration = {
|
||||
return moduleData;
|
||||
},
|
||||
preloadModule(moduleReference) {},
|
||||
loadModule(moduleReference) {
|
||||
return null;
|
||||
},
|
||||
requireModule(moduleReference) {
|
||||
return getFakeModule();
|
||||
},
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export type ModuleMetaData = {
|
||||
export opaque type ModuleMetaData = {
|
||||
id: string,
|
||||
chunks: Array<string>,
|
||||
name: string,
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export type ModuleReference<T> = ModuleMetaData;
|
||||
export opaque type ModuleReference<T> = ModuleMetaData;
|
||||
|
||||
export function resolveModuleReference<T>(
|
||||
moduleData: ModuleMetaData,
|
||||
@@ -23,7 +23,7 @@ export function resolveModuleReference<T>(
|
||||
}
|
||||
|
||||
type Thenable = {
|
||||
then(resolve: () => mixed, reject: (mixed) => mixed): mixed,
|
||||
then(resolve: (any) => mixed, reject?: (Error) => mixed): Thenable,
|
||||
...
|
||||
};
|
||||
|
||||
@@ -31,32 +31,37 @@ type Thenable = {
|
||||
// If they're still pending they're a thenable. This map also exists
|
||||
// in Webpack but unfortunately it's not exposed so we have to
|
||||
// replicate it in user space. null means that it has already loaded.
|
||||
const chunkCache: Map<string, null | Thenable> = new Map();
|
||||
const chunkCache: Map<string, null | Thenable | Error> = new Map();
|
||||
|
||||
// Returning null means that all dependencies are fulfilled and we
|
||||
// can synchronously require the module now. A thenable is returned
|
||||
// that when resolved, means we can try again.
|
||||
export function preloadModule<T>(moduleData: ModuleReference<T>): void {
|
||||
loadModule(moduleData);
|
||||
}
|
||||
|
||||
export function loadModule<T>(moduleData: ModuleReference<T>): null | Thenable {
|
||||
let chunks = moduleData.chunks;
|
||||
let anyRemainingThenable = null;
|
||||
for (let i = 0; i < chunks.length; i++) {
|
||||
let chunkId = chunks[i];
|
||||
let entry = chunkCache.get(chunkId);
|
||||
if (entry === undefined) {
|
||||
anyRemainingThenable = __webpack_chunk_load__(chunkId);
|
||||
chunkCache.set(chunkId, anyRemainingThenable);
|
||||
anyRemainingThenable.then(chunkCache.set.bind(chunkCache, chunkId, null));
|
||||
} else if (entry !== null) {
|
||||
anyRemainingThenable = entry;
|
||||
let thenable = __webpack_chunk_load__(chunkId);
|
||||
let resolve = chunkCache.set.bind(chunkCache, chunkId, null);
|
||||
let reject = chunkCache.set.bind(chunkCache, chunkId);
|
||||
thenable.then(resolve, reject);
|
||||
chunkCache.set(chunkId, thenable);
|
||||
}
|
||||
}
|
||||
return anyRemainingThenable;
|
||||
}
|
||||
|
||||
export function requireModule<T>(moduleData: ModuleReference<T>): T {
|
||||
let chunks = moduleData.chunks;
|
||||
for (let i = 0; i < chunks.length; i++) {
|
||||
let chunkId = chunks[i];
|
||||
let entry = chunkCache.get(chunkId);
|
||||
if (entry !== null) {
|
||||
// We assume that preloadModule has been called before.
|
||||
// So we don't expect to see entry being undefined here, that's an error.
|
||||
// Let's throw either an error or the Promise.
|
||||
throw entry;
|
||||
}
|
||||
}
|
||||
return __webpack_require__(moduleData.id)[moduleData.name];
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ export type ModuleReference = string;
|
||||
export type ModuleMetaData = {
|
||||
id: string,
|
||||
chunks: Array<string>,
|
||||
name: string,
|
||||
};
|
||||
|
||||
export function resolveModuleMetaData(
|
||||
|
||||
@@ -27,6 +27,15 @@ const {
|
||||
close,
|
||||
} = ReactFlightClient({
|
||||
supportsBinaryStreams: false,
|
||||
resolveModuleReference(name: string) {
|
||||
return name;
|
||||
},
|
||||
preloadModule(name: string) {},
|
||||
requireModule(name: string) {
|
||||
return function FakeModule() {
|
||||
return name;
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
function read<T>(source: Source): ReactModelRoot<T> {
|
||||
|
||||
@@ -11,5 +11,5 @@ declare var $$$hostConfig: any;
|
||||
|
||||
export opaque type BundlerConfig = mixed; // eslint-disable-line no-undef
|
||||
export opaque type ModuleReference = mixed; // eslint-disable-line no-undef
|
||||
export opaque type ModuleMetaData = mixed; // eslint-disable-line no-undef
|
||||
export opaque type ModuleMetaData: any = mixed; // eslint-disable-line no-undef
|
||||
export const resolveModuleMetaData = $$$hostConfig.resolveModuleMetaData;
|
||||
|
||||
@@ -67,5 +67,9 @@ declare module 'EventListener' {
|
||||
};
|
||||
}
|
||||
|
||||
declare function __webpack_chunk_load__(id: string): {then(() => mixed): mixed};
|
||||
type Thenable = {
|
||||
then(resolve: (mixed) => mixed, reject?: (Error) => mixed): Thenable,
|
||||
};
|
||||
|
||||
declare function __webpack_chunk_load__(id: string): Thenable;
|
||||
declare function __webpack_require__(id: string): {default: any};
|
||||
|
||||
10
scripts/flow/react-relay-hooks.js
vendored
10
scripts/flow/react-relay-hooks.js
vendored
@@ -15,11 +15,6 @@ type JSONValue =
|
||||
| {[key: string]: JSONValue}
|
||||
| Array<JSONValue>;
|
||||
|
||||
type Thenable = {
|
||||
then(resolve: () => mixed, reject: (error: Error) => mixed): mixed,
|
||||
...
|
||||
};
|
||||
|
||||
declare module 'ReactFlightDOMRelayServerIntegration' {
|
||||
declare export opaque type Destination;
|
||||
declare export function emitModel(
|
||||
@@ -43,7 +38,7 @@ declare module 'ReactFlightDOMRelayServerIntegration' {
|
||||
}
|
||||
|
||||
declare module 'ReactFlightDOMRelayClientIntegration' {
|
||||
declare export opaque type ModuleReference;
|
||||
declare export opaque type ModuleReference<T>;
|
||||
declare export opaque type ModuleMetaData;
|
||||
declare export function resolveModuleReference<T>(
|
||||
moduleData: ModuleMetaData,
|
||||
@@ -51,9 +46,6 @@ declare module 'ReactFlightDOMRelayClientIntegration' {
|
||||
declare export function preloadModule<T>(
|
||||
moduleReference: ModuleReference<T>,
|
||||
): void;
|
||||
declare export function loadModule<T>(
|
||||
moduleReference: ModuleReference<T>,
|
||||
): null | Thenable;
|
||||
declare export function requireModule<T>(
|
||||
moduleReference: ModuleReference<T>,
|
||||
): T;
|
||||
|
||||
Reference in New Issue
Block a user