NEW STUFF IN WEB DEVELOPMENT

at DriveTime!


Jenkins, AMD, RequireJS, Web Components, 

Node, Gulp & WebAPI

Created by Allen Rice with help from

Ryan Blatz, Chaz Guerrero and Eric Blatz

Lessons Learned from past projects

Client side applications are getting serious, our tooling needs to be up to par (Builds, Package Managers, Languages, Features)

Large applications can be developed, in parallel, successfully,  with developers of all skill levels

Developers work quickly when working within a framework

Always Automate, this demands easier automation

Large applications need to be simplified whenever possible


As a quick aside


Helping us work smarter, not harder

Focusing on tooling and techniques

tooling

We've been missing an important part of our development ecosystem - a Continuous Integration (CI) platform

CI starts the integration process by building the project
regularly and housing most (if not all) automation

CI a foundational tool, one of the most important tools

CI makes it easier and faster for developers to 
work together and integrate their code

Currently we use TFS for CI (we use TFS for a few things)

That's not a platform


We're getting a real CI platform 
because TFS is not a real CI Platform

 

Jenkins is a real CI platform where real, 
in depth automation can thrive

Remember, automation needs to be easy, 
so your CI platform better be easy to use!

Pro's

  • Enables developers to swarm on projects effectively and very quickly

  • Much faster turnaround for new processes: If you can do it in a batch file or exe, you’re done

  • Some staff have used it, interviewees have used it, its common in the industry

  • Can be phased in to use slowly, project by project

  • Everything is open source (extremely easy integration with other platforms)

  • Data at our fingertips! (analytics, trend graphing, accountability, project health at a glance)

  • TFS overly complicates the little work that it does.  Jenkins simplifies the work that it does and does it far better

Con's

  • We will eventually want integration into current processes like we did with Trello and TFS

      • We could go so far as to have code comments create trello cards or TFS work items when you check in

  • TFS is still used for source control, so Jenkins will be another platform.  This is a common occurrence in the industry.

I'm tired of talking about jenkins

Good, so am I, this stuff isn't exactly rocket surgery
 

More new things: Client side builds


A build process for our client side code, via Node 
(node is so cool)!

We've never had one before, this is entirely new

This has led to us doing stuff on the server that we shouldn't. 

It turns out this stuff can be done easily and it's almost 
entirely been done for us by the community

What's Node?
Why is it so cool?


Node (from Google) runs JavaScript on a server, any server

It turns out a LOT of people use JavaScript  because it runs on every platform via Node

We're going to use it for sharing code (npm, bower) and doing that client side build stuff (gulp) I was talking about ...

Client side builds: an 

evolutionary leap in tooling!

Really!  It has an extremely high potential


We're now going to be building everything 
client related: TypeScript, CSS, LESS, Images, BundlingMinficationSpritingVector Graphics and Video


This includes a huge chunk of what we do 
that had no build process before

Q: Weren't you already doing this?


Definitely, it was being done on the servers, in production
(spriting, bundling, minification, less)

Or it was being done in a really weird, half-documented process
(less, images, video, vector graphics)

Ok, so this way is better?


Yep, its more stable.  Less is done in production so 
less can fail in production.

POS and Carvana, and probably others, have had outages caused by this stuff breaking in production 

We're just producing static output and content.  This way reduces our footprint (debugging, startup) drastically

Failing at build time is so much better,
for reasons you might not think of

So this stuff is kind of a 

Paradigm shift

It's at least a copy of an already existing paradigm

Everything that we were doing for the server side code,
including sharing code, we can do for client side code

Speaking of which, we already have a way to share server side code that saves us a crazy amount of time already: 

So for client side, we'll use 
NPM and Bower!


Turns out this was a solved-problem in the industry
 

Don't get too excited about package managers themselves,
its the packages that are exciting!

Jenkins --> Node --> Gulp


Meet gulp, it's a JavaScript way to run client side builds

It's crazy fast ... and it was written in the valley!!

Gives us another way to automate via build scripts

This seems like a lot of stuff


It is, it's a ton, but it's just tooling (so far)

All of this runs already in a POC

There is little to no training for developers

It's a standardized way of doing things that will save a massive amount of time

Up Next: Code and organization


New Technologies: 

  1. AMD modules
  2. RequireJS loading and optimization
  3. Knockout 3.2 web components

More foundational stuff,
like code Dependencies!

We've been fighting an unsustainable fight since Carvana, where  client side dependencies are managed on the back of a cocktail napkin

You're lucky if you get a functional site, but now we want 
extremely precise control over dependencies

Basically, Carvana's about-us page shouldn't load
the purchase-process document-upload functionality

Similarly, the dependencies for the MPC or the gauges
shouldn't be loaded on the VDP unless the user requests them

Are there buzzwords

and logos for this stuff too?


