SlideShare une entreprise Scribd logo
1  sur  60
Adding a Modern Twist to
Legacy Web Applications
Process, Toolset and Buy In
by Jeff Dutra - @JeffDutraCanada
Housekeeping
All the code will be on GitHub
 https://github.com/jefferydutra/AddingModernTwistToLegacyApps
Who Am I
o It does not really matter
o Not an Authority
Who Am I
o software developer/amateur
skeptic/pretend psychologist
o Proficient Web Developer
working towards becoming
an Expert
Introduction
 Manage dependencies and build your JavaScript with Node.js, Gulp, Browserify
 Adding modern web functionality with React and Flux
 Strategies for Buy In to start using these toolsets now (or in some reasonable amount of time)
But Why?
 Avoid misery of working with legacy code
 We will see how you can add independent and isolated
components to existing pages; pages that may be difficult to
change
 React and Flux allow you to make self-contained additions that
handle their own data access/persistence
Go Time
GULP
&
JSHINT
What is Gulp
• Grabs some files
• Modify them
• Output new files
A build system should
only handle basic
functionality and allow
other libraries to do
things they are made to
do.
Why build with
Gulp?
o Minify
o Concatenate
o JSHint
o Compile LESS or
SASS
o Run your tests (now
there is no excuse
when it comes to
writing tests)
Why not Grunt
o Code over
configuration
o Grunt tries do
everything itself
o Gulp relies on an
eco-system of
plug-ins
o Faster
o Cooler logo
The 4 functions
Gulp provides
o gulp.task(name[, deps], fn)
o gulp.src(globs[, options])
o gulp.dest(path[, options])
o gulp.watch(glob[, opts],
tasks)
globs are a pattern or an array of patterns for file matching.
**/*.js = find all files that end in .js
JSHint Task
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var notify = require("gulp-notify");
gulp.task('jshint', function () {
return gulp.src("./js/library/src/**/*.js")
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter(stylish))
.pipe(notify(function (file) {
if (file.jshint.success) {
// Don't show something if success
return false;
}
var errors = file.jshint.results.map(function (data) {
if (data.error) {
return "(" + data.error.line + ':' + data.error.character + ') ' +
data.error.reason;
}
}).join("n");
return file.relative + " (" + file.jshint.results.length + " errors)n" + errors;
}));
JsHint Task Demo
(using AirBnb style guide)
What is Browserify?
o Tool for compiling
node-flavored
commonjs modules
for the browser
o Allows you to nicely
organize your code
o Promotes code
modularity
What are commonjs
modules?
o Were created in the early
days of server side
JavaScript
o Three main variables:
o require
o exports
o module
CommonJs
var numberGreaterThanOrEqualTo = require('./numberGreaterThanOrEqualTo');
console.log(numberGreaterThanOrEqualTo(4,2));
Declaration of numberGreaterThanOrEqualTo.js
Usage of module
var numberGreaterThanOrEqualTo = function( value, testValue ){
if(isNaN(value)){
return false;
}
if(isNaN(testValue)){
return true;
}
return Number(value) >= Number(testValue);
};
module.exports = numberGreaterThanOrEqualTo;
Webpack the
alternative to
Browserify?
o One tool that takes
care of your entire
workflow
o Faster
o Common code
splitting made
easy
Webpack cont..
o https://github.com
/petehunt/webpa
ck-howto
Commonjs/Browserify module
Demo
Tools
Webstorm
Node for visual studio
What is React
 Just the UI
 Virtual DOM
 One way reactive data flow
