Vite module load order - calling a named import before default import evaluated

999 Views Asked by At

I am using immer for state immutability in a Vite React application. If you want to load the immer plugin for drafting Maps and Sets (as well as object and array literals) you need to call enableMapSet() before importing the immer default export. More detail at https://immerjs.github.io/immer/installation/

Unfortunately in my Vite build process, the importing and running of enableMapSet() (which is defined in the first two lines of main.tsx) happens too late. The default import of immer has already completed. This leads to errors like...

Uncaught (in promise) Error: [Immer] The plugin for 'MapSet' has not been loaded into Immer. To enable the plugin, import and call `enableMapSet()` when initializing your application.

However, I don't know if I can control the load order. In my app immer is defined as a peer dependency. It is a second-order dependency because my app depends on https://www.npmjs.com/package/@lauf/store-edit/v/2.0.0-alpha.0 which in turn has a declared external dependency on immer. I have tried to ensure that no import of any library takes place before my import and invocation of enableMapSet() in main.tsx. However, somehow or another the import of @lauf/store-edit happens first as demonstrated by putting breakpoints at those lines in Chrome and seeing which comes first. It's possible there is preload behaviour which is causing everything to load before I get to call enableMapSet() but I don't know how to influence this. I attempted to prevent preload like this in vite.config.ts but it had no effect...

export default defineConfig({
  plugins: [react()],
  build: {
    modulePreload: {
      resolveDependencies: () => [],
    },
  },
});

Is there any way to influence the load order in Vite, to ensure that the import and invocation of enableMapSet() happens before loading other dependencies loaded by main.tsx?

1

There are 1 best solutions below

3
On
import { configureStore } from '@reduxjs/toolkit';
import { enableMapSet } from 'immer';
import { reducers } from './reducers';

enableMapSet();

export function configureStore() {
    const rootReducer = combineReducers({
        ...reducers,
    });

    return configureStore({
        reducer: rootReducer,
    });
}

const store = configureStore();
export type AppDispatch = typeof store.dispatch;
export default store;