-1

I have a react frontend that I want to use with my springboot rest api. I used nwb to create my react app. I'm trying to use the frontend-maven-plugin but I can not get my react app to work. The rest api works great. Can't find any info online. How should this be done?

I have tried various examples online but none incorporate nwb.

<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
   <installDirectory>target</installDirectory>
    <nodeVersion>v8.9.1</nodeVersion>
    <npmVersion>5.5.1</npmVersion>

</configuration>
<executions>
    <execution>
        <id>install node and npm</id>
        <goals>
            <goal>install-node-and-npm</goal>
        </goals>
        <configuration>
            <nodeVersion>v10.11.0</nodeVersion>
            <npmVersion>6.4.1</npmVersion>
        </configuration>
    </execution>
    <execution>
        <id>npm install</id>
        <goals>
            <goal>npm</goal>
        </goals>
        <configuration>
            <arguments>install</arguments>
        </configuration>
    </execution>
    <execution>
        <id>webpack build</id>
        <goals>
            <goal>webpack</goal>
        </goals>
    </execution>
</executions>

I would like the frontend react app to work nicely with the springboot rest. Thanks!

Roro
  • 297
  • 5
  • 17
  • When you say the Springboot rest, you are referring to a Spring Boot Restful API that is apart of your program or is the API a separate application? – Brandon Jan 31 '19 at 05:33
  • @Brandon I want to put them both together. – Roro Jan 31 '19 at 16:05

1 Answers1

1

In addition to an answer I submitted here: Hosting a single page application with spring boot

Below is the directory structure you will need. You'll obviously have your REST API within the java directory (make sure to note the controller specifics within my other answer I provided above):

- sample-project-root
    - src
        - main
            -java
            - js
                app.js
                index.js
            - resources
                - templates
                    index.html
 webpack.config.js
 package.json
 pom.xml

Below is the index.html page that your 'MainController' will render using Thymeleaf. This needs to be placed in the src/main/resources/templates/ directory (standard Spring behavior).

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head lang="en">
         <meta charset="UTF-8"/>
         <title>Sample Project</title>
    </head>
    <body>

         <!-- Entry point to our ReactJS single page web application -->
         <div id="root"></div>

         <script type="text/javascript" src="built/bundle.js"></script>
    </body>
</html>

Below is the index.js page that will actually boot up your React app. Notice that the main render function is getting the document id 'root' that's within your index.html page.

index.js

const React = require('react');
const ReactDOM = require('react-dom');

import App from './app.js';
import 'bootstrap/dist/css/bootstrap.min.css';

// Render main app
ReactDOM.render(
    <App />,
    document.getElementById('root')
);

You're going to need to utilize Webpack to manage your ReactJS dependencies. I'll share with you a sample webpack.config.js file that lives at the root of the project.

webpack.config.js

var path = require('path');

module.exports = {
    entry: ['babel-polyfill', './src/main/js/index.js'],
    devtool: 'sourcemaps',
    cache: true,
    mode: 'development',
    output: {
        path: __dirname,
        filename: './src/main/resources/static/built/bundle.js'
    },
    module: {
        rules: [
            {
                test: path.join(__dirname, '.'),
                exclude: /(node_modules)/,
                use: [{
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env", "@babel/preset-react"]
                    }
                }]
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.(png|svg|jpg|gif|eot|otf|ttf|woff|woff2)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {}
                    }
                 ]
            }
        ]
    }
};

Don't worry too much about the bottom two rules, what you want to focus on is the entry point which is our index.js page and the output path that is the result of running your package.json file.

package.json (place this at root level of your project as well)