Why React
o You can try it out
incrementally
o Facebook/Instagram
actually use it on their
important products.
o All about composition
Why React Contd.
o One way data-
binding
o Performance
o Not just the web
o Server sider
rendering
Why not the other
guys
o Angular
o Backbone
o Ember
o Durandal/Aurelia
o Knockout
Who is using it/migrating to
it?
o Khan Academy
o AirBnB
o Yahoo mail
o Flipboard canvas
o Github (issue
viewer)
o Atalassian HipChat
rewrite
What is the Virtual
DOM?
o Copy of the actual DOM
o When any change
happens re-render
everything to virtual
DOM
o Has its own diff algorithm
to learn what has
changed
o Only update real DOM
with changes only
JSX FTW!
var HelloMessage = React.createClass({
render: function() {
return (
<div className='thisCanNotBeRight'>
Hello {this.props.name}
</div>);
}
});
React.render(
<HelloMessage name="John" />,
mountNode);
Benefits of not
Data-Binding (JSX)
o JsHint,JSCS your
code
o Minification
o Type Checking
o Testable
Think in React
o Break up your User
Interface into
hierarchical pieces
o Create a static
version of your of
your interface
o Stake out a basic
representation of
your state
o Decide where your
state should live
State and Props
o Props are how
you pass data to
a child/owned
component
o State is the
internal state of
module
o Both trigger a re-
render
State
• this.setState({
mykey: 'my value'
});
o var value =
this.state.myKey;
o Should have one
source of truth
Component Specs
o ReactElement
render()
o object
getInitialState()
o object propTypes
o array mixins
o object statics
propTypes
propTypes: {
// You can declare that a prop is a specific JS primitive. By default, these
// are all optional.
optionalArray: React.PropTypes.array,
optionalString: React.PropTypes.string,
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Message)
]),
// An array of a certain type
optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
optionalObjectWithShape: React.PropTyes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
requiredFunc: React.PropTypes.func.isRequired,
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
}
* When an invalid value is
provided for a prop, a
warning will be shown in the
JavaScript console. Note
that for performance
reasons propTypes is only
checked in development
mode.
Component Specs
var React = require("React");
var Router = require('react-router');
var Sample = React.createClass({
mixins: [ Router.Navigation, Router.State ],
propTypes: {
optionalString: React.PropTypes.string
},
getInitialState: function() {
return {optionalString: this.props.optionalString};
},
render: function(){
return (
<div className="row">
{this.state.optionalString}
</div>
);
}
});
module.exports = Sample;
Lifecycle Methods
o componentWillMount
o componenetDidMount
o componentWillReceiveProps
o shouldComponentUpdate
o componentWillUpdate
o componentDidUpdate
o componentWillUnmount
Lifecycle Methods
componentWillMount
Invoked once, both on the client and server, immediately before the
initial rendering occurs.
invoked once, only on the client (not on the server), immediately after
the initial rendering occurs. At this point in the lifecycle, the
component has a DOM representation which you can access via
React.findDOMNode(this)
componentDidMount
Lifecycle Methods contd...
componentWillReceiveProps
Invoked when a component is receiving new props. This method is not
called for the initial render.
Invoked before rendering when new props or state are being
received. This method is not called for the initial render or
when forceUpdate is used.
shouldComponentUpdate
Lifecycle Methods contd...
componentWillUpdate
Invoked immediately before rendering when new props or state are
being received. This method is not called for the initial render.
Invoked immediately after the component's updates are flushed to
the DOM. This method is not called for the initial render.
componentDidUpdate
Lifecycle Methods contd...
componentWillUnmount
Invoked immediately before a component is unmounted from the
DOM.
Perform any necessary cleanup in this method, such as invalidating
timers or cleaning up any DOM elements that were created in
componentDidMount.
React
Demo
What is Flux
 Also brought to you by Facebook
 Uni-directional data flow
 Works great with React
 More of a pattern, than a framework
 Pub/Sub pattern
