Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot read properties of undefined (reading 'getStackAddendum') #31606

Closed
MichalekJan93 opened this issue Nov 21, 2024 · 5 comments
Closed

Cannot read properties of undefined (reading 'getStackAddendum') #31606

MichalekJan93 opened this issue Nov 21, 2024 · 5 comments
Labels
Resolution: Needs More Information Resolution: Stale Automatically closed due to inactivity Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@MichalekJan93
Copy link

MichalekJan93 commented Nov 21, 2024

After building the application on the production version I get the error Cannot read properties of undefined (reading 'getStackAddendum'). I have split the application into microfronts that are linked using the webpack module federation.

The error here is because ReactDebugCurrentFrame is undefined.

The problem does not appear in the dev version, only in the production version

function printWarning(level, format, args) {
      {
        var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
        var stack = ReactDebugCurrentFrame.getStackAddendum();
        if (stack !== '') {
          format += '%s';
          args = args.concat([stack]);
        } // eslint-disable-next-line react-internal/safe-string-coercion

        var argsWithFormat = args.map(function (item) {
          return String(item);
        }); // Careful: RN currently depends on this prefix

        argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
        // breaks IE9: https://github.com/facebook/react/issues/13610
        // eslint-disable-next-line react-internal/no-production-logging

        Function.prototype.apply.call(console[level], console, argsWithFormat);
      }
    }

package.json application shell

{
  "name": "wes-shell-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@cloudbeds/webpack-module-federation-types-plugin": "^1.18.0",
    "@emotion/react": "^11.11.4",
    "@emotion/styled": "^11.11.5",
    "@joint/core": "^4.0.4",
    "@mui/icons-material": "^5.11.6",
    "@mui/lab": "^5.0.0-alpha.125",
    "@mui/material": "^5.15.21",
    "@mui/x-charts": "^7.8.0",
    "@mui/x-date-pickers": "^5.0.18",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^14.4.3",
    "@types/react": "^18.0.27",
    "@types/react-dom": "^18.0.10",
    "chart.js": "^4.4.3",
    "color": "^4.2.3",
    "date-fns": "^2.29.3",
    "history": "^5.3.0",
    "js-cookie": "^3.0.5",
    "mobx": "^6.7.0",
    "mobx-react": "^7.6.0",
    "mobx-utils": "^6.0.5",
    "notistack": "^3.0.1",
    "path-to-regexp": "^6.2.1",
    "react": "^18.2.0",
    "react-chartjs-2": "^5.2.0",
    "react-custom-scrollbars-2": "^4.5.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.13.0",
    "react-scripts": "^5.0.1",
    "typescript": "^4.9.4",
    "web-vitals": "^3.0.4"
  },
  "scripts": {
    "dev": "npm run make-types && npm run generate-env && craco start --verbose",
    "make-types": "make-federated-types -o public/@types",
    "generate-env": "cd .. && env.sh && cd wes-shell-app",
    "serve": "serve -s build",
    "mock-api": "node \"src/mocks/api.js\"",
    "build": "craco build",
    "test": "craco test",
    "devcert": "set HTTPS=true&&set SSL_CRT_FILE=../wes-shell-app/cert.crt&&set SSL_KEY_FILE=../wes-shell-app/cert.key"
  },
  "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": {
    "@craco/craco": "^7.0.0",
    "@types/color": "^3.0.6",
    "@types/lodash": "^4.14.191",
    "connect-api-mocker": "^1.10.0",
    "express": "^4.18.2",
    "i18next": "^22.5.1",
    "i18next-browser-languagedetector": "^7.1.0",
    "jwt-decode": "^3.1.2",
    "lodash": "^4.17.21",
    "react-barcode-reader": "^0.0.2",
    "react-i18next": "^12.1.5",
    "tailwindcss": "^3.3.3",
    "zod": "^3.20.2"
  }
}

package.json second aplication

{
  "name": "wes-voice-picking-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@cloudbeds/webpack-module-federation-types-plugin": "^1.18.0",
    "@emotion/react": "^11.11.4",
    "@emotion/styled": "^11.11.5",
    "@mui/icons-material": "^5.11.16",
    "@mui/material": "^5.15.21",
    "@mui/x-charts": "^7.8.0",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^14.4.3",
    "external-remotes-plugin": "^1.0.0",
    "mobx": "^6.7.0",
    "mobx-react": "^7.6.0",
    "mobx-utils": "^6.0.5",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.13.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.4",
    "web-vitals": "^3.0.4"
  },
  "scripts": {
    "dev": "npm run generate-env && craco start --verbose",
    "generate-env": "cd .. && env.sh && cd wes-voice-picking-app",
    "serve": "serve -s build -p 3003",
    "build": "craco build",
    "test": "craco test"
  },
  "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": {
    "@craco/craco": "^7.0.0",
    "i18next": "^23.2.11",
    "i18next-browser-languagedetector": "^7.1.0",
    "react-i18next": "^13.0.2",
    "tailwindcss": "^3.3.3"
  }
}
@MichalekJan93 MichalekJan93 added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Nov 21, 2024
@eps1lon
Copy link
Collaborator

eps1lon commented Nov 21, 2024

Maybe you're mixing dev and prod? With module federation it's also easy to accidentally ship multiple Reacts. Without a minimal reproduction, we won't be able to help.

@MichalekJan93
Copy link
Author

MichalekJan93 commented Nov 21, 2024

federation.config.js in shell app

const deps = require("./package.json").dependencies;

