起因:看過Dubbo管控台的都知道,人家是個前后端分離的項目,可是一條打包命令能讓兩個項目整合在一起,我早想這樣玩玩了。
1. 建立個maven父項目
next
這個作為父工程,next
Finish,然后把項目目錄的src刪除
2. 建立springboot子項目(Module)
next
next
這里引入模板引擎,是為了能運行前端項目,next
3. 建立前端子項目
這里就不是new Module了,而是直接在父項目根目錄,用vue-cli3.0工具直接創建。
4. 先提前看一下最終項目目錄(這個目錄是我最后打包測試沒問題的目錄,所以會出現一些打包之后才會有的文件~)
5. 要實現打包整合只需要修改三個文件,即:三個pom.xml文件。
第一個,parent的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.demo</groupId> <artifactId>boot-vue-parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>boot-ui</module> <module>boot-server</module> </modules> <properties> <spring.boot.version>2.1.6.RELEASE</spring.boot.version> <maven.resource.version>3.1.0</maven.resource.version> <maven.clean.version>3.1.0</maven.clean.version> <maven.compiler.version>3.8.1</maven.compiler.version> <java.source.version>1.8</java.source.version> <java.target.version>1.8</java.target.version> <file.encoding>UTF-8</file.encoding> <checkstyle.skip>true</checkstyle.skip> <maven-checkstyle-plugin-version>3.0.0</maven-checkstyle-plugin-version> <jacoco-version>0.8.2</jacoco-version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring.boot.version}</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <profiles> <profile> <id>checkstyle</id> <activation> <jdk>[1.8,)</jdk> </activation> <build> <plugins> <!--輔助判斷代碼格式是否滿足規范(非必須)--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>${maven-checkstyle-plugin-version}</version> <dependencies> <dependency> <groupId>com.puppycrawl.tools</groupId> <artifactId>checkstyle</artifactId> <version>8.9</version> </dependency> </dependencies> <executions> <execution> <id>checkstyle-validation</id> <phase>validate</phase> <configuration> <configLocation>codestyle/checkstyle.xml</configLocation> <encoding>UTF-8</encoding> <consoleOutput>true</consoleOutput> <failOnViolation>true</failOnViolation> </configuration> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <!--Apache RAT (Release Audit Tool) 是一個用來檢查軟件許可證發行的准確性和高效性的工具。它的本質是:對可能出現的問題作出預測(非必須)--> <plugin> <groupId>org.apache.rat</groupId> <artifactId>apache-rat-plugin</artifactId> <version>0.12</version> <executions> <execution> <id>verify.rat</id> <phase>verify</phase> <goals> <goal>check</goal> </goals> <configuration> <excludes> <exclude>**/*.versionsBackup</exclude> <exclude>**/.idea/</exclude> <exclude>**/*.iml</exclude> <exclude>**/*.txt</exclude> <exclude>**/*.sh</exclude> <exclude>**/*.bat</exclude> <exclude>**/*.md</exclude> <exclude>.git/</exclude> <exclude>**/*.git*</exclude> <exclude>.gitignore</exclude> <exclude>**/.settings/*</exclude> <exclude>**/.classpath</exclude> <exclude>**/*.properties</exclude> <exclude>**/.project</exclude> <exclude>**/target/**</exclude> <exclude>**/*.log</exclude> <exclude>CODE_OF_CONDUCT.md</exclude> <exclude>.codecov.yml</exclude> <exclude>.travis.yml</exclude> <exclude>PULL_REQUEST_TEMPLATE.md</exclude> <exclude>CONTRIBUTING.md</exclude> <exclude>**/codestyle/*</exclude> <exclude>**/node_modules/**</exclude> <exclude>**/.babelrc</exclude> <exclude>**/.editorconfig</exclude> <exclude>**/package-lock.json</exclude> <exclude>**/package.json</exclude> <exclude>**/OpenSans.css</exclude> <exclude>**/.eslintignore</exclude> <exclude>**/resources/META-INF/**</exclude> <exclude>**/src/main/resources/public/**</exclude> <exclude>**/src/licenses/**</exclude> </excludes> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> <build> <plugins> <!--JAVA代碼覆蓋率工具(非必須)--> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco-version}</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> <!--編譯插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.version}</version> <configuration> <source>${java.source.version}</source> <target>${java.target.version}</target> <encoding>${file.encoding}</encoding> </configuration> </plugin> </plugins> </build> </project>
第二個,springboot項目的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> <parent> <groupId>com.demo</groupId> <artifactId>boot-vue-parent</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>boot-server</artifactId> <properties> <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-thymeleaf</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> <version>${spring.boot.version}</version> <!--解決打包后,執行java -jar 命令,找不到主清單屬性--> <executions> <execution> <phase>package</phase> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <!--clean插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> <version>${maven.clean.version}</version> <configuration> <filesets> <fileset> <directory>src/main/resources/static</directory> </fileset> <fileset> <directory>src/main/resources/templates</directory> </fileset> </filesets> </configuration> </plugin> <!--資源插件,主要為了從前端項目里復制打包好的文件到springboot項目--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>${maven.resource.version}</version> <executions> <execution> <id>copy static</id> <phase>generate-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>src/main/resources/static</outputDirectory> <overwrite>true</overwrite> <resources> <resource> <!--因為vue-cli打包的目錄在項目的根目錄,所以從這里復制--> <directory>${project.parent.basedir}/boot-ui/dist</directory> <includes> <include>css/</include> <include>img/</include> <include>js/</include> <include>favicon.ico</include> </includes> </resource> </resources> </configuration> </execution> <execution> <id>copy template</id> <phase>generate-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>src/main/resources/templates</outputDirectory> <overwrite>true</overwrite> <resources> <resource> <!--因為vue-cli打包的目錄在項目的根目錄,所以從這里復制--> <directory>${project.parent.basedir}/boot-ui/dist</directory> <includes> <include>index.html</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
最后一個,vue項目里新添加的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"> <parent> <groupId>com.demo</groupId> <artifactId>boot-vue-parent</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>boot-ui</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <frontend-maven-plugin.version>1.6</frontend-maven-plugin.version> </properties> <build> <plugins> <!--frontend-maven-plugin為項目本地下載/安裝Node和NPM,運行npm install命令--> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>${frontend-maven-plugin.version}</version> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> <configuration> <nodeVersion>v10.16.0</nodeVersion> <npmVersion>6.9.0</npmVersion> </configuration> </execution> <!-- Install all project dependencies --> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <!-- optional: default phase is "generate-resources" --> <phase>generate-resources</phase> <!-- Optional configuration which provides for running any npm command --> <configuration> <arguments>install</arguments> </configuration> </execution> <!-- Build and minify static files --> <execution> <id>npm run build</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>run build</arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
6. 解釋一下
最重要的插件就兩個,一個是springboot項目里的maven-resources-plugin,另一個是vue項目里的frontend-maven-plugin。
資源插件的復制路徑很好理解,vue-cli3.0打包的目錄如圖所示
而我們要在springboot項目里運行,就要把index.html文件復制到templates目錄,其他文件復制到static目錄。
7. 打包運行。
mvn clean package -Dmaven.test.skip=true
進入根目錄,執行打包命令
..
進入server的target目錄,執行java -jar命令
訪問:
完成 https://github.com/Mysakura/boot-vue-parent
8. 引申 frontend-maven-plugin
這個插件不僅僅支持node+npm,還支持node+yarn。這里我也寫了個例子 https://github.com/Mysakura/frontend-maven-plugin-demo
boot-ui項目的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"> <parent> <groupId>com.example</groupId> <artifactId>boot-vue-parent</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>boot-ui</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <frontend-maven-plugin.version>1.7.6</frontend-maven-plugin.version> </properties> <build> <plugins> <!--安裝node和npm的情況--> <!--<plugin>--> <!--<groupId>com.github.eirslett</groupId>--> <!--<artifactId>frontend-maven-plugin</artifactId>--> <!--<version>${frontend-maven-plugin.version}</version>--> <!--<executions>--> <!--<execution>--> <!--<id>install node and npm</id>--> <!--<goals>--> <!--<goal>install-node-and-npm</goal>--> <!--</goals>--> <!--<configuration>--> <!--<nodeVersion>v10.16.0</nodeVersion>--> <!--<npmVersion>6.9.0</npmVersion>--> <!--</configuration>--> <!--</execution>--> <!--<!– Install all project dependencies –>--> <!--<execution>--> <!--<id>npm install</id>--> <!--<goals>--> <!--<goal>npm</goal>--> <!--</goals>--> <!--<phase>generate-resources</phase>--> <!--<configuration>--> <!--<arguments>install</arguments>--> <!--</configuration>--> <!--</execution>--> <!--<!– Build and minify static files –>--> <!--<execution>--> <!--<id>npm run build</id>--> <!--<goals>--> <!--<goal>npm</goal>--> <!--</goals>--> <!--<configuration>--> <!--<arguments>run build</arguments>--> <!--</configuration>--> <!--</execution>--> <!--</executions>--> <!--</plugin>--> <!--安裝node和yarn的情況--> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>${frontend-maven-plugin.version}</version> <executions> <execution> <id>install node and yarn</id> <goals> <goal>install-node-and-yarn</goal> </goals> <phase>generate-resources</phase> <configuration> <nodeVersion>v10.16.0</nodeVersion> <yarnVersion>v1.13.0</yarnVersion> </configuration> </execution> <!-- Install all project dependencies --> <execution> <id>yarn install</id> <goals> <goal>yarn</goal> </goals> <configuration> <arguments>install</arguments> </configuration> </execution> <!-- Build and minify static files --> <execution> <id>yarn run build</id> <goals> <goal>yarn</goal> </goals> <configuration> <arguments>run build</arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>