React @ Namics
2017 / 2018
React @ Namics
2017 / 2018
Projects
Projects
Sunrise.ch
Pathe.ch
Migros Impuls Coach
& many other smaller React Projects
Homepage CMS only → SEO
React Widgets
Homepage React & CMS
One React App
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
Create React App
Fork React Scripts
Fork React Scripts
Code Quality
Code Quality
Flow
Prettier
Tests
Flow
Flow
Prettier
Tests
Frontend UI
Frontend UI
Separate Repository
Frontend UI JavaScript API
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 😉
HSR — React @ Namics
By Dominic Modalek
HSR — React @ Namics
Slides for my Talk at the HSR Frontend Best Practices Conference 2018.
- 445