Создание приложений React, React Router v4, React Redux уменьшает расщепление кода и source-map-explorer - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь уменьшить свой первоначальный пакет Create React App, применяя разделение кода как к моим компонентам на основе маршрутов, так и к моим редукторам Redux.

В то время как ранее было сделано и достигнуто с помощью React lazy иПриостановка, последнее выполняется в подходе, аналогичном описанному в этой статье .

В браузере это работает нормально, то есть компоненты React загружают редукторы во время выполнения..

Кроме того, для целей анализа я установил source-map-explorer и добавил в свой package.json скрипт для анализа моего пакета JS.

Теперь, когда я пытаюсь запустить npm run analyze, кажется, что в комплект всегда входит вся часть редукса.

Я делаю что-то не так в том, как я работаю с кодовыми разделителями кода, или это просто, как работает 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;

редукторs.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;

исходник-карта-выход проводника source-map-explorer output

...