Blog>
Snippets

Using ESM Tree Shaking with Redux Selectors

Provide a code example that takes advantage of ESM tree shaking in Redux, by exporting multiple selectors and showing how unused exports are omitted in the final bundle.
// selectors.js
// Exporting multiple selectors
export const selectUser = (state) => state.user;
export const selectPosts = (state) => state.posts;
export const selectComments = (state) => state.comments;
// ... possibly more selectors
This file (selectors.js) exports multiple selectors. When importing these selectors in other modules, ESM (ES6 Modules) allows us to pick only the selectors we need, aiding in tree shaking.
// userSlice.js
import { selectUser } from './selectors';

// Here we use only selectUser, so selectPosts and selectComments will not be included in the final bundle
export const userSelector = (state) => {
    const user = selectUser(state);
    // perform some operations specific to this slice ... 
    return user;
};
This file (userSlice.js) imports only the selectUser selector from the selectors.js. Because we use ESM, tree shaking will ensure that only the used selectors are included in the final bundle, thus unused exports like selectPosts and selectComments will be omitted.
// postSlice.js
import { selectPosts } from './selectors';

// Again, by only importing selectPosts, tree shaking will eliminate unused selectors
export const postSelector = (state) => {
    const posts = selectPosts(state);
    // operations specific to posts...
    return posts;
};
This file (postSlice.js) imports only the selectPosts selector. Only the necessary code is bundled thanks to the ESM tree shaking process, which helps in reducing bundle size and optimizing the application.
// In the application's entry point or a high-level module where you want to configure the store
import { createStore, combineReducers } from 'redux';
import userReducer from './userSlice';
import postReducer from './postSlice';

const rootReducer = combineReducers({
  user: userReducer,
  posts: postReducer
  // ... other reducers could be combined here
});

export const store = createStore(rootReducer);
Finally, an entry point or application configuration file combines only the slices used across the app, thus pulling in only the necessary selectors and related code into the final bundle when creating the Redux store.