What's in The Box?

There's a trivial example application in Breko-hub to help you explore the features.

There's a FooRoute component showing how to pre-load data on both server and client render (the prefetch). The FooRoute loads data unique to the client (the defer) which replaces the universally loaded data.

There's a BarRoute component showing how to pre-fetch route data with a promise-action.

An API to support the BarRoute's data needs.

There's a /private route doing a redirect on both client and server with a flash message. The flash message is then automatically removed using a redux-saga.

The FlashMessage component gives an example of action -> reducer flow. A saga removes messages after a delay (or by clicking remove). The FlashMessages component uses a Block Element Modifier (BEM) utility for managing class names in combination with CSS-modules.

There's a dispatch call in src/app/entry.js to show how to broadcast actions to a socket. A small socket server hosted within the app is (on the same port) forwarding any broadcast actions.

The test/functional/client/client-render.test.js file has tests for routes.

Description

The .env file

Breko-hub uses settings in your run-time environment, such as PORT, NODE_ENV and DEBUG. When developing, it's nice to use a .env file. The app loads an environment from your .env file to give you quick and convenient control when developing.

The .env file is untracked. This is important as environments contain sensitive information!

ES Imports

In Breko-hub, babel treats ./src/ as the default import root.

Using absolute require calls improves portability and clarity. No-one enjoys writing ../../../ and in a large application its important to give hierarchy to units of code. These two factors fight each other. By making ./src/ the default import root, you require any file without needing a relative path.

For example:

// inside `test/functional/client/client-render.test.js`
import App from '../../../src/app/components/App'
// becomes
import App from 'app/components/App'

Babel-root-imports resolves modules according to a configurable project route. Use a prefix of ~ to your import string if you need to require from above ./src/.

For example:

// inside `test/functional/client/client-render.test.js`
import '../../../package.json'
// becomes
import '~/package.json'

Head and Body Script Loading

A big performance factor for an application is the load time. CSS links contribute to this load time because of their large filesize. One quick improvement is to defer loading of styles for below the fold or progressive enhancement. Asynchronous asset loading is a great performance gain.

There're intentionally, 2 entry points for this application, body and head. This is to give the developer more control of their scripts location on the server render. The bodyStyles array loads CSS asynchronously after the DOMContentLoaded event.

The CSS to JS correspondence in applications are not perfect. It wouldn't be strange for JS required in the body build to require a CSS file suitable for the head.css bundle. You configure this in src/server/middleware/renderRouteContext.js by moving the available assets into the different arrays. The ExtractTextPlugin grabs any CSS into the head bundle from the body build if it's common to both.

Whilst developing, CSS-modules are not caught by the ExtractTextPlugin configuration for CSS hot reloading on the client.

CSS Modules

You import any SCSS or CSS into a client JS file. The file extension /.module.s?css/ instructs Webpack to import the file as a CSS-module. This gives more clarity to each CSS file and some flexibility when managing styles.

Engine

npm: "v3.x"
node: "v5.x"

This project uses the above versions of npm and node. It's advised to use the same engine when using this boilerplate.

It doesn't work to develop, build, test or serve on Windows... if you want to make PRs for windows, please do!

Thanks For Ideas!

This boilerplate is shamelessly reusing some ideas from:

results matching ""

    No results matching ""