From 9e360183ff1b751ad4d95fd8edb8b9c681c824e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Tekli=C5=84ski?= Date: Wed, 24 Jul 2024 20:25:05 +0200 Subject: [PATCH] [React] Improve error handling in `resolveReactComponent` --- src/React/CHANGELOG.md | 8 ++++++-- src/React/assets/dist/register_controller.js | 4 ++++ src/React/assets/src/register_controller.ts | 6 ++++++ src/React/assets/test/register_controller.test.tsx | 10 ++++++++++ src/React/doc/index.rst | 4 ++++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/React/CHANGELOG.md b/src/React/CHANGELOG.md index c9c5c066314..da9a6a6bd36 100644 --- a/src/React/CHANGELOG.md +++ b/src/React/CHANGELOG.md @@ -1,9 +1,13 @@ # CHANGELOG +## 2.26.0 + +- Improve error handling when resolving a React component + ## 2.21.0 -- Add `permanent` option to the `react_component` Twig function, to prevent the - _unmounting_ when the component is deconnected and immediately re-connected. +- Add `permanent` option to the `react_component` Twig function, to prevent the + _unmounting_ when the component is deconnected and immediately re-connected ## 2.13.2 diff --git a/src/React/assets/dist/register_controller.js b/src/React/assets/dist/register_controller.js index 2eef8cd8077..d0c38da6a83 100644 --- a/src/React/assets/dist/register_controller.js +++ b/src/React/assets/dist/register_controller.js @@ -10,6 +10,10 @@ function registerReactControllerComponents(context) { const component = reactControllers[`./${name}.jsx`] || reactControllers[`./${name}.tsx`]; if (typeof component === 'undefined') { const possibleValues = Object.keys(reactControllers).map((key) => key.replace('./', '').replace('.jsx', '').replace('.tsx', '')); + if (possibleValues.includes(name)) { + throw new Error(` + React controller "${name}" could not be resolved. Ensure the module exports the controller as a default export.`); + } throw new Error(`React controller "${name}" does not exist. Possible values: ${possibleValues.join(', ')}`); } return component; diff --git a/src/React/assets/src/register_controller.ts b/src/React/assets/src/register_controller.ts index e9d59afe84d..8be8923a660 100644 --- a/src/React/assets/src/register_controller.ts +++ b/src/React/assets/src/register_controller.ts @@ -37,6 +37,12 @@ export function registerReactControllerComponents(context: __WebpackModuleApi.Re const possibleValues = Object.keys(reactControllers).map((key) => key.replace('./', '').replace('.jsx', '').replace('.tsx', '') ); + + if (possibleValues.includes(name)) { + throw new Error(` + React controller "${name}" could not be resolved. Ensure the module exports the controller as a default export.`); + } + throw new Error(`React controller "${name}" does not exist. Possible values: ${possibleValues.join(', ')}`); } diff --git a/src/React/assets/test/register_controller.test.tsx b/src/React/assets/test/register_controller.test.tsx index 4595a7d9996..dcb3808219b 100644 --- a/src/React/assets/test/register_controller.test.tsx +++ b/src/React/assets/test/register_controller.test.tsx @@ -17,6 +17,7 @@ const createFakeFixturesContext = (): RequireContext => { const files: any = { './MyJsxComponent.jsx': { default: MyJsxComponent }, './MyTsxComponent.tsx': { default: MyTsxComponent }, + './NoDefaultExportComponent.jsx': { default: undefined }, }; const context = (id: string): any => files[id]; @@ -45,4 +46,13 @@ describe('registerReactControllerComponents', () => { 'React controller "MyABCComponent" does not exist. Possible values: MyJsxComponent, MyTsxComponent' ); }); + + it('throws when no default export found in imported module', () => { + registerReactControllerComponents(createFakeFixturesContext()); + const resolveComponent = (window as any).resolveReactComponent; + + expect(() => resolveComponent('NoDefaultExportComponent')).toThrow( + 'React controller "NoDefaultExportComponent" could not be resolved. Ensure the module exports the controller as a default export.' + ); + }); }); diff --git a/src/React/doc/index.rst b/src/React/doc/index.rst index 92097ca9025..0faa32c46ff 100644 --- a/src/React/doc/index.rst +++ b/src/React/doc/index.rst @@ -81,6 +81,10 @@ For example: return
Hello {props.fullName}
; } +.. note:: + + Ensure your module exports the controller as the ``export default``. The default export is used when resolving components. + .. code-block:: html+twig {# templates/home.html.twig #}