Building a Large Stock JS Application

By Matthew Smith — Sun, 15 Nov 2020 — Permanent Link

ArchitectureDevelopmentJavaScript

Learn how to build a simple, large scale vanilla JS application.

Architecting large scale JavaScript applications can be challenging. It requires planning for security, growth, and complexity over the lifespan of the app. Developers often adopt a front-end framework to make life easier. But, these frameworks come with many challenges that are often overlooked at the launch of the product.

  • JS frameworks come with an upgrade cost. Small updates can be distracting and take time away from other priorities. Updates that have breaking changes can lead to an entire re-architecture of your platform.
  • JS frameworks go in-and-out of fashion. If you started building an app a few years ago in Knockout or AngularJS, you might find your codebase woefully out-of-date now that Vue, Angular, Svelte and React are the popular choices.
  • If you are building something more complex than a typical CRUD app, you may find yourself building more complex code to work around a framework that does not accommodate your use case.

If you are a corporate dev team with many developers, these challenges may be acceptable when short term developer enthusiasm and skillset availability may trump longterm goals for a project. But, if you are an entrepreneur or a small business, I highly recommend you take a serious look at stock JS before jumping into a framework. Modern JS has gotten to the point where you can build a solid code base that is elegant and maintainable without any of the framework challenges I mentioned earlier.

Even with stock JS, I don’t recommend jumping into a codebase without a strategy. Morris Broderson (https://morrisbrodersen.de/) recently published a case study on structuring a to-do application using stock/vanilla JS (https://github.com/morris/vanilla-todo). He set forth a set of patterns to make developing clean, reusable code. I think he provides a great framework if you are in search of a well thought out pattern to start from. But, my personal approach is much simpler. I use these three patterns to build my Stock JS apps.

  • Classes for code modularity
  • Simple event handlers for UI events
  • Custom JS events to communicate between classes

In practice, this looks something like the following:

/*
 * Models a simple component
 */
class MyComponent {
	constructor() {
		this.view = `<div id=“my-component>”
			<button id=“my-component-button”>Click</button>
		</div>`
		// append view to DOM
 		document.body.insertAdjacentHTML('beforeend', this.view)
		// get references
		this.component = document.querySelector(“#my-component”)
		this.button = document.querySelector(“#my-button”)
		this.setupEvents()
	}
	setupEvents() {
		// handle and pass events to other components
		this.button.addEventListener(‘click’, function(e) {
			//-- do something
			window.dispatchEvent(new CustomEvent('app.showUpgrade', 
{detail: {data: `custom-data`}})) }) // listen to events from other components window.addEventListener('app.imageUploaded', data => { context.edit() }) } }

let myComponent = new MyComponent()

That is really it.   Using this simple pattern, I created both Profit Apps (Profit Pages and Profit Pix) applications. Having come from building a large application using Angular, I can tell you that this amount of simplicity is a breath of fresh air.  About the only thing I miss is the data binding that came with the framework.  But, I would much rather write some additional low level code than to have to deal with the complexities of the framework.