Web Frameworks: Using and Developing

By on August 23, 2017 10:02 am

Let’s figure out how to play our album. Is it a 45 vinyl or some sort of fancy SACD? Gaining insight into how we might develop and deploy an application built on a web framework helps us figure out if it is the right fit for our team.

In this post, we are going to explore how you might approach the workflow for a given framework, what sort of surrounding tooling is provided or recommended by the framework, how applications get built and deployed, and what sort of support there is for figuring things out when something inevitably goes wrong.

This is part of a series on web frameworks. If you have missed our previous posts, you may want to start with If we chose our JavaScript framework like we chose our music…

Typical workflow and roles

In some situations, applications are developed by a sole developer, or a small team. In larger situations, the roles become much more separated. Some frameworks are specifically designed for making it easy to separate out these roles, while others do not really give much thought to roles and just focus on the technology. How easy it is to scale and manage the development of an application can be a big factor in the success of a project.

Tooling

Long gone are the days of building a website with Notepad. With today’s feature-rich possibilities for web applications, the tooling ecosystem is extensive. Sometimes, selecting our tools is as complicated as choosing our framework. We need to explore how the frameworks make our lives easier, and if there is enough flexibility to allow for a bring your own tooling if desired.

Build and deployment

Authoring a web application might be the easiest step in the process. Ensuring that all of our HTML, CSS, and JavaScript source code can actually be optimized and deployed so our users can access our application, is a different story. Looking at the out of the box build pipeline and determining how straightforward it is to integrate the framework into an existing pipeline is another major consideration of whether or not a framework is right for you.

Debugging and instrumentation

After we have authored our application and it is deployed on a server and users are using it, we may think we are finished, but we are not. Eventually something will break and our users will take to Twitter demanding that we fix their application because of the irrevocable damage we have done to their lives. How are we going to figure out what has gone wrong?

Jump to:

  • logo
  • logo
  • logo
  • logo
  • logo
  • logo

Angular 2+

Typical workflow and roles

Angular 2+ is not designed with any particular workflow or developer roles in mind, but there are some natural concepts that allow a level of separation of the different roles within a team. As explored in the application approach, Angular has strong concepts around components and services. These can be addressed as two separate concerns, where designs are manifested in templates as components into views and others on the team focus on creating the services to provide the right data to those views.

Angular 2+ provides a tool for mocking data in applications, called in-memory-web-api, which can be used to provide data to the services. This would allow further decoupling of activities between the UI development and the data integration.

Specific consideration should be given to how components and views are constructed. It is easy with Angular 2+ to leak concerns outside of a component with the templating language that Angular 2+ provides. Combine this with two-way data binding and it can quickly become challenging to unpick the flow of data through an application, thereby difficult to identify a logic error in the application.

If using the Material 2 UI components, you would have a rational set of UI components that support a specific UX and are designed to not leak their concerns into the rest of the application. If you are building your own set of components, or using a third-party set of components, ensuring that they are well designed and do not leak their concerns is a critical consideration. Components that are not well designed can make it quite easy to create difficult to maintain applications and decrease the amount of re-usability and consistency with downstream development.

Tooling

Angular 2+ provides a feature rich command line tool called Angular CLI. It provides the following features:

  • Creating a project
  • Adding functionality to projects (adding components, routers, services, and pipes)
  • Serving an application on a local machine
  • Testing, linting and formatting
  • Building
  • Tooling for i18n to extract text resources for translation

Angular 2+ focuses on providing all of its recommended tooling via the CLI. If you want to vary from the prescribed, opinionated way, the CLI supports the concept of ejecting to provide a scaffold for integration with other tooling.

Build and deployment

For many scenarios, Angular 2+ applications can simply be built with the Angular CLI Build command. This uses webpack with a pre-configured build profile that generates a deployable bundle to the /dist directory of the project.

Using the CLI command Eject will remove the CLI command from the project, leaving behind a webpack configuration file with some other scripts. This is designed so that it is easier to integrate an Angular 2+ project into a different build pipeline, or combine it with other projects to create the appropriate assets for deployment.

