前面介绍过感觉vue和springboot的几篇文章,当一个项目做完了后,就该打包发布了。本节就研究下打包发布。

项目使用的技术:

  • 开发工具: idea
  • 前端: 使用vue element admin改造的
  • 后端:springboot、mysql、jpa
  • 打包手段: maven 插件

想知道原理和细节的,文章可以从头到尾看;直接看结果,可以跳到文章最后升级版打包方式。

结果图:

1.打包原理

前后端分离,先看下如何分别打包。

  • vue前端打包,可以通过package.json里提供的命令。如:npm run buildnpm run build:prod
  • springboot后端打包,项目是基于maven构建的,通过mvn clean package -Dmaven.test.skip=truemvn clean install -Dmaven.test.skip=true

两个分别打包,部署到web容器(nginx、tomcat等)中,没有问题,只要vue能够访问到springboot启动的服务既可以。(即启动了两个进程)

网上有教程,这就不多介绍了。这不是我想要的方式。提供个链接供需要的者参考下:

2.手动挡

了解spingboot的应该知道springboot里内嵌了tomcat,配置了默认静态文件路径。

有兴趣的可以看下我整理的springboot配置文件中最后有提到静态资源配置。

springboot通过全局配置spring.mvc.static-path-pattern=来指定静态资源路径

默认值:/static,/public,/resources,/META-INF/resources

官网定义:
By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) 
in the classpath or from the root of the ServletContext.

因此,我们可以将vue前端打包好的静态文件直接放到springboot的静态文件路径下,启动一个springboot项目就可以了。

2-1.vue打包

通过vue-element-admin代码里package.json我们可以找到打包命令

{
  "scripts": {
    "dev": "vue-cli-service serve",
    "lint": "eslint --ext .js,.vue src",
    "build:prod": "vue-cli-service build",
    "build:stage": "vue-cli-service build --mode staging",
    "preview": "node build/index.js --preview",
    "new": "plop",
    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
    "test:unit": "jest --clearCache && vue-cli-service test:unit",
    "test:ci": "npm run lint && npm run test:unit"
  }
}

可以通过命名行npm run build:prod进行打包,打包后可以在dist目录下看到打包好的静态文件。

然后就可以通过浏览器打开index.html文件,如果能看到画面说明打包成功,没有问题。

如果有问题,访问不了。可以修改vue.config.js文件里的publicPath修改为publicPath: './',。然后再打包,看下浏览器能否成功打开?

2-2.springboot打包

前端打包后,将其copy到springboot的静态路径下,通过maven打包即可。

默认静态路径有:/static,/public,/resources,/META-INF/resources,也可以通过spring.mvc.static-path-pattern=来指定静态资源路径修改。

然后通过maven打包mvn clean install -Dmaven.test.skip=true,到target目录下,找到打包的jar包,运行。

java -jar xxx-0.0.1-SNAPSHOT.jar --server-port=9898

注意这的jar是有依赖的jar(文件大的jar),而不是xxx-SNAPSHOT.jar.original的jar。
启动后就可以看到结果了。(注意数据库、redis用到的服务别忘了先启动)

这种方式也不是重点,主要告诉大家原理。如有不明白的,可以留言,或者参考下这篇blog,里面有图。

到这手动挡方式,就完成了。身为一个懒惰(合格)的程序员,还要手动去copy文件,肯定不行的。因此我们想想又没啥工具自动给我们copy文件了?

3.自动挡

上面手动挡,需要手动copy文件。很麻烦,我们使用的maven来进行打包的,因此我们很容易想到去找个插件,来替我们干这苦力活。

  • 复制文件maven插件叫maven-resources-plugin,具体细节怎么使用可以自己搜索下。
  • 当然了vue前端,也得找个maven插件,也一起打包就更完美。有个maven插件叫frontend-maven-plugin可以办到这事

主要思路:

  • frontend-maven-plugin打包生成静态文件
  • maven-resources-plugin将静态文件打包时,将静态文件复制到指定的目录下,一起打包。

比较著名的dubbo-admin就是使用这种方式maven一键打包完成。

查看下其dubbo-admin-ui模块里的pom.xml和dubbo-admin-server模块里的pom.xml

也可以看下这篇blog

这也不是我想要的,所以就不演示了。具体可参照dubbo-admin和提供的blog,自己试下即可。

