WebUI Component dependency breakage

I've noted that somewhere in the last month or so, I've had to pin @inductiveautomation/ignition-web-ui to 1.3.0 in order to avoid the following breakage on the WebUI Storybook's Button component:

TS2786: 'Button' cannot be used as a JSX component.
  Its type 'ForwardRefExoticComponent<Pick<IAButtonProps, "children" | "className" | "form" | "id" | "tabIndex" | "rel" | "onClick" | "component" | "stretch" | "size" | "disabled" | "dataLabel" | ... 9 more ... | "soloIcon"> & RefAttributes<...>>' is not a valid JSX element type.
    Type 'ForwardRefExoticComponent<Pick<IAButtonProps, "children" | "className" | "form" | "id" | "tabIndex" | "rel" | "onClick" | "component" | "stretch" | "size" | "disabled" | "dataLabel" | ... 9 more ... | "soloIcon"> & RefAttributes<...>>' is not assignable to type '(props: any, deprecatedLegacyContext?: any) => ReactNode'.
      Type 'ReactElement<any, string | JSXElementConstructor<any>> | null' is not assignable to type 'ReactNode'.
        Type 'ReactElement<any, string | JSXElementConstructor<any>>' is not assignable to type 'ReactNode'.
          Property 'children' is missing in type 'ReactElement<any, string | JSXElementConstructor<any>>' but required in type 'ReactPortal'.
     99 |                     margin: '10px'
    100 |                 }}>
  > 101 |                     <Button
        |                      ^^^^^^
    102 |                         download
    103 |                         disabled={props.deviceConfig.data.indexOf('Configured.eds') < 0}
    104 |                         href={dlRouteUrl + "/Configured.eds"}

If I disallow upgrading to 1.3.1 or 1.3.2, my build succeeds. A look into the node cache at Button.d.ts between the 1.3.0 and 1.3.2 shows a substantial type change, suggesting (I think) that pinning React to 18.2.0 may not be right.

Anyone recognize this and have some quick pointers? Or am I going to have dig into dependency hell?

Hi Phil,

This doesn’t look like a familiar error. The only thing I can think of is if “children” is used as a prop or if its passed in between the opening and closing tags of the component. I just tried to reproduce the error locally and got the expected error `218:25 error Do not pass children as props. Instead, nest children between the opening and closing tags react/no-children-prop`

Is the parent JSX just a div or another component?

<Button colorClass={ButtonColorClasses.PRIMARY} onClick={() => console.log('CLICKED')}>
    HELLO
</Button>

-- vs -- 

<Button
  colorClass={ButtonColorClasses.PRIMARY}
  onClick={() => console.log('CLICKED')}
  children={'HELLO'}
/>

A div, and the button children are enclosed properly. Like so:

<div style={{
    margin: '10px'
}}>
    <Button
        download
        disabled={props.deviceConfig.data.indexOf('units.csv') < 0}
        href={dlRouteUrl + "/units.csv"}
        id="mb-dev-csv-download"
    >
        Export Units CSV
    </Button>
</div>

I think you might have a type definition mismatch. Run yarn why @types/react. What do you get?

No difference. While pinned to 1.3.0:

$ yarn why @types/react
yarn why v1.22.22
[1/4] Why do we have the module "@types/react"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "@types/react@18.2.79"
info Has been hoisted to "@types/react"
info This module exists because it's specified in "dependencies".
info Disk size without dependencies: "460KB"
info Disk size with unique dependencies: "1.68MB"
info Disk size with transitive dependencies: "1.68MB"
info Number of shared dependencies: 2
=> Found "@types/react-dom#@types/react@19.2.7"
info This module exists because "@types#react-dom" depends on it.
info Disk size without dependencies: "432KB"
info Disk size with unique dependencies: "1.63MB"
info Disk size with transitive dependencies: "1.63MB"
info Number of shared dependencies: 1
=> Found "@inductiveautomation/ignition-web-ui#@types/react@18.0.26"
info This module exists because "@inductiveautomation#ignition-web-ui" depends on it.
info Disk size without dependencies: "196KB"
info Disk size with unique dependencies: "1.43MB"
info Disk size with transitive dependencies: "1.43MB"
info Number of shared dependencies: 3
=> Found "@inductiveautomation/ignition-web-ui#@types/react-dom#@types/react@19.2.7"
info This module exists because "@inductiveautomation#ignition-web-ui#@types#react-dom" depends on it.
info Disk size without dependencies: "432KB"
info Disk size with unique dependencies: "1.63MB"
info Disk size with transitive dependencies: "1.63MB"
info Number of shared dependencies: 1
Done in 0.12s.

