nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.51k stars 2.34k forks source link

State is not being shared by default between host and remote application after migration from nx 15.7.0 to 16.4.2 (React) #17914

Closed noamfeldman closed 8 months ago

noamfeldman commented 1 year ago

Current Behavior

We have a React host/remote micro-frontend application with shared-components library:

- apps
  - container (host)
  - page 1 (remote)
  - page 2 (remote)
  - ...
- libs
  - shared-components
    - src
      - state (state stores implemented using zustand) 

The state of the application is managed using the zustand state management library. Before migrating to NX 16.4.2, all remote applications used the same state instance. However, after the migration, each remote application now has its own state instance.

For example, the host application is a container app that contains the application's main navigation menu and logged in user information. When a logged in user changes their preferred theme or timezone, this change will affect all remote applications that use the same zustand state management library. However, after the migration, this default behavior no longer works.

A workaround that seems to solve the issue is adding the following "shared" settings to the host's (container) module-federation.config.js file settings:

// @ts-check

/**
 * @type {import('@nrwl/devkit').ModuleFederationConfig}
 **/
const moduleFederationConfig = {
  name: 'container',
  remotes: ['page1', 'page2', 'page3'],
  shared: (name, config) => {
    return { ...config, singleton: true };
  },
};

module.exports = moduleFederationConfig;

Expected Behavior

Keep the default behavior of state management as it was before the migration

GitHub Repo

No response

Steps to Reproduce

  1. Create a host/remote React application using NX version 15.7.0
  2. Add a shared-components with state management that will be used for read and update the store's state. For example:
import { PaletteMode } from '@mui/material';
import { create } from 'zustand';

type PaletteModeStore = {
  paletteMode: PaletteMode | null;
  update: (paletteMode: PaletteMode | null) => void;
};

export const usePaletteModeStore = create<PaletteModeStore>((set) => ({
  paletteMode: 'light',
  update: (value: PaletteMode | null): void => {
    set(() => ({ paletteMode: value }));
  },
}));
  1. Update the mode in the host/container app and listen for changes on the remote app. See that changes on the host application affect the remote application.
// Update example on the host container application
const paletteStore = usePaletteModeStore();
const handleMenuChange = (newMode: string) => {
  paletteStore.update(newMode);
}

// Read example on one of the remote applications
const paletteStore = usePaletteModeStore();
const [mode, setMode] = useState<PaletteMode>(
    paletteStore.paletteMode !== null
      ? paletteStore.paletteMode
      : 'light'
  );
  1. Migrate to NX 16.4.2 - the state is not being shared anymore.

Nx Report

NX Report Before Migration


 NX   Report complete - copy this into the issue template

   Node : 18.12.1
   OS   : darwin arm64
   yarn : 3.3.0

   nx                      : 15.7.0
   @nrwl/jest              : 15.7.0
   @nrwl/linter            : 15.7.0
   @nrwl/workspace         : 15.7.0
   @nrwl/cli               : 15.7.0
   @nrwl/cypress           : 15.7.0
   @nrwl/devkit            : 15.7.0
   @nrwl/eslint-plugin-nx  : 15.7.0
   @nrwl/js                : 15.7.0
   @nrwl/react             : 15.7.0
   @nrwl/rollup            : 15.7.0
   @nrwl/tao               : 15.7.0
   @nrwl/web               : 15.7.0
   @nrwl/webpack           : 15.7.0
   @nrwl/nx-cloud          : 15.0.3
   typescript              : 4.9.5

NX Report After Migration

  NX   Report complete - copy this into the issue template

   Node   : 18.12.1
   OS     : darwin-arm64
   yarn   : 3.3.0

   nx                 : 16.4.2
   @nx/js             : 16.4.2
   @nx/jest           : 16.4.2
   @nx/linter         : 16.3.2
   @nrwl/linter       : 16.4.2
   @nx/workspace      : 16.3.2
   @nrwl/workspace    : 16.4.2
   @nx/cypress        : 16.3.2
   @nx/devkit         : 16.4.2
   @nx/eslint-plugin  : 16.4.2
   @nx/react          : 16.4.2
   @nx/rollup         : 16.4.2
   @nrwl/tao          : 16.3.2
   @nx/web            : 16.4.2
   @nx/webpack        : 16.4.2
   nx-cloud           : 16.0.5
   typescript         : 5.1.6
   ---------------------------------------
   Local workspace plugins:
         @admintool.fe/shared-components
   ---------------------------------------

Failure Logs

No response

Operating System

Additional Information

This is our package.json file:

