Maybe you’ve heard the term “Modern Web” before. It embodies the idea of a constantly evolving, exciting platform that unique and powerful user experiences can be built upon. It is a platform that new capabilities are added to regularly, not waiting for long release cycles.
And maybe you’ve been asked to build a “modern web application”.
Let’s look at what a Modern Web Application might look like, considering only the pieces that are loaded into the browser (the client-side pieces), putting aside for now the whole story about what is running on the web server itself.
If you really want to track the health of your source code, a tool like Plato can be used to analyze the complexity and overall maintainability of your code. Taking snapshots of your code through this tool helps you determine if your team is heading in the right direction while maintaining and enhancing the code.
Many applications intermix code that interacts with the browser’s DOM (Document Object Model) with code that performs business logic with code that calls web APIs. In these cases it’s very hard to test the code in isolation. There are too many overlapping concerns that tests cannot be easily written to verify that the code is working correctly. Too often in the face of this, teams just abandon testing – at least all but the most laborious manual testing delegated to the unfortunate QA team.
If you do apply a bit of rigor to your development, you should be able to create isolated components. Then you can write tests using one of many testing frameworks. Jasmine, Mocha, and QUnit are all popular testing frameworks. These are generally used to create Unit Tests, which differ from end-to-end or integration tests in that the goal is to test a single component in isolation, usually mocking the dependencies that the component may have.
When you mock a dependency within a unit test, you are simulating an expected result the dependency might produce or just verifying that the component that is under test used the dependency in the expected manner. Jasmine has “spies” that can be used for this purpose, but other libraries exist that provide additional mocking functionality as well, like Sinon.JS.
Writing the tests is one task for your project, but there are also tools that help you run the tests, even automatically after you save files within your editor. A tool like Karma can watch for changes in your source code and automatically run the tests, giving you immediate feedback if your changes have inadvertently broken something. Systems like Gulp and Grunt can also be configured to watch files and run tests (and other build steps too, see below).
End-to-End / Integration Testing
Unit testing is important and can catch errors in the individual components of your application, but end-to-end and integration tests catch errors and validate functionality when these components are brought together. An end-to-end test would test from the browser page itself all the way to the back end Web APIs as if a user was sitting in front of the application. An integration test might only test portions of the stack, maybe just testing a service that calls a back-end Web API.
For this type of testing, you are testing with a real browser. You need a way to operate the browser itself and examine results. And you need to work with multiple browsers. Fortunately, Selenium WebDriver is a tool that can be used to automate user interactions on many different browsers. It can “drive” a browser, navigating to pages, interacting with user interface elements, and inspecting the results.
You can certainly write scripts to test your application with Selenium, but there are other tools that sit on top of Selenum that can then be used to write tests similar to the unit tests you might write. For example, Protractor, wraps Selenium and provides a testing environment and functionality that helps to identify and inspect components within AngularJS applications.
If you want to expand testing to the widest variety of browsers, including browsers that run on devices like an iPad tablet or Android phone, then there are services that provide access to physical and simulated devices that automated tests can be run against. SauceLabs and BrowserStack are two popular options.
How do you build your Modern Web application? These days, you certainly don’t start from scratch. There are too many good frameworks and libraries to build on. Most are free to use within your own application due to a community that values openly sharing these foundational tools with each other.
Any framework deals with an abstraction on top of the Brower’s DOM and related services (like the XMLHttpRequest object). jQuery was the first to really popularize these kinds of abstractions. Later, Backbone.js sought to focus on the model data you might use in your application, providing ways to define your models and interact with web services. Knockout.js focused on more easily integrating application code with DOM events.
Then higher-level and more comprehensive abstractions became popular. Ember and AngularJS provide a framework that covers more of what a web application might do. They prescribe patterns and provide conventions that can be used to make web applications more scalable and maintainable.
Web Components are yet another way to abstract and extend browser functionality.
You also have to consider the content of your web application, including how the content is generated as well as how it will look.
You might use templates to generate the HTML. A template specifies a subset of the overall HTML that is rendered into the page. Multiple templates can be merged together to generate the final HTML. Handlebars and Jade are used widely. On the server side you might dynamically render your HTML from your application, but you can also pre-render templates and have your web server deliver the resulting pre-generated content.
The content itself will be styled using CSS. But fortunately, you don’t have to start from scratch with design. Bootstrap and ZURB Foundation provide a great starting point for nice-looking web content. They also have the advantage of providing a “Responsive Design“. This is where a web site looks good on a web browser but also collapses and otherwise adapts itself to display well on smaller devices (like a phone).
When designing your application for mobile platforms, responsive design helps to ensure that your web application works well on whatever device it is used. But there are other considerations as well. For example, for images that are displayed within your application, you might want to optimize these images for best download speed.
Client Side Building
So you may have noticed that some of this work has to be done offline. This is a major component of a Modern Web Application – assets for your web application are generally built (pre-processed) before becoming part of your web application.
To perform this build, almost certainly you’ll end up using NodeJS (or the recent forked version of it, io.js). All of the components to build assets for Modern Web applications will be found in Node modules.
There are a number of build system implemented in Node. I already mentioned Gulp and Grunt. What do you build, then?
CSS files supports vendor prefixes which are specific to a particular type of browser. The Autoprefixer tool can automatically identify the CSS elements that need these additional prefixes and add them to your CSS.
To ensure that the latest copy of the files always get to the browser, a version number or other identifier is added to the file name, either as a query string parameter or by modifying the name of the file. This identifier ensures that the browser will request the file if the identifier is changed. This is called cache-busting.
If files are concatenated together or the file name is changed, then the reference to the file must be changed as well. This might be a
There are many other tasks, minifying your HTML files, automating the analysis of your image files for optimal delivery, or setting up watches for files being changed to automatically build the affected assets.
So … What Next?
If you made it this far, you might be overwhelmed by the scope of technology involved in Modern Web Applications. Fear not, though. And don’t give up. It is truly amazing what you can do with web applications these days. It’s worth the effort to learn this stuff and a great time to be working with it.