Book Image

Building Your Own JavaScript Framework

By : Vlad Filippov
Book Image

Building Your Own JavaScript Framework

By: Vlad Filippov

Overview of this book

JavaScript frameworks play an essential role in web application development; however, no single framework works perfectly for all projects. This book will help you understand existing projects, design new software architecture, and maintain projects as they grow. You’ll go through software architecture principles with JavaScript, along with a guided example of structuring your project and maintenance guidance. This book covers framework planning aspects, enabling you to identify key stakeholders, understand JavaScript API design, and leverage complex abstraction. The second part of the book takes a practical programming approach to building your own framework by showing you how to structure modules and interfaces. As you advance, you’ll discover how to develop data-binding components, work with JavaScript APIs, and much more. While writing a framework is half the job, continuing to develop it requires effort from everyone involved. The concluding chapters help to achieve this by teaching you the crucial aspects of software maintenance and highlighting the constants of framework development. By the end of this book, you’ll have gained a clear understanding of the JavaScript framework landscape, along with the ability to build frameworks for your use cases.
Table of Contents (16 chapters)
1
Part 1: The Landscape of JavaScript Frameworks
6
Part 2: Framework Development
11
Part 3: Maintaining Your Project

My experiences with frameworks

My professional web development career initially started with building basic websites before established frameworks or libraries were around. Looking ahead, I want to share my framework experiences of professionally utilizing them and contributing to some of the open source ones. These days, the accumulated knowledge gathered from these experiences has helped me better assess framework usefulness and introduce new software paradigms into my work. Many find it challenging to keep up with the latest innovations in the JavaScript field, but building even the smallest projects helps one grow as a developer in many ways.

Here are some examples from the full stack development areas that helped me become much more effective as a web developer.

Frontend development

The first few professional websites I built were developed for Internet Explorer 6 and early versions of Firefox web browsers. As we learned from this chapter, there were no frameworks for building web applications at the time, and I had to utilize the few libraries at my disposal. These would help add interactivity for components such as image galleries and dynamic page layouts. Luckily, when my focus switched to larger projects, the jQuery frontend library came along and started growing in popularity. Even to this day, jQuery is still a popular tool of choice for a large chunk of websites. I now had the opportunity to hand-craft a basic framework, which could be reused from project to project. This series of scripts was incredibly convenient and foreshadowed the bright future of frameworks that we have today. It was clear that the trend of single-page JavaScript applications was heading towards structured and opinionated solutions.

During one of my large early-on projects – specifically the Firefox Accounts frontend (accounts.firefox.com), I had the opportunity to use Backbone.js, with the help of jQuery and multiple extension libraries to make it more suitable for large projects. The Firefox Accounts frontend, which is serving millions of users, is still using Backbone.js to this day. The way the Backbone.js framework is structured allows for a soft dependency on jQuery, so it did feel like a natural continuation of my earlier approach to web application development. My key takeaways from this experience are that Backbone.js wasn’t the perfect answer to the challenges of frontend web applications, but it was beneficial in many ways. For example, it allowed the project to stay flexible with the ever-evolving JavaScript ecosystem and helped diverse developers work on the application while following a solid set of application guidelines. The unique opportunity to work on the client and the integrated services of the Firefox web browser taught me how to produce JavaScript components for a desktop client that runs on millions of computers worldwide.

Throughout many professional projects, I had the chance to work with Ember.js, Angular, and various React frameworks. I was impressed by how empowering these frameworks can be on these occasions. A notable mention from my experience is the Meteor web framework, released in early 2012. One of the big selling features of Meteor was the isomorphic or so-called universal JavaScript approach, where the code runs on both the client and the server. In many ways, we see similar approaches in popular frameworks today, where a full stack framework lets developers write JavaScript to develop on both sides of the stack. I have built a few applications and some plugins for this framework, and while it felt so easy to get started with Meteor, I have experienced hurdles while trying to build something that didn’t fit exactly into the scope of what Meteor supported, especially in the early releases of the framework. A particular example of fighting with the framework’s constraints was developing a feature with a synchronized document state across multiple clients. This ended up being challenging to implement with Meteor’s feature set at the time and had to be rebuilt with alternative tooling. Luckily this was not a critical project, but for times when it is important, it is a good idea to evaluate whether the framework of your choice is the right tool for what you are trying to build.

Backend development

