mobxjs / mobx-state-tree

Full-featured reactive state management without the boilerplate
https://mobx-state-tree.js.org/
MIT License
6.99k stars 641 forks source link

Mobx/Mobx-state-tree doesnt work in module federation of Webpack. #2185

Open AshwinAsp opened 5 months ago

AshwinAsp commented 5 months ago

Bug report

Sandbox link or minimal reproduction code

Minimal Reproduction is complex as it involves creating multiple deployed static environments.

Describe the expected behavior

MST should work in any environment. i.e. Microfronts / Module Federated environment

Describe the observed behavior

Its always throwing the error Error: [MobX] minified error nr: 27 __ob__,AnonymousModel. Find the full error at: https://github.com/mobxjs/mobx/blob/main/packages/mobx/src/errors.ts at r (remoteEntry.js:2:117398) at Jr (remoteEntry.js:2:175698) at Xr (remoteEntry.js:2:175833) at t.value (remoteEntry.js:2:88909) at t.value (remoteEntry.js:2:29294) at Array.value (remoteEntry.js:2:88166) at tr (remoteEntry.js:2:154042) at t.defineProperty_ (remoteEntry.js:2:170740) at Object.defineProperty (remoteEntry.js:2:153623) at Function.defineProperty (<anonymous>)

More description and screenshots:

The MST integration with a simple example like the one attached below is working smoothly in a local dev environment but failing on a deployed environment. Since there is no existing bug reports or proper error tracking in MST it is very difficult to debug this error. What could be the possible cause that it throws no observable property '${property.toString()}' found on the observable object '${name}' only in a deployed environment.

Code: Store.ts

import { types } from 'mobx-state-tree';

const Todo = types.model({
  title: '',
  done: false,
}).actions((self) => ({
  toggle() {
    self.done = !self.done;
  }
}));

const User = types.model({
  id: '',
  name: '',
  isLoggedIn: false,
});

const RootStore = types
  .model({
    users: types.array(User),
    todos: types.optional(types.array(Todo), []),
  })
  .actions((self) => ({
    addTodo(title: string, done: boolean) {
      self.todos.push(Todo.create({ title, done }));
    },
    addUser(id: string, name: string, isLoggedIn: boolean) {
      self.users.push(User.create({ id, name, isLoggedIn }));
    },
  }));

const store = RootStore.create({
  users: [], // users is not required really since arrays and maps are optional by default since MST3
});

export default store;

Component.tsx

import store from './Store';

const Screen = () => {
  console.log(store.users.at(0));

  useEffect(() => {
    store.addTodo('Patient', false);
    store.addUser('ZB123', 'John', true);
  }, []);
}

Local Environment

image

Deployed environment

image
coolsoftwaretyler commented 5 months ago

Hey @AshwinAsp, thanks for the bug report!

I've used MST successfully in Repack, which is a federated module system. But I haven't tried it with the tech you mentioned here. I will have to look into it more.

Also, reading the error closely, it seems possible this is a MobX issue, not a MobX-State-Tree issue. The first sentence of the error that says "find the error at..." Seems to be pointing to the MobX codebase and not us.

Have you checked with MobX or filed an issue there?

AshwinAsp commented 5 months ago

@coolsoftwaretyler When I did unprotect(store) it starts loading but bunch of irrelevant errors are coming now. Like Uncaught Error: [mobx-state-tree] users property is declared twice eventhough there's only one declaration. And unprotect and the error thats coming now is coming from mobx-state-tree. Now again the weirder part is in development environment there is no problems. But this is happening only after is deployment and in the integrated mode of MFE.

coolsoftwaretyler commented 5 months ago

Interesting. This is a strange one! I know you said a reproduction would be tough but I think we'll need to repro this to really get the bottom of things.

Can you describe the environment and maybe link to the technology you're using so we can try to put something together?

AshwinAsp commented 5 months ago

Ill try to add a reproduction repo soon

AshwinAsp commented 5 months ago

We have a legacy app using Vue2 with webpack which is hosting the MFE application. The MFE is a react application also using webpack to bundle this. Im not sure if the stack has any implication of the code because if its works for localhost it should work for server as well. I mean in standalone mode it does work but not in the integrated mode. Eventhough the same code is used in both the modes

coolsoftwaretyler commented 5 months ago

@AshwinAsp - does your local environment do the same minification step as your production deploy? I don't know a lot about MFE, and without a repro I don't have a good place to start, so please forgive me if this is an irrelevant question.

But if there's a difference between local and prod, a build step like minification seems like a good place to start with troubleshooting. Can you try turning off that step for MST or for the whole app and getting it into a production-like environment to see if that helps?

If so, that will help us narrow down or remove this as a possible culprit.

AshwinAsp commented 5 months ago

I wish I can add a repo for replication. But that would involve creating a new project with all the dependencies and build steps to match our current projects. But no there is no difference in the build/minification process as we test the built code locally which would have the same build steps.

On Wed, Jun 19, 2024, 8:22 PM Tyler Scott Williams @.***> wrote:

@AshwinAsp https://github.com/AshwinAsp - does your local environment do the same minification step as your production deploy? I don't know a lot about MFE, and without a repro I don't have a good place to start, so please forgive me if this is an irrelevant question.

But if there's a difference between local and prod, a build step like minification seems like a good place to start with troubleshooting. Can you try turning off that step for MST or for the whole app and getting it into a production-like environment to see if that helps?

If so, that will help us narrow down or remove this as a possible culprit.

— Reply to this email directly, view it on GitHub https://github.com/mobxjs/mobx-state-tree/issues/2185#issuecomment-2178903660, or unsubscribe https://github.com/notifications/unsubscribe-auth/BDMTETQDPP2OH5RA4XZ26KLZIGLKPAVCNFSM6AAAAABJLSCIHOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNZYHEYDGNRWGA . You are receiving this because you were mentioned.Message ID: @.***>

--

Attention: Confidential

This email message and any attachment is for the sole use of the intended recipient(s) and may contain confidential and/or privileged information, including patient information protected by federal and state privacy laws.  Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact me by reply email and destroy all copies of the original message.

coolsoftwaretyler commented 5 months ago

I totally understand. That just means we may not be able to help you entirely.

Have you tried my suggestion of turning off minification? Any improvement there?