Patrick Hund | Lead Frontend Developer | @wiekatz

Software Entropy

Accumulation of Technical Debt

(source: Dr. Carola Lilienthal)

Big Ball of Mud

React Component Spaghetti

Divide and Conquer

Separate presentational
and container components

Organize presentational components
in a separate style guide

Separation of Concerns

(source: Cristiano Rastelli)

Separation of Concerns

(source: Cristiano Rastelli)

Bricks

index.js


export { default as HackerNews } from './components';
export * from './actions';
export { default as reducer } from './reducer';
export { default as saga } from './sagas';
export { default as selectors } from './selectors';
                    

index.js


export { default as HackerNews } from './components';
export * from './actions';
export { default as reducer } from './reducer';
export { default as saga } from './sagas';
export { default as selectors } from './selectors';
                    

index.js


export { default as HackerNews } from './components';
export * from './actions';
export { default as reducer } from './reducer';
export { default as saga } from './sagas';
export { default as selectors } from './selectors';
                    

index.js


export { default as HackerNews } from './components';
export * from './actions';
export { default as reducer } from './reducer';
export { default as saga } from './sagas';
export { default as selectors } from './selectors';
                    

index.js


export { default as HackerNews } from './components';
export * from './actions';
export { default as reducer } from './reducer';
export { default as saga } from './sagas';
export { default as selectors } from './selectors';
                    

index.js


export { default as HackerNews } from './components';
export * from './actions';
export { default as reducer } from './reducer';
export { default as saga } from './sagas';
export { default as selectors } from './selectors';
                    

registerSelectors.js


import { registerSelectorsForUseWithGlobalState } from "@modular-toolkit/selectors";
import { selectors as hackerNews } from "@modular-toolkit/demo-module";

const selectorMapping = {
  "modules.hackerNews": hackerNews
};

export default () => {
  for (const [path, selectors] of Object.entries(selectorMapping)) {
    registerSelectorsForUseWithGlobalState(path, selectors);
  }
};
            

registerSelectors.js


import { registerSelectorsForUseWithGlobalState } from "@modular-toolkit/selectors";
import { selectors as hackerNews } from "@modular-toolkit/demo-module";

const selectorMapping = {
  "bricks.widgets.hackerNews": hackerNews
};

export default () => {
  for (const [path, selectors] of Object.entries(selectorMapping)) {
    registerSelectorsForUseWithGlobalState(path, selectors);
  }
};
            

registerSelectors.js


import { registerSelectorsForUseWithGlobalState } from "@modular-toolkit/selectors";
import { selectors as hackerNews } from "@modular-toolkit/demo-module";

const selectorMapping = {
  "bricks.widgets.hackerNews": hackerNews
};

export default () => {
  for (const [path, selectors] of Object.entries(selectorMapping)) {
    registerSelectorsForUseWithGlobalState(path, selectors);
  }
};
            

rootReducer.js


import { combineReducers } from "redux";

import { reducer as hackerNews } from "@modular-toolkit/demo-module";

export default combineReducers({
  bricks: combineReducers({
    hackerNews
  })
});
            

configureStore.js


import { applyMiddleware, createStore } from "redux";
import createSagaMiddleware from "redux-saga";
import rootReducer from "./rootReducer";
import { saga } from '@modular-toolkit/demo-module';

export default () => {
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
  sagaMiddleware.run(saga);
  return store;
};
            
  • Complicated “wiring up” of selectors, sagas and reducers
  • No code splitting

configureStore.js


import { applyMiddleware, createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './rootReducer';
import hackerNews from '@modular-toolkit/demo-module';
import { BrickManager } from '@modular-toolkit/bricks/BrickManager';

export default () => {
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(rootReducer, sagaMiddleware);
  const brickManager = new BrickManager({ store, reducer, sagaMiddleware });
  brickManager.installBricks({
    'bricks.hackerNews': hackerNews
  });
  return store;
};
            

configureStore.js


import { applyMiddleware, createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './rootReducer';
import hackerNews from '@modular-toolkit/demo-module';
import { BrickManager } from '@modular-toolkit/bricks/BrickManager';

export default () => {
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(rootReducer, sagaMiddleware);
  const brickManager = new BrickManager({ store, reducer, sagaMiddleware });
  brickManager.installBricks({
    'bricks.hackerNews': hackerNews
  });
  return store;
};
            

github.com/technology-ebay-de/modular-toolkit

npm install --save @modular-toolkit/bricks

Thank you!

Ninja Maaß

Frontend Developer

Daniel Schäfer

Frontend Developer

Eike Schulte-Kersmecke

Backend Developer

Anja Kunkel

Backend Developer

Torsten Walter

Frontend Developer

Juho Vepsäläinen

Dev Consultant

Mike Krüger

Quality Assurance

Hajo Skwirblies

Site Operations

Florian Stefan

Architect

Christoph Springer

Team Lead

Julia Thiele

Product Owner

Jakob Gehring

Product Owner

View this presentation online: http://bit.ly/breakdownreact

Patrick Hund | Lead Frontend Developer | @wiekatz
Copyright © 2018 mobile.de GmbH