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
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
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;
}));
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;
20. What is React
Just the UI
Virtual DOM
One way reactive data flow
21. Why React
o You can try it out
incrementally
o Facebook/Instagr
am actually use it
on their
important
products.
o All about
composition
22. Why React Contd.
o One way data-
binding
o Performance
o Not just the web
o Server sider
rendering
23. Why not the other
guys
o Angular
o Backbone
o Ember
o Durandal/Aurelia
o Knockout
24. 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
25. 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. 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
29. 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. 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.
34. Lifecycle Methods
o componentWillMount
o componenetDidMount
o componentWillReceiveProps
o shouldComponentUpdate
o componentWillUpdate
o componentDidUpdate
o componentWillUnmount
35. 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
40. 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
44. Major parts of a Flux app
o Dispatcher
o Stores
o Views (React components)
45. 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()
46. 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;
47. 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
48. 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;
50. 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
51. 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;
53. 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
55. 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