Unpinned (advances to 1.3.2):

$ yarn why @types/react
yarn why v1.22.22
[1/4] Why do we have the module "@types/react"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "@types/react@18.2.79"
info Has been hoisted to "@types/react"
info This module exists because it's specified in "dependencies".
info Disk size without dependencies: "460KB"
info Disk size with unique dependencies: "1.68MB"
info Disk size with transitive dependencies: "1.68MB"
info Number of shared dependencies: 2
=> Found "@types/react-dom#@types/react@19.2.7"
info This module exists because "@types#react-dom" depends on it.
info Disk size without dependencies: "432KB"
info Disk size with unique dependencies: "1.63MB"
info Disk size with transitive dependencies: "1.63MB"
info Number of shared dependencies: 1
=> Found "@inductiveautomation/ignition-web-ui#@types/react@18.0.26"
info This module exists because "@inductiveautomation#ignition-web-ui" depends on it.
info Disk size without dependencies: "196KB"
info Disk size with unique dependencies: "1.43MB"
info Disk size with transitive dependencies: "1.43MB"
info Number of shared dependencies: 3
=> Found "@inductiveautomation/ignition-web-ui#@types/react-dom#@types/react@19.2.7"
info This module exists because "@inductiveautomation#ignition-web-ui#@types#react-dom" depends on it.
info Disk size without dependencies: "432KB"
info Disk size with unique dependencies: "1.63MB"
info Disk size with transitive dependencies: "1.63MB"
info Number of shared dependencies: 1
Done in 0.13s.

Note that the implementation of Button differs between 1.3.0 and 1.3.2.

My package.json, if that helps:

{
  "name": "web",
  "version": "2.2.0",
  "private": true,
  "description": "Menu items for Advanced Modbus Devices",
  "main": "build/dist/index.js",
  "dependencies": {
    "@inductiveautomation/ignition-icons": "1.3.0",
    "@inductiveautomation/ignition-web-ui": "1.3.0",
    "@reduxjs/toolkit": "^1.9.3",
    "@types/react": "18.2",
    "@types/react-dom": "18.2",
    "babel-loader": "^10.0.0",
    "css-loader": "^7.1.2",
    "eslint": "^9.38.0",
    "eslint-webpack-plugin": "^5.0.2",
    "fork-ts-checker-webpack-plugin": "^9.1.0",
    "html-webpack-plugin": "^5.6.4",
    "react": "18.2",
    "react-dom": "18.2",
    "react-hook-form": "^7.44.3",
    "react-redux": "^8.0.5",
    "sass": "^1.93.2",
    "sass-loader": "^16.0.5",
    "style-loader": "^4.0.0",
    "ts-loader": "^9.5.4",
    "typescript": "^5.9.3",
    "webpack": "^5.102.1"
  },
  "scripts": {
    "build": "yarn run build:dev",
    "build:dev": "yarn run build-dev",
    "build-dev": "webpack --mode development",
    "build:prod": "yarn run build-prod",
    "build-prod": "rimraf build/dist && webpack --mode production",
    "build:dev-verbose": "webpack --mode development --progress --profile --colors",
    "build:prod-verbose": "webpack --mode production --progress --profile --colors",
    "run:dev": "webpack serve --env isStandalone",
    "clean": "rimraf build/dist",
    "deepClean": "yarn run clean && rimraf node_modules",
    "lint": "eslint ./src --ext .jsx,.js"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "webpack-cli": "^6.0.1"
  }
}

Thanks. Try downgrading your type definition versions to match ours and see if that helps. Here's your package.json. I took the liberty of organizing your dev dependencies.

