Welcome to Day 26 of #30DaysOfPWA! New to the series? Three things you can do to catch up:
- Read the kickoff post below for context.
- Watch the GitHub Repository for updates.
- Bookmark #30DaysOfPWA Blog for resources.
Welcome to #30DaysOfPWA
Nitya Narasimhan, Ph.D for Microsoft Azure ・ Feb 14 '22
This is a shortened version of this canonical post for the #30DaysOfPWA.
About The Author
Today's post is authored by Zach Teutsch - a software engineer at Microsoft focused on Windows Native and PWA Development. Follow Zach at @devteutsch.
Welcome to week 4 day 5 of the 30 Days of PWA series! In today's post we learn what maintainability looks like in large-scale PWA projects.
Where Do We Start With Maintainability?
Keeping our PWA maintainable, or any application for that matter, can be a serious undertaking with tons of unique challenges. The web capabilities that make PWAs possible allow for more capable and complicated web experiences, but it comes with a price. How do we keep our increasingly complex PWA projects clean and extensible?
Out of the many options available to us, today we'll be looking at one technology we can leverage in our projects: web components!
Web Components?
Web components are set of web technologies that allow you to create custom standalone components (like your very own <custom-button>
, for example) that work anywhere on the web. They come with a whole suite of development advantages, including project maintainability. Check out this "Why Web Components?" article for a quick primer on what Web Components bring to the table.
Now, let's take a look at how web components can improve our PWAs and make our projects more maintainable.
Encapsulation with Shadow DOM
When we create a web component, all of our behavior, html, and styling is contained to that component. We don't have to worry about it interfering with other aspects of our project when we include our component in our application. This a huge bonus for maintainability: it allows us to segment our code and avoid overly-verbose spaghetti code in our project files. Additionally, for larger PWAs that may have multiple developers working at once, web components allow for concurrent contribution by keeping unrelated components separated from each other.
Web components make this possible using Shadow DOM, which allows our component to live in a "hidden" portion of our larger DOM tree. We can prevent clashing with the rest of our DOM by isolating the portion related to the web component.
Web Standard
Web Components are a Web Standard, which means they are considered a fundamental model for component behavior on the Web. This means we can rely on the web components we build to work just about everywhere:
Another benefit to this is that web component frameworks are generally small and fully interoperable. This means that you can use web components within larger modern frameworks (like React or Angular) and they will still work as expected. You can even ditch the frameworks all together and build web components in vanilla javascript.
As far as maintainability goes for our PWAs, this is great. We know our components will work in different browsers and frameworks, and we don't have to write extra code to keep our project functional. When we go to update or extend one of our components, we can work freely without worrying about compatibility issues. Web Standards also generally guarantee forward-compatibility: our components will still work as the open web grows and changes.
Building Web Components with FAST
There are lots of framework options for building web components, but today we'll be using the FAST framework to see a beginner example.
Let's say we are building a naive <movie-review>
element that will live in an MovieReview.ts
file.
First, we can start with an element with a few attributes:
import { FASTElement, customElement, attr } from '@microsoft/fast-element';
@customElement('movie-review')
export class MovieReview extends FASTElement {
@attr movieName: string = "No Movie Listed";
@attr rating: string = "0";
}
Next, we can provide an HTML template so we can display our attributes:
import { FASTElement, customElement, attr, html } from '@microsoft/fast-element';
// our html template for our component
const template = html<MovieReview>`
<div class="reviewDiv">
<div class="nameDiv">${x => x.movieName}</div>
<div class="ratingDiv">${x=> x.rating} stars!<div>
</div>
`
// that we can pass into our customElement
@customElement({
name: 'movie-review',
template
})
export class MovieReview extends FASTElement {
@attr movieName: string = "No Movie Listed";
@attr rating: string = "0";
}
We could then use our element like so:
<movie-review moviename="Fast and Furious: Tokyo Drift" rating="5">
This is just going to give us some boring black text. Let's see how we can add styling:
import { FASTElement, customElement, attr, html, css } from '@microsoft/fast-element';
const styles = css`
.reviewDiv {
border: 1px solid black;
display: inline-block;
padding: 10px;
}
.nameDiv {
font-size: 24;
font-weight: bold;
font-style: italic;
}
.ratingDiv {
color: blue;
}
`
And we can pass those styles in just like our template:
@customElement({
name: 'movie-review',
template,
styles
})
export class MovieReview extends FASTElement {
@attr movieName: string = "No Movie Listed";
@attr rating: string = "0";
}
Our beautiful component would then look something like this:
We now have a reusable <movie-review>
component. As you can see, this example is fairly naive, but you can start to imagine the possibilities. Let's say we had a more in-depth <movie-review>
component that we could use inside a related <movie-review-list>
component. We could then change the appearance and functionality of our movie reviews separate from the list that displays them, allowing us extend and update our <movie-review>
component regardless of the environment it lives in. Encapsulated and maintainable!
If you want more depth on building quality components and adding functionality, or if you want to leverage the dozens of pre-built components FAST offers, check out the FAST documentation.
FAST isn't the only way to build web components: check out this blog post for a comprehensive list of options.
Wrapping Up
Today, we learned how we can write maintainable web code and power up our PWAs with web components. We just barely scratched the surface of web components and the FAST framework, and there's a ton more to dive into if you want to really make use of web components in our PWAs. Check out the resources for more learning!
Resources
- FAST documentation
- MDN documentation on Web Components
- Building PWAs with Web Components article by Justin Willis
Want to read more content from Microsoft technologists? Don't forget to follow Azure right here on dev.to: