SlideShare a Scribd company logo
FROM HACKER 

TO PROGRAMMER
Developing with Webpack,Babel, and React
@josephj6802
1 Oct 2015
Hacker? Probably Worse…
Inefficient or dirty works
Sadly especially for front-end code
Tag Soup in JS
if (inlineTileOptions['show_sharing'] === "1") {
// Inline Sharing Buttons
var tileSharing = $('<div class="tile-sharing"><a class="tile-sharing-expand js-expand-tile-
sharing stackla-icon-share" onclick="Widget.expandInlineSharingTool(th
var tileShareButtons = $('<ul class="tile-sharing-expanded"></ul>');
tileSharing.append(tileShareButtons);
item.append(tileSharing);
!
var shareText = t['share_text'] ? t['share_text'].replace(/["']/g, '$&') : '';
!
if (t['source'] != 'facebook') {
tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button
facebook" title="Share via Facebook" onclick="Widget.facebookShare(th
}
!
tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button
twitter" title="Share via Twitter" onclick="Widget.twitterShare(this)"><d
!
if (t['image']) {
tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button
pinterest" title="Share via Pinterest" onclick="Widget.pinterestShare
}
!
tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button gplus"
title="Share" onclick="Widget.googleShare(this)"><div class="share
!
tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button email"
title="Email a friend" onclick="Widget.emailShare(this)"><div clas
!
!
}
Difficult to read and maintain
Tag Soup in View
Difficult to read and maintain
CSS/JS Tags
Impossible to remove no longer used scripts
No Dependency
Environments
Too many environments
Feature Detection
Browser Support
Hacks
Responsive
Copy Paste
fluid.js fluid-horizontal.js
base_waterfall.js base_carousel.js
auto.js main.js carousel.js slideshow.js
base_billboard.js base_feed.js base_slideshow.js
80% duplicated code (~1500 lines) * 11
Widget Code
Once we start, it’s difficult to refactor
Prototype-based Class
Everyone has their own implementation
Stackla.createClass();
Widget = (function () {})();
function StacklaWidgetNode() {}
Global Variables
Global variables and function names are an incredibly
bad idea. The reason is that every JavaScript file
included in the page runs in the same scope. If you
have global variables or functions in your code, scripts
included after yours that contain the same variable and
function names will overwrite your variables/functions.
Stoyan Stefanov
The few man-hours spent writing the code initially
end up in man-weeks spent reading it.
Getting Worse
Eliminate the hacking
As a developer, we always seek for good
methodologies, patterns, or better technologies to
make our code to be maintained easier.
“A bug could be fixed within 10 mins by a newbie,
but a good developer is willing spend 4 hours to
make it better.”
Happy Developer!
when using right tools & code become less messy
Universal loader for all static assets
Ability to write next-generation JS
Lead and change the world of
front-end app development
Foundation
Accelerator
App
New Web Development Stacks
Universal Loader
Foundation
JS Module Before Webpack
AMD
<script/>
Make use of global variables
Ease of define dependencies
No dependencies
Load modules asynchronously
No compile needed by default
Ease of define dependencies
Always need to compile
Synchronous loading by a single file
(via global)
define(['./a', './b'], function (a, b) {!
});
var Acl = require('js/acl/acl.js');
Package Management
CSS Preproccessors
JS Module Loaders
JS Transpiler
Build Tools
https://www.flickr.com/photos/juhansonin/3141561416/
You’ll need…
Not fun… A lot of plug-ins and some hacks..
Package Management
CSS Preproccessors
JS Module Loaders
JS Transpiler
Build Tools
less-loader sass-loader
coffee-loader ts-loader
Support
ALL JS STATIC 

Modules
Webpack
Dev Server
// app/media/js/admin/terms/term-manage.jsx!
!
'use strict';!
!
var React = require('react'),!
$ = require('jquery'),!
LogMixin = require('common/log-mixin'),!
TermPanel = require('./term-panel'),!
TermList = require('./term-list'),!
History = require('exports?window.History!history.js/native.history'),!
queryString = require('query-string'),!
Cookies = require('js-cookie');!
!
module.exports = {!
// ...!
};
Define Dependencies
app/vendor/webpack/node_modules/
app/media/js/
app/media/components/
var History = require('exports?window.History!history.js/native.history');!
!
History.Adapter.bind(window, 'statechange', that.handleHistoryChange);
Global Module
require('history.js/native.history');!
!
window.History.Adapter.bind(window, 'statechange', that.handleHistoryChange);
Not Good
Better
exports?window.History!history.js/native.history
loader loader options (query) separator module path
JS Transpilers
var Tagla = require('coffee!./tagla.coffee');
var Stepper = require('ts!./stepper.js');
CSS Preprocessors
require('!style!css!sass!admin/acl/acl.scss');
require('!style!css!less!bootstrap/nav.less');
CSS Preprocessors
Wait! Are you writing CSS in JS?
require('!style!css!sass!admin/acl/acl.scss');
app/media/js/admin/acl/acl.js
• The stylesheet will be injected into HTML with <style> tag
• The images inside will be converted to Data URIs.
Define dependencies between JS and CSS
Code Splitting
fluid-embed.js

(required) when layout = portrait or landscape
Load extra assets conditionally
lightbox.js

(optional)
Dev Server
Incremental build instead of full build
• Module Loader / Dependencies
• Ability to load all kinds of assets
• High performance
• Often replaces grunt or gulp
Using the future of JS, Today!
Accelerator
Package Management
CSS Preproccessors
JS Module Loaders
JS Transpiler
Build Tools
sass-loader
coffee-loader ts-loader
Support
ALL
Modules
Webpack
Dev Server
babel-loader
less-loader
Why Babel?
All transpilers are trying to *fix* JavaScript language
These transpilers have obvious influence on the ES6/ES2015 standard.
However browser support is not ready yet
Why Babel?
Babel is another transpiler which let you to use latest JS
Babel keeps sync with ECMAScript
Ability to customise the stage or options you want use.
var: Function-scoped
Let & Const
function f() {!
var obj = {a: 1, b: 2, c: 3}; !
for (var i in obj) {!
// okay!
console.log(i); !
} !
// okay !
console.log(i);!
}!
f();
let: Block-scoped
function f() {!
var obj = {a: 1, b: 2, c: 3}; !
for (let i in obj) {!
// okay!
console.log(i); !
} !
// error - i is undefined !
console.log(i);!
}!
f();
const: Block-scoped
function a() {!
const DURATION = 100;!
{!
// output 100!
console.log(DURATION);!
}!
}!
!
function b() {!
const DURATION = 100;!
{!
// error "DURATION" is read-only!
DURATION = 200;!
} !
}!
!
function c() {!
const DURATION = 100;!
{!
// ok !
const DURATION = 200;!
console.log(DURATION); // output 200!
} !
}!
Single-assigment
`Template String`
// This is what I prefer to do!
var list = ['<ul>',!
' <li>Buy Milk</li>',!
' <li>Be kind to Pandas</li>',!
' <li>Forget about Dre</li>',!
'</ul>'].join('');
ES5
// This doesn't work!
var list = '<ul>!
<li>Buy Milk</li>!
<li>Be kind to Pandas</li>!
<li>Forget about Dre</li>!
</ul>';!
// This does, but urgh… !
var list = '<ul>!
<li>Buy Milk</li>!
<li>Be kind to Pandas</li>!
<li>Forget about Dre</li>!
</ul>';
// This is the most common way, and urgh, too…!
var list = '<ul>' +!
' <li>Buy Milk</li>' +!
' <li>Be kind to Pandas</li>' +!
' <li>Forget about Dre</li>' +!
'</ul>';
ES6
// This works!!
var list = `<ul>!
<li>Buy Milk</li>!
<li>Be kind to Pandas</li>!
<li>Forget about Dre</li>!
</ul>`;!
http://christianheilmann.com/2015/08/28/es6-for-now-template-strings/
`Template String`
ES5 - String + Variables
var avatar = '<div class="avatar">' +!
' <a href="' + avatarLink + '" target="_blank" class="avatar-profile">' +!
' <div class="avatar-place-holder">' +!
' <img src="/media/images/avatar-mask.png" alt="' + avatarAltText + '" />' +!
' </div>' +!
' <img src="' + getAvatarUrl(t.avatar, t.source) + '" alt="' + avatarAltText + '" />' +!
' </a>' +!
'</div>';
var avatar = `<div class="avatar">!
<a href="${avatarLink}" target="_blank" class="avatar-profile">!
<div class="avatar-place-holder">!
<img src="/media/images/avatar-mask.png" alt="${avatarAltText}" />!
</div>!
<img src="${getAvatarUrl(t.avatar, t.source)}" alt="${avatarAltText}" />!
</a>!
</div>`;
ES6 - String + Variables
The ${} construct can take any JS expression that returns a value
class Widget extends Stackla.Base {!
constructor(options) {!
super(options);!
!
this.domain = options.domain || null;!
this.list_url = `/widget/api/${this.guid}!
?filter_id=${this.filter_id}!
&domain=${this.domain}!
&page=1!
&ttl=1`; !
}!
render(el) {!
super.render();!
}!
static getInstances() {!
// ...!
}!
}
Classes
ES6 - Single convenient declarative form
Module
https://babeljs.io/docs/learn-es2015/#modules
Arrow
https://babeljs.io/docs/learn-es2015/#arrows-and-lexical-this
Summary
• Unlike CoffeeScript, it’s something you must
learn and use in the future.
• Just like PHP4 v.s. PHP5
• Makes my code more legible (ex. class)
• develop much faster (ex. less vague, type safety)
App
Build UI & APPs
Why so Popular?
Google Trend
http://reactkungfu.com/2015/07/big-names-using-react-js/
Big Brands using React.js
• Rethink best practices
• JSX - Template in JavaScript?
• CSS in JS - Inline style in JavaScript?
• Easy to learn
• Embracing Functional Programming
• One-way data flow model
• Impacting different areas
• ImmutableJS, GraphQL
Why so Popular?
Package Management
CSS Preproccessors
JS Module Loaders
JS Transpiler
Build Tools
sass-loader
Support
ALL
Modules
Webpack
Dev Server
babel-loader
less-loader
built-in support for React JSX
Abstraction
<button class="st-btn !
st-btn-danger !
st-btn-solid !
st-btn-md”>!
Delete!
</button>
<Button kind="danger" !
size="medium" !
solid>Delete</Button>
Button
New Way
Using Class Names
Using React.js
Old Way
Legible & Less Guessing
f
<Button kind="danger" size="large" solid>Delete</Button>
button.jsx
exports default class Button extends React.Component {!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
};
this.props.sizethis.props.kind this.props.solid this.props.children
Load CSS
Just CSS class name manipulation
render() is the only required method in React component
import React from 'react';!
import cx from 'classnames';!
import 'stackla-uikit/scss/_button';
render() {!
let that = this,!
props = that.props,!
className,!
node;!
!
className = cx('st-btn',`st-btn-${kind}`, {!
'st-btn-disabled': props.disabled,!
'st-btn-solid': props.solid,!
'st-btn-md': (props.size === 'medium'),!
'st-btn-sm': (props.size === 'small'),!
'st-active': props.active,!
}, props.className);!
!
return <button {...props} className={className}>{props.children}</button>!
}
The calculated class names
Properties
f
State
import React from 'react';!
import Button from './button';!
const data = [!
{text: 'Danger', kind: 'danger', size: 'large', solid: false, active: true},!
{text: 'Success', kind: 'success', size: 'medium', disabled: true, solid: true},!
{text: 'Info', kind: 'info', disabled: true, solid: true},!
{text: 'Default', kind: 'default', size: 'large', disabled: true, active: false}!
];!
exports default class App extends React.Component {!
constructor() {!
this.offset = 0;!
}!
componentDidMount() {!
setInterval(() => {!
this.offset = (data.length >= this.offset + 1) ? 0 : this.offset + 1;!
this.setState(data[this.offset]);!
}, 500);!
}!
render() {!
let state = this.state;!
return !
<Button !
kind={state.kind} !
size={state.size} !
solid={state.solid} !
active={state.active}>!
{state.text}!
</Button>;!
}!
};
app.jsx
React.render(<App>, document.getElementById('app'));
Mockup Data
Whenever the state changes, the render() will be invoked
For Button component,
whenever my property changes,
the Button#render() will be invoked
<StyleChooser/>
<StylePreview/>
<Breadcrumbs/>
<Panel/>
<WidgetsNew/>
<Button/>
<Button/>
Only outmost component is stateful
Others are stateless,
only accept properties
<StyleChooser/>
<StylePreview/>
<Breadcrumbs/>
<Panel/>
<WidgetsNew/>
<Button/>
<Button/>
Only outmost component is stateful
Others are stateless,
only accept properties
WidgetsNew
StyleChooser StylePreview
widgetTypes selectedWidget
render()
render() render()
<StyleChooser widgetTypes= />widgetTypes <StyleChooser selectedWidget= />selectedWidget
Top-down Rendering
JSX diffs and apply changes to DOM
UI = f(state)
Update UI by changing state object
Philosophy
Sebastian Markbåge
DOM as a Second-class Citizen
https://www.youtube.com/watch?v=Zemce4Y1Y-A
A Tool to Build Our Toolbox
Only ourselves knows what we
want, picking up technologies for
right abstraction is crucial.
No single library can fulfil our
need.
Can we build an app without a
single DOM element?
Abstraction for Different Targets
• React.js in Browser
• JSX ➡ DOM
• react-canvas in Browser
• JSX ➡ Canvas
• react-isomorphics in Server
• JSX ➡ HTML
• react-native in iOS
• JSX ➡ UIKit
• react-native in Android
• JSX ➡ android.view
Ambitious Abstraction
In Browser, React/JSX
relies on slow DOM API.
Goal
Ask WebGL/GPU to use
React directly
Now
➡
➡
➡
➡
➡
Getting Better & Mature
➡
➡
➡
➡
➡
➡
➡
➡
Getting Better & Mature
➡
➡
➡
Will these tools go out of fashion
in the following 18 months? POSSIBLY!
However, everything is becoming 

more mature and future-compatible
We developers just need to
choose right tools to do improvements
Feel blessed with
I feel much more solid to write UI now.
Not a hacker but a programmer!
Cheers!

More Related Content

PDF
Packing it all: JavaScript module bundling from 2000 to now
PPTX
Backbone.js
PDF
Vue 淺談前端建置工具
PDF
Red Hat and Oracle: Delivering on the Promise of Interoperability in Java EE 7
PPTX
Testing frontends with nightwatch & saucelabs
PDF
The JavaFX Ecosystem
PDF
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
PDF
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Packing it all: JavaScript module bundling from 2000 to now
Backbone.js
Vue 淺談前端建置工具
Red Hat and Oracle: Delivering on the Promise of Interoperability in Java EE 7
Testing frontends with nightwatch & saucelabs
The JavaFX Ecosystem
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...

What's hot (20)

PPTX
A few good JavaScript development tools
PDF
The Peanut Butter Cup of Web-dev: Plack and single page web apps
PDF
Using VueJS in front of Drupal 8
PDF
Building a Startup Stack with AngularJS
PDF
The JavaFX Ecosystem
PDF
An introduction to Vue.js
PDF
20160905 - BrisJS - nightwatch testing
PDF
Thomas Fuchs Presentation
PPTX
Javascript Bundling and modularization
PDF
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Angular Summit 2015
PPTX
Webpack Introduction
PDF
Laravel 8 export data as excel file with example
PDF
Django Rest Framework and React and Redux, Oh My!
PPT
Vue.js Getting Started
PDF
Module, AMD, RequireJS
PDF
Роман Лютиков "Web Apps Performance & JavaScript Compilers"
PDF
JavaOne - The JavaFX Community and Ecosystem
PDF
Vue.js is boring - and that's a good thing
ODP
An Introduction to Vuejs
PDF
VueJS Introduction
A few good JavaScript development tools
The Peanut Butter Cup of Web-dev: Plack and single page web apps
Using VueJS in front of Drupal 8
Building a Startup Stack with AngularJS
The JavaFX Ecosystem
An introduction to Vue.js
20160905 - BrisJS - nightwatch testing
Thomas Fuchs Presentation
Javascript Bundling and modularization
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Angular Summit 2015
Webpack Introduction
Laravel 8 export data as excel file with example
Django Rest Framework and React and Redux, Oh My!
Vue.js Getting Started
Module, AMD, RequireJS
Роман Лютиков "Web Apps Performance & JavaScript Compilers"
JavaOne - The JavaFX Community and Ecosystem
Vue.js is boring - and that's a good thing
An Introduction to Vuejs
VueJS Introduction

Similar to From Hacker to Programmer (w/ Webpack, Babel and React) (20)

PDF
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
PDF
PDF
Solid and Sustainable Development in Scala
PDF
Solid And Sustainable Development in Scala
PDF
Symfony Live 2018 - Développez votre frontend avec ReactJS et Symfony Webpack...
PDF
Wordless, stop writing WordPress themes like it's 1998
KEY
Angels versus demons: balancing shiny and inclusive
PDF
BP-6 Repository Customization Best Practices
PPT
Build Your Own CMS with Apache Sling
PDF
Modern Front-End Development
KEY
Taking your Web App for a walk
PDF
Web Development for UX Designers
PPT
Building Web Hack Interfaces
PDF
Html5 and beyond the next generation of mobile web applications - Touch Tou...
PPTX
SharePoint Saturday NYC - SharePoint and jQuery, what I wish I would have kno...
PDF
Using Ember to Make a Bazillion Dollars
PPTX
SharePoint Saturday St. Louis - SharePoint & jQuery
PPTX
Spsemea j query
PDF
Echo HTML5
PDF
Reactive Type safe Webcomponents with skateJS
TDC2017 | Florianopolis - Trilha DevOps How we figured out we had a SRE team ...
Solid and Sustainable Development in Scala
Solid And Sustainable Development in Scala
Symfony Live 2018 - Développez votre frontend avec ReactJS et Symfony Webpack...
Wordless, stop writing WordPress themes like it's 1998
Angels versus demons: balancing shiny and inclusive
BP-6 Repository Customization Best Practices
Build Your Own CMS with Apache Sling
Modern Front-End Development
Taking your Web App for a walk
Web Development for UX Designers
Building Web Hack Interfaces
Html5 and beyond the next generation of mobile web applications - Touch Tou...
SharePoint Saturday NYC - SharePoint and jQuery, what I wish I would have kno...
Using Ember to Make a Bazillion Dollars
SharePoint Saturday St. Louis - SharePoint & jQuery
Spsemea j query
Echo HTML5
Reactive Type safe Webcomponents with skateJS

More from Joseph Chiang (20)

PDF
不断归零的前端人生 - 2016 中国软件开发者大会
PDF
Let's Redux!
PDF
Automatic Functional Testing with Selenium and SauceLabs
PDF
JavaScript Promise
PDF
F2E for Enterprise
PDF
JavaScript Code Quality
PDF
F2E, the Keystone
PDF
前端的未來 - 前端工程實務訓練
PDF
Performance 入門 - 前端工程開發實務訓練
PDF
Debugging - 前端工程開發實務訓練
PDF
Javascript 入門 - 前端工程開發實務訓練
PDF
Node.js 入門 - 前端工程開發實務訓練
PDF
前端工程開發實務訓練
PDF
YUI 教學 - 前端工程開發實務訓練
PDF
CSS 入門 - 前端工程開發實務訓練
PDF
HTML 入門 - 前端工程開發實務訓練
PDF
模块加载策略 - 2012 SDCC, 北京
PDF
YUI is Sexy (for JSDC.tw)
PDF
YUI is Sexy - 使用 YUI 作為開發基礎
KEY
Git - The Social Coding System
不断归零的前端人生 - 2016 中国软件开发者大会
Let's Redux!
Automatic Functional Testing with Selenium and SauceLabs
JavaScript Promise
F2E for Enterprise
JavaScript Code Quality
F2E, the Keystone
前端的未來 - 前端工程實務訓練
Performance 入門 - 前端工程開發實務訓練
Debugging - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練
前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練
模块加载策略 - 2012 SDCC, 北京
YUI is Sexy (for JSDC.tw)
YUI is Sexy - 使用 YUI 作為開發基礎
Git - The Social Coding System

Recently uploaded (20)

PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Approach and Philosophy of On baking technology
PDF
Empathic Computing: Creating Shared Understanding
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
A Presentation on Artificial Intelligence
PDF
Encapsulation theory and applications.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Chapter 3 Spatial Domain Image Processing.pdf
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Approach and Philosophy of On baking technology
Empathic Computing: Creating Shared Understanding
Dropbox Q2 2025 Financial Results & Investor Presentation
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Spectral efficient network and resource selection model in 5G networks
A Presentation on Artificial Intelligence
Encapsulation theory and applications.pdf
The AUB Centre for AI in Media Proposal.docx
Diabetes mellitus diagnosis method based random forest with bat algorithm
The Rise and Fall of 3GPP – Time for a Sabbatical?
Network Security Unit 5.pdf for BCA BBA.
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Unlocking AI with Model Context Protocol (MCP)
NewMind AI Monthly Chronicles - July 2025
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...

From Hacker to Programmer (w/ Webpack, Babel and React)

  • 1. FROM HACKER 
 TO PROGRAMMER Developing with Webpack,Babel, and React @josephj6802 1 Oct 2015
  • 2. Hacker? Probably Worse… Inefficient or dirty works Sadly especially for front-end code
  • 3. Tag Soup in JS if (inlineTileOptions['show_sharing'] === "1") { // Inline Sharing Buttons var tileSharing = $('<div class="tile-sharing"><a class="tile-sharing-expand js-expand-tile- sharing stackla-icon-share" onclick="Widget.expandInlineSharingTool(th var tileShareButtons = $('<ul class="tile-sharing-expanded"></ul>'); tileSharing.append(tileShareButtons); item.append(tileSharing); ! var shareText = t['share_text'] ? t['share_text'].replace(/["']/g, '$&') : ''; ! if (t['source'] != 'facebook') { tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button facebook" title="Share via Facebook" onclick="Widget.facebookShare(th } ! tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button twitter" title="Share via Twitter" onclick="Widget.twitterShare(this)"><d ! if (t['image']) { tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button pinterest" title="Share via Pinterest" onclick="Widget.pinterestShare } ! tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button gplus" title="Share" onclick="Widget.googleShare(this)"><div class="share ! tileShareButtons.append('<li><a data-tile-id="' + t['_id'] + '" class="tile-share-button email" title="Email a friend" onclick="Widget.emailShare(this)"><div clas ! ! } Difficult to read and maintain
  • 4. Tag Soup in View Difficult to read and maintain
  • 5. CSS/JS Tags Impossible to remove no longer used scripts No Dependency
  • 6. Environments Too many environments Feature Detection Browser Support Hacks Responsive
  • 7. Copy Paste fluid.js fluid-horizontal.js base_waterfall.js base_carousel.js auto.js main.js carousel.js slideshow.js base_billboard.js base_feed.js base_slideshow.js 80% duplicated code (~1500 lines) * 11 Widget Code Once we start, it’s difficult to refactor
  • 8. Prototype-based Class Everyone has their own implementation Stackla.createClass(); Widget = (function () {})(); function StacklaWidgetNode() {}
  • 9. Global Variables Global variables and function names are an incredibly bad idea. The reason is that every JavaScript file included in the page runs in the same scope. If you have global variables or functions in your code, scripts included after yours that contain the same variable and function names will overwrite your variables/functions.
  • 10. Stoyan Stefanov The few man-hours spent writing the code initially end up in man-weeks spent reading it. Getting Worse
  • 11. Eliminate the hacking As a developer, we always seek for good methodologies, patterns, or better technologies to make our code to be maintained easier. “A bug could be fixed within 10 mins by a newbie, but a good developer is willing spend 4 hours to make it better.”
  • 12. Happy Developer! when using right tools & code become less messy
  • 13. Universal loader for all static assets Ability to write next-generation JS Lead and change the world of front-end app development Foundation Accelerator App New Web Development Stacks
  • 15. JS Module Before Webpack AMD <script/> Make use of global variables Ease of define dependencies No dependencies Load modules asynchronously No compile needed by default Ease of define dependencies Always need to compile Synchronous loading by a single file (via global) define(['./a', './b'], function (a, b) {! }); var Acl = require('js/acl/acl.js');
  • 16. Package Management CSS Preproccessors JS Module Loaders JS Transpiler Build Tools
  • 18. Package Management CSS Preproccessors JS Module Loaders JS Transpiler Build Tools less-loader sass-loader coffee-loader ts-loader Support ALL JS STATIC 
 Modules Webpack Dev Server
  • 19. // app/media/js/admin/terms/term-manage.jsx! ! 'use strict';! ! var React = require('react'),! $ = require('jquery'),! LogMixin = require('common/log-mixin'),! TermPanel = require('./term-panel'),! TermList = require('./term-list'),! History = require('exports?window.History!history.js/native.history'),! queryString = require('query-string'),! Cookies = require('js-cookie');! ! module.exports = {! // ...! }; Define Dependencies app/vendor/webpack/node_modules/ app/media/js/ app/media/components/
  • 20. var History = require('exports?window.History!history.js/native.history');! ! History.Adapter.bind(window, 'statechange', that.handleHistoryChange); Global Module require('history.js/native.history');! ! window.History.Adapter.bind(window, 'statechange', that.handleHistoryChange); Not Good Better exports?window.History!history.js/native.history loader loader options (query) separator module path
  • 21. JS Transpilers var Tagla = require('coffee!./tagla.coffee'); var Stepper = require('ts!./stepper.js');
  • 23. CSS Preprocessors Wait! Are you writing CSS in JS? require('!style!css!sass!admin/acl/acl.scss'); app/media/js/admin/acl/acl.js • The stylesheet will be injected into HTML with <style> tag • The images inside will be converted to Data URIs. Define dependencies between JS and CSS
  • 24. Code Splitting fluid-embed.js
 (required) when layout = portrait or landscape Load extra assets conditionally lightbox.js
 (optional)
  • 25. Dev Server Incremental build instead of full build
  • 26. • Module Loader / Dependencies • Ability to load all kinds of assets • High performance • Often replaces grunt or gulp
  • 27. Using the future of JS, Today! Accelerator
  • 28. Package Management CSS Preproccessors JS Module Loaders JS Transpiler Build Tools sass-loader coffee-loader ts-loader Support ALL Modules Webpack Dev Server babel-loader less-loader
  • 29. Why Babel? All transpilers are trying to *fix* JavaScript language These transpilers have obvious influence on the ES6/ES2015 standard. However browser support is not ready yet
  • 30. Why Babel? Babel is another transpiler which let you to use latest JS Babel keeps sync with ECMAScript Ability to customise the stage or options you want use.
  • 31. var: Function-scoped Let & Const function f() {! var obj = {a: 1, b: 2, c: 3}; ! for (var i in obj) {! // okay! console.log(i); ! } ! // okay ! console.log(i);! }! f(); let: Block-scoped function f() {! var obj = {a: 1, b: 2, c: 3}; ! for (let i in obj) {! // okay! console.log(i); ! } ! // error - i is undefined ! console.log(i);! }! f(); const: Block-scoped function a() {! const DURATION = 100;! {! // output 100! console.log(DURATION);! }! }! ! function b() {! const DURATION = 100;! {! // error "DURATION" is read-only! DURATION = 200;! } ! }! ! function c() {! const DURATION = 100;! {! // ok ! const DURATION = 200;! console.log(DURATION); // output 200! } ! }! Single-assigment
  • 32. `Template String` // This is what I prefer to do! var list = ['<ul>',! ' <li>Buy Milk</li>',! ' <li>Be kind to Pandas</li>',! ' <li>Forget about Dre</li>',! '</ul>'].join(''); ES5 // This doesn't work! var list = '<ul>! <li>Buy Milk</li>! <li>Be kind to Pandas</li>! <li>Forget about Dre</li>! </ul>';! // This does, but urgh… ! var list = '<ul>! <li>Buy Milk</li>! <li>Be kind to Pandas</li>! <li>Forget about Dre</li>! </ul>'; // This is the most common way, and urgh, too…! var list = '<ul>' +! ' <li>Buy Milk</li>' +! ' <li>Be kind to Pandas</li>' +! ' <li>Forget about Dre</li>' +! '</ul>'; ES6 // This works!! var list = `<ul>! <li>Buy Milk</li>! <li>Be kind to Pandas</li>! <li>Forget about Dre</li>! </ul>`;! http://christianheilmann.com/2015/08/28/es6-for-now-template-strings/
  • 33. `Template String` ES5 - String + Variables var avatar = '<div class="avatar">' +! ' <a href="' + avatarLink + '" target="_blank" class="avatar-profile">' +! ' <div class="avatar-place-holder">' +! ' <img src="/media/images/avatar-mask.png" alt="' + avatarAltText + '" />' +! ' </div>' +! ' <img src="' + getAvatarUrl(t.avatar, t.source) + '" alt="' + avatarAltText + '" />' +! ' </a>' +! '</div>'; var avatar = `<div class="avatar">! <a href="${avatarLink}" target="_blank" class="avatar-profile">! <div class="avatar-place-holder">! <img src="/media/images/avatar-mask.png" alt="${avatarAltText}" />! </div>! <img src="${getAvatarUrl(t.avatar, t.source)}" alt="${avatarAltText}" />! </a>! </div>`; ES6 - String + Variables The ${} construct can take any JS expression that returns a value
  • 34. class Widget extends Stackla.Base {! constructor(options) {! super(options);! ! this.domain = options.domain || null;! this.list_url = `/widget/api/${this.guid}! ?filter_id=${this.filter_id}! &domain=${this.domain}! &page=1! &ttl=1`; ! }! render(el) {! super.render();! }! static getInstances() {! // ...! }! } Classes ES6 - Single convenient declarative form
  • 37. Summary • Unlike CoffeeScript, it’s something you must learn and use in the future. • Just like PHP4 v.s. PHP5 • Makes my code more legible (ex. class) • develop much faster (ex. less vague, type safety)
  • 39. Why so Popular? Google Trend http://reactkungfu.com/2015/07/big-names-using-react-js/ Big Brands using React.js
  • 40. • Rethink best practices • JSX - Template in JavaScript? • CSS in JS - Inline style in JavaScript? • Easy to learn • Embracing Functional Programming • One-way data flow model • Impacting different areas • ImmutableJS, GraphQL Why so Popular?
  • 41. Package Management CSS Preproccessors JS Module Loaders JS Transpiler Build Tools sass-loader Support ALL Modules Webpack Dev Server babel-loader less-loader built-in support for React JSX
  • 42. Abstraction <button class="st-btn ! st-btn-danger ! st-btn-solid ! st-btn-md”>! Delete! </button> <Button kind="danger" ! size="medium" ! solid>Delete</Button> Button New Way Using Class Names Using React.js Old Way Legible & Less Guessing
  • 43. f <Button kind="danger" size="large" solid>Delete</Button> button.jsx exports default class Button extends React.Component {! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! }; this.props.sizethis.props.kind this.props.solid this.props.children Load CSS Just CSS class name manipulation render() is the only required method in React component import React from 'react';! import cx from 'classnames';! import 'stackla-uikit/scss/_button'; render() {! let that = this,! props = that.props,! className,! node;! ! className = cx('st-btn',`st-btn-${kind}`, {! 'st-btn-disabled': props.disabled,! 'st-btn-solid': props.solid,! 'st-btn-md': (props.size === 'medium'),! 'st-btn-sm': (props.size === 'small'),! 'st-active': props.active,! }, props.className);! ! return <button {...props} className={className}>{props.children}</button>! } The calculated class names Properties
  • 44. f State import React from 'react';! import Button from './button';! const data = [! {text: 'Danger', kind: 'danger', size: 'large', solid: false, active: true},! {text: 'Success', kind: 'success', size: 'medium', disabled: true, solid: true},! {text: 'Info', kind: 'info', disabled: true, solid: true},! {text: 'Default', kind: 'default', size: 'large', disabled: true, active: false}! ];! exports default class App extends React.Component {! constructor() {! this.offset = 0;! }! componentDidMount() {! setInterval(() => {! this.offset = (data.length >= this.offset + 1) ? 0 : this.offset + 1;! this.setState(data[this.offset]);! }, 500);! }! render() {! let state = this.state;! return ! <Button ! kind={state.kind} ! size={state.size} ! solid={state.solid} ! active={state.active}>! {state.text}! </Button>;! }! }; app.jsx React.render(<App>, document.getElementById('app')); Mockup Data Whenever the state changes, the render() will be invoked For Button component, whenever my property changes, the Button#render() will be invoked
  • 46. <StyleChooser/> <StylePreview/> <Breadcrumbs/> <Panel/> <WidgetsNew/> <Button/> <Button/> Only outmost component is stateful Others are stateless, only accept properties WidgetsNew StyleChooser StylePreview widgetTypes selectedWidget render() render() render() <StyleChooser widgetTypes= />widgetTypes <StyleChooser selectedWidget= />selectedWidget Top-down Rendering JSX diffs and apply changes to DOM
  • 47. UI = f(state) Update UI by changing state object Philosophy
  • 48. Sebastian Markbåge DOM as a Second-class Citizen https://www.youtube.com/watch?v=Zemce4Y1Y-A
  • 49. A Tool to Build Our Toolbox Only ourselves knows what we want, picking up technologies for right abstraction is crucial. No single library can fulfil our need. Can we build an app without a single DOM element?
  • 50. Abstraction for Different Targets • React.js in Browser • JSX ➡ DOM • react-canvas in Browser • JSX ➡ Canvas • react-isomorphics in Server • JSX ➡ HTML • react-native in iOS • JSX ➡ UIKit • react-native in Android • JSX ➡ android.view
  • 51. Ambitious Abstraction In Browser, React/JSX relies on slow DOM API. Goal Ask WebGL/GPU to use React directly Now
  • 53. ➡ ➡ ➡ ➡ ➡ Getting Better & Mature ➡ ➡ ➡ Will these tools go out of fashion in the following 18 months? POSSIBLY! However, everything is becoming 
 more mature and future-compatible We developers just need to choose right tools to do improvements
  • 54. Feel blessed with I feel much more solid to write UI now. Not a hacker but a programmer! Cheers!