I rode those docs about spring dev tools and hot reload
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-restart-exclude
And according to that is see there is such posibility to hot reload java and backed React/Typescript/webpack app
This is our architecture (in shortcut)
mainmodule
    backendModules <- those modules are just maven project have theirs poms and etc
          backendModule1
          backendModule2
fontendModule
       content <- React/Typescript/Webpack/Less etc
backendModule2 - We are using to start backend backendModule1 - is just some additional services fontendModule/content - is our whole react app
Am I right if I say to have reload for our frontend files I have to:
Configure Intellij as I'm doing it normally for backend <- this is easy
1a. Change registry
1b. select build project automatically
My question is what I have to do to force reloading of frontend files - So developer just need to run 1 app and then backend + frontend will be reloaded automaticlly
Add frontend extensions to resource patterns(Intellij: Build, execution -> compiler)? jsx, json, js, less and etc?
According to doc add "spring.devtools.restart.additional-paths"
Did anyone was able to do that? We are not getting any errors and etc...
Let me know if something seems to be unclear so we can clarify that
I know of 2 different ways that work to do that.
1) Using Intellij File Watcher Plugin
2) Running webpack dev server as a reverse proxy for your spring-boot app
1)
Now if you save a file in your defined scope the webpack task will run. After that you have to refresh the page in your browser. Got the idea from https://intellij-support.jetbrains.com
2) This way is more advanced, but harder to configure correctly. You will have auto-reload (the page refreshes) and full hot reloading (the react state persists)
The basic idea is to run a webpack-dev-server and use that server as a reverse proxy for your spring-boot backend. The dev-server will handle requests to hot-reloaded content himself and pass everything else to your backend. Got the idea from https://www.codingbismuth.com/ .
As a example configuration
{
  "name": "",
  "version": "0.0.1",
  "description": "",
  "repository": {
    "type": "git",
    "url": ""
  },
  "keywords": [
    "xy"
  ],
  "author": "murphy",
  "license": "",
  "bugs": {
    "url": ""
  },
  "scripts": {
    "start:dev": "webpack-dev-server --config webpack.dev_server.js"
  },
  "homepage": "",
  "dependencies": {
    "file-saver": "^1.3.3",
    "prop-types": "^15.5.10",
    "react": "^16.2.0",
    "react-bootstrap-typeahead": "^2.3.0",
    "react-dom": "^16.2.0",
    "react-modal": "^3.1.8",
    "react-router": "^4.2.0",
    "react-router-dom": "^4.2.2",
    "react-datetime": "^2.11.1",
    "rest": "^1.3.1",
    "moment": "^2.20.1",
    "webpack": "^3.10.0",
    "swagger-ui": "^3.13.4",
    "webpack-dev-server": "^2.11.2"
  },
  "devDependencies": {
    "webpack-cli": "^2.0.15",
    "react-hot-loader": "^4.1.2",
    "babel-core": "^6.18.2",
    "babel-eslint": "^8.0.3",
    "babel-loader": "^7.1.2",
    "babel-polyfill": "^6.26.0",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "eslint": "^4.13.1",
    "eslint-plugin-react": "^7.5.1",
    "eslint-loader": "^1.9.0",
    "eslint-watch": "^3.1.3",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-flowtype": "^2.40.1",
    "uglifyjs-webpack-plugin2": "^1.0.3"
  }
}
const { resolve } = require('path');
const path = require('path');
const webpack = require('webpack');
module.exports = {
    context: resolve(__dirname, '.'),
    entry: [
        'react-hot-loader/patch',
        // activate HMR for React
        'webpack-dev-server/client?http://localhost:8888',
        // bundle the client for webpack-dev-server
        // and connect to the provided endpoint
        'webpack/hot/only-dev-server',
        // bundle the client for hot reloading
        // only- means to only hot reload for successful updates
        // the entry point of our app
        './src/main/js/router/mainrouter.jsx',
    ],
    output: {
        filename: './mainbundle.js',
        // the output bundle
        path: resolve(__dirname, '/src/main/resources/static/js/bundled'),
        publicPath: '/js/bundled/',
        // necessary for HMR to know where to load the hot update chunks
    },
    devtool: 'sourcemaps',
    devServer: {
        hot: true,
        contentBase: [resolve(__dirname, "."), resolve(__dirname, "./src/main/resources/static/js/bundled")],
        proxy: {
            "/": {
                target: {
                    host: "localhost",
                    protocol: 'http:',
                    port: 8087,
                },
            },
            ignorePath: true,
            changeOrigin: true,
            secure: false,
        },
        publicPath: '/js/bundled/',
        port: 8888,
        host: "localhost",
    },
    module: {
        rules: [
            {
                enforce: "pre",
                test: /\.jsx$/,
                exclude: /node_modules/,
                loader: "eslint-loader",
                options: {
                    // fix: true, // autofix
                    cache: true,
                    failOnError: false,
                    emitWarning: true,
                    quiet: true,
                },
            },
            {
                test: path.join(__dirname, '.'),
                exclude: /node_modules/,
                loader: "babel-loader",
                query: {
                    // cacheDirectory: true,
                    presets: ['es2015', 'react'],
                },
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader?modules'],
            },
        ],
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        // enable HMR globally
        new webpack.NamedModulesPlugin(),
        // prints more readable module names in the browser console on HMR updates
    ],
};
The spring boot app is running on :8087 and the webpack dev server on :8888. Now in your index.html you include the mainbundle.js. Run your spring-boot app and in a second terminal run:
npm run start:dev
Access the webpage on :8888 to have hot reloading on file changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With