Desenvolvendo 

uma App multiplataforma
compartilhando 90% do código
GUILHERME HEYNEMANN BRUZZI | FRONT<IN>BH 2017
Guilherme
Heynemann
Bruzzi
+ 2000 lojas
97%Do comércio
no Brasil
97%
OmnichannelOmnichannelOmnichannel
PROBLEMAS + EQUIPE FRONTEND -> STACK
Construção
inStore
1. App nativa
2. Xamarin
3. Apps Híbridas
4. PWA
5. React Native ou Framework Expo
6. React XP
Possíveis escolhas
. Objetive-C / Swift para iOS
. Java para Android
. .NET para Windows
. Performance otimizada
. 3 códigos para as mesmas regras de negócio
Apps Nativas
. C# com Mono .NET framework e IDE própria
. Compilado para interagir com o Java e Obj-C
. Reaproveitamento de código
Xamarin
Apps Híbridas
. Cordova / Phonegap / Ionic
. Reaproveitamento de código
. Problemas da webview
. Cross-browser
PWA
. Renderização no browser
. Pouco espaço no aparelho
. Ausência nas lojas de apps
. APIs mais modernas do browser é o
importante
. Suporta boa parte das APIs nativas
. Para exceções é necessário ejetar para o nativo
. React Native Windows (suporte apenas ao 10)
Expo
. Suporte ao Windows é fraco ainda (WIP para
Windows 10)
. O ReactXP recomenda usar a sua versão web 

com electron para usar no Windows 7 e 8
React XP
Nativo + Web
Casca de
Apps
Arquitetura

Final
SPA
Electron
React Native
. Componentização por padrão
. Comunidade ativa e open source
. VTEX IO
Extensível
Customizável
React
React

Native
Electron
IdentificaçãoCarrinhoSeleção de PagamentosComunicação com servidoresConexão com a CapptaPagamentoConfirmação
1. RN Webview Bridge
2. Electron IPC
3. Tachyons
4. Eslint + Prettier
Outras escolhas
5. Flow
6. Jest
7. Redux + Redux Logic + Redux persist
8. PR + Continuous deployment
RN 

Webview
Bridge
const injectScript = `
WebViewBridge.onMessage = function (message) {
console.log('Received from react native', message);
};
WebViewBridge.send('hello from webview');
`;
class App extends React.Component {
onBridgeMessage(message) {
const { webviewbridge } = this.refs;
console.log('Received from webview', message);
webviewbridge.sendToBridge('hello from react-native');
}
render() {
return (
<WebViewBridge
ref="webviewbridge"
onBridgeMessage={this.onBridgeMessage.bind(this)}
injectedJavaScript={injectScript}
source={{uri: 'http://google.com'}}/>
);
}
}
github.com/vtex/react-native-webview-bridge
Electron
IPC
// main.js (node)
const ipcMain = require('electron').ipcMain
ipcMain.on('webview-event', function(event, data) {
console.log(data)
mainWindow.send('webview-event', { 'msg': 'hello from node' })
})
// renderer.js (browser)
const ipcRenderer = require('electron').ipcRenderer
ipcRenderer.on('webview-event', function(event, data) {
console.log(data)
})
ipcRenderer.send('webview-event', { 'msg': 'hello from chromium' })
Tachyons <div className=“flex flex-auto mv3 pa3"></div>
. CSS funcional
. 14KB
. Evita quebras 

de outros layouts
Eslint +
Prettier
Flow
// @flow
const foo = (b: boolean): string => (
(b) ? 'Hello' : 'World'
)
const bar: string = foo()
PR +

Continuous

Deployment
Jest
import Component from '../src/'
describe('Component', () => {
let node
beforeEach(() => {
node = document.createElement('div')
})
afterEach(() => {
unmountComponentAtNode(node)
})
it('displays a welcome message', () => {
render(<Component />, node, () => {
expect(node.innerHTML).toContain('Carregando...')
expect(node.innerHTML).toContain('inject')
})
})
})
Redux +
Redux Logic +
Redux persist
export default function createAppStore(initialValue = {}) {
const logicMiddleware = createLogicMiddleware(logic)
const middleware = [logicMiddleware]
let composeEnhancers = compose
if (process.env.NODE_ENV === 'development') {
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__()
: compose
}
const store = createStore(
reducer,
initialValue,
composeEnhancers(applyMiddleware(...middleware), autoRehydrate())
)
createPersistor(store)
return store
}
engineering.vtex.com
design.vtex.com
Sorteio de
smartwatch
no stand da
VTEX!
@guilhermebruzz
i
Muito obrigado! 😅