How does it work
With more info
A Closer look…
Major parts of a Flux app
o Dispatcher
o Stores
o Views (React components)
Dispatcher
o Singleton that is the central
hub for an app
o When new data comes it
propagates to all stores
through callbacks
o Propagation triggered by
dispatch()
Dispatcher
var Dispatcher = require('flux').Dispatcher;
var assign = require('object-assign');
var PayloadSources = require('../constants/PayloadSources');
function throwExceptionIfActionNotSpecified(action) {
if (!action.type) {
throw new Error('Action type was not provided');
}
}
var AppDispatcher = assign(new Dispatcher(), {
handleServerAction: function(action) {
console.info('server action', action);
throwExceptionIfActionNotSpecified(action);
this.dispatch({
source: PayloadSources.SERVER_ACTION,
action: action
});
},
handleViewAction: function(action) {
console.info('view action', action);
throwExceptionIfActionNotSpecified(action);
this.dispatch({
source: PayloadSources.VIEW_ACTION,
action: action
});
}
});
module.exports = AppDispatcher;
ActionCreators
o a library of helper methods
o create the action object
and pass the action to the
dispatcher
o flow into the stores through
the callbacks they define
and register
ActionCreators
var AppDispatcher = require('../dispatcher/AppDispatcher');
var CharacterApiUtils = require('../utils/CharacterApiUtils');
var CharacterConstants = require('../constants/CharacterConstants');
var CharacterActions = {
receiveAll: function(characters) {
AppDispatcher.handleServerAction({
type: CharacterConstants.ActionTypes.RECEIVE_CHARACTERS,
characters: characters
});
},
loadAll: function() {
CharacterApiUtils.getCharacters(CharacterActions.receiveAll);
}
};
module.exports = CharacterActions;
CharacterConstants
var ApiConstants = require('./ApiConstants');
var keymirror = require('keymirror');
module.exports = {
ApiEndPoints: {
CHARACTER_GET: ApiConstants.API_ROOT + '/Character'
},
ActionTypes: keymirror({
RECEIVE_CHARACTERS: null
})
};
CharacterApiUtils
var $ = require('jquery');
var CharacterConstants = require('../constants/CharacterConstants');
var CharacterApiUtils = {
getCharacters: function(successCallback) {
$.get(CharacterConstants.ApiEndPoints.CHARACTER_GET)
.done(function(data) {
successCallback(data);
});
}
};
module.exports = CharacterApiUtils;
Stores
o Contain application state
and logic
o Singleton
o Similar to MVC, except they
manage state of more
than one object
o Registers itself with the
dispatcher through
callbacks
o When updated, they
broadcast a change event
for views that are listening
Stores var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var CharacterConstants = require('../constants/CharacterConstants');
var assign = require('object-assign');
var CHANGE_EVENT = 'change';
var _characters = [];
var CharacterStore = assign({}, EventEmitter.prototype, {
init: function(characters) {
characters.forEach(function(character) {
_characters[character.id] = character;
}, this);
},
getAll: function() {
return _characters;
},
emitChange: function() {
this.emit(CHANGE_EVENT);
},
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeChangeListener(CHANGE_EVENT, callback);
}
});
AppDispatcher.register(function(payload) {
var action = payload.action;
switch (action.type) {
case CharacterConstants.ActionTypes.RECEIVE_CHARACTERS:
CharacterStore.init(action.characters);
CharacterStore.emitChange();
break;
}
});
module.exports = CharacterStore;
Stores & React var React = require('React');
var CharacterStore = require('../stores/CharacterStore');
function getCharacters() {
return CharacterStore.getAll();
}
var DataGrid = React.createClass({
getInitialState: function() {
return {
characters: getCharacters()
}
},
componentWillMount: function() {
CharacterStore.addChangeListener(this._onChange);
},
componentWillUnmount: function() {
CharacterStore.removeChangeListener(this._onChange)
},
_onChange: function() {
this.setState({characters: getCharacters()});
},
render: function() {
return (
//...
);
}
});
module.exports = DataGrid;
Flux
Demo
Implementation First Phase
1. Learn how to do this stuff on your own time
2. Start simple (JSHINT, JSCS)
3. Use Change management principles
 Up to you to explain what is in it for them