module.exports = {
  name: "wes_shell_app",
  filename: "wes_shell_app.js",
  exposes: {
    "./use-app-context": "./src/hooks/use-app-context.ts",
    ............
  },
  remotes: {},
  shared: {
    ...deps,
    react: { singleton: true, requiredVersion: deps.react },
    i18next: { singleton: true, requiredVersion: deps["i18next"] },
    "react-dom": { singleton: true, requiredVersion: deps["react-dom"] },
  },
};

webpack.config.js in shell app

const { ModuleFederationPlugin } = require("webpack").container;
const {
  ModuleFederationTypesPlugin,
} = require("@cloudbeds/webpack-module-federation-types-plugin");
const paths = require("react-scripts/config/paths");
const federationConfig = require("./federation.config");

module.exports = {
  plugins: [
    new ModuleFederationPlugin(federationConfig),
    new ModuleFederationTypesPlugin({}),
  ],
  configure: (webpackConfig, { env, paths }) => {
    webpackConfig.output.publicPath = "auto";

    configureTypesFederation(webpackConfig, env);
    configureHtml(webpackConfig);

    return webpackConfig;
  },
};

const configureHtml = (webpackConfig) => {
  const htmlWebpackPlugin = webpackConfig.plugins.find(
    (plugin) => plugin.constructor.name === "HtmlWebpackPlugin"
  );

  htmlWebpackPlugin.userOptions.publicPath = paths.publicUrlOrPath;
  htmlWebpackPlugin.excludeChunks = [federationConfig.name];

  return webpackConfig;
};

const configureTypesFederation = (webpackConfig, env) => {
  const moduleFederationTypesPlugin = webpackConfig.plugins.find(
    (plugin) => plugin.constructor.name === "ModuleFederationTypesPlugin"
  );

  if (env === "development") {
    // running on localhost using npm run dev
    moduleFederationTypesPlugin.options = {
      disableTypeCompilation: true,
      disableDownladingRemoteTypes: true,
    };
  } else if (env === "production") {
    if (process.env.FE_BUILD_ENV !== "prod") {
      // creating a production build locally or by pipeline
      moduleFederationTypesPlugin.options = {
        disableDownladingRemoteTypes: true,
      };
    } else {
      // creatoing a production build by pipeline after commit to master branch
      moduleFederationTypesPlugin.options = {
        disableDownladingRemoteTypes: true,
      };
    }
  }
  return webpackConfig;
};

federation.config.js second app

const deps = require("./package.json").dependencies;

module.exports = {
  name: "wes_voice_picking_app",
  filename: "wes_voice_picking_app.js",
  exposes: {
    "./app": "./src/app.tsx",
  },
  remotes: {
    wes_shell_app:
      "wes_shell_app@[window._env_.REACT_APP_SHELL_APP]wes_shell_app.js",
  },
  shared: {
    ...deps,
    react: { singleton: true, requiredVersion: deps.react },
    "react-dom": {
      singleton: true,
      requiredVersion: deps["react-dom"],
    },
  },
};

webpack.config.js in second app

const { ModuleFederationPlugin } = require("webpack").container;
const ExternalTemplateRemotesPlugin = require("external-remotes-plugin");
const {
  ModuleFederationTypesPlugin,
} = require("@cloudbeds/webpack-module-federation-types-plugin");
const paths = require("react-scripts/config/paths");
const federationConfig = require("./federation.config");

module.exports = {
  plugins: [
    new ModuleFederationPlugin(federationConfig),
    new ExternalTemplateRemotesPlugin(),
    new ModuleFederationTypesPlugin({
      remoteEntryUrls: {
        wes_shell_app: "",
      },
      disableTypeCompilation: true,
    }),
  ],
  configure: (webpackConfig, { env, paths }) => {
    webpackConfig.output.publicPath = "auto";

    configureTypesFederation(webpackConfig, env);
    configureHtml(webpackConfig);

    return webpackConfig;
  },
};

const configureHtml = (webpackConfig) => {
  const htmlWebpackPlugin = webpackConfig.plugins.find(
    (plugin) => plugin.constructor.name === "HtmlWebpackPlugin"
  );

  htmlWebpackPlugin.userOptions.publicPath = paths.publicUrlOrPath;
  htmlWebpackPlugin.excludeChunks = [federationConfig.name];

  return webpackConfig;
};

const configureTypesFederation = (webpackConfig, env) => {
  const moduleFederationTypesPlugin = webpackConfig.plugins.find(
    (plugin) => plugin.constructor.name === "ModuleFederationTypesPlugin"
  );

  if (env === "development") {
    // running on localhost using npm run dev
    // this urls must not end with a slash (/)
    // if it does it gets doubled and error appears
    moduleFederationTypesPlugin.options.remoteEntryUrls.wes_shell_app =
      "....";
  } else if (env === "production") {
    if (process.env.FE_BUILD_ENV !== "prod") {
      // creating a production build locally or by pipeline
      moduleFederationTypesPlugin.options.remoteEntryUrls.wes_shell_app =
        "....";
    } else {
      // creatoing a production build by pipeline after commit to master branch
      moduleFederationTypesPlugin.options.remoteEntryUrls.wes_shell_app =
        "....";
    }
  }
  return webpackConfig;
};

To avoid running multiple react and react-dom I use singleton: true

@eps1lon
Copy link
Collaborator

eps1lon commented Nov 21, 2024

This is not a minimal production. It needs to be stripped of all dependencies that don't contribute to the bug. So you'd strip code until it no longer reproduces. Then you can pack it into a cloneable repository with clear instructions how to reproduce.

Copy link

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

@github-actions github-actions bot added the Resolution: Stale Automatically closed due to inactivity label Feb 19, 2025
Copy link

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Needs More Information Resolution: Stale Automatically closed due to inactivity Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

2 participants