Desenvolvendo uma App multiplataforma compartilhando 90% do código

  • 1.
    Desenvolvendo 
 uma Appmultiplataforma compartilhando 90% do código GUILHERME HEYNEMANN BRUZZI | FRONT<IN>BH 2017
  • 2.
  • 4.
  • 5.
  • 6.
    PROBLEMAS + EQUIPEFRONTEND -> STACK Construção
  • 7.
  • 8.
    1. App nativa 2.Xamarin 3. Apps Híbridas 4. PWA 5. React Native ou Framework Expo 6. React XP Possíveis escolhas
  • 9.
    . Objetive-C /Swift para iOS . Java para Android . .NET para Windows . Performance otimizada . 3 códigos para as mesmas regras de negócio Apps Nativas
  • 10.
    . C# comMono .NET framework e IDE própria . Compilado para interagir com o Java e Obj-C . Reaproveitamento de código Xamarin
  • 11.
    Apps Híbridas . Cordova/ Phonegap / Ionic . Reaproveitamento de código . Problemas da webview . Cross-browser
  • 12.
    PWA . Renderização nobrowser . Pouco espaço no aparelho . Ausência nas lojas de apps . APIs mais modernas do browser é o importante
  • 13.
    . Suporta boaparte das APIs nativas . Para exceções é necessário ejetar para o nativo . React Native Windows (suporte apenas ao 10) Expo
  • 14.
    . Suporte aoWindows é fraco ainda (WIP para Windows 10) . O ReactXP recomenda usar a sua versão web 
 com electron para usar no Windows 7 e 8 React XP
  • 15.
  • 16.
  • 17.
    . Componentização porpadrão . Comunidade ativa e open source . VTEX IO Extensível Customizável React
  • 18.
  • 19.
  • 20.
    IdentificaçãoCarrinhoSeleção de PagamentosComunicaçãocom servidoresConexão com a CapptaPagamentoConfirmação
  • 21.
    1. RN WebviewBridge 2. Electron IPC 3. Tachyons 4. Eslint + Prettier Outras escolhas 5. Flow 6. Jest 7. Redux + Redux Logic + Redux persist 8. PR + Continuous deployment
  • 22.
    RN 
 Webview Bridge const injectScript= ` WebViewBridge.onMessage = function (message) { console.log('Received from react native', message); }; WebViewBridge.send('hello from webview'); `; class App extends React.Component { onBridgeMessage(message) { const { webviewbridge } = this.refs; console.log('Received from webview', message); webviewbridge.sendToBridge('hello from react-native'); } render() { return ( <WebViewBridge ref="webviewbridge" onBridgeMessage={this.onBridgeMessage.bind(this)} injectedJavaScript={injectScript} source={{uri: 'http://google.com'}}/> ); } } github.com/vtex/react-native-webview-bridge
  • 23.
    Electron IPC // main.js (node) constipcMain = require('electron').ipcMain ipcMain.on('webview-event', function(event, data) { console.log(data) mainWindow.send('webview-event', { 'msg': 'hello from node' }) }) // renderer.js (browser) const ipcRenderer = require('electron').ipcRenderer ipcRenderer.on('webview-event', function(event, data) { console.log(data) }) ipcRenderer.send('webview-event', { 'msg': 'hello from chromium' })
  • 24.
    Tachyons <div className=“flexflex-auto mv3 pa3"></div> . CSS funcional . 14KB . Evita quebras 
 de outros layouts
  • 25.
  • 26.
    Flow // @flow const foo= (b: boolean): string => ( (b) ? 'Hello' : 'World' ) const bar: string = foo()
  • 27.
  • 28.
    Jest import Component from'../src/' describe('Component', () => { let node beforeEach(() => { node = document.createElement('div') }) afterEach(() => { unmountComponentAtNode(node) }) it('displays a welcome message', () => { render(<Component />, node, () => { expect(node.innerHTML).toContain('Carregando...') expect(node.innerHTML).toContain('inject') }) }) })
  • 29.
    Redux + Redux Logic+ Redux persist export default function createAppStore(initialValue = {}) { const logicMiddleware = createLogicMiddleware(logic) const middleware = [logicMiddleware] let composeEnhancers = compose if (process.env.NODE_ENV === 'development') { composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__() : compose } const store = createStore( reducer, initialValue, composeEnhancers(applyMiddleware(...middleware), autoRehydrate()) ) createPersistor(store) return store }
  • 32.
  • 33.
  • 34.
  • 35.