During the early years of Node.js, I had the chance to work on several projects utilizing the microservices architecture, and these involved using the Express and hapi frameworks. I felt the contrast between the open-ended approach of the express framework versus the rigorous set of rules and options that were defined in hapi.js. To give some examples, overriding and customizing certain behaviors in hapi.js was quite difficult, and keeping the framework up to date required difficult migrations to the code base.

I still remember combing through the changelog of every new version of hapi.js, making sure not to miss any breaking changes that would make my projects dysfunctional. Even with the hardships of hapi.js, it did feel like the framework was providing a good set of abstractions. In many ways, following the existing examples from something like Flask in Python, hapi had the necessary components to build highly usable services. Meanwhile, my experiences with Express seemed more reminiscent of working with the jQuery and Backbone.js days. In the Express projects, I could have a highly flexible development environment, combining different Node.js modules to achieve what I wanted from the framework. This made me realize that the perfect framework for me would be something between Express and hapi, in the sense that it would allow me to stay creative, highly productive, and able to utilize the runtime ecosystem to the fullest, while at the same time having a strong opinionated framework core, which would keep my application efficient and reliable.

Developer tooling and more

As part of my profession, I have always been passionate about open source, so I focused my efforts on contributing to developer tooling and testing frameworks. I have been a maintainer of Grunt.js (gruntjs.com), a JavaScript task runner for many years. Grunt.js has been a core component of frameworks, such as Yeoman, and has been used as a tool of choice in the early version of AngularJS. The task runner conventions in Node.js have changed a lot since then, but there is still a solid number of projects that use Grunt.js. Maintaining this project for many years feels similar to maintaining a large framework project – releasing new versions, keeping a stable API, supporting it through security bounties, and much more. There is also a huge list of issues, feature demands, pull requests, and plugins to support.

In terms of my testing framework contributions, I was involved in developing the Intern.js testing framework (github.com/theintern), which enabled unit and functional testing for web applications. I was both the contributor and the consumer of this framework in my daily projects, which gave me a unique angle on the project. I was inspired to provide a good integration experience because it would aid my own projects. As part of this effort, besides learning how a testing framework is built, I focused on developing integration examples and documentation for other application frameworks. Covering many integration scenarios in the provided examples made it much easier for developers to integrate this testing system into their applications.

A final notable framework from my personal experience would be with voxel.js – an open source voxel game-building toolkit. While not that popular, it is a great example of creative use of JavaScript, combining both frontend and backend technologies. It is a framework built by a small team that fills in a niche for an audience of developers, who are looking into working on games and visualizations. voxel.js did not set out to be a world-changing framework; instead, it was a creative outlet for many to create. While exploring voxel.js in my personal project, I learned a lot about unique framework and module structures, and it was fun to experiment with systems that enable more imaginative thinking.

Contributing to new projects

These experiences with JavaScript frameworks in frontend, backend, and developer systems were incredibly valuable to me as part of my career. I have learned the importance of following best practices, adhering to software patterns, and developing for various runtime environments, which ultimately helped me write better code and deliver successful projects. As part of this book, I am sharing my learnings and as much knowledge as possible for the next generation of devoted JavaScript developers to build and contribute to their own framework projects.

The projects that I have been involved in always had different origins. In my case, I had to work with both private and open source frameworks. In work projects, I have focused on combining open source tooling with the context of the larger business organization. This approach helped align the existing tooling with the requirements of particular projects. In the open source context, I have been lucky to contribute to projects that have improved the overall developer experience. In many of the scenarios, I got to work on projects that were innovative and were firsts of their kind in the JavaScript ecosystem. For example, when Grunt.js was coming along, there were task runner tools from other languages, but the JavaScript tools were in their inception. Contributing to voxel.js was a similar experience; as more HTML5 APIs and WebGL enable more advanced graphics on the web, it enabled voxel.js as a project and created the contributor community.

During my contributions to the Intern.js testing framework, the overall feeling was that there were not fully fledged testing frameworks that solved all of the needs of web application testing. The goal of this project was to create an all-in solution for testing using the same types of testing APIs.

The framework that we create in this book focuses on the use of modern technologies, such as Web Components, intermixed with popular JavaScript libraries. The Web Components field does not feel as explored in the ecosystem just yet; therefore, with this book, we are taking aim to further widen the knowledge of these technologies among web developers. Besides expanding those skills, one of the greater goals is to make the framework development process more approachable and demystify the established JavaScript systems.