ICS & the Future
of the Front-End Stack

Let's get a few things out of the way.

myth 1: I can expect any member of my team to have a complete understanding of front-end back-end and database concerns.

Full stack developers are often expected to have deep understanding of the nuances of various concerns.

They do a great job of getting projects through temporary short falls in specialized talent pools.

But they are not a replacement for a specialized skill set.

Front-end is a discipline;

deal with it.

Creating successful, modern web products requires developers in specialized areas. Particularly in the front end.

No framework, library or technique will provide that for you.

If your team does not have access to at least one dedicated front-end developer, perhaps it time to consider one

Probably more than one.

One cannot fairly expect a developer not specialized in the front-end to keep pace with the changing front-end landscape.

myth 2: The stack team, especially the front-end stack, moves too fast.

Angular has been the recommended front-end application framework for three years now.

The stack team also continues to support backbone applications.

It is not that the stack team moves too fast,

nor that the front-end moves too fast,

nor that the web moves too fast.

We are moving too slow!

ICS is one car on a busy freeway, and our speed is noticeably less than the flow of traffic.

We are chronically 5 years or more behind on best and common practices.

myth 3: I can save the church money by not wasting resources on refactoring already working code, or by upgrading to the latest versions of a framework, library or stack.

Applications do not exist in static isolation.

They exist in ecosystems of servers, networks, infrastructure and user bases.

Even if the source code is never touched...

The hardware it runs on, the wires or waves it travels over, and the users that use the application all constantly change.

Your app begins to atrophy as soon as it is written.

Just like a mechanical or living system, your app needs routine maintenance.

We cannot expect our end user experiences to remain viable after years of neglect.

Walking away from a product for 3-5 years is not a model for cost savings, maintainability or success.

myth4: JavaScript is too hard by itself. I need `${framework || library}` in order to be productive.

Frameworks enforce opinion and libraries can help make certain things easier.

