Spring Bootとcreate-react-appを組み合わせて開発を行う


以下の記事を参考に、Spring BootとReactを組み合わせて開発を行ってみます。
[Using create-react-app with Spring Boot](https://www.blackpepper.co.uk/what-we-think/blog/using-create-react-app-with-spring)

[Spring Initializr](https://start.spring.io/)からダウンロードしたSpring Bootの雛形をEclipseにimportします。

import > Maven > Existing Maven Projects

でzipを解凍したファイルを指定すればOKです。

`src/main`ディレクトリに移動し、

```
create-react-app app --verbose
```

を実行します。

すると、`src/main/app`にreact開発用の雛形ができます。

次にpom.xmlを編集します。

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>websocket</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>websocket</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			
			<plugin>
			    <groupId>com.github.eirslett</groupId>
			    <artifactId>frontend-maven-plugin</artifactId>
			    <version>1.2</version>
			    <executions>
			        <execution>
			            <id>Install Node and Yarn</id>
			            <goals>
			                <goal>install-node-and-yarn</goal>
			            </goals>
			        </execution>
			
			        <execution>
			            <id>yarn install</id>
			            <goals>
			                <goal>yarn</goal>
			            </goals>
			            <configuration>
			                <arguments>install</arguments>
			            </configuration>
			        </execution>
			
			        <execution>
			            <id>Frontend production build</id>
			            <phase>package</phase>
			            <goals>
			                <goal>yarn</goal>
			            </goals>
			            <configuration>
			                <arguments>run build</arguments>
			            </configuration>
			        </execution>
			    </executions>
			    <configuration>
			        <nodeVersion>v7.2.0</nodeVersion>
			        <yarnVersion>v0.18.0</yarnVersion>
			        <installDirectory>.mvn</installDirectory>
			        <workingDirectory>src/main/app</workingDirectory>
			    </configuration>
			</plugin>
			<plugin>
			    <artifactId>maven-resources-plugin</artifactId>
			    <version>3.0.1</version>
			    <executions>
			        <execution>
			            <id>Copy frontend production build to resources</id>
			            <phase>package</phase>
			            <goals>
			                <goal>copy-resources</goal>
			            </goals>
			            <configuration>
			            	<!--  
			                <outputDirectory>${basedir}/target/classes</outputDirectory>
			                -->
			                <outputDirectory>${basedir}/src/main/resources/static</outputDirectory>
			                <resources>
			                    <resource> 
			                        <directory>src/main/app/build/</directory>
			                        <filtering>true</filtering>
			                    </resource>
			                </resources>
			            </configuration>
			        </execution>
			    </executions>
			</plugin>
		</plugins>
	</build>

</project>

```

デフォルトの雛形の`<plugins>`の中に`<plugin>`を追加します。
以下の記述がデフォルトです。

```xml
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			

```

その下に、以下のようなXMLを追記していきます。

```xml:pom.xml
			<plugin>
			    <groupId>com.github.eirslett</groupId>
			    <artifactId>frontend-maven-plugin</artifactId>
			    <version>1.2</version>
			    <executions>
			        <execution>
			            <id>Install Node and Yarn</id>
			            <goals>
			                <goal>install-node-and-yarn</goal>
			            </goals>
			        </execution>
			
			        <execution>
			            <id>yarn install</id>
			            <goals>
			                <goal>yarn</goal>
			            </goals>
			            <configuration>
			                <arguments>install</arguments>
			            </configuration>
			        </execution>
			
			        <execution>
			            <id>Frontend production build</id>
			            <phase>package</phase>
			            <goals>
			                <goal>yarn</goal>
			            </goals>
			            <configuration>
			                <arguments>run build</arguments>
			            </configuration>
			        </execution>
			    </executions>
			    <configuration>
			        <nodeVersion>v7.2.0</nodeVersion>
			        <yarnVersion>v0.18.0</yarnVersion>
			        <installDirectory>.mvn</installDirectory>
			        <workingDirectory>src/main/app</workingDirectory>
			    </configuration>
			</plugin>
			<plugin>
			    <artifactId>maven-resources-plugin</artifactId>
			    <version>3.0.1</version>
			    <executions>
			        <execution>
			            <id>Copy frontend production build to resources</id>
			            <phase>package</phase>
			            <goals>
			                <goal>copy-resources</goal>
			            </goals>
			            <configuration>
			            	<!--  
			                <outputDirectory>${basedir}/target/classes</outputDirectory>
			                -->
			                <outputDirectory>${basedir}/src/main/resources/static</outputDirectory>
			                <resources>
			                    <resource> 
			                        <directory>src/main/app/build/</directory>
			                        <filtering>true</filtering>
			                    </resource>
			                </resources>
			            </configuration>
			        </execution>
			    </executions>
			</plugin>
		</plugins>
	</build>


</project>
```

元々参考にしていたサイトでは`${basedir}/target/classes`にReactのbuildファイル群をコピーしていたのですが、僕は`${basedir}/src/main/resources/static`以下にコピーするように変更しました。

```xml
			            <configuration>
			            	<!--  
			                <outputDirectory>${basedir}/target/classes</outputDirectory>
			                -->
			                <outputDirectory>${basedir}/src/main/resources/static</outputDirectory>
	
```

プロジェクトのルートディレクトリで`mvn clean package`を実行します。
すると、Reactのソースがビルドされて、`${basedir}/src/main/resources/static`以下にコピーされていきます。

あとは普通にEclipseからJavaを実行するだけです。
`http://localhost:8080/`に接続すると、React Appの画面が見えます。