@samitouri / QOS-React-2 / commits / 163199d8cc

Dedupe module id generation (#20172)

Sebastian Markbåge committed Nov 10, 2020 at 22:58 UTC 163199d8cc99309e765c85e93c6b9dd1f22c2974
7 files changed +37
packages/react-noop-renderer/src/ReactNoopFlightServer.js
+3
@@ -45,6 +45,9 @@ const ReactNoopFlightServer = ReactFlightServer({
45 isModuleReference(reference: Object): boolean {
46 return reference.$$typeof === Symbol.for('react.module.reference');
47 },
48 + getModuleKey(reference: Object): Object {
49 + return reference;
50 + },
51 resolveModuleMetaData(
52 config: void,
53 reference: {$$typeof: Symbol, value: any},
packages/react-server/src/ReactFlightServer.js
+9
@@ -14,6 +14,7 @@ import type {
14 BundlerConfig,
15 ModuleMetaData,
16 ModuleReference,
17 + ModuleKey,
18 } from './ReactFlightServerConfig';
19
20 import {
@@ -28,6 +29,7 @@ import {
29 processSymbolChunk,
30 processErrorChunk,
31 resolveModuleMetaData,
32 + getModuleKey,
33 isModuleReference,
34 } from './ReactFlightServerConfig';
35
@@ -79,6 +81,7 @@ export type Request = {
81 completedJSONChunks: Array<Chunk>,
82 completedErrorChunks: Array<Chunk>,
83 writtenSymbols: Map<Symbol, number>,
84 + writtenModules: Map<ModuleKey, number>,
85 flowing: boolean,
86 toJSON: (key: string, value: ReactModel) => ReactJSONValue,
87 };
@@ -101,6 +104,7 @@ export function createRequest(
104 completedJSONChunks: [],
105 completedErrorChunks: [],
106 writtenSymbols: new Map(),
107 + writtenModules: new Map(),
108 flowing: false,
109 toJSON: function(key: string, value: ReactModel): ReactJSONValue {
110 return resolveModelToJSON(request, this, key, value);
@@ -425,6 +429,11 @@ export function resolveModelToJSON(
429 if (typeof value === 'object') {
430 if (isModuleReference(value)) {
431 const moduleReference: ModuleReference<any> = (value: any);
432 + const moduleKey: ModuleKey = getModuleKey(moduleReference);
433 + const existingId = request.writtenModules.get(moduleKey);
434 + if (existingId !== undefined) {
435 + return serializeByValueID(existingId);
436 + }
437 try {
438 const moduleMetaData: ModuleMetaData = resolveModuleMetaData(
439 request.bundlerConfig,
packages/react-server/src/ReactFlightServerBundlerConfigCustom.js
+2
@@ -12,5 +12,7 @@ declare var $$$hostConfig: any;
12 export opaque type BundlerConfig = mixed; // eslint-disable-line no-undef
13 export opaque type ModuleReference<T> = mixed; // eslint-disable-line no-undef
14 export opaque type ModuleMetaData: any = mixed; // eslint-disable-line no-undef
15 +export opaque type ModuleKey: any = mixed; // eslint-disable-line no-undef
16 export const isModuleReference = $$$hostConfig.isModuleReference;
17 +export const getModuleKey = $$$hostConfig.getModuleKey;
18 export const resolveModuleMetaData = $$$hostConfig.resolveModuleMetaData;
packages/react-transport-dom-relay/src/ReactFlightDOMRelayServerHostConfig.js
+8
@@ -38,6 +38,14 @@ export function isModuleReference(reference: Object): boolean {
38 return reference instanceof JSResourceReference;
39 }
40
41 +export type ModuleKey = ModuleReference<any>;
42 +
43 +export function getModuleKey(reference: ModuleReference<any>): ModuleKey {
44 + // We use the reference object itself as the key because we assume the
45 + // object will be cached by the bundler runtime.
46 + return reference;
47 +}
48 +
49 export function resolveModuleMetaData<T>(
50 config: BundlerConfig,
51 resource: ModuleReference<T>,
packages/react-transport-dom-webpack/src/ReactFlightServerWebpackBundlerConfig.js
+6
@@ -25,8 +25,14 @@ export type ModuleMetaData = {
25 name: string,
26 };
27
28 +export type ModuleKey = string;
29 +
30 const MODULE_TAG = Symbol.for('react.module.reference');
31
32 +export function getModuleKey(reference: ModuleReference<any>): ModuleKey {
33 + return reference.name;
34 +}
35 +
36 export function isModuleReference(reference: Object): boolean {
37 return reference.$$typeof === MODULE_TAG;
38 }
packages/react-transport-native-relay/src/ReactFlightNativeRelayServerHostConfig.js
+8
@@ -38,6 +38,14 @@ export function isModuleReference(reference: Object): boolean {
38 return reference instanceof JSResourceReferenceImpl;
39 }
40
41 +export type ModuleKey = ModuleReference<any>;
42 +
43 +export function getModuleKey(reference: ModuleReference<any>): ModuleKey {
44 + // We use the reference object itself as the key because we assume the
45 + // object will be cached by the bundler runtime.
46 + return reference;
47 +}
48 +
49 export function resolveModuleMetaData<T>(
50 config: BundlerConfig,
51 resource: ModuleReference<T>,
scripts/jest/setupHostConfigs.js
+1
@@ -35,6 +35,7 @@ jest.mock('react-server/flight', () => {
35 jest.mock(shimServerFormatConfigPath, () => config);
36 jest.mock('react-server/src/ReactFlightServerBundlerConfigCustom', () => ({
37 isModuleReference: config.isModuleReference,
38 + getModuleKey: config.getModuleKey,
39 resolveModuleMetaData: config.resolveModuleMetaData,
40 }));
41 jest.mock(shimFlightServerConfigPath, () =>