Debugging and instrumentation

The CLI Build tool preserves TypeScript and JavaScript source maps, so that the original authored code can be determined at run-time. This should make it possible, in most browsers, to debug applications with the browser’s debug tools, working with the source code, versus trying to track issues against transpiled source code.

When building the application in development mode, the Angular CLI will expose a global ng object which provides an easier way to interact with the application in the development console of the browser.

There is a development extension for Chrome, Angular Augury, which provides additional tooling for debugging and profiling Angular 2+ applications.

React + Redux

Typical workflow and roles

As discussed throughout this series, React and Redux are tools, and not an opinionated framework. This also means that there is significant flexibility. Numerous decisions must be made around workflow and how work will be separated amongst the team. Naturally, because React is just about making components, and Redux is just about state management, those two separate concerns are easy to divide amongst team members. It is easy to author re-usable components which then can be built into applications.

With actions and reducer functions with the Redux state container, it is designed to make it easy to separate those activities without a developer needing the full context and understanding of the application.

For focused efforts, rapid, structurally sound applications are relatively straightforward to create. We believe though that without establishing many conventions up front, it can lead to maintainability challenges. It is as easy to create a well designed component as it is a poorly designed one. It is also quite easy to have confusion around what is in the state container and what are the best and appropriate actions to operate on that state. It cannot be stressed enough that if the team is larger than an individual developer, it is critical to ensure there are documented conventions on how to use both React and Redux.

Tooling

React and Redux are focused libraries that each do one thing well. Neither project considers tooling to be a focus of their solutions. That does not mean tooling help is unavailable. In fact, there is a rather robust ecosystem of solutions. React provides a list of tools they feel help with React development. React has a semi-official scaffolding tool named create-react-app which will create an initial project structure.

Redux really strives to have no opinions about tooling, even trying to avoid giving specific advice on build tooling.

While both React and Redux focus on how a complex toolchain is not required, it is, in a way, a false economy. Because it is unlikely that any substantial application will be built just using React and Redux, the end developer is left to piece together the rest of the puzzle. In the right hands, this non-opinionated and unconstrained approach is great, for some it is daunting and frustrating, and for others it could lead to dangerous overconfidence.

Build and deployment

Building and deploying decisions are left to developers. React is authored in modern JavaScript (and recommends JSX), which, depending exactly on the target environment, almost certainly requires transpilation. React recommends using Babel to transpile source code.

Redux provides several different distributions so that transpilation and bundling is not required, though in practice, being part of a larger application, a more extensive build and deployment pipeline is required.

Debugging and instrumentation

React offers an official set of dev tools, providing intelligence to a browsers development tool to make it easier to debug and instrument a React application.

React (and many related React libraries) follow the convention of looking at an environment variable named NODE_ENV and if its value is not set to production. This adds additional run-time checks to the source code to make it easier to develop and debug a React application. React provides a development distribution with this pre-enabled in the code, though consuming React in this way is fairly uncommon as it is usually part of a larger build pipeline.

Redux does not have any official development tools, though there is a community Chrome extension which incorporates some other community projects to provide a robust set of tools to make debugging and instrumentation of Redux applications simple. In particular, this extension leverages the reactive and unidirectional data flow concepts to provide a time-travel mechanism for debugging Redux applications.

Vue.js

Typical workflow and roles

Vue.js focuses on being incrementally adoptable and being component centric. This tends to lend itself to a workflow of creating components in an Model, View, ViewModel type of application architecture. This could lead to separability of the work on the model and the view, though this may be difficult to accomplish in practice and you would decompose parts of the application via the application routes.

Because Vue.js is non-opinionated about the UI/UX part of an application, it does not place constraints or specifically enable a workflow from design through implementation.

Tooling

Vue.js provides a command line tool which primarily focuses on greenfield application scaffolding. Depending on the scaffold template used, additional build and deployment tasks might be integrated into the generated package. Ultimately though, Vue.js is designed to be incrementally adoptable and therefore focuses on providing significant information on how to best integrate it into tooling that the developer or development team is most comfortable using.

Build and deployment