AMD, or Asynchronous Module Definitions, is a 
very widely adopted technique to define modules of JavaScript

Previously, we didn't use anything or rolled our own

AMD is built into TypeScript, and is very easy to use:
import ns = require("ns"); 
ns.CompiledMethodCall(true); 

Without AMD

  • You'd have to add a new file to any and all cocktail napkins
  • You'd have to point the files at each other via comments (ugh)
  • Naming got a little out of hand
  • There was a lot of duplication and 
    different ways to do stuff
  • It was basically dependency hell, but way worse due to duplication
  • It was bad times overall and everyone knew it was ultimately
    going to be fixed with AMD, eventually (which is now)
  • This is no way to build a large scale application that you would have to maintain


I thought you said
there was a logo?


require.js is an optimizer and loader 
that works at run time for dev
and works at build time for test and prod

It can load html, css, images, etc, but its mostly used for 
loading AMD modules

I'm not sure why 

this is exciting


This changes everything about how we organize our code!

We never have to manage code dependencies again - no more cocktail napkins!

We have the ability to control any dependency loading scheme

We can deliver super light weight and fast web pages

This is Seriously exciting!


If you want to load different versions of the 
same code, you can do that.

If you want to pull down a utility library, you run
npm install dt-utilities --save-dev 
Now you're 1 line of code away from consuming packaged code, compiling against it and including it in your bundle.  It doesn't get much easier than this

All the previous scenarios can be done with minimal
amount of code, and all of it is run at build time!


CV.Search.viewModel.filterBoxes.financing.CreditBucketModel 
becomes
financing.CreditBucketModel 



Web Components!
AKA Knockout 3.2


Is this anything like components in POS?

An entirely new way to build components

Loading and scoping is done for you

There is a standard life cycle to follow and hook into

Provides a very clean way to re-use components!

Before / After

Had to invent our own lifecycle 
Html.QueuePreInitMessage(
 	"initDealershipSelector", 
 	new { domElementToBindAgainst = "#DealershipSelector" }) 
and 
 @RenderPartial("Components/DealershipSelector")
We're a little limited with this
  • We start all components at once
  • Components couldn't exist more than once
  • Components had to be full blown components
  • Home grown
  • Needed a unique ID
  • Difficult to unit test

Before / After

Knockout built lifecycle

<dealership-selector params="data: someData">
</dealership-selector>
or 
<!-- ko component: { name: "dealership-selector", data: someData } -->
<!-- /ko -->
and 
ko.components.register("dealership-selector", {
    template: ..., // Element name, or source URL, or a function 
                   // that asynchronously returns a node array,
    viewModel: ... // Object, or AMD module name, or a function that
                   // asynchronously returns an object
});

Is That better?

  • Components are started JIT
  • Infinite number of instances
  • Encapsulation
  • Death to the classic-style modules in TypeScript
  • Well documented (soon to be, anyway)
  • Very easy to unit test components very deeply
  • Can be very large or very small
  • Can be easily distributed
  • Sandbox could test more
  • much closer to C# in development style

examples

Entire pages as components
<ko-component name="{{ route().page }}" route="{{ route }}">
</ko-component>

Date pickers
<date-picker params="value: someObservable" />

Something in between
<override-field params="type: apr" />

Our own full blown framework

pro's
  • Decreased development time
  • Increased rate of sharing 
  • Decreased time unit testing
  • Increased durability
  • Better UX (routing!)

con's
  • Not compatible with POS components
  • Can't easily mix with razor

Last but not least: Web API

A new way of thinking about organizing our ajax

Likely to help us design, plan, implement and
integrate, much better than in POS

Extremely easy to learn

Extremely low risk

What we're trying to avoid


What was all this again?


Introduction of a real CI platform

Improved build process

Improvements in client development

Improvements in server side development

Recap:
Introduction of a real CI platform


Jenkins will be our build server, working along side TFS

Less down time due to build issues

Vast capabilities with minimal work

RECAP: 
Improvements in client development

AMD modules
  • Change the way we write and share client side code
  • Fix maintenance nightmares

KO 3.2 components
  • Change the way we write components
  • Be a natural evolution of the mediator component pattern

RequireJS optimization
  • Fix bundling and minfication nightmares
  • Allow us to extremely tweak our UX

RECAP: 
Improvements in server side development


WebAPI 

  • Improve collaboration between client and server developers

  • decrease integration time between client and server code

  • give us more control over the calls

What to look and plan for


We should be building reusable components between teams

We should tightly integrate jenkins with Trello and TFS

We should be running our own npm server

We should get this working for Azure projects

Hybrid projects are trickier than SPA's

Expect implementation challenges at first (but...)

New Tech for Leasing

By Allen Rice

New Tech for Leasing

A brief overview of the new technology that is going into the leasing project and web development in general at DriveTime

  • 990