JavaScript: Developing a Custom Framework for Single-Page-Apps

SPAC is a custom JavaScript framework for client-side, single-page web applications. It stands for “Stateful Pages, Actions and Components”. Its design goal is to provide robust and simple entities that help you to structure apps. Pages and components provide the HTML, JavaScript functions and UI internactions. Actions govern external API calls. You define these entities in plain js, load up the central controller, and you app is ready to be served. Read the development journey of SPAC in my series: https://admantium.com/category/spac-framework/

This article introduces the SPAC framework. Before we dive into the design of the framework itself, we will briefly touch upon how JavaScript is loaded in your browser — this understanding is the foundation how to structure your code. Read along and get some ideas and inspirations how to make PlainJS projects more maintainable.

This article originally appeared at my blog admantium.com.

Essentials: JavaScript in your Browser

As a developer, you have different options to load JavaScript — and they all behave a bit different.

Load JavaScript file with the <script src=""> tag

  • The browser stops loading any other resource. It will execute all code in the context of the global object. Variable declaration will happen in this global space.

Define inline JavaScript with ` code tag

  • The browser stops loading any other resource. The code can access all variables defined in the global scope. It is not possible to either load additional modules, or to declare modules that can be imported with statements in other <script> tags. It will execute all code in the context of the global object. Variable declaration will happen in this global space.

Register inline event listener on input elements, like <button onclick=parseData>

  • The browser will define an event listener for the DOM object by the given function name. In JavaScript, function definitions in the global namespace will be hoisted up, which means you can use a function name before its declaration. However, the browser also happily allows a undefined function to be used in this context - this can result in hard to figure out bugs.

Load JavaScript modules with the <script src="" type="module"> tag

  • The browser stops loading any other resource. It will execute all code in the context of the global object, but allow the definition and loading of modules.

Depending which methods you use, different challenges need to be considered:

  • Page load interrupt: Some methods will stop the browser from loading any additional resources before the JavaScript is parsed completely. If you load either very complex code or a lot of code, this might interrupt the page load speed
  • Execution context pileup: When you constantly load new scripts from newly rendered pages, the total amount of JavaScript inside the browser thread continues to pile up and can slow down the page performance
  • Namespace pollution: Inside the browser, the global object will be window. Any JavaScript that is executed can change the definition of the window object. It can happen that you accidentally overwrite function definitions when scripts on different pages use the same function names, because they will be re-defined the global object.

With this knowledge, we can now design the essential requirements of our custom framework.

Architecture of the Custom Framework

In a nutshell, the requirements are:

  • Use JavaScript modules to keep the namespace clear
  • Separate the application into the controller, action, and pages & components
  • Encapsulate HTML and JavaScript in the relevant components
  • Dynamically load and execute only required JavaScript

Let’s consider the central building blocks of the framework one-by-one.

JavaScript Modules

Controller

Actions

Pages and Components

Components work similar to pages: They also receive a root DOM and the state. They build their own DOM and attach JavaScript to it. The difference is that they provide additional helper functions that are specific to this component, complex UI functions or even functions that operate on the state.

State

Conclusion

IT Project Manager & Developer