List of Figures

Chapter 1. Introduction to isomorphic web application architecture

Figure 1.1. A wireframe showing the homepage for All Things Westies, an isomorphic web app

Figure 1.2. Isomorphic apps build and deploy the same JavaScript code to both environments.

Figure 1.3. The isomorphic app flow from initial browser request to SPA cycle

Figure 1.4. The server-rendered version of the All Things Westies homepage

Figure 1.5. App flow for the initial server render

Figure 1.6. Browser render and bootstrap—between steps 1 and 4, the app won’t respond to user input.

Figure 1.7. Google PageSpeed Insights presents a warning for a single-page application. The application makes too many AJAX calls to fetch visible content after the initial load of the page.

Figure 1.8. In a single-page app version of All Things Westies, spinners would be shown during the first load instead of the real content.

Figure 1.9. Comparison of when the user sees the content of a web app. An isomorphic app displays its content much sooner than a single-page app.

Figure 1.10. Comparing the DOM trees: the virtual DOM changes are compared to the browser DOM. Then React intelligently updates the browser DOM tree based on the calculated diff.

Figure 1.11. The view (React) uses Redux to update the app state when the user takes an action. Redux then lets the view know when it should update based on the new app state.

Chapter 2. A sample isomorphic app

Figure 2.1. The home screen for the recipes app you’ll build in this chapter

Figure 2.2. The application flow you’ll build in this chapter—initial render from the server and browser hydration

Figure 2.3. An overview of how the various libraries and build tools are used across the two environments the code runs in (server and browser). The files listed here can be found in the code example. See the next section for instructions on downloading the code.

Figure 2.4. Folder organization and top-level build and configuration files. A subset view of the folder structure for the recipes app that shows what files pertain to build and tools, the server, and the browser.

Figure 2.5. Expected output from the recipes API endpoint after the server is running

Figure 2.6. How React and Redux fit into the application flow

Figure 2.7. The recipes app is divided into three main components. By composing them together, the app is created.

Figure 2.8. Redux overview: flow of user interaction to store update to view update

Figure 2.9. Dispatching an action triggers a lookup in the reducer followed by an update to the store.

Chapter 3. React overview

Figure 3.1. A basic React component’s output when loaded into the browser

Figure 3.2. Rendering multiple HTML tags with React

Figure 3.3. React’s virtual DOM when the app starts up

Figure 3.4. The continuous update and diff cycle that React goes through to keep the DOM up-to-date

Figure 3.5. The virtual DOM updates the browser DOM based on the diff algorithm that React runs on state changes.

Figure 3.6. A wireframe for the Todo app you’ll build in this chapter

Figure 3.7. The button component rendered inside Storybook

Figure 3.8. Each rectangle encloses an individual component. Some components are nested; for example, the Button component is nested inside the ListItem component, which is inside the List component.

Figure 3.9. View of the todo item in Storybook with action logging

Figure 3.10. Link component rendered inside Storybook

Figure 3.11. The List component renders multiple list items based on the data it receives.

Figure 3.12. The ListItem component has a property that indicates whether the item is done. When it’s done, the Complete button no longer shows.

Figure 3.13. Adding tabs lets the app display different lists of todo items.

Chapter 4. Applying React

Figure 4.1. The All Things Westies sample app that you’ll begin building in this chapter. You’ll build out the various parts of this app in later chapters.

Figure 4.2. Example component tree with React Router as the root element

Figure 4.3. Using props.children to render components at runtime

Figure 4.4. The onEnter handler fires only once for the root route, but the onChange handler fires on every subsequent route change.

Figure 4.5. The React lifecycle consists of three types of lifecycle events. Each has corresponding method hooks.

Figure 4.6. The tooltip that shows as a user prompt

Figure 4.7. If a component is unmounted, but listeners or timers aren’t cleaned up, they’ll end up with a reference to a null component.

