From de5619ed8cf4a07d9a23a7714e25611e970ed46e Mon Sep 17 00:00:00 2001 From: Dmitry Rykun Date: Tue, 20 Feb 2024 07:04:03 -0800 Subject: [PATCH] Make codegenNativeComponent show warning and not error (#43070) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43070 **Context** The `codegenNativeComponent` function is a hint for the codegen that the file that contains it is a Native Component spec. Static ViewConfig codegen overwrites this function call by the generated ViewConfig. If this function is not overwritten by the codegen, it has runtime behaviour that falls back to `requireNativeComponent`. At the time when this system was built `requireNativeComponent` was not supported in Bridgeless mode because it is relied on some Bridge-only functionality. That's why it outputs error in Bridgeless mode. --- This is not the case any more, we now have interop layers which provide the functionality needed by `requireNativeComponent`. The SVC codegen is implemented as [Babel plugin](https://github.com/facebook/react-native/tree/main/packages/babel-plugin-codegen). The are scenarios when it is not run for the native component specs: - If the plugin is not used for whatever reason. - If Babel is not used for whatever reason. In order to not to regress the DevX for such cases, we've turned the error into the warning. **Note:** we use `console.info('⚠️...` instead of `console.warn('...`. That's because `console.warn` also prints a stack trace in the console, and we didn't want to create too much noise. Changelog: [General][Changed] - codegenNativeComponent show warning and not error if not code generated at build time. Reviewed By: huntie, rshest Differential Revision: D53761805 fbshipit-source-id: c924c7668e6d2e45b920672b8a309221be767a73 --- .../__tests__/codegenNativeComponent-test.js | 22 +++++++++++++++++++ .../Utilities/codegenNativeComponent.js | 10 ++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/react-native/Libraries/Utilities/__tests__/codegenNativeComponent-test.js b/packages/react-native/Libraries/Utilities/__tests__/codegenNativeComponent-test.js index 4efe80cc09dc33..a20f705a1ae4f3 100644 --- a/packages/react-native/Libraries/Utilities/__tests__/codegenNativeComponent-test.js +++ b/packages/react-native/Libraries/Utilities/__tests__/codegenNativeComponent-test.js @@ -29,6 +29,14 @@ jest ); describe('codegenNativeComponent', () => { + beforeEach(() => { + global.RN$Bridgeless = false; + jest + .spyOn(console, 'warn') + .mockReset() + .mockImplementation(() => {}); + }); + it('should require component as is ', () => { const component = codegenNativeComponent('ComponentName'); expect(component).toBe('ComponentName'); @@ -64,4 +72,18 @@ describe('codegenNativeComponent', () => { 'Failed to find native component for either ComponentNameDoesNotExistOne or ComponentNameDoesNotExistTwo', ); }); + + it('should NOT warn if called directly in BRIDGE mode', () => { + global.RN$Bridgeless = false; + codegenNativeComponent('ComponentName'); + expect(console.warn).not.toHaveBeenCalled(); + }); + + it('should warn if called directly in BRIDGELESS mode', () => { + global.RN$Bridgeless = true; + codegenNativeComponent('ComponentName'); + expect(console.warn).toHaveBeenCalledWith( + `Codegen didn't run for ComponentName. This will be an error in the future. Make sure you are using @react-native/babel-preset when building your JavaScript code.`, + ); + }); }); diff --git a/packages/react-native/Libraries/Utilities/codegenNativeComponent.js b/packages/react-native/Libraries/Utilities/codegenNativeComponent.js index 3f60697155e0df..3f9187f8fe173a 100644 --- a/packages/react-native/Libraries/Utilities/codegenNativeComponent.js +++ b/packages/react-native/Libraries/Utilities/codegenNativeComponent.js @@ -35,12 +35,10 @@ function codegenNativeComponent( componentName: string, options?: Options, ): NativeComponentType { - if (global.RN$Bridgeless === true) { - const errorMessage = - "Native Component '" + - componentName + - "' that calls codegenNativeComponent was not code generated at build time. Please check its definition."; - console.error(errorMessage); + if (global.RN$Bridgeless === true && __DEV__) { + console.warn( + `Codegen didn't run for ${componentName}. This will be an error in the future. Make sure you are using @react-native/babel-preset when building your JavaScript code.`, + ); } let componentNameInUse =