我正试图通过对基于路由的组件和Redux缩减器应用代码拆分来减少我的最初的React React App捆绑包。
使用React lazy和Suspense可以完成和实现前者,而this article中详细介绍了后者。
这似乎在浏览器中很好用,即React组件似乎在运行时加载了reducer。
此外,出于分析目的,我安装了source-map-explorer,并在package.json中添加了一个脚本来分析我的JS包。
现在,每当我尝试运行npm run analyze
时,捆绑软件似乎总是包含所有redux部分。
我在代码拆分化缩减器的方式上做错了吗,或者这仅仅是source-map-explorer的工作原理吗?
您可以在我的代码下方找到source-map-explorer输出的屏幕截图
package.json
...
"dependencies": {
...
"lodash": "^4.17.11",
"prop-types": "^15.6.2",
"react": "^16.6.3",
"react-app-polyfill": "^0.1.3",
"react-dom": "^16.6.3",
"react-redux": "^5.1.1",
"react-router-dom": "^4.3.1",
"redux": "^4.0.1",
"redux-saga": "^0.16.2",
...
},
"devDependencies": {
...
"react-scripts": "^2.1.1",
"redux-devtools-extension": "^2.13.7",
"source-map-explorer": "^1.6.0"
},
"scripts": {
"analyze": "source-map-explorer build/static/js/main.*",
"build": "react-scripts build",
...
},
...
store.js
import { applyMiddleware, combineReducers, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import createSagaMiddleware from 'redux-saga';
import throttle from 'lodash/throttle';
import { loadState, saveState } from './localStorage';
import reducerRegistry from './reducerRegistry';
import registerDefaultReducers from './reducers';
import rootSaga from './sagas';
export const configureStore = () => {
const { REACT_APP_STATE_DRIVER } = process.env;
const sagaMiddleware = createSagaMiddleware();
let store;
let persistedState;
if(REACT_APP_STATE_DRIVER === "localStorage") {
persistedState = loadState();
}
registerDefaultReducers();
if(persistedState) {
// We register additional reducers
// in case they are needed from preloaded state
Object.entries(persistedState).forEach(([name, reducer]) => {
reducerRegistry.register(name, reducer);
});
}
const reducers = reducerRegistry.getReducers();
const rootReducers = combineReducers(reducers);
if(persistedState) {
store = createStore(
rootReducers,
persistedState,
composeWithDevTools(
applyMiddleware(sagaMiddleware)
)
);
} else {
store = createStore(
rootReducers,
composeWithDevTools(
applyMiddleware(sagaMiddleware)
)
);
}
if(REACT_APP_STATE_DRIVER === "localStorage") {
store.subscribe(throttle(() => {
saveState(store.getState());
}, 1000));
}
// We set an event listener for the reducer registry
// So that whenever a new reducer gets added
// We replace the reducers with the new ones
reducerRegistry.setChangeListener((reducers) => {
store.replaceReducer(combineReducers(reducers));
});
sagaMiddleware.run(rootSaga);
return store;
}
const store = configureStore();
export default store;
reducers.js
import reducerRegistry from './reducerRegistry';
import auth from './auth/reducers';
// We only register the initial defaul reducers here,
// Leaving the other ones for async loading
export const defaultReducers = {
auth,
};
const registerDefaultReducers = () => {
Object.entries(defaultReducers).forEach(([name, reducer], idx) => {
reducerRegistry.register(name, reducer);
});
};
export default registerDefaultReducers;
reducerRegistry.js
export class ReducerRegistry {
constructor() {
this._emitChange = null;
this._reducers = {};
}
getReducers() {
return {
...this._reducers
};
}
register(name, reducer) {
if(this._reducers[name]) {
return;
}
this._reducers = {
...this._reducers,
[name]: reducer
};
if (this._emitChange) {
this._emitChange(this.getReducers());
}
}
setChangeListener(listener) {
this._emitChange = listener;
}
}
const reducerRegistry = new ReducerRegistry();
export default reducerRegistry;
Create.js 我尝试动态加载减速器的通用组件
import React from 'react';
import reducerRegistry from '../../../redux/reducerRegistry';
import users from '../../../redux/users/reducers';
reducerRegistry.register('users', users);
const Create = props => {
// code omitted...
}
export default Create;