Figure 4.8. Higher-order functions take a function and return a new function with additional functionality. (Reproduced from Azat Mardan’s React Quickly, Manning, 2017.

Chapter 5. Tools: webpack and Babel

Figure 5.1. The calendar reminder app you’ll be setting up with webpack in this chapter

Figure 5.2. The webpack compiler flow

Figure 5.3. How the Babel compiler transforms ES6 into browser- and Node.js-compatible code

Figure 5.4. Loaders are applied during the resolver phase of a webpack compile.

Figure 5.5. Chrome DevTools uses the generated sourcemaps to link the compiled code to the source file.

Figure 5.6. Production output compiled with additional webpack plugins

Chapter 6. Redux

Figure 6.1. Notifications update app—send and receive notifications

Figure 6.2. Redux single-direction flow from view

Figure 6.3. Using React Redux’s Provider and connect components to hook up the React view with the application state

Figure 6.4. Model-View-Controller (MVC) flow in Angular 1

Figure 6.5. Redux flow when initiated by a user action

Figure 6.6. The flow of information between the view and Redux

Figure 6.7. The input and output flow of a pure reducer function

Figure 6.8. Redux Logger console output

Chapter 7. Building the server

Figure 7.1. The main differences between server and browser code for React and React Router

Figure 7.2. Isomorphic app flow—server render only

Figure 7.3. The portion of the app you’ll build and render on the server in this chapter

Figure 7.4. Starting the Node.js server

Figure 7.5. Without route handling, the server throws an error.

Figure 7.6. Routing to the test route with Express

Figure 7.7. Efficiency versus lots of code duplication makes server routing with React Router the best choice.

Figure 7.8. The GET route handler for all routes allows you to pass any route to the server.

Figure 7.9. The middleware allows routing on the server to respond correctly based on the React Router shared routes.

Figure 7.10. The flow of a request through the Express router and associated middleware that use React Router to check for the presence of a valid route

Figure 7.11. Rendered output for the HTML in string form

Figure 7.12. The two-step process of rendering a valid HTML route

Figure 7.13. The data fetched by Redux on the server will be rendered into the list view in the cart.

Figure 7.14. The Redux flow on the server

Chapter 8. Isomorphic view rendering

Figure 8.1. This chapter focuses on the lower half of the flow, everything that happens after the server render (the browser render and the SPA logic).

Figure 8.2. Using the Network tab of Chrome Developer Tools to confirm that your JavaScript code is loading in the browser

Figure 8.3. The Cart page of your application before rendering in the browser or adding SPA functionality

Figure 8.4. The expected output after you render a simple div and message in the browser

Figure 8.5. Set a breakpoint on line 5 of main.jsx in the Sources tab of Chrome Developer Tools. This lets you view the browser output before the browser JavaScript runs.

Figure 8.6. Comparing the DOM from the server render with the DOM from the div rendered in main.jsx

Figure 8.7. The flow of the state serialization/deserialization

Figure 8.8. The serialized state in the browser

Figure 8.9. The isomorphic warning log that React issues when it’s detected an isomorphic render that isn’t truly isomorphic. This happens when the virtual DOM from the initial render cycle and the browser DOM don’t match.

Figure 8.10. Adding a banner to the bottom of the page

Figure 8.11. Loading the cart from the Products page results in an empty state.

Figure 8.12. Now that the browser fetches data, you see the XHR call in the Network tab of the Chrome Developer Tools.

Chapter 9. Testing and debugging

Figure 9.1. The browser test output when all the tests are passing

Figure 9.2. Karma launches Google Chrome for you so that your test runs in a real browser environment.

Figure 9.3. The server test output

Figure 9.4. Your tests will break if references are added that require a browser environment.

Figure 9.5. The differences between initial load and the SPA load require testing both use cases.

Figure 9.6. The React Dev Tools tab open in Chrome DevTools

Figure 9.7. React Dev Tools let you inspect components that don’t show up in regular HTML.

Figure 9.8. Inspecting the state and props for the Products component. You can manipulate the state from this panel.

Figure 9.9. Redux Dev Tools inside Chrome DevTools

Figure 9.10. Using the testing features of Redux Dev Tools

Figure 9.11. Using the playback feature of Redux Dev Tools

Chapter 10. Handling server/browser differences

Figure 10.1. The console output without preventing the analytics module from running on the server

Figure 10.2. Use the environment variable to determine when to run the analytics code, which relies on the window object.

Figure 10.3. Thoughtful SEO implementation leads to high rankings or featured rankings in Google search.

Figure 10.4. The product detail page

Figure 10.5. The title displayed in the browser

Figure 10.6. Set a breakpoint in the app-reducer.es6 and inspect the action.userAgent value.

Chapter 11. Optimizing for production

Figure 11.1. The default behavior of webpack results in a single file that represents all your code.

Figure 11.2. Using code splitting, webpack outputs multiple files that can be dynamically loaded. The specific files will vary by app.

Figure 11.3. In-memory caching allows some requests to benefit from faster response times.

Figure 11.4. Adding an edge server moves the caching in front of the server.

Figure 11.5. Repeat visits by the same user on the server. Saving cookies lets you store information about the user that can be retrieved during future sessions.

Figure 11.6. When the edge has to cache pages per user, the benefit of overlapping requests is lost.

Chapter 12. Other frameworks: implementing isomorphic without React

Figure 12.1. The homepage of the app that shows all the posts

Figure 12.2. The Post Detail page with the corresponding comments

Figure 12.3. Isomorphic app flow with Ember—Ember specifics are highlighted in bold.

Figure 12.4. Run ember serve to start the app.

Figure 12.5. The app directory and files that are used in this Ember app

Figure 12.6. The server-rendered app after you’ve added all of the isomorphic pieces

Figure 12.7. The header now renders on the server.

Figure 12.8. Ember replaces the DOM completely, but it’s imperceptible to the user.

Figure 12.9. The universal flow in Angular

Figure 12.10. The app folder and files that make up the SPA. It also includes the helper modules for universal state transfer and data fetching.

Figure 12.11. The isomorphic flow with Next.js

Figure 12.12. The folders and files that make up a basic Next.js app

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.63.145