Skip to content

varren/SpringBootReactExample

Repository files navigation

travis-ci status

How this React SpringBoot project works

To start use./gradlew bootRun

Be careful with yarn build because it will remove all files in spring boot src/main/resources/static/ directory Can setup different path(in gradle.build and Config.java) if you have some extra files you need to keep.

Implementation:

  1. Create Spring gradle spring-boot-starter-data-rest project

    App.java

     package ru.varren;
     
     import org.springframework.boot.SpringApplication;
     import org.springframework.boot.autoconfigure.SpringBootApplication;
     
     @SpringBootApplication
     public class App {
         public static void main(String[] args) {
             SpringApplication.run(App.class, args);
         }
     }
    

    application.properties

     spring.data.rest.base-path=/api
    
  2. Create react project

    npm install -g create-react-app
     
    create-react-app frontend
    cd frontend/
    
    1. Comment out registerServiceWorker(); in src/index.js for now.
  3. Setup spring configuration

    @Configuration
    public class Config implements WebMvcConfigurer {
    
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            ResourceResolver resolver = new ReactResourceResolver();
            registry.addResourceHandler("/**")
                    .resourceChain(true)
                    .addResolver(resolver);
        }
    
        public class ReactResourceResolver implements ResourceResolver {
            // this is the same directory you are using 
            // in package.json "build-spring-linux",
            // example REACT_DIR/index.html
            private static final String REACT_DIR = "/static/";
    
            // this is directory inside REACT_DIR for react static files
            // example REACT_DIR/REACT_STATIC_DIR/js/
            // example REACT_DIR/REACT_STATIC_DIR/css/
            private static final String REACT_STATIC_DIR = "static";
    
            private Resource index = new ClassPathResource(REACT_DIR + "index.html");
            private List<String> rootStaticFiles = Arrays.asList("favicon.io",
                    "asset-manifest.json", "manifest.json", "service-worker.js");
    
            @Override
            public Resource resolveResource(HttpServletRequest request, String requestPath,
                                            List<? extends Resource> locations, ResourceResolverChain chain) {
                return resolve(requestPath, locations);
            }
    
            @Override
            public String resolveUrlPath(String resourcePath, List<? extends Resource> locations, ResourceResolverChain chain) {
                Resource resolvedResource = resolve(resourcePath, locations);
                if (resolvedResource == null) {
                    return null;
                }
                try {
                    return resolvedResource.getURL().toString();
                } catch (IOException e) {
                    return resolvedResource.getFilename();
                }
            }
    
            private Resource resolve(String requestPath, List<? extends Resource> locations) {
                System.out.println(requestPath);
                if (requestPath == null) return null;
    
                if (rootStaticFiles.contains(requestPath)
                        || requestPath.startsWith(REACT_STATIC_DIR)) {
                    return new ClassPathResource(REACT_DIR + requestPath);
                } else
                    return index;
            }
    
        }
    
    }
    
  4. Connecting gradle:bootRun with yarn build-spring-linux

    Add classpath "com.moowork.gradle:gradle-node-plugin:1.2.0" gradle plugin

    node {
      
        // If true, it will download node using above parameters.
        // If false, it will try to use globally installed node.
        download = true
      
        // Set the work directory where node_modules should be located
        nodeModulesDir = file("${project.projectDir}/frontend")
    }
    
    // build react with webpack
    task webpack(type: YarnTask, dependsOn: yarn) {
        inputs.files(fileTree("${project.projectDir}/frontend/"))
        outputs.dir("${project.projectDir}/src/main/resources/static/")
    
        args = ['build']
    }
    
    // copy react build to spring resourses
    task moveJStoSpring(type: Copy) {
        from "${project.projectDir}/frontend/build/"
        into "${project.projectDir}/src/main/resources/static/"
    }
    
    moveJStoSpring.dependsOn 'webpack'
    processResources.dependsOn 'moveJStoSpring'
    

    Can comment out processResources.dependsOn 'webpack' or implement some debug/production logic if you don't want gradle to recompile javascipt on each spring boot start

About

Spring Boot React Example

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors