欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

程序员文章站 2022-07-12 08:11:35
...

玩过最新版Dubbo管控台的都知道,人家是个前后端分离的项目,可是一条打包命令能让两个项目整合在一起,生成一个jar包,这样的好处显而易见,部署的时候服务器不需要安装node环境单独部署前端项目,或者也不需要在写完前端代码后,手动打包前端项目再将js文件拷贝到SpringBoot目录下面。其实,我早想这样玩玩了。下面就看怎么玩?

一、dubbo-admin简介

新版dubbo管控台github地址:https://github.com/apache/dubbo-admin

dubbo-admin前端使用Vue.js作为javascript框架,Vuetify作为UI框架;后端为标准spring boot工程。

他的生产环境部署方式

  1. 下载代码: git clone https://github.com/apache/dubbo-admin.git

  2. 在 dubbo-admin-server/src/main/resources/application.properties中指定注册中心地址

  3. 构建mvn clean package

  4. 启动mvn --projects dubbo-admin-server spring-boot:ru

  5. 访问 http://localhost:8080

构建只需要一条命令,奥妙在哪里呢?我们接下里进行实操。

二、前后端项目工程结构改造

建立父工程的原因是为了使IDEA可以同时管理后端和前端项目,父工程只需要一个文件夹,里面弄个pom.xml文件即可。了解过maven父子工程的同学应该很容易理解,我们已前后端分离的老项目为例进行改造。

1.在IDEA中新建maven父工程

这个父工程只需要有一个pom.xml文件就可以了,不要去勾选骨架

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

接着设置父工程的属性

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

然后完成即可

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

2.导入已存在的后端工程

将后端工程检出或拷贝到父工程的目录下

打开父工程的工程结构

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

切换到Modules选项,更改jdk的版本为8

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

找到你父工程目录下的后端项目,进行模块添加

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

将后端项目作为maven项目导入

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

点击finish即可

3.导入已存在的前端工程

将后端工程检出或拷贝到父工程的目录下

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

找到你的前端项目,进行模块添加

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

完成后的这一步非常关键,选择创建模块

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

剩余步骤直接点就可以了。

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

最终效果

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

工程改造完成,总结一下,只是新建了一个父工程,将原来的项目移到这个父工程下即可

三、进行三个工程的maven打包配置

我们完全可以照着dubbo-admin工程的maven配置进行改造,主要的改动有:

  • 在父工程中指定子工程模块
  • 子工程指定父工程坐标
  • 后端子工程添加相应的maven插件
  • 后端子工程指定要拷贝到源地址和目标地址
  • 前端子工程也添加响应的maven插件
  • 前端安装node和npm

1.父工程maven配置

<?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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
    </parent>
    <groupId>com.anymk</groupId>
    <artifactId>parent-boot-vue</artifactId>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>csdn-reader</module>
        <module>construction-data</module>
    </modules>
    <packaging>pom</packaging>

    <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>

    <build>
        <plugins>
            <!--编译插件-->
            <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>

2.SpringBoot工程maven配置

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.anymk</groupId>
        <artifactId>parent-boot-vue</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>csdn-reader</artifactId>

    <properties>
        <java.version>1.8</java.version>
        <spring.boot.version>2.1.8.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>
    </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-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.8</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.54</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
        <!-- database -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </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}/construction-data/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}/construction-data/dist</directory>
                                    <includes>
                                        <include>index.html</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

3.Vue工程maven配置

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.anymk</groupId>
        <artifactId>parent-boot-vue</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>construction-data</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>

4.maven插件作用讲解

最重要的插件就两个,一个是springboot项目里的maven-resources-plugin,另一个是vue项目里的frontend-maven-plugin

资源插件的复制路径很好理解,vue项目打包的目录如图所示

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

而我们要在springboot项目里运行,就要把index.html文件复制到templates目录,其他文件复制到static目录。

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

四、 打包运行

1.运行前确保自己的node环境已经安装

事实证明我是想多了,插件里面已经进行了配置,不会使用本地的node环境,而是会去网上重新下载一个node,这样是有好处的,一个不懂node的后端工程师,本地不需要安装node,也可以将这个项目打包成功。在Mac和Linux的开发中,也不需要安装node。

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

2. 进入父工程根目录,执行打包命令

mvn clean package -Dmaven.test.skip=true

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

3.打包成功

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

4.查看最终的jar包

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

找到本地的这个jar包,用解压缩工具查看静态资源有没有被打包进去

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

 

5、安装过程中出现的错误

错误一、

在前端打包的过程中,还是出现了问题的,主要为打包程序并没有用本地的node,而是去网上直接下载了一个node.exe,该文件的位置为:

D:\parent-boot-vue\construction-data\node\node.exe

这个配置在哪里呢,是我们在pom.xml中进行了指定,包括node和npm的版本:

 如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

在此过程中,报错如下:

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

看报错日志,大致意思为下载下来的node文件有问题,于是我手动下载了一个,地址为:

https://nodejs.org/dist/v10.16.0/win-x64/node.exe

 然后再拷贝到D:\parent-boot-vue\construction-data\node目录去替换原来的node.exe文件,再次运行就完美。

ps:因为网络原因,可能执行命令时卡顿、报错,可以多尝试执行几次。

错误二、父工程找不到子工程的问题

我最开始没有将子工程放到父工程的目录下,所以打包时找不到子工程,后面将子工程进行拷贝问题就解决了。

错误三、index.html没有被拷贝的问题

后端maven配置错误,没有配置正确的源地址和目标地址,画红线的地方一定要注意

如何将SpringBoot+Vue前后端分离项目一次打包为一个Jar包运行?

 五、frontend-maven-plugin插件的扩展

这个插件不仅仅支持node+npm,还支持node+yarn。

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>

一定要多看报错日志,不能轻言放弃! 

面对敌人的严刑逼供,我一个字也没说,而是一五一十写了下来。

最后,非常感谢小LUA大大帖子对我的帮助,没有你的指引,我是无法完成这个配置的。也感谢dubbo-admin项目,大家可以参考该项目的配置。其实上面的配置都是从该项目中拷贝过来的,哈哈。

打包命令:mvn clean package -Dmaven.test.skip=true

参考资料: 

  1. https://www.cnblogs.com/LUA123/p/11189069.html
相关标签: 项目构建