electron-webpack icon indicating copy to clipboard operation
electron-webpack copied to clipboard

React is loaded multiple times when a dependency references it (in render)

Open zhoutwo opened this issue 4 years ago • 1 comments

  • Version: 22.5.1
  • Target: macOS 10.14.6 (using dev server)

I am suspecting this is my config issue because I can't seem to find a similar issue reported. In short, what happened was it seems react is being loaded twice, and that breaks the react-use library because it calls react hooks. And hooks don't like more than one instance of react. Screen Shot 2020-04-19 at 2 52 44 AM From the DevTool message it should be clear that there is one react from the bundled JS and the other from a later loaded bundle. I was not familiar with webpack, and after tracing it down, I thought the existence of the second bundle was due to all my libraries being in the externals of the webpack config. So I did a little hack to add react and react-dom into externals:

module.exports = (config) => {
  config.externals = [...config.externals, 'react', 'react-dom'];
  return config;
};

And then it worked: Screen Shot 2020-04-19 at 2 55 50 AM I see that they are intentionally removed from externals via https://github.com/electron-userland/electron-webpack/blob/ad730ec8da38cd8b570618091b77558284978070/packages/electron-webpack/src/main.ts#L281-L282 May I ask why that was necessary? Or what did I configure wrong? Here are my electron-related dependencies (add-ons and so on):

    "electron": "^8.2.2",
    "electron-builder": "^22.4.1",
    "electron-webpack": "^2.8.2",
    "electron-webpack-eslint": "^6.0.0",
    "electron-webpack-ts": "^4.0.1",
    "typescript": "^3.8.3",
    "webpack": "^4.42.1"

And my build config:

{
    "asar": true,
    "compression": "maximum",
    "dmg": {
      "format": "ULFO"
    },
    "mac": {
      "identity": null,
      "target": [
        {
          "target": "dmg",
          "arch": "x64"
        },
        {
          "target": "zip",
          "arch": "x64"
        }
      ]
    },
    "win": {
      "target": [
        {
          "target": "nsis",
          "arch": "x64"
        },
        {
          "target": "zip",
          "arch": "x64"
        }
      ]
    },
    "linux": {
      "target": [
        {
          "target": "AppImage",
          "arch": "x64"
        },
        {
          "target": "zip",
          "arch": "x64"
        }
      ],
      "category": "Audio"
    },
    "nsis": {
      "artifactName": "${productName}-setup-${version}.${ext}",
      "uninstallDisplayName": "${productName}",
      "oneClick": false,
      "perMachine": true,
      "packElevateHelper": true,
      "allowElevation": true,
      "allowToChangeInstallationDirectory": true,
      "deleteAppDataOnUninstall": true
    },
    "appImage": {
      "artifactName": "${productName}.${ext}"
    }
  }

I also looked at https://github.com/electron-userland/electron-webpack/issues/59 but I think that solution is outdated (react-hot-loader is V4 now). If people still recommend that I go down that route I'd be happy to do so. However, I still would like to get an answer for the above question. Thanks!

zhoutwo avatar Apr 19 '20 10:04 zhoutwo

Hi, I hit the same issue and reached this post. I think the issue is basically the same as #275 and the same solution (workaround) worked for me.

After the change #247, react/react-dom are included as a webpack bundled code. However, if the project has a dependency module that has a react/react-dom dependencies like react-redux, react/react-dom are loaded as an external module too. That is why you see 2 react-dom loadings in the console.

So, to make this work, we need to include those modules in the whiteListedModulessetting in the project package.json so that webpack also bundle them. In my case, I needed to add antd and react-redux modules to this list.

"electronWebpack": {
  "whiteListedModules": [
     "antd",
     "react-redux"
  ]
},

Hope this will apply to your case too.

amegan avatar Dec 20 '20 04:12 amegan