Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Modular Frontend Architectures

Steve Kinney
August 07, 2019
410

Building Modular Frontend Architectures

Steve Kinney

August 07, 2019
Tweet

Transcript

  1. TABLE OF CONTENTS 01. Defining Modularity 02. Layers of an

    Application 03. Creating Modular UI 04. Modular Deployment
  2. WHAT ARE SOME OF THE MOVING PARTS? • User Interface

    • State Management • Location Within the Application • Communication with the Server
  3. SINGLE RESPONSIBILITY A given component or module of your application

    should have only one reason why you’d need to change it.
  4. class CampaignsList extends React.Component { state = { campaigns: []

    }; componentDidMount() { getCampaignsFromApi() .then(campaigns !=> this.setState({ campaigns })); } render() { <section> { this.state.campaigns.map(campaign !=> { <Campaign campaign={campaign} !/> }) } !</section> } }
  5. class CampaignsFetcher extends React.Component { state = { campaigns: []

    }; componentDidMount() { getCampaignsFromApi() .then(campaigns !=> this.setState({ campaigns })); } render() { <Campaigns campaigns={campaigns} !/>; } } const CampaignsList = ({ campaigns }) !=> ( <section> {campaigns.map(campaign !=> { <Campaign campaign={campaign} !/>; })} !</section> );
  6. TAKING THIS PATTERN A STEP FURTHER • Tired: Multiple responsibilities

    • Wired: Separating responsibilities • Inspired: Creating reusable, higher-order components
  7. const withCampaigns = (WrappedComponent) !=> { return class extends React.Component

    { state = { campaigns: [] }; componentDidMount() { getCampaignsFromApi() .then(campaigns !=> this.setState({ campaigns })); } render() { return <WrappedComponent campaigns={campaigns} !/> } } }; const CampaignsList = ({ campaigns }) !=> ( <section> {campaigns.map(campaign !=> { <Campaign campaign={campaign} !/>; })} !</section> ); withCampaigns(CampaignsList);
  8. const mapStateToProps = (state) !=> { return state.campaigns; }; const

    mapDispatchToProps = { deleteCampaign, getCampaignStats, }; connect(mapStateToProps, mapDispatchToProps)(Campaigns);
  9. Automation Design Editor Side Panel Top Navigation Drag and Drop

    Module Editor Preview Settings Tab Build Tab Tags Tab Desktop Preview Mobile Preview Plain Text Preview
  10. Configuration in Context API Automations Index Page Automations Design Editor

    Automations Code Editor Design Editor Drag and Drop Modules Design Editor Preview HTML Editor Code Editor Preview
  11. “NETWORKS, CPUS, AND DISKS ALL HATE YOU. ON THE CLIENT,

    YOU PAY FOR WHAT YOU SEND IN WAYS YOU CAN'T EASILY SEE.” ALEX RUSSEL, GOOGLE
  12. export const Routes = ( <Fragment> <Route routeId="automations" path="/automations" component={Automations}!/>

    <Route routeId="campaigns" path="/campaigns" component={Campaigns}!/> <Route routeId="contacts" path="/contacts" component={Contacts}!/> <Route routeId="custom-fields" path="/custom-fields" component={CustomFields}!/> <Route routeId="marketing-templates" path="/marketing-templates" component={MarketingTemplates}!/> <Route routeId="notifications" path="/notifications" component={Notifications}!/> <Route routeId="overview" path="/overview" component={Overview}!/> <Route routeId="senders" path="/senders" component={Senders}!/> <Route routeId="templates" path="/templates" component={Templates}!/> <Route routeId="tour" path="/tour" component={Tour}!/> <Route routeId="welcome" path="/welcome" component={Welcome}!/> !</Fragment> );
  13. import Loadable from 'react-loadable'; import LoadingPage from '!../LoadingPage'; export default

    Loadable({ loader: () !=> import('./components/page'), loading: LoadingPage, });