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
Application
Architecture
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 function
async 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
Transpilation
module: {
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 minification
log('production message')
Application
Patterns
Dependency Injection
● Use higher-order functions
● No libraries needed
● Easier to test
// No dependency injection
var fetch = require('fetch')
module.exports = function get (id) {
return fetch('/resource/' + id)
.then(function checkAuth (response) {
if (response.status === 401)
document.location.refresh()
})
}
// Dependency injection
module.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.js
var Immutable = require('immutable')
var map1 = Immutable.Map({a:1, b:2, c:3})
var map2 = map1.set('b', 50)
map1.get('b') // 2
map2.get('b') // 50
Flux
Action
Action
Dispatcher Store View
Unidirectional data flow
Application
Workflows
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

Frontend application architecture, patterns, and workflows