Change Management
Implement React and Flux
If using ASP.NET MVC try React.Net first
Use on the next feature you work on (may require you
spending your own private time)
Write a blog/wiki on the experience
Then let others have their input/concerns heard
Chrome Dev Tools
Postman
JSON pretty
React plugin
Thank you!
@JeffDutraCanada
Jeff.dutra@gmail.com
https://github.com/jefferydutra/

Contenu connexe

Tendances

Ant - Another Neat Tool
Ant - Another Neat ToolAnt - Another Neat Tool
Ant - Another Neat Tool
Kanika2885
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_tw
Tse-Ching Ho
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6
Ray Ploski
 

Tendances (20)

Advanced JavaScript - Internship Presentation - Week6
Advanced JavaScript - Internship Presentation - Week6Advanced JavaScript - Internship Presentation - Week6
Advanced JavaScript - Internship Presentation - Week6
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
CDI: How do I ?
CDI: How do I ?CDI: How do I ?
CDI: How do I ?
 
Dependency Injection with CDI in 15 minutes
Dependency Injection with CDI in 15 minutesDependency Injection with CDI in 15 minutes
Dependency Injection with CDI in 15 minutes
 
Ant - Another Neat Tool
Ant - Another Neat ToolAnt - Another Neat Tool
Ant - Another Neat Tool
 
To inject or not to inject: CDI is the question
To inject or not to inject: CDI is the questionTo inject or not to inject: CDI is the question
To inject or not to inject: CDI is the question
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Rhino Mocks
Rhino MocksRhino Mocks
Rhino Mocks
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modules
 
Java Enterprise Edition
Java Enterprise EditionJava Enterprise Edition
Java Enterprise Edition
 
Java Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to MissJava Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to Miss
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_tw
 
Qt test framework
Qt test frameworkQt test framework
Qt test framework
 
Virtual events in C#: something went wrong
Virtual events in C#: something went wrongVirtual events in C#: something went wrong
Virtual events in C#: something went wrong
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6
 
Object Oreinted Approach in Coldfusion
Object Oreinted Approach in ColdfusionObject Oreinted Approach in Coldfusion
Object Oreinted Approach in Coldfusion
 
Epoxy 介紹
Epoxy 介紹Epoxy 介紹
Epoxy 介紹
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 Kotlin
 
Intro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSIntro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJS
 
Completable future
Completable futureCompletable future
Completable future
 

Similaire à Adding a modern twist to legacy web applications

Intro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptIntro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScript
jasonsich
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
react-slides.pdf gives information about react library
react-slides.pdf gives information about react libraryreact-slides.pdf gives information about react library
react-slides.pdf gives information about react library
janet736113
 

Similaire à Adding a modern twist to legacy web applications (20)

Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]
 
Fundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdfFundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdf
 
OttawaJS - React
OttawaJS - ReactOttawaJS - React
OttawaJS - React
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
Intro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptIntro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScript
 
Fundamental concepts of react js
Fundamental concepts of react jsFundamental concepts of react js
Fundamental concepts of react js
 
React JS: A Secret Preview
React JS: A Secret PreviewReact JS: A Secret Preview
React JS: A Secret Preview
 
JavaScript Miller Columns
JavaScript Miller ColumnsJavaScript Miller Columns
JavaScript Miller Columns
 
React, Flux and more (p1)
React, Flux and more (p1)React, Flux and more (p1)
React, Flux and more (p1)
 
React - Start learning today
React - Start learning today React - Start learning today
React - Start learning today
 
React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)
 
Intro react js
Intro react jsIntro react js
Intro react js
 
react-slides.pptx
react-slides.pptxreact-slides.pptx
react-slides.pptx
 
ReactJS (1)
ReactJS (1)ReactJS (1)
ReactJS (1)
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Getting Started with React, When You’re an Angular Developer
Getting Started with React, When You’re an Angular DeveloperGetting Started with React, When You’re an Angular Developer
Getting Started with React, When You’re an Angular Developer
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
 
react-slides.pdf
react-slides.pdfreact-slides.pdf
react-slides.pdf
 
