Skip to content

Commit

Permalink
Make codegenNativeComponent show warning and not error (#43070)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #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
  • Loading branch information
dmytrorykun authored and facebook-github-bot committed Feb 20, 2024
1 parent a4d6be8 commit de5619e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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.`,
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ function codegenNativeComponent<Props>(
componentName: string,
options?: Options,
): NativeComponentType<Props> {
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 =
Expand Down

0 comments on commit de5619e

Please sign in to comment.