这里给几个技巧,给大家避坑。其中install-node-and-npm时候会下载node和npm,可以将电脑上安装好的文件直接copy过去。
执行mvn打包前端时候,就不会再去下了。不然mvn执行下载时候会一直报错。(复制的路径是package.json所在目录的node目录下)

这里介绍下两个插件使用示例,以备需要的人使用

3-1.frontend插件

安装node和npm的情况

<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.7.6</version>
    <configuration>
      <workingDirectory>${basedir}</workingDirectory>
      <nodeDownloadRoot>https://npm.taobao.org/mirrors/node/</nodeDownloadRoot>
      <npmDownloadRoot>https://registry.npm.taobao.org/npm/</npmDownloadRoot>
      <npmRegistryURL>https://registry.npm.taobao.org</npmRegistryURL>
    </configuration>
    <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>
      <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:prod</arguments>
        </configuration>
      </execution>
    </executions>
</plugin>

根据自己需要改吧改吧即可。run build:prod还是run build根据package.json里定义而改。

安装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:prod</arguments>
        </configuration>
      </execution>
    </executions>
</plugin>

3-2.resources插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>copy static</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <!-- 复制前端打包文件到这里 -->
                <outputDirectory>${basedir}/src/main/resources/public</outputDirectory>
                <overwrite>true</overwrite>
                <resources>
                    <resource>
                        <!-- 从前端打包的目录dist进行指定文件、文件夹内容的复制-->
                        <directory>${vue.dist.dir}</directory>
                        <includes>
                            <!-- 具体根据实际前端代码、及目录结构进行配置-->
                            <include>css/</include>
                            <include>fonts/</include>
                            <include>img/</include>
                            <include>js/</include>
                            <include>favicon.ico</include>
                            <include>index.html</include>
                        </includes>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

路径啥的,自己改吧改吧即可。

4.升级版

我们在开发时候,往往是前端、后端是不同的人。前端开发完后,直接打包发布就完了,后端要用其文件直接maven添加依赖进来引用即可。

所以,我们变换个思路。前端通过maven打包jar后,静态已经在jar中指定的路径里。后端直接添加个依赖即可以用了。所以把打包的重任都方在vue前端静态文件的打包上。

4-1.vue打包

在package.json同级目录下建一个pom.xml文件

其中用到两个插件

  • exec-maven-plugin: 跟frontend-maven-plugin类似,只是没有去下载node、npm等操作,因为一般环境node、npm都是安装好的。直接执行npm run build:prod即可。
  • maven-resources-plugin: 将打包好的静态文件复制指定路径下(springboot能够识别的静态路径),并打jar包

下面给个完成的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.iworkh.xxx</groupId>
  <artifactId>xxx-tool-web</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>xxx-tool-web</name>

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

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
          <execution>
            <id>exec-npm-run-build</id>
            <phase>compile</phase>
            <goals>
              <goal>exec</goal>
            </goals>
            <configuration>
              <executable>npm</executable>
              <arguments>
                <argument>run</argument>
                <argument>build:prod</argument>
              </arguments>
              <workingDirectory>${basedir}</workingDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.1.0</version>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.outputDirectory}/META-INF/resources</outputDirectory>
              <!--<outputDirectory>${project.build.outputDirectory}/public</outputDirectory>-->
              <resources>
                <resource>
                  <!-- 指定resources插件处理哪个目录下的资源文件 -->
                  <directory>dist</directory>
                  <filtering>false</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

通过mvn clean install命令对前端进行打包。去maven的本地仓库中检查下生成的前端jar包。

4-2.springboot打包

后端就简单了,对前端的jar直接进行maven依赖即可

<dependency>
    <groupId>com.iworkh.xxx</groupId>
    <artifactId>xxx-tool-web</artifactId>
    <version>${project.version}</version>
</dependency>

通过mvn clean install -Dmaven.test.skip=true命令对后端进行打包,生成的jar使用压缩工具打开,查看lib下,有vue前端的jar。


再对生成的后端jar通过命令启动即可

java -jar xxx-0.0.1-SNAPSHOT.jar --server-port=9898

注意依赖的mysql、redis等服务别忘了先启动,最后浏览器打开验证效果。

5.结果展示

6.推荐

能读到文章最后,首先得谢谢您对本文的肯定,你的肯定是对博主最大的鼓励。

你觉本文有帮助,那就点个👍
你有疑问,那就留下您的💬
怕把我弄丢了,那就把我⭐
电脑不方便看,那就把发到你📲

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