You Should Be Using Flight
Stop the Fanaticism: Use the Right Tool for the job.
You Should be Using Flight
Why I use Flight, and you should consider it, too.
About Me
- Javascript Addict (Node, Front-End, Robotics)
- Engineering Evangelist at RetailMeNot
- I have a .gif problem.
What is Flight?
"Flight is a lightweight, component-based JavaScript framework that maps behavior to DOM nodes. Twitter uses it [...you're not even reading this far.]" - flightjs.github.io
But I'm a fan of [ , , , , , whatever ] framework!
Warning: opinion
incoming
I think a lot of frameworks are over-used and shoehorned into projects where they aren't the best tool for the job.
I question the work-to-reward ratio of a lot of today's front-end frameworks
We have a serious problem with framework fanaticism.
Instead of asking 'how is Y framework like [my favorite],' we should ask 'how will this make my JS better?'
Let the argument commence!
(Later. Over food or a beer.)
Definition of the word 'framework':
"an essential supporting structure of a building, vehicle, or object."
-Merriam-Webster
Flight is a framework:
- Set of small utilities
- Encourages well-written, modular apps
- Lightweight
Not Overly Prescriptive
- Not MV* (Unless you write it).
- Plays well with other libraries
- Gives you tools to structure your code
Commandments of Flight
- Components are atomic
- Communication via Events
- Use the DOM (, Luke!)
- Test Everything
An Aside about
Functional Mixins
Functional Mixins
- Applies functionality to a prototype
- "a process, not an object" - Angus Croll
- The best thing to happen to JS since JSHint
Generic
Resuable
Functionality
Why not
inheritance?
- Gang of Four: Composition over Inheritance
- Does a signup button inherit from signupFormElement, or Button?
- JS isn't meant for inheritance (!)
Writing a
Flight Application
You can follow along at GitHub
Step 1: write your HTML
Count: <span class="js-count"></span>
<a class="btn btn-success js-increment" href="" target="_blank"></a>
<a class="btn btn-danger js-decrement" href="" target="_blank">-</a>
Step 2: write your component code
function counter() {
this.attributes({
'counterDisplay': '.js-count',
'incrementButton': '.js-increment',
'decrementButton': '.js-decrement'
});
this.after('initialize', function () {
this.select('counterDisplay').text('0');
this.on('click', {
'incrementButton': this.increment,
'decrementButton': this.decrement
});
this.on('counterChange', this.change);
});
//...event handlers after this...
}
Component code breakdown
- this.attributes({})
- this.after('initialize', function(){})
- Event handlers
- Component Definition / Mixins
Component Definition / Mixins
- mixins go first - most generic -> most specific
- Overrides go in the component
return defineComponent(
withMixin1,
withMixin2,
withMixin3,
componentConstructor);
Step 3 - Actually using our component
- Require in our module
- run .attachTo(selector)
define(function(require){
var myCounter = require('components/counter');
myCounter.attachTo('.js-counter', {
//you can override attributes here.
});
})
Why we put all selectors in defaultAttrs
We can now override our selectors without changing the class. We have made our component markup agnostic.
This gives us a large chunk of the code reusability that we normally don't get.
Flight Component
Events Explained
Cute Critters as Components
this.on('toy_falls', this.omg);
this.after('initialize', function(){
this.on('friend_lick', this.nope);
})
this.nope = function(){
this.push();
this.cleanSelf();
}
//...some other code...
try{
this.weirdFunction();
} catch (e) {
$(this).trigger('weirdError', {
error: e
});
}
//...our component...
this.after('intiialize', function(){
this.on('weirdError', this.panic);
});
Testing Flight Applications
Flight provides all the utilites you need to write testable client-side JS
How is flight code testable
- Components = Tiny little services
- Each service has a consistent API
- Event A is listened to, Event B is emitted with data C
But wait, there's more
- Flight proivdes a full testing framework
- jasmine-flight, mocha-flight
-
Yeoman app generatorSets up karma, mocha-flight
What do these wrappers do?
- Event Spies
- Automate HTML markup injection
- headless test running
A Mocha-Flight test
beforeEach(function () {
setupComponent('<span class="js-counter"></span><span class="js-increment"></span>');
});
it('should fire a counterChange with 1 when the increment button is clicked',
function(){
var eventSpy = spyOnEvent(document, 'counterChange');
this.component.select('incrementButton').click();
expect(eventSpy).toHaveBeenTriggeredOn(document);
expect(eventSpy.mostRecentCall.data).toEqual({ value: 1 });
});
Not only does Flight give you the tools, it encourages you to write testable code.
But, I *still* like whatever.js better!
That's OK. Flight plays well with other libraries. Or maybe Flight isn't the solution. Use the right tool for the job.
"But...but...moving frameworks is haaaaard." - a friend
The super-secret super-complicated very-difficult omg-halp plan to mix Flight code into your codebase
- Put event handlers in your existing code
- Put event triggers in your existing code
Flight <3's Developers
(And you should totally <3 it, too.)
Everyone's Invited to the Party
Flight is a framework that allows you to structure your app without intimidating and confusing your newer devs.
Test all the things...easily!
Save yourself from absolute chaos, and relegate yourself to the normal level of chaos.
Because developer hapiness is contagious!
Questions?
http://github.com/kperch/midwest_js
@nodebotanist
kas@nodebots.io
Flight-Talk
By kperch
Flight-Talk
- 1,970