This is a React progressive web app boilerplate - there are literally hundreds of others out there.. I created this based off work by Manuel Bieh to have one central repo I can base my React projects on. It parallels my Vue boilerplate (at least in theory).
This project is designed to be, extendable, comprehensible, and powerful. It supports server side rendering, hot module reloading, font preloading, and a slew of other awesome πΆ features. It's highly configurable too!
Another reason I've created my own boilerplate is that I wan't to be working with bleeding edge tech in an environment I control using conventions that fit my tastes. As features are added there will probably be plenty of beta versions to check out so keep an eye out.
A few things might be familiar when you've worked with other starter projects before. I borrowed many ideas from the aforementioned react-ssr-setup. You'll find the overall structure very reminiscent of it with major differences in implementation details and design choices. Starting with its switch to TypeScript I expect the projects to diverge rapidly.
Static files are served with Nginx.
HAProxy is the tls terminator and reverse proxy.
-
Chops
-
π― 100 on all Google Lighthouse tests
-
π₯ Lots of sweet sweet Webpack 4 sauce
-
π± PWA
-
π¦ SSR + CSR
-
π Brotli compression
-
π Font preload and preconnecting with local fallbacks
-
π¦ Sweeet OG and Twitter meta
-
-
Cool stuff
- π₯ Babel 7
- β React 16
- π― Fastify
- β Hot Module Reloading (HMR)
- β Less modules
- β PostCSS
- β Redux + Redux Saga
- β Immer
- β React Router 4
- β React Helmet
- β
Checkout
doiuse
in postcss.config.js π
- Clone the project and npm install.
- Then run
config/init.sh
- Change the created
config/keys.js
to have your own values. $ docker-compose up -d
to start haproxy and nginx.$ npm run start
for development,$ npm run build && npm run start:live
for production.In production I'm using pm2
There are several critical configuration files:
config
β ...
β config.js
β env.js
β meta.js
β paths.js
β keys.js
config.js
: Google Analytics tracking id's and similar non-sensitive configuration values. This file is exposed to the client
env.js
: process.env
variables and the like. There's a section on them.
meta.js
: Site meta information. From here values are injected into the head and pwa manifest, and icons are generated. This file is exposed to the client.
paths.js
: Paths useful for the project. This file is not exposed to the client in part to keep fs
from being required there.
keys.js
: Database passwords and other critical info. This file is NOT exposed to the client π€¨
There are a few `process.env' variables in use (in order of importance).
NODE_ENV
: Set NODE_ENV=development
for development or NODE_ENV=production
for production.
LIVE_GA
: Uses live analytics id if and only if true
LITE_BUILD
: Prevents webpack compression, file copy, and image conversion plugins for a quick production build test when true
.
PORT
: Specifies a port other than the default of :8500
OMIT_SOURCEMAP
: Omits sourcemaps when true
MUTE_PACK
: Turns off warnings and console highlighting sugar if true
HOST
: Almost unnecessary. Specifies a different host for logging and static html.
start
: Start the app in development mode with HMR for client and webpack watching the server.
start:live
: Start the production server. (I suggest pm2 for actual production)
build
: Do a production build of the site.
build:live
: Do a production build of the site with live analytics.
build:lite
: Build without heavier production plugins for a quick test. π―Calories only!
analyze
: "npm run build:stats && npm run start:analyzer"
build:stats
: Output build to bundle-stats.json
for bundle analysis.
start:analyzer
: Start the bundle analyzer.
build:nomap
: Build without sourcemaps.
Certs are kept in the certs
directory. I generate them with (and maintain) auto-dns-certs.
HAProxy is the tls terminator and reverse proxy. Some files are proxied to a different directory so that they can be served from the site root. The config is well documented and covers it pretty nicely.
Nginx serves static files for production.
There's some rubbish with weback output files and [chunkhash]
not working when prefetching with magic comments. tl;dr:
// Gotta use
chunkFilename: '[id].chunk.js',
// Not
chunkFilename: '[name].[chunkhash:8].chunk.js',
// For now π€
This using fastify not express so remember that fastify doesn't expose the same request and response so use request.req
and reply.locals
in a few places.
- Bring in manifest helpers package
- Fix the
'unsafe-inline'
in the csp with a nonce - Write them tests
- Continuous integration
- Spruce up jodocs
- Change to destructure sntax jsdoc where applicable microsoft/TypeScript#30089
- Add @throws to jodocs
- Add @module to jsdocs
- Consider removing
@module
tags when nothing else is present - Switch to fastify π―
- Split static serving and security stuff in to plugins
- Add aria-attributes
- Add structured data of some kind
- Figure out why webpack resolvers are broken in less
- Checkout the occasional error where winston logs without transports (I think it's related to async processes)
- Consider switch to standard redis container
- Look at using the writeFilesToDisk flag instead of write-files-plugin
- Fix sourcemaps in less (are they even broken?)
- Exclude dev deps in webpack???
- Consider defining process.env.PRODUCTION_FLAG so we're not doing string testing all the time - DEVELOPMENT_FLAG too.
- Change ga id in keys
- Turn on hsts
https://github.com/limeandcoconut
Cheers!
Orignally based off react-ssr-setup.
ISC, see license for details.