{
  "name": "spring-data-rest-and-reactjs",
  "version": "0.1.0",
  "description": "Demo of ReactJS + Spring Data REST",
  "repository": {
    "type": "git",
    "url": "git@github.com:spring-guides/tut-react-and-spring-data-rest.git"
  },
  "keywords": [
    "rest",
    "hateoas",
    "spring",
    "data",
    "react"
  ],
  "author": "Sample Team",
  "license": "Apache-2.0",
  "bugs": {
  "url": ""
  },
  "homepage": "url",
  "dependencies": {
  "react": "^16.5.2",
  "react-dom": "^16.5.2",
  "rest": "^1.3.1",
  "bootstrap": "^4.2.1",
  "jquery": "^3.3.1",
  "popper.js": "^1.14.6",
  "style-loader": "^0.23.1",
  "css-loader": "^2.1.0",
  "url-loader": "^1.1.2",
  "postcss-loader": "^3.0.0",
  "precss": "^4.0.0",
  "autoprefixer": "^9.4.3",
  "sass-loader": "^7.1.0",
  "react-octicon": "^3.0.1"
},
"scripts": {
   "watch": "webpack --watch -d"
},
"devDependencies": {
  "@babel/core": "^7.1.0",
  "babel-polyfill": "^6.0.16",
  "@babel/preset-env": "^7.1.0",
  "@babel/preset-react": "^7.0.0",
  "babel-loader": "^8.0.2",
  "webpack": "^4.19.1",
  "webpack-cli": "^3.1.0"
  }
}

Your React app might require different dependencies but this is just an example.

Finally, add the following to your Maven plugins (pom.xml):

<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.6</version>
    <configuration>
        <installDirectory>target</installDirectory>
    </configuration>
    <executions>
        <execution>
            <id>install node and npm</id>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
            <configuration>
                <nodeVersion>v10.11.0</nodeVersion>
                <npmVersion>6.4.1</npmVersion>
            </configuration>
        </execution>
        <execution>
            <id>npm install</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>install</arguments>
            </configuration>
        </execution>
        <execution>
            <id>webpack build</id>
            <goals>
                <goal>webpack</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Resources:

Good luck!

Brandon
  • 637
  • 1
  • 6
  • 19
  • Thanks! I'm getting an error....npm ERR! path C:\RFIDRestAPI\node_modules\fsevents\node_modules [ERROR] npm ERR! code EPERM [ERROR] npm ERR! errno -4048 [ERROR] npm ERR! syscall scandir [ERROR] npm ERR! Error: EPERM: operation not permitted, scandir 'C:\RFIDRestAPI\node_modules\fsevents\node_modules' [ERROR] npm ERR! { Error: EPERM: operation not permitted, scandir 'C:\RFIDRestAPI\node_modules\fsevents\node_modules' [ERROR] npm ERR! stack: 'Error: EPERM: operation not permitted, scandir – Roro Feb 01 '19 at 17:49
  • \'C:\\RFIDRestAPI\\node_modules\\fsevents\\node_modules\'', [ERROR] npm ERR! errno: -4048, [ERROR] npm ERR! code: 'EPERM', [ERROR] npm ERR! syscall: 'scandir', [ERROR] npm ERR! path: 'C:\\RFIDRestAPI\\node_modules\\fsevents\\node_modules' } [ERROR] npm ERR! [ERROR] npm ERR! Please try running this command again as root/Administrator – Roro Feb 01 '19 at 17:50
  • Instead of webpack file, I have nwbconfig file. Is that the same? – Roro Feb 01 '19 at 17:52
  • It appears that error is caused by your fsevents dependency. Error: EPERM: operation not permitted, scandir. Is it possible for you to remove that dependency temporarily to debug further? I don't think the npm errors should be related to your Spring Security setup. – Brandon Feb 01 '19 at 19:04
  • OK I got rid of that error. Now when I go to the home page I get a 401 response. Maybe that is related to Spring Security? Not sure how to update my api to let react pages be shown..... – Roro Feb 01 '19 at 20:51
  • When I run the react app by itself it runs great. Its just trying to put them together where I run into problems. NWB has different configurations....that's where I need help. – Roro Feb 01 '19 at 22:26
  • How can I get the pages unauthorized? – Roro Feb 05 '19 at 00:25