-
Notifications
You must be signed in to change notification settings - Fork 642
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
Dynamic Import / Lazy Loading of Stores #1607
Comments
Hey @jamonholmgren, as the new Supreme Commander I am just checking if there is any particular channel I should be making requests like this? |
Hi @jamonholmgren, I'm wondering if you could chime in on this topic? This would really help build large web apps using MST without impacting loading times negatively 🙂 |
Hello. I like this proposal. To achieve similar effect I rely on volatiles and specific structure of my root store/substores. Which is a bit weird and I'm looking for a better&standard approach. import {
types,
getRoot,
getIdentifier,
resolveIdentifier,
} from 'mobx-state-tree';
export const ROOT_STORE = Symbol('rootStore');
export function storeReference(subType) {
return types.safeReference(subType, {
get(id, parent) {
let root = getRoot(parent);
if (!/^\$/.test(id)) {
return resolveIdentifier(subType, root, id);
}
let globalStore = root[ROOT_STORE];
if (!globalStore) {
throw new Error(
'substore should have ROOT_STORE volatile field',
);
}
let [, storeId, localId] = /^\$([^$]+)\$(.+)$/.exec(id);
let store = globalStore.subStores[storeId];
return resolveIdentifier(subType, store, localId);
},
set(value) {
let root = getRoot(value);
let storeId = root.storeId;
if (!storeId) {
throw new Error('substore should have storeId field');
}
return `$${storeId}$${getIdentifier(value)}`;
},
});
}
////////////////////////////////////////////////////////////////////////////////
const Global = types.model('Global', {}).volatile(() => {
return {
subStores: {},
};
});
let global = Global.create({});
const Val = types.model('Val', {
id: types.identifier,
answer: 42,
});
const StoreA = types
.model('A', {
value: Val,
})
.volatile(() => {
return {
[ROOT_STORE]: null,
};
})
.views(() => {
return {
get storeId() {
return 'storeA';
},
};
});
const StoreB = types
.model('B', {
ref: storeReference(Val),
})
.volatile(() => {
return {
[ROOT_STORE]: null,
};
})
.views(() => {
return {
get storeId() {
return 'storeB';
},
};
})
.actions((self) => {
return {
setRef(value) {
self.ref = value;
},
};
});
let storeA = StoreA.create({ value: { id: 'test' } });
let storeB = StoreB.create({});
storeA[ROOT_STORE] = global;
storeB[ROOT_STORE] = global;
global.subStores.storeA = storeA;
global.subStores.storeB = storeB;
storeB.setRef(storeA.value);
console.log(storeA.value === storeB.ref); // true |
I have created a PR that adds the functionality expressed in the original PR, for those who have commented please take a look and give some feedback/contribute 🙏 |
Hey folks, sorry about my silence on this issue. I'm looking at the PR and will talk it over with the core team. It looks like there's a fair amount of support for adding this functionality, and since it doesn't seem to break any backwards compatibility, I'm interested in getting it moved forward. |
Any updates to share about this PR? 🙂 |
Hey folks - sorry to keep kicking the can here, just wanted to pop in to say that I'm adding a label here for better categorization while Jamon and I take some time to clean things up in the repo overall. |
We merged #1722 so I'm gonna close this out! Sorry it took me a bit to go back through the issues and let y'all know! |
Feature request
Is your feature request related to a problem? Please describe.
When using MST, I have run in to issues with tools like
bundlesize
as having a common root store imports references to other stores, which can bring big packages along for the ride.E.g. I want to add some code which uses compresses images and uploads them to my server. The method lives in the PhotoStore and the package that I am using to do this is 50kb.
With my RootStore as such, now any where else in code that I reference the root store brings the 50kb package too (e.g. the user account password reset page)
Describe the solution you'd like
I would like to be able to lazy import a store so my root store can be smaller in size and users will not get shipped code they do not use. Ideally this will work similar to other code splitting strategies in webpack like dynamic imports
e.g.
Describe alternatives you've considered
If a route is entirely independent from existing stores, it can live in its own tree and not load the main RootStore at all.
Avoid the use of references, and instead use plain strings and do the lookups manually. There wouldn't need to be a RootStore at all anymore.
Additional context
A PR was closed a while back which seemed to offer this functionality
Are you willing to (attempt) a PR?
The text was updated successfully, but these errors were encountered: