frontend application architecture, patterns, and workflows

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

Upload: treasure-data-inc

Post on 22-Jul-2015

668 views

Category:

Engineering


1 download

TRANSCRIPT

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

●  [email protected]

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