Overall, there is not much to building a Vue app. Vue applications may be run with or without a build step. Without a build, a host page loads the minified Vue build and any component scripts and assets. With a build, a build tool like Webpack, Browserify, or Rollup is used to bundle up Vue.js and the application into a package.

The focus is very much on trying to provide sufficient information to integrate Vue.js into an existing toolchain.

Debugging and instrumentation

Vue provides an official devtools extension that works in Firefox, Chrome, and Safari. The extension can display the Vue component tree, component properties, and DOM connections. For applications using Vuex, the extension also allows time-travel debugging.

Dojo 2

Typical workflow and roles

Dojo 2 was designed to try to work well in larger teams, where different roles could be easily separable. While development teams could easily combine these roles, they are designed to be separable. Widget functionality is designed to be separated from the look and feel of a widget, and with a robust theming system, widgets can be reused and combined with a theme that adjusts the look and feel of the application. This allows the designers to express their design and make it easy to translate that into the UX without tight coupling of the widget developers and the design implementers. Also, with the one-way flow of data as part of the Dojo application architecture, the user interface is decoupled from the application logic and state, meaning that different developers can work on different aspects of the application with minimal impact on the work of others.

Tooling

Dojo 2 attempts to provide a fully opinionated solution via its command line interface. Dojo 2 provides the ability to scaffold a project or a new widget. It provides a build option that uses Webpack with configured loaders and plugins to produce an efficient build. It also provides an integration with Intern to provide a full solution for testing needs, including unit, functional, performance, visual regression, and accessibility testing.

The @dojo/cli commands support ejecting from a project, so if the opinionated tooling is not sufficient, or there is a desire to integrate a project into an custom toolchain, the command can be ejected leaving behind configuration information for further customization or configuration.

Build and deployment

The @dojo/cli build tool provides a production ready bundle ready for deployment to a server. The tool uses Webpack with some specialized loaders and plugins.

Also, widgets can be exported as standalone web components, which can then be used in other non-Dojo 2 applications.

Debugging and instrumentation

The @dojo/cli build tool can build a version of the source code which provides more debugging information at run-time, specifically about how the CSS module class names are namespaced. The Dojo 2 team plans to add a more complete solution, likely including a DevTools plugin which can provide more insight into debugging a Dojo 2 application.

Ember

Typical workflow and roles

Ember.js structures itself as an MVP application framework for the web. Given this model, it is very logical that an MVP type of workflow can lend itself to working well with Ember.js. That being said, it is ultimately a web application, where the application route/URL is the core concept that applications are developed around. So the design of components can be decoupled from the rest of the application and the application can take a very top down approach from the URL to Route to Route Handler to Model/Template to Component approach to break down the work within a larger application.

Because Ember.js is not opinionated about the UI/UX, the flow from UX design to implementation is also not opinionated.

Tooling

Ember.js has a feature rich, extensible CLI which provides a significant amount of tooling for every aspect of developing an Ember.js application, from adding routes and dependency management, through to build optimization and testing. There is also a significant amount of third-party commands for the ember-cli system.

Build and deployment

The command line tool is an opinionated system for building an Ember application, and solid documentation on build and deployment is available for Ember.

Debugging and instrumentation

Ember.js provides a debugging tool named Ember Inspector. This will allow developers to visualize an Ember application at run-time. This harnesses much of the instrumentation that is available from an Ember.js application as well as helping you continue to maintain your Ember application as the Ember APIs continue to develop and change, by being able to detect usage of deprecated APIs. There is also the ability to measure and determine the performance of your application.

Aurelia

Typical workflow and roles

The application model between Angular 2+ and Aurelia is very similar. Also similar is that Aurelia is not designed with a specific workflow in mind. Aurelia focuses on components and templates organized in routes with services providing information from the server-side. Because there is such significant two-way data binding throughout the solution, it can be difficult to demarcate between the templates, the components and even the CSS from a look and feel perspective.

Tooling

Aurelia has a CLI which provides the ability to scaffold, test, and build your Aurelia applications.

Aurelia also provides information on how to integrate Aurelia into other build pipelines and tooling including Webpack and Gulp with JSPM.

