Skip to content
This repository has been archived by the owner on Dec 6, 2019. It is now read-only.
/ react-with-moxy Public archive

MOXY's boilerplate to create isomorphic react applications

Notifications You must be signed in to change notification settings

moxystudio/react-with-moxy

Repository files navigation

react-with-moxy

Build Status Dependency status Dev Dependency status

Opinionated boilerplate to create isomorphic react applications.

Motivation

Isomorphic JavaScript applications can be pretty challenging and hard to setup.

react-with-moxy offers you the required tooling for your universal JavaScript application, as well as an opinionated frontend stack ready to kick-off your next project.

In the near future, we will be moving all the built-in tooling under scripts/ to a separate package. This will make it easier for projects based on this boilerplate to receive updates.

What's Included?

Table of Contents

Installation and setup

$ npm install

When the installation ends, copy .env.sample to .env. All the supported environment variables are described in this same file, in case you need to tweak any of them. You may read more under the Environment variables section.

Commands

build

$ npm run build

Builds the project for production, producing the bundled assets at public/_build. Please run npm run build -- -h for more options.

start

$ npm start

Starts a production server. You must run npm run build before running this command.
Please run npm start -- -h for more options.

start-dev

$ npm run start-dev

Starts a development server, opening a browser window automatically.
Please run npm run start-dev -- -h for more options.

test

$ npm test

Runs the project tests using Jest. You may pass whatever options the Jest CLI.

lint

$ npm run lint

Runs ESlint and Stylelint on the project. Please run npm run lint -- -h for more options.

release

$ npm run release

We use conventional commit messages. When running this command it will run standard-version that does the following:

  1. Bump the version in package.json (based on your commit history)
  2. Uses conventional-changelog to update CHANGELOG.md
  3. Commits package.json and CHANGELOG.md
  4. Tags a new release

And after the tagging step, it will run git push --follow-tags origin master, as defined here.

Environment variables

Your project can consume variables declared in your environment by accessing them via process.env.

The following variables will be made available:

  • NODE_ENV: One of development, production or test.
  • SITE_URL: Where the web app is accessible (e.g.: http://some-project.com).
  • PUBLIC_URL: Where the web app public/ folder is being served from. This is usually the same as the SITE_URL unless you use an external CDN to store and serve the files. You may use this to generate URLs to assets that do not go through Webpack.
  • REACT_APP_*: Custom variables that may be accessible in both the client and server bundles.

These will be embedded at build time, thus are read-only. This means you must rebuild your application every time you change them.

Server bundle

Besides the variables listed above, your server bundle will have access to the whole process.env just like a regular Node.js application.

Client bundle

Only the variables listed above will be available.

If you need custom environment variables, you must prefix them with REACT_APP_. This avoids accidentally exposing sensitive environment variables, such as a private key or a database credential.

.env file

Environment variables defined in the .env file will be automatically loaded into process.env.

This file is ignored in source control and it is intended to be created from .env.sample, which is committed and anyone who clones the project can easily use it as a starting point. All the supported variables, including their description and default values, are defined there.

Here's an example of how to declare two new environment variables:

REACT_APP_FOO=foo
REACT_APP_BAR=bar

Note that relying in the .env file is mostly useful for development. While you may still use it in production, it's advisable to pass environment variables explicitly when running commands. You may read the dotenv documentation for more information.

Passing environment variables when building a docker image

The project includes a Dockerfile, allowing you to generate a docker image of your project. Here's an example of how to build the docker image and pass a few environment variables:

$ docker build .
  --tag my-project:latest \
  --build-arg $SITE_URL=http://my-site.com \
  --build-arg $PUBLIC_URL=http://cdn.my-site.com

The environment variables are mapped to build args in the Dockerfile. This means that you must update the Dockerfile anytime you add new environment variables.

Customization

Customizing the server

You may tweak the express server on start and start-dev scripts:

└── scripts
    ├── start (production server)
    └── start-dev (development server)

Customizing Webpack

You may tweak the Webpack configuration, such as adding new loaders or editing Babel plugins on config-client.js and config-server.js:

└── scripts
    └── config
        └── webpack
            ├── config-client.js
            └── config-server.js

Customizing Jest

You may tweak the Jest configuration on jest folder:

└── scripts
    └── config
        └── jest
            ├── index.js
            ├── setup.js
            └── transformer.js

Customizing the manifest file

The build-manifest.json file contains a summary of the build, including the produced assets, to be used when rendering the document on the server. You can customize its content on manifest.js:

└── scripts
    └── util
        └── manifest.js

Examples

Integration with:

FAQ

How can I import an SVG as inline instead of adding it to the sprite?

Sometimes, you may want to import an SVG as inline either because you want to animate SVG paths or if you're just having issues with the sprite. If that is the case, you may change the file suffix from .svg to .inline.svg to import the SVG contents directly:

import someSvg from './some.inline.svg';

// `someSvg` is something like <svg ... />

Should Node.js be responsible for compressing responses?

Doing the compression in Node.js might hold the event loop which is not desirable for performance reasons.

That's why we employ gzip and br compression at build time for the built assets. We use compression-webpack-plugin to compress the assets when the project is built and the production server will attempt to serve the compressed files based on the requests' Accept-Encoding header.

For other responses, such as server-side rendered HTML, you may disable the on the fly compression and do it in a reverse-proxy server, like nginx. To do so, you may either pass the --no-compression flag or set the COMPRESSION=0 environment variable:

npm start -- --no-compression
COMPRESSION=0 npm start

Used in