Though some of the concepts in this course are still relevant, overall this course does not reflect our current course standards or industry best practices.
Table of Contents
Part 1: Introduction to JavaScript Architecture
Architecture: Decisions you make about your application
Architecture is the decisions you are making about your application. Architecture is not externalizing files or an organized file system. Good architecture uses minimal boilerplate code and a carefully curated library of tools. It’s a balance of performance and maintenance. Architecture should be able to wire up a new static page given mostly DOM references and server endpoints. Scaffolding is your architecture.What time is architecture time?
Obviously starting a new project is the right time. However, architecture should be added to existing pages if they contain multiple states, well-defined types of objects or repeated code. Architecture begins on the whiteboard. Drawing out your objects, relationships, and events being mapping out an application’s architecture. Downloading a framework and adding some custom JavaScript is not architecture. Architecture implies cataloguing objects, diagramming states and lots of planning.Example: Shopping Cart
A shopping cart is something most of us have encountered. We’ll use a shopping cart as our project while exploring proper architecture. The first step is to define our objects, states, interactions, and what we know about the application.Patterns Overview
There are many common patterns in JavaScript like Model-View-Controller, Model-View-Viewmodel, etc. Garann spends a few minutes defining a few patters and describing their differences. Within the vast array of architecture patterns, you have the same core concepts. These are data, views and events. Structuring these key concepts is important. Which pattern you use is less important.Patterns Explained
Garann discusses the concepts of a Model-View-* pattern using the Backbone.js Todo application. Presentation-Abstraction-Control takes a more observational approach with update and render methods prototyped on an object Objects in an Event-Driven Architecture subscribe to events or messages sent throughout the application. Deciding what you can usefully abstract will help narrow the decision on JavaScript architecture patterns. As long as you rule out the patterns that are a bad fit, your choice doesn’t really matter. Pull what you need from any pattern, but still maintain organization. Your code base will consist of implementation, stacked on top of utilities, stacked on top of a framework.Write (some) implementation first
Pro-tip: Write some of your implementation first. Garann walks us through a naïve outline of our shopping cart application with some basic implementation. Start thinking about inheritance. Reveal the abstractions you will need. Looking through the implementation outline, Garann asks the audience to suggest areas that require some abstraction.
Part 2: Abstractions and Frameworks
Messaging, Rendering, and Server Interactions
Messaging is responsible for notifying subscribers, caching, and tracking the context of events. Decoupling is encouraged by the ability of messaging to pass data along with the event. Rendering code provides rendered HTML by interpolating data while caching compiled templates. Server interactions pass server data to requesting objects and vice versa. They are also allow the decoupling of URLs from instance code and have a built-in notification system for when data is sent/received.State Management, Validation, and Framework Context
State management allows objects to have one or more states. As a state changes, the correct chain of events will be fired of and appropriate properties will be modified. - Question: Do you use routes with state management? Validation engines provide the user with results and update stating information based on valid/invalid operations. Validation function should be abstracted whenever possible to promote reusability. The framework context contains all the framework abstractions and distributes functionality to any registered objects. All framework code and implementations are initialized in the context and messaging/state management are enabled above the application level.Implementing a Framework
Implementing a framework starts with sketching out a small set of functionality and designing as much of the implementation as possible. Downloading your abstractions (as opposed to writing them yourself) can be beneficial. Third-party frameworks are almost always the right answer. Choose your frameworks carefully, though. How large is the base library? How much scaffolding is required by the implementation? Will it play nice with other libraries or will it have to be shoehorned into your application pattern.Angular JS
Angular JS looks a lot like a template engine and contains a wide library of services and objects. There are a number of built-in DOM elements. Angular JS code demonstration. - Question: How does the Angular framework wire up the DOM? The presentation in Angular JS is largely in HTML with simple event handling available. Angular also provides a straight-forward routing API. Data focuses heavily on bindings and, in general, Angular encourages the use of MVC for architecture.Backbone
Backbone is an MV* framework focused mostly on logic and very little on the DOM. It relies on Underscore for many utilities. Models in Backbone are built for inheritance and can easily be organized into collections. Views contain all the information about where the view is rendered, but the rendering has to be supplied by the developer.Ember
Ember is a hybrid of Angular and Backbone. Models, views and controllers are called explicitly and theirs a limited set of DOM interactions. Bindings in Ember are bi-directional allowing all modules to be in sync without additional effort. Computed properties give developers flexibility to use the same get/set pattern with compositional results. The auto-updating templates do not require explicit rendering. Selecting a framework for our shopping cart example depends on how trivial the abstractions might be, whether implementation will be mostly templating, and where the data will need to live.Questions & Code
Garann fields a couple questions from the first session and discusses some resources suggested by audience members.
Part 3: Outside Tools
The Reason for Third-Party Tools
Third-party tools implore best practices, save time, and make it easy for code and teams to scale. They may involve managing CSS and/or markup or simply be a set of utilities, plugins or widgets.CSS Tools
CSS is a substantial part of your application and should be decoupled. The right tool can eliminate classes of layout and presentation problems. Object Oriented CSS: Normalize CSS - https://necolas.github.io/normalize.css/Markup Tools
Like CSS, markup is equally as substantial in an application. It’s the foundation behind views and templates. Different deployments allow for the use of non-HTML syntax when defining markup. Markdown - http://daringfireball.net/projects/markdown/ HAML - http://haml.info/CSS and Markup Tools
There are also tools that work with both HTML and CSS. They tend to be more unified and highly configurable. Twitter Bootstrap - http://twitter.github.io/bootstrap/ HTML5 Boilerplate - http://html5boilerplate.com/Dependency Management Tools
Dependency management reduces the need to manually load/import scripts. It removes unnecessary code from the global namespace and is a necessity for robust architectures. Require JS: Yepnope JS - http://yepnopejs.com/Utilities
Utility tools give you big or small abstractions. They may or may not involve DOM manipulation and allow instant access to best practices. Finding the balance between covering use cases and code size is the key to a good utility tool. Underscore - http://underscorejs.org/ Modernizr - http://modernizr.com/ jQuery - http://jquery.comPlugins and Widgets
If you can imagine it, there’s a plugin for it. Don’t reinvent the wheel. While plugins are great, they tend to confine you to another tool. Widgets can be more flexible and easier to incorporate into any pattern. Finding the right plugin/widget can often times be difficult due to a lack of support or unusual implementation.
Part 4: Outside Tools, continued
Testing Tools
Testing is easier said than done. It can be simple and straight forward with synchronous code. Asynchronous code can be much more complex. QUnit - http://qunitjs.com/ Mocha - https://mochajs.org/ Audience Suggested:Linting
Linters check code for possible errors and enforce a minimum set of optimizations. They can also help prevent surprises due to coercion. JSLint - http://www.jslint.com/ JSHint - http://www.jshint.com/Documentation
Documentation will decay if not given proper time and diligence. Postponing documentation causes it to become an insurmountable task. While inline comments are better than nothing, it’s best to adopt a tool to make documentation easier. JSDoc - https://github.com/jsdoc3/jsdocDeployment Process
As an absolute minimum, concatenation and minification should be a part of a deployment process. Node has allowed for many open-source tools to emerge giving developers many options. UglifyJS - https://github.com/mishoo/UglifyJS Grunt - http://gruntjs.com/All-In-One Tools
Mature architectures typically follow the same steps throughout the development process. In these cases, they tend to use the same tools. Finding an all-in-one tool can eliminate a lot of repeated work. Enterprise tools can fit this description but may be less configurable. Garann, of course, favors the open sources. Yeoman - http://yeoman.io/Outside Tools
Garann concludes the discussion about third-party tools with a few additional resources that might come in handy - Node JS: http://nodejs.org/ - Template Engines - CSS Preprocessors & JavaScript TranspilersQuestions & Wrap-up
Final questions from the audience and session wrap-up What do you mean when you say JavaScript transpilers are portable?