question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Codespliting example / module

See original GitHub issue

To maintain small initial bundle size we should be able to split storeon modules (reducers) and load + inject them on demand.

The main problem right now is to init only fresh modules after load without dispatching @init for others.

initial api proposal:

const CounterPage = () => {
  const { dispatch, counter } = useStoreon('counter');

  return (
    <button onClick={() => dispatch('counter/inc')}>value: {counter}</button>
  );
};

const counterModule = store => {
  store.on('@init/counter', () => ({ counter: 0 }));

  store.on('counter/inc', ({ counter }) => ({ counter: counter + 1 }));
};

export default injectModule('counter', counterModule)(CounterPage);

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
aicommented, Sep 20, 2019

Current API was created to keep all store logic in one chunk. I will think about this feature in next big update, but it will not be soon.

0reactions
majo44commented, Sep 20, 2019

Hi, so I had same problem, I have mid size app and I want to split it to independent lazy loaded micro frontends (chunks ). Eg Admin panel which implementation contains business logic, ui, services is very rarely used I want to load lazy. In general each separate “page” of my app I implements as separate storeon module, and later I’m able to manage which of them should be lazy loaded which not.

Currently, as I controls all modules which I’m using I implemented this in that way:

// storeon-lazy-init.js
// utility for lazy init the storeon modules
export const INIT = Symbol('INIT');
// module for bind @init with INIT
export function lazyInitModule(store) {
    store.on('@init', () => {
        setTimeout(() => store.dispatch(INIT), 1);
    });
    store.on(INIT, () => {});
}
// storeon-lazy-module.js
// utility which call once loader on some event 
// then dispatch the INIT event
// then redispatch the event again (to be handled by true implementation)
export function loadLazyModuleOn(store, event, loader) {
    // lazy contact modal module
    const un = store.on(event, async (state, data) => {
        const module = await loader();
        module.module(store);
        un();
        store.dispatch(INIT);
        store.dispatch(event, data);
    });
}
// admin.module.js
// code of my feature 
export function module(store) {
    store.on(INIT, () => ({adminPageState: 'initail value'}));
    store.on('show-admin-view-event', (state, event) => ....);
}
// index.js
// code of my application
function appModule(store) {
     loadLazyModuleOn(store, 'show-admin-view-event', () => import('./admin.module.js'));
}
const store = createStore([lazyInitModule, appModule]);

Alternatively, if I decide that admin module should be loaded not lazy I can still change only my app module, and everything will work fine:

// index.js
import { module as adminModule } from './admin.module.js';
// code of my application
function appModule(store) {
     ...
}
const store = createStore([lazyInitModule, appModule, adminModule]);

It is not super simple, also it works only with my modules as only my modules knows my INIT event. So if I will try to take some module from npm and load it lazy, and this module will depends on @init event, my solution will not work.

I comes to conclusion that the best approach for solving that problem in generic way will be to change a bit behavior of storeon for the @init event. For this particular event, handler should be always called only once, and should be automatically unregistered. Then we will be able to always dispatch the generic @init event after chunk load.

With such change my admin.module.js can looks like standard module:

// admin.module.js
// code of my feature 
export function module(store) {
    store.on('@init', () => ({adminPageState: 'initail value'}));
    store.on('show-admin-view-event', (state, event) => ....);
}

And rest code can simplified to:

// storeon-lazy-module.js
// utility which call once loader on some event 
// then dispatch the @init event
// then redispatch the event again (to be handled by true implementation)
export function loadLazyModuleOn(store, event, loader) {
    // lazy contact modal module
    const un = store.on(event, async (state, data) => {
        const module = await loader();
        module.module(store);
        un();
        store.dispatch(`@init`);
        store.dispatch(event, data);
    });
}
// index.js
// code of my application
function appModule(store) {
     loadLazyModuleOn(store, 'show-admin-view-event',  () => import('./admin.module.js'));
}
const store = createStore([appModule]);

This will be a breaking change, but this should not affect any library as even if that libs are using @init event, expectation is that event is dispatched only once.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Code Splitting - webpack
This guide extends the example provided in Getting Started. ... Let's take a look at how we might split another module from the...
Read more >
How code spliting works and how to use it - DEV Community ‍ ‍
Webpack code splitting ... With import().then webpack will create another file, put all the logic of the module inside this file and only...
Read more >
Code Splitting - Parcel
Parcel supports zero configuration code splitting out of the box. This allows you to split your application code into separate bundles which can...
Read more >
Code-Splitting - React
Bundling is the process of following imported files and merging them into a single file: a “bundle”. This bundle can then be included...
Read more >
Code Splitting With Dynamic Module Imports
For example, code that is only needed for admin users of a site. It doesn't make sense to load this code for all...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found