React @ Namics

2017 / 2018

React @ Namics

2017 / 2018

About Namics

About Namics

500 People in total
 

53 Frontend Engineers

~ 16 React Developer
 

Locations in St. Gallen, Zurich, Frankfurt, Munich, Hamburg and Belgrade

Projects

Backend

Architecture

Code Quality

Frontend UI

Performance

 

Projects

Projects

Sunrise.ch
 

Pathe.ch
 

Migros Impuls Coach
 

...many other smaller Projects

Homepage CMS only → SEO

React Widgets

Homepage React & CMS

React only

React only

Backend

Backend

Bootstrap Apps

 

Backend Data

 

i18n

 

 


  // index.html

  <div class="js-react" data-appName="quickBuyWidget" data-productId="64031">

  // bootstrap.js

  const $apps = $("body").find(".js-react");

  $apps.each(function(index, app) {
    let htmlNode = app;
    const $app = $(app);
    const pageData = $app.data();
    const appName = $app.data("appName");
    const $mountNode = $app.find(".js-react-mount");

    $script(`/${appName}.js`, function() {
      $(document).trigger("bootstrap-react-app", {
        htmlNode, appName, pageData, store, history
      });
    });
  });

Bootstrap Apps 1/2

Bootstrap Apps 2/2


  // quickbuyApp.js

  $(document).on("bootstrap-react-app", function(event, data) {
    if (data.appName !== "quickBuyWidget") return this;
    ReactDOM.render(
      <RootRedux store={data.store}>
        <QuickBuyWidget
          productId={data.pageData.productId}
        />
      </RootRedux>,
      data.htmlNode
    );
  });

Backend Data


  // appConfig.js

  window.ReactApp = window.ReactApp || {};

  ReactApp.Env = ReactApp.Env || {};
  ReactApp.Env.urlMagnolia = "https://pathe-ch.namics-test.com";
  ReactApp.Env.urlSolr = "https://pathe-ch.namics-test.com/solr";

  ReactApp.Sites = {
    PLA: {
      label: "Plaza",
      wheelChairAreaCode: "0000000005",
      preferredComplexID: "1011"
    },
    KUC: {
      label: "Küchlin",
      wheelChairAreaCode: "0000000006",
      preferredComplexID: "1010"
    }
  }

i18n


  // appConfig.js

  window.ReactApp = window.ReactApp || {};

  ReactApp.I18n = ReactApp.I18n || {};
  ReactApp.I18n = {
    'react.impulsCoach.molecules.Record.title': "Your new record is {recordValue}kg"
  }

  // Record.jsx

  <Link
    href={routes.dashboard.newMeasurement.href}
    title={i18n('react.impulsCoach.molecules.Record.title', { recordValue, '60' })}
    modifier="button"
  />

Architecture

Architecture

Create React App

 

Fork React Scripts

 

Containers

 

Models

Create React App

Fork React Scripts

Containers

Models

Code Quality

Code Quality

Flow / TypeScript

 

Prettier

 

Tests

 

Continous Integration

Flow / TypeScript

Prettier

Tests

Continous Integration

  • Git Hooks
     

  • npm / yarn

  • Scripts
     

  • .nvmrc

Frontend UI

Frontend UI

Atomic Design

 

Frontend UI JavaScript API

Performance

Performance

Code Splitting using Dynamic Imports

 

Recompose: OnlyUpdateForKeys

 

Sourcemap Explorer

Dynamic Imports


  // Counter.jsx

  import React from 'react';
  import { onlyUpdateForKeys } from 'recompose';

  export type CounterProps = {
    count?: string | number,
    modifier?: string,
  };

  const Counter = ({ count, modifier }: CounterProps): any => {
    return (
      <div className={`a-counter${modifier ? ' a-counter--' + modifier : ''}`}>
        <span className="a-counter__number">{count}</span>
      </div>
    );
  };

  const shallowUpdate = onlyUpdateForKeys(['count']);

  export { Counter };
  export default shallowUpdate(Counter);

Only Update For Keys

Sourcemap Explorer

That's it

That's it

namics.com/jobs 😉