An example application that uses a Spring Java backend with a React frontend.
Yes, but with Java. It's inspired by the spring-react-isomorphic project, but uses:
- Yarn for installing Node modules.
- Webpack to bundle all the JavaScript and dependencies, plus LESS + CSS handling.
- Babel for ES6 syntax, using Babel 6 with the "es2016" and "react" presets.
- Hot module reloading (HMR) of React components
- Redux to manage state, both in the client and when rendering on the server.
- react-router for page routing, on client and server. Note that this is version 4, with a very different (and simpler) API to previous versions.
- react-helmet for managing meta-data in the HTML
- Linting integrated with Webpack via eslint.
- Type checking with Flow.
You also get:
- Project Lombok to cut down the Java boilerplate
- Jackson to serialize model data
before rendering on the server. For more information, see
this OpenJDK thread on the subject,
but summary is Nashorn won't (and actually can't) string-ify POJOs via
JSON.stringify
, meaning it can't be used to serialise the Redux state.
This isn't necessarily the best way to write a React application. Pull requests welcome!
Execute mvn
if you have Maven already installed, or ./mvnw
if you don't. You'll need
Java8 installed either way at
a minimum version of 1.8.0_65
. Older versions have a bug that makes rendering
brutally slow.
Run Webpack in hot-module reloading mode with: npm start
.
Controllers that render views are suffixed with Controller
. REST endpoints are
suffixed with Resource
, and handle requests under /api
.
In order to preempt runtime errors with Nashorn loading the bundle, a test
script is executed by Maven during the test-compile
phase, located at
src/test/js/test_bundle.js
. If this script fails, you can diagnose the problem
by:
- Running a debug build with
npm run debug
. This runs Webpack in a production mode but without uglification. - Run the script again:
jjs src/test/js/test_bundle.js
- Look at the line in the bundle from the stacktrace and figure out the problem.
It's easy to create a bundle that's broken on the server by including code that
expects a DOM - and that includes the Webpack style loader. This is the root of
most problems. You should note that server-side rendering does not require a
DOM - which is why src/main/resources/static/js/polyfill.js
doesn't provide
any window
or document
stubs.
We implement a customer render function for Spring to call. The source code
is in render.es6.js
, and is compiled to ES5 syntax during the Maven
build.