Everything you need to build and deploy a maintainable single page app. This course covers a broad range of topics as we build an app from scratch using React, Ampersand, ES6 (ES2015), and Webpack.
Henrik also covers lots of extra little goodies like hot-loading and auto-prefixing your styles without the need for browser extensions, securely implementing OAuth using Github’s API in the client, deploying a microservice, deploying you front-end app as static files, and pre-rendering your app at build-time for incredible performance.
Modern Web Apps
Foundations of a Web Application
00:00 - 15:23
Henrik Joreteg begins the Single Page Modern Web Applications course with a brief overview of what he’ll be covering. Henrik also walks through the Hubtags application that will be built throughout the course.
- 15:24 - 20:36 Project Setup Henrik walks through the project files for the course. He begins by describing the NPM scripts included in the application. He also discusses why he will be using Webpack for packaging dependencies.
- 20:37 - 26:08 Creating a React Component Using the ReactJS framework, Henrik creates a simple React component that will write some content to the page. React uses JSX to specify the HTML elements to be rendered.
- 26:09 - 36:10 React and the Virtual DOM Henrik dives a little deeper into the way ReactJS renders HTML. React abstracts itself away from the DOM giving developers a simple programming model and better performance when rendering. Henrik will be using React to create UI elements in the Hubtags application.
- 36:11 - 41:51 Using ES6 Henrik converts the code he’s written so far from ES5 to ES6. He will be using ES6 throughout this course. Webpack was preconfigured to use Babel for compiling the ES6 code.
- 41:52 - 53:53 Creating Styles Webpack looks at the extension of the style file to determine how to compile the styles. Henrik demonstrates this starting with a .css file and switching to a .styl file. Styles are included in the application using an import or require statement.
- 53:54 - 1:04:55 Handling Routes A router handles different URLs within an application. Henrik defines a simple router and demonstrates how to create an instance of that router in the application.
1:04:56 - 1:14:42
Public & Repos Components
After answering a few audience questions, Henrik creates two UI components. The Public component will represent the home/login page and the Repos component will display a list of repositories. He also introduces Yeti.css.
- 1:14:43 - 1:22:43 Audience Questions Henrik takes a break from coding to answer a few audience questions about client vs. server routing, Yeti.css, and the separation of concerns in views.
- 1:22:44 - 1:36:16 Creating a Layout Component Many element will be shared across different pages. It would be inefficient to recreate something like a navigation menu in each component. Henrik demonstrates how to create a layout and use the children property to inject dynamic content. He then modifies the routes handler to load the correct layout.
- 1:36:17 - 1:45:36 Handling Local Links At this point, clicking any link in the application triggers a undesired browser refresh. Henrik demonstrates how to handle local, in-app links without breaking external link functionality. He does this by using the local-links NPM module.
- 1:45:37 - 1:53:23 Creating a Local Links Component Henrik challenges the audience to create a component who’s only responsibility is to add an onClick event and handle local links. This component will then be utilized throughout the application. He also answers a few audience questions and demonstrates how to use the React developer tools in Google Chrome.
- 1:53:24 - 2:02:32 Local Links Component - Solution Henrik walks through how to implement the Local Links component. He creates a NavHelper component that wraps it’s content in a <div> tag and adds an onClick event handler.
- 2:02:33 - 2:12:02 Creating a Global App Object Up until now, Henrik has been referencing an app property that was added directly to the window object. This convention can be a little messy and hard to read. Henrik demonstrates how to use the ampersand-app module to create a global app object which can be required more cleanly in other components.
- 00:00 - 15:23 Introduction Henrik Joreteg begins the Single Page Modern Web Applications course with a brief overview of what he’ll be covering. Henrik also walks through the Hubtags application that will be built throughout the course.
- 2:12:03 - 2:16:36 OAuth Explained OAuth is the process of an application gaining access to a user’s information in another account. For example, if you want to send a tweet through a third-party application, that application needs access to your Twitter account. Henrik spends a few minutes explaining the OAuth workflow.
2:16:37 - 2:27:07
Henrik walks through adding a route to handle users logging in to the application with their GitHub account. He also opens the GitHub developer portal to show the OAuth documentation and demonstrates how to create a new GitHub application.
2:27:08 - 2:40:49
Now that GitHub has provided the application with an authorization code, Henrik creates a route to handle this callback. He then talks about how to use Gatekeeper to securely pass the application secret to the GitHub server.
- 2:40:50 - 2:51:41 Persisting the Login Henrik creates a Model in the application for storing user data. One item needing to be stored is the authentication token. He will be using the LocalStorage api to persistent the data and create session-like functionality.
- 2:51:42 - 3:00:37 Logging Out Since logins are manage by GitHub, this application can’t directly log out the user. It can, however, clear the LocalStorage data and refresh the browser so there isn’t any persistent data. Henrik adds the logout functionality and explains his reasoning behind using window.location for the browser refresh.
- 3:00:38 - 3:12:22 Fetching User Data Using the GitHub API, Henrik fetches the data for the current logged in user. Only properties defined in the model will be stored in the application. He also updates the model to fetch new data anytime the token is changed and when the application initially loads.
3:12:23 - 3:25:55
Binding to a Model
Henrik adds a mixin that will watch for changes on any “props” passed to a component. If a change is detected, the render method of that component will be called and the screen will be redrawn. Henrik also goes into more detail about React’s lifecycle methods.
- 3:25:56 - 3:35:17 Collections and Mixins Henrik introduces the Ampersand Collection module. A collection is an observable array. He creates a collection to store a list of repos for the current user. After that, Henrik demonstrates how to create a mixin that will make it easier to access the auth token.
- 3:35:18 - 3:45:45 Fetching User Repos To populate the collection of repos from the GitHub api, Henrik calls the fetch() method. Similar to the the Model code, the Collection will make an XHR request to the server specified in the url property. After verifying the request is working, Henrik spends a few minutes answering questions from the audience.
- 3:45:46 - 3:57:34 Rendering Repos Henrik modifies the Repos page to loop through the list of repos and populate an unordered list. He also utilizes the ampersand-react-mixin to monitor the collection for changes. Once the page is populated, Henrik demonstrates a few alternative ways to write the code with features of ES6.
- 3:57:35 - 4:01:25 Keys Henrik spends a few minutes talking about how to make the re-rendering of DOM elements more performant. Adding a “key” attribute and assigning it a primary key from the data will help React determine if that element needs to be updated or mutated.
- 4:01:26 - 4:07:56 Adding Icons Henrik introduces the GitHub Octicons NPM module which contains all the iconography from the GitHub website. He imports the module into the application and demonstrates how to style elements with these icons.
- 4:07:57 - 4:15:17 Derived Properties Derived properties are depending on other properties within a model. If any of its dependent properties are updated, the derived property will trigger a change event. Henrik creates an appUrl derived property and applies that property to each repo link.
- 4:15:18 - 4:24:25 Repo Detail Page Henrik creates another component to represent the repo detail page. Once the UI is created for this page, he adds a route to dynamically pass the data of the repo to be displayed. Henrik also adds a convenience method to the collection to find the appropriate repo.
- 4:24:26 - 4:34:58 Optimizing the Details Page Henrik wraps up the Labelr application by adding code to handle if a user enters the application directly through the details page. In this case, the Model will determine if it needs to fetch new data from the server. Henrik then talks a little about API security and answers a few audience questions.
- 4:34:59 - 4:41:15 Why Frameworks? Henrik talks about why frameworks can be useful to developers. Frameworks help organize code and use proven techniques. They provide solutions to problems and often allow for easier collaboration.
- 4:49:50 - 4:59:39 Framework Q&A Henrik spends a few minutes answering audience questions about the different frameworks he discussed earlier. He also shares his opinion on scaffolding tools like Yeoman and framework recommendations for agencies.
- 4:59:40 - 5:04:36 Exercise: Storing Labels Henrik introduces the first exercise. In this exercise, you will create a label model and a collection to store the labels for each repo. Henrik also provides a few hints to the solution along the way.
- 5:04:37 - 5:14:07 Storing Labels Solution Henrik walks through the solution to Exercise 1.
- 5:14:08 - 5:19:27 Using the extend() Method Henrik spends a few minutes explaining the extend method he’s using in each module. This method takes an Object as a parameter and appends the properties of this object to the object in which it is called. Henrik also answers a few questions about the behavior of collections and how changes are triggered.
- 5:19:28 - 5:28:27 Rendering Labels Building off the first exercise, Henrik quickly demonstrates how to render all the labels on the repos page. This involves passing the labels collection as a prop so it will be monitored for changes.
- 5:28:28 - 5:30:31 Exercise: Creating a Label Item Component In this exercise, you will refactor the rendering of a label item. You will move the list item mark-up into a component and render this new component on the repo details page. After giving the audience a few minutes to work on this, Henrik provides the solution.
- 5:30:32 - 5:43:30 Adding an Editing State Eventually, the labels and colors will be editable. Henrik adds conditional logic to the render method inside the label item component to determine which DOM elements to return. If the item is in editing mode, a form will be returned instead of the basic mark-up.
- 5:43:31 - 5:46:46 Label Colors Henrik uses the color property returned for each label item to dynamically style the background color of a <span> element with the label’s color. He also explains why the double-bracket syntax is required when using object-notation in JSX.
- 5:46:47 - 5:50:32 Exercise: Changing Label State In this exercise, you will add a click event to the edit button. When the edit button is clicked, the label should display the edit form. After providing a few hints, Henrik walks through the solution.
- 5:50:33 - 5:57:36 Canceling the Edit State Henrik walks through how to add another click event. This time he adds the event to the cancel button which will return the label back to its original state. After that, Henrik answers a few audience questions and shares a few more debugging tips.
- 5:57:37 - 6:03:13 Exercise: Deleting a Label In this exercise, you will implement the delete functionality for a label. Henrik begins by walking through the GitHub API as well as how React handles the removing of items through a RESTful service. He then gives the group a few minutes to implement this.
- 6:03:14 - 6:12:48 Deleting a Label: Solution Henrik walks through the solution for deleting a label. Remember that this is a live API and your GitHub repositories will reflect any changes.
- 6:12:49 - 6:27:29 Editing Labels Henrik demonstrates how to make labels editable. While doing this, he explains the unique behavior of forms in React. Since the form is re-rendered continuously in the application, Henrik relies on the state property to help set form input values.
- 6:27:30 - 6:34:49 Editing Label Colors The next form field needing implementation is the color field. Henrik adds the code for editing the color and also shows the audience how to revert the values back when the cancel button is pressed.
- 6:34:50 - 6:50:04 Sending Updates to Github, part 1 With the form fully implemented to edit labels and colors, Henrik adds an extra XHR request to the model to send the updated data to Github. If there’s an error when sending the request, Henrik makes sure to manually set the current state to the new values.
- 6:50:05 - 6:59:33 Sending Updates to Github, part 2 Henrik continues his work on sending the updated data to Github with a little debugging. For example, how the application handles a drop in network connectivity. Henrik also fields a few audience questions.
- 6:59:34 - 7:10:20 Creating New Labels Henrik adds a button for creating new labels. When a new label is created, it will need to know whether or not to make an API call for a PATCH (update) or a POST (add).
- 7:10:21 - 7:17:15 Canceling New Labels If the user chooses to cancel the creation of a new label, the model object in memory will need to be destroyed. Henrik adds a conditional statement to the onCancelClick method to determine if the label is saved or if it should be destroyed.
- 7:17:16 - 7:21:48 Exercise: Securing Routes In this exercise, you will create a requiresAuth function that will help secure routes that require authentication. This function will return a function that validates the current user is logged in. Henrik sets up the exercise and provides a couple hints to get everyone started.
- 7:21:49 - 7:30:46 Securing Routes: Solution Henrik walks through the solution to the Securing Routes exercise.
- 7:30:47 - 7:38:18 Handling 404 Errors Since the Labelr application is handling all the routes on the client, an invalid route will not trigger a traditional 404 error. Henrik demonstrates how to handle wild-card routes and creates a MessagePage component that can be reused in different situations.
- 7:38:19 - 7:44:11 Using a Config File Henrik demonstrates one technique for handling development and production configuration. He creates a config.js file to store the authentication URLs and Github application keys.
7:44:12 - 7:58:14
Deploying with Surge
Surge is a front-end development tool for deploying static content. It will take content built in the public directory of the application and publish it to a subdomain on surge.sh. Henrik demonstrates this process and answers a few additional questions about deployment.
- 7:58:15 - 8:09:07 Pre-rendering Content Currently the application home page does not contain any markup because React generates everything once the application is loaded in the browser. Henrik walks through how to configure the application in a way that Node will be able to generate markup through the build process.
- 8:09:08 - 8:16:52 Generating Layout Markup Henrik applies the same pre-rendering concept from the home page to the layout page. This way the user will see some of the layout even if the rest of the application and data is not loaded. Once the data is loaded, React will re-render the page.
- 8:16:53 - 8:30:53 Final Thoughts Henrik begins wrapping up the course with a few final thoughts about his experience as a developer. He talks about the benefits of using code linters, code-style enforcement, contributing to open source projects and other ways to stay in touch.
- 8:30:54 - 8:37:19 Q & A Henrik answers a few final audience questions about NPM Link, CSS frameworks, and Ampersand.