{
  "name": "our internal app name",
  "version": "0.1.0",
  "license": "MIT",
  "private": true,
  "devDependencies": {
    "@babel/preset-react": "^7.18.6",
    "@nrwl/devkit": "16.4.2",
    "@nrwl/eslint-plugin-nx": "16.4.2",
    "@nrwl/jest": "16.4.2",
    "@nrwl/js": "16.4.2",
    "@nrwl/linter": "16.4.2",
    "@nrwl/react": "16.4.2",
    "@nrwl/web": "16.4.2",
    "@nrwl/webpack": "16.4.2",
    "@nrwl/workspace": "16.4.2",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
    "@rollup/plugin-url": "^8.0.1",
    "@svgr/rollup": "8.0.1",
    "@svgr/webpack": "8.0.1",
    "@testing-library/dom": "^9.3.0",
    "@testing-library/react": "14.0.0",
    "@testing-library/user-event": "^14.4.3",
    "@types/jest": "29.4.4",
    "@types/node": "18.14.2",
    "@types/react": "18.2.13",
    "@types/react-dom": "18.2.6",
    "@types/react-router-dom": "^5.3.3",
    "@typescript-eslint/eslint-plugin": "5.60.1",
    "@typescript-eslint/parser": "5.60.1",
    "babel-jest": "29.4.3",
    "babel-plugin-import": "^1.13.6",
    "cypress": "12.16.0",
    "eslint": "^8.34.0",
    "eslint-config-prettier": "^8.6.0",
    "eslint-plugin-cypress": "^2.12.1",
    "eslint-plugin-import": "2.27.5",
    "eslint-plugin-jsx-a11y": "6.7.1",
    "eslint-plugin-react": "7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "husky": "^8.0.0",
    "jest": "29.4.3",
    "jest-environment-jsdom": "29.4.3",
    "jest-junit": "^15.0.0",
    "mimic": "^2.0.9",
    "nx": "16.4.2",
    "nx-cloud": "16.0.5",
    "prettier": "^2.8.4",
    "react-refresh": "^0.14.0",
    "react-test-renderer": "^18.2.0",
    "ts-jest": "29.1.1",
    "ts-node": "^10.9.1",
    "typescript": "5.1.6",
    "url-loader": "^4.1.1",
    "yarn-upgrade-all": "^0.7.2"
  },
  "dependencies": {
    "@emotion/react": "11.11.1",
    "@emotion/styled": "11.11.0",
    "@fontsource/montserrat": "^4.5.14",
    "@fontsource/roboto": "^4.5.8",
    "@material-ui/core": "^4.12.4",
    "@material-ui/styles": "^4.11.5",
    "@mui/icons-material": "^5.11.16",
    "@mui/lab": "^5.0.0-alpha.134",
    "@mui/material": "^5.13.6",
    "@mui/styled-engine-sc": "^5.12.0",
    "@mui/styles": "^5.13.2",
    "@mui/system": "^5.13.6",
    "@mui/utils": "^5.13.6",
    "@mui/x-data-grid": "^6.2.0",
    "@mui/x-data-grid-pro": "^6.2.0",
    "@mui/x-date-pickers": "^6.2.0",
    "@mui/x-date-pickers-pro": "^6.2.0",
    "@mui/x-license-pro": "^5.17.12",
    "@nrwl/cypress": "16.3.2",
    "@nrwl/rollup": "^16.4.2",
    "@tanstack/react-query": "^4.24.6",
    "@tanstack/react-query-devtools": "^4.24.6",
    "@types/raygun4js": "^2.13.8",
    "@types/react-copy-to-clipboard": "^5.0.4",
    "@types/react-syntax-highlighter": "^15.5.6",
    "axios": "^1.3.3",
    "clsx": "^1.2.1",
    "core-js": "^3.28.0",
    "dayjs": "^1.11.7",
    "dayjs-plugin-utc": "^0.1.2",
    "formik": "^2.2.9",
    "material-icons": "^1.13.1",
    "material-ui-confirm": "^3.0.9",
    "raygun4js": "^2.25.6",
    "react": "^18.2.0",
    "react-cookie": "^4.1.1",
    "react-copy-to-clipboard": "^5.1.0",
    "react-country-flag": "^3.1.0",
    "react-dom": "^18.2.0",
    "react-error-boundary": "^3.1.4",
    "react-router": "^6.14.0",
    "react-router-dom": "6.11.2",
    "react-select": "^5.7.3",
    "react-syntax-highlighter": "^15.5.0",
    "react-timezone-select": "^2.1.2",
    "recharts": "^2.7.2",
    "regenerator-runtime": "^0.13.11",
    "styled-components": "^5.3.11",
    "tslib": "^2.5.0",
    "universal-cookie": "^4.0.4",
    "xml-formatter": "^3.3.2",
    "yup": "^1.0.0",
    "zustand": "^4.3.8"
  },
  "scripts": {
    "postinstall": "husky install"
  }
}
AgentEnder commented 1 year ago

Hey @noamfeldman , it may be unrelated, but some of your @nrwl/ or @nx/ packages don't line up with the version of nx you have installed. Aside from @nrwl/nx-cloud, all packages under the nrwl scope should generally be set up with the same version.

Can you correct this and check that the issue still reproduces? An easy way to fix this would be to run nx migrate 16.4.2 Alternatively, updating to latest with nx migrate latest would also work.

github-actions[bot] commented 9 months ago

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! 🙏

github-actions[bot] commented 7 months ago

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.