HTML
CSS
JavaScript
Pages, not apps
Backbone
Mustache
jQuery
Sass / Less
Global CSS
Manual UI updates
No modules
No build process
ES6
Webpack
React
Redux
CSS Modules
console.log(square); // "undefined"?!?
for (var i = 0; i < 5; ++i) {
var square = i * i;
console.log(square);
}
console.log(square); // ReferenceError
for (let i = 0; i < 5; ++i) {
const square = i * i;
console.log(square);
square = 5; // TypeError
}
var a = 2;
console.log(a + ' fast ' + Math.sqrt(4) + ' furious');
const a = 2;
console.log(`${a} fast ${Math.sqrt(4)} furious`);
this
var self = this;
var foo = function() {
self.bar();
};
const foo = () => {
this.bar();
};
var add = function(a, b) {
return a + b;
};
const add = (a, b) => a + b; // lambda a, b: a + b
const add = (a, b) => {
return a + b;
};
var foo = require('foo.js');
module.exports = { bar: foo(5) };
import foo from 'foo.js';
export const bar = foo(5);
{
entry: './main.js',
output: {
filename: 'bundle.js'
}
}
Running Webpack
$ webpack
Loaders
loaders: [
{ test: /\.scss$/, loader: 'style!css!sass' }
]
output = style(css(sass(input)))
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new RemoveEmptyCSSRulesPlugin()
]
In the web rewrite, Webpack…
…on every file save, in under 2 seconds.
Replaces Mustache, jQuery, and most of Backbone
Open-sourced by Facebook in 2013
Used by Twitter, Dropbox, Netflix, Instagram, Asana...
<html>
<head>
<title>Example</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
var AppView = Backbone.View.extend({
el: $('#root'),
render: function() {
this.$el.html(this.template({ name: 'World' }));
return this;
},
template: require('app.tmpl')
});
new AppView().render();
app.tmpl
Hello {{ name }}!
const App = props => Hello {props.name}!
;
const mountNode = document.getElementById('root');
ReactDOM.render(<App name='World' />, mountNode);
App as state machine
Single source of truth
Update state by dispatching actions
Initializing the state machine
import { createStore } from 'redux';
const initialState = 0;
const reducer = (state, action) => state + action;
const store = createStore(reducer, initialState);
State transitioning
store.getState(); // Returns 0
store.dispatch(4);
store.dispatch(-1);
store.dispatch(2);
store.getState(); // Returns 5
Connecting components to a store
const Counter = props => (
<div>
<h2>{props.owner}'s Counter</h2>
<p>Current value is {props.currentValue}</p>
<button onClick={props.handleClick}>Add 1</button>
</div>
);
import { connect } from 'react-redux';
const CounterContainer = connect(
state => ({ currentValue: state }),
dispatch => ({ handleClick: () => dispatch(1) })
)(Counter);
<CounterContainer owner='Art' />
.home-page .sidebar button { color: red }
button { color: red }
#mutton { color: yellow }
button.glutton { color: green }
.glutton { color: blue }
<button id="mutton" class="glutton">Click me</button>
<button class="btn btn-blue btn-solid">Click me</button>
Only use single class names as CSS rule selectors
.HomePage--practice-button { ... }
.SkillPage--test-out-button { ... }
.SkillPage--practice-button { ... }
.SessionPage--next-button { ... }
.button--solid { ... }
.button--medium { ... }
Automatic class list generation
<button class="HomePage--practice-button button--solid
button--medium button--blue">Practice</button>
.practice {
composes: solid from 'button.css';
width: 100%;
}
.HomePage--practice { width: 100% }
import styles from 'HomePage.css';
// { practice: 'HomePage--practice button--solid' }
const HomePage = props => (
<button className={styles.practice}>Practice</button>
);