A Good Framework:

  • Establishes common patterns
  • Makes easy problems easy
  • Makes hard problems possible
  • Is easy to learn
  • Gets out of the way
  • Is a good citizen of the environment (doesn't pollute the global space)

But too often we over rely on these tools for things the platform can do just as well.

angular.extend(target, source);
jquery.extend(target, source);
_.extend(target, source);
Object.assign(target, source);
angular.element.toggleClass('is-on')
jQuery('.my-element').toggleClass('is-on')
[...document.querySelectorAll('.my-element')]
    .map(el => el.classList.toggle('is-on'));
qsa('.my-element').map(toggleClass('is-on'));



const qsa = (sel, from) => [...(from || document).querySelectorAll(sel)],
    toggleClass = className => el => el.classList.toggle(className);
Handlebars.compile('Hello {{ location}}')({ location: 'world'})
angular.compile('Hello {{ location}}')({ location: 'world'})
`Hello ${ location }`
render({location: world})



function render(data) {
    return `Hello ${ data.location }`;
}

You should make a habit of asking yourself:

 

Is this framework/library really making things easier for me or my users?

  • If you have an interest in code longevity
  • If you're tired of learning a new JS framework every time you turn around.
  • If you are concerned about performance
  • If your app has or will have users outside the US or which may be connected wirelessly.
  • If you prefer to iterate rather than recreate
  • If you are compelled to leave a project for years at a time.
  • If you still think of JS as a "toy" language.

Reasons to consider a native JS solution:

Cool bro! But I was here to talk about Angular.

Ok, let's talk about Angular.

Angular 1.4 & 1.5 are all about getting ready for Angular 2

What's so special about Angular 2?

  • Everything is a component.
  • Embraces binding to native events
  • Does away with magic two-way binding (performance)
  • Does away with $scope
  • Simplified Application Model (Services + Components)
  • Revamps Dependency Injection
  • Fully embraces transpilation. (Typescript)

MWS 2.5 (Endor)

  • Angular 1.4
  • MWS has always embraced components.
  • Controllers in Directives (Components)
  • Favors native over tribal where possible.
  • Encourages one time binding syntax
  • doesn't use `$scope`
  • Simplifies app structure (Services + Components)
  • modules imported into Angular, not vise versa.
  • Embraces Transpilation (ES6 + Babel)

MWS encourages the best of what Angular has to offer in 1.x and 2.x.

The MWS has always embraced and encouraged components.

Finally, Angular has too.

Angular2 <3 's Components

An Angular 2 application consists of nested components. So an Angular 2 application will always have a component tree.

Victor Savkin: core Angular 2 developer

This is a radical departure from the Angular apps you may have in production right now.

Regardless of what the Angular team does, any migration from <1.5 to 2.x will amount to a full scale rewrite.

We have a unique opportunity to take a close look at what is best for ICS going forward.

So what is a Component?

reusable === (repeatable && configurable && 
              extensible && composable)

A self-contained, reusable aspect or feature.

Self-contained

A component must not rely on the inferred existence of a particular state in the application. Any dependency should be provided to the component explicitly.

angular.factory('config', function () {

    return function (options) {

        const defaults = {    
            desert: 'gelato',
            entree: 'chicken cordon bleu',
            appetizer: 'cesar salad',
            drink: 'mint limeade'
        }
    
        return angular.extend({}, defaults, options);
    }
}
angular.factory('config', function () {

    return function (options) {

        const defaults = {    
            desert: 'gelato',
            entree: 'chicken cordon bleu',
            appetizer: 'cesar salad',
            drink: 'mint limeade'
        }
    
        return Object.assign({}, defaults, options);
    }
}
export default function () {

    return function (options) {

        const defaults = {    
            desert: 'gelato',
            entree: 'chicken cordon bleu',
            appetizer: 'cesar salad',
            drink: 'mint limeade'
        }
    
        return Object.assign({}, defaults, options);
    }
}
//app.js
import config from './config';

angular.module('myApp', [])
    .factory('config', config);
//app.js
import config from './config';

const myConfig = config({ entree: 'ratatouille'});

Self-contained

A component must not rely on the inferred existence of a particular state in the application. Any state should be provided to the component explicitly.

angular.module('MyApp', [])
    .factory('dataSomewhere', function ($resource) {

        return $resource('/data/somewhere/');
    })
    .controller('ctrl', function (dataSomewhere) {

        dataSomewhere.get().$promise.then(data => this.data = data);

    });
//dataSomewhere.js
export default function ($resource) {
    return $resource('/data/somewhere/', { id: '' });
});

//ctrl.js
export default function (dataSomewhere) {
    dataSomewhere.get({ id: 123 })
        .$promise.then(data => this.data = data);
}

//app.js
import dataSomewhere from 'dataSomewhere';

angular.module('MyApp', [])
    .factory('dataSomewhere', dataSomeWhere)
    .controller('ctrl', ctrl);
//dataSomewhere.js
export default function (fetch) {
    return { get(id) { return fetch(`/data/somewhere?id=${id}`); },
             save(data) { return fetch(`/data/somewhere`, {
                 method: 'post',
                 body: JSON.stringify(data);
           })}
    };
});

//ctrl.js
export default function (dataSomewhere) {
    dataSomewhere.get(123).then(data => this.data = data);
}

//app.js
import dataSomewhere from 'dataSomewhere';
import $resourceToFetch from 'resourceToFetch';

angular.module('MyApp', [])
    .factory('fetch', $resourceToFetch)
    .factory('dataSomewhere', dataSomeWhere)
    .controller('ctrl', ctrl);

Endor's strategy is to limit the impact of the framework on application to what a framework is for.

Making simple things simple, hard things possible & getting out of the way.

Why have this strategy?

  • Frameworks iterate faster than the platform
  • Frameworks come and go
  • Business logic should be portable from one framework to another.
  • Frameworks should be frameworks, not effectively new platforms or languages.
  • To date, the web platform hasn't introduced a single breaking change.
  • Always have a contingency plan

If you use the MWS - Endor, migration to anything will be a lot smoother.

Angular 2 is a complete makeover.

But quite honestly, Angular is late to the game with most of their features.

What it does right, others do better.

Angular 2 is feeling more like an "also ran", than the future of JavaScript.

Angular continues to embrace a paradigm that goes against the grain of JavaScript.

Their full throated enforcement endorsement of Typescript further's that perception.

We need to be removing cruft, not adding more.

Angular 2 adds unnecessary cognitive and page weight cruft.

For these reasons, and more, the stack team feels that Angular 2 may not be the path forward for ICS.

The
End

Just kidding :)

If not Angular 2, then what?

Simplicity is our guiding principle. Apps are complex enough on their own.

They don't need additional complexity or bloat from a do-it-all framework.

There are a few other contenders.

We believe that by focusing on the web platform (HTML, JS & CSS) and applying library code when needed, the effect will be:

  • More productive

  • More performant

  • More Efficient

  • Have greater code longevity

If you have any questions about our direction, see me or another front-end stack team member anytime.

So what do I do in the mean time?

Use the MWS. You will start out on the right foot. Talk to us about any challenges.

We need your collaboration if we are to be successful as an organization.

The
End

for real this time.