Skip to content

Commit

Permalink
bug symfony#548 [React] Fix window types (AlexandreGerault)
Browse files Browse the repository at this point in the history
This PR was squashed before being merged into the 2.x branch.

Discussion
----------

[React] Fix window types

Hi!

As I discussed with `@weaverryan` on the Slack, I got an error with the `symfony/ux-react` while using it at work in a Sylius project.

Here was the log I had:

```
30 files written to public/build/shop
2022-11-12T14:17:23.295499920Z  ERROR  Failed to compile with 5 errors2:17:23 PM
2022-11-12T14:17:23.295526133Z
2022-11-12T14:17:23.296104408Z  error  in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/register_controller.ts2:17:23 PM
2022-11-12T14:17:23.296117145Z
2022-11-12T14:17:23.296138524Z [tsl] ERROR in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/register_controller.ts(12,60)
2022-11-12T14:17:23.296153391Z       TS2503: Cannot find namespace '__WebpackModuleApi'.
2022-11-12T14:17:23.296154753Z
2022-11-12T14:17:23.296250335Z  error  in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/register_controller.ts2:17:23 PM
2022-11-12T14:17:23.296259533Z
2022-11-12T14:17:23.296270017Z [tsl] ERROR in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/register_controller.ts(15,42)
2022-11-12T14:17:23.296271595Z       TS2503: Cannot find namespace '__WebpackModuleApi'.
2022-11-12T14:17:23.296320585Z
2022-11-12T14:17:23.296401049Z  error  in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/register_controller.ts2:17:23 PM
2022-11-12T14:17:23.296408589Z
2022-11-12T14:17:23.296453666Z [tsl] ERROR in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/register_controller.ts(16,27)
2022-11-12T14:17:23.296455663Z       TS7006: Parameter 'key' implicitly has an 'any' type.
2022-11-12T14:17:23.296462276Z
2022-11-12T14:17:23.296522288Z  error  in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/render_controller.ts2:17:23 PM
2022-11-12T14:17:23.296537227Z
2022-11-12T14:17:23.296544783Z [tsl] ERROR in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/render_controller.ts(17,14)
2022-11-12T14:17:23.296546386Z       TS2564: Property 'componentValue' has no initializer and is not definitely assigned in the constructor.
2022-11-12T14:17:23.296547827Z
2022-11-12T14:17:23.296563284Z  error  in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/render_controller.ts2:17:23 PM
2022-11-12T14:17:23.296569130Z
2022-11-12T14:17:23.296578146Z [tsl] ERROR in /srv/sylius/vendor/symfony/ux-react/Resources/assets/src/render_controller.ts(30,34)
2022-11-12T14:17:23.296580556Z       TS2339: Property 'resolveReactComponent' does not exist on type 'Window & typeof globalThis'.
```

To handle errors about `__WebpackModuleApi` I just installed the ``@types`/webpack-env` package.

But I still had errors for the `window.resolveReactComponent` function and for the `componentValue` field.

My PR goal is to fix the two type errors. Also I wonder if it is possible to generate (maybe in other PR) the declaration files so that it is compatible with Typescript files without having to use `// `@ts`-expect-error` (or `// `@ts`-ignore`) when importing the register react controllers function like so:
```tsx
// `@ts`-expect-error No types exists
// eslint-disable-next-line import/no-extraneous-dependencies
import { registerReactControllerComponents } from '`@symfony`/ux-react';
import { FunctionComponent, ComponentClass } from 'react';
```

Commits
-------

9b43394 [React] Fix window types
  • Loading branch information
weaverryan committed Nov 21, 2022
2 parents 843f1dd + 9b43394 commit 2e0dc46
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
16 changes: 14 additions & 2 deletions src/React/Resources/assets/src/register_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@

'use strict';

import { ComponentClass, FunctionComponent } from 'react';

type Component = string | FunctionComponent<object> | ComponentClass<object, any>;

declare global {
function resolveReactComponent(name: string): Component;

interface Window {
resolveReactComponent(name: string): Component;
}
}

export function registerReactControllerComponents(context: __WebpackModuleApi.RequireContext) {
const reactControllers: { [key: string]: object } = {};
const reactControllers: { [key: string]: Component } = {};

const importAllReactComponents = (r: __WebpackModuleApi.RequireContext) => {
r.keys().forEach((key) => (reactControllers[key] = r(key).default));
Expand All @@ -19,7 +31,7 @@ export function registerReactControllerComponents(context: __WebpackModuleApi.Re
importAllReactComponents(context);

// Expose a global React loader to allow rendering from the Stimulus controller
(window as any).resolveReactComponent = (name: string): object => {
window.resolveReactComponent = (name: string): Component => {
const component = reactControllers[`./${name}.jsx`] || reactControllers[`./${name}.tsx`];
if (typeof component === 'undefined') {
throw new Error('React controller "' + name + '" does not exist');
Expand Down
6 changes: 5 additions & 1 deletion src/React/Resources/assets/src/render_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { createRoot } from 'react-dom/client';
import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
readonly componentValue: string;
readonly componentValue?: string;
readonly propsValue?: object;

static values = {
Expand All @@ -27,6 +27,10 @@ export default class extends Controller {

this._dispatchEvent('react:connect', { component: this.componentValue, props: props });

if (!this.componentValue) {
throw new Error('No component specified.');
}

const component = window.resolveReactComponent(this.componentValue);
this._renderReactElement(React.createElement(component, props, null));

Expand Down

0 comments on commit 2e0dc46

Please sign in to comment.