react-slides.pdf gives information about react library
react-slides.pdf gives information about react libraryreact-slides.pdf gives information about react library
react-slides.pdf gives information about react library
 
Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteor
 

Dernier

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 

Dernier (20)

OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 

Adding a modern twist to legacy web applications

  • 1. Adding a Modern Twist to Legacy Web Applications Process, Toolset and Buy In by Jeff Dutra - @JeffDutraCanada
  • 2. Housekeeping All the code will be on GitHub  https://github.com/jefferydutra/AddingModernTwistToLegacyApps
  • 3. Who Am I o It does not really matter o Not an Authority
  • 4. Who Am I o software developer/amateur skeptic/pretend psychologist o Proficient Web Developer working towards becoming an Expert
  • 5. Introduction  Manage dependencies and build your JavaScript with Node.js, Gulp, Browserify  Adding modern web functionality with React and Flux  Strategies for Buy In to start using these toolsets now (or in some reasonable amount of time)
  • 6. But Why?  Avoid misery of working with legacy code  We will see how you can add independent and isolated components to existing pages; pages that may be difficult to change  React and Flux allow you to make self-contained additions that handle their own data access/persistence
  • 8. What is Gulp • Grabs some files • Modify them • Output new files A build system should only handle basic functionality and allow other libraries to do things they are made to do.
  • 9. Why build with Gulp? o Minify o Concatenate o JSHint o Compile LESS or SASS o Run your tests (now there is no excuse when it comes to writing tests)
  • 10. Why not Grunt o Code over configuration o Grunt tries do everything itself o Gulp relies on an eco-system of plug-ins o Faster o Cooler logo
  • 11. The 4 functions Gulp provides o gulp.task(name[, deps], fn) o gulp.src(globs[, options]) o gulp.dest(path[, options]) o gulp.watch(glob[, opts], tasks) globs are a pattern or an array of patterns for file matching. **/*.js = find all files that end in .js
  • 12. JSHint Task var gulp = require('gulp'); var jshint = require('gulp-jshint'); var stylish = require('jshint-stylish'); var notify = require("gulp-notify"); gulp.task('jshint', function () { return gulp.src("./js/library/src/**/*.js") .pipe(jshint('.jshintrc')) .pipe(jshint.reporter(stylish)) .pipe(notify(function (file) { if (file.jshint.success) { // Don't show something if success return false; } var errors = file.jshint.results.map(function (data) { if (data.error) { return "(" + data.error.line + ':' + data.error.character + ') ' + data.error.reason; } }).join("n"); return file.relative + " (" + file.jshint.results.length + " errors)n" + errors; }));
  • 13.
  • 14. JsHint Task Demo (using AirBnb style guide)
  • 15. What is Browserify? o Tool for compiling node-flavored commonjs modules for the browser o Allows you to nicely organize your code o Promotes code modularity
  • 16. What are commonjs modules? o Were created in the early days of server side JavaScript o Three main variables: o require o exports o module
  • 17. CommonJs var numberGreaterThanOrEqualTo = require('./numberGreaterThanOrEqualTo'); console.log(numberGreaterThanOrEqualTo(4,2)); Declaration of numberGreaterThanOrEqualTo.js Usage of module var numberGreaterThanOrEqualTo = function( value, testValue ){ if(isNaN(value)){ return false; } if(isNaN(testValue)){ return true; } return Number(value) >= Number(testValue); }; module.exports = numberGreaterThanOrEqualTo;
  • 18. Webpack the alternative to Browserify? o One tool that takes care of your entire workflow o Faster o Common code splitting made easy
  • 22. What is React  Just the UI  Virtual DOM  One way reactive data flow
  • 23. Why React o You can try it out incrementally o Facebook/Instagram actually use it on their important products. o All about composition
  • 24. Why React Contd. o One way data- binding o Performance o Not just the web o Server sider rendering
  • 25. Why not the other guys o Angular o Backbone o Ember o Durandal/Aurelia o Knockout
  • 26. Who is using it/migrating to it? o Khan Academy o AirBnB o Yahoo mail o Flipboard canvas o Github (issue viewer) o Atalassian HipChat rewrite
  • 27. What is the Virtual DOM? o Copy of the actual DOM o When any change happens re-render everything to virtual DOM o Has its own diff algorithm to learn what has changed o Only update real DOM with changes only
  • 28. JSX FTW! var HelloMessage = React.createClass({ render: function() { return ( <div className='thisCanNotBeRight'> Hello {this.props.name} </div>); } }); React.render( <HelloMessage name="John" />, mountNode);
  • 29. Benefits of not Data-Binding (JSX) o JsHint,JSCS your code o Minification o Type Checking o Testable
  • 30. Think in React o Break up your User Interface into hierarchical pieces o Create a static version of your of your interface o Stake out a basic representation of your state o Decide where your state should live
  • 31. State and Props o Props are how you pass data to a child/owned component o State is the internal state of module o Both trigger a re- render
  • 32. State • this.setState({ mykey: 'my value' }); o var value = this.state.myKey; o Should have one source of truth
  • 33. Component Specs o ReactElement render() o object getInitialState() o object propTypes o array mixins o object statics
  • 34. propTypes propTypes: { // You can declare that a prop is a specific JS primitive. By default, these // are all optional. optionalArray: React.PropTypes.array, optionalString: React.PropTypes.string, optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // An array of a certain type optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), optionalObjectWithShape: React.PropTyes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), requiredFunc: React.PropTypes.func.isRequired, customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error('Validation failed!'); } } * When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. Note that for performance reasons propTypes is only checked in development mode.
  • 35. Component Specs var React = require("React"); var Router = require('react-router'); var Sample = React.createClass({ mixins: [ Router.Navigation, Router.State ], propTypes: { optionalString: React.PropTypes.string }, getInitialState: function() { return {optionalString: this.props.optionalString}; }, render: function(){ return ( <div className="row"> {this.state.optionalString} </div> ); } }); module.exports = Sample;
  • 36. Lifecycle Methods o componentWillMount o componenetDidMount o componentWillReceiveProps o shouldComponentUpdate o componentWillUpdate o componentDidUpdate o componentWillUnmount
  • 37. Lifecycle Methods componentWillMount Invoked once, both on the client and server, immediately before the initial rendering occurs. invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, the component has a DOM representation which you can access via React.findDOMNode(this) componentDidMount
  • 38. Lifecycle Methods contd... componentWillReceiveProps Invoked when a component is receiving new props. This method is not called for the initial render. Invoked before rendering when new props or state are being received. This method is not called for the initial render or when forceUpdate is used. shouldComponentUpdate
  • 39. Lifecycle Methods contd... componentWillUpdate Invoked immediately before rendering when new props or state are being received. This method is not called for the initial render. Invoked immediately after the component's updates are flushed to the DOM. This method is not called for the initial render. componentDidUpdate
  • 40. Lifecycle Methods contd... componentWillUnmount Invoked immediately before a component is unmounted from the DOM. Perform any necessary cleanup in this method, such as invalidating timers or cleaning up any DOM elements that were created in componentDidMount.
  • 42. What is Flux  Also brought to you by Facebook  Uni-directional data flow  Works great with React  More of a pattern, than a framework  Pub/Sub pattern
  • 43. How does it work
  • 46. Major parts of a Flux app o Dispatcher o Stores o Views (React components)
  • 47. Dispatcher o Singleton that is the central hub for an app o When new data comes it propagates to all stores through callbacks o Propagation triggered by dispatch()
  • 48. Dispatcher var Dispatcher = require('flux').Dispatcher; var assign = require('object-assign'); var PayloadSources = require('../constants/PayloadSources'); function throwExceptionIfActionNotSpecified(action) { if (!action.type) { throw new Error('Action type was not provided'); } } var AppDispatcher = assign(new Dispatcher(), { handleServerAction: function(action) { console.info('server action', action); throwExceptionIfActionNotSpecified(action); this.dispatch({ source: PayloadSources.SERVER_ACTION, action: action }); }, handleViewAction: function(action) { console.info('view action', action); throwExceptionIfActionNotSpecified(action); this.dispatch({ source: PayloadSources.VIEW_ACTION, action: action }); } }); module.exports = AppDispatcher;
  • 49. ActionCreators o a library of helper methods o create the action object and pass the action to the dispatcher o flow into the stores through the callbacks they define and register
  • 50. ActionCreators var AppDispatcher = require('../dispatcher/AppDispatcher'); var CharacterApiUtils = require('../utils/CharacterApiUtils'); var CharacterConstants = require('../constants/CharacterConstants'); var CharacterActions = { receiveAll: function(characters) { AppDispatcher.handleServerAction({ type: CharacterConstants.ActionTypes.RECEIVE_CHARACTERS, characters: characters }); }, loadAll: function() { CharacterApiUtils.getCharacters(CharacterActions.receiveAll); } }; module.exports = CharacterActions;
  • 51. CharacterConstants var ApiConstants = require('./ApiConstants'); var keymirror = require('keymirror'); module.exports = { ApiEndPoints: { CHARACTER_GET: ApiConstants.API_ROOT + '/Character' }, ActionTypes: keymirror({ RECEIVE_CHARACTERS: null }) }; CharacterApiUtils var $ = require('jquery'); var CharacterConstants = require('../constants/CharacterConstants'); var CharacterApiUtils = { getCharacters: function(successCallback) { $.get(CharacterConstants.ApiEndPoints.CHARACTER_GET) .done(function(data) { successCallback(data); }); } }; module.exports = CharacterApiUtils;
  • 52. Stores o Contain application state and logic o Singleton o Similar to MVC, except they manage state of more than one object o Registers itself with the dispatcher through callbacks o When updated, they broadcast a change event for views that are listening
  • 53. Stores var AppDispatcher = require('../dispatcher/AppDispatcher'); var EventEmitter = require('events').EventEmitter; var CharacterConstants = require('../constants/CharacterConstants'); var assign = require('object-assign'); var CHANGE_EVENT = 'change'; var _characters = []; var CharacterStore = assign({}, EventEmitter.prototype, { init: function(characters) { characters.forEach(function(character) { _characters[character.id] = character; }, this); }, getAll: function() { return _characters; }, emitChange: function() { this.emit(CHANGE_EVENT); }, addChangeListener: function(callback) { this.on(CHANGE_EVENT, callback); }, removeChangeListener: function(callback) { this.removeChangeListener(CHANGE_EVENT, callback); } }); AppDispatcher.register(function(payload) { var action = payload.action; switch (action.type) { case CharacterConstants.ActionTypes.RECEIVE_CHARACTERS: CharacterStore.init(action.characters); CharacterStore.emitChange(); break; } }); module.exports = CharacterStore;
  • 54. Stores & React var React = require('React'); var CharacterStore = require('../stores/CharacterStore'); function getCharacters() { return CharacterStore.getAll(); } var DataGrid = React.createClass({ getInitialState: function() { return { characters: getCharacters() } }, componentWillMount: function() { CharacterStore.addChangeListener(this._onChange); }, componentWillUnmount: function() { CharacterStore.removeChangeListener(this._onChange) }, _onChange: function() { this.setState({characters: getCharacters()}); }, render: function() { return ( //... ); } }); module.exports = DataGrid;
  • 56. Implementation First Phase 1. Learn how to do this stuff on your own time 2. Start simple (JSHINT, JSCS) 3. Use Change management principles  Up to you to explain what is in it for them
  • 58. Implement React and Flux If using ASP.NET MVC try React.Net first Use on the next feature you work on (may require you spending your own private time) Write a blog/wiki on the experience Then let others have their input/concerns heard
  • 59. Chrome Dev Tools Postman JSON pretty React plugin