Build and deployment

The Aurelia CLI provides a build command, which can also generate optimized bundles for deployment to production environments. There is some control over bundling provided by the CLI.

Debugging and instrumentation

One of the more unique focused features for Aurelia applications is there is a library for creating and comparing performance benchmarks for your app. For debugging, there is the Aurelia Inspector chrome extension, which provides additional information about Aurelia elements and the Aurelia Tools repository, which apparently has “tools used in the development of Aurelia itself as well as the source for browser debugging tools”, but lacks significant documentation at this time.

Summary

Angular 2+

We feel the overall architecture of Angular 2+ can lead to difficult to manage code in large teams. This can be mitigated by making sure conventions are well established and there is thought about how to separate the work. Angular 2+ comes with a feature rich CLI which makes the out of the box experience simple and provides sufficient information for integrating into other build pipelines. There are official resources for debugging and profiling applications, as well as a large community of alternative solutions and information.

React + Redux

The React and Redux libraries focus on providing functionality and make the assumption that they will only be part of a bigger picture and not attempt to inject much opinion. This means that it is even more critical to understand how you are going to build and develop applications built on React + Redux in order to avoid having projects that are difficult to maintain or do not deliver on their objectives.

Because there is significant community interest in React + Redux, there is a rich community of examples, tutorials, and help available, but like many things for every person espousing the right pattern, there will be someone claiming that it is actually an anti-pattern. For situations where there is a large amount of fundamental knowledge of web technologies and a willingness to set clear guidance, React + Redux can be a great solution. If there is not that strength, you can end up with solutions that are impossible to get working and maintain.

Vue.js

Vue.js focuses on an incrementally adoptable approach and that comes through in how they deal with their approach to development. It feels as if the framework automatically assumes it will need to co-exist with a larger solution. Because of this, Vue does not express strong opinions about how to go about developing with it and focuses on being as easy to use if the whole application is built on top of the framework or only parts of it. Also, while Vue.js focused originally on MVVM, their state container solution of Vuex would require you to structure your application quite differently. This could easily become confusing to a team which lacks a depth of experience in web application development.

This lack of opinion can lend itself to applications where there is continued incremental change, instead of a rip and replace type of approach. Also, greenfield developments on Vue.js might suit as well, but if there is not a toolchain or build pipeline, expertise to set this up and start using it would likely be needed.

Dojo 2

Dojo 2 was specifically designed to try to accommodate building complex web applications in an enterprise environment. As Dojo 2 is still in beta, it has not yet fully realized that vision, though the foundations are clearly there. Dojo 2 strives to balance having an opinion and a right way, but still allow enough flexibility to not constrain an experienced development team.

Again, while not fully polished, building a complex application with a minimally experienced team is possible. If you are looking for a framework that leverages modern standards and tries to focus on building complex enterprise web applications, then Dojo 2 might be right for you.

Ember.js

Ember.js likely has the most feature rich wrap outside of its core framework. It has an extensive ecosystem of other solutions tool and has provided stringent guidelines on how to fit into that ecosystem. There is a very clear Ember way of doing things. For teams that need a high level of structure and significant opinion about what the right way is, Ember.js fits this bill. If you are not sold on the Ember application model, teams may find it difficult to leverage only certain aspects of Ember.js.

Our feeling is that it is largely a binary decision of either leveraging the complete Ember.js ecosystem, or using something else.

Aurelia

While Aurelia keeps closer to standards than Angular 2+, it still has what we feel is an application model that can be challenging for large teams to create and maintain an application over a long period of team. It is easy to leak concerns across the application, making it difficult to reason out how a complex application works. Having strong architectural standards and strong enforcement at development time is required. There is sufficient documentation to be able to integrate an Aurelia application into a larger pipeline.

Up Next

We have taken a look at some of the basics of how actually developing an application might work, but in order to have a robust application, we have to accomplish the mantra of “test early and test often and test some more”. In the next article, we will delve into how to approach testing for these different frameworks and if there is any secret sauce that the frameworks can add.

Other posts in the series

Comments