Frontend application architecture, patterns, and workflows

33
Frontend Application Architecture, Patterns, and Workflows César Andreu @CesarAndreu

Transcript of Frontend application architecture, patterns, and workflows

Frontend Application Architecture, Patterns, and

Workflows

César Andreu@CesarAndreu

Treasure Data●~2 years●Full-stack engineer○Frontend○API

♥ ramen

Goals●Improve dev experience●Learn something new

ApplicationArchitectur

e

Future JavaScript●ES6, ES7●Write better JavaScript●Backwards compatible●Usable today =>

babeljs.io

Some ES6 features●Generators●Class syntax●Module system●Template strings

ES7: Async functionasync function getUserFileList (id) { var user = await User.get(id) var fileList = await s3.listObjects({ Bucket: user.bucket }) return fileList.Contents}

getUserFileList(1).then(list => { console.log('list', list)})

Builds●Transpilation●Debugging●Modules●Assets

Transpilationmodule: { loaders: [{ loader: 'babel', test: /\.(js|jsx)$/, exclude: /node_modules/ }]}

Debugging

Modules●ES6●CommonJS●AMD●globals

Assets

// Create <img>var logo = document.createElement('img')

// "/assets/0dcbbaa701328a3c262cfd45869e351f.png"logo.src = require('./logo.png')

Environments●development●production●staging●test

DefinePlugin

new webpack.DefinePlugin({ ENV: JSON.stringify(process.env.ENV)})

DefinePlugin example

// process.env.ENV = 'production'if (ENV === 'production') // true log('production message')if (ENV === 'development') // false log('development message')

// After minificationlog('production message')

ApplicationPatterns

Dependency Injection●Use higher-order

functions●No libraries needed●Easier to test

// No dependency injectionvar fetch = require('fetch')module.exports = function get (id) { return fetch('/resource/' + id) .then(function checkAuth (response) { if (response.status === 401) document.location.refresh() })}

// Dependency injectionmodule.exports = function getFactory (params) { var location = params.location var fetch = params.fetch return function get (id) { return fetch('/resource/' + id) .then(function checkAuth (response) { if (response.status === 401) location.refresh() }) }}

DI guidelines●Don't overdo it!●Static? Avoid DI●Dynamic? Consider DI

Immutability●Predictable●Transparent changes●Easier to understand

immutable.jsvar Immutable = require('immutable')var map1 = Immutable.Map({a:1, b:2, c:3})var map2 = map1.set('b', 50)map1.get('b') // 2map2.get('b') // 50

Flux

Action

Action

Dispatcher

Store View

Unidirectional data flow

ApplicationWorkflows

Node version manager●Both node.js and io.js●No magic

https://github.com/creationix/nvm

eslint●Catch errors early●ES6 with babel-eslint●Cross-platform●Great editor support

Webpack HMR●Hot module

replacement●react-hot-loader●style-loader

Contact

● César Andreu

● @CesarAndreu

● github.com/

cesarandreu

● cesar@treasure-

data.com

Fin.

Links● https://babeljs.io/● https://babeljs.io/docs/learn-es6/● https://github.com/lukehoban/ecmascript-asyncawait● http://webpack.github.io/● https://github.com/ryanseddon/source-map/wiki/● http://facebook.github.io/immutable-js/● https://github.com/creationix/nvm● http://eslint.org/● https://github.com/babel/babel-eslint● http://gaearon.github.io/react-hot-loader/● http://webpack.github.io/docs/hot-module-replacement-with-

webpack.html