{
  "name": "web",
  "version": "2.2.0",
  "private": true,
  "description": "Menu items for Advanced Modbus Devices",
  "main": "build/dist/index.js",
  "dependencies": {
    "@inductiveautomation/ignition-icons": "1.3.0",
    "@inductiveautomation/ignition-web-ui": "1.3.0",
    "@reduxjs/toolkit": "^1.9.3",
    "react": "18.2",
    "react-dom": "18.2",
    "react-hook-form": "^7.44.3",
    "react-redux": "^8.0.5"
  },
  "devDependencies": {
    "@types/react": "18.0.26",
    "@types/react-dom": "18.0.10",
    "babel-loader": "^10.0.0",
    "css-loader": "^7.1.2",
    "eslint": "^9.38.0",
    "eslint-webpack-plugin": "^5.0.2",
    "fork-ts-checker-webpack-plugin": "^9.1.0",
    "html-webpack-plugin": "^5.6.4",
    "sass": "^1.93.2",
    "sass-loader": "^16.0.5",
    "style-loader": "^4.0.0",
    "ts-loader": "^9.5.4",
    "typescript": "^5.9.3",
    "webpack": "^5.102.1",
    "webpack-cli": "^6.0.1"
  },
  "scripts": {
    "build": "yarn run build:dev",
    "build:dev": "yarn run build-dev",
    "build-dev": "webpack --mode development",
    "build:prod": "yarn run build-prod",
    "build-prod": "rimraf build/dist && webpack --mode production",
    "build:dev-verbose": "webpack --mode development --progress --profile --colors",
    "build:prod-verbose": "webpack --mode production --progress --profile --colors",
    "run:dev": "webpack serve --env isStandalone",
    "clean": "rimraf build/dist",
    "deepClean": "yarn run clean && rimraf node_modules",
    "lint": "eslint ./src --ext .jsx,.js"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

1 Like

That fixed it. (1.3.0 => 1.3.2 at the yarn install point)

philip@grim:~/ign83/Modbus/Web$ yarn build-prod
yarn run v1.22.22
$ rimraf build/dist && webpack --mode production
asset autopros_enip1.js 3.38 KiB [compared for emit] [minimized] (name: autopros_enip1) 2 related assets
runtime modules 670 bytes 3 modules
orphan modules 3.63 KiB [orphan] 1 module
built modules 4.9 KiB [built]
  cacheable modules 4.78 KiB
    ./src/index.tsx + 1 modules 3.73 KiB [built] [code generated]
    ./node_modules/react/jsx-runtime.js 214 bytes [built] [code generated]
    ./node_modules/react/cjs/react-jsx-runtime.production.min.js 859 bytes [built] [code generated]
  external "react-redux" 42 bytes [built] [code generated]
  external "@inductiveautomation/ignition-web-ui" 42 bytes [built] [code generated]
  external "react" 42 bytes [built] [code generated]
webpack 5.103.0 compiled successfully in 1949 ms
Done in 2.54s.
philip@grim:~/ign83/Modbus/Web$ yarn install
yarn install v1.22.22
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning " > @inductiveautomation/ignition-web-ui@1.3.2" has unmet peer dependency "@emotion/react@^11.10.6".
warning " > @inductiveautomation/ignition-web-ui@1.3.2" has unmet peer dependency "@mui/material@^5.11.11".
warning "@inductiveautomation/ignition-web-ui > react-day-picker@8.10.1" has unmet peer dependency "date-fns@^2.28.0 || ^3.0.0".
warning " > babel-loader@10.0.0" has unmet peer dependency "@babel/core@^7.12.0".
[4/4] Building fresh packages...
success Saved lockfile.
Done in 1.50s.
philip@grim:~/ign83/Modbus/Web$ yarn build-prod
yarn run v1.22.22
$ rimraf build/dist && webpack --mode production
asset autopros_enip1.js 3.38 KiB [compared for emit] [minimized] (name: autopros_enip1) 2 related assets
runtime modules 670 bytes 3 modules
orphan modules 3.63 KiB [orphan] 1 module
built modules 4.9 KiB [built]
  cacheable modules 4.78 KiB
    ./src/index.tsx + 1 modules 3.73 KiB [built] [code generated]
    ./node_modules/react/jsx-runtime.js 214 bytes [built] [code generated]
    ./node_modules/react/cjs/react-jsx-runtime.production.min.js 859 bytes [built] [code generated]
  external "react-redux" 42 bytes [built] [code generated]
  external "@inductiveautomation/ignition-web-ui" 42 bytes [built] [code generated]
  external "react" 42 bytes [built] [code generated]
webpack 5.103.0 compiled successfully in 2004 ms
Done in 2.56s.

Thanks for poking at this for me!

{....and just noticed a copy/paste error with a stale javascript name...}

Fun stuff! Glad we figured it out.

1 Like